diff --git a/Vagrantfile b/Vagrantfile index 86ff4a4..aff4e1e 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -8,17 +8,17 @@ Vagrant.configure("2") do |config| # Every Vagrant development environment requires a box. You can search for # boxes at https://atlas.hashicorp.com/search. - config.vm.box = "ubuntu/trusty64" + config.vm.box = "ubuntu/xenial64" config.vm.provider "lxc" do |lxc, override| - override.vm.box = "fgrehm/trusty64-lxc" + override.vm.box = "zaikin/xenial64-lxc" end # # mass-define "generic" Ubuntu boxes # - %w{5.1 5.2 5.4 5.7 5.8 5.9 6.0}.each { |version| + %w{5.7 5.8 5.9 6.0}.each { |version| config.vm.define "v8-#{version}" do |i| i.vm.synced_folder ".", "/data/v8js" diff --git a/config.m4 b/config.m4 index 69127ea..0e30b4c 100644 --- a/config.m4 +++ b/config.m4 @@ -188,6 +188,8 @@ int main () LDFLAGS="$old_LDFLAGS" CPPFLAGS=$old_CPPFLAGS + AC_DEFINE([V8_DEPRECATION_WARNINGS], [1], [Enable compiler warnings when using V8_DEPRECATED apis.]) + PHP_ADD_INCLUDE($V8_DIR) PHP_NEW_EXTENSION(v8js, [ \ v8js_array_access.cc \ diff --git a/v8js_class.cc b/v8js_class.cc index 43f8bfe..900b5d6 100644 --- a/v8js_class.cc +++ b/v8js_class.cc @@ -410,8 +410,7 @@ static PHP_METHOD(V8Js, __construct) v8::HandleScope handle_scope(isolate); /* Redirect fatal errors to PHP error handler */ - // This needs to be done within the context isolate - v8::V8::SetFatalErrorHandler(v8js_fatal_error_handler); + isolate->SetFatalErrorHandler(v8js_fatal_error_handler); /* Create global template for global object */ // Now we are using multiple isolates this needs to be created for every context @@ -486,7 +485,7 @@ static PHP_METHOD(V8Js, __construct) /* Add the PHP object into global object */ php_obj_t->InstanceTemplate()->SetInternalFieldCount(2); v8::Local php_obj = php_obj_t->InstanceTemplate()->NewInstance(); - V8JS_GLOBAL(isolate)->ForceSet(object_name_js, php_obj, v8::ReadOnly); + V8JS_GLOBAL(isolate)->DefineOwnProperty(context, object_name_js, php_obj, v8::ReadOnly); /* Export public property values */ HashTable *properties = zend_std_get_properties(getThis()); @@ -504,12 +503,12 @@ static PHP_METHOD(V8Js, __construct) return; } - v8::Local key = v8::String::NewFromUtf8(isolate, ZSTR_VAL(member), + v8::Local key = v8::String::NewFromUtf8(isolate, ZSTR_VAL(member), v8::String::kInternalizedString, static_cast(ZSTR_LEN(member))); /* Write value to PHP JS object */ value = OBJ_PROP(Z_OBJ_P(getThis()), property_info->offset); - php_obj->ForceSet(key, zval_to_v8js(value, isolate), v8::ReadOnly); + php_obj->DefineOwnProperty(context, key, zval_to_v8js(value, isolate), v8::ReadOnly); } } ZEND_HASH_FOREACH_END(); @@ -584,7 +583,7 @@ static PHP_METHOD(V8Js, __construct) persistent_ft->Reset(isolate, ft); } - php_obj->ForceSet(method_name, ft->GetFunction()); + php_obj->CreateDataProperty(context, method_name, ft->GetFunction()); } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -616,7 +615,7 @@ static void v8js_compile_script(zval *this_ptr, const zend_string *str, const ze V8JS_BEGIN_CTX(c, this_ptr) /* Catch JS exceptions */ - v8::TryCatch try_catch; + v8::TryCatch try_catch(isolate); /* Set script identifier */ if (identifier && ZSTR_LEN(identifier) > std::numeric_limits::max()) { @@ -1289,8 +1288,8 @@ static void v8js_write_property(zval *object, zval *member, zval *value, void ** } /* Write value to PHP JS object */ - v8::Local key = V8JS_SYML(Z_STRVAL_P(member), static_cast(Z_STRLEN_P(member))); - jsobj->ForceSet(key, zval_to_v8js(value, isolate), v8::ReadOnly); + v8::Local key = V8JS_SYML(Z_STRVAL_P(member), static_cast(Z_STRLEN_P(member))); + jsobj->DefineOwnProperty(v8_context, key, zval_to_v8js(value, isolate), v8::ReadOnly); } /* Write value to PHP object */ diff --git a/v8js_exceptions.cc b/v8js_exceptions.cc index 1e77dcd..42fe7b1 100644 --- a/v8js_exceptions.cc +++ b/v8js_exceptions.cc @@ -44,7 +44,7 @@ void v8js_create_script_exception(zval *return_value, v8::Isolate *isolate, v8:: v8::Local tc_message = try_catch->Message(); const char *filename_string, *sourceline_string; char *message_string; - int linenum, start_col, end_col; + int linenum, start_col; object_init_ex(return_value, php_ce_v8js_script_exception); @@ -70,8 +70,10 @@ void v8js_create_script_exception(zval *return_value, v8::Isolate *isolate, v8:: start_col = tc_message->GetStartColumn(); PHPV8_EXPROP(_long, JsStartColumn, start_col); - end_col = tc_message->GetEndColumn(); - PHPV8_EXPROP(_long, JsEndColumn, end_col); + v8::Maybe end_col = tc_message->GetEndColumn(isolate->GetEnteredContext()); + if (end_col.IsJust()) { + PHPV8_EXPROP(_long, JsEndColumn, end_col.FromJust()); + } spprintf(&message_string, 0, "%s:%d: %s", filename_string, linenum, exception_string); diff --git a/v8js_generator_export.cc b/v8js_generator_export.cc index 4aea008..a27fa93 100644 --- a/v8js_generator_export.cc +++ b/v8js_generator_export.cc @@ -24,7 +24,7 @@ v8::Local v8js_wrap_generator(v8::Isolate *isolate, v8::LocalIsObject()); - v8::TryCatch try_catch; + v8::TryCatch try_catch(isolate); v8::Local source = v8::String::NewFromUtf8(isolate, "(\ function(wrapped_object) { \ return (function*() { \ diff --git a/v8js_methods.cc b/v8js_methods.cc index f22aa18..21fef8b 100644 --- a/v8js_methods.cc +++ b/v8js_methods.cc @@ -92,7 +92,7 @@ static void v8js_dumper(v8::Isolate *isolate, v8::Local var, int leve return; } - v8::TryCatch try_catch; /* object.toString() can throw an exception */ + v8::TryCatch try_catch(isolate); /* object.toString() can throw an exception */ v8::Local details; if(var->IsRegExp()) { @@ -100,7 +100,7 @@ static void v8js_dumper(v8::Isolate *isolate, v8::Local var, int leve details = re->GetSource(); } else { - details = var->ToDetailString(); + details = var->ToDetailString(isolate->GetEnteredContext()).FromMaybe(v8::Local()); if (try_catch.HasCaught()) { details = V8JS_SYM(""); @@ -401,18 +401,18 @@ V8JS_METHOD(require) } // Create a template for the global object and set the built-in global functions - v8::Local global_template = v8::ObjectTemplate::New(); + v8::Local global_template = v8::ObjectTemplate::New(isolate); 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_template = v8::ObjectTemplate::New(isolate); 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::Local module_template = v8::ObjectTemplate::New(); + v8::Local module_template = v8::ObjectTemplate::New(isolate); module_template->Set(V8JS_SYM("id"), V8JS_STR(normalised_module_id)); global_template->Set(V8JS_SYM("module"), module_template); @@ -420,7 +420,7 @@ V8JS_METHOD(require) v8::Local context = v8::Local::New(isolate, v8::Context::New(isolate, NULL, global_template)); // Catch JS exceptions - v8::TryCatch try_catch; + v8::TryCatch try_catch(isolate); v8::Locker locker(isolate); v8::Isolate::Scope isolate_scope(isolate); diff --git a/v8js_object_export.cc b/v8js_object_export.cc index 5bf36ad..254e0ed 100644 --- a/v8js_object_export.cc +++ b/v8js_object_export.cc @@ -438,10 +438,17 @@ static void v8js_invoke_callback(const v8::FunctionCallbackInfo& info new_tpl = v8::Local::New (isolate, ctx->template_cache.at(ce->name)); - result = new_tpl->GetFunction()->NewInstance(argc, argv); + v8::MaybeLocal maybeResult = new_tpl->GetFunction()->NewInstance(isolate->GetEnteredContext(), argc, argv); + + if (!maybeResult.IsEmpty()) { + result = maybeResult.ToLocalChecked(); + } else { + result = V8JS_UNDEFINED; + } } else { result = cb->Call(self, argc, argv); } + info.GetReturnValue().Set(result); } /* }}} */ @@ -804,7 +811,7 @@ static void v8js_named_property_deleter(v8::Local property, const v8 -static v8::Local v8js_wrap_object(v8::Isolate *isolate, zend_class_entry *ce, zval *value) /* {{{ */ +static v8::MaybeLocal v8js_wrap_object(v8::Isolate *isolate, zend_class_entry *ce, zval *value) /* {{{ */ { v8js_ctx *ctx = (v8js_ctx *) isolate->GetData(0); v8::Local new_tpl; @@ -903,11 +910,11 @@ static v8::Local v8js_wrap_object(v8::Isolate *isolate, zend_class_e // Create v8 wrapper object v8::Local external = v8::External::New(isolate, Z_OBJ_P(value)); - v8::Local newobj = new_tpl->GetFunction()->NewInstance(1, &external); + v8::MaybeLocal newobj = new_tpl->GetFunction()->NewInstance(isolate->GetEnteredContext(), 1, &external); - if (ce == zend_ce_closure) { + if (ce == zend_ce_closure && !newobj.IsEmpty()) { // free uncached function template when object is freed - ctx->weak_closures[persist_tpl_].Reset(isolate, newobj); + ctx->weak_closures[persist_tpl_].Reset(isolate, newobj.ToLocalChecked()); ctx->weak_closures[persist_tpl_].SetWeak(persist_tpl_, v8js_weak_closure_callback, v8::WeakCallbackType::kParameter); } @@ -1025,15 +1032,19 @@ v8::Local v8js_hash_to_jsobj(zval *value, v8::Isolate *isolate) /* {{ /* If it's a PHP object, wrap it */ if (ce) { - v8::Local wrapped_object = v8js_wrap_object(isolate, ce, value); + v8::MaybeLocal wrapped_object = v8js_wrap_object(isolate, ce, value); + + if (wrapped_object.IsEmpty()) { + return V8JS_UNDEFINED; + } if (ce == zend_ce_generator) { /* Wrap PHP Generator object in a wrapper function that provides * ES6 style behaviour. */ - wrapped_object = v8js_wrap_generator(isolate, wrapped_object); + return v8js_wrap_generator(isolate, wrapped_object.ToLocalChecked()); } - return wrapped_object; + return wrapped_object.ToLocalChecked(); } /* Associative PHP arrays cannot be wrapped to JS arrays, convert them to diff --git a/v8js_timer.cc b/v8js_timer.cc index 965d865..185907f 100644 --- a/v8js_timer.cc +++ b/v8js_timer.cc @@ -67,7 +67,7 @@ static void v8js_timer_interrupt_handler(v8::Isolate *isolate, void *data) { /* if (timer_ctx->memory_limit > 0 && hs.used_heap_size() > timer_ctx->memory_limit) { if (has_sent_notification) { timer_ctx->killed = true; - v8::V8::TerminateExecution(c->isolate); + c->isolate->TerminateExecution(); c->memory_limit_hit = true; } else { // force garbage collection, then check again @@ -98,7 +98,7 @@ void v8js_timer_thread(zend_v8js_globals *globals) /* {{{ */ } else if(timer_ctx->time_limit > 0 && now > timer_ctx->time_point) { timer_ctx->killed = true; - v8::V8::TerminateExecution(c->isolate); + c->isolate->TerminateExecution(); c->time_limit_hit = true; } else if (timer_ctx->memory_limit > 0) { diff --git a/v8js_v8.cc b/v8js_v8.cc index f886f0c..607fb42 100644 --- a/v8js_v8.cc +++ b/v8js_v8.cc @@ -120,7 +120,7 @@ void v8js_v8_call(v8js_ctx *c, zval **return_value, V8JSG(timer_mutex).unlock(); /* Catch JS exceptions */ - v8::TryCatch try_catch; + v8::TryCatch try_catch(isolate); /* Set flags for runtime use */ c->flags = flags; @@ -246,7 +246,7 @@ void v8js_v8_call(v8js_ctx *c, zval **return_value, void v8js_terminate_execution(v8::Isolate *isolate) /* {{{ */ { - if(v8::V8::IsExecutionTerminating(isolate)) { + if(isolate->IsExecutionTerminating()) { /* Execution already terminating, needn't trigger it again and * especially must not execute the spinning loop (which would cause * crashes in V8 itself, at least with 4.2 and 4.3 version lines). */ @@ -264,7 +264,7 @@ void v8js_terminate_execution(v8::Isolate *isolate) /* {{{ */ v8::Local source = V8JS_STR("for(;;);"); v8::Local script = v8::Script::Compile(source); - v8::V8::TerminateExecution(isolate); + isolate->TerminateExecution(); script->Run(); } /* }}} */ @@ -282,7 +282,9 @@ int v8js_get_properties_hash(v8::Local jsValue, HashTable *retval, in v8::Local jsKey = jsKeys->Get(i)->ToString(); /* Skip any prototype properties */ - if (!jsObj->HasOwnProperty(jsKey) && !jsObj->HasRealNamedProperty(jsKey) && !jsObj->HasRealNamedCallbackProperty(jsKey)) { + if (!jsObj->HasOwnProperty(isolate->GetEnteredContext(), jsKey).FromMaybe(false) + && !jsObj->HasRealNamedProperty(jsKey) + && !jsObj->HasRealNamedCallbackProperty(jsKey)) { continue; } diff --git a/v8js_v8object_class.cc b/v8js_v8object_class.cc index 8814bc8..dcfc384 100644 --- a/v8js_v8object_class.cc +++ b/v8js_v8object_class.cc @@ -175,7 +175,7 @@ static void v8js_v8object_write_property(zval *object, zval *member, zval *value } if (v8obj->IsObject()) { - v8obj->ToObject()->ForceSet(V8JS_SYML(Z_STRVAL_P(member), static_cast(Z_STRLEN_P(member))), zval_to_v8js(value, isolate)); + v8obj->ToObject()->CreateDataProperty(v8_context, V8JS_SYML(Z_STRVAL_P(member), static_cast(Z_STRLEN_P(member))), zval_to_v8js(value, isolate)); } } /* }}} */