0
0
mirror of https://github.com/phpv8/v8js.git synced 2024-11-09 15:18:41 +00:00

Optimize and fix test reference from @redbullmarky

This commit is contained in:
Albert 2022-05-27 10:47:44 +08:00
parent 1db8f8de5e
commit cb7b3dcc29
19 changed files with 532 additions and 248 deletions

View File

@ -7,25 +7,49 @@ v8js.use_array_access = 1
--FILE-- --FILE--
<?php <?php
class MyArray implements ArrayAccess, Countable { if (PHP_VERSION_ID < 80000) {
public function offsetExists($offset): bool { class MyArray implements ArrayAccess, Countable {
return $offset >= 0 && $offset <= 20; public function offsetExists($offset) {
} return $offset >= 0 && $offset <= 20;
}
public function offsetGet($offset): mixed { public function offsetGet($offset) {
return 19 - $offset; return 19 - $offset;
} }
public function offsetSet($offset, $value): void { public function offsetSet($offset, $value) {
throw new Exception('Not implemented'); throw new Exception('Not implemented');
} }
public function offsetUnset($offset): void { public function offsetUnset($offset) {
throw new Exception('Not implemented'); throw new Exception('Not implemented');
} }
public function count(): int { public function count() {
return 20; return 20;
}
}
} else {
class MyArray implements ArrayAccess, Countable {
public function offsetExists($offset): bool {
return $offset >= 0 && $offset <= 20;
}
public function offsetGet(mixed $offset): mixed {
return 19 - $offset;
}
public function offsetSet(mixed $offset, mixed $value): void {
throw new Exception('Not implemented');
}
public function offsetUnset(mixed $offset): void {
throw new Exception('Not implemented');
}
public function count(): int {
return 20;
}
} }
} }

View File

@ -7,31 +7,61 @@ v8js.use_array_access = 1
--FILE-- --FILE--
<?php <?php
class MyArray implements ArrayAccess, Countable { if (PHP_VERSION_ID < 80000) {
private $data = Array('one', 'two', 'three'); class MyArray implements ArrayAccess, Countable {
private $data = Array('one', 'two', 'three');
public function offsetExists($offset): bool { public function offsetExists($offset) {
return isset($this->data[$offset]); return isset($this->data[$offset]);
}
public function offsetGet($offset) {
return $this->data[$offset];
}
public function offsetSet($offset, $value) {
$this->data[$offset] = $value;
}
public function offsetUnset($offset) {
throw new Exception('Not implemented');
}
public function count() {
return count($this->data);
}
public function push($value) {
$this->data[] = $value;
}
} }
} else {
class MyArray implements ArrayAccess, Countable {
private $data = Array('one', 'two', 'three');
public function offsetGet($offset): mixed { public function offsetExists($offset): bool {
return $this->data[$offset]; return isset($this->data[$offset]);
} }
public function offsetSet($offset, $value): void { public function offsetGet(mixed $offset): mixed {
$this->data[$offset] = $value; return $this->data[$offset];
} }
public function offsetUnset($offset): void { public function offsetSet(mixed $offset, mixed $value): void {
throw new Exception('Not implemented'); $this->data[$offset] = $value;
} }
public function count(): int { public function offsetUnset(mixed $offset): void {
return count($this->data); throw new Exception('Not implemented');
} }
public function push($value) { public function count(): int {
$this->data[] = $value; return count($this->data);
}
public function push($value) {
$this->data[] = $value;
}
} }
} }

View File

