-
Notifications
You must be signed in to change notification settings - Fork 67
/
SlangClass.class.st
210 lines (178 loc) · 6.1 KB
/
SlangClass.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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
Class {
#name : #SlangClass,
#superclass : #Object,
#classVars : [
'ExpensiveAsserts'
],
#category : #'Slang-Types'
}
{ #category : #translation }
SlangClass class >> ancilliaryClasses [
"Answer any extra classes to be included in the translation."
^{}
]
{ #category : #translation }
SlangClass class >> declareCVarsIn: aCCodeGenerator [
]
{ #category : #translation }
SlangClass class >> defineAtCompileTime: anObject [
"Override to define at translation time those variables that need to
be defined at compile time only in plugins, but not in the main VM,
because the VM generated is specific to these varables."
^ false
]
{ #category : #translation }
SlangClass class >> isStructClass [
"The various VMStructType classes override this."
^false
]
{ #category : #translation }
SlangClass class >> prepareToBeAddedToCodeGenerator: aCCodeGenerator [
"Hook for translation. e.g. allows a subclass to override its
superclass's methods by deleting them before it adds its own."
]
{ #category : #translation }
SlangClass class >> requiredMethodNames: options [
"Answer a list of method names that should be retained for export or other
support reasons. These are typically entry-points that unless explicitly noted
will be deleted by the code generator since it will assume these are not used."
^#()
]
{ #category : #translation }
SlangClass class >> shouldGenerateDeadCode [
"Answer if the code generator should generate dead code, e.g. in false ifTrue: [dead] ifFalse: [live].
This *may* be useful in debugging (see CCodeGenerator>>nilOrBooleanConstantReceiverOf: et al).
But by default we answer false."
^false
]
{ #category : #translation }
SlangClass class >> typeForSelf [
"Answer the type to give self if appropriate, or nil if not."
^nil
]
{ #category : #'translation support' }
SlangClass >> cCode: codeString [
"Support for Smalltalk-to-C translation.
For translation only; noop when running in Smalltalk.
The argument is output literally when generating C code."
<doNotGenerate>
]
{ #category : #'translation support' }
SlangClass >> cCode: codeStringOrBlock inSmalltalk: aBlock [
"Support for Smalltalk-to-C translation. The first argument is output when generating C code.
But if this code is being simulated in Smalltalk, answer the result of evaluating the given block.
If the first argument is a string it is output literally, and if it is a block it is translated.
N.B. If the first argument is a block then replacement happens at TMethod creation time so the use
of cCode:inSmalltalk: with a block first argument does not prevent inlining and is hence preferred."
<doNotGenerate>
^aBlock value
]
{ #category : #accessing }
SlangClass >> cogitClass [
self subclassResponsibility
]
{ #category : #'translation support' }
SlangClass >> cppIf: conditionBlockOrSymbolValue ifTrue: trueExpressionOrBlock ifFalse: falseExpressionOrBlockOrNil [
"When translated, produces #if (condition) #else #endif CPP directives.
Example usage:
self cppIf: [BytesPerWord = 8]
ifTrue: [self doSomethingFor64Bit]
ifFalse: [self doSomethingFor32Bit]
self cppIf: BytesPerWord = 8
ifTrue: [self doSomethingFor64Bit]
ifFalse: [self doSomethingFor32Bit]
self cppIf: #A_GLOBAL
ifTrue: [self doSomethingFor64Bit]
ifFalse: [self doSomethingFor32Bit]"
<doNotGenerate>
^(conditionBlockOrSymbolValue value
ifNil: [false]
ifNotNil: [:value|
value isInteger
ifTrue: [value ~= 0]
ifFalse:
[value isSymbol
ifTrue: [(self class bindingOf: value)
ifNil: [false]
ifNotNil: [:binding| binding value]]
ifFalse: [value]]])
ifTrue: trueExpressionOrBlock
ifFalse: falseExpressionOrBlockOrNil
]
{ #category : #'C pre-processor extensions' }
SlangClass >> defined: aSymbol [
"Simulated version of the C pre-processor defined()"
<doNotGenerate>
^(self class bindingOf: aSymbol)
ifNil: [false]
ifNotNil: [:binding| binding value ~~ #undefined]
]
{ #category : #'simulation support' }
SlangClass >> deny: aBooleanOrBlock [
<doNotGenerate>
aBooleanOrBlock value ifTrue: [AssertionFailure signal: 'Assertion failed']
]
{ #category : #'debug support' }
SlangClass >> eassert: aBooleanExpressionOrBlock [
"This is for expensive asserts that we're only interested in checking in extremis.
For example now that Spur objStacks are debugged there's no benefit to
evaluating isValidObjStack: throughout the mark loop because its damn slow."
<doNotGenerate>
ExpensiveAsserts ifTrue:
[aBooleanExpressionOrBlock value ifFalse:
[AssertionFailure signal: 'Assertion failed']]
]
{ #category : #'translation support' }
SlangClass >> error [
"Throw a generic Error exception."
^self error: 'Error!'.
]
{ #category : #accessing }
SlangClass >> initializationOptions [
self subclassResponsibility
]
{ #category : #accessing }
SlangClass >> interpreterClass [
self subclassResponsibility
]
{ #category : #accessing }
SlangClass >> objectMemoryClass [
self subclassResponsibility
]
{ #category : #'translation support' }
SlangClass >> simulationOnly: aBlock [
"Evaluate piece of code only during simulation.
This should get translated as a NOP"
<inline: #always>
self
cCode: [ ]
inSmalltalk: aBlock
]
{ #category : #'translation support' }
SlangClass >> sizeof: objectSymbolOrClass [
<doNotGenerate>
| index |
objectSymbolOrClass isInteger ifTrue:
[^self class objectMemoryClass wordSize].
(#(usqInt sqInt) includes: objectSymbolOrClass) ifTrue: [^self class objectMemoryClass bytesPerOop].
objectSymbolOrClass isSymbol ifTrue:
[(objectSymbolOrClass last == $*
or: [#(#long #'unsigned long' #'sqIntptr_t' #'usqIntptr_t' #'size_t') includes: objectSymbolOrClass]) ifTrue:
[^self class objectMemoryClass wordSize].
index := #( #sqLong #usqLong #double
#int #'unsigned int' #float
#short #'unsigned short'
#char #'unsigned char' #'signed char')
indexOf: objectSymbolOrClass
ifAbsent:
[self error: 'unrecognized C type name'].
^#(8 8 8
4 4 4
2 2
1 1 1) at: index].
^(objectSymbolOrClass isBehavior
ifTrue: [objectSymbolOrClass]
ifFalse: [objectSymbolOrClass class])
alignedByteSizeOf: objectSymbolOrClass
forClient: self
]