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

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

Issue 2305573002: [regexp] Port RegExp getters and setters (Closed)
Patch Set: Fix for layout test expectations 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 | « src/heap-symbols.h ('k') | src/messages.h » ('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
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 InternalArray = utils.InternalArray; 16 var InternalArray = utils.InternalArray;
17 var InternalPackedArray = utils.InternalPackedArray; 17 var InternalPackedArray = utils.InternalPackedArray;
18 var MaxSimple; 18 var MaxSimple;
19 var MinSimple; 19 var MinSimple;
20 var lastMatchInfoSymbol = utils.ImportNow("regexp_last_match_info_symbol");
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;
26 27
27 utils.Import(function(from) { 28 utils.Import(function(from) {
28 ExpandReplacement = from.ExpandReplacement; 29 ExpandReplacement = from.ExpandReplacement;
29 MaxSimple = from.MaxSimple; 30 MaxSimple = from.MaxSimple;
(...skipping 886 matching lines...) Expand 10 before | Expand all | Expand 10 after
916 var previousLastIndex = this.lastIndex; 917 var previousLastIndex = this.lastIndex;
917 this.lastIndex = 0; 918 this.lastIndex = 0;
918 var result = RegExpSubclassExec(this, string); 919 var result = RegExpSubclassExec(this, string);
919 this.lastIndex = previousLastIndex; 920 this.lastIndex = previousLastIndex;
920 if (IS_NULL(result)) return -1; 921 if (IS_NULL(result)) return -1;
921 return result.index; 922 return result.index;
922 } 923 }
923 %FunctionRemovePrototype(RegExpSubclassSearch); 924 %FunctionRemovePrototype(RegExpSubclassSearch);
924 925
925 926
926 // Getters for the static properties lastMatch, lastParen, leftContext, and
927 // rightContext of the RegExp constructor. The properties are computed based
928 // on the captures array of the last successful match and the subject string
929 // of the last successful match.
930 function RegExpGetLastMatch() {
931 var regExpSubject = LAST_SUBJECT(RegExpLastMatchInfo);
932 return %_SubString(regExpSubject,
933 RegExpLastMatchInfo[CAPTURE0],
934 RegExpLastMatchInfo[CAPTURE1]);
935 }
936
937
938 function RegExpGetLastParen() {
939 var length = NUMBER_OF_CAPTURES(RegExpLastMatchInfo);
940 if (length <= 2) return ''; // There were no captures.
941 // We match the SpiderMonkey behavior: return the substring defined by the
942 // last pair (after the first pair) of elements of the capture array even if
943 // it is empty.
944 var regExpSubject = LAST_SUBJECT(RegExpLastMatchInfo);
945 var start = RegExpLastMatchInfo[CAPTURE(length - 2)];
946 var end = RegExpLastMatchInfo[CAPTURE(length - 1)];
947 if (start != -1 && end != -1) {
948 return %_SubString(regExpSubject, start, end);
949 }
950 return "";
951 }
952
953
954 function RegExpGetLeftContext() {
955 var start_index;
956 var subject;
957 start_index = RegExpLastMatchInfo[CAPTURE0];
958 subject = LAST_SUBJECT(RegExpLastMatchInfo);
959 return %_SubString(subject, 0, start_index);
960 }
961
962
963 function RegExpGetRightContext() {
964 var start_index;
965 var subject;
966 start_index = RegExpLastMatchInfo[CAPTURE1];
967 subject = LAST_SUBJECT(RegExpLastMatchInfo);
968 return %_SubString(subject, start_index, subject.length);
969 }
970
971
972 // The properties $1..$9 are the first nine capturing substrings of the last
973 // successful match, or ''. The function RegExpMakeCaptureGetter will be
974 // called with indices from 1 to 9.
975 function RegExpMakeCaptureGetter(n) {
976 return function foo() {
977 var index = n * 2;
978 if (index >= NUMBER_OF_CAPTURES(RegExpLastMatchInfo)) return '';
979 var matchStart = RegExpLastMatchInfo[CAPTURE(index)];
980 var matchEnd = RegExpLastMatchInfo[CAPTURE(index + 1)];
981 if (matchStart == -1 || matchEnd == -1) return '';
982 return %_SubString(LAST_SUBJECT(RegExpLastMatchInfo), matchStart, matchEnd);
983 };
984 }
985
986
987 // ES6 21.2.5.3.
988 function RegExpGetFlags() {
989 if (!IS_RECEIVER(this)) {
990 throw %make_type_error(
991 kRegExpNonObject, "RegExp.prototype.flags", TO_STRING(this));
992 }
993 var result = '';
994 if (this.global) result += 'g';
995 if (this.ignoreCase) result += 'i';
996 if (this.multiline) result += 'm';
997 if (this.unicode) result += 'u';
998 if (this.sticky) result += 'y';
999 return result;
1000 }
1001
1002
1003 // ES6 21.2.5.4.
1004 function RegExpGetGlobal() {
1005 if (!IS_REGEXP(this)) {
1006 // TODO(littledan): Remove this RegExp compat workaround
1007 if (this === GlobalRegExp.prototype) {
1008 %IncrementUseCounter(kRegExpPrototypeOldFlagGetter);
1009 return UNDEFINED;
1010 }
1011 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.global");
1012 }
1013 return TO_BOOLEAN(REGEXP_GLOBAL(this));
1014 }
1015 %SetForceInlineFlag(RegExpGetGlobal);
1016
1017
1018 // ES6 21.2.5.5.
1019 function RegExpGetIgnoreCase() {
1020 if (!IS_REGEXP(this)) {
1021 // TODO(littledan): Remove this RegExp compat workaround
1022 if (this === GlobalRegExp.prototype) {
1023 %IncrementUseCounter(kRegExpPrototypeOldFlagGetter);
1024 return UNDEFINED;
1025 }
1026 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.ignoreCase");
1027 }
1028 return TO_BOOLEAN(REGEXP_IGNORE_CASE(this));
1029 }
1030
1031
1032 // ES6 21.2.5.7.
1033 function RegExpGetMultiline() {
1034 if (!IS_REGEXP(this)) {
1035 // TODO(littledan): Remove this RegExp compat workaround
1036 if (this === GlobalRegExp.prototype) {
1037 %IncrementUseCounter(kRegExpPrototypeOldFlagGetter);
1038 return UNDEFINED;
1039 }
1040 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.multiline");
1041 }
1042 return TO_BOOLEAN(REGEXP_MULTILINE(this));
1043 }
1044
1045
1046 // ES6 21.2.5.10.
1047 function RegExpGetSource() {
1048 if (!IS_REGEXP(this)) {
1049 // TODO(littledan): Remove this RegExp compat workaround
1050 if (this === GlobalRegExp.prototype) {
1051 %IncrementUseCounter(kRegExpPrototypeSourceGetter);
1052 return "(?:)";
1053 }
1054 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.source");
1055 }
1056 return REGEXP_SOURCE(this);
1057 }
1058
1059
1060 // ES6 21.2.5.12.
1061 function RegExpGetSticky() {
1062 if (!IS_REGEXP(this)) {
1063 // Compat fix: RegExp.prototype.sticky == undefined; UseCounter tracks it
1064 // TODO(littledan): Remove this workaround or standardize it
1065 if (this === GlobalRegExp.prototype) {
1066 %IncrementUseCounter(kRegExpPrototypeStickyGetter);
1067 return UNDEFINED;
1068 }
1069 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.sticky");
1070 }
1071 return TO_BOOLEAN(REGEXP_STICKY(this));
1072 }
1073 %SetForceInlineFlag(RegExpGetSticky);
1074
1075
1076 // ES6 21.2.5.15.
1077 function RegExpGetUnicode() {
1078 if (!IS_REGEXP(this)) {
1079 // TODO(littledan): Remove this RegExp compat workaround
1080 if (this === GlobalRegExp.prototype) {
1081 %IncrementUseCounter(kRegExpPrototypeUnicodeGetter);
1082 return UNDEFINED;
1083 }
1084 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.unicode");
1085 }
1086 return TO_BOOLEAN(REGEXP_UNICODE(this));
1087 }
1088 %SetForceInlineFlag(RegExpGetUnicode);
1089
1090
1091 function RegExpSpecies() {
1092 return this;
1093 }
1094
1095
1096 // ------------------------------------------------------------------- 927 // -------------------------------------------------------------------
1097 928
1098 utils.InstallGetter(GlobalRegExp, speciesSymbol, RegExpSpecies);
1099
1100 utils.InstallFunctions(GlobalRegExp.prototype, DONT_ENUM, [ 929 utils.InstallFunctions(GlobalRegExp.prototype, DONT_ENUM, [
1101 "exec", RegExpSubclassExecJS, 930 "exec", RegExpSubclassExecJS,
1102 "test", RegExpSubclassTest, 931 "test", RegExpSubclassTest,
1103 "toString", RegExpToString, 932 "toString", RegExpToString,
1104 "compile", RegExpCompileJS, 933 "compile", RegExpCompileJS,
1105 matchSymbol, RegExpSubclassMatch, 934 matchSymbol, RegExpSubclassMatch,
1106 replaceSymbol, RegExpSubclassReplace, 935 replaceSymbol, RegExpSubclassReplace,
1107 searchSymbol, RegExpSubclassSearch, 936 searchSymbol, RegExpSubclassSearch,
1108 splitSymbol, RegExpSubclassSplit, 937 splitSymbol, RegExpSubclassSplit,
1109 ]); 938 ]);
1110 939
1111 utils.InstallGetter(GlobalRegExp.prototype, 'flags', RegExpGetFlags); 940 // Temporary until all RegExpLastMatchInfo accesses are ported to C++.
1112 utils.InstallGetter(GlobalRegExp.prototype, 'global', RegExpGetGlobal); 941 SET_PRIVATE(GlobalRegExp, lastMatchInfoSymbol, RegExpLastMatchInfo);
1113 utils.InstallGetter(GlobalRegExp.prototype, 'ignoreCase', RegExpGetIgnoreCase);
1114 utils.InstallGetter(GlobalRegExp.prototype, 'multiline', RegExpGetMultiline);
1115 utils.InstallGetter(GlobalRegExp.prototype, 'source', RegExpGetSource);
1116 utils.InstallGetter(GlobalRegExp.prototype, 'sticky', RegExpGetSticky);
1117 utils.InstallGetter(GlobalRegExp.prototype, 'unicode', RegExpGetUnicode);
1118
1119 // The properties `input` and `$_` are aliases for each other. When this
1120 // value is set the value it is set to is coerced to a string.
1121 // Getter and setter for the input.
1122 var RegExpGetInput = function() {
1123 var regExpInput = LAST_INPUT(RegExpLastMatchInfo);
1124 return IS_UNDEFINED(regExpInput) ? "" : regExpInput;
1125 };
1126 var RegExpSetInput = function(string) {
1127 LAST_INPUT(RegExpLastMatchInfo) = TO_STRING(string);
1128 };
1129
1130 %OptimizeObjectForAddingMultipleProperties(GlobalRegExp, 22);
1131 utils.InstallGetterSetter(GlobalRegExp, 'input', RegExpGetInput, RegExpSetInput,
1132 DONT_DELETE);
1133 utils.InstallGetterSetter(GlobalRegExp, '$_', RegExpGetInput, RegExpSetInput,
1134 DONT_ENUM | DONT_DELETE);
1135
1136
1137 var NoOpSetter = function(ignored) {};
1138
1139
1140 // Static properties set by a successful match.
1141 utils.InstallGetterSetter(GlobalRegExp, 'lastMatch', RegExpGetLastMatch,
1142 NoOpSetter, DONT_DELETE);
1143 utils.InstallGetterSetter(GlobalRegExp, '$&', RegExpGetLastMatch, NoOpSetter,
1144 DONT_ENUM | DONT_DELETE);
1145 utils.InstallGetterSetter(GlobalRegExp, 'lastParen', RegExpGetLastParen,
1146 NoOpSetter, DONT_DELETE);
1147 utils.InstallGetterSetter(GlobalRegExp, '$+', RegExpGetLastParen, NoOpSetter,
1148 DONT_ENUM | DONT_DELETE);
1149 utils.InstallGetterSetter(GlobalRegExp, 'leftContext', RegExpGetLeftContext,
1150 NoOpSetter, DONT_DELETE);
1151 utils.InstallGetterSetter(GlobalRegExp, '$`', RegExpGetLeftContext, NoOpSetter,
1152 DONT_ENUM | DONT_DELETE);
1153 utils.InstallGetterSetter(GlobalRegExp, 'rightContext', RegExpGetRightContext,
1154 NoOpSetter, DONT_DELETE);
1155 utils.InstallGetterSetter(GlobalRegExp, "$'", RegExpGetRightContext, NoOpSetter,
1156 DONT_ENUM | DONT_DELETE);
1157
1158 for (var i = 1; i < 10; ++i) {
1159 utils.InstallGetterSetter(GlobalRegExp, '$' + i, RegExpMakeCaptureGetter(i),
1160 NoOpSetter, DONT_DELETE);
1161 }
1162 %ToFastProperties(GlobalRegExp);
1163 942
1164 // ------------------------------------------------------------------- 943 // -------------------------------------------------------------------
1165 // Internal 944 // Internal
1166 945
1167 var InternalRegExpMatchInfo = { 946 var InternalRegExpMatchInfo = {
1168 REGEXP_NUMBER_OF_CAPTURES: 2, 947 REGEXP_NUMBER_OF_CAPTURES: 2,
1169 REGEXP_LAST_SUBJECT: "", 948 REGEXP_LAST_SUBJECT: "",
1170 REGEXP_LAST_INPUT: UNDEFINED, 949 REGEXP_LAST_INPUT: UNDEFINED,
1171 CAPTURE0: 0, 950 CAPTURE0: 0,
1172 CAPTURE1: 0 951 CAPTURE1: 0
(...skipping 19 matching lines...) Expand all
1192 to.InternalRegExpMatch = InternalRegExpMatch; 971 to.InternalRegExpMatch = InternalRegExpMatch;
1193 to.InternalRegExpReplace = InternalRegExpReplace; 972 to.InternalRegExpReplace = InternalRegExpReplace;
1194 to.IsRegExp = IsRegExp; 973 to.IsRegExp = IsRegExp;
1195 to.RegExpExec = DoRegExpExec; 974 to.RegExpExec = DoRegExpExec;
1196 to.RegExpInitialize = RegExpInitialize; 975 to.RegExpInitialize = RegExpInitialize;
1197 to.RegExpLastMatchInfo = RegExpLastMatchInfo; 976 to.RegExpLastMatchInfo = RegExpLastMatchInfo;
1198 to.RegExpTest = RegExpTest; 977 to.RegExpTest = RegExpTest;
1199 }); 978 });
1200 979
1201 }) 980 })
OLDNEW
« no previous file with comments | « src/heap-symbols.h ('k') | src/messages.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698