From cb7b3dcc296a315c756f3dcde58860737d625438 Mon Sep 17 00:00:00 2001 From: Albert Date: Fri, 27 May 2022 10:47:44 +0800 Subject: [PATCH] Optimize and fix test reference from @redbullmarky --- tests/array_access.phpt | 54 ++++++++++++----- tests/array_access_001.phpt | 66 +++++++++++++++------ tests/array_access_002.phpt | 66 ++++++++++++++------- tests/array_access_003.phpt | 95 +++++++++++++++++++++--------- tests/array_access_004.phpt | 81 +++++++++++++++++-------- tests/array_access_005.phpt | 78 ++++++++++++++++-------- tests/array_access_006.phpt | 66 ++++++++++++++------- tests/array_access_007.phpt | 72 +++++++++++++++------- tests/array_access_008.phpt | 63 ++++++++++++++------ tests/array_access_basic2.phpt | 59 +++++++++++++------ tests/exception_clearing.phpt | 2 +- tests/exception_propagation_2.phpt | 2 +- tests/exception_propagation_3.phpt | 2 +- tests/issue_250_001.phpt | 26 +++----- tests/var_dump.phpt | 4 ++ v8js_class.cc | 4 +- v8js_object_export.cc | 4 -- v8js_v8.cc | 4 -- v8js_v8object_class.cc | 32 +++++++--- 19 files changed, 532 insertions(+), 248 deletions(-) diff --git a/tests/array_access.phpt b/tests/array_access.phpt index 9b02dcc..3163734 100644 --- a/tests/array_access.phpt +++ b/tests/array_access.phpt @@ -7,25 +7,49 @@ v8js.use_array_access = 1 --FILE-- = 0 && $offset <= 20; - } +if (PHP_VERSION_ID < 80000) { + class MyArray implements ArrayAccess, Countable { + public function offsetExists($offset) { + return $offset >= 0 && $offset <= 20; + } - public function offsetGet($offset): mixed { - return 19 - $offset; - } + public function offsetGet($offset) { + return 19 - $offset; + } - public function offsetSet($offset, $value): void { - throw new Exception('Not implemented'); - } + public function offsetSet($offset, $value) { + throw new Exception('Not implemented'); + } - public function offsetUnset($offset): void { - throw new Exception('Not implemented'); - } + public function offsetUnset($offset) { + throw new Exception('Not implemented'); + } - public function count(): int { - return 20; + public function count() { + 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; + } } } diff --git a/tests/array_access_001.phpt b/tests/array_access_001.phpt index 49a2d2e..92aa264 100644 --- a/tests/array_access_001.phpt +++ b/tests/array_access_001.phpt @@ -7,31 +7,61 @@ v8js.use_array_access = 1 --FILE-- data[$offset]); + public function offsetExists($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 { - return $this->data[$offset]; - } + public function offsetExists($offset): bool { + return isset($this->data[$offset]); + } - public function offsetSet($offset, $value): void { - $this->data[$offset] = $value; - } + public function offsetGet(mixed $offset): mixed { + return $this->data[$offset]; + } - public function offsetUnset($offset): void { - throw new Exception('Not implemented'); - } + public function offsetSet(mixed $offset, mixed $value): void { + $this->data[$offset] = $value; + } - public function count(): int { - return count($this->data); - } + public function offsetUnset(mixed $offset): void { + throw new Exception('Not implemented'); + } - public function push($value) { - $this->data[] = $value; + public function count(): int { + return count($this->data); + } + + public function push($value) { + $this->data[] = $value; + } } } diff --git a/tests/array_access_002.phpt b/tests/array_access_002.phpt index 2f3af8b..f7db125 100644 --- a/tests/array_access_002.phpt +++ b/tests/array_access_002.phpt @@ -6,29 +6,55 @@ Test V8::executeString() : Use ArrayAccess with JavaScript native push method v8js.use_array_access = 1 --FILE-- data[$offset]); + } - public function offsetExists($offset): bool { - return isset($this->data[$offset]); + public function offsetGet($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 offsetGet($offset): mixed { - return $this->data[$offset]; - } - - public function offsetSet($offset, $value): void { - echo "set[$offset] = $value\n"; - $this->data[$offset] = $value; - } - - public function offsetUnset($offset): void { - throw new Exception('Not implemented'); - } - - public function count(): int { - return count($this->data); +} else { + class MyArray implements ArrayAccess, Countable { + private $data = Array('one', 'two', 'three'); + + public function offsetExists($offset): bool { + return isset($this->data[$offset]); + } + + public function offsetGet(mixed $offset): mixed { + 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); + } } } diff --git a/tests/array_access_003.phpt b/tests/array_access_003.phpt index f894f8b..f488272 100644 --- a/tests/array_access_003.phpt +++ b/tests/array_access_003.phpt @@ -6,40 +6,77 @@ Test V8::executeString() : Export PHP methods on ArrayAccess objects v8js.use_array_access = 1 --FILE-- data[$offset]); + } - public function offsetExists($offset): bool { - return isset($this->data[$offset]); + public function offsetGet($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 offsetExists($offset): bool { + return isset($this->data[$offset]); + } + + public function offsetGet(mixed $offset): mixed { + 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 { + echo 'count() = ', count($this->data), "\n"; + return count($this->data); + } - public function offsetGet($offset): mixed { - return $this->data[$offset]; - } + public function phpSidePush($value) { + echo "push << $value\n"; + $this->data[] = $value; + } - public function offsetSet($offset, $value): void { - echo "set[$offset] = $value\n"; - $this->data[$offset] = $value; - } - - public function offsetUnset($offset): void { - throw new Exception('Not implemented'); - } - - public function count(): int { - 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; + public function push($value) { + echo "php-side-push << $value\n"; + $this->data[] = $value; + } } } diff --git a/tests/array_access_004.phpt b/tests/array_access_004.phpt index 89da71a..c5c664b 100644 --- a/tests/array_access_004.phpt +++ b/tests/array_access_004.phpt @@ -6,38 +6,73 @@ Test V8::executeString() : Export PHP properties on ArrayAccess objects v8js.use_array_access = 1 --FILE-- data[$offset]); + } - public function offsetExists($offset): bool { - return isset($this->data[$offset]); + public function offsetGet($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 { - return $this->data[$offset]; - } + private $privFoo = 23; + protected $protFoo = 23; + public $pubFoo = 42; - public function offsetSet($offset, $value): void { - echo "set[$offset] = $value\n"; - $this->data[$offset] = $value; - } + /* We can have a length property on the PHP object, but the length property + * of the JS object will still call count() method. Anyways it should be + * accessibly as $length. */ + public $length = 42; - public function offsetUnset($offset): void { - throw new Exception('Not implemented'); - } + public function offsetExists($offset): bool { + return isset($this->data[$offset]); + } - public function count(): int { - return count($this->data); + public function offsetGet(mixed $offset): mixed { + 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); + } } } diff --git a/tests/array_access_005.phpt b/tests/array_access_005.phpt index 7c73a4a..ba6bc73 100644 --- a/tests/array_access_005.phpt +++ b/tests/array_access_005.phpt @@ -6,33 +6,63 @@ Test V8::executeString() : Export __invoke method on ArrayAccess objects v8js.use_array_access = 1 --FILE-- data[$offset]); + } - public function offsetExists($offset): bool { - return isset($this->data[$offset]); + public function offsetGet($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"; + } } - - public function offsetGet($offset): mixed { - return $this->data[$offset]; - } - - public function offsetSet($offset, $value): void { - echo "set[$offset] = $value\n"; - $this->data[$offset] = $value; - } - - public function offsetUnset($offset): void { - throw new Exception('Not implemented'); - } - - public function count(): int { - 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 offsetExists($offset): bool { + return isset($this->data[$offset]); + } + + public function offsetGet(mixed $offset): mixed { + 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); + } + + public function __invoke() { + echo "__invoke called!\n"; + } } } diff --git a/tests/array_access_006.phpt b/tests/array_access_006.phpt index 53fff25..96af8e3 100644 --- a/tests/array_access_006.phpt +++ b/tests/array_access_006.phpt @@ -6,29 +6,55 @@ Test V8::executeString() : Enumerate ArrayAccess keys v8js.use_array_access = 1 --FILE-- data[$offset]); + } - public function offsetExists($offset): bool { - return isset($this->data[$offset]); + public function offsetGet($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 offsetGet($offset): mixed { - return $this->data[$offset]; - } - - public function offsetSet($offset, $value): void { - echo "set[$offset] = $value\n"; - $this->data[$offset] = $value; - } - - public function offsetUnset($offset): void { - throw new Exception('Not implemented'); - } - - public function count(): int { - return count($this->data); +} else { + class MyArray implements ArrayAccess, Countable { + private $data = Array('one', 'two', 'three', null, 'five'); + + public function offsetExists($offset): bool { + return isset($this->data[$offset]); + } + + public function offsetGet(mixed $offset): mixed { + 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); + } } } diff --git a/tests/array_access_007.phpt b/tests/array_access_007.phpt index 0f8d59f..1210c12 100644 --- a/tests/array_access_007.phpt +++ b/tests/array_access_007.phpt @@ -6,31 +6,59 @@ Test V8::executeString() : Delete (unset) ArrayAccess keys v8js.use_array_access = 1 --FILE-- data[$offset]); + } - public function offsetExists($offset): bool { - return isset($this->data[$offset]); + public function offsetGet($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; + } } - - public function offsetGet($offset): mixed { - if(!$this->offsetExists($offset)) { - return null; - } - return $this->data[$offset]; - } - - public function offsetSet($offset, $value): void { - $this->data[$offset] = $value; - } - - public function offsetUnset($offset): void { - unset($this->data[$offset]); - } - - public function count(): int { - return max(array_keys($this->data)) + 1; +} else { + class MyArray implements ArrayAccess, Countable { + private $data = Array('one', 'two', 'three'); + + public function offsetExists($offset): bool { + return isset($this->data[$offset]); + } + + public function offsetGet(mixed $offset): mixed { + if(!$this->offsetExists($offset)) { + return null; + } + return $this->data[$offset]; + } + + public function offsetSet(mixed $offset, mixed $value): void { + $this->data[$offset] = $value; + } + + public function offsetUnset(mixed $offset): void { + unset($this->data[$offset]); + } + + public function count(): int { + return max(array_keys($this->data)) + 1; + } } } diff --git a/tests/array_access_008.phpt b/tests/array_access_008.phpt index 48ee085..f49942d 100644 --- a/tests/array_access_008.phpt +++ b/tests/array_access_008.phpt @@ -6,28 +6,53 @@ Test V8::executeString() : in array (isset) behaviour of ArrayAccess v8js.use_array_access = 1 --FILE-- data[$offset]); + } - public function offsetExists($offset): bool { - 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) { + unset($this->data[$offset]); + } + + public function count() { + return max(array_keys($this->data)) + 1; + } } - - public function offsetGet($offset): mixed { - return $this->data[$offset]; - } - - public function offsetSet($offset, $value): void { - $this->data[$offset] = $value; - } - - public function offsetUnset($offset): void { - unset($this->data[$offset]); - } - - public function count(): int { - return max(array_keys($this->data)) + 1; +} else { + class MyArray implements ArrayAccess, Countable { + private $data = Array('one', null, 'three'); + + public function offsetExists($offset): bool { + return isset($this->data[$offset]); + } + + public function offsetGet(mixed $offset): mixed { + return $this->data[$offset]; + } + + public function offsetSet(mixed $offset, mixed $value): void { + $this->data[$offset] = $value; + } + + public function offsetUnset(mixed $offset): void { + unset($this->data[$offset]); + } + + public function count(): int { + return max(array_keys($this->data)) + 1; + } } } diff --git a/tests/array_access_basic2.phpt b/tests/array_access_basic2.phpt index 0dcdc44..0cbf403 100644 --- a/tests/array_access_basic2.phpt +++ b/tests/array_access_basic2.phpt @@ -6,28 +6,53 @@ Test V8::executeString() : Check array access setter behaviour v8js.use_array_access = 1 --FILE-- data[$offset]); +if (PHP_VERSION_ID < 80000) { + class MyArray implements ArrayAccess, Countable { + private $data = array('one', 'two', 'three'); + + public function offsetExists($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); + } } +} else { + class MyArray implements ArrayAccess, Countable { + private $data = array('one', 'two', 'three'); - public function offsetGet($offset): mixed { - return $this->data[$offset]; - } + public function offsetExists($offset): bool { + return isset($this->data[$offset]); + } - public function offsetSet($offset, $value): void { - $this->data[$offset] = $value; - } + public function offsetGet(mixed $offset): mixed { + return $this->data[$offset]; + } - public function offsetUnset($offset): void { - throw new Exception('Not implemented'); - } + public function offsetSet(mixed $offset, mixed $value): void { + $this->data[$offset] = $value; + } - public function count(): int { - return count($this->data); + public function offsetUnset(mixed $offset): void { + throw new Exception('Not implemented'); + } + + public function count(): int { + return count($this->data); + } } } diff --git a/tests/exception_clearing.phpt b/tests/exception_clearing.phpt index 0d797a6..3646c5a 100644 --- a/tests/exception_clearing.phpt +++ b/tests/exception_clearing.phpt @@ -5,7 +5,7 @@ Test V8::executeString() : Exception clearing test --FILE-- getPendingException()); diff --git a/tests/exception_propagation_2.phpt b/tests/exception_propagation_2.phpt index 9a879c6..c808e3a 100644 --- a/tests/exception_propagation_2.phpt +++ b/tests/exception_propagation_2.phpt @@ -10,7 +10,7 @@ class Foo { public function __construct() { - $this->v8 = new V8Js('', array(), array(), false); + $this->v8 = new V8Js(null, array(), array(), false); $this->v8->foo = $this; $this->v8->executeString('fooobar', 'throw_0'); var_dump($this->v8->getPendingException()); diff --git a/tests/exception_propagation_3.phpt b/tests/exception_propagation_3.phpt index 1bdaab3..bc93c1d 100644 --- a/tests/exception_propagation_3.phpt +++ b/tests/exception_propagation_3.phpt @@ -10,7 +10,7 @@ class Foo { public function __construct() { - $this->v8 = new V8Js('', array(), array(), false); + $this->v8 = new V8Js(null, array(), array(), false); $this->v8->foo = $this; $this->v8->executeString('function foobar() { throw new SyntaxError(); }', 'throw_1'); $this->v8->executeString('try { foobar(); } catch (e) { print(e + " caught in JS!\n"); }', 'trycatch1'); diff --git a/tests/issue_250_001.phpt b/tests/issue_250_001.phpt index dff9427..48bd5e4 100644 --- a/tests/issue_250_001.phpt +++ b/tests/issue_250_001.phpt @@ -54,22 +54,10 @@ try { ?> ===EOF=== ---EXPECTREGEX-- -(?:Warning\: Creating default object from empty value in [^\r\n]+\/issue_250_001\.php on line 9\s*)+ -object\(TestObject\)\#\d+ \(3\) \{ - \["data"\:"TestObject"\:private\]\=\> - object\(V8Object\)\#\d+ \(0\) \{ - \} - \["meta"\:"TestObject"\:private\]\=\> - array\(0\) \{ - \} - \["a"\]\=\> - object\(stdClass\)\#\d+ \(1\) \{ - \["b"\]\=\> - object\(stdClass\)\#\d+ \(1\) \{ - \["title"\]\=\> - string\(4\) "ouch" - \} - \} -\} -\=\=\=EOF\=\=\= +--EXPECTF-- +Fatal error: Uncaught Error: Attempt to modify property "b" on null in %s%eissue_250_001.php:9 +Stack trace: +#0 [internal function]: TestObject->setTitle('ouch') +#1 %s%eissue_250_001.php(44): V8Js->executeString(' var v1 = se...') +#2 {main} + thrown in %s%eissue_250_001.php on line 9 diff --git a/tests/var_dump.phpt b/tests/var_dump.phpt index e1d232b..cc0654c 100644 --- a/tests/var_dump.phpt +++ b/tests/var_dump.phpt @@ -139,6 +139,10 @@ array \(11\) \{ \["date"\] \=\> object\(DateTime\)\#\d+ \(\d+\) \{(?: \["createFromImmutable"\] \=\> + object\(Closure\)\#\d+ \{ + function \(\) \{ \[native code\] \} + \})?(?: + \["createFromInterface"\] \=\> object\(Closure\)\#\d+ \{ function \(\) \{ \[native code\] \} \})? diff --git a/v8js_class.cc b/v8js_class.cc index becac9d..49acc11 100644 --- a/v8js_class.cc +++ b/v8js_class.cc @@ -346,7 +346,7 @@ static PHP_METHOD(V8Js, __construct) 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; } @@ -705,7 +705,7 @@ static PHP_METHOD(V8Js, executeString) long flags = V8JS_FLAG_NONE, time_limit = 0, memory_limit = 0; 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; } diff --git a/v8js_object_export.cc b/v8js_object_export.cc index fa9a9fc..6b3b59b 100644 --- a/v8js_object_export.cc +++ b/v8js_object_export.cc @@ -158,10 +158,6 @@ static void v8js_call_php_func(zend_object *object, zend_function *method_ptr, c fcc.called_scope = object->ce; fcc.object = object; - if (!EG(current_execute_data) || !EG(current_execute_data)->func) { - EG(current_execute_data) = NULL; - } - zend_call_function(&fci, &fcc); } zend_catch { diff --git a/v8js_v8.cc b/v8js_v8.cc index aa0f71d..0b5eab1 100644 --- a/v8js_v8.cc +++ b/v8js_v8.cc @@ -178,10 +178,6 @@ void v8js_v8_call(v8js_ctx *c, zval **return_value, efree(timer_ctx); if(!V8JSG(fatal_error_abort)) { - if (!EG(current_execute_data) || !EG(current_execute_data)->func) { - EG(current_execute_data) = NULL; - } - char exception_string[64]; if (c->time_limit_hit) { diff --git a/v8js_v8object_class.cc b/v8js_v8object_class.cc index a78412d..b13554b 100644 --- a/v8js_v8object_class.cc +++ b/v8js_v8object_class.cc @@ -140,7 +140,7 @@ static zval *v8js_v8object_read_property(SINCE80(zend_object, zval) *_object, SI { zend_throw_exception(php_ce_v8js_exception, "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); @@ -152,7 +152,7 @@ static zval *v8js_v8object_read_property(SINCE80(zend_object, zval) *_object, SI { zend_throw_exception(php_ce_v8js_exception, "Member name length exceeds maximum supported length", 0); - return retval; + return SINCE80(&EG(uninitialized_zval), retval); } v8::Local jsKey = V8JS_ZSYM(member); @@ -313,9 +313,8 @@ static ZEND_FUNCTION(zend_v8object_func) /* Cleanup 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)); - EX(func) = NULL; + + bool bail = false; 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, "Can't access V8Object after V8Js instance is destroyed!", 0); - return; + bail = true; } if (obj->v8obj.IsEmpty()) { - return; + bail = true; } if (ZSTR_LEN(method) > std::numeric_limits::max()) { zend_throw_exception(php_ce_v8js_exception, "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; } @@ -413,6 +419,10 @@ static ZEND_FUNCTION(zend_v8object_func) efree(argv); } + zend_string_release(EX(func)->common.function_name); + zend_free_trampoline(EX(func)); + EX(func) = NULL; + if (V8JSG(fatal_error_abort)) { /* 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; #else 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->function_name = zend_string_copy(method); 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; #else 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->function_name = zend_string_init(V8JS_V8_INVOKE_FUNC_NAME, sizeof(V8JS_V8_INVOKE_FUNC_NAME) - 1, 0); *fptr_ptr = (zend_function *)invoke;