bug1542660-2.js (2235B)
1 // |jit-test| skip-if: !('gc' in this) || !('clearKeptObjects' in this) 2 // In generators, when we exit a lexical scope, its non-aliased bindings go away; 3 // they don't keep their last values gc-alive. 4 5 let cases = [ 6 function* onNormalExitFromFunction_VarBinding() { 7 var tmp = yield 1; 8 consumeValue(tmp); 9 }, 10 11 function* onNormalExitFromFunction_LetBinding() { 12 let tmp = yield 1; 13 consumeValue(tmp); 14 }, 15 16 function* onNormalExitFromBlock() { 17 if (typeof onNormalExitFromBlock === 'function') { 18 let tmp = yield 1; 19 consumeValue(tmp); 20 } 21 yield 2; 22 }, 23 24 function* onNormalExitFromCStyleForLet() { 25 for (let tmp = yield 1; tmp !== null; tmp = null) { 26 consumeValue(tmp); 27 } 28 yield 2; 29 }, 30 31 function* onNormalExitFromForLetOf() { 32 for (let tmp of [yield 1]) { 33 consumeValue(tmp); 34 } 35 yield 2; 36 }, 37 38 function* onNormalExitFromForConstOf() { 39 for (const tmp of [yield 1]) { 40 consumeValue(tmp); 41 } 42 yield 2; 43 }, 44 45 function* onNormalExitFromForConstDestructuringOf() { 46 for (const {a, b, c, d} of [yield 1]) { 47 consumeValue(a); 48 } 49 yield 2; 50 }, 51 52 function* onNormalExitFromForConstArrayDestructuringOf() { 53 for (const [x] of [[yield 1]]) { 54 consumeValue(x); 55 } 56 yield 2; 57 }, 58 59 function* onNormalExitFromBlockInLoop() { 60 for (var i = 0; i < 2; i++) { 61 if (i == 0) { 62 let tmp = yield 1; 63 consumeValue(tmp); 64 } else { 65 yield 2; 66 } 67 } 68 }, 69 70 function* onBreakFromBlock() { 71 x: { 72 let tmp = yield 1; 73 consumeValue(tmp); 74 break x; 75 } 76 yield 2; 77 }, 78 79 function* onExitFromCatchBlock() { 80 try { 81 throw yield 1; 82 } catch (exc) { 83 consumeValue(exc); 84 } 85 yield 2; 86 }, 87 ]; 88 89 var consumeValue; 90 91 function runTest(g) { 92 consumeValue = eval("_ => {}"); 93 94 let generator = g(); 95 let result = generator.next(); 96 assertEq(result.done, false); 97 assertEq(result.value, 1); 98 let object = {}; 99 let weakRef = new WeakRef(object); 100 result = generator.next(object); 101 assertEq(result.value, result.done ? undefined : 2); 102 103 object = null; 104 clearKeptObjects(); 105 gc(); 106 assertEq(weakRef.deref(), undefined); 107 } 108 109 for (let g of cases) { 110 runTest(g); 111 }