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 var $regexpExec; |
| 6 var $regexpExecNoTests; |
| 7 var $regexpLastMatchInfo; |
5 var $regexpLastMatchInfoOverride; | 8 var $regexpLastMatchInfoOverride; |
6 var harmony_regexps = false; | 9 var harmony_regexps = false; |
7 var harmony_unicode_regexps = false; | 10 var harmony_unicode_regexps = false; |
8 | 11 |
9 (function(global, utils) { | 12 (function(global, utils) { |
10 | 13 |
11 %CheckIsBootstrapping(); | 14 %CheckIsBootstrapping(); |
12 | 15 |
13 // ------------------------------------------------------------------- | 16 // ------------------------------------------------------------------- |
14 // Imports | 17 // Imports |
15 | 18 |
16 var GlobalRegExp = global.RegExp; | 19 var GlobalRegExp = global.RegExp; |
17 var InternalPackedArray = utils.InternalPackedArray; | 20 var InternalPackedArray = utils.InternalPackedArray; |
18 | 21 |
19 // ------------------------------------------------------------------- | 22 // ------------------------------------------------------------------- |
20 | 23 |
21 // Property of the builtins object for recording the result of the last | 24 // Property of the builtins object for recording the result of the last |
22 // regexp match. The property RegExpLastMatchInfo includes the matchIndices | 25 // regexp match. The property $regexpLastMatchInfo includes the matchIndices |
23 // array of the last successful regexp match (an array of start/end index | 26 // array of the last successful regexp match (an array of start/end index |
24 // pairs for the match and all the captured substrings), the invariant is | 27 // pairs for the match and all the captured substrings), the invariant is |
25 // that there are at least two capture indeces. The array also contains | 28 // that there are at least two capture indeces. The array also contains |
26 // the subject string for the last successful match. | 29 // the subject string for the last successful match. |
27 var RegExpLastMatchInfo = new InternalPackedArray( | 30 $regexpLastMatchInfo = new InternalPackedArray( |
28 2, // REGEXP_NUMBER_OF_CAPTURES | 31 2, // REGEXP_NUMBER_OF_CAPTURES |
29 "", // Last subject. | 32 "", // Last subject. |
30 UNDEFINED, // Last input - settable with RegExpSetInput. | 33 UNDEFINED, // Last input - settable with RegExpSetInput. |
31 0, // REGEXP_FIRST_CAPTURE + 0 | 34 0, // REGEXP_FIRST_CAPTURE + 0 |
32 0 // REGEXP_FIRST_CAPTURE + 1 | 35 0 // REGEXP_FIRST_CAPTURE + 1 |
33 ); | 36 ); |
34 | 37 |
35 // Override last match info with an array of actual substrings. | 38 // Override last match info with an array of actual substrings. |
36 // Used internally by replace regexp with function. | 39 // Used internally by replace regexp with function. |
37 // The array has the format of an "apply" argument for a replacement | 40 // The array has the format of an "apply" argument for a replacement |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 } | 97 } |
95 if (IS_UNDEFINED(pattern) && %_ArgumentsLength() != 0) { | 98 if (IS_UNDEFINED(pattern) && %_ArgumentsLength() != 0) { |
96 DoConstructRegExp(this, 'undefined', flags); | 99 DoConstructRegExp(this, 'undefined', flags); |
97 } else { | 100 } else { |
98 DoConstructRegExp(this, pattern, flags); | 101 DoConstructRegExp(this, pattern, flags); |
99 } | 102 } |
100 } | 103 } |
101 | 104 |
102 | 105 |
103 function DoRegExpExec(regexp, string, index) { | 106 function DoRegExpExec(regexp, string, index) { |
104 var result = %_RegExpExec(regexp, string, index, RegExpLastMatchInfo); | 107 var result = %_RegExpExec(regexp, string, index, $regexpLastMatchInfo); |
105 if (result !== null) $regexpLastMatchInfoOverride = null; | 108 if (result !== null) $regexpLastMatchInfoOverride = null; |
106 return result; | 109 return result; |
107 } | 110 } |
108 | 111 |
109 | 112 |
110 // This is kind of performance sensitive, so we want to avoid unnecessary | 113 // This is kind of performance sensitive, so we want to avoid unnecessary |
111 // type checks on inputs. But we also don't want to inline it several times | 114 // type checks on inputs. But we also don't want to inline it several times |
112 // manually, so we use a macro :-) | 115 // manually, so we use a macro :-) |
113 macro RETURN_NEW_RESULT_FROM_MATCH_INFO(MATCHINFO, STRING) | 116 macro RETURN_NEW_RESULT_FROM_MATCH_INFO(MATCHINFO, STRING) |
114 var numResults = NUMBER_OF_CAPTURES(MATCHINFO) >> 1; | 117 var numResults = NUMBER_OF_CAPTURES(MATCHINFO) >> 1; |
(...skipping 13 matching lines...) Expand all Loading... |
128 result[i] = %_SubString(STRING, start, end); | 131 result[i] = %_SubString(STRING, start, end); |
129 } | 132 } |
130 j++; | 133 j++; |
131 } | 134 } |
132 return result; | 135 return result; |
133 endmacro | 136 endmacro |
134 | 137 |
135 | 138 |
136 function RegExpExecNoTests(regexp, string, start) { | 139 function RegExpExecNoTests(regexp, string, start) { |
137 // Must be called with RegExp, string and positive integer as arguments. | 140 // Must be called with RegExp, string and positive integer as arguments. |
138 var matchInfo = %_RegExpExec(regexp, string, start, RegExpLastMatchInfo); | 141 var matchInfo = %_RegExpExec(regexp, string, start, $regexpLastMatchInfo); |
139 if (matchInfo !== null) { | 142 if (matchInfo !== null) { |
140 $regexpLastMatchInfoOverride = null; | 143 $regexpLastMatchInfoOverride = null; |
141 RETURN_NEW_RESULT_FROM_MATCH_INFO(matchInfo, string); | 144 RETURN_NEW_RESULT_FROM_MATCH_INFO(matchInfo, string); |
142 } | 145 } |
143 regexp.lastIndex = 0; | 146 regexp.lastIndex = 0; |
144 return null; | 147 return null; |
145 } | 148 } |
146 | 149 |
147 | 150 |
148 function RegExpExecJS(string) { | 151 function RegExpExecJS(string) { |
(...skipping 12 matching lines...) Expand all Loading... |
161 var updateLastIndex = this.global || (harmony_regexps && this.sticky); | 164 var updateLastIndex = this.global || (harmony_regexps && this.sticky); |
162 if (updateLastIndex) { | 165 if (updateLastIndex) { |
163 if (i < 0 || i > string.length) { | 166 if (i < 0 || i > string.length) { |
164 this.lastIndex = 0; | 167 this.lastIndex = 0; |
165 return null; | 168 return null; |
166 } | 169 } |
167 } else { | 170 } else { |
168 i = 0; | 171 i = 0; |
169 } | 172 } |
170 | 173 |
171 // matchIndices is either null or the RegExpLastMatchInfo array. | 174 // matchIndices is either null or the $regexpLastMatchInfo array. |
172 var matchIndices = %_RegExpExec(this, string, i, RegExpLastMatchInfo); | 175 var matchIndices = %_RegExpExec(this, string, i, $regexpLastMatchInfo); |
173 | 176 |
174 if (IS_NULL(matchIndices)) { | 177 if (IS_NULL(matchIndices)) { |
175 this.lastIndex = 0; | 178 this.lastIndex = 0; |
176 return null; | 179 return null; |
177 } | 180 } |
178 | 181 |
179 // Successful match. | 182 // Successful match. |
180 $regexpLastMatchInfoOverride = null; | 183 $regexpLastMatchInfoOverride = null; |
181 if (updateLastIndex) { | 184 if (updateLastIndex) { |
182 this.lastIndex = RegExpLastMatchInfo[CAPTURE1]; | 185 this.lastIndex = $regexpLastMatchInfo[CAPTURE1]; |
183 } | 186 } |
184 RETURN_NEW_RESULT_FROM_MATCH_INFO(matchIndices, string); | 187 RETURN_NEW_RESULT_FROM_MATCH_INFO(matchIndices, string); |
185 } | 188 } |
186 | 189 |
187 | 190 |
188 // One-element cache for the simplified test regexp. | 191 // One-element cache for the simplified test regexp. |
189 var regexp_key; | 192 var regexp_key; |
190 var regexp_val; | 193 var regexp_val; |
191 | 194 |
192 // Section 15.10.6.3 doesn't actually make sense, but the intention seems to be | 195 // Section 15.10.6.3 doesn't actually make sense, but the intention seems to be |
(...skipping 11 matching lines...) Expand all Loading... |
204 | 207 |
205 // Conversion is required by the ES5 specification (RegExp.prototype.exec | 208 // Conversion is required by the ES5 specification (RegExp.prototype.exec |
206 // algorithm, step 5) even if the value is discarded for non-global RegExps. | 209 // algorithm, step 5) even if the value is discarded for non-global RegExps. |
207 var i = TO_INTEGER(lastIndex); | 210 var i = TO_INTEGER(lastIndex); |
208 | 211 |
209 if (this.global || (harmony_regexps && this.sticky)) { | 212 if (this.global || (harmony_regexps && this.sticky)) { |
210 if (i < 0 || i > string.length) { | 213 if (i < 0 || i > string.length) { |
211 this.lastIndex = 0; | 214 this.lastIndex = 0; |
212 return false; | 215 return false; |
213 } | 216 } |
214 // matchIndices is either null or the RegExpLastMatchInfo array. | 217 // matchIndices is either null or the $regexpLastMatchInfo array. |
215 var matchIndices = %_RegExpExec(this, string, i, RegExpLastMatchInfo); | 218 var matchIndices = %_RegExpExec(this, string, i, $regexpLastMatchInfo); |
216 if (IS_NULL(matchIndices)) { | 219 if (IS_NULL(matchIndices)) { |
217 this.lastIndex = 0; | 220 this.lastIndex = 0; |
218 return false; | 221 return false; |
219 } | 222 } |
220 $regexpLastMatchInfoOverride = null; | 223 $regexpLastMatchInfoOverride = null; |
221 this.lastIndex = RegExpLastMatchInfo[CAPTURE1]; | 224 this.lastIndex = $regexpLastMatchInfo[CAPTURE1]; |
222 return true; | 225 return true; |
223 } else { | 226 } else { |
224 // Non-global, non-sticky regexp. | 227 // Non-global, non-sticky regexp. |
225 // Remove irrelevant preceeding '.*' in a test regexp. The expression | 228 // Remove irrelevant preceeding '.*' in a test regexp. The expression |
226 // checks whether this.source starts with '.*' and that the third char is | 229 // checks whether this.source starts with '.*' and that the third char is |
227 // not a '?'. But see https://code.google.com/p/v8/issues/detail?id=3560 | 230 // not a '?'. But see https://code.google.com/p/v8/issues/detail?id=3560 |
228 var regexp = this; | 231 var regexp = this; |
229 if (regexp.source.length >= 3 && | 232 if (regexp.source.length >= 3 && |
230 %_StringCharCodeAt(regexp.source, 0) == 46 && // '.' | 233 %_StringCharCodeAt(regexp.source, 0) == 46 && // '.' |
231 %_StringCharCodeAt(regexp.source, 1) == 42 && // '*' | 234 %_StringCharCodeAt(regexp.source, 1) == 42 && // '*' |
232 %_StringCharCodeAt(regexp.source, 2) != 63) { // '?' | 235 %_StringCharCodeAt(regexp.source, 2) != 63) { // '?' |
233 regexp = TrimRegExp(regexp); | 236 regexp = TrimRegExp(regexp); |
234 } | 237 } |
235 // matchIndices is either null or the RegExpLastMatchInfo array. | 238 // matchIndices is either null or the $regexpLastMatchInfo array. |
236 var matchIndices = %_RegExpExec(regexp, string, 0, RegExpLastMatchInfo); | 239 var matchIndices = %_RegExpExec(regexp, string, 0, $regexpLastMatchInfo); |
237 if (IS_NULL(matchIndices)) { | 240 if (IS_NULL(matchIndices)) { |
238 this.lastIndex = 0; | 241 this.lastIndex = 0; |
239 return false; | 242 return false; |
240 } | 243 } |
241 $regexpLastMatchInfoOverride = null; | 244 $regexpLastMatchInfoOverride = null; |
242 return true; | 245 return true; |
243 } | 246 } |
244 } | 247 } |
245 | 248 |
246 function TrimRegExp(regexp) { | 249 function TrimRegExp(regexp) { |
(...skipping 24 matching lines...) Expand all Loading... |
271 | 274 |
272 | 275 |
273 // Getters for the static properties lastMatch, lastParen, leftContext, and | 276 // Getters for the static properties lastMatch, lastParen, leftContext, and |
274 // rightContext of the RegExp constructor. The properties are computed based | 277 // rightContext of the RegExp constructor. The properties are computed based |
275 // on the captures array of the last successful match and the subject string | 278 // on the captures array of the last successful match and the subject string |
276 // of the last successful match. | 279 // of the last successful match. |
277 function RegExpGetLastMatch() { | 280 function RegExpGetLastMatch() { |
278 if ($regexpLastMatchInfoOverride !== null) { | 281 if ($regexpLastMatchInfoOverride !== null) { |
279 return OVERRIDE_MATCH($regexpLastMatchInfoOverride); | 282 return OVERRIDE_MATCH($regexpLastMatchInfoOverride); |
280 } | 283 } |
281 var regExpSubject = LAST_SUBJECT(RegExpLastMatchInfo); | 284 var regExpSubject = LAST_SUBJECT($regexpLastMatchInfo); |
282 return %_SubString(regExpSubject, | 285 return %_SubString(regExpSubject, |
283 RegExpLastMatchInfo[CAPTURE0], | 286 $regexpLastMatchInfo[CAPTURE0], |
284 RegExpLastMatchInfo[CAPTURE1]); | 287 $regexpLastMatchInfo[CAPTURE1]); |
285 } | 288 } |
286 | 289 |
287 | 290 |
288 function RegExpGetLastParen() { | 291 function RegExpGetLastParen() { |
289 if ($regexpLastMatchInfoOverride) { | 292 if ($regexpLastMatchInfoOverride) { |
290 var override = $regexpLastMatchInfoOverride; | 293 var override = $regexpLastMatchInfoOverride; |
291 if (override.length <= 3) return ''; | 294 if (override.length <= 3) return ''; |
292 return override[override.length - 3]; | 295 return override[override.length - 3]; |
293 } | 296 } |
294 var length = NUMBER_OF_CAPTURES(RegExpLastMatchInfo); | 297 var length = NUMBER_OF_CAPTURES($regexpLastMatchInfo); |
295 if (length <= 2) return ''; // There were no captures. | 298 if (length <= 2) return ''; // There were no captures. |
296 // We match the SpiderMonkey behavior: return the substring defined by the | 299 // We match the SpiderMonkey behavior: return the substring defined by the |
297 // last pair (after the first pair) of elements of the capture array even if | 300 // last pair (after the first pair) of elements of the capture array even if |
298 // it is empty. | 301 // it is empty. |
299 var regExpSubject = LAST_SUBJECT(RegExpLastMatchInfo); | 302 var regExpSubject = LAST_SUBJECT($regexpLastMatchInfo); |
300 var start = RegExpLastMatchInfo[CAPTURE(length - 2)]; | 303 var start = $regexpLastMatchInfo[CAPTURE(length - 2)]; |
301 var end = RegExpLastMatchInfo[CAPTURE(length - 1)]; | 304 var end = $regexpLastMatchInfo[CAPTURE(length - 1)]; |
302 if (start != -1 && end != -1) { | 305 if (start != -1 && end != -1) { |
303 return %_SubString(regExpSubject, start, end); | 306 return %_SubString(regExpSubject, start, end); |
304 } | 307 } |
305 return ""; | 308 return ""; |
306 } | 309 } |
307 | 310 |
308 | 311 |
309 function RegExpGetLeftContext() { | 312 function RegExpGetLeftContext() { |
310 var start_index; | 313 var start_index; |
311 var subject; | 314 var subject; |
312 if (!$regexpLastMatchInfoOverride) { | 315 if (!$regexpLastMatchInfoOverride) { |
313 start_index = RegExpLastMatchInfo[CAPTURE0]; | 316 start_index = $regexpLastMatchInfo[CAPTURE0]; |
314 subject = LAST_SUBJECT(RegExpLastMatchInfo); | 317 subject = LAST_SUBJECT($regexpLastMatchInfo); |
315 } else { | 318 } else { |
316 var override = $regexpLastMatchInfoOverride; | 319 var override = $regexpLastMatchInfoOverride; |
317 start_index = OVERRIDE_POS(override); | 320 start_index = OVERRIDE_POS(override); |
318 subject = OVERRIDE_SUBJECT(override); | 321 subject = OVERRIDE_SUBJECT(override); |
319 } | 322 } |
320 return %_SubString(subject, 0, start_index); | 323 return %_SubString(subject, 0, start_index); |
321 } | 324 } |
322 | 325 |
323 | 326 |
324 function RegExpGetRightContext() { | 327 function RegExpGetRightContext() { |
325 var start_index; | 328 var start_index; |
326 var subject; | 329 var subject; |
327 if (!$regexpLastMatchInfoOverride) { | 330 if (!$regexpLastMatchInfoOverride) { |
328 start_index = RegExpLastMatchInfo[CAPTURE1]; | 331 start_index = $regexpLastMatchInfo[CAPTURE1]; |
329 subject = LAST_SUBJECT(RegExpLastMatchInfo); | 332 subject = LAST_SUBJECT($regexpLastMatchInfo); |
330 } else { | 333 } else { |
331 var override = $regexpLastMatchInfoOverride; | 334 var override = $regexpLastMatchInfoOverride; |
332 subject = OVERRIDE_SUBJECT(override); | 335 subject = OVERRIDE_SUBJECT(override); |
333 var match = OVERRIDE_MATCH(override); | 336 var match = OVERRIDE_MATCH(override); |
334 start_index = OVERRIDE_POS(override) + match.length; | 337 start_index = OVERRIDE_POS(override) + match.length; |
335 } | 338 } |
336 return %_SubString(subject, start_index, subject.length); | 339 return %_SubString(subject, start_index, subject.length); |
337 } | 340 } |
338 | 341 |
339 | 342 |
340 // The properties $1..$9 are the first nine capturing substrings of the last | 343 // The properties $1..$9 are the first nine capturing substrings of the last |
341 // successful match, or ''. The function RegExpMakeCaptureGetter will be | 344 // successful match, or ''. The function RegExpMakeCaptureGetter will be |
342 // called with indices from 1 to 9. | 345 // called with indices from 1 to 9. |
343 function RegExpMakeCaptureGetter(n) { | 346 function RegExpMakeCaptureGetter(n) { |
344 return function foo() { | 347 return function foo() { |
345 if ($regexpLastMatchInfoOverride) { | 348 if ($regexpLastMatchInfoOverride) { |
346 if (n < $regexpLastMatchInfoOverride.length - 2) { | 349 if (n < $regexpLastMatchInfoOverride.length - 2) { |
347 return OVERRIDE_CAPTURE($regexpLastMatchInfoOverride, n); | 350 return OVERRIDE_CAPTURE($regexpLastMatchInfoOverride, n); |
348 } | 351 } |
349 return ''; | 352 return ''; |
350 } | 353 } |
351 var index = n * 2; | 354 var index = n * 2; |
352 if (index >= NUMBER_OF_CAPTURES(RegExpLastMatchInfo)) return ''; | 355 if (index >= NUMBER_OF_CAPTURES($regexpLastMatchInfo)) return ''; |
353 var matchStart = RegExpLastMatchInfo[CAPTURE(index)]; | 356 var matchStart = $regexpLastMatchInfo[CAPTURE(index)]; |
354 var matchEnd = RegExpLastMatchInfo[CAPTURE(index + 1)]; | 357 var matchEnd = $regexpLastMatchInfo[CAPTURE(index + 1)]; |
355 if (matchStart == -1 || matchEnd == -1) return ''; | 358 if (matchStart == -1 || matchEnd == -1) return ''; |
356 return %_SubString(LAST_SUBJECT(RegExpLastMatchInfo), matchStart, matchEnd); | 359 return %_SubString(LAST_SUBJECT($regexpLastMatchInfo), matchStart, matchEnd)
; |
357 }; | 360 }; |
358 } | 361 } |
359 | 362 |
360 // ------------------------------------------------------------------- | 363 // ------------------------------------------------------------------- |
361 | 364 |
362 %FunctionSetInstanceClassName(GlobalRegExp, 'RegExp'); | 365 %FunctionSetInstanceClassName(GlobalRegExp, 'RegExp'); |
363 %AddNamedProperty( | 366 %AddNamedProperty( |
364 GlobalRegExp.prototype, 'constructor', GlobalRegExp, DONT_ENUM); | 367 GlobalRegExp.prototype, 'constructor', GlobalRegExp, DONT_ENUM); |
365 %SetCode(GlobalRegExp, RegExpConstructor); | 368 %SetCode(GlobalRegExp, RegExpConstructor); |
366 | 369 |
367 utils.InstallFunctions(GlobalRegExp.prototype, DONT_ENUM, [ | 370 $installFunctions(GlobalRegExp.prototype, DONT_ENUM, [ |
368 "exec", RegExpExecJS, | 371 "exec", RegExpExecJS, |
369 "test", RegExpTest, | 372 "test", RegExpTest, |
370 "toString", RegExpToString, | 373 "toString", RegExpToString, |
371 "compile", RegExpCompileJS | 374 "compile", RegExpCompileJS |
372 ]); | 375 ]); |
373 | 376 |
374 // The length of compile is 1 in SpiderMonkey. | 377 // The length of compile is 1 in SpiderMonkey. |
375 %FunctionSetLength(GlobalRegExp.prototype.compile, 1); | 378 %FunctionSetLength(GlobalRegExp.prototype.compile, 1); |
376 | 379 |
377 // The properties `input` and `$_` are aliases for each other. When this | 380 // The properties `input` and `$_` are aliases for each other. When this |
378 // value is set the value it is set to is coerced to a string. | 381 // value is set the value it is set to is coerced to a string. |
379 // Getter and setter for the input. | 382 // Getter and setter for the input. |
380 var RegExpGetInput = function() { | 383 var RegExpGetInput = function() { |
381 var regExpInput = LAST_INPUT(RegExpLastMatchInfo); | 384 var regExpInput = LAST_INPUT($regexpLastMatchInfo); |
382 return IS_UNDEFINED(regExpInput) ? "" : regExpInput; | 385 return IS_UNDEFINED(regExpInput) ? "" : regExpInput; |
383 }; | 386 }; |
384 var RegExpSetInput = function(string) { | 387 var RegExpSetInput = function(string) { |
385 LAST_INPUT(RegExpLastMatchInfo) = $toString(string); | 388 LAST_INPUT($regexpLastMatchInfo) = $toString(string); |
386 }; | 389 }; |
387 | 390 |
388 %OptimizeObjectForAddingMultipleProperties(GlobalRegExp, 22); | 391 %OptimizeObjectForAddingMultipleProperties(GlobalRegExp, 22); |
389 %DefineAccessorPropertyUnchecked(GlobalRegExp, 'input', RegExpGetInput, | 392 %DefineAccessorPropertyUnchecked(GlobalRegExp, 'input', RegExpGetInput, |
390 RegExpSetInput, DONT_DELETE); | 393 RegExpSetInput, DONT_DELETE); |
391 %DefineAccessorPropertyUnchecked(GlobalRegExp, '$_', RegExpGetInput, | 394 %DefineAccessorPropertyUnchecked(GlobalRegExp, '$_', RegExpGetInput, |
392 RegExpSetInput, DONT_ENUM | DONT_DELETE); | 395 RegExpSetInput, DONT_ENUM | DONT_DELETE); |
393 | 396 |
394 // The properties multiline and $* are aliases for each other. When this | 397 // The properties multiline and $* are aliases for each other. When this |
395 // value is set in SpiderMonkey, the value it is set to is coerced to a | 398 // value is set in SpiderMonkey, the value it is set to is coerced to a |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 %DefineAccessorPropertyUnchecked(GlobalRegExp, "$'", RegExpGetRightContext, | 436 %DefineAccessorPropertyUnchecked(GlobalRegExp, "$'", RegExpGetRightContext, |
434 NoOpSetter, DONT_ENUM | DONT_DELETE); | 437 NoOpSetter, DONT_ENUM | DONT_DELETE); |
435 | 438 |
436 for (var i = 1; i < 10; ++i) { | 439 for (var i = 1; i < 10; ++i) { |
437 %DefineAccessorPropertyUnchecked(GlobalRegExp, '$' + i, | 440 %DefineAccessorPropertyUnchecked(GlobalRegExp, '$' + i, |
438 RegExpMakeCaptureGetter(i), NoOpSetter, | 441 RegExpMakeCaptureGetter(i), NoOpSetter, |
439 DONT_DELETE); | 442 DONT_DELETE); |
440 } | 443 } |
441 %ToFastProperties(GlobalRegExp); | 444 %ToFastProperties(GlobalRegExp); |
442 | 445 |
443 // ------------------------------------------------------------------- | 446 $regexpExecNoTests = RegExpExecNoTests; |
444 // Exports | 447 $regexpExec = DoRegExpExec; |
445 | |
446 utils.Export(function(to) { | |
447 to.RegExpExec = DoRegExpExec; | |
448 to.RegExpExecNoTests = RegExpExecNoTests; | |
449 to.RegExpLastMatchInfo = RegExpLastMatchInfo; | |
450 }); | |
451 | 448 |
452 }) | 449 }) |
OLD | NEW |