From 52f52ae99fe54b35df7e17a7243f996315583ed4 Mon Sep 17 00:00:00 2001 From: "sandholm@chromium.org" Date: Fri, 4 Jun 2010 11:58:40 +0000 Subject: [PATCH] Simplify regexp test call when the regexp starts and ends with '.*'. Review URL: http://codereview.chromium.org/2645002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4799 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/regexp.js | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/regexp.js b/src/regexp.js index 24e3309..fb9eaee 100644 --- a/src/regexp.js +++ b/src/regexp.js @@ -257,6 +257,10 @@ function RegExpExec(string) { } +// One-element cache for the simplified test regexp. +var regexp_key; +var regexp_val; + // Section 15.10.6.3 doesn't actually make sense, but the intention seems to be // that test is defined in terms of String.prototype.exec. However, it probably // means the original value of String.prototype.exec, which is what everybody @@ -281,9 +285,7 @@ function RegExpTest(string) { } var lastIndex = this.lastIndex; - var cache = regExpCache; - if (%_ObjectEquals(cache.type, 'test') && %_ObjectEquals(cache.regExp, this) && %_ObjectEquals(cache.subject, string) && @@ -291,6 +293,26 @@ function RegExpTest(string) { return cache.answer; } + // Remove irrelevant '.*' around a test regexp. The expression + // checks whether this.source starts and ends with '.*' and that the third + // char is not a '?' and that the third to last char is not a '\'. + if (%_StringCharCodeAt(this.source,0) == 46 && // '.' + %_StringCharCodeAt(this.source,1) == 42 && // '*' + %_StringCharCodeAt(this.source,2) != 63 && // '?' + %_StringCharCodeAt(this.source,this.source.length - 3) != 28 && // '\' + %_StringCharCodeAt(this.source,this.source.length - 2) == 46 && // '.' + %_StringCharCodeAt(this.source,this.source.length - 1) == 42) { // '*' + if (!%_ObjectEquals(regexp_key, this)) { + regexp_key = this; + regexp_val = new $RegExp(this.source.substring(2, + this.source.length - 2), + (this.global ? 'g' : '') + + (this.ignoreCase ? 'i' : '') + + (this.multiline ? 'm' : '')); + } + if (!regexp_val.test(s)) return false; + } + var length = s.length; var i = this.global ? TO_INTEGER(lastIndex) : 0; @@ -299,7 +321,7 @@ function RegExpTest(string) { cache.subject = s; cache.lastIndex = i; - if (i < 0 || i > s.length) { + if (i < 0 || i > length) { this.lastIndex = 0; cache.answer = false; return false; -- 2.7.4