tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 }