michael@0: // Test that a frame's onStep handler gets called at least once on each line of a function. michael@0: michael@0: var g = newGlobal(); michael@0: var dbg = new Debugger(g); michael@0: michael@0: // When we hit a 'debugger' statement, set offsets to the frame's script's michael@0: // table of line offsets --- a sparse array indexed by line number. Begin michael@0: // single-stepping the current frame; for each source line we hit, delete michael@0: // the line's entry in offsets. Thus, at the end, offsets is an array with michael@0: // an element for each line we did not reach. michael@0: var doSingleStep = true; michael@0: var offsets; michael@0: dbg.onDebuggerStatement = function (frame) { michael@0: var script = frame.script; michael@0: offsets = script.getAllOffsets(); michael@0: print("debugger line: " + script.getOffsetLine(frame.offset)); michael@0: print("original lines: " + uneval(Object.keys(offsets))); michael@0: if (doSingleStep) { michael@0: frame.onStep = function onStepHandler() { michael@0: var line = script.getOffsetLine(this.offset); michael@0: delete offsets[line]; michael@0: }; michael@0: } michael@0: }; michael@0: michael@0: g.eval( michael@0: 'function t(a, b, c) { \n' + michael@0: ' debugger; \n' + michael@0: ' var x = a; \n' + michael@0: ' x += b; \n' + michael@0: ' if (x < 10) \n' + michael@0: ' x -= c; \n' + michael@0: ' return x; \n' + michael@0: '} \n' michael@0: ); michael@0: michael@0: // This should stop at every line but the first of the function. michael@0: g.eval('t(1,2,3)'); michael@0: assertEq(Object.keys(offsets).length, 1); michael@0: michael@0: // This should stop at every line but the first of the function, and the michael@0: // body of the 'if'. michael@0: g.eval('t(10,20,30)'); michael@0: assertEq(Object.keys(offsets).length, 2); michael@0: michael@0: // This shouldn't stop at all. It's the frame that's in single-step mode, michael@0: // not the script, so the prior execution of t in single-step mode should michael@0: // have no effect on this one. michael@0: doSingleStep = false; michael@0: g.eval('t(0, 0, 0)'); michael@0: assertEq(Object.keys(offsets).length, 6); michael@0: doSingleStep = true; michael@0: michael@0: // Single-step in an eval frame. This should reach every line but the michael@0: // first. michael@0: g.eval( michael@0: 'debugger; \n' + michael@0: 'var a=1, b=2, c=3; \n' + michael@0: 'var x = a; \n' + michael@0: 'x += b; \n' + michael@0: 'if (x < 10) \n' + michael@0: ' x -= c; \n' michael@0: ); michael@0: print("final lines: " + uneval(Object.keys(offsets))); michael@0: assertEq(Object.keys(offsets).length, 1); michael@0: michael@0: // Single-step in a global code frame. This should reach every line but the michael@0: // first. michael@0: g.evaluate( michael@0: 'debugger; \n' + michael@0: 'var a=1, b=2, c=3; \n' + michael@0: 'var x = a; \n' + michael@0: 'x += b; \n' + michael@0: 'if (x < 10) \n' + michael@0: ' x -= c; \n' michael@0: ); michael@0: print("final lines: " + uneval(Object.keys(offsets))); michael@0: assertEq(Object.keys(offsets).length, 1);