mirror of
https://github.com/phpv8/v8js.git
synced 2024-12-22 10:31:53 +00:00
Remove support for uncaught exceptions. Use try/catch.
This commit is contained in:
parent
fa4babb307
commit
f6a93c3cd6
@ -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
|
||||
|
@ -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===
|
||||
|
@ -1,90 +0,0 @@
|
||||
--TEST--
|
||||
Test V8::executeString() : Exception clearing test
|
||||
--SKIPIF--
|
||||
<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$v8 = new V8Js(null, array(), false);
|
||||
|
||||
var_dump($v8->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===
|
@ -1,37 +0,0 @@
|
||||
--TEST--
|
||||
Test V8::executeString() : Exception propagation test 1
|
||||
--SKIPIF--
|
||||
<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Foo {
|
||||
private $v8 = NULL;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->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===
|
@ -1,112 +0,0 @@
|
||||
--TEST--
|
||||
Test V8::executeString() : Exception propagation test 2
|
||||
--SKIPIF--
|
||||
<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Foo {
|
||||
private $v8 = NULL;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->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===
|
@ -1,39 +0,0 @@
|
||||
--TEST--
|
||||
Test V8::executeString() : Exception propagation test 3
|
||||
--SKIPIF--
|
||||
<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Foo {
|
||||
private $v8 = NULL;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$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');
|
||||
$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===
|
@ -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===
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -37,8 +37,6 @@ struct cmp_str {
|
||||
struct v8js_ctx {
|
||||
v8::Persistent<v8::String> object_name;
|
||||
v8::Persistent<v8::Context> context;
|
||||
zend_bool report_uncaught;
|
||||
zval pending_exception;
|
||||
int in_execution;
|
||||
v8::Isolate *isolate;
|
||||
|
||||
|
17
v8js_v8.cc
17
v8js_v8.cc
@ -224,33 +224,16 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
/* Rethrow back to JS */
|
||||
try_catch.ReThrow();
|
||||
zval_ptr_dtor(&zv_v8inst);
|
||||
|
Loading…
Reference in New Issue
Block a user