| Index: src/x64/code-stubs-x64.cc
|
| diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
|
| index 6c09d2fca3c87a2882144a35e957331546946285..6670510e13302ec852fbf1a87a0adb295074a4a1 100644
|
| --- a/src/x64/code-stubs-x64.cc
|
| +++ b/src/x64/code-stubs-x64.cc
|
| @@ -2947,30 +2947,22 @@ void StackCheckStub::Generate(MacroAssembler* masm) {
|
| void CallFunctionStub::Generate(MacroAssembler* masm) {
|
| Label slow;
|
|
|
| - // If the receiver might be a value (string, number or boolean) check for this
|
| - // and box it if it is.
|
| - if (ReceiverMightBeValue()) {
|
| + // The receiver might implicitly be the global object. This is
|
| + // indicated by passing the hole as the receiver to the call
|
| + // function stub.
|
| + if (ReceiverMightBeImplicit()) {
|
| + Label call;
|
| // Get the receiver from the stack.
|
| // +1 ~ return address
|
| - Label receiver_is_value, receiver_is_js_object;
|
| __ movq(rax, Operand(rsp, (argc_ + 1) * kPointerSize));
|
| -
|
| - // Check if receiver is a smi (which is a number value).
|
| - __ JumpIfSmi(rax, &receiver_is_value);
|
| -
|
| - // Check if the receiver is a valid JS object.
|
| - __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rdi);
|
| - __ j(above_equal, &receiver_is_js_object);
|
| -
|
| - // Call the runtime to box the value.
|
| - __ bind(&receiver_is_value);
|
| - __ EnterInternalFrame();
|
| - __ push(rax);
|
| - __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
|
| - __ LeaveInternalFrame();
|
| - __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rax);
|
| -
|
| - __ bind(&receiver_is_js_object);
|
| + // Call as function is indicated with the hole.
|
| + __ CompareRoot(rax, Heap::kTheHoleValueRootIndex);
|
| + __ j(not_equal, &call, Label::kNear);
|
| + // Patch the receiver on the stack with the global receiver object.
|
| + __ movq(rbx, GlobalObjectOperand());
|
| + __ movq(rbx, FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset));
|
| + __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rbx);
|
| + __ bind(&call);
|
| }
|
|
|
| // Get the function to call from the stack.
|
| @@ -2985,7 +2977,19 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
|
|
|
| // Fast-case: Just invoke the function.
|
| ParameterCount actual(argc_);
|
| - __ InvokeFunction(rdi, actual, JUMP_FUNCTION);
|
| +
|
| + if (ReceiverMightBeImplicit()) {
|
| + Label call_as_function;
|
| + __ CompareRoot(rax, Heap::kTheHoleValueRootIndex);
|
| + __ j(equal, &call_as_function);
|
| + __ InvokeFunction(rdi, actual, JUMP_FUNCTION);
|
| + __ bind(&call_as_function);
|
| + }
|
| + __ InvokeFunction(rdi,
|
| + actual,
|
| + JUMP_FUNCTION,
|
| + NullCallWrapper(),
|
| + CALL_AS_FUNCTION);
|
|
|
| // Slow-case: Non-function called.
|
| __ bind(&slow);
|
|
|