bug1542660.js (1361B)
1 // |jit-test| skip-if: !('gc' in this) || !('clearKeptObjects' in this) 2 // Locals in async functions should not keep objects alive after going out of scope. 3 // Test by Mathieu Hofman. 4 5 let nextId = 0; 6 7 let weakRef; 8 let savedCallback; 9 10 const tests = [ 11 function() { 12 let object = { id: ++nextId }; 13 console.log(`created object ${object.id}`); 14 savedCallback = () => {}; 15 weakRef = new WeakRef(object); 16 }, 17 async function() { 18 let object = { id: ++nextId }; 19 console.log(`created object ${object.id}`); 20 savedCallback = () => {}; 21 weakRef = new WeakRef(object); 22 }, 23 async function() { 24 function* gen() { 25 { 26 let object = { id: ++nextId }; 27 console.log(`created object ${object.id}`); 28 // Yielding here stores the local variable `object` in the generator 29 // object. 30 yield 1; 31 weakRef = new WeakRef(object); 32 } 33 // Yielding here should clear it. 34 yield 2; 35 } 36 let iter = gen(); 37 assertEq(iter.next().value, 1); 38 assertEq(iter.next().value, 2); 39 savedCallback = iter; // Keep the generator alive for GC. 40 } 41 ]; 42 43 (async () => { 44 for (const test of tests) { 45 await test(); 46 assertEq(!!weakRef.deref(), true); 47 clearKeptObjects(); 48 gc(); 49 if (weakRef.deref()) { 50 throw new Error(`object ${nextId} was not collected`); 51 } 52 } 53 })();