tor-browser

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

padding-iteration-iterator-close-abrupt-completion.js (3415B)


      1 // Copyright (C) 2025 André Bargull. All rights reserved.
      2 // This code is governed by the BSD license found in the LICENSE file.
      3 
      4 /*---
      5 esid: sec-iterator.zip
      6 description: >
      7  Abrupt completion for IteratorClose in "padding" option iteration.
      8 info: |
      9  Iterator.zip ( iterables [ , options ] )
     10    ...
     11    14. If mode is "longest", then
     12      ...
     13      b. Else,
     14        i. Let paddingIter be Completion(GetIterator(paddingOption, sync)).
     15        ...
     16        v. If usingIterator is true, then
     17          1. Let completion be Completion(IteratorClose(paddingIter, NormalCompletion(unused))).
     18          2. IfAbruptCloseIterators(completion, iters).
     19    ...
     20 
     21  IfAbruptCloseIterators ( value, iteratorRecords )
     22    1. Assert: value is a Completion Record.
     23    2. If value is an abrupt completion, return ? IteratorCloseAll(iteratorRecords, value).
     24    3. Else, set value to value.[[Value]].
     25 
     26  IteratorCloseAll ( iters, completion )
     27    1. For each element iter of iters, in reverse List order, do
     28      a. Set completion to Completion(IteratorClose(iter, completion)).
     29    2. Return ? completion.
     30 
     31  IteratorClose ( iteratorRecord, completion )
     32    1. Assert: iteratorRecord.[[Iterator]] is an Object.
     33    2. Let iterator be iteratorRecord.[[Iterator]].
     34    3. Let innerResult be Completion(GetMethod(iterator, "return")).
     35    4. If innerResult is a normal completion, then
     36      a. Let return be innerResult.[[Value]].
     37      b. If return is undefined, return ? completion.
     38      c. Set innerResult to Completion(Call(return, iterator)).
     39    5. If completion is a throw completion, return ? completion.
     40    ...
     41 includes: [compareArray.js]
     42 features: [joint-iteration]
     43 ---*/
     44 
     45 var log = [];
     46 
     47 var first = {
     48  next() {
     49    log.push("unexpected call to next method");
     50  },
     51  return() {
     52    // Called with the correct receiver and no arguments.
     53    assert.sameValue(this, first);
     54    assert.sameValue(arguments.length, 0);
     55 
     56    // NB: Log after above asserts, because failures aren't propagated.
     57    log.push("first return");
     58 
     59    // This exception is ignored.
     60    throw new Test262Error();
     61  }
     62 };
     63 
     64 var second = {
     65  next() {
     66    log.push("unexpected call to next method");
     67  },
     68  return() {
     69    // Called with the correct receiver and no arguments.
     70    assert.sameValue(this, second);
     71    assert.sameValue(arguments.length, 0);
     72 
     73    // NB: Log after above asserts, because failures aren't propagated.
     74    log.push("second return");
     75 
     76    // This exception is ignored.
     77    throw new Test262Error();
     78  }
     79 };
     80 
     81 var third = {
     82  next() {
     83    log.push("unexpected call to next method");
     84  },
     85  get return() {
     86    // Called with the correct receiver and no arguments.
     87    assert.sameValue(this, third);
     88    assert.sameValue(arguments.length, 0);
     89 
     90    // NB: Log after above asserts, because failures aren't propagated.
     91    log.push("third return");
     92 
     93    // This exception is ignored.
     94    throw new Test262Error();
     95  }
     96 };
     97 
     98 function ExpectedError() {}
     99 
    100 // Padding iterator throws from |Symbol.iterator|.
    101 var padding = {
    102  [Symbol.iterator]() {
    103    return this;
    104  },
    105  next() {
    106    return {done: false};
    107  },
    108  return() {
    109    log.push("padding return");
    110 
    111    throw new ExpectedError();
    112  },
    113 };
    114 
    115 assert.throws(ExpectedError, function() {
    116  Iterator.zip([first, second, third], {mode: "longest", padding});
    117 });
    118 
    119 assert.compareArray(log, [
    120  "padding return",
    121  "third return",
    122  "second return",
    123  "first return",
    124 ]);
    125 
    126 reportCompare(0, 0);