From e4f5b74dd1ce0d87fb0237f96d0aca5dc7f043c4 Mon Sep 17 00:00:00 2001 From: "whesse@chromium.org" Date: Mon, 2 Nov 2009 08:44:19 +0000 Subject: [PATCH] Add conditional expressions (ternary choice operator) to fast compiler. Review URL: http://codereview.chromium.org/340058 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3192 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/compiler.cc | 6 +++++- src/fast-codegen.cc | 31 ++++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/compiler.cc b/src/compiler.cc index 63824f566f..4ff6bc65d8 100644 --- a/src/compiler.cc +++ b/src/compiler.cc @@ -625,7 +625,11 @@ void CodeGenSelector::VisitFunctionBoilerplateLiteral( void CodeGenSelector::VisitConditional(Conditional* expr) { - BAILOUT("Conditional"); + ProcessExpression(expr->condition(), Expression::kTest); + CHECK_BAILOUT; + ProcessExpression(expr->then_expression(), context_); + CHECK_BAILOUT; + ProcessExpression(expr->else_expression(), context_); } diff --git a/src/fast-codegen.cc b/src/fast-codegen.cc index 411ae0c484..7d7b21fdc5 100644 --- a/src/fast-codegen.cc +++ b/src/fast-codegen.cc @@ -380,7 +380,36 @@ void FastCodeGenerator::VisitFunctionBoilerplateLiteral( void FastCodeGenerator::VisitConditional(Conditional* expr) { - UNREACHABLE(); + ASSERT_EQ(Expression::kTest, expr->condition()->context()); + ASSERT_EQ(expr->context(), expr->then_expression()->context()); + ASSERT_EQ(expr->context(), expr->else_expression()->context()); + + + Label true_case, false_case, done; + Label* saved_true = true_label_; + Label* saved_false = false_label_; + + true_label_ = &true_case; + false_label_ = &false_case; + Visit(expr->condition()); + true_label_ = saved_true; + false_label_ = saved_false; + + __ bind(&true_case); + Visit(expr->then_expression()); + // If control flow falls through Visit, jump to done. + if (expr->context() == Expression::kEffect || + expr->context() == Expression::kValue) { + __ jmp(&done); + } + + __ bind(&false_case); + Visit(expr->else_expression()); + // If control flow falls through Visit, merge it with true case here. + if (expr->context() == Expression::kEffect || + expr->context() == Expression::kValue) { + __ bind(&done); + } }