suspended-start-iterator-close-calls-next.js (2557B)
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-start state and IteratorClose calls next. 8 info: | 9 %IteratorHelperPrototype%.return ( ) 10 ... 11 4. If O.[[GeneratorState]] is suspended-start, then 12 a. Set O.[[GeneratorState]] to completed. 13 ... 14 c. Perform ? IteratorCloseAll(O.[[UnderlyingIterators]], ReturnCompletion(undefined)). 15 d. Return CreateIteratorResultObject(undefined, true). 16 ... 17 18 IteratorCloseAll ( iters, completion ) 19 1. For each element iter of iters, in reverse List order, do 20 a. Set completion to Completion(IteratorClose(iter, completion)). 21 2. Return ? completion. 22 23 IteratorClose ( iteratorRecord, completion ) 24 ... 25 3. Let innerResult be Completion(GetMethod(iterator, "return")). 26 4. If innerResult is a normal completion, then 27 a. Let return be innerResult.[[Value]]. 28 b. If return is undefined, return ? completion. 29 c. Set innerResult to Completion(Call(return, iterator)). 30 ... 31 32 %IteratorHelperPrototype%.next ( ) 33 1. Return ? GeneratorResume(this value, undefined, "Iterator Helper"). 34 35 GeneratorResume ( generator, value, generatorBrand ) 36 1. Let state be ? GeneratorValidate(generator, generatorBrand). 37 2. If state is completed, return CreateIteratorResultObject(undefined, true). 38 ... 39 40 GeneratorValidate ( generator, generatorBrand ) 41 ... 42 5. Let state be generator.[[GeneratorState]]. 43 6. If state is executing, throw a TypeError exception. 44 7. Return state. 45 features: [joint-iteration] 46 ---*/ 47 48 var returnCallCount = 0; 49 50 var underlying = { 51 next() { 52 throw new Test262Error("Unexpected call to next"); 53 }, 54 return() { 55 returnCallCount += 1; 56 57 // The generator state is already set to "completed". The generator state is 58 // not "executing", so `GeneratorValidate` succeeds and `GeneratorResume` 59 // returns with `CreateIteratorResultObject()`. 60 var result = it.next(); 61 assert.sameValue(result.value, undefined); 62 assert.sameValue(result.done, true); 63 64 return {}; 65 }, 66 }; 67 68 var it = Iterator.zipKeyed({a: underlying}); 69 70 assert.sameValue(returnCallCount, 0); 71 72 // This `return()` call sets the generator state to "completed" and then calls 73 // `IteratorClose()`. 74 var result = it.return(); 75 assert.sameValue(result.value, undefined); 76 assert.sameValue(result.done, true); 77 78 assert.sameValue(returnCallCount, 1); 79 80 reportCompare(0, 0);