Index: src/arm/lithium-codegen-arm.cc |
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc |
index 95ee13a343dc5afce087022ceef7c861f42b658d..b00fdbb7c818527cf34ed77e7f739c512aebe653 100644 |
--- a/src/arm/lithium-codegen-arm.cc |
+++ b/src/arm/lithium-codegen-arm.cc |
@@ -145,6 +145,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). ecx is zero for method calls and non-zero for function |
Kevin Millikin (Chromium)
2011/05/24 13:21:36
ecx ==> r5.
Mads Ager (chromium)
2011/05/24 13:57:53
Done.
|
+ // 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. |
@@ -2768,7 +2782,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()) || |
@@ -2788,6 +2803,7 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function, |
RecordPosition(pointers->position()); |
// Invoke function. |
+ __ SetCallKind(r5, call_kind); |
__ ldr(ip, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); |
__ Call(ip); |
@@ -2802,7 +2818,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); |
} |
@@ -3184,10 +3203,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)); |
} |
@@ -3197,7 +3217,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)); |
@@ -3208,10 +3228,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)); |
} |
@@ -3219,7 +3240,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); |
} |