From ce61a704e3e8ed031f37c5bcd379d4ec9ae51e14 Mon Sep 17 00:00:00 2001 From: "yurys@chromium.org" Date: Thu, 3 Oct 2013 07:42:44 +0000 Subject: [PATCH] Debug: Allow stepping into on a given call frame. BUG=chromium:296963 R=yangguo@chromium.org, yurys Review URL: https://codereview.chromium.org/25605005 Patch from Andrey Adaikin . git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17095 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/runtime.cc | 7 ++- test/mjsunit/debug-step-4-in-frame.js | 89 +++++++++++++++++++-------- 2 files changed, 68 insertions(+), 28 deletions(-) diff --git a/src/runtime.cc b/src/runtime.cc index 9e3592b1c7..af3c39e45e 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -12610,8 +12610,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_PrepareStep) { return isolate->Throw(isolate->heap()->illegal_argument_string()); } - if (frame_id != StackFrame::NO_ID && step_action != StepNext && - step_action != StepMin && step_action != StepOut) { + if (frame_id != StackFrame::NO_ID && + step_action != StepIn && + step_action != StepNext && + step_action != StepOut && + step_action != StepMin) { return isolate->ThrowIllegalOperation(); } diff --git a/test/mjsunit/debug-step-4-in-frame.js b/test/mjsunit/debug-step-4-in-frame.js index 65ac4902dd..483883adc6 100644 --- a/test/mjsunit/debug-step-4-in-frame.js +++ b/test/mjsunit/debug-step-4-in-frame.js @@ -29,12 +29,17 @@ // Get the Debug object exposed from the debug context global object. Debug = debug.Debug -// Tests how debugger can step over not necessarily in the top frame. +// Tests how debugger can step into/over not necessarily in the top frame. // Simple 3 functions, that protocol their execution state in global // variable state. var state; +function e() { + for (state[3] = 0; state[3] < 5; state[3]++) { + void ("" + e + state[3]); + } +} function f() { var a = 1978; for (state[2] = 0; state[2] < 5; state[2]++) { @@ -43,18 +48,20 @@ function f() { } function g() { for (state[1] = 0; state[1] < 5; state[1]++) { - f(); + f() + e(); } } function h() { - state = [-1, -1, -1]; + state = [-1, -1, -1, -1]; for (state[0] = 0; state[0] < 5; state[0]++) { g(); } } -function TestCase(frame_index, step_count, expected_final_state) { - print("Test case, parameters " + frame_index + "/" + step_count); +function TestCase(frame_index, step_count, expected_final_state, action) { + action = action || Debug.StepAction.StepNext; + print("Test case, parameters " + frame_index + "/" + step_count + + ", action " + action); var listener_exception = null; var state_snapshot; @@ -72,8 +79,7 @@ function TestCase(frame_index, step_count, expected_final_state) { if (frame_index !== undefined) { context_frame = exec_state.frame(frame_index); } - exec_state.prepareStep(Debug.StepAction.StepNext, - step_count, context_frame); + exec_state.prepareStep(action, step_count, context_frame); listener_state = 1; } else if (listener_state == 1) { state_snapshot = String(state); @@ -103,30 +109,61 @@ function TestCase(frame_index, step_count, expected_final_state) { assertEquals(expected_final_state, state_snapshot); } +function TestCase2(frame_index, step_count, expected_final_state) { + return TestCase(frame_index, step_count, expected_final_state, + Debug.StepAction.StepIn); +} // Warm-up -- make sure all is compiled and ready for breakpoint. h(); -// Stepping in the default (top) frame. -TestCase(undefined, 0, "0,0,-1"); -TestCase(undefined, 1, "0,0,-1"); -TestCase(undefined, 2, "0,0,0"); -TestCase(undefined, 5, "0,0,1"); -TestCase(undefined, 8, "0,0,3"); +// Stepping over on the default (top) frame. +TestCase(undefined, 0, "0,0,-1,-1"); +TestCase(undefined, 1, "0,0,-1,-1"); +TestCase(undefined, 2, "0,0,0,-1"); +TestCase(undefined, 5, "0,0,1,-1"); +TestCase(undefined, 8, "0,0,3,-1"); -// Stepping in the frame #0 (should be exactly the same as above). -TestCase(0, 0, "0,0,-1"); -TestCase(0, 1, "0,0,-1"); -TestCase(0, 2, "0,0,0"); -TestCase(0, 5, "0,0,1"); -TestCase(0, 8, "0,0,3"); +// Stepping over on the frame #0 (should be exactly the same as above). +TestCase(0, 0, "0,0,-1,-1"); +TestCase(0, 1, "0,0,-1,-1"); +TestCase(0, 2, "0,0,0,-1"); +TestCase(0, 5, "0,0,1,-1"); +TestCase(0, 8, "0,0,3,-1"); -// Stepping in the frame #1. -TestCase(1, 0, "0,0,5"); -TestCase(1, 3, "0,1,5"); -TestCase(1, 8, "0,4,5"); +// Stepping over on the frame #1. +TestCase(1, 0, "0,0,5,5"); +TestCase(1, 3, "0,1,5,5"); +TestCase(1, 8, "0,4,5,5"); -// Stepping in the frame #2. -TestCase(2, 3, "1,5,5"); -TestCase(2, 8, "4,5,5"); +// Stepping over on the frame #2. +TestCase(2, 3, "1,5,5,5"); +TestCase(2, 8, "4,5,5,5"); + +// Stepping into on the default (top) frame. +TestCase2(undefined, 0, "0,0,-1,-1"); +TestCase2(undefined, 1, "0,0,-1,-1"); +TestCase2(undefined, 2, "0,0,0,-1"); +TestCase2(undefined, 5, "0,0,1,-1"); +TestCase2(undefined, 8, "0,0,3,-1"); + +// Stepping into on the frame #0 (should be exactly the same as above). +TestCase2(0, 0, "0,0,-1,-1"); +TestCase2(0, 1, "0,0,-1,-1"); +TestCase2(0, 2, "0,0,0,-1"); +TestCase2(0, 5, "0,0,1,-1"); +TestCase2(0, 8, "0,0,3,-1"); + +// Stepping into on the frame #1. +TestCase2(1, 0, "0,0,5,-1"); +TestCase2(1, 3, "0,0,5,0"); +TestCase2(1, 8, "0,0,5,2"); +TestCase2(1, 9, "0,0,5,3"); + +// Stepping into on the frame #2. +TestCase2(2, 0, "0,5,5,5"); +TestCase2(2, 3, "1,5,5,5"); +TestCase2(2, 4, "1,0,5,5"); +TestCase2(2, 8, "1,0,0,5"); +TestCase2(2, 9, "1,0,1,5");