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