review


git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1130 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 5ffd6a61
......@@ -244,6 +244,36 @@ Interval RegExpQuantifier::CaptureRegisters() {
}
bool RegExpAssertion::IsAnchored() {
return type() == RegExpAssertion::START_OF_INPUT;
}
bool RegExpAlternative::IsAnchored() {
return this->nodes()->at(0)->IsAnchored();
}
bool RegExpDisjunction::IsAnchored() {
ZoneList<RegExpTree*>* alternatives = this->alternatives();
for (int i = 0; i < alternatives->length(); i++) {
if (!alternatives->at(i)->IsAnchored())
return false;
}
return true;
}
bool RegExpLookahead::IsAnchored() {
return is_positive() && body()->IsAnchored();
}
bool RegExpCapture::IsAnchored() {
return body()->IsAnchored();
}
// Convert regular expression trees to a simple sexp representation.
// This representation should be different from the input grammar
// in as many cases as possible, to make it more difficult for incorrect
......@@ -417,6 +447,7 @@ SmartPointer<const char> RegExpTree::ToString() {
RegExpDisjunction::RegExpDisjunction(ZoneList<RegExpTree*>* alternatives)
: alternatives_(alternatives) {
ASSERT(alternatives->length() > 1);
RegExpTree* first_alternative = alternatives->at(0);
min_match_ = first_alternative->min_match();
max_match_ = first_alternative->max_match();
......@@ -430,6 +461,7 @@ RegExpDisjunction::RegExpDisjunction(ZoneList<RegExpTree*>* alternatives)
RegExpAlternative::RegExpAlternative(ZoneList<RegExpTree*>* nodes)
: nodes_(nodes) {
ASSERT(nodes->length() > 1);
min_match_ = 0;
max_match_ = 0;
for (int i = 0; i < nodes->length(); i++) {
......
......@@ -1253,6 +1253,7 @@ class RegExpTree: public ZoneObject {
virtual RegExpNode* ToNode(RegExpCompiler* compiler,
RegExpNode* on_success) = 0;
virtual bool IsTextElement() { return false; }
virtual bool IsAnchored() { return false; }
virtual int min_match() = 0;
virtual int max_match() = 0;
// Returns the interval of registers used for captures within this
......@@ -1277,6 +1278,7 @@ class RegExpDisjunction: public RegExpTree {
virtual RegExpDisjunction* AsDisjunction();
virtual Interval CaptureRegisters();
virtual bool IsDisjunction();
virtual bool IsAnchored();
virtual int min_match() { return min_match_; }
virtual int max_match() { return max_match_; }
ZoneList<RegExpTree*>* alternatives() { return alternatives_; }
......@@ -1296,6 +1298,7 @@ class RegExpAlternative: public RegExpTree {
virtual RegExpAlternative* AsAlternative();
virtual Interval CaptureRegisters();
virtual bool IsAlternative();
virtual bool IsAnchored();
virtual int min_match() { return min_match_; }
virtual int max_match() { return max_match_; }
ZoneList<RegExpTree*>* nodes() { return nodes_; }
......@@ -1322,6 +1325,7 @@ class RegExpAssertion: public RegExpTree {
RegExpNode* on_success);
virtual RegExpAssertion* AsAssertion();
virtual bool IsAssertion();
virtual bool IsAnchored();
virtual int min_match() { return 0; }
virtual int max_match() { return 0; }
Type type() { return type_; }
......@@ -1495,6 +1499,7 @@ class RegExpCapture: public RegExpTree {
RegExpCompiler* compiler,
RegExpNode* on_success);
virtual RegExpCapture* AsCapture();
virtual bool IsAnchored();
virtual Interval CaptureRegisters();
virtual bool IsCapture();
virtual int min_match() { return body_->min_match(); }
......@@ -1525,6 +1530,7 @@ class RegExpLookahead: public RegExpTree {
virtual RegExpLookahead* AsLookahead();
virtual Interval CaptureRegisters();
virtual bool IsLookahead();
virtual bool IsAnchored();
virtual int min_match() { return 0; }
virtual int max_match() { return 0; }
RegExpTree* body() { return body_; }
......
......@@ -4643,17 +4643,17 @@ Handle<FixedArray> RegExpEngine::Compile(RegExpCompileData* data,
0,
&compiler,
compiler.accept());
// Add a .*? at the beginning, outside the body capture.
// Note: We could choose to not add this if the regexp is anchored at
// the start of the input but I'm not sure how best to do that and
// since we don't even handle ^ yet I'm saving that optimization for
// later.
RegExpNode* node = RegExpQuantifier::ToNode(0,
RegExpTree::kInfinity,
false,
new RegExpCharacterClass('*'),
&compiler,
captured_body);
RegExpNode* node = captured_body;
if (!data->tree->IsAnchored()) {
// Add a .*? at the beginning, outside the body capture, unless
// this expression is anchored at the beginning.
node = RegExpQuantifier::ToNode(0,
RegExpTree::kInfinity,
false,
new RegExpCharacterClass('*'),
&compiler,
captured_body);
}
data->node = node;
Analysis analysis(ignore_case);
analysis.EnsureAnalyzed(node);
......
......@@ -37,9 +37,13 @@ for (i = 0; i < 18; i++) {
s = s + s;
}
var re = /^bar/;
for (i = 0; i < 1000; i++) {
re.test(s);
re = new RegExp("^bar");
function repeatRegexp(re) {
for (i = 0; i < 1000; i++) {
re.test(s);
}
}
repeatRegexp(/^bar/);
repeatRegexp(/^foo|^bar|^baz/);
repeatRegexp(/(^bar)/);
repeatRegexp(/(?=^bar)\w+/);
......@@ -44,10 +44,6 @@ regexp-loop-capture: PASS || FAIL
[ $arch == arm ]
# Optimize regexp search for non-multiline initial ^.
# http://code.google.com/p/v8/issues/detail?id=198
ascii-regexp-subject: PASS || FAIL
# Slow tests which times out in debug mode.
try: PASS, SKIP if $mode == debug
debug-scripts-request: PASS, SKIP if $mode == debug
......
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