reentrancy.optional.any.js (1480B)
1 // META: script=/common/gc.js 2 // META: script=resources/maybe-garbage-collect.js 3 // ├──> maybeGarbageCollectAndCleanupAsync 4 // └──> resolveGarbageCollection 5 /*--- 6 esid: sec-properties-of-the-finalization-registry-constructor 7 ---*/ 8 9 let called = 0; 10 let endOfCall = 0; 11 let finalizationRegistry = new FinalizationRegistry(function() {}); 12 13 function callback(holding) { 14 called += 1; 15 16 if (called === 1) { 17 // Atempt to re-enter the callback. 18 let nestedCallbackRan = false; 19 finalizationRegistry.cleanupSome(() => { nestedCallbackRan = true }); 20 assert_equals(nestedCallbackRan, true); 21 } 22 23 endOfCall += 1; 24 } 25 26 function emptyCells() { 27 let o1 = {}; 28 let o2 = {}; 29 // Register more than one objects to test reentrancy. 30 finalizationRegistry.register(o1, 'holdings 1'); 31 finalizationRegistry.register(o2, 'holdings 2'); 32 33 let prom = maybeGarbageCollectAndCleanupAsync(o1); 34 o1 = null; 35 36 return prom; 37 } 38 39 promise_test(() => { 40 return (async () => { 41 assert_implements( 42 typeof FinalizationRegistry.prototype.cleanupSome === 'function', 43 'FinalizationRegistry.prototype.cleanupSome is not implemented.' 44 ); 45 await emptyCells(); 46 finalizationRegistry.cleanupSome(callback); 47 48 assert_equals(called, 1, 'callback was called'); 49 assert_equals(endOfCall, 1, 'callback finished'); 50 })().catch(resolveGarbageCollection); 51 }, 'cleanupCallback has only one optional chance to be called for a GC that cleans up a registered target.');