/
InstanceVariableSlot.class.st
91 lines (75 loc) · 2.56 KB
/
InstanceVariableSlot.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
"
I add some special behavior:
- I override bytecode generation to generate ivar read and write bytecodes
- I print the definition as #name
If you subclass this class, take note that as it overrides both #emitStore: and #emitValue: to use the fast bytecode, it will *not* call the reflective #read: and #write:to: methods.
"
Class {
#name : #InstanceVariableSlot,
#superclass : #IndexedSlot,
#category : #'Slot-Core-Variables'
}
{ #category : #cleanup }
InstanceVariableSlot class >> resetIvarSlots [
"when the Ivar slots need to be re-created (e.g. due to changes in the layout of the class),
this method re-creates for every ivar a ivar slot"
"to be removed later when the system is in a stable state"
| block |
block := [ :class |
class instVarNames
withIndexDo: [ :ivarName :index |
class classLayout slotScope
at: index
put:
((InstanceVariableSlot named: ivarName asSymbol)
index: index + class superclass allInstVarNames size;
yourself) ] ].
Smalltalk allClasses
do: [ :class |
block value: class.
block value: class classSide ]
]
{ #category : #printing }
InstanceVariableSlot >> definitionString [
"non special globals are defined by the symbol"
^self useFullDefinition
ifTrue: [super definitionString]
ifFalse: [self name printString]
]
{ #category : #'code generation' }
InstanceVariableSlot >> emitStore: methodBuilder [
"generate store bytecode"
methodBuilder storeInstVar: index
]
{ #category : #'code generation' }
InstanceVariableSlot >> emitValue: methodBuilder [
"emit the bytecode to push ivar"
methodBuilder pushInstVar: index.
]
{ #category : #testing }
InstanceVariableSlot >> isAccessedIn: aCompiledCode [
^(aCompiledCode readsField: index) or: [aCompiledCode writesField: index]
]
{ #category : #testing }
InstanceVariableSlot >> isReadIn: aCompiledCode [
^aCompiledCode readsField: index
]
{ #category : #testing }
InstanceVariableSlot >> isWrittenIn: aCompiledCode [
^aCompiledCode writesField: index
]
{ #category : #testing }
InstanceVariableSlot >> useFullDefinition [
"I am just a backward compatible ivar slot and can use simple definitons.
Note: my subclasses need full definitons"
^ self class ~= InstanceVariableSlot
]
{ #category : #queries }
InstanceVariableSlot >> usingMethods [
"All methods that read or write the slot, we can do it here without having to use the AST"
^self definingClass
ifNil: [ #() ]
ifNotNil: [ :definingClass | definingClass withAllSubclasses flatCollect: [:class |
(class whichSelectorsAccess: self name) collect: [:sel |
class compiledMethodAt: sel ]]]
]