Frame-onPop-multiple-01.js (3312B)
1 // Multiple debuggers all get their onPop handlers called. 2 3 function completionsEqual(c1, c2) { 4 if (c1 && c2) { 5 if (c1.throw) 6 return c1.throw === c2.throw; 7 else 8 return c1.return === c2.return; 9 } 10 return c1 === c2; 11 } 12 13 function completionString(c) { 14 if (c == null) 15 return 'x'; 16 if (c.return) 17 return 'r' + c.return; 18 if (c.throw) 19 return 't' + c.throw; 20 return '?'; 21 } 22 23 var g = newGlobal({newCompartment: true}); // poor thing 24 g.eval('function f() { debugger; return "1"; }'); 25 26 // A list of the debuggers' Debugger.Frame instances. When it's all over, 27 // we test that they are all marked as no longer live. 28 var frames = []; 29 30 // We start off the test via Debugger.Frame.prototype.eval, so if we end 31 // with a termination, we still catch it, instead of aborting the whole 32 // test. (Debugger.Object.prototype.executeInGlobal would simplify this...) 33 var dbg0 = new Debugger(g); 34 dbg0.onEnterFrame = function handleOriginalEnter(frame) { 35 dbg0.log += '('; 36 dbg0.onEnterFrame = undefined; 37 38 assertEq(frame.onStack, true); 39 frames.push(frame); 40 41 var dbgs = []; 42 var log; 43 44 // Create a separate debugger to carry out each item in sequence. 45 for (let i = 0; i < 9; i++) { 46 // Each debugger's handlers close over a distinct 'dbg', but 47 // that's the only distinction between them. Otherwise, they're 48 // driven entirely by global data, so the order in which events are 49 // dispatched to them shouldn't matter. 50 let dbg = new Debugger(g); 51 dbgs.push(dbg); 52 53 dbg.onDebuggerStatement = function handleDebuggerStatement(f) { 54 log += 'd'; 55 assertEq(f.onStack, true); 56 frames.push(f); 57 }; 58 59 // First expect the 'eval'... 60 dbg.onEnterFrame = function handleEnterEval(f) { 61 log += 'e'; 62 assertEq(f.type, 'eval'); 63 assertEq(f.onStack, true); 64 frames.push(f); 65 66 // Then expect the call. 67 dbg.onEnterFrame = function handleEnterCall(f) { 68 log += '('; 69 assertEq(f.type, 'call'); 70 assertEq(f.onStack, true); 71 frames.push(f); 72 73 // Don't expect any further frames. 74 dbg.onEnterFrame = function handleExtraEnter(f) { 75 log += 'z'; 76 }; 77 78 f.onPop = function handlePop(c) { 79 log += ')'; 80 assertEq(this.onStack, true); 81 assertEq(completionsEqual(c, { return: '1' }), true); 82 frames.push(this); 83 84 // Check that this debugger is in the list, and then remove it. 85 var i = dbgs.indexOf(dbg); 86 assertEq(i != -1, true); 87 dbgs.splice(i,1); 88 }; 89 }; 90 }; 91 } 92 93 log = ''; 94 assertEq(completionsEqual(frame.eval('f()'), { return: '1' }), true); 95 assertEq(log, "eeeeeeeee(((((((((ddddddddd)))))))))"); 96 97 dbg0.log += '.'; 98 }; 99 100 dbg0.log = ''; 101 g.eval('eval'); 102 assertEq(dbg0.log, '(.'); 103 104 // Check that all Debugger.Frame instances we ran into are now marked as dead. 105 for (var i = 0; i < frames.length; i++) 106 assertEq(frames[i].onStack, false);