Commit 21a5bfbd authored by jochen's avatar jochen Committed by Commit bot

[api] Don't go to javascript to construct API functions

BUG=
R=bmeurer@chromium.org,verwaest@chromium.org

Review URL: https://codereview.chromium.org/1756433002

Cr-Commit-Position: refs/heads/master@{#34411}
parent 49587f68
......@@ -4153,7 +4153,8 @@ class RelocatableArguments
} // namespace
MaybeHandle<Object> Builtins::InvokeApiFunction(Handle<HeapObject> function,
MaybeHandle<Object> Builtins::InvokeApiFunction(bool is_construct,
Handle<HeapObject> function,
Handle<Object> receiver,
int argc,
Handle<Object> args[]) {
......@@ -4175,7 +4176,8 @@ MaybeHandle<Object> Builtins::InvokeApiFunction(Handle<HeapObject> function,
{
auto isolate = function->GetIsolate();
RelocatableArguments arguments(isolate, argc + 2, &argv[argc + 1]);
result = HandleApiCallHelper<false>(isolate, arguments);
result = is_construct ? HandleApiCallHelper<true>(isolate, arguments)
: HandleApiCallHelper<false>(isolate, arguments);
}
if (argv != small_argv) {
delete[] argv;
......
......@@ -398,8 +398,8 @@ class Builtins {
bool is_initialized() const { return initialized_; }
MUST_USE_RESULT static MaybeHandle<Object> InvokeApiFunction(
Handle<HeapObject> function, Handle<Object> receiver, int argc,
Handle<Object> args[]);
bool is_construct, Handle<HeapObject> function, Handle<Object> receiver,
int argc, Handle<Object> args[]);
private:
Builtins();
......
......@@ -59,6 +59,45 @@ MUST_USE_RESULT MaybeHandle<Object> Invoke(Isolate* isolate, bool is_construct,
Handle<Object> new_target) {
DCHECK(!receiver->IsJSGlobalObject());
// API callbacks can be called directly.
if (target->IsJSFunction() &&
Handle<JSFunction>::cast(target)->shared()->IsApiFunction()) {
Handle<JSFunction> function = Handle<JSFunction>::cast(target);
if (!function->IsConstructor()) {
THROW_NEW_ERROR(isolate,
NewTypeError(MessageTemplate::kNotConstructor, function),
Object);
}
SaveContext save(isolate);
isolate->set_context(function->context());
// Do proper receiver conversion for non-strict mode api functions.
if (!receiver->IsJSReceiver() &&
is_sloppy(function->shared()->language_mode())) {
if (receiver->IsUndefined() || receiver->IsNull()) {
if (is_construct) {
receiver = isolate->factory()->the_hole_value();
} else {
receiver = handle(function->global_proxy(), isolate);
}
} else {
ASSIGN_RETURN_ON_EXCEPTION(isolate, receiver,
Object::ToObject(isolate, receiver), Object);
}
}
DCHECK(function->context()->global_object()->IsJSGlobalObject());
auto value = Builtins::InvokeApiFunction(is_construct, function, receiver,
argc, args);
bool has_exception = value.is_null();
DCHECK(has_exception == isolate->has_pending_exception());
if (has_exception) {
isolate->ReportPendingMessages();
return MaybeHandle<Object>();
} else {
isolate->clear_pending_message();
}
return value;
}
// Entering JavaScript.
VMState<JS> state(isolate);
CHECK(AllowJavascriptExecution::IsAllowed(isolate));
......@@ -131,35 +170,6 @@ MaybeHandle<Object> Execution::Call(Isolate* isolate, Handle<Object> callable,
receiver =
handle(Handle<JSGlobalObject>::cast(receiver)->global_proxy(), isolate);
}
// api callbacks can be called directly.
if (callable->IsJSFunction() &&
Handle<JSFunction>::cast(callable)->shared()->IsApiFunction()) {
Handle<JSFunction> function = Handle<JSFunction>::cast(callable);
SaveContext save(isolate);
isolate->set_context(function->context());
// Do proper receiver conversion for non-strict mode api functions.
if (!receiver->IsJSReceiver() &&
is_sloppy(function->shared()->language_mode())) {
if (receiver->IsUndefined() || receiver->IsNull()) {
receiver = handle(function->global_proxy(), isolate);
} else {
ASSIGN_RETURN_ON_EXCEPTION(isolate, receiver,
Object::ToObject(isolate, receiver), Object);
}
}
DCHECK(function->context()->global_object()->IsJSGlobalObject());
auto value = Builtins::InvokeApiFunction(function, receiver, argc, argv);
bool has_exception = value.is_null();
DCHECK(has_exception == isolate->has_pending_exception());
if (has_exception) {
isolate->ReportPendingMessages();
return MaybeHandle<Object>();
} else {
isolate->clear_pending_message();
}
return value;
}
return Invoke(isolate, false, callable, receiver, argc, argv,
isolate->factory()->undefined_value());
}
......
......@@ -1081,7 +1081,8 @@ MaybeHandle<Object> Object::GetPropertyWithAccessor(LookupIterator* it) {
Handle<Object> getter(AccessorPair::cast(*structure)->getter(), isolate);
if (getter->IsFunctionTemplateInfo()) {
auto result = Builtins::InvokeApiFunction(
Handle<FunctionTemplateInfo>::cast(getter), receiver, 0, nullptr);
false, Handle<FunctionTemplateInfo>::cast(getter), receiver, 0,
nullptr);
if (isolate->has_pending_exception()) {
return MaybeHandle<Object>();
}
......@@ -1150,9 +1151,9 @@ Maybe<bool> Object::SetPropertyWithAccessor(LookupIterator* it,
Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate);
if (setter->IsFunctionTemplateInfo()) {
Handle<Object> argv[] = {value};
auto result =
Builtins::InvokeApiFunction(Handle<FunctionTemplateInfo>::cast(setter),
receiver, arraysize(argv), argv);
auto result = Builtins::InvokeApiFunction(
false, Handle<FunctionTemplateInfo>::cast(setter), receiver,
arraysize(argv), argv);
if (isolate->has_pending_exception()) {
return Nothing<bool>();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment