Fixed bug in interest propagation caused by following the loop edge

out of a loop choice node before the continuation edge.


git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@990 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 281845d3
......@@ -1596,6 +1596,11 @@ FOR_EACH_NODE_TYPE(DEFINE_ACCEPT)
#undef DEFINE_ACCEPT
void LoopChoiceNode::Accept(NodeVisitor* visitor) {
visitor->VisitLoopChoice(this);
}
// -------------------------------------------------------------------
// Emit code.
......@@ -2070,6 +2075,20 @@ int ChoiceNode::GreedyLoopTextLength(GuardedAlternative* alternative) {
}
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 @@ RegExpNode* RegExpQuantifier::ToNode(int min,
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 @@ RegExpNode* RegExpQuantifier::ToNode(int min,
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);
......@@ -3358,6 +3377,22 @@ void AssertionPropagation::VisitChoice(ChoiceNode* that) {
}
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());
}
void AssertionPropagation::VisitBackReference(BackReferenceNode* that) {
EnsureAnalyzed(that->on_success());
}
......
......@@ -912,9 +912,28 @@ class ChoiceNode: public RegExpNode {
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 @@ class NodeVisitor {
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 @@ class AssertionPropagation: public NodeVisitor {
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_;
......
......@@ -1466,5 +1466,5 @@ TEST(CharClassDifference) {
TEST(Graph) {
V8::Initialize(NULL);
Execute("\\bboy\\b", false, true, true);
Execute("\\b\\w+\\b", false, true, true);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment