tor-browser

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

job-realm.js (9070B)


      1 // `debugGetQueuedJobs` is available only in debug build.
      2 if (!getBuildConfiguration("debug")) {
      3  quit();
      4 }
      5 
      6 function testOne(func) {
      7  assertEq(debugGetQueuedJobs().length, 0);
      8 
      9  func();
     10 
     11  drainJobQueue();
     12 
     13  assertEq(debugGetQueuedJobs().length, 0);
     14 
     15  if (func.length == 1) {
     16    func({sameCompartmentAs: globalThis});
     17 
     18    drainJobQueue();
     19 
     20    assertEq(debugGetQueuedJobs().length, 0);
     21  }
     22 }
     23 
     24 function assertGlobal(obj, expectedGlobal) {
     25  const global = objectGlobal(obj);
     26  if (global) {
     27    assertEq(global === expectedGlobal, true);
     28  } else {
     29    // obj is a wrapper.
     30    // expectedGlobal should be other global than this.
     31    assertEq(expectedGlobal !== globalThis, true);
     32  }
     33 }
     34 
     35 testOne(() => {
     36  // Just creating a promise shouldn't enqueue any jobs.
     37  Promise.resolve(10);
     38  assertEq(debugGetQueuedJobs().length, 0);
     39 });
     40 
     41 testOne(() => {
     42  // Calling then should create a job for each.
     43  Promise.resolve(10).then(() => {});
     44  Promise.resolve(10).then(() => {});
     45  Promise.resolve(10).then(() => {});
     46 
     47  assertEq(debugGetQueuedJobs().length, 3);
     48 });
     49 
     50 testOne(() => {
     51  // The reaction job should use the function's realm.
     52  Promise.resolve(10).then(() => {});
     53 
     54  var jobs = debugGetQueuedJobs();
     55  assertEq(jobs.length, 1);
     56  assertGlobal(jobs[0], globalThis);
     57 });
     58 
     59 testOne(newGlobalOptions => {
     60  // The reaction job should use the function's realm.
     61  var g = newGlobal(newGlobalOptions);
     62  g.eval(`
     63 Promise.resolve(10).then(() => {});
     64 `);
     65 
     66  var jobs = debugGetQueuedJobs();
     67  assertEq(jobs.length, 1);
     68  assertGlobal(jobs[0], g);
     69 });
     70 
     71 testOne(newGlobalOptions => {
     72  // The reaction job should use the function's realm.
     73  var g = newGlobal(newGlobalOptions);
     74  g.Promise.resolve(10).then(g.eval(`() => {}`));
     75 
     76  var jobs = debugGetQueuedJobs();
     77  assertEq(jobs.length, 1);
     78  assertGlobal(jobs[0], g);
     79 });
     80 
     81 testOne(newGlobalOptions => {
     82  // The reaction job should use the function's realm.
     83  var g = newGlobal(newGlobalOptions);
     84  g.Promise.resolve(10).then(() => {});
     85 
     86  var jobs = debugGetQueuedJobs();
     87  assertEq(jobs.length, 1);
     88  assertGlobal(jobs[0], globalThis);
     89 });
     90 
     91 testOne(newGlobalOptions => {
     92  // The reaction job should use the bound function's target function's realm.
     93  var g = newGlobal(newGlobalOptions);
     94  g.Promise.resolve(10)
     95    .then(Function.prototype.bind.call(g.eval(`() => {}`), this));
     96 
     97  var jobs = debugGetQueuedJobs();
     98  assertEq(jobs.length, 1);
     99  assertGlobal(jobs[0], g);
    100 });
    101 
    102 testOne(newGlobalOptions => {
    103  // The reaction job should use the bound function's target function's realm.
    104  var g = newGlobal(newGlobalOptions);
    105  g.Promise.resolve(10)
    106    .then(g.Function.prototype.bind.call(() => {}, g));
    107 
    108  var jobs = debugGetQueuedJobs();
    109  assertEq(jobs.length, 1);
    110  assertGlobal(jobs[0], globalThis);
    111 });
    112 
    113 testOne(newGlobalOptions => {
    114  // The reaction job should use the bound function's target function's realm,
    115  // recursively
    116  var g = newGlobal(newGlobalOptions);
    117  g.Promise.resolve(10)
    118    .then(
    119      g.Function.prototype.bind.call(
    120        Function.prototype.bind.call(
    121          g.Function.prototype.bind.call(
    122            () => {},
    123            g),
    124          this),
    125        g)
    126    );
    127 
    128  var jobs = debugGetQueuedJobs();
    129  assertEq(jobs.length, 1);
    130  assertGlobal(jobs[0], globalThis);
    131 });
    132 
    133 testOne(newGlobalOptions => {
    134  // The reaction job should use the bound function's target function's realm,
    135  // recursively
    136  var g = newGlobal(newGlobalOptions);
    137  Promise.resolve(10)
    138    .then(
    139      g.Function.prototype.bind.call(
    140        Function.prototype.bind.call(
    141          g.Function.prototype.bind.call(
    142            Function.prototype.bind.call(
    143              g.eval(`() => {}`),
    144              this),
    145            g),
    146          this),
    147        g)
    148    );
    149 
    150  var jobs = debugGetQueuedJobs();
    151  assertEq(jobs.length, 1);
    152  assertGlobal(jobs[0], g);
    153 });
    154 
    155 testOne(newGlobalOptions => {
    156  // The reaction job should use the proxy's target function's realm.
    157  var g = newGlobal(newGlobalOptions);
    158  g.handler = () => {};
    159  g.eval(`
    160 Promise.resolve(10).then(new Proxy(handler, {}));
    161 `);
    162 
    163  var jobs = debugGetQueuedJobs();
    164  assertEq(jobs.length, 1);
    165  assertGlobal(jobs[0], globalThis);
    166 });
    167 
    168 testOne(newGlobalOptions => {
    169  // The reaction job should use the proxy's target function's realm.
    170  var g = newGlobal(newGlobalOptions);
    171  g.eval(`
    172 var handler = () => {};
    173 `);
    174  Promise.resolve(10).then(new Proxy(g.handler, {}));
    175 
    176  var jobs = debugGetQueuedJobs();
    177  assertEq(jobs.length, 1);
    178  assertGlobal(jobs[0], g);
    179 });
    180 
    181 
    182 testOne(newGlobalOptions => {
    183  // The reaction job should use the proxy's target function's realm,
    184  // recursively.
    185  var g = newGlobal(newGlobalOptions);
    186  g.handler = () => {};
    187  g.outerProxy = Proxy;
    188  g.eval(`
    189 Promise.resolve(10).then(
    190  new outerProxy(new Proxy(new outerProxy(new Proxy(handler, {}), {}), {}), {})
    191 );
    192 `);
    193 
    194  var jobs = debugGetQueuedJobs();
    195  assertEq(jobs.length, 1);
    196  assertGlobal(jobs[0], globalThis);
    197 });
    198 
    199 testOne(newGlobalOptions => {
    200  // The reaction job should use the proxy's target function's realm,
    201  // recursively.
    202  var g = newGlobal(newGlobalOptions);
    203  g.eval(`
    204 var handler = () => {};
    205 `);
    206  Promise.resolve(10)
    207    .then(new Proxy(new g.Proxy(new Proxy(g.handler, {}), {}), {}));
    208 
    209  var jobs = debugGetQueuedJobs();
    210  assertEq(jobs.length, 1);
    211  assertGlobal(jobs[0], g);
    212 });
    213 
    214 testOne(() => {
    215  // The thenable job should use the `then` function's realm.
    216  Promise.resolve({
    217    then: () => {}
    218  });
    219 
    220  var jobs = debugGetQueuedJobs();
    221  assertEq(jobs.length, 1);
    222  assertGlobal(jobs[0], globalThis);
    223 });
    224 
    225 testOne(newGlobalOptions => {
    226  // The thenable job should use the `then` function's realm.
    227  var g = newGlobal(newGlobalOptions);
    228  Promise.resolve(g.eval(`
    229 ({
    230  then: () => {}
    231 });
    232 `));
    233 
    234  var jobs = debugGetQueuedJobs();
    235  assertEq(jobs.length, 1);
    236  assertGlobal(jobs[0], g);
    237 });
    238 
    239 testOne(newGlobalOptions => {
    240  // The thenable job should use the `then` function's realm.
    241  var g = newGlobal(newGlobalOptions);
    242  Promise.resolve({
    243    then: g.eval(`() => {}`),
    244  });
    245 
    246  var jobs = debugGetQueuedJobs();
    247  assertEq(jobs.length, 1);
    248  assertGlobal(jobs[0], g);
    249 });
    250 
    251 testOne(newGlobalOptions => {
    252  // The thenable job should use the bound function's target function's realm.
    253  var g = newGlobal(newGlobalOptions);
    254  Promise.resolve({
    255    then: Function.prototype.bind.call(g.eval(`() => {}`), this),
    256  });
    257 
    258  var jobs = debugGetQueuedJobs();
    259  assertEq(jobs.length, 1);
    260  assertGlobal(jobs[0], g);
    261 });
    262 
    263 testOne(newGlobalOptions => {
    264  // The thenable job should use the bound function's target function's realm.
    265  var g = newGlobal(newGlobalOptions);
    266  Promise.resolve({
    267    then: g.Function.prototype.bind.call(() => {}, g),
    268  });
    269 
    270  var jobs = debugGetQueuedJobs();
    271  assertEq(jobs.length, 1);
    272  assertGlobal(jobs[0], globalThis);
    273 });
    274 
    275 testOne(newGlobalOptions => {
    276  // The thenable job should use the bound function's target function's realm,
    277  // recursively.
    278  var g = newGlobal(newGlobalOptions);
    279  Promise.resolve({
    280    then: Function.prototype.bind.call(
    281      g.Function.prototype.bind.call(
    282        Function.prototype.bind.call(
    283          g.eval(`() => {}`),
    284          this),
    285        g),
    286      this)
    287  });
    288 
    289  var jobs = debugGetQueuedJobs();
    290  assertEq(jobs.length, 1);
    291  assertGlobal(jobs[0], g);
    292 });
    293 
    294 testOne(newGlobalOptions => {
    295  // The thenable job should use the bound function's target function's realm,
    296  // recursively.
    297  var g = newGlobal(newGlobalOptions);
    298  Promise.resolve({
    299    then: g.Function.prototype.bind.call(
    300      Function.prototype.bind.call(
    301        g.Function.prototype.bind.call(
    302          () => {},
    303          g),
    304        this),
    305      g),
    306  });
    307 
    308  var jobs = debugGetQueuedJobs();
    309  assertEq(jobs.length, 1);
    310  assertGlobal(jobs[0], globalThis);
    311 });
    312 
    313 testOne(newGlobalOptions => {
    314  // The thenable job should use the proxy's target function's realm.
    315  var g = newGlobal(newGlobalOptions);
    316  Promise.resolve({
    317    then: new Proxy(g.eval(`() => {}`), {}),
    318  });
    319 
    320  var jobs = debugGetQueuedJobs();
    321  assertEq(jobs.length, 1);
    322  assertGlobal(jobs[0], g);
    323 });
    324 
    325 testOne(newGlobalOptions => {
    326  // The thenable job should use the proxy's target function's realm.
    327  var g = newGlobal(newGlobalOptions);
    328  Promise.resolve({
    329    then: new g.Proxy(() => {}, {}),
    330  });
    331 
    332  var jobs = debugGetQueuedJobs();
    333  assertEq(jobs.length, 1);
    334  assertGlobal(jobs[0], globalThis);
    335 });
    336 
    337 testOne(newGlobalOptions => {
    338  // The thenable job should use the proxy's target function's realm,
    339  // recursively.
    340  var g = newGlobal(newGlobalOptions);
    341  Promise.resolve({
    342    then: new Proxy(new g.Proxy(new Proxy(g.eval(`() => {}`), {}), {}), {}),
    343  });
    344 
    345  var jobs = debugGetQueuedJobs();
    346  assertEq(jobs.length, 1);
    347  assertGlobal(jobs[0], g);
    348 });
    349 
    350 testOne(newGlobalOptions => {
    351  // The thenable job should use the proxy's target function's realm,
    352  // recursively.
    353  var g = newGlobal(newGlobalOptions);
    354  Promise.resolve({
    355    then: new g.Proxy(new Proxy(new g.Proxy(() => {}, {}), {}), {}),
    356  });
    357 
    358  var jobs = debugGetQueuedJobs();
    359  assertEq(jobs.length, 1);
    360  assertGlobal(jobs[0], globalThis);
    361 });
    362 
    363 print("ok");