From 7dcebdd9275a1983af65b033ec0520852429e18f Mon Sep 17 00:00:00 2001 From: Stefan Siegl Date: Sun, 3 Jul 2016 22:52:50 +0200 Subject: [PATCH 1/2] forward exceptions thrown in module loader --- tests/commonjs_exception_001.phpt | 35 +++++++++++++++++++++++++++++++ v8js_methods.cc | 12 ++++++++--- 2 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 tests/commonjs_exception_001.phpt diff --git a/tests/commonjs_exception_001.phpt b/tests/commonjs_exception_001.phpt new file mode 100644 index 0000000..4f6a6d7 --- /dev/null +++ b/tests/commonjs_exception_001.phpt @@ -0,0 +1,35 @@ +--TEST-- +Test V8Js::setModuleLoader : Forward exceptions +--SKIPIF-- + +--FILE-- +setModuleLoader(function($module) { + throw new Exception('some exception'); +}); + +$v8->executeString($JS, 'module.js', V8Js::FLAG_PROPAGATE_PHP_EXCEPTIONS); +?> +===EOF=== +--EXPECTF-- +Fatal error: Uncaught Exception: some exception in %s%ecommonjs_exception_001.php:9 +Stack trace: +#0 [internal function]: {closure}('test') +#1 %s%ecommonjs_exception_001.php(12): V8Js->executeString('var foo = requi...', 'module.js', 4) +#2 {main} + +Next V8JsScriptException: module.js:1: Exception: some exception in %s%ecommonjs_exception_001.php:9 +Stack trace: +#0 [internal function]: {closure}('test') +#1 %s%ecommonjs_exception_001.php(12): V8Js->executeString('var foo = requi...', 'module.js', 4) +#2 {main} in %s%ecommonjs_exception_001.php:12 +Stack trace: +#0 %s%ecommonjs_exception_001.php(12): V8Js->executeString('var foo = requi...', 'module.js', 4) +#1 {main} + thrown in %s%ecommonjs_exception_001.php on line 12 diff --git a/v8js_methods.cc b/v8js_methods.cc index 4365a87..8996b6c 100644 --- a/v8js_methods.cc +++ b/v8js_methods.cc @@ -390,9 +390,15 @@ V8JS_METHOD(require) efree(normalised_module_id); efree(normalised_path); - // Clear the PHP exception and throw it in V8 instead - zend_clear_exception(TSRMLS_C); - info.GetReturnValue().Set(isolate->ThrowException(V8JS_SYM("Module loader callback exception"))); + if (c->flags & V8JS_FLAG_PROPAGATE_PHP_EXCEPTIONS) { + zval tmp_zv; + ZVAL_OBJ(&tmp_zv, EG(exception)); + info.GetReturnValue().Set(isolate->ThrowException(zval_to_v8js(&tmp_zv, isolate))); + zend_clear_exception(); + } else { + v8js_terminate_execution(isolate); + } + return; } From 9fd201eb16af6720f3a295c3cb3ce1f1773000c5 Mon Sep 17 00:00:00 2001 From: Stefan Siegl Date: Sun, 3 Jul 2016 22:57:11 +0200 Subject: [PATCH 2/2] forward exceptions thrown in module normaliser --- tests/commonjs_exception_002.phpt | 38 +++++++++++++++++++++++++++++++ v8js_methods.cc | 11 ++++++--- 2 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 tests/commonjs_exception_002.phpt diff --git a/tests/commonjs_exception_002.phpt b/tests/commonjs_exception_002.phpt new file mode 100644 index 0000000..34dd856 --- /dev/null +++ b/tests/commonjs_exception_002.phpt @@ -0,0 +1,38 @@ +--TEST-- +Test V8Js::setModuleNormaliser : Forward exceptions +--SKIPIF-- + +--FILE-- +setModuleNormaliser(function($module) { + throw new Exception('some exception'); +}); +$v8->setModuleLoader(function($module) { + echo 'dummy ...'; +}); + +$v8->executeString($JS, 'module.js', V8Js::FLAG_PROPAGATE_PHP_EXCEPTIONS); +?> +===EOF=== +--EXPECTF-- +Fatal error: Uncaught Exception: some exception in %s%ecommonjs_exception_002.php:9 +Stack trace: +#0 [internal function]: {closure}('', './test') +#1 %s%ecommonjs_exception_002.php(15): V8Js->executeString('var foo = requi...', 'module.js', 4) +#2 {main} + +Next V8JsScriptException: module.js:1: Exception: some exception in %s%ecommonjs_exception_002.php:9 +Stack trace: +#0 [internal function]: {closure}('', './test') +#1 %s%ecommonjs_exception_002.php(15): V8Js->executeString('var foo = requi...', 'module.js', 4) +#2 {main} in %s%ecommonjs_exception_002.php:15 +Stack trace: +#0 %s%ecommonjs_exception_002.php(15): V8Js->executeString('var foo = requi...', 'module.js', 4) +#1 {main} + thrown in %s%ecommonjs_exception_002.php on line 15 diff --git a/v8js_methods.cc b/v8js_methods.cc index 8996b6c..c435807 100644 --- a/v8js_methods.cc +++ b/v8js_methods.cc @@ -268,9 +268,14 @@ V8JS_METHOD(require) // Check if an exception was thrown if (EG(exception)) { - // Clear the PHP exception and throw it in V8 instead - zend_clear_exception(TSRMLS_C); - info.GetReturnValue().Set(isolate->ThrowException(V8JS_SYM("Module normaliser callback exception"))); + if (c->flags & V8JS_FLAG_PROPAGATE_PHP_EXCEPTIONS) { + zval tmp_zv; + ZVAL_OBJ(&tmp_zv, EG(exception)); + info.GetReturnValue().Set(isolate->ThrowException(zval_to_v8js(&tmp_zv, isolate))); + zend_clear_exception(); + } else { + v8js_terminate_execution(isolate); + } return; }