OLD | NEW |
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 |
11 | 11 |
12 var ExpandReplacement; | 12 var ExpandReplacement; |
13 var GlobalArray = global.Array; | 13 var GlobalArray = global.Array; |
14 var GlobalObject = global.Object; | 14 var GlobalObject = global.Object; |
15 var GlobalRegExp = global.RegExp; | 15 var GlobalRegExp = global.RegExp; |
16 var InternalArray = utils.InternalArray; | 16 var InternalArray = utils.InternalArray; |
17 var InternalPackedArray = utils.InternalPackedArray; | 17 var InternalPackedArray = utils.InternalPackedArray; |
18 var MaxSimple; | 18 var MaxSimple; |
19 var MinSimple; | 19 var MinSimple; |
20 var lastMatchInfoSymbol = utils.ImportNow("regexp_last_match_info_symbol"); | 20 var lastMatchInfoSymbol = utils.ImportNow("regexp_last_match_info_symbol"); |
21 var matchSymbol = utils.ImportNow("match_symbol"); | 21 var matchSymbol = utils.ImportNow("match_symbol"); |
22 var replaceSymbol = utils.ImportNow("replace_symbol"); | 22 var replaceSymbol = utils.ImportNow("replace_symbol"); |
23 var searchSymbol = utils.ImportNow("search_symbol"); | 23 var searchSymbol = utils.ImportNow("search_symbol"); |
24 var speciesSymbol = utils.ImportNow("species_symbol"); | 24 var speciesSymbol = utils.ImportNow("species_symbol"); |
25 var splitSymbol = utils.ImportNow("split_symbol"); | 25 var splitSymbol = utils.ImportNow("split_symbol"); |
26 var SpeciesConstructor; | 26 var SpeciesConstructor; |
| 27 var RegExpSubclassExecJS; |
27 | 28 |
28 utils.Import(function(from) { | 29 utils.Import(function(from) { |
29 ExpandReplacement = from.ExpandReplacement; | 30 ExpandReplacement = from.ExpandReplacement; |
30 MaxSimple = from.MaxSimple; | 31 MaxSimple = from.MaxSimple; |
31 MinSimple = from.MinSimple; | 32 MinSimple = from.MinSimple; |
32 SpeciesConstructor = from.SpeciesConstructor; | 33 SpeciesConstructor = from.SpeciesConstructor; |
33 }); | 34 }); |
34 | 35 |
35 // ------------------------------------------------------------------- | 36 // ------------------------------------------------------------------- |
36 | 37 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 if (matchInfo !== null) { | 109 if (matchInfo !== null) { |
109 // ES6 21.2.5.2.2 step 18. | 110 // ES6 21.2.5.2.2 step 18. |
110 if (REGEXP_STICKY(regexp)) regexp.lastIndex = matchInfo[CAPTURE1]; | 111 if (REGEXP_STICKY(regexp)) regexp.lastIndex = matchInfo[CAPTURE1]; |
111 RETURN_NEW_RESULT_FROM_MATCH_INFO(matchInfo, string); | 112 RETURN_NEW_RESULT_FROM_MATCH_INFO(matchInfo, string); |
112 } | 113 } |
113 regexp.lastIndex = 0; | 114 regexp.lastIndex = 0; |
114 return null; | 115 return null; |
115 } | 116 } |
116 | 117 |
117 | 118 |
118 // ES#sec-regexp.prototype.exec | |
119 // RegExp.prototype.exec ( string ) | |
120 function RegExpSubclassExecJS(string) { | |
121 if (!IS_REGEXP(this)) { | |
122 throw %make_type_error(kIncompatibleMethodReceiver, | |
123 'RegExp.prototype.exec', this); | |
124 } | |
125 | |
126 string = TO_STRING(string); | |
127 var lastIndex = this.lastIndex; | |
128 | |
129 // Conversion is required by the ES2015 specification (RegExpBuiltinExec | |
130 // algorithm, step 4) even if the value is discarded for non-global RegExps. | |
131 var i = TO_LENGTH(lastIndex); | |
132 | |
133 var global = TO_BOOLEAN(REGEXP_GLOBAL(this)); | |
134 var sticky = TO_BOOLEAN(REGEXP_STICKY(this)); | |
135 var updateLastIndex = global || sticky; | |
136 if (updateLastIndex) { | |
137 if (i > string.length) { | |
138 this.lastIndex = 0; | |
139 return null; | |
140 } | |
141 } else { | |
142 i = 0; | |
143 } | |
144 | |
145 // matchIndices is either null or the RegExpLastMatchInfo array. | |
146 // TODO(littledan): Whether a RegExp is sticky is compiled into the RegExp | |
147 // itself, but ES2015 allows monkey-patching this property to differ from | |
148 // the internal flags. If it differs, recompile a different RegExp? | |
149 var matchIndices = %_RegExpExec(this, string, i, RegExpLastMatchInfo); | |
150 | |
151 if (IS_NULL(matchIndices)) { | |
152 this.lastIndex = 0; | |
153 return null; | |
154 } | |
155 | |
156 // Successful match. | |
157 if (updateLastIndex) { | |
158 this.lastIndex = RegExpLastMatchInfo[CAPTURE1]; | |
159 } | |
160 RETURN_NEW_RESULT_FROM_MATCH_INFO(matchIndices, string); | |
161 } | |
162 %FunctionRemovePrototype(RegExpSubclassExecJS); | |
163 | |
164 | |
165 // ES#sec-regexpexec Runtime Semantics: RegExpExec ( R, S ) | 119 // ES#sec-regexpexec Runtime Semantics: RegExpExec ( R, S ) |
166 // Also takes an optional exec method in case our caller | 120 // Also takes an optional exec method in case our caller |
167 // has already fetched exec. | 121 // has already fetched exec. |
168 function RegExpSubclassExec(regexp, string, exec) { | 122 function RegExpSubclassExec(regexp, string, exec) { |
169 if (IS_UNDEFINED(exec)) { | 123 if (IS_UNDEFINED(exec)) { |
170 exec = regexp.exec; | 124 exec = regexp.exec; |
171 } | 125 } |
172 if (IS_CALLABLE(exec)) { | 126 if (IS_CALLABLE(exec)) { |
173 var result = %_Call(exec, regexp, string); | 127 var result = %_Call(exec, regexp, string); |
174 if (!IS_RECEIVER(result) && !IS_NULL(result)) { | 128 if (!IS_RECEIVER(result) && !IS_NULL(result)) { |
(...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
767 this.lastIndex = previousLastIndex; | 721 this.lastIndex = previousLastIndex; |
768 if (IS_NULL(result)) return -1; | 722 if (IS_NULL(result)) return -1; |
769 return result.index; | 723 return result.index; |
770 } | 724 } |
771 %FunctionRemovePrototype(RegExpSubclassSearch); | 725 %FunctionRemovePrototype(RegExpSubclassSearch); |
772 | 726 |
773 | 727 |
774 // ------------------------------------------------------------------- | 728 // ------------------------------------------------------------------- |
775 | 729 |
776 utils.InstallFunctions(GlobalRegExp.prototype, DONT_ENUM, [ | 730 utils.InstallFunctions(GlobalRegExp.prototype, DONT_ENUM, [ |
777 "exec", RegExpSubclassExecJS, | |
778 "test", RegExpSubclassTest, | 731 "test", RegExpSubclassTest, |
779 matchSymbol, RegExpSubclassMatch, | 732 matchSymbol, RegExpSubclassMatch, |
780 replaceSymbol, RegExpSubclassReplace, | 733 replaceSymbol, RegExpSubclassReplace, |
781 searchSymbol, RegExpSubclassSearch, | 734 searchSymbol, RegExpSubclassSearch, |
782 splitSymbol, RegExpSubclassSplit, | 735 splitSymbol, RegExpSubclassSplit, |
783 ]); | 736 ]); |
784 | 737 |
785 // Temporary until all RegExpLastMatchInfo accesses are ported to C++. | 738 // Temporary until all RegExpLastMatchInfo accesses are ported to C++. |
786 SET_PRIVATE(GlobalRegExp, lastMatchInfoSymbol, RegExpLastMatchInfo); | 739 SET_PRIVATE(GlobalRegExp, lastMatchInfoSymbol, RegExpLastMatchInfo); |
787 | 740 |
| 741 var RegExpSubclassExecJS = GlobalRegExp.prototype.exec; |
| 742 |
788 // ------------------------------------------------------------------- | 743 // ------------------------------------------------------------------- |
789 // Internal | 744 // Internal |
790 | 745 |
791 var InternalRegExpMatchInfo = { | 746 var InternalRegExpMatchInfo = { |
792 REGEXP_NUMBER_OF_CAPTURES: 2, | 747 REGEXP_NUMBER_OF_CAPTURES: 2, |
793 REGEXP_LAST_SUBJECT: "", | 748 REGEXP_LAST_SUBJECT: "", |
794 REGEXP_LAST_INPUT: UNDEFINED, | 749 REGEXP_LAST_INPUT: UNDEFINED, |
795 CAPTURE0: 0, | 750 CAPTURE0: 0, |
796 CAPTURE1: 0 | 751 CAPTURE1: 0 |
797 }; | 752 }; |
(...skipping 15 matching lines...) Expand all Loading... |
813 // Exports | 768 // Exports |
814 | 769 |
815 utils.Export(function(to) { | 770 utils.Export(function(to) { |
816 to.InternalRegExpMatch = InternalRegExpMatch; | 771 to.InternalRegExpMatch = InternalRegExpMatch; |
817 to.InternalRegExpReplace = InternalRegExpReplace; | 772 to.InternalRegExpReplace = InternalRegExpReplace; |
818 to.IsRegExp = IsRegExp; | 773 to.IsRegExp = IsRegExp; |
819 to.RegExpInitialize = RegExpInitialize; | 774 to.RegExpInitialize = RegExpInitialize; |
820 }); | 775 }); |
821 | 776 |
822 }) | 777 }) |
OLD | NEW |