| 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 FLAG_harmony_regexps; |  | 
| 13 var FLAG_harmony_tolength; | 12 var FLAG_harmony_tolength; | 
| 14 var FLAG_harmony_unicode_regexps; |  | 
| 15 var GlobalObject = global.Object; | 13 var GlobalObject = global.Object; | 
| 16 var GlobalRegExp = global.RegExp; | 14 var GlobalRegExp = global.RegExp; | 
| 17 var InternalPackedArray = utils.InternalPackedArray; | 15 var InternalPackedArray = utils.InternalPackedArray; | 
| 18 var MakeTypeError; | 16 var MakeTypeError; | 
|  | 17 var regExpFlagsSymbol = utils.ImportNow("regexp_flags_symbol"); | 
|  | 18 var regExpSourceSymbol = utils.ImportNow("regexp_source_symbol"); | 
| 19 | 19 | 
| 20 utils.ImportFromExperimental(function(from) { | 20 utils.ImportFromExperimental(function(from) { | 
| 21   FLAG_harmony_regexps = from.FLAG_harmony_regexps; |  | 
| 22   FLAG_harmony_tolength = from.FLAG_harmony_tolength; | 21   FLAG_harmony_tolength = from.FLAG_harmony_tolength; | 
| 23   FLAG_harmony_unicode_regexps = from.FLAG_harmony_unicode_regexps; |  | 
| 24 }); | 22 }); | 
| 25 | 23 | 
| 26 utils.Import(function(from) { | 24 utils.Import(function(from) { | 
| 27   MakeTypeError = from.MakeTypeError; | 25   MakeTypeError = from.MakeTypeError; | 
| 28 }); | 26 }); | 
| 29 | 27 | 
| 30 // ------------------------------------------------------------------- | 28 // ------------------------------------------------------------------- | 
| 31 | 29 | 
| 32 // Property of the builtins object for recording the result of the last | 30 // Property of the builtins object for recording the result of the last | 
| 33 // regexp match.  The property RegExpLastMatchInfo includes the matchIndices | 31 // regexp match.  The property RegExpLastMatchInfo includes the matchIndices | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 44 ); | 42 ); | 
| 45 | 43 | 
| 46 // ------------------------------------------------------------------- | 44 // ------------------------------------------------------------------- | 
| 47 | 45 | 
| 48 // A recursive descent parser for Patterns according to the grammar of | 46 // A recursive descent parser for Patterns according to the grammar of | 
| 49 // ECMA-262 15.10.1, with deviations noted below. | 47 // ECMA-262 15.10.1, with deviations noted below. | 
| 50 function DoConstructRegExp(object, pattern, flags) { | 48 function DoConstructRegExp(object, pattern, flags) { | 
| 51   // RegExp : Called as constructor; see ECMA-262, section 15.10.4. | 49   // RegExp : Called as constructor; see ECMA-262, section 15.10.4. | 
| 52   if (IS_REGEXP(pattern)) { | 50   if (IS_REGEXP(pattern)) { | 
| 53     if (!IS_UNDEFINED(flags)) throw MakeTypeError(kRegExpFlags); | 51     if (!IS_UNDEFINED(flags)) throw MakeTypeError(kRegExpFlags); | 
| 54     flags = (pattern.global ? 'g' : '') | 52     flags = (REGEXP_GLOBAL(pattern) ? 'g' : '') | 
| 55         + (pattern.ignoreCase ? 'i' : '') | 53         + (REGEXP_IGNORE_CASE(pattern) ? 'i' : '') | 
| 56         + (pattern.multiline ? 'm' : ''); | 54         + (REGEXP_MULTILINE(pattern) ? 'm' : '') | 
| 57     if (FLAG_harmony_unicode_regexps) | 55         + (REGEXP_UNICODE(pattern) ? 'u' : '') | 
| 58         flags += (pattern.unicode ? 'u' : ''); | 56         + (REGEXP_STICKY(pattern) ? 'y' : ''); | 
| 59     if (FLAG_harmony_regexps) | 57     pattern = REGEXP_SOURCE(pattern); | 
| 60         flags += (pattern.sticky ? 'y' : ''); |  | 
| 61     pattern = pattern.source; |  | 
| 62   } | 58   } | 
| 63 | 59 | 
| 64   pattern = IS_UNDEFINED(pattern) ? '' : TO_STRING(pattern); | 60   pattern = IS_UNDEFINED(pattern) ? '' : TO_STRING(pattern); | 
| 65   flags = IS_UNDEFINED(flags) ? '' : TO_STRING(flags); | 61   flags = IS_UNDEFINED(flags) ? '' : TO_STRING(flags); | 
| 66 | 62 | 
| 67   %RegExpInitializeAndCompile(object, pattern, flags); | 63   %RegExpInitializeAndCompile(object, pattern, flags); | 
| 68 } | 64 } | 
| 69 | 65 | 
| 70 | 66 | 
| 71 function RegExpConstructor(pattern, flags) { | 67 function RegExpConstructor(pattern, flags) { | 
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 135   } | 131   } | 
| 136   return result; | 132   return result; | 
| 137 endmacro | 133 endmacro | 
| 138 | 134 | 
| 139 | 135 | 
| 140 function RegExpExecNoTests(regexp, string, start) { | 136 function RegExpExecNoTests(regexp, string, start) { | 
| 141   // Must be called with RegExp, string and positive integer as arguments. | 137   // Must be called with RegExp, string and positive integer as arguments. | 
| 142   var matchInfo = %_RegExpExec(regexp, string, start, RegExpLastMatchInfo); | 138   var matchInfo = %_RegExpExec(regexp, string, start, RegExpLastMatchInfo); | 
| 143   if (matchInfo !== null) { | 139   if (matchInfo !== null) { | 
| 144     // ES6 21.2.5.2.2 step 18. | 140     // ES6 21.2.5.2.2 step 18. | 
| 145     if (FLAG_harmony_regexps && regexp.sticky) { | 141     if (REGEXP_STICKY(regexp)) regexp.lastIndex = matchInfo[CAPTURE1]; | 
| 146       regexp.lastIndex = matchInfo[CAPTURE1]; |  | 
| 147     } |  | 
| 148     RETURN_NEW_RESULT_FROM_MATCH_INFO(matchInfo, string); | 142     RETURN_NEW_RESULT_FROM_MATCH_INFO(matchInfo, string); | 
| 149   } | 143   } | 
| 150   regexp.lastIndex = 0; | 144   regexp.lastIndex = 0; | 
| 151   return null; | 145   return null; | 
| 152 } | 146 } | 
| 153 | 147 | 
| 154 | 148 | 
| 155 function RegExpExecJS(string) { | 149 function RegExpExecJS(string) { | 
| 156   if (!IS_REGEXP(this)) { | 150   if (!IS_REGEXP(this)) { | 
| 157     throw MakeTypeError(kIncompatibleMethodReceiver, | 151     throw MakeTypeError(kIncompatibleMethodReceiver, | 
| 158                         'RegExp.prototype.exec', this); | 152                         'RegExp.prototype.exec', this); | 
| 159   } | 153   } | 
| 160 | 154 | 
| 161   string = TO_STRING(string); | 155   string = TO_STRING(string); | 
| 162   var lastIndex = this.lastIndex; | 156   var lastIndex = this.lastIndex; | 
| 163 | 157 | 
| 164   // Conversion is required by the ES2015 specification (RegExpBuiltinExec | 158   // Conversion is required by the ES2015 specification (RegExpBuiltinExec | 
| 165   // algorithm, step 4) even if the value is discarded for non-global RegExps. | 159   // algorithm, step 4) even if the value is discarded for non-global RegExps. | 
| 166   var i = TO_LENGTH_OR_INTEGER(lastIndex); | 160   var i = TO_LENGTH_OR_INTEGER(lastIndex); | 
| 167 | 161 | 
| 168   var updateLastIndex = this.global || (FLAG_harmony_regexps && this.sticky); | 162   var updateLastIndex = REGEXP_GLOBAL(this) || REGEXP_STICKY(this); | 
| 169   if (updateLastIndex) { | 163   if (updateLastIndex) { | 
| 170     if (i < 0 || i > string.length) { | 164     if (i < 0 || i > string.length) { | 
| 171       this.lastIndex = 0; | 165       this.lastIndex = 0; | 
| 172       return null; | 166       return null; | 
| 173     } | 167     } | 
| 174   } else { | 168   } else { | 
| 175     i = 0; | 169     i = 0; | 
| 176   } | 170   } | 
| 177 | 171 | 
| 178   // matchIndices is either null or the RegExpLastMatchInfo array. | 172   // matchIndices is either null or the RegExpLastMatchInfo array. | 
| (...skipping 26 matching lines...) Expand all  Loading... | 
| 205                         'RegExp.prototype.test', this); | 199                         'RegExp.prototype.test', this); | 
| 206   } | 200   } | 
| 207   string = TO_STRING(string); | 201   string = TO_STRING(string); | 
| 208 | 202 | 
| 209   var lastIndex = this.lastIndex; | 203   var lastIndex = this.lastIndex; | 
| 210 | 204 | 
| 211   // Conversion is required by the ES2015 specification (RegExpBuiltinExec | 205   // Conversion is required by the ES2015 specification (RegExpBuiltinExec | 
| 212   // algorithm, step 4) even if the value is discarded for non-global RegExps. | 206   // algorithm, step 4) even if the value is discarded for non-global RegExps. | 
| 213   var i = TO_LENGTH_OR_INTEGER(lastIndex); | 207   var i = TO_LENGTH_OR_INTEGER(lastIndex); | 
| 214 | 208 | 
| 215   if (this.global || (FLAG_harmony_regexps && this.sticky)) { | 209   if (REGEXP_GLOBAL(this) || REGEXP_STICKY(this)) { | 
| 216     if (i < 0 || i > string.length) { | 210     if (i < 0 || i > string.length) { | 
| 217       this.lastIndex = 0; | 211       this.lastIndex = 0; | 
| 218       return false; | 212       return false; | 
| 219     } | 213     } | 
| 220     // matchIndices is either null or the RegExpLastMatchInfo array. | 214     // matchIndices is either null or the RegExpLastMatchInfo array. | 
| 221     var matchIndices = %_RegExpExec(this, string, i, RegExpLastMatchInfo); | 215     var matchIndices = %_RegExpExec(this, string, i, RegExpLastMatchInfo); | 
| 222     if (IS_NULL(matchIndices)) { | 216     if (IS_NULL(matchIndices)) { | 
| 223       this.lastIndex = 0; | 217       this.lastIndex = 0; | 
| 224       return false; | 218       return false; | 
| 225     } | 219     } | 
| 226     this.lastIndex = RegExpLastMatchInfo[CAPTURE1]; | 220     this.lastIndex = RegExpLastMatchInfo[CAPTURE1]; | 
| 227     return true; | 221     return true; | 
| 228   } else { | 222   } else { | 
| 229     // Non-global, non-sticky regexp. | 223     // Non-global, non-sticky regexp. | 
| 230     // Remove irrelevant preceeding '.*' in a test regexp.  The expression | 224     // Remove irrelevant preceeding '.*' in a test regexp.  The expression | 
| 231     // checks whether this.source starts with '.*' and that the third char is | 225     // checks whether this.source starts with '.*' and that the third char is | 
| 232     // not a '?'.  But see https://code.google.com/p/v8/issues/detail?id=3560 | 226     // not a '?'.  But see https://code.google.com/p/v8/issues/detail?id=3560 | 
| 233     var regexp = this; | 227     var regexp = this; | 
| 234     if (regexp.source.length >= 3 && | 228     var source = REGEXP_SOURCE(regexp); | 
| 235         %_StringCharCodeAt(regexp.source, 0) == 46 &&  // '.' | 229     if (regexp.length >= 3 && | 
| 236         %_StringCharCodeAt(regexp.source, 1) == 42 &&  // '*' | 230         %_StringCharCodeAt(regexp, 0) == 46 &&  // '.' | 
| 237         %_StringCharCodeAt(regexp.source, 2) != 63) {  // '?' | 231         %_StringCharCodeAt(regexp, 1) == 42 &&  // '*' | 
|  | 232         %_StringCharCodeAt(regexp, 2) != 63) {  // '?' | 
| 238       regexp = TrimRegExp(regexp); | 233       regexp = TrimRegExp(regexp); | 
| 239     } | 234     } | 
| 240     // matchIndices is either null or the RegExpLastMatchInfo array. | 235     // matchIndices is either null or the RegExpLastMatchInfo array. | 
| 241     var matchIndices = %_RegExpExec(regexp, string, 0, RegExpLastMatchInfo); | 236     var matchIndices = %_RegExpExec(regexp, string, 0, RegExpLastMatchInfo); | 
| 242     if (IS_NULL(matchIndices)) { | 237     if (IS_NULL(matchIndices)) { | 
| 243       this.lastIndex = 0; | 238       this.lastIndex = 0; | 
| 244       return false; | 239       return false; | 
| 245     } | 240     } | 
| 246     return true; | 241     return true; | 
| 247   } | 242   } | 
| 248 } | 243 } | 
| 249 | 244 | 
| 250 function TrimRegExp(regexp) { | 245 function TrimRegExp(regexp) { | 
| 251   if (!%_ObjectEquals(regexp_key, regexp)) { | 246   if (!%_ObjectEquals(regexp_key, regexp)) { | 
| 252     regexp_key = regexp; | 247     regexp_key = regexp; | 
| 253     regexp_val = | 248     regexp_val = | 
| 254       new GlobalRegExp(%_SubString(regexp.source, 2, regexp.source.length), | 249       new GlobalRegExp( | 
| 255                        (regexp.ignoreCase ? regexp.multiline ? "im" : "i" | 250           %_SubString(REGEXP_SOURCE(regexp), 2, REGEXP_SOURCE(regexp).length), | 
| 256                                           : regexp.multiline ? "m" : "")); | 251           (REGEXP_IGNORE_CASE(regexp) ? REGEXP_MULTILINE(regexp) ? "im" : "i" | 
|  | 252                                       : REGEXP_MULTILINE(regexp) ? "m" : "")); | 
| 257   } | 253   } | 
| 258   return regexp_val; | 254   return regexp_val; | 
| 259 } | 255 } | 
| 260 | 256 | 
| 261 | 257 | 
| 262 function RegExpToString() { | 258 function RegExpToString() { | 
| 263   if (!IS_REGEXP(this)) { | 259   if (!IS_REGEXP(this)) { | 
| 264     throw MakeTypeError(kIncompatibleMethodReceiver, | 260     throw MakeTypeError(kIncompatibleMethodReceiver, | 
| 265                         'RegExp.prototype.toString', this); | 261                         'RegExp.prototype.toString', this); | 
| 266   } | 262   } | 
| 267   var result = '/' + this.source + '/'; | 263   var result = '/' + REGEXP_SOURCE(this) + '/'; | 
| 268   if (this.global) result += 'g'; | 264   if (REGEXP_GLOBAL(this)) result += 'g'; | 
| 269   if (this.ignoreCase) result += 'i'; | 265   if (REGEXP_IGNORE_CASE(this)) result += 'i'; | 
| 270   if (this.multiline) result += 'm'; | 266   if (REGEXP_MULTILINE(this)) result += 'm'; | 
| 271   if (FLAG_harmony_unicode_regexps && this.unicode) result += 'u'; | 267   if (REGEXP_UNICODE(this)) result += 'u'; | 
| 272   if (FLAG_harmony_regexps && this.sticky) result += 'y'; | 268   if (REGEXP_STICKY(this)) result += 'y'; | 
| 273   return result; | 269   return result; | 
| 274 } | 270 } | 
| 275 | 271 | 
| 276 | 272 | 
| 277 // Getters for the static properties lastMatch, lastParen, leftContext, and | 273 // Getters for the static properties lastMatch, lastParen, leftContext, and | 
| 278 // rightContext of the RegExp constructor.  The properties are computed based | 274 // rightContext of the RegExp constructor.  The properties are computed based | 
| 279 // 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 | 
| 280 // of the last successful match. | 276 // of the last successful match. | 
| 281 function RegExpGetLastMatch() { | 277 function RegExpGetLastMatch() { | 
| 282   var regExpSubject = LAST_SUBJECT(RegExpLastMatchInfo); | 278   var regExpSubject = LAST_SUBJECT(RegExpLastMatchInfo); | 
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 327   return function foo() { | 323   return function foo() { | 
| 328     var index = n * 2; | 324     var index = n * 2; | 
| 329     if (index >= NUMBER_OF_CAPTURES(RegExpLastMatchInfo)) return ''; | 325     if (index >= NUMBER_OF_CAPTURES(RegExpLastMatchInfo)) return ''; | 
| 330     var matchStart = RegExpLastMatchInfo[CAPTURE(index)]; | 326     var matchStart = RegExpLastMatchInfo[CAPTURE(index)]; | 
| 331     var matchEnd = RegExpLastMatchInfo[CAPTURE(index + 1)]; | 327     var matchEnd = RegExpLastMatchInfo[CAPTURE(index + 1)]; | 
| 332     if (matchStart == -1 || matchEnd == -1) return ''; | 328     if (matchStart == -1 || matchEnd == -1) return ''; | 
| 333     return %_SubString(LAST_SUBJECT(RegExpLastMatchInfo), matchStart, matchEnd); | 329     return %_SubString(LAST_SUBJECT(RegExpLastMatchInfo), matchStart, matchEnd); | 
| 334   }; | 330   }; | 
| 335 } | 331 } | 
| 336 | 332 | 
|  | 333 | 
|  | 334 // ES6 21.2.5.4. | 
|  | 335 function RegExpGetGlobal() { | 
|  | 336   if (!IS_REGEXP(this)) { | 
|  | 337     throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.global"); | 
|  | 338   } | 
|  | 339   return !!REGEXP_GLOBAL(this); | 
|  | 340 } | 
|  | 341 %FunctionSetName(RegExpGetGlobal, "RegExp.prototype.global"); | 
|  | 342 %SetNativeFlag(RegExpGetGlobal); | 
|  | 343 | 
|  | 344 | 
|  | 345 // ES6 21.2.5.5. | 
|  | 346 function RegExpGetIgnoreCase() { | 
|  | 347   if (!IS_REGEXP(this)) { | 
|  | 348     throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.ignoreCase"); | 
|  | 349   } | 
|  | 350   return !!REGEXP_IGNORE_CASE(this); | 
|  | 351 } | 
|  | 352 %FunctionSetName(RegExpGetIgnoreCase, "RegExp.prototype.ignoreCase"); | 
|  | 353 %SetNativeFlag(RegExpGetIgnoreCase); | 
|  | 354 | 
|  | 355 | 
|  | 356 // ES6 21.2.5.7. | 
|  | 357 function RegExpGetMultiline() { | 
|  | 358   if (!IS_REGEXP(this)) { | 
|  | 359     throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.multiline"); | 
|  | 360   } | 
|  | 361   return !!REGEXP_MULTILINE(this); | 
|  | 362 } | 
|  | 363 %FunctionSetName(RegExpGetMultiline, "RegExp.prototype.multiline"); | 
|  | 364 %SetNativeFlag(RegExpGetMultiline); | 
|  | 365 | 
|  | 366 | 
|  | 367 // ES6 21.2.5.10. | 
|  | 368 function RegExpGetSource() { | 
|  | 369   if (!IS_REGEXP(this)) { | 
|  | 370     throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.source"); | 
|  | 371   } | 
|  | 372   return REGEXP_SOURCE(this); | 
|  | 373 } | 
|  | 374 %FunctionSetName(RegExpGetSource, "RegExp.prototype.source"); | 
|  | 375 %SetNativeFlag(RegExpGetSource); | 
|  | 376 | 
| 337 // ------------------------------------------------------------------- | 377 // ------------------------------------------------------------------- | 
| 338 | 378 | 
| 339 %FunctionSetInstanceClassName(GlobalRegExp, 'RegExp'); | 379 %FunctionSetInstanceClassName(GlobalRegExp, 'RegExp'); | 
| 340 %FunctionSetPrototype(GlobalRegExp, new GlobalObject()); | 380 %FunctionSetPrototype(GlobalRegExp, new GlobalObject()); | 
| 341 %AddNamedProperty( | 381 %AddNamedProperty( | 
| 342     GlobalRegExp.prototype, 'constructor', GlobalRegExp, DONT_ENUM); | 382     GlobalRegExp.prototype, 'constructor', GlobalRegExp, DONT_ENUM); | 
| 343 %SetCode(GlobalRegExp, RegExpConstructor); | 383 %SetCode(GlobalRegExp, RegExpConstructor); | 
| 344 | 384 | 
| 345 utils.InstallFunctions(GlobalRegExp.prototype, DONT_ENUM, [ | 385 utils.InstallFunctions(GlobalRegExp.prototype, DONT_ENUM, [ | 
| 346   "exec", RegExpExecJS, | 386   "exec", RegExpExecJS, | 
| 347   "test", RegExpTest, | 387   "test", RegExpTest, | 
| 348   "toString", RegExpToString, | 388   "toString", RegExpToString, | 
| 349   "compile", RegExpCompileJS | 389   "compile", RegExpCompileJS | 
| 350 ]); | 390 ]); | 
| 351 | 391 | 
|  | 392 %DefineGetterPropertyUnchecked(GlobalRegExp.prototype, "global", | 
|  | 393                                RegExpGetGlobal, DONT_ENUM); | 
|  | 394 %DefineGetterPropertyUnchecked(GlobalRegExp.prototype, "ignoreCase", | 
|  | 395                                RegExpGetIgnoreCase, DONT_ENUM); | 
|  | 396 %DefineGetterPropertyUnchecked(GlobalRegExp.prototype, "multiline", | 
|  | 397                                RegExpGetMultiline, DONT_ENUM); | 
|  | 398 %DefineGetterPropertyUnchecked(GlobalRegExp.prototype, "source", | 
|  | 399                                RegExpGetSource, DONT_ENUM); | 
|  | 400 | 
| 352 // The length of compile is 1 in SpiderMonkey. | 401 // The length of compile is 1 in SpiderMonkey. | 
| 353 %FunctionSetLength(GlobalRegExp.prototype.compile, 1); | 402 %FunctionSetLength(GlobalRegExp.prototype.compile, 1); | 
| 354 | 403 | 
| 355 // The properties `input` and `$_` are aliases for each other.  When this | 404 // The properties `input` and `$_` are aliases for each other.  When this | 
| 356 // value is set the value it is set to is coerced to a string. | 405 // value is set the value it is set to is coerced to a string. | 
| 357 // Getter and setter for the input. | 406 // Getter and setter for the input. | 
| 358 var RegExpGetInput = function() { | 407 var RegExpGetInput = function() { | 
| 359   var regExpInput = LAST_INPUT(RegExpLastMatchInfo); | 408   var regExpInput = LAST_INPUT(RegExpLastMatchInfo); | 
| 360   return IS_UNDEFINED(regExpInput) ? "" : regExpInput; | 409   return IS_UNDEFINED(regExpInput) ? "" : regExpInput; | 
| 361 }; | 410 }; | 
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 422 // Exports | 471 // Exports | 
| 423 | 472 | 
| 424 utils.Export(function(to) { | 473 utils.Export(function(to) { | 
| 425   to.RegExpExec = DoRegExpExec; | 474   to.RegExpExec = DoRegExpExec; | 
| 426   to.RegExpExecNoTests = RegExpExecNoTests; | 475   to.RegExpExecNoTests = RegExpExecNoTests; | 
| 427   to.RegExpLastMatchInfo = RegExpLastMatchInfo; | 476   to.RegExpLastMatchInfo = RegExpLastMatchInfo; | 
| 428   to.RegExpTest = RegExpTest; | 477   to.RegExpTest = RegExpTest; | 
| 429 }); | 478 }); | 
| 430 | 479 | 
| 431 }) | 480 }) | 
| OLD | NEW | 
|---|