ASTCodegen.cpp 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280
  1. /*
  2. * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
  3. * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
  4. * Copyright (c) 2021, Gunnar Beutner <gbeutner@serenityos.org>
  5. * Copyright (c) 2021, Marcin Gasperowicz <xnooga@gmail.com>
  6. *
  7. * SPDX-License-Identifier: BSD-2-Clause
  8. */
  9. #include <AK/Format.h>
  10. #include <LibJS/AST.h>
  11. #include <LibJS/Bytecode/Generator.h>
  12. #include <LibJS/Bytecode/Instruction.h>
  13. #include <LibJS/Bytecode/Op.h>
  14. #include <LibJS/Bytecode/Register.h>
  15. #include <LibJS/Bytecode/StringTable.h>
  16. #include <LibJS/Runtime/Environment.h>
  17. namespace JS {
  18. void ASTNode::generate_bytecode(Bytecode::Generator&) const
  19. {
  20. dbgln("Missing generate_bytecode() in {}", class_name());
  21. TODO();
  22. }
  23. void ScopeNode::generate_bytecode(Bytecode::Generator& generator) const
  24. {
  25. // FIXME: This is an ad-hoc fix but should be done as the spec says in
  26. // {Global, Block, Function, Eval}DeclarationInstantiation.
  27. for (auto& function : m_functions_hoistable_with_annexB_extension) {
  28. generator.emit<Bytecode::Op::NewFunction>(function);
  29. generator.emit<Bytecode::Op::SetVariable>(generator.intern_identifier(function.name()));
  30. }
  31. HashTable<FlyString> functions_initialized;
  32. for_each_var_function_declaration_in_reverse_order([&](FunctionDeclaration const& function) {
  33. if (functions_initialized.set(function.name()) != AK::HashSetResult::InsertedNewEntry)
  34. return;
  35. generator.emit<Bytecode::Op::NewFunction>(function);
  36. generator.emit<Bytecode::Op::SetVariable>(generator.intern_identifier(function.name()));
  37. });
  38. // FIXME: Register lexical and variable scope declarations
  39. for (auto& child : children()) {
  40. child.generate_bytecode(generator);
  41. if (generator.is_current_block_terminated())
  42. break;
  43. }
  44. }
  45. void EmptyStatement::generate_bytecode(Bytecode::Generator&) const
  46. {
  47. }
  48. void ExpressionStatement::generate_bytecode(Bytecode::Generator& generator) const
  49. {
  50. m_expression->generate_bytecode(generator);
  51. }
  52. void BinaryExpression::generate_bytecode(Bytecode::Generator& generator) const
  53. {
  54. m_lhs->generate_bytecode(generator);
  55. auto lhs_reg = generator.allocate_register();
  56. generator.emit<Bytecode::Op::Store>(lhs_reg);
  57. m_rhs->generate_bytecode(generator);
  58. switch (m_op) {
  59. case BinaryOp::Addition:
  60. generator.emit<Bytecode::Op::Add>(lhs_reg);
  61. break;
  62. case BinaryOp::Subtraction:
  63. generator.emit<Bytecode::Op::Sub>(lhs_reg);
  64. break;
  65. case BinaryOp::Multiplication:
  66. generator.emit<Bytecode::Op::Mul>(lhs_reg);
  67. break;
  68. case BinaryOp::Division:
  69. generator.emit<Bytecode::Op::Div>(lhs_reg);
  70. break;
  71. case BinaryOp::Modulo:
  72. generator.emit<Bytecode::Op::Mod>(lhs_reg);
  73. break;
  74. case BinaryOp::Exponentiation:
  75. generator.emit<Bytecode::Op::Exp>(lhs_reg);
  76. break;
  77. case BinaryOp::GreaterThan:
  78. generator.emit<Bytecode::Op::GreaterThan>(lhs_reg);
  79. break;
  80. case BinaryOp::GreaterThanEquals:
  81. generator.emit<Bytecode::Op::GreaterThanEquals>(lhs_reg);
  82. break;
  83. case BinaryOp::LessThan:
  84. generator.emit<Bytecode::Op::LessThan>(lhs_reg);
  85. break;
  86. case BinaryOp::LessThanEquals:
  87. generator.emit<Bytecode::Op::LessThanEquals>(lhs_reg);
  88. break;
  89. case BinaryOp::LooselyInequals:
  90. generator.emit<Bytecode::Op::LooselyInequals>(lhs_reg);
  91. break;
  92. case BinaryOp::LooselyEquals:
  93. generator.emit<Bytecode::Op::LooselyEquals>(lhs_reg);
  94. break;
  95. case BinaryOp::StrictlyInequals:
  96. generator.emit<Bytecode::Op::StrictlyInequals>(lhs_reg);
  97. break;
  98. case BinaryOp::StrictlyEquals:
  99. generator.emit<Bytecode::Op::StrictlyEquals>(lhs_reg);
  100. break;
  101. case BinaryOp::BitwiseAnd:
  102. generator.emit<Bytecode::Op::BitwiseAnd>(lhs_reg);
  103. break;
  104. case BinaryOp::BitwiseOr:
  105. generator.emit<Bytecode::Op::BitwiseOr>(lhs_reg);
  106. break;
  107. case BinaryOp::BitwiseXor:
  108. generator.emit<Bytecode::Op::BitwiseXor>(lhs_reg);
  109. break;
  110. case BinaryOp::LeftShift:
  111. generator.emit<Bytecode::Op::LeftShift>(lhs_reg);
  112. break;
  113. case BinaryOp::RightShift:
  114. generator.emit<Bytecode::Op::RightShift>(lhs_reg);
  115. break;
  116. case BinaryOp::UnsignedRightShift:
  117. generator.emit<Bytecode::Op::UnsignedRightShift>(lhs_reg);
  118. break;
  119. case BinaryOp::In:
  120. generator.emit<Bytecode::Op::In>(lhs_reg);
  121. break;
  122. case BinaryOp::InstanceOf:
  123. generator.emit<Bytecode::Op::InstanceOf>(lhs_reg);
  124. break;
  125. default:
  126. VERIFY_NOT_REACHED();
  127. }
  128. }
  129. void LogicalExpression::generate_bytecode(Bytecode::Generator& generator) const
  130. {
  131. m_lhs->generate_bytecode(generator);
  132. // lhs
  133. // jump op (true) end (false) rhs
  134. // rhs
  135. // jump always (true) end
  136. // end
  137. auto& rhs_block = generator.make_block();
  138. auto& end_block = generator.make_block();
  139. switch (m_op) {
  140. case LogicalOp::And:
  141. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  142. Bytecode::Label { rhs_block },
  143. Bytecode::Label { end_block });
  144. break;
  145. case LogicalOp::Or:
  146. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  147. Bytecode::Label { end_block },
  148. Bytecode::Label { rhs_block });
  149. break;
  150. case LogicalOp::NullishCoalescing:
  151. generator.emit<Bytecode::Op::JumpNullish>().set_targets(
  152. Bytecode::Label { rhs_block },
  153. Bytecode::Label { end_block });
  154. break;
  155. default:
  156. VERIFY_NOT_REACHED();
  157. }
  158. generator.switch_to_basic_block(rhs_block);
  159. m_rhs->generate_bytecode(generator);
  160. generator.emit<Bytecode::Op::Jump>().set_targets(
  161. Bytecode::Label { end_block },
  162. {});
  163. generator.switch_to_basic_block(end_block);
  164. }
  165. void UnaryExpression::generate_bytecode(Bytecode::Generator& generator) const
  166. {
  167. m_lhs->generate_bytecode(generator);
  168. switch (m_op) {
  169. case UnaryOp::BitwiseNot:
  170. generator.emit<Bytecode::Op::BitwiseNot>();
  171. break;
  172. case UnaryOp::Not:
  173. generator.emit<Bytecode::Op::Not>();
  174. break;
  175. case UnaryOp::Plus:
  176. generator.emit<Bytecode::Op::UnaryPlus>();
  177. break;
  178. case UnaryOp::Minus:
  179. generator.emit<Bytecode::Op::UnaryMinus>();
  180. break;
  181. case UnaryOp::Typeof:
  182. generator.emit<Bytecode::Op::Typeof>();
  183. break;
  184. case UnaryOp::Void:
  185. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  186. break;
  187. default:
  188. TODO();
  189. }
  190. }
  191. void NumericLiteral::generate_bytecode(Bytecode::Generator& generator) const
  192. {
  193. generator.emit<Bytecode::Op::LoadImmediate>(m_value);
  194. }
  195. void BooleanLiteral::generate_bytecode(Bytecode::Generator& generator) const
  196. {
  197. generator.emit<Bytecode::Op::LoadImmediate>(Value(m_value));
  198. }
  199. void NullLiteral::generate_bytecode(Bytecode::Generator& generator) const
  200. {
  201. generator.emit<Bytecode::Op::LoadImmediate>(js_null());
  202. }
  203. void BigIntLiteral::generate_bytecode(Bytecode::Generator& generator) const
  204. {
  205. generator.emit<Bytecode::Op::NewBigInt>(Crypto::SignedBigInteger::from_base(10, m_value.substring(0, m_value.length() - 1)));
  206. }
  207. void StringLiteral::generate_bytecode(Bytecode::Generator& generator) const
  208. {
  209. generator.emit<Bytecode::Op::NewString>(generator.intern_string(m_value));
  210. }
  211. void RegExpLiteral::generate_bytecode(Bytecode::Generator& generator) const
  212. {
  213. auto source_index = generator.intern_string(m_pattern);
  214. auto flags_index = generator.intern_string(m_flags);
  215. generator.emit<Bytecode::Op::NewRegExp>(source_index, flags_index);
  216. }
  217. void Identifier::generate_bytecode(Bytecode::Generator& generator) const
  218. {
  219. generator.emit<Bytecode::Op::GetVariable>(generator.intern_identifier(m_string));
  220. }
  221. void AssignmentExpression::generate_bytecode(Bytecode::Generator& generator) const
  222. {
  223. // FIXME: Implement this for BindingPatterns too.
  224. auto& lhs = m_lhs.get<NonnullRefPtr<Expression>>();
  225. if (m_op == AssignmentOp::Assignment) {
  226. m_rhs->generate_bytecode(generator);
  227. generator.emit_store_to_reference(lhs);
  228. return;
  229. }
  230. generator.emit_load_from_reference(lhs);
  231. Bytecode::BasicBlock* rhs_block_ptr { nullptr };
  232. Bytecode::BasicBlock* end_block_ptr { nullptr };
  233. // Logical assignments short circuit.
  234. if (m_op == AssignmentOp::AndAssignment) { // &&=
  235. rhs_block_ptr = &generator.make_block();
  236. end_block_ptr = &generator.make_block();
  237. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  238. Bytecode::Label { *rhs_block_ptr },
  239. Bytecode::Label { *end_block_ptr });
  240. } else if (m_op == AssignmentOp::OrAssignment) { // ||=
  241. rhs_block_ptr = &generator.make_block();
  242. end_block_ptr = &generator.make_block();
  243. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  244. Bytecode::Label { *end_block_ptr },
  245. Bytecode::Label { *rhs_block_ptr });
  246. } else if (m_op == AssignmentOp::NullishAssignment) { // ??=
  247. rhs_block_ptr = &generator.make_block();
  248. end_block_ptr = &generator.make_block();
  249. generator.emit<Bytecode::Op::JumpNullish>().set_targets(
  250. Bytecode::Label { *rhs_block_ptr },
  251. Bytecode::Label { *end_block_ptr });
  252. }
  253. if (rhs_block_ptr)
  254. generator.switch_to_basic_block(*rhs_block_ptr);
  255. // lhs_reg is a part of the rhs_block because the store isn't necessary
  256. // if the logical assignment condition fails.
  257. auto lhs_reg = generator.allocate_register();
  258. generator.emit<Bytecode::Op::Store>(lhs_reg);
  259. m_rhs->generate_bytecode(generator);
  260. switch (m_op) {
  261. case AssignmentOp::AdditionAssignment:
  262. generator.emit<Bytecode::Op::Add>(lhs_reg);
  263. break;
  264. case AssignmentOp::SubtractionAssignment:
  265. generator.emit<Bytecode::Op::Sub>(lhs_reg);
  266. break;
  267. case AssignmentOp::MultiplicationAssignment:
  268. generator.emit<Bytecode::Op::Mul>(lhs_reg);
  269. break;
  270. case AssignmentOp::DivisionAssignment:
  271. generator.emit<Bytecode::Op::Div>(lhs_reg);
  272. break;
  273. case AssignmentOp::ModuloAssignment:
  274. generator.emit<Bytecode::Op::Mod>(lhs_reg);
  275. break;
  276. case AssignmentOp::ExponentiationAssignment:
  277. generator.emit<Bytecode::Op::Exp>(lhs_reg);
  278. break;
  279. case AssignmentOp::BitwiseAndAssignment:
  280. generator.emit<Bytecode::Op::BitwiseAnd>(lhs_reg);
  281. break;
  282. case AssignmentOp::BitwiseOrAssignment:
  283. generator.emit<Bytecode::Op::BitwiseOr>(lhs_reg);
  284. break;
  285. case AssignmentOp::BitwiseXorAssignment:
  286. generator.emit<Bytecode::Op::BitwiseXor>(lhs_reg);
  287. break;
  288. case AssignmentOp::LeftShiftAssignment:
  289. generator.emit<Bytecode::Op::LeftShift>(lhs_reg);
  290. break;
  291. case AssignmentOp::RightShiftAssignment:
  292. generator.emit<Bytecode::Op::RightShift>(lhs_reg);
  293. break;
  294. case AssignmentOp::UnsignedRightShiftAssignment:
  295. generator.emit<Bytecode::Op::UnsignedRightShift>(lhs_reg);
  296. break;
  297. case AssignmentOp::AndAssignment:
  298. case AssignmentOp::OrAssignment:
  299. case AssignmentOp::NullishAssignment:
  300. break; // These are handled above.
  301. default:
  302. TODO();
  303. }
  304. generator.emit_store_to_reference(lhs);
  305. if (end_block_ptr) {
  306. generator.emit<Bytecode::Op::Jump>().set_targets(
  307. Bytecode::Label { *end_block_ptr },
  308. {});
  309. generator.switch_to_basic_block(*end_block_ptr);
  310. }
  311. }
  312. void WhileStatement::generate_bytecode(Bytecode::Generator& generator) const
  313. {
  314. // test
  315. // jump if_false (true) end (false) body
  316. // body
  317. // jump always (true) test
  318. // end
  319. auto& test_block = generator.make_block();
  320. auto& body_block = generator.make_block();
  321. auto& end_block = generator.make_block();
  322. // Init result register
  323. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  324. auto result_reg = generator.allocate_register();
  325. generator.emit<Bytecode::Op::Store>(result_reg);
  326. // jump to the test block
  327. generator.emit<Bytecode::Op::Jump>().set_targets(
  328. Bytecode::Label { test_block },
  329. {});
  330. generator.switch_to_basic_block(test_block);
  331. m_test->generate_bytecode(generator);
  332. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  333. Bytecode::Label { body_block },
  334. Bytecode::Label { end_block });
  335. generator.switch_to_basic_block(body_block);
  336. generator.begin_continuable_scope(Bytecode::Label { test_block });
  337. generator.begin_breakable_scope(Bytecode::Label { end_block });
  338. m_body->generate_bytecode(generator);
  339. if (!generator.is_current_block_terminated()) {
  340. generator.emit<Bytecode::Op::Jump>().set_targets(
  341. Bytecode::Label { test_block },
  342. {});
  343. generator.end_continuable_scope();
  344. generator.end_breakable_scope();
  345. generator.switch_to_basic_block(end_block);
  346. generator.emit<Bytecode::Op::Load>(result_reg);
  347. }
  348. }
  349. void DoWhileStatement::generate_bytecode(Bytecode::Generator& generator) const
  350. {
  351. // jump always (true) body
  352. // test
  353. // jump if_false (true) end (false) body
  354. // body
  355. // jump always (true) test
  356. // end
  357. auto& test_block = generator.make_block();
  358. auto& body_block = generator.make_block();
  359. auto& end_block = generator.make_block();
  360. // Init result register
  361. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  362. auto result_reg = generator.allocate_register();
  363. generator.emit<Bytecode::Op::Store>(result_reg);
  364. // jump to the body block
  365. generator.emit<Bytecode::Op::Jump>().set_targets(
  366. Bytecode::Label { body_block },
  367. {});
  368. generator.switch_to_basic_block(test_block);
  369. m_test->generate_bytecode(generator);
  370. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  371. Bytecode::Label { body_block },
  372. Bytecode::Label { end_block });
  373. generator.switch_to_basic_block(body_block);
  374. generator.begin_continuable_scope(Bytecode::Label { test_block });
  375. generator.begin_breakable_scope(Bytecode::Label { end_block });
  376. m_body->generate_bytecode(generator);
  377. if (!generator.is_current_block_terminated()) {
  378. generator.emit<Bytecode::Op::Jump>().set_targets(
  379. Bytecode::Label { test_block },
  380. {});
  381. generator.end_continuable_scope();
  382. generator.end_breakable_scope();
  383. generator.switch_to_basic_block(end_block);
  384. generator.emit<Bytecode::Op::Load>(result_reg);
  385. }
  386. }
  387. void ForStatement::generate_bytecode(Bytecode::Generator& generator) const
  388. {
  389. // init
  390. // jump always (true) test
  391. // test
  392. // jump if_true (true) body (false) end
  393. // body
  394. // jump always (true) update
  395. // update
  396. // jump always (true) test
  397. // end
  398. // If 'test' is missing, fuse the 'test' and 'body' basic blocks
  399. // If 'update' is missing, fuse the 'body' and 'update' basic blocks
  400. Bytecode::BasicBlock* test_block_ptr { nullptr };
  401. Bytecode::BasicBlock* body_block_ptr { nullptr };
  402. Bytecode::BasicBlock* update_block_ptr { nullptr };
  403. auto& end_block = generator.make_block();
  404. if (m_init)
  405. m_init->generate_bytecode(generator);
  406. body_block_ptr = &generator.make_block();
  407. if (m_test)
  408. test_block_ptr = &generator.make_block();
  409. else
  410. test_block_ptr = body_block_ptr;
  411. if (m_update)
  412. update_block_ptr = &generator.make_block();
  413. else
  414. update_block_ptr = body_block_ptr;
  415. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  416. auto result_reg = generator.allocate_register();
  417. generator.emit<Bytecode::Op::Store>(result_reg);
  418. generator.emit<Bytecode::Op::Jump>().set_targets(
  419. Bytecode::Label { *test_block_ptr },
  420. {});
  421. if (m_test) {
  422. generator.switch_to_basic_block(*test_block_ptr);
  423. m_test->generate_bytecode(generator);
  424. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  425. Bytecode::Label { *body_block_ptr },
  426. Bytecode::Label { end_block });
  427. }
  428. generator.switch_to_basic_block(*body_block_ptr);
  429. generator.begin_continuable_scope(Bytecode::Label { *update_block_ptr });
  430. generator.begin_breakable_scope(Bytecode::Label { end_block });
  431. m_body->generate_bytecode(generator);
  432. generator.end_continuable_scope();
  433. if (!generator.is_current_block_terminated()) {
  434. if (m_update) {
  435. generator.emit<Bytecode::Op::Jump>().set_targets(
  436. Bytecode::Label { *update_block_ptr },
  437. {});
  438. generator.switch_to_basic_block(*update_block_ptr);
  439. m_update->generate_bytecode(generator);
  440. }
  441. generator.emit<Bytecode::Op::Jump>().set_targets(
  442. Bytecode::Label { *test_block_ptr },
  443. {});
  444. generator.end_breakable_scope();
  445. generator.switch_to_basic_block(end_block);
  446. generator.emit<Bytecode::Op::Load>(result_reg);
  447. }
  448. }
  449. void ObjectExpression::generate_bytecode(Bytecode::Generator& generator) const
  450. {
  451. generator.emit<Bytecode::Op::NewObject>();
  452. if (m_properties.is_empty())
  453. return;
  454. auto object_reg = generator.allocate_register();
  455. generator.emit<Bytecode::Op::Store>(object_reg);
  456. for (auto& property : m_properties) {
  457. if (property.type() != ObjectProperty::Type::KeyValue)
  458. TODO();
  459. if (is<StringLiteral>(property.key())) {
  460. auto& string_literal = static_cast<StringLiteral const&>(property.key());
  461. Bytecode::IdentifierTableIndex key_name = generator.intern_identifier(string_literal.value());
  462. property.value().generate_bytecode(generator);
  463. generator.emit<Bytecode::Op::PutById>(object_reg, key_name);
  464. } else {
  465. property.key().generate_bytecode(generator);
  466. auto property_reg = generator.allocate_register();
  467. generator.emit<Bytecode::Op::Store>(property_reg);
  468. property.value().generate_bytecode(generator);
  469. generator.emit<Bytecode::Op::PutByValue>(object_reg, property_reg);
  470. }
  471. }
  472. generator.emit<Bytecode::Op::Load>(object_reg);
  473. }
  474. void ArrayExpression::generate_bytecode(Bytecode::Generator& generator) const
  475. {
  476. Vector<Bytecode::Register> element_regs;
  477. for (auto& element : m_elements) {
  478. if (element) {
  479. element->generate_bytecode(generator);
  480. if (is<SpreadExpression>(*element)) {
  481. TODO();
  482. continue;
  483. }
  484. } else {
  485. generator.emit<Bytecode::Op::LoadImmediate>(Value {});
  486. }
  487. auto element_reg = generator.allocate_register();
  488. generator.emit<Bytecode::Op::Store>(element_reg);
  489. element_regs.append(element_reg);
  490. }
  491. generator.emit_with_extra_register_slots<Bytecode::Op::NewArray>(element_regs.size(), element_regs);
  492. }
  493. void MemberExpression::generate_bytecode(Bytecode::Generator& generator) const
  494. {
  495. generator.emit_load_from_reference(*this);
  496. }
  497. void FunctionDeclaration::generate_bytecode(Bytecode::Generator&) const
  498. {
  499. }
  500. void FunctionExpression::generate_bytecode(Bytecode::Generator& generator) const
  501. {
  502. generator.emit<Bytecode::Op::NewFunction>(*this);
  503. }
  504. static void generate_binding_pattern_bytecode(Bytecode::Generator& generator, BindingPattern const& pattern, Bytecode::Register const& value_reg);
  505. static void generate_object_binding_pattern_bytecode(Bytecode::Generator& generator, BindingPattern const& pattern, Bytecode::Register const& value_reg)
  506. {
  507. Vector<Bytecode::Register> excluded_property_names;
  508. auto has_rest = false;
  509. if (pattern.entries.size() > 0)
  510. has_rest = pattern.entries[pattern.entries.size() - 1].is_rest;
  511. for (auto& [name, alias, initializer, is_rest] : pattern.entries) {
  512. if (is_rest) {
  513. VERIFY(name.has<NonnullRefPtr<Identifier>>());
  514. VERIFY(alias.has<Empty>());
  515. VERIFY(!initializer);
  516. auto identifier = name.get<NonnullRefPtr<Identifier>>()->string();
  517. auto interned_identifier = generator.intern_identifier(identifier);
  518. generator.emit_with_extra_register_slots<Bytecode::Op::CopyObjectExcludingProperties>(excluded_property_names.size(), value_reg, excluded_property_names);
  519. generator.emit<Bytecode::Op::SetVariable>(interned_identifier);
  520. return;
  521. }
  522. Bytecode::StringTableIndex name_index;
  523. if (name.has<NonnullRefPtr<Identifier>>()) {
  524. auto identifier = name.get<NonnullRefPtr<Identifier>>()->string();
  525. name_index = generator.intern_string(identifier);
  526. if (has_rest) {
  527. auto excluded_name_reg = generator.allocate_register();
  528. excluded_property_names.append(excluded_name_reg);
  529. generator.emit<Bytecode::Op::NewString>(name_index);
  530. generator.emit<Bytecode::Op::Store>(excluded_name_reg);
  531. }
  532. generator.emit<Bytecode::Op::Load>(value_reg);
  533. generator.emit<Bytecode::Op::GetById>(generator.intern_identifier(identifier));
  534. } else {
  535. auto expression = name.get<NonnullRefPtr<Expression>>();
  536. expression->generate_bytecode(generator);
  537. if (has_rest) {
  538. auto excluded_name_reg = generator.allocate_register();
  539. excluded_property_names.append(excluded_name_reg);
  540. generator.emit<Bytecode::Op::Store>(excluded_name_reg);
  541. }
  542. generator.emit<Bytecode::Op::GetByValue>(value_reg);
  543. }
  544. if (initializer) {
  545. auto& if_undefined_block = generator.make_block();
  546. auto& if_not_undefined_block = generator.make_block();
  547. generator.emit<Bytecode::Op::JumpUndefined>().set_targets(
  548. Bytecode::Label { if_undefined_block },
  549. Bytecode::Label { if_not_undefined_block });
  550. generator.switch_to_basic_block(if_undefined_block);
  551. initializer->generate_bytecode(generator);
  552. generator.emit<Bytecode::Op::Jump>().set_targets(
  553. Bytecode::Label { if_not_undefined_block },
  554. {});
  555. generator.switch_to_basic_block(if_not_undefined_block);
  556. }
  557. if (alias.has<NonnullRefPtr<BindingPattern>>()) {
  558. auto& binding_pattern = *alias.get<NonnullRefPtr<BindingPattern>>();
  559. auto nested_value_reg = generator.allocate_register();
  560. generator.emit<Bytecode::Op::Store>(nested_value_reg);
  561. generate_binding_pattern_bytecode(generator, binding_pattern, nested_value_reg);
  562. } else if (alias.has<Empty>()) {
  563. if (name.has<NonnullRefPtr<Expression>>()) {
  564. // This needs some sort of SetVariableByValue opcode, as it's a runtime binding
  565. TODO();
  566. }
  567. auto& identifier = alias.get<NonnullRefPtr<Identifier>>()->string();
  568. generator.emit<Bytecode::Op::SetVariable>(generator.intern_identifier(identifier));
  569. } else {
  570. auto& identifier = alias.get<NonnullRefPtr<Identifier>>()->string();
  571. generator.emit<Bytecode::Op::SetVariable>(generator.intern_identifier(identifier));
  572. }
  573. }
  574. }
  575. static void generate_array_binding_pattern_bytecode(Bytecode::Generator& generator, BindingPattern const& pattern, Bytecode::Register const& value_reg)
  576. {
  577. /*
  578. * Consider the following destructuring assignment:
  579. *
  580. * let [a, b, c, d, e] = o;
  581. *
  582. * It would be fairly trivial to just loop through this iterator, getting the value
  583. * at each step and assigning them to the binding sequentially. However, this is not
  584. * correct: once an iterator is exhausted, it must not be called again. This complicates
  585. * the bytecode. In order to accomplish this, we do the following:
  586. *
  587. * - Reserve a special boolean register which holds 'true' if the iterator is exhausted,
  588. * and false otherwise
  589. * - When we are retrieving the value which should be bound, we first check this register.
  590. * If it is 'true', we load undefined into the accumulator. Otherwise, we grab the next
  591. * value from the iterator and store it into the accumulator.
  592. *
  593. * Note that the is_exhausted register does not need to be loaded with false because the
  594. * first IteratorNext bytecode is _not_ proceeded by an exhausted check, as it is
  595. * unnecessary.
  596. */
  597. auto is_iterator_exhausted_register = generator.allocate_register();
  598. auto iterator_reg = generator.allocate_register();
  599. generator.emit<Bytecode::Op::Load>(value_reg);
  600. generator.emit<Bytecode::Op::GetIterator>();
  601. generator.emit<Bytecode::Op::Store>(iterator_reg);
  602. bool first = true;
  603. auto temp_iterator_result_reg = generator.allocate_register();
  604. auto assign_accumulator_to_alias = [&](auto& alias) {
  605. alias.visit(
  606. [&](Empty) {
  607. // This element is an elision
  608. },
  609. [&](NonnullRefPtr<Identifier> const& identifier) {
  610. auto interned_index = generator.intern_identifier(identifier->string());
  611. generator.emit<Bytecode::Op::SetVariable>(interned_index);
  612. },
  613. [&](NonnullRefPtr<BindingPattern> const& pattern) {
  614. // Store the accumulator value in a permanent register
  615. auto target_reg = generator.allocate_register();
  616. generator.emit<Bytecode::Op::Store>(target_reg);
  617. generate_binding_pattern_bytecode(generator, pattern, target_reg);
  618. },
  619. [&](NonnullRefPtr<MemberExpression> const&) {
  620. TODO();
  621. });
  622. };
  623. for (auto& [name, alias, initializer, is_rest] : pattern.entries) {
  624. VERIFY(name.has<Empty>());
  625. if (is_rest) {
  626. if (first) {
  627. // The iterator has not been called, and is thus known to be not exhausted
  628. generator.emit<Bytecode::Op::Load>(iterator_reg);
  629. generator.emit<Bytecode::Op::IteratorToArray>();
  630. } else {
  631. auto& if_exhausted_block = generator.make_block();
  632. auto& if_not_exhausted_block = generator.make_block();
  633. auto& continuation_block = generator.make_block();
  634. generator.emit<Bytecode::Op::Load>(is_iterator_exhausted_register);
  635. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  636. Bytecode::Label { if_exhausted_block },
  637. Bytecode::Label { if_not_exhausted_block });
  638. generator.switch_to_basic_block(if_exhausted_block);
  639. generator.emit<Bytecode::Op::NewArray>();
  640. generator.emit<Bytecode::Op::Jump>().set_targets(
  641. Bytecode::Label { continuation_block },
  642. {});
  643. generator.switch_to_basic_block(if_not_exhausted_block);
  644. generator.emit<Bytecode::Op::Load>(iterator_reg);
  645. generator.emit<Bytecode::Op::IteratorToArray>();
  646. generator.emit<Bytecode::Op::Jump>().set_targets(
  647. Bytecode::Label { continuation_block },
  648. {});
  649. generator.switch_to_basic_block(continuation_block);
  650. }
  651. assign_accumulator_to_alias(alias);
  652. return;
  653. }
  654. // In the first iteration of the loop, a few things are true which can save
  655. // us some bytecode:
  656. // - the iterator result is still in the accumulator, so we can avoid a load
  657. // - the iterator is not yet exhausted, which can save us a jump and some
  658. // creation
  659. auto& iterator_is_exhausted_block = generator.make_block();
  660. if (!first) {
  661. auto& iterator_is_not_exhausted_block = generator.make_block();
  662. generator.emit<Bytecode::Op::Load>(is_iterator_exhausted_register);
  663. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  664. Bytecode::Label { iterator_is_exhausted_block },
  665. Bytecode::Label { iterator_is_not_exhausted_block });
  666. generator.switch_to_basic_block(iterator_is_not_exhausted_block);
  667. generator.emit<Bytecode::Op::Load>(iterator_reg);
  668. }
  669. generator.emit<Bytecode::Op::IteratorNext>();
  670. generator.emit<Bytecode::Op::Store>(temp_iterator_result_reg);
  671. generator.emit<Bytecode::Op::IteratorResultDone>();
  672. generator.emit<Bytecode::Op::Store>(is_iterator_exhausted_register);
  673. // We still have to check for exhaustion here. If the iterator is exhausted,
  674. // we need to bail before trying to get the value
  675. auto& no_bail_block = generator.make_block();
  676. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  677. Bytecode::Label { iterator_is_exhausted_block },
  678. Bytecode::Label { no_bail_block });
  679. generator.switch_to_basic_block(no_bail_block);
  680. // Get the next value in the iterator
  681. generator.emit<Bytecode::Op::Load>(temp_iterator_result_reg);
  682. generator.emit<Bytecode::Op::IteratorResultValue>();
  683. auto& create_binding_block = generator.make_block();
  684. generator.emit<Bytecode::Op::Jump>().set_targets(
  685. Bytecode::Label { create_binding_block },
  686. {});
  687. // The iterator is exhausted, so we just load undefined and continue binding
  688. generator.switch_to_basic_block(iterator_is_exhausted_block);
  689. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  690. generator.emit<Bytecode::Op::Jump>().set_targets(
  691. Bytecode::Label { create_binding_block },
  692. {});
  693. // Create the actual binding. The value which this entry must bind is now in the
  694. // accumulator. We can proceed, processing the alias as a nested destructuring
  695. // pattern if necessary.
  696. generator.switch_to_basic_block(create_binding_block);
  697. assign_accumulator_to_alias(alias);
  698. first = false;
  699. }
  700. }
  701. static void generate_binding_pattern_bytecode(Bytecode::Generator& generator, BindingPattern const& pattern, Bytecode::Register const& value_reg)
  702. {
  703. if (pattern.kind == BindingPattern::Kind::Object) {
  704. generate_object_binding_pattern_bytecode(generator, pattern, value_reg);
  705. } else {
  706. generate_array_binding_pattern_bytecode(generator, pattern, value_reg);
  707. }
  708. };
  709. void VariableDeclaration::generate_bytecode(Bytecode::Generator& generator) const
  710. {
  711. for (auto& declarator : m_declarations) {
  712. if (declarator.init())
  713. declarator.init()->generate_bytecode(generator);
  714. else
  715. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  716. declarator.target().visit(
  717. [&](NonnullRefPtr<Identifier> const& id) {
  718. generator.emit<Bytecode::Op::SetVariable>(generator.intern_identifier(id->string()));
  719. },
  720. [&](NonnullRefPtr<BindingPattern> const& pattern) {
  721. auto value_register = generator.allocate_register();
  722. generator.emit<Bytecode::Op::Store>(value_register);
  723. generate_binding_pattern_bytecode(generator, pattern, value_register);
  724. });
  725. }
  726. }
  727. void CallExpression::generate_bytecode(Bytecode::Generator& generator) const
  728. {
  729. auto callee_reg = generator.allocate_register();
  730. auto this_reg = generator.allocate_register();
  731. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  732. generator.emit<Bytecode::Op::Store>(this_reg);
  733. if (is<NewExpression>(this)) {
  734. m_callee->generate_bytecode(generator);
  735. generator.emit<Bytecode::Op::Store>(callee_reg);
  736. } else if (is<SuperExpression>(*m_callee)) {
  737. TODO();
  738. } else if (is<MemberExpression>(*m_callee)) {
  739. auto& member_expression = static_cast<const MemberExpression&>(*m_callee);
  740. if (is<SuperExpression>(member_expression.object())) {
  741. TODO();
  742. } else {
  743. member_expression.object().generate_bytecode(generator);
  744. generator.emit<Bytecode::Op::Store>(this_reg);
  745. if (member_expression.is_computed()) {
  746. member_expression.property().generate_bytecode(generator);
  747. generator.emit<Bytecode::Op::GetByValue>(this_reg);
  748. } else {
  749. auto identifier_table_ref = generator.intern_identifier(verify_cast<Identifier>(member_expression.property()).string());
  750. generator.emit<Bytecode::Op::GetById>(identifier_table_ref);
  751. }
  752. generator.emit<Bytecode::Op::Store>(callee_reg);
  753. }
  754. } else {
  755. // FIXME: this = global object in sloppy mode.
  756. m_callee->generate_bytecode(generator);
  757. generator.emit<Bytecode::Op::Store>(callee_reg);
  758. }
  759. Vector<Bytecode::Register> argument_registers;
  760. for (auto& arg : m_arguments) {
  761. arg.value->generate_bytecode(generator);
  762. auto arg_reg = generator.allocate_register();
  763. generator.emit<Bytecode::Op::Store>(arg_reg);
  764. argument_registers.append(arg_reg);
  765. }
  766. Bytecode::Op::Call::CallType call_type;
  767. if (is<NewExpression>(*this)) {
  768. call_type = Bytecode::Op::Call::CallType::Construct;
  769. } else {
  770. call_type = Bytecode::Op::Call::CallType::Call;
  771. }
  772. generator.emit_with_extra_register_slots<Bytecode::Op::Call>(argument_registers.size(), call_type, callee_reg, this_reg, argument_registers);
  773. }
  774. void ReturnStatement::generate_bytecode(Bytecode::Generator& generator) const
  775. {
  776. if (m_argument)
  777. m_argument->generate_bytecode(generator);
  778. if (generator.is_in_generator_or_async_function())
  779. generator.emit<Bytecode::Op::Yield>(nullptr);
  780. else
  781. generator.emit<Bytecode::Op::Return>();
  782. }
  783. void YieldExpression::generate_bytecode(Bytecode::Generator& generator) const
  784. {
  785. VERIFY(generator.is_in_generator_function());
  786. if (m_is_yield_from)
  787. TODO();
  788. if (m_argument)
  789. m_argument->generate_bytecode(generator);
  790. auto& continuation_block = generator.make_block();
  791. generator.emit<Bytecode::Op::Yield>(Bytecode::Label { continuation_block });
  792. generator.switch_to_basic_block(continuation_block);
  793. }
  794. void IfStatement::generate_bytecode(Bytecode::Generator& generator) const
  795. {
  796. // test
  797. // jump if_true (true) true (false) false
  798. // true
  799. // jump always (true) end
  800. // false
  801. // jump always (true) end
  802. // end
  803. auto& true_block = generator.make_block();
  804. auto& false_block = generator.make_block();
  805. m_predicate->generate_bytecode(generator);
  806. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  807. Bytecode::Label { true_block },
  808. Bytecode::Label { false_block });
  809. Bytecode::Op::Jump* true_block_jump { nullptr };
  810. generator.switch_to_basic_block(true_block);
  811. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  812. m_consequent->generate_bytecode(generator);
  813. if (!generator.is_current_block_terminated())
  814. true_block_jump = &generator.emit<Bytecode::Op::Jump>();
  815. generator.switch_to_basic_block(false_block);
  816. auto& end_block = generator.make_block();
  817. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  818. if (m_alternate)
  819. m_alternate->generate_bytecode(generator);
  820. if (!generator.is_current_block_terminated())
  821. generator.emit<Bytecode::Op::Jump>().set_targets(Bytecode::Label { end_block }, {});
  822. if (true_block_jump)
  823. true_block_jump->set_targets(Bytecode::Label { end_block }, {});
  824. generator.switch_to_basic_block(end_block);
  825. }
  826. void ContinueStatement::generate_bytecode(Bytecode::Generator& generator) const
  827. {
  828. generator.emit<Bytecode::Op::Jump>().set_targets(
  829. generator.nearest_continuable_scope(),
  830. {});
  831. }
  832. void DebuggerStatement::generate_bytecode(Bytecode::Generator&) const
  833. {
  834. }
  835. void ConditionalExpression::generate_bytecode(Bytecode::Generator& generator) const
  836. {
  837. // test
  838. // jump if_true (true) true (false) false
  839. // true
  840. // jump always (true) end
  841. // false
  842. // jump always (true) end
  843. // end
  844. auto& true_block = generator.make_block();
  845. auto& false_block = generator.make_block();
  846. auto& end_block = generator.make_block();
  847. m_test->generate_bytecode(generator);
  848. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  849. Bytecode::Label { true_block },
  850. Bytecode::Label { false_block });
  851. generator.switch_to_basic_block(true_block);
  852. m_consequent->generate_bytecode(generator);
  853. generator.emit<Bytecode::Op::Jump>().set_targets(
  854. Bytecode::Label { end_block },
  855. {});
  856. generator.switch_to_basic_block(false_block);
  857. m_alternate->generate_bytecode(generator);
  858. generator.emit<Bytecode::Op::Jump>().set_targets(
  859. Bytecode::Label { end_block },
  860. {});
  861. generator.switch_to_basic_block(end_block);
  862. }
  863. void SequenceExpression::generate_bytecode(Bytecode::Generator& generator) const
  864. {
  865. for (auto& expression : m_expressions)
  866. expression.generate_bytecode(generator);
  867. }
  868. void TemplateLiteral::generate_bytecode(Bytecode::Generator& generator) const
  869. {
  870. auto string_reg = generator.allocate_register();
  871. for (size_t i = 0; i < m_expressions.size(); i++) {
  872. m_expressions[i].generate_bytecode(generator);
  873. if (i == 0) {
  874. generator.emit<Bytecode::Op::Store>(string_reg);
  875. } else {
  876. generator.emit<Bytecode::Op::ConcatString>(string_reg);
  877. }
  878. }
  879. generator.emit<Bytecode::Op::Load>(string_reg);
  880. }
  881. void TaggedTemplateLiteral::generate_bytecode(Bytecode::Generator& generator) const
  882. {
  883. m_tag->generate_bytecode(generator);
  884. auto tag_reg = generator.allocate_register();
  885. generator.emit<Bytecode::Op::Store>(tag_reg);
  886. Vector<Bytecode::Register> string_regs;
  887. auto& expressions = m_template_literal->expressions();
  888. for (size_t i = 0; i < expressions.size(); ++i) {
  889. if (i % 2 != 0)
  890. continue;
  891. expressions[i].generate_bytecode(generator);
  892. auto string_reg = generator.allocate_register();
  893. generator.emit<Bytecode::Op::Store>(string_reg);
  894. string_regs.append(string_reg);
  895. }
  896. generator.emit_with_extra_register_slots<Bytecode::Op::NewArray>(string_regs.size(), string_regs);
  897. auto strings_reg = generator.allocate_register();
  898. generator.emit<Bytecode::Op::Store>(strings_reg);
  899. Vector<Bytecode::Register> argument_regs;
  900. argument_regs.append(strings_reg);
  901. for (size_t i = 0; i < expressions.size(); ++i) {
  902. if (i % 2 == 0)
  903. continue;
  904. expressions[i].generate_bytecode(generator);
  905. auto string_reg = generator.allocate_register();
  906. generator.emit<Bytecode::Op::Store>(string_reg);
  907. argument_regs.append(string_reg);
  908. }
  909. Vector<Bytecode::Register> raw_string_regs;
  910. for (auto& raw_string : m_template_literal->raw_strings()) {
  911. raw_string.generate_bytecode(generator);
  912. auto raw_string_reg = generator.allocate_register();
  913. generator.emit<Bytecode::Op::Store>(raw_string_reg);
  914. raw_string_regs.append(raw_string_reg);
  915. }
  916. generator.emit_with_extra_register_slots<Bytecode::Op::NewArray>(raw_string_regs.size(), raw_string_regs);
  917. auto raw_strings_reg = generator.allocate_register();
  918. generator.emit<Bytecode::Op::Store>(raw_strings_reg);
  919. generator.emit<Bytecode::Op::Load>(strings_reg);
  920. generator.emit<Bytecode::Op::PutById>(raw_strings_reg, generator.intern_identifier("raw"));
  921. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  922. auto this_reg = generator.allocate_register();
  923. generator.emit<Bytecode::Op::Store>(this_reg);
  924. generator.emit_with_extra_register_slots<Bytecode::Op::Call>(argument_regs.size(), Bytecode::Op::Call::CallType::Call, tag_reg, this_reg, move(argument_regs));
  925. }
  926. void UpdateExpression::generate_bytecode(Bytecode::Generator& generator) const
  927. {
  928. generator.emit_load_from_reference(*m_argument);
  929. Optional<Bytecode::Register> previous_value_for_postfix_reg;
  930. if (!m_prefixed) {
  931. previous_value_for_postfix_reg = generator.allocate_register();
  932. generator.emit<Bytecode::Op::Store>(*previous_value_for_postfix_reg);
  933. }
  934. if (m_op == UpdateOp::Increment)
  935. generator.emit<Bytecode::Op::Increment>();
  936. else
  937. generator.emit<Bytecode::Op::Decrement>();
  938. generator.emit_store_to_reference(*m_argument);
  939. if (!m_prefixed)
  940. generator.emit<Bytecode::Op::Load>(*previous_value_for_postfix_reg);
  941. }
  942. void ThrowStatement::generate_bytecode(Bytecode::Generator& generator) const
  943. {
  944. m_argument->generate_bytecode(generator);
  945. generator.emit<Bytecode::Op::Throw>();
  946. }
  947. void BreakStatement::generate_bytecode(Bytecode::Generator& generator) const
  948. {
  949. generator.emit<Bytecode::Op::Jump>().set_targets(
  950. generator.nearest_breakable_scope(),
  951. {});
  952. }
  953. void TryStatement::generate_bytecode(Bytecode::Generator& generator) const
  954. {
  955. auto& saved_block = generator.current_block();
  956. Optional<Bytecode::Label> handler_target;
  957. Optional<Bytecode::Label> finalizer_target;
  958. Bytecode::BasicBlock* next_block { nullptr };
  959. if (m_finalizer) {
  960. auto& finalizer_block = generator.make_block();
  961. generator.switch_to_basic_block(finalizer_block);
  962. m_finalizer->generate_bytecode(generator);
  963. if (!generator.is_current_block_terminated()) {
  964. next_block = &generator.make_block();
  965. auto next_target = Bytecode::Label { *next_block };
  966. generator.emit<Bytecode::Op::ContinuePendingUnwind>(next_target);
  967. }
  968. finalizer_target = Bytecode::Label { finalizer_block };
  969. }
  970. if (m_handler) {
  971. auto& handler_block = generator.make_block();
  972. generator.switch_to_basic_block(handler_block);
  973. m_handler->parameter().visit(
  974. [&](FlyString const& parameter) {
  975. if (!parameter.is_empty()) {
  976. // FIXME: We need a separate DeclarativeEnvironment here
  977. generator.emit<Bytecode::Op::SetVariable>(generator.intern_identifier(parameter));
  978. }
  979. },
  980. [&](NonnullRefPtr<BindingPattern> const&) {
  981. // FIXME: Implement this path when the above DeclarativeEnvironment issue is dealt with.
  982. TODO();
  983. });
  984. m_handler->body().generate_bytecode(generator);
  985. handler_target = Bytecode::Label { handler_block };
  986. if (!generator.is_current_block_terminated()) {
  987. if (m_finalizer) {
  988. generator.emit<Bytecode::Op::LeaveUnwindContext>();
  989. generator.emit<Bytecode::Op::Jump>(finalizer_target);
  990. } else {
  991. VERIFY(!next_block);
  992. next_block = &generator.make_block();
  993. auto next_target = Bytecode::Label { *next_block };
  994. generator.emit<Bytecode::Op::Jump>(next_target);
  995. }
  996. }
  997. }
  998. auto& target_block = generator.make_block();
  999. generator.switch_to_basic_block(saved_block);
  1000. generator.emit<Bytecode::Op::EnterUnwindContext>(Bytecode::Label { target_block }, handler_target, finalizer_target);
  1001. generator.switch_to_basic_block(target_block);
  1002. m_block->generate_bytecode(generator);
  1003. if (!generator.is_current_block_terminated()) {
  1004. if (m_finalizer) {
  1005. generator.emit<Bytecode::Op::Jump>(finalizer_target);
  1006. } else {
  1007. auto& block = generator.make_block();
  1008. generator.emit<Bytecode::Op::FinishUnwind>(Bytecode::Label { block });
  1009. next_block = &block;
  1010. }
  1011. }
  1012. generator.switch_to_basic_block(next_block ? *next_block : saved_block);
  1013. }
  1014. void SwitchStatement::generate_bytecode(Bytecode::Generator& generator) const
  1015. {
  1016. auto discriminant_reg = generator.allocate_register();
  1017. m_discriminant->generate_bytecode(generator);
  1018. generator.emit<Bytecode::Op::Store>(discriminant_reg);
  1019. Vector<Bytecode::BasicBlock&> case_blocks;
  1020. Bytecode::BasicBlock* default_block { nullptr };
  1021. Bytecode::BasicBlock* next_test_block = &generator.make_block();
  1022. generator.emit<Bytecode::Op::Jump>().set_targets(Bytecode::Label { *next_test_block }, {});
  1023. for (auto& switch_case : m_cases) {
  1024. auto& case_block = generator.make_block();
  1025. if (switch_case.test()) {
  1026. generator.switch_to_basic_block(*next_test_block);
  1027. switch_case.test()->generate_bytecode(generator);
  1028. generator.emit<Bytecode::Op::StrictlyEquals>(discriminant_reg);
  1029. next_test_block = &generator.make_block();
  1030. generator.emit<Bytecode::Op::JumpConditional>().set_targets(Bytecode::Label { case_block }, Bytecode::Label { *next_test_block });
  1031. } else {
  1032. default_block = &case_block;
  1033. }
  1034. case_blocks.append(case_block);
  1035. }
  1036. generator.switch_to_basic_block(*next_test_block);
  1037. auto& end_block = generator.make_block();
  1038. if (default_block != nullptr) {
  1039. generator.emit<Bytecode::Op::Jump>().set_targets(Bytecode::Label { *default_block }, {});
  1040. } else {
  1041. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  1042. generator.emit<Bytecode::Op::Jump>().set_targets(Bytecode::Label { end_block }, {});
  1043. }
  1044. auto current_block = case_blocks.begin();
  1045. generator.begin_breakable_scope(Bytecode::Label { end_block });
  1046. for (auto& switch_case : m_cases) {
  1047. generator.switch_to_basic_block(*current_block);
  1048. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  1049. for (auto& statement : switch_case.children()) {
  1050. statement.generate_bytecode(generator);
  1051. }
  1052. if (!generator.is_current_block_terminated()) {
  1053. auto next_block = current_block;
  1054. next_block++;
  1055. if (next_block.is_end()) {
  1056. generator.emit<Bytecode::Op::Jump>().set_targets(Bytecode::Label { end_block }, {});
  1057. } else {
  1058. generator.emit<Bytecode::Op::Jump>().set_targets(Bytecode::Label { *next_block }, {});
  1059. }
  1060. }
  1061. current_block++;
  1062. }
  1063. generator.end_breakable_scope();
  1064. generator.switch_to_basic_block(end_block);
  1065. }
  1066. void ClassDeclaration::generate_bytecode(Bytecode::Generator& generator) const
  1067. {
  1068. generator.emit<Bytecode::Op::NewClass>(m_class_expression);
  1069. generator.emit<Bytecode::Op::SetVariable>(generator.intern_identifier(m_class_expression.ptr()->name()));
  1070. }
  1071. void ThisExpression::generate_bytecode(Bytecode::Generator& generator) const
  1072. {
  1073. generator.emit<Bytecode::Op::ResolveThisBinding>();
  1074. }
  1075. void AwaitExpression::generate_bytecode(Bytecode::Generator& generator) const
  1076. {
  1077. VERIFY(generator.is_in_async_function());
  1078. // Transform `await expr` to `yield expr`
  1079. m_argument->generate_bytecode(generator);
  1080. auto& continuation_block = generator.make_block();
  1081. generator.emit<Bytecode::Op::Yield>(Bytecode::Label { continuation_block });
  1082. generator.switch_to_basic_block(continuation_block);
  1083. }
  1084. }