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

Unified Diff: src/jsregexp.cc

Issue 10793: More assertion propagation. (Closed)
Patch Set: Created 12 years, 1 month 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.h » ('j') | src/parser.cc » ('J')
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 7bb94826fb07b7ae661d0a275818ed27412d75db..fd28c01d2d2c093f2194aa174bbacd59c7d9136d 100644
--- a/src/jsregexp.cc
+++ b/src/jsregexp.cc
@@ -218,7 +218,7 @@ Handle<Object> RegExpImpl::Compile(Handle<JSRegExp> re,
FlattenString(pattern);
RegExpParseResult parse_result;
FlatStringReader reader(pattern);
- if (!ParseRegExp(&reader, &parse_result)) {
+ if (!ParseRegExp(&reader, flags.is_multiline(), &parse_result)) {
// Throw an exception if we fail to parse the pattern.
ThrowRegExpException(re,
pattern,
@@ -241,7 +241,8 @@ Handle<Object> RegExpImpl::Compile(Handle<JSRegExp> re,
Handle<FixedArray> irregexp_data =
RegExpEngine::Compile(&parse_result,
&node,
- flags.is_ignore_case());
+ flags.is_ignore_case(),
+ flags.is_multiline());
if (irregexp_data.is_null()) {
if (FLAG_disable_jscre) {
UNIMPLEMENTED();
@@ -980,7 +981,8 @@ bool RegExpNode::GoTo(RegExpCompiler* compiler) {
// TODO(erikcorry): Implement support.
if (info_.follows_word_interest ||
info_.follows_newline_interest ||
- info_.follows_start_interest) {
+ info_.follows_start_interest ||
+ info_.at_end) {
return false;
}
if (label_.is_bound()) {
@@ -1002,9 +1004,10 @@ bool RegExpNode::GoTo(RegExpCompiler* compiler) {
bool EndNode::GoTo(RegExpCompiler* compiler) {
- if (info()->follows_word_interest ||
- info()->follows_newline_interest ||
- info()->follows_start_interest) {
+ if (info_.follows_word_interest ||
+ info_.follows_newline_interest ||
+ info_.follows_start_interest ||
+ info_.at_end) {
return false;
}
if (!label()->is_bound()) {
@@ -1629,14 +1632,21 @@ void DotPrinter::PrintAttributes(RegExpNode* that) {
"fontcolor=lightgrey, margin=0.1, fontsize=10, label=\"{",
that);
NodeInfo* info = that->info();
- stream()->Add("{NI|%i}|{SI|%i}|{WI|%i}",
+ stream()->Add("{NI|%i}|{WI|%i}|{SI|%i}",
info->follows_newline_interest,
- info->follows_start_interest,
- info->follows_word_interest);
- stream()->Add("|{DN|%i}|{DS|%i}|{DW|%i}",
+ info->follows_word_interest,
+ info->follows_start_interest);
+ stream()->Add("|{DN|%i}|{DW|%i}|{DS|%i}|{AE|%i}",
info->determine_newline,
+ info->determine_word,
info->determine_start,
- info->determine_word);
+ info->at_end);
+ if (info->follows_newline != NodeInfo::UNKNOWN)
+ stream()->Add("|{FN|%i}", info->follows_newline);
+ if (info->follows_word != NodeInfo::UNKNOWN)
+ stream()->Add("|{FW|%i}", info->follows_word);
+ if (info->follows_start != NodeInfo::UNKNOWN)
+ stream()->Add("|{FS|%i}", info->follows_start);
Label* label = that->label();
if (label->is_bound())
stream()->Add("|{@|%x}", label->pos());
@@ -1924,11 +1934,14 @@ RegExpNode* RegExpAssertion::ToNode(RegExpCompiler* compiler,
case BOUNDARY: case NON_BOUNDARY:
info.follows_word_interest = true;
break;
- case END_OF_LINE: case END_OF_INPUT:
+ case END_OF_INPUT:
+ info.at_end = true;
+ break;
+ case END_OF_LINE:
// This is wrong but has the effect of making the compiler abort.
- info.follows_start_interest = true;
+ info.at_end = true;
}
- return on_success->PropagateInterest(&info);
+ return on_success->PropagateForward(&info);
}
@@ -2216,7 +2229,7 @@ void CharacterRange::AddCaseEquivalents(ZoneList<CharacterRange>* ranges) {
RegExpNode* RegExpNode::GetSibling(NodeInfo* info) {
for (int i = 0; i < siblings_.length(); i++) {
RegExpNode* sibling = siblings_.Get(i);
- if (sibling->info()->SameInterests(info))
+ if (sibling->info()->HasSameForwardInterests(info))
return sibling;
}
return NULL;
@@ -2225,58 +2238,64 @@ RegExpNode* RegExpNode::GetSibling(NodeInfo* info) {
template <class C>
static RegExpNode* PropagateToEndpoint(C* node, NodeInfo* info) {
- RegExpNode* sibling = node->GetSibling(info);
+ NodeInfo full_info(*node->info());
+ full_info.AddFromPreceding(info);
+ RegExpNode* sibling = node->GetSibling(&full_info);
if (sibling != NULL) return sibling;
node->EnsureSiblings();
sibling = new C(*node);
- sibling->info()->AdoptInterests(info);
+ sibling->info()->AddFromPreceding(&full_info);
node->AddSibling(sibling);
return sibling;
}
-RegExpNode* ActionNode::PropagateInterest(NodeInfo* info) {
- RegExpNode* sibling = GetSibling(info);
+RegExpNode* ActionNode::PropagateForward(NodeInfo* info) {
+ NodeInfo full_info(*this->info());
+ full_info.AddFromPreceding(info);
+ RegExpNode* sibling = GetSibling(&full_info);
if (sibling != NULL) return sibling;
EnsureSiblings();
ActionNode* action = new ActionNode(*this);
- action->info()->AdoptInterests(info);
+ action->info()->AddFromPreceding(&full_info);
AddSibling(action);
- action->set_on_success(action->on_success()->PropagateInterest(info));
+ action->set_on_success(action->on_success()->PropagateForward(info));
return action;
}
-RegExpNode* ChoiceNode::PropagateInterest(NodeInfo* info) {
- RegExpNode* sibling = GetSibling(info);
+RegExpNode* ChoiceNode::PropagateForward(NodeInfo* info) {
+ NodeInfo full_info(*this->info());
+ full_info.AddFromPreceding(info);
+ RegExpNode* sibling = GetSibling(&full_info);
if (sibling != NULL) return sibling;
EnsureSiblings();
ChoiceNode* choice = new ChoiceNode(*this);
- choice->info()->AdoptInterests(info);
+ choice->info()->AddFromPreceding(&full_info);
AddSibling(choice);
ZoneList<GuardedAlternative>* old_alternatives = alternatives();
int count = old_alternatives->length();
choice->alternatives_ = new ZoneList<GuardedAlternative>(count);
for (int i = 0; i < count; i++) {
GuardedAlternative alternative = old_alternatives->at(i);
- alternative.set_node(alternative.node()->PropagateInterest(info));
+ alternative.set_node(alternative.node()->PropagateForward(info));
choice->alternatives()->Add(alternative);
}
return choice;
}
-RegExpNode* EndNode::PropagateInterest(NodeInfo* info) {
+RegExpNode* EndNode::PropagateForward(NodeInfo* info) {
return PropagateToEndpoint(this, info);
}
-RegExpNode* BackReferenceNode::PropagateInterest(NodeInfo* info) {
+RegExpNode* BackReferenceNode::PropagateForward(NodeInfo* info) {
return PropagateToEndpoint(this, info);
}
-RegExpNode* TextNode::PropagateInterest(NodeInfo* info) {
+RegExpNode* TextNode::PropagateForward(NodeInfo* info) {
return PropagateToEndpoint(this, info);
}
@@ -2455,15 +2474,21 @@ void Analysis::VisitText(TextNode* that) {
}
EnsureAnalyzed(that->on_success());
EnsureAnalyzed(that->on_failure());
+ 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;
}
void Analysis::VisitAction(ActionNode* that) {
- RegExpNode* next = that->on_success();
- EnsureAnalyzed(next);
- that->info()->determine_newline = next->info()->prev_determine_newline();
- that->info()->determine_word = next->info()->prev_determine_word();
- that->info()->determine_start = next->info()->prev_determine_start();
+ EnsureAnalyzed(that->on_success());
+ // If the next node is interested in what it follows then this node
+ // has to be interested too so it can pass the information on.
+ that->info()->AddFromFollowing(that->on_success()->info());
}
@@ -2472,9 +2497,9 @@ void Analysis::VisitChoice(ChoiceNode* that) {
for (int i = 0; i < that->alternatives()->length(); i++) {
RegExpNode* node = that->alternatives()->at(i).node();
EnsureAnalyzed(node);
- info->determine_newline |= node->info()->prev_determine_newline();
- info->determine_word |= node->info()->prev_determine_word();
- info->determine_start |= node->info()->prev_determine_start();
+ // Anything the following nodes need to know has to be known by
+ // this node also, so it can pass it on.
+ info->AddFromFollowing(node->info());
}
if (!that->table_calculated()) {
DispatchTableConstructor cons(that->table());
@@ -2607,7 +2632,8 @@ void DispatchTableConstructor::VisitAction(ActionNode* that) {
Handle<FixedArray> RegExpEngine::Compile(RegExpParseResult* input,
RegExpNode** node_return,
- bool ignore_case) {
+ bool ignore_case,
+ bool is_multiline) {
RegExpCompiler compiler(input->capture_count, ignore_case);
// Wrap the body of the regexp in capture #0.
RegExpNode* captured_body = RegExpCapture::ToNode(input->tree,
« no previous file with comments | « src/jsregexp.h ('k') | src/parser.h » ('j') | src/parser.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698