mirror of
https://github.com/phpv8/v8js.git
synced 2024-11-09 15:18:41 +00:00
Provide correct "this" on V8Object method invocation, closes #185
This commit is contained in:
parent
d9e4ae5abe
commit
3c5508b956
36
tests/issue_185_001.phpt
Normal file
36
tests/issue_185_001.phpt
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
--TEST--
|
||||||
|
Test V8::executeString() : Issue #185 this on direct invocation of method
|
||||||
|
--SKIPIF--
|
||||||
|
<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$v8 = new V8Js();
|
||||||
|
|
||||||
|
$JS = <<<EOT
|
||||||
|
|
||||||
|
function Bar(i) {
|
||||||
|
this.theValue = i;
|
||||||
|
}
|
||||||
|
Bar.prototype.tell = function() {
|
||||||
|
var_dump(this.theValue);
|
||||||
|
var_dump(typeof this.exit);
|
||||||
|
};
|
||||||
|
var inst = new Bar(23);
|
||||||
|
var fn = inst.tell;
|
||||||
|
fn();
|
||||||
|
EOT;
|
||||||
|
|
||||||
|
$v8->executeString($JS);
|
||||||
|
|
||||||
|
// now fetch `inst` from V8 and call method from PHP
|
||||||
|
$fn = $v8->executeString('(inst.tell)');
|
||||||
|
$fn();
|
||||||
|
?>
|
||||||
|
===EOF===
|
||||||
|
--EXPECT--
|
||||||
|
NULL
|
||||||
|
string(8) "function"
|
||||||
|
NULL
|
||||||
|
string(8) "function"
|
||||||
|
===EOF===
|
28
tests/issue_185_002.phpt
Normal file
28
tests/issue_185_002.phpt
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
--TEST--
|
||||||
|
Test V8::executeString() : Issue #185 this on function invocation
|
||||||
|
--SKIPIF--
|
||||||
|
<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$v8 = new V8Js();
|
||||||
|
|
||||||
|
$JS = <<<EOT
|
||||||
|
|
||||||
|
function fn() {
|
||||||
|
var_dump(typeof this.exit);
|
||||||
|
};
|
||||||
|
fn();
|
||||||
|
EOT;
|
||||||
|
|
||||||
|
$v8->executeString($JS);
|
||||||
|
|
||||||
|
// now fetch `inst` from V8 and call method from PHP
|
||||||
|
$fn = $v8->executeString('(fn)');
|
||||||
|
$fn();
|
||||||
|
?>
|
||||||
|
===EOF===
|
||||||
|
--EXPECT--
|
||||||
|
string(8) "function"
|
||||||
|
string(8) "function"
|
||||||
|
===EOF===
|
32
tests/issue_185_basic.phpt
Normal file
32
tests/issue_185_basic.phpt
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
--TEST--
|
||||||
|
Test V8::executeString() : Issue #185 Wrong this on V8Object method invocation
|
||||||
|
--SKIPIF--
|
||||||
|
<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$v8 = new V8Js();
|
||||||
|
|
||||||
|
$JS = <<<EOT
|
||||||
|
|
||||||
|
function Bar(i) {
|
||||||
|
this.theValue = i;
|
||||||
|
}
|
||||||
|
Bar.prototype.tell = function() {
|
||||||
|
var_dump(this.theValue);
|
||||||
|
};
|
||||||
|
var inst = new Bar(23);
|
||||||
|
inst.tell();
|
||||||
|
EOT;
|
||||||
|
|
||||||
|
$v8->executeString($JS);
|
||||||
|
|
||||||
|
// now fetch `inst` from V8 and call method from PHP
|
||||||
|
$inst = $v8->executeString('(inst)');
|
||||||
|
$inst->tell();
|
||||||
|
?>
|
||||||
|
===EOF===
|
||||||
|
--EXPECT--
|
||||||
|
int(23)
|
||||||
|
int(23)
|
||||||
|
===EOF===
|
@ -302,6 +302,7 @@ static int v8js_v8object_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS)
|
|||||||
|
|
||||||
v8::Local<v8::String> method_name = V8JS_SYML(method, strlen(method));
|
v8::Local<v8::String> method_name = V8JS_SYML(method, strlen(method));
|
||||||
v8::Local<v8::Object> v8obj = v8::Local<v8::Value>::New(isolate, obj->v8obj)->ToObject();
|
v8::Local<v8::Object> v8obj = v8::Local<v8::Value>::New(isolate, obj->v8obj)->ToObject();
|
||||||
|
v8::Local<v8::Object> thisObj;
|
||||||
v8::Local<v8::Function> cb;
|
v8::Local<v8::Function> cb;
|
||||||
|
|
||||||
if (method_name->Equals(V8JS_SYM(V8JS_V8_INVOKE_FUNC_NAME))) {
|
if (method_name->Equals(V8JS_SYM(V8JS_V8_INVOKE_FUNC_NAME))) {
|
||||||
@ -310,6 +311,15 @@ static int v8js_v8object_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS)
|
|||||||
cb = v8::Local<v8::Function>::Cast(v8obj->Get(method_name));
|
cb = v8::Local<v8::Function>::Cast(v8obj->Get(method_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If a method is invoked on V8Object, then set the object itself as
|
||||||
|
// "this" on JS side. Otherwise fall back to global object.
|
||||||
|
if (obj->std.ce == php_ce_v8object) {
|
||||||
|
thisObj = v8obj;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
thisObj = V8JS_GLOBAL(isolate);
|
||||||
|
}
|
||||||
|
|
||||||
v8::Local<v8::Value> *jsArgv = static_cast<v8::Local<v8::Value> *>(alloca(sizeof(v8::Local<v8::Value>) * argc));
|
v8::Local<v8::Value> *jsArgv = static_cast<v8::Local<v8::Value> *>(alloca(sizeof(v8::Local<v8::Value>) * argc));
|
||||||
v8::Local<v8::Value> js_retval;
|
v8::Local<v8::Value> js_retval;
|
||||||
|
|
||||||
@ -318,7 +328,7 @@ static int v8js_v8object_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS)
|
|||||||
jsArgv[i] = v8::Local<v8::Value>::New(isolate, zval_to_v8js(*argv[i], isolate TSRMLS_CC));
|
jsArgv[i] = v8::Local<v8::Value>::New(isolate, zval_to_v8js(*argv[i], isolate TSRMLS_CC));
|
||||||
}
|
}
|
||||||
|
|
||||||
return cb->Call(V8JS_GLOBAL(isolate), argc, jsArgv);
|
return cb->Call(thisObj, argc, jsArgv);
|
||||||
};
|
};
|
||||||
|
|
||||||
v8js_v8_call(obj->ctx, &return_value, obj->flags, obj->ctx->time_limit, obj->ctx->memory_limit, v8_call TSRMLS_CC);
|
v8js_v8_call(obj->ctx, &return_value, obj->flags, obj->ctx->time_limit, obj->ctx->memory_limit, v8_call TSRMLS_CC);
|
||||||
|
Loading…
Reference in New Issue
Block a user