@@ -543,6 +543,7 @@ void Debug::ThreadInit() {
543
543
thread_local_.last_statement_position_ = RelocInfo::kNoPosition ;
544
544
thread_local_.step_count_ = 0 ;
545
545
thread_local_.last_fp_ = 0 ;
546
+ thread_local_.queued_step_count_ = 0 ;
546
547
thread_local_.step_into_fp_ = 0 ;
547
548
thread_local_.step_out_fp_ = 0 ;
548
549
thread_local_.after_break_target_ = 0 ;
@@ -958,14 +959,49 @@ Object* Debug::Break(Arguments args) {
958
959
// Clear all current stepping setup.
959
960
ClearStepping ();
960
961
961
- // Notify the debug event listeners.
962
- isolate_->debugger ()->OnDebugBreak (break_points_hit, false );
962
+ if (thread_local_.queued_step_count_ > 0 ) {
963
+ // Perform queued steps
964
+ int step_count = thread_local_.queued_step_count_ ;
965
+
966
+ // Clear queue
967
+ thread_local_.queued_step_count_ = 0 ;
968
+
969
+ PrepareStep (StepNext, step_count);
970
+ } else {
971
+ // Notify the debug event listeners.
972
+ isolate_->debugger ()->OnDebugBreak (break_points_hit, false );
973
+ }
963
974
} else if (thread_local_.last_step_action_ != StepNone) {
964
975
// Hold on to last step action as it is cleared by the call to
965
976
// ClearStepping.
966
977
StepAction step_action = thread_local_.last_step_action_ ;
967
978
int step_count = thread_local_.step_count_ ;
968
979
980
+ // If StepNext goes deeper in code, StepOut until original frame
981
+ // and keep step count queued up in the meantime.
982
+ if (step_action == StepNext && frame->fp () < thread_local_.last_fp_ ) {
983
+ // Count frames until target frame
984
+ int count = 0 ;
985
+ JavaScriptFrameIterator it (isolate_);
986
+ while (!it.done () && it.frame ()->fp () != thread_local_.last_fp_ ) {
987
+ count++;
988
+ it.Advance ();
989
+ }
990
+
991
+ // If we found original frame
992
+ if (it.frame ()->fp () == thread_local_.last_fp_ ) {
993
+ if (step_count > 1 ) {
994
+ // Save old count and action to continue stepping after
995
+ // StepOut
996
+ thread_local_.queued_step_count_ = step_count - 1 ;
997
+ }
998
+
999
+ // Set up for StepOut to reach target frame
1000
+ step_action = StepOut;
1001
+ step_count = count;
1002
+ }
1003
+ }
1004
+
969
1005
// Clear all current stepping setup.
970
1006
ClearStepping ();
971
1007
@@ -1455,6 +1491,13 @@ void Debug::PrepareStep(StepAction step_action, int step_count) {
1455
1491
// steps before reporting break back to the debugger.
1456
1492
bool Debug::StepNextContinue (BreakLocationIterator* break_location_iterator,
1457
1493
JavaScriptFrame* frame) {
1494
+ // StepNext and StepOut shouldn't bring us deeper in code, so last frame
1495
+ // shouldn't be a parent of current frame.
1496
+ if (thread_local_.last_step_action_ == StepNext ||
1497
+ thread_local_.last_step_action_ == StepOut) {
1498
+ if (frame->fp () < thread_local_.last_fp_ ) return true ;
1499
+ }
1500
+
1458
1501
// If the step last action was step next or step in make sure that a new
1459
1502
// statement is hit.
1460
1503
if (thread_local_.last_step_action_ == StepNext ||
0 commit comments