@ -6,29 +6,55 @@ Test V8::executeString() : Use ArrayAccess with JavaScript native push method
v8js.use_array_access = 1 v8js.use_array_access = 1
--FILE-- --FILE--
<?php <?php
if (PHP_VERSION_ID < 80000) {
class MyArray implements ArrayAccess, Countable {
private $data = Array('one', 'two', 'three');
class MyArray implements ArrayAccess, Countable { public function offsetExists($offset) {
private $data = Array('one', 'two', 'three'); return isset($this->data[$offset]);
}
public function offsetExists($offset): bool { public function offsetGet($offset) {
return isset($this->data[$offset]); return $this->data[$offset];
}
public function offsetSet($offset, $value) {
echo "set[$offset] = $value\n";
$this->data[$offset] = $value;
}
public function offsetUnset($offset) {
throw new Exception('Not implemented');
}
public function count() {
return count($this->data);
}
} }
} else {
class MyArray implements ArrayAccess, Countable {
private $data = Array('one', 'two', 'three');
public function offsetGet($offset): mixed { public function offsetExists($offset): bool {
return $this->data[$offset]; return isset($this->data[$offset]);
} }
public function offsetSet($offset, $value): void { public function offsetGet(mixed $offset): mixed {
echo "set[$offset] = $value\n"; return $this->data[$offset];
$this->data[$offset] = $value; }
}
public function offsetUnset($offset): void { public function offsetSet(mixed $offset, mixed $value): void {
throw new Exception('Not implemented'); echo "set[$offset] = $value\n";
} $this->data[$offset] = $value;
}
public function count(): int { public function offsetUnset(mixed $offset): void {
return count($this->data); throw new Exception('Not implemented');
}
public function count(): int {
return count($this->data);
}
} }
} }

View File

@ -6,40 +6,77 @@ Test V8::executeString() : Export PHP methods on ArrayAccess objects
v8js.use_array_access = 1 v8js.use_array_access = 1
--FILE-- --FILE--
<?php <?php
if (PHP_VERSION_ID < 80000) {
class MyArray implements ArrayAccess, Countable {
private $data = Array('one', 'two', 'three');
class MyArray implements ArrayAccess, Countable { public function offsetExists($offset) {
private $data = Array('one', 'two', 'three'); return isset($this->data[$offset]);
}
public function offsetExists($offset): bool { public function offsetGet($offset) {
return isset($this->data[$offset]); return $this->data[$offset];
}
public function offsetSet($offset, $value) {
echo "set[$offset] = $value\n";
$this->data[$offset] = $value;
}
public function offsetUnset($offset) {
throw new Exception('Not implemented');
}
public function count() {
echo 'count() = ', count($this->data), "\n";
return count($this->data);
}
public function phpSidePush($value) {
echo "push << $value\n";
$this->data[] = $value;
}
public function push($value) {
echo "php-side-push << $value\n";
$this->data[] = $value;
}
} }
} else {
class MyArray implements ArrayAccess, Countable {
private $data = Array('one', 'two', 'three');
public function offsetGet($offset): mixed { public function offsetExists($offset): bool {
return $this->data[$offset]; return isset($this->data[$offset]);
} }
public function offsetSet($offset, $value): void { public function offsetGet(mixed $offset): mixed {
echo "set[$offset] = $value\n"; return $this->data[$offset];
$this->data[$offset] = $value; }
}
public function offsetUnset($offset): void { public function offsetSet(mixed $offset, mixed $value): void {
throw new Exception('Not implemented'); echo "set[$offset] = $value\n";
} $this->data[$offset] = $value;
}
public function count(): int { public function offsetUnset(mixed $offset): void {
echo 'count() = ', count($this->data), "\n"; throw new Exception('Not implemented');
return count($this->data); }
}
public function phpSidePush($value) { public function count(): int {
echo "push << $value\n"; echo 'count() = ', count($this->data), "\n";
$this->data[] = $value; return count($this->data);
} }
public function push($value) { public function phpSidePush($value) {
echo "php-side-push << $value\n"; echo "push << $value\n";
$this->data[] = $value; $this->data[] = $value;
}
public function push($value) {
echo "php-side-push << $value\n";
$this->data[] = $value;
}
} }
} }

View File

