Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: skip up to does not allow to skip return nodes which prevents from skipping up to an inlined if true block if there is an inlined if false block before #75

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions src/Sindarin-Tests/SindarinDebuggerTest.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,18 @@ SindarinDebuggerTest >> methodWithSeveralInstructionsInBlock [
^ 42
]

{ #category : #helpers }
SindarinDebuggerTest >> methodWithSeveralReturns [
"There is only one explicit return but there is also an implicit return after `a := 3`. In that sense, there are several returns in this method"

| a |
a := true.
a
ifFalse: [ ^ a := 1 ]
ifTrue: [ a := 2 ].
a := 3
]

{ #category : #helpers }
SindarinDebuggerTest >> methodWithTwoAssignments [

Expand Down Expand Up @@ -1311,6 +1323,52 @@ SindarinDebuggerTest >> testSkipBlockNode [
self assert: scdbg topStack equals: 43
]

{ #category : #tests }
SindarinDebuggerTest >> testSkipCanSkipReturnIfItIsNotTheLastReturn [

| scdbg |
scdbg := SindarinDebugger debug: [ self methodWithSeveralReturns ].

"we step until we arrive on the node `^ a := 1` in `SindarinDebuggerTest>>#methodWithSeveralReturns`."
scdbg
step;
skip;
skip;
step.

self assert: scdbg node isReturn.
self assert: scdbg topStack equals: 1.

"We skip the return node"
self shouldnt: [ scdbg skip ] raise: SindarinSkippingReturnWarning.

"We should be on the `a := 2` node"
self assert: scdbg node isAssignment.
self assert: scdbg node value value equals: 2
]

{ #category : #tests }
SindarinDebuggerTest >> testSkipCannotSkipReturnIfItIsTheLastReturn [

| scdbg nodeWithImplicitReturn |
scdbg := SindarinDebugger debug: [ self methodWithSeveralReturns ].

"we step until we arrive on the method node in `SindarinDebuggerTest>>#methodWithSeveralReturns`, which is mapped to the implicit return bycode."
scdbg step.
nodeWithImplicitReturn := scdbg methodNode.
3 timesRepeat: [ scdbg step ].

self assert: scdbg node identicalTo: nodeWithImplicitReturn.
self assert: scdbg instructionStream willReturn.

"We skip the return node"
self should: [ scdbg skip ] raise: SindarinSkippingReturnWarning.

"We should still be on the method node"
self assert: scdbg node identicalTo: nodeWithImplicitReturn.
self assert: scdbg instructionStream willReturn
]

{ #category : #tests }
SindarinDebuggerTest >> testSkipDoesNotSkipReturn [

Expand Down
20 changes: 18 additions & 2 deletions src/Sindarin/SindarinDebugger.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -424,8 +424,24 @@ SindarinDebugger >> skipMessageNodeWith: replacementValue [
{ #category : #'stepping - skip' }
SindarinDebugger >> skipReturnNode [

self flag: 'We should be able to skip a return node as long as it''s not the last one in the method'.
^ SindarinSkippingReturnWarning signal: 'Cannot skip a return node'
| node allReturnNodes |
node := self node.

"We collect the list of nodes associated to a return bytecode, via the IR"
allReturnNodes := self method ir children flatCollect: [ :irSequence |
irSequence sequence
select: [ :irInstruction |
irInstruction isReturn ]
thenCollect: [ :irInstruction |
irInstruction sourceNode ] ].
"If this is the last node of the method that is mapped to a return bytecode, we can't skip it and we stop there."
node == allReturnNodes last ifTrue: [
^ SindarinSkippingReturnWarning signal:
'Cannot skip the last return in the method' ].

self skipPcToNextBytecode.
self debugSession stepToFirstInterestingBytecodeWithJumpIn:
self debugSession interruptedProcess
]

{ #category : #'stepping - skip' }
Expand Down
Loading