| Index: src/ia32/fast-codegen-ia32.cc
|
| ===================================================================
|
| --- src/ia32/fast-codegen-ia32.cc (revision 3140)
|
| +++ src/ia32/fast-codegen-ia32.cc (working copy)
|
| @@ -108,6 +108,39 @@
|
| }
|
|
|
|
|
| +void FastCodeGenerator::Move(Location destination, Slot* source) {
|
| + switch (destination.type()) {
|
| + case Location::NOWHERE:
|
| + break;
|
| + case Location::TEMP:
|
| + __ push(Operand(ebp, SlotOffset(source)));
|
| + break;
|
| + }
|
| +}
|
| +
|
| +
|
| +void FastCodeGenerator::Move(Location destination, Literal* expr) {
|
| + switch (destination.type()) {
|
| + case Location::NOWHERE:
|
| + break;
|
| + case Location::TEMP:
|
| + __ push(Immediate(expr->handle()));
|
| + break;
|
| + }
|
| +}
|
| +
|
| +
|
| +void FastCodeGenerator::Move(Slot* destination, Location source) {
|
| + switch (source.type()) {
|
| + case Location::NOWHERE:
|
| + UNREACHABLE();
|
| + case Location::TEMP:
|
| + __ pop(Operand(ebp, SlotOffset(destination)));
|
| + break;
|
| + }
|
| +}
|
| +
|
| +
|
| void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
|
| // Call the runtime to declare the globals.
|
| __ push(esi); // The context is the first argument.
|
| @@ -118,20 +151,6 @@
|
| }
|
|
|
|
|
| -void FastCodeGenerator::VisitBlock(Block* stmt) {
|
| - Comment cmnt(masm_, "[ Block");
|
| - SetStatementPosition(stmt);
|
| - VisitStatements(stmt->statements());
|
| -}
|
| -
|
| -
|
| -void FastCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
|
| - Comment cmnt(masm_, "[ ExpressionStatement");
|
| - SetStatementPosition(stmt);
|
| - Visit(stmt->expression());
|
| -}
|
| -
|
| -
|
| void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
|
| Comment cmnt(masm_, "[ ReturnStatement");
|
| SetStatementPosition(stmt);
|
| @@ -141,8 +160,7 @@
|
| __ mov(eax, expr->AsLiteral()->handle());
|
| } else {
|
| Visit(expr);
|
| - ASSERT(expr->location().is_temporary());
|
| - __ pop(eax);
|
| + Move(eax, expr->location());
|
| }
|
|
|
| if (FLAG_trace) {
|
| @@ -172,12 +190,7 @@
|
| __ push(esi);
|
| __ push(Immediate(boilerplate));
|
| __ CallRuntime(Runtime::kNewClosure, 2);
|
| -
|
| - if (expr->location().is_temporary()) {
|
| - __ push(eax);
|
| - } else {
|
| - ASSERT(expr->location().is_nowhere());
|
| - }
|
| + Move(expr->location(), eax);
|
| }
|
|
|
|
|
| @@ -197,36 +210,23 @@
|
| // indicate that the inobject property case was inlined. Ensure there
|
| // is no test eax instruction here. Remember that the assembler may
|
| // choose to do peephole optimization (eg, push/pop elimination).
|
| - if (expr->location().is_temporary()) {
|
| - // Replace the global object with the result.
|
| - __ mov(Operand(esp, 0), eax);
|
| - } else {
|
| - ASSERT(expr->location().is_nowhere());
|
| - __ add(Operand(esp), Immediate(kPointerSize));
|
| + switch (expr->location().type()) {
|
| + case Location::NOWHERE:
|
| + __ add(Operand(esp), Immediate(kPointerSize));
|
| + break;
|
| + case Location::TEMP:
|
| + // Replace the global object with the result.
|
| + __ mov(Operand(esp, 0), eax);
|
| + break;
|
| }
|
|
|
| } else {
|
| Comment cmnt(masm_, "Stack slot");
|
| - Slot* slot = rewrite->AsSlot();
|
| - ASSERT(slot != NULL);
|
| - if (expr->location().is_temporary()) {
|
| - __ push(Operand(ebp, SlotOffset(slot)));
|
| - } else {
|
| - ASSERT(expr->location().is_nowhere());
|
| - }
|
| + Move(expr->location(), rewrite->AsSlot());
|
| }
|
| }
|
|
|
|
|
| -void FastCodeGenerator::VisitLiteral(Literal* expr) {
|
| - if (expr->location().is_temporary()) {
|
| - __ push(Immediate(expr->handle()));
|
| - } else {
|
| - ASSERT(expr->location().is_nowhere());
|
| - }
|
| -}
|
| -
|
| -
|
| void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
|
| Comment cmnt(masm_, "[ ObjectLiteral");
|
| Label exists;
|
| @@ -283,8 +283,7 @@
|
| case ObjectLiteral::Property::COMPUTED:
|
| if (key->handle()->IsSymbol()) {
|
| Visit(value);
|
| - ASSERT(value->location().is_temporary());
|
| - __ pop(eax);
|
| + Move(eax, value->location());
|
| __ mov(ecx, Immediate(key->handle()));
|
| Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
|
| __ call(ic, RelocInfo::CODE_TARGET);
|
| @@ -295,7 +294,7 @@
|
| case ObjectLiteral::Property::PROTOTYPE:
|
| __ push(eax);
|
| Visit(key);
|
| - ASSERT(key->location().is_temporary());
|
| + ASSERT(value->location().is_temporary());
|
| Visit(value);
|
| ASSERT(value->location().is_temporary());
|
| __ CallRuntime(Runtime::kSetProperty, 3);
|
| @@ -317,10 +316,13 @@
|
| default: UNREACHABLE();
|
| }
|
| }
|
| - if (expr->location().is_nowhere() && result_saved) {
|
| - __ add(Operand(esp), Immediate(kPointerSize));
|
| - } else if (expr->location().is_temporary() && !result_saved) {
|
| - __ push(eax);
|
| + switch (expr->location().type()) {
|
| + case Location::NOWHERE:
|
| + if (result_saved) __ add(Operand(esp), Immediate(kPointerSize));
|
| + break;
|
| + case Location::TEMP:
|
| + if (!result_saved) __ push(eax);
|
| + break;
|
| }
|
| }
|
|
|
| @@ -348,11 +350,7 @@
|
| __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
|
| // Label done:
|
| __ bind(&done);
|
| - if (expr->location().is_temporary()) {
|
| - __ push(eax);
|
| - } else {
|
| - ASSERT(expr->location().is_nowhere());
|
| - }
|
| + Move(expr->location(), eax);
|
| }
|
|
|
|
|
| @@ -417,11 +415,13 @@
|
| __ RecordWrite(ebx, offset, eax, ecx);
|
| }
|
|
|
| - Location destination = expr->location();
|
| - if (destination.is_nowhere() && result_saved) {
|
| - __ add(Operand(esp), Immediate(kPointerSize));
|
| - } else if (destination.is_temporary() && !result_saved) {
|
| - __ push(eax);
|
| + switch (expr->location().type()) {
|
| + case Location::NOWHERE:
|
| + if (result_saved) __ add(Operand(esp), Immediate(kPointerSize));
|
| + break;
|
| + case Location::TEMP:
|
| + if (!result_saved) __ push(eax);
|
| + break;
|
| }
|
| }
|
|
|
| @@ -436,7 +436,6 @@
|
| ASSERT(var->is_global() || var->slot() != NULL);
|
|
|
| Expression* rhs = expr->value();
|
| - Location destination = expr->location();
|
| if (var->is_global()) {
|
| // Assignment to a global variable, use inline caching. Right-hand-side
|
| // value is passed in eax, variable name in ecx, and the global object
|
| @@ -455,11 +454,13 @@
|
| Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
|
| __ call(ic, RelocInfo::CODE_TARGET);
|
| // Overwrite the global object on the stack with the result if needed.
|
| - if (destination.is_temporary()) {
|
| - __ mov(Operand(esp, 0), eax);
|
| - } else {
|
| - ASSERT(destination.is_nowhere());
|
| - __ add(Operand(esp), Immediate(kPointerSize));
|
| + switch (expr->location().type()) {
|
| + case Location::NOWHERE:
|
| + __ add(Operand(esp), Immediate(kPointerSize));
|
| + break;
|
| + case Location::TEMP:
|
| + __ mov(Operand(esp, 0), eax);
|
| + break;
|
| }
|
| } else {
|
| // Local or parameter assignment.
|
| @@ -470,22 +471,21 @@
|
| // discarded result. Always perform the assignment.
|
| __ mov(eax, rhs->AsLiteral()->handle());
|
| __ mov(Operand(ebp, SlotOffset(var->slot())), eax);
|
| - if (destination.is_temporary()) {
|
| - // Case 'temp <- (var = constant)'. Save result.
|
| - __ push(eax);
|
| - }
|
| + Move(expr->location(), eax);
|
| } else {
|
| ASSERT(rhs->location().is_temporary());
|
| Visit(rhs);
|
| - if (destination.is_temporary()) {
|
| - // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side
|
| - // temporary on the stack.
|
| - __ mov(eax, Operand(esp, 0));
|
| - __ mov(Operand(ebp, SlotOffset(var->slot())), eax);
|
| - } else {
|
| - ASSERT(destination.is_nowhere());
|
| - // Case 'var = temp'. Discard right-hand-side temporary.
|
| - __ pop(Operand(ebp, SlotOffset(var->slot())));
|
| + switch (expr->location().type()) {
|
| + case Location::NOWHERE:
|
| + // Case 'var = temp'. Discard right-hand-side temporary.
|
| + Move(var->slot(), rhs->location());
|
| + break;
|
| + case Location::TEMP:
|
| + // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side
|
| + // temporary on the stack.
|
| + __ mov(eax, Operand(esp, 0));
|
| + __ mov(Operand(ebp, SlotOffset(var->slot())), eax);
|
| + break;
|
| }
|
| }
|
| }
|
| @@ -516,11 +516,13 @@
|
| // Restore context register.
|
| __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
|
| // Discard the function left on TOS.
|
| - if (expr->location().is_temporary()) {
|
| - __ mov(Operand(esp, 0), eax);
|
| - } else {
|
| - ASSERT(expr->location().is_nowhere());
|
| - __ add(Operand(esp), Immediate(kPointerSize));
|
| + switch (expr->location().type()) {
|
| + case Location::NOWHERE:
|
| + __ add(Operand(esp), Immediate(kPointerSize));
|
| + break;
|
| + case Location::TEMP:
|
| + __ mov(Operand(esp, 0), eax);
|
| + break;
|
| }
|
| }
|
|
|
| @@ -540,11 +542,7 @@
|
| }
|
|
|
| __ CallRuntime(function, arg_count);
|
| - if (expr->location().is_temporary()) {
|
| - __ push(eax);
|
| - } else {
|
| - ASSERT(expr->location().is_nowhere());
|
| - }
|
| + Move(expr->location(), eax);
|
| }
|
|
|
|
|
| @@ -572,14 +570,17 @@
|
| } else {
|
| Visit(left);
|
| ASSERT(left->location().is_temporary());
|
| - if (destination.is_temporary()) {
|
| - // Copy the left-hand value into eax because we may need it as the
|
| - // final result.
|
| - __ mov(eax, Operand(esp, 0));
|
| - } else {
|
| - // Pop the left-hand value into eax because we will not need it as the
|
| - // final result.
|
| - __ pop(eax);
|
| + switch (destination.type()) {
|
| + case Location::NOWHERE:
|
| + // Pop the left-hand value into eax because we will not need it as the
|
| + // final result.
|
| + __ pop(eax);
|
| + break;
|
| + case Location::TEMP:
|
| + // Copy the left-hand value into eax because we may need it as the
|
| + // final result.
|
| + __ mov(eax, Operand(esp, 0));
|
| + break;
|
| }
|
| }
|
| // The left-hand value is in eax. It is also on the stack iff the
|
| @@ -612,19 +613,10 @@
|
| }
|
| // Save or discard the right-hand value as needed.
|
| if (right->AsLiteral() != NULL) {
|
| - if (destination.is_temporary()) {
|
| - __ push(Immediate(right->AsLiteral()->handle()));
|
| - } else {
|
| - ASSERT(destination.is_nowhere());
|
| - }
|
| + Move(destination, right->AsLiteral());
|
| } else {
|
| Visit(right);
|
| - ASSERT(right->location().is_temporary());
|
| - if (destination.is_nowhere()) {
|
| - __ add(Operand(esp), Immediate(kPointerSize));
|
| - } else {
|
| - ASSERT(destination.is_temporary());
|
| - }
|
| + Move(destination, right->location());
|
| }
|
|
|
| __ bind(&done);
|
|
|