}
+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
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();
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++) {
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
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_; }
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_; }
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_; }
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(); }
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_; }
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);
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+/);
[ $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