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 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
260 | 260 |
261 // Successful match. | 261 // Successful match. |
262 if (updateLastIndex) { | 262 if (updateLastIndex) { |
263 this.lastIndex = RegExpLastMatchInfo[CAPTURE1]; | 263 this.lastIndex = RegExpLastMatchInfo[CAPTURE1]; |
264 } | 264 } |
265 RETURN_NEW_RESULT_FROM_MATCH_INFO(matchIndices, string); | 265 RETURN_NEW_RESULT_FROM_MATCH_INFO(matchIndices, string); |
266 } | 266 } |
267 | 267 |
268 | 268 |
269 // ES#sec-regexpexec Runtime Semantics: RegExpExec ( R, S ) | 269 // ES#sec-regexpexec Runtime Semantics: RegExpExec ( R, S ) |
270 function RegExpSubclassExec(regexp, string) { | 270 // Also takes an optional exec method in case our caller |
271 var exec = regexp.exec; | 271 // has already fetched exec. |
272 function RegExpSubclassExec(regexp, string, exec) { | |
273 if (IS_UNDEFINED(exec)) { | |
274 exec = regexp.exec; | |
275 } | |
272 if (IS_CALLABLE(exec)) { | 276 if (IS_CALLABLE(exec)) { |
273 var result = %_Call(exec, regexp, string); | 277 var result = %_Call(exec, regexp, string); |
274 if (!IS_RECEIVER(result) && !IS_NULL(result)) { | 278 if (!IS_RECEIVER(result) && !IS_NULL(result)) { |
275 throw MakeTypeError(kInvalidRegExpExecResult); | 279 throw MakeTypeError(kInvalidRegExpExecResult); |
276 } | 280 } |
277 return result; | 281 return result; |
278 } | 282 } |
279 return %_Call(RegExpExecJS, regexp, string); | 283 return %_Call(RegExpExecJS, regexp, string); |
280 } | 284 } |
285 %SetForceInlineFlag(RegExpSubclassExec); | |
281 | 286 |
282 | 287 |
283 // One-element cache for the simplified test regexp. | 288 // One-element cache for the simplified test regexp. |
284 var regexp_key; | 289 var regexp_key; |
285 var regexp_val; | 290 var regexp_val; |
286 | 291 |
287 // Legacy implementation of RegExp.prototype.test | 292 // Legacy implementation of RegExp.prototype.test |
288 // Section 15.10.6.3 doesn't actually make sense, but the intention seems to be | 293 // Section 15.10.6.3 doesn't actually make sense, but the intention seems to be |
289 // that test is defined in terms of String.prototype.exec. However, it probably | 294 // that test is defined in terms of String.prototype.exec. However, it probably |
290 // means the original value of String.prototype.exec, which is what everybody | 295 // means the original value of String.prototype.exec, which is what everybody |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
476 // ES#sec-regexp.prototype-@@split | 481 // ES#sec-regexp.prototype-@@split |
477 // RegExp.prototype [ @@split ] ( string, limit ) | 482 // RegExp.prototype [ @@split ] ( string, limit ) |
478 function RegExpSubclassSplit(string, limit) { | 483 function RegExpSubclassSplit(string, limit) { |
479 if (!IS_RECEIVER(this)) { | 484 if (!IS_RECEIVER(this)) { |
480 throw MakeTypeError(kIncompatibleMethodReceiver, | 485 throw MakeTypeError(kIncompatibleMethodReceiver, |
481 "RegExp.prototype.@@split", this); | 486 "RegExp.prototype.@@split", this); |
482 } | 487 } |
483 string = TO_STRING(string); | 488 string = TO_STRING(string); |
484 var constructor = SpeciesConstructor(this, GlobalRegExp); | 489 var constructor = SpeciesConstructor(this, GlobalRegExp); |
485 var flags = TO_STRING(this.flags); | 490 var flags = TO_STRING(this.flags); |
491 | |
492 // TODO(adamk): this fast path is wrong with respect to this.global | |
493 // and this.sticky, but hopefully the spec will open up soon. | |
494 // Also, it doesn't ensure that 'exec' is actually a data property | |
495 // on RegExp.prototype. | |
496 var exec; | |
497 if (IS_REGEXP(this) && constructor === GlobalRegExp) { | |
498 exec = this.exec; | |
499 if (exec === RegExpSubclassExecJS) { | |
500 return %_Call(RegExpSplit, this, string, limit); | |
501 } | |
502 } | |
503 | |
486 var unicode = %StringIndexOf(flags, 'u', 0) >= 0; | 504 var unicode = %StringIndexOf(flags, 'u', 0) >= 0; |
487 var sticky = %StringIndexOf(flags, 'y', 0) >= 0; | 505 var sticky = %StringIndexOf(flags, 'y', 0) >= 0; |
488 var newFlags = sticky ? flags : flags + "y"; | 506 var newFlags = sticky ? flags : flags + "y"; |
489 var splitter = new constructor(this, newFlags); | 507 var splitter = new constructor(this, newFlags); |
490 var array = new GlobalArray(); | 508 var array = new GlobalArray(); |
491 var arrayIndex = 0; | 509 var arrayIndex = 0; |
492 var lim = (IS_UNDEFINED(limit)) ? kMaxUint32 : TO_UINT32(limit); | 510 var lim = (IS_UNDEFINED(limit)) ? kMaxUint32 : TO_UINT32(limit); |
493 var size = string.length; | 511 var size = string.length; |
494 var prevStringIndex = 0; | 512 var prevStringIndex = 0; |
495 if (lim === 0) return array; | 513 if (lim === 0) return array; |
496 var result; | 514 var result; |
497 if (size === 0) { | 515 if (size === 0) { |
498 result = RegExpSubclassExec(splitter, string); | 516 result = RegExpSubclassExec(splitter, string); |
499 if (IS_NULL(result)) AddIndexedProperty(array, 0, string); | 517 if (IS_NULL(result)) AddIndexedProperty(array, 0, string); |
500 return array; | 518 return array; |
501 } | 519 } |
502 var stringIndex = prevStringIndex; | 520 var stringIndex = prevStringIndex; |
503 while (stringIndex < size) { | 521 while (stringIndex < size) { |
504 splitter.lastIndex = stringIndex; | 522 splitter.lastIndex = stringIndex; |
505 result = RegExpSubclassExec(splitter, string); | 523 result = RegExpSubclassExec(splitter, string, exec); |
524 // Ensure exec will be read again on the next loop through. | |
525 exec = UNDEFINED; | |
506 if (IS_NULL(result)) { | 526 if (IS_NULL(result)) { |
507 stringIndex += AdvanceStringIndex(string, stringIndex, unicode); | 527 stringIndex += AdvanceStringIndex(string, stringIndex, unicode); |
508 } else { | 528 } else { |
509 var end = MinSimple(TO_LENGTH(splitter.lastIndex), size); | 529 var end = MinSimple(TO_LENGTH(splitter.lastIndex), size); |
510 if (end === stringIndex) { | 530 if (end === stringIndex) { |
511 stringIndex += AdvanceStringIndex(string, stringIndex, unicode); | 531 stringIndex += AdvanceStringIndex(string, stringIndex, unicode); |
512 } else { | 532 } else { |
513 AddIndexedProperty( | 533 AddIndexedProperty( |
514 array, arrayIndex, | 534 array, arrayIndex, |
515 %_SubString(string, prevStringIndex, stringIndex)); | 535 %_SubString(string, prevStringIndex, stringIndex)); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
554 function RegExpSubclassMatch(string) { | 574 function RegExpSubclassMatch(string) { |
555 if (!IS_RECEIVER(this)) { | 575 if (!IS_RECEIVER(this)) { |
556 throw MakeTypeError(kIncompatibleMethodReceiver, | 576 throw MakeTypeError(kIncompatibleMethodReceiver, |
557 "RegExp.prototype.@@match", this); | 577 "RegExp.prototype.@@match", this); |
558 } | 578 } |
559 string = TO_STRING(string); | 579 string = TO_STRING(string); |
560 var global = this.global; | 580 var global = this.global; |
561 if (!global) return RegExpSubclassExec(this, string); | 581 if (!global) return RegExpSubclassExec(this, string); |
562 var unicode = this.unicode; | 582 var unicode = this.unicode; |
563 this.lastIndex = 0; | 583 this.lastIndex = 0; |
564 var array = []; | 584 var array = new InternalArray(); |
565 var n = 0; | 585 var n = 0; |
566 var result; | 586 var result; |
567 while (true) { | 587 while (true) { |
568 result = RegExpSubclassExec(this, string); | 588 result = RegExpSubclassExec(this, string); |
569 if (IS_NULL(result)) { | 589 if (IS_NULL(result)) { |
570 if (n === 0) return null; | 590 if (n === 0) return null; |
571 return array; | 591 break; |
572 } | 592 } |
573 var matchStr = TO_STRING(result[0]); | 593 var matchStr = TO_STRING(result[0]); |
574 %AddElement(array, n, matchStr); | 594 array[n] = matchStr; |
575 if (matchStr === "") SetAdvancedStringIndex(this, string, unicode); | 595 if (matchStr === "") SetAdvancedStringIndex(this, string, unicode); |
576 n++; | 596 n++; |
577 } | 597 } |
598 var resultArray = []; | |
599 %MoveArrayContents(array, resultArray); | |
600 return resultArray; | |
578 } | 601 } |
579 %FunctionRemovePrototype(RegExpSubclassMatch); | 602 %FunctionRemovePrototype(RegExpSubclassMatch); |
580 | 603 |
581 | 604 |
582 // Legacy implementation of RegExp.prototype[Symbol.replace] which | 605 // Legacy implementation of RegExp.prototype[Symbol.replace] which |
583 // doesn't properly call the underlying exec method. | 606 // doesn't properly call the underlying exec method. |
584 | 607 |
585 // TODO(lrn): This array will survive indefinitely if replace is never | 608 // TODO(lrn): This array will survive indefinitely if replace is never |
586 // called again. However, it will be empty, since the contents are cleared | 609 // called again. However, it will be empty, since the contents are cleared |
587 // in the finally block. | 610 // in the finally block. |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
844 var first = %_StringCharCodeAt(string, index); | 867 var first = %_StringCharCodeAt(string, index); |
845 if (first >= 0xD800 && first <= 0xDBFF && string.length > index + 1) { | 868 if (first >= 0xD800 && first <= 0xDBFF && string.length > index + 1) { |
846 var second = %_StringCharCodeAt(string, index + 1); | 869 var second = %_StringCharCodeAt(string, index + 1); |
847 if (second >= 0xDC00 && second <= 0xDFFF) { | 870 if (second >= 0xDC00 && second <= 0xDFFF) { |
848 increment = 2; | 871 increment = 2; |
849 } | 872 } |
850 } | 873 } |
851 } | 874 } |
852 return increment; | 875 return increment; |
853 } | 876 } |
877 %SetForceInlineFlag(AdvanceStringIndex); | |
854 | 878 |
855 | 879 |
856 function SetAdvancedStringIndex(regexp, string, unicode) { | 880 function SetAdvancedStringIndex(regexp, string, unicode) { |
857 var lastIndex = regexp.lastIndex; | 881 var lastIndex = regexp.lastIndex; |
858 regexp.lastIndex = lastIndex + | 882 regexp.lastIndex = lastIndex + |
859 AdvanceStringIndex(string, lastIndex, unicode); | 883 AdvanceStringIndex(string, lastIndex, unicode); |
860 } | 884 } |
885 %SetForceInlineFlag(SetAdvancedStringIndex); | |
861 | 886 |
862 | 887 |
863 // ES#sec-regexp.prototype-@@replace | 888 // ES#sec-regexp.prototype-@@replace |
864 // RegExp.prototype [ @@replace ] ( string, replaceValue ) | 889 // RegExp.prototype [ @@replace ] ( string, replaceValue ) |
865 function RegExpSubclassReplace(string, replace) { | 890 function RegExpSubclassReplace(string, replace) { |
866 if (!IS_RECEIVER(this)) { | 891 if (!IS_RECEIVER(this)) { |
867 throw MakeTypeError(kIncompatibleMethodReceiver, | 892 throw MakeTypeError(kIncompatibleMethodReceiver, |
868 "RegExp.prototype.@@replace", this); | 893 "RegExp.prototype.@@replace", this); |
869 } | 894 } |
870 string = TO_STRING(string); | 895 string = TO_STRING(string); |
871 var length = string.length; | 896 var length = string.length; |
872 var functionalReplace = IS_CALLABLE(replace); | 897 var functionalReplace = IS_CALLABLE(replace); |
873 if (!functionalReplace) replace = TO_STRING(replace); | 898 if (!functionalReplace) replace = TO_STRING(replace); |
874 var global = this.global; | 899 var global = TO_BOOLEAN(this.global); |
875 if (global) { | 900 if (global) { |
876 var unicode = this.unicode; | 901 var unicode = TO_BOOLEAN(this.unicode); |
877 this.lastIndex = 0; | 902 this.lastIndex = 0; |
878 } | 903 } |
904 | |
905 // TODO(adamk): this fast path is wrong with respect to this.global | |
906 // and this.sticky, but hopefully the spec will open up soon. | |
907 // Also, it doesn't ensure that 'exec' is actually a data property | |
908 // on RegExp.prototype. | |
Dan Ehrenberg
2016/03/28 22:56:09
I believe there is also a shortcut with respect to
adamk
2016/03/28 23:14:37
Added more to this comment.
| |
909 var exec; | |
910 if (IS_REGEXP(this)) { | |
911 exec = this.exec; | |
912 if (exec === RegExpSubclassExecJS) { | |
913 return %_Call(RegExpReplace, this, string, replace); | |
914 } | |
915 } | |
916 | |
879 var results = new InternalArray(); | 917 var results = new InternalArray(); |
880 var result, replacement; | 918 var result, replacement; |
881 while (true) { | 919 while (true) { |
882 result = RegExpSubclassExec(this, string); | 920 result = RegExpSubclassExec(this, string, exec); |
921 // Ensure exec will be read again on the next loop through. | |
922 exec = UNDEFINED; | |
883 if (IS_NULL(result)) { | 923 if (IS_NULL(result)) { |
884 break; | 924 break; |
885 } else { | 925 } else { |
886 results.push(result); | 926 results.push(result); |
887 if (!global) break; | 927 if (!global) break; |
888 var matchStr = TO_STRING(result[0]); | 928 var matchStr = TO_STRING(result[0]); |
889 if (matchStr === "") SetAdvancedStringIndex(this, string, unicode); | 929 if (matchStr === "") SetAdvancedStringIndex(this, string, unicode); |
890 } | 930 } |
891 } | 931 } |
892 var accumulatedResult = ""; | 932 var accumulatedResult = ""; |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1027 kRegExpNonObject, "RegExp.prototype.flags", TO_STRING(this)); | 1067 kRegExpNonObject, "RegExp.prototype.flags", TO_STRING(this)); |
1028 } | 1068 } |
1029 var result = ''; | 1069 var result = ''; |
1030 if (this.global) result += 'g'; | 1070 if (this.global) result += 'g'; |
1031 if (this.ignoreCase) result += 'i'; | 1071 if (this.ignoreCase) result += 'i'; |
1032 if (this.multiline) result += 'm'; | 1072 if (this.multiline) result += 'm'; |
1033 if (this.unicode) result += 'u'; | 1073 if (this.unicode) result += 'u'; |
1034 if (this.sticky) result += 'y'; | 1074 if (this.sticky) result += 'y'; |
1035 return result; | 1075 return result; |
1036 } | 1076 } |
1077 %SetForceInlineFlag(RegExpGetFlags); | |
1037 | 1078 |
1038 | 1079 |
1039 // ES6 21.2.5.4. | 1080 // ES6 21.2.5.4. |
1040 function RegExpGetGlobal() { | 1081 function RegExpGetGlobal() { |
1041 if (!IS_REGEXP(this)) { | 1082 if (!IS_REGEXP(this)) { |
1042 // TODO(littledan): Remove this RegExp compat workaround | 1083 // TODO(littledan): Remove this RegExp compat workaround |
1043 if (this === GlobalRegExpPrototype) { | 1084 if (this === GlobalRegExpPrototype) { |
1044 %IncrementUseCounter(kRegExpPrototypeOldFlagGetter); | 1085 %IncrementUseCounter(kRegExpPrototypeOldFlagGetter); |
1045 return UNDEFINED; | 1086 return UNDEFINED; |
1046 } | 1087 } |
1047 throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.global"); | 1088 throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.global"); |
1048 } | 1089 } |
1049 return !!REGEXP_GLOBAL(this); | 1090 return !!REGEXP_GLOBAL(this); |
1050 } | 1091 } |
1092 %SetForceInlineFlag(RegExpGetGlobal); | |
1051 | 1093 |
1052 | 1094 |
1053 // ES6 21.2.5.5. | 1095 // ES6 21.2.5.5. |
1054 function RegExpGetIgnoreCase() { | 1096 function RegExpGetIgnoreCase() { |
1055 if (!IS_REGEXP(this)) { | 1097 if (!IS_REGEXP(this)) { |
1056 // TODO(littledan): Remove this RegExp compat workaround | 1098 // TODO(littledan): Remove this RegExp compat workaround |
1057 if (this === GlobalRegExpPrototype) { | 1099 if (this === GlobalRegExpPrototype) { |
1058 %IncrementUseCounter(kRegExpPrototypeOldFlagGetter); | 1100 %IncrementUseCounter(kRegExpPrototypeOldFlagGetter); |
1059 return UNDEFINED; | 1101 return UNDEFINED; |
1060 } | 1102 } |
1061 throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.ignoreCase"); | 1103 throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.ignoreCase"); |
1062 } | 1104 } |
1063 return !!REGEXP_IGNORE_CASE(this); | 1105 return !!REGEXP_IGNORE_CASE(this); |
1064 } | 1106 } |
1107 %SetForceInlineFlag(RegExpGetIgnoreCase); | |
1065 | 1108 |
1066 | 1109 |
1067 // ES6 21.2.5.7. | 1110 // ES6 21.2.5.7. |
1068 function RegExpGetMultiline() { | 1111 function RegExpGetMultiline() { |
1069 if (!IS_REGEXP(this)) { | 1112 if (!IS_REGEXP(this)) { |
1070 // TODO(littledan): Remove this RegExp compat workaround | 1113 // TODO(littledan): Remove this RegExp compat workaround |
1071 if (this === GlobalRegExpPrototype) { | 1114 if (this === GlobalRegExpPrototype) { |
1072 %IncrementUseCounter(kRegExpPrototypeOldFlagGetter); | 1115 %IncrementUseCounter(kRegExpPrototypeOldFlagGetter); |
1073 return UNDEFINED; | 1116 return UNDEFINED; |
1074 } | 1117 } |
1075 throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.multiline"); | 1118 throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.multiline"); |
1076 } | 1119 } |
1077 return !!REGEXP_MULTILINE(this); | 1120 return !!REGEXP_MULTILINE(this); |
1078 } | 1121 } |
1122 %SetForceInlineFlag(RegExpGetMultiline); | |
1079 | 1123 |
1080 | 1124 |
1081 // ES6 21.2.5.10. | 1125 // ES6 21.2.5.10. |
1082 function RegExpGetSource() { | 1126 function RegExpGetSource() { |
1083 if (!IS_REGEXP(this)) { | 1127 if (!IS_REGEXP(this)) { |
1084 // TODO(littledan): Remove this RegExp compat workaround | 1128 // TODO(littledan): Remove this RegExp compat workaround |
1085 if (this === GlobalRegExpPrototype) { | 1129 if (this === GlobalRegExpPrototype) { |
1086 %IncrementUseCounter(kRegExpPrototypeSourceGetter); | 1130 %IncrementUseCounter(kRegExpPrototypeSourceGetter); |
1087 return UNDEFINED; | 1131 return UNDEFINED; |
1088 } | 1132 } |
1089 throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.source"); | 1133 throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.source"); |
1090 } | 1134 } |
1091 return REGEXP_SOURCE(this); | 1135 return REGEXP_SOURCE(this); |
1092 } | 1136 } |
1093 | 1137 |
1094 | 1138 |
1095 // ES6 21.2.5.12. | 1139 // ES6 21.2.5.12. |
1096 function RegExpGetSticky() { | 1140 function RegExpGetSticky() { |
1097 if (!IS_REGEXP(this)) { | 1141 if (!IS_REGEXP(this)) { |
1098 // Compat fix: RegExp.prototype.sticky == undefined; UseCounter tracks it | 1142 // Compat fix: RegExp.prototype.sticky == undefined; UseCounter tracks it |
1099 // TODO(littledan): Remove this workaround or standardize it | 1143 // TODO(littledan): Remove this workaround or standardize it |
1100 if (this === GlobalRegExpPrototype) { | 1144 if (this === GlobalRegExpPrototype) { |
1101 %IncrementUseCounter(kRegExpPrototypeStickyGetter); | 1145 %IncrementUseCounter(kRegExpPrototypeStickyGetter); |
1102 return UNDEFINED; | 1146 return UNDEFINED; |
1103 } | 1147 } |
1104 throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.sticky"); | 1148 throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.sticky"); |
1105 } | 1149 } |
1106 return !!REGEXP_STICKY(this); | 1150 return !!REGEXP_STICKY(this); |
1107 } | 1151 } |
1152 %SetForceInlineFlag(RegExpGetSticky); | |
1108 | 1153 |
1109 // ------------------------------------------------------------------- | 1154 // ------------------------------------------------------------------- |
1110 | 1155 |
1111 %FunctionSetInstanceClassName(GlobalRegExp, 'RegExp'); | 1156 %FunctionSetInstanceClassName(GlobalRegExp, 'RegExp'); |
1112 GlobalRegExpPrototype = new GlobalObject(); | 1157 GlobalRegExpPrototype = new GlobalObject(); |
1113 %FunctionSetPrototype(GlobalRegExp, GlobalRegExpPrototype); | 1158 %FunctionSetPrototype(GlobalRegExp, GlobalRegExpPrototype); |
1114 %AddNamedProperty( | 1159 %AddNamedProperty( |
1115 GlobalRegExp.prototype, 'constructor', GlobalRegExp, DONT_ENUM); | 1160 GlobalRegExp.prototype, 'constructor', GlobalRegExp, DONT_ENUM); |
1116 %SetCode(GlobalRegExp, RegExpConstructor); | 1161 %SetCode(GlobalRegExp, RegExpConstructor); |
1117 | 1162 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1188 to.RegExpSubclassMatch = RegExpSubclassMatch; | 1233 to.RegExpSubclassMatch = RegExpSubclassMatch; |
1189 to.RegExpSubclassReplace = RegExpSubclassReplace; | 1234 to.RegExpSubclassReplace = RegExpSubclassReplace; |
1190 to.RegExpSubclassSearch = RegExpSubclassSearch; | 1235 to.RegExpSubclassSearch = RegExpSubclassSearch; |
1191 to.RegExpSubclassSplit = RegExpSubclassSplit; | 1236 to.RegExpSubclassSplit = RegExpSubclassSplit; |
1192 to.RegExpSubclassTest = RegExpSubclassTest; | 1237 to.RegExpSubclassTest = RegExpSubclassTest; |
1193 to.RegExpTest = RegExpTest; | 1238 to.RegExpTest = RegExpTest; |
1194 to.IsRegExp = IsRegExp; | 1239 to.IsRegExp = IsRegExp; |
1195 }); | 1240 }); |
1196 | 1241 |
1197 }) | 1242 }) |
OLD | NEW |