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