diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /js/src/builtin/Utilities.js | |
parent | Initial commit. (diff) | |
download | thunderbird-upstream.tar.xz thunderbird-upstream.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/builtin/Utilities.js')
-rw-r--r-- | js/src/builtin/Utilities.js | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/js/src/builtin/Utilities.js b/js/src/builtin/Utilities.js new file mode 100644 index 0000000000..dad4e26bb9 --- /dev/null +++ b/js/src/builtin/Utilities.js @@ -0,0 +1,242 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "SelfHostingDefines.h" + +// Assertions and debug printing, defined here instead of in the header above +// to make `assert` invisible to C++. +#ifdef DEBUG +#define assert(b, info) \ + do { \ + if (!(b)) { \ + AssertionFailed(__FILE__ + ":" + __LINE__ + ": " + info) \ + } \ + } while (false) +#define dbg(msg) \ + do { \ + DumpMessage(callFunction(std_Array_pop, \ + StringSplitString(__FILE__, '/')) + \ + '#' + __LINE__ + ': ' + msg) \ + } while (false) +#else +#define assert(b, info) ; // Elided assertion. +#define dbg(msg) ; // Elided debugging output. +#endif + +// All C++-implemented standard builtins library functions used in self-hosted +// code are installed via the std_functions JSFunctionSpec[] in +// SelfHosting.cpp. + +/********** Specification types **********/ + +// A "Record" is an internal type used in the ECMAScript spec to define a struct +// made up of key / values. It is never exposed to user script, but we use a +// simple Object (with null prototype) as a convenient implementation. +function new_Record() { + return std_Object_create(null); +} + +/********** Abstract operations defined in ECMAScript Language Specification **********/ + +/* Spec: ECMAScript Language Specification, 5.1 edition, 9.2 and 11.4.9 */ +function ToBoolean(v) { + return !!v; +} + +/* Spec: ECMAScript Language Specification, 5.1 edition, 9.3 and 11.4.6 */ +function ToNumber(v) { + return +v; +} + +// ES2017 draft rev aebf014403a3e641fb1622aec47c40f051943527 +// 7.2.10 SameValueZero ( x, y ) +function SameValueZero(x, y) { + return x === y || (x !== x && y !== y); +} + +// ES 2017 draft (April 6, 2016) 7.3.9 +function GetMethod(V, P) { + // Step 1. + assert(IsPropertyKey(P), "Invalid property key"); + + // Step 2. + var func = V[P]; + + // Step 3. + if (IsNullOrUndefined(func)) { + return undefined; + } + + // Step 4. + if (!IsCallable(func)) { + ThrowTypeError(JSMSG_NOT_FUNCTION, typeof func); + } + + // Step 5. + return func; +} + +/* Spec: ECMAScript Draft, 6th edition Dec 24, 2014, 7.2.7 */ +function IsPropertyKey(argument) { + var type = typeof argument; + return type === "string" || type === "symbol"; +} + +#define TO_PROPERTY_KEY(name) \ +(typeof name !== "string" && typeof name !== "number" && typeof name !== "symbol" ? ToPropertyKey(name) : name) + +// ES 2016 draft Mar 25, 2016 7.3.20. +function SpeciesConstructor(obj, defaultConstructor) { + // Step 1. + assert(IsObject(obj), "not passed an object"); + + // Step 2. + var ctor = obj.constructor; + + // Step 3. + if (ctor === undefined) { + return defaultConstructor; + } + + // Step 4. + if (!IsObject(ctor)) { + ThrowTypeError(JSMSG_OBJECT_REQUIRED, "object's 'constructor' property"); + } + + // Steps 5. + var s = ctor[GetBuiltinSymbol("species")]; + + // Step 6. + if (IsNullOrUndefined(s)) { + return defaultConstructor; + } + + // Step 7. + if (IsConstructor(s)) { + return s; + } + + // Step 8. + ThrowTypeError( + JSMSG_NOT_CONSTRUCTOR, + "@@species property of object's constructor" + ); +} + +function GetTypeError(...args) { + try { + FUN_APPLY(ThrowTypeError, undefined, args); + } catch (e) { + return e; + } + assert(false, "the catch block should've returned from this function."); +} + +function GetAggregateError(...args) { + try { + FUN_APPLY(ThrowAggregateError, undefined, args); + } catch (e) { + return e; + } + assert(false, "the catch block should've returned from this function."); +} + +function GetInternalError(...args) { + try { + FUN_APPLY(ThrowInternalError, undefined, args); + } catch (e) { + return e; + } + assert(false, "the catch block should've returned from this function."); +} + +// To be used when a function is required but calling it shouldn't do anything. +function NullFunction() {} + +// ES2019 draft rev 4c2df13f4194057f09b920ee88712e5a70b1a556 +// 7.3.23 CopyDataProperties (target, source, excludedItems) +function CopyDataProperties(target, source, excludedItems) { + // Step 1. + assert(IsObject(target), "target is an object"); + + // Step 2. + assert(IsObject(excludedItems), "excludedItems is an object"); + + // Steps 3 and 7. + if (IsNullOrUndefined(source)) { + return; + } + + // Step 4. + var from = ToObject(source); + + // Step 5. + var keys = CopyDataPropertiesOrGetOwnKeys(target, from, excludedItems); + + // Return if we copied all properties in native code. + if (keys === null) { + return; + } + + // Step 6. + for (var index = 0; index < keys.length; index++) { + var key = keys[index]; + + // We abbreviate this by calling propertyIsEnumerable which is faster + // and returns false for not defined properties. + if ( + !hasOwn(key, excludedItems) && + callFunction(std_Object_propertyIsEnumerable, from, key) + ) { + DefineDataProperty(target, key, from[key]); + } + } + + // Step 7 (Return). +} + +// ES2019 draft rev 4c2df13f4194057f09b920ee88712e5a70b1a556 +// 7.3.23 CopyDataProperties (target, source, excludedItems) +function CopyDataPropertiesUnfiltered(target, source) { + // Step 1. + assert(IsObject(target), "target is an object"); + + // Step 2 (Not applicable). + + // Steps 3 and 7. + if (IsNullOrUndefined(source)) { + return; + } + + // Step 4. + var from = ToObject(source); + + // Step 5. + var keys = CopyDataPropertiesOrGetOwnKeys(target, from, null); + + // Return if we copied all properties in native code. + if (keys === null) { + return; + } + + // Step 6. + for (var index = 0; index < keys.length; index++) { + var key = keys[index]; + + // We abbreviate this by calling propertyIsEnumerable which is faster + // and returns false for not defined properties. + if (callFunction(std_Object_propertyIsEnumerable, from, key)) { + DefineDataProperty(target, key, from[key]); + } + } + + // Step 7 (Return). +} + +/*************************************** Testing functions ***************************************/ +function outer() { + return function inner() { + return "foo"; + }; +} |