Utilities.js (5377B)
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/. */ 4 5 #include "SelfHostingDefines.h" 6 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 26 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. 30 31 /********** Abstract operations defined in ECMAScript Language Specification **********/ 32 33 // ES 2017 draft (April 6, 2016) 7.3.9 34 function GetMethod(V, P) { 35 // Step 1. 36 assert(IsPropertyKey(P), "Invalid property key"); 37 38 // Step 2. 39 var func = V[P]; 40 41 // Step 3. 42 if (IsNullOrUndefined(func)) { 43 return undefined; 44 } 45 46 // Step 4. 47 if (!IsCallable(func)) { 48 ThrowTypeError(JSMSG_NOT_FUNCTION, typeof func); 49 } 50 51 // Step 5. 52 return func; 53 } 54 55 /* Spec: ECMAScript Draft, 6th edition Dec 24, 2014, 7.2.7 */ 56 function IsPropertyKey(argument) { 57 var type = typeof argument; 58 return type === "string" || type === "symbol"; 59 } 60 61 #define TO_PROPERTY_KEY(name) \ 62 (typeof name !== "string" && typeof name !== "number" && typeof name !== "symbol" ? ToPropertyKey(name) : name) 63 64 // ES 2016 draft Mar 25, 2016 7.3.20. 65 function SpeciesConstructor(obj, defaultConstructor) { 66 // Step 1. 67 assert(IsObject(obj), "not passed an object"); 68 69 // Step 2. 70 var ctor = obj.constructor; 71 72 // Step 3. 73 if (ctor === undefined) { 74 return defaultConstructor; 75 } 76 77 // Step 4. 78 if (!IsObject(ctor)) { 79 ThrowTypeError(JSMSG_OBJECT_REQUIRED, "object's 'constructor' property"); 80 } 81 82 // Steps 5. 83 var s = ctor[GetBuiltinSymbol("species")]; 84 85 // Step 6. 86 if (IsNullOrUndefined(s)) { 87 return defaultConstructor; 88 } 89 90 // Step 7. 91 if (IsConstructor(s)) { 92 return s; 93 } 94 95 // Step 8. 96 ThrowTypeError( 97 JSMSG_NOT_CONSTRUCTOR, 98 "@@species property of object's constructor" 99 ); 100 } 101 102 function GetTypeError(...args) { 103 try { 104 FUN_APPLY(ThrowTypeError, undefined, args); 105 } catch (e) { 106 return e; 107 } 108 assert(false, "the catch block should've returned from this function."); 109 } 110 111 function GetAggregateError(...args) { 112 try { 113 FUN_APPLY(ThrowAggregateError, undefined, args); 114 } catch (e) { 115 return e; 116 } 117 assert(false, "the catch block should've returned from this function."); 118 } 119 120 function GetInternalError(...args) { 121 try { 122 FUN_APPLY(ThrowInternalError, undefined, args); 123 } catch (e) { 124 return e; 125 } 126 assert(false, "the catch block should've returned from this function."); 127 } 128 129 // To be used when a function is required but calling it shouldn't do anything. 130 function NullFunction() {} 131 132 // ES2019 draft rev 4c2df13f4194057f09b920ee88712e5a70b1a556 133 // 7.3.23 CopyDataProperties (target, source, excludedItems) 134 function CopyDataProperties(target, source, excludedItems) { 135 // Step 1. 136 assert(IsObject(target), "target is an object"); 137 138 // Step 2. 139 assert(IsObject(excludedItems), "excludedItems is an object"); 140 141 // Steps 3 and 7. 142 if (IsNullOrUndefined(source)) { 143 return; 144 } 145 146 // Step 4. 147 var from = ToObject(source); 148 149 // Step 5. 150 var keys = CopyDataPropertiesOrGetOwnKeys(target, from, excludedItems); 151 152 // Return if we copied all properties in native code. 153 if (keys === null) { 154 return; 155 } 156 157 // Step 6. 158 for (var index = 0; index < keys.length; index++) { 159 var key = keys[index]; 160 161 // We abbreviate this by calling propertyIsEnumerable which is faster 162 // and returns false for not defined properties. 163 if ( 164 !hasOwn(key, excludedItems) && 165 callFunction(std_Object_propertyIsEnumerable, from, key) 166 ) { 167 DefineDataProperty(target, key, from[key]); 168 } 169 } 170 171 // Step 7 (Return). 172 } 173 174 // ES2019 draft rev 4c2df13f4194057f09b920ee88712e5a70b1a556 175 // 7.3.23 CopyDataProperties (target, source, excludedItems) 176 function CopyDataPropertiesUnfiltered(target, source) { 177 // Step 1. 178 assert(IsObject(target), "target is an object"); 179 180 // Step 2 (Not applicable). 181 182 // Steps 3 and 7. 183 if (IsNullOrUndefined(source)) { 184 return; 185 } 186 187 // Step 4. 188 var from = ToObject(source); 189 190 // Step 5. 191 var keys = CopyDataPropertiesOrGetOwnKeys(target, from, null); 192 193 // Return if we copied all properties in native code. 194 if (keys === null) { 195 return; 196 } 197 198 // Step 6. 199 for (var index = 0; index < keys.length; index++) { 200 var key = keys[index]; 201 202 // We abbreviate this by calling propertyIsEnumerable which is faster 203 // and returns false for not defined properties. 204 if (callFunction(std_Object_propertyIsEnumerable, from, key)) { 205 DefineDataProperty(target, key, from[key]); 206 } 207 } 208 209 // Step 7 (Return). 210 } 211 212 /*************************************** Testing functions ***************************************/ 213 function outer() { 214 return function inner() { 215 return "foo"; 216 }; 217 }