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

Fixing: jump to caret does not keep a correct stack when there are vector arrays to store common variables between methods and blocks #78

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
47 changes: 47 additions & 0 deletions src/Sindarin-Tests/SindarinDebuggerTest.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,16 @@ SindarinDebuggerTest >> methodWithNotEvaluatedBlock [
^ a * 42
]

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

| a block |
block := [ a := a + 1 ].
a := 1.
a := a + 2.
^ a * 42
]

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

Expand Down Expand Up @@ -919,6 +929,43 @@ SindarinDebuggerTest >> testMoveToNodeWhenFromNonInlinedEmbeddedBlockToNodeThatI
self assert: sdbg topStack equals: 2
]

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

| aimedBlock sdbg aimedNode |
sdbg := SindarinDebugger debug: [
self
methodWithNotEvaluatedBlockWhoseCreationIsFirstBytecodeInFirstStatement ].
"We step until the `a * 42` node"
sdbg step.
6 timesRepeat: [ sdbg stepOver ].

self assert: sdbg method identicalTo: self class
>>
#methodWithNotEvaluatedBlockWhoseCreationIsFirstBytecodeInFirstStatement.
self assert: (sdbg readVariableNamed: #a) identicalTo: 3.

"We jump to the node `a + 1` inside the block"
aimedBlock := sdbg methodNode statements first value.
aimedNode := aimedBlock body statements first value.
sdbg moveToNode: aimedNode.

"We are in the block context"
self assert: sdbg method ast identicalTo: aimedBlock.
"The block context can also read #a"
self assert: (sdbg readVariableNamed: #a) identicalTo: 3.

"We step the entire block"
3 timesRepeat: [ sdbg stepOver ].

"We are back in the context method"
self assert: sdbg method identicalTo: self class
>>
#methodWithNotEvaluatedBlockWhoseCreationIsFirstBytecodeInFirstStatement.
"We can still read #a in the method context"
self assert: (sdbg readVariableNamed: #a) identicalTo: 4
]

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

Expand Down
11 changes: 8 additions & 3 deletions src/Sindarin/SindarinDebugger.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -243,13 +243,12 @@ SindarinDebugger >> nextExecutedNodeAfter: aNode [

{ #category : #'API - changes' }
SindarinDebugger >> pc: anInteger [

"Allows to move to the first PC associated to the node to which anInteger is associated. anInteger must be a valid pc in the suspended context"

| nextNode methodNode firstPCOfStatementNode |
"If aimedPC is outside the context PCs range, then an error is signaled"
(anInteger < self method initialPC or: [
anInteger > self method endPC ]) ifTrue: [
(anInteger < self method initialPC or: [
anInteger > self method endPC ]) ifTrue: [
^ NotValidPcError signal ].
methodNode := self methodNode.
nextNode := methodNode sourceNodeForPC: anInteger.
Expand All @@ -261,6 +260,12 @@ SindarinDebugger >> pc: anInteger [
methodNode statements first.
self cleanStack ].
self context pc: firstPCOfStatementNode.

"If the first pc of the first statement is mapped to a block creation. That means that it needs the associated temp vector on top of the stack. The bytecode that pushes this vector on the stack precedes the block creation. So, here, this bytecode is mapped to the method node and has been skipped. Thus, we go back to the previous bytecode to execute it."
self instructionStream willCreateBlock ifTrue: [
self context pc: self instructionStream previousPc.
self stepBytecode ].

self debugSession stepToFirstInterestingBytecodeIn:
self debugSession interruptedProcess.
self skipUpToNode: nextNode
Expand Down
Loading