@ -6,38 +6,73 @@ Test V8::executeString() : Export PHP properties on ArrayAccess objects
v8js.use_array_access = 1 v8js.use_array_access = 1
--FILE-- --FILE--
<?php <?php
if (PHP_VERSION_ID < 80000) {
class MyArray implements ArrayAccess, Countable {
private $data = Array('one', 'two', 'three');
class MyArray implements ArrayAccess, Countable { private $privFoo = 23;
private $data = Array('one', 'two', 'three'); protected $protFoo = 23;
public $pubFoo = 42;
private $privFoo = 23; /* We can have a length property on the PHP object, but the length property
protected $protFoo = 23; * of the JS object will still call count() method. Anyways it should be
public $pubFoo = 42; * accessibly as $length. */
public $length = 42;
/* We can have a length property on the PHP object, but the length property public function offsetExists($offset) {
* of the JS object will still call count() method. Anyways it should be return isset($this->data[$offset]);
* accessibly as $length. */ }
public $length = 42;
public function offsetExists($offset): bool { public function offsetGet($offset) {
return isset($this->data[$offset]); return $this->data[$offset];
}
public function offsetSet($offset, $value) {
echo "set[$offset] = $value\n";
$this->data[$offset] = $value;
}
public function offsetUnset($offset) {
throw new Exception('Not implemented');
}
public function count() {
return count($this->data);
}
} }
} else {
class MyArray implements ArrayAccess, Countable {
private $data = Array('one', 'two', 'three');
public function offsetGet($offset): mixed { private $privFoo = 23;
return $this->data[$offset]; protected $protFoo = 23;
} public $pubFoo = 42;
public function offsetSet($offset, $value): void { /* We can have a length property on the PHP object, but the length property
echo "set[$offset] = $value\n"; * of the JS object will still call count() method. Anyways it should be
$this->data[$offset] = $value; * accessibly as $length. */
} public $length = 42;
public function offsetUnset($offset): void { public function offsetExists($offset): bool {
throw new Exception('Not implemented'); return isset($this->data[$offset]);
} }
public function count(): int { public function offsetGet(mixed $offset): mixed {
return count($this->data); return $this->data[$offset];
}
public function offsetSet(mixed $offset, mixed $value): void {
echo "set[$offset] = $value\n";
$this->data[$offset] = $value;
}
public function offsetUnset(mixed $offset): void {
throw new Exception('Not implemented');
}
public function count(): int {
return count($this->data);
}
} }
} }

View File

@ -6,33 +6,63 @@ Test V8::executeString() : Export __invoke method on ArrayAccess objects
v8js.use_array_access = 1 v8js.use_array_access = 1
--FILE-- --FILE--
<?php <?php
if (PHP_VERSION_ID < 80000) {
class MyArray implements ArrayAccess, Countable {
private $data = Array('one', 'two', 'three');
class MyArray implements ArrayAccess, Countable { public function offsetExists($offset) {
private $data = Array('one', 'two', 'three'); return isset($this->data[$offset]);
}
public function offsetExists($offset): bool { public function offsetGet($offset) {
return isset($this->data[$offset]); return $this->data[$offset];
}
public function offsetSet($offset, $value) {
echo "set[$offset] = $value\n";
$this->data[$offset] = $value;
}
public function offsetUnset($offset) {
throw new Exception('Not implemented');
}
public function count() {
return count($this->data);
}
public function __invoke() {
echo "__invoke called!\n";
}
} }
} else {
class MyArray implements ArrayAccess, Countable {
private $data = Array('one', 'two', 'three');
public function offsetGet($offset): mixed { public function offsetExists($offset): bool {
return $this->data[$offset]; return isset($this->data[$offset]);
} }
public function offsetSet($offset, $value): void { public function offsetGet(mixed $offset): mixed {
echo "set[$offset] = $value\n"; return $this->data[$offset];
$this->data[$offset] = $value; }
}
public function offsetUnset($offset): void { public function offsetSet(mixed $offset, mixed $value): void {
throw new Exception('Not implemented'); echo "set[$offset] = $value\n";
} $this->data[$offset] = $value;
}
public function count(): int { public function offsetUnset(mixed $offset): void {
return count($this->data); throw new Exception('Not implemented');
} }
public function __invoke() { public function count(): int {
echo "__invoke called!\n"; return count($this->data);
}
public function __invoke() {
echo "__invoke called!\n";
}
} }
} }

View File

