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