| Index: src/arm/fast-codegen-arm.cc
|
| ===================================================================
|
| --- src/arm/fast-codegen-arm.cc (revision 3115)
|
| +++ src/arm/fast-codegen-arm.cc (working copy)
|
| @@ -479,4 +479,61 @@
|
| }
|
|
|
|
|
| +void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
|
| + // Compile a short-circuited boolean or operation in a non-test
|
| + // context.
|
| + ASSERT(expr->op() == Token::OR);
|
| + // Compile (e0 || e1) as if it were
|
| + // (let (temp = e0) temp ? temp : e1).
|
| +
|
| + Label 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);
|
| + // Call the runtime to find the boolean value of the left-hand
|
| + // subexpression. Duplicate the value if it may be needed as the final
|
| + // result.
|
| + if (left_source.is_temporary()) {
|
| + if (destination.is_temporary()) {
|
| + __ ldr(r0, MemOperand(sp));
|
| + __ push(r0);
|
| + }
|
| + } else {
|
| + ASSERT(left->AsLiteral() != NULL);
|
| + __ mov(r0, Operand(left->AsLiteral()->handle()));
|
| + __ push(r0);
|
| + if (destination.is_temporary()) __ push(r0);
|
| + }
|
| + // The left-hand value is in on top of the stack. It is duplicated on the
|
| + // stack iff the destination location is temporary.
|
| + __ CallRuntime(Runtime::kToBool, 1);
|
| + __ LoadRoot(ip, Heap::kTrueValueRootIndex);
|
| + __ cmp(r0, ip);
|
| + __ b(eq, &done);
|
| +
|
| + // Discard the left-hand value if present on the stack.
|
| + if (destination.is_temporary()) __ pop();
|
| + Visit(right);
|
| +
|
| + // Save or discard the right-hand value as needed.
|
| + if (destination.is_temporary() && right_source.is_constant()) {
|
| + ASSERT(right->AsLiteral() != NULL);
|
| + __ mov(ip, Operand(right->AsLiteral()->handle()));
|
| + __ push(ip);
|
| + } else if (destination.is_nowhere() && right_source.is_temporary()) {
|
| + __ pop();
|
| + }
|
| +
|
| + __ bind(&done);
|
| +}
|
| +
|
| } } // namespace v8::internal
|
|
|