// Ensure we create Ion ICs to cover IonCacheIRCompiler code paths. setJitCompilerOption("ion.forceinlineCaches", 1); // Ignore unhandled rejections when calling Promise and AsyncFunction methods. ignoreUnhandledRejections(); // Function cloned for each test. function test(v) { for (var i = 0; i < 100; ++i) { // |v.key| is a getter calling a built-in method or accessor. v.key; } } // Add |fn| as a method on |holder| and then call it using |thisValue| as the this-value. function runTest(holder, thisValue, key, fn) { assertEq(typeof fn, "function"); assertEq( holder === thisValue || Object.prototype.isPrototypeOf.call(holder, Object(thisValue)), true, `${String(key)} can be found on thisValue when stored in holder` ); // Add a prefix so we don't overwrite built-in methods. var safeKey = "__" + String(key); Object.defineProperty(holder, safeKey, { get: fn, configurable: true, }); try { var t = Function(`return ${test.toString().replaceAll("key", safeKey)}`)(); t(thisValue); } catch { // Intentionally ignore any errors. } // Also test wrappers of primitive values. if (Object(thisValue) !== thisValue) { try { var t = Function(`return ${test.toString().replaceAll("key", safeKey)}`)(); t(Object(thisValue)); } catch { // Intentionally ignore any errors. } } } // Test all methods and accessors of |object|. function testForEach(object, holder, thisValue) { for (var key of Reflect.ownKeys(object)) { var desc = Reflect.getOwnPropertyDescriptor(object, key); if (typeof desc.value === "function") runTest(holder, thisValue, key, desc.value); if (typeof desc.get === "function") runTest(holder, thisValue, key, desc.get); if (typeof desc.set === "function") runTest(holder, thisValue, key, desc.set); } } var seenProto = new Set(); // Test along the prototype chain of |objectOrPrimitive|. function testProto(objectOrPrimitive) { var proto = Object.getPrototypeOf(objectOrPrimitive); while (proto) { // Install methods on |proto| and then call wih |obj| as the this-value. testForEach(proto, proto, objectOrPrimitive); // Cover all objects on the prototype chain. proto = Reflect.getPrototypeOf(proto); // But skip already seen prototypes to ensure we don't spend too much time on this test. if (seenProto.has(proto)) { break; } seenProto.add(proto); } } // Test constructor of |objectOrPrimitive|. function testConstructor(objectOrPrimitive) { // Install constructor methods on the prototype object and then call with |objectOrPrimitive| // as the this-value. testForEach(obj.constructor, Object.getPrototypeOf(objectOrPrimitive), objectOrPrimitive); } function testSingleton(singleton) { var thisValue = {}; testForEach(singleton, thisValue, thisValue); } for (var obj of [ // Fundamental Objects . {}, Function(), false, Symbol(), new Error(), // Numbers and Dates 0, 0n, new Date(0), // Text Processing "", /(?:)/, // Indexed Collections [], new Int32Array(1), new Uint8Array(1), // Keyed Collections new Map(), new Set(), new WeakMap(), new WeakSet(), // Structured Data new ArrayBuffer(1), new SharedArrayBuffer(1), new DataView(new ArrayBuffer(8)), // Managing Memory new WeakRef({}), new FinalizationRegistry(() => {}), // Control Abstraction Objects new class extends Iterator{}, new Promise(() => {}), (function*(){}).constructor, (async function*(){}).constructor, (async function(){}).constructor, ]) { testProto(obj); testConstructor(obj); } testSingleton(Math); testSingleton(Atomics); testSingleton(JSON); testSingleton(Reflect);