mirror of
https://github.com/phpv8/v8js.git
synced 2024-12-23 09:31:52 +00:00
Unwind V8 execution context on fatal error, refs #87
This is yet a first hack to prove applicability. Currently unwind environment is held in a global variable, i.e. solution is neither thread safe nor reentrant yet.
This commit is contained in:
parent
997b237240
commit
a49fa8ce02
@ -205,6 +205,8 @@ struct php_v8js_ctx {
|
|||||||
|
|
||||||
std::vector<php_v8js_accessor_ctx *> accessor_list;
|
std::vector<php_v8js_accessor_ctx *> accessor_list;
|
||||||
char *tz;
|
char *tz;
|
||||||
|
|
||||||
|
bool fatal_error_abort;
|
||||||
#ifdef ZTS
|
#ifdef ZTS
|
||||||
void ***zts_ctx;
|
void ***zts_ctx;
|
||||||
#endif
|
#endif
|
||||||
|
4
v8js.cc
4
v8js.cc
@ -1134,6 +1134,10 @@ static PHP_METHOD(V8Js, executeString)
|
|||||||
php_v8js_timer_pop(TSRMLS_C);
|
php_v8js_timer_pop(TSRMLS_C);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(c->fatal_error_abort) {
|
||||||
|
zend_error(E_ERROR, "V8Js caught fatal error; message lost, sorry :-)");
|
||||||
|
}
|
||||||
|
|
||||||
char exception_string[64];
|
char exception_string[64];
|
||||||
|
|
||||||
if (c->time_limit_hit) {
|
if (c->time_limit_hit) {
|
||||||
|
@ -30,6 +30,17 @@ extern "C" {
|
|||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
|
|
||||||
|
jmp_buf *unwind_env;
|
||||||
|
|
||||||
|
static void php_v8js_error_handler(int error_num, const char *error_filename, const uint error_lineno, const char *format, va_list args)
|
||||||
|
{
|
||||||
|
longjmp(*unwind_env, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void php_v8js_weak_object_callback(const v8::WeakCallbackData<v8::Object, zval> &data);
|
static void php_v8js_weak_object_callback(const v8::WeakCallbackData<v8::Object, zval> &data);
|
||||||
|
|
||||||
/* Callback for PHP methods and functions */
|
/* Callback for PHP methods and functions */
|
||||||
@ -43,6 +54,13 @@ static void php_v8js_call_php_func(zval *value, zend_class_entry *ce, zend_funct
|
|||||||
char *error;
|
char *error;
|
||||||
int error_len, i, flags = V8JS_FLAG_NONE;
|
int error_len, i, flags = V8JS_FLAG_NONE;
|
||||||
|
|
||||||
|
#if PHP_V8_API_VERSION <= 3023008
|
||||||
|
/* Until V8 3.23.8 Isolate could only take one external pointer. */
|
||||||
|
php_v8js_ctx *ctx = (php_v8js_ctx *) isolate->GetData();
|
||||||
|
#else
|
||||||
|
php_v8js_ctx *ctx = (php_v8js_ctx *) isolate->GetData(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Set parameter limits */
|
/* Set parameter limits */
|
||||||
min_num_args = method_ptr->common.required_num_args;
|
min_num_args = method_ptr->common.required_num_args;
|
||||||
max_num_args = method_ptr->common.num_args;
|
max_num_args = method_ptr->common.num_args;
|
||||||
@ -125,12 +143,34 @@ static void php_v8js_call_php_func(zval *value, zend_class_entry *ce, zend_funct
|
|||||||
fcc.called_scope = ce;
|
fcc.called_scope = ce;
|
||||||
fcc.object_ptr = value;
|
fcc.object_ptr = value;
|
||||||
|
|
||||||
/* Call the method */
|
jmp_buf env;
|
||||||
zend_call_function(&fci, &fcc TSRMLS_CC);
|
int val;
|
||||||
|
|
||||||
|
void (*old_error_handler)(int, const char *, const uint, const char*, va_list);
|
||||||
|
old_error_handler = zend_error_cb;
|
||||||
|
zend_error_cb = php_v8js_error_handler;
|
||||||
|
|
||||||
|
val = setjmp (env);
|
||||||
|
unwind_env = &env;
|
||||||
|
|
||||||
|
if (val) {
|
||||||
|
ctx->fatal_error_abort = true;
|
||||||
|
zend_error_cb = old_error_handler;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Call the method */
|
||||||
|
zend_call_function(&fci, &fcc TSRMLS_CC);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isolate->Enter();
|
isolate->Enter();
|
||||||
|
|
||||||
|
if(ctx->fatal_error_abort) {
|
||||||
|
v8::V8::TerminateExecution(isolate);
|
||||||
|
info.GetReturnValue().Set(V8JS_NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
failure:
|
failure:
|
||||||
/* Cleanup */
|
/* Cleanup */
|
||||||
if (argc) {
|
if (argc) {
|
||||||
|
Loading…
Reference in New Issue
Block a user