Compiler-Inlining.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647
  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.IRNonLocalReturn, [], '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('IRInlinedIfTrue', 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, "_visitIRInlinedIfTrue_", [self]);
  165. return self;},
  166. args: ["aVisitor"],
  167. source: "accept: aVisitor\x0a\x09aVisitor visitIRInlinedIfTrue: self",
  168. messageSends: ["visitIRInlinedIfTrue:"],
  169. referencedClasses: []
  170. }),
  171. smalltalk.IRInlinedIfTrue);
  172. smalltalk.addClass('IRInliner', smalltalk.IRVisitor, [], 'Compiler-Inlining');
  173. smalltalk.addMethod(
  174. "_assignmentInliner",
  175. smalltalk.method({
  176. selector: "assignmentInliner",
  177. category: 'visiting',
  178. fn: function () {
  179. var self=this;
  180. return (function($rec){smalltalk.send($rec, "_translator_", [self]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.IRAssignmentInliner || IRAssignmentInliner), "_new", []));
  181. return self;},
  182. args: [],
  183. source: "assignmentInliner\x0a\x09^ IRAssignmentInliner new \x0a\x09\x09translator: self;\x0a\x09\x09yourself",
  184. messageSends: ["translator:", "yourself", "new"],
  185. referencedClasses: ["IRAssignmentInliner"]
  186. }),
  187. smalltalk.IRInliner);
  188. smalltalk.addMethod(
  189. "_sendInliner",
  190. smalltalk.method({
  191. selector: "sendInliner",
  192. category: 'visiting',
  193. fn: function () {
  194. var self=this;
  195. return (function($rec){smalltalk.send($rec, "_translator_", [self]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.IRSendInliner || IRSendInliner), "_new", []));
  196. return self;},
  197. args: [],
  198. source: "sendInliner\x0a\x09^ IRSendInliner new \x0a\x09\x09translator: self;\x0a\x09\x09yourself",
  199. messageSends: ["translator:", "yourself", "new"],
  200. referencedClasses: ["IRSendInliner"]
  201. }),
  202. smalltalk.IRInliner);
  203. smalltalk.addMethod(
  204. "_shouldInlineAssignment_",
  205. smalltalk.method({
  206. selector: "shouldInlineAssignment:",
  207. category: 'testing',
  208. fn: function (anIRAssignment){
  209. var self=this;
  210. 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", [])]);})]);})]);
  211. return self;},
  212. args: ["anIRAssignment"],
  213. 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) ]]",
  214. messageSends: ["and:", "not", "isInlined", "isSend", "last", "instructions", "shouldInlineSend:"],
  215. referencedClasses: []
  216. }),
  217. smalltalk.IRInliner);
  218. smalltalk.addMethod(
  219. "_shouldInlineSend_",
  220. smalltalk.method({
  221. selector: "shouldInlineSend:",
  222. category: 'testing',
  223. fn: function (anIRSend){
  224. var self=this;
  225. 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", [])]);})]);
  226. return self;},
  227. args: ["anIRSend"],
  228. source: "shouldInlineSend: anIRSend\x0a\x09^ anIRSend isInlined not and: [\x0a\x09\x09IRSendInliner inlinedSelectors includes: anIRSend selector ]",
  229. messageSends: ["and:", "not", "isInlined", "includes:", "inlinedSelectors", "selector"],
  230. referencedClasses: ["IRSendInliner"]
  231. }),
  232. smalltalk.IRInliner);
  233. smalltalk.addMethod(
  234. "_visitIRAssignment_",
  235. smalltalk.method({
  236. selector: "visitIRAssignment:",
  237. category: 'visiting',
  238. fn: function (anIRAssignment){
  239. var self=this;
  240. return ((($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);})]));
  241. return self;},
  242. args: ["anIRAssignment"],
  243. source: "visitIRAssignment: anIRAssignment\x0a\x09^ (self shouldInlineAssignment: anIRAssignment) \x0a\x09\x09ifTrue: [ self assignmentInliner inlineAssignment: anIRAssignment ]\x0a\x09\x09ifFalse: [ super visitIRAssignment: anIRAssignment ]",
  244. messageSends: ["ifTrue:ifFalse:", "shouldInlineAssignment:", "inlineAssignment:", "assignmentInliner", "visitIRAssignment:"],
  245. referencedClasses: []
  246. }),
  247. smalltalk.IRInliner);
  248. smalltalk.addMethod(
  249. "_visitIRSend_",
  250. smalltalk.method({
  251. selector: "visitIRSend:",
  252. category: 'visiting',
  253. fn: function (anIRSend){
  254. var self=this;
  255. return ((($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);})]));
  256. return self;},
  257. args: ["anIRSend"],
  258. source: "visitIRSend: anIRSend\x0a\x09^ (self shouldInlineSend: anIRSend)\x0a\x09\x09ifTrue: [ self sendInliner inlineSend: anIRSend ]\x0a\x09\x09ifFalse: [ super visitIRSend: anIRSend ]",
  259. messageSends: ["ifTrue:ifFalse:", "shouldInlineSend:", "inlineSend:", "sendInliner", "visitIRSend:"],
  260. referencedClasses: []
  261. }),
  262. smalltalk.IRInliner);
  263. smalltalk.addMethod(
  264. "_visitSendNode_",
  265. smalltalk.method({
  266. selector: "visitSendNode:",
  267. category: 'visiting',
  268. fn: function (aNode) {
  269. var self=this;
  270. ((($receiver = smalltalk.send(aNode, "_canBeInlined", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(smalltalk.send(self, "_sendInliner", []), "_inlineSend_", [aNode]);})() : (function(){return smalltalk.send(self, "_visitSendNode_", [aNode], smalltalk.IRInliningASTResolver.superclass || nil);})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(smalltalk.send(self, "_sendInliner", []), "_inlineSend_", [aNode]);}), (function(){return smalltalk.send(self, "_visitSendNode_", [aNode], smalltalk.IRInliningASTResolver.superclass || nil);})]));
  271. return self;},
  272. args: ["aNode"],
  273. source: "visitSendNode: aNode\x0a\x09aNode canBeInlined\x0a\x09\x09ifTrue: [ self sendInliner inlineSend: aNode ]\x0a\x09\x09ifFalse: [ super visitSendNode: aNode ]",
  274. messageSends: ["ifTrue:ifFalse:", "canBeInlined", "inlineSend:", "sendInliner", "visitSendNode:"],
  275. referencedClasses: []
  276. }),
  277. smalltalk.IRInliner);
  278. smalltalk.addClass('IRInliningJSTranslator', smalltalk.IRJSTranslator, [], 'Compiler-Inlining');
  279. smalltalk.addMethod(
  280. "_visitIRInlinedAssignment_",
  281. smalltalk.method({
  282. selector: "visitIRInlinedAssignment:",
  283. category: 'visiting',
  284. fn: function (anIRInlinedAssignment){
  285. var self=this;
  286. smalltalk.send(self, "_visit_", [smalltalk.send(smalltalk.send(anIRInlinedAssignment, "_instructions", []), "_last", [])]);
  287. return self;},
  288. args: ["anIRInlinedAssignment"],
  289. source: "visitIRInlinedAssignment: anIRInlinedAssignment\x0a\x09self visit: anIRInlinedAssignment instructions last",
  290. messageSends: ["visit:", "last", "instructions"],
  291. referencedClasses: []
  292. }),
  293. smalltalk.IRInliningJSTranslator);
  294. smalltalk.addMethod(
  295. "_visitIRInlinedClosure_",
  296. smalltalk.method({
  297. selector: "visitIRInlinedClosure:",
  298. category: 'visiting',
  299. fn: function (anIRInlinedClosure){
  300. var self=this;
  301. smalltalk.send(smalltalk.send(smalltalk.send(anIRInlinedClosure, "_instructions", []), "_allButLast", []), "_do_", [(function(each){return smalltalk.send(self, "_visit_", [each]);})]);
  302. (($receiver = smalltalk.send(anIRInlinedClosure, "_assignTo", [])) != nil && $receiver != undefined) ? (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;
  303. smalltalk.send(self, "_visit_", [smalltalk.send(smalltalk.send(anIRInlinedClosure, "_instructions", []), "_last", [])]);
  304. return self;},
  305. args: ["anIRInlinedClosure"],
  306. source: "visitIRInlinedClosure: anIRInlinedClosure\x0a\x09anIRInlinedClosure instructions allButLast do: [ :each | self visit: each ].\x0a\x09anIRInlinedClosure assignTo ifNotNil: [\x0a\x09\x09self stream nextPutAll: anIRInlinedClosure assignTo variable alias.\x0a\x09\x09self stream nextPutAssignment ].\x0a\x09self visit: anIRInlinedClosure instructions last",
  307. messageSends: ["do:", "allButLast", "instructions", "visit:", "ifNotNil:", "assignTo", "nextPutAll:", "stream", "alias", "variable", "nextPutAssignment", "last"],
  308. referencedClasses: []
  309. }),
  310. smalltalk.IRInliningJSTranslator);
  311. smalltalk.addMethod(
  312. "_visitIRInlinedIfTrue_",
  313. smalltalk.method({
  314. selector: "visitIRInlinedIfTrue:",
  315. category: 'visiting',
  316. fn: function (anIRInlinedIfTrue) {
  317. var self=this;
  318. 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", [])]);})]);
  319. return self;},
  320. args: ["anIRInlinedIfTrue"],
  321. source: "visitIRInlinedIfTrue: anIRInlinedIfTrue\x0a\x09self stream \x0a\x09\x09nextPutIf: [ self visit: anIRInlinedIfTrue instructions first ]\x0a\x09\x09with: [ self visit: anIRInlinedIfTrue instructions last ]",
  322. messageSends: ["nextPutIf:with:", "stream", "visit:", "first", "instructions", "last"],
  323. referencedClasses: []
  324. }),
  325. smalltalk.IRInliningJSTranslator);
  326. smalltalk.addClass('IRSendInliner', smalltalk.Object, ['send', 'translator'], 'Compiler-Inlining');
  327. smalltalk.IRSendInliner.comment="I inline some message sends and block closure arguments. I heavily rely on #perform: to dispatch inlining methods."
  328. smalltalk.addMethod(
  329. "_ifTrue_",
  330. smalltalk.method({
  331. selector: "ifTrue:",
  332. category: 'inlining',
  333. fn: function (anIRInstruction){
  334. var self=this;
  335. var inlinedSend=nil;
  336. var inlinedClosure=nil;
  337. ((($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"]);})]));
  338. ((($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"]);})]));
  339. (inlinedClosure=smalltalk.send(self, "_inlinedClosure", []));
  340. smalltalk.send(smalltalk.send(anIRInstruction, "_instructions", []), "_do_", [(function(each){(instruction=smalltalk.send(smalltalk.send(smalltalk.send(self, "_translator", []), "_visit_", [each]), "_first", []));return smalltalk.send(inlinedClosure, "_add_", [(typeof instruction == 'undefined' ? nil : instruction)]);})]);
  341. (inlinedSend=smalltalk.send((smalltalk.IRInlinedIfTrue || IRInlinedIfTrue), "_new", []));
  342. (function($rec){smalltalk.send($rec, "_add_", [smalltalk.send(smalltalk.send(smalltalk.send(self, "_send", []), "_instructions", []), "_first", [])]);return smalltalk.send($rec, "_add_", [inlinedClosure]);})(inlinedSend);
  343. smalltalk.send(smalltalk.send(self, "_send", []), "_replaceWith_", [inlinedSend]);
  344. return inlinedSend;
  345. return self;},
  346. args: ["anIRInstruction"],
  347. 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 inlinedClosure.\x0a\x09anIRInstruction instructions do: [ :each |\x0a\x09\x09instruction := (self translator visit: each) first.\x0a\x09\x09inlinedClosure add: instruction ].\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",
  348. messageSends: ["ifFalse:", "isClosure", "inliningError:", "=", "size", "arguments", "inlinedClosure", "do:", "instructions", "first", "visit:", "translator", "add:", "new", "send", "replaceWith:"],
  349. referencedClasses: ["IRInlinedIfTrue"]
  350. }),
  351. smalltalk.IRSendInliner);
  352. smalltalk.addMethod(
  353. "_inlineSend_",
  354. smalltalk.method({
  355. selector: "inlineSend:",
  356. category: 'inlining',
  357. fn: function (anIRSend){
  358. var self=this;
  359. smalltalk.send(self, "_send_", [anIRSend]);
  360. smalltalk.send(self, "_perform_withArguments_", [smalltalk.send(smalltalk.send(self, "_send", []), "_selector", []), smalltalk.send(smalltalk.send(smalltalk.send(self, "_send", []), "_instructions", []), "_allButFirst", [])]);
  361. return self;},
  362. args: ["anIRSend"],
  363. source: "inlineSend: anIRSend\x0a\x09self send: anIRSend.\x0a\x09self perform: self send selector withArguments: self send instructions allButFirst",
  364. messageSends: ["send:", "perform:withArguments:", "selector", "send", "allButFirst", "instructions"],
  365. referencedClasses: []
  366. }),
  367. smalltalk.IRSendInliner);
  368. smalltalk.addMethod(
  369. "_inlinedClosure",
  370. smalltalk.method({
  371. selector: "inlinedClosure",
  372. category: 'accessing',
  373. fn: function (){
  374. var self=this;
  375. return smalltalk.send((smalltalk.IRInlinedClosure || IRInlinedClosure), "_new", []);
  376. return self;},
  377. args: [],
  378. source: "inlinedClosure\x0a\x09^ IRInlinedClosure new",
  379. messageSends: ["new"],
  380. referencedClasses: ["IRInlinedClosure"]
  381. }),
  382. smalltalk.IRSendInliner);
  383. smalltalk.addMethod(
  384. "_inliningError_",
  385. smalltalk.method({
  386. selector: "inliningError:",
  387. category: 'error handling',
  388. fn: function (aString) {
  389. var self=this;
  390. smalltalk.send((smalltalk.InliningError || InliningError), "_signal_", [aString]);
  391. return self;},
  392. args: ["aString"],
  393. source: "inliningError: aString\x0a\x09InliningError signal: aString",
  394. messageSends: ["signal:"],
  395. referencedClasses: ["InliningError"]
  396. }),
  397. smalltalk.IRSendInliner);
  398. smalltalk.addMethod(
  399. "_send",
  400. smalltalk.method({
  401. selector: "send",
  402. category: 'accessing',
  403. fn: function () {
  404. var self=this;
  405. return self['@send'];
  406. return self;},
  407. args: [],
  408. source: "send\x0a\x09^ send",
  409. messageSends: [],
  410. referencedClasses: []
  411. }),
  412. smalltalk.IRSendInliner);
  413. smalltalk.addMethod(
  414. "_send_",
  415. smalltalk.method({
  416. selector: "send:",
  417. category: 'accessing',
  418. fn: function (anIRSend) {
  419. var self=this;
  420. (self['@send']=anIRSend);
  421. return self;},
  422. args: ["anIRSend"],
  423. source: "send: anIRSend\x0a\x09send := anIRSend",
  424. messageSends: [],
  425. referencedClasses: []
  426. }),
  427. smalltalk.IRSendInliner);
  428. smalltalk.addMethod(
  429. "_translator",
  430. smalltalk.method({
  431. selector: "translator",
  432. category: 'accessing',
  433. fn: function () {
  434. var self=this;
  435. return self['@translator'];
  436. return self;},
  437. args: [],
  438. source: "translator\x0a\x09^ translator",
  439. messageSends: [],
  440. referencedClasses: []
  441. }),
  442. smalltalk.IRSendInliner);
  443. smalltalk.addMethod(
  444. "_translator_",
  445. smalltalk.method({
  446. selector: "translator:",
  447. category: 'accessing',
  448. fn: function (anASTTranslator) {
  449. var self=this;
  450. (self['@translator']=anASTTranslator);
  451. return self;},
  452. args: ["anASTTranslator"],
  453. source: "translator: anASTTranslator\x0a\x09translator := anASTTranslator",
  454. messageSends: [],
  455. referencedClasses: []
  456. }),
  457. smalltalk.IRSendInliner);
  458. smalltalk.addMethod(
  459. "_inlinedSelectors",
  460. smalltalk.method({
  461. selector: "inlinedSelectors",
  462. category: 'accessing',
  463. fn: function () {
  464. var self=this;
  465. return ["ifTrue:"];
  466. return self;},
  467. args: [],
  468. source: "inlinedSelectors\x0a\x09^ #('ifTrue:')",
  469. messageSends: [],
  470. referencedClasses: []
  471. }),
  472. smalltalk.IRSendInliner.klass);
  473. smalltalk.addClass('IRAssignmentInliner', smalltalk.IRSendInliner, ['assignment'], 'Compiler-Inlining');
  474. smalltalk.addMethod(
  475. "_assignment",
  476. smalltalk.method({
  477. selector: "assignment",
  478. category: 'accessing',
  479. fn: function () {
  480. var self=this;
  481. return self['@assignment'];
  482. return self;},
  483. args: [],
  484. source: "assignment\x0a\x09^ assignment",
  485. messageSends: [],
  486. referencedClasses: []
  487. }),
  488. smalltalk.IRAssignmentInliner);
  489. smalltalk.addMethod(
  490. "_assignment_",
  491. smalltalk.method({
  492. selector: "assignment:",
  493. category: 'accessing',
  494. fn: function (aNode) {
  495. var self=this;
  496. (self['@assignment']=aNode);
  497. return self;},
  498. args: ["aNode"],
  499. source: "assignment: aNode\x0a\x09assignment := aNode",
  500. messageSends: [],
  501. referencedClasses: []
  502. }),
  503. smalltalk.IRAssignmentInliner);
  504. smalltalk.addMethod(
  505. "_inlineAssignment_",
  506. smalltalk.method({
  507. selector: "inlineAssignment:",
  508. category: 'inlining',
  509. fn: function (anIRAssignment){
  510. var self=this;
  511. var inlinedAssignment=nil;
  512. smalltalk.send(self, "_assignment_", [anIRAssignment]);
  513. (inlinedAssignment=smalltalk.send((smalltalk.IRInlinedAssignment || IRInlinedAssignment), "_new", []));
  514. smalltalk.send(smalltalk.send(anIRAssignment, "_instructions", []), "_do_", [(function(each){return smalltalk.send(inlinedAssignment, "_add_", [each]);})]);
  515. smalltalk.send(anIRAssignment, "_replaceWith_", [inlinedAssignment]);
  516. smalltalk.send(self, "_inlineSend_", [smalltalk.send(smalltalk.send(inlinedAssignment, "_instructions", []), "_last", [])]);
  517. return inlinedAssignment;
  518. return self;},
  519. args: ["anIRAssignment"],
  520. 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",
  521. messageSends: ["assignment:", "new", "do:", "instructions", "add:", "replaceWith:", "inlineSend:", "last"],
  522. referencedClasses: ["IRInlinedAssignment"]
  523. }),
  524. smalltalk.IRAssignmentInliner);
  525. smalltalk.addMethod(
  526. "_inlinedClosure",
  527. smalltalk.method({
  528. selector: "inlinedClosure",
  529. category: 'accessing',
  530. fn: function (){
  531. var self=this;
  532. 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));
  533. return self;},
  534. args: [],
  535. source: "inlinedClosure\x0a\x09^ super inlinedClosure\x0a\x09\x09assignTo: self assignment instructions first;\x0a\x09\x09yourself",
  536. messageSends: ["assignTo:", "first", "instructions", "assignment", "yourself", "inlinedClosure"],
  537. referencedClasses: []
  538. }),
  539. smalltalk.IRAssignmentInliner);
  540. smalltalk.addClass('InliningCodeGenerator', smalltalk.CodeGenerator, [], 'Compiler-Inlining');
  541. smalltalk.addMethod(
  542. "_compileNode_",
  543. smalltalk.method({
  544. selector: "compileNode:",
  545. category: 'compiling',
  546. fn: function (aNode){
  547. var self=this;
  548. var ir=nil;
  549. var stream=nil;
  550. smalltalk.send(smalltalk.send(self, "_semanticAnalyzer", []), "_visit_", [aNode]);
  551. (ir=smalltalk.send(smalltalk.send(self, "_translator", []), "_visit_", [aNode]));
  552. smalltalk.send(smalltalk.send(self, "_inliner", []), "_visit_", [ir]);
  553. return (function($rec){smalltalk.send($rec, "_visit_", [ir]);return smalltalk.send($rec, "_contents", []);})(smalltalk.send(self, "_irTranslator", []));
  554. return self;},
  555. args: ["aNode"],
  556. 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",
  557. messageSends: ["visit:", "semanticAnalyzer", "translator", "inliner", "contents", "irTranslator"],
  558. referencedClasses: []
  559. }),
  560. smalltalk.InliningCodeGenerator);
  561. smalltalk.addMethod(
  562. "_inliner",
  563. smalltalk.method({
  564. selector: "inliner",
  565. category: 'compiling',
  566. fn: function (){
  567. var self=this;
  568. return smalltalk.send((smalltalk.IRInliner || IRInliner), "_new", []);
  569. return self;},
  570. args: [],
  571. source: "inliner\x0a\x09^ IRInliner new",
  572. messageSends: ["new"],
  573. referencedClasses: ["IRInliner"]
  574. }),
  575. smalltalk.InliningCodeGenerator);
  576. smalltalk.addMethod(
  577. "_irTranslator",
  578. smalltalk.method({
  579. selector: "irTranslator",
  580. category: 'compiling',
  581. fn: function () {
  582. var self=this;
  583. return smalltalk.send((smalltalk.IRInliningJSTranslator || IRInliningJSTranslator), "_new", []);
  584. return self;},
  585. args: [],
  586. source: "irTranslator\x0a\x09^ IRInliningJSTranslator new",
  587. messageSends: ["new"],
  588. referencedClasses: ["IRInliningJSTranslator"]
  589. }),
  590. smalltalk.InliningCodeGenerator);