Reviewers: Kasper Lund,

Description:
Fix a bug in our handling of conditional expressions in test contexts.

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.

Please review this at http://codereview.chromium.org/3621013/show

Affected files:
  M src/full-codegen.h
  M src/full-codegen.cc


Index: src/full-codegen.cc
diff --git a/src/full-codegen.cc b/src/full-codegen.cc
index 796b0717cf0e84dc1a627cfeed126f4565e2ab2a..97987c27a80c7aae2c1349a12141fbcf171bad70 100644
--- a/src/full-codegen.cc
+++ b/src/full-codegen.cc
@@ -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: src/full-codegen.h
diff --git a/src/full-codegen.h b/src/full-codegen.h
index 9e126b848356b642f84b3c587c63bd795193f034..201507b2af338ea6e32b59d36c6a8cc145e22e0a 100644
--- a/src/full-codegen.h
+++ b/src/full-codegen.h
@@ -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;


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to