Reviewers: Erik Corry,

Message:
PTAL.

Description:
Use simple concat of substrings instead of ReplaceStringBuilder for non-global
replacements.

BUG=
TEST=


Please review this at http://codereview.chromium.org/10134057/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/string.js


Index: src/string.js
diff --git a/src/string.js b/src/string.js
index 1fcabc407aa23584830b0013b34a5b722724f1e9..aa67b7881312635acc0929b0b332f409768dba44 100644
--- a/src/string.js
+++ b/src/string.js
@@ -277,47 +277,37 @@ function StringReplace(search, replace) {
   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,17 +316,16 @@ function ExpandReplacement(string, subject, matchInfo, builder) {
       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);
+        result += SubString(subject, matchInfo[CAPTURE1], subject.length);
       } else if (peek >= 48 && peek <= 57) {  // $n, 0 <= n <= 9
         ++position;
         var n = peek - 48;
@@ -357,20 +346,20 @@ function ExpandReplacement(string, subject, matchInfo, builder) {
           }
         }
         if (0 < n && n < m) {
-          addCaptureString(builder, matchInfo, n);
+          result = addCaptureString(result, subject, 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('$');
+          result += '$';
           --position;
         }
       } else {
-        builder_elements.push('$');
+        result += '$';
       }
     } else {
-      builder_elements.push('$');
+      result += '$';
     }

     // Go the the next $ in the string.
@@ -380,16 +369,17 @@ function ExpandReplacement(string, subject, matchInfo, builder) {
     // haven't reached the end, we need to append the suffix.
     if (next < 0) {
       if (position < length) {
-        builder_elements.push(SubString(string, position, length));
+        result += SubString(string, position, length);
       }
-      return;
+      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;
 }


@@ -408,14 +398,14 @@ function CaptureString(string, lastCaptureInfo, index) {

 // Add the string of a given regular expression capture to the
 // ReplaceResultBuilder
-function addCaptureString(builder, matchInfo, index) {
+function addCaptureString(result, subject, 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);
+  return result + SubString(subject, start, end);
 }

 // TODO(lrn): This array will survive indefinitely if replace is never
@@ -506,9 +496,8 @@ function StringReplaceGlobalRegExpWithFunction(subject, regexp, replace) { 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 +521,10 @@ function StringReplaceNonGlobalRegExpWithFunction(subject, regexp, replace) {
     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