瀏覽代碼

Merge pull request #39 from stesie/fix-property-read

Create temporary HandleScopes when reading properties
Patrick Reilly 11 年之前
父節點
當前提交
1c4d9817dc
共有 3 個文件被更改,包括 73 次插入1 次删除
  1. 26 0
      tests/function_call.phpt
  2. 28 0
      tests/function_passback2.phpt
  3. 19 1
      v8js.cc

+ 26 - 0
tests/function_call.phpt

@@ -0,0 +1,26 @@
+--TEST--
+Test V8::executeString() : Call passed-back function (directly)
+--SKIPIF--
+<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
+--FILE--
+<?php
+
+$v8 = new V8Js();
+
+$JS = <<< EOT
+(function(exports) {
+  // begin module code
+  exports.hello = function() { return 'hello'; };
+  // end module code
+  return exports;
+})({})
+EOT;
+
+$exports = $v8->executeString($JS, 'basic.js');
+echo $exports->hello()."\n";
+
+?>
+===EOF===
+--EXPECT--
+hello
+===EOF===

+ 28 - 0
tests/function_passback2.phpt

@@ -0,0 +1,28 @@
+--TEST--
+Test V8::executeString() : Call passed-back function (property access)
+--SKIPIF--
+<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
+--FILE--
+<?php
+
+$v8 = new V8Js();
+
+$JS = <<< EOT
+(function(exports) {
+  // begin module code
+  exports.hello = function() { return 'hello'; };
+  // end module code
+  return exports;
+})({})
+EOT;
+
+$exports = $v8->executeString($JS, 'basic.js');
+$v8->func = $exports->hello;
+
+echo $v8->executeString('PHP.func();')."\n";
+
+?>
+===EOF===
+--EXPECT--
+hello
+===EOF===

+ 19 - 1
v8js.cc

@@ -118,6 +118,12 @@ static zval *php_v8js_v8_read_property(zval *object, zval *member, int type ZEND
 
 	if (Z_TYPE_P(member) == IS_STRING && obj->v8obj->IsObject() && !obj->v8obj->IsFunction())
 	{
+		v8::Locker locker(obj->isolate);
+		v8::Isolate::Scope isolate_scope(obj->isolate);
+		v8::HandleScope local_scope(obj->isolate);
+		v8::Local<v8::Context> temp_context = v8::Context::New(obj->isolate);
+		v8::Context::Scope temp_scope(temp_context);
+
 		v8::Local<v8::Object> jsObj = obj->v8obj->ToObject();
 		v8::Local<v8::String> jsKey = V8JS_STRL(Z_STRVAL_P(member), Z_STRLEN_P(member));
 		v8::Local<v8::Value> jsVal;
@@ -236,9 +242,15 @@ static HashTable *php_v8js_v8_get_debug_info(zval *object, int *is_temp TSRMLS_D
 
 static zend_function *php_v8js_v8_get_method(zval **object_ptr, char *method, int method_len ZEND_HASH_KEY_DC TSRMLS_DC) /* {{{ */
 {
+	php_v8js_object *obj = (php_v8js_object *) zend_object_store_get_object(*object_ptr TSRMLS_CC);
 	zend_function *f;
+
+	v8::Locker locker(obj->isolate);
+	v8::Isolate::Scope isolate_scope(obj->isolate);
+	v8::HandleScope local_scope(obj->isolate);
+	v8::Local<v8::Context> temp_context = v8::Context::New(obj->isolate);
+	v8::Context::Scope temp_scope(temp_context);
 	v8::Local<v8::String> jsKey = V8JS_STRL(method, method_len);
-	php_v8js_object *obj = (php_v8js_object *) zend_object_store_get_object(*object_ptr TSRMLS_CC);
 
 	if (!obj->v8obj.IsEmpty() && obj->v8obj->IsObject() && !obj->v8obj->IsFunction()) {
 		v8::Local<v8::Object> jsObj = obj->v8obj->ToObject();
@@ -277,6 +289,12 @@ static int php_v8js_v8_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS) /
 		zend_get_parameters_array_ex(argc, argv);
 	}
 
+	v8::Locker locker(obj->isolate);
+	v8::Isolate::Scope isolate_scope(obj->isolate);
+	v8::HandleScope local_scope(obj->isolate);
+	v8::Local<v8::Context> temp_context = v8::Context::New(obj->isolate);
+	v8::Context::Scope temp_scope(temp_context);
+
 	v8::Local<v8::String> method_name = V8JS_SYML(method, strlen(method));
 	v8::Local<v8::Object> v8obj = obj->v8obj->ToObject();
 	v8::Local<v8::Function> cb;