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.
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
+