Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(28)

Side by Side Diff: src/js/regexp.js

Issue 2319203002: Clean up RegExp comments and test262 status (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | test/test262/test262.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 if (updateLastIndex) { 197 if (updateLastIndex) {
198 if (i > string.length) { 198 if (i > string.length) {
199 this.lastIndex = 0; 199 this.lastIndex = 0;
200 return null; 200 return null;
201 } 201 }
202 } else { 202 } else {
203 i = 0; 203 i = 0;
204 } 204 }
205 205
206 // matchIndices is either null or the RegExpLastMatchInfo array. 206 // matchIndices is either null or the RegExpLastMatchInfo array.
207 // TODO(littledan): Whether a RegExp is sticky is compiled into the RegExp
208 // itself, but ES2015 allows monkey-patching this property to differ from
209 // the internal flags. If it differs, recompile a different RegExp?
210 var matchIndices = %_RegExpExec(this, string, i, RegExpLastMatchInfo); 207 var matchIndices = %_RegExpExec(this, string, i, RegExpLastMatchInfo);
211 208
212 if (IS_NULL(matchIndices)) { 209 if (IS_NULL(matchIndices)) {
213 this.lastIndex = 0; 210 this.lastIndex = 0;
214 return null; 211 return null;
215 } 212 }
216 213
217 // Successful match. 214 // Successful match.
218 if (updateLastIndex) { 215 if (updateLastIndex) {
219 this.lastIndex = RegExpLastMatchInfo[CAPTURE1]; 216 this.lastIndex = RegExpLastMatchInfo[CAPTURE1];
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 377
381 function AtSurrogatePair(subject, index) { 378 function AtSurrogatePair(subject, index) {
382 if (index + 1 >= subject.length) return false; 379 if (index + 1 >= subject.length) return false;
383 var first = %_StringCharCodeAt(subject, index); 380 var first = %_StringCharCodeAt(subject, index);
384 if (first < 0xD800 || first > 0xDBFF) return false; 381 if (first < 0xD800 || first > 0xDBFF) return false;
385 var second = %_StringCharCodeAt(subject, index + 1); 382 var second = %_StringCharCodeAt(subject, index + 1);
386 return second >= 0xDC00 || second <= 0xDFFF; 383 return second >= 0xDC00 || second <= 0xDFFF;
387 } 384 }
388 385
389 386
390 // Legacy implementation of RegExp.prototype[Symbol.split] which 387 // Fast path implementation of RegExp.prototype[Symbol.split] which
391 // doesn't properly call the underlying exec, @@species methods 388 // doesn't properly call the underlying exec, @@species methods
392 function RegExpSplit(string, limit) { 389 function RegExpSplit(string, limit) {
393 // TODO(yangguo): allow non-regexp receivers.
394 if (!IS_REGEXP(this)) { 390 if (!IS_REGEXP(this)) {
395 throw %make_type_error(kIncompatibleMethodReceiver, 391 throw %make_type_error(kIncompatibleMethodReceiver,
396 "RegExp.prototype.@@split", this); 392 "RegExp.prototype.@@split", this);
397 } 393 }
398 var separator = this; 394 var separator = this;
399 var subject = TO_STRING(string); 395 var subject = TO_STRING(string);
400 396
401 limit = (IS_UNDEFINED(limit)) ? kMaxUint32 : TO_UINT32(limit); 397 limit = (IS_UNDEFINED(limit)) ? kMaxUint32 : TO_UINT32(limit);
402 var length = subject.length; 398 var length = subject.length;
403 399
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
466 // RegExp.prototype [ @@split ] ( string, limit ) 462 // RegExp.prototype [ @@split ] ( string, limit )
467 function RegExpSubclassSplit(string, limit) { 463 function RegExpSubclassSplit(string, limit) {
468 if (!IS_RECEIVER(this)) { 464 if (!IS_RECEIVER(this)) {
469 throw %make_type_error(kIncompatibleMethodReceiver, 465 throw %make_type_error(kIncompatibleMethodReceiver,
470 "RegExp.prototype.@@split", this); 466 "RegExp.prototype.@@split", this);
471 } 467 }
472 string = TO_STRING(string); 468 string = TO_STRING(string);
473 var constructor = SpeciesConstructor(this, GlobalRegExp); 469 var constructor = SpeciesConstructor(this, GlobalRegExp);
474 var flags = TO_STRING(this.flags); 470 var flags = TO_STRING(this.flags);
475 471
476 // TODO(adamk): this fast path is wrong with respect to this.global 472 // TODO(adamk): this fast path is wrong as we doesn't ensure that 'exec'
477 // and this.sticky, but hopefully the spec will remove those gets 473 // is actually a data property on RegExp.prototype.
478 // and thus make the assumption of 'exec' having no side-effects
479 // more correct. Also, we doesn't ensure that 'exec' is actually
480 // a data property on RegExp.prototype.
481 var exec; 474 var exec;
482 if (IS_REGEXP(this) && constructor === GlobalRegExp) { 475 if (IS_REGEXP(this) && constructor === GlobalRegExp) {
483 exec = this.exec; 476 exec = this.exec;
484 if (exec === RegExpSubclassExecJS) { 477 if (exec === RegExpSubclassExecJS) {
485 return %_Call(RegExpSplit, this, string, limit); 478 return %_Call(RegExpSplit, this, string, limit);
486 } 479 }
487 } 480 }
488 481
489 var unicode = %StringIndexOf(flags, 'u', 0) >= 0; 482 var unicode = %StringIndexOf(flags, 'u', 0) >= 0;
490 var sticky = %StringIndexOf(flags, 'y', 0) >= 0; 483 var sticky = %StringIndexOf(flags, 'y', 0) >= 0;
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
862 string = TO_STRING(string); 855 string = TO_STRING(string);
863 var length = string.length; 856 var length = string.length;
864 var functionalReplace = IS_CALLABLE(replace); 857 var functionalReplace = IS_CALLABLE(replace);
865 if (!functionalReplace) replace = TO_STRING(replace); 858 if (!functionalReplace) replace = TO_STRING(replace);
866 var global = TO_BOOLEAN(this.global); 859 var global = TO_BOOLEAN(this.global);
867 if (global) { 860 if (global) {
868 var unicode = TO_BOOLEAN(this.unicode); 861 var unicode = TO_BOOLEAN(this.unicode);
869 this.lastIndex = 0; 862 this.lastIndex = 0;
870 } 863 }
871 864
872 // TODO(adamk): this fast path is wrong with respect to this.global 865 // TODO(adamk): this fast path is wrong as we doesn't ensure that 'exec'
873 // and this.sticky, but hopefully the spec will remove those gets 866 // is actually a data property on RegExp.prototype.
874 // and thus make the assumption of 'exec' having no side-effects
875 // more correct. Also, we doesn't ensure that 'exec' is actually
876 // a data property on RegExp.prototype, nor does the fast path
877 // correctly handle lastIndex setting.
878 var exec; 867 var exec;
879 if (IS_REGEXP(this)) { 868 if (IS_REGEXP(this)) {
880 exec = this.exec; 869 exec = this.exec;
881 if (exec === RegExpSubclassExecJS) { 870 if (exec === RegExpSubclassExecJS) {
882 return %_Call(RegExpReplace, this, string, replace); 871 return %_Call(RegExpReplace, this, string, replace);
883 } 872 }
884 } 873 }
885 874
886 var results = new InternalArray(); 875 var results = new InternalArray();
887 var result, replacement; 876 var result, replacement;
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
1028 if (this.multiline) result += 'm'; 1017 if (this.multiline) result += 'm';
1029 if (this.unicode) result += 'u'; 1018 if (this.unicode) result += 'u';
1030 if (this.sticky) result += 'y'; 1019 if (this.sticky) result += 'y';
1031 return result; 1020 return result;
1032 } 1021 }
1033 1022
1034 1023
1035 // ES6 21.2.5.4. 1024 // ES6 21.2.5.4.
1036 function RegExpGetGlobal() { 1025 function RegExpGetGlobal() {
1037 if (!IS_REGEXP(this)) { 1026 if (!IS_REGEXP(this)) {
1038 // TODO(littledan): Remove this RegExp compat workaround
1039 if (this === GlobalRegExpPrototype) { 1027 if (this === GlobalRegExpPrototype) {
1040 %IncrementUseCounter(kRegExpPrototypeOldFlagGetter); 1028 %IncrementUseCounter(kRegExpPrototypeOldFlagGetter);
1041 return UNDEFINED; 1029 return UNDEFINED;
1042 } 1030 }
1043 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.global"); 1031 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.global");
1044 } 1032 }
1045 return TO_BOOLEAN(REGEXP_GLOBAL(this)); 1033 return TO_BOOLEAN(REGEXP_GLOBAL(this));
1046 } 1034 }
1047 %SetForceInlineFlag(RegExpGetGlobal); 1035 %SetForceInlineFlag(RegExpGetGlobal);
1048 1036
1049 1037
1050 // ES6 21.2.5.5. 1038 // ES6 21.2.5.5.
1051 function RegExpGetIgnoreCase() { 1039 function RegExpGetIgnoreCase() {
1052 if (!IS_REGEXP(this)) { 1040 if (!IS_REGEXP(this)) {
1053 // TODO(littledan): Remove this RegExp compat workaround
1054 if (this === GlobalRegExpPrototype) { 1041 if (this === GlobalRegExpPrototype) {
1055 %IncrementUseCounter(kRegExpPrototypeOldFlagGetter); 1042 %IncrementUseCounter(kRegExpPrototypeOldFlagGetter);
1056 return UNDEFINED; 1043 return UNDEFINED;
1057 } 1044 }
1058 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.ignoreCase"); 1045 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.ignoreCase");
1059 } 1046 }
1060 return TO_BOOLEAN(REGEXP_IGNORE_CASE(this)); 1047 return TO_BOOLEAN(REGEXP_IGNORE_CASE(this));
1061 } 1048 }
1062 1049
1063 1050
1064 // ES6 21.2.5.7. 1051 // ES6 21.2.5.7.
1065 function RegExpGetMultiline() { 1052 function RegExpGetMultiline() {
1066 if (!IS_REGEXP(this)) { 1053 if (!IS_REGEXP(this)) {
1067 // TODO(littledan): Remove this RegExp compat workaround
1068 if (this === GlobalRegExpPrototype) { 1054 if (this === GlobalRegExpPrototype) {
1069 %IncrementUseCounter(kRegExpPrototypeOldFlagGetter); 1055 %IncrementUseCounter(kRegExpPrototypeOldFlagGetter);
1070 return UNDEFINED; 1056 return UNDEFINED;
1071 } 1057 }
1072 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.multiline"); 1058 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.multiline");
1073 } 1059 }
1074 return TO_BOOLEAN(REGEXP_MULTILINE(this)); 1060 return TO_BOOLEAN(REGEXP_MULTILINE(this));
1075 } 1061 }
1076 1062
1077 1063
1078 // ES6 21.2.5.10. 1064 // ES6 21.2.5.10.
1079 function RegExpGetSource() { 1065 function RegExpGetSource() {
1080 if (!IS_REGEXP(this)) { 1066 if (!IS_REGEXP(this)) {
1081 // TODO(littledan): Remove this RegExp compat workaround
1082 if (this === GlobalRegExpPrototype) { 1067 if (this === GlobalRegExpPrototype) {
1083 %IncrementUseCounter(kRegExpPrototypeSourceGetter); 1068 %IncrementUseCounter(kRegExpPrototypeSourceGetter);
1084 return "(?:)"; 1069 return "(?:)";
1085 } 1070 }
1086 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.source"); 1071 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.source");
1087 } 1072 }
1088 return REGEXP_SOURCE(this); 1073 return REGEXP_SOURCE(this);
1089 } 1074 }
1090 1075
1091 1076
1092 // ES6 21.2.5.12. 1077 // ES6 21.2.5.12.
1093 function RegExpGetSticky() { 1078 function RegExpGetSticky() {
1094 if (!IS_REGEXP(this)) { 1079 if (!IS_REGEXP(this)) {
1095 // Compat fix: RegExp.prototype.sticky == undefined; UseCounter tracks it
1096 // TODO(littledan): Remove this workaround or standardize it
1097 if (this === GlobalRegExpPrototype) { 1080 if (this === GlobalRegExpPrototype) {
1098 %IncrementUseCounter(kRegExpPrototypeStickyGetter); 1081 %IncrementUseCounter(kRegExpPrototypeStickyGetter);
1099 return UNDEFINED; 1082 return UNDEFINED;
1100 } 1083 }
1101 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.sticky"); 1084 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.sticky");
1102 } 1085 }
1103 return TO_BOOLEAN(REGEXP_STICKY(this)); 1086 return TO_BOOLEAN(REGEXP_STICKY(this));
1104 } 1087 }
1105 %SetForceInlineFlag(RegExpGetSticky); 1088 %SetForceInlineFlag(RegExpGetSticky);
1106 1089
1107 1090
1108 // ES6 21.2.5.15. 1091 // ES6 21.2.5.15.
1109 function RegExpGetUnicode() { 1092 function RegExpGetUnicode() {
1110 if (!IS_REGEXP(this)) { 1093 if (!IS_REGEXP(this)) {
1111 // TODO(littledan): Remove this RegExp compat workaround
1112 if (this === GlobalRegExpPrototype) { 1094 if (this === GlobalRegExpPrototype) {
1113 %IncrementUseCounter(kRegExpPrototypeUnicodeGetter); 1095 %IncrementUseCounter(kRegExpPrototypeUnicodeGetter);
1114 return UNDEFINED; 1096 return UNDEFINED;
1115 } 1097 }
1116 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.unicode"); 1098 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.unicode");
1117 } 1099 }
1118 return TO_BOOLEAN(REGEXP_UNICODE(this)); 1100 return TO_BOOLEAN(REGEXP_UNICODE(this));
1119 } 1101 }
1120 %SetForceInlineFlag(RegExpGetUnicode); 1102 %SetForceInlineFlag(RegExpGetUnicode);
1121 1103
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1164 }; 1146 };
1165 var RegExpSetInput = function(string) { 1147 var RegExpSetInput = function(string) {
1166 LAST_INPUT(RegExpLastMatchInfo) = TO_STRING(string); 1148 LAST_INPUT(RegExpLastMatchInfo) = TO_STRING(string);
1167 }; 1149 };
1168 1150
1169 // TODO(jgruber): All of these getters and setters were intended to be installed 1151 // TODO(jgruber): All of these getters and setters were intended to be installed
1170 // with various attributes (e.g. DONT_ENUM | DONT_DELETE), but 1152 // with various attributes (e.g. DONT_ENUM | DONT_DELETE), but
1171 // InstallGetterSetter had a bug which ignored the passed attributes and 1153 // InstallGetterSetter had a bug which ignored the passed attributes and
1172 // simply installed as DONT_ENUM instead. We might want to change back 1154 // simply installed as DONT_ENUM instead. We might want to change back
1173 // to the intended attributes at some point. 1155 // to the intended attributes at some point.
1156 // On the other hand, installing attributes as DONT_ENUM matches the draft
1157 // specification at
1158 // https://github.com/claudepache/es-regexp-legacy-static-properties
1174 1159
1175 %OptimizeObjectForAddingMultipleProperties(GlobalRegExp, 22); 1160 %OptimizeObjectForAddingMultipleProperties(GlobalRegExp, 22);
1176 utils.InstallGetterSetter(GlobalRegExp, 'input', RegExpGetInput, RegExpSetInput, 1161 utils.InstallGetterSetter(GlobalRegExp, 'input', RegExpGetInput, RegExpSetInput,
1177 DONT_ENUM); 1162 DONT_ENUM);
1178 utils.InstallGetterSetter(GlobalRegExp, '$_', RegExpGetInput, RegExpSetInput, 1163 utils.InstallGetterSetter(GlobalRegExp, '$_', RegExpGetInput, RegExpSetInput,
1179 DONT_ENUM); 1164 DONT_ENUM);
1180 1165
1181 1166
1182 var NoOpSetter = function(ignored) {}; 1167 var NoOpSetter = function(ignored) {};
1183 1168
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1237 to.InternalRegExpMatch = InternalRegExpMatch; 1222 to.InternalRegExpMatch = InternalRegExpMatch;
1238 to.InternalRegExpReplace = InternalRegExpReplace; 1223 to.InternalRegExpReplace = InternalRegExpReplace;
1239 to.IsRegExp = IsRegExp; 1224 to.IsRegExp = IsRegExp;
1240 to.RegExpExec = DoRegExpExec; 1225 to.RegExpExec = DoRegExpExec;
1241 to.RegExpInitialize = RegExpInitialize; 1226 to.RegExpInitialize = RegExpInitialize;
1242 to.RegExpLastMatchInfo = RegExpLastMatchInfo; 1227 to.RegExpLastMatchInfo = RegExpLastMatchInfo;
1243 to.RegExpTest = RegExpTest; 1228 to.RegExpTest = RegExpTest;
1244 }); 1229 });
1245 1230
1246 }) 1231 })
OLDNEW
« no previous file with comments | « no previous file | test/test262/test262.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698