onEnterFrame-generator-01.js (2496B)
1 // Frame properties and methods work in generator-resuming onEnterFrame events. 2 // Also tests onPop events, for good measure. 3 4 let g = newGlobal({newCompartment: true}); 5 g.eval(`\ 6 function* gen(lo, hi) { 7 var a = 1/2; 8 yield a; 9 yield a * a; 10 } 11 `); 12 let dbg = new Debugger; 13 let gw = dbg.addDebuggee(g); 14 15 let hits = 0; 16 let savedScript = null; 17 let savedEnv = null; 18 let savedOffsets = new Set; 19 20 function check(frame) { 21 assertEq(frame.type, "call"); 22 assertEq(frame.constructing, false); 23 assertEq(frame.callee, gw.makeDebuggeeValue(g.gen)); 24 25 // `arguments` elements don't work in resumed generator frames, 26 // because generators don't keep the arguments around. 27 // However, some of this is initialized when the frame.arguments object is 28 // created, so if they are created during the first onEnterFrame or onPop 29 // event, the properties exist, and those events can also see the values. 30 assertEq(frame.arguments.length, args.length); 31 for (var i = 0; i < args.length; i++) { 32 assertEq(frame.arguments.hasOwnProperty(i), true); 33 34 if (hits < 2) 35 assertEq(frame.arguments[i], gw.makeDebuggeeValue(args[i]), `arguments[${i}]`); 36 else 37 assertEq(frame.arguments[i], undefined); 38 } 39 40 if (savedEnv === null) { 41 savedEnv = frame.environment; 42 assertEq(savedScript, null); 43 savedScript = frame.script; 44 } else { 45 assertEq(frame.environment, savedEnv); 46 assertEq(frame.script, savedScript); 47 } 48 let a_expected = hits < 3 ? undefined : 1/2; 49 assertEq(savedEnv.getVariable("a"), a_expected); 50 51 assertEq(frame.onStack, true); 52 53 let pc = frame.offset; 54 assertEq(savedOffsets.has(pc), false); 55 savedOffsets.add(pc); 56 57 assertEq(frame.older, null); 58 assertEq(frame.this, gw.makeDebuggeeValue(g)); 59 assertEq(typeof frame.implementation, "string"); 60 61 // And the moment of truth: 62 assertEq(frame.eval("2 + 2").return, 4); 63 assertEq(frame.eval("a").return, a_expected); 64 assertEq(frame.eval("if (a !== undefined) { assertEq(a < (lo + hi) / 2, true); } 7;").return, 7); 65 } 66 67 dbg.onEnterFrame = frame => { 68 if (frame.type === "eval") 69 return; 70 check(frame); 71 hits++; 72 frame.onPop = completion => { 73 check(frame); 74 hits++; 75 }; 76 }; 77 78 // g.gen ignores the arguments passed to it, but we use them to test 79 // frame.arguments. 80 let args = [0, 10, g, dbg]; 81 for (let v of g.gen(...args)) {} 82 assertEq(hits, 8);