@ -6,29 +6,55 @@ Test V8::executeString() : Enumerate ArrayAccess keys
v8js.use_array_access = 1 v8js.use_array_access = 1
--FILE-- --FILE--
<?php <?php
if (PHP_VERSION_ID < 80000) {
class MyArray implements ArrayAccess, Countable {
private $data = Array('one', 'two', 'three', null, 'five');
class MyArray implements ArrayAccess, Countable { public function offsetExists($offset) {
private $data = Array('one', 'two', 'three', null, 'five'); return isset($this->data[$offset]);
}
public function offsetExists($offset): bool { public function offsetGet($offset) {
return isset($this->data[$offset]); return $this->data[$offset];
}
public function offsetSet($offset, $value) {
echo "set[$offset] = $value\n";
$this->data[$offset] = $value;
}
public function offsetUnset($offset) {
throw new Exception('Not implemented');
}
public function count() {
return count($this->data);
}
} }
} else {
class MyArray implements ArrayAccess, Countable {
private $data = Array('one', 'two', 'three', null, 'five');
public function offsetGet($offset): mixed { public function offsetExists($offset): bool {
return $this->data[$offset]; return isset($this->data[$offset]);
} }
public function offsetSet($offset, $value): void { public function offsetGet(mixed $offset): mixed {
echo "set[$offset] = $value\n"; return $this->data[$offset];
$this->data[$offset] = $value; }
}
public function offsetUnset($offset): void { public function offsetSet(mixed $offset, mixed $value): void {
throw new Exception('Not implemented'); echo "set[$offset] = $value\n";
} $this->data[$offset] = $value;
}
public function count(): int { public function offsetUnset(mixed $offset): void {
return count($this->data); throw new Exception('Not implemented');
}
public function count(): int {
return count($this->data);
}
} }
} }

View File

@ -6,31 +6,59 @@ Test V8::executeString() : Delete (unset) ArrayAccess keys
v8js.use_array_access = 1 v8js.use_array_access = 1
--FILE-- --FILE--
<?php <?php
if (PHP_VERSION_ID < 80000) {
class MyArray implements ArrayAccess, Countable {
private $data = Array('one', 'two', 'three');
class MyArray implements ArrayAccess, Countable { public function offsetExists($offset) {
private $data = Array('one', 'two', 'three'); return isset($this->data[$offset]);
}
public function offsetExists($offset): bool { public function offsetGet($offset) {
return isset($this->data[$offset]); if(!$this->offsetExists($offset)) {
return null;
}
return $this->data[$offset];
}
public function offsetSet($offset, $value) {
$this->data[$offset] = $value;
}
public function offsetUnset($offset) {
unset($this->data[$offset]);
}
public function count() {
return max(array_keys($this->data)) + 1;
}
} }
} else {
class MyArray implements ArrayAccess, Countable {
private $data = Array('one', 'two', 'three');
public function offsetGet($offset): mixed { public function offsetExists($offset): bool {
if(!$this->offsetExists($offset)) { return isset($this->data[$offset]);
return null; }
}
return $this->data[$offset];
}
public function offsetSet($offset, $value): void { public function offsetGet(mixed $offset): mixed {
$this->data[$offset] = $value; if(!$this->offsetExists($offset)) {
} return null;
}
return $this->data[$offset];
}
public function offsetUnset($offset): void { public function offsetSet(mixed $offset, mixed $value): void {
unset($this->data[$offset]); $this->data[$offset] = $value;
} }
public function count(): int { public function offsetUnset(mixed $offset): void {
return max(array_keys($this->data)) + 1; unset($this->data[$offset]);
}
public function count(): int {
return max(array_keys($this->data)) + 1;
}
} }
} }

View File

@ -6,28 +6,53 @@ Test V8::executeString() : in array (isset) behaviour of ArrayAccess
v8js.use_array_access = 1 v8js.use_array_access = 1
--FILE-- --FILE--
<?php <?php
if (PHP_VERSION_ID < 80000) {
class MyArray implements ArrayAccess, Countable {
private $data = Array('one', null, 'three');
class MyArray implements ArrayAccess, Countable { public function offsetExists($offset) {
private $data = Array('one', null, 'three'); return isset($this->data[$offset]);
}
public function offsetExists($offset): bool { public function offsetGet($offset) {
return isset($this->data[$offset]); return $this->data[$offset];
}
public function offsetSet($offset, $value) {
$this->data[$offset] = $value;
}
public function offsetUnset($offset) {
unset($this->data[$offset]);
}
public function count() {
return max(array_keys($this->data)) + 1;
}
} }
} else {
class MyArray implements ArrayAccess, Countable {
private $data = Array('one', null, 'three');
public function offsetGet($offset): mixed { public function offsetExists($offset): bool {
return $this->data[$offset]; return isset($this->data[$offset]);
} }
public function offsetSet($offset, $value): void { public function offsetGet(mixed $offset): mixed {
$this->data[$offset] = $value; return $this->data[$offset];
} }
public function offsetUnset($offset): void { public function offsetSet(mixed $offset, mixed $value): void {
unset($this->data[$offset]); $this->data[$offset] = $value;
} }
public function count(): int { public function offsetUnset(mixed $offset): void {
return max(array_keys($this->data)) + 1; unset($this->data[$offset]);
}
public function count(): int {
return max(array_keys($this->data)) + 1;
}
} }
} }

