Index: src/x64/code-stubs-x64.cc |
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc |
index d04e976e0dbe3e21c7434d3c2ad51c9591f2cd9e..b029036cc36ca4e3bf2a9d494f3cd4e83fccff45 100644 |
--- a/src/x64/code-stubs-x64.cc |
+++ b/src/x64/code-stubs-x64.cc |
@@ -2553,29 +2553,40 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { |
Label slow, non_function; |
StackArgumentsAccessor args(rsp, argc_); |
+ // Check that the function really is a JavaScript function. |
+ __ JumpIfSmi(rdi, &non_function); |
+ |
// 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. |
- __ movq(rax, args.GetReceiverOperand()); |
- // Call as function is indicated with the hole. |
- __ CompareRoot(rax, Heap::kTheHoleValueRootIndex); |
- __ j(not_equal, &call, Label::kNear); |
+ if (ReceiverMightBeImplicit() || ReceiverIsImplicit()) { |
+ Label call, patch_current_context; |
+ if (ReceiverMightBeImplicit()) { |
+ // Get the receiver from the stack. |
+ __ movq(rax, args.GetReceiverOperand()); |
+ // 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. |
+ // Goto slow case if we do not have a function. |
+ __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); |
+ __ j(not_equal, &patch_current_context); |
+ CallStubCompiler::FetchGlobalProxy(masm, rdi, rcx); |
+ __ movq(args.GetReceiverOperand(), rcx); |
+ __ jmp(&call, Label::kNear); |
+ __ bind(&patch_current_context); |
__ movq(rcx, GlobalObjectOperand()); |
__ movq(rcx, FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset)); |
__ movq(args.GetReceiverOperand(), rcx); |
+ __ jmp(&slow); |
__ bind(&call); |
+ } else { |
+ // Goto slow case if we do not have a function. |
+ __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); |
+ __ j(not_equal, &slow); |
} |
- // Check that the function really is a JavaScript function. |
- __ JumpIfSmi(rdi, &non_function); |
- // Goto slow case if we do not have a function. |
- __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); |
- __ j(not_equal, &slow); |
- |
if (RecordCallTarget()) { |
GenerateRecordCallTarget(masm); |
} |