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 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); |
| } |