Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(45)

Side by Side Diff: src/arm/lithium-codegen-arm.cc

Issue 7039036: Fix calls of strict mode function with an implicit receiver. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Port to x64 and arm. Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 info_->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { 138 info_->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
139 __ stop("stop_at"); 139 __ stop("stop_at");
140 } 140 }
141 #endif 141 #endif
142 142
143 // r1: Callee's JS function. 143 // r1: Callee's JS function.
144 // cp: Callee's context. 144 // cp: Callee's context.
145 // fp: Caller's frame pointer. 145 // fp: Caller's frame pointer.
146 // lr: Caller's pc. 146 // lr: Caller's pc.
147 147
148 // Strict mode functions need to replace the receiver with undefined
149 // when called as functions (without an explicit receiver
150 // 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.
151 // calls.
152 if (info_->is_strict_mode()) {
153 Label ok;
154 __ cmp(r5, Operand(0));
155 __ b(eq, &ok);
156 int receiver_offset = scope()->num_parameters() * kPointerSize;
157 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
158 __ str(r2, MemOperand(sp, receiver_offset));
159 __ bind(&ok);
160 }
161
148 __ stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit()); 162 __ stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit());
149 __ add(fp, sp, Operand(2 * kPointerSize)); // Adjust FP to point to saved FP. 163 __ add(fp, sp, Operand(2 * kPointerSize)); // Adjust FP to point to saved FP.
150 164
151 // Reserve space for the stack slots needed by the code. 165 // Reserve space for the stack slots needed by the code.
152 int slots = GetStackSlotCount(); 166 int slots = GetStackSlotCount();
153 if (slots > 0) { 167 if (slots > 0) {
154 if (FLAG_debug_code) { 168 if (FLAG_debug_code) {
155 __ mov(r0, Operand(slots)); 169 __ mov(r0, Operand(slots));
156 __ mov(r2, Operand(kSlotsZapValue)); 170 __ mov(r2, Operand(kSlotsZapValue));
157 Label loop; 171 Label loop;
(...skipping 2603 matching lines...) Expand 10 before | Expand all | Expand 10 after
2761 2775
2762 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { 2776 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) {
2763 Register global = ToRegister(instr->global()); 2777 Register global = ToRegister(instr->global());
2764 Register result = ToRegister(instr->result()); 2778 Register result = ToRegister(instr->result());
2765 __ ldr(result, FieldMemOperand(global, GlobalObject::kGlobalReceiverOffset)); 2779 __ ldr(result, FieldMemOperand(global, GlobalObject::kGlobalReceiverOffset));
2766 } 2780 }
2767 2781
2768 2782
2769 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, 2783 void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
2770 int arity, 2784 int arity,
2771 LInstruction* instr) { 2785 LInstruction* instr,
2786 CallKind call_kind) {
2772 // Change context if needed. 2787 // Change context if needed.
2773 bool change_context = 2788 bool change_context =
2774 (info()->closure()->context() != function->context()) || 2789 (info()->closure()->context() != function->context()) ||
2775 scope()->contains_with() || 2790 scope()->contains_with() ||
2776 (scope()->num_heap_slots() > 0); 2791 (scope()->num_heap_slots() > 0);
2777 if (change_context) { 2792 if (change_context) {
2778 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); 2793 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
2779 } 2794 }
2780 2795
2781 // Set r0 to arguments count if adaption is not needed. Assumes that r0 2796 // Set r0 to arguments count if adaption is not needed. Assumes that r0
2782 // is available to write to at this point. 2797 // is available to write to at this point.
2783 if (!function->NeedsArgumentsAdaption()) { 2798 if (!function->NeedsArgumentsAdaption()) {
2784 __ mov(r0, Operand(arity)); 2799 __ mov(r0, Operand(arity));
2785 } 2800 }
2786 2801
2787 LPointerMap* pointers = instr->pointer_map(); 2802 LPointerMap* pointers = instr->pointer_map();
2788 RecordPosition(pointers->position()); 2803 RecordPosition(pointers->position());
2789 2804
2790 // Invoke function. 2805 // Invoke function.
2806 __ SetCallKind(r5, call_kind);
2791 __ ldr(ip, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); 2807 __ ldr(ip, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
2792 __ Call(ip); 2808 __ Call(ip);
2793 2809
2794 // Setup deoptimization. 2810 // Setup deoptimization.
2795 RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT); 2811 RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT);
2796 2812
2797 // Restore context. 2813 // Restore context.
2798 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2814 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2799 } 2815 }
2800 2816
2801 2817
2802 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { 2818 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
2803 ASSERT(ToRegister(instr->result()).is(r0)); 2819 ASSERT(ToRegister(instr->result()).is(r0));
2804 __ mov(r1, Operand(instr->function())); 2820 __ mov(r1, Operand(instr->function()));
2805 CallKnownFunction(instr->function(), instr->arity(), instr); 2821 CallKnownFunction(instr->function(),
2822 instr->arity(),
2823 instr,
2824 CALL_AS_METHOD);
2806 } 2825 }
2807 2826
2808 2827
2809 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { 2828 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
2810 ASSERT(instr->InputAt(0)->Equals(instr->result())); 2829 ASSERT(instr->InputAt(0)->Equals(instr->result()));
2811 Register input = ToRegister(instr->InputAt(0)); 2830 Register input = ToRegister(instr->InputAt(0));
2812 Register scratch = scratch0(); 2831 Register scratch = scratch0();
2813 2832
2814 // Deoptimize if not a heap number. 2833 // Deoptimize if not a heap number.
2815 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); 2834 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
3177 isolate()->stub_cache()->ComputeKeyedCallInitialize(arity, NOT_IN_LOOP); 3196 isolate()->stub_cache()->ComputeKeyedCallInitialize(arity, NOT_IN_LOOP);
3178 CallCode(ic, RelocInfo::CODE_TARGET, instr); 3197 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3179 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 3198 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
3180 } 3199 }
3181 3200
3182 3201
3183 void LCodeGen::DoCallNamed(LCallNamed* instr) { 3202 void LCodeGen::DoCallNamed(LCallNamed* instr) {
3184 ASSERT(ToRegister(instr->result()).is(r0)); 3203 ASSERT(ToRegister(instr->result()).is(r0));
3185 3204
3186 int arity = instr->arity(); 3205 int arity = instr->arity();
3187 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize( 3206 RelocInfo::Mode mode = RelocInfo::CODE_TARGET;
3188 arity, NOT_IN_LOOP); 3207 Handle<Code> ic =
3208 isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode);
3189 __ mov(r2, Operand(instr->name())); 3209 __ mov(r2, Operand(instr->name()));
3190 CallCode(ic, RelocInfo::CODE_TARGET, instr); 3210 CallCode(ic, mode, instr);
3191 // Restore context register. 3211 // Restore context register.
3192 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 3212 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
3193 } 3213 }
3194 3214
3195 3215
3196 void LCodeGen::DoCallFunction(LCallFunction* instr) { 3216 void LCodeGen::DoCallFunction(LCallFunction* instr) {
3197 ASSERT(ToRegister(instr->result()).is(r0)); 3217 ASSERT(ToRegister(instr->result()).is(r0));
3198 3218
3199 int arity = instr->arity(); 3219 int arity = instr->arity();
3200 CallFunctionStub stub(arity, NOT_IN_LOOP, RECEIVER_MIGHT_BE_VALUE); 3220 CallFunctionStub stub(arity, NOT_IN_LOOP, RECEIVER_MIGHT_BE_IMPLICIT);
3201 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 3221 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
3202 __ Drop(1); 3222 __ Drop(1);
3203 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 3223 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
3204 } 3224 }
3205 3225
3206 3226
3207 void LCodeGen::DoCallGlobal(LCallGlobal* instr) { 3227 void LCodeGen::DoCallGlobal(LCallGlobal* instr) {
3208 ASSERT(ToRegister(instr->result()).is(r0)); 3228 ASSERT(ToRegister(instr->result()).is(r0));
3209 3229
3210 int arity = instr->arity(); 3230 int arity = instr->arity();
3231 RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT;
3211 Handle<Code> ic = 3232 Handle<Code> ic =
3212 isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP); 3233 isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode);
3213 __ mov(r2, Operand(instr->name())); 3234 __ mov(r2, Operand(instr->name()));
3214 CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr); 3235 CallCode(ic, mode, instr);
3215 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 3236 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
3216 } 3237 }
3217 3238
3218 3239
3219 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { 3240 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) {
3220 ASSERT(ToRegister(instr->result()).is(r0)); 3241 ASSERT(ToRegister(instr->result()).is(r0));
3221 __ mov(r1, Operand(instr->target())); 3242 __ mov(r1, Operand(instr->target()));
3222 CallKnownFunction(instr->target(), instr->arity(), instr); 3243 CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION);
3223 } 3244 }
3224 3245
3225 3246
3226 void LCodeGen::DoCallNew(LCallNew* instr) { 3247 void LCodeGen::DoCallNew(LCallNew* instr) {
3227 ASSERT(ToRegister(instr->InputAt(0)).is(r1)); 3248 ASSERT(ToRegister(instr->InputAt(0)).is(r1));
3228 ASSERT(ToRegister(instr->result()).is(r0)); 3249 ASSERT(ToRegister(instr->result()).is(r0));
3229 3250
3230 Handle<Code> builtin = isolate()->builtins()->JSConstructCall(); 3251 Handle<Code> builtin = isolate()->builtins()->JSConstructCall();
3231 __ mov(r0, Operand(instr->arity())); 3252 __ mov(r0, Operand(instr->arity()));
3232 CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr); 3253 CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr);
(...skipping 1233 matching lines...) Expand 10 before | Expand all | Expand 10 after
4466 ASSERT(osr_pc_offset_ == -1); 4487 ASSERT(osr_pc_offset_ == -1);
4467 osr_pc_offset_ = masm()->pc_offset(); 4488 osr_pc_offset_ = masm()->pc_offset();
4468 } 4489 }
4469 4490
4470 4491
4471 4492
4472 4493
4473 #undef __ 4494 #undef __
4474 4495
4475 } } // namespace v8::internal 4496 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698