mirror of
https://github.com/phpv8/v8js.git
synced 2024-12-22 15:11:53 +00:00
Allow PHP exception to JS propagation
This commit is contained in:
parent
f7a592052f
commit
462eb623b3
@ -83,6 +83,7 @@ extern "C" {
|
|||||||
/* Options */
|
/* Options */
|
||||||
#define V8JS_FLAG_NONE (1<<0)
|
#define V8JS_FLAG_NONE (1<<0)
|
||||||
#define V8JS_FLAG_FORCE_ARRAY (1<<1)
|
#define V8JS_FLAG_FORCE_ARRAY (1<<1)
|
||||||
|
#define V8JS_FLAG_PROPAGATE_PHP_EXCEPTIONS (1<<2)
|
||||||
|
|
||||||
#define V8JS_DEBUG_AUTO_BREAK_NEVER 0
|
#define V8JS_DEBUG_AUTO_BREAK_NEVER 0
|
||||||
#define V8JS_DEBUG_AUTO_BREAK_ONCE 1
|
#define V8JS_DEBUG_AUTO_BREAK_ONCE 1
|
||||||
|
36
tests/php_exceptions_003.phpt
Normal file
36
tests/php_exceptions_003.phpt
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
--TEST--
|
||||||
|
Test V8::executeString() : PHP Exception handling (basic JS 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
|
||||||
|
try {
|
||||||
|
PHP.foo.throwException();
|
||||||
|
// the exception should abort further execution,
|
||||||
|
// hence the print must not pop up
|
||||||
|
print("after throwException\\n");
|
||||||
|
} catch(e) {
|
||||||
|
print("JS caught exception!\\n");
|
||||||
|
var_dump(e.getMessage());
|
||||||
|
}
|
||||||
|
EOT;
|
||||||
|
|
||||||
|
$v8->executeString($JS, 'php_exceptions_003', V8Js::FLAG_PROPAGATE_PHP_EXCEPTIONS);
|
||||||
|
|
||||||
|
?>
|
||||||
|
===EOF===
|
||||||
|
--EXPECTF--
|
||||||
|
JS caught exception!
|
||||||
|
string(14) "Test-Exception"
|
||||||
|
===EOF===
|
@ -1078,6 +1078,7 @@ PHP_MINIT_FUNCTION(v8js_class) /* {{{ */
|
|||||||
|
|
||||||
zend_declare_class_constant_long(php_ce_v8js, ZEND_STRL("FLAG_NONE"), V8JS_FLAG_NONE TSRMLS_CC);
|
zend_declare_class_constant_long(php_ce_v8js, ZEND_STRL("FLAG_NONE"), V8JS_FLAG_NONE TSRMLS_CC);
|
||||||
zend_declare_class_constant_long(php_ce_v8js, ZEND_STRL("FLAG_FORCE_ARRAY"), V8JS_FLAG_FORCE_ARRAY TSRMLS_CC);
|
zend_declare_class_constant_long(php_ce_v8js, ZEND_STRL("FLAG_FORCE_ARRAY"), V8JS_FLAG_FORCE_ARRAY TSRMLS_CC);
|
||||||
|
zend_declare_class_constant_long(php_ce_v8js, ZEND_STRL("FLAG_PROPAGATE_PHP_EXCEPTIONS"), V8JS_FLAG_PROPAGATE_PHP_EXCEPTIONS TSRMLS_CC);
|
||||||
|
|
||||||
#ifdef ENABLE_DEBUGGER_SUPPORT
|
#ifdef ENABLE_DEBUGGER_SUPPORT
|
||||||
zend_declare_class_constant_long(php_ce_v8js, ZEND_STRL("DEBUG_AUTO_BREAK_NEVER"), V8JS_DEBUG_AUTO_BREAK_NEVER TSRMLS_CC);
|
zend_declare_class_constant_long(php_ce_v8js, ZEND_STRL("DEBUG_AUTO_BREAK_NEVER"), V8JS_DEBUG_AUTO_BREAK_NEVER TSRMLS_CC);
|
||||||
|
@ -21,6 +21,7 @@ extern "C" {
|
|||||||
#include "ext/standard/php_string.h"
|
#include "ext/standard/php_string.h"
|
||||||
#include "zend_interfaces.h"
|
#include "zend_interfaces.h"
|
||||||
#include "zend_closures.h"
|
#include "zend_closures.h"
|
||||||
|
#include "zend_exceptions.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "php_v8js_macros.h"
|
#include "php_v8js_macros.h"
|
||||||
@ -33,7 +34,7 @@ static void v8js_weak_object_callback(const v8::WeakCallbackData<v8::Object, zva
|
|||||||
/* Callback for PHP methods and functions */
|
/* Callback for PHP methods and functions */
|
||||||
static void v8js_call_php_func(zval *value, zend_class_entry *ce, zend_function *method_ptr, v8::Isolate *isolate, const v8::FunctionCallbackInfo<v8::Value>& info TSRMLS_DC) /* {{{ */
|
static void v8js_call_php_func(zval *value, zend_class_entry *ce, zend_function *method_ptr, v8::Isolate *isolate, const v8::FunctionCallbackInfo<v8::Value>& info TSRMLS_DC) /* {{{ */
|
||||||
{
|
{
|
||||||
v8::Handle<v8::Value> return_value;
|
v8::Handle<v8::Value> return_value = V8JS_NULL;
|
||||||
zend_fcall_info fci;
|
zend_fcall_info fci;
|
||||||
zend_fcall_info_cache fcc;
|
zend_fcall_info_cache fcc;
|
||||||
zval fname, *retval_ptr = NULL, **argv = NULL;
|
zval fname, *retval_ptr = NULL, **argv = NULL;
|
||||||
@ -138,10 +139,6 @@ static void v8js_call_php_func(zval *value, zend_class_entry *ce, zend_function
|
|||||||
}
|
}
|
||||||
zend_end_try();
|
zend_end_try();
|
||||||
|
|
||||||
if(EG(exception)) {
|
|
||||||
v8js_terminate_execution(isolate);
|
|
||||||
}
|
|
||||||
|
|
||||||
failure:
|
failure:
|
||||||
/* Cleanup */
|
/* Cleanup */
|
||||||
if (argc) {
|
if (argc) {
|
||||||
@ -152,11 +149,19 @@ failure:
|
|||||||
efree(fci.params);
|
efree(fci.params);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (retval_ptr != NULL) {
|
if(EG(exception)) {
|
||||||
return_value = zval_to_v8js(retval_ptr, isolate TSRMLS_CC);
|
if(ctx->flags & V8JS_FLAG_PROPAGATE_PHP_EXCEPTIONS) {
|
||||||
zval_ptr_dtor(&retval_ptr);
|
return_value = isolate->ThrowException(zval_to_v8js(EG(exception), isolate TSRMLS_CC));
|
||||||
|
zend_clear_exception(TSRMLS_C);
|
||||||
} else {
|
} else {
|
||||||
return_value = V8JS_NULL;
|
v8js_terminate_execution(isolate);
|
||||||
|
}
|
||||||
|
} else if (retval_ptr != NULL) {
|
||||||
|
return_value = zval_to_v8js(retval_ptr, isolate TSRMLS_CC);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (retval_ptr != NULL) {
|
||||||
|
zval_ptr_dtor(&retval_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
info.GetReturnValue().Set(return_value);
|
info.GetReturnValue().Set(return_value);
|
||||||
|
Loading…
Reference in New Issue
Block a user