diff --git a/src/compiler.cc b/src/compiler.cc index 22384bf8d1..75060b0a7b 100644 --- a/src/compiler.cc +++ b/src/compiler.cc @@ -708,12 +708,20 @@ void CodeGenSelector::VisitSwitchStatement(SwitchStatement* stmt) { void CodeGenSelector::VisitDoWhileStatement(DoWhileStatement* stmt) { - BAILOUT("DoWhileStatement"); + // We do not handle loops with breaks or continue statements in their + // body. We will bailout when we hit those statements in the body. + ProcessExpression(stmt->cond(), Expression::kTest); + CHECK_BAILOUT; + Visit(stmt->body()); } void CodeGenSelector::VisitWhileStatement(WhileStatement* stmt) { - BAILOUT("WhileStatement"); + // We do not handle loops with breaks or continue statements in their + // body. We will bailout when we hit those statements in the body. + ProcessExpression(stmt->cond(), Expression::kTest); + CHECK_BAILOUT; + Visit(stmt->body()); } diff --git a/src/fast-codegen.cc b/src/fast-codegen.cc index f5a6157de9..bb5ed8ab08 100644 --- a/src/fast-codegen.cc +++ b/src/fast-codegen.cc @@ -304,12 +304,53 @@ void FastCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { void FastCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { - UNREACHABLE(); + Comment cmnt(masm_, "[ DoWhileStatement"); + increment_loop_depth(); + Label body, exit; + + // Emit the test at the bottom of the loop. + __ bind(&body); + Visit(stmt->body()); + + // We are not in an expression context because we have been compiling + // statements. Set up a test expression context for the condition. + ASSERT_EQ(NULL, true_label_); + ASSERT_EQ(NULL, false_label_); + true_label_ = &body; + false_label_ = &exit; + ASSERT(stmt->cond()->context() == Expression::kTest); + Visit(stmt->cond()); + + __ bind(&exit); + + decrement_loop_depth(); } void FastCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { - UNREACHABLE(); + Comment cmnt(masm_, "[ WhileStatement"); + increment_loop_depth(); + Label test, body, exit; + + // Emit the test at the bottom of the loop. + __ jmp(&test); + + __ bind(&body); + Visit(stmt->body()); + + __ bind(&test); + // We are not in an expression context because we have been compiling + // statements. Set up a test expression context for the condition. + ASSERT_EQ(NULL, true_label_); + ASSERT_EQ(NULL, false_label_); + true_label_ = &body; + false_label_ = &exit; + ASSERT(stmt->cond()->context() == Expression::kTest); + Visit(stmt->cond()); + + __ bind(&exit); + + decrement_loop_depth(); }