From b21ba328d072650555fe532eb14135fb39472913 Mon Sep 17 00:00:00 2001 From: Stefan Siegl Date: Sun, 22 May 2016 13:27:48 +0200 Subject: [PATCH] Don't call ObjectTemplate.Set with Object instances, fixes #230 This works fine with V8 < 5.2.50 somehow, but is now (properly) detected and causing V8 to bail out. Fixed by always setting templates on other templates and finally use Global-Proxy on context to get the actually created object instances. --- v8js_methods.cc | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/v8js_methods.cc b/v8js_methods.cc index 0719b721..166788f9 100644 --- a/v8js_methods.cc +++ b/v8js_methods.cc @@ -208,7 +208,7 @@ V8JS_METHOD(require) V8JS_TSRMLS_FETCH(); // Get the extension context - v8::Handle data = v8::Handle::Cast(info.Data()); + v8::Local data = v8::Local::Cast(info.Data()); v8js_ctx *c = static_cast(data->Value()); // Check that we have a module loader @@ -411,25 +411,23 @@ V8JS_METHOD(require) } // Create a template for the global object and set the built-in global functions - v8::Handle global = v8::ObjectTemplate::New(); - global->Set(V8JS_SYM("print"), v8::FunctionTemplate::New(isolate, V8JS_MN(print)), v8::ReadOnly); - global->Set(V8JS_SYM("var_dump"), v8::FunctionTemplate::New(isolate, V8JS_MN(var_dump)), v8::ReadOnly); - global->Set(V8JS_SYM("sleep"), v8::FunctionTemplate::New(isolate, V8JS_MN(sleep)), v8::ReadOnly); - global->Set(V8JS_SYM("require"), v8::FunctionTemplate::New(isolate, V8JS_MN(require), v8::External::New(isolate, c)), v8::ReadOnly); + v8::Local global_template = v8::ObjectTemplate::New(); + global_template->Set(V8JS_SYM("print"), v8::FunctionTemplate::New(isolate, V8JS_MN(print)), v8::ReadOnly); + global_template->Set(V8JS_SYM("var_dump"), v8::FunctionTemplate::New(isolate, V8JS_MN(var_dump)), v8::ReadOnly); + global_template->Set(V8JS_SYM("sleep"), v8::FunctionTemplate::New(isolate, V8JS_MN(sleep)), v8::ReadOnly); + global_template->Set(V8JS_SYM("require"), v8::FunctionTemplate::New(isolate, V8JS_MN(require), v8::External::New(isolate, c)), v8::ReadOnly); // Add the exports object in which the module can return its API v8::Local exports_template = v8::ObjectTemplate::New(); - v8::Local exports = exports_template->NewInstance(); - global->Set(V8JS_SYM("exports"), exports); + global_template->Set(V8JS_SYM("exports"), exports_template); // Add the module object in which the module can have more fine-grained control over what it can return - v8::Handle module_template = v8::ObjectTemplate::New(); - v8::Handle module = module_template->NewInstance(); - module->Set(V8JS_SYM("id"), V8JS_STR(normalised_module_id)); - global->Set(V8JS_SYM("module"), module); + v8::Local module_template = v8::ObjectTemplate::New(); + module_template->Set(V8JS_SYM("id"), V8JS_STR(normalised_module_id)); + global_template->Set(V8JS_SYM("module"), module_template); // Each module gets its own context so different modules do not affect each other - v8::Local context = v8::Local::New(isolate, v8::Context::New(isolate, NULL, global)); + v8::Local context = v8::Local::New(isolate, v8::Context::New(isolate, NULL, global_template)); // Catch JS exceptions v8::TryCatch try_catch; @@ -487,16 +485,19 @@ V8JS_METHOD(require) return; } - v8::Handle newobj; + v8::Local newobj; // Cache the module so it doesn't need to be compiled and run again // Ensure compatibility with CommonJS implementations such as NodeJS by playing nicely with module.exports and exports - if (module->Has(V8JS_SYM("exports")) && !module->Get(V8JS_SYM("exports"))->IsUndefined()) { + if (context->Global()->Has(V8JS_SYM("module")) + && context->Global()->Get(V8JS_SYM("module"))->IsObject() + && context->Global()->Get(V8JS_SYM("module"))->ToObject()->Has(V8JS_SYM("exports")) + && context->Global()->Get(V8JS_SYM("module"))->ToObject()->Get(V8JS_SYM("exports"))->IsObject()) { // If module.exports has been set then we cache this arbitrary value... - newobj = module->Get(V8JS_SYM("exports"))->ToObject(); + newobj = context->Global()->Get(V8JS_SYM("module"))->ToObject()->Get(V8JS_SYM("exports"))->ToObject(); } else { // ...otherwise we cache the exports object itself - newobj = exports; + newobj = context->Global()->Get(V8JS_SYM("exports"))->ToObject(); } c->modules_loaded[normalised_module_id].Reset(isolate, newobj);