Index: src/x64/lithium-codegen-x64.cc |
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc |
index 7c78a4e790dd11e32ce90f37781478729c5339cb..97177de6ea3577b68f48a4933c649de2b3aab0c2 100644 |
--- a/src/x64/lithium-codegen-x64.cc |
+++ b/src/x64/lithium-codegen-x64.cc |
@@ -140,6 +140,21 @@ bool LCodeGen::GeneratePrologue() { |
} |
#endif |
+ // Strict mode functions need to replace the receiver with undefined |
+ // when called as functions (without an explicit receiver |
+ // object). rcx is zero for method calls and non-zero for function |
+ // calls. |
+ if (info_->is_strict_mode()) { |
+ Label ok; |
+ __ testq(rcx, rcx); |
+ __ j(zero, &ok, Label::kNear); |
+ // +1 for return address. |
+ int receiver_offset = (scope()->num_parameters() + 1) * kPointerSize; |
+ __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex); |
+ __ movq(Operand(rsp, receiver_offset), kScratchRegister); |
+ __ bind(&ok); |
+ } |
+ |
__ push(rbp); // Caller's frame pointer. |
__ movq(rbp, rsp); |
__ push(rsi); // Callee's context. |
@@ -2688,7 +2703,8 @@ void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { |
void LCodeGen::CallKnownFunction(Handle<JSFunction> function, |
int arity, |
- LInstruction* instr) { |
+ LInstruction* instr, |
+ CallKind call_kind) { |
// Change context if needed. |
bool change_context = |
(info()->closure()->context() != function->context()) || |
@@ -2708,6 +2724,7 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function, |
RecordPosition(pointers->position()); |
// Invoke function. |
+ __ SetCallKind(rcx, call_kind); |
if (*function == *info()->closure()) { |
__ CallSelf(); |
} else { |
@@ -2725,7 +2742,10 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function, |
void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { |
ASSERT(ToRegister(instr->result()).is(rax)); |
__ Move(rdi, instr->function()); |
- CallKnownFunction(instr->function(), instr->arity(), instr); |
+ CallKnownFunction(instr->function(), |
+ instr->arity(), |
+ instr, |
+ CALL_AS_METHOD); |
} |
@@ -3076,10 +3096,11 @@ void LCodeGen::DoCallNamed(LCallNamed* instr) { |
ASSERT(ToRegister(instr->result()).is(rax)); |
int arity = instr->arity(); |
- Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize( |
- arity, NOT_IN_LOOP); |
+ RelocInfo::Mode mode = RelocInfo::CODE_TARGET; |
+ Handle<Code> ic = |
+ isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode); |
__ Move(rcx, instr->name()); |
- CallCode(ic, RelocInfo::CODE_TARGET, instr); |
+ CallCode(ic, mode, instr); |
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
} |
@@ -3088,7 +3109,7 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) { |
ASSERT(ToRegister(instr->result()).is(rax)); |
int arity = instr->arity(); |
- CallFunctionStub stub(arity, NOT_IN_LOOP, RECEIVER_MIGHT_BE_VALUE); |
+ CallFunctionStub stub(arity, NOT_IN_LOOP, RECEIVER_MIGHT_BE_IMPLICIT); |
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
__ Drop(1); |
@@ -3098,10 +3119,11 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) { |
void LCodeGen::DoCallGlobal(LCallGlobal* instr) { |
ASSERT(ToRegister(instr->result()).is(rax)); |
int arity = instr->arity(); |
- Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize( |
- arity, NOT_IN_LOOP); |
+ RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT; |
+ Handle<Code> ic = |
+ isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode); |
__ Move(rcx, instr->name()); |
- CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr); |
+ CallCode(ic, mode, instr); |
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
} |
@@ -3109,7 +3131,7 @@ void LCodeGen::DoCallGlobal(LCallGlobal* instr) { |
void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { |
ASSERT(ToRegister(instr->result()).is(rax)); |
__ Move(rdi, instr->target()); |
- CallKnownFunction(instr->target(), instr->arity(), instr); |
+ CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION); |
} |