1
0

Compiler-Inlining.js 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725
  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(anIRInlinedClosure, "_instructions", []), "_ifNotEmpty_", [(function(){smalltalk.send(smalltalk.send(smalltalk.send(anIRInlinedClosure, "_instructions", []), "_allButLast", []), "_do_", [(function(each){return smalltalk.send(self, "_visit_", [each]);})]);((($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", []);})]));return smalltalk.send(self, "_visit_", [smalltalk.send(smalltalk.send(anIRInlinedClosure, "_instructions", []), "_last", [])]);})]);
  320. return self;},
  321. args: ["anIRInlinedClosure"],
  322. source: "visitIRInlinedClosure: anIRInlinedClosure\x0a\x09anIRInlinedClosure instructions ifNotEmpty: [\x0a\x09\x09anIRInlinedClosure instructions allButLast do: [ :each | self visit: each ].\x0a\x09\x09(anIRInlinedClosure assignTo notNil and: [\x0a\x09\x09\x09anIRInlinedClosure instructions last canBeAssigned ]) ifTrue: [\x0a\x09\x09\x09\x09self stream nextPutAll: anIRInlinedClosure assignTo variable alias.\x0a\x09\x09\x09\x09self stream nextPutAssignment ].\x0a\x09\x09self visit: anIRInlinedClosure instructions last ]",
  323. messageSends: ["ifNotEmpty:", "instructions", "do:", "allButLast", "visit:", "ifTrue:", "and:", "notNil", "assignTo", "canBeAssigned", "last", "nextPutAll:", "stream", "alias", "variable", "nextPutAssignment"],
  324. referencedClasses: []
  325. }),
  326. smalltalk.IRInliningJSTranslator);
  327. smalltalk.addMethod(
  328. "_visitIRInlinedIfFalse_",
  329. smalltalk.method({
  330. selector: "visitIRInlinedIfFalse:",
  331. category: 'visiting',
  332. fn: function (anIRInlinedIfFalse) {
  333. var self=this;
  334. smalltalk.send(smalltalk.send(self, "_stream", []), "_nextPutIf_with_", [(function(){smalltalk.send(smalltalk.send(self, "_stream", []), "_nextPutAll_", ["! smalltalk.assert("]);smalltalk.send(self, "_visit_", [smalltalk.send(smalltalk.send(anIRInlinedIfFalse, "_instructions", []), "_first", [])]);return smalltalk.send(smalltalk.send(self, "_stream", []), "_nextPutAll_", [")"]);}), (function(){return smalltalk.send(self, "_visit_", [smalltalk.send(smalltalk.send(anIRInlinedIfFalse, "_instructions", []), "_last", [])]);})]);
  335. return self;},
  336. args: ["anIRInlinedIfFalse"],
  337. source: "visitIRInlinedIfFalse: anIRInlinedIfFalse\x0a\x09self stream \x0a\x09\x09nextPutIf: [ \x0a\x09\x09\x09self stream nextPutAll: '! smalltalk.assert('.\x0a\x09\x09\x09self visit: anIRInlinedIfFalse instructions first.\x0a\x09\x09\x09self stream nextPutAll: ')' ]\x0a\x09\x09with: [ self visit: anIRInlinedIfFalse instructions last ]",
  338. messageSends: ["nextPutIf:with:", "stream", "nextPutAll:", "visit:", "first", "instructions", "last"],
  339. referencedClasses: []
  340. }),
  341. smalltalk.IRInliningJSTranslator);
  342. smalltalk.addMethod(
  343. "_visitIRInlinedIfTrue_",
  344. smalltalk.method({
  345. selector: "visitIRInlinedIfTrue:",
  346. category: 'visiting',
  347. fn: function (anIRInlinedIfTrue) {
  348. var self=this;
  349. smalltalk.send(smalltalk.send(self, "_stream", []), "_nextPutIf_with_", [(function(){smalltalk.send(smalltalk.send(self, "_stream", []), "_nextPutAll_", ["smalltalk.assert("]);smalltalk.send(self, "_visit_", [smalltalk.send(smalltalk.send(anIRInlinedIfTrue, "_instructions", []), "_first", [])]);return smalltalk.send(smalltalk.send(self, "_stream", []), "_nextPutAll_", [")"]);}), (function(){return smalltalk.send(self, "_visit_", [smalltalk.send(smalltalk.send(anIRInlinedIfTrue, "_instructions", []), "_last", [])]);})]);
  350. return self;},
  351. args: ["anIRInlinedIfTrue"],
  352. source: "visitIRInlinedIfTrue: anIRInlinedIfTrue\x0a\x09self stream \x0a\x09\x09nextPutIf: [ \x0a\x09\x09\x09self stream nextPutAll: 'smalltalk.assert('. \x0a\x09\x09\x09self visit: anIRInlinedIfTrue instructions first.\x0a\x09\x09\x09self stream nextPutAll: ')' ]\x0a\x09\x09with: [ self visit: anIRInlinedIfTrue instructions last ]",
  353. messageSends: ["nextPutIf:with:", "stream", "nextPutAll:", "visit:", "first", "instructions", "last"],
  354. referencedClasses: []
  355. }),
  356. smalltalk.IRInliningJSTranslator);
  357. smalltalk.addClass('IRSendInliner', smalltalk.Object, ['send', 'translator'], 'Compiler-Inlining');
  358. smalltalk.IRSendInliner.comment="I inline some message sends and block closure arguments. I heavily rely on #perform: to dispatch inlining methods."
  359. smalltalk.addMethod(
  360. "_ifFalse_",
  361. smalltalk.method({
  362. selector: "ifFalse:",
  363. category: 'inlining',
  364. fn: function (anIRInstruction) {
  365. var self=this;
  366. var inlinedSend=nil;
  367. var inlinedClosure=nil;
  368. ((($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"]);})]));
  369. ((($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"]);})]));
  370. (inlinedClosure=smalltalk.send(self, "_inlineClosure_", [anIRInstruction]));
  371. (inlinedSend=smalltalk.send((smalltalk.IRInlinedIfFalse || IRInlinedIfFalse), "_new", []));
  372. (function($rec){smalltalk.send($rec, "_add_", [smalltalk.send(smalltalk.send(smalltalk.send(self, "_send", []), "_instructions", []), "_first", [])]);return smalltalk.send($rec, "_add_", [inlinedClosure]);})(inlinedSend);
  373. smalltalk.send(smalltalk.send(self, "_send", []), "_replaceWith_", [inlinedSend]);
  374. return inlinedSend;
  375. return self;},
  376. args: ["anIRInstruction"],
  377. 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",
  378. messageSends: ["ifFalse:", "isClosure", "inliningError:", "=", "size", "arguments", "inlineClosure:", "new", "add:", "first", "instructions", "send", "replaceWith:"],
  379. referencedClasses: ["IRInlinedIfFalse"]
  380. }),
  381. smalltalk.IRSendInliner);
  382. smalltalk.addMethod(
  383. "_ifTrue_",
  384. smalltalk.method({
  385. selector: "ifTrue:",
  386. category: 'inlining',
  387. fn: function (anIRInstruction) {
  388. var self=this;
  389. var inlinedSend=nil;
  390. var inlinedClosure=nil;
  391. ((($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"]);})]));
  392. ((($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"]);})]));
  393. (inlinedClosure=smalltalk.send(self, "_inlineClosure_", [anIRInstruction]));
  394. (inlinedSend=smalltalk.send((smalltalk.IRInlinedIfTrue || IRInlinedIfTrue), "_new", []));
  395. (function($rec){smalltalk.send($rec, "_add_", [smalltalk.send(smalltalk.send(smalltalk.send(self, "_send", []), "_instructions", []), "_first", [])]);return smalltalk.send($rec, "_add_", [inlinedClosure]);})(inlinedSend);
  396. smalltalk.send(smalltalk.send(self, "_send", []), "_replaceWith_", [inlinedSend]);
  397. return inlinedSend;
  398. return self;},
  399. args: ["anIRInstruction"],
  400. 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",
  401. messageSends: ["ifFalse:", "isClosure", "inliningError:", "=", "size", "arguments", "inlineClosure:", "new", "add:", "first", "instructions", "send", "replaceWith:"],
  402. referencedClasses: ["IRInlinedIfTrue"]
  403. }),
  404. smalltalk.IRSendInliner);
  405. smalltalk.addMethod(
  406. "_inlineClosure_",
  407. smalltalk.method({
  408. selector: "inlineClosure:",
  409. category: 'inlining',
  410. fn: function (anIRClosure) {
  411. var self=this;
  412. var inlinedClosure=nil;
  413. (inlinedClosure=smalltalk.send(self, "_inlinedClosure", []));
  414. smalltalk.send(inlinedClosure, "_scope_", [smalltalk.send(anIRClosure, "_scope", [])]);
  415. 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])]);})]);
  416. return inlinedClosure;
  417. return self;},
  418. args: ["anIRClosure"],
  419. 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",
  420. messageSends: ["inlinedClosure", "scope:", "scope", "do:", "instructions", "first", "add:", "visit:", "translator"],
  421. referencedClasses: []
  422. }),
  423. smalltalk.IRSendInliner);
  424. smalltalk.addMethod(
  425. "_inlineSend_",
  426. smalltalk.method({
  427. selector: "inlineSend:",
  428. category: 'inlining',
  429. fn: function (anIRSend) {
  430. var self=this;
  431. smalltalk.send(self, "_send_", [anIRSend]);
  432. smalltalk.send(self, "_perform_withArguments_", [smalltalk.send(smalltalk.send(self, "_send", []), "_selector", []), smalltalk.send(smalltalk.send(smalltalk.send(self, "_send", []), "_instructions", []), "_allButFirst", [])]);
  433. return self;},
  434. args: ["anIRSend"],
  435. source: "inlineSend: anIRSend\x0a\x09self send: anIRSend.\x0a\x09self perform: self send selector withArguments: self send instructions allButFirst",
  436. messageSends: ["send:", "perform:withArguments:", "selector", "send", "allButFirst", "instructions"],
  437. referencedClasses: []
  438. }),
  439. smalltalk.IRSendInliner);
  440. smalltalk.addMethod(
  441. "_inlinedClosure",
  442. smalltalk.method({
  443. selector: "inlinedClosure",
  444. category: 'accessing',
  445. fn: function () {
  446. var self=this;
  447. return smalltalk.send((smalltalk.IRInlinedClosure || IRInlinedClosure), "_new", []);
  448. return self;},
  449. args: [],
  450. source: "inlinedClosure\x0a\x09^ IRInlinedClosure new",
  451. messageSends: ["new"],
  452. referencedClasses: ["IRInlinedClosure"]
  453. }),
  454. smalltalk.IRSendInliner);
  455. smalltalk.addMethod(
  456. "_inliningError_",
  457. smalltalk.method({
  458. selector: "inliningError:",
  459. category: 'error handling',
  460. fn: function (aString) {
  461. var self=this;
  462. smalltalk.send((smalltalk.InliningError || InliningError), "_signal_", [aString]);
  463. return self;},
  464. args: ["aString"],
  465. source: "inliningError: aString\x0a\x09InliningError signal: aString",
  466. messageSends: ["signal:"],
  467. referencedClasses: ["InliningError"]
  468. }),
  469. smalltalk.IRSendInliner);
  470. smalltalk.addMethod(
  471. "_send",
  472. smalltalk.method({
  473. selector: "send",
  474. category: 'accessing',
  475. fn: function () {
  476. var self=this;
  477. return self['@send'];
  478. return self;},
  479. args: [],
  480. source: "send\x0a\x09^ send",
  481. messageSends: [],
  482. referencedClasses: []
  483. }),
  484. smalltalk.IRSendInliner);
  485. smalltalk.addMethod(
  486. "_send_",
  487. smalltalk.method({
  488. selector: "send:",
  489. category: 'accessing',
  490. fn: function (anIRSend) {
  491. var self=this;
  492. (self['@send']=anIRSend);
  493. return self;},
  494. args: ["anIRSend"],
  495. source: "send: anIRSend\x0a\x09send := anIRSend",
  496. messageSends: [],
  497. referencedClasses: []
  498. }),
  499. smalltalk.IRSendInliner);
  500. smalltalk.addMethod(
  501. "_translator",
  502. smalltalk.method({
  503. selector: "translator",
  504. category: 'accessing',
  505. fn: function () {
  506. var self=this;
  507. return self['@translator'];
  508. return self;},
  509. args: [],
  510. source: "translator\x0a\x09^ translator",
  511. messageSends: [],
  512. referencedClasses: []
  513. }),
  514. smalltalk.IRSendInliner);
  515. smalltalk.addMethod(
  516. "_translator_",
  517. smalltalk.method({
  518. selector: "translator:",
  519. category: 'accessing',
  520. fn: function (anASTTranslator) {
  521. var self=this;
  522. (self['@translator']=anASTTranslator);
  523. return self;},
  524. args: ["anASTTranslator"],
  525. source: "translator: anASTTranslator\x0a\x09translator := anASTTranslator",
  526. messageSends: [],
  527. referencedClasses: []
  528. }),
  529. smalltalk.IRSendInliner);
  530. smalltalk.addMethod(
  531. "_inlinedSelectors",
  532. smalltalk.method({
  533. selector: "inlinedSelectors",
  534. category: 'accessing',
  535. fn: function () {
  536. var self=this;
  537. return ["ifTrue:", "ifFalse:"];
  538. return self;},
  539. args: [],
  540. source: "inlinedSelectors\x0a\x09^ #('ifTrue:' 'ifFalse:')",
  541. messageSends: [],
  542. referencedClasses: []
  543. }),
  544. smalltalk.IRSendInliner.klass);
  545. smalltalk.addClass('IRAssignmentInliner', smalltalk.IRSendInliner, ['assignment'], 'Compiler-Inlining');
  546. smalltalk.addMethod(
  547. "_assignment",
  548. smalltalk.method({
  549. selector: "assignment",
  550. category: 'accessing',
  551. fn: function () {
  552. var self=this;
  553. return self['@assignment'];
  554. return self;},
  555. args: [],
  556. source: "assignment\x0a\x09^ assignment",
  557. messageSends: [],
  558. referencedClasses: []
  559. }),
  560. smalltalk.IRAssignmentInliner);
  561. smalltalk.addMethod(
  562. "_assignment_",
  563. smalltalk.method({
  564. selector: "assignment:",
  565. category: 'accessing',
  566. fn: function (aNode) {
  567. var self=this;
  568. (self['@assignment']=aNode);
  569. return self;},
  570. args: ["aNode"],
  571. source: "assignment: aNode\x0a\x09assignment := aNode",
  572. messageSends: [],
  573. referencedClasses: []
  574. }),
  575. smalltalk.IRAssignmentInliner);
  576. smalltalk.addMethod(
  577. "_inlineAssignment_",
  578. smalltalk.method({
  579. selector: "inlineAssignment:",
  580. category: 'inlining',
  581. fn: function (anIRAssignment) {
  582. var self=this;
  583. var inlinedAssignment=nil;
  584. smalltalk.send(self, "_assignment_", [anIRAssignment]);
  585. (inlinedAssignment=smalltalk.send((smalltalk.IRInlinedAssignment || IRInlinedAssignment), "_new", []));
  586. smalltalk.send(smalltalk.send(anIRAssignment, "_instructions", []), "_do_", [(function(each){return smalltalk.send(inlinedAssignment, "_add_", [each]);})]);
  587. smalltalk.send(anIRAssignment, "_replaceWith_", [inlinedAssignment]);
  588. smalltalk.send(self, "_inlineSend_", [smalltalk.send(smalltalk.send(inlinedAssignment, "_instructions", []), "_last", [])]);
  589. return inlinedAssignment;
  590. return self;},
  591. args: ["anIRAssignment"],
  592. 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",
  593. messageSends: ["assignment:", "new", "do:", "instructions", "add:", "replaceWith:", "inlineSend:", "last"],
  594. referencedClasses: ["IRInlinedAssignment"]
  595. }),
  596. smalltalk.IRAssignmentInliner);
  597. smalltalk.addMethod(
  598. "_inlinedClosure",
  599. smalltalk.method({
  600. selector: "inlinedClosure",
  601. category: 'accessing',
  602. fn: function () {
  603. var self=this;
  604. 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));
  605. return self;},
  606. args: [],
  607. source: "inlinedClosure\x0a\x09^ super inlinedClosure\x0a\x09\x09assignTo: self assignment instructions first;\x0a\x09\x09yourself",
  608. messageSends: ["assignTo:", "first", "instructions", "assignment", "yourself", "inlinedClosure"],
  609. referencedClasses: []
  610. }),
  611. smalltalk.IRAssignmentInliner);
  612. smalltalk.addClass('InliningCodeGenerator', smalltalk.CodeGenerator, [], 'Compiler-Inlining');
  613. smalltalk.addMethod(
  614. "_compileNode_",
  615. smalltalk.method({
  616. selector: "compileNode:",
  617. category: 'compiling',
  618. fn: function (aNode) {
  619. var self=this;
  620. var ir=nil;
  621. var stream=nil;
  622. smalltalk.send(smalltalk.send(self, "_semanticAnalyzer", []), "_visit_", [aNode]);
  623. (ir=smalltalk.send(smalltalk.send(self, "_translator", []), "_visit_", [aNode]));
  624. smalltalk.send(smalltalk.send(self, "_inliner", []), "_visit_", [ir]);
  625. return (function($rec){smalltalk.send($rec, "_visit_", [ir]);return smalltalk.send($rec, "_contents", []);})(smalltalk.send(self, "_irTranslator", []));
  626. return self;},
  627. args: ["aNode"],
  628. 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",
  629. messageSends: ["visit:", "semanticAnalyzer", "translator", "inliner", "contents", "irTranslator"],
  630. referencedClasses: []
  631. }),
  632. smalltalk.InliningCodeGenerator);
  633. smalltalk.addMethod(
  634. "_inliner",
  635. smalltalk.method({
  636. selector: "inliner",
  637. category: 'compiling',
  638. fn: function () {
  639. var self=this;
  640. return smalltalk.send((smalltalk.IRInliner || IRInliner), "_new", []);
  641. return self;},
  642. args: [],
  643. source: "inliner\x0a\x09^ IRInliner new",
  644. messageSends: ["new"],
  645. referencedClasses: ["IRInliner"]
  646. }),
  647. smalltalk.InliningCodeGenerator);
  648. smalltalk.addMethod(
  649. "_irTranslator",
  650. smalltalk.method({
  651. selector: "irTranslator",
  652. category: 'compiling',
  653. fn: function () {
  654. var self=this;
  655. return smalltalk.send((smalltalk.IRInliningJSTranslator || IRInliningJSTranslator), "_new", []);
  656. return self;},
  657. args: [],
  658. source: "irTranslator\x0a\x09^ IRInliningJSTranslator new",
  659. messageSends: ["new"],
  660. referencedClasses: ["IRInliningJSTranslator"]
  661. }),
  662. smalltalk.InliningCodeGenerator);