yield-exception-stack-in-finally.js (904B)
1 load(libdir + "asserts.js"); 2 3 var g = newGlobal({newCompartment: true}) 4 5 // Throw an exception from a different compartment. 6 var thrower = g.Function(` 7 throw 0; 8 `); 9 10 function* throwAndYield() { 11 try { 12 thrower(); 13 } finally { 14 // The |finally| block is entered with the exception stack on the function 15 // stack. The function stack is saved in the generator object when executing 16 // |yield|, so the exception stack, which was created in a different 17 // compartment, has to be wrapped into the current compartment. 18 yield; 19 } 20 } 21 assertThrowsValue(() => [...throwAndYield()], 0); 22 23 function* throwAndNuke() { 24 try { 25 thrower(); 26 } finally { 27 // The function stack contains the wrapped exception stack when entering 28 // the |finally| block. When nuking all CCWs it becomes a dead wrapper. 29 nukeAllCCWs(); 30 yield; 31 } 32 } 33 assertThrowsValue(() => [...throwAndNuke()], 0);