View File

@ -6,28 +6,53 @@ Test V8::executeString() : Check array access setter behaviour
v8js.use_array_access = 1 v8js.use_array_access = 1
--FILE-- --FILE--
<?php <?php
if (PHP_VERSION_ID < 80000) {
class MyArray implements ArrayAccess, Countable {
private $data = array('one', 'two', 'three');
class MyArray implements ArrayAccess, Countable { public function offsetExists($offset) {
private $data = array('one', 'two', 'three'); return isset($this->data[$offset]);
}
public function offsetExists($offset): bool { public function offsetGet($offset) {
return isset($this->data[$offset]); return $this->data[$offset];
}
public function offsetSet($offset, $value) {
$this->data[$offset] = $value;
}
public function offsetUnset($offset) {
throw new Exception('Not implemented');
}
public function count() {
return count($this->data);
}
} }
} else {
class MyArray implements ArrayAccess, Countable {
private $data = array('one', 'two', 'three');
public function offsetGet($offset): mixed { public function offsetExists($offset): bool {
return $this->data[$offset]; return isset($this->data[$offset]);
} }
public function offsetSet($offset, $value): void { public function offsetGet(mixed $offset): mixed {
$this->data[$offset] = $value; return $this->data[$offset];
} }
public function offsetUnset($offset): void { public function offsetSet(mixed $offset, mixed $value): void {
throw new Exception('Not implemented'); $this->data[$offset] = $value;
} }
public function count(): int { public function offsetUnset(mixed $offset): void {
return count($this->data); throw new Exception('Not implemented');
}
public function count(): int {
return count($this->data);
}
} }
} }

View File

@ -5,7 +5,7 @@ Test V8::executeString() : Exception clearing test
--FILE-- --FILE--
<?php <?php
$v8 = new V8Js('', array(), array(), false); $v8 = new V8Js(null, array(), array(), false);
var_dump($v8->getPendingException()); var_dump($v8->getPendingException());

View File

@ -10,7 +10,7 @@ class Foo {
public function __construct() public function __construct()
{ {
$this->v8 = new V8Js('', array(), array(), false); $this->v8 = new V8Js(null, array(), array(), false);
$this->v8->foo = $this; $this->v8->foo = $this;
$this->v8->executeString('fooobar', 'throw_0'); $this->v8->executeString('fooobar', 'throw_0');
var_dump($this->v8->getPendingException()); var_dump($this->v8->getPendingException());

View File

@ -10,7 +10,7 @@ class Foo {
public function __construct() public function __construct()
{ {
$this->v8 = new V8Js('', array(), array(), false); $this->v8 = new V8Js(null, array(), array(), false);
$this->v8->foo = $this; $this->v8->foo = $this;
$this->v8->executeString('function foobar() { throw new SyntaxError(); }', 'throw_1'); $this->v8->executeString('function foobar() { throw new SyntaxError(); }', 'throw_1');
$this->v8->executeString('try { foobar(); } catch (e) { print(e + " caught in JS!\n"); }', 'trycatch1'); $this->v8->executeString('try { foobar(); } catch (e) { print(e + " caught in JS!\n"); }', 'trycatch1');

View File

@ -54,22 +54,10 @@ try {
?> ?>
===EOF=== ===EOF===
--EXPECTREGEX-- --EXPECTF--
(?:Warning\: Creating default object from empty value in [^\r\n]+\/issue_250_001\.php on line 9\s*)+ Fatal error: Uncaught Error: Attempt to modify property "b" on null in %s%eissue_250_001.php:9
object\(TestObject\)\#\d+ \(3\) \{ Stack trace:
\["data"\:"TestObject"\:private\]\=\> #0 [internal function]: TestObject->setTitle('ouch')
object\(V8Object\)\#\d+ \(0\) \{ #1 %s%eissue_250_001.php(44): V8Js->executeString(' var v1 = se...')
\} #2 {main}
\["meta"\:"TestObject"\:private\]\=\> thrown in %s%eissue_250_001.php on line 9
array\(0\) \{
\}
\["a"\]\=\>
object\(stdClass\)\#\d+ \(1\) \{
\["b"\]\=\>
object\(stdClass\)\#\d+ \(1\) \{
\["title"\]\=\>
string\(4\) "ouch"
\}
\}
\}
\=\=\=EOF\=\=\=

View File

@ -139,6 +139,10 @@ array \(11\) \{
\["date"\] \=\> \["date"\] \=\>
object\(DateTime\)\#\d+ \(\d+\) \{(?: object\(DateTime\)\#\d+ \(\d+\) \{(?:
\["createFromImmutable"\] \=\> \["createFromImmutable"\] \=\>
object\(Closure\)\#\d+ \{
function \(\) \{ \[native code\] \}
\})?(?:
\["createFromInterface"\] \=\>
object\(Closure\)\#\d+ \{ object\(Closure\)\#\d+ \{
function \(\) \{ \[native code\] \} function \(\) \{ \[native code\] \}
\})? \})?

