Revision: 11448
Author:   [email protected]
Date:     Thu Apr 26 04:43:59 2012
Log: Use simple concat of substrings instead of ReplaceStringBuilder for non-global replacements.

BUG=
TEST=

Review URL: https://chromiumcodereview.appspot.com/10134057
http://code.google.com/p/v8/source/detail?r=11448

Modified:
 /branches/bleeding_edge/src/string.js

=======================================
--- /branches/bleeding_edge/src/string.js       Mon Apr 23 11:56:07 2012
+++ /branches/bleeding_edge/src/string.js       Thu Apr 26 04:43:59 2012
@@ -277,47 +277,34 @@
   if (start < 0) return subject;
   var end = start + search.length;

-  var builder = new ReplaceResultBuilder(subject);
-  // prefix
-  builder.addSpecialSlice(0, start);
+  var result = SubString(subject, 0, start);

   // Compute the string to replace with.
   if (IS_SPEC_FUNCTION(replace)) {
     var receiver = %GetDefaultReceiver(replace);
-    builder.add(%_CallFunction(receiver,
-                               search,
-                               start,
-                               subject,
-                               replace));
+    result += %_CallFunction(receiver, search, start, subject, replace);
   } else {
     reusableMatchInfo[CAPTURE0] = start;
     reusableMatchInfo[CAPTURE1] = end;
     replace = TO_STRING_INLINE(replace);
-    ExpandReplacement(replace, subject, reusableMatchInfo, builder);
+ result = ExpandReplacement(replace, subject, reusableMatchInfo, result);
   }

-  // suffix
-  builder.addSpecialSlice(end, subject.length);
-
-  return builder.generate();
+  return result + SubString(subject, end, subject.length);
 }


 // Expand the $-expressions in the string and return a new string with
 // the result.
-function ExpandReplacement(string, subject, matchInfo, builder) {
+function ExpandReplacement(string, subject, matchInfo, result) {
   var length = string.length;
-  var builder_elements = builder.elements;
   var next = %StringIndexOf(string, '$', 0);
   if (next < 0) {
-    if (length > 0) builder_elements.push(string);
-    return;
+    if (length > 0) result += string;
+    return result;
   }

-  // Compute the number of captures; see ECMA-262, 15.5.4.11, p. 102.
-  var m = NUMBER_OF_CAPTURES(matchInfo) >> 1;  // Includes the match.
-
-  if (next > 0) builder_elements.push(SubString(string, 0, next));
+  if (next > 0) result += SubString(string, 0, next);

   while (true) {
     var expansion = '$';
@@ -326,51 +313,21 @@
       var peek = %_StringCharCodeAt(string, position);
       if (peek == 36) {         // $$
         ++position;
-        builder_elements.push('$');
+        result += '$';
       } else if (peek == 38) {  // $& - match
         ++position;
-        builder.addSpecialSlice(matchInfo[CAPTURE0],
-                                matchInfo[CAPTURE1]);
+ result += SubString(subject, matchInfo[CAPTURE0], matchInfo[CAPTURE1]);
       } else if (peek == 96) {  // $` - prefix
         ++position;
-        builder.addSpecialSlice(0, matchInfo[CAPTURE0]);
+        result += SubString(subject, 0, matchInfo[CAPTURE0]);
       } else if (peek == 39) {  // $' - suffix
         ++position;
-        builder.addSpecialSlice(matchInfo[CAPTURE1], subject.length);
-      } else if (peek >= 48 && peek <= 57) {  // $n, 0 <= n <= 9
-        ++position;
-        var n = peek - 48;
-        if (position < length) {
-          peek = %_StringCharCodeAt(string, position);
-          // $nn, 01 <= nn <= 99
-          if (n != 0 && peek == 48 || peek >= 49 && peek <= 57) {
-            var nn = n * 10 + (peek - 48);
-            if (nn < m) {
-              // If the two digit capture reference is within range of
-              // the captures, we use it instead of the single digit
-              // one. Otherwise, we fall back to using the single
-              // digit reference. This matches the behavior of
-              // SpiderMonkey.
-              ++position;
-              n = nn;
-            }
-          }
-        }
-        if (0 < n && n < m) {
-          addCaptureString(builder, matchInfo, n);
-        } else {
-          // Because of the captures range check in the parsing of two
-          // digit capture references, we can only enter here when a
-          // single digit capture reference is outside the range of
-          // captures.
-          builder_elements.push('$');
-          --position;
-        }
+        result += SubString(subject, matchInfo[CAPTURE1], subject.length);
       } else {
-        builder_elements.push('$');
+        result += '$';
       }
     } else {
-      builder_elements.push('$');
+      result += '$';
     }

     // Go the the next $ in the string.
@@ -380,16 +337,17 @@
     // haven't reached the end, we need to append the suffix.
     if (next < 0) {
       if (position < length) {
-        builder_elements.push(SubString(string, position, length));
-      }
-      return;
+        result += SubString(string, position, length);
+      }
+      return result;
     }

     // Append substring between the previous and the next $ character.
     if (next > position) {
-      builder_elements.push(SubString(string, position, next));
+      result += SubString(string, position, next);
     }
   }
+  return result;
 }


@@ -405,18 +363,6 @@
   return SubString(string, start, end);
 }

-
-// Add the string of a given regular expression capture to the
-// ReplaceResultBuilder
-function addCaptureString(builder, matchInfo, index) {
-  // Scale the index.
-  var scaled = index << 1;
-  // Compute start and end.
-  var start = matchInfo[CAPTURE(scaled)];
-  if (start < 0) return;
-  var end = matchInfo[CAPTURE(scaled + 1)];
-  builder.addSpecialSlice(start, end);
-}

 // TODO(lrn): This array will survive indefinitely if replace is never
 // called again. However, it will be empty, since the contents are cleared
@@ -506,9 +452,8 @@
function StringReplaceNonGlobalRegExpWithFunction(subject, regexp, replace) {
   var matchInfo = DoRegExpExec(regexp, subject, 0);
   if (IS_NULL(matchInfo)) return subject;
-  var result = new ReplaceResultBuilder(subject);
   var index = matchInfo[CAPTURE0];
-  result.addSpecialSlice(0, index);
+  var result = SubString(subject, 0, index);
   var endOfMatch = matchInfo[CAPTURE1];
   // Compute the parameter list consisting of the match, captures, index,
   // and subject for the replace function invocation.
@@ -532,11 +477,10 @@
     replacement = %Apply(replace, receiver, parameters, 0, j + 2);
   }

- result.add(replacement); // The add method converts to string if necessary. + result += replacement; // The add method converts to string if necessary.
   // Can't use matchInfo any more from here, since the function could
   // overwrite it.
-  result.addSpecialSlice(endOfMatch, subject.length);
-  return result.generate();
+  return result + SubString(subject, endOfMatch, subject.length);
 }


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to