tor-browser

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

iterator-zip-iteration-strict-iterator-step-abrupt-completion.js (3699B)


      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        iii. For each integer i such that 0 ≤ i < iterCount, in ascending order, do
     21          ...
     22          3. Else,
     23            ...
     24            d. If result is done, then
     25              i. Remove iter from openIters.
     26              ...
     27              iii. Else if mode is "strict", then
     28                ...
     29                ii. For each integer k such that 1 ≤ k < iterCount, in ascending order, do
     30                  ...
     31                  ii. Let open be Completion(IteratorStep(iters[k])).
     32                  iii. If open is an abrupt completion, then
     33                    i. Remove iters[k] from openIters.
     34                    ii. Return ? IteratorCloseAll(openIters, open).
     35                  ...
     36 
     37  IteratorCloseAll ( iters, completion )
     38    1. For each element iter of iters, in reverse List order, do
     39       a. Set completion to Completion(IteratorClose(iter, completion)).
     40    2. Return ? completion.
     41 
     42  IteratorClose ( iteratorRecord, completion )
     43    1. Assert: iteratorRecord.[[Iterator]] is an Object.
     44    2. Let iterator be iteratorRecord.[[Iterator]].
     45    3. Let innerResult be Completion(GetMethod(iterator, "return")).
     46    4. If innerResult is a normal completion, then
     47      a. Let return be innerResult.[[Value]].
     48      b. If return is undefined, return ? completion.
     49      c. Set innerResult to Completion(Call(return, iterator)).
     50    5. If completion is a throw completion, return ? completion.
     51    ...
     52 includes: [compareArray.js]
     53 features: [joint-iteration]
     54 ---*/
     55 
     56 function ExpectedError() {}
     57 
     58 var log = [];
     59 
     60 var first = {
     61  next() {
     62    log.push("call first next");
     63    return {done: true};
     64  },
     65  return() {
     66    log.push("unexpected call first return");
     67  }
     68 };
     69 
     70 var second = {
     71  next() {
     72    log.push("call second next");
     73    throw new ExpectedError();
     74  },
     75  return() {
     76    log.push("unexpected call second return");
     77  }
     78 };
     79 
     80 var third = {
     81  next() {
     82    log.push("unexpected call third next");
     83  },
     84  return() {
     85    // Called with the correct receiver and no arguments.
     86    assert.sameValue(this, third);
     87    assert.sameValue(arguments.length, 0);
     88 
     89    // NB: Log after above asserts, because failures aren't propagated.
     90    log.push("call third return");
     91 
     92    // IteratorClose ignores new exceptions when called with a Throw completion.
     93    throw new Test262Error();
     94  }
     95 };
     96 
     97 var fourth = {
     98  next() {
     99    log.push("unexpected call fourth next");
    100  },
    101  return() {
    102    // Called with the correct receiver and no arguments.
    103    assert.sameValue(this, fourth);
    104    assert.sameValue(arguments.length, 0);
    105 
    106    // NB: Log after above asserts, because failures aren't propagated.
    107    log.push("call fourth return");
    108 
    109    // IteratorClose ignores new exceptions when called with a Throw completion.
    110    throw new Test262Error();
    111  }
    112 };
    113 
    114 var it = Iterator.zipKeyed({first, second, third, fourth}, {mode: "strict"});
    115 
    116 assert.throws(ExpectedError, function() {
    117  it.next();
    118 });
    119 
    120 assert.compareArray(log, [
    121  "call first next",
    122  "call second next",
    123  "call fourth return",
    124  "call third return",
    125 ]);
    126 
    127 reportCompare(0, 0);