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