From 966fc118628484a6454c3a0457f1700764f6ca01 Mon Sep 17 00:00:00 2001 From: Shu-yu Guo Date: Fri, 13 Mar 2020 16:43:25 -0700 Subject: [PATCH] Migrate FinalizationRegistry tests to per-item callback API --- harness/async-gc.js | 4 +- .../Symbol.toStringTag.js | 64 ------------ .../next-job-not-active-throws.js | 69 ------------- .../next-length.js | 74 -------------- .../next-missing-internal-throws.js | 90 ----------------- .../next-name.js | 75 -------------- .../next-not-object-throws.js | 89 ----------------- .../next-prop-desc.js | 67 ------------- .../proto.js | 91 ----------------- ...-has-one-chance-to-call-cleanupCallback.js | 64 +++--------- .../cleanupSome/callback-iterator-proto.js | 98 ------------------- .../cleanup-prevented-with-reference.js | 6 +- .../cleanup-prevented-with-unregister.js | 2 +- .../cleanupcallback-iterator-proto.js | 86 ---------------- ...-values.js => holdings-multiple-values.js} | 21 ++-- .../cleanupSome/poisoned-callback-throws.js | 62 ------------ ...up-throws-in-callback.js => reentrancy.js} | 18 ++-- .../cleanupSome/return-undefined-with-gc.js | 38 ++----- .../unregister/unregister-cleaned-up-cell.js | 19 ++-- 19 files changed, 50 insertions(+), 987 deletions(-) delete mode 100644 test/built-ins/FinalizationRegistry/FinalizationRegistryCleanupIteratorPrototype/Symbol.toStringTag.js delete mode 100644 test/built-ins/FinalizationRegistry/FinalizationRegistryCleanupIteratorPrototype/next-job-not-active-throws.js delete mode 100644 test/built-ins/FinalizationRegistry/FinalizationRegistryCleanupIteratorPrototype/next-length.js delete mode 100644 test/built-ins/FinalizationRegistry/FinalizationRegistryCleanupIteratorPrototype/next-missing-internal-throws.js delete mode 100644 test/built-ins/FinalizationRegistry/FinalizationRegistryCleanupIteratorPrototype/next-name.js delete mode 100644 test/built-ins/FinalizationRegistry/FinalizationRegistryCleanupIteratorPrototype/next-not-object-throws.js delete mode 100644 test/built-ins/FinalizationRegistry/FinalizationRegistryCleanupIteratorPrototype/next-prop-desc.js delete mode 100644 test/built-ins/FinalizationRegistry/FinalizationRegistryCleanupIteratorPrototype/proto.js delete mode 100644 test/built-ins/FinalizationRegistry/prototype/cleanupSome/callback-iterator-proto.js delete mode 100644 test/built-ins/FinalizationRegistry/prototype/cleanupSome/cleanupcallback-iterator-proto.js rename test/built-ins/FinalizationRegistry/prototype/cleanupSome/{iterator-holdings-multiple-values.js => holdings-multiple-values.js} (76%) delete mode 100644 test/built-ins/FinalizationRegistry/prototype/cleanupSome/poisoned-callback-throws.js rename test/built-ins/FinalizationRegistry/prototype/cleanupSome/{cleanup-throws-in-callback.js => reentrancy.js} (69%) diff --git a/harness/async-gc.js b/harness/async-gc.js index 8cb7a44b66..8b5787b684 100644 --- a/harness/async-gc.js +++ b/harness/async-gc.js @@ -21,10 +21,10 @@ function asyncGC(...targets) { targets = null; return Promise.resolve('tick').then(() => asyncGCDeref()).then(() => { - var names; + var names = []; // consume iterator to capture names - finalizationRegistry.cleanupSome(iter => { names = [...iter]; }); + finalizationRegistry.cleanupSome(name => { names.push(name); }); if (!names || names.length != length) { throw asyncGC.notCollected; diff --git a/test/built-ins/FinalizationRegistry/FinalizationRegistryCleanupIteratorPrototype/Symbol.toStringTag.js b/test/built-ins/FinalizationRegistry/FinalizationRegistryCleanupIteratorPrototype/Symbol.toStringTag.js deleted file mode 100644 index fdf4786340..0000000000 --- a/test/built-ins/FinalizationRegistry/FinalizationRegistryCleanupIteratorPrototype/Symbol.toStringTag.js +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (C) 2019 Leo Balter. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-properties-of-the-finalization-registry-constructor -description: > - FinalizationRegistryCleanupIteratorPrototype @@toStringTag -info: | - FinalizationRegistry.prototype.cleanupSome ( [ callback ] ) - - 1. Let finalizationRegistry be the this value. - ... - 5. Perform ! CleanupFinalizationRegistry(finalizationRegistry, callback). - ... - - CleanupFinalizationRegistry ( finalizationRegistry [ , callback ] ) - - ... - 3. Let iterator be ! CreateFinalizationRegistryCleanupIterator(finalizationRegistry). - ... - 6. Let result be Call(callback, undefined, « iterator »). - ... - - %FinalizationRegistryCleanupIteratorPrototype% [ @@toStringTag ] - - The initial value of the @@toStringTag property is the String value "FinalizationRegistry Cleanup Iterator". - - This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. -features: [FinalizationRegistry, host-gc-required, Symbol, Symbol.toStringTag] -includes: [async-gc.js, propertyHelper.js] -flags: [async, non-deterministic] ----*/ - -var FinalizationRegistryCleanupIteratorPrototype; -var called = 0; -var finalizationRegistry = new FinalizationRegistry(function() {}); - -function callback(iterator) { - called += 1; - FinalizationRegistryCleanupIteratorPrototype = Object.getPrototypeOf(iterator); -} - -function emptyCells() { - var target = {}; - finalizationRegistry.register(target); - - var prom = asyncGC(target); - target = null; - - return prom; -} - -emptyCells().then(function() { - finalizationRegistry.cleanupSome(callback); - - assert.sameValue(called, 1, 'cleanup successful'); - - verifyProperty(FinalizationRegistryCleanupIteratorPrototype, Symbol.toStringTag, { - value: 'FinalizationRegistry Cleanup Iterator', - writable: false, - enumerable: false, - configurable: true - }); -}).then($DONE, resolveAsyncGC); diff --git a/test/built-ins/FinalizationRegistry/FinalizationRegistryCleanupIteratorPrototype/next-job-not-active-throws.js b/test/built-ins/FinalizationRegistry/FinalizationRegistryCleanupIteratorPrototype/next-job-not-active-throws.js deleted file mode 100644 index 0a95c15732..0000000000 --- a/test/built-ins/FinalizationRegistry/FinalizationRegistryCleanupIteratorPrototype/next-job-not-active-throws.js +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (C) 2019 Leo Balter. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-properties-of-the-finalization-registry-constructor -description: > - Throws a TypeError if [[IsFinalizationRegistryCleanupJobActive]] is false -info: | - FinalizationRegistry.prototype.cleanupSome ( [ callback ] ) - - 1. Let finalizationRegistry be the this value. - ... - 5. Perform ! CleanupFinalizationRegistry(finalizationRegistry, callback). - ... - - CleanupFinalizationRegistry ( finalizationRegistry [ , callback ] ) - - ... - 3. Let iterator be ! CreateFinalizationRegistryCleanupIterator(finalizationRegistry). - ... - 5. Set finalizationRegistry.[[IsFinalizationRegistryCleanupJobActive]] to true. - 6. Let result be Call(callback, undefined, « iterator »). - 7. Set finalizationRegistry.[[IsFinalizationRegistryCleanupJobActive]] to false. - ... - - %FinalizationRegistryCleanupIteratorPrototype%.next ( ) - - 1. Let iterator be the this value. - 2. If Type(iterator) is not Object, throw a TypeError exception. - 3. If iterator does not have a [[FinalizationRegistry]] internal slot, throw a TypeError exception. -features: [FinalizationRegistry, WeakRef, host-gc-required, Symbol] -includes: [async-gc.js] -flags: [async, non-deterministic] ----*/ - -var iter; -var FinalizationRegistryCleanupIteratorPrototype; -var called = 0; -var finalizationRegistry = new FinalizationRegistry(function() {}); - -function callback(iterator) { - called += 1; - iter = iterator; - FinalizationRegistryCleanupIteratorPrototype = Object.getPrototypeOf(iterator); -} - -function emptyCells() { - var target = {}; - finalizationRegistry.register(target, 'target'); - - var prom = asyncGC(target); - target = null; - - return prom; -} - -emptyCells().then(function() { - finalizationRegistry.cleanupSome(callback); - - // Make sure everything is set - assert.sameValue(called, 1, 'cleanup successful'); - assert.sameValue(typeof iter, 'object'); - assert.sameValue(Object.getPrototypeOf(iter), FinalizationRegistryCleanupIteratorPrototype); - - // To the actual assertion - assert.throws(TypeError, function() { - iter.next(); - }, 'Iter should fail if not called during the cleanupSome call'); -}).then($DONE, resolveAsyncGC); diff --git a/test/built-ins/FinalizationRegistry/FinalizationRegistryCleanupIteratorPrototype/next-length.js b/test/built-ins/FinalizationRegistry/FinalizationRegistryCleanupIteratorPrototype/next-length.js deleted file mode 100644 index 449f700dec..0000000000 --- a/test/built-ins/FinalizationRegistry/FinalizationRegistryCleanupIteratorPrototype/next-length.js +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (C) 2019 Leo Balter. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-properties-of-the-finalization-registry-constructor -description: > - FinalizationRegistryCleanupIteratorPrototype.next.length property descriptor -info: | - FinalizationRegistry.prototype.cleanupSome ( [ callback ] ) - - 1. Let finalizationRegistry be the this value. - ... - 5. Perform ! CleanupFinalizationRegistry(finalizationRegistry, callback). - ... - - CleanupFinalizationRegistry ( finalizationRegistry [ , callback ] ) - - ... - 3. Let iterator be ! CreateFinalizationRegistryCleanupIterator(finalizationRegistry). - ... - 6. Let result be Call(callback, undefined, « iterator »). - ... - - 17 ECMAScript Standard Built-in Objects - - Every built-in function object, including constructors, has a length - property whose value is an integer. Unless otherwise specified, this - value is equal to the largest number of named arguments shown in the - subclause headings for the function description. Optional parameters - (which are indicated with brackets: [ ]) or rest parameters (which - are shown using the form «...name») are not included in the default - argument count. - - Unless otherwise specified, the length property of a built-in - function object has the attributes { [[Writable]]: false, - [[Enumerable]]: false, [[Configurable]]: true }. -includes: [async-gc.js, propertyHelper.js] -flags: [async, non-deterministic] -features: [FinalizationRegistry, host-gc-required, Symbol] ----*/ - -var FinalizationRegistryCleanupIteratorPrototype; -var called = 0; -var finalizationRegistry = new FinalizationRegistry(function() {}); - -function callback(iterator) { - called += 1; - FinalizationRegistryCleanupIteratorPrototype = Object.getPrototypeOf(iterator); -} - -function emptyCells() { - var target = {}; - finalizationRegistry.register(target); - - var prom = asyncGC(target); - target = null; - - return prom; -} - -emptyCells().then(function() { - finalizationRegistry.cleanupSome(callback); - - assert.sameValue(called, 1, 'cleanup successful'); - - assert.sameValue(typeof FinalizationRegistryCleanupIteratorPrototype.next, 'function'); - - verifyProperty(FinalizationRegistryCleanupIteratorPrototype.next, 'length', { - value: 0, - enumerable: false, - writable: false, - configurable: true, - }); -}).then($DONE, resolveAsyncGC); diff --git a/test/built-ins/FinalizationRegistry/FinalizationRegistryCleanupIteratorPrototype/next-missing-internal-throws.js b/test/built-ins/FinalizationRegistry/FinalizationRegistryCleanupIteratorPrototype/next-missing-internal-throws.js deleted file mode 100644 index 7eadb345d9..0000000000 --- a/test/built-ins/FinalizationRegistry/FinalizationRegistryCleanupIteratorPrototype/next-missing-internal-throws.js +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright (C) 2019 Leo Balter. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-properties-of-the-finalization-registry-constructor -description: > - If iterator does not have a [[FinalizationRegistry]] internal slot, throw a TypeError exception. -info: | - FinalizationRegistry.prototype.cleanupSome ( [ callback ] ) - - 1. Let finalizationRegistry be the this value. - ... - 5. Perform ! CleanupFinalizationRegistry(finalizationRegistry, callback). - ... - - CleanupFinalizationRegistry ( finalizationRegistry [ , callback ] ) - - ... - 3. Let iterator be ! CreateFinalizationRegistryCleanupIterator(finalizationRegistry). - ... - 6. Let result be Call(callback, undefined, « iterator »). - ... - - %FinalizationRegistryCleanupIteratorPrototype%.next ( ) - - 1. Let iterator be the this value. - 2. If Type(iterator) is not Object, throw a TypeError exception. - 3. If iterator does not have a [[FinalizationRegistry]] internal slot, throw a TypeError exception. -features: [FinalizationRegistry, WeakRef, host-gc-required, Symbol] -includes: [async-gc.js] -flags: [async, non-deterministic] ----*/ - -var FinalizationRegistryCleanupIteratorPrototype; -var called = 0; -var endOfCall = 0; -var finalizationRegistry = new FinalizationRegistry(function() {}); - -function callback(iterator) { - called += 1; - // Only the iterator itself will have a [[FinalizationRegistry]] internal - FinalizationRegistryCleanupIteratorPrototype = Object.getPrototypeOf(iterator); - - // It's sensitive the assertions remain inside this function in order to secure - // [[IsFinalizationRegistryCleanupJobActive]] is true - assert.sameValue(typeof FinalizationRegistryCleanupIteratorPrototype.next, 'function'); - - var next = FinalizationRegistryCleanupIteratorPrototype.next; - - assert.throws(TypeError, function() { - next.call({}); - }, '{}'); - - assert.throws(TypeError, function() { - next.call(FinalizationRegistry); - }, 'FinalizationRegistry'); - - assert.throws(TypeError, function() { - next.call(FinalizationRegistryCleanupIteratorPrototype); - }, 'FinalizationRegistryCleanupIteratorPrototype'); - - assert.throws(TypeError, function() { - next.call(finalizationRegistry); - }, 'FinalizationRegistry instance'); - - var wr = new WeakRef({}); - assert.throws(TypeError, function() { - next.call(wr); - }, 'WeakRef instance'); - - // Abrupt completions are not directly returned. - endOfCall += 1; -} - -function emptyCells() { - var target = {}; - finalizationRegistry.register(target); - - var prom = asyncGC(target); - target = null; - - return prom; -} - -emptyCells().then(function() { - finalizationRegistry.cleanupSome(callback); - - assert.sameValue(called, 1, 'cleanup successful'); - assert.sameValue(endOfCall, 1, 'Abrupt completions are not directly returned.'); -}).then($DONE, resolveAsyncGC); diff --git a/test/built-ins/FinalizationRegistry/FinalizationRegistryCleanupIteratorPrototype/next-name.js b/test/built-ins/FinalizationRegistry/FinalizationRegistryCleanupIteratorPrototype/next-name.js deleted file mode 100644 index 0a3c87d1c9..0000000000 --- a/test/built-ins/FinalizationRegistry/FinalizationRegistryCleanupIteratorPrototype/next-name.js +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (C) 2019 Leo Balter. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-properties-of-the-finalization-registry-constructor -description: > - FinalizationRegistryCleanupIteratorPrototype.next.name property descriptor -info: | - FinalizationRegistry.prototype.cleanupSome ( [ callback ] ) - - 1. Let finalizationRegistry be the this value. - ... - 5. Perform ! CleanupFinalizationRegistry(finalizationRegistry, callback). - ... - - CleanupFinalizationRegistry ( finalizationRegistry [ , callback ] ) - - ... - 3. Let iterator be ! CreateFinalizationRegistryCleanupIterator(finalizationRegistry). - ... - 6. Let result be Call(callback, undefined, « iterator »). - ... - - 17 ECMAScript Standard Built-in Objects - - Every built-in function object, including constructors, that is not - identified as an anonymous function has a name property whose value - is a String. Unless otherwise specified, this value is the name that - is given to the function in this specification. For functions that - are specified as properties of objects, the name value is the - property name string used to access the function. [...] - - Unless otherwise specified, the name property of a built-in function - object, if it exists, has the attributes { [[Writable]]: false, - [[Enumerable]]: false, [[Configurable]]: true }. -includes: [async-gc.js, propertyHelper.js] -flags: [async, non-deterministic] -features: [FinalizationRegistry, host-gc-required, Symbol] ----*/ - -var FinalizationRegistryCleanupIteratorPrototype; -var called = 0; -var finalizationRegistry = new FinalizationRegistry(function() {}); - -function callback(iterator) { - called += 1; - FinalizationRegistryCleanupIteratorPrototype = Object.getPrototypeOf(iterator); -} - -function emptyCells() { - var target = {}; - finalizationRegistry.register(target); - - var prom = asyncGC(target); - target = null; - - return prom; -} - -emptyCells().then(function() { - finalizationRegistry.cleanupSome(callback); - - assert.sameValue(called, 1, 'cleanup successful'); - - assert.sameValue(typeof FinalizationRegistryCleanupIteratorPrototype.next, 'function'); - - var next = FinalizationRegistryCleanupIteratorPrototype.next; - - verifyProperty(next, 'name', { - value: 'next', - enumerable: false, - writable: false, - configurable: true, - }); -}).then($DONE, resolveAsyncGC); diff --git a/test/built-ins/FinalizationRegistry/FinalizationRegistryCleanupIteratorPrototype/next-not-object-throws.js b/test/built-ins/FinalizationRegistry/FinalizationRegistryCleanupIteratorPrototype/next-not-object-throws.js deleted file mode 100644 index 36164fe2f5..0000000000 --- a/test/built-ins/FinalizationRegistry/FinalizationRegistryCleanupIteratorPrototype/next-not-object-throws.js +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (C) 2019 Leo Balter. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-properties-of-the-finalization-registry-constructor -description: > - FinalizationRegistryCleanupIteratorPrototype.next() throws if this is not Object -info: | - FinalizationRegistry.prototype.cleanupSome ( [ callback ] ) - - 1. Let finalizationRegistry be the this value. - ... - 5. Perform ! CleanupFinalizationRegistry(finalizationRegistry, callback). - ... - - CleanupFinalizationRegistry ( finalizationRegistry [ , callback ] ) - - ... - 3. Let iterator be ! CreateFinalizationRegistryCleanupIterator(finalizationRegistry). - ... - 6. Let result be Call(callback, undefined, « iterator »). - ... - - %FinalizationRegistryCleanupIteratorPrototype%.next ( ) - - 1. Let iterator be the this value. - 2. If Type(iterator) is not Object, throw a TypeError exception. -features: [FinalizationRegistry, host-gc-required, Symbol] -includes: [async-gc.js] -flags: [async, non-deterministic] ----*/ - -var FinalizationRegistryCleanupIteratorPrototype; -var called = 0; -var finalizationRegistry = new FinalizationRegistry(function() {}); - -function callback(iterator) { - called += 1; - FinalizationRegistryCleanupIteratorPrototype = Object.getPrototypeOf(iterator); -} - -function emptyCells() { - var target = {}; - finalizationRegistry.register(target); - - var prom = asyncGC(target); - target = null; - - return prom; -} - -emptyCells().then(function() { - finalizationRegistry.cleanupSome(callback); - - assert.sameValue(called, 1, 'cleanup successful'); - - assert.sameValue(typeof FinalizationRegistryCleanupIteratorPrototype.next, 'function'); - - var next = FinalizationRegistryCleanupIteratorPrototype.next; - - assert.throws(TypeError, function() { - next.call(undefined); - }, 'undefined'); - - assert.throws(TypeError, function() { - next.call(null); - }, 'null'); - - assert.throws(TypeError, function() { - next.call(true); - }, 'true'); - - assert.throws(TypeError, function() { - next.call(false); - }, 'false'); - - assert.throws(TypeError, function() { - next.call(1); - }, '1'); - - assert.throws(TypeError, function() { - next.call('string'); - }, 'string'); - - var symbol = Symbol(); - assert.throws(TypeError, function() { - next.call(symbol); - }, 'symbol'); -}).then($DONE, resolveAsyncGC); diff --git a/test/built-ins/FinalizationRegistry/FinalizationRegistryCleanupIteratorPrototype/next-prop-desc.js b/test/built-ins/FinalizationRegistry/FinalizationRegistryCleanupIteratorPrototype/next-prop-desc.js deleted file mode 100644 index c65a69a5c8..0000000000 --- a/test/built-ins/FinalizationRegistry/FinalizationRegistryCleanupIteratorPrototype/next-prop-desc.js +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (C) 2019 Leo Balter. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-properties-of-the-finalization-registry-constructor -description: > - Prop descriptor for FinalizationRegistryCleanupIteratorPrototype.next -info: | - FinalizationRegistry.prototype.cleanupSome ( [ callback ] ) - - 1. Let finalizationRegistry be the this value. - ... - 5. Perform ! CleanupFinalizationRegistry(finalizationRegistry, callback). - ... - - CleanupFinalizationRegistry ( finalizationRegistry [ , callback ] ) - - ... - 3. Let iterator be ! CreateFinalizationRegistryCleanupIterator(finalizationRegistry). - ... - 6. Let result be Call(callback, undefined, « iterator »). - ... - - 17 ECMAScript Standard Built-in Objects: - - Every other data property described in clauses 18 through 26 and in Annex B.2 - has the attributes { [[Writable]]: true, [[Enumerable]]: false, - [[Configurable]]: true } unless otherwise specified. -includes: [propertyHelper.js, async-gc.js] -flags: [async, non-deterministic] -features: [FinalizationRegistry, host-gc-required, Symbol] ----*/ - -var FinalizationRegistryCleanupIteratorPrototype; -var called = 0; -var finalizationRegistry = new FinalizationRegistry(function() {}); - -function callback(iterator) { - called += 1; - FinalizationRegistryCleanupIteratorPrototype = Object.getPrototypeOf(iterator); -} - -function emptyCells() { - var target = {}; - finalizationRegistry.register(target); - - var prom = asyncGC(target); - target = null; - - return prom; -} - -emptyCells().then(function() { - finalizationRegistry.cleanupSome(callback); - - assert.sameValue(called, 1, 'cleanup successful'); - - assert.sameValue(typeof FinalizationRegistryCleanupIteratorPrototype.next, 'function'); - - var next = FinalizationRegistryCleanupIteratorPrototype.next; - - verifyProperty(FinalizationRegistryCleanupIteratorPrototype, 'next', { - enumerable: false, - writable: true, - configurable: true, - }); -}).then($DONE, resolveAsyncGC); diff --git a/test/built-ins/FinalizationRegistry/FinalizationRegistryCleanupIteratorPrototype/proto.js b/test/built-ins/FinalizationRegistry/FinalizationRegistryCleanupIteratorPrototype/proto.js deleted file mode 100644 index 2d4dc9081a..0000000000 --- a/test/built-ins/FinalizationRegistry/FinalizationRegistryCleanupIteratorPrototype/proto.js +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright (C) 2019 Leo Balter. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-properties-of-the-finalization-registry-constructor -description: > - FinalizationRegistryCleanupIterator has a [[Prototype]] internal slot whose value is the intrinsic - object %IteratorPrototype%. -info: | - The %FinalizationRegistryCleanupIteratorPrototype% Object - - - has properties that are inherited by all FinalizationRegistry Cleanup Iterator Objects. - - is an ordinary object. - - has a [[Prototype]] internal slot whose value is the intrinsic object %IteratorPrototype%. - ... - - FinalizationRegistry.prototype.cleanupSome ( [ callback ] ) - - 1. Let finalizationRegistry be the this value. - 2. If Type(finalizationRegistry) is not Object, throw a TypeError exception. - 3. If finalizationRegistry does not have a [[Cells]] internal slot, throw a TypeError exception. - 4. If callback is not undefined and IsCallable(callback) is false, throw a TypeError exception. - 5. Perform ! CleanupFinalizationRegistry(finalizationRegistry, callback). - 6. Return undefined. - - CleanupFinalizationRegistry ( finalizationRegistry [ , callback ] ) - - ... - 2. If CheckForEmptyCells(finalizationRegistry) is false, return. - 3. Let iterator be ! CreateFinalizationRegistryCleanupIterator(finalizationRegistry). - 4. If callback is undefined, set callback to finalizationRegistry.[[CleanupCallback]]. - 5. Set finalizationRegistry.[[IsFinalizationRegistryCleanupJobActive]] to true. - 6. Let result be Call(callback, undefined, « iterator »). - ... - - CheckForEmptyCells ( finalizationRegistry ) - - ... - 2. For each cell in finalizationRegistry.[[Cells]], do - a. If cell.[[Target]] is empty, then - i. Return true. - 3. Return false. - - CreateFinalizationRegistryCleanupIterator ( finalizationRegistry ) - - ... - 4. Let prototype be finalizationRegistry.[[Realm]].[[Intrinsics]].[[%FinalizationRegistryCleanupIteratorPrototype%]]. - 5. Let iterator be ObjectCreate(prototype, « [[FinalizationRegistry]] »). - 6. Set iterator.[[FinalizationRegistry]] to finalizationRegistry. - 7. Return iterator. -features: [FinalizationRegistry, host-gc-required] -includes: [async-gc.js] -flags: [async, non-deterministic] ----*/ - -var IteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]())); -var FinalizationRegistryCleanupIteratorPrototype; -var called = 0; -var cleanupCallbackCalled = 0; - -function callback(iterator) { - called += 1; - - FinalizationRegistryCleanupIteratorPrototype = Object.getPrototypeOf(iterator); -} - -var finalizationRegistry = new FinalizationRegistry(function() {}); - -function emptyCells() { - var target = {}; - finalizationRegistry.register(target); - - var prom = asyncGC(target); - target = null; - - return prom; -} - -emptyCells().then(function() { - finalizationRegistry.cleanupSome(callback); - - assert.sameValue(called, 1, 'cleanup successful'); - - var proto = Object.getPrototypeOf(FinalizationRegistryCleanupIteratorPrototype); - assert.sameValue( - proto, IteratorPrototype, - '[[Prototype]] internal slot whose value is the intrinsic object %IteratorPrototype%' - ); - - assert.sameValue(cleanupCallbackCalled, 0, 'if a callback is given, do not call cleanupCallback'); -}).then($DONE, resolveAsyncGC); diff --git a/test/built-ins/FinalizationRegistry/gc-has-one-chance-to-call-cleanupCallback.js b/test/built-ins/FinalizationRegistry/gc-has-one-chance-to-call-cleanupCallback.js index 2210f12dc9..3aabb32b48 100644 --- a/test/built-ins/FinalizationRegistry/gc-has-one-chance-to-call-cleanupCallback.js +++ b/test/built-ins/FinalizationRegistry/gc-has-one-chance-to-call-cleanupCallback.js @@ -33,10 +33,8 @@ includes: [async-gc.js] var cleanupCallback = 0; var called = 0; -// both this cb and the finalizationRegistry callback are not exhausting the iterator to prevent -// the target cell from being removed from the finalizationRegistry.[[Cells]]. -// More info at %FinalizationRegistryCleanupIteratorPrototype%.next ( ) -function cb() { +function cb(holding) { + assert.sameValue(holding, 'a'); called += 1; } @@ -54,14 +52,17 @@ function emptyCells() { return prom; } -// Let's add some async ticks, as the cleanupCallback is not meant to interrupt -// synchronous operations. -async function fn() { +emptyCells() + .then(async function() { await Promise.resolve(1); finalizationRegistry.cleanupSome(cb); + + // cleanupSome will be invoked if there are empty cells left. If the + // cleanupCallback already ran, then cb won't be called. + let expectedCalled = cleanupCallback === 1 ? 0 : 1; // This asserts the registered object was emptied in the previous GC. - assert.sameValue(called, 1, 'cleanupSome callback for the first time'); + assert.sameValue(called, expectedCalled, 'cleanupSome callback for the first time'); // At this point, we can't assert if cleanupCallback was called, because it's // optional. Although, we can finally assert it's not gonna be called anymore @@ -71,8 +72,8 @@ async function fn() { assert(cleanupCallback >= 0, 'cleanupCallback might be 0'); assert(cleanupCallback <= 1, 'cleanupCallback might be 1'); - // Restoring the cleanupCallback variable to 0 will help us asserting the finalizationRegistry - // callback is not called again. + // Restoring the cleanupCallback variable to 0 will help us asserting the + // finalizationRegistry callback is not called again. cleanupCallback = 0; await $262.gc(); @@ -80,9 +81,7 @@ async function fn() { finalizationRegistry.cleanupSome(cb); - // This cb is called again because finalizationRegistry still holds an emptied cell, but it's - // not yet removed from the - assert.sameValue(called, 2, 'cleanupSome callback for the second time'); + assert.sameValue(called, expectedCalled, 'cleanupSome callback is not called anymore, no empty cells'); assert.sameValue(cleanupCallback, 0, 'cleanupCallback is not called again #1'); await $262.gc(); @@ -90,46 +89,9 @@ async function fn() { finalizationRegistry.cleanupSome(cb); - assert.sameValue(called, 3, 'cleanupSome callback for the third time'); + assert.sameValue(called, expectedCalled, 'cleanupSome callback is not called again #2'); assert.sameValue(cleanupCallback, 0, 'cleanupCallback is not called again #2'); await $262.gc(); -} - -emptyCells() - .then(async function() { - await fn();// tick - await Promise.resolve(4); // tick - - assert.sameValue(cleanupCallback, 0, 'cleanupCallback is not called again #3'); - - finalizationRegistry.cleanupSome(cb); - - assert.sameValue(called, 4, 'cleanupSome callback for the fourth time'); - assert.sameValue(cleanupCallback, 0, 'cleanupCallback is not called again #4'); - - await $262.gc(); - - // Now we are exhausting the iterator, so cleanupSome callback will also not be called. - finalizationRegistry.cleanupSome(iterator => { - var exhausted = [...iterator]; - assert.sameValue(exhausted.length, 1); - assert.sameValue(exhausted[0], 'a'); - called += 1; - }); - - assert.sameValue(called, 5, 'cleanupSome callback for the fifth time'); - assert.sameValue(cleanupCallback, 0, 'cleanupCallback is not called again #4'); - - await $262.gc(); - - await Promise.resolve(5); // tick - await await Promise.resolve(6); // more ticks - await await await Promise.resolve(7); // even more ticks - - finalizationRegistry.cleanupSome(cb); - - assert.sameValue(called, 5, 'cleanupSome callback is not called anymore, no empty cells'); - assert.sameValue(cleanupCallback, 0, 'cleanupCallback is not called again #5'); }) .then($DONE, resolveAsyncGC); diff --git a/test/built-ins/FinalizationRegistry/prototype/cleanupSome/callback-iterator-proto.js b/test/built-ins/FinalizationRegistry/prototype/cleanupSome/callback-iterator-proto.js deleted file mode 100644 index 32b217dbe9..0000000000 --- a/test/built-ins/FinalizationRegistry/prototype/cleanupSome/callback-iterator-proto.js +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (C) 2019 Leo Balter. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-properties-of-the-finalization-registry-constructor -description: > - The callback function is called with a FinalizationRegistryCleanupIterator -info: | - The %FinalizationRegistryCleanupIteratorPrototype% Object - - - has properties that are inherited by all FinalizationRegistry Cleanup Iterator Objects. - - is an ordinary object. - - has a [[Prototype]] internal slot whose value is the intrinsic object %IteratorPrototype%. - ... - - FinalizationRegistry.prototype.cleanupSome ( [ callback ] ) - - 1. Let finalizationRegistry be the this value. - 2. If Type(finalizationRegistry) is not Object, throw a TypeError exception. - 3. If finalizationRegistry does not have a [[Cells]] internal slot, throw a TypeError exception. - 4. If callback is not undefined and IsCallable(callback) is false, throw a TypeError exception. - 5. Perform ! CleanupFinalizationRegistry(finalizationRegistry, callback). - 6. Return undefined. - - CleanupFinalizationRegistry ( finalizationRegistry [ , callback ] ) - - ... - 2. If CheckForEmptyCells(finalizationRegistry) is false, return. - 3. Let iterator be ! CreateFinalizationRegistryCleanupIterator(finalizationRegistry). - 4. If callback is undefined, set callback to finalizationRegistry.[[CleanupCallback]]. - 5. Set finalizationRegistry.[[IsFinalizationRegistryCleanupJobActive]] to true. - 6. Let result be Call(callback, undefined, « iterator »). - ... - - CheckForEmptyCells ( finalizationRegistry ) - - ... - 2. For each cell in finalizationRegistry.[[Cells]], do - a. If cell.[[Target]] is empty, then - i. Return true. - 3. Return false. - - CreateFinalizationRegistryCleanupIterator ( finalizationRegistry ) - - ... - 4. Let prototype be finalizationRegistry.[[Realm]].[[Intrinsics]].[[%FinalizationRegistryCleanupIteratorPrototype%]]. - 5. Let iterator be ObjectCreate(prototype, « [[FinalizationRegistry]] »). - 6. Set iterator.[[FinalizationRegistry]] to finalizationRegistry. - 7. Return iterator. -features: [FinalizationRegistry, host-gc-required] -includes: [async-gc.js] -flags: [async, non-deterministic] ----*/ - -var IteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]())); -var FinalizationRegistryCleanupIteratorPrototype; -var called = 0; -var cleanupCallbackCalled = 0; - -function callback(iterator) { - called += 1; - - FinalizationRegistryCleanupIteratorPrototype = Object.getPrototypeOf(iterator); -} - -var finalizationRegistry = new FinalizationRegistry(function() { - cleanupCallbackCalled += 1; -}); - -async function register() { - var target = {}; - finalizationRegistry.register(target); - var prom = asyncGC(target); - - target = null; - assert.sameValue(called, 0); // never called in sync execution - - return prom; -} - -register() - .then(function() { - // We can't observe if the cleanupCallback was called, but we can make sure cleanupSome won't call it. - cleanupCallbackCalled = 0; - - finalizationRegistry.cleanupSome(callback); - - assert.sameValue(called, 1); - - var proto = Object.getPrototypeOf(FinalizationRegistryCleanupIteratorPrototype); - assert.sameValue( - proto, IteratorPrototype, - '[[Prototype]] internal slot whose value is the intrinsic object %IteratorPrototype%' - ); - - assert.sameValue(cleanupCallbackCalled, 0, 'if a callback is given, do not call cleanupCallback'); - }) - .then($DONE, resolveAsyncGC); diff --git a/test/built-ins/FinalizationRegistry/prototype/cleanupSome/cleanup-prevented-with-reference.js b/test/built-ins/FinalizationRegistry/prototype/cleanupSome/cleanup-prevented-with-reference.js index 157cbaff4d..62e1721c27 100644 --- a/test/built-ins/FinalizationRegistry/prototype/cleanupSome/cleanup-prevented-with-reference.js +++ b/test/built-ins/FinalizationRegistry/prototype/cleanupSome/cleanup-prevented-with-reference.js @@ -18,9 +18,9 @@ includes: [async-gc.js] flags: [async, non-deterministic] ---*/ -var holdingsList; -function cb(iterator) { - holdingsList = [...iterator]; +var holdingsList = []; +function cb(holding) { + holdingsList.push(holding); }; var finalizationRegistry = new FinalizationRegistry(function() {}); diff --git a/test/built-ins/FinalizationRegistry/prototype/cleanupSome/cleanup-prevented-with-unregister.js b/test/built-ins/FinalizationRegistry/prototype/cleanupSome/cleanup-prevented-with-unregister.js index 9cde4df71a..8f86818708 100644 --- a/test/built-ins/FinalizationRegistry/prototype/cleanupSome/cleanup-prevented-with-unregister.js +++ b/test/built-ins/FinalizationRegistry/prototype/cleanupSome/cleanup-prevented-with-unregister.js @@ -46,7 +46,7 @@ emptyCells().then(function() { var res = finalizationRegistry.unregister(token); assert.sameValue(res, true, 'unregister target before iterating over it in cleanup'); - finalizationRegistry.cleanupSome(function cb(iterator) { + finalizationRegistry.cleanupSome(function cb(holding) { called += 1; }); diff --git a/test/built-ins/FinalizationRegistry/prototype/cleanupSome/cleanupcallback-iterator-proto.js b/test/built-ins/FinalizationRegistry/prototype/cleanupSome/cleanupcallback-iterator-proto.js deleted file mode 100644 index 9a0dd65493..0000000000 --- a/test/built-ins/FinalizationRegistry/prototype/cleanupSome/cleanupcallback-iterator-proto.js +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright (C) 2019 Leo Balter. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-properties-of-the-finalization-registry-constructor -description: > - The cleanup callback function is called with a FinalizationRegistryCleanupIterator -info: | - The %FinalizationRegistryCleanupIteratorPrototype% Object - - - has properties that are inherited by all FinalizationRegistry Cleanup Iterator Objects. - - is an ordinary object. - - has a [[Prototype]] internal slot whose value is the intrinsic object %IteratorPrototype%. - ... - - FinalizationRegistry.prototype.cleanupSome ( [ callback ] ) - - 1. Let finalizationRegistry be the this value. - 2. If Type(finalizationRegistry) is not Object, throw a TypeError exception. - 3. If finalizationRegistry does not have a [[Cells]] internal slot, throw a TypeError exception. - 4. If callback is not undefined and IsCallable(callback) is false, throw a TypeError exception. - 5. Perform ! CleanupFinalizationRegistry(finalizationRegistry, callback). - 6. Return undefined. - - CleanupFinalizationRegistry ( finalizationRegistry [ , callback ] ) - - ... - 2. If CheckForEmptyCells(finalizationRegistry) is false, return. - 3. Let iterator be ! CreateFinalizationRegistryCleanupIterator(finalizationRegistry). - 4. If callback is undefined, set callback to finalizationRegistry.[[CleanupCallback]]. - 5. Set finalizationRegistry.[[IsFinalizationRegistryCleanupJobActive]] to true. - 6. Let result be Call(callback, undefined, « iterator »). - ... - - CheckForEmptyCells ( finalizationRegistry ) - - ... - 2. For each cell in finalizationRegistry.[[Cells]], do - a. If cell.[[Target]] is empty, then - i. Return true. - 3. Return false. - - CreateFinalizationRegistryCleanupIterator ( finalizationRegistry ) - - ... - 4. Let prototype be finalizationRegistry.[[Realm]].[[Intrinsics]].[[%FinalizationRegistryCleanupIteratorPrototype%]]. - 5. Let iterator be ObjectCreate(prototype, « [[FinalizationRegistry]] »). - 6. Set iterator.[[FinalizationRegistry]] to finalizationRegistry. - 7. Return iterator. -features: [FinalizationRegistry, host-gc-required] -includes: [async-gc.js] -flags: [async, non-deterministic] ----*/ - -var IteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]())); -var FinalizationRegistryCleanupIteratorPrototype; -var called = 0; - -function callback(iterator) { - called += 1; - - FinalizationRegistryCleanupIteratorPrototype = Object.getPrototypeOf(iterator); -} - -var finalizationRegistry = new FinalizationRegistry(function() {}); - -function emptyCells() { - var target = {}; - finalizationRegistry.register(target); - - var prom = asyncGC(target); - target = null; - - return prom; -} - -emptyCells().then(function() { - finalizationRegistry.cleanupSome(callback); - assert.sameValue(called, 1); - - var proto = Object.getPrototypeOf(FinalizationRegistryCleanupIteratorPrototype); - assert.sameValue( - proto, IteratorPrototype, - '[[Prototype]] internal slot whose value is the intrinsic object %IteratorPrototype%' - ); -}).then($DONE, resolveAsyncGC); diff --git a/test/built-ins/FinalizationRegistry/prototype/cleanupSome/iterator-holdings-multiple-values.js b/test/built-ins/FinalizationRegistry/prototype/cleanupSome/holdings-multiple-values.js similarity index 76% rename from test/built-ins/FinalizationRegistry/prototype/cleanupSome/iterator-holdings-multiple-values.js rename to test/built-ins/FinalizationRegistry/prototype/cleanupSome/holdings-multiple-values.js index 09d68c5f14..2d40e05155 100644 --- a/test/built-ins/FinalizationRegistry/prototype/cleanupSome/iterator-holdings-multiple-values.js +++ b/test/built-ins/FinalizationRegistry/prototype/cleanupSome/holdings-multiple-values.js @@ -16,31 +16,26 @@ info: | CleanupFinalizationRegistry ( finalizationRegistry [ , callback ] ) ... - 3. Let iterator be ! CreateFinalizationRegistryCleanupIterator(finalizationRegistry). - ... - 6. Let result be Call(callback, undefined, « iterator »). - ... - - %FinalizationRegistryCleanupIteratorPrototype%.next ( ) - - 8. If finalizationRegistry.[[Cells]] contains a Record cell such that cell.[[Target]] is empty, + 3. While finalizationRegistry.[[Cells]] contains a Record cell such that cell.[[WeakRefTarget]] is ~empty~, then an implementation may perform the following steps, a. Choose any such cell. b. Remove cell from finalizationRegistry.[[Cells]]. - c. Return CreateIterResultObject(cell.[[Holdings]], false). - 9. Otherwise, return CreateIterResultObject(undefined, true). + c. Perform ? Call(callback, undefined, << cell.[[HeldValue]] >>). + ... + + features: [FinalizationRegistry, Symbol, host-gc-required] includes: [async-gc.js] flags: [async, non-deterministic] ---*/ function check(value, expectedName) { - var holdings; + var holdings = []; var called = 0; var finalizationRegistry = new FinalizationRegistry(function() {}); - function callback(iterator) { + function callback(holding) { called += 1; - holdings = [...iterator]; + holdings.push(holding); } // This is internal to avoid conflicts diff --git a/test/built-ins/FinalizationRegistry/prototype/cleanupSome/poisoned-callback-throws.js b/test/built-ins/FinalizationRegistry/prototype/cleanupSome/poisoned-callback-throws.js deleted file mode 100644 index e62d073fa9..0000000000 --- a/test/built-ins/FinalizationRegistry/prototype/cleanupSome/poisoned-callback-throws.js +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (C) 2019 Leo Balter. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-finalization-registry.prototype.cleanupSome -description: Return abrupt completion from CleanupFinalizationRegistry -info: | - FinalizationRegistry.prototype.cleanupSome ( [ callback ] ) - - 1. Let finalizationRegistry be the this value. - 2. If Type(finalizationRegistry) is not Object, throw a TypeError exception. - 3. If finalizationRegistry does not have a [[Cells]] internal slot, throw a TypeError exception. - 4. If callback is not undefined and IsCallable(callback) is false, throw a TypeError exception. - 5. Perform ? CleanupFinalizationRegistry(finalizationRegistry, callback). - 6. Return undefined. - - CleanupFinalizationRegistry ( finalizationRegistry [ , callback ] ) - - 4. If callback is undefined, set callback to finalizationRegistry.[[CleanupCallback]]. - 5. Set finalizationRegistry.[[IsFinalizationRegistryCleanupJobActive]] to true. - 6. Let result be Call(callback, undefined, « iterator »). - 7. Set finalizationRegistry.[[IsFinalizationRegistryCleanupJobActive]] to false. - 8. If result is an abrupt completion, return result. -features: [FinalizationRegistry, arrow-function, async-functions, async-iteration, class, host-gc-required] -includes: [async-gc.js] -flags: [async, non-deterministic] ----*/ - -var called = 0; -var iterator = false; - -function poisoned(iter) { - called += 1; - iterator = iter; - iter.next(); // Won't throw - throw new Test262Error(); -} -var finalizationRegistry = new FinalizationRegistry(function() {}); - -function emptyCells() { - var target = {}; - finalizationRegistry.register(target); - - var prom = asyncGC(target); - target = null; - - return prom; -} - -emptyCells().then(function() { - assert.throws(Test262Error, function() { - finalizationRegistry.cleanupSome(poisoned); - }); - - assert.sameValue(called, 1); - - assert.sameValue(typeof iterator, 'object'); - assert.sameValue(typeof iterator.next, 'function'); - assert.throws(TypeError, function() { - iterator.next(); - }, 'iterator.next throws a TypeError if IsFinalizationRegistryCleanupJobActive is false'); -}).then($DONE, resolveAsyncGC); diff --git a/test/built-ins/FinalizationRegistry/prototype/cleanupSome/cleanup-throws-in-callback.js b/test/built-ins/FinalizationRegistry/prototype/cleanupSome/reentrancy.js similarity index 69% rename from test/built-ins/FinalizationRegistry/prototype/cleanupSome/cleanup-throws-in-callback.js rename to test/built-ins/FinalizationRegistry/prototype/cleanupSome/reentrancy.js index 94fba9cd16..82b2d660c2 100644 --- a/test/built-ins/FinalizationRegistry/prototype/cleanupSome/cleanup-throws-in-callback.js +++ b/test/built-ins/FinalizationRegistry/prototype/cleanupSome/reentrancy.js @@ -4,15 +4,10 @@ /*--- esid: sec-properties-of-the-finalization-registry-constructor description: > - The cleanupSome() method throws if cleanup is currently in progress. + The cleanupSome() method can be reentered info: | FinalizationRegistry.prototype.cleanupSome ( [ callback ] ) - 1. Let finalizationRegistry be the this value. - ... - 4. If finalizationRegistry.[[IsFinalizationRegistryCleanupJobActive]] is true, - throw a TypeError exception. - features: [FinalizationRegistry, host-gc-required] includes: [async-gc.js] flags: [async, non-deterministic] @@ -22,16 +17,14 @@ var called = 0; var endOfCall = 0; var finalizationRegistry = new FinalizationRegistry(function() {}); -function callback(iterator) { +function callback(holding) { called += 1; if (called === 1) { // Atempt to re-enter the callback. var nestedCallbackRan = false; - assert.throws(TypeError, () => { - finalizationRegistry.cleanupSome(() => { nestedCallbackRan = true }); - }); - assert.sameValue(nestedCallbackRan, false); + finalizationRegistry.cleanupSome(() => { nestedCallbackRan = true }); + assert.sameValue(nestedCallbackRan, true); } endOfCall += 1; @@ -39,7 +32,10 @@ function callback(iterator) { function emptyCells() { var o1 = {}; + var o2 = {}; + // Register more than one objects to test reentrancy. finalizationRegistry.register(o1, 'holdings 1'); + finalizationRegistry.register(o2, 'holdings 2'); var prom = asyncGC(o1); o1 = null; diff --git a/test/built-ins/FinalizationRegistry/prototype/cleanupSome/return-undefined-with-gc.js b/test/built-ins/FinalizationRegistry/prototype/cleanupSome/return-undefined-with-gc.js index 2a7bbaf6b7..90b15c4743 100644 --- a/test/built-ins/FinalizationRegistry/prototype/cleanupSome/return-undefined-with-gc.js +++ b/test/built-ins/FinalizationRegistry/prototype/cleanupSome/return-undefined-with-gc.js @@ -39,46 +39,28 @@ function emptyCells() { return prom; } -var tests = []; - -tests.push(emptyCells().then(function() { +emptyCells().then(function() { called = 0; assert.sameValue(finalizationRegistry.cleanupSome(cb), undefined, 'regular callback'); assert.sameValue(called, 1); -})); - -tests.push(emptyCells().then(function() { +}).then(emptyCells).then(function() { called = 0; assert.sameValue(finalizationRegistry.cleanupSome(fn), undefined, 'regular callback, same FG cleanup function'); assert.sameValue(called, 1); -})); - -tests.push(emptyCells().then(function() { +}).then(emptyCells).then(function() { called = 0; assert.sameValue(finalizationRegistry.cleanupSome(), undefined, 'undefined (implicit) callback, defer to FB callback'); assert.sameValue(called, 1); -})); - -tests.push(emptyCells().then(function() { +}).then(emptyCells).then(function() { called = 0; assert.sameValue(finalizationRegistry.cleanupSome(undefined), undefined, 'undefined (explicit) callback, defer to FB callback'); assert.sameValue(called, 1); -})); - -tests.push(emptyCells().then(function() { - assert.sameValue(finalizationRegistry.cleanupSome(() => 1), undefined, 'arrow function'); -})); - -tests.push(emptyCells().then(function() { +}).then(emptyCells).then(function() { + assert.sameValue(finalizationRegistry.cleanupSome(() => 1), undefined, 'arrow function'); +}).then(emptyCells).then(function() { assert.sameValue(finalizationRegistry.cleanupSome(async function() {}), undefined, 'async function'); -})); - -tests.push(emptyCells().then(function() { +}).then(emptyCells).then(function() { assert.sameValue(finalizationRegistry.cleanupSome(function *() {}), undefined, 'generator'); -})); - -tests.push(emptyCells().then(function() { +}).then(emptyCells).then(function() { assert.sameValue(finalizationRegistry.cleanupSome(async function *() {}), undefined, 'async generator'); -})); - -Promise.all(tests).then(() => { $DONE(); }, resolveAsyncGC); +}).then($DONE, resolveAsyncGC); diff --git a/test/built-ins/FinalizationRegistry/prototype/unregister/unregister-cleaned-up-cell.js b/test/built-ins/FinalizationRegistry/prototype/unregister/unregister-cleaned-up-cell.js index 76233105cf..3fe732087f 100644 --- a/test/built-ins/FinalizationRegistry/prototype/unregister/unregister-cleaned-up-cell.js +++ b/test/built-ins/FinalizationRegistry/prototype/unregister/unregister-cleaned-up-cell.js @@ -15,18 +15,11 @@ info: | CleanupFinalizationRegistry ( finalizationRegistry [ , callback ] ) ... - 3. Let iterator be ! CreateFinalizationRegistryCleanupIterator(finalizationRegistry). - ... - 6. Let result be Call(callback, undefined, « iterator »). - ... - - %FinalizationRegistryCleanupIteratorPrototype%.next ( ) - - 8. If finalizationRegistry.[[Cells]] contains a Record cell such that cell.[[Target]] is empty, + 3. While finalizationRegistry.[[Cells]] contains a Record cell such that cell.[[WeakRefTarget]] is ~empty~, then an implementation may perform the following steps, a. Choose any such cell. b. Remove cell from finalizationRegistry.[[Cells]]. - c. Return CreateIterResultObject(cell.[[Holdings]], false). - 9. Otherwise, return CreateIterResultObject(undefined, true). + c. Perform ? Call(callback, undefined, << cell.[[HeldValue]] >>). + ... FinalizationRegistry.prototype.unregister ( unregisterToken ) @@ -57,10 +50,10 @@ function emptyCells() { emptyCells().then(function() { var called = 0; - var holdings; - finalizationRegistry.cleanupSome(function cb(iterator) { + var holdings = []; + finalizationRegistry.cleanupSome(function cb(holding) { called += 1; - holdings = [...iterator]; + holdings.push(holding); }); assert.sameValue(called, 1);