Browse Source

Merge pull request #416 from stesie/issue-410

Fixes #410
Stefan Siegl 5 years ago
parent
commit
af2279626e
4 changed files with 55 additions and 6 deletions
  1. 49 0
      tests/issue_410_basic.phpt
  2. 3 3
      v8js_class.cc
  3. 1 1
      v8js_class.h
  4. 2 2
      v8js_object_export.cc

+ 49 - 0
tests/issue_410_basic.phpt

@@ -0,0 +1,49 @@
+--TEST--
+Test V8::executeString() : Method access from multiple derived classes
+--SKIPIF--
+<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
+--FILE--
+<?php
+
+class BaseClass {
+        public function bla() {
+            printf('print bla, called class: %s' . PHP_EOL, get_called_class());
+        }
+}
+
+class Foo extends BaseClass {}
+
+class Bar extends BaseClass {}
+
+$v8 = new V8Js('PHP');
+$v8->Foo = new Foo();
+$v8->Bar = new Bar();
+
+$code = <<<EOT
+var_dump(PHP.Foo);
+PHP.Foo.bla();
+var_dump(PHP.Bar);
+PHP.Bar.bla();
+EOT;
+
+$v8->executeString($code);
+
+?>
+===EOF===
+--EXPECTF--
+object(Foo)#%d (1) {
+  ["bla"] =>
+  object(Closure)#%d {
+      function () { [native code] }
+  }
+}
+print bla, called class: Foo
+object(Bar)#%d (1) {
+  ["bla"] =>
+  object(Closure)#%d {
+      function () { [native code] }
+  }
+}
+print bla, called class: Bar
+===EOF===
+

+ 3 - 3
v8js_class.cc

@@ -119,7 +119,7 @@ static void v8js_free_storage(zend_object *object) /* {{{ */
 	}
 	c->call_impls.~map();
 
-	for (std::map<zend_function *, v8js_function_tmpl_t>::iterator it = c->method_tmpls.begin();
+	for (std::map<std::pair<zend_class_entry *, zend_function *>, v8js_function_tmpl_t>::iterator it = c->method_tmpls.begin();
 		 it != c->method_tmpls.end(); ++it) {
 		it->second.Reset();
 	}
@@ -232,7 +232,7 @@ static zend_object* v8js_new(zend_class_entry *ce) /* {{{ */
 	new(&c->weak_closures) std::map<v8js_function_tmpl_t *, v8js_persistent_obj_t>();
 	new(&c->weak_objects) std::map<zend_object *, v8js_persistent_obj_t>();
 	new(&c->call_impls) std::map<v8js_function_tmpl_t *, v8js_function_tmpl_t>();
-	new(&c->method_tmpls) std::map<zend_function *, v8js_function_tmpl_t>();
+	new(&c->method_tmpls) std::map<std::pair<zend_class_entry *, zend_function *>, v8js_function_tmpl_t>();
 
 	new(&c->v8js_v8objects) std::list<v8js_v8object *>();
 	new(&c->script_objects) std::vector<v8js_script *>();
@@ -589,7 +589,7 @@ static PHP_METHOD(V8Js, __construct)
 		ft = v8::FunctionTemplate::New(isolate, v8js_php_callback,
 				v8::External::New((isolate), method_ptr));
 		// @fixme add/check Signature v8::Signature::New((isolate), tmpl));
-		v8js_function_tmpl_t *persistent_ft = &c->method_tmpls[method_ptr];
+		v8js_function_tmpl_t *persistent_ft = &c->method_tmpls[std::make_pair(ce, method_ptr)];
 		persistent_ft->Reset(isolate, ft);
 
 		php_obj->CreateDataProperty(context, method_name, ft->GetFunction(context).ToLocalChecked());

+ 1 - 1
v8js_class.h

@@ -63,7 +63,7 @@ struct v8js_ctx {
   std::map<zend_object *, v8js_persistent_obj_t> weak_objects;
   std::map<v8js_function_tmpl_t *, v8js_persistent_obj_t> weak_closures;
   std::map<v8js_function_tmpl_t *, v8js_function_tmpl_t> call_impls;
-  std::map<zend_function *, v8js_function_tmpl_t> method_tmpls;
+  std::map<std::pair<zend_class_entry *, zend_function *>, v8js_function_tmpl_t> method_tmpls;
 
   std::list<v8js_v8object *> v8js_v8objects;
 

+ 2 - 2
v8js_object_export.cc

@@ -701,13 +701,13 @@ v8::Local<v8::Value> v8js_named_property_callback(v8::Local<v8::Name> property_n
 					v8::Local<v8::FunctionTemplate> ft;
 					try {
 						ft = v8::Local<v8::FunctionTemplate>::New
-							(isolate, ctx->method_tmpls.at(method_ptr));
+							(isolate, ctx->method_tmpls.at(std::make_pair(ce, method_ptr)));
 					}
 					catch (const std::out_of_range &) {
 						ft = v8::FunctionTemplate::New(isolate, v8js_php_callback,
 								v8::External::New((isolate), method_ptr),
 								v8::Signature::New((isolate), tmpl));
-						v8js_function_tmpl_t *persistent_ft = &ctx->method_tmpls[method_ptr];
+						v8js_function_tmpl_t *persistent_ft = &ctx->method_tmpls[std::make_pair(ce, method_ptr)];
 						persistent_ft->Reset(isolate, ft);
 					}
 					ft->GetFunction(v8_context).ToLocal(&ret_value);