OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 // This files contains runtime support implemented in JavaScript. | 5 // This files contains runtime support implemented in JavaScript. |
6 | 6 |
7 // CAUTION: Some of the functions specified in this file are called | 7 // CAUTION: Some of the functions specified in this file are called |
8 // directly from compiled code. These are the functions with names in | 8 // directly from compiled code. These are the functions with names in |
9 // ALL CAPS. The compiled code passes the first argument in 'this'. | 9 // ALL CAPS. The compiled code passes the first argument in 'this'. |
10 | 10 |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 EQUALS = function EQUALS(y) { | 95 EQUALS = function EQUALS(y) { |
96 if (IS_STRING(this) && IS_STRING(y)) return %StringEquals(this, y); | 96 if (IS_STRING(this) && IS_STRING(y)) return %StringEquals(this, y); |
97 var x = this; | 97 var x = this; |
98 | 98 |
99 while (true) { | 99 while (true) { |
100 if (IS_NUMBER(x)) { | 100 if (IS_NUMBER(x)) { |
101 while (true) { | 101 while (true) { |
102 if (IS_NUMBER(y)) return %NumberEquals(x, y); | 102 if (IS_NUMBER(y)) return %NumberEquals(x, y); |
103 if (IS_NULL_OR_UNDEFINED(y)) return 1; // not equal | 103 if (IS_NULL_OR_UNDEFINED(y)) return 1; // not equal |
104 if (!IS_SPEC_OBJECT(y)) { | 104 if (!IS_SPEC_OBJECT(y)) { |
105 if (IS_SYMBOL(y) || IS_SIMD_OBJECT(y)) return 1; // not equal | 105 if (IS_SYMBOL(y) || IS_SIMD_VALUE(y)) return 1; // not equal |
106 // String or boolean. | 106 // String or boolean. |
107 return %NumberEquals(x, %$toNumber(y)); | 107 return %NumberEquals(x, %$toNumber(y)); |
108 } | 108 } |
109 y = %$toPrimitive(y, NO_HINT); | 109 y = %$toPrimitive(y, NO_HINT); |
110 } | 110 } |
111 } else if (IS_STRING(x)) { | 111 } else if (IS_STRING(x)) { |
112 while (true) { | 112 while (true) { |
113 if (IS_STRING(y)) return %StringEquals(x, y); | 113 if (IS_STRING(y)) return %StringEquals(x, y); |
114 if (IS_NUMBER(y)) return %NumberEquals(%$toNumber(x), y); | 114 if (IS_NUMBER(y)) return %NumberEquals(%$toNumber(x), y); |
115 if (IS_BOOLEAN(y)) return %NumberEquals(%$toNumber(x), %$toNumber(y)); | 115 if (IS_BOOLEAN(y)) return %NumberEquals(%$toNumber(x), %$toNumber(y)); |
116 if (IS_NULL_OR_UNDEFINED(y)) return 1; // not equal | 116 if (IS_NULL_OR_UNDEFINED(y)) return 1; // not equal |
117 if (IS_SYMBOL(y) || IS_SIMD_OBJECT(y)) return 1; // not equal | 117 if (IS_SYMBOL(y) || IS_SIMD_VALUE(y)) return 1; // not equal |
118 y = %$toPrimitive(y, NO_HINT); | 118 y = %$toPrimitive(y, NO_HINT); |
119 } | 119 } |
120 } else if (IS_SYMBOL(x)) { | 120 } else if (IS_SYMBOL(x)) { |
121 if (IS_SYMBOL(y)) return %_ObjectEquals(x, y) ? 0 : 1; | 121 if (IS_SYMBOL(y)) return %_ObjectEquals(x, y) ? 0 : 1; |
122 return 1; // not equal | 122 return 1; // not equal |
123 } else if (IS_BOOLEAN(x)) { | 123 } else if (IS_BOOLEAN(x)) { |
124 if (IS_BOOLEAN(y)) return %_ObjectEquals(x, y) ? 0 : 1; | 124 if (IS_BOOLEAN(y)) return %_ObjectEquals(x, y) ? 0 : 1; |
125 if (IS_NULL_OR_UNDEFINED(y)) return 1; | 125 if (IS_NULL_OR_UNDEFINED(y)) return 1; |
126 if (IS_NUMBER(y)) return %NumberEquals(%$toNumber(x), y); | 126 if (IS_NUMBER(y)) return %NumberEquals(%$toNumber(x), y); |
127 if (IS_STRING(y)) return %NumberEquals(%$toNumber(x), %$toNumber(y)); | 127 if (IS_STRING(y)) return %NumberEquals(%$toNumber(x), %$toNumber(y)); |
128 if (IS_SYMBOL(y) || IS_SIMD_OBJECT(y)) return 1; // not equal | 128 if (IS_SYMBOL(y) || IS_SIMD_VALUE(y)) return 1; // not equal |
129 // y is object. | 129 // y is object. |
130 x = %$toNumber(x); | 130 x = %$toNumber(x); |
131 y = %$toPrimitive(y, NO_HINT); | 131 y = %$toPrimitive(y, NO_HINT); |
132 } else if (IS_NULL_OR_UNDEFINED(x)) { | 132 } else if (IS_NULL_OR_UNDEFINED(x)) { |
133 return IS_NULL_OR_UNDEFINED(y) ? 0 : 1; | 133 return IS_NULL_OR_UNDEFINED(y) ? 0 : 1; |
134 } else if (IS_SIMD_OBJECT(x)) { | 134 } else if (IS_SIMD_VALUE(x)) { |
135 return %SimdEquals(x, y); | 135 return %SimdEquals(x, y); |
136 } else { | 136 } else { |
137 // x is an object. | 137 // x is an object. |
138 if (IS_SPEC_OBJECT(y)) return %_ObjectEquals(x, y) ? 0 : 1; | 138 if (IS_SPEC_OBJECT(y)) return %_ObjectEquals(x, y) ? 0 : 1; |
139 if (IS_NULL_OR_UNDEFINED(y)) return 1; // not equal | 139 if (IS_NULL_OR_UNDEFINED(y)) return 1; // not equal |
140 if (IS_BOOLEAN(y)) { | 140 if (IS_BOOLEAN(y)) { |
141 y = %$toNumber(y); | 141 y = %$toNumber(y); |
142 } else if (IS_SYMBOL(y) || IS_SIMD_OBJECT(y)) { | 142 } else if (IS_SYMBOL(y) || IS_SIMD_VALUE(y)) { |
143 return 1; // not equal | 143 return 1; // not equal |
144 } | 144 } |
145 x = %$toPrimitive(x, NO_HINT); | 145 x = %$toPrimitive(x, NO_HINT); |
146 } | 146 } |
147 } | 147 } |
148 } | 148 } |
149 | 149 |
150 // ECMA-262, section 11.9.4, page 56. | 150 // ECMA-262, section 11.9.4, page 56. |
151 STRICT_EQUALS = function STRICT_EQUALS(x) { | 151 STRICT_EQUALS = function STRICT_EQUALS(x) { |
152 if (IS_STRING(this)) { | 152 if (IS_STRING(this)) { |
153 if (!IS_STRING(x)) return 1; // not equal | 153 if (!IS_STRING(x)) return 1; // not equal |
154 return %StringEquals(this, x); | 154 return %StringEquals(this, x); |
155 } | 155 } |
156 | 156 |
157 if (IS_NUMBER(this)) { | 157 if (IS_NUMBER(this)) { |
158 if (!IS_NUMBER(x)) return 1; // not equal | 158 if (!IS_NUMBER(x)) return 1; // not equal |
159 return %NumberEquals(this, x); | 159 return %NumberEquals(this, x); |
160 } | 160 } |
161 | 161 |
162 if (IS_SIMD_OBJECT(this)) return %SimdEquals(this, x); | 162 if (IS_SIMD_VALUE(this)) return %SimdEquals(this, x); |
163 | 163 |
164 // If anything else gets here, we just do simple identity check. | 164 // If anything else gets here, we just do simple identity check. |
165 // Objects (including functions), null, undefined and booleans were | 165 // Objects (including functions), null, undefined and booleans were |
166 // checked in the CompareStub, so there should be nothing left. | 166 // checked in the CompareStub, so there should be nothing left. |
167 return %_ObjectEquals(this, x) ? 0 : 1; | 167 return %_ObjectEquals(this, x) ? 0 : 1; |
168 } | 168 } |
169 | 169 |
170 | 170 |
171 // ECMA-262, section 11.8.5, page 53. The 'ncr' parameter is used as | 171 // ECMA-262, section 11.8.5, page 53. The 'ncr' parameter is used as |
172 // the result when either (or both) the operands are NaN. | 172 // the result when either (or both) the operands are NaN. |
(...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
749 ------------------------------------- | 749 ------------------------------------- |
750 */ | 750 */ |
751 | 751 |
752 // ECMA-262, section 9.1, page 30. Use null/undefined for no hint, | 752 // ECMA-262, section 9.1, page 30. Use null/undefined for no hint, |
753 // (1) for number hint, and (2) for string hint. | 753 // (1) for number hint, and (2) for string hint. |
754 function ToPrimitive(x, hint) { | 754 function ToPrimitive(x, hint) { |
755 // Fast case check. | 755 // Fast case check. |
756 if (IS_STRING(x)) return x; | 756 if (IS_STRING(x)) return x; |
757 // Normal behavior. | 757 // Normal behavior. |
758 if (!IS_SPEC_OBJECT(x)) return x; | 758 if (!IS_SPEC_OBJECT(x)) return x; |
759 if (IS_SIMD_OBJECT(x)) return x; | 759 if (IS_SIMD_VALUE(x)) return x; |
760 if (hint == NO_HINT) hint = (IS_DATE(x)) ? STRING_HINT : NUMBER_HINT; | 760 if (hint == NO_HINT) hint = (IS_DATE(x)) ? STRING_HINT : NUMBER_HINT; |
761 return (hint == NUMBER_HINT) ? DefaultNumber(x) : DefaultString(x); | 761 return (hint == NUMBER_HINT) ? DefaultNumber(x) : DefaultString(x); |
762 } | 762 } |
763 | 763 |
764 | 764 |
765 // ECMA-262, section 9.2, page 30 | 765 // ECMA-262, section 9.2, page 30 |
766 function ToBoolean(x) { | 766 function ToBoolean(x) { |
767 if (IS_BOOLEAN(x)) return x; | 767 if (IS_BOOLEAN(x)) return x; |
768 if (IS_STRING(x)) return x.length != 0; | 768 if (IS_STRING(x)) return x.length != 0; |
769 if (x == null) return false; | 769 if (x == null) return false; |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
855 // ES5, section 9.12 | 855 // ES5, section 9.12 |
856 function SameValue(x, y) { | 856 function SameValue(x, y) { |
857 if (typeof x != typeof y) return false; | 857 if (typeof x != typeof y) return false; |
858 if (IS_NUMBER(x)) { | 858 if (IS_NUMBER(x)) { |
859 if (NUMBER_IS_NAN(x) && NUMBER_IS_NAN(y)) return true; | 859 if (NUMBER_IS_NAN(x) && NUMBER_IS_NAN(y)) return true; |
860 // x is +0 and y is -0 or vice versa. | 860 // x is +0 and y is -0 or vice versa. |
861 if (x === 0 && y === 0 && %_IsMinusZero(x) != %_IsMinusZero(y)) { | 861 if (x === 0 && y === 0 && %_IsMinusZero(x) != %_IsMinusZero(y)) { |
862 return false; | 862 return false; |
863 } | 863 } |
864 } | 864 } |
865 if (IS_SIMD_OBJECT(x)) return %SimdSameValue(x, y); | 865 if (IS_SIMD_VALUE(x)) return %SimdSameValue(x, y); |
866 return x === y; | 866 return x === y; |
867 } | 867 } |
868 | 868 |
869 | 869 |
870 // ES6, section 7.2.4 | 870 // ES6, section 7.2.4 |
871 function SameValueZero(x, y) { | 871 function SameValueZero(x, y) { |
872 if (typeof x != typeof y) return false; | 872 if (typeof x != typeof y) return false; |
873 if (IS_NUMBER(x)) { | 873 if (IS_NUMBER(x)) { |
874 if (NUMBER_IS_NAN(x) && NUMBER_IS_NAN(y)) return true; | 874 if (NUMBER_IS_NAN(x) && NUMBER_IS_NAN(y)) return true; |
875 } | 875 } |
876 if (IS_SIMD_OBJECT(x)) return %SimdSameValueZero(x, y); | 876 if (IS_SIMD_VALUE(x)) return %SimdSameValueZero(x, y); |
877 return x === y; | 877 return x === y; |
878 } | 878 } |
879 | 879 |
880 | 880 |
881 function ConcatIterableToArray(target, iterable) { | 881 function ConcatIterableToArray(target, iterable) { |
882 var index = target.length; | 882 var index = target.length; |
883 for (var element of iterable) { | 883 for (var element of iterable) { |
884 %AddElement(target, index++, element); | 884 %AddElement(target, index++, element); |
885 } | 885 } |
886 return target; | 886 return target; |
(...skipping 23 matching lines...) Expand all Loading... |
910 return ToBoolean(spreadable); | 910 return ToBoolean(spreadable); |
911 } | 911 } |
912 | 912 |
913 | 913 |
914 // ECMA-262, section 8.6.2.6, page 28. | 914 // ECMA-262, section 8.6.2.6, page 28. |
915 function DefaultNumber(x) { | 915 function DefaultNumber(x) { |
916 var valueOf = x.valueOf; | 916 var valueOf = x.valueOf; |
917 if (IS_SPEC_FUNCTION(valueOf)) { | 917 if (IS_SPEC_FUNCTION(valueOf)) { |
918 var v = %_CallFunction(x, valueOf); | 918 var v = %_CallFunction(x, valueOf); |
919 if (IS_SYMBOL(v)) throw MakeTypeError(kSymbolToNumber); | 919 if (IS_SYMBOL(v)) throw MakeTypeError(kSymbolToNumber); |
920 if (IS_SIMD_OBJECT(x)) throw MakeTypeError(kSimdToNumber); | 920 if (IS_SIMD_VALUE(x)) throw MakeTypeError(kSimdToNumber); |
921 if (IsPrimitive(v)) return v; | 921 if (IsPrimitive(v)) return v; |
922 } | 922 } |
923 var toString = x.toString; | 923 var toString = x.toString; |
924 if (IS_SPEC_FUNCTION(toString)) { | 924 if (IS_SPEC_FUNCTION(toString)) { |
925 var s = %_CallFunction(x, toString); | 925 var s = %_CallFunction(x, toString); |
926 if (IsPrimitive(s)) return s; | 926 if (IsPrimitive(s)) return s; |
927 } | 927 } |
928 throw MakeTypeError(kCannotConvertToPrimitive); | 928 throw MakeTypeError(kCannotConvertToPrimitive); |
929 } | 929 } |
930 | 930 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
977 $toInteger = ToInteger; | 977 $toInteger = ToInteger; |
978 $toLength = ToLength; | 978 $toLength = ToLength; |
979 $toName = ToName; | 979 $toName = ToName; |
980 $toNumber = ToNumber; | 980 $toNumber = ToNumber; |
981 $toPositiveInteger = ToPositiveInteger; | 981 $toPositiveInteger = ToPositiveInteger; |
982 $toPrimitive = ToPrimitive; | 982 $toPrimitive = ToPrimitive; |
983 $toString = ToString; | 983 $toString = ToString; |
984 $toUint32 = ToUint32; | 984 $toUint32 = ToUint32; |
985 | 985 |
986 }) | 986 }) |
OLD | NEW |