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 ...@@ -4153,7 +4153,8 @@ class RelocatableArguments
} // namespace } // namespace
MaybeHandle<Object> Builtins::InvokeApiFunction(Handle<HeapObject> function, MaybeHandle<Object> Builtins::InvokeApiFunction(bool is_construct,
Handle<HeapObject> function,
Handle<Object> receiver, Handle<Object> receiver,
int argc, int argc,
Handle<Object> args[]) { Handle<Object> args[]) {
...@@ -4175,7 +4176,8 @@ MaybeHandle<Object> Builtins::InvokeApiFunction(Handle<HeapObject> function, ...@@ -4175,7 +4176,8 @@ MaybeHandle<Object> Builtins::InvokeApiFunction(Handle<HeapObject> function,
{ {
auto isolate = function->GetIsolate(); auto isolate = function->GetIsolate();
RelocatableArguments arguments(isolate, argc + 2, &argv[argc + 1]); 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) { if (argv != small_argv) {
delete[] argv; delete[] argv;
......
...@@ -398,8 +398,8 @@ class Builtins { ...@@ -398,8 +398,8 @@ class Builtins {
bool is_initialized() const { return initialized_; } bool is_initialized() const { return initialized_; }
MUST_USE_RESULT static MaybeHandle<Object> InvokeApiFunction( MUST_USE_RESULT static MaybeHandle<Object> InvokeApiFunction(
Handle<HeapObject> function, Handle<Object> receiver, int argc, bool is_construct, Handle<HeapObject> function, Handle<Object> receiver,
Handle<Object> args[]); int argc, Handle<Object> args[]);
private: private:
Builtins(); Builtins();
......
...@@ -59,6 +59,45 @@ MUST_USE_RESULT MaybeHandle<Object> Invoke(Isolate* isolate, bool is_construct, ...@@ -59,6 +59,45 @@ MUST_USE_RESULT MaybeHandle<Object> Invoke(Isolate* isolate, bool is_construct,
Handle<Object> new_target) { Handle<Object> new_target) {
DCHECK(!receiver->IsJSGlobalObject()); 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. // Entering JavaScript.
VMState<JS> state(isolate); VMState<JS> state(isolate);
CHECK(AllowJavascriptExecution::IsAllowed(isolate)); CHECK(AllowJavascriptExecution::IsAllowed(isolate));
...@@ -131,35 +170,6 @@ MaybeHandle<Object> Execution::Call(Isolate* isolate, Handle<Object> callable, ...@@ -131,35 +170,6 @@ MaybeHandle<Object> Execution::Call(Isolate* isolate, Handle<Object> callable,
receiver = receiver =
handle(Handle<JSGlobalObject>::cast(receiver)->global_proxy(), isolate); 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, return Invoke(isolate, false, callable, receiver, argc, argv,
isolate->factory()->undefined_value()); isolate->factory()->undefined_value());
} }
......
...@@ -1081,7 +1081,8 @@ MaybeHandle<Object> Object::GetPropertyWithAccessor(LookupIterator* it) { ...@@ -1081,7 +1081,8 @@ MaybeHandle<Object> Object::GetPropertyWithAccessor(LookupIterator* it) {
Handle<Object> getter(AccessorPair::cast(*structure)->getter(), isolate); Handle<Object> getter(AccessorPair::cast(*structure)->getter(), isolate);
if (getter->IsFunctionTemplateInfo()) { if (getter->IsFunctionTemplateInfo()) {
auto result = Builtins::InvokeApiFunction( auto result = Builtins::InvokeApiFunction(
Handle<FunctionTemplateInfo>::cast(getter), receiver, 0, nullptr); false, Handle<FunctionTemplateInfo>::cast(getter), receiver, 0,
nullptr);
if (isolate->has_pending_exception()) { if (isolate->has_pending_exception()) {
return MaybeHandle<Object>(); return MaybeHandle<Object>();
} }
...@@ -1150,9 +1151,9 @@ Maybe<bool> Object::SetPropertyWithAccessor(LookupIterator* it, ...@@ -1150,9 +1151,9 @@ Maybe<bool> Object::SetPropertyWithAccessor(LookupIterator* it,
Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate); Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate);
if (setter->IsFunctionTemplateInfo()) { if (setter->IsFunctionTemplateInfo()) {
Handle<Object> argv[] = {value}; Handle<Object> argv[] = {value};
auto result = auto result = Builtins::InvokeApiFunction(
Builtins::InvokeApiFunction(Handle<FunctionTemplateInfo>::cast(setter), false, Handle<FunctionTemplateInfo>::cast(setter), receiver,
receiver, arraysize(argv), argv); arraysize(argv), argv);
if (isolate->has_pending_exception()) { if (isolate->has_pending_exception()) {
return Nothing<bool>(); 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