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 'use strict'; | 7 'use strict'; |
8 | 8 |
9 %CheckIsBootstrapping(); | 9 %CheckIsBootstrapping(); |
10 | 10 |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
115 } | 115 } |
116 | 116 |
117 RegExpInitialize(this, pattern, flags); | 117 RegExpInitialize(this, pattern, flags); |
118 | 118 |
119 // Return undefined for compatibility with JSC. | 119 // Return undefined for compatibility with JSC. |
120 // See http://crbug.com/585775 for web compat details. | 120 // See http://crbug.com/585775 for web compat details. |
121 } | 121 } |
122 | 122 |
123 | 123 |
124 function DoRegExpExec(regexp, string, index) { | 124 function DoRegExpExec(regexp, string, index) { |
125 return %_RegExpExec(regexp, string, index, RegExpLastMatchInfo); | 125 return %RegExpExec(regexp, string, index, RegExpLastMatchInfo); |
Dan Ehrenberg
2016/03/23 15:55:41
Why this change? Will it have performance implicat
Yang
2016/03/24 06:14:13
Thanks for catching this. I changed it for easier
| |
126 } | 126 } |
127 | 127 |
128 | 128 |
129 // This is kind of performance sensitive, so we want to avoid unnecessary | 129 // This is kind of performance sensitive, so we want to avoid unnecessary |
130 // type checks on inputs. But we also don't want to inline it several times | 130 // type checks on inputs. But we also don't want to inline it several times |
131 // manually, so we use a macro :-) | 131 // manually, so we use a macro :-) |
132 macro RETURN_NEW_RESULT_FROM_MATCH_INFO(MATCHINFO, STRING) | 132 macro RETURN_NEW_RESULT_FROM_MATCH_INFO(MATCHINFO, STRING) |
133 var numResults = NUMBER_OF_CAPTURES(MATCHINFO) >> 1; | 133 var numResults = NUMBER_OF_CAPTURES(MATCHINFO) >> 1; |
134 var start = MATCHINFO[CAPTURE0]; | 134 var start = MATCHINFO[CAPTURE0]; |
135 var end = MATCHINFO[CAPTURE1]; | 135 var end = MATCHINFO[CAPTURE1]; |
(...skipping 11 matching lines...) Expand all Loading... | |
147 result[i] = %_SubString(STRING, start, end); | 147 result[i] = %_SubString(STRING, start, end); |
148 } | 148 } |
149 j++; | 149 j++; |
150 } | 150 } |
151 return result; | 151 return result; |
152 endmacro | 152 endmacro |
153 | 153 |
154 | 154 |
155 function RegExpExecNoTests(regexp, string, start) { | 155 function RegExpExecNoTests(regexp, string, start) { |
156 // Must be called with RegExp, string and positive integer as arguments. | 156 // Must be called with RegExp, string and positive integer as arguments. |
157 var matchInfo = %_RegExpExec(regexp, string, start, RegExpLastMatchInfo); | 157 var matchInfo = %RegExpExec(regexp, string, start, RegExpLastMatchInfo); |
158 if (matchInfo !== null) { | 158 if (matchInfo !== null) { |
159 // ES6 21.2.5.2.2 step 18. | 159 // ES6 21.2.5.2.2 step 18. |
160 if (REGEXP_STICKY(regexp)) regexp.lastIndex = matchInfo[CAPTURE1]; | 160 if (REGEXP_STICKY(regexp)) regexp.lastIndex = matchInfo[CAPTURE1]; |
161 RETURN_NEW_RESULT_FROM_MATCH_INFO(matchInfo, string); | 161 RETURN_NEW_RESULT_FROM_MATCH_INFO(matchInfo, string); |
162 } | 162 } |
163 regexp.lastIndex = 0; | 163 regexp.lastIndex = 0; |
164 return null; | 164 return null; |
165 } | 165 } |
166 | 166 |
167 | 167 |
(...skipping 14 matching lines...) Expand all Loading... | |
182 if (updateLastIndex) { | 182 if (updateLastIndex) { |
183 if (i < 0 || i > string.length) { | 183 if (i < 0 || i > string.length) { |
184 this.lastIndex = 0; | 184 this.lastIndex = 0; |
185 return null; | 185 return null; |
186 } | 186 } |
187 } else { | 187 } else { |
188 i = 0; | 188 i = 0; |
189 } | 189 } |
190 | 190 |
191 // matchIndices is either null or the RegExpLastMatchInfo array. | 191 // matchIndices is either null or the RegExpLastMatchInfo array. |
192 var matchIndices = %_RegExpExec(this, string, i, RegExpLastMatchInfo); | 192 var matchIndices = %RegExpExec(this, string, i, RegExpLastMatchInfo); |
193 | 193 |
194 if (IS_NULL(matchIndices)) { | 194 if (IS_NULL(matchIndices)) { |
195 this.lastIndex = 0; | 195 this.lastIndex = 0; |
196 return null; | 196 return null; |
197 } | 197 } |
198 | 198 |
199 // Successful match. | 199 // Successful match. |
200 if (updateLastIndex) { | 200 if (updateLastIndex) { |
201 this.lastIndex = RegExpLastMatchInfo[CAPTURE1]; | 201 this.lastIndex = RegExpLastMatchInfo[CAPTURE1]; |
202 } | 202 } |
(...skipping 21 matching lines...) Expand all Loading... | |
224 // Conversion is required by the ES2015 specification (RegExpBuiltinExec | 224 // Conversion is required by the ES2015 specification (RegExpBuiltinExec |
225 // algorithm, step 4) even if the value is discarded for non-global RegExps. | 225 // algorithm, step 4) even if the value is discarded for non-global RegExps. |
226 var i = TO_LENGTH(lastIndex); | 226 var i = TO_LENGTH(lastIndex); |
227 | 227 |
228 if (REGEXP_GLOBAL(this) || REGEXP_STICKY(this)) { | 228 if (REGEXP_GLOBAL(this) || REGEXP_STICKY(this)) { |
229 if (i < 0 || i > string.length) { | 229 if (i < 0 || i > string.length) { |
230 this.lastIndex = 0; | 230 this.lastIndex = 0; |
231 return false; | 231 return false; |
232 } | 232 } |
233 // matchIndices is either null or the RegExpLastMatchInfo array. | 233 // matchIndices is either null or the RegExpLastMatchInfo array. |
234 var matchIndices = %_RegExpExec(this, string, i, RegExpLastMatchInfo); | 234 var matchIndices = %RegExpExec(this, string, i, RegExpLastMatchInfo); |
235 if (IS_NULL(matchIndices)) { | 235 if (IS_NULL(matchIndices)) { |
236 this.lastIndex = 0; | 236 this.lastIndex = 0; |
237 return false; | 237 return false; |
238 } | 238 } |
239 this.lastIndex = RegExpLastMatchInfo[CAPTURE1]; | 239 this.lastIndex = RegExpLastMatchInfo[CAPTURE1]; |
240 return true; | 240 return true; |
241 } else { | 241 } else { |
242 // Non-global, non-sticky regexp. | 242 // Non-global, non-sticky regexp. |
243 // Remove irrelevant preceeding '.*' in a test regexp. The expression | 243 // Remove irrelevant preceeding '.*' in a test regexp. The expression |
244 // checks whether this.source starts with '.*' and that the third char is | 244 // checks whether this.source starts with '.*' and that the third char is |
245 // not a '?'. But see https://code.google.com/p/v8/issues/detail?id=3560 | 245 // not a '?'. But see https://code.google.com/p/v8/issues/detail?id=3560 |
246 var regexp = this; | 246 var regexp = this; |
247 var source = REGEXP_SOURCE(regexp); | 247 var source = REGEXP_SOURCE(regexp); |
248 if (regexp.length >= 3 && | 248 if (regexp.length >= 3 && |
249 %_StringCharCodeAt(regexp, 0) == 46 && // '.' | 249 %_StringCharCodeAt(regexp, 0) == 46 && // '.' |
250 %_StringCharCodeAt(regexp, 1) == 42 && // '*' | 250 %_StringCharCodeAt(regexp, 1) == 42 && // '*' |
251 %_StringCharCodeAt(regexp, 2) != 63) { // '?' | 251 %_StringCharCodeAt(regexp, 2) != 63) { // '?' |
252 regexp = TrimRegExp(regexp); | 252 regexp = TrimRegExp(regexp); |
253 } | 253 } |
254 // matchIndices is either null or the RegExpLastMatchInfo array. | 254 // matchIndices is either null or the RegExpLastMatchInfo array. |
255 var matchIndices = %_RegExpExec(regexp, string, 0, RegExpLastMatchInfo); | 255 var matchIndices = %RegExpExec(regexp, string, 0, RegExpLastMatchInfo); |
256 if (IS_NULL(matchIndices)) { | 256 if (IS_NULL(matchIndices)) { |
257 this.lastIndex = 0; | 257 this.lastIndex = 0; |
258 return false; | 258 return false; |
259 } | 259 } |
260 return true; | 260 return true; |
261 } | 261 } |
262 } | 262 } |
263 | 263 |
264 function TrimRegExp(regexp) { | 264 function TrimRegExp(regexp) { |
265 if (regexp_key !== regexp) { | 265 if (regexp_key !== regexp) { |
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
768 utils.InstallGetterSetter(GlobalRegExp, "$'", RegExpGetRightContext, NoOpSetter, | 768 utils.InstallGetterSetter(GlobalRegExp, "$'", RegExpGetRightContext, NoOpSetter, |
769 DONT_ENUM | DONT_DELETE); | 769 DONT_ENUM | DONT_DELETE); |
770 | 770 |
771 for (var i = 1; i < 10; ++i) { | 771 for (var i = 1; i < 10; ++i) { |
772 utils.InstallGetterSetter(GlobalRegExp, '$' + i, RegExpMakeCaptureGetter(i), | 772 utils.InstallGetterSetter(GlobalRegExp, '$' + i, RegExpMakeCaptureGetter(i), |
773 NoOpSetter, DONT_DELETE); | 773 NoOpSetter, DONT_DELETE); |
774 } | 774 } |
775 %ToFastProperties(GlobalRegExp); | 775 %ToFastProperties(GlobalRegExp); |
776 | 776 |
777 // ------------------------------------------------------------------- | 777 // ------------------------------------------------------------------- |
778 // Internal | |
779 | |
780 var InternalRegExpMatchInfo = UNDEFINED; | |
781 | |
782 function InternalRegExpMatch(regexp, subject) { | |
783 if (IS_UNDEFINED(InternalRegExpMatchInfo)) { | |
784 InternalRegExpMatchInfo = new InternalPackedArray(2, "", UNDEFINED, 0, 0); | |
785 } | |
786 var matchInfo = %RegExpExec(regexp, subject, 0, InternalRegExpMatchInfo); | |
787 if (!IS_NULL(matchInfo)) { | |
788 RETURN_NEW_RESULT_FROM_MATCH_INFO(matchInfo, subject); | |
789 } | |
790 return null; | |
791 } | |
792 | |
793 function InternalRegExpReplace(regexp, subject, replacement) { | |
794 return %StringReplaceGlobalRegExpWithString( | |
795 subject, regexp, replacement, InternalRegExpMatchInfo); | |
796 } | |
797 | |
798 // ------------------------------------------------------------------- | |
778 // Exports | 799 // Exports |
779 | 800 |
780 utils.Export(function(to) { | 801 utils.Export(function(to) { |
802 to.InternalRegExpMatch = InternalRegExpMatch; | |
803 to.InternalRegExpReplace = InternalRegExpReplace; | |
804 to.IsRegExp = IsRegExp; | |
781 to.RegExpExec = DoRegExpExec; | 805 to.RegExpExec = DoRegExpExec; |
782 to.RegExpExecNoTests = RegExpExecNoTests; | 806 to.RegExpExecNoTests = RegExpExecNoTests; |
783 to.RegExpLastMatchInfo = RegExpLastMatchInfo; | 807 to.RegExpLastMatchInfo = RegExpLastMatchInfo; |
784 to.RegExpTest = RegExpTest; | 808 to.RegExpTest = RegExpTest; |
785 to.IsRegExp = IsRegExp; | |
786 }); | 809 }); |
787 | 810 |
788 }) | 811 }) |
OLD | NEW |