resin 0.2.2 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/amber/css/amber-normalize.css +73 -73
- data/amber/css/amber-normalize.less +1 -1
- data/amber/css/amber.css +106 -106
- data/amber/css/helios.css +242 -0
- data/amber/images/hsplitter.png +0 -0
- data/amber/images/vsplitter.png +0 -0
- data/amber/js/Benchfib.deploy.js +116 -38
- data/amber/js/Benchfib.js +120 -42
- data/amber/js/Canvas.deploy.js +674 -403
- data/amber/js/Canvas.js +682 -411
- data/amber/js/Compiler-AST.deploy.js +1150 -0
- data/amber/js/Compiler-AST.js +1591 -0
- data/amber/js/Compiler-Core.deploy.js +1562 -0
- data/amber/js/Compiler-Core.js +1972 -0
- data/amber/js/Compiler-Exceptions.deploy.js +114 -0
- data/amber/js/Compiler-Exceptions.js +161 -0
- data/amber/js/Compiler-IR.deploy.js +2326 -0
- data/amber/js/Compiler-IR.js +3146 -0
- data/amber/js/Compiler-Inlining.deploy.js +1147 -0
- data/amber/js/Compiler-Inlining.js +1514 -0
- data/amber/js/Compiler-Semantic.deploy.js +1207 -0
- data/amber/js/Compiler-Semantic.js +1628 -0
- data/amber/js/Compiler-Tests.deploy.js +646 -60
- data/amber/js/Compiler-Tests.js +843 -82
- data/amber/js/Compiler.deploy.js +1097 -159
- data/amber/js/Compiler.js +1414 -161
- data/amber/js/Examples.deploy.js +31 -15
- data/amber/js/Examples.js +33 -17
- data/amber/js/Helios-Announcements.deploy.js +127 -0
- data/amber/js/Helios-Announcements.js +157 -0
- data/amber/js/Helios-Browser.deploy.js +1473 -0
- data/amber/js/Helios-Browser.js +1953 -0
- data/amber/js/Helios-Commands.deploy.js +403 -0
- data/amber/js/Helios-Commands.js +563 -0
- data/amber/js/Helios-Core.deploy.js +1070 -0
- data/amber/js/Helios-Core.js +1445 -0
- data/amber/js/Helios-Environments.deploy.js +132 -0
- data/amber/js/Helios-Environments.js +179 -0
- data/amber/js/Helios-Inspector.deploy.js +855 -0
- data/amber/js/Helios-Inspector.js +1155 -0
- data/amber/js/Helios-KeyBindings.deploy.js +753 -0
- data/amber/js/Helios-KeyBindings.js +1023 -0
- data/amber/js/Helios-Layout.deploy.js +383 -0
- data/amber/js/Helios-Layout.js +523 -0
- data/amber/js/Helios-Workspace.deploy.js +799 -0
- data/amber/js/Helios-Workspace.js +1074 -0
- data/amber/js/IDE.deploy.js +2541 -1490
- data/amber/js/IDE.js +2721 -1660
- data/amber/js/Importer-Exporter.deploy.js +671 -0
- data/amber/js/Importer-Exporter.js +816 -0
- data/amber/js/Kernel-Announcements.deploy.js +137 -20
- data/amber/js/Kernel-Announcements.js +176 -22
- data/amber/js/Kernel-Classes.deploy.js +555 -168
- data/amber/js/Kernel-Classes.js +662 -205
- data/amber/js/Kernel-Collections.deploy.js +1403 -618
- data/amber/js/Kernel-Collections.js +1545 -690
- data/amber/js/Kernel-Exceptions.deploy.js +109 -45
- data/amber/js/Kernel-Exceptions.js +123 -49
- data/amber/js/Kernel-Methods.deploy.js +196 -81
- data/amber/js/Kernel-Methods.js +214 -89
- data/amber/js/Kernel-Objects.deploy.js +1542 -1117
- data/amber/js/Kernel-Objects.js +1593 -1148
- data/amber/js/Kernel-Tests.deploy.js +1725 -772
- data/amber/js/Kernel-Tests.js +2301 -1123
- data/amber/js/Kernel-Transcript.deploy.js +23 -25
- data/amber/js/Kernel-Transcript.js +24 -26
- data/amber/js/SUnit.deploy.js +204 -131
- data/amber/js/SUnit.js +222 -139
- data/amber/js/Spaces.deploy.js +240 -0
- data/amber/js/Spaces.js +326 -0
- data/amber/js/amber.js +26 -7
- data/amber/js/boot.js +65 -47
- data/amber/js/init.js +1 -1
- data/amber/js/lib/CodeMirror/amber.css +21 -21
- data/amber/js/lib/CodeMirror/codemirror.css +119 -13
- data/amber/js/lib/CodeMirror/codemirror.js +2219 -1220
- data/amber/js/lib/CodeMirror/smalltalk.js +134 -129
- data/amber/js/lib/bootstrap/css/bootstrap.css +5837 -0
- data/amber/js/lib/bootstrap/css/bootstrap.min.css +841 -0
- data/amber/js/lib/bootstrap/img/glyphicons-halflings-white.png +0 -0
- data/amber/js/lib/bootstrap/img/glyphicons-halflings.png +0 -0
- data/amber/js/lib/bootstrap/js/bootstrap.js +2038 -0
- data/amber/js/lib/bootstrap/js/bootstrap.min.js +7 -0
- data/amber/js/lib/jQuery/jquery-1.8.2.min.js +2 -0
- data/amber/js/lib/jQuery/jquery-ui-1.8.24.custom.min.js +125 -0
- data/amber/st/Compiler-AST.st +505 -0
- data/amber/st/Compiler-Core.st +835 -0
- data/amber/st/Compiler-Exceptions.st +87 -0
- data/amber/st/Compiler-IR.st +1097 -0
- data/amber/st/Compiler-Inlining.st +650 -0
- data/amber/st/Compiler-Semantic.st +558 -0
- data/amber/st/Compiler-Tests.st +285 -381
- data/amber/st/Compiler.st +725 -2
- data/amber/st/Helios-Announcements.st +104 -0
- data/amber/st/Helios-Browser.st +708 -0
- data/amber/st/Helios-Commands.st +223 -0
- data/amber/st/Helios-Core.st +532 -0
- data/amber/st/Helios-Environments.st +98 -0
- data/amber/st/Helios-Inspector.st +367 -0
- data/amber/st/Helios-KeyBindings.st +337 -0
- data/amber/st/Helios-Layout.st +199 -0
- data/amber/st/Helios-Workspace.st +367 -0
- data/amber/st/IDE.st +75 -53
- data/amber/st/Importer-Exporter.st +386 -0
- data/amber/st/Kernel-Announcements.st +92 -0
- data/amber/st/Kernel-Classes.st +137 -15
- data/amber/st/Kernel-Collections.st +137 -47
- data/amber/st/Kernel-Exceptions.st +14 -0
- data/amber/st/Kernel-Methods.st +9 -1
- data/amber/st/Kernel-Objects.st +29 -5
- data/amber/st/Kernel-Tests.st +545 -199
- data/amber/st/SUnit.st +10 -0
- data/amber/st/Spaces.st +142 -0
- data/lib/resin/app.rb +1 -1
- metadata +86 -31
- data/amber/js/lib/jQuery/jquery-1.4.4.min.js +0 -167
- data/amber/js/lib/jQuery/jquery-1.6.4.min.js +0 -4
|
@@ -0,0 +1,650 @@
|
|
|
1
|
+
Smalltalk current createPackage: 'Compiler-Inlining' properties: #{}!
|
|
2
|
+
IRAssignment subclass: #IRInlinedAssignment
|
|
3
|
+
instanceVariableNames: ''
|
|
4
|
+
package: 'Compiler-Inlining'!
|
|
5
|
+
!IRInlinedAssignment commentStamp!
|
|
6
|
+
I represent an inlined assignment instruction.!
|
|
7
|
+
|
|
8
|
+
!IRInlinedAssignment methodsFor: 'testing'!
|
|
9
|
+
|
|
10
|
+
isInlined
|
|
11
|
+
^ true
|
|
12
|
+
! !
|
|
13
|
+
|
|
14
|
+
!IRInlinedAssignment methodsFor: 'visiting'!
|
|
15
|
+
|
|
16
|
+
accept: aVisitor
|
|
17
|
+
^ aVisitor visitIRInlinedAssignment: self
|
|
18
|
+
! !
|
|
19
|
+
|
|
20
|
+
IRClosure subclass: #IRInlinedClosure
|
|
21
|
+
instanceVariableNames: ''
|
|
22
|
+
package: 'Compiler-Inlining'!
|
|
23
|
+
!IRInlinedClosure commentStamp!
|
|
24
|
+
I represent an inlined closure instruction.!
|
|
25
|
+
|
|
26
|
+
!IRInlinedClosure methodsFor: 'testing'!
|
|
27
|
+
|
|
28
|
+
isInlined
|
|
29
|
+
^ true
|
|
30
|
+
! !
|
|
31
|
+
|
|
32
|
+
!IRInlinedClosure methodsFor: 'visiting'!
|
|
33
|
+
|
|
34
|
+
accept: aVisitor
|
|
35
|
+
aVisitor visitIRInlinedClosure: self
|
|
36
|
+
! !
|
|
37
|
+
|
|
38
|
+
IRReturn subclass: #IRInlinedReturn
|
|
39
|
+
instanceVariableNames: ''
|
|
40
|
+
package: 'Compiler-Inlining'!
|
|
41
|
+
!IRInlinedReturn commentStamp!
|
|
42
|
+
I represent an inlined local return instruction.!
|
|
43
|
+
|
|
44
|
+
!IRInlinedReturn methodsFor: 'testing'!
|
|
45
|
+
|
|
46
|
+
isInlined
|
|
47
|
+
^ true
|
|
48
|
+
! !
|
|
49
|
+
|
|
50
|
+
!IRInlinedReturn methodsFor: 'visiting'!
|
|
51
|
+
|
|
52
|
+
accept: aVisitor
|
|
53
|
+
^ aVisitor visitIRInlinedReturn: self
|
|
54
|
+
! !
|
|
55
|
+
|
|
56
|
+
IRInlinedReturn subclass: #IRInlinedNonLocalReturn
|
|
57
|
+
instanceVariableNames: ''
|
|
58
|
+
package: 'Compiler-Inlining'!
|
|
59
|
+
!IRInlinedNonLocalReturn commentStamp!
|
|
60
|
+
I represent an inlined non local return instruction.!
|
|
61
|
+
|
|
62
|
+
!IRInlinedNonLocalReturn methodsFor: 'testing'!
|
|
63
|
+
|
|
64
|
+
isInlined
|
|
65
|
+
^ true
|
|
66
|
+
! !
|
|
67
|
+
|
|
68
|
+
!IRInlinedNonLocalReturn methodsFor: 'visiting'!
|
|
69
|
+
|
|
70
|
+
accept: aVisitor
|
|
71
|
+
^ aVisitor visitIRInlinedNonLocalReturn: self
|
|
72
|
+
! !
|
|
73
|
+
|
|
74
|
+
IRSend subclass: #IRInlinedSend
|
|
75
|
+
instanceVariableNames: ''
|
|
76
|
+
package: 'Compiler-Inlining'!
|
|
77
|
+
!IRInlinedSend commentStamp!
|
|
78
|
+
I am the abstract super class of inlined message send instructions.!
|
|
79
|
+
|
|
80
|
+
!IRInlinedSend methodsFor: 'testing'!
|
|
81
|
+
|
|
82
|
+
isInlined
|
|
83
|
+
^ true
|
|
84
|
+
! !
|
|
85
|
+
|
|
86
|
+
!IRInlinedSend methodsFor: 'visiting'!
|
|
87
|
+
|
|
88
|
+
accept: aVisitor
|
|
89
|
+
aVisitor visitInlinedSend: self
|
|
90
|
+
! !
|
|
91
|
+
|
|
92
|
+
IRInlinedSend subclass: #IRInlinedIfFalse
|
|
93
|
+
instanceVariableNames: ''
|
|
94
|
+
package: 'Compiler-Inlining'!
|
|
95
|
+
|
|
96
|
+
!IRInlinedIfFalse methodsFor: 'visiting'!
|
|
97
|
+
|
|
98
|
+
accept: aVisitor
|
|
99
|
+
aVisitor visitIRInlinedIfFalse: self
|
|
100
|
+
! !
|
|
101
|
+
|
|
102
|
+
IRInlinedSend subclass: #IRInlinedIfNilIfNotNil
|
|
103
|
+
instanceVariableNames: ''
|
|
104
|
+
package: 'Compiler-Inlining'!
|
|
105
|
+
|
|
106
|
+
!IRInlinedIfNilIfNotNil methodsFor: 'visiting'!
|
|
107
|
+
|
|
108
|
+
accept: aVisitor
|
|
109
|
+
aVisitor visitIRInlinedIfNilIfNotNil: self
|
|
110
|
+
! !
|
|
111
|
+
|
|
112
|
+
IRInlinedSend subclass: #IRInlinedIfTrue
|
|
113
|
+
instanceVariableNames: ''
|
|
114
|
+
package: 'Compiler-Inlining'!
|
|
115
|
+
|
|
116
|
+
!IRInlinedIfTrue methodsFor: 'visiting'!
|
|
117
|
+
|
|
118
|
+
accept: aVisitor
|
|
119
|
+
aVisitor visitIRInlinedIfTrue: self
|
|
120
|
+
! !
|
|
121
|
+
|
|
122
|
+
IRInlinedSend subclass: #IRInlinedIfTrueIfFalse
|
|
123
|
+
instanceVariableNames: ''
|
|
124
|
+
package: 'Compiler-Inlining'!
|
|
125
|
+
|
|
126
|
+
!IRInlinedIfTrueIfFalse methodsFor: 'visiting'!
|
|
127
|
+
|
|
128
|
+
accept: aVisitor
|
|
129
|
+
aVisitor visitIRInlinedIfTrueIfFalse: self
|
|
130
|
+
! !
|
|
131
|
+
|
|
132
|
+
IRBlockSequence subclass: #IRInlinedSequence
|
|
133
|
+
instanceVariableNames: ''
|
|
134
|
+
package: 'Compiler-Inlining'!
|
|
135
|
+
!IRInlinedSequence commentStamp!
|
|
136
|
+
I represent a (block) sequence inside an inlined closure instruction (instance of `IRInlinedClosure`).!
|
|
137
|
+
|
|
138
|
+
!IRInlinedSequence methodsFor: 'testing'!
|
|
139
|
+
|
|
140
|
+
isInlined
|
|
141
|
+
^ true
|
|
142
|
+
! !
|
|
143
|
+
|
|
144
|
+
!IRInlinedSequence methodsFor: 'visiting'!
|
|
145
|
+
|
|
146
|
+
accept: aVisitor
|
|
147
|
+
aVisitor visitIRInlinedSequence: self
|
|
148
|
+
! !
|
|
149
|
+
|
|
150
|
+
IRVisitor subclass: #IRInliner
|
|
151
|
+
instanceVariableNames: ''
|
|
152
|
+
package: 'Compiler-Inlining'!
|
|
153
|
+
!IRInliner commentStamp!
|
|
154
|
+
I visit an IR tree, inlining message sends and block closures.
|
|
155
|
+
|
|
156
|
+
Message selectors that can be inlined are answered by `IRSendInliner >> #inlinedSelectors`!
|
|
157
|
+
|
|
158
|
+
!IRInliner methodsFor: 'factory'!
|
|
159
|
+
|
|
160
|
+
assignmentInliner
|
|
161
|
+
^ IRAssignmentInliner new
|
|
162
|
+
translator: self;
|
|
163
|
+
yourself
|
|
164
|
+
!
|
|
165
|
+
|
|
166
|
+
nonLocalReturnInliner
|
|
167
|
+
^ IRNonLocalReturnInliner new
|
|
168
|
+
translator: self;
|
|
169
|
+
yourself
|
|
170
|
+
!
|
|
171
|
+
|
|
172
|
+
returnInliner
|
|
173
|
+
^ IRReturnInliner new
|
|
174
|
+
translator: self;
|
|
175
|
+
yourself
|
|
176
|
+
!
|
|
177
|
+
|
|
178
|
+
sendInliner
|
|
179
|
+
^ IRSendInliner new
|
|
180
|
+
translator: self;
|
|
181
|
+
yourself
|
|
182
|
+
! !
|
|
183
|
+
|
|
184
|
+
!IRInliner methodsFor: 'testing'!
|
|
185
|
+
|
|
186
|
+
shouldInlineAssignment: anIRAssignment
|
|
187
|
+
^ anIRAssignment isInlined not and: [
|
|
188
|
+
anIRAssignment instructions last isSend and: [
|
|
189
|
+
self shouldInlineSend: (anIRAssignment instructions last) ]]
|
|
190
|
+
!
|
|
191
|
+
|
|
192
|
+
shouldInlineReturn: anIRReturn
|
|
193
|
+
^ anIRReturn isInlined not and: [
|
|
194
|
+
anIRReturn instructions first isSend and: [
|
|
195
|
+
self shouldInlineSend: (anIRReturn instructions first) ]]
|
|
196
|
+
!
|
|
197
|
+
|
|
198
|
+
shouldInlineSend: anIRSend
|
|
199
|
+
^ anIRSend isInlined not and: [
|
|
200
|
+
IRSendInliner shouldInline: anIRSend ]
|
|
201
|
+
! !
|
|
202
|
+
|
|
203
|
+
!IRInliner methodsFor: 'visiting'!
|
|
204
|
+
|
|
205
|
+
transformNonLocalReturn: anIRNonLocalReturn
|
|
206
|
+
"Replace a non local return into a local return"
|
|
207
|
+
|
|
208
|
+
| localReturn |
|
|
209
|
+
anIRNonLocalReturn scope canInlineNonLocalReturns ifTrue: [
|
|
210
|
+
anIRNonLocalReturn scope methodScope removeNonLocalReturn: anIRNonLocalReturn scope.
|
|
211
|
+
localReturn := IRReturn new
|
|
212
|
+
scope: anIRNonLocalReturn scope;
|
|
213
|
+
yourself.
|
|
214
|
+
anIRNonLocalReturn instructions do: [ :each |
|
|
215
|
+
localReturn add: each ].
|
|
216
|
+
anIRNonLocalReturn replaceWith: localReturn.
|
|
217
|
+
^ localReturn ].
|
|
218
|
+
^ super visitIRNonLocalReturn: anIRNonLocalReturn
|
|
219
|
+
!
|
|
220
|
+
|
|
221
|
+
visitIRAssignment: anIRAssignment
|
|
222
|
+
^ (self shouldInlineAssignment: anIRAssignment)
|
|
223
|
+
ifTrue: [ self assignmentInliner inlineAssignment: anIRAssignment ]
|
|
224
|
+
ifFalse: [ super visitIRAssignment: anIRAssignment ]
|
|
225
|
+
!
|
|
226
|
+
|
|
227
|
+
visitIRNonLocalReturn: anIRNonLocalReturn
|
|
228
|
+
^ (self shouldInlineReturn: anIRNonLocalReturn)
|
|
229
|
+
ifTrue: [ self nonLocalReturnInliner inlineReturn: anIRNonLocalReturn ]
|
|
230
|
+
ifFalse: [ self transformNonLocalReturn: anIRNonLocalReturn ]
|
|
231
|
+
!
|
|
232
|
+
|
|
233
|
+
visitIRReturn: anIRReturn
|
|
234
|
+
^ (self shouldInlineReturn: anIRReturn)
|
|
235
|
+
ifTrue: [ self returnInliner inlineReturn: anIRReturn ]
|
|
236
|
+
ifFalse: [ super visitIRReturn: anIRReturn ]
|
|
237
|
+
!
|
|
238
|
+
|
|
239
|
+
visitIRSend: anIRSend
|
|
240
|
+
^ (self shouldInlineSend: anIRSend)
|
|
241
|
+
ifTrue: [ self sendInliner inlineSend: anIRSend ]
|
|
242
|
+
ifFalse: [ super visitIRSend: anIRSend ]
|
|
243
|
+
! !
|
|
244
|
+
|
|
245
|
+
IRJSTranslator subclass: #IRInliningJSTranslator
|
|
246
|
+
instanceVariableNames: ''
|
|
247
|
+
package: 'Compiler-Inlining'!
|
|
248
|
+
!IRInliningJSTranslator commentStamp!
|
|
249
|
+
I am a specialized JavaScript translator able to write inlined IR instructions to JavaScript stream (`JSStream` instance).!
|
|
250
|
+
|
|
251
|
+
!IRInliningJSTranslator methodsFor: 'visiting'!
|
|
252
|
+
|
|
253
|
+
visitIRInlinedAssignment: anIRInlinedAssignment
|
|
254
|
+
self visit: anIRInlinedAssignment instructions last
|
|
255
|
+
!
|
|
256
|
+
|
|
257
|
+
visitIRInlinedClosure: anIRInlinedClosure
|
|
258
|
+
anIRInlinedClosure instructions do: [ :each |
|
|
259
|
+
self visit: each ]
|
|
260
|
+
!
|
|
261
|
+
|
|
262
|
+
visitIRInlinedIfFalse: anIRInlinedIfFalse
|
|
263
|
+
self stream nextPutIf: [
|
|
264
|
+
self stream nextPutAll: '!! smalltalk.assert('.
|
|
265
|
+
self visit: anIRInlinedIfFalse instructions first.
|
|
266
|
+
self stream nextPutAll: ')' ]
|
|
267
|
+
with: [ self visit: anIRInlinedIfFalse instructions last ]
|
|
268
|
+
!
|
|
269
|
+
|
|
270
|
+
visitIRInlinedIfNil: anIRInlinedIfNil
|
|
271
|
+
self stream nextPutIf: [
|
|
272
|
+
self stream nextPutAll: '($receiver = '.
|
|
273
|
+
self visit: anIRInlinedIfNil instructions first.
|
|
274
|
+
self stream nextPutAll: ') == nil || $receiver == undefined' ]
|
|
275
|
+
with: [ self visit: anIRInlinedIfNil instructions last ]
|
|
276
|
+
!
|
|
277
|
+
|
|
278
|
+
visitIRInlinedIfNilIfNotNil: anIRInlinedIfNilIfNotNil
|
|
279
|
+
self stream
|
|
280
|
+
nextPutIfElse: [
|
|
281
|
+
self stream nextPutAll: '($receiver = '.
|
|
282
|
+
self visit: anIRInlinedIfNilIfNotNil instructions first.
|
|
283
|
+
self stream nextPutAll: ') == nil || $receiver == undefined' ]
|
|
284
|
+
with: [ self visit: anIRInlinedIfNilIfNotNil instructions second ]
|
|
285
|
+
with: [ self visit: anIRInlinedIfNilIfNotNil instructions third ]
|
|
286
|
+
!
|
|
287
|
+
|
|
288
|
+
visitIRInlinedIfTrue: anIRInlinedIfTrue
|
|
289
|
+
self stream nextPutIf: [
|
|
290
|
+
self stream nextPutAll: 'smalltalk.assert('.
|
|
291
|
+
self visit: anIRInlinedIfTrue instructions first.
|
|
292
|
+
self stream nextPutAll: ')' ]
|
|
293
|
+
with: [ self visit: anIRInlinedIfTrue instructions last ]
|
|
294
|
+
!
|
|
295
|
+
|
|
296
|
+
visitIRInlinedIfTrueIfFalse: anIRInlinedIfTrueIfFalse
|
|
297
|
+
self stream
|
|
298
|
+
nextPutIfElse: [
|
|
299
|
+
self stream nextPutAll: 'smalltalk.assert('.
|
|
300
|
+
self visit: anIRInlinedIfTrueIfFalse instructions first.
|
|
301
|
+
self stream nextPutAll: ')' ]
|
|
302
|
+
with: [ self visit: anIRInlinedIfTrueIfFalse instructions second ]
|
|
303
|
+
with: [ self visit: anIRInlinedIfTrueIfFalse instructions third ]
|
|
304
|
+
!
|
|
305
|
+
|
|
306
|
+
visitIRInlinedNonLocalReturn: anIRInlinedReturn
|
|
307
|
+
self stream nextPutStatementWith: [
|
|
308
|
+
self visit: anIRInlinedReturn instructions last ].
|
|
309
|
+
self stream nextPutNonLocalReturnWith: [ ]
|
|
310
|
+
!
|
|
311
|
+
|
|
312
|
+
visitIRInlinedReturn: anIRInlinedReturn
|
|
313
|
+
self visit: anIRInlinedReturn instructions last
|
|
314
|
+
!
|
|
315
|
+
|
|
316
|
+
visitIRInlinedSequence: anIRInlinedSequence
|
|
317
|
+
anIRInlinedSequence instructions do: [ :each |
|
|
318
|
+
self stream nextPutStatementWith: [ self visit: each ]]
|
|
319
|
+
! !
|
|
320
|
+
|
|
321
|
+
Object subclass: #IRSendInliner
|
|
322
|
+
instanceVariableNames: 'send translator'
|
|
323
|
+
package: 'Compiler-Inlining'!
|
|
324
|
+
!IRSendInliner commentStamp!
|
|
325
|
+
I inline some message sends and block closure arguments. I heavily rely on #perform: to dispatch inlining methods.!
|
|
326
|
+
|
|
327
|
+
!IRSendInliner methodsFor: 'accessing'!
|
|
328
|
+
|
|
329
|
+
send
|
|
330
|
+
^ send
|
|
331
|
+
!
|
|
332
|
+
|
|
333
|
+
send: anIRSend
|
|
334
|
+
send := anIRSend
|
|
335
|
+
!
|
|
336
|
+
|
|
337
|
+
translator
|
|
338
|
+
^ translator
|
|
339
|
+
!
|
|
340
|
+
|
|
341
|
+
translator: anASTTranslator
|
|
342
|
+
translator := anASTTranslator
|
|
343
|
+
! !
|
|
344
|
+
|
|
345
|
+
!IRSendInliner methodsFor: 'error handling'!
|
|
346
|
+
|
|
347
|
+
inliningError: aString
|
|
348
|
+
InliningError signal: aString
|
|
349
|
+
! !
|
|
350
|
+
|
|
351
|
+
!IRSendInliner methodsFor: 'factory'!
|
|
352
|
+
|
|
353
|
+
inlinedClosure
|
|
354
|
+
^ IRInlinedClosure new
|
|
355
|
+
!
|
|
356
|
+
|
|
357
|
+
inlinedSequence
|
|
358
|
+
^ IRInlinedSequence new
|
|
359
|
+
! !
|
|
360
|
+
|
|
361
|
+
!IRSendInliner methodsFor: 'inlining'!
|
|
362
|
+
|
|
363
|
+
ifFalse: anIRInstruction
|
|
364
|
+
^ self inlinedSend: IRInlinedIfFalse new with: anIRInstruction
|
|
365
|
+
!
|
|
366
|
+
|
|
367
|
+
ifFalse: anIRInstruction ifTrue: anotherIRInstruction
|
|
368
|
+
^ self perform: #ifTrue:ifFalse: withArguments: { anotherIRInstruction. anIRInstruction }
|
|
369
|
+
!
|
|
370
|
+
|
|
371
|
+
ifNil: anIRInstruction
|
|
372
|
+
^ self
|
|
373
|
+
inlinedSend: IRInlinedIfNilIfNotNil new
|
|
374
|
+
with: anIRInstruction
|
|
375
|
+
with: (IRClosure new
|
|
376
|
+
scope: anIRInstruction scope copy;
|
|
377
|
+
add: (IRBlockSequence new
|
|
378
|
+
add: self send instructions first;
|
|
379
|
+
yourself);
|
|
380
|
+
yourself)
|
|
381
|
+
!
|
|
382
|
+
|
|
383
|
+
ifNil: anIRInstruction ifNotNil: anotherIRInstruction
|
|
384
|
+
^ self inlinedSend: IRInlinedIfNilIfNotNil new with: anIRInstruction with: anotherIRInstruction
|
|
385
|
+
!
|
|
386
|
+
|
|
387
|
+
ifNotNil: anIRInstruction
|
|
388
|
+
^ self
|
|
389
|
+
inlinedSend: IRInlinedIfNilIfNotNil new
|
|
390
|
+
with: (IRClosure new
|
|
391
|
+
scope: anIRInstruction scope copy;
|
|
392
|
+
add: (IRBlockSequence new
|
|
393
|
+
add: self send instructions first;
|
|
394
|
+
yourself);
|
|
395
|
+
yourself)
|
|
396
|
+
with: anIRInstruction
|
|
397
|
+
!
|
|
398
|
+
|
|
399
|
+
ifNotNil: anIRInstruction ifNil: anotherIRInstruction
|
|
400
|
+
^ self inlinedSend: IRInlinedIfNilIfNotNil new with: anotherIRInstruction with: anIRInstruction
|
|
401
|
+
!
|
|
402
|
+
|
|
403
|
+
ifTrue: anIRInstruction
|
|
404
|
+
^ self inlinedSend: IRInlinedIfTrue new with: anIRInstruction
|
|
405
|
+
!
|
|
406
|
+
|
|
407
|
+
ifTrue: anIRInstruction ifFalse: anotherIRInstruction
|
|
408
|
+
^ self inlinedSend: IRInlinedIfTrueIfFalse new with: anIRInstruction with: anotherIRInstruction
|
|
409
|
+
!
|
|
410
|
+
|
|
411
|
+
inlineClosure: anIRClosure
|
|
412
|
+
| inlinedClosure sequence statements |
|
|
413
|
+
|
|
414
|
+
inlinedClosure := self inlinedClosure.
|
|
415
|
+
inlinedClosure scope: anIRClosure scope.
|
|
416
|
+
|
|
417
|
+
"Add the possible temp declarations"
|
|
418
|
+
anIRClosure instructions do: [ :each |
|
|
419
|
+
each isSequence ifFalse: [
|
|
420
|
+
inlinedClosure add: each ]].
|
|
421
|
+
|
|
422
|
+
"Add a block sequence"
|
|
423
|
+
sequence := self inlinedSequence.
|
|
424
|
+
inlinedClosure add: sequence.
|
|
425
|
+
|
|
426
|
+
"Get all the statements"
|
|
427
|
+
statements := anIRClosure instructions last instructions.
|
|
428
|
+
|
|
429
|
+
statements ifNotEmpty: [
|
|
430
|
+
statements allButLast do: [ :each | sequence add: each ].
|
|
431
|
+
|
|
432
|
+
"Inlined closures don't have implicit local returns"
|
|
433
|
+
(statements last isReturn and: [ statements last isBlockReturn ])
|
|
434
|
+
ifTrue: [ sequence add: statements last instructions first ]
|
|
435
|
+
ifFalse: [ sequence add: statements last ] ].
|
|
436
|
+
|
|
437
|
+
^ inlinedClosure
|
|
438
|
+
!
|
|
439
|
+
|
|
440
|
+
inlineSend: anIRSend
|
|
441
|
+
self send: anIRSend.
|
|
442
|
+
^ self
|
|
443
|
+
perform: self send selector
|
|
444
|
+
withArguments: self send instructions allButFirst
|
|
445
|
+
!
|
|
446
|
+
|
|
447
|
+
inlinedSend: inlinedSend with: anIRInstruction
|
|
448
|
+
| inlinedClosure |
|
|
449
|
+
|
|
450
|
+
anIRInstruction isClosure ifFalse: [ self inliningError: 'Message argument should be a block' ].
|
|
451
|
+
anIRInstruction arguments size = 0 ifFalse: [ self inliningError: 'Inlined block should have zero argument' ].
|
|
452
|
+
|
|
453
|
+
inlinedClosure := self translator visit: (self inlineClosure: anIRInstruction).
|
|
454
|
+
|
|
455
|
+
inlinedSend
|
|
456
|
+
add: self send instructions first;
|
|
457
|
+
add: inlinedClosure.
|
|
458
|
+
|
|
459
|
+
self send replaceWith: inlinedSend.
|
|
460
|
+
|
|
461
|
+
^ inlinedSend
|
|
462
|
+
!
|
|
463
|
+
|
|
464
|
+
inlinedSend: inlinedSend with: anIRInstruction with: anotherIRInstruction
|
|
465
|
+
| inlinedClosure1 inlinedClosure2 |
|
|
466
|
+
|
|
467
|
+
anIRInstruction isClosure ifFalse: [ self inliningError: 'Message argument should be a block' ].
|
|
468
|
+
anIRInstruction arguments size = 0 ifFalse: [ self inliningError: 'Inlined block should have zero argument' ].
|
|
469
|
+
|
|
470
|
+
anotherIRInstruction isClosure ifFalse: [ self inliningError: 'Message argument should be a block' ].
|
|
471
|
+
anotherIRInstruction arguments size = 0 ifFalse: [ self inliningError: 'Inlined block should have zero argument' ].
|
|
472
|
+
|
|
473
|
+
inlinedClosure1 := self translator visit: (self inlineClosure: anIRInstruction).
|
|
474
|
+
inlinedClosure2 := self translator visit: (self inlineClosure: anotherIRInstruction).
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
inlinedSend
|
|
478
|
+
add: self send instructions first;
|
|
479
|
+
add: inlinedClosure1;
|
|
480
|
+
add: inlinedClosure2.
|
|
481
|
+
|
|
482
|
+
self send replaceWith: inlinedSend.
|
|
483
|
+
^ inlinedSend
|
|
484
|
+
! !
|
|
485
|
+
|
|
486
|
+
!IRSendInliner class methodsFor: 'accessing'!
|
|
487
|
+
|
|
488
|
+
inlinedSelectors
|
|
489
|
+
^ #('ifTrue:' 'ifFalse:' 'ifTrue:ifFalse:' 'ifFalse:ifTrue:' 'ifNil:' 'ifNotNil:' 'ifNil:ifNotNil:' 'ifNotNil:ifNil')
|
|
490
|
+
!
|
|
491
|
+
|
|
492
|
+
shouldInline: anIRInstruction
|
|
493
|
+
(self inlinedSelectors includes: anIRInstruction selector) ifFalse: [ ^ false ].
|
|
494
|
+
anIRInstruction instructions allButFirst do: [ :each |
|
|
495
|
+
each isClosure ifFalse: [ ^ false ]].
|
|
496
|
+
^ true
|
|
497
|
+
! !
|
|
498
|
+
|
|
499
|
+
IRSendInliner subclass: #IRAssignmentInliner
|
|
500
|
+
instanceVariableNames: 'assignment'
|
|
501
|
+
package: 'Compiler-Inlining'!
|
|
502
|
+
!IRAssignmentInliner commentStamp!
|
|
503
|
+
I inline message sends together with assignments by moving them around into the inline closure instructions.
|
|
504
|
+
|
|
505
|
+
##Example
|
|
506
|
+
|
|
507
|
+
foo
|
|
508
|
+
| a |
|
|
509
|
+
a := true ifTrue: [ 1 ]
|
|
510
|
+
|
|
511
|
+
Will produce:
|
|
512
|
+
|
|
513
|
+
if(smalltalk.assert(true) {
|
|
514
|
+
a = 1;
|
|
515
|
+
};!
|
|
516
|
+
|
|
517
|
+
!IRAssignmentInliner methodsFor: 'accessing'!
|
|
518
|
+
|
|
519
|
+
assignment
|
|
520
|
+
^ assignment
|
|
521
|
+
!
|
|
522
|
+
|
|
523
|
+
assignment: aNode
|
|
524
|
+
assignment := aNode
|
|
525
|
+
! !
|
|
526
|
+
|
|
527
|
+
!IRAssignmentInliner methodsFor: 'inlining'!
|
|
528
|
+
|
|
529
|
+
inlineAssignment: anIRAssignment
|
|
530
|
+
| inlinedAssignment |
|
|
531
|
+
self assignment: anIRAssignment.
|
|
532
|
+
inlinedAssignment := IRInlinedAssignment new.
|
|
533
|
+
anIRAssignment instructions do: [ :each |
|
|
534
|
+
inlinedAssignment add: each ].
|
|
535
|
+
anIRAssignment replaceWith: inlinedAssignment.
|
|
536
|
+
self inlineSend: inlinedAssignment instructions last.
|
|
537
|
+
^ inlinedAssignment
|
|
538
|
+
!
|
|
539
|
+
|
|
540
|
+
inlineClosure: anIRClosure
|
|
541
|
+
| inlinedClosure statements |
|
|
542
|
+
|
|
543
|
+
inlinedClosure := super inlineClosure: anIRClosure.
|
|
544
|
+
statements := inlinedClosure instructions last instructions.
|
|
545
|
+
|
|
546
|
+
statements ifNotEmpty: [
|
|
547
|
+
statements last canBeAssigned ifTrue: [
|
|
548
|
+
statements last replaceWith: (IRAssignment new
|
|
549
|
+
add: self assignment instructions first;
|
|
550
|
+
add: statements last copy;
|
|
551
|
+
yourself) ] ].
|
|
552
|
+
|
|
553
|
+
^ inlinedClosure
|
|
554
|
+
! !
|
|
555
|
+
|
|
556
|
+
IRSendInliner subclass: #IRNonLocalReturnInliner
|
|
557
|
+
instanceVariableNames: ''
|
|
558
|
+
package: 'Compiler-Inlining'!
|
|
559
|
+
|
|
560
|
+
!IRNonLocalReturnInliner methodsFor: 'factory'!
|
|
561
|
+
|
|
562
|
+
inlinedReturn
|
|
563
|
+
^ IRInlinedNonLocalReturn new
|
|
564
|
+
! !
|
|
565
|
+
|
|
566
|
+
!IRNonLocalReturnInliner methodsFor: 'inlining'!
|
|
567
|
+
|
|
568
|
+
inlineClosure: anIRClosure
|
|
569
|
+
"| inlinedClosure statements |
|
|
570
|
+
|
|
571
|
+
inlinedClosure := super inlineClosure: anIRClosure.
|
|
572
|
+
statements := inlinedClosure instructions last instructions.
|
|
573
|
+
|
|
574
|
+
statements ifNotEmpty: [
|
|
575
|
+
statements last replaceWith: (IRNonLocalReturn new
|
|
576
|
+
add: statements last copy;
|
|
577
|
+
yourself) ].
|
|
578
|
+
|
|
579
|
+
^ inlinedClosure"
|
|
580
|
+
|
|
581
|
+
^ super inlineCLosure: anIRClosure
|
|
582
|
+
! !
|
|
583
|
+
|
|
584
|
+
IRSendInliner subclass: #IRReturnInliner
|
|
585
|
+
instanceVariableNames: ''
|
|
586
|
+
package: 'Compiler-Inlining'!
|
|
587
|
+
!IRReturnInliner commentStamp!
|
|
588
|
+
I inline message sends with inlined closure together with a return instruction.!
|
|
589
|
+
|
|
590
|
+
!IRReturnInliner methodsFor: 'factory'!
|
|
591
|
+
|
|
592
|
+
inlinedReturn
|
|
593
|
+
^ IRInlinedReturn new
|
|
594
|
+
! !
|
|
595
|
+
|
|
596
|
+
!IRReturnInliner methodsFor: 'inlining'!
|
|
597
|
+
|
|
598
|
+
inlineClosure: anIRClosure
|
|
599
|
+
| closure statements |
|
|
600
|
+
|
|
601
|
+
closure := super inlineClosure: anIRClosure.
|
|
602
|
+
statements := closure instructions last instructions.
|
|
603
|
+
|
|
604
|
+
statements ifNotEmpty: [
|
|
605
|
+
statements last isReturn
|
|
606
|
+
ifFalse: [ statements last replaceWith: (IRReturn new
|
|
607
|
+
add: statements last copy;
|
|
608
|
+
yourself)] ].
|
|
609
|
+
|
|
610
|
+
^ closure
|
|
611
|
+
!
|
|
612
|
+
|
|
613
|
+
inlineReturn: anIRReturn
|
|
614
|
+
| return |
|
|
615
|
+
return := self inlinedReturn.
|
|
616
|
+
anIRReturn instructions do: [ :each |
|
|
617
|
+
return add: each ].
|
|
618
|
+
anIRReturn replaceWith: return.
|
|
619
|
+
self inlineSend: return instructions last.
|
|
620
|
+
^ return
|
|
621
|
+
! !
|
|
622
|
+
|
|
623
|
+
CodeGenerator subclass: #InliningCodeGenerator
|
|
624
|
+
instanceVariableNames: ''
|
|
625
|
+
package: 'Compiler-Inlining'!
|
|
626
|
+
!InliningCodeGenerator commentStamp!
|
|
627
|
+
I am a specialized code generator that uses inlining to produce more optimized JavaScript output!
|
|
628
|
+
|
|
629
|
+
!InliningCodeGenerator methodsFor: 'compiling'!
|
|
630
|
+
|
|
631
|
+
compileNode: aNode
|
|
632
|
+
| ir stream |
|
|
633
|
+
|
|
634
|
+
self semanticAnalyzer visit: aNode.
|
|
635
|
+
ir := self translator visit: aNode.
|
|
636
|
+
self inliner visit: ir.
|
|
637
|
+
|
|
638
|
+
^ self irTranslator
|
|
639
|
+
visit: ir;
|
|
640
|
+
contents
|
|
641
|
+
!
|
|
642
|
+
|
|
643
|
+
inliner
|
|
644
|
+
^ IRInliner new
|
|
645
|
+
!
|
|
646
|
+
|
|
647
|
+
irTranslator
|
|
648
|
+
^ IRInliningJSTranslator new
|
|
649
|
+
! !
|
|
650
|
+
|