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 ExpandReplacement; | 12 var ExpandReplacement; |
13 var GlobalArray = global.Array; | 13 var GlobalArray = global.Array; |
14 var GlobalObject = global.Object; | 14 var GlobalObject = global.Object; |
15 var GlobalRegExp = global.RegExp; | 15 var GlobalRegExp = global.RegExp; |
| 16 var GlobalRegExpPrototype; |
16 var InternalArray = utils.InternalArray; | 17 var InternalArray = utils.InternalArray; |
17 var InternalPackedArray = utils.InternalPackedArray; | 18 var InternalPackedArray = utils.InternalPackedArray; |
18 var MaxSimple; | 19 var MaxSimple; |
19 var MinSimple; | 20 var MinSimple; |
20 var matchSymbol = utils.ImportNow("match_symbol"); | 21 var matchSymbol = utils.ImportNow("match_symbol"); |
21 var replaceSymbol = utils.ImportNow("replace_symbol"); | 22 var replaceSymbol = utils.ImportNow("replace_symbol"); |
22 var searchSymbol = utils.ImportNow("search_symbol"); | 23 var searchSymbol = utils.ImportNow("search_symbol"); |
23 var speciesSymbol = utils.ImportNow("species_symbol"); | 24 var speciesSymbol = utils.ImportNow("species_symbol"); |
24 var splitSymbol = utils.ImportNow("split_symbol"); | 25 var splitSymbol = utils.ImportNow("split_symbol"); |
25 var SpeciesConstructor; | 26 var SpeciesConstructor; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 | 73 |
73 function PatternFlags(pattern) { | 74 function PatternFlags(pattern) { |
74 return (REGEXP_GLOBAL(pattern) ? 'g' : '') + | 75 return (REGEXP_GLOBAL(pattern) ? 'g' : '') + |
75 (REGEXP_IGNORE_CASE(pattern) ? 'i' : '') + | 76 (REGEXP_IGNORE_CASE(pattern) ? 'i' : '') + |
76 (REGEXP_MULTILINE(pattern) ? 'm' : '') + | 77 (REGEXP_MULTILINE(pattern) ? 'm' : '') + |
77 (REGEXP_UNICODE(pattern) ? 'u' : '') + | 78 (REGEXP_UNICODE(pattern) ? 'u' : '') + |
78 (REGEXP_STICKY(pattern) ? 'y' : ''); | 79 (REGEXP_STICKY(pattern) ? 'y' : ''); |
79 } | 80 } |
80 | 81 |
81 | 82 |
| 83 // ES#sec-regexp-pattern-flags |
| 84 // RegExp ( pattern, flags ) |
| 85 function RegExpConstructor(pattern, flags) { |
| 86 var newtarget = new.target; |
| 87 var pattern_is_regexp = IsRegExp(pattern); |
| 88 |
| 89 if (IS_UNDEFINED(newtarget)) { |
| 90 newtarget = GlobalRegExp; |
| 91 |
| 92 // ES6 section 21.2.3.1 step 3.b |
| 93 if (pattern_is_regexp && IS_UNDEFINED(flags) && |
| 94 pattern.constructor === newtarget) { |
| 95 return pattern; |
| 96 } |
| 97 } |
| 98 |
| 99 if (IS_REGEXP(pattern)) { |
| 100 if (IS_UNDEFINED(flags)) flags = PatternFlags(pattern); |
| 101 pattern = REGEXP_SOURCE(pattern); |
| 102 |
| 103 } else if (pattern_is_regexp) { |
| 104 var input_pattern = pattern; |
| 105 pattern = pattern.source; |
| 106 if (IS_UNDEFINED(flags)) flags = input_pattern.flags; |
| 107 } |
| 108 |
| 109 var object = %_NewObject(GlobalRegExp, newtarget); |
| 110 return RegExpInitialize(object, pattern, flags); |
| 111 } |
| 112 |
| 113 |
82 // ES#sec-regexp.prototype.compile RegExp.prototype.compile (pattern, flags) | 114 // ES#sec-regexp.prototype.compile RegExp.prototype.compile (pattern, flags) |
83 function RegExpCompileJS(pattern, flags) { | 115 function RegExpCompileJS(pattern, flags) { |
84 if (!IS_REGEXP(this)) { | 116 if (!IS_REGEXP(this)) { |
85 throw %make_type_error(kIncompatibleMethodReceiver, | 117 throw %make_type_error(kIncompatibleMethodReceiver, |
86 "RegExp.prototype.compile", this); | 118 "RegExp.prototype.compile", this); |
87 } | 119 } |
88 | 120 |
89 if (IS_REGEXP(pattern)) { | 121 if (IS_REGEXP(pattern)) { |
90 if (!IS_UNDEFINED(flags)) throw %make_type_error(kRegExpFlags); | 122 if (!IS_UNDEFINED(flags)) throw %make_type_error(kRegExpFlags); |
91 | 123 |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 } | 364 } |
333 return regexp_val; | 365 return regexp_val; |
334 } | 366 } |
335 | 367 |
336 | 368 |
337 function RegExpToString() { | 369 function RegExpToString() { |
338 if (!IS_RECEIVER(this)) { | 370 if (!IS_RECEIVER(this)) { |
339 throw %make_type_error( | 371 throw %make_type_error( |
340 kIncompatibleMethodReceiver, 'RegExp.prototype.toString', this); | 372 kIncompatibleMethodReceiver, 'RegExp.prototype.toString', this); |
341 } | 373 } |
342 if (this === GlobalRegExp.prototype) { | 374 if (this === GlobalRegExpPrototype) { |
343 %IncrementUseCounter(kRegExpPrototypeToString); | 375 %IncrementUseCounter(kRegExpPrototypeToString); |
344 } | 376 } |
345 return '/' + TO_STRING(this.source) + '/' + TO_STRING(this.flags); | 377 return '/' + TO_STRING(this.source) + '/' + TO_STRING(this.flags); |
346 } | 378 } |
347 | 379 |
348 | 380 |
349 function AtSurrogatePair(subject, index) { | 381 function AtSurrogatePair(subject, index) { |
350 if (index + 1 >= subject.length) return false; | 382 if (index + 1 >= subject.length) return false; |
351 var first = %_StringCharCodeAt(subject, index); | 383 var first = %_StringCharCodeAt(subject, index); |
352 if (first < 0xD800 || first > 0xDBFF) return false; | 384 if (first < 0xD800 || first > 0xDBFF) return false; |
(...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
997 if (this.unicode) result += 'u'; | 1029 if (this.unicode) result += 'u'; |
998 if (this.sticky) result += 'y'; | 1030 if (this.sticky) result += 'y'; |
999 return result; | 1031 return result; |
1000 } | 1032 } |
1001 | 1033 |
1002 | 1034 |
1003 // ES6 21.2.5.4. | 1035 // ES6 21.2.5.4. |
1004 function RegExpGetGlobal() { | 1036 function RegExpGetGlobal() { |
1005 if (!IS_REGEXP(this)) { | 1037 if (!IS_REGEXP(this)) { |
1006 // TODO(littledan): Remove this RegExp compat workaround | 1038 // TODO(littledan): Remove this RegExp compat workaround |
1007 if (this === GlobalRegExp.prototype) { | 1039 if (this === GlobalRegExpPrototype) { |
1008 %IncrementUseCounter(kRegExpPrototypeOldFlagGetter); | 1040 %IncrementUseCounter(kRegExpPrototypeOldFlagGetter); |
1009 return UNDEFINED; | 1041 return UNDEFINED; |
1010 } | 1042 } |
1011 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.global"); | 1043 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.global"); |
1012 } | 1044 } |
1013 return TO_BOOLEAN(REGEXP_GLOBAL(this)); | 1045 return TO_BOOLEAN(REGEXP_GLOBAL(this)); |
1014 } | 1046 } |
1015 %SetForceInlineFlag(RegExpGetGlobal); | 1047 %SetForceInlineFlag(RegExpGetGlobal); |
1016 | 1048 |
1017 | 1049 |
1018 // ES6 21.2.5.5. | 1050 // ES6 21.2.5.5. |
1019 function RegExpGetIgnoreCase() { | 1051 function RegExpGetIgnoreCase() { |
1020 if (!IS_REGEXP(this)) { | 1052 if (!IS_REGEXP(this)) { |
1021 // TODO(littledan): Remove this RegExp compat workaround | 1053 // TODO(littledan): Remove this RegExp compat workaround |
1022 if (this === GlobalRegExp.prototype) { | 1054 if (this === GlobalRegExpPrototype) { |
1023 %IncrementUseCounter(kRegExpPrototypeOldFlagGetter); | 1055 %IncrementUseCounter(kRegExpPrototypeOldFlagGetter); |
1024 return UNDEFINED; | 1056 return UNDEFINED; |
1025 } | 1057 } |
1026 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.ignoreCase"); | 1058 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.ignoreCase"); |
1027 } | 1059 } |
1028 return TO_BOOLEAN(REGEXP_IGNORE_CASE(this)); | 1060 return TO_BOOLEAN(REGEXP_IGNORE_CASE(this)); |
1029 } | 1061 } |
1030 | 1062 |
1031 | 1063 |
1032 // ES6 21.2.5.7. | 1064 // ES6 21.2.5.7. |
1033 function RegExpGetMultiline() { | 1065 function RegExpGetMultiline() { |
1034 if (!IS_REGEXP(this)) { | 1066 if (!IS_REGEXP(this)) { |
1035 // TODO(littledan): Remove this RegExp compat workaround | 1067 // TODO(littledan): Remove this RegExp compat workaround |
1036 if (this === GlobalRegExp.prototype) { | 1068 if (this === GlobalRegExpPrototype) { |
1037 %IncrementUseCounter(kRegExpPrototypeOldFlagGetter); | 1069 %IncrementUseCounter(kRegExpPrototypeOldFlagGetter); |
1038 return UNDEFINED; | 1070 return UNDEFINED; |
1039 } | 1071 } |
1040 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.multiline"); | 1072 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.multiline"); |
1041 } | 1073 } |
1042 return TO_BOOLEAN(REGEXP_MULTILINE(this)); | 1074 return TO_BOOLEAN(REGEXP_MULTILINE(this)); |
1043 } | 1075 } |
1044 | 1076 |
1045 | 1077 |
1046 // ES6 21.2.5.10. | 1078 // ES6 21.2.5.10. |
1047 function RegExpGetSource() { | 1079 function RegExpGetSource() { |
1048 if (!IS_REGEXP(this)) { | 1080 if (!IS_REGEXP(this)) { |
1049 // TODO(littledan): Remove this RegExp compat workaround | 1081 // TODO(littledan): Remove this RegExp compat workaround |
1050 if (this === GlobalRegExp.prototype) { | 1082 if (this === GlobalRegExpPrototype) { |
1051 %IncrementUseCounter(kRegExpPrototypeSourceGetter); | 1083 %IncrementUseCounter(kRegExpPrototypeSourceGetter); |
1052 return "(?:)"; | 1084 return "(?:)"; |
1053 } | 1085 } |
1054 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.source"); | 1086 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.source"); |
1055 } | 1087 } |
1056 return REGEXP_SOURCE(this); | 1088 return REGEXP_SOURCE(this); |
1057 } | 1089 } |
1058 | 1090 |
1059 | 1091 |
1060 // ES6 21.2.5.12. | 1092 // ES6 21.2.5.12. |
1061 function RegExpGetSticky() { | 1093 function RegExpGetSticky() { |
1062 if (!IS_REGEXP(this)) { | 1094 if (!IS_REGEXP(this)) { |
1063 // Compat fix: RegExp.prototype.sticky == undefined; UseCounter tracks it | 1095 // Compat fix: RegExp.prototype.sticky == undefined; UseCounter tracks it |
1064 // TODO(littledan): Remove this workaround or standardize it | 1096 // TODO(littledan): Remove this workaround or standardize it |
1065 if (this === GlobalRegExp.prototype) { | 1097 if (this === GlobalRegExpPrototype) { |
1066 %IncrementUseCounter(kRegExpPrototypeStickyGetter); | 1098 %IncrementUseCounter(kRegExpPrototypeStickyGetter); |
1067 return UNDEFINED; | 1099 return UNDEFINED; |
1068 } | 1100 } |
1069 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.sticky"); | 1101 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.sticky"); |
1070 } | 1102 } |
1071 return TO_BOOLEAN(REGEXP_STICKY(this)); | 1103 return TO_BOOLEAN(REGEXP_STICKY(this)); |
1072 } | 1104 } |
1073 %SetForceInlineFlag(RegExpGetSticky); | 1105 %SetForceInlineFlag(RegExpGetSticky); |
1074 | 1106 |
1075 | 1107 |
1076 // ES6 21.2.5.15. | 1108 // ES6 21.2.5.15. |
1077 function RegExpGetUnicode() { | 1109 function RegExpGetUnicode() { |
1078 if (!IS_REGEXP(this)) { | 1110 if (!IS_REGEXP(this)) { |
1079 // TODO(littledan): Remove this RegExp compat workaround | 1111 // TODO(littledan): Remove this RegExp compat workaround |
1080 if (this === GlobalRegExp.prototype) { | 1112 if (this === GlobalRegExpPrototype) { |
1081 %IncrementUseCounter(kRegExpPrototypeUnicodeGetter); | 1113 %IncrementUseCounter(kRegExpPrototypeUnicodeGetter); |
1082 return UNDEFINED; | 1114 return UNDEFINED; |
1083 } | 1115 } |
1084 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.unicode"); | 1116 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.unicode"); |
1085 } | 1117 } |
1086 return TO_BOOLEAN(REGEXP_UNICODE(this)); | 1118 return TO_BOOLEAN(REGEXP_UNICODE(this)); |
1087 } | 1119 } |
1088 %SetForceInlineFlag(RegExpGetUnicode); | 1120 %SetForceInlineFlag(RegExpGetUnicode); |
1089 | 1121 |
1090 | 1122 |
1091 function RegExpSpecies() { | 1123 function RegExpSpecies() { |
1092 return this; | 1124 return this; |
1093 } | 1125 } |
1094 | 1126 |
1095 | 1127 |
1096 // ------------------------------------------------------------------- | 1128 // ------------------------------------------------------------------- |
1097 | 1129 |
| 1130 %FunctionSetInstanceClassName(GlobalRegExp, 'RegExp'); |
| 1131 GlobalRegExpPrototype = new GlobalObject(); |
| 1132 %FunctionSetPrototype(GlobalRegExp, GlobalRegExpPrototype); |
| 1133 %AddNamedProperty( |
| 1134 GlobalRegExp.prototype, 'constructor', GlobalRegExp, DONT_ENUM); |
| 1135 %SetCode(GlobalRegExp, RegExpConstructor); |
| 1136 |
1098 utils.InstallGetter(GlobalRegExp, speciesSymbol, RegExpSpecies); | 1137 utils.InstallGetter(GlobalRegExp, speciesSymbol, RegExpSpecies); |
1099 | 1138 |
1100 utils.InstallFunctions(GlobalRegExp.prototype, DONT_ENUM, [ | 1139 utils.InstallFunctions(GlobalRegExp.prototype, DONT_ENUM, [ |
1101 "exec", RegExpSubclassExecJS, | 1140 "exec", RegExpSubclassExecJS, |
1102 "test", RegExpSubclassTest, | 1141 "test", RegExpSubclassTest, |
1103 "toString", RegExpToString, | 1142 "toString", RegExpToString, |
1104 "compile", RegExpCompileJS, | 1143 "compile", RegExpCompileJS, |
1105 matchSymbol, RegExpSubclassMatch, | 1144 matchSymbol, RegExpSubclassMatch, |
1106 replaceSymbol, RegExpSubclassReplace, | 1145 replaceSymbol, RegExpSubclassReplace, |
1107 searchSymbol, RegExpSubclassSearch, | 1146 searchSymbol, RegExpSubclassSearch, |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1192 to.InternalRegExpMatch = InternalRegExpMatch; | 1231 to.InternalRegExpMatch = InternalRegExpMatch; |
1193 to.InternalRegExpReplace = InternalRegExpReplace; | 1232 to.InternalRegExpReplace = InternalRegExpReplace; |
1194 to.IsRegExp = IsRegExp; | 1233 to.IsRegExp = IsRegExp; |
1195 to.RegExpExec = DoRegExpExec; | 1234 to.RegExpExec = DoRegExpExec; |
1196 to.RegExpInitialize = RegExpInitialize; | 1235 to.RegExpInitialize = RegExpInitialize; |
1197 to.RegExpLastMatchInfo = RegExpLastMatchInfo; | 1236 to.RegExpLastMatchInfo = RegExpLastMatchInfo; |
1198 to.RegExpTest = RegExpTest; | 1237 to.RegExpTest = RegExpTest; |
1199 }); | 1238 }); |
1200 | 1239 |
1201 }) | 1240 }) |
OLD | NEW |