From fa4babb30743dd19b4b24160bcc7acd5743801cc Mon Sep 17 00:00:00 2001 From: Stefan Siegl Date: Tue, 31 May 2022 09:35:09 +0200 Subject: [PATCH 1/3] Remove support for V8 extensions --- README.md | 34 +-- php_v8js_macros.h | 3 - tests/create_snapshot_basic.phpt | 2 +- tests/exception_clearing.phpt | 2 +- tests/exception_propagation_2.phpt | 2 +- tests/exception_propagation_3.phpt | 2 +- tests/extensions_basic.phpt | 42 ---- tests/extensions_circular_dependency.phpt | 52 ----- tests/extensions_error.phpt | 44 ---- tests/unicode.phpt | 2 +- v8js_class.cc | 260 +--------------------- v8js_main.cc | 6 - 12 files changed, 11 insertions(+), 440 deletions(-) delete mode 100644 tests/extensions_basic.phpt delete mode 100644 tests/extensions_circular_dependency.phpt delete mode 100644 tests/extensions_error.phpt diff --git a/README.md b/README.md index 59066510..21fb08c6 100644 --- a/README.md +++ b/README.md @@ -78,11 +78,10 @@ class V8Js * Initializes and starts V8 engine and returns new V8Js object with it's own V8 context. * @param string $object_name * @param array $variables - * @param array $extensions * @param bool $report_uncaught_exceptions * @param string $snapshot_blob */ - public function __construct($object_name = "PHP", array $variables = [], array $extensions = [], $report_uncaught_exceptions = TRUE, $snapshot_blob = NULL) + public function __construct($object_name = "PHP", array $variables = [], $report_uncaught_exceptions = TRUE, $snapshot_blob = NULL) {} /** @@ -177,30 +176,8 @@ class V8Js /** Static methods **/ - /** - * Registers persistent context independent global Javascript extension. - * NOTE! These extensions exist until PHP is shutdown and they need to be registered before V8 is initialized. - * For best performance V8 is initialized only once per process thus this call has to be done before any V8Js objects are created! - * @param string $extension_name - * @param string $code - * @param array $dependencies - * @param bool $auto_enable - * @return bool - */ - public static function registerExtension($extension_name, $code, array $dependencies, $auto_enable = FALSE) - {} - - /** - * Returns extensions successfully registered with V8Js::registerExtension(). - * @return array|string[] - */ - public static function getExtensions() - {} - /** * Creates a custom V8 heap snapshot with the provided JavaScript source embedded. - * Snapshots are supported by V8 4.3.7 and higher. For older versions of V8 this - * extension doesn't provide this method. * @param string $embed_source * @return string|false */ @@ -353,15 +330,6 @@ This behaviour can be changed by enabling the php.ini flag `v8js.use_array_acces Snapshots ========= -First of all snapshots are incompatible with extensions. So when you see - - # - # Fatal error in ../src/snapshot/startup-serializer.cc, line 122 - # Check failed: !isolate->has_installed_extensions(). - # - -you need to remove all extension registrations. - First of all [custom startup snapshots](https://v8project.blogspot.de/2015/09/custom-startup-snapshots.html) is a feature provided by V8 itself, built on top of it's general heap snapshots feature. The idea is that, since it is quite common to load some JavaScript library prior to any actual work to be done, that this library code diff --git a/php_v8js_macros.h b/php_v8js_macros.h index eb6d8118..606fa4d2 100644 --- a/php_v8js_macros.h +++ b/php_v8js_macros.h @@ -138,7 +138,6 @@ ZEND_EXTERN_MODULE_GLOBALS(v8js) * * - whether V8 has been initialized at all * - the V8 backend platform - * - loaded extensions * - V8 "command line" flags * * In a ZTS-enabled environment access to all of these variables must happen @@ -150,8 +149,6 @@ struct _v8js_process_globals { std::mutex lock; #endif - HashTable *extensions; - /* V8 command line flags */ char *v8_flags; diff --git a/tests/create_snapshot_basic.phpt b/tests/create_snapshot_basic.phpt index 731426de..56444493 100644 --- a/tests/create_snapshot_basic.phpt +++ b/tests/create_snapshot_basic.phpt @@ -22,7 +22,7 @@ if (strlen($snap) > 0) { var_dump("snapshot successfully created"); } -$v8 = new V8Js('PHP', array(), array(), true, $snap); +$v8 = new V8Js('PHP', array(), true, $snap); $v8->executeString('var_dump(doublify(23));'); ?> ===EOF=== diff --git a/tests/exception_clearing.phpt b/tests/exception_clearing.phpt index 3646c5a9..c02d465f 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 c808e3aa..ce88e6a9 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(null, 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 bc93c1d8..af7de8ce 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(null, 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/extensions_basic.phpt b/tests/extensions_basic.phpt deleted file mode 100644 index 308c79cd..00000000 --- a/tests/extensions_basic.phpt +++ /dev/null @@ -1,42 +0,0 @@ ---TEST-- -Test V8::registerExtension() : Basic extension registering ---SKIPIF-- - ---FILE-- - -===EOF=== ---EXPECTF-- -Deprecated: %s V8Js::registerExtension() is deprecated in %s%eextensions_basic.php on line 3 - -Deprecated: %s V8Js::registerExtension() is deprecated in %s%eextensions_basic.php on line 4 - -Deprecated: %s V8Js::getExtensions() is deprecated in %s%eextensions_basic.php on line 6 -array(2) { - ["a"]=> - array(2) { - ["auto_enable"]=> - bool(false) - ["deps"]=> - array(1) { - [0]=> - string(1) "b" - } - } - ["b"]=> - array(1) { - ["auto_enable"]=> - bool(false) - } -} - -Deprecated: V8Js::__construct(): Use of extensions is deprecated, $extensions array passed in %s%eextensions_basic.php on line 8 -Hello world! -===EOF=== diff --git a/tests/extensions_circular_dependency.phpt b/tests/extensions_circular_dependency.phpt deleted file mode 100644 index f015293b..00000000 --- a/tests/extensions_circular_dependency.phpt +++ /dev/null @@ -1,52 +0,0 @@ ---TEST-- -Test V8::registerExtension() : Circular dependencies ---SKIPIF-- - ---FILE-- - ---EXPECTF-- -Deprecated: %s V8Js::registerExtension() is deprecated in %s%eextensions_circular_dependency.php on line 3 - -Deprecated: %s V8Js::registerExtension() is deprecated in %s%eextensions_circular_dependency.php on line 4 - -Deprecated: %s V8Js::getExtensions() is deprecated in %s%eextensions_circular_dependency.php on line 6 -array(2) { - ["a"]=> - array(2) { - ["auto_enable"]=> - bool(false) - ["deps"]=> - array(1) { - [0]=> - string(1) "b" - } - } - ["b"]=> - array(2) { - ["auto_enable"]=> - bool(false) - ["deps"]=> - array(1) { - [0]=> - string(1) "a" - } - } -} - -Deprecated: V8Js::__construct(): Use of extensions is deprecated, $extensions array passed in %s%eextensions_circular_dependency.php on line 8 - -Warning: Fatal V8 error in v8::Context::New(): Circular extension dependency in %s on line 8 - -Fatal error: Uncaught V8JsException: Failed to create V8 context. Check that registered extensions do not have errors. in %s:8 -Stack trace: -#0 %s(8): V8Js->__construct('myobj', Array, Array) -#1 {main} - thrown in %s on line 8 diff --git a/tests/extensions_error.phpt b/tests/extensions_error.phpt deleted file mode 100644 index d2210ada..00000000 --- a/tests/extensions_error.phpt +++ /dev/null @@ -1,44 +0,0 @@ ---TEST-- -Test V8::registerExtension() : Register extension with errors ---SKIPIF-- - (.*)/", $minfo, $matches)) { - $version = explode('.', $matches[1]); - if($version[0] < 5 || ($version[0] == 5 && $version[1] < 7)) { - // old v8 version, has shorter error message and hence doesn't - // fit our EXCEPTF below - echo "SKIP too old V8 version"; - } -} - -?> ---FILE-- - -===EOF=== ---EXPECTF-- --- registerExtension -- - -Deprecated: %s V8Js::registerExtension() is deprecated in %s%eextensions_error.php on line 5 --- creating V8Js object -- -Error installing extension 'handlebars'. - -Fatal error: Uncaught V8JsException: Failed to create V8 context. Check that registered extensions do not have errors. in %s%eextensions_error.php:7 -Stack trace: -#0 %s%eextensions_error.php(7): V8Js->__construct() -#1 {main} - thrown in %s%eextensions_error.php on line 7 diff --git a/tests/unicode.phpt b/tests/unicode.phpt index 58fd2f59..0bbfa704 100644 --- a/tests/unicode.phpt +++ b/tests/unicode.phpt @@ -12,7 +12,7 @@ $unicode = 'äöüßÜÄÖÜ߀áàâÁÀµ²³▁▂▃▄▅▆▇█ $snapshot = V8Js::createSnapshot("var snapshot = {unicode: '" . $unicode . "'}"); # start V8Js -$jscript = new V8Js('php', array(), array(), true, $snapshot); +$jscript = new V8Js('php', array(), true, $snapshot); # insert unicode via php var $jscript->unicode = $unicode; diff --git a/v8js_class.cc b/v8js_class.cc index 0f49c832..0ca181ce 100644 --- a/v8js_class.cc +++ b/v8js_class.cc @@ -59,17 +59,6 @@ static void v8js_script_free(v8js_script *res); int le_v8js_script; -/* {{{ Extension container */ -struct v8js_jsext { - zend_bool auto_enable; - HashTable *deps_ht; - const char **deps; - int deps_count; - zend_string *name; - zend_string *source; -}; -/* }}} */ - #ifdef USE_INTERNAL_ALLOCATOR class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator { public: @@ -247,73 +236,6 @@ static zend_object* v8js_new(zend_class_entry *ce) /* {{{ */ } /* }}} */ -static void v8js_free_ext_strarr(const char **arr, int count) /* {{{ */ -{ - int i; - - if (arr) { - for (i = 0; i < count; i++) { - if (arr[i]) { - free((void *) arr[i]); - } - } - free(arr); - } -} -/* }}} */ - -static void v8js_jsext_free_storage(v8js_jsext *jsext) /* {{{ */ -{ - if (jsext->deps_ht) { - zend_hash_destroy(jsext->deps_ht); - free(jsext->deps_ht); - } - if (jsext->deps) { - v8js_free_ext_strarr(jsext->deps, jsext->deps_count); - } - - // Free the persisted non-interned strings we allocated. - if (jsext->name) { - zend_string_release(jsext->name); - } - if (jsext->source) { - zend_string_release(jsext->source); - } - - free(jsext); -} -/* }}} */ - -static void v8js_jsext_dtor(zval *zv) /* {{{ */ -{ - v8js_jsext_free_storage(reinterpret_cast(Z_PTR_P(zv))); -} -/* }}} */ - -static int v8js_create_ext_strarr(const char ***retval, int count, HashTable *ht) /* {{{ */ -{ - const char **exts = NULL; - HashPosition pos; - zval *tmp; - int i = 0; - - exts = (const char **) calloc(1, count * sizeof(char *)); - zend_hash_internal_pointer_reset_ex(ht, &pos); - while ((tmp = zend_hash_get_current_data_ex(ht, &pos))) { - if (Z_TYPE_P(tmp) == IS_STRING) { - exts[i++] = zend_strndup(Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); - } else { - v8js_free_ext_strarr(exts, i); - return FAILURE; - } - zend_hash_move_forward_ex(ht, &pos); - } - *retval = exts; - - return SUCCESS; -} -/* }}} */ - static void v8js_fatal_error_handler(const char *location, const char *message) /* {{{ */ { if (location) { @@ -328,15 +250,13 @@ static void v8js_fatal_error_handler(const char *location, const char *message) ((ZSTR_LEN(key) == sizeof(mname) - 1) && \ !strncasecmp(ZSTR_VAL(key), mname, ZSTR_LEN(key))) -/* {{{ proto void V8Js::__construct([string object_name [, array variables [, array extensions [, bool report_uncaught_exceptions [, string snapshot_blob]]]]]) +/* {{{ proto void V8Js::__construct([string object_name [, array variables [, bool report_uncaught_exceptions [, string snapshot_blob]]]]) __construct for V8Js */ static PHP_METHOD(V8Js, __construct) { zend_string *object_name = NULL; zend_bool report_uncaught = 1; - zval *vars_arr = NULL, *exts_arr = NULL; - const char **exts = NULL; - int exts_count = 0; + zval *vars_arr = NULL; zval *snapshot_blob = NULL; v8js_ctx *c = Z_V8JS_CTX_OBJ_P(getThis()) @@ -346,7 +266,7 @@ static PHP_METHOD(V8Js, __construct) return; } - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S!aabz", &object_name, &vars_arr, &exts_arr, &report_uncaught, &snapshot_blob) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S!abz", &object_name, &vars_arr, &report_uncaught, &snapshot_blob) == FAILURE) { return; } @@ -401,26 +321,6 @@ static PHP_METHOD(V8Js, __construct) ZVAL_NULL(&c->module_normaliser); ZVAL_NULL(&c->module_loader); - /* Include extensions used by this context */ - /* Note: Extensions registered with auto_enable do not need to be added separately like this. */ - if (exts_arr) - { - exts_count = zend_hash_num_elements(Z_ARRVAL_P(exts_arr)); - - if (exts_count != 0) { - php_error_docref(NULL, E_DEPRECATED, "Use of extensions is deprecated, $extensions array passed"); - } - - if (v8js_create_ext_strarr(&exts, exts_count, Z_ARRVAL_P(exts_arr)) == FAILURE) { - zend_throw_exception(php_ce_v8js_exception, - "Invalid extensions array passed", 0); - return; - } - } - - /* Declare configuration for extensions */ - v8::ExtensionConfiguration extension_conf(exts_count, exts); - // Isolate execution v8::Isolate *isolate = c->isolate; v8::Locker locker(isolate); @@ -442,17 +342,10 @@ static PHP_METHOD(V8Js, __construct) v8js_register_methods(global_template, c); /* Create context */ - v8::Local context = v8::Context::New(isolate, &extension_conf, global_template); - - if (exts) { - v8js_free_ext_strarr(exts, exts_count); - } + v8::Local context = v8::Context::New(isolate, nullptr, global_template); - /* If extensions have errors, context will be empty. (NOTE: This is V8 stuff, they expect the passed sources to compile :) */ if (context.IsEmpty()) { - zend_throw_exception(php_ce_v8js_exception, - "Failed to create V8 context. " - "Check that registered extensions do not have errors.", 0); + zend_throw_exception(php_ce_v8js_exception, "Failed to create V8 context.", 0); return; } @@ -1006,140 +899,10 @@ static void v8js_script_dtor(zend_resource *rsrc) /* {{{ */ } /* }}} */ -static int v8js_register_extension(zend_string *name, zend_string *source, zval *deps_arr, zend_bool auto_enable) /* {{{ */ -{ - v8js_jsext *jsext = NULL; - -#ifdef ZTS - v8js_process_globals.lock.lock(); -#endif - - if (!v8js_process_globals.extensions) { - v8js_process_globals.extensions = (HashTable *) malloc(sizeof(HashTable)); - zend_hash_init(v8js_process_globals.extensions, 1, NULL, v8js_jsext_dtor, 1); - } else if (zend_hash_exists(v8js_process_globals.extensions, name)) { -#ifdef ZTS - v8js_process_globals.lock.unlock(); -#endif - return FAILURE; - } - - jsext = (v8js_jsext *) calloc(1, sizeof(v8js_jsext)); - - if (deps_arr) { - jsext->deps_count = zend_hash_num_elements(Z_ARRVAL_P(deps_arr)); - - if (v8js_create_ext_strarr(&jsext->deps, jsext->deps_count, Z_ARRVAL_P(deps_arr)) == FAILURE) { - php_error_docref(NULL, E_WARNING, "Invalid dependency array passed"); - v8js_jsext_free_storage(jsext); -#ifdef ZTS - v8js_process_globals.lock.unlock(); -#endif - return FAILURE; - } - } - - jsext->auto_enable = auto_enable; - // Allocate a persistent string which will survive until module shutdown on both ZTS(Persistent) and NTS(Not interned, those would be cleaned up) - // (zend_string_dup would return the original interned string, if interned, so we don't use that) - jsext->name = zend_string_init(ZSTR_VAL(name), ZSTR_LEN(name), 1); - jsext->source = zend_string_init(ZSTR_VAL(source), ZSTR_LEN(source), 1); - - if (jsext->deps) { - jsext->deps_ht = (HashTable *) malloc(sizeof(HashTable)); - zend_hash_init(jsext->deps_ht, jsext->deps_count, NULL, v8js_persistent_zval_dtor, 1); - zend_hash_copy(jsext->deps_ht, Z_ARRVAL_P(deps_arr), v8js_persistent_zval_ctor); - } - - v8::Extension *extension = new v8::Extension(ZSTR_VAL(jsext->name), ZSTR_VAL(jsext->source), jsext->deps_count, jsext->deps); - - if (!zend_hash_add_ptr(v8js_process_globals.extensions, jsext->name, jsext)) { - v8js_jsext_free_storage(jsext); -#ifdef ZTS - v8js_process_globals.lock.unlock(); -#endif - return FAILURE; - } - -#ifdef ZTS - v8js_process_globals.lock.unlock(); -#endif - - extension->set_auto_enable(auto_enable ? true : false); - v8::RegisterExtension(std::unique_ptr(extension)); - - return SUCCESS; -} -/* }}} */ - /* ## Static methods ## */ -/* {{{ proto bool V8Js::registerExtension(string ext_name, string script [, array deps [, bool auto_enable]]) - */ -static PHP_METHOD(V8Js, registerExtension) -{ - zend_string *ext_name, *script; - zval *deps_arr = NULL; - zend_bool auto_enable = 0; - - if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS|ab", &ext_name, &script, &deps_arr, &auto_enable) == FAILURE) { - return; - } - - if (!ZSTR_LEN(ext_name)) { - php_error_docref(NULL, E_WARNING, "Extension name cannot be empty"); - } else if (!ZSTR_LEN(script)) { - php_error_docref(NULL, E_WARNING, "Script cannot be empty"); - } else if (v8js_register_extension(ext_name, script, deps_arr, auto_enable) == SUCCESS) { - RETURN_TRUE; - } - RETURN_FALSE; -} -/* }}} */ - -/* {{{ proto array V8Js::getExtensions() - */ -static PHP_METHOD(V8Js, getExtensions) -{ - v8js_jsext *jsext; - zend_string *key; - zval *val, ext; - - if (zend_parse_parameters_none() == FAILURE) { - return; - } - - array_init(return_value); - -#ifdef ZTS - v8js_process_globals.lock.lock(); -#endif - - if (v8js_process_globals.extensions) { - ZEND_HASH_FOREACH_STR_KEY_VAL(v8js_process_globals.extensions, key, val) { - if (key) { - jsext = (v8js_jsext *) Z_PTR_P(val); - array_init(&ext); - add_assoc_bool_ex(&ext, ZEND_STRL("auto_enable"), jsext->auto_enable); - if (jsext->deps_ht) { - zval deps_arr; - array_init(&deps_arr); - zend_hash_copy(Z_ARRVAL_P(&deps_arr), jsext->deps_ht, (copy_ctor_func_t) zval_add_ref); - add_assoc_zval_ex(&ext, ZEND_STRL("deps"), &deps_arr); - } - add_assoc_zval_ex(return_value, ZSTR_VAL(key), ZSTR_LEN(key), &ext); - } - } ZEND_HASH_FOREACH_END(); - } - -#ifdef ZTS - v8js_process_globals.lock.unlock(); -#endif -} -/* }}} */ - static v8::StartupData createSnapshotDataBlob(v8::SnapshotCreator *snapshot_creator, zend_string *str) /* {{{ */ { v8::Isolate *isolate = snapshot_creator->GetIsolate(); @@ -1203,7 +966,6 @@ static PHP_METHOD(V8Js, createSnapshot) ZEND_BEGIN_ARG_INFO_EX(arginfo_v8js_construct, 0, 0, 0) ZEND_ARG_INFO(0, object_name) ZEND_ARG_INFO(0, variables) - ZEND_ARG_INFO(0, extensions) ZEND_ARG_INFO(0, report_uncaught_exceptions) ZEND_ARG_INFO(0, snapshot_blob) ZEND_END_ARG_INFO() @@ -1257,16 +1019,6 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_v8js_setaverageobjectsize, 0, 0, 1) ZEND_ARG_INFO(0, average_object_size) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_v8js_registerextension, 0, 0, 2) - ZEND_ARG_INFO(0, extension_name) - ZEND_ARG_INFO(0, script) - ZEND_ARG_INFO(0, dependencies) - ZEND_ARG_INFO(0, auto_enable) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_v8js_getextensions, 0) -ZEND_END_ARG_INFO() - ZEND_BEGIN_ARG_INFO_EX(arginfo_v8js_createsnapshot, 0, 0, 1) ZEND_ARG_INFO(0, script) ZEND_END_ARG_INFO() @@ -1295,8 +1047,6 @@ const zend_function_entry v8js_methods[] = { /* {{{ */ PHP_ME(V8Js, setTimeLimit, arginfo_v8js_settimelimit, ZEND_ACC_PUBLIC) PHP_ME(V8Js, setMemoryLimit, arginfo_v8js_setmemorylimit, ZEND_ACC_PUBLIC) PHP_ME(V8Js, setAverageObjectSize, arginfo_v8js_setaverageobjectsize, ZEND_ACC_PUBLIC) - PHP_ME(V8Js, registerExtension, arginfo_v8js_registerextension, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_DEPRECATED) - PHP_ME(V8Js, getExtensions, arginfo_v8js_getextensions, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_DEPRECATED) PHP_ME(V8Js, createSnapshot, arginfo_v8js_createsnapshot, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) {NULL, NULL, NULL} }; diff --git a/v8js_main.cc b/v8js_main.cc index 66b58ef1..43453404 100644 --- a/v8js_main.cc +++ b/v8js_main.cc @@ -172,12 +172,6 @@ static PHP_MSHUTDOWN_FUNCTION(v8js) v8js_process_globals.v8_flags = NULL; } - if (v8js_process_globals.extensions) { - zend_hash_destroy(v8js_process_globals.extensions); - free(v8js_process_globals.extensions); - v8js_process_globals.extensions = NULL; - } - return SUCCESS; } /* }}} */ From f6a93c3cd6942beb243a87053b40b9d6f1aa3aeb Mon Sep 17 00:00:00 2001 From: Stefan Siegl Date: Tue, 31 May 2022 09:53:09 +0200 Subject: [PATCH 2/3] Remove support for uncaught exceptions. Use try/catch. --- README.md | 6 +- tests/create_snapshot_basic.phpt | 2 +- tests/exception_clearing.phpt | 90 ----------------------- tests/exception_propagation_1.phpt | 37 ---------- tests/exception_propagation_2.phpt | 112 ----------------------------- tests/exception_propagation_3.phpt | 39 ---------- tests/issue_183_003.phpt | 2 - tests/unicode.phpt | 2 +- v8js_class.cc | 58 +-------------- v8js_class.h | 2 - v8js_v8.cc | 23 +----- 11 files changed, 9 insertions(+), 364 deletions(-) delete mode 100644 tests/exception_clearing.phpt delete mode 100644 tests/exception_propagation_1.phpt delete mode 100644 tests/exception_propagation_2.phpt delete mode 100644 tests/exception_propagation_3.phpt diff --git a/README.md b/README.md index 21fb08c6..fa30f9ab 100644 --- a/README.md +++ b/README.md @@ -78,10 +78,9 @@ class V8Js * Initializes and starts V8 engine and returns new V8Js object with it's own V8 context. * @param string $object_name * @param array $variables - * @param bool $report_uncaught_exceptions * @param string $snapshot_blob */ - public function __construct($object_name = "PHP", array $variables = [], $report_uncaught_exceptions = TRUE, $snapshot_blob = NULL) + public function __construct($object_name = "PHP", array $variables = [], $snapshot_blob = NULL) {} /** @@ -358,8 +357,7 @@ Exceptions ========== If the JavaScript code throws (without catching), causes errors or doesn't -compile, `V8JsScriptException` exceptions are thrown unless the `V8Js` object -is constructed with `report_uncaught_exceptions` set `FALSE`. +compile, `V8JsScriptException` exceptions are thrown. PHP exceptions that occur due to calls from JavaScript code by default are *not* re-thrown into JavaScript context but cause the JavaScript execution to diff --git a/tests/create_snapshot_basic.phpt b/tests/create_snapshot_basic.phpt index 56444493..0f75296a 100644 --- a/tests/create_snapshot_basic.phpt +++ b/tests/create_snapshot_basic.phpt @@ -22,7 +22,7 @@ if (strlen($snap) > 0) { var_dump("snapshot successfully created"); } -$v8 = new V8Js('PHP', array(), true, $snap); +$v8 = new V8Js('PHP', array(), $snap); $v8->executeString('var_dump(doublify(23));'); ?> ===EOF=== diff --git a/tests/exception_clearing.phpt b/tests/exception_clearing.phpt deleted file mode 100644 index c02d465f..00000000 --- a/tests/exception_clearing.phpt +++ /dev/null @@ -1,90 +0,0 @@ ---TEST-- -Test V8::executeString() : Exception clearing test ---SKIPIF-- - ---FILE-- -getPendingException()); - -$v8->clearPendingException(); -var_dump($v8->getPendingException()); - -$v8->executeString('fooobar', 'throw_0'); -var_dump($v8->getPendingException()); - -$v8->clearPendingException(); -var_dump($v8->getPendingException()); - -?> -===EOF=== ---EXPECTF-- -Deprecated: V8Js::__construct(): Disabling exception reporting is deprecated, $report_uncaught_exceptions != true in %s%eexception_clearing.php on line 3 - -Deprecated: %s V8Js::getPendingException() is deprecated in %s%eexception_clearing.php on line 5 -NULL - -Deprecated: %s V8Js::clearPendingException() is deprecated in %s%eexception_clearing.php on line 7 - -Deprecated: %s V8Js::getPendingException() is deprecated in %s%eexception_clearing.php on line 8 -NULL - -Deprecated: %s V8Js::getPendingException() is deprecated in %s%eexception_clearing.php on line 11 -object(V8JsScriptException)#%d (13) { - ["message":protected]=> - string(49) "throw_0:1: ReferenceError: fooobar is not defined" - ["string":"Exception":private]=> - string(0) "" - ["code":protected]=> - int(0) - ["file":protected]=> - string(%d) "%s" - ["line":protected]=> - int(10) - ["trace":"Exception":private]=> - array(1) { - [0]=> - array(6) { - ["file"]=> - string(%d) "%s" - ["line"]=> - int(10) - ["function"]=> - string(13) "executeString" - ["class"]=> - string(4) "V8Js" - ["type"]=> - string(2) "->" - ["args"]=> - array(2) { - [0]=> - string(7) "fooobar" - [1]=> - string(7) "throw_0" - } - } - } - ["previous":"Exception":private]=> - NULL - ["JsFileName":protected]=> - string(7) "throw_0" - ["JsLineNumber":protected]=> - int(1) - ["JsStartColumn":protected]=> - int(0) - ["JsEndColumn":protected]=> - int(1) - ["JsSourceLine":protected]=> - string(7) "fooobar" - ["JsTrace":protected]=> - string(57) "ReferenceError: fooobar is not defined - at throw_0:1:1" -} - -Deprecated: %s V8Js::clearPendingException() is deprecated in %s%eexception_clearing.php on line 13 - -Deprecated: %s V8Js::getPendingException() is deprecated in %s%eexception_clearing.php on line 14 -NULL -===EOF=== diff --git a/tests/exception_propagation_1.phpt b/tests/exception_propagation_1.phpt deleted file mode 100644 index cdc7f5f1..00000000 --- a/tests/exception_propagation_1.phpt +++ /dev/null @@ -1,37 +0,0 @@ ---TEST-- -Test V8::executeString() : Exception propagation test 1 ---SKIPIF-- - ---FILE-- -v8 = new V8Js(); - $this->v8->foo = $this; - $this->v8->executeString('fooobar', 'throw_0'); - var_dump($this->v8->getPendingException()); - $this->v8->executeString('try { PHP.foo.bar(); } catch (e) { print(e + " caught!\n"); }', 'trycatch1'); - $this->v8->executeString('try { PHP.foo.bar(); } catch (e) { print(e + " caught!\n"); }', 'trycatch2'); - } - - public function bar() - { - echo "To Bar!\n"; - $this->v8->executeString('throw new Error();', 'throw_1'); - } -} - -try { - $foo = new Foo(); -} catch (V8JsScriptException $e) { - echo "PHP Exception: ", $e->getMessage(), "\n"; //var_dump($e); -} -?> -===EOF=== ---EXPECTF-- -PHP Exception: throw_0:1: ReferenceError: fooobar is not defined -===EOF=== diff --git a/tests/exception_propagation_2.phpt b/tests/exception_propagation_2.phpt deleted file mode 100644 index ce88e6a9..00000000 --- a/tests/exception_propagation_2.phpt +++ /dev/null @@ -1,112 +0,0 @@ ---TEST-- -Test V8::executeString() : Exception propagation test 2 ---SKIPIF-- - ---FILE-- -v8 = new V8Js(null, array(), false); - $this->v8->foo = $this; - $this->v8->executeString('fooobar', 'throw_0'); - var_dump($this->v8->getPendingException()); - // the exception is not cleared before the next executeString call, - // hence the next *exiting* executeString will throw. - // In this case this is the executeString call in bar() function. - $this->v8->executeString('try { PHP.foo.bar(); } catch (e) { print(e + " caught!\n"); }', 'trycatch1'); - $this->v8->executeString('try { PHP.foo.bar(); } catch (e) { print(e + " caught!\n"); }', 'trycatch2'); - } - - public function bar() - { - echo "To Bar!\n"; - // This executeString call throws a PHP exception, not propagated - // to JS, hence immediately triggering the top-level catch handler. - $this->v8->executeString('throw new Error();', 'throw_1'); - } -} - -try { - $foo = new Foo(); -} catch (V8JsScriptException $e) { - echo "PHP Exception: ", $e->getMessage(), "\n"; //var_dump($e); -} -?> -===EOF=== ---EXPECTF-- -Deprecated: V8Js::__construct(): Disabling exception reporting is deprecated, $report_uncaught_exceptions != true in %s%eexception_propagation_2.php on line 8 - -Deprecated: %s V8Js::getPendingException() is deprecated in %s%eexception_propagation_2.php on line 11 -object(V8JsScriptException)#%d (13) { - ["message":protected]=> - string(49) "throw_0:1: ReferenceError: fooobar is not defined" - ["string":"Exception":private]=> - string(0) "" - ["code":protected]=> - int(0) - ["file":protected]=> - string(%d) "%s" - ["line":protected]=> - int(10) - ["trace":"Exception":private]=> - array(2) { - [0]=> - array(6) { - ["file"]=> - string(%d) "%s" - ["line"]=> - int(10) - ["function"]=> - string(13) "executeString" - ["class"]=> - string(4) "V8Js" - ["type"]=> - string(2) "->" - ["args"]=> - array(2) { - [0]=> - string(7) "fooobar" - [1]=> - string(7) "throw_0" - } - } - [1]=> - array(6) { - ["file"]=> - string(%d) "%s" - ["line"]=> - int(29) - ["function"]=> - string(11) "__construct" - ["class"]=> - string(3) "Foo" - ["type"]=> - string(2) "->" - ["args"]=> - array(0) { - } - } - } - ["previous":"Exception":private]=> - NULL - ["JsFileName":protected]=> - string(7) "throw_0" - ["JsLineNumber":protected]=> - int(1) - ["JsStartColumn":protected]=> - int(0) - ["JsEndColumn":protected]=> - int(1) - ["JsSourceLine":protected]=> - string(7) "fooobar" - ["JsTrace":protected]=> - string(57) "ReferenceError: fooobar is not defined - at throw_0:1:1" -} -To Bar! -PHP Exception: throw_0:1: ReferenceError: fooobar is not defined -===EOF=== diff --git a/tests/exception_propagation_3.phpt b/tests/exception_propagation_3.phpt deleted file mode 100644 index af7de8ce..00000000 --- a/tests/exception_propagation_3.phpt +++ /dev/null @@ -1,39 +0,0 @@ ---TEST-- -Test V8::executeString() : Exception propagation test 3 ---SKIPIF-- - ---FILE-- -v8 = new V8Js(null, 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'); - $this->v8->executeString('try { PHP.foo.bar(); } catch (e) { print(e + " caught via PHP callback!\n"); }', 'trycatch2'); - } - - public function bar() - { - echo "To Bar!\n"; - $this->v8->executeString('throw new Error();', 'throw_2'); - } -} - -try { - $foo = new Foo(); -} catch (V8JsScriptException $e) { - echo "PHP Exception: ", $e->getMessage(), "\n"; -} -?> -===EOF=== ---EXPECTF-- -Deprecated: V8Js::__construct(): Disabling exception reporting is deprecated, $report_uncaught_exceptions != true in %s%eexception_propagation_3.php on line 8 -SyntaxError caught in JS! -To Bar! -Error caught via PHP callback! -===EOF=== diff --git a/tests/issue_183_003.phpt b/tests/issue_183_003.phpt index 1a96c3f3..3b92b423 100644 --- a/tests/issue_183_003.phpt +++ b/tests/issue_183_003.phpt @@ -19,7 +19,6 @@ var_dump(typeof PHP.executeString); var_dump(typeof PHP.compileString); var_dump(typeof PHP.executeScript); var_dump(typeof PHP.checkString); -var_dump(typeof PHP.getPendingException); var_dump(typeof PHP.setModuleNormaliser); var_dump(typeof PHP.setModuleLoader); var_dump(typeof PHP.registerExtension); @@ -52,6 +51,5 @@ string(9) "undefined" string(9) "undefined" string(9) "undefined" string(9) "undefined" -string(9) "undefined" string(6) "caught" ===EOF=== diff --git a/tests/unicode.phpt b/tests/unicode.phpt index 0bbfa704..648ed041 100644 --- a/tests/unicode.phpt +++ b/tests/unicode.phpt @@ -12,7 +12,7 @@ $unicode = 'äöüßÜÄÖÜ߀áàâÁÀµ²³▁▂▃▄▅▆▇█ $snapshot = V8Js::createSnapshot("var snapshot = {unicode: '" . $unicode . "'}"); # start V8Js -$jscript = new V8Js('php', array(), true, $snapshot); +$jscript = new V8Js('php', array(), $snapshot); # insert unicode via php var $jscript->unicode = $unicode; diff --git a/v8js_class.cc b/v8js_class.cc index 0ca181ce..badbe117 100644 --- a/v8js_class.cc +++ b/v8js_class.cc @@ -78,7 +78,6 @@ static void v8js_free_storage(zend_object *object) /* {{{ */ zend_object_std_dtor(&c->std); - zval_ptr_dtor(&c->pending_exception); zval_ptr_dtor(&c->module_normaliser); zval_ptr_dtor(&c->module_loader); @@ -250,12 +249,11 @@ static void v8js_fatal_error_handler(const char *location, const char *message) ((ZSTR_LEN(key) == sizeof(mname) - 1) && \ !strncasecmp(ZSTR_VAL(key), mname, ZSTR_LEN(key))) -/* {{{ proto void V8Js::__construct([string object_name [, array variables [, bool report_uncaught_exceptions [, string snapshot_blob]]]]) +/* {{{ proto void V8Js::__construct([string object_name [, array variables [, string snapshot_blob]]]) __construct for V8Js */ static PHP_METHOD(V8Js, __construct) { zend_string *object_name = NULL; - zend_bool report_uncaught = 1; zval *vars_arr = NULL; zval *snapshot_blob = NULL; @@ -266,7 +264,7 @@ static PHP_METHOD(V8Js, __construct) return; } - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S!abz", &object_name, &vars_arr, &report_uncaught, &snapshot_blob) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S!az", &object_name, &vars_arr, &snapshot_blob) == FAILURE) { return; } @@ -274,14 +272,8 @@ static PHP_METHOD(V8Js, __construct) v8js_v8_init(); /* Throw PHP exception if uncaught exceptions exist */ - c->report_uncaught = report_uncaught; - ZVAL_NULL(&c->pending_exception); c->in_execution = 0; - if (report_uncaught != 1) { - php_error_docref(NULL, E_DEPRECATED, "Disabling exception reporting is deprecated, $report_uncaught_exceptions != true"); - } - new (&c->create_params) v8::Isolate::CreateParams(); #ifdef USE_INTERNAL_ALLOCATOR @@ -703,43 +695,6 @@ static PHP_METHOD(V8Js, checkString) } /* }}} */ -/* {{{ proto mixed V8Js::getPendingException() - */ -static PHP_METHOD(V8Js, getPendingException) -{ - v8js_ctx *c; - - if (zend_parse_parameters_none() == FAILURE) { - return; - } - - c = Z_V8JS_CTX_OBJ_P(getThis()); - - if (Z_TYPE(c->pending_exception) == IS_OBJECT) { - RETURN_ZVAL(&c->pending_exception, 1, 0); - } -} -/* }}} */ - -/* {{{ proto void V8Js::clearPendingException() - */ -static PHP_METHOD(V8Js, clearPendingException) -{ - v8js_ctx *c; - - if (zend_parse_parameters_none() == FAILURE) { - return; - } - - c = Z_V8JS_CTX_OBJ_P(getThis()); - - if (Z_TYPE(c->pending_exception) == IS_OBJECT) { - zval_ptr_dtor(&c->pending_exception); - ZVAL_NULL(&c->pending_exception); - } -} -/* }}} */ - /* {{{ proto void V8Js::setModuleNormaliser(string base, string module_id) */ static PHP_METHOD(V8Js, setModuleNormaliser) @@ -966,7 +921,6 @@ static PHP_METHOD(V8Js, createSnapshot) ZEND_BEGIN_ARG_INFO_EX(arginfo_v8js_construct, 0, 0, 0) ZEND_ARG_INFO(0, object_name) ZEND_ARG_INFO(0, variables) - ZEND_ARG_INFO(0, report_uncaught_exceptions) ZEND_ARG_INFO(0, snapshot_blob) ZEND_END_ARG_INFO() @@ -1000,12 +954,6 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_v8js_checkstring, 0, 0, 1) ZEND_ARG_INFO(0, script) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_v8js_getpendingexception, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_v8js_clearpendingexception, 0) -ZEND_END_ARG_INFO() - ZEND_BEGIN_ARG_INFO_EX(arginfo_v8js_setmodulenormaliser, 0, 0, 2) ZEND_ARG_INFO(0, base) ZEND_ARG_INFO(0, module_id) @@ -1040,8 +988,6 @@ const zend_function_entry v8js_methods[] = { /* {{{ */ PHP_ME(V8Js, compileString, arginfo_v8js_compilestring, ZEND_ACC_PUBLIC) PHP_ME(V8Js, executeScript, arginfo_v8js_executescript, ZEND_ACC_PUBLIC) PHP_ME(V8Js, checkString, arginfo_v8js_checkstring, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED) - PHP_ME(V8Js, getPendingException, arginfo_v8js_getpendingexception, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED) - PHP_ME(V8Js, clearPendingException, arginfo_v8js_clearpendingexception, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED) PHP_ME(V8Js, setModuleNormaliser, arginfo_v8js_setmodulenormaliser, ZEND_ACC_PUBLIC) PHP_ME(V8Js, setModuleLoader, arginfo_v8js_setmoduleloader, ZEND_ACC_PUBLIC) PHP_ME(V8Js, setTimeLimit, arginfo_v8js_settimelimit, ZEND_ACC_PUBLIC) diff --git a/v8js_class.h b/v8js_class.h index 3277573f..e5caeb1c 100644 --- a/v8js_class.h +++ b/v8js_class.h @@ -37,8 +37,6 @@ struct cmp_str { struct v8js_ctx { v8::Persistent object_name; v8::Persistent context; - zend_bool report_uncaught; - zval pending_exception; int in_execution; v8::Isolate *isolate; diff --git a/v8js_v8.cc b/v8js_v8.cc index 8d8f99a6..32444002 100644 --- a/v8js_v8.cc +++ b/v8js_v8.cc @@ -224,31 +224,14 @@ void v8js_v8_call(v8js_ctx *c, zval **return_value, return; } - /* There was pending exception left from earlier executions -> throw to PHP */ - if (Z_TYPE(c->pending_exception) == IS_OBJECT) { - zend_throw_exception_object(&c->pending_exception); - ZVAL_NULL(&c->pending_exception); - } - /* Handle runtime JS exceptions */ if (try_catch.HasCaught()) { /* Pending exceptions are set only in outer caller, inner caller exceptions are always rethrown */ if (c->in_execution < 1) { - - /* Report immediately if report_uncaught is true */ - if (c->report_uncaught) { - v8js_throw_script_exception(c->isolate, &try_catch); - zval_ptr_dtor(&zv_v8inst); - return; - } - - /* Exception thrown from JS, preserve it for future execution */ - if (result.IsEmpty()) { - v8js_create_script_exception(&c->pending_exception, c->isolate, &try_catch); - zval_ptr_dtor(&zv_v8inst); - return; - } + v8js_throw_script_exception(c->isolate, &try_catch); + zval_ptr_dtor(&zv_v8inst); + return; } /* Rethrow back to JS */ From bfd2bfc2df167dcf2f2e1b94a0add57766441dda Mon Sep 17 00:00:00 2001 From: Stefan Siegl Date: Tue, 31 May 2022 09:57:52 +0200 Subject: [PATCH 3/3] remove deprected V8Js::checkString function --- tests/checkstring.phpt | 24 ------------------------ v8js_class.cc | 27 --------------------------- 2 files changed, 51 deletions(-) delete mode 100644 tests/checkstring.phpt diff --git a/tests/checkstring.phpt b/tests/checkstring.phpt deleted file mode 100644 index dc2ff5b0..00000000 --- a/tests/checkstring.phpt +++ /dev/null @@ -1,24 +0,0 @@ ---TEST-- -Test V8::executeString() : Script validator test ---SKIPIF-- - ---FILE-- -checkString('print("Hello World!");')); - -try { - var_dump($v8->checkString('print("Hello World!);')); -} catch (V8JsScriptException $e) { - var_dump($e->getMessage()); -} -?> -===EOF=== ---EXPECTF-- -Deprecated: %s V8Js::checkString() is deprecated in %s on line %d -bool(true) - -Deprecated: %s V8Js::checkString() is deprecated in %s on line %d -string(%d) "V8Js::checkString():1: SyntaxError: %s" -===EOF=== diff --git a/v8js_class.cc b/v8js_class.cc index badbe117..6fdfa07c 100644 --- a/v8js_class.cc +++ b/v8js_class.cc @@ -669,32 +669,6 @@ static PHP_METHOD(V8Js, executeScript) } /* }}} */ -/* {{{ proto mixed V8Js::checkString(string script) - */ -static PHP_METHOD(V8Js, checkString) -{ - zend_string *str = NULL; - zend_string *identifier = zend_string_init("V8Js::checkString()", 19, 0); - - v8js_script *res = NULL; - - if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &str) == FAILURE) { - return; - } - - v8js_compile_script(getThis(), str, identifier, &res); - zend_string_release(identifier); - - if (!res) { - RETURN_FALSE; - } - - v8js_script_free(res); - efree(res); - RETURN_TRUE; -} -/* }}} */ - /* {{{ proto void V8Js::setModuleNormaliser(string base, string module_id) */ static PHP_METHOD(V8Js, setModuleNormaliser) @@ -987,7 +961,6 @@ const zend_function_entry v8js_methods[] = { /* {{{ */ PHP_ME(V8Js, executeString, arginfo_v8js_executestring, ZEND_ACC_PUBLIC) PHP_ME(V8Js, compileString, arginfo_v8js_compilestring, ZEND_ACC_PUBLIC) PHP_ME(V8Js, executeScript, arginfo_v8js_executescript, ZEND_ACC_PUBLIC) - PHP_ME(V8Js, checkString, arginfo_v8js_checkstring, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED) PHP_ME(V8Js, setModuleNormaliser, arginfo_v8js_setmodulenormaliser, ZEND_ACC_PUBLIC) PHP_ME(V8Js, setModuleLoader, arginfo_v8js_setmoduleloader, ZEND_ACC_PUBLIC) PHP_ME(V8Js, setTimeLimit, arginfo_v8js_settimelimit, ZEND_ACC_PUBLIC)