finalizationRegistry-ccw.js (2577B)
1 // Test combinations of arguments in different compartments. 2 3 gczeal(0); 4 5 let heldValues = []; 6 7 function ccwToObject() { 8 return evalcx('({})', newGlobal({newCompartment: true})); 9 } 10 11 function newRegistry() { 12 return new FinalizationRegistry(value => { 13 heldValues.push(value); 14 }); 15 } 16 17 function ccwToRegistry() { 18 let global = newGlobal({newCompartment: true}); 19 global.heldValues = heldValues; 20 return global.eval( 21 `new FinalizationRegistry(value => heldValues.push(value))`); 22 } 23 24 function incrementalGC() { 25 startgc(1); 26 while (gcstate() !== "NotActive") { 27 gcslice(1000); 28 } 29 } 30 31 const RegistryKinds = ['SameZoneRegistry', 'OtherZoneRegistry']; 32 function makeRegistry(kind) { 33 if (kind === 'SameZoneRegistry') { 34 return new FinalizationRegistry(value => { 35 heldValues.push(value); 36 }); 37 } 38 39 assertEq(kind, 'OtherZoneRegistry'); 40 let global = newGlobal({newCompartment: true}); 41 global.heldValues = heldValues; 42 return global.eval( 43 `new FinalizationRegistry(value => heldValues.push(value))`); 44 return evalcx('({})', newGlobal({newCompartment: true})); 45 } 46 47 const ObjectKinds = ['SameZoneObject', 'OtherZoneObject']; 48 function makeObject(kind) { 49 if (kind === 'SameZoneObject') { 50 return {}; 51 } 52 53 assertEq(kind, 'OtherZoneObject'); 54 return evalcx('({})', newGlobal({newCompartment: true})); 55 } 56 57 for (let registryReachable of [false, true]) { 58 for (let registryKind of RegistryKinds) { 59 for (let targetKind of ObjectKinds) { 60 for (let heldValueKind of ObjectKinds) { 61 for (let tokenKind of ObjectKinds) { 62 let registry = makeRegistry(registryKind); 63 let target = makeObject(targetKind); 64 let heldValue = makeObject(heldValueKind); 65 let token = makeObject(tokenKind); 66 67 registry.register(target, heldValue, token); 68 registry.unregister(token); 69 70 registry.register(target, heldValue, token); 71 72 target = undefined; 73 token = undefined; 74 heldValue = undefined; 75 if (!registryReachable) { 76 registry = undefined; 77 } 78 incrementalGC(); 79 heldValues.length = 0; // Clear, don't replace. 80 drainJobQueue(); 81 82 if (registryReachable) { 83 assertEq(heldValues.length, 1); 84 } else { 85 // The cleanup callback may or may not be run depending on 86 // which order the zones are swept in, which itself depends on 87 // the arrangement of CCWs. 88 assertEq(heldValues.length <= 1, true); 89 } 90 } 91 } 92 } 93 } 94 }