Explorar o código

V8 isolates need to be passed into all variable accessor and conversion functions.

Simon Best %!s(int64=12) %!d(string=hai) anos
pai
achega
8d8c671aa0
Modificáronse 4 ficheiros con 61 adicións e 45 borrados
  1. 5 5
      php_v8js_macros.h
  2. 17 17
      v8js.cc
  3. 17 15
      v8js_convert.cc
  4. 22 8
      v8js_variables.cc

+ 5 - 5
php_v8js_macros.h

@@ -92,19 +92,19 @@ extern zend_class_entry *php_ce_v8_object;
 extern zend_class_entry *php_ce_v8_function;
 
 /* Create PHP V8 object */
-void php_v8js_create_v8(zval *, v8::Handle<v8::Value>, int TSRMLS_DC);
+void php_v8js_create_v8(zval *, v8::Handle<v8::Value>, int, v8::Isolate * TSRMLS_DC);
 
 /* Fetch V8 object properties */
-int php_v8js_v8_get_properties_hash(v8::Handle<v8::Value>, HashTable *, int TSRMLS_DC);
+int php_v8js_v8_get_properties_hash(v8::Handle<v8::Value>, HashTable *, int, v8::Isolate * TSRMLS_DC);
 
 /* Convert zval into V8 value */
-v8::Handle<v8::Value> zval_to_v8js(zval * TSRMLS_DC);
+v8::Handle<v8::Value> zval_to_v8js(zval *, v8::Isolate * TSRMLS_DC);
 
 /* Convert V8 value into zval */
-int v8js_to_zval(v8::Handle<v8::Value>, zval *, int TSRMLS_DC);
+int v8js_to_zval(v8::Handle<v8::Value>, zval *, int, v8::Isolate * TSRMLS_DC);
 
 /* Register accessors into passed object */
