Chromium Code Reviews| Index: src/execution.cc |
| diff --git a/src/execution.cc b/src/execution.cc |
| index e6a569f33d967d66bdfc0065ef10c7117a3a091a..ada638b1d8107e2b39c205b853996877dcc72c26 100644 |
| --- a/src/execution.cc |
| +++ b/src/execution.cc |
| @@ -59,6 +59,40 @@ 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); |
| + 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 +165,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()); |
| } |
| @@ -176,6 +181,13 @@ MaybeHandle<Object> Execution::New(Handle<JSFunction> constructor, int argc, |
| MaybeHandle<Object> Execution::New(Isolate* isolate, Handle<Object> constructor, |
| Handle<Object> new_target, int argc, |
| Handle<Object> argv[]) { |
| + if (!constructor->IsConstructor() && |
|
Toon Verwaest
2016/03/01 17:30:35
Move up to the fast-path in the is_construct case.
|
| + (!constructor->IsJSFunction() || |
| + !Handle<JSFunction>::cast(constructor)->shared()->is_generator())) { |
| + THROW_NEW_ERROR(isolate, |
| + NewTypeError(MessageTemplate::kNotConstructor, constructor), |
| + Object); |
| + } |
| return Invoke(isolate, true, constructor, |
| isolate->factory()->undefined_value(), argc, argv, new_target); |
| } |