summaryrefslogtreecommitdiffstats
path: root/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome')
-rw-r--r--js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/callback-not-callable-throws.js56
-rw-r--r--js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/cleanup-prevented-with-reference.js48
-rw-r--r--js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/cleanup-prevented-with-unregister.js55
-rw-r--r--js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/custom-this.js29
-rw-r--r--js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/holdings-multiple-values.js70
-rw-r--r--js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/length.js35
-rw-r--r--js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/name.js34
-rw-r--r--js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/not-a-constructor.js36
-rw-r--r--js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/prop-desc.js27
-rw-r--r--js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/reentrancy.js52
-rw-r--r--js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/return-undefined-with-gc.js67
-rw-r--r--js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/return-undefined.js44
-rw-r--r--js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/shell.js0
-rw-r--r--js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/this-does-not-have-internal-cells-throws.js51
-rw-r--r--js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/this-not-object-throws.js53
16 files changed, 657 insertions, 0 deletions
diff --git a/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/browser.js b/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/browser.js
diff --git a/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/callback-not-callable-throws.js b/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/callback-not-callable-throws.js
new file mode 100644
index 0000000000..2e8450b19e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/callback-not-callable-throws.js
@@ -0,0 +1,56 @@
+// |reftest| skip-if(!this.hasOwnProperty('FinalizationRegistry')) -- FinalizationRegistry is not enabled unconditionally
+// 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: Throws a TypeError if callback is not callable
+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.
+ ...
+features: [FinalizationRegistry.prototype.cleanupSome, FinalizationRegistry]
+---*/
+
+assert.sameValue(typeof FinalizationRegistry.prototype.cleanupSome, 'function');
+
+var finalizationRegistry = new FinalizationRegistry(function() {});
+
+assert.throws(TypeError, function() {
+ finalizationRegistry.cleanupSome(null);
+}, 'null');
+
+assert.throws(TypeError, function() {
+ finalizationRegistry.cleanupSome(true);
+}, 'true');
+
+assert.throws(TypeError, function() {
+ finalizationRegistry.cleanupSome(false);
+}, 'false');
+
+assert.throws(TypeError, function() {
+ finalizationRegistry.cleanupSome(1);
+}, 'number');
+
+assert.throws(TypeError, function() {
+ finalizationRegistry.cleanupSome('object');
+}, 'string');
+
+var s = Symbol();
+assert.throws(TypeError, function() {
+ finalizationRegistry.cleanupSome(s);
+}, 'symbol');
+
+assert.throws(TypeError, function() {
+ finalizationRegistry.cleanupSome({});
+}, 'object');
+
+assert.throws(TypeError, function() {
+ finalizationRegistry.cleanupSome(FinalizationRegistry.prototype);
+}, 'FinalizationRegistry.prototype');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/cleanup-prevented-with-reference.js b/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/cleanup-prevented-with-reference.js
new file mode 100644
index 0000000000..d8c23a7d1e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/cleanup-prevented-with-reference.js
@@ -0,0 +1,48 @@
+// |reftest| skip-if(!this.hasOwnProperty('FinalizationRegistry')) async -- FinalizationRegistry is not enabled unconditionally
+// 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: Cleanup might be prevented with a reference usage;
+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.
+features: [FinalizationRegistry.prototype.cleanupSome, FinalizationRegistry, host-gc-required]
+includes: [async-gc.js]
+flags: [async, non-deterministic]
+---*/
+
+var holdingsList = [];
+function cb(holding) {
+ holdingsList.push(holding);
+};
+var finalizationRegistry = new FinalizationRegistry(function() {});
+
+var referenced = {};
+
+function emptyCells() {
+ var target = {};
+ finalizationRegistry.register(target, 'target!');
+ finalizationRegistry.register(referenced, 'referenced');
+
+ var prom = asyncGC(target);
+ target = null;
+
+ return prom;
+}
+
+emptyCells().then(function() {
+ finalizationRegistry.cleanupSome(cb);
+
+ assert.sameValue(holdingsList.length, 1);
+ assert.sameValue(holdingsList[0], 'target!');
+
+ assert.sameValue(typeof referenced, 'object', 'referenced preserved');
+}).then($DONE, resolveAsyncGC);
diff --git a/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/cleanup-prevented-with-unregister.js b/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/cleanup-prevented-with-unregister.js
new file mode 100644
index 0000000000..6669be38b2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/cleanup-prevented-with-unregister.js
@@ -0,0 +1,55 @@
+// |reftest| skip-if(!this.hasOwnProperty('FinalizationRegistry')) async -- FinalizationRegistry is not enabled unconditionally
+// 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: Cleanup might be prevented with an unregister usage
+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.
+
+ FinalizationRegistry.prototype.unregister ( unregisterToken )
+
+ 1. Let removed be false.
+ 2. For each Record { [[Target]], [[Holdings]], [[UnregisterToken]] } cell that is an element of finalizationRegistry.[[Cells]], do
+ a. If SameValue(cell.[[UnregisterToken]], unregisterToken) is true, then
+ i. Remove cell from finalizationRegistry.[[Cells]].
+ ii. Set removed to true.
+ 3. Return removed.
+features: [FinalizationRegistry.prototype.cleanupSome, FinalizationRegistry, host-gc-required]
+includes: [async-gc.js]
+flags: [async, non-deterministic]
+---*/
+
+var token = {};
+var finalizationRegistry = new FinalizationRegistry(function() {});
+
+function emptyCells() {
+ var target = {};
+ finalizationRegistry.register(target, 'target!', token);
+
+ var prom = asyncGC(target);
+ target = null;
+
+ return prom;
+}
+
+emptyCells().then(function() {
+ var called = 0;
+
+ var res = finalizationRegistry.unregister(token);
+ assert.sameValue(res, true, 'unregister target before iterating over it in cleanup');
+
+ finalizationRegistry.cleanupSome(function cb(holding) {
+ called += 1;
+ });
+
+ assert.sameValue(called, 0, 'callback was not called');
+}).then($DONE, resolveAsyncGC);
diff --git a/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/custom-this.js b/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/custom-this.js
new file mode 100644
index 0000000000..1b99dc1917
--- /dev/null
+++ b/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/custom-this.js
@@ -0,0 +1,29 @@
+// |reftest| skip-if(!this.hasOwnProperty('FinalizationRegistry')) -- FinalizationRegistry is not enabled unconditionally
+// 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 values applying custom this
+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.
+features: [FinalizationRegistry.prototype.cleanupSome, FinalizationRegistry]
+---*/
+
+var fn = function() {};
+var cleanupSome = FinalizationRegistry.prototype.cleanupSome;
+var finalizationRegistry = new FinalizationRegistry(fn);
+
+var cb = function() {};
+
+assert.sameValue(cleanupSome.call(finalizationRegistry, cb), undefined);
+assert.sameValue(cleanupSome.call(finalizationRegistry, fn), undefined), 'reuse the same cleanup callback fn';
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/holdings-multiple-values.js b/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/holdings-multiple-values.js
new file mode 100644
index 0000000000..4c8d99b11a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/holdings-multiple-values.js
@@ -0,0 +1,70 @@
+// |reftest| skip-if(!this.hasOwnProperty('FinalizationRegistry')) async -- FinalizationRegistry is not enabled unconditionally
+// 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: >
+ Iterates over different type values in holdings
+info: |
+ FinalizationRegistry.prototype.cleanupSome ( [ callback ] )
+
+ 1. Let finalizationRegistry be the this value.
+ ...
+ 5. Perform ! CleanupFinalizationRegistry(finalizationRegistry, callback).
+ ...
+
+ CleanupFinalizationRegistry ( finalizationRegistry [ , callback ] )
+
+ ...
+ 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. Perform ? Call(callback, undefined, << cell.[[HeldValue]] >>).
+ ...
+
+
+features: [FinalizationRegistry.prototype.cleanupSome, FinalizationRegistry, Symbol, host-gc-required]
+includes: [async-gc.js]
+flags: [async, non-deterministic]
+---*/
+
+function check(value, expectedName) {
+ var holdings = [];
+ var called = 0;
+ var finalizationRegistry = new FinalizationRegistry(function() {});
+
+ function callback(holding) {
+ called += 1;
+ holdings.push(holding);
+ }
+
+ // This is internal to avoid conflicts
+ function emptyCells(value) {
+ var target = {};
+ finalizationRegistry.register(target, value);
+
+ var prom = asyncGC(target);
+ target = null;
+
+ return prom;
+ }
+
+ return emptyCells(value).then(function() {
+ finalizationRegistry.cleanupSome(callback);
+ assert.sameValue(called, 1, expectedName);
+ assert.sameValue(holdings.length, 1, expectedName);
+ assert.sameValue(holdings[0], value, expectedName);
+ });
+}
+
+Promise.all([
+ check(undefined, 'undefined'),
+ check(null, 'null'),
+ check('', 'the empty string'),
+ check({}, 'object'),
+ check(42, 'number'),
+ check(true, 'true'),
+ check(false, 'false'),
+ check(Symbol(1), 'symbol'),
+]).then(() => $DONE(), resolveAsyncGC);
diff --git a/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/length.js b/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/length.js
new file mode 100644
index 0000000000..797ecd5694
--- /dev/null
+++ b/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/length.js
@@ -0,0 +1,35 @@
+// |reftest| skip-if(!this.hasOwnProperty('FinalizationRegistry')) -- FinalizationRegistry is not enabled unconditionally
+// 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: FinalizationRegistry.prototype.cleanupSome.length property descriptor
+info: |
+ FinalizationRegistry.prototype.cleanupSome ( [ callback ] )
+
+ 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: [propertyHelper.js]
+features: [FinalizationRegistry.prototype.cleanupSome, FinalizationRegistry]
+---*/
+
+verifyProperty(FinalizationRegistry.prototype.cleanupSome, 'length', {
+ value: 0,
+ writable: false,
+ enumerable: false,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/name.js b/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/name.js
new file mode 100644
index 0000000000..e71415a2c2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/name.js
@@ -0,0 +1,34 @@
+// |reftest| skip-if(!this.hasOwnProperty('FinalizationRegistry')) -- FinalizationRegistry is not enabled unconditionally
+// 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: FinalizationRegistry.prototype.cleanupSome.name property descriptor
+info: |
+ FinalizationRegistry.prototype.cleanupSome.name value and property descriptor
+
+ 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: [propertyHelper.js]
+features: [FinalizationRegistry.prototype.cleanupSome, FinalizationRegistry]
+---*/
+
+verifyProperty(FinalizationRegistry.prototype.cleanupSome, 'name', {
+ value: 'cleanupSome',
+ writable: false,
+ enumerable: false,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/not-a-constructor.js b/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/not-a-constructor.js
new file mode 100644
index 0000000000..12c979cc12
--- /dev/null
+++ b/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/not-a-constructor.js
@@ -0,0 +1,36 @@
+// |reftest| skip-if(!this.hasOwnProperty('FinalizationRegistry')) -- FinalizationRegistry is not enabled unconditionally
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-ecmascript-standard-built-in-objects
+description: >
+ FinalizationRegistry.prototype.cleanupSome does not implement [[Construct]], is not new-able
+info: |
+ ECMAScript Function Objects
+
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified in
+ the description of a particular function.
+
+ sec-evaluatenew
+
+ ...
+ 7. If IsConstructor(constructor) is false, throw a TypeError exception.
+ ...
+includes: [isConstructor.js]
+features: [Reflect.construct, FinalizationRegistry, FinalizationRegistry.prototype.cleanupSome, arrow-function]
+---*/
+
+assert.sameValue(
+ isConstructor(FinalizationRegistry.prototype.cleanupSome),
+ false,
+ 'isConstructor(FinalizationRegistry.prototype.cleanupSome) must return false'
+);
+
+assert.throws(TypeError, () => {
+ let fr = new FinalizationRegistry(() => {}); new fr.cleanupSome(() => {});
+}, '`let fr = new FinalizationRegistry(() => {}); new fr.cleanupSome(() => {})` throws TypeError');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/prop-desc.js b/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/prop-desc.js
new file mode 100644
index 0000000000..f942e2c1a4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/prop-desc.js
@@ -0,0 +1,27 @@
+// |reftest| skip-if(!this.hasOwnProperty('FinalizationRegistry')) -- FinalizationRegistry is not enabled unconditionally
+// 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: >
+ Property descriptor of FinalizationRegistry.prototype.cleanupSome
+info: |
+ 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]
+features: [FinalizationRegistry.prototype.cleanupSome, FinalizationRegistry]
+---*/
+
+assert.sameValue(typeof FinalizationRegistry.prototype.cleanupSome, 'function');
+
+verifyProperty(FinalizationRegistry.prototype, 'cleanupSome', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/reentrancy.js b/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/reentrancy.js
new file mode 100644
index 0000000000..ebecca0725
--- /dev/null
+++ b/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/reentrancy.js
@@ -0,0 +1,52 @@
+// |reftest| skip-if(!this.hasOwnProperty('FinalizationRegistry')) async -- FinalizationRegistry is not enabled unconditionally
+// 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 cleanupSome() method can be reentered
+info: |
+ FinalizationRegistry.prototype.cleanupSome ( [ callback ] )
+
+features: [FinalizationRegistry.prototype.cleanupSome, FinalizationRegistry, host-gc-required]
+includes: [async-gc.js]
+flags: [async, non-deterministic]
+---*/
+
+var called = 0;
+var endOfCall = 0;
+var finalizationRegistry = new FinalizationRegistry(function() {});
+
+function callback(holding) {
+ called += 1;
+
+ if (called === 1) {
+ // Atempt to re-enter the callback.
+ var nestedCallbackRan = false;
+ finalizationRegistry.cleanupSome(() => { nestedCallbackRan = true });
+ assert.sameValue(nestedCallbackRan, true);
+ }
+
+ endOfCall += 1;
+}
+
+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;
+
+ return prom;
+}
+
+emptyCells().then(function() {
+ finalizationRegistry.cleanupSome(callback);
+
+ assert.sameValue(called, 1, 'callback was called');
+ assert.sameValue(endOfCall, 1, 'callback finished');
+}).then($DONE, resolveAsyncGC);
diff --git a/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/return-undefined-with-gc.js b/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/return-undefined-with-gc.js
new file mode 100644
index 0000000000..ef1f04b0e7
--- /dev/null
+++ b/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/return-undefined-with-gc.js
@@ -0,0 +1,67 @@
+// |reftest| skip-if(!this.hasOwnProperty('FinalizationRegistry')) async -- FinalizationRegistry is not enabled unconditionally
+// 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 undefined regardless the result of 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.
+features: [FinalizationRegistry.prototype.cleanupSome, FinalizationRegistry, arrow-function, async-functions, async-iteration, class, host-gc-required]
+includes: [async-gc.js]
+flags: [async, non-deterministic]
+---*/
+
+var called;
+var fn = function() {
+ called += 1;
+ return 39;
+};
+var cb = function() {
+ called += 1;
+ return 42;
+};
+var finalizationRegistry = new FinalizationRegistry(fn);
+
+function emptyCells() {
+ var target = {};
+ finalizationRegistry.register(target);
+
+ var prom = asyncGC(target);
+ target = null;
+
+ return prom;
+}
+
+emptyCells().then(function() {
+ called = 0;
+ assert.sameValue(finalizationRegistry.cleanupSome(cb), undefined, 'regular callback');
+ assert.sameValue(called, 1);
+}).then(emptyCells).then(function() {
+ called = 0;
+ assert.sameValue(finalizationRegistry.cleanupSome(fn), undefined, 'regular callback, same FG cleanup function');
+ assert.sameValue(called, 1);
+}).then(emptyCells).then(function() {
+ called = 0;
+ assert.sameValue(finalizationRegistry.cleanupSome(), undefined, 'undefined (implicit) callback, defer to FB callback');
+ assert.sameValue(called, 1);
+}).then(emptyCells).then(function() {
+ called = 0;
+ assert.sameValue(finalizationRegistry.cleanupSome(undefined), undefined, 'undefined (explicit) callback, defer to FB callback');
+ assert.sameValue(called, 1);
+}).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');
+}).then(emptyCells).then(function() {
+ assert.sameValue(finalizationRegistry.cleanupSome(function *() {}), undefined, 'generator');
+}).then(emptyCells).then(function() {
+ assert.sameValue(finalizationRegistry.cleanupSome(async function *() {}), undefined, 'async generator');
+}).then($DONE, resolveAsyncGC);
diff --git a/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/return-undefined.js b/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/return-undefined.js
new file mode 100644
index 0000000000..6a5ff5a6e5
--- /dev/null
+++ b/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/return-undefined.js
@@ -0,0 +1,44 @@
+// |reftest| skip-if(!this.hasOwnProperty('FinalizationRegistry')) -- FinalizationRegistry is not enabled unconditionally
+// 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 undefined regardless the result of 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.
+features: [FinalizationRegistry.prototype.cleanupSome, FinalizationRegistry, arrow-function, async-functions, async-iteration, class]
+---*/
+
+var fn = function() {};
+var cb = function() {};
+var poisoned = function() { throw new Test262Error(); };
+var finalizationRegistry = new FinalizationRegistry(fn);
+
+assert.sameValue(finalizationRegistry.cleanupSome(cb), undefined, 'regular callback');
+assert.sameValue(finalizationRegistry.cleanupSome(fn), undefined, 'regular callback, same FG cleanup function');
+
+assert.sameValue(finalizationRegistry.cleanupSome(() => {}), undefined, 'arrow function');
+assert.sameValue(finalizationRegistry.cleanupSome(finalizationRegistry.cleanupSome), undefined, 'cleanupSome itself');
+assert.sameValue(finalizationRegistry.cleanupSome(poisoned), undefined, 'poisoned');
+assert.sameValue(finalizationRegistry.cleanupSome(class {}), undefined, 'class expression');
+assert.sameValue(finalizationRegistry.cleanupSome(async function() {}), undefined, 'async function');
+assert.sameValue(finalizationRegistry.cleanupSome(function *() {}), undefined, 'generator');
+assert.sameValue(finalizationRegistry.cleanupSome(async function *() {}), undefined, 'async generator');
+
+assert.sameValue(finalizationRegistry.cleanupSome(), undefined, 'undefined, implicit');
+assert.sameValue(finalizationRegistry.cleanupSome(undefined), undefined, 'undefined, explicit');
+
+var poisonedFg = new FinalizationRegistry(poisoned);
+
+assert.sameValue(poisonedFg.cleanupSome(cb), undefined, 'regular callback on poisoned FG cleanup callback');
+assert.sameValue(poisonedFg.cleanupSome(poisoned), undefined, 'poisoned callback on poisoned FG cleanup callback');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/shell.js b/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/shell.js
diff --git a/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/this-does-not-have-internal-cells-throws.js b/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/this-does-not-have-internal-cells-throws.js
new file mode 100644
index 0000000000..267e6d3163
--- /dev/null
+++ b/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/this-does-not-have-internal-cells-throws.js
@@ -0,0 +1,51 @@
+// |reftest| skip-if(!this.hasOwnProperty('FinalizationRegistry')||!this.hasOwnProperty('WeakRef')) -- FinalizationRegistry,WeakRef is not enabled unconditionally
+// 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: Throws a TypeError if this does not have a [[Cells]] internal slot
+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.
+ ...
+features: [FinalizationRegistry.prototype.cleanupSome, WeakSet, WeakMap, FinalizationRegistry, WeakRef]
+---*/
+
+assert.sameValue(typeof FinalizationRegistry.prototype.cleanupSome, 'function');
+
+var cleanupSome = FinalizationRegistry.prototype.cleanupSome;
+var cb = function() {};
+
+assert.throws(TypeError, function() {
+ cleanupSome.call({ ['[[Cells]]']: {} }, cb);
+}, 'Ordinary object without [[Cells]]');
+
+assert.throws(TypeError, function() {
+ cleanupSome.call(WeakRef.prototype, cb);
+}, 'WeakRef.prototype does not have a [[Cells]] internal slot');
+
+assert.throws(TypeError, function() {
+ cleanupSome.call(WeakRef, cb);
+}, 'WeakRef does not have a [[Cells]] internal slot');
+
+var wr = new WeakRef({});
+assert.throws(TypeError, function() {
+ cleanupSome.call(wr, cb);
+}, 'WeakRef instance');
+
+var wm = new WeakMap();
+assert.throws(TypeError, function() {
+ cleanupSome.call(wm, cb);
+}, 'WeakMap instance');
+
+var ws = new WeakSet();
+assert.throws(TypeError, function() {
+ cleanupSome.call(ws, cb);
+}, 'WeakSet instance');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/this-not-object-throws.js b/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/this-not-object-throws.js
new file mode 100644
index 0000000000..0be9066201
--- /dev/null
+++ b/js/src/tests/test262/built-ins/FinalizationRegistry/prototype/cleanupSome/this-not-object-throws.js
@@ -0,0 +1,53 @@
+// |reftest| skip-if(!this.hasOwnProperty('FinalizationRegistry')) -- FinalizationRegistry is not enabled unconditionally
+// 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: Throws a TypeError if this is not an Object
+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.
+ ...
+features: [FinalizationRegistry.prototype.cleanupSome, FinalizationRegistry]
+---*/
+
+assert.sameValue(typeof FinalizationRegistry.prototype.cleanupSome, 'function');
+
+var cleanupSome = FinalizationRegistry.prototype.cleanupSome;
+var cb = function() {};
+
+assert.throws(TypeError, function() {
+ cleanupSome.call(undefined, cb);
+}, 'undefined');
+
+assert.throws(TypeError, function() {
+ cleanupSome.call(null, cb);
+}, 'null');
+
+assert.throws(TypeError, function() {
+ cleanupSome.call(true, cb);
+}, 'true');
+
+assert.throws(TypeError, function() {
+ cleanupSome.call(false, cb);
+}, 'false');
+
+assert.throws(TypeError, function() {
+ cleanupSome.call(1, cb);
+}, 'number');
+
+assert.throws(TypeError, function() {
+ cleanupSome.call('object', cb);
+}, 'string');
+
+var s = Symbol();
+assert.throws(TypeError, function() {
+ cleanupSome.call(s, cb);
+}, 'symbol');
+
+reportCompare(0, 0);