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