mirror of
https://github.com/phpv8/v8js.git
synced 2024-12-22 14:01:53 +00:00
adapt mandatory api changes for V8 7.0.276.3, refs #374
This commit is contained in:
parent
18b79d9004
commit
ab6e2267af
@ -65,10 +65,6 @@ extern "C" {
|
|||||||
/* V8Js Version */
|
/* V8Js Version */
|
||||||
#define PHP_V8JS_VERSION "2.1.0"
|
#define PHP_V8JS_VERSION "2.1.0"
|
||||||
|
|
||||||
/* Helper macros */
|
|
||||||
#define V8JS_GET_CLASS_NAME(var, obj) \
|
|
||||||
v8::String::Utf8Value var(obj->GetConstructorName());
|
|
||||||
|
|
||||||
/* 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)
|
||||||
|
@ -221,9 +221,11 @@ void v8js_array_access_enumerator(const v8::PropertyCallbackInfo<v8::Array>& inf
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void v8js_array_access_named_getter(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info) /* {{{ */
|
void v8js_array_access_named_getter(v8::Local<v8::Name> property_name, const v8::PropertyCallbackInfo<v8::Value> &info) /* {{{ */
|
||||||
{
|
{
|
||||||
v8::String::Utf8Value cstr(property);
|
v8::Local<v8::String> property = v8::Local<v8::String>::Cast(property_name);
|
||||||
|
v8::Isolate *isolate = info.GetIsolate();
|
||||||
|
v8::String::Utf8Value cstr(isolate, property);
|
||||||
const char *name = ToCString(cstr);
|
const char *name = ToCString(cstr);
|
||||||
|
|
||||||
if(strcmp(name, "length") == 0) {
|
if(strcmp(name, "length") == 0) {
|
||||||
@ -234,7 +236,6 @@ void v8js_array_access_named_getter(v8::Local<v8::String> property, const v8::Pr
|
|||||||
v8::Local<v8::Value> ret_value = v8js_named_property_callback(property, info, V8JS_PROP_GETTER);
|
v8::Local<v8::Value> ret_value = v8js_named_property_callback(property, info, V8JS_PROP_GETTER);
|
||||||
|
|
||||||
if(ret_value.IsEmpty()) {
|
if(ret_value.IsEmpty()) {
|
||||||
v8::Isolate *isolate = info.GetIsolate();
|
|
||||||
v8::Local<v8::Array> arr = v8::Array::New(isolate);
|
v8::Local<v8::Array> arr = v8::Array::New(isolate);
|
||||||
v8::Local<v8::Value> prototype = arr->GetPrototype();
|
v8::Local<v8::Value> prototype = arr->GetPrototype();
|
||||||
|
|
||||||
@ -243,7 +244,7 @@ void v8js_array_access_named_getter(v8::Local<v8::String> property, const v8::Pr
|
|||||||
info.GetReturnValue().Set(ret_value);
|
info.GetReturnValue().Set(ret_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret_value = prototype->ToObject()->Get(property);
|
ret_value = prototype->ToObject(isolate)->Get(property);
|
||||||
}
|
}
|
||||||
|
|
||||||
info.GetReturnValue().Set(ret_value);
|
info.GetReturnValue().Set(ret_value);
|
||||||
|
@ -25,7 +25,7 @@ void v8js_array_access_query(uint32_t index,
|
|||||||
const v8::PropertyCallbackInfo<v8::Integer>& info);
|
const v8::PropertyCallbackInfo<v8::Integer>& info);
|
||||||
|
|
||||||
/* Named Property Handlers */
|
/* Named Property Handlers */
|
||||||
void v8js_array_access_named_getter(v8::Local<v8::String> property,
|
void v8js_array_access_named_getter(v8::Local<v8::Name> property,
|
||||||
const v8::PropertyCallbackInfo<v8::Value> &info);
|
const v8::PropertyCallbackInfo<v8::Value> &info);
|
||||||
|
|
||||||
#endif /* V8JS_ARRAY_ACCESS_H */
|
#endif /* V8JS_ARRAY_ACCESS_H */
|
||||||
|
@ -648,8 +648,8 @@ static void v8js_compile_script(zval *this_ptr, const zend_string *str, const ze
|
|||||||
v8::Local<v8::String> sname = identifier
|
v8::Local<v8::String> sname = identifier
|
||||||
? v8::String::NewFromUtf8(isolate, ZSTR_VAL(identifier), v8::String::kNormalString, static_cast<int>(ZSTR_LEN(identifier)))
|
? v8::String::NewFromUtf8(isolate, ZSTR_VAL(identifier), v8::String::kNormalString, static_cast<int>(ZSTR_LEN(identifier)))
|
||||||
: V8JS_SYM("V8Js::compileString()");
|
: V8JS_SYM("V8Js::compileString()");
|
||||||
|
v8::ScriptOrigin origin(sname);
|
||||||
|
|
||||||
/* Compiles a string context independently. TODO: Add a php function which calls this and returns the result as resource which can be executed later. */
|
|
||||||
if (ZSTR_LEN(str) > std::numeric_limits<int>::max()) {
|
if (ZSTR_LEN(str) > std::numeric_limits<int>::max()) {
|
||||||
zend_throw_exception(php_ce_v8js_exception,
|
zend_throw_exception(php_ce_v8js_exception,
|
||||||
"Script source exceeds maximum supported length", 0);
|
"Script source exceeds maximum supported length", 0);
|
||||||
@ -657,7 +657,7 @@ static void v8js_compile_script(zval *this_ptr, const zend_string *str, const ze
|
|||||||
}
|
}
|
||||||
|
|
||||||
v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate, ZSTR_VAL(str), v8::String::kNormalString, static_cast<int>(ZSTR_LEN(str)));
|
v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate, ZSTR_VAL(str), v8::String::kNormalString, static_cast<int>(ZSTR_LEN(str)));
|
||||||
v8::Local<v8::Script> script = v8::Script::Compile(source, sname);
|
v8::MaybeLocal<v8::Script> script = v8::Script::Compile(v8::Local<v8::Context>::New(isolate, c->context), source, &origin);
|
||||||
|
|
||||||
/* Compile errors? */
|
/* Compile errors? */
|
||||||
if (script.IsEmpty()) {
|
if (script.IsEmpty()) {
|
||||||
@ -665,9 +665,9 @@ static void v8js_compile_script(zval *this_ptr, const zend_string *str, const ze
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
res = (v8js_script *)emalloc(sizeof(v8js_script));
|
res = (v8js_script *)emalloc(sizeof(v8js_script));
|
||||||
res->script = new v8::Persistent<v8::Script, v8::CopyablePersistentTraits<v8::Script>>(c->isolate, script);
|
res->script = new v8::Persistent<v8::Script, v8::CopyablePersistentTraits<v8::Script>>(c->isolate, script.ToLocalChecked());
|
||||||
|
|
||||||
v8::String::Utf8Value _sname(sname);
|
v8::String::Utf8Value _sname(isolate, sname);
|
||||||
res->name = estrndup(ToCString(_sname), _sname.length());
|
res->name = estrndup(ToCString(_sname), _sname.length());
|
||||||
res->ctx = c;
|
res->ctx = c;
|
||||||
*ret = res;
|
*ret = res;
|
||||||
@ -695,9 +695,9 @@ static void v8js_execute_script(zval *this_ptr, v8js_script *res, long flags, lo
|
|||||||
/* std::function relies on its dtor to be executed, otherwise it leaks
|
/* std::function relies on its dtor to be executed, otherwise it leaks
|
||||||
* some memory on bailout. */
|
* some memory on bailout. */
|
||||||
{
|
{
|
||||||
std::function< v8::Local<v8::Value>(v8::Isolate *) > v8_call = [res](v8::Isolate *isolate) {
|
std::function< v8::MaybeLocal<v8::Value>(v8::Isolate *) > v8_call = [c, res](v8::Isolate *isolate) {
|
||||||
v8::Local<v8::Script> script = v8::Local<v8::Script>::New(isolate, *res->script);
|
v8::Local<v8::Script> script = v8::Local<v8::Script>::New(isolate, *res->script);
|
||||||
return script->Run();
|
return script->Run(v8::Local<v8::Context>::New(isolate, c->context));
|
||||||
};
|
};
|
||||||
|
|
||||||
v8js_v8_call(c, return_value, flags, time_limit, memory_limit, v8_call);
|
v8js_v8_call(c, return_value, flags, time_limit, memory_limit, v8_call);
|
||||||
@ -1153,6 +1153,31 @@ static PHP_METHOD(V8Js, getExtensions)
|
|||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
static v8::StartupData createSnapshotDataBlob(v8::SnapshotCreator *snapshot_creator, zend_string *str) /* {{{ */
|
||||||
|
{
|
||||||
|
v8::Isolate *isolate = snapshot_creator->GetIsolate();
|
||||||
|
|
||||||
|
{
|
||||||
|
v8::HandleScope scope(isolate);
|
||||||
|
v8::Local<v8::Context> context = v8::Context::New(isolate);
|
||||||
|
|
||||||
|
v8::Context::Scope context_scope(context);
|
||||||
|
v8::TryCatch try_catch(isolate);
|
||||||
|
|
||||||
|
v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate, ZSTR_VAL(str), v8::String::kNormalString, static_cast<int>(ZSTR_LEN(str)));
|
||||||
|
v8::MaybeLocal<v8::Script> script = v8::Script::Compile(context, source);
|
||||||
|
|
||||||
|
if (script.IsEmpty() || script.ToLocalChecked()->Run(context).IsEmpty())
|
||||||
|
{
|
||||||
|
return {nullptr, 0};
|
||||||
|
}
|
||||||
|
|
||||||
|
snapshot_creator->SetDefaultContext(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
return snapshot_creator->CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
|
||||||
|
} /* }}} */
|
||||||
|
|
||||||
|
|
||||||
/* {{{ proto string|bool V8Js::createSnapshot(string embed_source)
|
/* {{{ proto string|bool V8Js::createSnapshot(string embed_source)
|
||||||
*/
|
*/
|
||||||
@ -1172,7 +1197,9 @@ static PHP_METHOD(V8Js, createSnapshot)
|
|||||||
/* Initialize V8, if not already done. */
|
/* Initialize V8, if not already done. */
|
||||||
v8js_v8_init();
|
v8js_v8_init();
|
||||||
|
|
||||||
v8::StartupData snapshot_blob = v8::V8::CreateSnapshotDataBlob(ZSTR_VAL(script));
|
v8::Isolate *isolate = v8::Isolate::Allocate();
|
||||||
|
v8::SnapshotCreator snapshot_creator(isolate);
|
||||||
|
v8::StartupData snapshot_blob = createSnapshotDataBlob(&snapshot_creator, script);
|
||||||
|
|
||||||
if (!snapshot_blob.data) {
|
if (!snapshot_blob.data) {
|
||||||
php_error_docref(NULL, E_WARNING, "Failed to create V8 heap snapshot. Check $embed_source for errors.");
|
php_error_docref(NULL, E_WARNING, "Failed to create V8 heap snapshot. Check $embed_source for errors.");
|
||||||
@ -1303,7 +1330,7 @@ static void v8js_write_property(zval *object, zval *member, zval *value, void **
|
|||||||
(property_info->flags & ZEND_ACC_PUBLIC))) {
|
(property_info->flags & ZEND_ACC_PUBLIC))) {
|
||||||
/* Global PHP JS object */
|
/* Global PHP JS object */
|
||||||
v8::Local<v8::String> object_name_js = v8::Local<v8::String>::New(isolate, c->object_name);
|
v8::Local<v8::String> object_name_js = v8::Local<v8::String>::New(isolate, c->object_name);
|
||||||
v8::Local<v8::Object> jsobj = V8JS_GLOBAL(isolate)->Get(object_name_js)->ToObject();
|
v8::Local<v8::Object> jsobj = V8JS_GLOBAL(isolate)->Get(object_name_js)->ToObject(isolate);
|
||||||
|
|
||||||
if (Z_STRLEN_P(member) > std::numeric_limits<int>::max()) {
|
if (Z_STRLEN_P(member) > std::numeric_limits<int>::max()) {
|
||||||
zend_throw_exception(php_ce_v8js_exception,
|
zend_throw_exception(php_ce_v8js_exception,
|
||||||
@ -1327,7 +1354,7 @@ static void v8js_unset_property(zval *object, zval *member, void **cache_slot) /
|
|||||||
|
|
||||||
/* Global PHP JS object */
|
/* Global PHP JS object */
|
||||||
v8::Local<v8::String> object_name_js = v8::Local<v8::String>::New(isolate, c->object_name);
|
v8::Local<v8::String> object_name_js = v8::Local<v8::String>::New(isolate, c->object_name);
|
||||||
v8::Local<v8::Object> jsobj = V8JS_GLOBAL(isolate)->Get(object_name_js)->ToObject();
|
v8::Local<v8::Object> jsobj = V8JS_GLOBAL(isolate)->Get(object_name_js)->ToObject(isolate);
|
||||||
|
|
||||||
if (Z_STRLEN_P(member) > std::numeric_limits<int>::max()) {
|
if (Z_STRLEN_P(member) > std::numeric_limits<int>::max()) {
|
||||||
zend_throw_exception(php_ce_v8js_exception,
|
zend_throw_exception(php_ce_v8js_exception,
|
||||||
|
@ -200,27 +200,41 @@ v8::Local<v8::Value> zval_to_v8js(zval *value, v8::Isolate *isolate) /* {{{ */
|
|||||||
|
|
||||||
int v8js_to_zval(v8::Local<v8::Value> jsValue, zval *return_value, int flags, v8::Isolate *isolate) /* {{{ */
|
int v8js_to_zval(v8::Local<v8::Value> jsValue, zval *return_value, int flags, v8::Isolate *isolate) /* {{{ */
|
||||||
{
|
{
|
||||||
|
v8js_ctx *ctx = (v8js_ctx *) isolate->GetData(0);
|
||||||
|
|
||||||
if (jsValue->IsString())
|
if (jsValue->IsString())
|
||||||
{
|
{
|
||||||
v8::String::Utf8Value str(jsValue);
|
v8::String::Utf8Value str(isolate, jsValue);
|
||||||
const char *cstr = ToCString(str);
|
const char *cstr = ToCString(str);
|
||||||
RETVAL_STRINGL(cstr, jsValue->ToString()->Utf8Length());
|
RETVAL_STRINGL(cstr, jsValue->ToString(isolate)->Utf8Length(isolate));
|
||||||
}
|
}
|
||||||
else if (jsValue->IsBoolean())
|
else if (jsValue->IsBoolean())
|
||||||
{
|
{
|
||||||
RETVAL_BOOL(jsValue->Uint32Value());
|
v8::Maybe<bool> value = jsValue->BooleanValue(v8::Local<v8::Context>::New(isolate, ctx->context));
|
||||||
|
if (value.IsNothing()) {
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
RETVAL_BOOL(value.ToChecked());
|
||||||
}
|
}
|
||||||
else if (jsValue->IsInt32() || jsValue->IsUint32())
|
else if (jsValue->IsInt32() || jsValue->IsUint32())
|
||||||
{
|
{
|
||||||
RETVAL_LONG((long) jsValue->IntegerValue());
|
v8::Maybe<int64_t> value = jsValue->IntegerValue(v8::Local<v8::Context>::New(isolate, ctx->context));
|
||||||
|
if (value.IsNothing()) {
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
RETVAL_LONG((long) value.ToChecked());
|
||||||
}
|
}
|
||||||
else if (jsValue->IsNumber())
|
else if (jsValue->IsNumber())
|
||||||
{
|
{
|
||||||
RETVAL_DOUBLE(jsValue->NumberValue());
|
v8::Maybe<double> value = jsValue->NumberValue(v8::Local<v8::Context>::New(isolate, ctx->context));
|
||||||
|
if (value.IsNothing()) {
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
RETVAL_DOUBLE(value.ToChecked());
|
||||||
}
|
}
|
||||||
else if (jsValue->IsDate()) /* Return as a PHP DateTime object */
|
else if (jsValue->IsDate()) /* Return as a PHP DateTime object */
|
||||||
{
|
{
|
||||||
v8::String::Utf8Value str(jsValue);
|
v8::String::Utf8Value str(isolate, jsValue);
|
||||||
const char *cstr = ToCString(str);
|
const char *cstr = ToCString(str);
|
||||||
|
|
||||||
/* cstr has two timezone specifications:
|
/* cstr has two timezone specifications:
|
||||||
@ -253,7 +267,7 @@ int v8js_to_zval(v8::Local<v8::Value> jsValue, zval *return_value, int flags, v8
|
|||||||
}
|
}
|
||||||
else if (jsValue->IsObject())
|
else if (jsValue->IsObject())
|
||||||
{
|
{
|
||||||
v8::Local<v8::Object> self = jsValue->ToObject();
|
v8::Local<v8::Object> self = jsValue->ToObject(isolate);
|
||||||
|
|
||||||
// if this is a wrapped PHP object, then just unwrap it.
|
// if this is a wrapped PHP object, then just unwrap it.
|
||||||
if (self->InternalFieldCount() == 2) {
|
if (self->InternalFieldCount() == 2) {
|
||||||
|
@ -39,12 +39,14 @@ zend_class_entry *php_ce_v8js_memory_limit_exception;
|
|||||||
|
|
||||||
void v8js_create_script_exception(zval *return_value, v8::Isolate *isolate, v8::TryCatch *try_catch) /* {{{ */
|
void v8js_create_script_exception(zval *return_value, v8::Isolate *isolate, v8::TryCatch *try_catch) /* {{{ */
|
||||||
{
|
{
|
||||||
v8::String::Utf8Value exception(try_catch->Exception());
|
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);
|
const char *exception_string = ToCString(exception);
|
||||||
v8::Local<v8::Message> tc_message = try_catch->Message();
|
v8::Local<v8::Message> tc_message = try_catch->Message();
|
||||||
const char *filename_string, *sourceline_string;
|
const char *filename_string, *sourceline_string;
|
||||||
char *message_string;
|
char *message_string;
|
||||||
int linenum, start_col;
|
|
||||||
|
|
||||||
object_init_ex(return_value, php_ce_v8js_script_exception);
|
object_init_ex(return_value, php_ce_v8js_script_exception);
|
||||||
|
|
||||||
@ -56,35 +58,42 @@ void v8js_create_script_exception(zval *return_value, v8::Isolate *isolate, v8::
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
v8::String::Utf8Value filename(tc_message->GetScriptResourceName());
|
v8::String::Utf8Value filename(isolate, tc_message->GetScriptResourceName());
|
||||||
filename_string = ToCString(filename);
|
filename_string = ToCString(filename);
|
||||||
PHPV8_EXPROP(_string, JsFileName, filename_string);
|
PHPV8_EXPROP(_string, JsFileName, filename_string);
|
||||||
|
|
||||||
v8::String::Utf8Value sourceline(tc_message->GetSourceLine());
|
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);
|
sourceline_string = ToCString(sourceline);
|
||||||
PHPV8_EXPROP(_string, JsSourceLine, sourceline_string);
|
PHPV8_EXPROP(_string, JsSourceLine, sourceline_string);
|
||||||
|
}
|
||||||
|
|
||||||
linenum = tc_message->GetLineNumber();
|
v8::Maybe<int> linenum = tc_message->GetLineNumber(context);
|
||||||
PHPV8_EXPROP(_long, JsLineNumber, linenum);
|
if (linenum.IsJust()) {
|
||||||
|
PHPV8_EXPROP(_long, JsLineNumber, linenum.FromJust());
|
||||||
|
}
|
||||||
|
|
||||||
start_col = tc_message->GetStartColumn();
|
v8::Maybe<int> start_col = tc_message->GetStartColumn(context);
|
||||||
PHPV8_EXPROP(_long, JsStartColumn, start_col);
|
if (start_col.IsJust()) {
|
||||||
|
PHPV8_EXPROP(_long, JsStartColumn, start_col.FromJust());
|
||||||
|
}
|
||||||
|
|
||||||
v8::Maybe<int> end_col = tc_message->GetEndColumn(isolate->GetEnteredContext());
|
v8::Maybe<int> end_col = tc_message->GetEndColumn(context);
|
||||||
if (end_col.IsJust()) {
|
if (end_col.IsJust()) {
|
||||||
PHPV8_EXPROP(_long, JsEndColumn, end_col.FromJust());
|
PHPV8_EXPROP(_long, JsEndColumn, end_col.FromJust());
|
||||||
}
|
}
|
||||||
|
|
||||||
spprintf(&message_string, 0, "%s:%d: %s", filename_string, linenum, exception_string);
|
spprintf(&message_string, 0, "%s:%d: %s", filename_string, linenum.FromMaybe(0), exception_string);
|
||||||
|
|
||||||
v8::String::Utf8Value stacktrace(try_catch->StackTrace());
|
v8::MaybeLocal<v8::Value> maybe_stacktrace = try_catch->StackTrace(context);
|
||||||
if (stacktrace.length() > 0) {
|
if (!maybe_stacktrace.IsEmpty()) {
|
||||||
const char* stacktrace_string = ToCString(stacktrace);
|
v8::String::Utf8Value stacktrace(isolate, maybe_stacktrace.ToLocalChecked());
|
||||||
PHPV8_EXPROP(_string, JsTrace, stacktrace_string);
|
PHPV8_EXPROP(_string, JsTrace, ToCString(stacktrace));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(try_catch->Exception()->IsObject() && try_catch->Exception()->ToObject()->InternalFieldCount() == 2) {
|
if(try_catch->Exception()->IsObject() && try_catch->Exception()->ToObject(isolate)->InternalFieldCount() == 2) {
|
||||||
zend_object *php_exception = reinterpret_cast<zend_object *>(try_catch->Exception()->ToObject()->GetAlignedPointerFromInternalField(1));
|
zend_object *php_exception = reinterpret_cast<zend_object *>(try_catch->Exception()->ToObject(isolate)->GetAlignedPointerFromInternalField(1));
|
||||||
|
|
||||||
zend_class_entry *exception_ce = zend_exception_get_default();
|
zend_class_entry *exception_ce = zend_exception_get_default();
|
||||||
if (instanceof_function(php_exception->ce, exception_ce)) {
|
if (instanceof_function(php_exception->ce, exception_ce)) {
|
||||||
@ -106,7 +115,7 @@ void v8js_create_script_exception(zval *return_value, v8::Isolate *isolate, v8::
|
|||||||
|
|
||||||
void v8js_throw_script_exception(v8::Isolate *isolate, v8::TryCatch *try_catch) /* {{{ */
|
void v8js_throw_script_exception(v8::Isolate *isolate, v8::TryCatch *try_catch) /* {{{ */
|
||||||
{
|
{
|
||||||
v8::String::Utf8Value exception(try_catch->Exception());
|
v8::String::Utf8Value exception(isolate, try_catch->Exception());
|
||||||
const char *exception_string = ToCString(exception);
|
const char *exception_string = ToCString(exception);
|
||||||
zval zexception;
|
zval zexception;
|
||||||
|
|
||||||
|
@ -24,6 +24,9 @@ v8::Local<v8::Value> v8js_wrap_generator(v8::Isolate *isolate, v8::Local<v8::Val
|
|||||||
assert(!wrapped_object.IsEmpty());
|
assert(!wrapped_object.IsEmpty());
|
||||||
assert(wrapped_object->IsObject());
|
assert(wrapped_object->IsObject());
|
||||||
|
|
||||||
|
v8js_ctx *ctx = (v8js_ctx *) isolate->GetData(0);
|
||||||
|
v8::Local<v8::Context> context = v8::Local<v8::Context>::New(isolate, ctx->context);
|
||||||
|
|
||||||
v8::TryCatch try_catch(isolate);
|
v8::TryCatch try_catch(isolate);
|
||||||
v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate, "(\
|
v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate, "(\
|
||||||
function(wrapped_object) { \
|
function(wrapped_object) { \
|
||||||
@ -37,21 +40,21 @@ function(wrapped_object) { \
|
|||||||
} \
|
} \
|
||||||
})(); \
|
})(); \
|
||||||
})");
|
})");
|
||||||
v8::Local<v8::Script> script = v8::Script::Compile(source);
|
v8::MaybeLocal<v8::Script> script = v8::Script::Compile(context, source);
|
||||||
|
|
||||||
if(script.IsEmpty()) {
|
if(script.IsEmpty()) {
|
||||||
zend_error(E_ERROR, "Failed to compile Generator object wrapper");
|
zend_error(E_ERROR, "Failed to compile Generator object wrapper");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
v8::Local<v8::Value> wrapper_fn_val = script->Run();
|
v8::MaybeLocal<v8::Value> wrapper_fn_val = script.ToLocalChecked()->Run(context);
|
||||||
|
|
||||||
if(wrapper_fn_val.IsEmpty() || !wrapper_fn_val->IsFunction()) {
|
if(wrapper_fn_val.IsEmpty() || !wrapper_fn_val.ToLocalChecked()->IsFunction()) {
|
||||||
zend_error(E_ERROR, "Failed to create Generator object wrapper function");
|
zend_error(E_ERROR, "Failed to create Generator object wrapper function");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
v8::Local<v8::Function> wrapper_fn = v8::Local<v8::Function>::Cast(wrapper_fn_val);
|
v8::Local<v8::Function> wrapper_fn = v8::Local<v8::Function>::Cast(wrapper_fn_val.ToLocalChecked());
|
||||||
v8::Local<v8::Value> *jsArgv = static_cast<v8::Local<v8::Value> *>(alloca(sizeof(v8::Local<v8::Value>)));
|
v8::Local<v8::Value> *jsArgv = static_cast<v8::Local<v8::Value> *>(alloca(sizeof(v8::Local<v8::Value>)));
|
||||||
|
|
||||||
new(&jsArgv[0]) v8::Local<v8::Value>;
|
new(&jsArgv[0]) v8::Local<v8::Value>;
|
||||||
|
@ -35,7 +35,14 @@ V8JS_METHOD(exit) /* {{{ */
|
|||||||
/* global.sleep - sleep for passed seconds */
|
/* global.sleep - sleep for passed seconds */
|
||||||
V8JS_METHOD(sleep) /* {{{ */
|
V8JS_METHOD(sleep) /* {{{ */
|
||||||
{
|
{
|
||||||
php_sleep(info[0]->Int32Value());
|
v8::Isolate *isolate = info.GetIsolate();
|
||||||
|
v8js_ctx *c = (v8js_ctx *) isolate->GetData(0);
|
||||||
|
|
||||||
|
v8::Maybe<int32_t> t = info[0]->Int32Value(v8::Local<v8::Context>::New(isolate, c->context));
|
||||||
|
|
||||||
|
if (t.IsJust()) {
|
||||||
|
php_sleep(t.FromJust());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
@ -46,7 +53,7 @@ V8JS_METHOD(print) /* {{{ */
|
|||||||
zend_long ret = 0;
|
zend_long ret = 0;
|
||||||
|
|
||||||
for (int i = 0; i < info.Length(); i++) {
|
for (int i = 0; i < info.Length(); i++) {
|
||||||
v8::String::Utf8Value str(info[i]);
|
v8::String::Utf8Value str(isolate, info[i]);
|
||||||
const char *cstr = ToCString(str);
|
const char *cstr = ToCString(str);
|
||||||
ret = PHPWRITE(cstr, strlen(cstr));
|
ret = PHPWRITE(cstr, strlen(cstr));
|
||||||
}
|
}
|
||||||
@ -57,6 +64,9 @@ V8JS_METHOD(print) /* {{{ */
|
|||||||
|
|
||||||
static void v8js_dumper(v8::Isolate *isolate, v8::Local<v8::Value> var, int level) /* {{{ */
|
static void v8js_dumper(v8::Isolate *isolate, v8::Local<v8::Value> var, int level) /* {{{ */
|
||||||
{
|
{
|
||||||
|
v8js_ctx *c = (v8js_ctx *) isolate->GetData(0);
|
||||||
|
v8::Local<v8::Context> context = v8::Local<v8::Context>::New(isolate, c->context);
|
||||||
|
|
||||||
if (level > 1) {
|
if (level > 1) {
|
||||||
php_printf("%*c", (level - 1) * 2, ' ');
|
php_printf("%*c", (level - 1) * 2, ' ');
|
||||||
}
|
}
|
||||||
@ -73,22 +83,54 @@ static void v8js_dumper(v8::Isolate *isolate, v8::Local<v8::Value> var, int leve
|
|||||||
}
|
}
|
||||||
if (var->IsInt32())
|
if (var->IsInt32())
|
||||||
{
|
{
|
||||||
php_printf("int(%ld)\n", (long) var->IntegerValue());
|
v8::Maybe<int64_t> value = var->IntegerValue(context);
|
||||||
|
if (value.IsNothing())
|
||||||
|
{
|
||||||
|
php_printf("<empty>\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
php_printf("int(%ld)\n", (long) value.FromJust());
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (var->IsUint32())
|
if (var->IsUint32())
|
||||||
{
|
{
|
||||||
php_printf("int(%lu)\n", (unsigned long) var->IntegerValue());
|
v8::Maybe<uint32_t> value = var->Uint32Value(context);
|
||||||
|
if (value.IsNothing())
|
||||||
|
{
|
||||||
|
php_printf("<empty>\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
php_printf("int(%lu)\n", (unsigned long) value.FromJust());
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (var->IsNumber())
|
if (var->IsNumber())
|
||||||
{
|
{
|
||||||
php_printf("float(%f)\n", var->NumberValue());
|
v8::Maybe<double> value = var->NumberValue(context);
|
||||||
|
if (value.IsNothing())
|
||||||
|
{
|
||||||
|
php_printf("<empty>\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
php_printf("float(%f)\n", value.FromJust());
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (var->IsBoolean())
|
if (var->IsBoolean())
|
||||||
{
|
{
|
||||||
php_printf("bool(%s)\n", var->BooleanValue() ? "true" : "false");
|
v8::Maybe<bool> value = var->BooleanValue(context);
|
||||||
|
if (value.IsNothing())
|
||||||
|
{
|
||||||
|
php_printf("<empty>\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
php_printf("bool(%s)\n", value.FromJust() ? "true" : "false");
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,16 +142,16 @@ static void v8js_dumper(v8::Isolate *isolate, v8::Local<v8::Value> var, int leve
|
|||||||
details = re->GetSource();
|
details = re->GetSource();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
details = var->ToDetailString(isolate->GetEnteredContext()).FromMaybe(v8::Local<v8::String>());
|
details = var->ToDetailString(context).FromMaybe(v8::Local<v8::String>());
|
||||||
|
|
||||||
if (try_catch.HasCaught()) {
|
if (try_catch.HasCaught()) {
|
||||||
details = V8JS_SYM("<toString threw exception>");
|
details = V8JS_SYM("<toString threw exception>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
v8::String::Utf8Value str(details);
|
v8::String::Utf8Value str(isolate, details);
|
||||||
const char *valstr = ToCString(str);
|
const char *valstr = ToCString(str);
|
||||||
size_t valstr_len = details->ToString()->Utf8Length();
|
size_t valstr_len = details->ToString(isolate)->Utf8Length(isolate);
|
||||||
|
|
||||||
if (var->IsString())
|
if (var->IsString())
|
||||||
{
|
{
|
||||||
@ -147,12 +189,12 @@ static void v8js_dumper(v8::Isolate *isolate, v8::Local<v8::Value> var, int leve
|
|||||||
else if (var->IsObject())
|
else if (var->IsObject())
|
||||||
{
|
{
|
||||||
v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(var);
|
v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(var);
|
||||||
V8JS_GET_CLASS_NAME(cname, object);
|
v8::String::Utf8Value cname(isolate, object->GetConstructorName());
|
||||||
int hash = object->GetIdentityHash();
|
int hash = object->GetIdentityHash();
|
||||||
|
|
||||||
if (var->IsFunction() && strcmp(ToCString(cname), "Closure") != 0)
|
if (var->IsFunction() && strcmp(ToCString(cname), "Closure") != 0)
|
||||||
{
|
{
|
||||||
v8::String::Utf8Value csource(object->ToString());
|
v8::String::Utf8Value csource(isolate, object->ToString(isolate));
|
||||||
php_printf("object(Closure)#%d {\n%*c%s\n", hash, level * 2 + 2, ' ', ToCString(csource));
|
php_printf("object(Closure)#%d {\n%*c%s\n", hash, level * 2 + 2, ' ', ToCString(csource));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -169,8 +211,8 @@ static void v8js_dumper(v8::Isolate *isolate, v8::Local<v8::Value> var, int leve
|
|||||||
php_printf(" (%d) {\n", length);
|
php_printf(" (%d) {\n", length);
|
||||||
|
|
||||||
for (unsigned i = 0; i < length; i++) {
|
for (unsigned i = 0; i < length; i++) {
|
||||||
v8::Local<v8::String> key = keys->Get(i)->ToString();
|
v8::Local<v8::String> key = keys->Get(i)->ToString(isolate);
|
||||||
v8::String::Utf8Value kname(key);
|
v8::String::Utf8Value kname(isolate, key);
|
||||||
php_printf("%*c[\"%s\"] =>\n", level * 2, ' ', ToCString(kname));
|
php_printf("%*c[\"%s\"] =>\n", level * 2, ' ', ToCString(kname));
|
||||||
v8js_dumper(isolate, object->Get(key), level + 1);
|
v8js_dumper(isolate, object->Get(key), level + 1);
|
||||||
}
|
}
|
||||||
@ -207,7 +249,7 @@ V8JS_METHOD(require)
|
|||||||
v8::Isolate *isolate = info.GetIsolate();
|
v8::Isolate *isolate = info.GetIsolate();
|
||||||
v8js_ctx *c = (v8js_ctx *) isolate->GetData(0);
|
v8js_ctx *c = (v8js_ctx *) isolate->GetData(0);
|
||||||
|
|
||||||
v8::String::Utf8Value module_base(info.Data());
|
v8::String::Utf8Value module_base(isolate, info.Data());
|
||||||
const char *module_base_cstr = ToCString(module_base);
|
const char *module_base_cstr = ToCString(module_base);
|
||||||
|
|
||||||
// Check that we have a module loader
|
// Check that we have a module loader
|
||||||
@ -216,7 +258,7 @@ V8JS_METHOD(require)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
v8::String::Utf8Value module_id_v8(info[0]);
|
v8::String::Utf8Value module_id_v8(isolate, info[0]);
|
||||||
const char *module_id = ToCString(module_id_v8);
|
const char *module_id = ToCString(module_id_v8);
|
||||||
char *normalised_path, *module_name;
|
char *normalised_path, *module_name;
|
||||||
|
|
||||||
@ -407,7 +449,7 @@ V8JS_METHOD(require)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(Z_TYPE(module_code) == IS_OBJECT) {
|
if(Z_TYPE(module_code) == IS_OBJECT) {
|
||||||
v8::Local<v8::Object> newobj = zval_to_v8js(&module_code, isolate)->ToObject();
|
v8::Local<v8::Object> newobj = zval_to_v8js(&module_code, isolate)->ToObject(isolate);
|
||||||
c->modules_loaded[normalised_module_id].Reset(isolate, newobj);
|
c->modules_loaded[normalised_module_id].Reset(isolate, newobj);
|
||||||
info.GetReturnValue().Set(newobj);
|
info.GetReturnValue().Set(newobj);
|
||||||
|
|
||||||
@ -435,6 +477,7 @@ V8JS_METHOD(require)
|
|||||||
|
|
||||||
// Set script identifier
|
// Set script identifier
|
||||||
v8::Local<v8::String> sname = V8JS_STR(normalised_module_id);
|
v8::Local<v8::String> sname = V8JS_STR(normalised_module_id);
|
||||||
|
v8::ScriptOrigin origin(sname);
|
||||||
|
|
||||||
if (Z_STRLEN(module_code) > std::numeric_limits<int>::max()) {
|
if (Z_STRLEN(module_code) > std::numeric_limits<int>::max()) {
|
||||||
zend_throw_exception(php_ce_v8js_exception,
|
zend_throw_exception(php_ce_v8js_exception,
|
||||||
@ -445,11 +488,11 @@ V8JS_METHOD(require)
|
|||||||
v8::Local<v8::String> source = V8JS_ZSTR(Z_STR(module_code));
|
v8::Local<v8::String> source = V8JS_ZSTR(Z_STR(module_code));
|
||||||
zval_ptr_dtor(&module_code);
|
zval_ptr_dtor(&module_code);
|
||||||
|
|
||||||
source = v8::String::Concat(V8JS_SYM("(function (exports, module, require) {"), source);
|
source = v8::String::Concat(isolate, V8JS_SYM("(function (exports, module, require) {"), source);
|
||||||
source = v8::String::Concat(source, V8JS_SYM("\n});"));
|
source = v8::String::Concat(isolate, source, V8JS_SYM("\n});"));
|
||||||
|
|
||||||
// Create and compile script
|
// Create and compile script
|
||||||
v8::Local<v8::Script> script = v8::Script::Compile(source, sname);
|
v8::MaybeLocal<v8::Script> script = v8::Script::Compile(context, source, &origin);
|
||||||
|
|
||||||
// The script will be empty if there are compile errors
|
// The script will be empty if there are compile errors
|
||||||
if (script.IsEmpty()) {
|
if (script.IsEmpty()) {
|
||||||
@ -474,7 +517,7 @@ V8JS_METHOD(require)
|
|||||||
c->modules_stack.push_back(normalised_module_id);
|
c->modules_stack.push_back(normalised_module_id);
|
||||||
|
|
||||||
// Run script to evaluate closure
|
// Run script to evaluate closure
|
||||||
v8::Local<v8::Value> module_function = script->Run();
|
v8::MaybeLocal<v8::Value> module_function = script.ToLocalChecked()->Run(context);
|
||||||
|
|
||||||
// Prepare exports & module object
|
// Prepare exports & module object
|
||||||
v8::Local<v8::Object> exports = v8::Object::New(isolate);
|
v8::Local<v8::Object> exports = v8::Object::New(isolate);
|
||||||
@ -483,7 +526,7 @@ V8JS_METHOD(require)
|
|||||||
module->Set(V8JS_SYM("id"), V8JS_STR(normalised_module_id));
|
module->Set(V8JS_SYM("id"), V8JS_STR(normalised_module_id));
|
||||||
module->Set(V8JS_SYM("exports"), exports);
|
module->Set(V8JS_SYM("exports"), exports);
|
||||||
|
|
||||||
if (module_function->IsFunction()) {
|
if (!module_function.IsEmpty() && module_function.ToLocalChecked()->IsFunction()) {
|
||||||
v8::Local<v8::Value> *jsArgv = static_cast<v8::Local<v8::Value> *>(alloca(3 * sizeof(v8::Local<v8::Value>)));
|
v8::Local<v8::Value> *jsArgv = static_cast<v8::Local<v8::Value> *>(alloca(3 * sizeof(v8::Local<v8::Value>)));
|
||||||
new(&jsArgv[0]) v8::Local<v8::Value>;
|
new(&jsArgv[0]) v8::Local<v8::Value>;
|
||||||
jsArgv[0] = exports;
|
jsArgv[0] = exports;
|
||||||
@ -495,7 +538,7 @@ V8JS_METHOD(require)
|
|||||||
jsArgv[2] = require_fn.ToLocalChecked();
|
jsArgv[2] = require_fn.ToLocalChecked();
|
||||||
|
|
||||||
// actually call the module
|
// actually call the module
|
||||||
v8::Local<v8::Function>::Cast(module_function)->Call(exports, 3, jsArgv);
|
v8::Local<v8::Function>::Cast(module_function.ToLocalChecked())->Call(exports, 3, jsArgv);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove this module and path from the stack
|
// Remove this module and path from the stack
|
||||||
@ -503,7 +546,7 @@ V8JS_METHOD(require)
|
|||||||
|
|
||||||
efree(normalised_path);
|
efree(normalised_path);
|
||||||
|
|
||||||
if (!module_function->IsFunction()) {
|
if (module_function.IsEmpty() || !module_function.ToLocalChecked()->IsFunction()) {
|
||||||
info.GetReturnValue().Set(isolate->ThrowException(V8JS_SYM("Wrapped module script failed to return function")));
|
info.GetReturnValue().Set(isolate->ThrowException(V8JS_SYM("Wrapped module script failed to return function")));
|
||||||
efree(normalised_module_id);
|
efree(normalised_module_id);
|
||||||
return;
|
return;
|
||||||
|
@ -100,9 +100,9 @@ static void v8js_call_php_func(zend_object *object, zend_function *method_ptr, v
|
|||||||
if (argc) {
|
if (argc) {
|
||||||
fci.params = (zval *) safe_emalloc(argc, sizeof(zval), 0);
|
fci.params = (zval *) safe_emalloc(argc, sizeof(zval), 0);
|
||||||
for (i = 0; i < argc; i++) {
|
for (i = 0; i < argc; i++) {
|
||||||
if (info[i]->IsObject() && info[i]->ToObject()->InternalFieldCount() == 2) {
|
if (info[i]->IsObject() && info[i]->ToObject(isolate)->InternalFieldCount() == 2) {
|
||||||
/* This is a PHP object, passed to JS and back. */
|
/* This is a PHP object, passed to JS and back. */
|
||||||
zend_object *object = reinterpret_cast<zend_object *>(info[i]->ToObject()->GetAlignedPointerFromInternalField(1));
|
zend_object *object = reinterpret_cast<zend_object *>(info[i]->ToObject(isolate)->GetAlignedPointerFromInternalField(1));
|
||||||
ZVAL_OBJ(&fci.params[i], object);
|
ZVAL_OBJ(&fci.params[i], object);
|
||||||
Z_ADDREF_P(&fci.params[i]);
|
Z_ADDREF_P(&fci.params[i]);
|
||||||
} else {
|
} else {
|
||||||
@ -404,7 +404,7 @@ static void v8js_named_property_enumerator(const v8::PropertyCallbackInfo<v8::Ar
|
|||||||
efree(prefixed);
|
efree(prefixed);
|
||||||
} else {
|
} else {
|
||||||
// even numeric indices are enumerated as strings in JavaScript
|
// even numeric indices are enumerated as strings in JavaScript
|
||||||
result->Set(result_len++, V8JS_FLOAT((double) index)->ToString());
|
result->Set(result_len++, V8JS_FLOAT((double) index)->ToString(isolate));
|
||||||
}
|
}
|
||||||
} ZEND_HASH_FOREACH_END();
|
} ZEND_HASH_FOREACH_END();
|
||||||
|
|
||||||
@ -430,9 +430,9 @@ static void v8js_invoke_callback(const v8::FunctionCallbackInfo<v8::Value>& info
|
|||||||
if (info.IsConstructCall()) {
|
if (info.IsConstructCall()) {
|
||||||
v8js_ctx *ctx = (v8js_ctx *) isolate->GetData(0);
|
v8js_ctx *ctx = (v8js_ctx *) isolate->GetData(0);
|
||||||
|
|
||||||
v8::Local<v8::String> str = self->GetConstructorName()->ToString();
|
v8::MaybeLocal<v8::String> str = self->GetConstructorName()->ToString(isolate);
|
||||||
v8::String::Utf8Value str_value(str);
|
v8::String::Utf8Value str_value(isolate, str.ToLocalChecked());
|
||||||
zend_string *constructor_name = zend_string_init(ToCString(str_value), str->Utf8Length(), 0);
|
zend_string *constructor_name = zend_string_init(ToCString(str_value), str.ToLocalChecked()->Utf8Length(isolate), 0);
|
||||||
zend_class_entry *ce = zend_lookup_class(constructor_name);
|
zend_class_entry *ce = zend_lookup_class(constructor_name);
|
||||||
zend_string_release(constructor_name);
|
zend_string_release(constructor_name);
|
||||||
|
|
||||||
@ -529,10 +529,30 @@ static void v8js_fake_call_impl(const v8::FunctionCallbackInfo<v8::Value>& info)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
v8::Local<v8::String> str = info[0]->ToString();
|
v8::MaybeLocal<v8::String> str = info[0]->ToString(isolate);
|
||||||
v8::String::Utf8Value str_value(str);
|
|
||||||
|
if (str.IsEmpty())
|
||||||
|
{
|
||||||
|
error_len = spprintf(&error, 0,
|
||||||
|
"%s::__call expect 1st parameter to be valid function name, toString() invocation failed.",
|
||||||
|
ce->name);
|
||||||
|
|
||||||
|
if (error_len > std::numeric_limits<int>::max()) {
|
||||||
|
zend_throw_exception(php_ce_v8js_exception,
|
||||||
|
"Generated error message length exceeds maximum supported length", 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return_value = V8JS_THROW(isolate, TypeError, error, static_cast<int>(error_len));
|
||||||
|
}
|
||||||
|
|
||||||
|
efree(error);
|
||||||
|
info.GetReturnValue().Set(return_value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
v8::String::Utf8Value str_value(isolate, str.ToLocalChecked());
|
||||||
const char *method_c_name = ToCString(str_value);
|
const char *method_c_name = ToCString(str_value);
|
||||||
zend_string *method_name = zend_string_init(method_c_name, str->Utf8Length(), 0);
|
zend_string *method_name = zend_string_init(method_c_name, str.ToLocalChecked()->Utf8Length(isolate), 0);
|
||||||
|
|
||||||
// okay, look up the method name and manually invoke it.
|
// okay, look up the method name and manually invoke it.
|
||||||
const zend_object_handlers *h = object->handlers;
|
const zend_object_handlers *h = object->handlers;
|
||||||
@ -577,13 +597,15 @@ static void v8js_fake_call_impl(const v8::FunctionCallbackInfo<v8::Value>& info)
|
|||||||
|
|
||||||
/* This method handles named property and method get/set/query/delete. */
|
/* This method handles named property and method get/set/query/delete. */
|
||||||
template<typename T>
|
template<typename T>
|
||||||
v8::Local<v8::Value> v8js_named_property_callback(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<T> &info, property_op_t callback_type, v8::Local<v8::Value> set_value) /* {{{ */
|
v8::Local<v8::Value> v8js_named_property_callback(v8::Local<v8::Name> property_name, const v8::PropertyCallbackInfo<T> &info, property_op_t callback_type, v8::Local<v8::Value> set_value) /* {{{ */
|
||||||
{
|
{
|
||||||
|
v8::Local<v8::String> property = v8::Local<v8::String>::Cast(property_name);
|
||||||
|
|
||||||
v8::Isolate *isolate = info.GetIsolate();
|
v8::Isolate *isolate = info.GetIsolate();
|
||||||
v8js_ctx *ctx = (v8js_ctx *) isolate->GetData(0);
|
v8js_ctx *ctx = (v8js_ctx *) isolate->GetData(0);
|
||||||
v8::String::Utf8Value cstr(property);
|
v8::String::Utf8Value cstr(isolate, property);
|
||||||
const char *name = ToCString(cstr);
|
const char *name = ToCString(cstr);
|
||||||
uint name_len = property->Utf8Length();
|
uint name_len = property->Utf8Length(isolate);
|
||||||
char *lower = estrndup(name, name_len);
|
char *lower = estrndup(name, name_len);
|
||||||
zend_string *method_name;
|
zend_string *method_name;
|
||||||
|
|
||||||
@ -780,32 +802,44 @@ v8::Local<v8::Value> v8js_named_property_callback(v8::Local<v8::String> property
|
|||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
static void v8js_named_property_getter(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info) /* {{{ */
|
static void v8js_named_property_getter(v8::Local<v8::Name> property, const v8::PropertyCallbackInfo<v8::Value> &info) /* {{{ */
|
||||||
{
|
{
|
||||||
info.GetReturnValue().Set(v8js_named_property_callback(property, info, V8JS_PROP_GETTER));
|
info.GetReturnValue().Set(v8js_named_property_callback(property, info, V8JS_PROP_GETTER));
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
static void v8js_named_property_setter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<v8::Value> &info) /* {{{ */
|
static void v8js_named_property_setter(v8::Local<v8::Name> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<v8::Value> &info) /* {{{ */
|
||||||
{
|
{
|
||||||
info.GetReturnValue().Set(v8js_named_property_callback(property, info, V8JS_PROP_SETTER, value));
|
info.GetReturnValue().Set(v8js_named_property_callback(property, info, V8JS_PROP_SETTER, value));
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
static void v8js_named_property_query(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Integer> &info) /* {{{ */
|
static void v8js_named_property_query(v8::Local<v8::Name> property, const v8::PropertyCallbackInfo<v8::Integer> &info) /* {{{ */
|
||||||
{
|
{
|
||||||
v8::Local<v8::Value> r = v8js_named_property_callback(property, info, V8JS_PROP_QUERY);
|
v8::Local<v8::Value> r = v8js_named_property_callback(property, info, V8JS_PROP_QUERY);
|
||||||
if (!r.IsEmpty()) {
|
if (r.IsEmpty()) {
|
||||||
info.GetReturnValue().Set(r->ToInteger());
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
v8::Isolate *isolate = info.GetIsolate();
|
||||||
|
v8::MaybeLocal<v8::Integer> value = r->ToInteger(isolate->GetEnteredContext());
|
||||||
|
if (!value.IsEmpty()) {
|
||||||
|
info.GetReturnValue().Set(value.ToLocalChecked());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
static void v8js_named_property_deleter(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Boolean> &info) /* {{{ */
|
static void v8js_named_property_deleter(v8::Local<v8::Name> property, const v8::PropertyCallbackInfo<v8::Boolean> &info) /* {{{ */
|
||||||
{
|
{
|
||||||
v8::Local<v8::Value> r = v8js_named_property_callback(property, info, V8JS_PROP_DELETER);
|
v8::Local<v8::Value> r = v8js_named_property_callback(property, info, V8JS_PROP_DELETER);
|
||||||
if (!r.IsEmpty()) {
|
if (r.IsEmpty()) {
|
||||||
info.GetReturnValue().Set(r->ToBoolean());
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
v8::Isolate *isolate = info.GetIsolate();
|
||||||
|
v8::MaybeLocal<v8::Boolean> value = r->ToBoolean(isolate->GetEnteredContext());
|
||||||
|
if (!value.IsEmpty()) {
|
||||||
|
info.GetReturnValue().Set(value.ToLocalChecked());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
@ -847,8 +881,8 @@ static v8::MaybeLocal<v8::Object> v8js_wrap_object(v8::Isolate *isolate, zend_cl
|
|||||||
/* We'll free persist_tpl_ when template_cache is destroyed */
|
/* We'll free persist_tpl_ when template_cache is destroyed */
|
||||||
|
|
||||||
v8::Local<v8::ObjectTemplate> inst_tpl = new_tpl->InstanceTemplate();
|
v8::Local<v8::ObjectTemplate> inst_tpl = new_tpl->InstanceTemplate();
|
||||||
v8::NamedPropertyGetterCallback getter = v8js_named_property_getter;
|
v8::GenericNamedPropertyGetterCallback getter = v8js_named_property_getter;
|
||||||
v8::NamedPropertyEnumeratorCallback enumerator = v8js_named_property_enumerator;
|
v8::GenericNamedPropertyEnumeratorCallback enumerator = v8js_named_property_enumerator;
|
||||||
|
|
||||||
/* Check for ArrayAccess object */
|
/* Check for ArrayAccess object */
|
||||||
if (V8JSG(use_array_access) && ce) {
|
if (V8JSG(use_array_access) && ce) {
|
||||||
@ -884,14 +918,14 @@ static v8::MaybeLocal<v8::Object> v8js_wrap_object(v8::Isolate *isolate, zend_cl
|
|||||||
|
|
||||||
|
|
||||||
// Finish setup of new_tpl
|
// Finish setup of new_tpl
|
||||||
inst_tpl->SetNamedPropertyHandler
|
inst_tpl->SetHandler(v8::NamedPropertyHandlerConfiguration
|
||||||
(getter, /* getter */
|
(getter, /* getter */
|
||||||
v8js_named_property_setter, /* setter */
|
v8js_named_property_setter, /* setter */
|
||||||
v8js_named_property_query, /* query */
|
v8js_named_property_query, /* query */
|
||||||
v8js_named_property_deleter, /* deleter */
|
v8js_named_property_deleter, /* deleter */
|
||||||
enumerator, /* enumerator */
|
enumerator, /* enumerator */
|
||||||
V8JS_NULL /* data */
|
V8JS_NULL /* data */
|
||||||
);
|
));
|
||||||
// add __invoke() handler
|
// add __invoke() handler
|
||||||
zend_string *invoke_str = zend_string_init
|
zend_string *invoke_str = zend_string_init
|
||||||
(ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME) - 1, 0);
|
(ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME) - 1, 0);
|
||||||
|
@ -25,7 +25,7 @@ typedef enum {
|
|||||||
} property_op_t;
|
} property_op_t;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
v8::Local<v8::Value> v8js_named_property_callback(v8::Local<v8::String> property,
|
v8::Local<v8::Value> v8js_named_property_callback(v8::Local<v8::Name> property,
|
||||||
const v8::PropertyCallbackInfo<T> &info,
|
const v8::PropertyCallbackInfo<T> &info,
|
||||||
property_op_t callback_type,
|
property_op_t callback_type,
|
||||||
v8::Local<v8::Value> set_value = v8::Local<v8::Value>());
|
v8::Local<v8::Value> set_value = v8::Local<v8::Value>());
|
||||||
|
25
v8js_v8.cc
25
v8js_v8.cc
@ -108,7 +108,7 @@ void v8js_v8_init() /* {{{ */
|
|||||||
*/
|
*/
|
||||||
void v8js_v8_call(v8js_ctx *c, zval **return_value,
|
void v8js_v8_call(v8js_ctx *c, zval **return_value,
|
||||||
long flags, long time_limit, size_t memory_limit,
|
long flags, long time_limit, size_t memory_limit,
|
||||||
std::function< v8::Local<v8::Value>(v8::Isolate *) >& v8_call) /* {{{ */
|
std::function< v8::MaybeLocal<v8::Value>(v8::Isolate *) >& v8_call) /* {{{ */
|
||||||
{
|
{
|
||||||
char *tz = NULL;
|
char *tz = NULL;
|
||||||
|
|
||||||
@ -154,7 +154,7 @@ void v8js_v8_call(v8js_ctx *c, zval **return_value,
|
|||||||
|
|
||||||
/* Execute script */
|
/* Execute script */
|
||||||
c->in_execution++;
|
c->in_execution++;
|
||||||
v8::Local<v8::Value> result = v8_call(c->isolate);
|
v8::MaybeLocal<v8::Value> result = v8_call(c->isolate);
|
||||||
c->in_execution--;
|
c->in_execution--;
|
||||||
|
|
||||||
/* Pop our context from the stack and read (possibly updated) limits
|
/* Pop our context from the stack and read (possibly updated) limits
|
||||||
@ -238,7 +238,7 @@ void v8js_v8_call(v8js_ctx *c, zval **return_value,
|
|||||||
|
|
||||||
/* Convert V8 value to PHP value */
|
/* Convert V8 value to PHP value */
|
||||||
if (return_value && !result.IsEmpty()) {
|
if (return_value && !result.IsEmpty()) {
|
||||||
v8js_to_zval(result, *return_value, flags, c->isolate);
|
v8js_to_zval(result.ToLocalChecked(), *return_value, flags, c->isolate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -262,24 +262,27 @@ void v8js_terminate_execution(v8::Isolate *isolate) /* {{{ */
|
|||||||
v8::Isolate::Scope isolate_scope(isolate);
|
v8::Isolate::Scope isolate_scope(isolate);
|
||||||
v8::HandleScope handle_scope(isolate);
|
v8::HandleScope handle_scope(isolate);
|
||||||
|
|
||||||
|
v8js_ctx *ctx = (v8js_ctx *) isolate->GetData(0);
|
||||||
|
v8::Local<v8::Context> context = v8::Local<v8::Context>::New(isolate, ctx->context);
|
||||||
|
|
||||||
v8::Local<v8::String> source = V8JS_STR("for(;;);");
|
v8::Local<v8::String> source = V8JS_STR("for(;;);");
|
||||||
v8::Local<v8::Script> script = v8::Script::Compile(source);
|
v8::Local<v8::Script> script = v8::Script::Compile(context, source).ToLocalChecked();
|
||||||
isolate->TerminateExecution();
|
isolate->TerminateExecution();
|
||||||
script->Run();
|
script->Run(context);
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
|
||||||
int v8js_get_properties_hash(v8::Local<v8::Value> jsValue, HashTable *retval, int flags, v8::Isolate *isolate) /* {{{ */
|
int v8js_get_properties_hash(v8::Local<v8::Value> jsValue, HashTable *retval, int flags, v8::Isolate *isolate) /* {{{ */
|
||||||
{
|
{
|
||||||
v8::Local<v8::Object> jsObj = jsValue->ToObject();
|
v8::Local<v8::Object> jsObj = jsValue->ToObject(isolate);
|
||||||
|
|
||||||
if (!jsObj.IsEmpty()) {
|
if (!jsObj.IsEmpty()) {
|
||||||
v8::Local<v8::Array> jsKeys = jsObj->GetPropertyNames();
|
v8::Local<v8::Array> jsKeys = jsObj->GetPropertyNames();
|
||||||
|
|
||||||
for (unsigned i = 0; i < jsKeys->Length(); i++)
|
for (unsigned i = 0; i < jsKeys->Length(); i++)
|
||||||
{
|
{
|
||||||
v8::Local<v8::String> jsKey = jsKeys->Get(i)->ToString();
|
v8::Local<v8::String> jsKey = jsKeys->Get(i)->ToString(isolate);
|
||||||
|
|
||||||
/* Skip any prototype properties */
|
/* Skip any prototype properties */
|
||||||
if (!jsObj->HasOwnProperty(isolate->GetEnteredContext(), jsKey).FromMaybe(false)
|
if (!jsObj->HasOwnProperty(isolate->GetEnteredContext(), jsKey).FromMaybe(false)
|
||||||
@ -289,15 +292,15 @@ int v8js_get_properties_hash(v8::Local<v8::Value> jsValue, HashTable *retval, in
|
|||||||
}
|
}
|
||||||
|
|
||||||
v8::Local<v8::Value> jsVal = jsObj->Get(jsKey);
|
v8::Local<v8::Value> jsVal = jsObj->Get(jsKey);
|
||||||
v8::String::Utf8Value cstr(jsKey);
|
v8::String::Utf8Value cstr(isolate, jsKey);
|
||||||
const char *c_key = ToCString(cstr);
|
const char *c_key = ToCString(cstr);
|
||||||
zend_string *key = zend_string_init(c_key, jsKey->ToString()->Utf8Length(), 0);
|
zend_string *key = zend_string_init(c_key, jsKey->ToString(isolate)->Utf8Length(isolate), 0);
|
||||||
zval value;
|
zval value;
|
||||||
ZVAL_UNDEF(&value);
|
ZVAL_UNDEF(&value);
|
||||||
|
|
||||||
if (jsVal->IsObject() && jsVal->ToObject()->InternalFieldCount() == 2) {
|
if (jsVal->IsObject() && jsVal->ToObject(isolate)->InternalFieldCount() == 2) {
|
||||||
/* This is a PHP object, passed to JS and back. */
|
/* This is a PHP object, passed to JS and back. */
|
||||||
zend_object *object = reinterpret_cast<zend_object *>(jsVal->ToObject()->GetAlignedPointerFromInternalField(1));
|
zend_object *object = reinterpret_cast<zend_object *>(jsVal->ToObject(isolate)->GetAlignedPointerFromInternalField(1));
|
||||||
ZVAL_OBJ(&value, object);
|
ZVAL_OBJ(&value, object);
|
||||||
Z_ADDREF_P(&value);
|
Z_ADDREF_P(&value);
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ static inline const char * ToCString(const v8::String::Utf8Value &value) /* {{{
|
|||||||
void v8js_v8_init();
|
void v8js_v8_init();
|
||||||
void v8js_v8_call(v8js_ctx *c, zval **return_value,
|
void v8js_v8_call(v8js_ctx *c, zval **return_value,
|
||||||
long flags, long time_limit, size_t memory_limit,
|
long flags, long time_limit, size_t memory_limit,
|
||||||
std::function< v8::Local<v8::Value>(v8::Isolate *) >& v8_call);
|
std::function< v8::MaybeLocal<v8::Value>(v8::Isolate *) >& v8_call);
|
||||||
void v8js_terminate_execution(v8::Isolate *isolate);
|
void v8js_terminate_execution(v8::Isolate *isolate);
|
||||||
|
|
||||||
/* Fetch V8 object properties */
|
/* Fetch V8 object properties */
|
||||||
|
@ -73,7 +73,7 @@ static int v8js_v8object_has_property(zval *object, zval *member, int has_set_ex
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
v8::Local<v8::Object> jsObj = v8obj->ToObject();
|
v8::Local<v8::Object> jsObj = v8obj->ToObject(isolate);
|
||||||
v8::Local<v8::String> jsKey = V8JS_STRL(Z_STRVAL_P(member), static_cast<int>(Z_STRLEN_P(member)));
|
v8::Local<v8::String> jsKey = V8JS_STRL(Z_STRVAL_P(member), static_cast<int>(Z_STRLEN_P(member)));
|
||||||
v8::Local<v8::Value> jsVal;
|
v8::Local<v8::Value> jsVal;
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ static int v8js_v8object_has_property(zval *object, zval *member, int has_set_ex
|
|||||||
retval = !( jsVal->IsNull() || jsVal->IsUndefined() );
|
retval = !( jsVal->IsNull() || jsVal->IsUndefined() );
|
||||||
} else {
|
} else {
|
||||||
/* empty() */
|
/* empty() */
|
||||||
retval = jsVal->BooleanValue();
|
retval = jsVal->BooleanValue(v8_context).FromMaybe(false);
|
||||||
/* for PHP compatibility, [] should also be empty */
|
/* for PHP compatibility, [] should also be empty */
|
||||||
if (jsVal->IsArray() && retval) {
|
if (jsVal->IsArray() && retval) {
|
||||||
v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(jsVal);
|
v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(jsVal);
|
||||||
@ -98,10 +98,10 @@ static int v8js_v8object_has_property(zval *object, zval *member, int has_set_ex
|
|||||||
}
|
}
|
||||||
/* for PHP compatibility, '0' should also be empty */
|
/* for PHP compatibility, '0' should also be empty */
|
||||||
if (jsVal->IsString() && retval) {
|
if (jsVal->IsString() && retval) {
|
||||||
v8::Local<v8::String> str = jsVal->ToString();
|
v8::MaybeLocal<v8::String> str = jsVal->ToString(isolate);
|
||||||
if (str->Length() == 1) {
|
if (!str.IsEmpty() && str.ToLocalChecked()->Length() == 1) {
|
||||||
uint16_t c = 0;
|
uint16_t c = 0;
|
||||||
str->Write(&c, 0, 1);
|
str.ToLocalChecked()->Write(isolate, &c, 0, 1);
|
||||||
if (c == '0') {
|
if (c == '0') {
|
||||||
retval = false;
|
retval = false;
|
||||||
}
|
}
|
||||||
@ -137,7 +137,7 @@ static zval *v8js_v8object_read_property(zval *object, zval *member, int type, v
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
v8::Local<v8::Object> jsObj = v8obj->ToObject();
|
v8::Local<v8::Object> jsObj = v8obj->ToObject(isolate);
|
||||||
v8::Local<v8::String> jsKey = V8JS_STRL(Z_STRVAL_P(member), static_cast<int>(Z_STRLEN_P(member)));
|
v8::Local<v8::String> jsKey = V8JS_STRL(Z_STRVAL_P(member), static_cast<int>(Z_STRLEN_P(member)));
|
||||||
v8::Local<v8::Value> jsVal;
|
v8::Local<v8::Value> jsVal;
|
||||||
|
|
||||||
@ -175,7 +175,7 @@ static void v8js_v8object_write_property(zval *object, zval *member, zval *value
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (v8obj->IsObject()) {
|
if (v8obj->IsObject()) {
|
||||||
v8obj->ToObject()->CreateDataProperty(v8_context, V8JS_SYML(Z_STRVAL_P(member), static_cast<int>(Z_STRLEN_P(member))), zval_to_v8js(value, isolate));
|
v8obj->ToObject(isolate)->CreateDataProperty(v8_context, V8JS_SYML(Z_STRVAL_P(member), static_cast<int>(Z_STRLEN_P(member))), zval_to_v8js(value, isolate));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
@ -200,7 +200,7 @@ static void v8js_v8object_unset_property(zval *object, zval *member, void **cach
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (v8obj->IsObject()) {
|
if (v8obj->IsObject()) {
|
||||||
v8obj->ToObject()->Delete(V8JS_SYML(Z_STRVAL_P(member), static_cast<int>(Z_STRLEN_P(member))));
|
v8obj->ToObject(isolate)->Delete(V8JS_SYML(Z_STRVAL_P(member), static_cast<int>(Z_STRLEN_P(member))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
@ -276,7 +276,7 @@ static zend_function *v8js_v8object_get_method(zend_object **object_ptr, zend_st
|
|||||||
v8::Local<v8::Value> v8obj = v8::Local<v8::Value>::New(isolate, obj->v8obj);
|
v8::Local<v8::Value> v8obj = v8::Local<v8::Value>::New(isolate, obj->v8obj);
|
||||||
|
|
||||||
if (!obj->v8obj.IsEmpty() && v8obj->IsObject() && !v8obj->IsFunction()) {
|
if (!obj->v8obj.IsEmpty() && v8obj->IsObject() && !v8obj->IsFunction()) {
|
||||||
v8::Local<v8::Object> jsObj = v8obj->ToObject();
|
v8::Local<v8::Object> jsObj = v8obj->ToObject(isolate);
|
||||||
|
|
||||||
if (jsObj->Has(jsKey) && jsObj->Get(jsKey)->IsFunction()) {
|
if (jsObj->Has(jsKey) && jsObj->Get(jsKey)->IsFunction()) {
|
||||||
f = (zend_function *) ecalloc(1, sizeof(*f));
|
f = (zend_function *) ecalloc(1, sizeof(*f));
|
||||||
@ -321,15 +321,16 @@ static int v8js_v8object_call_method(zend_string *method, zend_object *object, I
|
|||||||
/* std::function relies on its dtor to be executed, otherwise it leaks
|
/* std::function relies on its dtor to be executed, otherwise it leaks
|
||||||
* some memory on bailout. */
|
* some memory on bailout. */
|
||||||
{
|
{
|
||||||
std::function< v8::Local<v8::Value>(v8::Isolate *) > v8_call = [obj, method, argc, argv, object, &return_value](v8::Isolate *isolate) {
|
std::function< v8::MaybeLocal<v8::Value>(v8::Isolate *) > v8_call = [obj, method, argc, argv, object, &return_value](v8::Isolate *isolate) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
|
v8::Local<v8::Context> context = v8::Local<v8::Context>::New(isolate, obj->ctx->context);
|
||||||
v8::Local<v8::String> method_name = V8JS_SYML(ZSTR_VAL(method), static_cast<int>(ZSTR_LEN(method)));
|
v8::Local<v8::String> method_name = V8JS_SYML(ZSTR_VAL(method), static_cast<int>(ZSTR_LEN(method)));
|
||||||
v8::Local<v8::Object> v8obj = v8::Local<v8::Value>::New(isolate, obj->v8obj)->ToObject();
|
v8::Local<v8::Object> v8obj = v8::Local<v8::Value>::New(isolate, obj->v8obj)->ToObject(isolate);
|
||||||
v8::Local<v8::Object> thisObj;
|
v8::Local<v8::Object> thisObj;
|
||||||
v8::Local<v8::Function> cb;
|
v8::Local<v8::Function> cb;
|
||||||
|
|
||||||
if (method_name->Equals(V8JS_SYM(V8JS_V8_INVOKE_FUNC_NAME))) {
|
if (method_name->Equals(context, V8JS_SYM(V8JS_V8_INVOKE_FUNC_NAME)).FromMaybe(false)) {
|
||||||
cb = v8::Local<v8::Function>::Cast(v8obj);
|
cb = v8::Local<v8::Function>::Cast(v8obj);
|
||||||
} else {
|
} else {
|
||||||
cb = v8::Local<v8::Function>::Cast(v8obj->Get(method_name));
|
cb = v8::Local<v8::Function>::Cast(v8obj->Get(method_name));
|
||||||
@ -545,9 +546,9 @@ static void v8js_v8generator_next(v8js_v8generator *g) /* {{{ */
|
|||||||
/* std::function relies on its dtor to be executed, otherwise it leaks
|
/* std::function relies on its dtor to be executed, otherwise it leaks
|
||||||
* some memory on bailout. */
|
* some memory on bailout. */
|
||||||
{
|
{
|
||||||
std::function< v8::Local<v8::Value>(v8::Isolate *) > v8_call = [g](v8::Isolate *isolate) {
|
std::function< v8::MaybeLocal<v8::Value>(v8::Isolate *) > v8_call = [g](v8::Isolate *isolate) {
|
||||||
v8::Local<v8::String> method_name = V8JS_STR("next");
|
v8::Local<v8::String> method_name = V8JS_STR("next");
|
||||||
v8::Local<v8::Object> v8obj = v8::Local<v8::Value>::New(isolate, g->v8obj.v8obj)->ToObject();
|
v8::Local<v8::Object> v8obj = v8::Local<v8::Value>::New(isolate, g->v8obj.v8obj)->ToObject(isolate);
|
||||||
v8::Local<v8::Function> cb = v8::Local<v8::Function>::Cast(v8obj->Get(method_name));;
|
v8::Local<v8::Function> cb = v8::Local<v8::Function>::Cast(v8obj->Get(method_name));;
|
||||||
|
|
||||||
v8::Local<v8::Value> result = cb->Call(v8obj, 0, NULL);
|
v8::Local<v8::Value> result = cb->Call(v8obj, 0, NULL);
|
||||||
@ -563,7 +564,7 @@ static void v8js_v8generator_next(v8js_v8generator *g) /* {{{ */
|
|||||||
return V8JS_NULL;
|
return V8JS_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
v8::Local<v8::Object> resultObj = result->ToObject();
|
v8::Local<v8::Object> resultObj = result->ToObject(isolate);
|
||||||
v8::Local<v8::Value> val = resultObj->Get(V8JS_STR("value"));
|
v8::Local<v8::Value> val = resultObj->Get(V8JS_STR("value"));
|
||||||
v8::Local<v8::Value> done = resultObj->Get(V8JS_STR("done"));
|
v8::Local<v8::Value> done = resultObj->Get(V8JS_STR("done"));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user