tor-browser

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

shell.js (15524B)


      1 // GENERATED, DO NOT EDIT
      2 // file: asyncHelpers.js
      3 // Copyright (C) 2022 Igalia, S.L. All rights reserved.
      4 // This code is governed by the BSD license found in the LICENSE file.
      5 /*---
      6 description: |
      7    A collection of assertion and wrapper functions for testing asynchronous built-ins.
      8 defines: [asyncTest, assert.throwsAsync]
      9 ---*/
     10 
     11 /**
     12 * Defines the **sole** asynchronous test of a file.
     13 * @see {@link ../docs/rfcs/async-helpers.md} for background.
     14 *
     15 * @param {Function} testFunc a callback whose returned promise indicates test results
     16 *   (fulfillment for success, rejection for failure)
     17 * @returns {void}
     18 */
     19 function asyncTest(testFunc) {
     20  if (!Object.prototype.hasOwnProperty.call(globalThis, "$DONE")) {
     21    throw new Test262Error("asyncTest called without async flag");
     22  }
     23  if (typeof testFunc !== "function") {
     24    $DONE(new Test262Error("asyncTest called with non-function argument"));
     25    return;
     26  }
     27  try {
     28    testFunc().then(
     29      function () {
     30        $DONE();
     31      },
     32      function (error) {
     33        $DONE(error);
     34      }
     35    );
     36  } catch (syncError) {
     37    $DONE(syncError);
     38  }
     39 }
     40 
     41 /**
     42 * Asserts that a callback asynchronously throws an instance of a particular
     43 * error (i.e., returns a promise whose rejection value is an object referencing
     44 * the constructor).
     45 *
     46 * @param {Function} expectedErrorConstructor the expected constructor of the
     47 *   rejection value
     48 * @param {Function} func the callback
     49 * @param {string} [message] the prefix to use for failure messages
     50 * @returns {Promise<void>} fulfills if the expected error is thrown,
     51 *   otherwise rejects
     52 */
     53 assert.throwsAsync = function (expectedErrorConstructor, func, message) {
     54  return new Promise(function (resolve) {
     55    var fail = function (detail) {
     56      if (message === undefined) {
     57        throw new Test262Error(detail);
     58      }
     59      throw new Test262Error(message + " " + detail);
     60    };
     61    if (typeof expectedErrorConstructor !== "function") {
     62      fail("assert.throwsAsync called with an argument that is not an error constructor");
     63    }
     64    if (typeof func !== "function") {
     65      fail("assert.throwsAsync called with an argument that is not a function");
     66    }
     67    var expectedName = expectedErrorConstructor.name;
     68    var expectation = "Expected a " + expectedName + " to be thrown asynchronously";
     69    var res;
     70    try {
     71      res = func();
     72    } catch (thrown) {
     73      fail(expectation + " but the function threw synchronously");
     74    }
     75    if (res === null || typeof res !== "object" || typeof res.then !== "function") {
     76      fail(expectation + " but result was not a thenable");
     77    }
     78    var onResFulfilled, onResRejected;
     79    var resSettlementP = new Promise(function (onFulfilled, onRejected) {
     80      onResFulfilled = onFulfilled;
     81      onResRejected = onRejected;
     82    });
     83    try {
     84      res.then(onResFulfilled, onResRejected)
     85    } catch (thrown) {
     86      fail(expectation + " but .then threw synchronously");
     87    }
     88    resolve(resSettlementP.then(
     89      function () {
     90        fail(expectation + " but no exception was thrown at all");
     91      },
     92      function (thrown) {
     93        var actualName;
     94        if (thrown === null || typeof thrown !== "object") {
     95          fail(expectation + " but thrown value was not an object");
     96        } else if (thrown.constructor !== expectedErrorConstructor) {
     97          actualName = thrown.constructor.name;
     98          if (expectedName === actualName) {
     99            fail(expectation +
    100              " but got a different error constructor with the same name");
    101          }
    102          fail(expectation + " but got a " + actualName);
    103        }
    104      }
    105    ));
    106  });
    107 };
    108 
    109 // file: atomicsHelper.js
    110 // Copyright (C) 2017 Mozilla Corporation.  All rights reserved.
    111 // This code is governed by the BSD license found in the LICENSE file.
    112 /*---
    113 description: >
    114    Collection of functions used to interact with Atomics.* operations across agent boundaries.
    115 defines:
    116  - $262.agent.getReportAsync
    117  - $262.agent.getReport
    118  - $262.agent.safeBroadcastAsync
    119  - $262.agent.safeBroadcast
    120  - $262.agent.setTimeout
    121  - $262.agent.tryYield
    122  - $262.agent.trySleep
    123 ---*/
    124 
    125 /**
    126 * @return {String} A report sent from an agent.
    127 */
    128 {
    129  // This is only necessary because the original
    130  // $262.agent.getReport API was insufficient.
    131  //
    132  // All runtimes currently have their own
    133  // $262.agent.getReport which is wrong, so we
    134  // will pave over it with a corrected version.
    135  //
    136  // Binding $262.agent is necessary to prevent
    137  // breaking SpiderMonkey's $262.agent.getReport
    138  let getReport = $262.agent.getReport.bind($262.agent);
    139 
    140  $262.agent.getReport = function() {
    141    var r;
    142    while ((r = getReport()) == null) {
    143      $262.agent.sleep(1);
    144    }
    145    return r;
    146  };
    147 
    148  if (this.setTimeout === undefined) {
    149    (function(that) {
    150      that.setTimeout = function(callback, delay) {
    151        let p = Promise.resolve();
    152        let start = Date.now();
    153        let end = start + delay;
    154        function check() {
    155          if ((end - Date.now()) > 0) {
    156            p.then(check);
    157          }
    158          else {
    159            callback();
    160          }
    161        }
    162        p.then(check);
    163      }
    164    })(this);
    165  }
    166 
    167  $262.agent.setTimeout = setTimeout;
    168 
    169  $262.agent.getReportAsync = function() {
    170    return new Promise(function(resolve) {
    171      (function loop() {
    172        let result = getReport();
    173        if (!result) {
    174          setTimeout(loop, 1000);
    175        } else {
    176          resolve(result);
    177        }
    178      })();
    179    });
    180  };
    181 }
    182 
    183 /**
    184 *
    185 * Share a given Int32Array or BigInt64Array to all running agents. Ensure that the
    186 * provided TypedArray is a "shared typed array".
    187 *
    188 * NOTE: Migrating all tests to this API is necessary to prevent tests from hanging
    189 * indefinitely when a SAB is sent to a worker but the code in the worker attempts to
    190 * create a non-sharable TypedArray (something that is not Int32Array or BigInt64Array).
    191 * When that scenario occurs, an exception is thrown and the agent worker can no
    192 * longer communicate with any other threads that control the SAB. If the main
    193 * thread happens to be spinning in the $262.agent.waitUntil() while loop, it will never
    194 * meet its termination condition and the test will hang indefinitely.
    195 *
    196 * Because we've defined $262.agent.broadcast(SAB) in
    197 * https://github.com/tc39/test262/blob/HEAD/INTERPRETING.md, there are host implementations
    198 * that assume compatibility, which must be maintained.
    199 *
    200 *
    201 * $262.agent.safeBroadcast(TA) should not be included in
    202 * https://github.com/tc39/test262/blob/HEAD/INTERPRETING.md
    203 *
    204 *
    205 * @param {(Int32Array|BigInt64Array)} typedArray An Int32Array or BigInt64Array with a SharedArrayBuffer
    206 */
    207 $262.agent.safeBroadcast = function(typedArray) {
    208  let Constructor = Object.getPrototypeOf(typedArray).constructor;
    209  let temp = new Constructor(
    210    new SharedArrayBuffer(Constructor.BYTES_PER_ELEMENT)
    211  );
    212  try {
    213    // This will never actually wait, but that's fine because we only
    214    // want to ensure that this typedArray CAN be waited on and is shareable.
    215    Atomics.wait(temp, 0, Constructor === Int32Array ? 1 : BigInt(1));
    216  } catch (error) {
    217    throw new Test262Error(`${Constructor.name} cannot be used as a shared typed array. (${error})`);
    218  }
    219 
    220  $262.agent.broadcast(typedArray.buffer);
    221 };
    222 
    223 $262.agent.safeBroadcastAsync = async function(ta, index, expected) {
    224  await $262.agent.broadcast(ta.buffer);
    225  await $262.agent.waitUntil(ta, index, expected);
    226  await $262.agent.tryYield();
    227  return await Atomics.load(ta, index);
    228 };
    229 
    230 
    231 /**
    232 * With a given Int32Array or BigInt64Array, wait until the expected number of agents have
    233 * reported themselves by calling:
    234 *
    235 *    Atomics.add(typedArray, index, 1);
    236 *
    237 * @param {(Int32Array|BigInt64Array)} typedArray An Int32Array or BigInt64Array with a SharedArrayBuffer
    238 * @param {number} index    The index of which all agents will report.
    239 * @param {number} expected The number of agents that are expected to report as active.
    240 */
    241 $262.agent.waitUntil = function(typedArray, index, expected) {
    242 
    243  var agents = 0;
    244  while ((agents = Atomics.load(typedArray, index)) !== expected) {
    245    /* nothing */
    246  }
    247  assert.sameValue(agents, expected, "Reporting number of 'agents' equals the value of 'expected'");
    248 };
    249 
    250 /**
    251 * Timeout values used throughout the Atomics tests. All timeouts are specified in milliseconds.
    252 *
    253 * @property {number} yield Used for `$262.agent.tryYield`. Must not be used in other functions.
    254 * @property {number} small Used when agents will always timeout and `Atomics.wake` is not part
    255 *                          of the test semantics. Must be larger than `$262.agent.timeouts.yield`.
    256 * @property {number} long  Used when some agents may timeout and `Atomics.wake` is called on some
    257 *                          agents. The agents are required to wait and this needs to be observable
    258 *                          by the main thread.
    259 * @property {number} huge  Used when `Atomics.wake` is called on all waiting agents. The waiting
    260 *                          must not timeout. The agents are required to wait and this needs to be
    261 *                          observable by the main thread. All waiting agents must be woken by the
    262 *                          main thread.
    263 *
    264 * Usage for `$262.agent.timeouts.small`:
    265 *   const WAIT_INDEX = 0;
    266 *   const RUNNING = 1;
    267 *   const TIMEOUT = $262.agent.timeouts.small;
    268 *   const i32a = new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 2));
    269 *
    270 *   $262.agent.start(`
    271 *     $262.agent.receiveBroadcast(function(sab) {
    272 *       const i32a = new Int32Array(sab);
    273 *       Atomics.add(i32a, ${RUNNING}, 1);
    274 *
    275 *       $262.agent.report(Atomics.wait(i32a, ${WAIT_INDEX}, 0, ${TIMEOUT}));
    276 *
    277 *       $262.agent.leaving();
    278 *     });
    279 *   `);
    280 *   $262.agent.safeBroadcast(i32a.buffer);
    281 *
    282 *   // Wait until the agent was started and then try to yield control to increase
    283 *   // the likelihood the agent has called `Atomics.wait` and is now waiting.
    284 *   $262.agent.waitUntil(i32a, RUNNING, 1);
    285 *   $262.agent.tryYield();
    286 *
    287 *   // The agent is expected to time out.
    288 *   assert.sameValue($262.agent.getReport(), "timed-out");
    289 *
    290 *
    291 * Usage for `$262.agent.timeouts.long`:
    292 *   const WAIT_INDEX = 0;
    293 *   const RUNNING = 1;
    294 *   const NUMAGENT = 2;
    295 *   const TIMEOUT = $262.agent.timeouts.long;
    296 *   const i32a = new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 2));
    297 *
    298 *   for (let i = 0; i < NUMAGENT; i++) {
    299 *     $262.agent.start(`
    300 *       $262.agent.receiveBroadcast(function(sab) {
    301 *         const i32a = new Int32Array(sab);
    302 *         Atomics.add(i32a, ${RUNNING}, 1);
    303 *
    304 *         $262.agent.report(Atomics.wait(i32a, ${WAIT_INDEX}, 0, ${TIMEOUT}));
    305 *
    306 *         $262.agent.leaving();
    307 *       });
    308 *     `);
    309 *   }
    310 *   $262.agent.safeBroadcast(i32a.buffer);
    311 *
    312 *   // Wait until the agents were started and then try to yield control to increase
    313 *   // the likelihood the agents have called `Atomics.wait` and are now waiting.
    314 *   $262.agent.waitUntil(i32a, RUNNING, NUMAGENT);
    315 *   $262.agent.tryYield();
    316 *
    317 *   // Wake exactly one agent.
    318 *   assert.sameValue(Atomics.wake(i32a, WAIT_INDEX, 1), 1);
    319 *
    320 *   // When it doesn't matter how many agents were woken at once, a while loop
    321 *   // can be used to make the test more resilient against intermittent failures
    322 *   // in case even though `tryYield` was called, the agents haven't started to
    323 *   // wait.
    324 *   //
    325 *   // // Repeat until exactly one agent was woken.
    326 *   // var woken = 0;
    327 *   // while ((woken = Atomics.wake(i32a, WAIT_INDEX, 1)) !== 0) ;
    328 *   // assert.sameValue(woken, 1);
    329 *
    330 *   // One agent was woken and the other one timed out.
    331 *   const reports = [$262.agent.getReport(), $262.agent.getReport()];
    332 *   assert(reports.includes("ok"));
    333 *   assert(reports.includes("timed-out"));
    334 *
    335 *
    336 * Usage for `$262.agent.timeouts.huge`:
    337 *   const WAIT_INDEX = 0;
    338 *   const RUNNING = 1;
    339 *   const NUMAGENT = 2;
    340 *   const TIMEOUT = $262.agent.timeouts.huge;
    341 *   const i32a = new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 2));
    342 *
    343 *   for (let i = 0; i < NUMAGENT; i++) {
    344 *     $262.agent.start(`
    345 *       $262.agent.receiveBroadcast(function(sab) {
    346 *         const i32a = new Int32Array(sab);
    347 *         Atomics.add(i32a, ${RUNNING}, 1);
    348 *
    349 *         $262.agent.report(Atomics.wait(i32a, ${WAIT_INDEX}, 0, ${TIMEOUT}));
    350 *
    351 *         $262.agent.leaving();
    352 *       });
    353 *     `);
    354 *   }
    355 *   $262.agent.safeBroadcast(i32a.buffer);
    356 *
    357 *   // Wait until the agents were started and then try to yield control to increase
    358 *   // the likelihood the agents have called `Atomics.wait` and are now waiting.
    359 *   $262.agent.waitUntil(i32a, RUNNING, NUMAGENT);
    360 *   $262.agent.tryYield();
    361 *
    362 *   // Wake all agents.
    363 *   assert.sameValue(Atomics.wake(i32a, WAIT_INDEX), NUMAGENT);
    364 *
    365 *   // When it doesn't matter how many agents were woken at once, a while loop
    366 *   // can be used to make the test more resilient against intermittent failures
    367 *   // in case even though `tryYield` was called, the agents haven't started to
    368 *   // wait.
    369 *   //
    370 *   // // Repeat until all agents were woken.
    371 *   // for (var wokenCount = 0; wokenCount < NUMAGENT; ) {
    372 *   //   var woken = 0;
    373 *   //   while ((woken = Atomics.wake(i32a, WAIT_INDEX)) !== 0) ;
    374 *   //   // Maybe perform an action on the woken agents here.
    375 *   //   wokenCount += woken;
    376 *   // }
    377 *
    378 *   // All agents were woken and none timeout.
    379 *   for (var i = 0; i < NUMAGENT; i++) {
    380 *     assert($262.agent.getReport(), "ok");
    381 *   }
    382 */
    383 $262.agent.timeouts = {
    384  yield: 100,
    385  small: 200,
    386  long: 1000,
    387  huge: 10000,
    388 };
    389 
    390 /**
    391 * Try to yield control to the agent threads.
    392 *
    393 * Usage:
    394 *   const VALUE = 0;
    395 *   const RUNNING = 1;
    396 *   const i32a = new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 2));
    397 *
    398 *   $262.agent.start(`
    399 *     $262.agent.receiveBroadcast(function(sab) {
    400 *       const i32a = new Int32Array(sab);
    401 *       Atomics.add(i32a, ${RUNNING}, 1);
    402 *
    403 *       Atomics.store(i32a, ${VALUE}, 1);
    404 *
    405 *       $262.agent.leaving();
    406 *     });
    407 *   `);
    408 *   $262.agent.safeBroadcast(i32a.buffer);
    409 *
    410 *   // Wait until agent was started and then try to yield control.
    411 *   $262.agent.waitUntil(i32a, RUNNING, 1);
    412 *   $262.agent.tryYield();
    413 *
    414 *   // Note: This result is not guaranteed, but should hold in practice most of the time.
    415 *   assert.sameValue(Atomics.load(i32a, VALUE), 1);
    416 *
    417 * The default implementation simply waits for `$262.agent.timeouts.yield` milliseconds.
    418 */
    419 $262.agent.tryYield = function() {
    420  $262.agent.sleep($262.agent.timeouts.yield);
    421 };
    422 
    423 /**
    424 * Try to sleep the current agent for the given amount of milliseconds. It is acceptable,
    425 * but not encouraged, to ignore this sleep request and directly continue execution.
    426 *
    427 * The default implementation calls `$262.agent.sleep(ms)`.
    428 *
    429 * @param {number} ms Time to sleep in milliseconds.
    430 */
    431 $262.agent.trySleep = function(ms) {
    432  $262.agent.sleep(ms);
    433 };
    434 
    435 // file: detachArrayBuffer.js
    436 // Copyright (C) 2016 the V8 project authors.  All rights reserved.
    437 // This code is governed by the BSD license found in the LICENSE file.
    438 /*---
    439 description: |
    440    A function used in the process of asserting correctness of TypedArray objects.
    441 
    442    $262.detachArrayBuffer is defined by a host.
    443 defines: [$DETACHBUFFER]
    444 ---*/
    445 
    446 function $DETACHBUFFER(buffer) {
    447  if (!$262 || typeof $262.detachArrayBuffer !== "function") {
    448    throw new Test262Error("No method available to detach an ArrayBuffer");
    449  }
    450  $262.detachArrayBuffer(buffer);
    451 }