Make Script.prototype.nameOrSourceURL use indexOf search first before trying to match...
authorlrn@chromium.org <lrn@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 18 Mar 2011 13:40:48 +0000 (13:40 +0000)
committerlrn@chromium.org <lrn@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 18 Mar 2011 13:40:48 +0000 (13:40 +0000)
This should use Boyer-Moore search with a long string, which is potentially
faster than RegExp search.
The target string is typically, but not guaranteed, at the end of the
source, so for long sources, there will be a lot of characters to skip.

Review URL: http://codereview.chromium.org/6709027

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7263 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/messages.js

index ea0096f..45de71c 100644 (file)
@@ -495,10 +495,24 @@ Script.prototype.nameOrSourceURL = function() {
   // because this file is being processed by js2c whose handling of spaces
   // in regexps is broken. Also, ['"] are excluded from allowed URLs to
   // avoid matches against sources that invoke evals with sourceURL.
-  var sourceUrlPattern =
-    /\/\/@[\040\t]sourceURL=[\040\t]*([^\s'"]*)[\040\t]*$/m;
-  var match = sourceUrlPattern.exec(this.source);
-  return match ? match[1] : this.name;
+  // A better solution would be to detect these special comments in
+  // the scanner/parser.
+  var source = ToString(this.source);
+  var sourceUrlPos = %StringIndexOf(source, "sourceURL=", 0);
+  if (sourceUrlPos > 4) {
+    var sourceUrlPattern =
+        /\/\/@[\040\t]sourceURL=[\040\t]*([^\s\'\"]*)[\040\t]*$/gm;
+    // Don't reuse lastMatchInfo here, so we create a new array with room
+    // for four captures (array with length one longer than the index
+    // of the fourth capture, where the numbering is zero-based).
+    var matchInfo = new InternalArray(CAPTURE(3) + 1);
+    var match =
+        %_RegExpExec(sourceUrlPattern, source, sourceUrlPos - 4, matchInfo);
+    if (match) {
+      return SubString(source, matchInfo[CAPTURE(2)], matchInfo[CAPTURE(3)]);
+    }
+  }
+  return this.name;
 }