-void php_v8js_register_accessors(v8::Local<v8::ObjectTemplate>, zval * TSRMLS_DC);
+void php_v8js_register_accessors(v8::Local<v8::ObjectTemplate>, zval *, v8::Isolate * TSRMLS_DC);
 
 /* {{{ Context container */
 struct php_v8js_ctx {

+ 17 - 17
v8js.cc

@@ -112,6 +112,7 @@ struct php_v8js_object {
 	zend_object std;
 	v8::Persistent<v8::Value> v8obj;
 	int flags;
+	v8::Isolate *isolate;
 };
 /* }}} */
 
@@ -147,7 +148,7 @@ static zval *php_v8js_v8_read_property(zval *object, zval *member, int type ZEND
 				MAKE_STD_ZVAL(retval);
 			}
 
-			if (v8js_to_zval(jsVal, retval, obj->flags TSRMLS_CC) == SUCCESS) {
+			if (v8js_to_zval(jsVal, retval, obj->flags, obj->isolate TSRMLS_CC) == SUCCESS) {
 				return retval;
 			}
 		}
@@ -164,7 +165,7 @@ static void php_v8js_v8_write_property(zval *object, zval *member, zval *value Z
 	php_v8js_object *obj = (php_v8js_object *) zend_object_store_get_object(object TSRMLS_CC);
 
 	if (obj->v8obj->IsObject() && !obj->v8obj->IsFunction()) {
-		obj->v8obj->ToObject()->ForceSet(V8JS_SYML(Z_STRVAL_P(member), Z_STRLEN_P(member)), zval_to_v8js(value TSRMLS_CC));
+		obj->v8obj->ToObject()->ForceSet(V8JS_SYML(Z_STRVAL_P(member), Z_STRLEN_P(member)), zval_to_v8js(value, obj->isolate TSRMLS_CC));
 	}
 }
 /* }}} */
@@ -179,7 +180,7 @@ static void php_v8js_v8_unset_property(zval *object, zval *member ZEND_HASH_KEY_
 }
 /* }}} */
 
-int php_v8js_v8_get_properties_hash(v8::Handle<v8::Value> jsValue, HashTable *retval, int flags TSRMLS_DC) /* {{{ */
+int php_v8js_v8_get_properties_hash(v8::Handle<v8::Value> jsValue, HashTable *retval, int flags, v8::Isolate *isolate TSRMLS_DC) /* {{{ */
 {
 	v8::Local<v8::Object> jsObj = jsValue->ToObject();
 
@@ -202,7 +203,7 @@ int php_v8js_v8_get_properties_hash(v8::Handle<v8::Value> jsValue, HashTable *re
 
 			MAKE_STD_ZVAL(value);
 
-			if (v8js_to_zval(jsVal, value, flags TSRMLS_CC) == FAILURE) {
+			if (v8js_to_zval(jsVal, value, flags, isolate TSRMLS_CC) == FAILURE) {
 				zval_ptr_dtor(&value);
 				return FAILURE;
 			}
@@ -223,19 +224,17 @@ static HashTable *php_v8js_v8_get_properties(zval *object TSRMLS_DC) /* {{{ */
 {
 	php_v8js_object *obj = (php_v8js_object *) zend_object_store_get_object(object TSRMLS_CC);
 	HashTable *retval;
-	
+
 	ALLOC_HASHTABLE(retval);
 	zend_hash_init(retval, 0, NULL, ZVAL_PTR_DTOR, 0);
 
-	php_v8js_ctx *c = (php_v8js_ctx *)v8::Context::GetCurrent()->GetAlignedPointerFromEmbedderData(1);
-	v8::Locker locker(c->isolate);
-	v8::Isolate::Scope isolate_scope(c->isolate);
-
-	v8::HandleScope local_scope(c->isolate);
+	v8::Locker locker(obj->isolate);
+	v8::Isolate::Scope isolate_scope(obj->isolate);
+	v8::HandleScope local_scope(obj->isolate);
 	v8::Handle<v8::Context> temp_context = v8::Context::New();
 	v8::Context::Scope temp_scope(temp_context);
 
-	if (php_v8js_v8_get_properties_hash(obj->v8obj, retval, obj->flags TSRMLS_CC) == SUCCESS) {
+	if (php_v8js_v8_get_properties_hash(obj->v8obj, retval, obj->flags, obj->isolate TSRMLS_CC) == SUCCESS) {
 		return retval;
 	}
 	return NULL;
@@ -306,7 +305,7 @@ static int php_v8js_v8_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS) /
 	v8::Local<v8::Value> js_retval;
 
 	for (i = 0; i < argc; i++) {
-		jsArgv[i] = v8::Local<v8::Value>::New(zval_to_v8js(*argv[i] TSRMLS_CC));
+		jsArgv[i] = v8::Local<v8::Value>::New(zval_to_v8js(*argv[i], obj->isolate TSRMLS_CC));
 	}
 
 	js_retval = cb->Call(V8JS_GLOBAL, argc, jsArgv);
@@ -318,7 +317,7 @@ static int php_v8js_v8_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS) /
 	}
 
 	if (return_value_used) {
-		return v8js_to_zval(js_retval, return_value, obj->flags TSRMLS_CC);
+		return v8js_to_zval(js_retval, return_value, obj->flags, obj->isolate TSRMLS_CC);
 	}
 
 	return SUCCESS;
@@ -381,7 +380,7 @@ static zend_object_value php_v8js_v8_new(zend_class_entry *ce TSRMLS_DC) /* {{{
 }
 /* }}} */
 
-void php_v8js_create_v8(zval *res, v8::Handle<v8::Value> value, int flags TSRMLS_DC) /* {{{ */
+void php_v8js_create_v8(zval *res, v8::Handle<v8::Value> value, int flags, v8::Isolate *isolate TSRMLS_DC) /* {{{ */
 {
 	php_v8js_object *c;
 
@@ -391,6 +390,7 @@ void php_v8js_create_v8(zval *res, v8::Handle<v8::Value> value, int flags TSRMLS
 
 	c->v8obj = v8::Persistent<v8::Value>::New(value);
 	c->flags = flags;
+	c->isolate = isolate;
 }
 /* }}} */
 
@@ -626,7 +626,7 @@ static PHP_METHOD(V8Js, __construct)
 
 	/* Register Get accessor for passed variables */
 	if (vars_arr && zend_hash_num_elements(Z_ARRVAL_P(vars_arr)) > 0) {
-		php_v8js_register_accessors(php_obj_t->InstanceTemplate(), vars_arr TSRMLS_CC);
+		php_v8js_register_accessors(php_obj_t->InstanceTemplate(), vars_arr, c->isolate TSRMLS_CC);
 	}
 
 	/* Set name for the PHP JS object */
@@ -847,7 +847,7 @@ static PHP_METHOD(V8Js, executeString)
 
 	/* Convert V8 value to PHP value */
 	if (!result.IsEmpty()) {
-		v8js_to_zval(result, return_value, flags TSRMLS_CC);
+		v8js_to_zval(result, return_value, flags, c->isolate TSRMLS_CC);
 	}
 }
 /* }}} */
@@ -1090,7 +1090,7 @@ static void php_v8js_write_property(zval *object, zval *member, zval *value ZEND
 	v8::Local<v8::Object> jsobj = V8JS_GLOBAL->Get(c->object_name)->ToObject();
 
 	/* Write value to PHP JS object */
-	jsobj->ForceSet(V8JS_SYML(Z_STRVAL_P(member), Z_STRLEN_P(member)), zval_to_v8js(value TSRMLS_CC), v8::ReadOnly);
+	jsobj->ForceSet(V8JS_SYML(Z_STRVAL_P(member), Z_STRLEN_P(member)), zval_to_v8js(value, c->isolate TSRMLS_CC), v8::ReadOnly);
 
 	/* Write value to PHP object */
 	std_object_handlers.write_property(object, member, value ZEND_HASH_KEY_CC TSRMLS_CC);

+ 17 - 15
v8js_convert.cc

@@ -38,6 +38,7 @@ static v8::Handle<v8::Value> php_v8js_php_callback(const v8::Arguments &args) /*
 {
 	v8::Handle<v8::Value> return_value;
 	zval *value = reinterpret_cast<zval *>(args.This()->GetAlignedPointerFromInternalField(0));
+	v8::Isolate *isolate = reinterpret_cast<v8::Isolate *>(args.This()->GetAlignedPointerFromInternalField(1));
 	zend_function *method_ptr;
 	zend_fcall_info fci;
 	zend_fcall_info_cache fcc;
@@ -99,7 +100,7 @@ static v8::Handle<v8::Value> 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 TSRMLS_CC) == FAILURE) {
+			if (v8js_to_zval(args[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);
@@ -134,7 +135,7 @@ failure:
 	}
 
 	if (retval_ptr != NULL) {
-		return_value = zval_to_v8js(retval_ptr TSRMLS_CC);
+		return_value = zval_to_v8js(retval_ptr, isolate TSRMLS_CC);
 		zval_ptr_dtor(&retval_ptr);
 	} else {
 		return_value = V8JS_NULL;
@@ -275,7 +276,7 @@ static v8::Handle<v8::Integer> php_v8js_property_query(v8::Local<v8::String> pro
 #define PHP_V8JS_CALLBACK(mptr) \
 	v8::FunctionTemplate::New(php_v8js_php_callback, v8::External::New(mptr))->GetFunction()
 
-static v8::Handle<v8::Value> php_v8js_hash_to_jsobj(zval *value TSRMLS_DC) /* {{{ */
+static v8::Handle<v8::Value> php_v8js_hash_to_jsobj(zval *value, v8::Isolate *isolate TSRMLS_DC) /* {{{ */
 {
 	v8::Local<v8::FunctionTemplate> new_tpl = v8::FunctionTemplate::New();
 	v8::Local<v8::Object> newobj;
@@ -303,7 +304,7 @@ static v8::Handle<v8::Value> php_v8js_hash_to_jsobj(zval *value TSRMLS_DC) /* {{
 	/* Object methods */
 	if (ce) {
 		new_tpl->SetClassName(V8JS_STRL(ce->name, ce->name_length));
-		new_tpl->InstanceTemplate()->SetInternalFieldCount(1);
+		new_tpl->InstanceTemplate()->SetInternalFieldCount(2);
 
 		if (ce == zend_ce_closure) {
 			new_tpl->InstanceTemplate()->SetCallAsFunctionHandler(php_v8js_php_callback);
@@ -390,6 +391,7 @@ static v8::Handle<v8::Value> php_v8js_hash_to_jsobj(zval *value TSRMLS_DC) /* {{
 		Z_ADDREF_P(value);
 
 		newobj->SetAlignedPointerInInternalField(0, (void *) value);
+		newobj->SetAlignedPointerInInternalField(1, (void *) isolate);
 	} else {
 		new_tpl->SetClassName(V8JS_SYM("Array"));
 		newobj = new_tpl->InstanceTemplate()->NewInstance();
@@ -426,9 +428,9 @@ static v8::Handle<v8::Value> php_v8js_hash_to_jsobj(zval *value TSRMLS_DC) /* {{
 						}
 						continue;
 					}
-					newobj->Set(V8JS_STRL(key, key_len - 1), zval_to_v8js(*data TSRMLS_CC), v8::ReadOnly);
+					newobj->Set(V8JS_STRL(key, key_len - 1), zval_to_v8js(*data, isolate TSRMLS_CC), v8::ReadOnly);
 				} else {
-					newobj->Set(index, zval_to_v8js(*data TSRMLS_CC));
+					newobj->Set(index, zval_to_v8js(*data, isolate TSRMLS_CC));
 				}
 
 				if (tmp_ht) {
@@ -441,14 +443,14 @@ static v8::Handle<v8::Value> php_v8js_hash_to_jsobj(zval *value TSRMLS_DC) /* {{
 }
 /* }}} */
 
-static v8::Handle<v8::Value> php_v8js_hash_to_jsarr(zval *value TSRMLS_DC) /* {{{ */
+static v8::Handle<v8::Value> php_v8js_hash_to_jsarr(zval *value, v8::Isolate *isolate TSRMLS_DC) /* {{{ */
 {
 	HashTable *myht = HASH_OF(value);
 	int i = myht ? zend_hash_num_elements(myht) : 0;
 
 	/* Return object if dealing with assoc array */
 	if (i > 0 && _php_v8js_is_assoc_array(myht TSRMLS_CC)) {
-		return php_v8js_hash_to_jsobj(value TSRMLS_CC);
+		return php_v8js_hash_to_jsobj(value, isolate TSRMLS_CC);
 	}
 
 	v8::Local<v8::Array> newarr;
@@ -477,7 +479,7 @@ static v8::Handle<v8::Value> php_v8js_hash_to_jsarr(zval *value TSRMLS_DC) /* {{
 				tmp_ht->nApplyCount++;
 			}
 
-			newarr->Set(index++, zval_to_v8js(*data TSRMLS_CC));
+			newarr->Set(index++, zval_to_v8js(*data, isolate TSRMLS_CC));
 
 			if (tmp_ht) {
 				tmp_ht->nApplyCount--;
@@ -488,18 +490,18 @@ static v8::Handle<v8::Value> php_v8js_hash_to_jsarr(zval *value TSRMLS_DC) /* {{
 }
 /* }}} */
 
-v8::Handle<v8::Value> zval_to_v8js(zval *value TSRMLS_DC) /* {{{ */
+v8::Handle<v8::Value> zval_to_v8js(zval *value, v8::Isolate *isolate TSRMLS_DC) /* {{{ */
 {
 	v8::Handle<v8::Value> jsValue;
 
 	switch (Z_TYPE_P(value))
 	{
 		case IS_ARRAY:
-			jsValue = php_v8js_hash_to_jsarr(value TSRMLS_CC);
+			jsValue = php_v8js_hash_to_jsarr(value, isolate TSRMLS_CC);
 			break;
 
 		case IS_OBJECT:
-			jsValue = php_v8js_hash_to_jsobj(value TSRMLS_CC);
+			jsValue = php_v8js_hash_to_jsobj(value, isolate TSRMLS_CC);
 			break;
 
 		case IS_STRING:
@@ -527,7 +529,7 @@ v8::Handle<v8::Value> zval_to_v8js(zval *value TSRMLS_DC) /* {{{ */
 }
 /* }}} */
 
-int v8js_to_zval(v8::Handle<v8::Value> jsValue, zval *return_value, int flags TSRMLS_DC) /* {{{ */
+int v8js_to_zval(v8::Handle<v8::Value> jsValue, zval *return_value, int flags, v8::Isolate *isolate TSRMLS_DC) /* {{{ */
 {
 	if (jsValue->IsString())
 	{
@@ -576,9 +578,9 @@ int v8js_to_zval(v8::Handle<v8::Value> jsValue, zval *return_value, int flags TS
 	{
 		if ((flags & V8JS_FLAG_FORCE_ARRAY) || jsValue->IsArray()) {
 			array_init(return_value);
-			return php_v8js_v8_get_properties_hash(jsValue, Z_ARRVAL_P(return_value), flags TSRMLS_CC);
+			return php_v8js_v8_get_properties_hash(jsValue, Z_ARRVAL_P(return_value), flags, isolate TSRMLS_CC);
 		} else {
-			php_v8js_create_v8(return_value, jsValue, flags TSRMLS_CC);
+			php_v8js_create_v8(return_value, jsValue, flags, isolate TSRMLS_CC);
 			return SUCCESS;
 		}
 	}

+ 22 - 8
v8js_variables.cc

@@ -29,26 +29,34 @@ extern "C" {
 
 #include "php_v8js_macros.h"
 #include <v8.h>
+#include <string>
+
+struct php_v8js_accessor_ctx
+{
+    char *variable_name_string;
+    uint variable_name_string_len;
+    v8::Isolate *isolate;
+};
 
 static v8::Handle<v8::Value> php_v8js_fetch_php_variable(v8::Local<v8::String> name, const v8::AccessorInfo &info) /* {{{ */
 {
-	v8::String::Utf8Value variable_name(info.Data()->ToString());
-	const char *variable_name_string = ToCString(variable_name);
-	uint variable_name_string_len = strlen(variable_name_string);
+    v8::Handle<v8::External> data = v8::Handle<v8::External>::Cast(info.Data());
+    php_v8js_accessor_ctx *ctx = static_cast<php_v8js_accessor_ctx *>(data->Value());
 	zval **variable;
 
 	TSRMLS_FETCH();
 
-	zend_is_auto_global(variable_name_string, variable_name_string_len TSRMLS_CC);
+	zend_is_auto_global(ctx->variable_name_string, ctx->variable_name_string_len TSRMLS_CC);
 
-	if (zend_hash_find(&EG(symbol_table), variable_name_string, variable_name_string_len + 1, (void **) &variable) == SUCCESS) {
-		return zval_to_v8js(*variable 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);
 	}
+
 	return v8::Undefined();
 }
 /* }}} */
 
-void php_v8js_register_accessors(v8::Local<v8::ObjectTemplate> php_obj, zval *array TSRMLS_DC) /* {{{ */
+void php_v8js_register_accessors(v8::Local<v8::ObjectTemplate> php_obj, zval *array, v8::Isolate *isolate TSRMLS_DC) /* {{{ */
 {
 	char *property_name;
 	uint property_name_len;
@@ -76,8 +84,14 @@ void php_v8js_register_accessors(v8::Local<v8::ObjectTemplate> php_obj, zval *ar
 			continue; /* Ignore invalid property names */
 		}
 
+        // Create context to store accessor data
+        php_v8js_accessor_ctx *ctx = (php_v8js_accessor_ctx *)emalloc(sizeof(php_v8js_accessor_ctx));
+        ctx->variable_name_string = estrdup(Z_STRVAL_PP(item));
+        ctx->variable_name_string_len = Z_STRLEN_PP(item);
+        ctx->isolate = isolate;
+
 		/* Set the variable fetch callback for given symbol on named property */
-		php_obj->SetAccessor(V8JS_STRL(property_name, property_name_len - 1), php_v8js_fetch_php_variable, NULL, V8JS_STRL(Z_STRVAL_PP(item), Z_STRLEN_PP(item)), v8::PROHIBITS_OVERWRITING, v8::ReadOnly);
+		php_obj->SetAccessor(V8JS_STRL(property_name, property_name_len - 1), php_v8js_fetch_php_variable, NULL, v8::External::New(ctx), v8::PROHIBITS_OVERWRITING, v8::ReadOnly);
 	}
 }
 /* }}} */