0
0
mirror of https://github.com/phpv8/v8js.git synced 2024-12-22 09:21:52 +00:00

Improve PHP->JS->PHP exception back propagation

This commit is contained in:
Stefan Siegl 2015-08-23 15:09:21 +02:00
parent 462eb623b3
commit f7c33539c2
5 changed files with 63 additions and 12 deletions

View File

@ -0,0 +1,36 @@
--TEST--
Test V8::executeString() : PHP Exception handling (PHP->JS->PHP back propagation)
--SKIPIF--
<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
--FILE--
<?php
class Foo {
function throwException() {
throw new \Exception("Test-Exception");
}
}
$v8 = new V8Js();
$v8->foo = new \Foo();
$JS = <<< EOT
PHP.foo.throwException();
// the exception should abort further execution,
// hence the print must not pop up
print("after throwException\\n");
EOT;
try {
$v8->executeString($JS, 'php_exceptions_004', V8Js::FLAG_PROPAGATE_PHP_EXCEPTIONS);
}
catch(V8JsScriptException $e) {
echo "Got V8JsScriptException\n";
var_dump($e->getPrevious()->getMessage());
}
?>
===EOF===
--EXPECTF--
Got V8JsScriptException
string(14) "Test-Exception"
===EOF===

View File

@ -2,12 +2,13 @@
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| PHP Version 5 | | PHP Version 5 |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| Copyright (c) 1997-2013 The PHP Group | | Copyright (c) 1997-2015 The PHP Group |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| http://www.opensource.org/licenses/mit-license.php MIT License | | http://www.opensource.org/licenses/mit-license.php MIT License |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| Author: Jani Taskinen <jani.taskinen@iki.fi> | | Author: Jani Taskinen <jani.taskinen@iki.fi> |
| Author: Patrick Reilly <preilly@php.net> | | Author: Patrick Reilly <preilly@php.net> |
| Author: Stefan Siegl <stesie@php.net> |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
*/ */
@ -498,7 +499,7 @@ static void v8js_compile_script(zval *this_ptr, const char *str, int str_len, co
/* Compile errors? */ /* Compile errors? */
if (script.IsEmpty()) { if (script.IsEmpty()) {
v8js_throw_script_exception(&try_catch TSRMLS_CC); v8js_throw_script_exception(c->isolate, &try_catch TSRMLS_CC);
return; return;
} }
res = (v8js_script *)emalloc(sizeof(v8js_script)); res = (v8js_script *)emalloc(sizeof(v8js_script));

View File

@ -2,12 +2,13 @@
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| PHP Version 5 | | PHP Version 5 |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| Copyright (c) 1997-2013 The PHP Group | | Copyright (c) 1997-2015 The PHP Group |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| http://www.opensource.org/licenses/mit-license.php MIT License | | http://www.opensource.org/licenses/mit-license.php MIT License |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| Author: Jani Taskinen <jani.taskinen@iki.fi> | | Author: Jani Taskinen <jani.taskinen@iki.fi> |
| Author: Patrick Reilly <preilly@php.net> | | Author: Patrick Reilly <preilly@php.net> |
| Author: Stefan Siegl <stesie@php.net> |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
*/ */
@ -38,7 +39,7 @@ zend_class_entry *php_ce_v8js_memory_limit_exception;
/* {{{ Class: V8JsScriptException */ /* {{{ Class: V8JsScriptException */
void v8js_create_script_exception(zval *return_value, v8::TryCatch *try_catch TSRMLS_DC) /* {{{ */ void v8js_create_script_exception(zval *return_value, v8::Isolate *isolate, v8::TryCatch *try_catch TSRMLS_DC) /* {{{ */
{ {
v8::String::Utf8Value exception(try_catch->Exception()); v8::String::Utf8Value exception(try_catch->Exception());
const char *exception_string = ToCString(exception); const char *exception_string = ToCString(exception);
@ -81,6 +82,17 @@ void v8js_create_script_exception(zval *return_value, v8::TryCatch *try_catch TS
const char* stacktrace_string = ToCString(stacktrace); const char* stacktrace_string = ToCString(stacktrace);
PHPV8_EXPROP(_string, JsTrace, stacktrace_string); PHPV8_EXPROP(_string, JsTrace, stacktrace_string);
} }
if(try_catch->Exception()->IsObject()) {
v8::Local<v8::Value> php_ref = try_catch->Exception()->ToObject()->GetHiddenValue(V8JS_SYM(PHPJS_OBJECT_KEY));
if(!php_ref.IsEmpty()) {
assert(php_ref->IsExternal());
zval *php_exception = reinterpret_cast<zval *>(v8::External::Cast(*php_ref)->Value());
zend_exception_set_previous(return_value, php_exception TSRMLS_CC);
}
}
} }
PHPV8_EXPROP(_string, message, message_string); PHPV8_EXPROP(_string, message, message_string);
@ -89,7 +101,7 @@ void v8js_create_script_exception(zval *return_value, v8::TryCatch *try_catch TS
} }
/* }}} */ /* }}} */
void v8js_throw_script_exception(v8::TryCatch *try_catch TSRMLS_DC) /* {{{ */ void v8js_throw_script_exception(v8::Isolate *isolate, v8::TryCatch *try_catch TSRMLS_DC) /* {{{ */
{ {
v8::String::Utf8Value exception(try_catch->Exception()); v8::String::Utf8Value exception(try_catch->Exception());
const char *exception_string = ToCString(exception); const char *exception_string = ToCString(exception);
@ -99,7 +111,7 @@ void v8js_throw_script_exception(v8::TryCatch *try_catch TSRMLS_DC) /* {{{ */
zend_throw_exception(php_ce_v8js_script_exception, (char *) exception_string, 0 TSRMLS_CC); zend_throw_exception(php_ce_v8js_script_exception, (char *) exception_string, 0 TSRMLS_CC);
} else { } else {
MAKE_STD_ZVAL(zexception); MAKE_STD_ZVAL(zexception);
v8js_create_script_exception(zexception, try_catch TSRMLS_CC); v8js_create_script_exception(zexception, isolate, try_catch TSRMLS_CC);
zend_throw_exception_object(zexception TSRMLS_CC); zend_throw_exception_object(zexception TSRMLS_CC);
} }
} }

