| Index: src/execution.cc
|
| diff --git a/src/execution.cc b/src/execution.cc
|
| index 2fc376ab95b4fafb3ccfc931364a49a03ca4dd51..2496439ca3c14891ab7ba25c723958209a61cc3a 100644
|
| --- a/src/execution.cc
|
| +++ b/src/execution.cc
|
| @@ -53,26 +53,21 @@
|
| }
|
|
|
|
|
| -namespace {
|
| -
|
| -MUST_USE_RESULT MaybeHandle<Object> Invoke(bool is_construct,
|
| - Handle<JSFunction> function,
|
| - Handle<Object> receiver, int argc,
|
| - Handle<Object> args[]) {
|
| - Isolate* const isolate = function->GetIsolate();
|
| -
|
| - // Convert calls on global objects to be calls on the global
|
| - // receiver instead to avoid having a 'this' pointer which refers
|
| - // directly to a global object.
|
| - if (receiver->IsGlobalObject()) {
|
| - receiver =
|
| - handle(Handle<GlobalObject>::cast(receiver)->global_proxy(), isolate);
|
| - }
|
| +MUST_USE_RESULT static MaybeHandle<Object> Invoke(
|
| + bool is_construct,
|
| + Handle<JSFunction> function,
|
| + Handle<Object> receiver,
|
| + int argc,
|
| + Handle<Object> args[]) {
|
| + Isolate* isolate = function->GetIsolate();
|
|
|
| // api callbacks can be called directly.
|
| if (!is_construct && function->shared()->IsApiFunction()) {
|
| SaveContext save(isolate);
|
| isolate->set_context(function->context());
|
| + if (receiver->IsGlobalObject()) {
|
| + receiver = handle(Handle<GlobalObject>::cast(receiver)->global_proxy());
|
| + }
|
| DCHECK(function->context()->global_object()->IsGlobalObject());
|
| auto value = Builtins::InvokeApiFunction(function, receiver, argc, args);
|
| bool has_exception = value.is_null();
|
| @@ -108,6 +103,13 @@
|
| ? isolate->factory()->js_construct_entry_code()
|
| : isolate->factory()->js_entry_code();
|
|
|
| + // Convert calls on global objects to be calls on the global
|
| + // receiver instead to avoid having a 'this' pointer which refers
|
| + // directly to a global object.
|
| + if (receiver->IsGlobalObject()) {
|
| + receiver = handle(Handle<GlobalObject>::cast(receiver)->global_proxy());
|
| + }
|
| +
|
| // Make sure that the global object of the context we're about to
|
| // make the current one is indeed a global object.
|
| DCHECK(function->context()->global_object()->IsGlobalObject());
|
| @@ -120,12 +122,13 @@
|
| JSEntryFunction stub_entry = FUNCTION_CAST<JSEntryFunction>(code->entry());
|
|
|
| // Call the function through the right JS entry stub.
|
| - byte* ignored = nullptr; // TODO(bmeurer): Remove this altogether.
|
| + byte* function_entry = function->code()->entry();
|
| JSFunction* func = *function;
|
| Object* recv = *receiver;
|
| Object*** argv = reinterpret_cast<Object***>(args);
|
| if (FLAG_profile_deserialization) PrintDeserializedCodeInfo(function);
|
| - value = CALL_GENERATED_CODE(stub_entry, ignored, func, recv, argc, argv);
|
| + value =
|
| + CALL_GENERATED_CODE(stub_entry, function_entry, func, recv, argc, argv);
|
| }
|
|
|
| #ifdef VERIFY_HEAP
|
| @@ -151,17 +154,30 @@
|
| return Handle<Object>(value, isolate);
|
| }
|
|
|
| -} // namespace
|
| -
|
| -
|
| -MaybeHandle<Object> Execution::Call(Isolate* isolate, Handle<Object> callable,
|
| - Handle<Object> receiver, int argc,
|
| - Handle<Object> argv[]) {
|
| +
|
| +MaybeHandle<Object> Execution::Call(Isolate* isolate,
|
| + Handle<Object> callable,
|
| + Handle<Object> receiver,
|
| + int argc,
|
| + Handle<Object> argv[],
|
| + bool convert_receiver) {
|
| if (!callable->IsJSFunction()) {
|
| ASSIGN_RETURN_ON_EXCEPTION(isolate, callable,
|
| GetFunctionDelegate(isolate, callable), Object);
|
| }
|
| Handle<JSFunction> func = Handle<JSFunction>::cast(callable);
|
| +
|
| + // In sloppy mode, convert receiver.
|
| + if (convert_receiver && !receiver->IsJSReceiver() &&
|
| + !func->shared()->native() && is_sloppy(func->shared()->language_mode())) {
|
| + if (receiver->IsUndefined() || receiver->IsNull()) {
|
| + receiver = handle(func->global_proxy());
|
| + DCHECK(!receiver->IsJSBuiltinsObject());
|
| + } else {
|
| + ASSIGN_RETURN_ON_EXCEPTION(
|
| + isolate, receiver, ToObject(isolate, receiver), Object);
|
| + }
|
| + }
|
|
|
| return Invoke(false, func, receiver, argc, argv);
|
| }
|
| @@ -191,7 +207,7 @@
|
| catcher.SetVerbose(false);
|
| catcher.SetCaptureMessage(false);
|
|
|
| - maybe_result = Call(isolate, func, receiver, argc, args);
|
| + maybe_result = Invoke(false, func, receiver, argc, args);
|
|
|
| if (maybe_result.is_null()) {
|
| DCHECK(catcher.HasCaught());
|
|
|