disposal-during-non-local-jump-with-async-iterator-close.js (2776B)
1 // |jit-test| skip-if: !getBuildConfiguration("explicit-resource-management"); --enable-explicit-resource-management 2 3 load(libdir + "asserts.js"); 4 5 { 6 const values = []; 7 const iterator = { 8 [Symbol.asyncIterator]: () => ({ 9 i: 0, 10 async return() { 11 values.push("return"); 12 return { done: true }; 13 }, 14 async next() { 15 return { 16 value: { 17 val: this.i++, 18 [Symbol.dispose]() { 19 values.push(this.val); 20 } 21 }, 22 done: false 23 } 24 } 25 }) 26 } 27 28 async function testAsyncReturnsHappenAfterDisposal() { 29 for await (using d of iterator) { 30 if (d.val === 3) { 31 break; 32 } 33 } 34 } 35 36 testAsyncReturnsHappenAfterDisposal(); 37 drainJobQueue(); 38 assertArrayEq(values, [0, 1, 2, 3, "return"]); 39 } 40 41 { 42 const values = []; 43 async function* iterator() { 44 let i = 0; 45 try { 46 while (true) { 47 yield { 48 val: i++, 49 [Symbol.dispose]() { 50 values.push(this.val); 51 } 52 }; 53 } 54 } finally { 55 await new Promise((resolve) => { 56 values.push("return"); 57 resolve(); 58 }); 59 } 60 } 61 62 async function testReturnsHappenAfterAsyncDisposalWithGeneratorWithFinally() { 63 for await (using d of iterator()) { 64 if (d.val === 3) { 65 break; 66 } 67 } 68 } 69 70 testReturnsHappenAfterAsyncDisposalWithGeneratorWithFinally(); 71 drainJobQueue(); 72 assertArrayEq(values, [0, 1, 2, 3, "return"]); 73 } 74 75 { 76 const values = []; 77 const iterator = { 78 [Symbol.asyncIterator]: () => ({ 79 i: 0, 80 async return() { 81 values.push("return"); 82 return { done: true }; 83 }, 84 async next() { 85 return { 86 value: { 87 val: this.i++, 88 [Symbol.dispose]() { 89 values.push(this.val); 90 } 91 }, 92 done: false 93 } 94 } 95 }) 96 } 97 98 async function testReturnsHappenAfterDisposalWithLabels() { 99 outer: for (let action of ['continue', 'break']) { 100 for await (using d of iterator) { 101 const toJump = d.val === 3; 102 switch (action) { 103 case 'continue': 104 if (toJump) { 105 // The line is to force the creation of an environment object. 106 let a = 0, b = () => a; 107 values.push(action); 108 continue outer; 109 } 110 break; 111 case 'break': 112 if (toJump) { 113 let a = 0, b = () => a; 114 values.push(action); 115 break outer; 116 } 117 break; 118 } 119 } 120 } 121 } 122 123 testReturnsHappenAfterDisposalWithLabels(); 124 drainJobQueue(); 125 assertArrayEq(values, [0,1,2,'continue', 3,"return",0,1,2,'break',3,"return"]); 126 }