/** * maybeGarbageCollectAsync * * It might garbage collect, it might not. If it doesn't, that's ok. */ self.maybeGarbageCollectAsync = garbageCollect; /** * maybeGarbageCollectKeptObjectsAsync * * Based on "asyncGCDeref" in https://github.com/tc39/test262/blob/master/harness/async-gc.js * * @return {Promise} Resolves to a trigger if ClearKeptObjects * exists to provide one */ async function maybeGarbageCollectKeptObjectsAsync() { let trigger; if (typeof ClearKeptObjects === 'function') { trigger = ClearKeptObjects(); } await maybeGarbageCollectAsync(); return trigger; } /** * maybeGarbageCollectAndCleanupAsync * * Based on "asyncGC" in https://github.com/tc39/test262/blob/master/harness/async-gc.js * * @return {undefined} */ async function maybeGarbageCollectAndCleanupAsync(...targets) { let finalizationRegistry = new FinalizationRegistry(() => {}); let length = targets.length; for (let target of targets) { finalizationRegistry.register(target, 'target'); target = null; } targets = null; await 'tick'; await maybeGarbageCollectKeptObjectsAsync(); let names = []; finalizationRegistry.cleanupSome(name => names.push(name)); if (names.length !== length) { throw maybeGarbageCollectAndCleanupAsync.NOT_COLLECTED; } } maybeGarbageCollectAndCleanupAsync.NOT_COLLECTED = Symbol('Object was not collected'); /** * resolveGarbageCollection * * Based on "resolveAsyncGC" in https://github.com/tc39/test262/blob/master/harness/async-gc.js * * @param {Error} error An error object. * @return {undefined} */ function resolveGarbageCollection(error) { if (error && error !== maybeGarbageCollectAndCleanupAsync.NOT_COLLECTED) { throw error; } }