Index: src/arm/lithium-codegen-arm.cc |
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc |
index dd740c2c60c565aa99dc29e570c81dd6a33bf4b9..27c32eb6006821e1d0a37e62763cd95d9535776d 100644 |
--- a/src/arm/lithium-codegen-arm.cc |
+++ b/src/arm/lithium-codegen-arm.cc |
@@ -1705,7 +1705,62 @@ void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { |
void LCodeGen::DoApplyArguments(LApplyArguments* instr) { |
- Abort("DoApplyArguments unimplemented."); |
+ Register receiver = ToRegister(instr->receiver()); |
+ Register function = ToRegister(instr->function()); |
+ Register scratch = scratch0(); |
+ |
+ ASSERT(receiver.is(r0)); |
+ ASSERT(function.is(r1)); |
+ ASSERT(ToRegister(instr->result()).is(r0)); |
+ |
+ // If the receiver is null or undefined, we have to pass the |
+ // global object as a receiver. |
+ Label global_receiver, receiver_ok; |
+ __ LoadRoot(scratch, Heap::kNullValueRootIndex); |
+ __ cmp(receiver, scratch); |
+ __ b(eq, &global_receiver); |
+ __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); |
+ __ cmp(receiver, scratch); |
+ __ b(ne, &receiver_ok); |
+ __ bind(&global_receiver); |
+ __ ldr(receiver, GlobalObjectOperand()); |
+ __ bind(&receiver_ok); |
+ |
+ Register length = ToRegister(instr->length()); |
+ Register elements = ToRegister(instr->elements()); |
+ |
+ Label invoke; |
+ |
+ // Copy the arguments to this function possibly from the |
+ // adaptor frame below it. |
+ const uint32_t kArgumentsLimit = 1 * KB; |
+ __ cmp(length, Operand(kArgumentsLimit)); |
+ DeoptimizeIf(hi, instr->environment()); |
+ |
+ __ push(receiver); |
+ __ mov(receiver, length); |
Søren Thygesen Gjesse
2011/01/11 12:01:28
Please add a comment why we are adding 4 here, and
Karl Klose
2011/01/11 13:04:33
Done.
|
+ __ add(elements, elements, Operand(4)); |
+ |
+ // Loop through the arguments pushing them onto the execution |
+ // stack. |
+ Label loop; |
Søren Thygesen Gjesse
2011/01/11 12:01:28
I don't know if it will make a difference, but we
Karl Klose
2011/01/11 13:04:33
I do not see large numbers of arguments, so I did
|
+ // length is a small non-negative integer, due to the test above. |
+ __ tst(length, Operand(length)); |
+ __ b(eq, &invoke); |
+ __ bind(&loop); |
+ __ ldr(scratch, MemOperand(elements, length, LSL, 2)); |
+ __ push(scratch); |
+ __ sub(length, length, Operand(1), SetCC); |
+ __ b(ne, &loop); |
+ |
+ // Invoke the function. |
+ __ bind(&invoke); |
+ v8::internal::ParameterCount actual(receiver); |
Søren Thygesen Gjesse
2011/01/11 12:01:28
Maybe comment here that receiver stores the origin
Karl Klose
2011/01/11 13:04:33
Done.
|
+ |
+ SafepointGenerator safepoint_generator(this, |
+ instr->pointer_map(), |
+ Safepoint::kNoDeoptimizationIndex); |
+ __ InvokeFunction(function, actual, CALL_FUNCTION, &safepoint_generator); |
} |