Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
8647db7
Adding first test when moving cursor to the beginning of a statement,…
adri09070 Jun 29, 2022
3fb6656
implement API to get the statement node that contains an exact subtree
adri09070 Oct 4, 2022
30d24a3
forgot to commit a method
adri09070 Oct 4, 2022
13199b1
Merge 8647db7fd467d669090c7a9d935d2d00615739bf
adri09070 Oct 4, 2022
b1058fc
refactoring statementNodeContaining using propagation to RBMethodNode
adri09070 Oct 4, 2022
bcbda13
tests for changing pc
adri09070 Oct 4, 2022
00fbf26
Allowing `pc :` to move pc, while ensuring that the right number of …
adri09070 Oct 7, 2022
0b8bc14
Adding moveToNode: method for classic cases
adri09070 Oct 10, 2022
74d9c3d
fixing pc: that was always rewinding to initialPC + making it possib…
adri09070 Oct 11, 2022
504de90
making moveToNode: work if the aimed node is a literal value node or …
adri09070 Oct 11, 2022
a496704
Making moveToNode: work when the aimed node is a method node that has…
adri09070 Oct 11, 2022
d1444b8
adding test when changing pc to a non-existing bytecode offset
adri09070 Oct 11, 2022
dc88d04
Implementing logic to enter blocks. It doesn't work because the debug…
adri09070 Oct 17, 2022
94f3452
allowing moveToNode: to enter a block that is not embedded + adding …
adri09070 Oct 17, 2022
8d3025d
skipBlockNode now stepsToFirstInterestingBytecode after skipping the …
adri09070 Oct 21, 2022
a8c4d77
adding a way to skip jumps with skip/skipUpTo
adri09070 Oct 21, 2022
c80a890
adding tests for skipping jumps
adri09070 Oct 21, 2022
32006e3
Adding a forgotten extension method in Context
adri09070 Oct 28, 2022
d740d5f
fixing moveToNode to go on AFTER the block after jumping inside a blo…
adri09070 Oct 28, 2022
d225aa2
making jumpToCaret jump into embedded blocks
adri09070 Oct 28, 2022
cd3390c
making moveToNode exit blocks + tests
adri09070 Nov 2, 2022
f5bfa5a
Merge 32006e39c22a3c239fdc86b7b5f8fe63ea465084
adri09070 Nov 2, 2022
33fbceb
Adding tests that were failing because of skipUpTo bugs
adri09070 Nov 2, 2022
9888805
cleaning code in moveToNode: and pc:
adri09070 Nov 2, 2022
5e3d832
Merge pull request #53 from adri09070/52-SkipUpTo-does-not-stepToFirs…
StevenCostiou Nov 18, 2022
26ca352
refactoring Context>>#stepToSendOrReturnOrJump to make it more readab…
adri09070 Nov 25, 2022
ebbacd0
deleting a useless method call
adri09070 Nov 25, 2022
d88ef2b
simplifying skip using InstructionStream>>#willReturn + adding commen…
adri09070 Nov 25, 2022
bdfc077
refactoring skip to use double dispatch
adri09070 Nov 25, 2022
473e219
Merge branch 'master' into 51-SkipUpTo-enters-an-infinite-loop-when-i…
adri09070 Nov 25, 2022
9791efd
Merge branch 'master' into 30-Request-We-should-have-a-command-to-mov…
adri09070 Feb 3, 2023
96fd175
Merge pull request #54 from adri09070/51-SkipUpTo-enters-an-infinite-…
StevenCostiou Feb 6, 2023
4e2778b
Merge branch 'master' into 30-Request-We-should-have-a-command-to-mov…
adri09070 Feb 6, 2023
9166045
Update RBBlockNode.extension.st
adri09070 Feb 6, 2023
f95a1eb
Update RBProgramNode.extension.st
adri09070 Feb 6, 2023
d1a09a9
classifying extension methods
adri09070 Feb 6, 2023
0f21281
Merge pull request #56 from adri09070/30-Request-We-should-have-a-com…
StevenCostiou Feb 6, 2023
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
860 changes: 860 additions & 0 deletions Sindarin-Tests/SindarinDebuggerTest.class.st

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions Sindarin/Context.extension.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Extension { #name : #Context }

{ #category : #'*Sindarin' }
Context >> stepToSendOrReturnOrJump [

"Simulate the execution of bytecodes until either sending a message or
returning a value to the receiver (that is, until switching contexts)."

| stream context |
stream := InstructionStream on: method pc: pc.
[
self isDead or: [
stream willSendOrReturnOrStoreOrCreateBlock or: [ stream willJump ] ] ]
whileFalse: [
context := stream interpretNextInstructionFor: self.
context == self ifFalse: [ "Caused by mustBeBoolean handling"
^ context ] ]
]
25 changes: 25 additions & 0 deletions Sindarin/DebugSession.extension.st
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,28 @@ Extension { #name : #DebugSession }
DebugSession >> asSindarinDebugSession [
^ SindarinDebugSession new debugSession: self
]

{ #category : #'*Sindarin' }
DebugSession >> stepToFirstInterestingBytecodeWithJumpIn: aProcess [
"After a restart of a method activation step to the first
bytecode instruction that is of interest for the debugger.

In this case step until a bytecode that causes a context switch,
as otherwise one will have to press may time step into without
seeing any visible results."

"If we are are stepping into a quick method,
make sure that we step correctly over the first primitive bytecode"
| suspendedContext |
suspendedContext := aProcess suspendedContext.
(suspendedContext method isQuick and: [ suspendedContext pc == suspendedContext method initialPC ])
ifTrue: [ ^ suspendedContext updatePCForQuickPrimitiveRestart ].

^ aProcess stepToSendOrReturnOrJump
]

{ #category : #'*Sindarin' }
DebugSession >> suspendedContext: aContext [

interruptedContext := aContext
]
38 changes: 38 additions & 0 deletions Sindarin/InstructionStream.extension.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
Extension { #name : #InstructionStream }

{ #category : #'*Sindarin' }
InstructionStream >> willJump [
"Answer whether the next bytecode will jump."

^ self willJumpIfFalse or:[ self willJumpIfTrue or: [ self willJumpTo ] ]
]

{ #category : #'*Sindarin' }
InstructionStream >> willJumpIfFalse [
"Answer whether the next bytecode is a jump-if-false."

^ self method encoderClass isBranchIfFalseAt: pc in: self method
]

{ #category : #'*Sindarin' }
InstructionStream >> willJumpIfTrue [
"Answer whether the next bytecode is a jump-if-false."

^ self method encoderClass isBranchIfTrueAt: pc in: self method
]

{ #category : #'*Sindarin' }
InstructionStream >> willJumpTo [
"Answer whether the next bytecode is a jump-if-false."

^ self method encoderClass isJumpAt: pc in: self method
]

{ #category : #'*Sindarin' }
InstructionStream >> willSendOrReturnOrStoreOrCreateBlock [

"Answer whether the next bytecode will be interesting for the debugger to stop."

^ self willSend or: [
self willReturn or: [ self willStore or: [ self willCreateBlock ] ] ]
]
8 changes: 8 additions & 0 deletions Sindarin/NodeNotInASTError.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"
I am signaled when we try to move the execution to a node that is not in the home context's method ast.
"
Class {
#name : #NodeNotInASTError,
#superclass : #Error,
#category : #'Sindarin-Exceptions'
}
8 changes: 8 additions & 0 deletions Sindarin/NotValidPcError.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"
I am signaled when I try to modify the execution of a context to get to an invalid PC (lower than the method initalPC or greater than the method endPC)
"
Class {
#name : #NotValidPcError,
#superclass : #Error,
#category : #'Sindarin-Exceptions'
}
8 changes: 8 additions & 0 deletions Sindarin/OCBytecodeToASTCache.extension.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Extension { #name : #OCBytecodeToASTCache }

{ #category : #'*Sindarin' }
OCBytecodeToASTCache >> firstRecursiveBcOffsetForStatementNode: aStatementNode [

^ self methodOrBlockNode bcToASTCache bcToASTMap keys sorted detect: [
:key | (self nodeForPC: key) statementNode == aStatementNode ]
]
9 changes: 9 additions & 0 deletions Sindarin/Process.extension.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Extension { #name : #Process }

{ #category : #'*Sindarin' }
Process >> stepToSendOrReturnOrJump [

^Processor activeProcess
evaluate: [suspendedContext := suspendedContext stepToSendOrReturnOrJump]
onBehalfOf: self
]
7 changes: 7 additions & 0 deletions Sindarin/RBAssignmentNode.extension.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Extension { #name : #RBAssignmentNode }

{ #category : #'*Sindarin' }
RBAssignmentNode >> skipWithDebugger: aSindarinDebugger [

aSindarinDebugger skipAssignmentNodeCompletely
]
47 changes: 47 additions & 0 deletions Sindarin/RBBlockNode.extension.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
Extension { #name : #RBBlockNode }

{ #category : #'*Sindarin' }
RBBlockNode >> executedNodesAfter: aNode [

"Gives all nodes that are executed after aNode. Assuming that aNode is a recursive child, then all nodes executed after it are all nodes after it in allChildrenPostOrder"

| nodesAfter indexOfNode |
nodesAfter := self allChildrenPostOrder.
indexOfNode := nodesAfter identityIndexOf: aNode.
nodesAfter := nodesAfter withIndexSelect: [ :value :index |
index > indexOfNode ].
^ nodesAfter
]

{ #category : #'*Sindarin' }
RBBlockNode >> firstPCOfStatement: aStatementNode [

^ self bcToASTCache firstRecursiveBcOffsetForStatementNode: aStatementNode
]

{ #category : #'*Sindarin' }
RBBlockNode >> nextExecutedNodeAfter: aNode [

"Find first node that is after aNode that has an associated pc in method node all children (post-order)"

| indexOfNextNode nodesAfter |
nodesAfter := self executedNodesAfter: aNode.
indexOfNextNode := nodesAfter findFirst: [ :each |
(self firstPcForNode: each) isNotNil ].
^ nodesAfter at: indexOfNextNode
]

{ #category : #'*Sindarin' }
RBBlockNode >> parentOfIdenticalSubtree: subtree [

^ self allChildren reversed
detect: [ :e | e == subtree ]
ifFound: [ :e | e parent ]
ifNone: [ nil ]
]

{ #category : #'*Sindarin' }
RBBlockNode >> skipWithDebugger: aSindarinDebugger [

aSindarinDebugger skipBlockNode
]
7 changes: 7 additions & 0 deletions Sindarin/RBMessageNode.extension.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Extension { #name : #RBMessageNode }

{ #category : #'*Sindarin' }
RBMessageNode >> skipWithDebugger: aSindarinDebugger [

aSindarinDebugger skipMessageNode
]
57 changes: 57 additions & 0 deletions Sindarin/RBMethodNode.extension.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
Extension { #name : #RBMethodNode }

{ #category : #'*Sindarin' }
RBMethodNode >> executedNodesAfter: aNode [

"Gives all nodes that are executed after aNode. Assuming that aNode is a recursive child, then all nodes executed after it are all nodes after it in allChildrenPostOrder"

| nodesAfter indexOfNode |
nodesAfter := self allChildrenPostOrder.
indexOfNode := nodesAfter identityIndexOf: aNode.
nodesAfter := nodesAfter withIndexSelect: [ :value :index |
index > indexOfNode ].
^ nodesAfter
]

{ #category : #'*Sindarin' }
RBMethodNode >> firstPCOfStatement: aStatementNode [

^ self bcToASTCache firstRecursiveBcOffsetForStatementNode: aStatementNode
]

{ #category : #'*Sindarin' }
RBMethodNode >> nextExecutedNodeAfter: aNode [

"Find first node that is after aNode that has an associated pc in method node all children (post-order)"

| indexOfNextNode nodesAfter |
nodesAfter := self executedNodesAfter: aNode.
indexOfNextNode := nodesAfter findFirst: [ :each |
(self firstPcForNode: each) isNotNil ].
^ nodesAfter at: indexOfNextNode
]

{ #category : #'*Sindarin' }
RBMethodNode >> parentOfIdenticalSubtree: subtree [

^ self allChildren reversed
detect: [ :e | e == subtree ]
ifFound: [ :e | e parent ]
ifNone: [ nil ]
]

{ #category : #'*Sindarin' }
RBMethodNode >> statementNodeContaining: aNode [

| statementNode parentOfStatementNode |
statementNode := aNode.
parentOfStatementNode := self parentOfIdenticalSubtree:
statementNode.
parentOfStatementNode
ifNil: [ ^ NodeNotInASTError signal ]
ifNotNil: [
[ parentOfStatementNode isSequence ] whileFalse: [
statementNode := parentOfStatementNode.
parentOfStatementNode := parentOfStatementNode parent ] ].
^ statementNode
]
18 changes: 18 additions & 0 deletions Sindarin/RBProgramNode.extension.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Extension { #name : #RBProgramNode }

{ #category : #'*Sindarin' }
RBProgramNode >> allChildrenPostOrder [

| children |
children := OrderedCollection new.
self children do: [ :each |
each allChildrenPostOrder do: [ :child | children addLast: child ] ].
children addLast: self.
^ children
]

{ #category : #'*Sindarin' }
RBProgramNode >> skipWithDebugger: aSindarinDebugger [

aSindarinDebugger step
]
7 changes: 7 additions & 0 deletions Sindarin/RBReturnNode.extension.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Extension { #name : #RBReturnNode }

{ #category : #'*Sindarin' }
RBReturnNode >> skipWithDebugger: aSindarinDebugger [

aSindarinDebugger skipReturnNode
]
Loading