tor-browser

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

iterator-zip-iteration-iterator-close-abrupt-completion.js (3219B)


      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.zipkeyed
      6 description: >
      7  Handle abrupt completion from IteratorStep in IteratorZip.
      8 info: |
      9  Iterator.zipKeyed ( iterables [ , options ] )
     10    ...
     11    16. Return IteratorZip(iters, mode, padding, finishResults).
     12 
     13  IteratorZip ( iters, mode, padding, finishResults )
     14    3. Let closure be a new Abstract Closure with no parameters that captures
     15       iters, iterCount, openIters, mode, padding, and finishResults, and
     16       performs the following steps when called:
     17      ...
     18      b. Repeat,
     19        ...
     20        v. Let completion be Completion(Yield(results)).
     21        vi. If completion is an abrupt completion, then
     22          1. Return ? IteratorCloseAll(openIters, completion).
     23    ...
     24 
     25  IteratorCloseAll ( iters, completion )
     26    1. For each element iter of iters, in reverse List order, do
     27       a. Set completion to Completion(IteratorClose(iter, completion)).
     28    2. Return ? completion.
     29 
     30  IteratorClose ( iteratorRecord, completion )
     31    1. Assert: iteratorRecord.[[Iterator]] is an Object.
     32    2. Let iterator be iteratorRecord.[[Iterator]].
     33    3. Let innerResult be Completion(GetMethod(iterator, "return")).
     34    4. If innerResult is a normal completion, then
     35      a. Let return be innerResult.[[Value]].
     36      b. If return is undefined, return ? completion.
     37      c. Set innerResult to Completion(Call(return, iterator)).
     38    5. If completion is a throw completion, return ? completion.
     39    ...
     40 includes: [compareArray.js]
     41 features: [joint-iteration]
     42 ---*/
     43 
     44 function ExpectedError() {}
     45 
     46 var log = [];
     47 
     48 var first = {
     49  next() {
     50    log.push("call first next");
     51    return {done: false};
     52  },
     53  return() {
     54    // Called with the correct receiver and no arguments.
     55    assert.sameValue(this, first);
     56    assert.sameValue(arguments.length, 0);
     57 
     58    // NB: Log after above asserts, because failures aren't propagated.
     59    log.push("call first return");
     60 
     61    // IteratorClose ignores new exceptions when called with a Throw completion.
     62    throw new Test262Error();
     63  }
     64 };
     65 
     66 var second = {
     67  next() {
     68    log.push("call second next");
     69    return {done: false};
     70  },
     71  return() {
     72    // Called with the correct receiver and no arguments.
     73    assert.sameValue(this, second);
     74    assert.sameValue(arguments.length, 0);
     75 
     76    // NB: Log after above asserts, because failures aren't propagated.
     77    log.push("call second return");
     78 
     79    throw new ExpectedError();
     80  }
     81 };
     82 
     83 var third = {
     84  next() {
     85    log.push("call third next");
     86    return {done: false};
     87  },
     88  return() {
     89    // Called with the correct receiver and no arguments.
     90    assert.sameValue(this, third);
     91    assert.sameValue(arguments.length, 0);
     92 
     93    // NB: Log after above asserts, because failures aren't propagated.
     94    log.push("call third return");
     95 
     96    return {};
     97  }
     98 };
     99 
    100 var it = Iterator.zipKeyed({first, second, third});
    101 
    102 it.next();
    103 
    104 assert.throws(ExpectedError, function() {
    105  it.return();
    106 });
    107 
    108 assert.compareArray(log, [
    109  "call first next",
    110  "call second next",
    111  "call third next",
    112 
    113  "call third return",
    114  "call second return",
    115  "call first return",
    116 ]);
    117 
    118 reportCompare(0, 0);