Add conditional expressions (ternary choice operator) to fast compiler.
authorwhesse@chromium.org <whesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 2 Nov 2009 08:44:19 +0000 (08:44 +0000)
committerwhesse@chromium.org <whesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 2 Nov 2009 08:44:19 +0000 (08:44 +0000)
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
src/fast-codegen.cc

index 63824f566f3f5f946067d0bdfe29d9791f16b422..4ff6bc65d8d445fdb960ed0b5d99972f981c8fcc 100644 (file)
@@ -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_);
 }
 
 
index 411ae0c484ebd01601e7044ce17f1cda5adcbe08..7d7b21fdc586f7d7c6b80e519fd9529e85953138 100644 (file)
@@ -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);
+  }
 }