Index: src/ia32/builtins-ia32.cc |
diff --git a/src/ia32/builtins-ia32.cc b/src/ia32/builtins-ia32.cc |
index 44f0a977dca4e227046c37cb8596c6fcb4ec71bd..5b2f257615c02169bb606cacb0b1ea0b1da4394c 100644 |
--- a/src/ia32/builtins-ia32.cc |
+++ b/src/ia32/builtins-ia32.cc |
@@ -102,6 +102,7 @@ void Builtins::Generate_JSConstructCall(MacroAssembler* masm) { |
__ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); |
Handle<Code> arguments_adaptor = |
masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); |
+ __ SetReceiverType(ecx, EXPLICIT_RECEIVER); |
__ jmp(arguments_adaptor, RelocInfo::CODE_TARGET); |
} |
@@ -467,19 +468,25 @@ void Builtins::Generate_LazyCompile(MacroAssembler* masm) { |
// Enter an internal frame. |
__ EnterInternalFrame(); |
- // Push a copy of the function onto the stack. |
+ // Push a copy of the function. |
__ push(edi); |
+ // Push implicit receiver information. |
+ __ push(ecx); |
__ push(edi); // Function is also the parameter to the runtime call. |
__ CallRuntime(Runtime::kLazyCompile, 1); |
+ |
+ // Restore called with implicit receiver info. |
+ __ pop(ecx); |
+ // Restore receiver. |
__ pop(edi); |
// Tear down temporary frame. |
__ LeaveInternalFrame(); |
// Do a tail-call of the compiled function. |
- __ lea(ecx, FieldOperand(eax, Code::kHeaderSize)); |
- __ jmp(Operand(ecx)); |
+ __ lea(eax, FieldOperand(eax, Code::kHeaderSize)); |
+ __ jmp(Operand(eax)); |
} |
@@ -489,17 +496,23 @@ void Builtins::Generate_LazyRecompile(MacroAssembler* masm) { |
// Push a copy of the function onto the stack. |
__ push(edi); |
+ // Push implicit receiver information. |
+ __ push(ecx); |
__ push(edi); // Function is also the parameter to the runtime call. |
__ CallRuntime(Runtime::kLazyRecompile, 1); |
- // Restore function and tear down temporary frame. |
+ // Restore called with implicit receiver info. |
+ __ pop(ecx); |
+ // Restore receiver. |
__ pop(edi); |
+ |
+ // Tear down temporary frame. |
__ LeaveInternalFrame(); |
// Do a tail-call of the compiled function. |
- __ lea(ecx, FieldOperand(eax, Code::kHeaderSize)); |
- __ jmp(Operand(ecx)); |
+ __ lea(eax, FieldOperand(eax, Code::kHeaderSize)); |
+ __ jmp(Operand(eax)); |
} |
@@ -683,6 +696,7 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { |
__ j(not_zero, &function); |
__ Set(ebx, Immediate(0)); |
__ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); |
+ __ SetReceiverType(ecx, EXPLICIT_RECEIVER); |
__ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
RelocInfo::CODE_TARGET); |
__ bind(&function); |
@@ -696,6 +710,7 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { |
FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset)); |
__ mov(edx, FieldOperand(edi, JSFunction::kCodeEntryOffset)); |
__ SmiUntag(ebx); |
+ __ SetReceiverType(ecx, EXPLICIT_RECEIVER); |
__ cmp(eax, Operand(ebx)); |
__ j(not_equal, |
masm->isolate()->builtins()->ArgumentsAdaptorTrampoline()); |
@@ -1430,11 +1445,11 @@ static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { |
__ push(edi); |
// Preserve the number of arguments on the stack. Must preserve both |
Kevin Millikin (Chromium)
2011/05/18 15:57:23
"both" --> ""
Mads Ager (chromium)
2011/05/23 16:31:34
Done.
|
- // eax and ebx because these registers are used when copying the |
+ // eax, ebx and ecx because these registers are used when copying the |
// arguments and the receiver. |
ASSERT(kSmiTagSize == 1); |
- __ lea(ecx, Operand(eax, eax, times_1, kSmiTag)); |
- __ push(ecx); |
+ __ lea(edi, Operand(eax, eax, times_1, kSmiTag)); |
+ __ push(edi); |
} |
@@ -1457,6 +1472,7 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { |
// ----------- S t a t e ------------- |
// -- eax : actual number of arguments |
// -- ebx : expected number of arguments |
+ // -- ecx : implicit or explict receiver info |
// -- edx : code entry to call |
// ----------------------------------- |
@@ -1476,14 +1492,14 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { |
// Copy receiver and all expected arguments. |
const int offset = StandardFrameConstants::kCallerSPOffset; |
__ lea(eax, Operand(ebp, eax, times_4, offset)); |
- __ mov(ecx, -1); // account for receiver |
+ __ mov(edi, -1); // account for receiver |
Kevin Millikin (Chromium)
2011/05/18 15:57:23
Not your code, but this loop could also count down
Mads Ager (chromium)
2011/05/23 16:31:34
Won't this push the arguments in the wrong order?
Kevin Millikin (Chromium)
2011/05/24 08:25:26
It pushes in the right order (high to low addresse
|
Label copy; |
__ bind(©); |
- __ inc(ecx); |
+ __ inc(edi); |
__ push(Operand(eax, 0)); |
__ sub(Operand(eax), Immediate(kPointerSize)); |
- __ cmp(ecx, Operand(ebx)); |
+ __ cmp(edi, Operand(ebx)); |
__ j(less, ©); |
__ jmp(&invoke); |
} |
@@ -1495,30 +1511,33 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { |
// Copy receiver and all actual arguments. |
const int offset = StandardFrameConstants::kCallerSPOffset; |
__ lea(edi, Operand(ebp, eax, times_4, offset)); |
- __ mov(ecx, -1); // account for receiver |
+ // ebx = expected - actual. |
Kevin Millikin (Chromium)
2011/05/18 15:57:23
Then here, I think you can use more or less the sa
Mads Ager (chromium)
2011/05/23 16:31:34
Same as above. I think this will push arguments in
Kevin Millikin (Chromium)
2011/05/24 08:25:26
It copies the wrong block of stuff. Sorry about t
|
+ __ sub(ebx, Operand(eax)); |
+ // eax = -actual - 1 |
+ __ neg(eax); |
+ __ sub(Operand(eax), Immediate(1)); |
Label copy; |
__ bind(©); |
- __ inc(ecx); |
+ __ inc(eax); |
__ push(Operand(edi, 0)); |
__ sub(Operand(edi), Immediate(kPointerSize)); |
- __ cmp(ecx, Operand(eax)); |
- __ j(less, ©); |
+ __ test(eax, Operand(eax)); |
+ __ j(not_zero, ©); |
// Fill remaining expected arguments with undefined values. |
Label fill; |
__ bind(&fill); |
- __ inc(ecx); |
+ __ inc(eax); |
__ push(Immediate(masm->isolate()->factory()->undefined_value())); |
- __ cmp(ecx, Operand(ebx)); |
+ __ cmp(eax, Operand(ebx)); |
__ j(less, &fill); |
- |
- // Restore function pointer. |
- __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
} |
// Call the entry point. |
__ bind(&invoke); |
+ // Restore function pointer. |
+ __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
__ call(Operand(edx)); |
// Leave frame and return. |