Compiler-Inlining.js 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727
  1. smalltalk.addPackage('Compiler-Inlining', {});
  2. smalltalk.addClass('IRInlinedAssignment', smalltalk.IRAssignment, [], 'Compiler-Inlining');
  3. smalltalk.addMethod(
  4. "_accept_",
  5. smalltalk.method({
  6. selector: "accept:",
  7. category: 'visiting',
  8. fn: function (aVisitor){
  9. var self=this;
  10. return smalltalk.send(aVisitor, "_visitIRInlinedAssignment_", [self]);
  11. return self;},
  12. args: ["aVisitor"],
  13. source: "accept: aVisitor\x0a\x09^ aVisitor visitIRInlinedAssignment: self",
  14. messageSends: ["visitIRInlinedAssignment:"],
  15. referencedClasses: []
  16. }),
  17. smalltalk.IRInlinedAssignment);
  18. smalltalk.addMethod(
  19. "_isInlined",
  20. smalltalk.method({
  21. selector: "isInlined",
  22. category: 'testing',
  23. fn: function (){
  24. var self=this;
  25. return true;
  26. return self;},
  27. args: [],
  28. source: "isInlined\x0a\x09^ true",
  29. messageSends: [],
  30. referencedClasses: []
  31. }),
  32. smalltalk.IRInlinedAssignment);
  33. smalltalk.addClass('IRInlinedClosure', smalltalk.IRClosure, ['assignTo'], 'Compiler-Inlining');
  34. smalltalk.addMethod(
  35. "_accept_",
  36. smalltalk.method({
  37. selector: "accept:",
  38. category: 'visiting',
  39. fn: function (aVisitor) {
  40. var self=this;
  41. smalltalk.send(aVisitor, "_visitIRInlinedClosure_", [self]);
  42. return self;},
  43. args: ["aVisitor"],
  44. source: "accept: aVisitor\x0a\x09aVisitor visitIRInlinedClosure: self",
  45. messageSends: ["visitIRInlinedClosure:"],
  46. referencedClasses: []
  47. }),
  48. smalltalk.IRInlinedClosure);
  49. smalltalk.addMethod(
  50. "_assignTo",
  51. smalltalk.method({
  52. selector: "assignTo",
  53. category: 'accessing',
  54. fn: function () {
  55. var self=this;
  56. return self['@assignTo'];
  57. return self;},
  58. args: [],
  59. source: "assignTo\x0a\x09^ assignTo",
  60. messageSends: [],
  61. referencedClasses: []
  62. }),
  63. smalltalk.IRInlinedClosure);
  64. smalltalk.addMethod(
  65. "_assignTo_",
  66. smalltalk.method({
  67. selector: "assignTo:",
  68. category: 'accessing',
  69. fn: function (aScopeVar){
  70. var self=this;
  71. (self['@assignTo']=aScopeVar);
  72. return self;},
  73. args: ["aScopeVar"],
  74. source: "assignTo: aScopeVar\x0a\x09assignTo := aScopeVar",
  75. messageSends: [],
  76. referencedClasses: []
  77. }),
  78. smalltalk.IRInlinedClosure);
  79. smalltalk.addMethod(
  80. "_isInlined",
  81. smalltalk.method({
  82. selector: "isInlined",
  83. category: 'testing',
  84. fn: function (){
  85. var self=this;
  86. return true;
  87. return self;},
  88. args: [],
  89. source: "isInlined\x0a\x09^ true",
  90. messageSends: [],
  91. referencedClasses: []
  92. }),
  93. smalltalk.IRInlinedClosure);
  94. smalltalk.addClass('IRInlinedNonLocalReturn', smalltalk.IRReturn, [], 'Compiler-Inlining');
  95. smalltalk.addMethod(
  96. "_accept_",
  97. smalltalk.method({
  98. selector: "accept:",
  99. category: 'visiting',
  100. fn: function (aVisitor){
  101. var self=this;
  102. return smalltalk.send(aVisitor, "_visitIRInlinedNonLocalReturn_", [self]);
  103. return self;},
  104. args: ["aVisitor"],
  105. source: "accept: aVisitor\x0a\x09^ aVisitor visitIRInlinedNonLocalReturn: self",
  106. messageSends: ["visitIRInlinedNonLocalReturn:"],
  107. referencedClasses: []
  108. }),
  109. smalltalk.IRInlinedNonLocalReturn);
  110. smalltalk.addMethod(
  111. "_isInlined",
  112. smalltalk.method({
  113. selector: "isInlined",
  114. category: 'testing',
  115. fn: function (){
  116. var self=this;
  117. return true;
  118. return self;},
  119. args: [],
  120. source: "isInlined\x0a\x09^ true",
  121. messageSends: [],
  122. referencedClasses: []
  123. }),
  124. smalltalk.IRInlinedNonLocalReturn);
  125. smalltalk.addClass('IRInlinedSend', smalltalk.IRSend, [], 'Compiler-Inlining');
  126. smalltalk.addMethod(
  127. "_accept_",
  128. smalltalk.method({
  129. selector: "accept:",
  130. category: 'visiting',
  131. fn: function (aVisitor) {
  132. var self=this;
  133. smalltalk.send(aVisitor, "_visitInlinedSend_", [self]);
  134. return self;},
  135. args: ["aVisitor"],
  136. source: "accept: aVisitor\x0a\x09aVisitor visitInlinedSend: self",
  137. messageSends: ["visitInlinedSend:"],
  138. referencedClasses: []
  139. }),
  140. smalltalk.IRInlinedSend);
  141. smalltalk.addMethod(
  142. "_isInlined",
  143. smalltalk.method({
  144. selector: "isInlined",
  145. category: 'testing',
  146. fn: function (){
  147. var self=this;
  148. return true;
  149. return self;},
  150. args: [],
  151. source: "isInlined\x0a\x09^ true",
  152. messageSends: [],
  153. referencedClasses: []
  154. }),
  155. smalltalk.IRInlinedSend);
  156. smalltalk.addClass('IRInlinedIfFalse', smalltalk.IRInlinedSend, [], 'Compiler-Inlining');
  157. smalltalk.addMethod(
  158. "_accept_",
  159. smalltalk.method({
  160. selector: "accept:",
  161. category: 'visiting',
  162. fn: function (aVisitor){
  163. var self=this;
  164. smalltalk.send(aVisitor, "_visitIRInlinedIfFalse_", [self]);
  165. return self;},
  166. args: ["aVisitor"],
  167. source: "accept: aVisitor\x0a\x09aVisitor visitIRInlinedIfFalse: self",
  168. messageSends: ["visitIRInlinedIfFalse:"],
  169. referencedClasses: []
  170. }),
  171. smalltalk.IRInlinedIfFalse);
  172. smalltalk.addClass('IRInlinedIfTrue', smalltalk.IRInlinedSend, [], 'Compiler-Inlining');
  173. smalltalk.addMethod(
  174. "_accept_",
  175. smalltalk.method({
  176. selector: "accept:",
  177. category: 'visiting',
  178. fn: function (aVisitor) {
  179. var self=this;
  180. smalltalk.send(aVisitor, "_visitIRInlinedIfTrue_", [self]);
  181. return self;},
  182. args: ["aVisitor"],
  183. source: "accept: aVisitor\x0a\x09aVisitor visitIRInlinedIfTrue: self",
  184. messageSends: ["visitIRInlinedIfTrue:"],
  185. referencedClasses: []
  186. }),
  187. smalltalk.IRInlinedIfTrue);
  188. smalltalk.addClass('IRInliner', smalltalk.IRVisitor, [], 'Compiler-Inlining');
  189. smalltalk.addMethod(
  190. "_assignmentInliner",
  191. smalltalk.method({
  192. selector: "assignmentInliner",
  193. category: 'visiting',
  194. fn: function () {
  195. var self=this;
  196. return (function($rec){smalltalk.send($rec, "_translator_", [self]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.IRAssignmentInliner || IRAssignmentInliner), "_new", []));
  197. return self;},
  198. args: [],
  199. source: "assignmentInliner\x0a\x09^ IRAssignmentInliner new \x0a\x09\x09translator: self;\x0a\x09\x09yourself",
  200. messageSends: ["translator:", "yourself", "new"],
  201. referencedClasses: ["IRAssignmentInliner"]
  202. }),
  203. smalltalk.IRInliner);
  204. smalltalk.addMethod(
  205. "_sendInliner",
  206. smalltalk.method({
  207. selector: "sendInliner",
  208. category: 'visiting',
  209. fn: function () {
  210. var self=this;
  211. return (function($rec){smalltalk.send($rec, "_translator_", [self]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.IRSendInliner || IRSendInliner), "_new", []));
  212. return self;},
  213. args: [],
  214. source: "sendInliner\x0a\x09^ IRSendInliner new \x0a\x09\x09translator: self;\x0a\x09\x09yourself",
  215. messageSends: ["translator:", "yourself", "new"],
  216. referencedClasses: ["IRSendInliner"]
  217. }),
  218. smalltalk.IRInliner);
  219. smalltalk.addMethod(
  220. "_shouldInlineAssignment_",
  221. smalltalk.method({
  222. selector: "shouldInlineAssignment:",
  223. category: 'testing',
  224. fn: function (anIRAssignment){
  225. var self=this;
  226. return smalltalk.send(smalltalk.send(smalltalk.send(anIRAssignment, "_isInlined", []), "_not", []), "_and_", [(function(){return smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(anIRAssignment, "_instructions", []), "_last", []), "_isSend", []), "_and_", [(function(){return smalltalk.send(self, "_shouldInlineSend_", [smalltalk.send(smalltalk.send(anIRAssignment, "_instructions", []), "_last", [])]);})]);})]);
  227. return self;},
  228. args: ["anIRAssignment"],
  229. source: "shouldInlineAssignment: anIRAssignment\x0a\x09^ anIRAssignment isInlined not and: [ \x0a\x09\x09anIRAssignment instructions last isSend and: [\x09\x0a\x09\x09\x09self shouldInlineSend: (anIRAssignment instructions last) ]]",
  230. messageSends: ["and:", "not", "isInlined", "isSend", "last", "instructions", "shouldInlineSend:"],
  231. referencedClasses: []
  232. }),
  233. smalltalk.IRInliner);
  234. smalltalk.addMethod(
  235. "_shouldInlineSend_",
  236. smalltalk.method({
  237. selector: "shouldInlineSend:",
  238. category: 'testing',
  239. fn: function (anIRSend){
  240. var self=this;
  241. return smalltalk.send(smalltalk.send(smalltalk.send(anIRSend, "_isInlined", []), "_not", []), "_and_", [(function(){return smalltalk.send(smalltalk.send((smalltalk.IRSendInliner || IRSendInliner), "_inlinedSelectors", []), "_includes_", [smalltalk.send(anIRSend, "_selector", [])]);})]);
  242. return self;},
  243. args: ["anIRSend"],
  244. source: "shouldInlineSend: anIRSend\x0a\x09^ anIRSend isInlined not and: [\x0a\x09\x09IRSendInliner inlinedSelectors includes: anIRSend selector ]",
  245. messageSends: ["and:", "not", "isInlined", "includes:", "inlinedSelectors", "selector"],
  246. referencedClasses: ["IRSendInliner"]
  247. }),
  248. smalltalk.IRInliner);
  249. smalltalk.addMethod(
  250. "_visitIRAssignment_",
  251. smalltalk.method({
  252. selector: "visitIRAssignment:",
  253. category: 'visiting',
  254. fn: function (anIRAssignment){
  255. var self=this;
  256. ((($receiver = smalltalk.send(self, "_shouldInlineAssignment_", [anIRAssignment])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(smalltalk.send(self, "_assignmentInliner", []), "_inlineAssignment_", [anIRAssignment]);})() : (function(){return smalltalk.send(self, "_visitIRAssignment_", [anIRAssignment], smalltalk.IRInliner.superclass || nil);})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(smalltalk.send(self, "_assignmentInliner", []), "_inlineAssignment_", [anIRAssignment]);}), (function(){return smalltalk.send(self, "_visitIRAssignment_", [anIRAssignment], smalltalk.IRInliner.superclass || nil);})]));
  257. return self;},
  258. args: ["anIRAssignment"],
  259. source: "visitIRAssignment: anIRAssignment\x0a\x09(self shouldInlineAssignment: anIRAssignment) \x0a\x09\x09ifTrue: [ self assignmentInliner inlineAssignment: anIRAssignment ]\x0a\x09\x09ifFalse: [ super visitIRAssignment: anIRAssignment ]",
  260. messageSends: ["ifTrue:ifFalse:", "shouldInlineAssignment:", "inlineAssignment:", "assignmentInliner", "visitIRAssignment:"],
  261. referencedClasses: []
  262. }),
  263. smalltalk.IRInliner);
  264. smalltalk.addMethod(
  265. "_visitIRNonLocalReturn_",
  266. smalltalk.method({
  267. selector: "visitIRNonLocalReturn:",
  268. category: 'visiting',
  269. fn: function (anIRNonLocalReturn){
  270. var self=this;
  271. var localReturn=nil;
  272. ((($receiver = smalltalk.send(smalltalk.send(anIRNonLocalReturn, "_scope", []), "_canInlineNonLocalReturns", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){smalltalk.send(smalltalk.send(smalltalk.send(anIRNonLocalReturn, "_scope", []), "_methodScope", []), "_removeNonLocalReturn_", [smalltalk.send(anIRNonLocalReturn, "_scope", [])]);(localReturn=(function($rec){smalltalk.send($rec, "_scope_", [smalltalk.send(anIRNonLocalReturn, "_scope", [])]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.IRInlinedNonLocalReturn || IRInlinedNonLocalReturn), "_new", [])));smalltalk.send(smalltalk.send(anIRNonLocalReturn, "_instructions", []), "_do_", [(function(each){return smalltalk.send(localReturn, "_add_", [each]);})]);return smalltalk.send(anIRNonLocalReturn, "_replaceWith_", [localReturn]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){smalltalk.send(smalltalk.send(smalltalk.send(anIRNonLocalReturn, "_scope", []), "_methodScope", []), "_removeNonLocalReturn_", [smalltalk.send(anIRNonLocalReturn, "_scope", [])]);(localReturn=(function($rec){smalltalk.send($rec, "_scope_", [smalltalk.send(anIRNonLocalReturn, "_scope", [])]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.IRInlinedNonLocalReturn || IRInlinedNonLocalReturn), "_new", [])));smalltalk.send(smalltalk.send(anIRNonLocalReturn, "_instructions", []), "_do_", [(function(each){return smalltalk.send(localReturn, "_add_", [each]);})]);return smalltalk.send(anIRNonLocalReturn, "_replaceWith_", [localReturn]);})]));
  273. smalltalk.send(self, "_visitIRNonLocalReturn_", [anIRNonLocalReturn], smalltalk.IRInliner.superclass || nil);
  274. return self;},
  275. args: ["anIRNonLocalReturn"],
  276. source: "visitIRNonLocalReturn: anIRNonLocalReturn\x0a\x09| localReturn |\x0a\x09anIRNonLocalReturn scope canInlineNonLocalReturns ifTrue: [\x0a\x09\x09anIRNonLocalReturn scope methodScope removeNonLocalReturn: anIRNonLocalReturn scope.\x0a\x09\x09localReturn := IRInlinedNonLocalReturn new\x0a\x09\x09\x09scope: anIRNonLocalReturn scope;\x0a\x09\x09\x09yourself.\x0a\x09\x09anIRNonLocalReturn instructions do: [ :each |\x0a\x09\x09\x09localReturn add: each ].\x0a\x09\x09anIRNonLocalReturn replaceWith: localReturn ].\x0a\x09super visitIRNonLocalReturn: anIRNonLocalReturn",
  277. messageSends: ["ifTrue:", "canInlineNonLocalReturns", "scope", "removeNonLocalReturn:", "methodScope", "scope:", "yourself", "new", "do:", "instructions", "add:", "replaceWith:", "visitIRNonLocalReturn:"],
  278. referencedClasses: ["IRInlinedNonLocalReturn"]
  279. }),
  280. smalltalk.IRInliner);
  281. smalltalk.addMethod(
  282. "_visitIRSend_",
  283. smalltalk.method({
  284. selector: "visitIRSend:",
  285. category: 'visiting',
  286. fn: function (anIRSend){
  287. var self=this;
  288. ((($receiver = smalltalk.send(self, "_shouldInlineSend_", [anIRSend])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(smalltalk.send(self, "_sendInliner", []), "_inlineSend_", [anIRSend]);})() : (function(){return smalltalk.send(self, "_visitIRSend_", [anIRSend], smalltalk.IRInliner.superclass || nil);})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(smalltalk.send(self, "_sendInliner", []), "_inlineSend_", [anIRSend]);}), (function(){return smalltalk.send(self, "_visitIRSend_", [anIRSend], smalltalk.IRInliner.superclass || nil);})]));
  289. return self;},
  290. args: ["anIRSend"],
  291. source: "visitIRSend: anIRSend\x0a\x09(self shouldInlineSend: anIRSend)\x0a\x09\x09ifTrue: [ self sendInliner inlineSend: anIRSend ]\x0a\x09\x09ifFalse: [ super visitIRSend: anIRSend ]",
  292. messageSends: ["ifTrue:ifFalse:", "shouldInlineSend:", "inlineSend:", "sendInliner", "visitIRSend:"],
  293. referencedClasses: []
  294. }),
  295. smalltalk.IRInliner);
  296. smalltalk.addClass('IRInliningJSTranslator', smalltalk.IRJSTranslator, [], 'Compiler-Inlining');
  297. smalltalk.addMethod(
  298. "_visitIRInlinedAssignment_",
  299. smalltalk.method({
  300. selector: "visitIRInlinedAssignment:",
  301. category: 'visiting',
  302. fn: function (anIRInlinedAssignment){
  303. var self=this;
  304. smalltalk.send(self, "_visit_", [smalltalk.send(smalltalk.send(anIRInlinedAssignment, "_instructions", []), "_last", [])]);
  305. return self;},
  306. args: ["anIRInlinedAssignment"],
  307. source: "visitIRInlinedAssignment: anIRInlinedAssignment\x0a\x09self visit: anIRInlinedAssignment instructions last",
  308. messageSends: ["visit:", "last", "instructions"],
  309. referencedClasses: []
  310. }),
  311. smalltalk.IRInliningJSTranslator);
  312. smalltalk.addMethod(
  313. "_visitIRInlinedClosure_",
  314. smalltalk.method({
  315. selector: "visitIRInlinedClosure:",
  316. category: 'visiting',
  317. fn: function (anIRInlinedClosure){
  318. var self=this;
  319. smalltalk.send(smalltalk.send(smalltalk.send(anIRInlinedClosure, "_instructions", []), "_allButLast", []), "_do_", [(function(each){return smalltalk.send(self, "_visit_", [each]);})]);
  320. ((($receiver = smalltalk.send(smalltalk.send(smalltalk.send(anIRInlinedClosure, "_assignTo", []), "_notNil", []), "_and_", [(function(){return smalltalk.send(smalltalk.send(smalltalk.send(anIRInlinedClosure, "_instructions", []), "_last", []), "_canBeAssigned", []);})])).klass === smalltalk.Boolean) ? ($receiver ? (function(){smalltalk.send(smalltalk.send(self, "_stream", []), "_nextPutAll_", [smalltalk.send(smalltalk.send(smalltalk.send(anIRInlinedClosure, "_assignTo", []), "_variable", []), "_alias", [])]);return smalltalk.send(smalltalk.send(self, "_stream", []), "_nextPutAssignment", []);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){smalltalk.send(smalltalk.send(self, "_stream", []), "_nextPutAll_", [smalltalk.send(smalltalk.send(smalltalk.send(anIRInlinedClosure, "_assignTo", []), "_variable", []), "_alias", [])]);return smalltalk.send(smalltalk.send(self, "_stream", []), "_nextPutAssignment", []);})]));
  321. smalltalk.send(self, "_visit_", [smalltalk.send(smalltalk.send(anIRInlinedClosure, "_instructions", []), "_last", [])]);
  322. return self;},
  323. args: ["anIRInlinedClosure"],
  324. source: "visitIRInlinedClosure: anIRInlinedClosure\x0a\x09anIRInlinedClosure instructions allButLast do: [ :each | self visit: each ].\x0a\x09(anIRInlinedClosure assignTo notNil and: [\x0a\x09\x09anIRInlinedClosure instructions last canBeAssigned ]) ifTrue: [\x0a\x09\x09\x09self stream nextPutAll: anIRInlinedClosure assignTo variable alias.\x0a\x09\x09\x09self stream nextPutAssignment ].\x0a\x09self visit: anIRInlinedClosure instructions last",
  325. messageSends: ["do:", "allButLast", "instructions", "visit:", "ifTrue:", "and:", "notNil", "assignTo", "canBeAssigned", "last", "nextPutAll:", "stream", "alias", "variable", "nextPutAssignment"],
  326. referencedClasses: []
  327. }),
  328. smalltalk.IRInliningJSTranslator);
  329. smalltalk.addMethod(
  330. "_visitIRInlinedIfFalse_",
  331. smalltalk.method({
  332. selector: "visitIRInlinedIfFalse:",
  333. category: 'visiting',
  334. fn: function (anIRInlinedIfFalse){
  335. var self=this;
  336. smalltalk.send(smalltalk.send(self, "_stream", []), "_nextPutIf_with_", [(function(){smalltalk.send(smalltalk.send(self, "_stream", []), "_nextPutAll_", ["!"]);return smalltalk.send(self, "_visit_", [smalltalk.send(smalltalk.send(anIRInlinedIfFalse, "_instructions", []), "_first", [])]);}), (function(){return smalltalk.send(self, "_visit_", [smalltalk.send(smalltalk.send(anIRInlinedIfFalse, "_instructions", []), "_last", [])]);})]);
  337. return self;},
  338. args: ["anIRInlinedIfFalse"],
  339. source: "visitIRInlinedIfFalse: anIRInlinedIfFalse\x0a\x09self stream \x0a\x09\x09nextPutIf: [ \x0a\x09\x09\x09self stream nextPutAll: '!'.\x0a\x09\x09\x09self visit: anIRInlinedIfFalse instructions first ]\x0a\x09\x09with: [ self visit: anIRInlinedIfFalse instructions last ]",
  340. messageSends: ["nextPutIf:with:", "stream", "nextPutAll:", "visit:", "first", "instructions", "last"],
  341. referencedClasses: []
  342. }),
  343. smalltalk.IRInliningJSTranslator);
  344. smalltalk.addMethod(
  345. "_visitIRInlinedIfTrue_",
  346. smalltalk.method({
  347. selector: "visitIRInlinedIfTrue:",
  348. category: 'visiting',
  349. fn: function (anIRInlinedIfTrue){
  350. var self=this;
  351. smalltalk.send(smalltalk.send(self, "_stream", []), "_nextPutIf_with_", [(function(){return smalltalk.send(self, "_visit_", [smalltalk.send(smalltalk.send(anIRInlinedIfTrue, "_instructions", []), "_first", [])]);}), (function(){return smalltalk.send(self, "_visit_", [smalltalk.send(smalltalk.send(anIRInlinedIfTrue, "_instructions", []), "_last", [])]);})]);
  352. return self;},
  353. args: ["anIRInlinedIfTrue"],
  354. source: "visitIRInlinedIfTrue: anIRInlinedIfTrue\x0a\x09self stream \x0a\x09\x09nextPutIf: [ self visit: anIRInlinedIfTrue instructions first ]\x0a\x09\x09with: [ self visit: anIRInlinedIfTrue instructions last ]",
  355. messageSends: ["nextPutIf:with:", "stream", "visit:", "first", "instructions", "last"],
  356. referencedClasses: []
  357. }),
  358. smalltalk.IRInliningJSTranslator);
  359. smalltalk.addClass('IRSendInliner', smalltalk.Object, ['send', 'translator'], 'Compiler-Inlining');
  360. smalltalk.IRSendInliner.comment="I inline some message sends and block closure arguments. I heavily rely on #perform: to dispatch inlining methods."
  361. smalltalk.addMethod(
  362. "_ifFalse_",
  363. smalltalk.method({
  364. selector: "ifFalse:",
  365. category: 'inlining',
  366. fn: function (anIRInstruction){
  367. var self=this;
  368. var inlinedSend=nil;
  369. var inlinedClosure=nil;
  370. ((($receiver = smalltalk.send(anIRInstruction, "_isClosure", [])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return smalltalk.send(self, "_inliningError_", ["Message argument should be a block"]);})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return smalltalk.send(self, "_inliningError_", ["Message argument should be a block"]);})]));
  371. ((($receiver = smalltalk.send(smalltalk.send(smalltalk.send(anIRInstruction, "_arguments", []), "_size", []), "__eq", [(0)])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return smalltalk.send(self, "_inliningError_", ["Inlined block should have zero argument"]);})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return smalltalk.send(self, "_inliningError_", ["Inlined block should have zero argument"]);})]));
  372. (inlinedClosure=smalltalk.send(self, "_inlineClosure_", [anIRInstruction]));
  373. (inlinedSend=smalltalk.send((smalltalk.IRInlinedIfFalse || IRInlinedIfFalse), "_new", []));
  374. (function($rec){smalltalk.send($rec, "_add_", [smalltalk.send(smalltalk.send(smalltalk.send(self, "_send", []), "_instructions", []), "_first", [])]);return smalltalk.send($rec, "_add_", [inlinedClosure]);})(inlinedSend);
  375. smalltalk.send(smalltalk.send(self, "_send", []), "_replaceWith_", [inlinedSend]);
  376. return inlinedSend;
  377. return self;},
  378. args: ["anIRInstruction"],
  379. source: "ifFalse: anIRInstruction\x0a\x09| inlinedSend inlinedClosure |\x0a\x0a\x09anIRInstruction isClosure ifFalse: [ self inliningError: 'Message argument should be a block' ].\x0a\x09anIRInstruction arguments size = 0 ifFalse: [ self inliningError: 'Inlined block should have zero argument' ].\x0a\x0a\x09inlinedClosure := self inlineClosure: anIRInstruction.\x0a\x0a\x09inlinedSend := IRInlinedIfFalse new.\x0a\x09inlinedSend\x0a\x09\x09add: self send instructions first;\x0a\x09\x09add: inlinedClosure.\x0a\x0a\x09self send replaceWith: inlinedSend.\x0a\x09^ inlinedSend",
  380. messageSends: ["ifFalse:", "isClosure", "inliningError:", "=", "size", "arguments", "inlineClosure:", "new", "add:", "first", "instructions", "send", "replaceWith:"],
  381. referencedClasses: ["IRInlinedIfFalse"]
  382. }),
  383. smalltalk.IRSendInliner);
  384. smalltalk.addMethod(
  385. "_ifTrue_",
  386. smalltalk.method({
  387. selector: "ifTrue:",
  388. category: 'inlining',
  389. fn: function (anIRInstruction){
  390. var self=this;
  391. var inlinedSend=nil;
  392. var inlinedClosure=nil;
  393. ((($receiver = smalltalk.send(anIRInstruction, "_isClosure", [])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return smalltalk.send(self, "_inliningError_", ["Message argument should be a block"]);})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return smalltalk.send(self, "_inliningError_", ["Message argument should be a block"]);})]));
  394. ((($receiver = smalltalk.send(smalltalk.send(smalltalk.send(anIRInstruction, "_arguments", []), "_size", []), "__eq", [(0)])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return smalltalk.send(self, "_inliningError_", ["Inlined block should have zero argument"]);})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return smalltalk.send(self, "_inliningError_", ["Inlined block should have zero argument"]);})]));
  395. (inlinedClosure=smalltalk.send(self, "_inlineClosure_", [anIRInstruction]));
  396. (inlinedSend=smalltalk.send((smalltalk.IRInlinedIfTrue || IRInlinedIfTrue), "_new", []));
  397. (function($rec){smalltalk.send($rec, "_add_", [smalltalk.send(smalltalk.send(smalltalk.send(self, "_send", []), "_instructions", []), "_first", [])]);return smalltalk.send($rec, "_add_", [inlinedClosure]);})(inlinedSend);
  398. smalltalk.send(smalltalk.send(self, "_send", []), "_replaceWith_", [inlinedSend]);
  399. return inlinedSend;
  400. return self;},
  401. args: ["anIRInstruction"],
  402. source: "ifTrue: anIRInstruction\x0a\x09| inlinedSend inlinedClosure |\x0a\x0a\x09anIRInstruction isClosure ifFalse: [ self inliningError: 'Message argument should be a block' ].\x0a\x09anIRInstruction arguments size = 0 ifFalse: [ self inliningError: 'Inlined block should have zero argument' ].\x0a\x0a\x09inlinedClosure := self inlineClosure: anIRInstruction.\x0a\x0a\x09inlinedSend := IRInlinedIfTrue new.\x0a\x09inlinedSend\x0a\x09\x09add: self send instructions first;\x0a\x09\x09add: inlinedClosure.\x0a\x0a\x09self send replaceWith: inlinedSend.\x0a\x09^ inlinedSend",
  403. messageSends: ["ifFalse:", "isClosure", "inliningError:", "=", "size", "arguments", "inlineClosure:", "new", "add:", "first", "instructions", "send", "replaceWith:"],
  404. referencedClasses: ["IRInlinedIfTrue"]
  405. }),
  406. smalltalk.IRSendInliner);
  407. smalltalk.addMethod(
  408. "_inlineClosure_",
  409. smalltalk.method({
  410. selector: "inlineClosure:",
  411. category: 'inlining',
  412. fn: function (anIRClosure){
  413. var self=this;
  414. var inlinedClosure=nil;
  415. (inlinedClosure=smalltalk.send(self, "_inlinedClosure", []));
  416. smalltalk.send(inlinedClosure, "_scope_", [smalltalk.send(anIRClosure, "_scope", [])]);
  417. smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(anIRClosure, "_instructions", []), "_first", []), "_instructions", []), "_do_", [(function(each){return smalltalk.send(inlinedClosure, "_add_", [smalltalk.send(smalltalk.send(self, "_translator", []), "_visit_", [each])]);})]);
  418. return inlinedClosure;
  419. return self;},
  420. args: ["anIRClosure"],
  421. source: "inlineClosure: anIRClosure\x0a\x09| inlinedClosure |\x0a\x09inlinedClosure := self inlinedClosure.\x0a\x09inlinedClosure scope: anIRClosure scope.\x0a\x09anIRClosure instructions first instructions do: [ :each |\x0a\x09\x09inlinedClosure add: (self translator visit: each) ].\x0a\x09^ inlinedClosure",
  422. messageSends: ["inlinedClosure", "scope:", "scope", "do:", "instructions", "first", "add:", "visit:", "translator"],
  423. referencedClasses: []
  424. }),
  425. smalltalk.IRSendInliner);
  426. smalltalk.addMethod(
  427. "_inlineSend_",
  428. smalltalk.method({
  429. selector: "inlineSend:",
  430. category: 'inlining',
  431. fn: function (anIRSend){
  432. var self=this;
  433. smalltalk.send(self, "_send_", [anIRSend]);
  434. smalltalk.send(self, "_perform_withArguments_", [smalltalk.send(smalltalk.send(self, "_send", []), "_selector", []), smalltalk.send(smalltalk.send(smalltalk.send(self, "_send", []), "_instructions", []), "_allButFirst", [])]);
  435. return self;},
  436. args: ["anIRSend"],
  437. source: "inlineSend: anIRSend\x0a\x09self send: anIRSend.\x0a\x09self perform: self send selector withArguments: self send instructions allButFirst",
  438. messageSends: ["send:", "perform:withArguments:", "selector", "send", "allButFirst", "instructions"],
  439. referencedClasses: []
  440. }),
  441. smalltalk.IRSendInliner);
  442. smalltalk.addMethod(
  443. "_inlinedClosure",
  444. smalltalk.method({
  445. selector: "inlinedClosure",
  446. category: 'accessing',
  447. fn: function (){
  448. var self=this;
  449. return smalltalk.send((smalltalk.IRInlinedClosure || IRInlinedClosure), "_new", []);
  450. return self;},
  451. args: [],
  452. source: "inlinedClosure\x0a\x09^ IRInlinedClosure new",
  453. messageSends: ["new"],
  454. referencedClasses: ["IRInlinedClosure"]
  455. }),
  456. smalltalk.IRSendInliner);
  457. smalltalk.addMethod(
  458. "_inliningError_",
  459. smalltalk.method({
  460. selector: "inliningError:",
  461. category: 'error handling',
  462. fn: function (aString) {
  463. var self=this;
  464. smalltalk.send((smalltalk.InliningError || InliningError), "_signal_", [aString]);
  465. return self;},
  466. args: ["aString"],
  467. source: "inliningError: aString\x0a\x09InliningError signal: aString",
  468. messageSends: ["signal:"],
  469. referencedClasses: ["InliningError"]
  470. }),
  471. smalltalk.IRSendInliner);
  472. smalltalk.addMethod(
  473. "_send",
  474. smalltalk.method({
  475. selector: "send",
  476. category: 'accessing',
  477. fn: function () {
  478. var self=this;
  479. return self['@send'];
  480. return self;},
  481. args: [],
  482. source: "send\x0a\x09^ send",
  483. messageSends: [],
  484. referencedClasses: []
  485. }),
  486. smalltalk.IRSendInliner);
  487. smalltalk.addMethod(
  488. "_send_",
  489. smalltalk.method({
  490. selector: "send:",
  491. category: 'accessing',
  492. fn: function (anIRSend) {
  493. var self=this;
  494. (self['@send']=anIRSend);
  495. return self;},
  496. args: ["anIRSend"],
  497. source: "send: anIRSend\x0a\x09send := anIRSend",
  498. messageSends: [],
  499. referencedClasses: []
  500. }),
  501. smalltalk.IRSendInliner);
  502. smalltalk.addMethod(
  503. "_translator",
  504. smalltalk.method({
  505. selector: "translator",
  506. category: 'accessing',
  507. fn: function () {
  508. var self=this;
  509. return self['@translator'];
  510. return self;},
  511. args: [],
  512. source: "translator\x0a\x09^ translator",
  513. messageSends: [],
  514. referencedClasses: []
  515. }),
  516. smalltalk.IRSendInliner);
  517. smalltalk.addMethod(
  518. "_translator_",
  519. smalltalk.method({
  520. selector: "translator:",
  521. category: 'accessing',
  522. fn: function (anASTTranslator) {
  523. var self=this;
  524. (self['@translator']=anASTTranslator);
  525. return self;},
  526. args: ["anASTTranslator"],
  527. source: "translator: anASTTranslator\x0a\x09translator := anASTTranslator",
  528. messageSends: [],
  529. referencedClasses: []
  530. }),
  531. smalltalk.IRSendInliner);
  532. smalltalk.addMethod(
  533. "_inlinedSelectors",
  534. smalltalk.method({
  535. selector: "inlinedSelectors",
  536. category: 'accessing',
  537. fn: function (){
  538. var self=this;
  539. return ["ifTrue:", "ifFalse:"];
  540. return self;},
  541. args: [],
  542. source: "inlinedSelectors\x0a\x09^ #('ifTrue:' 'ifFalse:')",
  543. messageSends: [],
  544. referencedClasses: []
  545. }),
  546. smalltalk.IRSendInliner.klass);
  547. smalltalk.addClass('IRAssignmentInliner', smalltalk.IRSendInliner, ['assignment'], 'Compiler-Inlining');
  548. smalltalk.addMethod(
  549. "_assignment",
  550. smalltalk.method({
  551. selector: "assignment",
  552. category: 'accessing',
  553. fn: function () {
  554. var self=this;
  555. return self['@assignment'];
  556. return self;},
  557. args: [],
  558. source: "assignment\x0a\x09^ assignment",
  559. messageSends: [],
  560. referencedClasses: []
  561. }),
  562. smalltalk.IRAssignmentInliner);
  563. smalltalk.addMethod(
  564. "_assignment_",
  565. smalltalk.method({
  566. selector: "assignment:",
  567. category: 'accessing',
  568. fn: function (aNode) {
  569. var self=this;
  570. (self['@assignment']=aNode);
  571. return self;},
  572. args: ["aNode"],
  573. source: "assignment: aNode\x0a\x09assignment := aNode",
  574. messageSends: [],
  575. referencedClasses: []
  576. }),
  577. smalltalk.IRAssignmentInliner);
  578. smalltalk.addMethod(
  579. "_inlineAssignment_",
  580. smalltalk.method({
  581. selector: "inlineAssignment:",
  582. category: 'inlining',
  583. fn: function (anIRAssignment){
  584. var self=this;
  585. var inlinedAssignment=nil;
  586. smalltalk.send(self, "_assignment_", [anIRAssignment]);
  587. (inlinedAssignment=smalltalk.send((smalltalk.IRInlinedAssignment || IRInlinedAssignment), "_new", []));
  588. smalltalk.send(smalltalk.send(anIRAssignment, "_instructions", []), "_do_", [(function(each){return smalltalk.send(inlinedAssignment, "_add_", [each]);})]);
  589. smalltalk.send(anIRAssignment, "_replaceWith_", [inlinedAssignment]);
  590. smalltalk.send(self, "_inlineSend_", [smalltalk.send(smalltalk.send(inlinedAssignment, "_instructions", []), "_last", [])]);
  591. return inlinedAssignment;
  592. return self;},
  593. args: ["anIRAssignment"],
  594. source: "inlineAssignment: anIRAssignment\x0a\x09| inlinedAssignment |\x0a\x09self assignment: anIRAssignment.\x0a\x09inlinedAssignment := IRInlinedAssignment new.\x0a\x09anIRAssignment instructions do: [ :each |\x0a\x09\x09inlinedAssignment add: each ].\x0a\x09anIRAssignment replaceWith: inlinedAssignment.\x0a\x09self inlineSend: inlinedAssignment instructions last.\x0a\x09^ inlinedAssignment",
  595. messageSends: ["assignment:", "new", "do:", "instructions", "add:", "replaceWith:", "inlineSend:", "last"],
  596. referencedClasses: ["IRInlinedAssignment"]
  597. }),
  598. smalltalk.IRAssignmentInliner);
  599. smalltalk.addMethod(
  600. "_inlinedClosure",
  601. smalltalk.method({
  602. selector: "inlinedClosure",
  603. category: 'accessing',
  604. fn: function (){
  605. var self=this;
  606. return (function($rec){smalltalk.send($rec, "_assignTo_", [smalltalk.send(smalltalk.send(smalltalk.send(self, "_assignment", []), "_instructions", []), "_first", [])]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_inlinedClosure", [], smalltalk.IRAssignmentInliner.superclass || nil));
  607. return self;},
  608. args: [],
  609. source: "inlinedClosure\x0a\x09^ super inlinedClosure\x0a\x09\x09assignTo: self assignment instructions first;\x0a\x09\x09yourself",
  610. messageSends: ["assignTo:", "first", "instructions", "assignment", "yourself", "inlinedClosure"],
  611. referencedClasses: []
  612. }),
  613. smalltalk.IRAssignmentInliner);
  614. smalltalk.addClass('InliningCodeGenerator', smalltalk.CodeGenerator, [], 'Compiler-Inlining');
  615. smalltalk.addMethod(
  616. "_compileNode_",
  617. smalltalk.method({
  618. selector: "compileNode:",
  619. category: 'compiling',
  620. fn: function (aNode){
  621. var self=this;
  622. var ir=nil;
  623. var stream=nil;
  624. smalltalk.send(smalltalk.send(self, "_semanticAnalyzer", []), "_visit_", [aNode]);
  625. (ir=smalltalk.send(smalltalk.send(self, "_translator", []), "_visit_", [aNode]));
  626. smalltalk.send(smalltalk.send(self, "_inliner", []), "_visit_", [ir]);
  627. return (function($rec){smalltalk.send($rec, "_visit_", [ir]);return smalltalk.send($rec, "_contents", []);})(smalltalk.send(self, "_irTranslator", []));
  628. return self;},
  629. args: ["aNode"],
  630. source: "compileNode: aNode\x0a\x09| ir stream |\x0a\x09self semanticAnalyzer visit: aNode.\x0a\x09ir := self translator visit: aNode.\x0a\x09self inliner visit: ir.\x0a\x09^ self irTranslator\x0a\x09\x09visit: ir;\x0a\x09\x09contents",
  631. messageSends: ["visit:", "semanticAnalyzer", "translator", "inliner", "contents", "irTranslator"],
  632. referencedClasses: []
  633. }),
  634. smalltalk.InliningCodeGenerator);
  635. smalltalk.addMethod(
  636. "_inliner",
  637. smalltalk.method({
  638. selector: "inliner",
  639. category: 'compiling',
  640. fn: function (){
  641. var self=this;
  642. return smalltalk.send((smalltalk.IRInliner || IRInliner), "_new", []);
  643. return self;},
  644. args: [],
  645. source: "inliner\x0a\x09^ IRInliner new",
  646. messageSends: ["new"],
  647. referencedClasses: ["IRInliner"]
  648. }),
  649. smalltalk.InliningCodeGenerator);
  650. smalltalk.addMethod(
  651. "_irTranslator",
  652. smalltalk.method({
  653. selector: "irTranslator",
  654. category: 'compiling',
  655. fn: function () {
  656. var self=this;
  657. return smalltalk.send((smalltalk.IRInliningJSTranslator || IRInliningJSTranslator), "_new", []);
  658. return self;},
  659. args: [],
  660. source: "irTranslator\x0a\x09^ IRInliningJSTranslator new",
  661. messageSends: ["new"],
  662. referencedClasses: ["IRInliningJSTranslator"]
  663. }),
  664. smalltalk.InliningCodeGenerator);