-
-
Notifications
You must be signed in to change notification settings - Fork 353
/
DebuggerMethodMapOpal.class.st
93 lines (70 loc) · 2.8 KB
/
DebuggerMethodMapOpal.class.st
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
"
I provide helper methods deadling with
-> pc to text mapping
-> temporary variables for contexts
-> reading and setting tempary variables
All methods here should be moved to MethodContext.
"
Class {
#name : #DebuggerMethodMapOpal,
#superclass : #Object,
#instVars : [
'methodNode'
],
#category : #'OpalCompiler-Core-FrontEnd'
}
{ #category : #'instance creation' }
DebuggerMethodMapOpal class >> forMethod: aMethod [ "<CompiledMethod>"
"Answer a DebuggerMethodMap suitable for debugging activations of aMethod"
^self new forMethod: aMethod
]
{ #category : #initialization }
DebuggerMethodMapOpal >> forMethod: aCompiledMethod [
methodNode := aCompiledMethod ast
]
{ #category : #public }
DebuggerMethodMapOpal >> namedTempAt: index in: aContext [
"Answer the value of the temp at index in aContext where index is relative"
^self tempNamed: (aContext tempNames at: index) in: aContext
]
{ #category : #public }
DebuggerMethodMapOpal >> namedTempAt: index put: aValue in: aContext [
"Assign the value of the temp at index in aContext where index is relative
to the array of temp names
If the value is a copied value we also need to set it along the lexical chain."
^self tempNamed: (aContext tempNames at: index) in: aContext put: aValue
]
{ #category : #initialization }
DebuggerMethodMapOpal >> rangeForPC: aPC contextIsActiveContext: aBoolean [
"return the debug highlight for aPC"
| pc |
"When on the top of the stack the pc is pointing to right instruction, but deeper in the stack
the pc was already advanced one bytecode, so we need to go back this one bytecode, which
can consist of multiple bytes. But on IR, we record the *last* bytecode offset as the offset of the
IR instruction, which means we can just go back one"
pc := aBoolean ifTrue: [aPC] ifFalse: [aPC - 1].
^(methodNode sourceNodeForPC: pc) debugHighlightRange
]
{ #category : #public }
DebuggerMethodMapOpal >> tempNamed: name in: aContext [
"Answer the value of the temp with name in aContext"
| scope var |
scope := aContext sourceNodeExecuted scope.
var := scope lookupVar: name.
^var readFromContext: aContext scope: scope.
]
{ #category : #public }
DebuggerMethodMapOpal >> tempNamed: name in: aContext put: aValue [
"Assign the value of the temp with name in aContext
If the value is a copied value we also need to set it along the lexical chain."
| scope var |
scope := aContext sourceNodeExecuted scope.
var := scope lookupVar: name.
^var writeFromContext: aContext scope: scope value: aValue.
]
{ #category : #public }
DebuggerMethodMapOpal >> tempNamesForContext: aContext [
"Answer an Array of all the temp names in scope in aContext starting with
the home's first local (the first argument or first temporary if no arguments)."
^ aContext sourceNodeExecuted scope allTempNames.
]