Chromium Code Reviews| Index: src/ia32/fast-codegen-ia32.cc |
| =================================================================== |
| --- src/ia32/fast-codegen-ia32.cc (revision 3133) |
| +++ src/ia32/fast-codegen-ia32.cc (working copy) |
| @@ -136,18 +136,15 @@ |
| Comment cmnt(masm_, "[ ReturnStatement"); |
| SetStatementPosition(stmt); |
| Expression* expr = stmt->expression(); |
| - Visit(expr); |
| - |
| - // Complete the statement based on the location of the subexpression. |
| - Location source = expr->location(); |
| - ASSERT(!source.is_nowhere()); |
| - if (source.is_temporary()) { |
| - __ pop(eax); |
| - } else { |
| - ASSERT(source.is_constant()); |
| - ASSERT(expr->AsLiteral() != NULL); |
| + // Complete the statement based on the type of the subexpression. |
| + if (expr->AsLiteral() != NULL) { |
| __ mov(eax, expr->AsLiteral()->handle()); |
| + } else { |
| + Visit(expr); |
| + ASSERT(expr->location().is_temporary()); |
| + __ pop(eax); |
| } |
| + |
| if (FLAG_trace) { |
| __ push(eax); |
| __ CallRuntime(Runtime::kTraceExit, 1); |
| @@ -221,6 +218,15 @@ |
| } |
| +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; |
| @@ -289,9 +295,7 @@ |
| case ObjectLiteral::Property::PROTOTYPE: |
| __ push(eax); |
| Visit(key); |
| - if (key->location().is_constant()) { |
| - __ push(Immediate(key->handle())); |
| - } |
| + ASSERT(key->location().is_temporary()); |
| Visit(value); |
| ASSERT(value->location().is_temporary()); |
| __ CallRuntime(Runtime::kSetProperty, 3); |
| @@ -301,9 +305,7 @@ |
| case ObjectLiteral::Property::GETTER: |
| __ push(eax); |
| Visit(key); |
| - if (key->location().is_constant()) { |
| - __ push(Immediate(key->handle())); |
| - } |
| + ASSERT(key->location().is_temporary()); |
| __ push(Immediate(property->kind() == ObjectLiteral::Property::SETTER ? |
| Smi::FromInt(1) : |
| Smi::FromInt(0))); |
| @@ -427,31 +429,26 @@ |
| void FastCodeGenerator::VisitAssignment(Assignment* expr) { |
| Comment cmnt(masm_, "[ Assignment"); |
| ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR); |
| - Expression* rhs = expr->value(); |
| - Visit(rhs); |
| // Left-hand side can only be a global or a (parameter or local) slot. |
| Variable* var = expr->target()->AsVariableProxy()->AsVariable(); |
| ASSERT(var != NULL); |
| ASSERT(var->is_global() || var->slot() != NULL); |
| - // Complete the assignment based on the location of the right-hand-side |
| - // value and the desired location of the assignment value. |
| + Expression* rhs = expr->value(); |
| Location destination = expr->location(); |
| - Location source = rhs->location(); |
| - ASSERT(!destination.is_constant()); |
| - ASSERT(!source.is_nowhere()); |
| - |
| 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 |
| // on the stack. |
| - if (source.is_temporary()) { |
| - __ pop(eax); |
| - } else { |
| - ASSERT(source.is_constant()); |
| - ASSERT(rhs->AsLiteral() != NULL); |
| + |
| + // Code for the right-hand-side expression depends on its type. |
| + if (rhs->AsLiteral() != NULL) { |
| __ mov(eax, rhs->AsLiteral()->handle()); |
| + } else { |
| + ASSERT(rhs->location().is_temporary()); |
| + Visit(rhs); |
| + __ pop(eax); |
| } |
| __ mov(ecx, var->name()); |
| __ push(CodeGenerator::GlobalObject()); |
| @@ -464,11 +461,23 @@ |
| ASSERT(destination.is_nowhere()); |
| __ add(Operand(esp), Immediate(kPointerSize)); |
| } |
| - |
| } else { |
| // Local or parameter assignment. |
| - if (source.is_temporary()) { |
| + |
| + // Code for the right-hand side expression depends on its type. |
| + if (rhs->AsLiteral() != NULL) { |
| + // Two cases: 'temp <- (var = constant)', or 'var = constant' with a |
| + // 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); |
|
fschneider
2009/10/26 17:57:20
Add an assert here to be consistent with the rest
|
| + } |
| + } 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)); |
| @@ -478,17 +487,6 @@ |
| // Case 'var = temp'. Discard right-hand-side temporary. |
| __ pop(Operand(ebp, SlotOffset(var->slot()))); |
| } |
| - } else { |
| - ASSERT(source.is_constant()); |
| - ASSERT(rhs->AsLiteral() != NULL); |
| - // Two cases: 'temp <- (var = constant)', or 'var = constant' with a |
| - // 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); |
| - } |
| } |
| } |
| } |
| @@ -507,11 +505,7 @@ |
| int arg_count = args->length(); |
| for (int i = 0; i < arg_count; i++) { |
| Visit(args->at(i)); |
| - ASSERT(!args->at(i)->location().is_nowhere()); |
| - if (args->at(i)->location().is_constant()) { |
| - ASSERT(args->at(i)->AsLiteral() != NULL); |
| - __ push(Immediate(args->at(i)->AsLiteral()->handle())); |
| - } |
| + ASSERT(args->at(i)->location().is_temporary()); |
| } |
| // Record source position for debugger |
| SetSourcePosition(expr->position()); |
| @@ -542,15 +536,7 @@ |
| int arg_count = args->length(); |
| for (int i = 0; i < arg_count; i++) { |
| Visit(args->at(i)); |
| - ASSERT(!args->at(i)->location().is_nowhere()); |
| - if (args->at(i)->location().is_constant()) { |
| - ASSERT(args->at(i)->AsLiteral() != NULL); |
| - __ push(Immediate(args->at(i)->AsLiteral()->handle())); |
| - } else { |
| - ASSERT(args->at(i)->location().is_temporary()); |
| - // If location is temporary, it is already on the stack, |
| - // so nothing to do here. |
| - } |
| + ASSERT(args->at(i)->location().is_temporary()); |
| } |
| __ CallRuntime(function, arg_count); |
| @@ -571,21 +557,21 @@ |
| Label eval_right, done; |
| Location destination = expr->location(); |
| - ASSERT(!destination.is_constant()); |
| - |
| Expression* left = expr->left(); |
| - Location left_source = left->location(); |
| - ASSERT(!left_source.is_nowhere()); |
| - |
| Expression* right = expr->right(); |
| - Location right_source = right->location(); |
| - ASSERT(!right_source.is_nowhere()); |
| - Visit(left); |
| // Use the shared ToBoolean stub to find the boolean value of the |
| // left-hand subexpression. Load the value into eax to perform some |
| // inlined checks assumed by the stub. |
| - if (left_source.is_temporary()) { |
| + |
| + // Compile the left-hand value into eax. Put it on the stack if we may |
| + // need it as the value of the whole expression. |
| + if (left->AsLiteral() != NULL) { |
| + __ mov(eax, left->AsLiteral()->handle()); |
| + if (destination.is_temporary()) __ push(eax); |
|
fschneider
2009/10/26 17:57:20
May want to add an assert here to be consistent wi
|
| + } 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. |
| @@ -595,12 +581,6 @@ |
| // final result. |
| __ pop(eax); |
|
fschneider
2009/10/26 17:57:20
Adding an assert to be consistent on all platforms
|
| } |
| - } else { |
| - // Load the left-hand value into eax. Put it on the stack if we may |
| - // need it. |
| - ASSERT(left->AsLiteral() != NULL); |
| - __ mov(eax, left->AsLiteral()->handle()); |
| - if (destination.is_temporary()) __ push(eax); |
| } |
| // The left-hand value is in eax. It is also on the stack iff the |
| // destination location is temporary. |
| @@ -630,14 +610,21 @@ |
| if (destination.is_temporary()) { |
| __ add(Operand(esp), Immediate(kPointerSize)); |
| } |
| - Visit(right); |
| - |
| // Save or discard the right-hand value as needed. |
| - if (destination.is_temporary() && right_source.is_constant()) { |
| - ASSERT(right->AsLiteral() != NULL); |
| - __ push(Immediate(right->AsLiteral()->handle())); |
| - } else if (destination.is_nowhere() && right_source.is_temporary()) { |
| - __ add(Operand(esp), Immediate(kPointerSize)); |
| + if (right->AsLiteral() != NULL) { |
| + if (destination.is_temporary()) { |
| + __ push(Immediate(right->AsLiteral()->handle())); |
| + } else { |
| + ASSERT(destination.is_nowhere()); |
| + } |
| + } else { |
| + Visit(right); |
| + ASSERT(right->location().is_temporary()); |
| + if (destination.is_nowhere()) { |
| + __ add(Operand(esp), Immediate(kPointerSize)); |
| + } else { |
| + ASSERT(destination.is_temporary()); |
| + } |
| } |
| __ bind(&done); |