Fix a bug in our handling of conditional expressions in test contexts.
authorkmillikin@chromium.org <kmillikin@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 8 Oct 2010 13:07:55 +0000 (13:07 +0000)
committerkmillikin@chromium.org <kmillikin@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 8 Oct 2010 13:07:55 +0000 (13:07 +0000)
In the FullCodeGenerator, we compile the true subexpression of a
conditional (ternary) expression in the inherited context of the
entire expression.  This is correct for effect and value contexts, but
not for test contexts where the context includes a possible
fall-through label.

Review URL: http://codereview.chromium.org/3621013

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5607 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/full-codegen.cc
src/full-codegen.h

index 796b071..97987c2 100644 (file)
@@ -1128,9 +1128,14 @@ void FullCodeGenerator::VisitConditional(Conditional* expr) {
   __ bind(&true_case);
   SetExpressionPosition(expr->then_expression(),
                         expr->then_expression_position());
-  Visit(expr->then_expression());
-  // If control flow falls through Visit, jump to done.
-  if (!context()->IsTest()) {
+  if (context()->IsTest()) {
+    const TestContext* for_test = TestContext::cast(context());
+    VisitForControl(expr->then_expression(),
+                    for_test->true_label(),
+                    for_test->false_label(),
+                    NULL);
+  } else {
+    Visit(expr->then_expression());
     __ jmp(&done);
   }
 
index 9e126b8..201507b 100644 (file)
@@ -604,6 +604,15 @@ class FullCodeGenerator: public AstVisitor {
           false_label_(false_label),
           fall_through_(fall_through) { }
 
+    static const TestContext* cast(const ExpressionContext* context) {
+      ASSERT(context->IsTest());
+      return reinterpret_cast<const TestContext*>(context);
+    }
+
+    Label* true_label() const { return true_label_; }
+    Label* false_label() const { return false_label_; }
+    Label* fall_through() const { return fall_through_; }
+
     virtual void Plug(bool flag) const;
     virtual void Plug(Register reg) const;
     virtual void Plug(Label* materialize_true, Label* materialize_false) const;