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

Side by Side Diff: src/js/string.js

Issue 1418703003: RegExp: remove last match info override. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix Created 5 years, 1 month 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 unified diff | Download patch
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 (function(global, utils) { 5 (function(global, utils) {
6 6
7 %CheckIsBootstrapping(); 7 %CheckIsBootstrapping();
8 8
9 // ------------------------------------------------------------------- 9 // -------------------------------------------------------------------
10 // Imports 10 // Imports
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 150
151 151
152 // ECMA-262 section 15.5.4.10 152 // ECMA-262 section 15.5.4.10
153 function StringMatchJS(regexp) { 153 function StringMatchJS(regexp) {
154 CHECK_OBJECT_COERCIBLE(this, "String.prototype.match"); 154 CHECK_OBJECT_COERCIBLE(this, "String.prototype.match");
155 155
156 var subject = TO_STRING(this); 156 var subject = TO_STRING(this);
157 if (IS_REGEXP(regexp)) { 157 if (IS_REGEXP(regexp)) {
158 if (!regexp.global) return RegExpExecNoTests(regexp, subject, 0); 158 if (!regexp.global) return RegExpExecNoTests(regexp, subject, 0);
159 var result = %StringMatch(subject, regexp, RegExpLastMatchInfo); 159 var result = %StringMatch(subject, regexp, RegExpLastMatchInfo);
160 if (result !== null) $regexpLastMatchInfoOverride = null;
161 regexp.lastIndex = 0; 160 regexp.lastIndex = 0;
162 return result; 161 return result;
163 } 162 }
164 // Non-regexp argument. 163 // Non-regexp argument.
165 regexp = new GlobalRegExp(regexp); 164 regexp = new GlobalRegExp(regexp);
166 return RegExpExecNoTests(regexp, subject, 0); 165 return RegExpExecNoTests(regexp, subject, 0);
167 } 166 }
168 167
169 168
170 // ECMA-262 v6, section 21.1.3.12 169 // ECMA-262 v6, section 21.1.3.12
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 return %_SubString(subject, 0, match[CAPTURE0]) + 236 return %_SubString(subject, 0, match[CAPTURE0]) +
238 %_SubString(subject, match[CAPTURE1], subject.length) 237 %_SubString(subject, match[CAPTURE1], subject.length)
239 } 238 }
240 return ExpandReplacement(replace, subject, RegExpLastMatchInfo, 239 return ExpandReplacement(replace, subject, RegExpLastMatchInfo,
241 %_SubString(subject, 0, match[CAPTURE0])) + 240 %_SubString(subject, 0, match[CAPTURE0])) +
242 %_SubString(subject, match[CAPTURE1], subject.length); 241 %_SubString(subject, match[CAPTURE1], subject.length);
243 } 242 }
244 243
245 // Global regexp search, string replace. 244 // Global regexp search, string replace.
246 search.lastIndex = 0; 245 search.lastIndex = 0;
247 if ($regexpLastMatchInfoOverride == null) { 246 return %StringReplaceGlobalRegExpWithString(
248 return %StringReplaceGlobalRegExpWithString( 247 subject, search, replace, RegExpLastMatchInfo);
249 subject, search, replace, RegExpLastMatchInfo);
250 } else {
251 // We use this hack to detect whether StringReplaceRegExpWithString
252 // found at least one hit. In that case we need to remove any
253 // override.
254 var saved_subject = RegExpLastMatchInfo[LAST_SUBJECT_INDEX];
255 RegExpLastMatchInfo[LAST_SUBJECT_INDEX] = 0;
256 var answer = %StringReplaceGlobalRegExpWithString(
257 subject, search, replace, RegExpLastMatchInfo);
258 if (%_IsSmi(RegExpLastMatchInfo[LAST_SUBJECT_INDEX])) {
259 RegExpLastMatchInfo[LAST_SUBJECT_INDEX] = saved_subject;
260 } else {
261 $regexpLastMatchInfoOverride = null;
262 }
263 return answer;
264 }
265 } 248 }
266 249
267 if (search.global) { 250 if (search.global) {
268 // Global regexp search, function replace. 251 // Global regexp search, function replace.
269 return StringReplaceGlobalRegExpWithFunction(subject, search, replace); 252 return StringReplaceGlobalRegExpWithFunction(subject, search, replace);
270 } 253 }
271 // Non-global regexp search, function replace. 254 // Non-global regexp search, function replace.
272 return StringReplaceNonGlobalRegExpWithFunction(subject, search, replace); 255 return StringReplaceNonGlobalRegExpWithFunction(subject, search, replace);
273 } 256 }
274 257
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 } 414 }
432 var len = res.length; 415 var len = res.length;
433 if (NUMBER_OF_CAPTURES(RegExpLastMatchInfo) == 2) { 416 if (NUMBER_OF_CAPTURES(RegExpLastMatchInfo) == 2) {
434 // If the number of captures is two then there are no explicit captures in 417 // If the number of captures is two then there are no explicit captures in
435 // the regexp, just the implicit capture that captures the whole match. In 418 // the regexp, just the implicit capture that captures the whole match. In
436 // this case we can simplify quite a bit and end up with something faster. 419 // this case we can simplify quite a bit and end up with something faster.
437 // The builder will consist of some integers that indicate slices of the 420 // The builder will consist of some integers that indicate slices of the
438 // input string and some replacements that were returned from the replace 421 // input string and some replacements that were returned from the replace
439 // function. 422 // function.
440 var match_start = 0; 423 var match_start = 0;
441 var override = new InternalPackedArray(null, 0, subject);
442 for (var i = 0; i < len; i++) { 424 for (var i = 0; i < len; i++) {
443 var elem = res[i]; 425 var elem = res[i];
444 if (%_IsSmi(elem)) { 426 if (%_IsSmi(elem)) {
445 // Integers represent slices of the original string. Use these to 427 // Integers represent slices of the original string.
446 // get the offsets we need for the override array (so things like
447 // RegExp.leftContext work during the callback function.
448 if (elem > 0) { 428 if (elem > 0) {
449 match_start = (elem >> 11) + (elem & 0x7ff); 429 match_start = (elem >> 11) + (elem & 0x7ff);
450 } else { 430 } else {
451 match_start = res[++i] - elem; 431 match_start = res[++i] - elem;
452 } 432 }
453 } else { 433 } else {
454 override[0] = elem;
455 override[1] = match_start;
456 $regexpLastMatchInfoOverride = override;
457 var func_result = replace(elem, match_start, subject); 434 var func_result = replace(elem, match_start, subject);
458 // Overwrite the i'th element in the results with the string we got 435 // Overwrite the i'th element in the results with the string we got
459 // back from the callback function. 436 // back from the callback function.
460 res[i] = TO_STRING(func_result); 437 res[i] = TO_STRING(func_result);
461 match_start += elem.length; 438 match_start += elem.length;
462 } 439 }
463 } 440 }
464 } else { 441 } else {
465 for (var i = 0; i < len; i++) { 442 for (var i = 0; i < len; i++) {
466 var elem = res[i]; 443 var elem = res[i];
467 if (!%_IsSmi(elem)) { 444 if (!%_IsSmi(elem)) {
468 // elem must be an Array. 445 // elem must be an Array.
469 // Use the apply argument as backing for global RegExp properties. 446 // Use the apply argument as backing for global RegExp properties.
470 $regexpLastMatchInfoOverride = elem;
471 var func_result = %Apply(replace, UNDEFINED, elem, 0, elem.length); 447 var func_result = %Apply(replace, UNDEFINED, elem, 0, elem.length);
472 // Overwrite the i'th element in the results with the string we got 448 // Overwrite the i'th element in the results with the string we got
473 // back from the callback function. 449 // back from the callback function.
474 res[i] = TO_STRING(func_result); 450 res[i] = TO_STRING(func_result);
475 } 451 }
476 } 452 }
477 } 453 }
478 var result = %StringBuilderConcat(res, res.length, subject); 454 var result = %StringBuilderConcat(res, len, subject);
479 resultArray.length = 0; 455 resultArray.length = 0;
480 reusableReplaceArray = resultArray; 456 reusableReplaceArray = resultArray;
481 return result; 457 return result;
482 } 458 }
483 459
484 460
485 function StringReplaceNonGlobalRegExpWithFunction(subject, regexp, replace) { 461 function StringReplaceNonGlobalRegExpWithFunction(subject, regexp, replace) {
486 var matchInfo = RegExpExec(regexp, subject, 0); 462 var matchInfo = RegExpExec(regexp, subject, 0);
487 if (IS_NULL(matchInfo)) { 463 if (IS_NULL(matchInfo)) {
488 regexp.lastIndex = 0; 464 regexp.lastIndex = 0;
(...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after
1194 to.StringLastIndexOf = StringLastIndexOfJS; 1170 to.StringLastIndexOf = StringLastIndexOfJS;
1195 to.StringMatch = StringMatchJS; 1171 to.StringMatch = StringMatchJS;
1196 to.StringReplace = StringReplace; 1172 to.StringReplace = StringReplace;
1197 to.StringSlice = StringSlice; 1173 to.StringSlice = StringSlice;
1198 to.StringSplit = StringSplitJS; 1174 to.StringSplit = StringSplitJS;
1199 to.StringSubstr = StringSubstr; 1175 to.StringSubstr = StringSubstr;
1200 to.StringSubstring = StringSubstring; 1176 to.StringSubstring = StringSubstring;
1201 }); 1177 });
1202 1178
1203 }) 1179 })
OLDNEW
« no previous file with comments | « src/js/regexp.js ('k') | src/regexp/jsregexp.h » ('j') | src/runtime/runtime-regexp.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698