View File

@ -346,7 +346,7 @@ static PHP_METHOD(V8Js, __construct)
return; return;
} }
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|Saabz", &object_name, &vars_arr, &exts_arr, &report_uncaught, &snapshot_blob) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S!aabz", &object_name, &vars_arr, &exts_arr, &report_uncaught, &snapshot_blob) == FAILURE) {
return; return;
} }
@ -705,7 +705,7 @@ static PHP_METHOD(V8Js, executeString)
long flags = V8JS_FLAG_NONE, time_limit = 0, memory_limit = 0; long flags = V8JS_FLAG_NONE, time_limit = 0, memory_limit = 0;
v8js_script *res = NULL; v8js_script *res = NULL;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|Slll", &str, &identifier, &flags, &time_limit, &memory_limit) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|S!lll", &str, &identifier, &flags, &time_limit, &memory_limit) == FAILURE) {
return; return;
} }

View File

@ -158,10 +158,6 @@ static void v8js_call_php_func(zend_object *object, zend_function *method_ptr, c
fcc.called_scope = object->ce; fcc.called_scope = object->ce;
fcc.object = object; fcc.object = object;
if (!EG(current_execute_data) || !EG(current_execute_data)->func) {
EG(current_execute_data) = NULL;
}
zend_call_function(&fci, &fcc); zend_call_function(&fci, &fcc);
} }
zend_catch { zend_catch {

View File

@ -178,10 +178,6 @@ void v8js_v8_call(v8js_ctx *c, zval **return_value,
efree(timer_ctx); efree(timer_ctx);
if(!V8JSG(fatal_error_abort)) { if(!V8JSG(fatal_error_abort)) {
if (!EG(current_execute_data) || !EG(current_execute_data)->func) {
EG(current_execute_data) = NULL;
}
char exception_string[64]; char exception_string[64];
if (c->time_limit_hit) { if (c->time_limit_hit) {

View File

@ -140,7 +140,7 @@ static zval *v8js_v8object_read_property(SINCE80(zend_object, zval) *_object, SI
{ {
zend_throw_exception(php_ce_v8js_exception, zend_throw_exception(php_ce_v8js_exception,
"Can't access V8Object after V8Js instance is destroyed!", 0); "Can't access V8Object after V8Js instance is destroyed!", 0);
return retval; return SINCE80(&EG(uninitialized_zval), retval);
} }
V8JS_CTX_PROLOGUE_EX(obj->ctx, retval); V8JS_CTX_PROLOGUE_EX(obj->ctx, retval);
@ -152,7 +152,7 @@ static zval *v8js_v8object_read_property(SINCE80(zend_object, zval) *_object, SI
{ {
zend_throw_exception(php_ce_v8js_exception, zend_throw_exception(php_ce_v8js_exception,
"Member name length exceeds maximum supported length", 0); "Member name length exceeds maximum supported length", 0);
return retval; return SINCE80(&EG(uninitialized_zval), retval);
} }
v8::Local<v8::String> jsKey = V8JS_ZSYM(member); v8::Local<v8::String> jsKey = V8JS_ZSYM(member);
@ -313,9 +313,8 @@ static ZEND_FUNCTION(zend_v8object_func)
/* Cleanup trampoline */ /* Cleanup trampoline */
ZEND_ASSERT(EX(func)->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE); ZEND_ASSERT(EX(func)->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE);
zend_string_release(EX(func)->common.function_name);
zend_free_trampoline(EX(func)); bool bail = false;
EX(func) = NULL;
v8js_v8object *obj = v8js_v8object_fetch_object(object); v8js_v8object *obj = v8js_v8object_fetch_object(object);
@ -323,18 +322,25 @@ static ZEND_FUNCTION(zend_v8object_func)
{ {
zend_throw_exception(php_ce_v8js_exception, zend_throw_exception(php_ce_v8js_exception,
"Can't access V8Object after V8Js instance is destroyed!", 0); "Can't access V8Object after V8Js instance is destroyed!", 0);
return; bail = true;
} }
if (obj->v8obj.IsEmpty()) if (obj->v8obj.IsEmpty())
{ {
return; bail = true;
} }
if (ZSTR_LEN(method) > std::numeric_limits<int>::max()) if (ZSTR_LEN(method) > std::numeric_limits<int>::max())
{ {
zend_throw_exception(php_ce_v8js_exception, zend_throw_exception(php_ce_v8js_exception,
"Method name length exceeds maximum supported length", 0); "Method name length exceeds maximum supported length", 0);
bail = true;
}
if (bail) {
zend_string_release(EX(func)->common.function_name);
zend_free_trampoline(EX(func));
EX(func) = NULL;
return; return;
} }
@ -413,6 +419,10 @@ static ZEND_FUNCTION(zend_v8object_func)
efree(argv); efree(argv);
} }
zend_string_release(EX(func)->common.function_name);
zend_free_trampoline(EX(func));
EX(func) = NULL;
if (V8JSG(fatal_error_abort)) if (V8JSG(fatal_error_abort))
{ {
/* Check for fatal error marker possibly set by v8js_error_handler; just /* Check for fatal error marker possibly set by v8js_error_handler; just
@ -458,7 +468,9 @@ static zend_function *v8js_v8object_get_method(zend_object **object_ptr, zend_st
return f; return f;
#else #else
f = (zend_internal_function *)ecalloc(1, sizeof(*f)); f = (zend_internal_function *)ecalloc(1, sizeof(*f));
f->type = ZEND_ACC_CALL_VIA_HANDLER; f->type = ZEND_INTERNAL_FUNCTION;
f->scope = (*object_ptr)->ce;
f->fn_flags = ZEND_ACC_CALL_VIA_HANDLER;
f->handler = ZEND_FN(zend_v8object_func); f->handler = ZEND_FN(zend_v8object_func);
f->function_name = zend_string_copy(method); f->function_name = zend_string_copy(method);
return (zend_function *)f; return (zend_function *)f;
@ -613,7 +625,9 @@ static int v8js_v8object_get_closure(zval *object, zend_class_entry **ce_ptr, ze
*fptr_ptr = invoke; *fptr_ptr = invoke;
#else #else
invoke = (zend_internal_function *)ecalloc(1, sizeof(*invoke)); invoke = (zend_internal_function *)ecalloc(1, sizeof(*invoke));
invoke->type = ZEND_ACC_CALL_VIA_HANDLER; invoke->type = ZEND_INTERNAL_FUNCTION;
invoke->fn_flags = ZEND_ACC_CALL_VIA_HANDLER;
invoke->scope = object->ce;
invoke->handler = ZEND_FN(zend_v8object_func); invoke->handler = ZEND_FN(zend_v8object_func);
invoke->function_name = zend_string_init(V8JS_V8_INVOKE_FUNC_NAME, sizeof(V8JS_V8_INVOKE_FUNC_NAME) - 1, 0); invoke->function_name = zend_string_init(V8JS_V8_INVOKE_FUNC_NAME, sizeof(V8JS_V8_INVOKE_FUNC_NAME) - 1, 0);
*fptr_ptr = (zend_function *)invoke; *fptr_ptr = (zend_function *)invoke;