| Index: src/arm/lithium-codegen-arm.cc
|
| diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
|
| index 1d46dd2891a16823869155f18cb1d2cb1e9c5a68..4303e745430df162fb9f2388526e8d6f8f9211d5 100644
|
| --- a/src/arm/lithium-codegen-arm.cc
|
| +++ b/src/arm/lithium-codegen-arm.cc
|
| @@ -1718,7 +1718,65 @@ 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 the receiver and use the register to keep the original
|
| + // number of arguments.
|
| + __ push(receiver);
|
| + __ mov(receiver, length);
|
| + // The arguments are at a one pointer size offset from elements.
|
| + __ add(elements, elements, Operand(1 * kPointerSize));
|
| +
|
| + // Loop through the arguments pushing them onto the execution
|
| + // stack.
|
| + Label loop;
|
| + // 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);
|
| +
|
| + __ bind(&invoke);
|
| + // Invoke the function. The number of arguments is stored in receiver
|
| + // which is r0, as expected by InvokeFunction.
|
| + v8::internal::ParameterCount actual(receiver);
|
| + SafepointGenerator safepoint_generator(this,
|
| + instr->pointer_map(),
|
| + Safepoint::kNoDeoptimizationIndex);
|
| + __ InvokeFunction(function, actual, CALL_FUNCTION, &safepoint_generator);
|
| }
|
|
|
|
|
|
|