Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem handling Class Inheritance #410

Closed
juan-morales opened this issue Jun 6, 2019 · 2 comments
Closed

Problem handling Class Inheritance #410

juan-morales opened this issue Jun 6, 2019 · 2 comments

Comments

@juan-morales
Copy link

juan-morales commented Jun 6, 2019

This issue is related to #386 , but enriched.

I dont know if the problem is in v8js or v8, I tried hard to follow the code of the extension and I have my doubts.

Code that produces the error:

class BaseClass {
        public function bla() {
            echo "print bla";
        }
}

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;

//$resourceScript = $v8->compileString($code);
$v8->executeString($code);

Execution Output:

object(Foo)#1515588 (1) {
  ["bla"] =>
  object(Closure)#1289866 {
      function () { [native code] }
  }
}
print blaobject(Bar)#259312 (1) {
  ["bla"] =>
  object(Closure)#1289866 {
      function () { [native code] }
  }
}
PHP Fatal error:  Uncaught V8JsScriptException: V8Js::compileString():4: TypeError: Illegal invocation in /home/user/testv8.php:25
Stack trace:
#0 /home/user/testv8.php(25): V8Js->executeString('var_dump(PHP.Fo...')
#1 {main}
  thrown in /home/user/testv8.php on line 25

Fatal error: Uncaught V8JsScriptException: V8Js::compileString():4: TypeError: Illegal invocation in /home/user/testv8.php on line 25

V8JsScriptException: V8Js::compileString():4: TypeError: Illegal invocation in /home/user/testv8.php on line 25

Call Stack:
    0.0001     394408   1. {main}() /home/user/testv8.php:0
    0.0080     395744   2. V8Js->executeString() /home/user/testv8.php:25

Tip 1 - If we just compile ... everything looks ok
(Just look at the end of the code snippet and un/comment as showed here)

$resourceScript = $v8->compileString($code);
//$v8->executeString($code);

Execution output: Nothing (ok?)

Ok, solutions/workarounds ?

1) Use __call to call methods in class

class BaseClass {
        public function bla() {
            echo "print bla";
        }
}

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.__call("bla", []);
var_dump(PHP.Bar);
PHP.Bar.__call("bla", []);
EOT;

//$resourceScript = $v8->compileString($code);
$v8->executeString($code);

2) Re-declare your derived clases like so:

class BaseClass {
        public function bla() {
            echo "print bla";
        }
}

class Foo extends BaseClass {
        public function bla() {
            parent::bla();
        }    
}

class Bar extends BaseClass {
        public function bla() {
            parent::bla();
        }
}

$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;

//$resourceScript = $v8->compileString($code);
$v8->executeString($code);

My environment:

OS: LINUX UBUNTU

Linux user 4.18.0-20-generic #21~18.04.1-Ubuntu SMP Wed May 8 08:43:37 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

PHP info

php -v
PHP 7.2.19-0ubuntu0.18.04.1 (cli) (built: Jun  4 2019 14:48:12) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.2.19-0ubuntu0.18.04.1, Copyright (c) 1999-2018, by Zend Technologies

V8JS info

$ php --ri v8js

V8 Javascript Engine => enabled
V8 Engine Compiled Version => 7.6.57
V8 Engine Linked Version => 7.6.57
Version => 2.1.0

Directive => Local Value => Master Value
v8js.flags => no value => no value
v8js.icudtl_dat_path => no value => no value
v8js.use_date => 0 => 0
v8js.use_array_access => 0 => 0**

I hope to get a better understanding regarding this.

@stesie
Copy link
Member

stesie commented Jun 22, 2019

Interesting catch, it's related to the v8::FunctionTemplate reuse/caching. If you comment it out like this:

diff --git a/v8js_object_export.cc b/v8js_object_export.cc
index b36574c..0aaa0e3 100644
--- a/v8js_object_export.cc
+++ b/v8js_object_export.cc
@@ -699,11 +699,11 @@ v8::Local<v8::Value> v8js_named_property_callback(v8::Local<v8::Name> property_n
                                        }
                                } else {
                                        v8::Local<v8::FunctionTemplate> ft;
-                                       try {
+                                       /* try {
                                                ft = v8::Local<v8::FunctionTemplate>::New
                                                        (isolate, ctx->method_tmpls.at(method_ptr));
                                        }
-                                       catch (const std::out_of_range &) {
+                                       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));

... it works :)

Of course this is not a proper solution, but shows the cause of the problem. The cache is solely based on method_ptr, which is the zend_function * to call.

stesie added a commit to stesie/v8js that referenced this issue Jun 22, 2019
@stesie stesie closed this as completed in 35398cc Jun 22, 2019
stesie added a commit that referenced this issue Jun 22, 2019
@juan-morales
Copy link
Author

thanks @stesie

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants