| Index: src/ia32/lithium-codegen-ia32.cc
|
| diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
|
| index 25961b28524e1c796f58a0662886f3fa2223e635..d8bf93d939245edba6859b464e1c9f1ade924cb4 100644
|
| --- a/src/ia32/lithium-codegen-ia32.cc
|
| +++ b/src/ia32/lithium-codegen-ia32.cc
|
| @@ -128,6 +128,20 @@ bool LCodeGen::GeneratePrologue() {
|
| }
|
| #endif
|
|
|
| + // Strict mode functions need to replace the receiver with undefined
|
| + // when called with an implicit receiver. ecx is zero for explicit
|
| + // receiver calls and one for implicit receiver calls.
|
| + if (info_->is_strict_mode()) {
|
| + Label ok;
|
| + __ test(ecx, Operand(ecx));
|
| + __ j(zero, &ok, Label::kNear);
|
| + // +1 for return address.
|
| + int receiver_offset = (scope()->num_parameters() + 1) * kPointerSize;
|
| + __ mov(Operand(esp, receiver_offset),
|
| + Immediate(isolate()->factory()->undefined_value()));
|
| + __ bind(&ok);
|
| + }
|
| +
|
| __ push(ebp); // Caller's frame pointer.
|
| __ mov(ebp, esp);
|
| __ push(esi); // Callee's context.
|
| @@ -2685,7 +2699,8 @@ void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) {
|
|
|
| void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
|
| int arity,
|
| - LInstruction* instr) {
|
| + LInstruction* instr,
|
| + ReceiverType receiver_type) {
|
| // Change context if needed.
|
| bool change_context =
|
| (info()->closure()->context() != function->context()) ||
|
| @@ -2707,6 +2722,7 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
|
| RecordPosition(pointers->position());
|
|
|
| // Invoke function.
|
| + __ SetReceiverType(ecx, receiver_type);
|
| if (*function == *info()->closure()) {
|
| __ CallSelf();
|
| } else {
|
| @@ -2721,7 +2737,10 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
|
| void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
|
| ASSERT(ToRegister(instr->result()).is(eax));
|
| __ mov(edi, instr->function());
|
| - CallKnownFunction(instr->function(), instr->arity(), instr);
|
| + CallKnownFunction(instr->function(),
|
| + instr->arity(),
|
| + instr,
|
| + EXPLICIT_RECEIVER);
|
| }
|
|
|
|
|
| @@ -3084,10 +3103,11 @@ void LCodeGen::DoCallNamed(LCallNamed* instr) {
|
| ASSERT(ToRegister(instr->result()).is(eax));
|
|
|
| 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(ecx, instr->name());
|
| - CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED);
|
| + CallCode(ic, mode, instr, CONTEXT_ADJUSTED);
|
| }
|
|
|
|
|
| @@ -3107,17 +3127,18 @@ void LCodeGen::DoCallGlobal(LCallGlobal* instr) {
|
| ASSERT(ToRegister(instr->result()).is(eax));
|
|
|
| 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);
|
| __ mov(ecx, instr->name());
|
| - CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr, CONTEXT_ADJUSTED);
|
| + CallCode(ic, mode, instr, CONTEXT_ADJUSTED);
|
| }
|
|
|
|
|
| void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) {
|
| ASSERT(ToRegister(instr->result()).is(eax));
|
| __ mov(edi, instr->target());
|
| - CallKnownFunction(instr->target(), instr->arity(), instr);
|
| + CallKnownFunction(instr->target(), instr->arity(), instr, IMPLICIT_RECEIVER);
|
| }
|
|
|
|
|
|
|