Author: [email protected]
Date: Wed Dec 17 05:16:38 2008
New Revision: 990

Modified:
    branches/bleeding_edge/src/jsregexp.cc
    branches/bleeding_edge/src/jsregexp.h
    branches/bleeding_edge/test/cctest/test-regexp.cc

Log:
Fixed bug in interest propagation caused by following the loop edge
out of a loop choice node before the continuation edge.


Modified: branches/bleeding_edge/src/jsregexp.cc
==============================================================================
--- branches/bleeding_edge/src/jsregexp.cc      (original)
+++ branches/bleeding_edge/src/jsregexp.cc      Wed Dec 17 05:16:38 2008
@@ -1596,6 +1596,11 @@
  #undef DEFINE_ACCEPT


+void LoopChoiceNode::Accept(NodeVisitor* visitor) {
+  visitor->VisitLoopChoice(this);
+}
+
+
  // -------------------------------------------------------------------
  // Emit code.

@@ -2070,6 +2075,20 @@
  }


+void LoopChoiceNode::AddLoopAlternative(GuardedAlternative alt) {
+  ASSERT_EQ(loop_node_, NULL);
+  AddAlternative(alt);
+  loop_node_ = alt.node();
+}
+
+
+void LoopChoiceNode::AddContinueAlternative(GuardedAlternative alt) {
+  ASSERT_EQ(continue_node_, NULL);
+  AddAlternative(alt);
+  continue_node_ = alt.node();
+}
+
+
  bool LoopChoiceNode::Emit(RegExpCompiler* compiler,
                            GenerationVariant* variant) {
    RegExpMacroAssembler* macro_assembler = compiler->macro_assembler();
@@ -2680,7 +2699,7 @@
    bool has_max = max < RegExpTree::kInfinity;
    bool needs_counter = has_min || has_max;
    int reg_ctr = needs_counter ? compiler->AllocateRegister() : -1;
-  ChoiceNode* center = new LoopChoiceNode(2);
+  LoopChoiceNode* center = new LoopChoiceNode();
    RegExpNode* loop_return = needs_counter
        ? static_cast<RegExpNode*>(ActionNode::IncrementRegister(reg_ctr,  
center))
        : static_cast<RegExpNode*>(center);
@@ -2696,11 +2715,11 @@
      rest_alt.AddGuard(rest_guard);
    }
    if (is_greedy) {
-    center->AddAlternative(body_alt);
-    center->AddAlternative(rest_alt);
+    center->AddLoopAlternative(body_alt);
+    center->AddContinueAlternative(rest_alt);
    } else {
-    center->AddAlternative(rest_alt);
-    center->AddAlternative(body_alt);
+    center->AddContinueAlternative(rest_alt);
+    center->AddLoopAlternative(body_alt);
    }
    if (needs_counter) {
      return ActionNode::SetRegister(reg_ctr, 0, center);
@@ -3355,6 +3374,22 @@
      // this node also, so it can pass it on.
      info->AddFromFollowing(node->info());
    }
+}
+
+
+void AssertionPropagation::VisitLoopChoice(LoopChoiceNode* that) {
+  NodeInfo* info = that->info();
+  for (int i = 0; i < that->alternatives()->length(); i++) {
+    RegExpNode* node = that->alternatives()->at(i).node();
+    if (node != that->loop_node()) {
+      EnsureAnalyzed(node);
+      info->AddFromFollowing(node->info());
+    }
+  }
+  // Check the loop last since it may need the value of this node
+  // to get a correct result.
+  EnsureAnalyzed(that->loop_node());
+  info->AddFromFollowing(that->loop_node()->info());
  }



Modified: branches/bleeding_edge/src/jsregexp.h
==============================================================================
--- branches/bleeding_edge/src/jsregexp.h       (original)
+++ branches/bleeding_edge/src/jsregexp.h       Wed Dec 17 05:16:38 2008
@@ -912,9 +912,28 @@

  class LoopChoiceNode: public ChoiceNode {
   public:
-  explicit LoopChoiceNode(int expected_size) : ChoiceNode(expected_size) {  
}
+  explicit LoopChoiceNode()
+      : ChoiceNode(2),
+        loop_node_(NULL),
+        continue_node_(NULL) { }
+  void AddLoopAlternative(GuardedAlternative alt);
+  void AddContinueAlternative(GuardedAlternative alt);
    virtual bool Emit(RegExpCompiler* compiler, GenerationVariant* variant);
    virtual LoopChoiceNode* Clone() { return new LoopChoiceNode(*this); }
+  RegExpNode* loop_node() { return loop_node_; }
+  RegExpNode* continue_node() { return continue_node_; }
+  virtual void Accept(NodeVisitor* visitor);
+
+ private:
+  // AddAlternative is made private for loop nodes because alternatives
+  // should not be added freely, we need to keep track of which node
+  // goes back to the node itself.
+  void AddAlternative(GuardedAlternative node) {
+    ChoiceNode::AddAlternative(node);
+  }
+
+  RegExpNode* loop_node_;
+  RegExpNode* continue_node_;
  };


@@ -1024,6 +1043,7 @@
    virtual void Visit##Type(Type##Node* that) = 0;
  FOR_EACH_NODE_TYPE(DECLARE_VISIT)
  #undef DECLARE_VISIT
+  virtual void VisitLoopChoice(LoopChoiceNode* that) { VisitChoice(that); }
  };


@@ -1105,6 +1125,7 @@
    virtual void Visit##Type(Type##Node* that);
  FOR_EACH_NODE_TYPE(DECLARE_VISIT)
  #undef DECLARE_VISIT
+  virtual void VisitLoopChoice(LoopChoiceNode* that);

   private:
    bool ignore_case_;

Modified: branches/bleeding_edge/test/cctest/test-regexp.cc
==============================================================================
--- branches/bleeding_edge/test/cctest/test-regexp.cc   (original)
+++ branches/bleeding_edge/test/cctest/test-regexp.cc   Wed Dec 17 05:16:38  
2008
@@ -1466,5 +1466,5 @@

  TEST(Graph) {
    V8::Initialize(NULL);
-  Execute("\\bboy\\b", false, true, true);
+  Execute("\\b\\w+\\b", false, true, true);
  }

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

Reply via email to