| Index: src/ia32/fast-codegen-ia32.cc
|
| diff --git a/src/ia32/fast-codegen-ia32.cc b/src/ia32/fast-codegen-ia32.cc
|
| index 4ea09507654328f791b1dcf667965b7ab0f05703..611a510526554eb956783e3a8c7038b0ce419fb4 100644
|
| --- a/src/ia32/fast-codegen-ia32.cc
|
| +++ b/src/ia32/fast-codegen-ia32.cc
|
| @@ -67,11 +67,43 @@ void FastCodeGenerator::Generate(FunctionLiteral* fun) {
|
| }
|
| }
|
|
|
| + bool function_in_register = true;
|
| +
|
| + Variable* arguments = fun->scope()->arguments()->AsVariable();
|
| + if (arguments != NULL) {
|
| + // Function uses arguments object.
|
| + Comment cmnt(masm_, "[ Allocate arguments object");
|
| + __ push(edi);
|
| + // Receiver is located above the frame pointer, return address and
|
| + // parameters.
|
| + __ lea(edx, Operand(ebp, (fun->num_parameters() + 2) * kPointerSize));
|
| + __ push(edx);
|
| + __ push(Immediate(Smi::FromInt(fun->num_parameters())));
|
| + // Arguments to ArgumentsAccessStub:
|
| + // function, receiver address, parameter count.
|
| + // The stub will rewrite receiever and parameter count if the previous
|
| + // stack frame was an arguments adapter frame.
|
| + ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT);
|
| + __ CallStub(&stub);
|
| + Slot* arguments_slot = arguments->slot();
|
| + __ mov(Operand(ebp, SlotOffset(arguments_slot)), eax);
|
| + Slot* dot_arguments_slot =
|
| + fun->scope()->arguments_shadow()->AsVariable()->slot();
|
| + __ mov(Operand(ebp, SlotOffset(dot_arguments_slot)), eax);
|
| +
|
| + function_in_register = false;
|
| + }
|
| +
|
| // Possibly allocate a local context.
|
| if (fun->scope()->num_heap_slots() > 0) {
|
| Comment cmnt(masm_, "[ Allocate local context");
|
| - // Argument to NewContext is the function, still in edi.
|
| - __ push(edi);
|
| + if (function_in_register) {
|
| + // Argument to NewContext is the function, still in edi.
|
| + __ push(edi);
|
| + } else {
|
| + // Argument to NewContext is the function, no longer in edi.
|
| + __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
|
| + }
|
| __ CallRuntime(Runtime::kNewContext, 1);
|
| // Context is returned in both eax and esi. It replaces the context
|
| // passed to us. It's saved in the stack and kept live in esi.
|
| @@ -425,9 +457,8 @@ void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
|
| __ nop();
|
|
|
| DropAndMove(expr->context(), eax);
|
| - } else {
|
| + } else if (rewrite->AsSlot() != NULL) {
|
| Slot* slot = rewrite->AsSlot();
|
| - ASSERT_NE(NULL, slot);
|
| switch (slot->type()) {
|
| case Slot::LOCAL:
|
| case Slot::PARAMETER: {
|
| @@ -468,6 +499,13 @@ void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
|
| UNREACHABLE();
|
| break;
|
| }
|
| + } else {
|
| + // The parameter variable has been rewritten into an explict access to
|
| + // the arguments object.
|
| + Property* property = rewrite->AsProperty();
|
| + ASSERT_NOT_NULL(property);
|
| + ASSERT_EQ(expr->context(), property->context());
|
| + Visit(property);
|
| }
|
| }
|
|
|
|
|