Compiler-Inlining.js 63 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413
  1. smalltalk.addPackage('Compiler-Inlining', {});
  2. smalltalk.addClass('IRInlinedAssignment', smalltalk.IRAssignment, [], 'Compiler-Inlining');
  3. smalltalk.IRInlinedAssignment.comment="I represent an inlined assignment instruction."
  4. smalltalk.addMethod(
  5. "_accept_",
  6. smalltalk.method({
  7. selector: "accept:",
  8. category: 'visiting',
  9. fn: function (aVisitor) {
  10. var self = this;
  11. var $1;
  12. $1 = smalltalk.send(aVisitor, "_visitIRInlinedAssignment_", [self]);
  13. return $1;
  14. },
  15. args: ["aVisitor"],
  16. source: "accept: aVisitor\x0a\x09^ aVisitor visitIRInlinedAssignment: self",
  17. messageSends: ["visitIRInlinedAssignment:"],
  18. referencedClasses: []
  19. }),
  20. smalltalk.IRInlinedAssignment);
  21. smalltalk.addMethod(
  22. "_isInlined",
  23. smalltalk.method({
  24. selector: "isInlined",
  25. category: 'testing',
  26. fn: function () {
  27. var self = this;
  28. return true;
  29. },
  30. args: [],
  31. source: "isInlined\x0a\x09^ true",
  32. messageSends: [],
  33. referencedClasses: []
  34. }),
  35. smalltalk.IRInlinedAssignment);
  36. smalltalk.addClass('IRInlinedClosure', smalltalk.IRClosure, [], 'Compiler-Inlining');
  37. smalltalk.IRInlinedClosure.comment="I represent an inlined closure instruction."
  38. smalltalk.addMethod(
  39. "_accept_",
  40. smalltalk.method({
  41. selector: "accept:",
  42. category: 'visiting',
  43. fn: function (aVisitor) {
  44. var self = this;
  45. smalltalk.send(aVisitor, "_visitIRInlinedClosure_", [self]);
  46. return self;
  47. },
  48. args: ["aVisitor"],
  49. source: "accept: aVisitor\x0a\x09aVisitor visitIRInlinedClosure: self",
  50. messageSends: ["visitIRInlinedClosure:"],
  51. referencedClasses: []
  52. }),
  53. smalltalk.IRInlinedClosure);
  54. smalltalk.addMethod(
  55. "_isInlined",
  56. smalltalk.method({
  57. selector: "isInlined",
  58. category: 'testing',
  59. fn: function () {
  60. var self = this;
  61. return true;
  62. },
  63. args: [],
  64. source: "isInlined\x0a\x09^ true",
  65. messageSends: [],
  66. referencedClasses: []
  67. }),
  68. smalltalk.IRInlinedClosure);
  69. smalltalk.addClass('IRInlinedReturn', smalltalk.IRReturn, [], 'Compiler-Inlining');
  70. smalltalk.IRInlinedReturn.comment="I represent an inlined local return instruction."
  71. smalltalk.addMethod(
  72. "_accept_",
  73. smalltalk.method({
  74. selector: "accept:",
  75. category: 'visiting',
  76. fn: function (aVisitor) {
  77. var self = this;
  78. var $1;
  79. $1 = smalltalk.send(aVisitor, "_visitIRInlinedReturn_", [self]);
  80. return $1;
  81. },
  82. args: ["aVisitor"],
  83. source: "accept: aVisitor\x0a\x09^ aVisitor visitIRInlinedReturn: self",
  84. messageSends: ["visitIRInlinedReturn:"],
  85. referencedClasses: []
  86. }),
  87. smalltalk.IRInlinedReturn);
  88. smalltalk.addMethod(
  89. "_isInlined",
  90. smalltalk.method({
  91. selector: "isInlined",
  92. category: 'testing',
  93. fn: function () {
  94. var self = this;
  95. return true;
  96. },
  97. args: [],
  98. source: "isInlined\x0a\x09^ true",
  99. messageSends: [],
  100. referencedClasses: []
  101. }),
  102. smalltalk.IRInlinedReturn);
  103. smalltalk.addClass('IRInlinedNonLocalReturn', smalltalk.IRInlinedReturn, [], 'Compiler-Inlining');
  104. smalltalk.IRInlinedNonLocalReturn.comment="I represent an inlined non local return instruction."
  105. smalltalk.addMethod(
  106. "_accept_",
  107. smalltalk.method({
  108. selector: "accept:",
  109. category: 'visiting',
  110. fn: function (aVisitor) {
  111. var self = this;
  112. var $1;
  113. $1 = smalltalk.send(aVisitor, "_visitIRInlinedNonLocalReturn_", [self]);
  114. return $1;
  115. },
  116. args: ["aVisitor"],
  117. source: "accept: aVisitor\x0a\x09^ aVisitor visitIRInlinedNonLocalReturn: self",
  118. messageSends: ["visitIRInlinedNonLocalReturn:"],
  119. referencedClasses: []
  120. }),
  121. smalltalk.IRInlinedNonLocalReturn);
  122. smalltalk.addMethod(
  123. "_isInlined",
  124. smalltalk.method({
  125. selector: "isInlined",
  126. category: 'testing',
  127. fn: function () {
  128. var self = this;
  129. return true;
  130. },
  131. args: [],
  132. source: "isInlined\x0a\x09^ true",
  133. messageSends: [],
  134. referencedClasses: []
  135. }),
  136. smalltalk.IRInlinedNonLocalReturn);
  137. smalltalk.addClass('IRInlinedSend', smalltalk.IRSend, [], 'Compiler-Inlining');
  138. smalltalk.IRInlinedSend.comment="I am the abstract super class of inlined message send instructions."
  139. smalltalk.addMethod(
  140. "_accept_",
  141. smalltalk.method({
  142. selector: "accept:",
  143. category: 'visiting',
  144. fn: function (aVisitor) {
  145. var self = this;
  146. smalltalk.send(aVisitor, "_visitInlinedSend_", [self]);
  147. return self;
  148. },
  149. args: ["aVisitor"],
  150. source: "accept: aVisitor\x0a\x09aVisitor visitInlinedSend: self",
  151. messageSends: ["visitInlinedSend:"],
  152. referencedClasses: []
  153. }),
  154. smalltalk.IRInlinedSend);
  155. smalltalk.addMethod(
  156. "_isInlined",
  157. smalltalk.method({
  158. selector: "isInlined",
  159. category: 'testing',
  160. fn: function () {
  161. var self = this;
  162. return true;
  163. },
  164. args: [],
  165. source: "isInlined\x0a\x09^ true",
  166. messageSends: [],
  167. referencedClasses: []
  168. }),
  169. smalltalk.IRInlinedSend);
  170. smalltalk.addClass('IRInlinedIfFalse', smalltalk.IRInlinedSend, [], 'Compiler-Inlining');
  171. smalltalk.addMethod(
  172. "_accept_",
  173. smalltalk.method({
  174. selector: "accept:",
  175. category: 'visiting',
  176. fn: function (aVisitor) {
  177. var self = this;
  178. smalltalk.send(aVisitor, "_visitIRInlinedIfFalse_", [self]);
  179. return self;
  180. },
  181. args: ["aVisitor"],
  182. source: "accept: aVisitor\x0a\x09aVisitor visitIRInlinedIfFalse: self",
  183. messageSends: ["visitIRInlinedIfFalse:"],
  184. referencedClasses: []
  185. }),
  186. smalltalk.IRInlinedIfFalse);
  187. smalltalk.addClass('IRInlinedIfNilIfNotNil', smalltalk.IRInlinedSend, [], 'Compiler-Inlining');
  188. smalltalk.addMethod(
  189. "_accept_",
  190. smalltalk.method({
  191. selector: "accept:",
  192. category: 'visiting',
  193. fn: function (aVisitor) {
  194. var self = this;
  195. smalltalk.send(aVisitor, "_visitIRInlinedIfNilIfNotNil_", [self]);
  196. return self;
  197. },
  198. args: ["aVisitor"],
  199. source: "accept: aVisitor\x0a\x09aVisitor visitIRInlinedIfNilIfNotNil: self",
  200. messageSends: ["visitIRInlinedIfNilIfNotNil:"],
  201. referencedClasses: []
  202. }),
  203. smalltalk.IRInlinedIfNilIfNotNil);
  204. smalltalk.addClass('IRInlinedIfTrue', smalltalk.IRInlinedSend, [], 'Compiler-Inlining');
  205. smalltalk.addMethod(
  206. "_accept_",
  207. smalltalk.method({
  208. selector: "accept:",
  209. category: 'visiting',
  210. fn: function (aVisitor) {
  211. var self = this;
  212. smalltalk.send(aVisitor, "_visitIRInlinedIfTrue_", [self]);
  213. return self;
  214. },
  215. args: ["aVisitor"],
  216. source: "accept: aVisitor\x0a\x09aVisitor visitIRInlinedIfTrue: self",
  217. messageSends: ["visitIRInlinedIfTrue:"],
  218. referencedClasses: []
  219. }),
  220. smalltalk.IRInlinedIfTrue);
  221. smalltalk.addClass('IRInlinedIfTrueIfFalse', smalltalk.IRInlinedSend, [], 'Compiler-Inlining');
  222. smalltalk.addMethod(
  223. "_accept_",
  224. smalltalk.method({
  225. selector: "accept:",
  226. category: 'visiting',
  227. fn: function (aVisitor) {
  228. var self = this;
  229. smalltalk.send(aVisitor, "_visitIRInlinedIfTrueIfFalse_", [self]);
  230. return self;
  231. },
  232. args: ["aVisitor"],
  233. source: "accept: aVisitor\x0a\x09aVisitor visitIRInlinedIfTrueIfFalse: self",
  234. messageSends: ["visitIRInlinedIfTrueIfFalse:"],
  235. referencedClasses: []
  236. }),
  237. smalltalk.IRInlinedIfTrueIfFalse);
  238. smalltalk.addClass('IRInlinedSequence', smalltalk.IRBlockSequence, [], 'Compiler-Inlining');
  239. smalltalk.IRInlinedSequence.comment="I represent a (block) sequence inside an inlined closure instruction (instance of `IRInlinedClosure`)."
  240. smalltalk.addMethod(
  241. "_accept_",
  242. smalltalk.method({
  243. selector: "accept:",
  244. category: 'visiting',
  245. fn: function (aVisitor) {
  246. var self = this;
  247. smalltalk.send(aVisitor, "_visitIRInlinedSequence_", [self]);
  248. return self;
  249. },
  250. args: ["aVisitor"],
  251. source: "accept: aVisitor\x0a\x09aVisitor visitIRInlinedSequence: self",
  252. messageSends: ["visitIRInlinedSequence:"],
  253. referencedClasses: []
  254. }),
  255. smalltalk.IRInlinedSequence);
  256. smalltalk.addMethod(
  257. "_isInlined",
  258. smalltalk.method({
  259. selector: "isInlined",
  260. category: 'testing',
  261. fn: function () {
  262. var self = this;
  263. return true;
  264. },
  265. args: [],
  266. source: "isInlined\x0a\x09^ true",
  267. messageSends: [],
  268. referencedClasses: []
  269. }),
  270. smalltalk.IRInlinedSequence);
  271. smalltalk.addClass('IRInliner', smalltalk.IRVisitor, [], 'Compiler-Inlining');
  272. smalltalk.IRInliner.comment="I visit an IR tree, inlining message sends and block closures.\x0a\x0aMessage selectors that can be inlined are answered by `IRSendInliner >> #inlinedSelectors`"
  273. smalltalk.addMethod(
  274. "_assignmentInliner",
  275. smalltalk.method({
  276. selector: "assignmentInliner",
  277. category: 'factory',
  278. fn: function () {
  279. var self = this;
  280. var $2, $3, $1;
  281. $2 = smalltalk.send(smalltalk.IRAssignmentInliner || IRAssignmentInliner, "_new", []);
  282. smalltalk.send($2, "_translator_", [self]);
  283. $3 = smalltalk.send($2, "_yourself", []);
  284. $1 = $3;
  285. return $1;
  286. },
  287. args: [],
  288. source: "assignmentInliner\x0a\x09^ IRAssignmentInliner new \x0a\x09\x09translator: self;\x0a\x09\x09yourself",
  289. messageSends: ["translator:", "new", "yourself"],
  290. referencedClasses: ["IRAssignmentInliner"]
  291. }),
  292. smalltalk.IRInliner);
  293. smalltalk.addMethod(
  294. "_nonLocalReturnInliner",
  295. smalltalk.method({
  296. selector: "nonLocalReturnInliner",
  297. category: 'factory',
  298. fn: function () {
  299. var self = this;
  300. var $2, $3, $1;
  301. $2 = smalltalk.send(smalltalk.IRNonLocalReturnInliner || IRNonLocalReturnInliner, "_new", []);
  302. smalltalk.send($2, "_translator_", [self]);
  303. $3 = smalltalk.send($2, "_yourself", []);
  304. $1 = $3;
  305. return $1;
  306. },
  307. args: [],
  308. source: "nonLocalReturnInliner\x0a\x09^ IRNonLocalReturnInliner new \x0a\x09\x09translator: self;\x0a\x09\x09yourself",
  309. messageSends: ["translator:", "new", "yourself"],
  310. referencedClasses: ["IRNonLocalReturnInliner"]
  311. }),
  312. smalltalk.IRInliner);
  313. smalltalk.addMethod(
  314. "_returnInliner",
  315. smalltalk.method({
  316. selector: "returnInliner",
  317. category: 'factory',
  318. fn: function () {
  319. var self = this;
  320. var $2, $3, $1;
  321. $2 = smalltalk.send(smalltalk.IRReturnInliner || IRReturnInliner, "_new", []);
  322. smalltalk.send($2, "_translator_", [self]);
  323. $3 = smalltalk.send($2, "_yourself", []);
  324. $1 = $3;
  325. return $1;
  326. },
  327. args: [],
  328. source: "returnInliner\x0a\x09^ IRReturnInliner new \x0a\x09\x09translator: self;\x0a\x09\x09yourself",
  329. messageSends: ["translator:", "new", "yourself"],
  330. referencedClasses: ["IRReturnInliner"]
  331. }),
  332. smalltalk.IRInliner);
  333. smalltalk.addMethod(
  334. "_sendInliner",
  335. smalltalk.method({
  336. selector: "sendInliner",
  337. category: 'factory',
  338. fn: function () {
  339. var self = this;
  340. var $2, $3, $1;
  341. $2 = smalltalk.send(smalltalk.IRSendInliner || IRSendInliner, "_new", []);
  342. smalltalk.send($2, "_translator_", [self]);
  343. $3 = smalltalk.send($2, "_yourself", []);
  344. $1 = $3;
  345. return $1;
  346. },
  347. args: [],
  348. source: "sendInliner\x0a\x09^ IRSendInliner new \x0a\x09\x09translator: self;\x0a\x09\x09yourself",
  349. messageSends: ["translator:", "new", "yourself"],
  350. referencedClasses: ["IRSendInliner"]
  351. }),
  352. smalltalk.IRInliner);
  353. smalltalk.addMethod(
  354. "_shouldInlineAssignment_",
  355. smalltalk.method({
  356. selector: "shouldInlineAssignment:",
  357. category: 'testing',
  358. fn: function (anIRAssignment) {
  359. var self = this;
  360. var $1;
  361. $1 = 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", [])]);}]);}]);
  362. return $1;
  363. },
  364. args: ["anIRAssignment"],
  365. 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) ]]",
  366. messageSends: ["and:", "shouldInlineSend:", "last", "instructions", "isSend", "not", "isInlined"],
  367. referencedClasses: []
  368. }),
  369. smalltalk.IRInliner);
  370. smalltalk.addMethod(
  371. "_shouldInlineReturn_",
  372. smalltalk.method({
  373. selector: "shouldInlineReturn:",
  374. category: 'testing',
  375. fn: function (anIRReturn) {
  376. var self = this;
  377. var $1;
  378. $1 = smalltalk.send(smalltalk.send(smalltalk.send(anIRReturn, "_isInlined", []), "_not", []), "_and_", [function () {return smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(anIRReturn, "_instructions", []), "_first", []), "_isSend", []), "_and_", [function () {return smalltalk.send(self, "_shouldInlineSend_", [smalltalk.send(smalltalk.send(anIRReturn, "_instructions", []), "_first", [])]);}]);}]);
  379. return $1;
  380. },
  381. args: ["anIRReturn"],
  382. source: "shouldInlineReturn: anIRReturn\x0a\x09^ anIRReturn isInlined not and: [ \x0a\x09\x09anIRReturn instructions first isSend and: [\x09\x0a\x09\x09\x09self shouldInlineSend: (anIRReturn instructions first) ]]",
  383. messageSends: ["and:", "shouldInlineSend:", "first", "instructions", "isSend", "not", "isInlined"],
  384. referencedClasses: []
  385. }),
  386. smalltalk.IRInliner);
  387. smalltalk.addMethod(
  388. "_shouldInlineSend_",
  389. smalltalk.method({
  390. selector: "shouldInlineSend:",
  391. category: 'testing',
  392. fn: function (anIRSend) {
  393. var self = this;
  394. var $1;
  395. $1 = smalltalk.send(smalltalk.send(smalltalk.send(anIRSend, "_isInlined", []), "_not", []), "_and_", [function () {return smalltalk.send(smalltalk.IRSendInliner || IRSendInliner, "_shouldInline_", [anIRSend]);}]);
  396. return $1;
  397. },
  398. args: ["anIRSend"],
  399. source: "shouldInlineSend: anIRSend\x0a\x09^ anIRSend isInlined not and: [\x0a\x09\x09IRSendInliner shouldInline: anIRSend ]",
  400. messageSends: ["and:", "shouldInline:", "not", "isInlined"],
  401. referencedClasses: ["IRSendInliner"]
  402. }),
  403. smalltalk.IRInliner);
  404. smalltalk.addMethod(
  405. "_transformNonLocalReturn_",
  406. smalltalk.method({
  407. selector: "transformNonLocalReturn:",
  408. category: 'visiting',
  409. fn: function (anIRNonLocalReturn) {
  410. var self = this;
  411. var $1, $2, $3, $4;
  412. var localReturn;
  413. $1 = smalltalk.send(smalltalk.send(anIRNonLocalReturn, "_scope", []), "_canInlineNonLocalReturns", []);
  414. if (smalltalk.assert($1)) {
  415. smalltalk.send(smalltalk.send(smalltalk.send(anIRNonLocalReturn, "_scope", []), "_methodScope", []), "_removeNonLocalReturn_", [smalltalk.send(anIRNonLocalReturn, "_scope", [])]);
  416. $2 = smalltalk.send(smalltalk.IRReturn || IRReturn, "_new", []);
  417. smalltalk.send($2, "_scope_", [smalltalk.send(anIRNonLocalReturn, "_scope", [])]);
  418. $3 = smalltalk.send($2, "_yourself", []);
  419. localReturn = $3;
  420. smalltalk.send(smalltalk.send(anIRNonLocalReturn, "_instructions", []), "_do_", [function (each) {return smalltalk.send(localReturn, "_add_", [each]);}]);
  421. smalltalk.send(anIRNonLocalReturn, "_replaceWith_", [localReturn]);
  422. return localReturn;
  423. }
  424. $4 = smalltalk.send(self, "_visitIRNonLocalReturn_", [anIRNonLocalReturn], smalltalk.IRVisitor);
  425. return $4;
  426. },
  427. args: ["anIRNonLocalReturn"],
  428. source: "transformNonLocalReturn: anIRNonLocalReturn\x0a\x09\x22Replace a non local return into a local return\x22\x0a\x0a\x09| localReturn |\x0a\x09anIRNonLocalReturn scope canInlineNonLocalReturns ifTrue: [\x0a\x09\x09anIRNonLocalReturn scope methodScope removeNonLocalReturn: anIRNonLocalReturn scope.\x0a\x09\x09localReturn := IRReturn 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\x09\x09^ localReturn ].\x0a\x09^ super visitIRNonLocalReturn: anIRNonLocalReturn",
  429. messageSends: ["ifTrue:", "removeNonLocalReturn:", "scope", "methodScope", "scope:", "new", "yourself", "do:", "add:", "instructions", "replaceWith:", "canInlineNonLocalReturns", "visitIRNonLocalReturn:"],
  430. referencedClasses: ["IRReturn"]
  431. }),
  432. smalltalk.IRInliner);
  433. smalltalk.addMethod(
  434. "_visitIRAssignment_",
  435. smalltalk.method({
  436. selector: "visitIRAssignment:",
  437. category: 'visiting',
  438. fn: function (anIRAssignment) {
  439. var self = this;
  440. var $2, $1;
  441. $2 = smalltalk.send(self, "_shouldInlineAssignment_", [anIRAssignment]);
  442. if (smalltalk.assert($2)) {
  443. $1 = smalltalk.send(smalltalk.send(self, "_assignmentInliner", []), "_inlineAssignment_", [anIRAssignment]);
  444. } else {
  445. $1 = smalltalk.send(self, "_visitIRAssignment_", [anIRAssignment], smalltalk.IRVisitor);
  446. }
  447. return $1;
  448. },
  449. args: ["anIRAssignment"],
  450. source: "visitIRAssignment: anIRAssignment\x0a\x09^ (self shouldInlineAssignment: anIRAssignment) \x0a\x09\x09ifTrue: [ self assignmentInliner inlineAssignment: anIRAssignment ]\x0a\x09\x09ifFalse: [ super visitIRAssignment: anIRAssignment ]",
  451. messageSends: ["ifTrue:ifFalse:", "inlineAssignment:", "assignmentInliner", "visitIRAssignment:", "shouldInlineAssignment:"],
  452. referencedClasses: []
  453. }),
  454. smalltalk.IRInliner);
  455. smalltalk.addMethod(
  456. "_visitIRNonLocalReturn_",
  457. smalltalk.method({
  458. selector: "visitIRNonLocalReturn:",
  459. category: 'visiting',
  460. fn: function (anIRNonLocalReturn) {
  461. var self = this;
  462. var $2, $1;
  463. $2 = smalltalk.send(self, "_shouldInlineReturn_", [anIRNonLocalReturn]);
  464. if (smalltalk.assert($2)) {
  465. $1 = smalltalk.send(smalltalk.send(self, "_nonLocalReturnInliner", []), "_inlineReturn_", [anIRNonLocalReturn]);
  466. } else {
  467. $1 = smalltalk.send(self, "_transformNonLocalReturn_", [anIRNonLocalReturn]);
  468. }
  469. return $1;
  470. },
  471. args: ["anIRNonLocalReturn"],
  472. source: "visitIRNonLocalReturn: anIRNonLocalReturn\x0a\x09^ (self shouldInlineReturn: anIRNonLocalReturn) \x0a\x09\x09ifTrue: [ self nonLocalReturnInliner inlineReturn: anIRNonLocalReturn ]\x0a\x09\x09ifFalse: [ self transformNonLocalReturn: anIRNonLocalReturn ]",
  473. messageSends: ["ifTrue:ifFalse:", "inlineReturn:", "nonLocalReturnInliner", "transformNonLocalReturn:", "shouldInlineReturn:"],
  474. referencedClasses: []
  475. }),
  476. smalltalk.IRInliner);
  477. smalltalk.addMethod(
  478. "_visitIRReturn_",
  479. smalltalk.method({
  480. selector: "visitIRReturn:",
  481. category: 'visiting',
  482. fn: function (anIRReturn) {
  483. var self = this;
  484. var $2, $1;
  485. $2 = smalltalk.send(self, "_shouldInlineReturn_", [anIRReturn]);
  486. if (smalltalk.assert($2)) {
  487. $1 = smalltalk.send(smalltalk.send(self, "_returnInliner", []), "_inlineReturn_", [anIRReturn]);
  488. } else {
  489. $1 = smalltalk.send(self, "_visitIRReturn_", [anIRReturn], smalltalk.IRVisitor);
  490. }
  491. return $1;
  492. },
  493. args: ["anIRReturn"],
  494. source: "visitIRReturn: anIRReturn\x0a\x09^ (self shouldInlineReturn: anIRReturn) \x0a\x09\x09ifTrue: [ self returnInliner inlineReturn: anIRReturn ]\x0a\x09\x09ifFalse: [ super visitIRReturn: anIRReturn ]",
  495. messageSends: ["ifTrue:ifFalse:", "inlineReturn:", "returnInliner", "visitIRReturn:", "shouldInlineReturn:"],
  496. referencedClasses: []
  497. }),
  498. smalltalk.IRInliner);
  499. smalltalk.addMethod(
  500. "_visitIRSend_",
  501. smalltalk.method({
  502. selector: "visitIRSend:",
  503. category: 'visiting',
  504. fn: function (anIRSend) {
  505. var self = this;
  506. var $2, $1;
  507. $2 = smalltalk.send(self, "_shouldInlineSend_", [anIRSend]);
  508. if (smalltalk.assert($2)) {
  509. $1 = smalltalk.send(smalltalk.send(self, "_sendInliner", []), "_inlineSend_", [anIRSend]);
  510. } else {
  511. $1 = smalltalk.send(self, "_visitIRSend_", [anIRSend], smalltalk.IRVisitor);
  512. }
  513. return $1;
  514. },
  515. args: ["anIRSend"],
  516. source: "visitIRSend: anIRSend\x0a\x09^ (self shouldInlineSend: anIRSend)\x0a\x09\x09ifTrue: [ self sendInliner inlineSend: anIRSend ]\x0a\x09\x09ifFalse: [ super visitIRSend: anIRSend ]",
  517. messageSends: ["ifTrue:ifFalse:", "inlineSend:", "sendInliner", "visitIRSend:", "shouldInlineSend:"],
  518. referencedClasses: []
  519. }),
  520. smalltalk.IRInliner);
  521. smalltalk.addClass('IRInliningJSTranslator', smalltalk.IRJSTranslator, [], 'Compiler-Inlining');
  522. smalltalk.IRInliningJSTranslator.comment="I am a specialized JavaScript translator able to write inlined IR instructions to JavaScript stream (`JSStream` instance)."
  523. smalltalk.addMethod(
  524. "_visitIRInlinedAssignment_",
  525. smalltalk.method({
  526. selector: "visitIRInlinedAssignment:",
  527. category: 'visiting',
  528. fn: function (anIRInlinedAssignment) {
  529. var self = this;
  530. smalltalk.send(self, "_visit_", [smalltalk.send(smalltalk.send(anIRInlinedAssignment, "_instructions", []), "_last", [])]);
  531. return self;
  532. },
  533. args: ["anIRInlinedAssignment"],
  534. source: "visitIRInlinedAssignment: anIRInlinedAssignment\x0a\x09self visit: anIRInlinedAssignment instructions last",
  535. messageSends: ["visit:", "last", "instructions"],
  536. referencedClasses: []
  537. }),
  538. smalltalk.IRInliningJSTranslator);
  539. smalltalk.addMethod(
  540. "_visitIRInlinedClosure_",
  541. smalltalk.method({
  542. selector: "visitIRInlinedClosure:",
  543. category: 'visiting',
  544. fn: function (anIRInlinedClosure) {
  545. var self = this;
  546. smalltalk.send(smalltalk.send(anIRInlinedClosure, "_instructions", []), "_do_", [function (each) {return smalltalk.send(self, "_visit_", [each]);}]);
  547. return self;
  548. },
  549. args: ["anIRInlinedClosure"],
  550. source: "visitIRInlinedClosure: anIRInlinedClosure\x0a\x09anIRInlinedClosure instructions do: [ :each |\x0a\x09\x09self visit: each ]",
  551. messageSends: ["do:", "visit:", "instructions"],
  552. referencedClasses: []
  553. }),
  554. smalltalk.IRInliningJSTranslator);
  555. smalltalk.addMethod(
  556. "_visitIRInlinedIfFalse_",
  557. smalltalk.method({
  558. selector: "visitIRInlinedIfFalse:",
  559. category: 'visiting',
  560. fn: function (anIRInlinedIfFalse) {
  561. var self = this;
  562. 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", [])]);}]);
  563. return self;
  564. },
  565. args: ["anIRInlinedIfFalse"],
  566. source: "visitIRInlinedIfFalse: anIRInlinedIfFalse\x0a\x09self stream nextPutIf: [ \x0a\x09\x09self stream nextPutAll: '! smalltalk.assert('.\x0a\x09\x09self visit: anIRInlinedIfFalse instructions first.\x0a\x09\x09self stream nextPutAll: ')' ]\x0a\x09\x09with: [ self visit: anIRInlinedIfFalse instructions last ]",
  567. messageSends: ["nextPutIf:with:", "nextPutAll:", "stream", "visit:", "first", "instructions", "last"],
  568. referencedClasses: []
  569. }),
  570. smalltalk.IRInliningJSTranslator);
  571. smalltalk.addMethod(
  572. "_visitIRInlinedIfNil_",
  573. smalltalk.method({
  574. selector: "visitIRInlinedIfNil:",
  575. category: 'visiting',
  576. fn: function (anIRInlinedIfNil) {
  577. var self = this;
  578. smalltalk.send(smalltalk.send(self, "_stream", []), "_nextPutIf_with_", [function () {smalltalk.send(smalltalk.send(self, "_stream", []), "_nextPutAll_", ["($receiver = "]);smalltalk.send(self, "_visit_", [smalltalk.send(smalltalk.send(anIRInlinedIfNil, "_instructions", []), "_first", [])]);return smalltalk.send(smalltalk.send(self, "_stream", []), "_nextPutAll_", [") == nil || $receiver == undefined"]);}, function () {return smalltalk.send(self, "_visit_", [smalltalk.send(smalltalk.send(anIRInlinedIfNil, "_instructions", []), "_last", [])]);}]);
  579. return self;
  580. },
  581. args: ["anIRInlinedIfNil"],
  582. source: "visitIRInlinedIfNil: anIRInlinedIfNil\x0a\x09self stream nextPutIf: [ \x0a\x09\x09self stream nextPutAll: '($receiver = '. \x0a\x09\x09self visit: anIRInlinedIfNil instructions first.\x0a\x09\x09self stream nextPutAll: ') == nil || $receiver == undefined' ]\x0a\x09\x09with: [ self visit: anIRInlinedIfNil instructions last ]",
  583. messageSends: ["nextPutIf:with:", "nextPutAll:", "stream", "visit:", "first", "instructions", "last"],
  584. referencedClasses: []
  585. }),
  586. smalltalk.IRInliningJSTranslator);
  587. smalltalk.addMethod(
  588. "_visitIRInlinedIfNilIfNotNil_",
  589. smalltalk.method({
  590. selector: "visitIRInlinedIfNilIfNotNil:",
  591. category: 'visiting',
  592. fn: function (anIRInlinedIfNilIfNotNil) {
  593. var self = this;
  594. smalltalk.send(smalltalk.send(self, "_stream", []), "_nextPutIfElse_with_with_", [function () {smalltalk.send(smalltalk.send(self, "_stream", []), "_nextPutAll_", ["($receiver = "]);smalltalk.send(self, "_visit_", [smalltalk.send(smalltalk.send(anIRInlinedIfNilIfNotNil, "_instructions", []), "_first", [])]);return smalltalk.send(smalltalk.send(self, "_stream", []), "_nextPutAll_", [") == nil || $receiver == undefined"]);}, function () {return smalltalk.send(self, "_visit_", [smalltalk.send(smalltalk.send(anIRInlinedIfNilIfNotNil, "_instructions", []), "_second", [])]);}, function () {return smalltalk.send(self, "_visit_", [smalltalk.send(smalltalk.send(anIRInlinedIfNilIfNotNil, "_instructions", []), "_third", [])]);}]);
  595. return self;
  596. },
  597. args: ["anIRInlinedIfNilIfNotNil"],
  598. source: "visitIRInlinedIfNilIfNotNil: anIRInlinedIfNilIfNotNil\x0a\x09self stream \x0a\x09\x09nextPutIfElse: [ \x0a\x09\x09\x09self stream nextPutAll: '($receiver = '. \x0a\x09\x09\x09self visit: anIRInlinedIfNilIfNotNil instructions first.\x0a\x09\x09\x09self stream nextPutAll: ') == nil || $receiver == undefined' ]\x0a\x09\x09with: [ self visit: anIRInlinedIfNilIfNotNil instructions second ]\x0a\x09\x09with: [ self visit: anIRInlinedIfNilIfNotNil instructions third ]",
  599. messageSends: ["nextPutIfElse:with:with:", "nextPutAll:", "stream", "visit:", "first", "instructions", "second", "third"],
  600. referencedClasses: []
  601. }),
  602. smalltalk.IRInliningJSTranslator);
  603. smalltalk.addMethod(
  604. "_visitIRInlinedIfTrue_",
  605. smalltalk.method({
  606. selector: "visitIRInlinedIfTrue:",
  607. category: 'visiting',
  608. fn: function (anIRInlinedIfTrue) {
  609. var self = this;
  610. 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", [])]);}]);
  611. return self;
  612. },
  613. args: ["anIRInlinedIfTrue"],
  614. source: "visitIRInlinedIfTrue: anIRInlinedIfTrue\x0a\x09self stream nextPutIf: [ \x0a\x09\x09self stream nextPutAll: 'smalltalk.assert('. \x0a\x09\x09self visit: anIRInlinedIfTrue instructions first.\x0a\x09\x09self stream nextPutAll: ')' ]\x0a\x09\x09with: [ self visit: anIRInlinedIfTrue instructions last ]",
  615. messageSends: ["nextPutIf:with:", "nextPutAll:", "stream", "visit:", "first", "instructions", "last"],
  616. referencedClasses: []
  617. }),
  618. smalltalk.IRInliningJSTranslator);
  619. smalltalk.addMethod(
  620. "_visitIRInlinedIfTrueIfFalse_",
  621. smalltalk.method({
  622. selector: "visitIRInlinedIfTrueIfFalse:",
  623. category: 'visiting',
  624. fn: function (anIRInlinedIfTrueIfFalse) {
  625. var self = this;
  626. smalltalk.send(smalltalk.send(self, "_stream", []), "_nextPutIfElse_with_with_", [function () {smalltalk.send(smalltalk.send(self, "_stream", []), "_nextPutAll_", ["smalltalk.assert("]);smalltalk.send(self, "_visit_", [smalltalk.send(smalltalk.send(anIRInlinedIfTrueIfFalse, "_instructions", []), "_first", [])]);return smalltalk.send(smalltalk.send(self, "_stream", []), "_nextPutAll_", [")"]);}, function () {return smalltalk.send(self, "_visit_", [smalltalk.send(smalltalk.send(anIRInlinedIfTrueIfFalse, "_instructions", []), "_second", [])]);}, function () {return smalltalk.send(self, "_visit_", [smalltalk.send(smalltalk.send(anIRInlinedIfTrueIfFalse, "_instructions", []), "_third", [])]);}]);
  627. return self;
  628. },
  629. args: ["anIRInlinedIfTrueIfFalse"],
  630. source: "visitIRInlinedIfTrueIfFalse: anIRInlinedIfTrueIfFalse\x0a\x09self stream \x0a\x09\x09nextPutIfElse: [ \x0a\x09\x09\x09self stream nextPutAll: 'smalltalk.assert('. \x0a\x09\x09\x09self visit: anIRInlinedIfTrueIfFalse instructions first.\x0a\x09\x09\x09self stream nextPutAll: ')' ]\x0a\x09\x09with: [ self visit: anIRInlinedIfTrueIfFalse instructions second ]\x0a\x09\x09with: [ self visit: anIRInlinedIfTrueIfFalse instructions third ]",
  631. messageSends: ["nextPutIfElse:with:with:", "nextPutAll:", "stream", "visit:", "first", "instructions", "second", "third"],
  632. referencedClasses: []
  633. }),
  634. smalltalk.IRInliningJSTranslator);
  635. smalltalk.addMethod(
  636. "_visitIRInlinedNonLocalReturn_",
  637. smalltalk.method({
  638. selector: "visitIRInlinedNonLocalReturn:",
  639. category: 'visiting',
  640. fn: function (anIRInlinedReturn) {
  641. var self = this;
  642. smalltalk.send(smalltalk.send(self, "_stream", []), "_nextPutStatementWith_", [function () {return smalltalk.send(self, "_visit_", [smalltalk.send(smalltalk.send(anIRInlinedReturn, "_instructions", []), "_last", [])]);}]);
  643. smalltalk.send(smalltalk.send(self, "_stream", []), "_nextPutNonLocalReturnWith_", [function () {}]);
  644. return self;
  645. },
  646. args: ["anIRInlinedReturn"],
  647. source: "visitIRInlinedNonLocalReturn: anIRInlinedReturn\x0a\x09self stream nextPutStatementWith: [\x0a\x09\x09self visit: anIRInlinedReturn instructions last ].\x0a\x09self stream nextPutNonLocalReturnWith: [ ]",
  648. messageSends: ["nextPutStatementWith:", "visit:", "last", "instructions", "stream", "nextPutNonLocalReturnWith:"],
  649. referencedClasses: []
  650. }),
  651. smalltalk.IRInliningJSTranslator);
  652. smalltalk.addMethod(
  653. "_visitIRInlinedReturn_",
  654. smalltalk.method({
  655. selector: "visitIRInlinedReturn:",
  656. category: 'visiting',
  657. fn: function (anIRInlinedReturn) {
  658. var self = this;
  659. smalltalk.send(self, "_visit_", [smalltalk.send(smalltalk.send(anIRInlinedReturn, "_instructions", []), "_last", [])]);
  660. return self;
  661. },
  662. args: ["anIRInlinedReturn"],
  663. source: "visitIRInlinedReturn: anIRInlinedReturn\x0a\x09self visit: anIRInlinedReturn instructions last",
  664. messageSends: ["visit:", "last", "instructions"],
  665. referencedClasses: []
  666. }),
  667. smalltalk.IRInliningJSTranslator);
  668. smalltalk.addMethod(
  669. "_visitIRInlinedSequence_",
  670. smalltalk.method({
  671. selector: "visitIRInlinedSequence:",
  672. category: 'visiting',
  673. fn: function (anIRInlinedSequence) {
  674. var self = this;
  675. smalltalk.send(smalltalk.send(anIRInlinedSequence, "_instructions", []), "_do_", [function (each) {return smalltalk.send(smalltalk.send(self, "_stream", []), "_nextPutStatementWith_", [function () {return smalltalk.send(self, "_visit_", [each]);}]);}]);
  676. return self;
  677. },
  678. args: ["anIRInlinedSequence"],
  679. source: "visitIRInlinedSequence: anIRInlinedSequence\x0a\x09anIRInlinedSequence instructions do: [ :each | \x0a\x09\x09self stream nextPutStatementWith: [ self visit: each ]]",
  680. messageSends: ["do:", "nextPutStatementWith:", "visit:", "stream", "instructions"],
  681. referencedClasses: []
  682. }),
  683. smalltalk.IRInliningJSTranslator);
  684. smalltalk.addClass('IRSendInliner', smalltalk.Object, ['send', 'translator'], 'Compiler-Inlining');
  685. smalltalk.IRSendInliner.comment="I inline some message sends and block closure arguments. I heavily rely on #perform: to dispatch inlining methods."
  686. smalltalk.addMethod(
  687. "_ifFalse_",
  688. smalltalk.method({
  689. selector: "ifFalse:",
  690. category: 'inlining',
  691. fn: function (anIRInstruction) {
  692. var self = this;
  693. var $1;
  694. $1 = smalltalk.send(self, "_inlinedSend_with_", [smalltalk.send(smalltalk.IRInlinedIfFalse || IRInlinedIfFalse, "_new", []), anIRInstruction]);
  695. return $1;
  696. },
  697. args: ["anIRInstruction"],
  698. source: "ifFalse: anIRInstruction\x0a\x09^ self inlinedSend: IRInlinedIfFalse new with: anIRInstruction",
  699. messageSends: ["inlinedSend:with:", "new"],
  700. referencedClasses: ["IRInlinedIfFalse"]
  701. }),
  702. smalltalk.IRSendInliner);
  703. smalltalk.addMethod(
  704. "_ifFalse_ifTrue_",
  705. smalltalk.method({
  706. selector: "ifFalse:ifTrue:",
  707. category: 'inlining',
  708. fn: function (anIRInstruction, anotherIRInstruction) {
  709. var self = this;
  710. var $1;
  711. $1 = smalltalk.send(self, "_perform_withArguments_", [smalltalk.symbolFor("ifTrue:ifFalse:"), [anotherIRInstruction, anIRInstruction]]);
  712. return $1;
  713. },
  714. args: ["anIRInstruction", "anotherIRInstruction"],
  715. source: "ifFalse: anIRInstruction ifTrue: anotherIRInstruction\x0a\x09^ self perform: #ifTrue:ifFalse: withArguments: { anotherIRInstruction. anIRInstruction }",
  716. messageSends: ["perform:withArguments:"],
  717. referencedClasses: []
  718. }),
  719. smalltalk.IRSendInliner);
  720. smalltalk.addMethod(
  721. "_ifNil_",
  722. smalltalk.method({
  723. selector: "ifNil:",
  724. category: 'inlining',
  725. fn: function (anIRInstruction) {
  726. var self = this;
  727. var $2, $3, $4, $5, $1;
  728. $2 = smalltalk.send(smalltalk.IRClosure || IRClosure, "_new", []);
  729. smalltalk.send($2, "_scope_", [smalltalk.send(smalltalk.send(anIRInstruction, "_scope", []), "_copy", [])]);
  730. $3 = smalltalk.send(smalltalk.IRBlockSequence || IRBlockSequence, "_new", []);
  731. smalltalk.send($3, "_add_", [smalltalk.send(smalltalk.send(smalltalk.send(self, "_send", []), "_instructions", []), "_first", [])]);
  732. $4 = smalltalk.send($3, "_yourself", []);
  733. smalltalk.send($2, "_add_", [$4]);
  734. $5 = smalltalk.send($2, "_yourself", []);
  735. $1 = smalltalk.send(self, "_inlinedSend_with_with_", [smalltalk.send(smalltalk.IRInlinedIfNilIfNotNil || IRInlinedIfNilIfNotNil, "_new", []), anIRInstruction, $5]);
  736. return $1;
  737. },
  738. args: ["anIRInstruction"],
  739. source: "ifNil: anIRInstruction\x0a\x09^ self \x0a\x09\x09inlinedSend: IRInlinedIfNilIfNotNil new \x0a\x09\x09with: anIRInstruction\x0a\x09\x09with: (IRClosure new\x0a\x09\x09\x09scope: anIRInstruction scope copy;\x0a\x09\x09\x09add: (IRBlockSequence new\x0a\x09\x09\x09\x09add: self send instructions first;\x0a\x09\x09\x09\x09yourself);\x0a\x09\x09\x09yourself)",
  740. messageSends: ["inlinedSend:with:with:", "new", "scope:", "copy", "scope", "add:", "first", "instructions", "send", "yourself"],
  741. referencedClasses: ["IRInlinedIfNilIfNotNil", "IRClosure", "IRBlockSequence"]
  742. }),
  743. smalltalk.IRSendInliner);
  744. smalltalk.addMethod(
  745. "_ifNil_ifNotNil_",
  746. smalltalk.method({
  747. selector: "ifNil:ifNotNil:",
  748. category: 'inlining',
  749. fn: function (anIRInstruction, anotherIRInstruction) {
  750. var self = this;
  751. var $1;
  752. $1 = smalltalk.send(self, "_inlinedSend_with_with_", [smalltalk.send(smalltalk.IRInlinedIfNilIfNotNil || IRInlinedIfNilIfNotNil, "_new", []), anIRInstruction, anotherIRInstruction]);
  753. return $1;
  754. },
  755. args: ["anIRInstruction", "anotherIRInstruction"],
  756. source: "ifNil: anIRInstruction ifNotNil: anotherIRInstruction\x0a\x09^ self inlinedSend: IRInlinedIfNilIfNotNil new with: anIRInstruction with: anotherIRInstruction",
  757. messageSends: ["inlinedSend:with:with:", "new"],
  758. referencedClasses: ["IRInlinedIfNilIfNotNil"]
  759. }),
  760. smalltalk.IRSendInliner);
  761. smalltalk.addMethod(
  762. "_ifNotNil_",
  763. smalltalk.method({
  764. selector: "ifNotNil:",
  765. category: 'inlining',
  766. fn: function (anIRInstruction) {
  767. var self = this;
  768. var $2, $3, $4, $5, $1;
  769. $2 = smalltalk.send(smalltalk.IRClosure || IRClosure, "_new", []);
  770. smalltalk.send($2, "_scope_", [smalltalk.send(smalltalk.send(anIRInstruction, "_scope", []), "_copy", [])]);
  771. $3 = smalltalk.send(smalltalk.IRBlockSequence || IRBlockSequence, "_new", []);
  772. smalltalk.send($3, "_add_", [smalltalk.send(smalltalk.send(smalltalk.send(self, "_send", []), "_instructions", []), "_first", [])]);
  773. $4 = smalltalk.send($3, "_yourself", []);
  774. smalltalk.send($2, "_add_", [$4]);
  775. $5 = smalltalk.send($2, "_yourself", []);
  776. $1 = smalltalk.send(self, "_inlinedSend_with_with_", [smalltalk.send(smalltalk.IRInlinedIfNilIfNotNil || IRInlinedIfNilIfNotNil, "_new", []), $5, anIRInstruction]);
  777. return $1;
  778. },
  779. args: ["anIRInstruction"],
  780. source: "ifNotNil: anIRInstruction\x0a\x09^ self \x0a\x09\x09inlinedSend: IRInlinedIfNilIfNotNil new\x0a\x09\x09with: (IRClosure new\x0a\x09\x09\x09scope: anIRInstruction scope copy;\x0a\x09\x09\x09add: (IRBlockSequence new\x0a\x09\x09\x09\x09add: self send instructions first;\x0a\x09\x09\x09\x09yourself);\x0a\x09\x09\x09yourself)\x0a\x09\x09with: anIRInstruction",
  781. messageSends: ["inlinedSend:with:with:", "new", "scope:", "copy", "scope", "add:", "first", "instructions", "send", "yourself"],
  782. referencedClasses: ["IRInlinedIfNilIfNotNil", "IRClosure", "IRBlockSequence"]
  783. }),
  784. smalltalk.IRSendInliner);
  785. smalltalk.addMethod(
  786. "_ifNotNil_ifNil_",
  787. smalltalk.method({
  788. selector: "ifNotNil:ifNil:",
  789. category: 'inlining',
  790. fn: function (anIRInstruction, anotherIRInstruction) {
  791. var self = this;
  792. var $1;
  793. $1 = smalltalk.send(self, "_inlinedSend_with_with_", [smalltalk.send(smalltalk.IRInlinedIfNilIfNotNil || IRInlinedIfNilIfNotNil, "_new", []), anotherIRInstruction, anIRInstruction]);
  794. return $1;
  795. },
  796. args: ["anIRInstruction", "anotherIRInstruction"],
  797. source: "ifNotNil: anIRInstruction ifNil: anotherIRInstruction\x0a\x09^ self inlinedSend: IRInlinedIfNilIfNotNil new with: anotherIRInstruction with: anIRInstruction",
  798. messageSends: ["inlinedSend:with:with:", "new"],
  799. referencedClasses: ["IRInlinedIfNilIfNotNil"]
  800. }),
  801. smalltalk.IRSendInliner);
  802. smalltalk.addMethod(
  803. "_ifTrue_",
  804. smalltalk.method({
  805. selector: "ifTrue:",
  806. category: 'inlining',
  807. fn: function (anIRInstruction) {
  808. var self = this;
  809. var $1;
  810. $1 = smalltalk.send(self, "_inlinedSend_with_", [smalltalk.send(smalltalk.IRInlinedIfTrue || IRInlinedIfTrue, "_new", []), anIRInstruction]);
  811. return $1;
  812. },
  813. args: ["anIRInstruction"],
  814. source: "ifTrue: anIRInstruction\x0a\x09^ self inlinedSend: IRInlinedIfTrue new with: anIRInstruction",
  815. messageSends: ["inlinedSend:with:", "new"],
  816. referencedClasses: ["IRInlinedIfTrue"]
  817. }),
  818. smalltalk.IRSendInliner);
  819. smalltalk.addMethod(
  820. "_ifTrue_ifFalse_",
  821. smalltalk.method({
  822. selector: "ifTrue:ifFalse:",
  823. category: 'inlining',
  824. fn: function (anIRInstruction, anotherIRInstruction) {
  825. var self = this;
  826. var $1;
  827. $1 = smalltalk.send(self, "_inlinedSend_with_with_", [smalltalk.send(smalltalk.IRInlinedIfTrueIfFalse || IRInlinedIfTrueIfFalse, "_new", []), anIRInstruction, anotherIRInstruction]);
  828. return $1;
  829. },
  830. args: ["anIRInstruction", "anotherIRInstruction"],
  831. source: "ifTrue: anIRInstruction ifFalse: anotherIRInstruction\x0a\x09^ self inlinedSend: IRInlinedIfTrueIfFalse new with: anIRInstruction with: anotherIRInstruction",
  832. messageSends: ["inlinedSend:with:with:", "new"],
  833. referencedClasses: ["IRInlinedIfTrueIfFalse"]
  834. }),
  835. smalltalk.IRSendInliner);
  836. smalltalk.addMethod(
  837. "_inlineClosure_",
  838. smalltalk.method({
  839. selector: "inlineClosure:",
  840. category: 'inlining',
  841. fn: function (anIRClosure){
  842. var self=this;
  843. var inlinedClosure=nil;
  844. var sequence=nil;
  845. var statements=nil;
  846. (inlinedClosure=smalltalk.send(self, "_inlinedClosure", []));
  847. smalltalk.send(inlinedClosure, "_scope_", [smalltalk.send(anIRClosure, "_scope", [])]);
  848. smalltalk.send(smalltalk.send(anIRClosure, "_instructions", []), "_do_", [(function(each){return ((($receiver = smalltalk.send(each, "_isSequence", [])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return smalltalk.send(inlinedClosure, "_add_", [each]);})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return smalltalk.send(inlinedClosure, "_add_", [each]);})]));})]);
  849. (sequence=smalltalk.send(self, "_inlinedSequence", []));
  850. smalltalk.send(inlinedClosure, "_add_", [sequence]);
  851. (statements=smalltalk.send(smalltalk.send(smalltalk.send(anIRClosure, "_instructions", []), "_last", []), "_instructions", []));
  852. smalltalk.send(statements, "_ifNotEmpty_", [(function(){smalltalk.send(smalltalk.send(statements, "_allButLast", []), "_do_", [(function(each){return smalltalk.send(sequence, "_add_", [each]);})]);return ((($receiver = smalltalk.send(smalltalk.send(smalltalk.send(statements, "_last", []), "_isReturn", []), "_and_", [(function(){return smalltalk.send(smalltalk.send(statements, "_last", []), "_isBlockReturn", []);})])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(sequence, "_add_", [smalltalk.send(smalltalk.send(smalltalk.send(statements, "_last", []), "_instructions", []), "_first", [])]);})() : (function(){return smalltalk.send(sequence, "_add_", [smalltalk.send(statements, "_last", [])]);})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(sequence, "_add_", [smalltalk.send(smalltalk.send(smalltalk.send(statements, "_last", []), "_instructions", []), "_first", [])]);}), (function(){return smalltalk.send(sequence, "_add_", [smalltalk.send(statements, "_last", [])]);})]));})]);
  853. return inlinedClosure;
  854. return self;},
  855. args: ["anIRClosure"],
  856. source: "inlineClosure: anIRClosure\x0a\x09| inlinedClosure sequence statements |\x0a\x0a\x09inlinedClosure := self inlinedClosure.\x0a\x09inlinedClosure scope: anIRClosure scope.\x0a\x0a\x09\x22Add the possible temp declarations\x22\x0a\x09anIRClosure instructions do: [ :each | \x0a\x09\x09each isSequence ifFalse: [\x0a\x09\x09\x09inlinedClosure add: each ]].\x0a\x0a\x09\x22Add a block sequence\x22\x0a\x09sequence := self inlinedSequence.\x0a\x09inlinedClosure add: sequence.\x0a\x0a\x09\x22Get all the statements\x22\x0a\x09statements := anIRClosure instructions last instructions.\x0a\x09\x0a\x09statements ifNotEmpty: [\x0a\x09\x09statements allButLast do: [ :each | sequence add: each ].\x0a\x0a\x09\x09\x22Inlined closures don't have implicit local returns\x22\x0a\x09\x09(statements last isReturn and: [ statements last isBlockReturn ])\x0a\x09\x09\x09ifTrue: [ sequence add: statements last instructions first ]\x0a\x09\x09\x09ifFalse: [ sequence add: statements last ] ].\x0a\x0a\x09^ inlinedClosure",
  857. messageSends: ["inlinedClosure", "scope:", "scope", "do:", "instructions", "ifFalse:", "isSequence", "add:", "inlinedSequence", "last", "ifNotEmpty:", "allButLast", "ifTrue:ifFalse:", "and:", "isReturn", "isBlockReturn", "first"],
  858. referencedClasses: []
  859. }),
  860. smalltalk.IRSendInliner);
  861. smalltalk.addMethod(
  862. "_inlineSend_",
  863. smalltalk.method({
  864. selector: "inlineSend:",
  865. category: 'inlining',
  866. fn: function (anIRSend) {
  867. var self = this;
  868. smalltalk.send(self, "_send_", [anIRSend]);
  869. return smalltalk.send(self, "_perform_withArguments_", [smalltalk.send(smalltalk.send(self, "_send", []), "_selector", []), smalltalk.send(smalltalk.send(smalltalk.send(self, "_send", []), "_instructions", []), "_allButFirst", [])]);
  870. return self;
  871. },
  872. args: ["anIRSend"],
  873. source: "inlineSend: anIRSend\x0a\x09self send: anIRSend.\x0a\x09^ self \x0a\x09\x09perform: self send selector \x0a\x09\x09withArguments: self send instructions allButFirst",
  874. messageSends: ["send:", "perform:withArguments:", "selector", "send", "allButFirst", "instructions"],
  875. referencedClasses: []
  876. }),
  877. smalltalk.IRSendInliner);
  878. smalltalk.addMethod(
  879. "_inlinedClosure",
  880. smalltalk.method({
  881. selector: "inlinedClosure",
  882. category: 'factory',
  883. fn: function () {
  884. var self = this;
  885. var $1;
  886. $1 = smalltalk.send(smalltalk.IRInlinedClosure || IRInlinedClosure, "_new", []);
  887. return $1;
  888. },
  889. args: [],
  890. source: "inlinedClosure\x0a\x09^ IRInlinedClosure new",
  891. messageSends: ["new"],
  892. referencedClasses: ["IRInlinedClosure"]
  893. }),
  894. smalltalk.IRSendInliner);
  895. smalltalk.addMethod(
  896. "_inlinedSend_with_",
  897. smalltalk.method({
  898. selector: "inlinedSend:with:",
  899. category: 'inlining',
  900. fn: function (inlinedSend, anIRInstruction) {
  901. var self = this;
  902. var inlinedClosure = nil;
  903. ($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"]);}]);
  904. ($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"]);}]);
  905. inlinedClosure = smalltalk.send(smalltalk.send(self, "_translator", []), "_visit_", [smalltalk.send(self, "_inlineClosure_", [anIRInstruction])]);
  906. (function ($rec) {smalltalk.send($rec, "_add_", [smalltalk.send(smalltalk.send(smalltalk.send(self, "_send", []), "_instructions", []), "_first", [])]);return smalltalk.send($rec, "_add_", [inlinedClosure]);}(inlinedSend));
  907. smalltalk.send(smalltalk.send(self, "_send", []), "_replaceWith_", [inlinedSend]);
  908. return inlinedSend;
  909. return self;
  910. },
  911. args: ["inlinedSend", "anIRInstruction"],
  912. source: "inlinedSend: inlinedSend with: anIRInstruction\x0a\x09| 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 translator visit: (self inlineClosure: anIRInstruction).\x0a\x0a\x09inlinedSend\x0a\x09\x09add: self send instructions first;\x0a\x09\x09add: inlinedClosure.\x0a\x0a\x09self send replaceWith: inlinedSend.\x0a\x0a\x09^ inlinedSend",
  913. messageSends: ["ifFalse:", "isClosure", "inliningError:", "=", "size", "arguments", "visit:", "translator", "inlineClosure:", "add:", "first", "instructions", "send", "replaceWith:"],
  914. referencedClasses: []
  915. }),
  916. smalltalk.IRSendInliner);
  917. smalltalk.addMethod(
  918. "_inlinedSend_with_with_",
  919. smalltalk.method({
  920. selector: "inlinedSend:with:with:",
  921. category: 'inlining',
  922. fn: function (inlinedSend, anIRInstruction, anotherIRInstruction) {
  923. var self = this;
  924. var inlinedClosure1 = nil;
  925. var inlinedClosure2 = nil;
  926. ($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"]);}]);
  927. ($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"]);}]);
  928. ($receiver = smalltalk.send(anotherIRInstruction, "_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"]);}]);
  929. ($receiver = smalltalk.send(smalltalk.send(smalltalk.send(anotherIRInstruction, "_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"]);}]);
  930. inlinedClosure1 = smalltalk.send(smalltalk.send(self, "_translator", []), "_visit_", [smalltalk.send(self, "_inlineClosure_", [anIRInstruction])]);
  931. inlinedClosure2 = smalltalk.send(smalltalk.send(self, "_translator", []), "_visit_", [smalltalk.send(self, "_inlineClosure_", [anotherIRInstruction])]);
  932. (function ($rec) {smalltalk.send($rec, "_add_", [smalltalk.send(smalltalk.send(smalltalk.send(self, "_send", []), "_instructions", []), "_first", [])]);smalltalk.send($rec, "_add_", [inlinedClosure1]);return smalltalk.send($rec, "_add_", [inlinedClosure2]);}(inlinedSend));
  933. smalltalk.send(smalltalk.send(self, "_send", []), "_replaceWith_", [inlinedSend]);
  934. return inlinedSend;
  935. return self;
  936. },
  937. args: ["inlinedSend", "anIRInstruction", "anotherIRInstruction"],
  938. source: "inlinedSend: inlinedSend with: anIRInstruction with: anotherIRInstruction\x0a\x09| inlinedClosure1 inlinedClosure2 |\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\x09anotherIRInstruction isClosure ifFalse: [ self inliningError: 'Message argument should be a block' ].\x0a\x09anotherIRInstruction arguments size = 0 ifFalse: [ self inliningError: 'Inlined block should have zero argument' ].\x0a\x0a\x09inlinedClosure1 := self translator visit: (self inlineClosure: anIRInstruction).\x0a\x09inlinedClosure2 := self translator visit: (self inlineClosure: anotherIRInstruction).\x0a\x0a\x0a\x09inlinedSend\x0a\x09\x09add: self send instructions first;\x0a\x09\x09add: inlinedClosure1;\x0a\x09\x09add: inlinedClosure2.\x0a\x0a\x09self send replaceWith: inlinedSend.\x0a\x09^ inlinedSend",
  939. messageSends: ["ifFalse:", "isClosure", "inliningError:", "=", "size", "arguments", "visit:", "translator", "inlineClosure:", "add:", "first", "instructions", "send", "replaceWith:"],
  940. referencedClasses: []
  941. }),
  942. smalltalk.IRSendInliner);
  943. smalltalk.addMethod(
  944. "_inlinedSequence",
  945. smalltalk.method({
  946. selector: "inlinedSequence",
  947. category: 'factory',
  948. fn: function () {
  949. var self = this;
  950. var $1;
  951. $1 = smalltalk.send(smalltalk.IRInlinedSequence || IRInlinedSequence, "_new", []);
  952. return $1;
  953. },
  954. args: [],
  955. source: "inlinedSequence\x0a\x09^ IRInlinedSequence new",
  956. messageSends: ["new"],
  957. referencedClasses: ["IRInlinedSequence"]
  958. }),
  959. smalltalk.IRSendInliner);
  960. smalltalk.addMethod(
  961. "_inliningError_",
  962. smalltalk.method({
  963. selector: "inliningError:",
  964. category: 'error handling',
  965. fn: function (aString) {
  966. var self = this;
  967. smalltalk.send(smalltalk.InliningError || InliningError, "_signal_", [aString]);
  968. return self;
  969. },
  970. args: ["aString"],
  971. source: "inliningError: aString\x0a\x09InliningError signal: aString",
  972. messageSends: ["signal:"],
  973. referencedClasses: ["InliningError"]
  974. }),
  975. smalltalk.IRSendInliner);
  976. smalltalk.addMethod(
  977. "_send",
  978. smalltalk.method({
  979. selector: "send",
  980. category: 'accessing',
  981. fn: function () {
  982. var self = this;
  983. return self['@send'];
  984. },
  985. args: [],
  986. source: "send\x0a\x09^ send",
  987. messageSends: [],
  988. referencedClasses: []
  989. }),
  990. smalltalk.IRSendInliner);
  991. smalltalk.addMethod(
  992. "_send_",
  993. smalltalk.method({
  994. selector: "send:",
  995. category: 'accessing',
  996. fn: function (anIRSend) {
  997. var self = this;
  998. self['@send'] = anIRSend;
  999. return self;
  1000. },
  1001. args: ["anIRSend"],
  1002. source: "send: anIRSend\x0a\x09send := anIRSend",
  1003. messageSends: [],
  1004. referencedClasses: []
  1005. }),
  1006. smalltalk.IRSendInliner);
  1007. smalltalk.addMethod(
  1008. "_translator",
  1009. smalltalk.method({
  1010. selector: "translator",
  1011. category: 'accessing',
  1012. fn: function () {
  1013. var self = this;
  1014. return self['@translator'];
  1015. },
  1016. args: [],
  1017. source: "translator\x0a\x09^ translator",
  1018. messageSends: [],
  1019. referencedClasses: []
  1020. }),
  1021. smalltalk.IRSendInliner);
  1022. smalltalk.addMethod(
  1023. "_translator_",
  1024. smalltalk.method({
  1025. selector: "translator:",
  1026. category: 'accessing',
  1027. fn: function (anASTTranslator) {
  1028. var self = this;
  1029. self['@translator'] = anASTTranslator;
  1030. return self;
  1031. },
  1032. args: ["anASTTranslator"],
  1033. source: "translator: anASTTranslator\x0a\x09translator := anASTTranslator",
  1034. messageSends: [],
  1035. referencedClasses: []
  1036. }),
  1037. smalltalk.IRSendInliner);
  1038. smalltalk.addMethod(
  1039. "_inlinedSelectors",
  1040. smalltalk.method({
  1041. selector: "inlinedSelectors",
  1042. category: 'accessing',
  1043. fn: function () {
  1044. var self = this;
  1045. return ["ifTrue:", "ifFalse:", "ifTrue:ifFalse:", "ifFalse:ifTrue:", "ifNil:", "ifNotNil:", "ifNil:ifNotNil:", "ifNotNil:ifNil"];
  1046. },
  1047. args: [],
  1048. source: "inlinedSelectors\x0a\x09^ #('ifTrue:' 'ifFalse:' 'ifTrue:ifFalse:' 'ifFalse:ifTrue:' 'ifNil:' 'ifNotNil:' 'ifNil:ifNotNil:' 'ifNotNil:ifNil')",
  1049. messageSends: [],
  1050. referencedClasses: []
  1051. }),
  1052. smalltalk.IRSendInliner.klass);
  1053. smalltalk.addMethod(
  1054. "_shouldInline_",
  1055. smalltalk.method({
  1056. selector: "shouldInline:",
  1057. category: 'accessing',
  1058. fn: function (anIRInstruction) {
  1059. var self = this;
  1060. var $1, $2;
  1061. var $early = {};
  1062. try {
  1063. $1 = smalltalk.send(smalltalk.send(self, "_inlinedSelectors", []), "_includes_", [smalltalk.send(anIRInstruction, "_selector", [])]);
  1064. if (!smalltalk.assert($1)) {
  1065. return false;
  1066. }
  1067. smalltalk.send(smalltalk.send(smalltalk.send(anIRInstruction, "_instructions", []), "_allButFirst", []), "_do_", [function (each) {$2 = smalltalk.send(each, "_isClosure", []);if (!smalltalk.assert($2)) {throw $early = [false];}}]);
  1068. return true;
  1069. } catch (e) {
  1070. if (e === $early) {
  1071. return e[0];
  1072. }
  1073. throw e;
  1074. }
  1075. },
  1076. args: ["anIRInstruction"],
  1077. source: "shouldInline: anIRInstruction\x0a\x09(self inlinedSelectors includes: anIRInstruction selector) ifFalse: [ ^ false ].\x0a\x09anIRInstruction instructions allButFirst do: [ :each |\x0a\x09\x09each isClosure ifFalse: [ ^ false ]].\x0a\x09^ true",
  1078. messageSends: ["ifFalse:", "includes:", "selector", "inlinedSelectors", "do:", "isClosure", "allButFirst", "instructions"],
  1079. referencedClasses: []
  1080. }),
  1081. smalltalk.IRSendInliner.klass);
  1082. smalltalk.addClass('IRAssignmentInliner', smalltalk.IRSendInliner, ['assignment'], 'Compiler-Inlining');
  1083. smalltalk.IRAssignmentInliner.comment="I inline message sends together with assignments by moving them around into the inline closure instructions. \x0a\x0a##Example\x0a\x0a\x09foo\x0a\x09\x09| a |\x0a\x09\x09a := true ifTrue: [ 1 ]\x0a\x0aWill produce:\x0a\x0a\x09if(smalltalk.assert(true) {\x0a\x09\x09a = 1;\x0a\x09};"
  1084. smalltalk.addMethod(
  1085. "_assignment",
  1086. smalltalk.method({
  1087. selector: "assignment",
  1088. category: 'accessing',
  1089. fn: function () {
  1090. var self = this;
  1091. return self['@assignment'];
  1092. },
  1093. args: [],
  1094. source: "assignment\x0a\x09^ assignment",
  1095. messageSends: [],
  1096. referencedClasses: []
  1097. }),
  1098. smalltalk.IRAssignmentInliner);
  1099. smalltalk.addMethod(
  1100. "_assignment_",
  1101. smalltalk.method({
  1102. selector: "assignment:",
  1103. category: 'accessing',
  1104. fn: function (aNode) {
  1105. var self = this;
  1106. self['@assignment'] = aNode;
  1107. return self;
  1108. },
  1109. args: ["aNode"],
  1110. source: "assignment: aNode\x0a\x09assignment := aNode",
  1111. messageSends: [],
  1112. referencedClasses: []
  1113. }),
  1114. smalltalk.IRAssignmentInliner);
  1115. smalltalk.addMethod(
  1116. "_inlineAssignment_",
  1117. smalltalk.method({
  1118. selector: "inlineAssignment:",
  1119. category: 'inlining',
  1120. fn: function (anIRAssignment) {
  1121. var self = this;
  1122. var inlinedAssignment;
  1123. smalltalk.send(self, "_assignment_", [anIRAssignment]);
  1124. inlinedAssignment = smalltalk.send(smalltalk.IRInlinedAssignment || IRInlinedAssignment, "_new", []);
  1125. smalltalk.send(smalltalk.send(anIRAssignment, "_instructions", []), "_do_", [function (each) {return smalltalk.send(inlinedAssignment, "_add_", [each]);}]);
  1126. smalltalk.send(anIRAssignment, "_replaceWith_", [inlinedAssignment]);
  1127. smalltalk.send(self, "_inlineSend_", [smalltalk.send(smalltalk.send(inlinedAssignment, "_instructions", []), "_last", [])]);
  1128. return inlinedAssignment;
  1129. },
  1130. args: ["anIRAssignment"],
  1131. 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",
  1132. messageSends: ["assignment:", "new", "do:", "add:", "instructions", "replaceWith:", "inlineSend:", "last"],
  1133. referencedClasses: ["IRInlinedAssignment"]
  1134. }),
  1135. smalltalk.IRAssignmentInliner);
  1136. smalltalk.addMethod(
  1137. "_inlineClosure_",
  1138. smalltalk.method({
  1139. selector: "inlineClosure:",
  1140. category: 'inlining',
  1141. fn: function (anIRClosure) {
  1142. var self = this;
  1143. var inlinedClosure = nil;
  1144. var statements = nil;
  1145. inlinedClosure = smalltalk.send(self, "_inlineClosure_", [anIRClosure], smalltalk.IRAssignmentInliner.superclass || nil);
  1146. statements = smalltalk.send(smalltalk.send(smalltalk.send(inlinedClosure, "_instructions", []), "_last", []), "_instructions", []);
  1147. smalltalk.send(statements, "_ifNotEmpty_", [function () {return ($receiver = smalltalk.send(smalltalk.send(statements, "_last", []), "_canBeAssigned", [])).klass === smalltalk.Boolean ? $receiver ? function () {return smalltalk.send(smalltalk.send(statements, "_last", []), "_replaceWith_", [function ($rec) {smalltalk.send($rec, "_add_", [smalltalk.send(smalltalk.send(smalltalk.send(self, "_assignment", []), "_instructions", []), "_first", [])]);smalltalk.send($rec, "_add_", [smalltalk.send(smalltalk.send(statements, "_last", []), "_copy", [])]);return smalltalk.send($rec, "_yourself", []);}(smalltalk.send(smalltalk.IRAssignment || IRAssignment, "_new", []))]);}() : nil : smalltalk.send($receiver, "_ifTrue_", [function () {return smalltalk.send(smalltalk.send(statements, "_last", []), "_replaceWith_", [function ($rec) {smalltalk.send($rec, "_add_", [smalltalk.send(smalltalk.send(smalltalk.send(self, "_assignment", []), "_instructions", []), "_first", [])]);smalltalk.send($rec, "_add_", [smalltalk.send(smalltalk.send(statements, "_last", []), "_copy", [])]);return smalltalk.send($rec, "_yourself", []);}(smalltalk.send(smalltalk.IRAssignment || IRAssignment, "_new", []))]);}]);}]);
  1148. return inlinedClosure;
  1149. return self;
  1150. },
  1151. args: ["anIRClosure"],
  1152. source: "inlineClosure: anIRClosure\x0a\x09| inlinedClosure statements |\x0a\x0a\x09inlinedClosure := super inlineClosure: anIRClosure.\x0a\x09statements := inlinedClosure instructions last instructions.\x0a\x09\x0a\x09statements ifNotEmpty: [\x0a\x09\x09statements last canBeAssigned ifTrue: [\x0a\x09\x09\x09statements last replaceWith: (IRAssignment new\x0a\x09\x09\x09\x09add: self assignment instructions first;\x0a\x09\x09\x09\x09add: statements last copy;\x0a\x09\x09\x09\x09yourself) ] ].\x0a\x0a\x09^ inlinedClosure",
  1153. messageSends: ["inlineClosure:", "instructions", "last", "ifNotEmpty:", "ifTrue:", "canBeAssigned", "replaceWith:", "add:", "first", "assignment", "copy", "yourself", "new"],
  1154. referencedClasses: ["IRAssignment"]
  1155. }),
  1156. smalltalk.IRAssignmentInliner);
  1157. smalltalk.addClass('IRNonLocalReturnInliner', smalltalk.IRSendInliner, [], 'Compiler-Inlining');
  1158. smalltalk.addMethod(
  1159. "_inlineClosure_",
  1160. smalltalk.method({
  1161. selector: "inlineClosure:",
  1162. category: 'inlining',
  1163. fn: function (anIRClosure) {
  1164. var self = this;
  1165. return smalltalk.send(self, "_inlineCLosure_", [anIRClosure], smalltalk.IRNonLocalReturnInliner.superclass || nil);
  1166. return self;
  1167. },
  1168. args: ["anIRClosure"],
  1169. source: "inlineClosure: anIRClosure\x0a\x09\x22| inlinedClosure statements |\x0a\x0a\x09inlinedClosure := super inlineClosure: anIRClosure.\x0a\x09statements := inlinedClosure instructions last instructions.\x0a\x09\x0a\x09statements ifNotEmpty: [\x0a\x09\x09statements last replaceWith: (IRNonLocalReturn new\x0a\x09\x09\x09add: statements last copy;\x0a\x09\x09\x09yourself) ].\x0a\x0a\x09^ inlinedClosure\x22\x0a\x0a\x09^ super inlineCLosure: anIRClosure",
  1170. messageSends: ["inlineCLosure:"],
  1171. referencedClasses: []
  1172. }),
  1173. smalltalk.IRNonLocalReturnInliner);
  1174. smalltalk.addMethod(
  1175. "_inlinedReturn",
  1176. smalltalk.method({
  1177. selector: "inlinedReturn",
  1178. category: 'factory',
  1179. fn: function () {
  1180. var self = this;
  1181. var $1;
  1182. $1 = smalltalk.send(smalltalk.IRInlinedNonLocalReturn || IRInlinedNonLocalReturn, "_new", []);
  1183. return $1;
  1184. },
  1185. args: [],
  1186. source: "inlinedReturn\x0a\x09^ IRInlinedNonLocalReturn new",
  1187. messageSends: ["new"],
  1188. referencedClasses: ["IRInlinedNonLocalReturn"]
  1189. }),
  1190. smalltalk.IRNonLocalReturnInliner);
  1191. smalltalk.addClass('IRReturnInliner', smalltalk.IRSendInliner, [], 'Compiler-Inlining');
  1192. smalltalk.IRReturnInliner.comment="I inline message sends with inlined closure together with a return instruction."
  1193. smalltalk.addMethod(
  1194. "_inlineClosure_",
  1195. smalltalk.method({
  1196. selector: "inlineClosure:",
  1197. category: 'inlining',
  1198. fn: function (anIRClosure) {
  1199. var self = this;
  1200. var closure = nil;
  1201. var statements = nil;
  1202. closure = smalltalk.send(self, "_inlineClosure_", [anIRClosure], smalltalk.IRReturnInliner.superclass || nil);
  1203. statements = smalltalk.send(smalltalk.send(smalltalk.send(closure, "_instructions", []), "_last", []), "_instructions", []);
  1204. smalltalk.send(statements, "_ifNotEmpty_", [function () {return ($receiver = smalltalk.send(smalltalk.send(statements, "_last", []), "_isReturn", [])).klass === smalltalk.Boolean ? !$receiver ? function () {return smalltalk.send(smalltalk.send(statements, "_last", []), "_replaceWith_", [function ($rec) {smalltalk.send($rec, "_add_", [smalltalk.send(smalltalk.send(statements, "_last", []), "_copy", [])]);return smalltalk.send($rec, "_yourself", []);}(smalltalk.send(smalltalk.IRReturn || IRReturn, "_new", []))]);}() : nil : smalltalk.send($receiver, "_ifFalse_", [function () {return smalltalk.send(smalltalk.send(statements, "_last", []), "_replaceWith_", [function ($rec) {smalltalk.send($rec, "_add_", [smalltalk.send(smalltalk.send(statements, "_last", []), "_copy", [])]);return smalltalk.send($rec, "_yourself", []);}(smalltalk.send(smalltalk.IRReturn || IRReturn, "_new", []))]);}]);}]);
  1205. return closure;
  1206. return self;
  1207. },
  1208. args: ["anIRClosure"],
  1209. source: "inlineClosure: anIRClosure\x0a\x09| closure statements |\x0a\x0a\x09closure := super inlineClosure: anIRClosure.\x0a\x09statements := closure instructions last instructions.\x0a\x09\x0a\x09statements ifNotEmpty: [\x0a\x09\x09statements last isReturn\x0a\x09\x09\x09ifFalse: [ statements last replaceWith: (IRReturn new\x0a\x09\x09\x09\x09add: statements last copy;\x0a\x09\x09\x09\x09yourself)] ].\x0a\x0a\x09^ closure",
  1210. messageSends: ["inlineClosure:", "instructions", "last", "ifNotEmpty:", "ifFalse:", "isReturn", "replaceWith:", "add:", "copy", "yourself", "new"],
  1211. referencedClasses: ["IRReturn"]
  1212. }),
  1213. smalltalk.IRReturnInliner);
  1214. smalltalk.addMethod(
  1215. "_inlineReturn_",
  1216. smalltalk.method({
  1217. selector: "inlineReturn:",
  1218. category: 'inlining',
  1219. fn: function (anIRReturn) {
  1220. var self = this;
  1221. var return_ = nil;
  1222. return_ = smalltalk.send(self, "_inlinedReturn", []);
  1223. smalltalk.send(smalltalk.send(anIRReturn, "_instructions", []), "_do_", [function (each) {return smalltalk.send(return_, "_add_", [each]);}]);
  1224. smalltalk.send(anIRReturn, "_replaceWith_", [return_]);
  1225. smalltalk.send(self, "_inlineSend_", [smalltalk.send(smalltalk.send(return_, "_instructions", []), "_last", [])]);
  1226. return return_;
  1227. return self;
  1228. },
  1229. args: ["anIRReturn"],
  1230. source: "inlineReturn: anIRReturn\x0a\x09| return |\x0a\x09return := self inlinedReturn.\x0a\x09anIRReturn instructions do: [ :each |\x0a\x09\x09return add: each ].\x0a\x09anIRReturn replaceWith: return.\x0a\x09self inlineSend: return instructions last.\x0a\x09^ return",
  1231. messageSends: ["inlinedReturn", "do:", "instructions", "add:", "replaceWith:", "inlineSend:", "last"],
  1232. referencedClasses: []
  1233. }),
  1234. smalltalk.IRReturnInliner);
  1235. smalltalk.addMethod(
  1236. "_inlinedReturn",
  1237. smalltalk.method({
  1238. selector: "inlinedReturn",
  1239. category: 'factory',
  1240. fn: function () {
  1241. var self = this;
  1242. var $1;
  1243. $1 = smalltalk.send(smalltalk.IRInlinedReturn || IRInlinedReturn, "_new", []);
  1244. return $1;
  1245. },
  1246. args: [],
  1247. source: "inlinedReturn\x0a\x09^ IRInlinedReturn new",
  1248. messageSends: ["new"],
  1249. referencedClasses: ["IRInlinedReturn"]
  1250. }),
  1251. smalltalk.IRReturnInliner);
  1252. smalltalk.addClass('InliningCodeGenerator', smalltalk.CodeGenerator, [], 'Compiler-Inlining');
  1253. smalltalk.InliningCodeGenerator.comment="I am a specialized code generator that uses inlining to produce more optimized JavaScript output"
  1254. smalltalk.addMethod(
  1255. "_compileNode_",
  1256. smalltalk.method({
  1257. selector: "compileNode:",
  1258. category: 'compiling',
  1259. fn: function (aNode) {
  1260. var self = this;
  1261. var ir = nil;
  1262. var stream = nil;
  1263. smalltalk.send(smalltalk.send(self, "_semanticAnalyzer", []), "_visit_", [aNode]);
  1264. ir = smalltalk.send(smalltalk.send(self, "_translator", []), "_visit_", [aNode]);
  1265. smalltalk.send(smalltalk.send(self, "_inliner", []), "_visit_", [ir]);
  1266. return function ($rec) {smalltalk.send($rec, "_visit_", [ir]);return smalltalk.send($rec, "_contents", []);}(smalltalk.send(self, "_irTranslator", []));
  1267. return self;
  1268. },
  1269. args: ["aNode"],
  1270. source: "compileNode: aNode\x0a\x09| ir stream |\x0a\x0a\x09self semanticAnalyzer visit: aNode.\x0a\x09ir := self translator visit: aNode.\x0a\x09self inliner visit: ir.\x0a\x0a\x09^ self irTranslator\x0a\x09\x09visit: ir;\x0a\x09\x09contents",
  1271. messageSends: ["visit:", "semanticAnalyzer", "translator", "inliner", "contents", "irTranslator"],
  1272. referencedClasses: []
  1273. }),
  1274. smalltalk.InliningCodeGenerator);
  1275. smalltalk.addMethod(
  1276. "_inliner",
  1277. smalltalk.method({
  1278. selector: "inliner",
  1279. category: 'compiling',
  1280. fn: function () {
  1281. var self = this;
  1282. var $1;
  1283. $1 = smalltalk.send(smalltalk.IRInliner || IRInliner, "_new", []);
  1284. return $1;
  1285. },
  1286. args: [],
  1287. source: "inliner\x0a\x09^ IRInliner new",
  1288. messageSends: ["new"],
  1289. referencedClasses: ["IRInliner"]
  1290. }),
  1291. smalltalk.InliningCodeGenerator);
  1292. smalltalk.addMethod(
  1293. "_irTranslator",
  1294. smalltalk.method({
  1295. selector: "irTranslator",
  1296. category: 'compiling',
  1297. fn: function () {
  1298. var self = this;
  1299. var $1;
  1300. $1 = smalltalk.send(smalltalk.IRInliningJSTranslator || IRInliningJSTranslator, "_new", []);
  1301. return $1;
  1302. },
  1303. args: [],
  1304. source: "irTranslator\x0a\x09^ IRInliningJSTranslator new",
  1305. messageSends: ["new"],
  1306. referencedClasses: ["IRInliningJSTranslator"]
  1307. }),
  1308. smalltalk.InliningCodeGenerator);