| 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 |