Frame-onStep-generator-resumption-02.js (2252B)
1 // Like Frame-onStep-generator-resumption-01.js, but bail out by throwing. 2 3 let g = newGlobal({newCompartment: true}); 4 g.eval(` 5 function* f() { 6 yield 1; 7 } 8 `); 9 10 // Try force-returning from one of the instructions in `f` before the initial 11 // yield. In detail: 12 // 13 // * This test calls `g.f()` under the Debugger. 14 // * It uses the Debugger to step `ttl` times. 15 // If we reach the initial yield before stepping the `ttl`th time, we're done. 16 // * Otherwise, the test tries to force-return from `f`. 17 // * That's an error, so the uncaughtExceptionHook is called. 18 // * The uncaughtExceptionHook returns a `throw` completion value. 19 // 20 // Returns `true` if we reached the initial yield, false otherwise. 21 // 22 // Note that this function is called in a loop so that every possible relevant 23 // value of `ttl` is tried once. 24 function test(ttl) { 25 let dbg = new Debugger(g); 26 let exiting = false; // we ran out of time-to-live and have forced return 27 let done = false; // we reached the initial yield without forced return 28 let reported = false; // a TypeError was reported. 29 30 dbg.onEnterFrame = frame => { 31 assertEq(frame.callee.name, "f"); 32 dbg.onEnterFrame = undefined; 33 frame.onStep = () => { 34 if (ttl == 0) { 35 exiting = true; 36 // This test case never resumes the generator after the initial 37 // yield. Therefore the initial yield has not happened yet. So this 38 // force-return will be an error. 39 return {return: "ponies"}; 40 } 41 ttl--; 42 }; 43 frame.onPop = completion => { 44 if (!exiting) 45 done = true; 46 }; 47 }; 48 49 dbg.uncaughtExceptionHook = (exc) => { 50 // When onStep returns an invalid resumption value, 51 // the error is reported here. 52 assertEq(exc instanceof TypeError, true); 53 reported = true; 54 return {throw: "FAIL"}; // Bail out of the test. 55 }; 56 57 let result; 58 let caught = undefined; 59 try { 60 result = g.f(); 61 } catch (exc) { 62 caught = exc; 63 } 64 65 if (done) { 66 assertEq(reported, false); 67 assertEq(result instanceof g.f, true); 68 assertEq(caught, undefined); 69 } else { 70 assertEq(reported, true); 71 assertEq(caught, "FAIL"); 72 } 73 74 dbg.enabled = false; 75 return done; 76 } 77 78 for (let ttl = 0; !test(ttl); ttl++) {}