Simplify regexp test call when the regexp starts and ends with '.*'.
authorsandholm@chromium.org <sandholm@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 4 Jun 2010 11:58:40 +0000 (11:58 +0000)
committersandholm@chromium.org <sandholm@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 4 Jun 2010 11:58:40 +0000 (11:58 +0000)
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

index 24e3309..fb9eaee 100644 (file)
@@ -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;