View File

@ -2,12 +2,13 @@
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| PHP Version 5 | | PHP Version 5 |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| Copyright (c) 1997-2013 The PHP Group | | Copyright (c) 1997-2015 The PHP Group |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| http://www.opensource.org/licenses/mit-license.php MIT License | | http://www.opensource.org/licenses/mit-license.php MIT License |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| Author: Jani Taskinen <jani.taskinen@iki.fi> | | Author: Jani Taskinen <jani.taskinen@iki.fi> |
| Author: Patrick Reilly <preilly@php.net> | | Author: Patrick Reilly <preilly@php.net> |
| Author: Stefan Siegl <stesie@php.net> |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
*/ */
@ -19,8 +20,8 @@ extern zend_class_entry *php_ce_v8js_script_exception;
extern zend_class_entry *php_ce_v8js_time_limit_exception; extern zend_class_entry *php_ce_v8js_time_limit_exception;
extern zend_class_entry *php_ce_v8js_memory_limit_exception; extern zend_class_entry *php_ce_v8js_memory_limit_exception;
void v8js_create_script_exception(zval *return_value, v8::TryCatch *try_catch TSRMLS_DC); void v8js_create_script_exception(zval *return_value, v8::Isolate *isolate, v8::TryCatch *try_catch TSRMLS_DC);
void v8js_throw_script_exception(v8::TryCatch *try_catch TSRMLS_DC); void v8js_throw_script_exception(v8::Isolate *isolate, v8::TryCatch *try_catch TSRMLS_DC);
PHP_MINIT_FUNCTION(v8js_exceptions); PHP_MINIT_FUNCTION(v8js_exceptions);

View File

@ -2,12 +2,13 @@
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| PHP Version 5 | | PHP Version 5 |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| Copyright (c) 1997-2013 The PHP Group | | Copyright (c) 1997-2015 The PHP Group |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| http://www.opensource.org/licenses/mit-license.php MIT License | | http://www.opensource.org/licenses/mit-license.php MIT License |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| Author: Jani Taskinen <jani.taskinen@iki.fi> | | Author: Jani Taskinen <jani.taskinen@iki.fi> |
| Author: Patrick Reilly <preilly@php.net> | | Author: Patrick Reilly <preilly@php.net> |
| Author: Stefan Siegl <stesie@php.net> |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
*/ */
@ -175,14 +176,14 @@ void v8js_v8_call(v8js_ctx *c, zval **return_value,
/* Report immediately if report_uncaught is true */ /* Report immediately if report_uncaught is true */
if (c->report_uncaught) { if (c->report_uncaught) {
v8js_throw_script_exception(&try_catch TSRMLS_CC); v8js_throw_script_exception(c->isolate, &try_catch TSRMLS_CC);
return; return;
} }
/* Exception thrown from JS, preserve it for future execution */ /* Exception thrown from JS, preserve it for future execution */
if (result.IsEmpty()) { if (result.IsEmpty()) {
MAKE_STD_ZVAL(c->pending_exception); MAKE_STD_ZVAL(c->pending_exception);
v8js_create_script_exception(c->pending_exception, &try_catch TSRMLS_CC); v8js_create_script_exception(c->pending_exception, c->isolate, &try_catch TSRMLS_CC);
return; return;
} }
} }