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 var $stringCharAt; | 5 var $stringCharAt; |
6 var $stringIndexOf; | 6 var $stringIndexOf; |
7 var $stringSubstring; | 7 var $stringSubstring; |
8 | 8 |
9 (function() { | 9 (function() { |
10 | 10 |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 // ECMA-262 section 15.5.4.8 | 106 // ECMA-262 section 15.5.4.8 |
107 function StringLastIndexOfJS(pat /* position */) { // length == 1 | 107 function StringLastIndexOfJS(pat /* position */) { // length == 1 |
108 CHECK_OBJECT_COERCIBLE(this, "String.prototype.lastIndexOf"); | 108 CHECK_OBJECT_COERCIBLE(this, "String.prototype.lastIndexOf"); |
109 | 109 |
110 var sub = TO_STRING_INLINE(this); | 110 var sub = TO_STRING_INLINE(this); |
111 var subLength = sub.length; | 111 var subLength = sub.length; |
112 var pat = TO_STRING_INLINE(pat); | 112 var pat = TO_STRING_INLINE(pat); |
113 var patLength = pat.length; | 113 var patLength = pat.length; |
114 var index = subLength - patLength; | 114 var index = subLength - patLength; |
115 if (%_ArgumentsLength() > 1) { | 115 if (%_ArgumentsLength() > 1) { |
116 var position = $toNumber(%_Arguments(1)); | 116 var position = ToNumber(%_Arguments(1)); |
117 if (!NUMBER_IS_NAN(position)) { | 117 if (!NUMBER_IS_NAN(position)) { |
118 position = TO_INTEGER(position); | 118 position = TO_INTEGER(position); |
119 if (position < 0) { | 119 if (position < 0) { |
120 position = 0; | 120 position = 0; |
121 } | 121 } |
122 if (position + patLength < subLength) { | 122 if (position + patLength < subLength) { |
123 index = position; | 123 index = position; |
124 } | 124 } |
125 } | 125 } |
126 } | 126 } |
(...skipping 669 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
796 CHECK_OBJECT_COERCIBLE(this, "String.prototype.trimRight"); | 796 CHECK_OBJECT_COERCIBLE(this, "String.prototype.trimRight"); |
797 | 797 |
798 return %StringTrim(TO_STRING_INLINE(this), false, true); | 798 return %StringTrim(TO_STRING_INLINE(this), false, true); |
799 } | 799 } |
800 | 800 |
801 | 801 |
802 // ECMA-262, section 15.5.3.2 | 802 // ECMA-262, section 15.5.3.2 |
803 function StringFromCharCode(code) { | 803 function StringFromCharCode(code) { |
804 var n = %_ArgumentsLength(); | 804 var n = %_ArgumentsLength(); |
805 if (n == 1) { | 805 if (n == 1) { |
806 if (!%_IsSmi(code)) code = $toNumber(code); | 806 if (!%_IsSmi(code)) code = ToNumber(code); |
807 return %_StringCharFromCode(code & 0xffff); | 807 return %_StringCharFromCode(code & 0xffff); |
808 } | 808 } |
809 | 809 |
810 var one_byte = %NewString(n, NEW_ONE_BYTE_STRING); | 810 var one_byte = %NewString(n, NEW_ONE_BYTE_STRING); |
811 var i; | 811 var i; |
812 for (i = 0; i < n; i++) { | 812 for (i = 0; i < n; i++) { |
813 var code = %_Arguments(i); | 813 var code = %_Arguments(i); |
814 if (!%_IsSmi(code)) code = $toNumber(code) & 0xffff; | 814 if (!%_IsSmi(code)) code = ToNumber(code) & 0xffff; |
815 if (code < 0) code = code & 0xffff; | 815 if (code < 0) code = code & 0xffff; |
816 if (code > 0xff) break; | 816 if (code > 0xff) break; |
817 %_OneByteSeqStringSetChar(i, code, one_byte); | 817 %_OneByteSeqStringSetChar(i, code, one_byte); |
818 } | 818 } |
819 if (i == n) return one_byte; | 819 if (i == n) return one_byte; |
820 one_byte = %TruncateString(one_byte, i); | 820 one_byte = %TruncateString(one_byte, i); |
821 | 821 |
822 var two_byte = %NewString(n - i, NEW_TWO_BYTE_STRING); | 822 var two_byte = %NewString(n - i, NEW_TWO_BYTE_STRING); |
823 for (var j = 0; i < n; i++, j++) { | 823 for (var j = 0; i < n; i++, j++) { |
824 var code = %_Arguments(i); | 824 var code = %_Arguments(i); |
825 if (!%_IsSmi(code)) code = $toNumber(code) & 0xffff; | 825 if (!%_IsSmi(code)) code = ToNumber(code) & 0xffff; |
826 %_TwoByteSeqStringSetChar(j, code, two_byte); | 826 %_TwoByteSeqStringSetChar(j, code, two_byte); |
827 } | 827 } |
828 return one_byte + two_byte; | 828 return one_byte + two_byte; |
829 } | 829 } |
830 | 830 |
831 | 831 |
832 // ES6 draft, revision 26 (2014-07-18), section B.2.3.2.1 | 832 // ES6 draft, revision 26 (2014-07-18), section B.2.3.2.1 |
833 function HtmlEscape(str) { | 833 function HtmlEscape(str) { |
834 return TO_STRING_INLINE(str).replace(/"/g, """); | 834 return TO_STRING_INLINE(str).replace(/"/g, """); |
835 } | 835 } |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
923 function StringSup() { | 923 function StringSup() { |
924 CHECK_OBJECT_COERCIBLE(this, "String.prototype.sup"); | 924 CHECK_OBJECT_COERCIBLE(this, "String.prototype.sup"); |
925 return "<sup>" + this + "</sup>"; | 925 return "<sup>" + this + "</sup>"; |
926 } | 926 } |
927 | 927 |
928 // ES6 draft 01-20-14, section 21.1.3.13 | 928 // ES6 draft 01-20-14, section 21.1.3.13 |
929 function StringRepeat(count) { | 929 function StringRepeat(count) { |
930 CHECK_OBJECT_COERCIBLE(this, "String.prototype.repeat"); | 930 CHECK_OBJECT_COERCIBLE(this, "String.prototype.repeat"); |
931 | 931 |
932 var s = TO_STRING_INLINE(this); | 932 var s = TO_STRING_INLINE(this); |
933 var n = $toInteger(count); | 933 var n = ToInteger(count); |
934 // The maximum string length is stored in a smi, so a longer repeat | 934 // The maximum string length is stored in a smi, so a longer repeat |
935 // must result in a range error. | 935 // must result in a range error. |
936 if (n < 0 || n > %_MaxSmi()) throw MakeRangeError(kInvalidCountValue); | 936 if (n < 0 || n > %_MaxSmi()) throw MakeRangeError(kInvalidCountValue); |
937 | 937 |
938 var r = ""; | 938 var r = ""; |
939 while (true) { | 939 while (true) { |
940 if (n & 1) r += s; | 940 if (n & 1) r += s; |
941 n >>= 1; | 941 n >>= 1; |
942 if (n === 0) return r; | 942 if (n === 0) return r; |
943 s += s; | 943 s += s; |
944 } | 944 } |
945 } | 945 } |
946 | 946 |
947 | 947 |
948 // ES6 draft 04-05-14, section 21.1.3.18 | 948 // ES6 draft 04-05-14, section 21.1.3.18 |
949 function StringStartsWith(searchString /* position */) { // length == 1 | 949 function StringStartsWith(searchString /* position */) { // length == 1 |
950 CHECK_OBJECT_COERCIBLE(this, "String.prototype.startsWith"); | 950 CHECK_OBJECT_COERCIBLE(this, "String.prototype.startsWith"); |
951 | 951 |
952 var s = TO_STRING_INLINE(this); | 952 var s = TO_STRING_INLINE(this); |
953 | 953 |
954 if (IS_REGEXP(searchString)) { | 954 if (IS_REGEXP(searchString)) { |
955 throw MakeTypeError(kFirstArgumentNotRegExp, "String.prototype.startsWith"); | 955 throw MakeTypeError(kFirstArgumentNotRegExp, "String.prototype.startsWith"); |
956 } | 956 } |
957 | 957 |
958 var ss = TO_STRING_INLINE(searchString); | 958 var ss = TO_STRING_INLINE(searchString); |
959 var pos = 0; | 959 var pos = 0; |
960 if (%_ArgumentsLength() > 1) { | 960 if (%_ArgumentsLength() > 1) { |
961 pos = %_Arguments(1); // position | 961 pos = %_Arguments(1); // position |
962 pos = $toInteger(pos); | 962 pos = ToInteger(pos); |
963 } | 963 } |
964 | 964 |
965 var s_len = s.length; | 965 var s_len = s.length; |
966 var start = $min($max(pos, 0), s_len); | 966 var start = $min($max(pos, 0), s_len); |
967 var ss_len = ss.length; | 967 var ss_len = ss.length; |
968 if (ss_len + start > s_len) { | 968 if (ss_len + start > s_len) { |
969 return false; | 969 return false; |
970 } | 970 } |
971 | 971 |
972 return %StringIndexOf(s, ss, start) === start; | 972 return %StringIndexOf(s, ss, start) === start; |
973 } | 973 } |
974 | 974 |
975 | 975 |
976 // ES6 draft 04-05-14, section 21.1.3.7 | 976 // ES6 draft 04-05-14, section 21.1.3.7 |
977 function StringEndsWith(searchString /* position */) { // length == 1 | 977 function StringEndsWith(searchString /* position */) { // length == 1 |
978 CHECK_OBJECT_COERCIBLE(this, "String.prototype.endsWith"); | 978 CHECK_OBJECT_COERCIBLE(this, "String.prototype.endsWith"); |
979 | 979 |
980 var s = TO_STRING_INLINE(this); | 980 var s = TO_STRING_INLINE(this); |
981 | 981 |
982 if (IS_REGEXP(searchString)) { | 982 if (IS_REGEXP(searchString)) { |
983 throw MakeTypeError(kFirstArgumentNotRegExp, "String.prototype.endsWith"); | 983 throw MakeTypeError(kFirstArgumentNotRegExp, "String.prototype.endsWith"); |
984 } | 984 } |
985 | 985 |
986 var ss = TO_STRING_INLINE(searchString); | 986 var ss = TO_STRING_INLINE(searchString); |
987 var s_len = s.length; | 987 var s_len = s.length; |
988 var pos = s_len; | 988 var pos = s_len; |
989 if (%_ArgumentsLength() > 1) { | 989 if (%_ArgumentsLength() > 1) { |
990 var arg = %_Arguments(1); // position | 990 var arg = %_Arguments(1); // position |
991 if (!IS_UNDEFINED(arg)) { | 991 if (!IS_UNDEFINED(arg)) { |
992 pos = $toInteger(arg); | 992 pos = ToInteger(arg); |
993 } | 993 } |
994 } | 994 } |
995 | 995 |
996 var end = $min($max(pos, 0), s_len); | 996 var end = $min($max(pos, 0), s_len); |
997 var ss_len = ss.length; | 997 var ss_len = ss.length; |
998 var start = end - ss_len; | 998 var start = end - ss_len; |
999 if (start < 0) { | 999 if (start < 0) { |
1000 return false; | 1000 return false; |
1001 } | 1001 } |
1002 | 1002 |
1003 return %StringLastIndexOf(s, ss, start) === start; | 1003 return %StringLastIndexOf(s, ss, start) === start; |
1004 } | 1004 } |
1005 | 1005 |
1006 | 1006 |
1007 // ES6 draft 04-05-14, section 21.1.3.6 | 1007 // ES6 draft 04-05-14, section 21.1.3.6 |
1008 function StringIncludes(searchString /* position */) { // length == 1 | 1008 function StringIncludes(searchString /* position */) { // length == 1 |
1009 CHECK_OBJECT_COERCIBLE(this, "String.prototype.includes"); | 1009 CHECK_OBJECT_COERCIBLE(this, "String.prototype.includes"); |
1010 | 1010 |
1011 var s = TO_STRING_INLINE(this); | 1011 var s = TO_STRING_INLINE(this); |
1012 | 1012 |
1013 if (IS_REGEXP(searchString)) { | 1013 if (IS_REGEXP(searchString)) { |
1014 throw MakeTypeError(kFirstArgumentNotRegExp, "String.prototype.includes"); | 1014 throw MakeTypeError(kFirstArgumentNotRegExp, "String.prototype.includes"); |
1015 } | 1015 } |
1016 | 1016 |
1017 var ss = TO_STRING_INLINE(searchString); | 1017 var ss = TO_STRING_INLINE(searchString); |
1018 var pos = 0; | 1018 var pos = 0; |
1019 if (%_ArgumentsLength() > 1) { | 1019 if (%_ArgumentsLength() > 1) { |
1020 pos = %_Arguments(1); // position | 1020 pos = %_Arguments(1); // position |
1021 pos = $toInteger(pos); | 1021 pos = ToInteger(pos); |
1022 } | 1022 } |
1023 | 1023 |
1024 var s_len = s.length; | 1024 var s_len = s.length; |
1025 var start = $min($max(pos, 0), s_len); | 1025 var start = $min($max(pos, 0), s_len); |
1026 var ss_len = ss.length; | 1026 var ss_len = ss.length; |
1027 if (ss_len + start > s_len) { | 1027 if (ss_len + start > s_len) { |
1028 return false; | 1028 return false; |
1029 } | 1029 } |
1030 | 1030 |
1031 return %StringIndexOf(s, ss, start) !== -1; | 1031 return %StringIndexOf(s, ss, start) !== -1; |
(...skipping 24 matching lines...) Expand all Loading... |
1056 | 1056 |
1057 // ES6 Draft 05-22-2014, section 21.1.2.2 | 1057 // ES6 Draft 05-22-2014, section 21.1.2.2 |
1058 function StringFromCodePoint(_) { // length = 1 | 1058 function StringFromCodePoint(_) { // length = 1 |
1059 var code; | 1059 var code; |
1060 var length = %_ArgumentsLength(); | 1060 var length = %_ArgumentsLength(); |
1061 var index; | 1061 var index; |
1062 var result = ""; | 1062 var result = ""; |
1063 for (index = 0; index < length; index++) { | 1063 for (index = 0; index < length; index++) { |
1064 code = %_Arguments(index); | 1064 code = %_Arguments(index); |
1065 if (!%_IsSmi(code)) { | 1065 if (!%_IsSmi(code)) { |
1066 code = $toNumber(code); | 1066 code = ToNumber(code); |
1067 } | 1067 } |
1068 if (code < 0 || code > 0x10FFFF || code !== TO_INTEGER(code)) { | 1068 if (code < 0 || code > 0x10FFFF || code !== TO_INTEGER(code)) { |
1069 throw MakeRangeError(kInvalidCodePoint, code); | 1069 throw MakeRangeError(kInvalidCodePoint, code); |
1070 } | 1070 } |
1071 if (code <= 0xFFFF) { | 1071 if (code <= 0xFFFF) { |
1072 result += %_StringCharFromCode(code); | 1072 result += %_StringCharFromCode(code); |
1073 } else { | 1073 } else { |
1074 code -= 0x10000; | 1074 code -= 0x10000; |
1075 result += %_StringCharFromCode((code >>> 10) & 0x3FF | 0xD800); | 1075 result += %_StringCharFromCode((code >>> 10) & 0x3FF | 0xD800); |
1076 result += %_StringCharFromCode(code & 0x3FF | 0xDC00); | 1076 result += %_StringCharFromCode(code & 0x3FF | 0xDC00); |
1077 } | 1077 } |
1078 } | 1078 } |
1079 return result; | 1079 return result; |
1080 } | 1080 } |
1081 | 1081 |
1082 | 1082 |
1083 // ------------------------------------------------------------------- | 1083 // ------------------------------------------------------------------- |
1084 // String methods related to templates | 1084 // String methods related to templates |
1085 | 1085 |
1086 // ES6 Draft 03-17-2015, section 21.1.2.4 | 1086 // ES6 Draft 03-17-2015, section 21.1.2.4 |
1087 function StringRaw(callSite) { | 1087 function StringRaw(callSite) { |
1088 // TODO(caitp): Use rest parameters when implemented | 1088 // TODO(caitp): Use rest parameters when implemented |
1089 var numberOfSubstitutions = %_ArgumentsLength(); | 1089 var numberOfSubstitutions = %_ArgumentsLength(); |
1090 var cooked = $toObject(callSite); | 1090 var cooked = ToObject(callSite); |
1091 var raw = $toObject(cooked.raw); | 1091 var raw = ToObject(cooked.raw); |
1092 var literalSegments = $toLength(raw.length); | 1092 var literalSegments = ToLength(raw.length); |
1093 if (literalSegments <= 0) return ""; | 1093 if (literalSegments <= 0) return ""; |
1094 | 1094 |
1095 var result = $toString(raw[0]); | 1095 var result = ToString(raw[0]); |
1096 | 1096 |
1097 for (var i = 1; i < literalSegments; ++i) { | 1097 for (var i = 1; i < literalSegments; ++i) { |
1098 if (i < numberOfSubstitutions) { | 1098 if (i < numberOfSubstitutions) { |
1099 result += $toString(%_Arguments(i)); | 1099 result += ToString(%_Arguments(i)); |
1100 } | 1100 } |
1101 result += $toString(raw[i]); | 1101 result += ToString(raw[i]); |
1102 } | 1102 } |
1103 | 1103 |
1104 return result; | 1104 return result; |
1105 } | 1105 } |
1106 | 1106 |
1107 // ------------------------------------------------------------------- | 1107 // ------------------------------------------------------------------- |
1108 | 1108 |
1109 // Set the String function and constructor. | 1109 // Set the String function and constructor. |
1110 %SetCode(GlobalString, StringConstructor); | 1110 %SetCode(GlobalString, StringConstructor); |
1111 %FunctionSetPrototype(GlobalString, new GlobalString()); | 1111 %FunctionSetPrototype(GlobalString, new GlobalString()); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1165 "strike", StringStrike, | 1165 "strike", StringStrike, |
1166 "sub", StringSub, | 1166 "sub", StringSub, |
1167 "sup", StringSup | 1167 "sup", StringSup |
1168 ]); | 1168 ]); |
1169 | 1169 |
1170 $stringCharAt = StringCharAtJS; | 1170 $stringCharAt = StringCharAtJS; |
1171 $stringIndexOf = StringIndexOfJS; | 1171 $stringIndexOf = StringIndexOfJS; |
1172 $stringSubstring = StringSubstring; | 1172 $stringSubstring = StringSubstring; |
1173 | 1173 |
1174 })(); | 1174 })(); |
OLD | NEW |