1
0

Compiler-Inlining.js 68 KB

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