Bug 1885489 - Part 5: Add SnapshotIterator::readInt32(). r=iain
[gecko.git] / js / src / builtin / Utilities.js
blobdad4e26bb9289d26d43ae5c310af171b197641c9
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "SelfHostingDefines.h"
7 // Assertions and debug printing, defined here instead of in the header above
8 // to make `assert` invisible to C++.
9 #ifdef DEBUG
10 #define assert(b, info) \
11   do { \
12     if (!(b)) { \
13       AssertionFailed(__FILE__ + ":" + __LINE__ + ": " + info) \
14     } \
15   } while (false)
16 #define dbg(msg) \
17   do { \
18     DumpMessage(callFunction(std_Array_pop, \
19                              StringSplitString(__FILE__, '/')) + \
20                 '#' + __LINE__ + ': ' + msg) \
21   } while (false)
22 #else
23 #define assert(b, info) ; // Elided assertion.
24 #define dbg(msg) ; // Elided debugging output.
25 #endif
27 // All C++-implemented standard builtins library functions used in self-hosted
28 // code are installed via the std_functions JSFunctionSpec[] in
29 // SelfHosting.cpp.
31 /********** Specification types **********/
33 // A "Record" is an internal type used in the ECMAScript spec to define a struct
34 // made up of key / values. It is never exposed to user script, but we use a
35 // simple Object (with null prototype) as a convenient implementation.
36 function new_Record() {
37   return std_Object_create(null);
40 /********** Abstract operations defined in ECMAScript Language Specification **********/
42 /* Spec: ECMAScript Language Specification, 5.1 edition, 9.2 and 11.4.9 */
43 function ToBoolean(v) {
44   return !!v;
47 /* Spec: ECMAScript Language Specification, 5.1 edition, 9.3 and 11.4.6 */
48 function ToNumber(v) {
49   return +v;
52 // ES2017 draft rev aebf014403a3e641fb1622aec47c40f051943527
53 // 7.2.10 SameValueZero ( x, y )
54 function SameValueZero(x, y) {
55   return x === y || (x !== x && y !== y);
58 // ES 2017 draft (April 6, 2016) 7.3.9
59 function GetMethod(V, P) {
60   // Step 1.
61   assert(IsPropertyKey(P), "Invalid property key");
63   // Step 2.
64   var func = V[P];
66   // Step 3.
67   if (IsNullOrUndefined(func)) {
68     return undefined;
69   }
71   // Step 4.
72   if (!IsCallable(func)) {
73     ThrowTypeError(JSMSG_NOT_FUNCTION, typeof func);
74   }
76   // Step 5.
77   return func;
80 /* Spec: ECMAScript Draft, 6th edition Dec 24, 2014, 7.2.7 */
81 function IsPropertyKey(argument) {
82   var type = typeof argument;
83   return type === "string" || type === "symbol";
86 #define TO_PROPERTY_KEY(name) \
87 (typeof name !== "string" && typeof name !== "number" && typeof name !== "symbol" ? ToPropertyKey(name) : name)
89 // ES 2016 draft Mar 25, 2016 7.3.20.
90 function SpeciesConstructor(obj, defaultConstructor) {
91   // Step 1.
92   assert(IsObject(obj), "not passed an object");
94   // Step 2.
95   var ctor = obj.constructor;
97   // Step 3.
98   if (ctor === undefined) {
99     return defaultConstructor;
100   }
102   // Step 4.
103   if (!IsObject(ctor)) {
104     ThrowTypeError(JSMSG_OBJECT_REQUIRED, "object's 'constructor' property");
105   }
107   // Steps 5.
108   var s = ctor[GetBuiltinSymbol("species")];
110   // Step 6.
111   if (IsNullOrUndefined(s)) {
112     return defaultConstructor;
113   }
115   // Step 7.
116   if (IsConstructor(s)) {
117     return s;
118   }
120   // Step 8.
121   ThrowTypeError(
122     JSMSG_NOT_CONSTRUCTOR,
123     "@@species property of object's constructor"
124   );
127 function GetTypeError(...args) {
128   try {
129     FUN_APPLY(ThrowTypeError, undefined, args);
130   } catch (e) {
131     return e;
132   }
133   assert(false, "the catch block should've returned from this function.");
136 function GetAggregateError(...args) {
137   try {
138     FUN_APPLY(ThrowAggregateError, undefined, args);
139   } catch (e) {
140     return e;
141   }
142   assert(false, "the catch block should've returned from this function.");
145 function GetInternalError(...args) {
146   try {
147     FUN_APPLY(ThrowInternalError, undefined, args);
148   } catch (e) {
149     return e;
150   }
151   assert(false, "the catch block should've returned from this function.");
154 // To be used when a function is required but calling it shouldn't do anything.
155 function NullFunction() {}
157 // ES2019 draft rev 4c2df13f4194057f09b920ee88712e5a70b1a556
158 // 7.3.23 CopyDataProperties (target, source, excludedItems)
159 function CopyDataProperties(target, source, excludedItems) {
160   // Step 1.
161   assert(IsObject(target), "target is an object");
163   // Step 2.
164   assert(IsObject(excludedItems), "excludedItems is an object");
166   // Steps 3 and 7.
167   if (IsNullOrUndefined(source)) {
168     return;
169   }
171   // Step 4.
172   var from = ToObject(source);
174   // Step 5.
175   var keys = CopyDataPropertiesOrGetOwnKeys(target, from, excludedItems);
177   // Return if we copied all properties in native code.
178   if (keys === null) {
179     return;
180   }
182   // Step 6.
183   for (var index = 0; index < keys.length; index++) {
184     var key = keys[index];
186     // We abbreviate this by calling propertyIsEnumerable which is faster
187     // and returns false for not defined properties.
188     if (
189       !hasOwn(key, excludedItems) &&
190       callFunction(std_Object_propertyIsEnumerable, from, key)
191     ) {
192       DefineDataProperty(target, key, from[key]);
193     }
194   }
196   // Step 7 (Return).
199 // ES2019 draft rev 4c2df13f4194057f09b920ee88712e5a70b1a556
200 // 7.3.23 CopyDataProperties (target, source, excludedItems)
201 function CopyDataPropertiesUnfiltered(target, source) {
202   // Step 1.
203   assert(IsObject(target), "target is an object");
205   // Step 2 (Not applicable).
207   // Steps 3 and 7.
208   if (IsNullOrUndefined(source)) {
209     return;
210   }
212   // Step 4.
213   var from = ToObject(source);
215   // Step 5.
216   var keys = CopyDataPropertiesOrGetOwnKeys(target, from, null);
218   // Return if we copied all properties in native code.
219   if (keys === null) {
220     return;
221   }
223   // Step 6.
224   for (var index = 0; index < keys.length; index++) {
225     var key = keys[index];
227     // We abbreviate this by calling propertyIsEnumerable which is faster
228     // and returns false for not defined properties.
229     if (callFunction(std_Object_propertyIsEnumerable, from, key)) {
230       DefineDataProperty(target, key, from[key]);
231     }
232   }
234   // Step 7 (Return).
237 /*************************************** Testing functions ***************************************/
238 function outer() {
239   return function inner() {
240     return "foo";
241   };