Compiler-Inlining.js 66 KB

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