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

269 lines
8.9 KiB
C++
Raw Normal View History

/*
+----------------------------------------------------------------------+
2017-03-11 11:33:49 +00:00
| PHP Version 7 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2016 The PHP Group |
+----------------------------------------------------------------------+
| http://www.opensource.org/licenses/mit-license.php MIT License |
+----------------------------------------------------------------------+
| Author: Jani Taskinen <jani.taskinen@iki.fi> |
| Author: Patrick Reilly <preilly@php.net> |
| Author: Stefan Siegl <stesie@php.net> |
+----------------------------------------------------------------------+
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php_v8js_macros.h"
extern "C" {
#include "ext/date/php_date.h"
#include "ext/standard/php_string.h"
#include "zend_interfaces.h"
#include "zend_closures.h"
#include "ext/spl/spl_exceptions.h"
#include "zend_exceptions.h"
}
/* {{{ Class Entries */
zend_class_entry *php_ce_v8js_exception;
zend_class_entry *php_ce_v8js_script_exception;
zend_class_entry *php_ce_v8js_time_limit_exception;
zend_class_entry *php_ce_v8js_memory_limit_exception;
/* }}} */
/* {{{ Class: V8JsScriptException */
2017-03-11 12:35:21 +00:00
void v8js_create_script_exception(zval *return_value, v8::Isolate *isolate, v8::TryCatch *try_catch) /* {{{ */
{
v8js_ctx *ctx = (v8js_ctx *) isolate->GetData(0);
v8::Local<v8::Context> context = v8::Local<v8::Context>::New(isolate, ctx->context);
v8::String::Utf8Value exception(isolate, try_catch->Exception());
const char *exception_string = ToCString(exception);
2017-03-11 12:31:40 +00:00
v8::Local<v8::Message> tc_message = try_catch->Message();
const char *filename_string, *sourceline_string;
char *message_string;
object_init_ex(return_value, php_ce_v8js_script_exception);
#define PHPV8_EXPROP(type, name, value) \
2017-03-11 12:35:21 +00:00
zend_update_property##type(php_ce_v8js_script_exception, return_value, #name, sizeof(#name) - 1, value);
if (tc_message.IsEmpty()) {
2016-03-26 11:11:11 +00:00
spprintf(&message_string, 0, "%s", exception_string);
}
else
{
v8::String::Utf8Value filename(isolate, tc_message->GetScriptResourceName());
filename_string = ToCString(filename);
PHPV8_EXPROP(_string, JsFileName, filename_string);
v8::MaybeLocal<v8::String> maybe_sourceline = tc_message->GetSourceLine(context);
if (!maybe_sourceline.IsEmpty()) {
v8::String::Utf8Value sourceline(isolate, maybe_sourceline.ToLocalChecked());
sourceline_string = ToCString(sourceline);
PHPV8_EXPROP(_string, JsSourceLine, sourceline_string);
}
v8::Maybe<int> linenum = tc_message->GetLineNumber(context);
if (linenum.IsJust()) {
PHPV8_EXPROP(_long, JsLineNumber, linenum.FromJust());
}
v8::Maybe<int> start_col = tc_message->GetStartColumn(context);
if (start_col.IsJust()) {
PHPV8_EXPROP(_long, JsStartColumn, start_col.FromJust());
}
v8::Maybe<int> end_col = tc_message->GetEndColumn(context);
2017-04-23 20:50:00 +00:00
if (end_col.IsJust()) {
2017-04-24 05:26:54 +00:00
PHPV8_EXPROP(_long, JsEndColumn, end_col.FromJust());
2017-04-23 20:50:00 +00:00
}
spprintf(&message_string, 0, "%s:%d: %s", filename_string, linenum.FromMaybe(0), exception_string);
v8::MaybeLocal<v8::Value> maybe_stacktrace = try_catch->StackTrace(context);
if (!maybe_stacktrace.IsEmpty()) {
v8::String::Utf8Value stacktrace(isolate, maybe_stacktrace.ToLocalChecked());
PHPV8_EXPROP(_string, JsTrace, ToCString(stacktrace));
}
2018-09-13 12:01:15 +00:00
v8::Local<v8::Object> error_object;
if(try_catch->Exception()->IsObject() && try_catch->Exception()->ToObject(context).ToLocal(&error_object) && error_object->InternalFieldCount() == 2) {
zend_object *php_exception = reinterpret_cast<zend_object *>(error_object->GetAlignedPointerFromInternalField(1));
2017-03-11 12:45:23 +00:00
zend_class_entry *exception_ce = zend_exception_get_default();
2017-03-11 12:35:21 +00:00
if (instanceof_function(php_exception->ce, exception_ce)) {
2018-07-05 09:30:20 +00:00
#ifdef GC_ADDREF
GC_ADDREF(php_exception);
#else
++GC_REFCOUNT(php_exception);
2018-07-05 09:30:20 +00:00
#endif
zend_exception_set_previous(Z_OBJ_P(return_value), php_exception);
}
}
}
PHPV8_EXPROP(_string, message, message_string);
efree(message_string);
}
/* }}} */
2017-03-11 12:35:21 +00:00
void v8js_throw_script_exception(v8::Isolate *isolate, v8::TryCatch *try_catch) /* {{{ */
{
v8::String::Utf8Value exception(isolate, try_catch->Exception());
const char *exception_string = ToCString(exception);
zval zexception;
if (try_catch->Message().IsEmpty()) {
2017-03-11 12:35:21 +00:00
zend_throw_exception(php_ce_v8js_script_exception, (char *) exception_string, 0);
} else {
2017-03-11 12:35:21 +00:00
v8js_create_script_exception(&zexception, isolate, try_catch);
zend_throw_exception_object(&zexception);
}
}
/* }}} */
#define V8JS_EXCEPTION_METHOD(property) \
static PHP_METHOD(V8JsScriptException, get##property) \
{ \
zval *value, rv; \
\
if (zend_parse_parameters_none() == FAILURE) { \
return; \
} \
2017-03-11 12:35:21 +00:00
value = zend_read_property(php_ce_v8js_script_exception, getThis(), #property, sizeof(#property) - 1, 0, &rv); \
RETURN_ZVAL(value, 1, 0); \
}
/* {{{ proto string V8JsEScriptxception::getJsFileName()
*/
V8JS_EXCEPTION_METHOD(JsFileName);
/* }}} */
/* {{{ proto string V8JsScriptException::getJsLineNumber()
*/
V8JS_EXCEPTION_METHOD(JsLineNumber);
/* }}} */
/* {{{ proto string V8JsScriptException::getJsStartColumn()
*/
V8JS_EXCEPTION_METHOD(JsStartColumn);
/* }}} */
/* {{{ proto string V8JsScriptException::getJsEndColumn()
*/
V8JS_EXCEPTION_METHOD(JsEndColumn);
/* }}} */
/* {{{ proto string V8JsScriptException::getJsSourceLine()
*/
V8JS_EXCEPTION_METHOD(JsSourceLine);
/* }}} */
/* {{{ proto string V8JsScriptException::getJsTrace()
*/
V8JS_EXCEPTION_METHOD(JsTrace);
/* }}} */
ZEND_BEGIN_ARG_INFO(arginfo_v8jsscriptexception_no_args, 0)
ZEND_END_ARG_INFO()
static const zend_function_entry v8js_script_exception_methods[] = { /* {{{ */
PHP_ME(V8JsScriptException, getJsFileName, arginfo_v8jsscriptexception_no_args, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(V8JsScriptException, getJsLineNumber, arginfo_v8jsscriptexception_no_args, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(V8JsScriptException, getJsStartColumn, arginfo_v8jsscriptexception_no_args, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(V8JsScriptException, getJsEndColumn, arginfo_v8jsscriptexception_no_args, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(V8JsScriptException, getJsSourceLine, arginfo_v8jsscriptexception_no_args, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(V8JsScriptException, getJsTrace, arginfo_v8jsscriptexception_no_args, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
{NULL, NULL, NULL}
};
/* }}} */
/* }}} V8JsScriptException */
/* {{{ Class: V8JsException */
static const zend_function_entry v8js_exception_methods[] = { /* {{{ */
{NULL, NULL, NULL}
};
/* }}} */
/* }}} V8JsException */
/* {{{ Class: V8JsTimeLimitException */
static const zend_function_entry v8js_time_limit_exception_methods[] = { /* {{{ */
{NULL, NULL, NULL}
};
/* }}} */
/* }}} V8JsTimeLimitException */
/* {{{ Class: V8JsMemoryLimitException */
static const zend_function_entry v8js_memory_limit_exception_methods[] = { /* {{{ */
{NULL, NULL, NULL}
};
/* }}} */
/* }}} V8JsMemoryLimitException */
PHP_MINIT_FUNCTION(v8js_exceptions) /* {{{ */
{
zend_class_entry ce;
/* V8JsException Class */
INIT_CLASS_ENTRY(ce, "V8JsException", v8js_exception_methods);
2017-03-11 12:35:21 +00:00
php_ce_v8js_exception = zend_register_internal_class_ex(&ce, spl_ce_RuntimeException);
/* V8JsScriptException Class */
INIT_CLASS_ENTRY(ce, "V8JsScriptException", v8js_script_exception_methods);
2017-03-11 12:35:21 +00:00
php_ce_v8js_script_exception = zend_register_internal_class_ex(&ce, php_ce_v8js_exception);
php_ce_v8js_script_exception->ce_flags |= ZEND_ACC_FINAL;
/* Add custom JS specific properties */
2017-03-11 12:35:21 +00:00
zend_declare_property_null(php_ce_v8js_script_exception, ZEND_STRL("JsFileName"), ZEND_ACC_PROTECTED);
zend_declare_property_null(php_ce_v8js_script_exception, ZEND_STRL("JsLineNumber"), ZEND_ACC_PROTECTED);
zend_declare_property_null(php_ce_v8js_script_exception, ZEND_STRL("JsStartColumn"), ZEND_ACC_PROTECTED);
zend_declare_property_null(php_ce_v8js_script_exception, ZEND_STRL("JsEndColumn"), ZEND_ACC_PROTECTED);
zend_declare_property_null(php_ce_v8js_script_exception, ZEND_STRL("JsSourceLine"), ZEND_ACC_PROTECTED);
zend_declare_property_null(php_ce_v8js_script_exception, ZEND_STRL("JsTrace"), ZEND_ACC_PROTECTED);
/* V8JsTimeLimitException Class */
INIT_CLASS_ENTRY(ce, "V8JsTimeLimitException", v8js_time_limit_exception_methods);
2017-03-11 12:35:21 +00:00
php_ce_v8js_time_limit_exception = zend_register_internal_class_ex(&ce, php_ce_v8js_exception);
php_ce_v8js_time_limit_exception->ce_flags |= ZEND_ACC_FINAL;
/* V8JsMemoryLimitException Class */
INIT_CLASS_ENTRY(ce, "V8JsMemoryLimitException", v8js_memory_limit_exception_methods);
2017-03-11 12:35:21 +00:00
php_ce_v8js_memory_limit_exception = zend_register_internal_class_ex(&ce, php_ce_v8js_exception);
php_ce_v8js_memory_limit_exception->ce_flags |= ZEND_ACC_FINAL;
2015-03-12 11:13:33 +00:00
return SUCCESS;
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* indent-tabs-mode: t
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/