Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(109)

Unified Diff: src/string.js

Issue 5959002: Improve regexp split, replace and test. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/regexp.js ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/string.js
===================================================================
--- src/string.js (revision 6062)
+++ src/string.js (working copy)
@@ -159,7 +159,7 @@
function StringMatch(regexp) {
var subject = TO_STRING_INLINE(this);
if (IS_REGEXP(regexp)) {
- if (!regexp.global) return regexp.exec(subject);
+ if (!regexp.global) return RegExpExecNoTests(regexp, subject, 0);
%_Log('regexp', 'regexp-match,%0S,%1r', [subject, regexp]);
// lastMatchInfo is defined in regexp.js.
return %StringMatch(subject, regexp, lastMatchInfo);
@@ -245,17 +245,18 @@
// Expand the $-expressions in the string and return a new string with
// the result.
function ExpandReplacement(string, subject, matchInfo, builder) {
+ var length = string.length;
+ var builder_elements = builder.elements;
var next = %StringIndexOf(string, '$', 0);
if (next < 0) {
- builder.add(string);
+ if (length > 0) builder_elements.push(string);
return;
}
// 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.add(SubString(string, 0, next));
- var length = string.length;
+ if (next > 0) builder_elements.push(SubString(string, 0, next));
while (true) {
var expansion = '$';
@@ -264,7 +265,7 @@
var peek = %_StringCharCodeAt(string, position);
if (peek == 36) { // $$
++position;
- builder.add('$');
+ builder_elements.push('$');
} else if (peek == 38) { // $& - match
++position;
builder.addSpecialSlice(matchInfo[CAPTURE0],
@@ -301,14 +302,14 @@
// digit capture references, we can only enter here when a
// single digit capture reference is outside the range of
// captures.
- builder.add('$');
+ builder_elements.push('$');
--position;
}
} else {
- builder.add('$');
+ builder_elements.push('$');
}
} else {
- builder.add('$');
+ builder_elements.push('$');
}
// Go the the next $ in the string.
@@ -318,13 +319,15 @@
// haven't reached the end, we need to append the suffix.
if (next < 0) {
if (position < length) {
- builder.add(SubString(string, position, length));
+ builder_elements.push(SubString(string, position, length));
}
return;
}
// Append substring between the previous and the next $ character.
- builder.add(SubString(string, position, next));
+ if (next > position) {
+ builder_elements.push(SubString(string, position, next));
+ }
}
};
@@ -559,23 +562,22 @@
var currentIndex = 0;
var startIndex = 0;
+ var startMatch = 0;
var result = [];
outer_loop:
while (true) {
if (startIndex === length) {
- result.push(subject.slice(currentIndex, length));
+ result.push(SubString(subject, currentIndex, length));
break;
}
- var matchInfo = splitMatch(separator, subject, currentIndex, startIndex);
-
- if (IS_NULL(matchInfo)) {
- result.push(subject.slice(currentIndex, length));
+ var matchInfo = DoRegExpExec(separator, subject, startIndex);
+ if (matchInfo == null || length === (startMatch = matchInfo[CAPTURE0])) {
+ result.push(SubString(subject, currentIndex, length));
break;
}
-
var endIndex = matchInfo[CAPTURE1];
// We ignore a zero-length match at the currentIndex.
@@ -584,7 +586,12 @@
continue;
}
- result.push(SubString(subject, currentIndex, matchInfo[CAPTURE0]));
+ if (currentIndex + 1 == startMatch) {
+ result.push(%_StringCharAt(subject, currentIndex));
+ } else {
+ result.push(%_SubString(subject, currentIndex, startMatch));
+ }
+
if (result.length === limit) break;
var matchinfo_len = NUMBER_OF_CAPTURES(matchInfo) + REGEXP_FIRST_CAPTURE;
@@ -609,19 +616,6 @@
}
-// ECMA-262 section 15.5.4.14
-// Helper function used by split. This version returns the matchInfo
-// instead of allocating a new array with basically the same information.
-function splitMatch(separator, subject, current_index, start_index) {
- var matchInfo = DoRegExpExec(separator, subject, start_index);
- if (matchInfo == null) return null;
- // Section 15.5.4.14 paragraph two says that we do not allow zero length
- // matches at the end of the string.
- if (matchInfo[CAPTURE0] === subject.length) return null;
- return matchInfo;
-}
-
-
// ECMA-262 section 15.5.4.15
function StringSubstring(start, end) {
var s = TO_STRING_INLINE(this);
@@ -844,24 +838,21 @@
ReplaceResultBuilder.prototype.add = function(str) {
str = TO_STRING_INLINE(str);
- if (str.length > 0) {
- var elements = this.elements;
- elements[elements.length] = str;
- }
+ if (str.length > 0) this.elements.push(str);
}
ReplaceResultBuilder.prototype.addSpecialSlice = function(start, end) {
var len = end - start;
if (start < 0 || len <= 0) return;
- var elements = this.elements;
if (start < 0x80000 && len < 0x800) {
- elements[elements.length] = (start << 11) | len;
+ this.elements.push((start << 11) | len);
} else {
// 0 < len <= String::kMaxLength and Smi::kMaxValue >= String::kMaxLength,
// so -len is a smi.
- elements[elements.length] = -len;
- elements[elements.length] = start;
+ var elements = this.elements;
+ elements.push(-len);
+ elements.push(start);
}
}
« no previous file with comments | « src/regexp.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698