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