blob: 0c0a7925b9e16350907e3287a388b37b3ec2f9bf [file] [log] [blame]
Ben Murdoch014dc512016-03-22 12:00:34 +00001// 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
3// found in the LICENSE file.
4
5(function(global, utils) {
6
7%CheckIsBootstrapping();
8
9// ----------------------------------------------------------------------------
10// Imports
11
Ben Murdoch014dc512016-03-22 12:00:34 +000012var GlobalNumber = global.Number;
13var GlobalObject = global.Object;
Ben Murdoch014dc512016-03-22 12:00:34 +000014var iteratorSymbol = utils.ImportNow("iterator_symbol");
Ben Murdoch014dc512016-03-22 12:00:34 +000015var NaN = %GetRootNaN();
16var ObjectToString = utils.ImportNow("object_to_string");
Ben Murdoch014dc512016-03-22 12:00:34 +000017
18// ----------------------------------------------------------------------------
19
20
21// ES6 18.2.3 isNaN(number)
22function GlobalIsNaN(number) {
23 number = TO_NUMBER(number);
24 return NUMBER_IS_NAN(number);
25}
26
27
28// ES6 18.2.2 isFinite(number)
29function GlobalIsFinite(number) {
30 number = TO_NUMBER(number);
31 return NUMBER_IS_FINITE(number);
32}
33
34
35// ES6 18.2.5 parseInt(string, radix)
36function GlobalParseInt(string, radix) {
37 if (IS_UNDEFINED(radix) || radix === 10 || radix === 0) {
38 // Some people use parseInt instead of Math.floor. This
39 // optimization makes parseInt on a Smi 12 times faster (60ns
40 // vs 800ns). The following optimization makes parseInt on a
41 // non-Smi number 9 times faster (230ns vs 2070ns). Together
42 // they make parseInt on a string 1.4% slower (274ns vs 270ns).
43 if (%_IsSmi(string)) return string;
44 if (IS_NUMBER(string) &&
45 ((0.01 < string && string < 1e9) ||
46 (-1e9 < string && string < -0.01))) {
47 // Truncate number.
48 return string | 0;
49 }
50 string = TO_STRING(string);
51 radix = radix | 0;
52 } else {
53 // The spec says ToString should be evaluated before ToInt32.
54 string = TO_STRING(string);
55 radix = TO_INT32(radix);
56 if (!(radix == 0 || (2 <= radix && radix <= 36))) {
57 return NaN;
58 }
59 }
60
61 if (%_HasCachedArrayIndex(string) &&
62 (radix == 0 || radix == 10)) {
63 return %_GetCachedArrayIndex(string);
64 }
65 return %StringParseInt(string, radix);
66}
67
68
69// ES6 18.2.4 parseFloat(string)
70function GlobalParseFloat(string) {
71 // 1. Let inputString be ? ToString(string).
72 string = TO_STRING(string);
73 if (%_HasCachedArrayIndex(string)) return %_GetCachedArrayIndex(string);
74 return %StringParseFloat(string);
75}
76
77
78// ----------------------------------------------------------------------------
79
80// Set up global object.
81var attributes = DONT_ENUM | DONT_DELETE | READ_ONLY;
82
83utils.InstallConstants(global, [
84 // ES6 18.1.1
85 "Infinity", INFINITY,
86 // ES6 18.1.2
87 "NaN", NaN,
88 // ES6 18.1.3
89 "undefined", UNDEFINED,
90]);
91
92// Set up non-enumerable function on the global object.
93utils.InstallFunctions(global, DONT_ENUM, [
94 "isNaN", GlobalIsNaN,
95 "isFinite", GlobalIsFinite,
96 "parseInt", GlobalParseInt,
97 "parseFloat", GlobalParseFloat,
98]);
99
100
101// ----------------------------------------------------------------------------
102// Object
103
104// ES6 19.1.3.5 Object.prototype.toLocaleString([reserved1 [,reserved2]])
105function ObjectToLocaleString() {
106 CHECK_OBJECT_COERCIBLE(this, "Object.prototype.toLocaleString");
107 return this.toString();
108}
109
110
111// ES6 19.1.3.7 Object.prototype.valueOf()
112function ObjectValueOf() {
113 return TO_OBJECT(this);
114}
115
116
Ben Murdoch014dc512016-03-22 12:00:34 +0000117// ES6 19.1.3.3 Object.prototype.isPrototypeOf(V)
118function ObjectIsPrototypeOf(V) {
119 if (!IS_RECEIVER(V)) return false;
120 var O = TO_OBJECT(this);
121 return %HasInPrototypeChain(V, O);
122}
123
124
Ben Murdoch014dc512016-03-22 12:00:34 +0000125// ES6 7.3.9
126function GetMethod(obj, p) {
127 var func = obj[p];
128 if (IS_NULL_OR_UNDEFINED(func)) return UNDEFINED;
129 if (IS_CALLABLE(func)) return func;
Ben Murdochf91f0612016-11-29 16:50:11 +0000130 throw %make_type_error(kCalledNonCallable, typeof func);
Ben Murdoch014dc512016-03-22 12:00:34 +0000131}
132
Ben Murdoch014dc512016-03-22 12:00:34 +0000133// ES6 section 19.1.2.18.
134function ObjectSetPrototypeOf(obj, proto) {
135 CHECK_OBJECT_COERCIBLE(obj, "Object.setPrototypeOf");
136
137 if (proto !== null && !IS_RECEIVER(proto)) {
Ben Murdochf91f0612016-11-29 16:50:11 +0000138 throw %make_type_error(kProtoObjectOrNull, proto);
Ben Murdoch014dc512016-03-22 12:00:34 +0000139 }
140
141 if (IS_RECEIVER(obj)) {
142 %SetPrototype(obj, proto);
143 }
144
145 return obj;
146}
147
Ben Murdoch014dc512016-03-22 12:00:34 +0000148// ES6 B.2.2.1.1
149function ObjectGetProto() {
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100150 return %object_get_prototype_of(this);
Ben Murdoch014dc512016-03-22 12:00:34 +0000151}
152
153
154// ES6 B.2.2.1.2
155function ObjectSetProto(proto) {
156 CHECK_OBJECT_COERCIBLE(this, "Object.prototype.__proto__");
157
158 if ((IS_RECEIVER(proto) || IS_NULL(proto)) && IS_RECEIVER(this)) {
159 %SetPrototype(this, proto);
160 }
161}
162
163
164// ES6 19.1.1.1
165function ObjectConstructor(x) {
166 if (GlobalObject != new.target && !IS_UNDEFINED(new.target)) {
167 return this;
168 }
169 if (IS_NULL(x) || IS_UNDEFINED(x)) return {};
170 return TO_OBJECT(x);
171}
172
173
174// ----------------------------------------------------------------------------
175// Object
176
177%SetNativeFlag(GlobalObject);
178%SetCode(GlobalObject, ObjectConstructor);
179
180%AddNamedProperty(GlobalObject.prototype, "constructor", GlobalObject,
181 DONT_ENUM);
182
183// Set up non-enumerable functions on the Object.prototype object.
184utils.InstallFunctions(GlobalObject.prototype, DONT_ENUM, [
185 "toString", ObjectToString,
186 "toLocaleString", ObjectToLocaleString,
187 "valueOf", ObjectValueOf,
Ben Murdoch014dc512016-03-22 12:00:34 +0000188 "isPrototypeOf", ObjectIsPrototypeOf,
Ben Murdochf91f0612016-11-29 16:50:11 +0000189 // propertyIsEnumerable is added in bootstrapper.cc.
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100190 // __defineGetter__ is added in bootstrapper.cc.
191 // __lookupGetter__ is added in bootstrapper.cc.
192 // __defineSetter__ is added in bootstrapper.cc.
193 // __lookupSetter__ is added in bootstrapper.cc.
Ben Murdoch014dc512016-03-22 12:00:34 +0000194]);
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100195utils.InstallGetterSetter(
196 GlobalObject.prototype, "__proto__", ObjectGetProto, ObjectSetProto);
Ben Murdoch014dc512016-03-22 12:00:34 +0000197
198// Set up non-enumerable functions in the Object object.
199utils.InstallFunctions(GlobalObject, DONT_ENUM, [
Ben Murdoch014dc512016-03-22 12:00:34 +0000200 "setPrototypeOf", ObjectSetPrototypeOf,
Ben Murdoch014dc512016-03-22 12:00:34 +0000201 // getOwnPropertySymbols is added in symbol.js.
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100202 // Others are added in bootstrapper.cc.
Ben Murdoch014dc512016-03-22 12:00:34 +0000203]);
204
205
Ben Murdoch014dc512016-03-22 12:00:34 +0000206
207// ----------------------------------------------------------------------------
208// Number
209
Ben Murdoch014dc512016-03-22 12:00:34 +0000210// Harmony isFinite.
211function NumberIsFinite(number) {
212 return IS_NUMBER(number) && NUMBER_IS_FINITE(number);
213}
214
215
216// Harmony isInteger
217function NumberIsInteger(number) {
218 return NumberIsFinite(number) && TO_INTEGER(number) == number;
219}
220
221
222// Harmony isNaN.
223function NumberIsNaN(number) {
224 return IS_NUMBER(number) && NUMBER_IS_NAN(number);
225}
226
227
228// Harmony isSafeInteger
229function NumberIsSafeInteger(number) {
230 if (NumberIsFinite(number)) {
231 var integral = TO_INTEGER(number);
232 if (integral == number) {
Ben Murdochf91f0612016-11-29 16:50:11 +0000233 return -kMaxSafeInteger <= integral && integral <= kMaxSafeInteger;
Ben Murdoch014dc512016-03-22 12:00:34 +0000234 }
235 }
236 return false;
237}
238
239
240// ----------------------------------------------------------------------------
241
Ben Murdoch014dc512016-03-22 12:00:34 +0000242utils.InstallConstants(GlobalNumber, [
243 // ECMA-262 section 15.7.3.1.
244 "MAX_VALUE", 1.7976931348623157e+308,
245 // ECMA-262 section 15.7.3.2.
246 "MIN_VALUE", 5e-324,
247 // ECMA-262 section 15.7.3.3.
248 "NaN", NaN,
249 // ECMA-262 section 15.7.3.4.
250 "NEGATIVE_INFINITY", -INFINITY,
251 // ECMA-262 section 15.7.3.5.
252 "POSITIVE_INFINITY", INFINITY,
253
254 // --- Harmony constants (no spec refs until settled.)
255
Ben Murdochf91f0612016-11-29 16:50:11 +0000256 "MAX_SAFE_INTEGER", 9007199254740991,
257 "MIN_SAFE_INTEGER", -9007199254740991,
258 "EPSILON", 2.220446049250313e-16,
Ben Murdoch014dc512016-03-22 12:00:34 +0000259]);
260
261// Harmony Number constructor additions
262utils.InstallFunctions(GlobalNumber, DONT_ENUM, [
263 "isFinite", NumberIsFinite,
264 "isInteger", NumberIsInteger,
265 "isNaN", NumberIsNaN,
266 "isSafeInteger", NumberIsSafeInteger,
267 "parseInt", GlobalParseInt,
268 "parseFloat", GlobalParseFloat
269]);
270
271%SetForceInlineFlag(NumberIsNaN);
272
273
274// ----------------------------------------------------------------------------
275// Iterator related spec functions.
276
277// ES6 7.4.1 GetIterator(obj, method)
278function GetIterator(obj, method) {
279 if (IS_UNDEFINED(method)) {
280 method = obj[iteratorSymbol];
281 }
282 if (!IS_CALLABLE(method)) {
Ben Murdochf91f0612016-11-29 16:50:11 +0000283 throw %make_type_error(kNotIterable, obj);
Ben Murdoch014dc512016-03-22 12:00:34 +0000284 }
285 var iterator = %_Call(method, obj);
286 if (!IS_RECEIVER(iterator)) {
Ben Murdochf91f0612016-11-29 16:50:11 +0000287 throw %make_type_error(kNotAnIterator, iterator);
Ben Murdoch014dc512016-03-22 12:00:34 +0000288 }
289 return iterator;
290}
291
292// ----------------------------------------------------------------------------
293// Exports
294
295utils.Export(function(to) {
296 to.GetIterator = GetIterator;
297 to.GetMethod = GetMethod;
Ben Murdoch014dc512016-03-22 12:00:34 +0000298 to.IsNaN = GlobalIsNaN;
299 to.NumberIsNaN = NumberIsNaN;
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100300 to.NumberIsInteger = NumberIsInteger;
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100301 to.ObjectHasOwnProperty = GlobalObject.prototype.hasOwnProperty;
Ben Murdoch014dc512016-03-22 12:00:34 +0000302});
303
304%InstallToContext([
305 "object_value_of", ObjectValueOf,
306]);
307
308})