Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 201 %_Log('regexp', 'regexp-replace,%0r,%1S', [search, subject]); | 201 %_Log('regexp', 'regexp-replace,%0r,%1S', [search, subject]); |
| 202 if (IS_FUNCTION(replace)) { | 202 if (IS_FUNCTION(replace)) { |
| 203 if (search.global) { | 203 if (search.global) { |
| 204 return StringReplaceGlobalRegExpWithFunction(subject, search, replace); | 204 return StringReplaceGlobalRegExpWithFunction(subject, search, replace); |
| 205 } else { | 205 } else { |
| 206 return StringReplaceNonGlobalRegExpWithFunction(subject, | 206 return StringReplaceNonGlobalRegExpWithFunction(subject, |
| 207 search, | 207 search, |
| 208 replace); | 208 replace); |
| 209 } | 209 } |
| 210 } else { | 210 } else { |
| 211 return StringReplaceRegExp(subject, search, replace); | 211 return %StringReplaceRegExpWithString(subject, |
| 212 search, | |
| 213 TO_STRING_INLINE(replace), | |
| 214 lastMatchInfo); | |
| 212 } | 215 } |
| 213 } | 216 } |
| 214 | 217 |
| 215 // Convert the search argument to a string and search for it. | 218 // Convert the search argument to a string and search for it. |
| 216 search = TO_STRING_INLINE(search); | 219 if (!IS_STRING(search)) search = NonStringToString(search); |
| 217 var start = %StringIndexOf(subject, search, 0); | 220 var start = %StringIndexOf(subject, search, 0); |
| 218 if (start < 0) return subject; | 221 if (start < 0) return subject; |
| 219 var end = start + search.length; | 222 var end = start + search.length; |
| 220 | 223 |
| 221 var builder = new ReplaceResultBuilder(subject); | 224 var builder = new ReplaceResultBuilder(subject); |
| 222 // prefix | 225 // prefix |
| 223 builder.addSpecialSlice(0, start); | 226 builder.addSpecialSlice(0, start); |
| 224 | 227 |
| 225 // Compute the string to replace with. | 228 // Compute the string to replace with. |
| 226 if (IS_FUNCTION(replace)) { | 229 if (IS_FUNCTION(replace)) { |
| 227 builder.add(replace.call(null, search, start, subject)); | 230 builder.add(%_CallFunction(%GetGlobalReceiver(), |
| 231 search, | |
| 232 start, | |
| 233 subject, | |
| 234 replace)); | |
| 228 } else { | 235 } else { |
| 229 reusableMatchInfo[CAPTURE0] = start; | 236 reusableMatchInfo[CAPTURE0] = start; |
| 230 reusableMatchInfo[CAPTURE1] = end; | 237 reusableMatchInfo[CAPTURE1] = end; |
| 231 replace = TO_STRING_INLINE(replace); | 238 if (!IS_STRING(replace)) replace = NonStringToString(replace); |
|
Lasse Reichstein
2010/12/13 09:29:13
Is this really faster than the macro:
macro TO_ST
sandholm
2010/12/13 12:03:35
No, not really. I reverted this change.
| |
| 232 ExpandReplacement(replace, subject, reusableMatchInfo, builder); | 239 ExpandReplacement(replace, subject, reusableMatchInfo, builder); |
| 233 } | 240 } |
| 234 | 241 |
| 235 // suffix | 242 // suffix |
| 236 builder.addSpecialSlice(end, subject.length); | 243 builder.addSpecialSlice(end, subject.length); |
| 237 | 244 |
| 238 return builder.generate(); | 245 return builder.generate(); |
| 239 } | 246 } |
| 240 | 247 |
| 241 | 248 |
| 242 // Helper function for regular expressions in String.prototype.replace. | |
| 243 function StringReplaceRegExp(subject, regexp, replace) { | |
| 244 return %StringReplaceRegExpWithString(subject, | |
| 245 regexp, | |
| 246 TO_STRING_INLINE(replace), | |
| 247 lastMatchInfo); | |
| 248 } | |
| 249 | |
| 250 | |
| 251 // Expand the $-expressions in the string and return a new string with | 249 // Expand the $-expressions in the string and return a new string with |
| 252 // the result. | 250 // the result. |
| 253 function ExpandReplacement(string, subject, matchInfo, builder) { | 251 function ExpandReplacement(string, subject, matchInfo, builder) { |
| 254 var next = %StringIndexOf(string, '$', 0); | 252 var next = %StringIndexOf(string, '$', 0); |
| 255 if (next < 0) { | 253 if (next < 0) { |
| 256 builder.add(string); | 254 builder.add(string); |
| 257 return; | 255 return; |
| 258 } | 256 } |
| 259 | 257 |
| 260 // Compute the number of captures; see ECMA-262, 15.5.4.11, p. 102. | 258 // Compute the number of captures; see ECMA-262, 15.5.4.11, p. 102. |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 569 } | 567 } |
| 570 | 568 |
| 571 var currentIndex = 0; | 569 var currentIndex = 0; |
| 572 var startIndex = 0; | 570 var startIndex = 0; |
| 573 var result = []; | 571 var result = []; |
| 574 | 572 |
| 575 outer_loop: | 573 outer_loop: |
| 576 while (true) { | 574 while (true) { |
| 577 | 575 |
| 578 if (startIndex === length) { | 576 if (startIndex === length) { |
| 579 result[result.length] = subject.slice(currentIndex, length); | 577 result.push(subject.slice(currentIndex, length)); |
| 580 break; | 578 break; |
| 581 } | 579 } |
| 582 | 580 |
| 583 var matchInfo = splitMatch(separator, subject, currentIndex, startIndex); | 581 var matchInfo = splitMatch(separator, subject, currentIndex, startIndex); |
| 584 | 582 |
| 585 if (IS_NULL(matchInfo)) { | 583 if (IS_NULL(matchInfo)) { |
| 586 result[result.length] = subject.slice(currentIndex, length); | 584 result.push(subject.slice(currentIndex, length)); |
| 587 break; | 585 break; |
| 588 } | 586 } |
| 589 | 587 |
| 590 var endIndex = matchInfo[CAPTURE1]; | 588 var endIndex = matchInfo[CAPTURE1]; |
| 591 | 589 |
| 592 // We ignore a zero-length match at the currentIndex. | 590 // We ignore a zero-length match at the currentIndex. |
| 593 if (startIndex === endIndex && endIndex === currentIndex) { | 591 if (startIndex === endIndex && endIndex === currentIndex) { |
| 594 startIndex++; | 592 startIndex++; |
| 595 continue; | 593 continue; |
| 596 } | 594 } |
| 597 | 595 |
| 598 result[result.length] = SubString(subject, currentIndex, matchInfo[CAPTURE0] ); | 596 result.push(SubString(subject, currentIndex, matchInfo[CAPTURE0])); |
|
Lasse Reichstein
2010/12/13 09:29:13
No special casing of this substring?
sandholm
2010/12/13 12:03:35
I have only inlined SubString calls inside loops.
| |
| 599 if (result.length === limit) break; | 597 if (result.length === limit) break; |
| 600 | 598 |
| 601 var num_captures = NUMBER_OF_CAPTURES(matchInfo); | 599 var num_captures_plus3 = NUMBER_OF_CAPTURES(matchInfo) + 3; |
|
Lasse Reichstein
2010/12/13 09:29:13
Use REGEXP_FIRST_CAPTURE instead of 3.
sandholm
2010/12/13 12:03:35
Done.
| |
| 602 for (var i = 2; i < num_captures; i += 2) { | 600 for (var i = 5; i < num_captures_plus3; ) { |
|
Lasse Reichstein
2010/12/13 09:29:13
And REGEXP_FIRST_CAPTURE + 2 instead of 5.
sandholm
2010/12/13 12:03:35
Done.
| |
| 603 var start = matchInfo[CAPTURE(i)]; | 601 var start = matchInfo[i++]; |
| 604 var end = matchInfo[CAPTURE(i + 1)]; | 602 var end = matchInfo[i++]; |
| 605 if (start != -1 && end != -1) { | 603 if (end != -1) { |
| 606 result[result.length] = SubString(subject, start, end); | 604 if (start + 1 == end) { |
| 605 result.push(%_StringCharAt(subject, start)); | |
| 606 } else { | |
| 607 result.push(%_SubString(subject, start, end)); | |
| 608 } | |
| 607 } else { | 609 } else { |
| 608 result[result.length] = void 0; | 610 result.push(void 0); |
| 609 } | 611 } |
| 610 if (result.length === limit) break outer_loop; | 612 if (result.length === limit) break outer_loop; |
| 611 } | 613 } |
| 612 | 614 |
| 613 startIndex = currentIndex = endIndex; | 615 startIndex = currentIndex = endIndex; |
| 614 } | 616 } |
| 615 return result; | 617 return result; |
| 616 } | 618 } |
| 617 | 619 |
| 618 | 620 |
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 929 "small", StringSmall, | 931 "small", StringSmall, |
| 930 "strike", StringStrike, | 932 "strike", StringStrike, |
| 931 "sub", StringSub, | 933 "sub", StringSub, |
| 932 "sup", StringSup, | 934 "sup", StringSup, |
| 933 "toJSON", StringToJSON | 935 "toJSON", StringToJSON |
| 934 )); | 936 )); |
| 935 } | 937 } |
| 936 | 938 |
| 937 | 939 |
| 938 SetupString(); | 940 SetupString(); |
| OLD | NEW |