diff --git a/php_v8js_macros.h b/php_v8js_macros.h index 85eeffa..c04c41e 100644 --- a/php_v8js_macros.h +++ b/php_v8js_macros.h @@ -50,7 +50,7 @@ extern "C" { #define V8JS_BOOL(v) v8::Boolean::New(v) #define V8JS_NULL v8::Null() #define V8JS_MN(name) v8js_method_##name -#define V8JS_METHOD(name) v8::Handle V8JS_MN(name)(const v8::Arguments& args) +#define V8JS_METHOD(name) void V8JS_MN(name)(const v8::FunctionCallbackInfo& info) #define V8JS_THROW(type, message, message_len) v8::ThrowException(v8::Exception::type(V8JS_STRL(message, message_len))) #define V8JS_GLOBAL v8::Context::GetCurrent()->Global() diff --git a/v8js.cc b/v8js.cc index f4eb533..930624d 100644 --- a/v8js.cc +++ b/v8js.cc @@ -231,15 +231,13 @@ static HashTable *php_v8js_v8_get_properties(zval *object TSRMLS_DC) /* {{{ */ v8::Locker locker(obj->isolate); v8::Isolate::Scope isolate_scope(obj->isolate); v8::HandleScope local_scope(obj->isolate); - v8::Persistent temp_context = v8::Context::New(); + v8::Local temp_context = v8::Context::New(obj->isolate); v8::Context::Scope temp_scope(temp_context); if (php_v8js_v8_get_properties_hash(obj->v8obj, retval, obj->flags, obj->isolate TSRMLS_CC) == SUCCESS) { - temp_context.Dispose(); return retval; } - temp_context.Dispose(); return NULL; } /* }}} */ @@ -391,7 +389,7 @@ void php_v8js_create_v8(zval *res, v8::Handle value, int flags, v8::I c = (php_v8js_object *) zend_object_store_get_object(res TSRMLS_CC); - c->v8obj = v8::Persistent::New(value); + c->v8obj = v8::Persistent::New(isolate, value); c->flags = flags; c->isolate = isolate; } @@ -589,14 +587,14 @@ static PHP_METHOD(V8Js, __construct) /* Create global template for global object */ // Now we are using multiple isolates this needs to be created for every context - c->global_template = v8::Persistent::New(v8::FunctionTemplate::New()); + c->global_template = v8::Persistent::New(c->isolate, v8::FunctionTemplate::New()); c->global_template->SetClassName(V8JS_SYM("V8Js")); /* Register builtin methods */ php_v8js_register_methods(c->global_template->InstanceTemplate(), c); /* Create context */ - c->context = v8::Context::New(&extension_conf, c->global_template->InstanceTemplate()); + c->context = v8::Persistent::New(c->isolate, v8::Context::New(c->isolate, &extension_conf, c->global_template->InstanceTemplate())); c->context->SetAlignedPointerInEmbedderData(1, c); if (exts) { @@ -634,7 +632,7 @@ static PHP_METHOD(V8Js, __construct) } /* Set name for the PHP JS object */ - c->object_name = v8::Persistent::New((object_name_len) ? V8JS_SYML(object_name, object_name_len) : V8JS_SYM("PHP")); + c->object_name = v8::Persistent::New(c->isolate, (object_name_len) ? V8JS_SYML(object_name, object_name_len) : V8JS_SYM("PHP")); /* Add the PHP object into global object */ V8JS_GLOBAL->Set(c->object_name, php_obj_t->InstanceTemplate()->NewInstance(), v8::ReadOnly); diff --git a/v8js_convert.cc b/v8js_convert.cc index 5784c84..7bb875f 100644 --- a/v8js_convert.cc +++ b/v8js_convert.cc @@ -34,24 +34,24 @@ extern "C" { #include /* Callback for PHP methods and functions */ -static v8::Handle php_v8js_php_callback(const v8::Arguments &args) /* {{{ */ +static void php_v8js_php_callback(const v8::FunctionCallbackInfo& info) /* {{{ */ { v8::Handle return_value; - zval *value = reinterpret_cast(args.This()->GetAlignedPointerFromInternalField(0)); - v8::Isolate *isolate = reinterpret_cast(args.This()->GetAlignedPointerFromInternalField(1)); + zval *value = reinterpret_cast(info.This()->GetAlignedPointerFromInternalField(0)); + v8::Isolate *isolate = reinterpret_cast(info.This()->GetAlignedPointerFromInternalField(1)); zend_function *method_ptr; zend_fcall_info fci; zend_fcall_info_cache fcc; zval fname, *retval_ptr = NULL, **argv = NULL; TSRMLS_FETCH(); zend_class_entry *ce = Z_OBJCE_P(value); - zend_uint argc = args.Length(), min_num_args = 0, max_num_args = 0; + zend_uint argc = info.Length(), min_num_args = 0, max_num_args = 0; char *error; int error_len, i, flags = V8JS_FLAG_NONE; /* Set method_ptr from v8::External or fetch the closure invoker */ - if (!args.Data().IsEmpty() && args.Data()->IsExternal()) { - method_ptr = static_cast(v8::External::Cast(*args.Data())->Value()); + if (!info.Data().IsEmpty() && info.Data()->IsExternal()) { + method_ptr = static_cast(v8::External::Cast(*info.Data())->Value()); } else { method_ptr = zend_get_closure_invoke_method(value TSRMLS_CC); } @@ -90,7 +90,8 @@ static v8::Handle php_v8js_php_callback(const v8::Arguments &args) /* efree(method_ptr); } efree(error); - return return_value; + info.GetReturnValue().Set(return_value); + return; } /* Convert parameters passed from V8 */ @@ -100,7 +101,7 @@ static v8::Handle php_v8js_php_callback(const v8::Arguments &args) /* argv = (zval **) safe_emalloc(argc, sizeof(zval *), 0); for (i = 0; i < argc; i++) { MAKE_STD_ZVAL(argv[i]); - if (v8js_to_zval(args[i], argv[i], flags, isolate TSRMLS_CC) == FAILURE) { + if (v8js_to_zval(info[i], argv[i], flags, isolate TSRMLS_CC) == FAILURE) { fci.param_count++; error_len = spprintf(&error, 0, "converting parameter #%d passed to %s() failed", i + 1, method_ptr->common.function_name); return_value = V8JS_THROW(Error, error, error_len); @@ -141,7 +142,7 @@ failure: return_value = V8JS_NULL; } - return return_value; + info.GetReturnValue().Set(return_value); } /* }}} */ @@ -167,24 +168,24 @@ static int _php_v8js_is_assoc_array(HashTable *myht TSRMLS_DC) /* {{{ */ } /* }}} */ -static v8::Handle php_v8js_property_caller(const v8::Arguments &args) /* {{{ */ +static void php_v8js_property_caller(const v8::FunctionCallbackInfo& info) /* {{{ */ { - v8::Local self = args.Holder(); - v8::Local cname = args.Callee()->GetName()->ToString(); + v8::Local self = info.Holder(); + v8::Local cname = info.Callee()->GetName()->ToString(); v8::Local value; - v8::Local cb_func = v8::Local::Cast(args.Data()); + v8::Local cb_func = v8::Local::Cast(info.Data()); value = self->GetHiddenValue(cb_func); if (!value.IsEmpty() && value->IsFunction()) { - int argc = args.Length(), i = 0; + int argc = info.Length(), i = 0; v8::Local *argv = new v8::Local[argc]; v8::Local cb = v8::Local::Cast(value); if (cb_func->Equals(V8JS_SYM(ZEND_INVOKE_FUNC_NAME))) { for (; i < argc; ++i) { - argv[i] = args[i]; + argv[i] = info[i]; } value = cb->Call(self, argc, argv); } @@ -192,25 +193,28 @@ static v8::Handle php_v8js_property_caller(const v8::Arguments &args) { v8::Local argsarr = v8::Array::New(argc); for (; i < argc; ++i) { - argsarr->Set(i, args[i]); + argsarr->Set(i, info[i]); } v8::Local argsv[2] = { cname, argsarr }; value = cb->Call(self, 2, argsv); } } - if (args.IsConstructCall()) { + if (info.IsConstructCall()) { if (!value.IsEmpty() && !value->IsNull()) { - return value; + info.GetReturnValue().Set(value); + return; } - return self; + + info.GetReturnValue().Set(self); + return; } - return value; + info.GetReturnValue().Set(value); } /* }}} */ -static v8::Handle php_v8js_property_getter(v8::Local property, const v8::AccessorInfo &info) /* {{{ */ +static void php_v8js_property_getter(v8::Local property, const v8::PropertyCallbackInfo &info) /* {{{ */ { v8::Local self = info.Holder(); v8::Local value; @@ -220,7 +224,8 @@ static v8::Handle php_v8js_property_getter(v8::Local prop value = self->GetRealNamedProperty(property); if (!value.IsEmpty()) { - return value; + info.GetReturnValue().Set(value); + return; } /* If __get() is set for PHP object, call it */ @@ -236,21 +241,23 @@ static v8::Handle php_v8js_property_getter(v8::Local prop v8::Local cb_t = v8::FunctionTemplate::New(php_v8js_property_caller, V8JS_SYM(ZEND_CALL_FUNC_NAME)); cb = cb_t->GetFunction(); cb->SetName(property); - return cb; + info.GetReturnValue().Set(cb); + return; } - return value; + info.GetReturnValue().Set(value); } /* }}} */ -static v8::Handle php_v8js_property_query(v8::Local property, const v8::AccessorInfo &info) /* {{{ */ +static void php_v8js_property_query(v8::Local property, const v8::PropertyCallbackInfo &info) /* {{{ */ { v8::Local self = info.Holder(); v8::Local value; /* Return early if property is set in JS object */ if (self->HasRealNamedProperty(property)) { - return V8JS_INT(v8::ReadOnly); + info.GetReturnValue().Set(V8JS_INT(v8::ReadOnly)); + return; } value = self->GetHiddenValue(V8JS_SYM(ZEND_ISSET_FUNC_NAME)); @@ -260,7 +267,7 @@ static v8::Handle php_v8js_property_query(v8::Local pro value = cb->Call(self, 1, argv); } - return (!value.IsEmpty() && value->IsTrue()) ? V8JS_INT(v8::ReadOnly) : v8::Local(); + info.GetReturnValue().Set((!value.IsEmpty() && value->IsTrue()) ? V8JS_INT(v8::ReadOnly) : v8::Local()); } /* }}} */ diff --git a/v8js_methods.cc b/v8js_methods.cc index 5fcd005..abd5475 100644 --- a/v8js_methods.cc +++ b/v8js_methods.cc @@ -36,15 +36,13 @@ void php_v8js_commonjs_normalise_identifier(char *base, char *identifier, char * V8JS_METHOD(exit) /* {{{ */ { v8::V8::TerminateExecution(); - return v8::Undefined(); } /* }}} */ /* global.sleep - sleep for passed seconds */ V8JS_METHOD(sleep) /* {{{ */ { - php_sleep(args[0]->Int32Value()); - return v8::Undefined(); + php_sleep(info[0]->Int32Value()); } /* }}} */ @@ -54,12 +52,12 @@ V8JS_METHOD(print) /* {{{ */ int ret = 0; TSRMLS_FETCH(); - for (int i = 0; i < args.Length(); i++) { - v8::String::Utf8Value str(args[i]); + for (int i = 0; i < info.Length(); i++) { + v8::String::Utf8Value str(info[i]); const char *cstr = ToCString(str); ret = PHPWRITE(cstr, strlen(cstr)); } - return V8JS_INT(ret); + info.GetReturnValue().Set(V8JS_INT(ret)); } /* }}} */ @@ -161,26 +159,27 @@ V8JS_METHOD(var_dump) /* {{{ */ int i; TSRMLS_FETCH(); - for (int i = 0; i < args.Length(); i++) { - _php_v8js_dumper(args[i], 1 TSRMLS_CC); + for (int i = 0; i < info.Length(); i++) { + _php_v8js_dumper(info[i], 1 TSRMLS_CC); } - return V8JS_NULL; + info.GetReturnValue().Set(V8JS_NULL); } /* }}} */ V8JS_METHOD(require) { // Get the extension context - v8::Handle data = v8::Handle::Cast(args.Data()); + v8::Handle data = v8::Handle::Cast(info.Data()); php_v8js_ctx *c = static_cast(data->Value()); // Check that we have a module loader if (c->module_loader == NULL) { - return v8::ThrowException(v8::String::New("No module loader")); + info.GetReturnValue().Set(v8::ThrowException(v8::String::New("No module loader"))); + return; } - v8::String::Utf8Value module_id_v8(args[0]); + v8::String::Utf8Value module_id_v8(info[0]); // Make sure to duplicate the module name string so it doesn't get freed by the V8 garbage collector char *module_id = estrdup(ToCString(module_id_v8)); @@ -207,7 +206,8 @@ V8JS_METHOD(require) if (!strcmp(*it, normalised_module_id)) { efree(normalised_path); - return v8::ThrowException(v8::String::New("Module cyclic dependency")); + info.GetReturnValue().Set(v8::ThrowException(v8::String::New("Module cyclic dependency"))); + return; } } @@ -215,7 +215,8 @@ V8JS_METHOD(require) if (V8JSG(modules_loaded).count(normalised_module_id) > 0) { efree(normalised_path); - return V8JSG(modules_loaded)[normalised_module_id]; + info.GetReturnValue().Set(V8JSG(modules_loaded)[normalised_module_id]); + return; } // Callback to PHP to load the module code @@ -230,7 +231,8 @@ V8JS_METHOD(require) if (FAILURE == call_user_function(EG(function_table), NULL, c->module_loader, &module_code, 1, params TSRMLS_CC)) { efree(normalised_path); - return v8::ThrowException(v8::String::New("Module loader callback failed")); + info.GetReturnValue().Set(v8::ThrowException(v8::String::New("Module loader callback failed"))); + return; } // Check if an exception was thrown @@ -239,7 +241,8 @@ V8JS_METHOD(require) // Clear the PHP exception and throw it in V8 instead zend_clear_exception(TSRMLS_CC); - return v8::ThrowException(v8::String::New("Module loader callback exception")); + info.GetReturnValue().Set(v8::ThrowException(v8::String::New("Module loader callback exception"))); + return; } // Convert the return value to string @@ -251,7 +254,8 @@ V8JS_METHOD(require) if (!strlen(Z_STRVAL(module_code))) { efree(normalised_path); - return v8::ThrowException(v8::String::New("Module loader callback did not return code")); + info.GetReturnValue().Set(v8::ThrowException(v8::String::New("Module loader callback did not return code"))); + return; } // Create a template for the global object and set the built-in global functions @@ -272,7 +276,7 @@ V8JS_METHOD(require) global->Set(v8::String::New("module"), module); // Each module gets its own context so different modules do not affect each other - v8::Persistent context = v8::Context::New(NULL, global); + v8::Persistent context = v8::Persistent::New(c->isolate, v8::Context::New(c->isolate, NULL, global)); // Catch JS exceptions v8::TryCatch try_catch; @@ -295,7 +299,8 @@ V8JS_METHOD(require) // The script will be empty if there are compile errors if (script.IsEmpty()) { efree(normalised_path); - return v8::ThrowException(v8::String::New("Module script compile failed")); + info.GetReturnValue().Set(v8::ThrowException(v8::String::New("Module script compile failed"))); + return; } // Add this module and path to the stack @@ -314,13 +319,15 @@ V8JS_METHOD(require) // Script possibly terminated, return immediately if (!try_catch.CanContinue()) { - return v8::ThrowException(v8::String::New("Module script compile failed")); + info.GetReturnValue().Set(v8::ThrowException(v8::String::New("Module script compile failed"))); + return; } // Handle runtime JS exceptions if (try_catch.HasCaught()) { // Rethrow the exception back to JS - return try_catch.ReThrow(); + info.GetReturnValue().Set(try_catch.ReThrow()); + return; } // Cache the module so it doesn't need to be compiled and run again @@ -333,7 +340,7 @@ V8JS_METHOD(require) V8JSG(modules_loaded)[normalised_module_id] = handle_scope.Close(exports); } - return V8JSG(modules_loaded)[normalised_module_id]; + info.GetReturnValue().Set(V8JSG(modules_loaded)[normalised_module_id]); } void php_v8js_register_methods(v8::Handle global, php_v8js_ctx *c) /* {{{ */ diff --git a/v8js_variables.cc b/v8js_variables.cc index e58e77d..0ecfa74 100644 --- a/v8js_variables.cc +++ b/v8js_variables.cc @@ -38,7 +38,7 @@ struct php_v8js_accessor_ctx v8::Isolate *isolate; }; -static v8::Handle php_v8js_fetch_php_variable(v8::Local name, const v8::AccessorInfo &info) /* {{{ */ +static void php_v8js_fetch_php_variable(v8::Local name, const v8::PropertyCallbackInfo& info) /* {{{ */ { v8::Handle data = v8::Handle::Cast(info.Data()); php_v8js_accessor_ctx *ctx = static_cast(data->Value()); @@ -49,10 +49,9 @@ static v8::Handle php_v8js_fetch_php_variable(v8::Local n zend_is_auto_global(ctx->variable_name_string, ctx->variable_name_string_len TSRMLS_CC); if (zend_hash_find(&EG(symbol_table), ctx->variable_name_string, ctx->variable_name_string_len + 1, (void **) &variable) == SUCCESS) { - return zval_to_v8js(*variable, ctx->isolate TSRMLS_CC); + info.GetReturnValue().Set(zval_to_v8js(*variable, ctx->isolate TSRMLS_CC)); + return; } - - return v8::Undefined(); } /* }}} */