resin 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. data/amber/css/amber-normalize.css +73 -73
  2. data/amber/css/amber-normalize.less +1 -1
  3. data/amber/css/amber.css +106 -106
  4. data/amber/css/helios.css +242 -0
  5. data/amber/images/hsplitter.png +0 -0
  6. data/amber/images/vsplitter.png +0 -0
  7. data/amber/js/Benchfib.deploy.js +116 -38
  8. data/amber/js/Benchfib.js +120 -42
  9. data/amber/js/Canvas.deploy.js +674 -403
  10. data/amber/js/Canvas.js +682 -411
  11. data/amber/js/Compiler-AST.deploy.js +1150 -0
  12. data/amber/js/Compiler-AST.js +1591 -0
  13. data/amber/js/Compiler-Core.deploy.js +1562 -0
  14. data/amber/js/Compiler-Core.js +1972 -0
  15. data/amber/js/Compiler-Exceptions.deploy.js +114 -0
  16. data/amber/js/Compiler-Exceptions.js +161 -0
  17. data/amber/js/Compiler-IR.deploy.js +2326 -0
  18. data/amber/js/Compiler-IR.js +3146 -0
  19. data/amber/js/Compiler-Inlining.deploy.js +1147 -0
  20. data/amber/js/Compiler-Inlining.js +1514 -0
  21. data/amber/js/Compiler-Semantic.deploy.js +1207 -0
  22. data/amber/js/Compiler-Semantic.js +1628 -0
  23. data/amber/js/Compiler-Tests.deploy.js +646 -60
  24. data/amber/js/Compiler-Tests.js +843 -82
  25. data/amber/js/Compiler.deploy.js +1097 -159
  26. data/amber/js/Compiler.js +1414 -161
  27. data/amber/js/Examples.deploy.js +31 -15
  28. data/amber/js/Examples.js +33 -17
  29. data/amber/js/Helios-Announcements.deploy.js +127 -0
  30. data/amber/js/Helios-Announcements.js +157 -0
  31. data/amber/js/Helios-Browser.deploy.js +1473 -0
  32. data/amber/js/Helios-Browser.js +1953 -0
  33. data/amber/js/Helios-Commands.deploy.js +403 -0
  34. data/amber/js/Helios-Commands.js +563 -0
  35. data/amber/js/Helios-Core.deploy.js +1070 -0
  36. data/amber/js/Helios-Core.js +1445 -0
  37. data/amber/js/Helios-Environments.deploy.js +132 -0
  38. data/amber/js/Helios-Environments.js +179 -0
  39. data/amber/js/Helios-Inspector.deploy.js +855 -0
  40. data/amber/js/Helios-Inspector.js +1155 -0
  41. data/amber/js/Helios-KeyBindings.deploy.js +753 -0
  42. data/amber/js/Helios-KeyBindings.js +1023 -0
  43. data/amber/js/Helios-Layout.deploy.js +383 -0
  44. data/amber/js/Helios-Layout.js +523 -0
  45. data/amber/js/Helios-Workspace.deploy.js +799 -0
  46. data/amber/js/Helios-Workspace.js +1074 -0
  47. data/amber/js/IDE.deploy.js +2541 -1490
  48. data/amber/js/IDE.js +2721 -1660
  49. data/amber/js/Importer-Exporter.deploy.js +671 -0
  50. data/amber/js/Importer-Exporter.js +816 -0
  51. data/amber/js/Kernel-Announcements.deploy.js +137 -20
  52. data/amber/js/Kernel-Announcements.js +176 -22
  53. data/amber/js/Kernel-Classes.deploy.js +555 -168
  54. data/amber/js/Kernel-Classes.js +662 -205
  55. data/amber/js/Kernel-Collections.deploy.js +1403 -618
  56. data/amber/js/Kernel-Collections.js +1545 -690
  57. data/amber/js/Kernel-Exceptions.deploy.js +109 -45
  58. data/amber/js/Kernel-Exceptions.js +123 -49
  59. data/amber/js/Kernel-Methods.deploy.js +196 -81
  60. data/amber/js/Kernel-Methods.js +214 -89
  61. data/amber/js/Kernel-Objects.deploy.js +1542 -1117
  62. data/amber/js/Kernel-Objects.js +1593 -1148
  63. data/amber/js/Kernel-Tests.deploy.js +1725 -772
  64. data/amber/js/Kernel-Tests.js +2301 -1123
  65. data/amber/js/Kernel-Transcript.deploy.js +23 -25
  66. data/amber/js/Kernel-Transcript.js +24 -26
  67. data/amber/js/SUnit.deploy.js +204 -131
  68. data/amber/js/SUnit.js +222 -139
  69. data/amber/js/Spaces.deploy.js +240 -0
  70. data/amber/js/Spaces.js +326 -0
  71. data/amber/js/amber.js +26 -7
  72. data/amber/js/boot.js +65 -47
  73. data/amber/js/init.js +1 -1
  74. data/amber/js/lib/CodeMirror/amber.css +21 -21
  75. data/amber/js/lib/CodeMirror/codemirror.css +119 -13
  76. data/amber/js/lib/CodeMirror/codemirror.js +2219 -1220
  77. data/amber/js/lib/CodeMirror/smalltalk.js +134 -129
  78. data/amber/js/lib/bootstrap/css/bootstrap.css +5837 -0
  79. data/amber/js/lib/bootstrap/css/bootstrap.min.css +841 -0
  80. data/amber/js/lib/bootstrap/img/glyphicons-halflings-white.png +0 -0
  81. data/amber/js/lib/bootstrap/img/glyphicons-halflings.png +0 -0
  82. data/amber/js/lib/bootstrap/js/bootstrap.js +2038 -0
  83. data/amber/js/lib/bootstrap/js/bootstrap.min.js +7 -0
  84. data/amber/js/lib/jQuery/jquery-1.8.2.min.js +2 -0
  85. data/amber/js/lib/jQuery/jquery-ui-1.8.24.custom.min.js +125 -0
  86. data/amber/st/Compiler-AST.st +505 -0
  87. data/amber/st/Compiler-Core.st +835 -0
  88. data/amber/st/Compiler-Exceptions.st +87 -0
  89. data/amber/st/Compiler-IR.st +1097 -0
  90. data/amber/st/Compiler-Inlining.st +650 -0
  91. data/amber/st/Compiler-Semantic.st +558 -0
  92. data/amber/st/Compiler-Tests.st +285 -381
  93. data/amber/st/Compiler.st +725 -2
  94. data/amber/st/Helios-Announcements.st +104 -0
  95. data/amber/st/Helios-Browser.st +708 -0
  96. data/amber/st/Helios-Commands.st +223 -0
  97. data/amber/st/Helios-Core.st +532 -0
  98. data/amber/st/Helios-Environments.st +98 -0
  99. data/amber/st/Helios-Inspector.st +367 -0
  100. data/amber/st/Helios-KeyBindings.st +337 -0
  101. data/amber/st/Helios-Layout.st +199 -0
  102. data/amber/st/Helios-Workspace.st +367 -0
  103. data/amber/st/IDE.st +75 -53
  104. data/amber/st/Importer-Exporter.st +386 -0
  105. data/amber/st/Kernel-Announcements.st +92 -0
  106. data/amber/st/Kernel-Classes.st +137 -15
  107. data/amber/st/Kernel-Collections.st +137 -47
  108. data/amber/st/Kernel-Exceptions.st +14 -0
  109. data/amber/st/Kernel-Methods.st +9 -1
  110. data/amber/st/Kernel-Objects.st +29 -5
  111. data/amber/st/Kernel-Tests.st +545 -199
  112. data/amber/st/SUnit.st +10 -0
  113. data/amber/st/Spaces.st +142 -0
  114. data/lib/resin/app.rb +1 -1
  115. metadata +86 -31
  116. data/amber/js/lib/jQuery/jquery-1.4.4.min.js +0 -167
  117. 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
+