| Index: src/arm/fast-codegen-arm.cc
|
| ===================================================================
|
| --- src/arm/fast-codegen-arm.cc (revision 3079)
|
| +++ src/arm/fast-codegen-arm.cc (working copy)
|
| @@ -114,8 +114,19 @@
|
| void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
|
| Comment cmnt(masm_, "[ ReturnStatement");
|
| SetStatementPosition(stmt);
|
| - Visit(stmt->expression());
|
| - __ pop(r0);
|
| + 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(r0);
|
| + } else {
|
| + ASSERT(source.is_constant());
|
| + ASSERT(expr->AsLiteral() != NULL);
|
| + __ mov(r0, Operand(expr->AsLiteral()->handle()));
|
| + }
|
| __ RecordJSReturn();
|
| __ mov(sp, fp);
|
| __ ldm(ia_w, sp, fp.bit() | lr.bit());
|
| @@ -143,33 +154,46 @@
|
| }
|
|
|
|
|
| -void FastCodeGenerator::VisitLiteral(Literal* expr) {
|
| - Comment cmnt(masm_, "[ Literal");
|
| - if (expr->location().is_temporary()) {
|
| - __ mov(ip, Operand(expr->handle()));
|
| - __ push(ip);
|
| - } else {
|
| - ASSERT(expr->location().is_nowhere());
|
| - }
|
| -}
|
| -
|
| -
|
| 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);
|
|
|
| - Visit(expr->value());
|
| -
|
| + // Left-hand side is always a (parameter or local) slot.
|
| Variable* var = expr->target()->AsVariableProxy()->AsVariable();
|
| ASSERT(var != NULL && var->slot() != NULL);
|
|
|
| - if (expr->location().is_temporary()) {
|
| - __ ldr(ip, MemOperand(sp));
|
| + // Complete the assignment based on the location of the right-hand-side
|
| + // value and the desired location of the assignment value.
|
| + Location destination = expr->location();
|
| + Location source = rhs->location();
|
| + ASSERT(!destination.is_constant());
|
| + ASSERT(!source.is_nowhere());
|
| +
|
| + if (source.is_temporary()) {
|
| + if (destination.is_temporary()) {
|
| + // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side temporary
|
| + // on the stack.
|
| + __ ldr(ip, MemOperand(sp));
|
| + } else {
|
| + ASSERT(destination.is_nowhere());
|
| + // Case 'var = temp'. Discard right-hand-side temporary.
|
| + __ pop(ip);
|
| + }
|
| + __ str(ip, MemOperand(fp, SlotOffset(var->slot())));
|
| } else {
|
| - ASSERT(expr->location().is_nowhere());
|
| - __ pop(ip);
|
| + 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(ip, Operand(rhs->AsLiteral()->handle()));
|
| + __ str(ip, MemOperand(fp, SlotOffset(var->slot())));
|
| + if (destination.is_temporary()) {
|
| + // Case 'temp <- (var = constant)'. Save result.
|
| + __ push(ip);
|
| + }
|
| }
|
| - __ str(ip, MemOperand(fp, SlotOffset(var->slot())));
|
| }
|
|
|
|
|
|
|