Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(186)

Unified Diff: src/jsregexp.cc

Issue 14837: Remove assertion expansion. (Closed)
Patch Set: Added a bugfix Created 12 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/jsregexp.h ('k') | src/parser.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/jsregexp.cc
diff --git a/src/jsregexp.cc b/src/jsregexp.cc
index 4855443debffd54d9f9a88a9cdb12d4a50d0a2be..ce370e739d5ca2774813ddbdb6c6e1cb9e7b17c2 100644
--- a/src/jsregexp.cc
+++ b/src/jsregexp.cc
@@ -2453,17 +2453,6 @@ void DotPrinter::PrintAttributes(RegExpNode* that) {
printer.PrintBit("NI", info->follows_newline_interest);
printer.PrintBit("WI", info->follows_word_interest);
printer.PrintBit("SI", info->follows_start_interest);
- printer.PrintBit("DN", info->determine_newline);
- printer.PrintBit("DW", info->determine_word);
- printer.PrintBit("DS", info->determine_start);
- printer.PrintBit("DDN", info->does_determine_newline);
- printer.PrintBit("DDW", info->does_determine_word);
- printer.PrintBit("DDS", info->does_determine_start);
- printer.PrintPositive("IW", info->is_word);
- printer.PrintPositive("IN", info->is_newline);
- printer.PrintPositive("FN", info->follows_newline);
- printer.PrintPositive("FW", info->follows_word);
- printer.PrintPositive("FS", info->follows_start);
Label* label = that->label();
if (label->is_bound())
printer.PrintPositive("@", label->pos());
@@ -3075,7 +3064,6 @@ RegExpNode* RegExpNode::TryGetSibling(NodeInfo* info) {
RegExpNode* RegExpNode::EnsureSibling(NodeInfo* info, bool* cloned) {
ASSERT_EQ(false, *cloned);
- ASSERT(!info->HasAssertions());
siblings_.Ensure(this);
RegExpNode* result = TryGetSibling(info);
if (result != NULL) return result;
@@ -3307,7 +3295,7 @@ OutSet* DispatchTable::Get(uc16 value) {
// Analysis
-void AssertionPropagation::EnsureAnalyzed(RegExpNode* that) {
+void Analysis::EnsureAnalyzed(RegExpNode* that) {
if (that->info()->been_analyzed || that->info()->being_analyzed)
return;
that->info()->being_analyzed = true;
@@ -3317,7 +3305,7 @@ void AssertionPropagation::EnsureAnalyzed(RegExpNode* that) {
}
-void AssertionPropagation::VisitEnd(EndNode* that) {
+void Analysis::VisitEnd(EndNode* that) {
// nothing to do
}
@@ -3340,23 +3328,16 @@ void TextNode::CalculateOffsets() {
}
-void AssertionPropagation::VisitText(TextNode* that) {
+void Analysis::VisitText(TextNode* that) {
if (ignore_case_) {
that->MakeCaseIndependent();
}
EnsureAnalyzed(that->on_success());
- NodeInfo* info = that->info();
- NodeInfo* next_info = that->on_success()->info();
- // If the following node is interested in what it follows then this
- // node must determine it.
- info->determine_newline = next_info->follows_newline_interest;
- info->determine_word = next_info->follows_word_interest;
- info->determine_start = next_info->follows_start_interest;
that->CalculateOffsets();
}
-void AssertionPropagation::VisitAction(ActionNode* that) {
+void Analysis::VisitAction(ActionNode* that) {
RegExpNode* target = that->on_success();
EnsureAnalyzed(target);
// If the next node is interested in what it follows then this node
@@ -3365,7 +3346,7 @@ void AssertionPropagation::VisitAction(ActionNode* that) {
}
-void AssertionPropagation::VisitChoice(ChoiceNode* that) {
+void Analysis::VisitChoice(ChoiceNode* that) {
NodeInfo* info = that->info();
for (int i = 0; i < that->alternatives()->length(); i++) {
RegExpNode* node = that->alternatives()->at(i).node();
@@ -3377,7 +3358,7 @@ void AssertionPropagation::VisitChoice(ChoiceNode* that) {
}
-void AssertionPropagation::VisitLoopChoice(LoopChoiceNode* that) {
+void Analysis::VisitLoopChoice(LoopChoiceNode* that) {
NodeInfo* info = that->info();
for (int i = 0; i < that->alternatives()->length(); i++) {
RegExpNode* node = that->alternatives()->at(i).node();
@@ -3393,212 +3374,12 @@ void AssertionPropagation::VisitLoopChoice(LoopChoiceNode* that) {
}
-void AssertionPropagation::VisitBackReference(BackReferenceNode* that) {
+void Analysis::VisitBackReference(BackReferenceNode* that) {
EnsureAnalyzed(that->on_success());
}
// -------------------------------------------------------------------
-// Assumption expansion
-
-
-RegExpNode* RegExpNode::EnsureExpanded(NodeInfo* info) {
- siblings_.Ensure(this);
- NodeInfo new_info = *this->info();
- if (new_info.follows_word_interest)
- new_info.follows_word = info->follows_word;
- if (new_info.follows_newline_interest)
- new_info.follows_newline = info->follows_newline;
- // If the following node should determine something we need to get
- // a sibling that determines it.
- new_info.does_determine_newline = new_info.determine_newline;
- new_info.does_determine_word = new_info.determine_word;
- new_info.does_determine_start = new_info.determine_start;
- RegExpNode* sibling = TryGetSibling(&new_info);
- if (sibling == NULL) {
- sibling = ExpandLocal(&new_info);
- siblings_.Add(sibling);
- sibling->info()->being_expanded = true;
- sibling->ExpandChildren();
- sibling->info()->being_expanded = false;
- sibling->info()->been_expanded = true;
- } else {
- NodeInfo* sib_info = sibling->info();
- if (!sib_info->been_expanded && !sib_info->being_expanded) {
- sibling->info()->being_expanded = true;
- sibling->ExpandChildren();
- sibling->info()->being_expanded = false;
- sibling->info()->been_expanded = true;
- }
- }
- return sibling;
-}
-
-
-RegExpNode* ChoiceNode::ExpandLocal(NodeInfo* info) {
- ChoiceNode* clone = this->Clone();
- clone->info()->ResetCompilationState();
- clone->info()->AddAssumptions(info);
- return clone;
-}
-
-
-void ChoiceNode::ExpandChildren() {
- ZoneList<GuardedAlternative>* alts = alternatives();
- ZoneList<GuardedAlternative>* new_alts
- = new ZoneList<GuardedAlternative>(alts->length());
- for (int i = 0; i < alts->length(); i++) {
- GuardedAlternative next = alts->at(i);
- next.set_node(next.node()->EnsureExpanded(info()));
- new_alts->Add(next);
- }
- alternatives_ = new_alts;
-}
-
-
-RegExpNode* TextNode::ExpandLocal(NodeInfo* info) {
- TextElement last = elements()->last();
- if (last.type == TextElement::CHAR_CLASS) {
- RegExpCharacterClass* char_class = last.data.u_char_class;
- if (info->does_determine_word) {
- ZoneList<CharacterRange>* word = NULL;
- ZoneList<CharacterRange>* non_word = NULL;
- CharacterRange::Split(char_class->ranges(),
- CharacterRange::GetWordBounds(),
- &word,
- &non_word);
- if (non_word == NULL) {
- // This node contains no non-word characters so it must be
- // all word.
- this->info()->is_word = NodeInfo::TRUE;
- } else if (word == NULL) {
- // Vice versa.
- this->info()->is_word = NodeInfo::FALSE;
- } else {
- // If this character class contains both word and non-word
- // characters we need to split it into two.
- ChoiceNode* result = new ChoiceNode(2);
- // Welcome to the family, son!
- result->set_siblings(this->siblings());
- *result->info() = *this->info();
- result->info()->ResetCompilationState();
- result->info()->AddAssumptions(info);
- RegExpNode* word_node
- = new TextNode(new RegExpCharacterClass(word, false),
- on_success());
- word_node->info()->determine_word = true;
- word_node->info()->does_determine_word = true;
- word_node->info()->is_word = NodeInfo::TRUE;
- result->alternatives()->Add(GuardedAlternative(word_node));
- RegExpNode* non_word_node
- = new TextNode(new RegExpCharacterClass(non_word, false),
- on_success());
- non_word_node->info()->determine_word = true;
- non_word_node->info()->does_determine_word = true;
- non_word_node->info()->is_word = NodeInfo::FALSE;
- result->alternatives()->Add(GuardedAlternative(non_word_node));
- return result;
- }
- }
- }
- TextNode* clone = this->Clone();
- clone->info()->ResetCompilationState();
- clone->info()->AddAssumptions(info);
- return clone;
-}
-
-
-void TextNode::ExpandAtomChildren(RegExpAtom* that) {
- NodeInfo new_info = *info();
- uc16 last = that->data()[that->data().length() - 1];
- if (info()->determine_word) {
- new_info.follows_word = IsRegExpWord(last)
- ? NodeInfo::TRUE : NodeInfo::FALSE;
- } else {
- new_info.follows_word = NodeInfo::UNKNOWN;
- }
- if (info()->determine_newline) {
- new_info.follows_newline = IsRegExpNewline(last)
- ? NodeInfo::TRUE : NodeInfo::FALSE;
- } else {
- new_info.follows_newline = NodeInfo::UNKNOWN;
- }
- if (info()->determine_start) {
- new_info.follows_start = NodeInfo::FALSE;
- } else {
- new_info.follows_start = NodeInfo::UNKNOWN;
- }
- set_on_success(on_success()->EnsureExpanded(&new_info));
-}
-
-
-void TextNode::ExpandCharClassChildren(RegExpCharacterClass* that) {
- if (info()->does_determine_word) {
- // ASSERT(info()->is_word != NodeInfo::UNKNOWN);
- NodeInfo next_info = *on_success()->info();
- next_info.follows_word = info()->is_word;
- set_on_success(on_success()->EnsureExpanded(&next_info));
- } else {
- set_on_success(on_success()->EnsureExpanded(info()));
- }
-}
-
-
-void TextNode::ExpandChildren() {
- TextElement last = elements()->last();
- switch (last.type) {
- case TextElement::ATOM:
- ExpandAtomChildren(last.data.u_atom);
- break;
- case TextElement::CHAR_CLASS:
- ExpandCharClassChildren(last.data.u_char_class);
- break;
- default:
- UNREACHABLE();
- }
-}
-
-
-RegExpNode* ActionNode::ExpandLocal(NodeInfo* info) {
- ActionNode* clone = this->Clone();
- clone->info()->ResetCompilationState();
- clone->info()->AddAssumptions(info);
- return clone;
-}
-
-
-void ActionNode::ExpandChildren() {
- set_on_success(on_success()->EnsureExpanded(info()));
-}
-
-
-RegExpNode* BackReferenceNode::ExpandLocal(NodeInfo* info) {
- BackReferenceNode* clone = this->Clone();
- clone->info()->ResetCompilationState();
- clone->info()->AddAssumptions(info);
- return clone;
-}
-
-
-void BackReferenceNode::ExpandChildren() {
- set_on_success(on_success()->EnsureExpanded(info()));
-}
-
-
-RegExpNode* EndNode::ExpandLocal(NodeInfo* info) {
- EndNode* clone = this->Clone();
- clone->info()->ResetCompilationState();
- clone->info()->AddAssumptions(info);
- return clone;
-}
-
-
-void EndNode::ExpandChildren() {
- // nothing to do
-}
-
-
-// -------------------------------------------------------------------
// Dispatch table construction
@@ -3708,110 +3489,6 @@ void DispatchTableConstructor::VisitAction(ActionNode* that) {
}
-#ifdef DEBUG
-
-
-class VisitNodeScope {
- public:
- explicit VisitNodeScope(RegExpNode* node) : node_(node) {
- ASSERT(!node->info()->visited);
- node->info()->visited = true;
- }
- ~VisitNodeScope() {
- node_->info()->visited = false;
- }
- private:
- RegExpNode* node_;
-};
-
-
-class NodeValidator : public NodeVisitor {
- public:
- virtual void ValidateInfo(NodeInfo* info) = 0;
-#define DECLARE_VISIT(Type) \
- virtual void Visit##Type(Type##Node* that);
-FOR_EACH_NODE_TYPE(DECLARE_VISIT)
-#undef DECLARE_VISIT
-};
-
-
-class PostAnalysisNodeValidator : public NodeValidator {
- public:
- virtual void ValidateInfo(NodeInfo* info);
-};
-
-
-class PostExpansionNodeValidator : public NodeValidator {
- public:
- virtual void ValidateInfo(NodeInfo* info);
-};
-
-
-void PostAnalysisNodeValidator::ValidateInfo(NodeInfo* info) {
- ASSERT(info->been_analyzed);
-}
-
-
-void PostExpansionNodeValidator::ValidateInfo(NodeInfo* info) {
- ASSERT_EQ(info->determine_newline, info->does_determine_newline);
- ASSERT_EQ(info->determine_start, info->does_determine_start);
- ASSERT_EQ(info->determine_word, info->does_determine_word);
- ASSERT_EQ(info->follows_word_interest,
- (info->follows_word != NodeInfo::UNKNOWN));
- if (false) {
- // These are still unimplemented.
- ASSERT_EQ(info->follows_start_interest,
- (info->follows_start != NodeInfo::UNKNOWN));
- ASSERT_EQ(info->follows_newline_interest,
- (info->follows_newline != NodeInfo::UNKNOWN));
- }
-}
-
-
-void NodeValidator::VisitAction(ActionNode* that) {
- if (that->info()->visited) return;
- VisitNodeScope scope(that);
- ValidateInfo(that->info());
- that->on_success()->Accept(this);
-}
-
-
-void NodeValidator::VisitBackReference(BackReferenceNode* that) {
- if (that->info()->visited) return;
- VisitNodeScope scope(that);
- ValidateInfo(that->info());
- that->on_success()->Accept(this);
-}
-
-
-void NodeValidator::VisitChoice(ChoiceNode* that) {
- if (that->info()->visited) return;
- VisitNodeScope scope(that);
- ValidateInfo(that->info());
- ZoneList<GuardedAlternative>* alts = that->alternatives();
- for (int i = 0; i < alts->length(); i++)
- alts->at(i).node()->Accept(this);
-}
-
-
-void NodeValidator::VisitEnd(EndNode* that) {
- if (that->info()->visited) return;
- VisitNodeScope scope(that);
- ValidateInfo(that->info());
-}
-
-
-void NodeValidator::VisitText(TextNode* that) {
- if (that->info()->visited) return;
- VisitNodeScope scope(that);
- ValidateInfo(that->info());
- that->on_success()->Accept(this);
-}
-
-
-#endif
-
-
Handle<FixedArray> RegExpEngine::Compile(RegExpCompileData* data,
bool ignore_case,
bool is_multiline,
@@ -3834,43 +3511,16 @@ Handle<FixedArray> RegExpEngine::Compile(RegExpCompileData* data,
new RegExpCharacterClass('*'),
&compiler,
captured_body);
- AssertionPropagation analysis(ignore_case);
+ data->node = node;
+ Analysis analysis(ignore_case);
analysis.EnsureAnalyzed(node);
NodeInfo info = *node->info();
- data->has_lookbehind = info.HasLookbehind();
- if (data->has_lookbehind) {
- // If this node needs information about the preceding text we let
- // it start with a character class that consumes a single character
- // and proceeds to wherever is appropriate. This means that if
- // has_lookbehind is set the code generator must start one character
- // before the start position.
- node = new TextNode(new RegExpCharacterClass('*'), node);
- analysis.EnsureAnalyzed(node);
- }
-
-#ifdef DEBUG
- PostAnalysisNodeValidator post_analysis_validator;
- node->Accept(&post_analysis_validator);
-#endif
-
- node = node->EnsureExpanded(&info);
-
-#ifdef DEBUG
- PostExpansionNodeValidator post_expansion_validator;
- node->Accept(&post_expansion_validator);
-#endif
-
- data->node = node;
if (is_multiline && !FLAG_attempt_multiline_irregexp) {
return Handle<FixedArray>::null();
}
- if (data->has_lookbehind) {
- return Handle<FixedArray>::null();
- }
-
if (FLAG_irregexp_native) {
#ifdef ARM
// Unimplemented, fall-through to bytecode implementation.
« no previous file with comments | « src/jsregexp.h ('k') | src/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698