Index: src/x64/full-codegen-x64.cc |
=================================================================== |
--- src/x64/full-codegen-x64.cc (revision 3896) |
+++ src/x64/full-codegen-x64.cc (working copy) |
@@ -1015,6 +1015,92 @@ |
} |
+void FullCodeGenerator::VisitAssignment(Assignment* expr) { |
+ Comment cmnt(masm_, "[ Assignment"); |
+ ASSERT(expr->op() != Token::INIT_CONST); |
+ // Left-hand side can only be a property, a global or a (parameter or local) |
+ // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY. |
+ enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; |
+ LhsKind assign_type = VARIABLE; |
+ Property* prop = expr->target()->AsProperty(); |
+ if (prop != NULL) { |
+ assign_type = |
+ (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; |
+ } |
+ |
+ // Evaluate LHS expression. |
+ switch (assign_type) { |
+ case VARIABLE: |
+ // Nothing to do here. |
+ break; |
+ case NAMED_PROPERTY: |
+ if (expr->is_compound()) { |
+ // We need the receiver both on the stack and in the accumulator. |
+ VisitForValue(prop->obj(), kAccumulator); |
+ __ push(result_register()); |
+ } else { |
+ VisitForValue(prop->obj(), kStack); |
+ } |
+ break; |
+ case KEYED_PROPERTY: |
+ VisitForValue(prop->obj(), kStack); |
+ VisitForValue(prop->key(), kStack); |
+ break; |
+ } |
+ |
+ // If we have a compound assignment: Get value of LHS expression and |
+ // store in on top of the stack. |
+ if (expr->is_compound()) { |
+ Location saved_location = location_; |
+ location_ = kStack; |
+ switch (assign_type) { |
+ case VARIABLE: |
+ EmitVariableLoad(expr->target()->AsVariableProxy()->var(), |
+ Expression::kValue); |
+ break; |
+ case NAMED_PROPERTY: |
+ EmitNamedPropertyLoad(prop); |
+ __ push(result_register()); |
+ break; |
+ case KEYED_PROPERTY: |
+ EmitKeyedPropertyLoad(prop); |
+ __ push(result_register()); |
+ break; |
+ } |
+ location_ = saved_location; |
+ } |
+ |
+ // Evaluate RHS expression. |
+ Expression* rhs = expr->value(); |
+ VisitForValue(rhs, kAccumulator); |
+ |
+ // If we have a compound assignment: Apply operator. |
+ if (expr->is_compound()) { |
+ Location saved_location = location_; |
+ location_ = kAccumulator; |
+ EmitBinaryOp(expr->binary_op(), Expression::kValue); |
+ location_ = saved_location; |
+ } |
+ |
+ // Record source position before possible IC call. |
+ SetSourcePosition(expr->position()); |
+ |
+ // Store the value. |
+ switch (assign_type) { |
+ case VARIABLE: |
+ EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), |
+ context_); |
+ break; |
+ case NAMED_PROPERTY: |
+ EmitNamedPropertyAssignment(expr); |
+ break; |
+ case KEYED_PROPERTY: |
+ EmitKeyedPropertyAssignment(expr); |
+ break; |
+ } |
+} |
+ |
+ |
void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
SetSourcePosition(prop->position()); |
Literal* key = prop->key()->AsLiteral(); |