| Index: src/string.js
|
| diff --git a/src/string.js b/src/string.js
|
| index 1fcabc407aa23584830b0013b34a5b722724f1e9..6115930b6c8ff69568f425b8b996a821bc93cb87 100644
|
| --- a/src/string.js
|
| +++ b/src/string.js
|
| @@ -277,47 +277,34 @@ 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,51 +313,21 @@ 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);
|
| - } 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 @@ 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;
|
| }
|
|
|
|
|
| @@ -406,18 +364,6 @@ function CaptureString(string, lastCaptureInfo, index) {
|
| }
|
|
|
|
|
| -// 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
|
| // in the finally block.
|
| @@ -506,9 +452,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 +477,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);
|
| }
|
|
|
|
|
|
|