Chromium Code Reviews| 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); |
| } |