Index: src/arm/lithium-codegen-arm.cc |
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc |
index 445ee62ad6e6378c7275c9750b8bcdc595cadaca..100f4d2fdf9be1616265a71a90e3041870214009 100644 |
--- a/src/arm/lithium-codegen-arm.cc |
+++ b/src/arm/lithium-codegen-arm.cc |
@@ -146,6 +146,20 @@ bool LCodeGen::GeneratePrologue() { |
// fp: Caller's frame pointer. |
// lr: Caller's pc. |
+ // Strict mode functions need to replace the receiver with undefined |
+ // when called as functions (without an explicit receiver |
+ // object). r5 is zero for method calls and non-zero for function |
+ // calls. |
+ if (info_->is_strict_mode()) { |
+ Label ok; |
+ __ cmp(r5, Operand(0)); |
+ __ b(eq, &ok); |
+ int receiver_offset = scope()->num_parameters() * kPointerSize; |
+ __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); |
+ __ str(r2, MemOperand(sp, receiver_offset)); |
+ __ bind(&ok); |
+ } |
+ |
__ stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit()); |
__ add(fp, sp, Operand(2 * kPointerSize)); // Adjust FP to point to saved FP. |
@@ -2798,7 +2812,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()) || |
@@ -2818,6 +2833,7 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function, |
RecordPosition(pointers->position()); |
// Invoke function. |
+ __ SetCallKind(r5, call_kind); |
__ ldr(ip, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); |
__ Call(ip); |
@@ -2832,7 +2848,10 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function, |
void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { |
ASSERT(ToRegister(instr->result()).is(r0)); |
__ mov(r1, Operand(instr->function())); |
- CallKnownFunction(instr->function(), instr->arity(), instr); |
+ CallKnownFunction(instr->function(), |
+ instr->arity(), |
+ instr, |
+ CALL_AS_METHOD); |
} |
@@ -3214,10 +3233,11 @@ void LCodeGen::DoCallNamed(LCallNamed* instr) { |
ASSERT(ToRegister(instr->result()).is(r0)); |
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); |
__ mov(r2, Operand(instr->name())); |
- CallCode(ic, RelocInfo::CODE_TARGET, instr); |
+ CallCode(ic, mode, instr); |
// Restore context register. |
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
} |
@@ -3227,7 +3247,7 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) { |
ASSERT(ToRegister(instr->result()).is(r0)); |
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); |
__ Drop(1); |
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
@@ -3238,10 +3258,11 @@ void LCodeGen::DoCallGlobal(LCallGlobal* instr) { |
ASSERT(ToRegister(instr->result()).is(r0)); |
int arity = instr->arity(); |
+ RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT; |
Handle<Code> ic = |
- isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP); |
+ isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode); |
__ mov(r2, Operand(instr->name())); |
- CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr); |
+ CallCode(ic, mode, instr); |
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
} |
@@ -3249,7 +3270,7 @@ void LCodeGen::DoCallGlobal(LCallGlobal* instr) { |
void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { |
ASSERT(ToRegister(instr->result()).is(r0)); |
__ mov(r1, Operand(instr->target())); |
- CallKnownFunction(instr->target(), instr->arity(), instr); |
+ CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION); |
} |