blob: 301d75a391c2391921489830b18733ea96365cc7 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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
3// found in the LICENSE file.
4
5// This files contains runtime support implemented in JavaScript.
6
7// CAUTION: Some of the functions specified in this file are called
8// directly from compiled code. These are the functions with names in
9// ALL CAPS. The compiled code passes the first argument in 'this'.
10
11
12// The following declarations are shared with other native JS files.
13// They are all declared at this one spot to avoid redeclaration errors.
14
15(function(global, utils) {
16
17%CheckIsBootstrapping();
18
19var FLAG_harmony_species;
20var GlobalArray = global.Array;
21var GlobalBoolean = global.Boolean;
22var GlobalString = global.String;
23var MakeRangeError;
24var MakeTypeError;
25var speciesSymbol;
26
27utils.Import(function(from) {
28 MakeRangeError = from.MakeRangeError;
29 MakeTypeError = from.MakeTypeError;
30 speciesSymbol = from.species_symbol;
31});
32
33utils.ImportFromExperimental(function(from) {
34 FLAG_harmony_species = from.FLAG_harmony_species;
35});
36
37// ----------------------------------------------------------------------------
38
39/* -----------------------------
40 - - - H e l p e r s - - -
41 -----------------------------
42*/
43
44function CONCAT_ITERABLE_TO_ARRAY(iterable) {
45 return %concat_iterable_to_array(this, iterable);
46};
47
48
49/* -------------------------------------
50 - - - C o n v e r s i o n s - - -
51 -------------------------------------
52*/
53
54// ES5, section 9.12
55function SameValue(x, y) {
56 if (typeof x != typeof y) return false;
57 if (IS_NUMBER(x)) {
58 if (NUMBER_IS_NAN(x) && NUMBER_IS_NAN(y)) return true;
59 // x is +0 and y is -0 or vice versa.
60 if (x === 0 && y === 0 && %_IsMinusZero(x) != %_IsMinusZero(y)) {
61 return false;
62 }
63 }
64 if (IS_SIMD_VALUE(x)) return %SimdSameValue(x, y);
65 return x === y;
66}
67
68
69// ES6, section 7.2.4
70function SameValueZero(x, y) {
71 if (typeof x != typeof y) return false;
72 if (IS_NUMBER(x)) {
73 if (NUMBER_IS_NAN(x) && NUMBER_IS_NAN(y)) return true;
74 }
75 if (IS_SIMD_VALUE(x)) return %SimdSameValueZero(x, y);
76 return x === y;
77}
78
79
80function ConcatIterableToArray(target, iterable) {
81 var index = target.length;
82 for (var element of iterable) {
83 AddIndexedProperty(target, index++, element);
84 }
85 return target;
86}
87
88
89/* ---------------------------------
90 - - - U t i l i t i e s - - -
91 ---------------------------------
92*/
93
94
95// This function should be called rather than %AddElement in contexts where the
96// argument might not be less than 2**32-1. ES2015 ToLength semantics mean that
97// this is a concern at basically all callsites.
98function AddIndexedProperty(obj, index, value) {
99 if (index === TO_UINT32(index) && index !== kMaxUint32) {
100 %AddElement(obj, index, value);
101 } else {
102 %AddNamedProperty(obj, TO_STRING(index), value, NONE);
103 }
104}
105%SetForceInlineFlag(AddIndexedProperty);
106
107
108function ToPositiveInteger(x, rangeErrorIndex) {
109 var i = TO_INTEGER_MAP_MINUS_ZERO(x);
110 if (i < 0) throw MakeRangeError(rangeErrorIndex);
111 return i;
112}
113
114
115function MaxSimple(a, b) {
116 return a > b ? a : b;
117}
118
119
120function MinSimple(a, b) {
121 return a > b ? b : a;
122}
123
124
125%SetForceInlineFlag(MaxSimple);
126%SetForceInlineFlag(MinSimple);
127
128
129// ES2015 7.3.20
130// For the fallback with --harmony-species off, there are two possible choices:
131// - "conservative": return defaultConstructor
132// - "not conservative": return object.constructor
133// This fallback path is only needed in the transition to ES2015, and the
134// choice is made simply to preserve the previous behavior so that we don't
135// have a three-step upgrade: old behavior, unspecified intermediate behavior,
136// and ES2015.
137// In some cases, we were "conservative" (e.g., ArrayBuffer, RegExp), and in
138// other cases we were "not conservative (e.g., TypedArray, Promise).
139function SpeciesConstructor(object, defaultConstructor, conservative) {
140 if (FLAG_harmony_species) {
141 var constructor = object.constructor;
142 if (IS_UNDEFINED(constructor)) {
143 return defaultConstructor;
144 }
145 if (!IS_RECEIVER(constructor)) {
146 throw MakeTypeError(kConstructorNotReceiver);
147 }
148 var species = constructor[speciesSymbol];
149 if (IS_NULL_OR_UNDEFINED(species)) {
150 return defaultConstructor;
151 }
152 if (%IsConstructor(species)) {
153 return species;
154 }
155 throw MakeTypeError(kSpeciesNotConstructor);
156 } else {
157 return conservative ? defaultConstructor : object.constructor;
158 }
159}
160
161//----------------------------------------------------------------------------
162
163// NOTE: Setting the prototype for Array must take place as early as
164// possible due to code generation for array literals. When
165// generating code for a array literal a boilerplate array is created
166// that is cloned when running the code. It is essential that the
167// boilerplate gets the right prototype.
168%FunctionSetPrototype(GlobalArray, new GlobalArray(0));
169
170// ----------------------------------------------------------------------------
171// Exports
172
173utils.Export(function(to) {
174 to.AddIndexedProperty = AddIndexedProperty;
175 to.MaxSimple = MaxSimple;
176 to.MinSimple = MinSimple;
177 to.SameValue = SameValue;
178 to.SameValueZero = SameValueZero;
179 to.ToPositiveInteger = ToPositiveInteger;
180 to.SpeciesConstructor = SpeciesConstructor;
181});
182
183%InstallToContext([
184 "concat_iterable_to_array_builtin", CONCAT_ITERABLE_TO_ARRAY,
185]);
186
187%InstallToContext([
188 "concat_iterable_to_array", ConcatIterableToArray,
189]);
190
191})