@@ -239,6 +239,30 @@ SindarinDebuggerTest >> helperMethodWithBlockWithNoReturn [
239239 ^ 43
240240]
241241
242+ { #category : #helpers }
243+ SindarinDebuggerTest >> helperMethodWithEvaluatedBlock [
244+
245+ | a b block |
246+ a := 1 .
247+ block := [ a := 2 . b := 3 + 2 ].
248+ block value.
249+ ^ 42
250+
251+ ]
252+
253+ { #category : #helpers }
254+ SindarinDebuggerTest >> helperMethodWithSeveralInstructionsInBlock [
255+
256+ | a b block |
257+ a := 3 .
258+ block := [
259+ a := 1 .
260+ b := 2 .
261+ 1 + 2 ].
262+ b := block value.
263+ ^ 42
264+ ]
265+
242266{ #category : #running }
243267SindarinDebuggerTest >> runCaseManaged [
244268 ^ self runCase
@@ -306,6 +330,62 @@ SindarinDebuggerTest >> testAssignmentVariableName [
306330 self assert: scdbg assignmentVariableName equals: #a
307331]
308332
333+ { #category : #tests }
334+ SindarinDebuggerTest >> testCanStillExecuteWhenAimedNodePcIsAfterInAnyContext [
335+
336+ | sdbg aimedNodeInContext aimedNodeOutsideContext |
337+ sdbg := SindarinDebugger debug: [
338+ self helperMethodWithSeveralInstructionsInBlock ].
339+ sdbg
340+ step;
341+ stepOver;
342+ stepOver;
343+ stepOver;
344+ stepThrough;
345+ stepOver.
346+
347+ aimedNodeInContext := sdbg methodNode body statements last.
348+
349+ self assert: sdbg pc
350+ < (sdbg methodNode lastPcForNode: aimedNodeInContext).
351+ self assert: (sdbg canStillExecute: aimedNodeInContext).
352+
353+ aimedNodeOutsideContext := sdbg node methodNode body statements last.
354+
355+ self assert: (sdbg outerMostContextOf: sdbg context) pc
356+ < (sdbg node methodNode lastPcForNode:
357+ aimedNodeOutsideContext).
358+ self assert: (sdbg canStillExecute: aimedNodeOutsideContext)
359+ ]
360+
361+ { #category : #tests }
362+ SindarinDebuggerTest >> testCanStillExecuteWhenAimedNodePcIsBeforeInAnyContext [
363+
364+ | sdbg aimedNodeInContext aimedNodeOutsideContext |
365+ sdbg := SindarinDebugger debug: [
366+ self helperMethodWithSeveralInstructionsInBlock ].
367+ sdbg
368+ step;
369+ stepOver;
370+ stepOver;
371+ stepOver;
372+ stepThrough;
373+ stepOver.
374+
375+ aimedNodeInContext := sdbg methodNode body statements first.
376+
377+ self deny: sdbg pc
378+ < (sdbg methodNode lastPcForNode: aimedNodeInContext).
379+ self deny: (sdbg canStillExecute: aimedNodeInContext).
380+
381+ aimedNodeOutsideContext := sdbg node methodNode body statements second.
382+
383+ self deny: (sdbg outerMostContextOf: sdbg context) pc
384+ < (sdbg node methodNode lastPcForNode:
385+ aimedNodeOutsideContext).
386+ self deny: (sdbg canStillExecute: aimedNodeOutsideContext)
387+ ]
388+
309389{ #category : #tests }
310390SindarinDebuggerTest >> testContext [
311391 | scdbg |
@@ -606,6 +686,56 @@ SindarinDebuggerTest >> testSkipAssignmentWithStoreIntoBytecodePushesReplacement
606686 self assert: a equals: aFormerValue
607687]
608688
689+ { #category : #tests }
690+ SindarinDebuggerTest >> testSkipBlockNode [
691+
692+ | scdbg targetContext |
693+ scdbg := SindarinDebugger debug: [ self helperMethodNonLocalReturn ].
694+
695+ scdbg
696+ step;
697+ step.
698+
699+ self assert: scdbg topStack isBlock.
700+
701+ scdbg stepUntil: [
702+ scdbg node isMessage and : [ scdbg messageSelector = #value ] ].
703+
704+ targetContext := scdbg context sender.
705+ scdbg stepOver.
706+
707+ self assert: scdbg context identicalTo: targetContext.
708+ self assert: scdbg topStack equals: 42 .
709+
710+ scdbg := SindarinDebugger debug: [ self helperMethodNonLocalReturn ].
711+
712+ scdbg
713+ step;
714+ skip.
715+
716+ self assert: scdbg topStack isNil.
717+
718+ scdbg stepUntil: [
719+ scdbg node isMessage and : [ scdbg messageSelector = #value ] ].
720+
721+ targetContext := scdbg context.
722+
723+ scdbg stepOver.
724+
725+ self assert: scdbg context identicalTo: targetContext.
726+ self assert: scdbg topStack equals: 43
727+ ]
728+
729+ { #category : #tests }
730+ SindarinDebuggerTest >> testSkipDoesNotSkipReturn [
731+
732+ | a scdbg |
733+ scdbg := SindarinDebugger debug: [ a := 1 . ^ 42 ].
734+
735+ self shouldnt: [ scdbg skip ] raise: SindarinSkippingReturnWarning .
736+ self should: [ scdbg skip ] raise: SindarinSkippingReturnWarning
737+ ]
738+
609739{ #category : #tests }
610740SindarinDebuggerTest >> testSkipSkipsMessagesByPuttingReceiverOnStack [
611741
@@ -640,16 +770,6 @@ SindarinDebuggerTest >> testSkipSkipsSuperSendBytecodesCorrectly [
640770 self assert: a equals: oldValueOfA
641771]
642772
643- { #category : #tests }
644- SindarinDebuggerTest >> testSkipDoesNotSkipReturn [
645-
646- | a scdbg |
647- scdbg := SindarinDebugger debug: [ a := 1 . ^ 42 ].
648-
649- self shouldnt: [ scdbg skip ] raise: SindarinSkippingReturnWarning .
650- self should: [ scdbg skip ] raise: SindarinSkippingReturnWarning
651- ]
652-
653773{ #category : #tests }
654774SindarinDebuggerTest >> testSkipStepsMethodNodes [
655775
@@ -676,46 +796,6 @@ SindarinDebuggerTest >> testSkipStepsMethodNodes [
676796 self assert: scdbg topStack equals: realTopStack
677797]
678798
679- { #category : #tests }
680- SindarinDebuggerTest >> testSkipBlockNode [
681-
682- | scdbg targetContext |
683- scdbg := SindarinDebugger debug: [ self helperMethodNonLocalReturn ].
684-
685- scdbg
686- step;
687- step.
688-
689- self assert: scdbg topStack isBlock.
690-
691- scdbg stepUntil: [
692- scdbg node isMessage and : [ scdbg messageSelector = #value ] ].
693-
694- targetContext := scdbg context sender.
695- scdbg stepOver.
696-
697- self assert: scdbg context identicalTo: targetContext.
698- self assert: scdbg topStack equals: 42 .
699-
700- scdbg := SindarinDebugger debug: [ self helperMethodNonLocalReturn ].
701-
702- scdbg
703- step;
704- skip.
705-
706- self assert: scdbg topStack isNil.
707-
708- scdbg stepUntil: [
709- scdbg node isMessage and : [ scdbg messageSelector = #value ] ].
710-
711- targetContext := scdbg context.
712-
713- scdbg stepOver.
714-
715- self assert: scdbg context identicalTo: targetContext.
716- self assert: scdbg topStack equals: 43
717- ]
718-
719799{ #category : #' tests - skipping' }
720800SindarinDebuggerTest >> testSkipThroughNode [
721801 | dbg realExecPC realValueOfA targetExecNode realExecTopStack nodeAfterSkipThrough |
@@ -766,6 +846,45 @@ SindarinDebuggerTest >> testSkipToPC [
766846 self assert: dbg topStack equals: realExecTopStack
767847]
768848
849+ { #category : #tests }
850+ SindarinDebuggerTest >> testSkipToPcDoesNotLoopWhenAimedPcIsAfterEndPc [
851+
852+ | sdbg aimedPc pcBeforeSkip |
853+ sdbg := SindarinDebugger debug: [
854+ self helperMethodWithSeveralInstructionsInBlock ].
855+ sdbg
856+ step;
857+ stepOver.
858+
859+ sdbg stepOver.
860+ pcBeforeSkip := sdbg pc.
861+ aimedPc := sdbg context endPC + 1 .
862+
863+ sdbg skipToPC: aimedPc.
864+
865+ self assert: sdbg pc equals: sdbg context endPC.
866+ ]
867+
868+ { #category : #tests }
869+ SindarinDebuggerTest >> testSkipToPcDoesNotLoopWhenAimedPcIsBeforeCurrentPc [
870+
871+ | sdbg aimedPc pcBeforeSkip |
872+ sdbg := SindarinDebugger debug: [
873+ self helperMethodWithSeveralInstructionsInBlock ].
874+ sdbg
875+ step;
876+ stepOver.
877+
878+ aimedPc := sdbg pc.
879+
880+ sdbg stepOver.
881+ pcBeforeSkip := sdbg pc.
882+
883+ sdbg skipToPC: aimedPc.
884+
885+ self assert: sdbg pc equals: pcBeforeSkip.
886+ ]
887+
769888{ #category : #' tests - skipping' }
770889SindarinDebuggerTest >> testSkipUpToNode [
771890 | dbg realExecPC realValueOfA realExecNode realExecTopStack |
@@ -789,8 +908,74 @@ SindarinDebuggerTest >> testSkipUpToNode [
789908 self assert: dbg topStack equals: realExecTopStack
790909]
791910
911+ { #category : #tests }
912+ SindarinDebuggerTest >> testSkipUpToNodeDoesNotLoopWhenAimedNodeIsBeforeCurrentNode [
913+
914+ | sdbg aimedNode nodeBeforeSkip |
915+ sdbg := SindarinDebugger debug: [
916+ self helperMethodWithSeveralInstructionsInBlock ].
917+ sdbg
918+ step;
919+ stepOver.
920+
921+ aimedNode := sdbg node.
922+ sdbg stepOver.
923+ nodeBeforeSkip := sdbg node.
924+
925+ sdbg skipUpToNode: aimedNode.
926+
927+ self assert: sdbg node identicalTo: nodeBeforeSkip
928+ ]
929+
930+ { #category : #' tests - skipping' }
931+ SindarinDebuggerTest >> testSkipUpToNodeInEvaluatedBlock [
932+
933+ | dbg realExecPC realExecNode realExecTopStack oldValueOfA valueOfBAfterSkipAndStep |
934+ self skipOnPharoCITestingEnvironment.
935+ dbg := SindarinDebugger debug: [ self helperMethodWithEvaluatedBlock ].
936+ " after stepping, we stop at the beginning of the block"
937+ dbg
938+ step;
939+ step;
940+ stepOver;
941+ stepOver;
942+ stepOver;
943+ stepThrough.
944+ oldValueOfA := dbg temporaryNamed: #a .
945+ " after stepping, we stop on b: = 3 + 2 assignment node"
946+ dbg stepOver.
947+
948+ self assert: dbg node isMessage.
949+ valueOfBAfterSkipAndStep := dbg node receiver value.
950+
951+ dbg stepOver.
952+
953+ realExecPC := dbg pc.
954+ realExecNode := dbg node.
955+ realExecTopStack := dbg topStack.
956+
957+ dbg := SindarinDebugger debug: [ self helperMethodWithEvaluatedBlock ].
958+
959+ dbg
960+ step;
961+ step;
962+ stepOver;
963+ stepOver;
964+ stepOver;
965+ stepThrough;
966+ skipUpToNode: realExecNode.
967+ self assert: dbg pc equals: realExecPC.
968+ self assert: dbg node identicalTo: realExecNode.
969+ self assert: (dbg temporaryNamed: #a ) equals: oldValueOfA.
970+ self assert: dbg topStack equals: valueOfBAfterSkipAndStep.
971+
972+ dbg stepOver.
973+ " 3 is on the stack so stepping over the assignment should put 3 into b"
974+ self assert: (dbg temporaryNamed: #b ) equals: valueOfBAfterSkipAndStep
975+ ]
976+
792977{ #category : #helpers }
793- SindarinDebuggerTest >> testSkipUpToNodeStopsOnImplicitReturn [
978+ SindarinDebuggerTest >> testSkipUpToNodeStopsOnImplicitReturnIfAimedNodeCanStillBeExecuted [
794979
795980 | scdbg implicitReturnPc implicitReturnNode realExecPc realExecNode |
796981 scdbg := SindarinDebugger debug: [
@@ -821,8 +1006,11 @@ SindarinDebuggerTest >> testSkipUpToNodeStopsOnImplicitReturn [
8211006 stepOver;
8221007 stepOver;
8231008 stepOver;
824- stepThrough;
825- skipUpToNode: realExecNode.
1009+ stepThrough.
1010+
1011+ self assert: (scdbg canStillExecute: realExecNode).
1012+
1013+ scdbg skipUpToNode: realExecNode.
8261014
8271015 self assert: scdbg pc equals: implicitReturnPc.
8281016 self assert: scdbg node identicalTo: implicitReturnNode
0 commit comments