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

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

Issue 2394713003: [regexp] Port test, match, and search (Closed)
Patch Set: Rebaseline bytecode expectations Created 4 years, 2 months 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
« no previous file with comments | « src/heap-symbols.h ('k') | src/objects.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 'use strict'; 7 'use strict';
8 8
9 %CheckIsBootstrapping(); 9 %CheckIsBootstrapping();
10 10
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 if (start != -1) { 96 if (start != -1) {
97 end = MATCHINFO[j]; 97 end = MATCHINFO[j];
98 result[i] = %_SubString(STRING, start, end); 98 result[i] = %_SubString(STRING, start, end);
99 } 99 }
100 j++; 100 j++;
101 } 101 }
102 return result; 102 return result;
103 endmacro 103 endmacro
104 104
105 105
106
107 // ES#sec-regexpexec Runtime Semantics: RegExpExec ( R, S ) 106 // ES#sec-regexpexec Runtime Semantics: RegExpExec ( R, S )
108 // Also takes an optional exec method in case our caller 107 // Also takes an optional exec method in case our caller
109 // has already fetched exec. 108 // has already fetched exec.
110 function RegExpSubclassExec(regexp, string, exec) { 109 function RegExpSubclassExec(regexp, string, exec) {
111 if (IS_UNDEFINED(exec)) { 110 if (IS_UNDEFINED(exec)) {
112 exec = regexp.exec; 111 exec = regexp.exec;
113 } 112 }
114 if (IS_CALLABLE(exec)) { 113 if (IS_CALLABLE(exec)) {
115 var result = %_Call(exec, regexp, string); 114 var result = %_Call(exec, regexp, string);
116 if (!IS_RECEIVER(result) && !IS_NULL(result)) { 115 if (!IS_RECEIVER(result) && !IS_NULL(result)) {
117 throw %make_type_error(kInvalidRegExpExecResult); 116 throw %make_type_error(kInvalidRegExpExecResult);
118 } 117 }
119 return result; 118 return result;
120 } 119 }
121 return %_Call(RegExpExecJS, regexp, string); 120 return %_Call(RegExpExecJS, regexp, string);
122 } 121 }
123 %SetForceInlineFlag(RegExpSubclassExec); 122 %SetForceInlineFlag(RegExpSubclassExec);
124 123
125 124
126 // ES#sec-regexp.prototype.test RegExp.prototype.test ( S )
127 function RegExpSubclassTest(string) {
128 if (!IS_RECEIVER(this)) {
129 throw %make_type_error(kIncompatibleMethodReceiver,
130 'RegExp.prototype.test', this);
131 }
132 string = TO_STRING(string);
133 var match = RegExpSubclassExec(this, string);
134 return !IS_NULL(match);
135 }
136 %FunctionRemovePrototype(RegExpSubclassTest);
137
138
139 function AtSurrogatePair(subject, index) { 125 function AtSurrogatePair(subject, index) {
140 if (index + 1 >= subject.length) return false; 126 if (index + 1 >= subject.length) return false;
141 var first = %_StringCharCodeAt(subject, index); 127 var first = %_StringCharCodeAt(subject, index);
142 if (first < 0xD800 || first > 0xDBFF) return false; 128 if (first < 0xD800 || first > 0xDBFF) return false;
143 var second = %_StringCharCodeAt(subject, index + 1); 129 var second = %_StringCharCodeAt(subject, index + 1);
144 return second >= 0xDC00 && second <= 0xDFFF; 130 return second >= 0xDC00 && second <= 0xDFFF;
145 } 131 }
146 132
147 133
148 // Fast path implementation of RegExp.prototype[Symbol.split] which 134 // Fast path implementation of RegExp.prototype[Symbol.split] which
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 } 268 }
283 } 269 }
284 } 270 }
285 %AddElement(array, arrayIndex, 271 %AddElement(array, arrayIndex,
286 %_SubString(string, prevStringIndex, size)); 272 %_SubString(string, prevStringIndex, size));
287 return array; 273 return array;
288 } 274 }
289 %FunctionRemovePrototype(RegExpSubclassSplit); 275 %FunctionRemovePrototype(RegExpSubclassSplit);
290 276
291 277
292 // ES#sec-regexp.prototype-@@match
293 // RegExp.prototype [ @@match ] ( string )
294 function RegExpSubclassMatch(string) {
295 if (!IS_RECEIVER(this)) {
296 throw %make_type_error(kIncompatibleMethodReceiver,
297 "RegExp.prototype.@@match", this);
298 }
299 string = TO_STRING(string);
300 var global = this.global;
301 if (!global) return RegExpSubclassExec(this, string);
302 var unicode = this.unicode;
303 this.lastIndex = 0;
304 var array = new InternalArray();
305 var n = 0;
306 var result;
307 while (true) {
308 result = RegExpSubclassExec(this, string);
309 if (IS_NULL(result)) {
310 if (n === 0) return null;
311 break;
312 }
313 var matchStr = TO_STRING(result[0]);
314 array[n] = matchStr;
315 if (matchStr === "") SetAdvancedStringIndex(this, string, unicode);
316 n++;
317 }
318 var resultArray = [];
319 %MoveArrayContents(array, resultArray);
320 return resultArray;
321 }
322 %FunctionRemovePrototype(RegExpSubclassMatch);
323
324
325 // Legacy implementation of RegExp.prototype[Symbol.replace] which 278 // Legacy implementation of RegExp.prototype[Symbol.replace] which
326 // doesn't properly call the underlying exec method. 279 // doesn't properly call the underlying exec method.
327 280
328 // TODO(lrn): This array will survive indefinitely if replace is never 281 // TODO(lrn): This array will survive indefinitely if replace is never
329 // called again. However, it will be empty, since the contents are cleared 282 // called again. However, it will be empty, since the contents are cleared
330 // in the finally block. 283 // in the finally block.
331 var reusableReplaceArray = new InternalArray(4); 284 var reusableReplaceArray = new InternalArray(4);
332 285
333 // Helper function for replacing regular expressions with the result of a 286 // Helper function for replacing regular expressions with the result of a
334 // function application in String.prototype.replace. 287 // function application in String.prototype.replace.
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after
709 %_SubString(string, nextSourcePosition, position) + replacement; 662 %_SubString(string, nextSourcePosition, position) + replacement;
710 nextSourcePosition = position + matchedLength; 663 nextSourcePosition = position + matchedLength;
711 } 664 }
712 } 665 }
713 if (nextSourcePosition >= length) return accumulatedResult; 666 if (nextSourcePosition >= length) return accumulatedResult;
714 return accumulatedResult + %_SubString(string, nextSourcePosition, length); 667 return accumulatedResult + %_SubString(string, nextSourcePosition, length);
715 } 668 }
716 %FunctionRemovePrototype(RegExpSubclassReplace); 669 %FunctionRemovePrototype(RegExpSubclassReplace);
717 670
718 671
719 // ES#sec-regexp.prototype-@@search
720 // RegExp.prototype [ @@search ] ( string )
721 function RegExpSubclassSearch(string) {
722 if (!IS_RECEIVER(this)) {
723 throw %make_type_error(kIncompatibleMethodReceiver,
724 "RegExp.prototype.@@search", this);
725 }
726 string = TO_STRING(string);
727 var previousLastIndex = this.lastIndex;
728 if (previousLastIndex != 0) this.lastIndex = 0;
729 var result = RegExpSubclassExec(this, string);
730 var currentLastIndex = this.lastIndex;
731 if (currentLastIndex != previousLastIndex) this.lastIndex = previousLastIndex;
732 if (IS_NULL(result)) return -1;
733 return result.index;
734 }
735 %FunctionRemovePrototype(RegExpSubclassSearch);
736
737 672
738 // ------------------------------------------------------------------- 673 // -------------------------------------------------------------------
739 674
740 utils.InstallFunctions(GlobalRegExp.prototype, DONT_ENUM, [ 675 utils.InstallFunctions(GlobalRegExp.prototype, DONT_ENUM, [
741 "test", RegExpSubclassTest,
742 matchSymbol, RegExpSubclassMatch,
743 replaceSymbol, RegExpSubclassReplace, 676 replaceSymbol, RegExpSubclassReplace,
744 searchSymbol, RegExpSubclassSearch,
745 splitSymbol, RegExpSubclassSplit, 677 splitSymbol, RegExpSubclassSplit,
746 ]); 678 ]);
747 679
748 %InstallToContext(["regexp_last_match_info", RegExpLastMatchInfo]); 680 %InstallToContext(["regexp_last_match_info", RegExpLastMatchInfo]);
749 681
750 // ------------------------------------------------------------------- 682 // -------------------------------------------------------------------
751 // Internal 683 // Internal
752 684
753 var InternalRegExpMatchInfo = { 685 var InternalRegExpMatchInfo = {
754 REGEXP_NUMBER_OF_CAPTURES: 2, 686 REGEXP_NUMBER_OF_CAPTURES: 2,
(...skipping 23 matching lines...) Expand all
778 to.GetSubstitution = GetSubstitution; 710 to.GetSubstitution = GetSubstitution;
779 to.InternalRegExpMatch = InternalRegExpMatch; 711 to.InternalRegExpMatch = InternalRegExpMatch;
780 to.InternalRegExpReplace = InternalRegExpReplace; 712 to.InternalRegExpReplace = InternalRegExpReplace;
781 to.IsRegExp = IsRegExp; 713 to.IsRegExp = IsRegExp;
782 to.RegExpExec = DoRegExpExec; 714 to.RegExpExec = DoRegExpExec;
783 to.RegExpInitialize = RegExpInitialize; 715 to.RegExpInitialize = RegExpInitialize;
784 to.RegExpLastMatchInfo = RegExpLastMatchInfo; 716 to.RegExpLastMatchInfo = RegExpLastMatchInfo;
785 }); 717 });
786 718
787 }) 719 })
OLDNEW
« no previous file with comments | « src/heap-symbols.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698