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);