tor-browser

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

suspended-yield-iterator-close-calls-next.js (3274B)


      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  Generator is closed from suspended-yield state and IteratorClose calls next.
      8 info: |
      9  %IteratorHelperPrototype%.return ( )
     10    ...
     11    5. Let C be ReturnCompletion(undefined).
     12    6. Return ? GeneratorResumeAbrupt(O, C, "Iterator Helper").
     13 
     14  GeneratorResumeAbrupt ( generator, abruptCompletion, generatorBrand )
     15    1. Let state be ? GeneratorValidate(generator, generatorBrand).
     16    ...
     17    4. Assert: state is suspended-yield.
     18    ...
     19    8. Set generator.[[GeneratorState]] to executing.
     20    ...
     21    10. Resume the suspended evaluation of genContext using abruptCompletion as
     22        the result of the operation that suspended it. Let result be the
     23        Completion Record returned by the resumed computation.
     24    ...
     25 
     26  GeneratorValidate ( generator, generatorBrand )
     27    ...
     28    5. Let state be generator.[[GeneratorState]].
     29    6. If state is executing, throw a TypeError exception.
     30    7. Return state.
     31 
     32  IteratorZip ( iters, mode, padding, finishResults )
     33    ...
     34    3. Let closure be a new Abstract Closure with no parameters that captures
     35       iters, iterCount, openIters, mode, padding, and finishResults, and
     36       performs the following steps when called:
     37      ...
     38      b. Repeat,
     39        ...
     40        v. Let completion be Completion(Yield(results)).
     41        vi. If completion is an abrupt completion, then
     42          1. Return ? IteratorCloseAll(openIters, completion).
     43    ...
     44 
     45  IteratorCloseAll ( iters, completion )
     46    1. For each element iter of iters, in reverse List order, do
     47      a. Set completion to Completion(IteratorClose(iter, completion)).
     48    2. Return ? completion.
     49 
     50  IteratorClose ( iteratorRecord, completion )
     51    ...
     52    3. Let innerResult be Completion(GetMethod(iterator, "return")).
     53    4. If innerResult is a normal completion, then
     54      a. Let return be innerResult.[[Value]].
     55      b. If return is undefined, return ? completion.
     56      c. Set innerResult to Completion(Call(return, iterator)).
     57    ...
     58 
     59  %IteratorHelperPrototype%.next ( )
     60    1. Return ? GeneratorResume(this value, undefined, "Iterator Helper").
     61 
     62  GeneratorResume ( generator, value, generatorBrand )
     63    1. Let state be ? GeneratorValidate(generator, generatorBrand).
     64    ...
     65 features: [joint-iteration]
     66 ---*/
     67 
     68 var returnCallCount = 0;
     69 
     70 var underlying = {
     71  next() {
     72    return {value: 123, done: false};
     73  },
     74  return() {
     75    returnCallCount += 1;
     76 
     77    // The generator state is set to "executing", so this `next()` call throws
     78    // a TypeError when `GeneratorResume` performs `GeneratorValidate`.
     79    assert.throws(TypeError, function() {
     80      it.next();
     81    });
     82 
     83    return {};
     84  },
     85 };
     86 
     87 var it = Iterator.zipKeyed({a: underlying});
     88 
     89 // Move generator into "suspended-yield" state.
     90 var result = it.next();
     91 assert.sameValue(result.value.a, 123);
     92 assert.sameValue(result.done, false);
     93 
     94 assert.sameValue(returnCallCount, 0);
     95 
     96 // This `return()` call continues execution in the suspended generator.
     97 var result = it.return();
     98 assert.sameValue(result.value, undefined);
     99 assert.sameValue(result.done, true);
    100 
    101 assert.sameValue(returnCallCount, 1);
    102 
    103 reportCompare(0, 0);