From 1db8f8de5e83f62de6d16986973de252e101170b Mon Sep 17 00:00:00 2001 From: Albert Date: Mon, 23 May 2022 15:41:57 +0800 Subject: [PATCH] Support PHP8.1+ --- tests/array_access.phpt | 10 ++++---- tests/array_access_001.phpt | 10 ++++---- tests/array_access_002.phpt | 10 ++++---- tests/array_access_003.phpt | 10 ++++---- tests/array_access_004.phpt | 10 ++++---- tests/array_access_005.phpt | 10 ++++---- tests/array_access_006.phpt | 10 ++++---- tests/array_access_007.phpt | 10 ++++---- tests/array_access_008.phpt | 10 ++++---- tests/array_access_basic2.phpt | 10 ++++---- tests/exception_clearing.phpt | 2 +- tests/exception_propagation_2.phpt | 2 +- tests/exception_propagation_3.phpt | 2 +- v8js_object_export.cc | 4 +++ v8js_v8.cc | 4 +++ v8js_v8.h | 39 ++++++++++++++++++++++++++++++ v8js_v8object_class.cc | 20 +++++++-------- 17 files changed, 110 insertions(+), 63 deletions(-) diff --git a/tests/array_access.phpt b/tests/array_access.phpt index 6792c61..9b02dcc 100644 --- a/tests/array_access.phpt +++ b/tests/array_access.phpt @@ -8,23 +8,23 @@ v8js.use_array_access = 1 = 0 && $offset <= 20; } - public function offsetGet($offset) { + public function offsetGet($offset): mixed { return 19 - $offset; } - public function offsetSet($offset, $value) { + public function offsetSet($offset, $value): void { throw new Exception('Not implemented'); } - public function offsetUnset($offset) { + public function offsetUnset($offset): void { throw new Exception('Not implemented'); } - public function count() { + public function count(): int { return 20; } } diff --git a/tests/array_access_001.phpt b/tests/array_access_001.phpt index dd92bbd..49a2d2e 100644 --- a/tests/array_access_001.phpt +++ b/tests/array_access_001.phpt @@ -10,23 +10,23 @@ v8js.use_array_access = 1 class MyArray implements ArrayAccess, Countable { private $data = Array('one', 'two', 'three'); - public function offsetExists($offset) { + public function offsetExists($offset): bool { return isset($this->data[$offset]); } - public function offsetGet($offset) { + public function offsetGet($offset): mixed { return $this->data[$offset]; } - public function offsetSet($offset, $value) { + public function offsetSet($offset, $value): void { $this->data[$offset] = $value; } - public function offsetUnset($offset) { + public function offsetUnset($offset): void { throw new Exception('Not implemented'); } - public function count() { + public function count(): int { return count($this->data); } diff --git a/tests/array_access_002.phpt b/tests/array_access_002.phpt index dde425c..2f3af8b 100644 --- a/tests/array_access_002.phpt +++ b/tests/array_access_002.phpt @@ -10,24 +10,24 @@ v8js.use_array_access = 1 class MyArray implements ArrayAccess, Countable { private $data = Array('one', 'two', 'three'); - public function offsetExists($offset) { + public function offsetExists($offset): bool { return isset($this->data[$offset]); } - public function offsetGet($offset) { + public function offsetGet($offset): mixed { return $this->data[$offset]; } - public function offsetSet($offset, $value) { + public function offsetSet($offset, $value): void { echo "set[$offset] = $value\n"; $this->data[$offset] = $value; } - public function offsetUnset($offset) { + public function offsetUnset($offset): void { throw new Exception('Not implemented'); } - public function count() { + public function count(): int { return count($this->data); } } diff --git a/tests/array_access_003.phpt b/tests/array_access_003.phpt index 22c7f09..f894f8b 100644 --- a/tests/array_access_003.phpt +++ b/tests/array_access_003.phpt @@ -10,24 +10,24 @@ v8js.use_array_access = 1 class MyArray implements ArrayAccess, Countable { private $data = Array('one', 'two', 'three'); - public function offsetExists($offset) { + public function offsetExists($offset): bool { return isset($this->data[$offset]); } - public function offsetGet($offset) { + public function offsetGet($offset): mixed { return $this->data[$offset]; } - public function offsetSet($offset, $value) { + public function offsetSet($offset, $value): void { echo "set[$offset] = $value\n"; $this->data[$offset] = $value; } - public function offsetUnset($offset) { + public function offsetUnset($offset): void { throw new Exception('Not implemented'); } - public function count() { + public function count(): int { echo 'count() = ', count($this->data), "\n"; return count($this->data); } diff --git a/tests/array_access_004.phpt b/tests/array_access_004.phpt index fa5160a..89da71a 100644 --- a/tests/array_access_004.phpt +++ b/tests/array_access_004.phpt @@ -19,24 +19,24 @@ class MyArray implements ArrayAccess, Countable { * accessibly as $length. */ public $length = 42; - public function offsetExists($offset) { + public function offsetExists($offset): bool { return isset($this->data[$offset]); } - public function offsetGet($offset) { + public function offsetGet($offset): mixed { return $this->data[$offset]; } - public function offsetSet($offset, $value) { + public function offsetSet($offset, $value): void { echo "set[$offset] = $value\n"; $this->data[$offset] = $value; } - public function offsetUnset($offset) { + public function offsetUnset($offset): void { throw new Exception('Not implemented'); } - public function count() { + public function count(): int { return count($this->data); } } diff --git a/tests/array_access_005.phpt b/tests/array_access_005.phpt index afe8492..7c73a4a 100644 --- a/tests/array_access_005.phpt +++ b/tests/array_access_005.phpt @@ -10,24 +10,24 @@ v8js.use_array_access = 1 class MyArray implements ArrayAccess, Countable { private $data = Array('one', 'two', 'three'); - public function offsetExists($offset) { + public function offsetExists($offset): bool { return isset($this->data[$offset]); } - public function offsetGet($offset) { + public function offsetGet($offset): mixed { return $this->data[$offset]; } - public function offsetSet($offset, $value) { + public function offsetSet($offset, $value): void { echo "set[$offset] = $value\n"; $this->data[$offset] = $value; } - public function offsetUnset($offset) { + public function offsetUnset($offset): void { throw new Exception('Not implemented'); } - public function count() { + public function count(): int { return count($this->data); } diff --git a/tests/array_access_006.phpt b/tests/array_access_006.phpt index 95cdf9c..53fff25 100644 --- a/tests/array_access_006.phpt +++ b/tests/array_access_006.phpt @@ -10,24 +10,24 @@ v8js.use_array_access = 1 class MyArray implements ArrayAccess, Countable { private $data = Array('one', 'two', 'three', null, 'five'); - public function offsetExists($offset) { + public function offsetExists($offset): bool { return isset($this->data[$offset]); } - public function offsetGet($offset) { + public function offsetGet($offset): mixed { return $this->data[$offset]; } - public function offsetSet($offset, $value) { + public function offsetSet($offset, $value): void { echo "set[$offset] = $value\n"; $this->data[$offset] = $value; } - public function offsetUnset($offset) { + public function offsetUnset($offset): void { throw new Exception('Not implemented'); } - public function count() { + public function count(): int { return count($this->data); } } diff --git a/tests/array_access_007.phpt b/tests/array_access_007.phpt index 724176e..0f8d59f 100644 --- a/tests/array_access_007.phpt +++ b/tests/array_access_007.phpt @@ -10,26 +10,26 @@ v8js.use_array_access = 1 class MyArray implements ArrayAccess, Countable { private $data = Array('one', 'two', 'three'); - public function offsetExists($offset) { + public function offsetExists($offset): bool { return isset($this->data[$offset]); } - public function offsetGet($offset) { + public function offsetGet($offset): mixed { if(!$this->offsetExists($offset)) { return null; } return $this->data[$offset]; } - public function offsetSet($offset, $value) { + public function offsetSet($offset, $value): void { $this->data[$offset] = $value; } - public function offsetUnset($offset) { + public function offsetUnset($offset): void { unset($this->data[$offset]); } - public function count() { + 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 23507eb..48ee085 100644 --- a/tests/array_access_008.phpt +++ b/tests/array_access_008.phpt @@ -10,23 +10,23 @@ v8js.use_array_access = 1 class MyArray implements ArrayAccess, Countable { private $data = Array('one', null, 'three'); - public function offsetExists($offset) { + public function offsetExists($offset): bool { return isset($this->data[$offset]); } - public function offsetGet($offset) { + public function offsetGet($offset): mixed { return $this->data[$offset]; } - public function offsetSet($offset, $value) { + public function offsetSet($offset, $value): void { $this->data[$offset] = $value; } - public function offsetUnset($offset) { + public function offsetUnset($offset): void { unset($this->data[$offset]); } - public function count() { + 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 925eb2c..0dcdc44 100644 --- a/tests/array_access_basic2.phpt +++ b/tests/array_access_basic2.phpt @@ -10,23 +10,23 @@ v8js.use_array_access = 1 class MyArray implements ArrayAccess, Countable { private $data = array('one', 'two', 'three'); - public function offsetExists($offset) { + public function offsetExists($offset): bool { return isset($this->data[$offset]); } - public function offsetGet($offset) { + public function offsetGet($offset): mixed { return $this->data[$offset]; } - public function offsetSet($offset, $value) { + public function offsetSet($offset, $value): void { $this->data[$offset] = $value; } - public function offsetUnset($offset) { + public function offsetUnset($offset): void { throw new Exception('Not implemented'); } - public function count() { + public function count(): int { return count($this->data); } } diff --git a/tests/exception_clearing.phpt b/tests/exception_clearing.phpt index 3646c5a..0d797a6 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 c808e3a..9a879c6 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(null, array(), array(), false); + $this->v8 = new V8Js('', 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 bc93c1d..1bdaab3 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(null, array(), array(), false); + $this->v8 = new V8Js('', 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/v8js_object_export.cc b/v8js_object_export.cc index 6b3b59b..fa9a9fc 100644 --- a/v8js_object_export.cc +++ b/v8js_object_export.cc @@ -158,6 +158,10 @@ 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 0b5eab1..aa0f71d 100644 --- a/v8js_v8.cc +++ b/v8js_v8.cc @@ -178,6 +178,10 @@ 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_v8.h b/v8js_v8.h index 7adc67d..59b374d 100644 --- a/v8js_v8.h +++ b/v8js_v8.h @@ -100,6 +100,45 @@ int v8js_get_properties_hash(v8::Local jsValue, HashTable *retval, in #define SINCE80(x,y) x #endif +#if PHP_VERSION_ID < 70200 +#define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(name, return_reference, required_num_args, class_name, allow_null) \ + ZEND_BEGIN_ARG_INFO_EX(name, return_reference, required_num_args, allow_null) +#endif + +// polyfill for ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX, which changes between 7.1 and 7.2 +#if PHP_VERSION_ID < 70200 +#define V8_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, return_reference, required_num_args, type, allow_null) \ + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, return_reference, required_num_args, type, /*class_name*/ 0, allow_null) +#else +#define V8_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, return_reference, required_num_args, type, allow_null) \ + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, return_reference, required_num_args, type, allow_null) +#endif + +// In PHP 8.1, mismatched tentative return types emit a deprecation notice. +// https://wiki.php.net/rfc/internal_method_return_types +// +// When compiling for earlier php versions, the return type is dropped. +#if PHP_VERSION_ID < 80100 +#define ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(name, return_reference, required_num_args, type, allow_null) \ + ZEND_BEGIN_ARG_INFO_EX(name, return_reference, required_num_args, allow_null) +#endif + +#ifndef IS_VOID +#define IS_VOID 99 +#endif + +#ifndef IS_MIXED +#define IS_MIXED 99 +#endif + +#ifndef _IS_BOOL +#define _IS_BOOL 99 +#endif + +#ifndef IS_LONG +#define IS_LONG 99 +#endif + #endif /* V8JS_V8_H */ diff --git a/v8js_v8object_class.cc b/v8js_v8object_class.cc index a4a3097..a78412d 100644 --- a/v8js_v8object_class.cc +++ b/v8js_v8object_class.cc @@ -853,7 +853,7 @@ PHP_METHOD(V8Generator, __wakeup) } /* }}} */ -/* {{{ mixed V8Generator::current() +/* {{{ mixed V8Generator::current(): mixed */ PHP_METHOD(V8Generator, current) { @@ -868,7 +868,7 @@ PHP_METHOD(V8Generator, current) } /* }}} */ -/* {{{ scalar V8Generator::key() +/* {{{ scalar V8Generator::key(): mixed */ PHP_METHOD(V8Generator, key) { @@ -876,7 +876,7 @@ PHP_METHOD(V8Generator, key) } /* }}} */ -/* {{{ void V8Generator::next() +/* {{{ void V8Generator::next(): void */ PHP_METHOD(V8Generator, next) { @@ -885,7 +885,7 @@ PHP_METHOD(V8Generator, next) } /* }}} */ -/* {{{ void V8Generator::rewind() +/* {{{ void V8Generator::rewind(): void */ PHP_METHOD(V8Generator, rewind) { @@ -901,7 +901,7 @@ PHP_METHOD(V8Generator, rewind) } /* }}} */ -/* {{{ boolean V8Generator::valid() +/* {{{ boolean V8Generator::valid(): bool */ PHP_METHOD(V8Generator, valid) { @@ -982,19 +982,19 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO(arginfo_v8generator_wakeup, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_v8generator_current, 0) +V8_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_v8generator_current, 0, 0, IS_MIXED, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_v8generator_key, 0) +V8_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_v8generator_key, 0, 0, IS_MIXED, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_v8generator_next, 0) +V8_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_v8generator_next, 0, 0, IS_VOID, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_v8generator_rewind, 0) +V8_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_v8generator_rewind, 0, 0, IS_VOID, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_v8generator_valid, 0) +V8_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_v8generator_valid, 0, 0, _IS_BOOL, 0) ZEND_END_ARG_INFO() static const zend_function_entry v8js_v8generator_methods[] = {/* {{{ */