ASTCodegen.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  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. *
  6. * SPDX-License-Identifier: BSD-2-Clause
  7. */
  8. #include <LibJS/AST.h>
  9. #include <LibJS/Bytecode/Generator.h>
  10. #include <LibJS/Bytecode/Instruction.h>
  11. #include <LibJS/Bytecode/Op.h>
  12. #include <LibJS/Bytecode/Register.h>
  13. namespace JS {
  14. void ASTNode::generate_bytecode(Bytecode::Generator&) const
  15. {
  16. dbgln("Missing generate_bytecode() in {}", class_name());
  17. TODO();
  18. }
  19. void ScopeNode::generate_bytecode(Bytecode::Generator& generator) const
  20. {
  21. generator.emit<Bytecode::Op::EnterScope>(*this);
  22. for (auto& child : children())
  23. child.generate_bytecode(generator);
  24. }
  25. void EmptyStatement::generate_bytecode(Bytecode::Generator&) const
  26. {
  27. }
  28. void ExpressionStatement::generate_bytecode(Bytecode::Generator& generator) const
  29. {
  30. m_expression->generate_bytecode(generator);
  31. }
  32. void BinaryExpression::generate_bytecode(Bytecode::Generator& generator) const
  33. {
  34. m_lhs->generate_bytecode(generator);
  35. auto lhs_reg = generator.allocate_register();
  36. generator.emit<Bytecode::Op::Store>(lhs_reg);
  37. m_rhs->generate_bytecode(generator);
  38. switch (m_op) {
  39. case BinaryOp::Addition:
  40. generator.emit<Bytecode::Op::Add>(lhs_reg);
  41. break;
  42. case BinaryOp::Subtraction:
  43. generator.emit<Bytecode::Op::Sub>(lhs_reg);
  44. break;
  45. case BinaryOp::Multiplication:
  46. generator.emit<Bytecode::Op::Mul>(lhs_reg);
  47. break;
  48. case BinaryOp::Division:
  49. generator.emit<Bytecode::Op::Div>(lhs_reg);
  50. break;
  51. case BinaryOp::Modulo:
  52. generator.emit<Bytecode::Op::Mod>(lhs_reg);
  53. break;
  54. case BinaryOp::Exponentiation:
  55. generator.emit<Bytecode::Op::Exp>(lhs_reg);
  56. break;
  57. case BinaryOp::GreaterThan:
  58. generator.emit<Bytecode::Op::GreaterThan>(lhs_reg);
  59. break;
  60. case BinaryOp::GreaterThanEquals:
  61. generator.emit<Bytecode::Op::GreaterThanEquals>(lhs_reg);
  62. break;
  63. case BinaryOp::LessThan:
  64. generator.emit<Bytecode::Op::LessThan>(lhs_reg);
  65. break;
  66. case BinaryOp::LessThanEquals:
  67. generator.emit<Bytecode::Op::LessThanEquals>(lhs_reg);
  68. break;
  69. case BinaryOp::AbstractInequals:
  70. generator.emit<Bytecode::Op::AbstractInequals>(lhs_reg);
  71. break;
  72. case BinaryOp::AbstractEquals:
  73. generator.emit<Bytecode::Op::AbstractEquals>(lhs_reg);
  74. break;
  75. case BinaryOp::TypedInequals:
  76. generator.emit<Bytecode::Op::TypedInequals>(lhs_reg);
  77. break;
  78. case BinaryOp::TypedEquals:
  79. generator.emit<Bytecode::Op::TypedEquals>(lhs_reg);
  80. break;
  81. case BinaryOp::BitwiseAnd:
  82. generator.emit<Bytecode::Op::BitwiseAnd>(lhs_reg);
  83. break;
  84. case BinaryOp::BitwiseOr:
  85. generator.emit<Bytecode::Op::BitwiseOr>(lhs_reg);
  86. break;
  87. case BinaryOp::BitwiseXor:
  88. generator.emit<Bytecode::Op::BitwiseXor>(lhs_reg);
  89. break;
  90. case BinaryOp::LeftShift:
  91. generator.emit<Bytecode::Op::LeftShift>(lhs_reg);
  92. break;
  93. case BinaryOp::RightShift:
  94. generator.emit<Bytecode::Op::RightShift>(lhs_reg);
  95. break;
  96. case BinaryOp::UnsignedRightShift:
  97. generator.emit<Bytecode::Op::UnsignedRightShift>(lhs_reg);
  98. break;
  99. case BinaryOp::In:
  100. generator.emit<Bytecode::Op::In>(lhs_reg);
  101. break;
  102. case BinaryOp::InstanceOf:
  103. generator.emit<Bytecode::Op::InstanceOf>(lhs_reg);
  104. break;
  105. default:
  106. VERIFY_NOT_REACHED();
  107. }
  108. }
  109. void LogicalExpression::generate_bytecode(Bytecode::Generator& generator) const
  110. {
  111. m_lhs->generate_bytecode(generator);
  112. // lhs
  113. // jump op (true) end (false) rhs
  114. // rhs
  115. // jump always (true) end
  116. // end
  117. auto& rhs_block = generator.make_block();
  118. auto& end_block = generator.make_block();
  119. switch (m_op) {
  120. case LogicalOp::And:
  121. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  122. Bytecode::Label { rhs_block },
  123. Bytecode::Label { end_block });
  124. break;
  125. case LogicalOp::Or:
  126. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  127. Bytecode::Label { end_block },
  128. Bytecode::Label { rhs_block });
  129. break;
  130. case LogicalOp::NullishCoalescing:
  131. generator.emit<Bytecode::Op::JumpNullish>().set_targets(
  132. Bytecode::Label { rhs_block },
  133. Bytecode::Label { end_block });
  134. break;
  135. default:
  136. VERIFY_NOT_REACHED();
  137. }
  138. generator.switch_to_basic_block(rhs_block);
  139. m_rhs->generate_bytecode(generator);
  140. generator.emit<Bytecode::Op::Jump>().set_targets(
  141. Bytecode::Label { end_block },
  142. {});
  143. generator.switch_to_basic_block(end_block);
  144. }
  145. void UnaryExpression::generate_bytecode(Bytecode::Generator& generator) const
  146. {
  147. m_lhs->generate_bytecode(generator);
  148. switch (m_op) {
  149. case UnaryOp::BitwiseNot:
  150. generator.emit<Bytecode::Op::BitwiseNot>();
  151. break;
  152. case UnaryOp::Not:
  153. generator.emit<Bytecode::Op::Not>();
  154. break;
  155. case UnaryOp::Plus:
  156. generator.emit<Bytecode::Op::UnaryPlus>();
  157. break;
  158. case UnaryOp::Minus:
  159. generator.emit<Bytecode::Op::UnaryMinus>();
  160. break;
  161. case UnaryOp::Typeof:
  162. generator.emit<Bytecode::Op::Typeof>();
  163. break;
  164. case UnaryOp::Void:
  165. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  166. break;
  167. default:
  168. TODO();
  169. }
  170. }
  171. void NumericLiteral::generate_bytecode(Bytecode::Generator& generator) const
  172. {
  173. generator.emit<Bytecode::Op::LoadImmediate>(m_value);
  174. }
  175. void BooleanLiteral::generate_bytecode(Bytecode::Generator& generator) const
  176. {
  177. generator.emit<Bytecode::Op::LoadImmediate>(Value(m_value));
  178. }
  179. void NullLiteral::generate_bytecode(Bytecode::Generator& generator) const
  180. {
  181. generator.emit<Bytecode::Op::LoadImmediate>(js_null());
  182. }
  183. void BigIntLiteral::generate_bytecode(Bytecode::Generator& generator) const
  184. {
  185. generator.emit<Bytecode::Op::NewBigInt>(Crypto::SignedBigInteger::from_base10(m_value.substring(0, m_value.length() - 1)));
  186. }
  187. void StringLiteral::generate_bytecode(Bytecode::Generator& generator) const
  188. {
  189. generator.emit<Bytecode::Op::NewString>(generator.intern_string(m_value));
  190. }
  191. void Identifier::generate_bytecode(Bytecode::Generator& generator) const
  192. {
  193. generator.emit<Bytecode::Op::GetVariable>(generator.intern_string(m_string));
  194. }
  195. void AssignmentExpression::generate_bytecode(Bytecode::Generator& generator) const
  196. {
  197. if (is<Identifier>(*m_lhs)) {
  198. auto& identifier = static_cast<Identifier const&>(*m_lhs);
  199. if (m_op == AssignmentOp::Assignment) {
  200. m_rhs->generate_bytecode(generator);
  201. generator.emit<Bytecode::Op::SetVariable>(generator.intern_string(identifier.string()));
  202. return;
  203. }
  204. m_lhs->generate_bytecode(generator);
  205. auto lhs_reg = generator.allocate_register();
  206. generator.emit<Bytecode::Op::Store>(lhs_reg);
  207. m_rhs->generate_bytecode(generator);
  208. switch (m_op) {
  209. case AssignmentOp::AdditionAssignment:
  210. generator.emit<Bytecode::Op::Add>(lhs_reg);
  211. break;
  212. case AssignmentOp::SubtractionAssignment:
  213. generator.emit<Bytecode::Op::Sub>(lhs_reg);
  214. break;
  215. case AssignmentOp::MultiplicationAssignment:
  216. generator.emit<Bytecode::Op::Mul>(lhs_reg);
  217. break;
  218. case AssignmentOp::DivisionAssignment:
  219. generator.emit<Bytecode::Op::Div>(lhs_reg);
  220. break;
  221. case AssignmentOp::ModuloAssignment:
  222. generator.emit<Bytecode::Op::Mod>(lhs_reg);
  223. break;
  224. case AssignmentOp::ExponentiationAssignment:
  225. generator.emit<Bytecode::Op::Exp>(lhs_reg);
  226. break;
  227. case AssignmentOp::BitwiseAndAssignment:
  228. generator.emit<Bytecode::Op::BitwiseAnd>(lhs_reg);
  229. break;
  230. case AssignmentOp::BitwiseOrAssignment:
  231. generator.emit<Bytecode::Op::BitwiseOr>(lhs_reg);
  232. break;
  233. case AssignmentOp::BitwiseXorAssignment:
  234. generator.emit<Bytecode::Op::BitwiseXor>(lhs_reg);
  235. break;
  236. case AssignmentOp::LeftShiftAssignment:
  237. generator.emit<Bytecode::Op::LeftShift>(lhs_reg);
  238. break;
  239. case AssignmentOp::RightShiftAssignment:
  240. generator.emit<Bytecode::Op::RightShift>(lhs_reg);
  241. break;
  242. case AssignmentOp::UnsignedRightShiftAssignment:
  243. generator.emit<Bytecode::Op::UnsignedRightShift>(lhs_reg);
  244. break;
  245. default:
  246. TODO();
  247. }
  248. generator.emit<Bytecode::Op::SetVariable>(generator.intern_string(identifier.string()));
  249. return;
  250. }
  251. if (is<MemberExpression>(*m_lhs)) {
  252. auto& expression = static_cast<MemberExpression const&>(*m_lhs);
  253. expression.object().generate_bytecode(generator);
  254. auto object_reg = generator.allocate_register();
  255. generator.emit<Bytecode::Op::Store>(object_reg);
  256. if (expression.is_computed()) {
  257. TODO();
  258. } else {
  259. VERIFY(is<Identifier>(expression.property()));
  260. m_rhs->generate_bytecode(generator);
  261. auto identifier_table_ref = generator.intern_string(static_cast<Identifier const&>(expression.property()).string());
  262. generator.emit<Bytecode::Op::PutById>(object_reg, identifier_table_ref);
  263. return;
  264. }
  265. }
  266. TODO();
  267. }
  268. void WhileStatement::generate_bytecode(Bytecode::Generator& generator) const
  269. {
  270. // test
  271. // jump if_false (true) end (false) body
  272. // body
  273. // jump always (true) test
  274. // end
  275. auto& test_block = generator.make_block();
  276. auto& body_block = generator.make_block();
  277. auto& end_block = generator.make_block();
  278. // Init result register
  279. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  280. auto result_reg = generator.allocate_register();
  281. generator.emit<Bytecode::Op::Store>(result_reg);
  282. // jump to the test block
  283. generator.emit<Bytecode::Op::Jump>().set_targets(
  284. Bytecode::Label { test_block },
  285. {});
  286. generator.switch_to_basic_block(test_block);
  287. m_test->generate_bytecode(generator);
  288. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  289. Bytecode::Label { body_block },
  290. Bytecode::Label { end_block });
  291. generator.switch_to_basic_block(body_block);
  292. generator.begin_continuable_scope(Bytecode::Label { test_block });
  293. m_body->generate_bytecode(generator);
  294. generator.emit<Bytecode::Op::Jump>().set_targets(
  295. Bytecode::Label { test_block },
  296. {});
  297. generator.end_continuable_scope();
  298. generator.switch_to_basic_block(end_block);
  299. generator.emit<Bytecode::Op::Load>(result_reg);
  300. }
  301. void DoWhileStatement::generate_bytecode(Bytecode::Generator& generator) const
  302. {
  303. // jump always (true) body
  304. // test
  305. // jump if_false (true) end (false) body
  306. // body
  307. // jump always (true) test
  308. // end
  309. auto& test_block = generator.make_block();
  310. auto& body_block = generator.make_block();
  311. auto& end_block = generator.make_block();
  312. // Init result register
  313. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  314. auto result_reg = generator.allocate_register();
  315. generator.emit<Bytecode::Op::Store>(result_reg);
  316. // jump to the body block
  317. generator.emit<Bytecode::Op::Jump>().set_targets(
  318. Bytecode::Label { body_block },
  319. {});
  320. generator.switch_to_basic_block(test_block);
  321. m_test->generate_bytecode(generator);
  322. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  323. Bytecode::Label { body_block },
  324. Bytecode::Label { end_block });
  325. generator.switch_to_basic_block(body_block);
  326. generator.begin_continuable_scope(Bytecode::Label { test_block });
  327. m_body->generate_bytecode(generator);
  328. generator.emit<Bytecode::Op::Jump>().set_targets(
  329. Bytecode::Label { test_block },
  330. {});
  331. generator.end_continuable_scope();
  332. generator.switch_to_basic_block(end_block);
  333. generator.emit<Bytecode::Op::Load>(result_reg);
  334. }
  335. void ForStatement::generate_bytecode(Bytecode::Generator& generator) const
  336. {
  337. // init
  338. // jump always (true) test
  339. // test
  340. // jump if_true (true) body (false) end
  341. // body
  342. // jump always (true) update
  343. // update
  344. // jump always (true) test
  345. // end
  346. // If 'test' is missing, fuse the 'test' and 'body' basic blocks
  347. // If 'update' is missing, fuse the 'body' and 'update' basic blocks
  348. Bytecode::BasicBlock* test_block_ptr { nullptr };
  349. Bytecode::BasicBlock* body_block_ptr { nullptr };
  350. Bytecode::BasicBlock* update_block_ptr { nullptr };
  351. auto& end_block = generator.make_block();
  352. if (m_init)
  353. m_init->generate_bytecode(generator);
  354. body_block_ptr = &generator.make_block();
  355. if (m_test)
  356. test_block_ptr = &generator.make_block();
  357. else
  358. test_block_ptr = body_block_ptr;
  359. if (m_update)
  360. update_block_ptr = &generator.make_block();
  361. else
  362. update_block_ptr = body_block_ptr;
  363. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  364. auto result_reg = generator.allocate_register();
  365. generator.emit<Bytecode::Op::Store>(result_reg);
  366. generator.emit<Bytecode::Op::Jump>().set_targets(
  367. Bytecode::Label { *test_block_ptr },
  368. {});
  369. if (m_test) {
  370. generator.switch_to_basic_block(*test_block_ptr);
  371. m_test->generate_bytecode(generator);
  372. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  373. Bytecode::Label { *body_block_ptr },
  374. Bytecode::Label { end_block });
  375. }
  376. generator.switch_to_basic_block(*body_block_ptr);
  377. generator.begin_continuable_scope(Bytecode::Label { *update_block_ptr });
  378. m_body->generate_bytecode(generator);
  379. generator.end_continuable_scope();
  380. if (m_update) {
  381. generator.emit<Bytecode::Op::Jump>().set_targets(
  382. Bytecode::Label { *update_block_ptr },
  383. {});
  384. generator.switch_to_basic_block(*update_block_ptr);
  385. m_update->generate_bytecode(generator);
  386. }
  387. generator.emit<Bytecode::Op::Jump>().set_targets(
  388. Bytecode::Label { *test_block_ptr },
  389. {});
  390. generator.switch_to_basic_block(end_block);
  391. generator.emit<Bytecode::Op::Load>(result_reg);
  392. }
  393. void ObjectExpression::generate_bytecode(Bytecode::Generator& generator) const
  394. {
  395. generator.emit<Bytecode::Op::NewObject>();
  396. if (!m_properties.is_empty())
  397. TODO();
  398. }
  399. void ArrayExpression::generate_bytecode(Bytecode::Generator& generator) const
  400. {
  401. Vector<Bytecode::Register> element_regs;
  402. for (auto& element : m_elements) {
  403. if (element) {
  404. element->generate_bytecode(generator);
  405. if (is<SpreadExpression>(*element)) {
  406. TODO();
  407. continue;
  408. }
  409. } else {
  410. generator.emit<Bytecode::Op::LoadImmediate>(Value {});
  411. }
  412. auto element_reg = generator.allocate_register();
  413. generator.emit<Bytecode::Op::Store>(element_reg);
  414. element_regs.append(element_reg);
  415. }
  416. generator.emit_with_extra_register_slots<Bytecode::Op::NewArray>(element_regs.size(), element_regs);
  417. }
  418. void MemberExpression::generate_bytecode(Bytecode::Generator& generator) const
  419. {
  420. object().generate_bytecode(generator);
  421. if (is_computed()) {
  422. TODO();
  423. } else {
  424. VERIFY(is<Identifier>(property()));
  425. auto identifier_table_ref = generator.intern_string(static_cast<Identifier const&>(property()).string());
  426. generator.emit<Bytecode::Op::GetById>(identifier_table_ref);
  427. }
  428. }
  429. void FunctionDeclaration::generate_bytecode(Bytecode::Generator&) const
  430. {
  431. }
  432. void CallExpression::generate_bytecode(Bytecode::Generator& generator) const
  433. {
  434. m_callee->generate_bytecode(generator);
  435. auto callee_reg = generator.allocate_register();
  436. generator.emit<Bytecode::Op::Store>(callee_reg);
  437. // FIXME: Load the correct 'this' value into 'this_reg'.
  438. auto this_reg = generator.allocate_register();
  439. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  440. generator.emit<Bytecode::Op::Store>(this_reg);
  441. Vector<Bytecode::Register> argument_registers;
  442. for (auto& arg : m_arguments) {
  443. arg.value->generate_bytecode(generator);
  444. auto arg_reg = generator.allocate_register();
  445. generator.emit<Bytecode::Op::Store>(arg_reg);
  446. argument_registers.append(arg_reg);
  447. }
  448. generator.emit_with_extra_register_slots<Bytecode::Op::Call>(argument_registers.size(), callee_reg, this_reg, argument_registers);
  449. }
  450. void ReturnStatement::generate_bytecode(Bytecode::Generator& generator) const
  451. {
  452. if (m_argument)
  453. m_argument->generate_bytecode(generator);
  454. generator.emit<Bytecode::Op::Return>();
  455. }
  456. void IfStatement::generate_bytecode(Bytecode::Generator& generator) const
  457. {
  458. // test
  459. // jump if_true (true) true (false) false
  460. // true
  461. // jump always (true) end
  462. // false
  463. // jump always (true) end
  464. // end
  465. // If the 'false' branch doesn't exist, we're just gonna substitute it for 'end' and elide the last two entries above.
  466. auto& true_block = generator.make_block();
  467. auto& false_block = generator.make_block();
  468. m_predicate->generate_bytecode(generator);
  469. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  470. Bytecode::Label { true_block },
  471. Bytecode::Label { false_block });
  472. Bytecode::Op::Jump* true_block_jump { nullptr };
  473. generator.switch_to_basic_block(true_block);
  474. m_consequent->generate_bytecode(generator);
  475. if (!generator.is_current_block_terminated())
  476. true_block_jump = &generator.emit<Bytecode::Op::Jump>();
  477. generator.switch_to_basic_block(false_block);
  478. if (m_alternate) {
  479. auto& end_block = generator.make_block();
  480. m_alternate->generate_bytecode(generator);
  481. if (!generator.is_current_block_terminated())
  482. generator.emit<Bytecode::Op::Jump>().set_targets(
  483. Bytecode::Label { end_block },
  484. {});
  485. if (true_block_jump)
  486. true_block_jump->set_targets(
  487. Bytecode::Label { end_block },
  488. {});
  489. generator.switch_to_basic_block(end_block);
  490. } else {
  491. if (true_block_jump)
  492. true_block_jump->set_targets(
  493. Bytecode::Label { false_block },
  494. {});
  495. }
  496. }
  497. void ContinueStatement::generate_bytecode(Bytecode::Generator& generator) const
  498. {
  499. generator.emit<Bytecode::Op::Jump>().set_targets(
  500. generator.nearest_continuable_scope(),
  501. {});
  502. }
  503. void DebuggerStatement::generate_bytecode(Bytecode::Generator&) const
  504. {
  505. }
  506. void ConditionalExpression::generate_bytecode(Bytecode::Generator& generator) const
  507. {
  508. // test
  509. // jump if_true (true) true (false) false
  510. // true
  511. // jump always (true) end
  512. // false
  513. // jump always (true) end
  514. // end
  515. auto& true_block = generator.make_block();
  516. auto& false_block = generator.make_block();
  517. auto& end_block = generator.make_block();
  518. m_test->generate_bytecode(generator);
  519. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  520. Bytecode::Label { true_block },
  521. Bytecode::Label { false_block });
  522. generator.switch_to_basic_block(true_block);
  523. m_consequent->generate_bytecode(generator);
  524. generator.emit<Bytecode::Op::Jump>().set_targets(
  525. Bytecode::Label { end_block },
  526. {});
  527. generator.switch_to_basic_block(false_block);
  528. m_alternate->generate_bytecode(generator);
  529. generator.emit<Bytecode::Op::Jump>().set_targets(
  530. Bytecode::Label { end_block },
  531. {});
  532. generator.switch_to_basic_block(end_block);
  533. }
  534. void SequenceExpression::generate_bytecode(Bytecode::Generator& generator) const
  535. {
  536. for (auto& expression : m_expressions)
  537. expression.generate_bytecode(generator);
  538. }
  539. void TemplateLiteral::generate_bytecode(Bytecode::Generator& generator) const
  540. {
  541. auto string_reg = generator.allocate_register();
  542. for (size_t i = 0; i < m_expressions.size(); i++) {
  543. m_expressions[i].generate_bytecode(generator);
  544. if (i == 0) {
  545. generator.emit<Bytecode::Op::Store>(string_reg);
  546. } else {
  547. generator.emit<Bytecode::Op::ConcatString>(string_reg);
  548. }
  549. }
  550. }
  551. void UpdateExpression::generate_bytecode(Bytecode::Generator& generator) const
  552. {
  553. if (is<Identifier>(*m_argument)) {
  554. auto& identifier = static_cast<Identifier const&>(*m_argument);
  555. generator.emit<Bytecode::Op::GetVariable>(generator.intern_string(identifier.string()));
  556. Optional<Bytecode::Register> previous_value_for_postfix_reg;
  557. if (!m_prefixed) {
  558. previous_value_for_postfix_reg = generator.allocate_register();
  559. generator.emit<Bytecode::Op::Store>(*previous_value_for_postfix_reg);
  560. }
  561. if (m_op == UpdateOp::Increment)
  562. generator.emit<Bytecode::Op::Increment>();
  563. else
  564. generator.emit<Bytecode::Op::Decrement>();
  565. generator.emit<Bytecode::Op::SetVariable>(generator.intern_string(identifier.string()));
  566. if (!m_prefixed)
  567. generator.emit<Bytecode::Op::Load>(*previous_value_for_postfix_reg);
  568. return;
  569. }
  570. TODO();
  571. }
  572. void ThrowStatement::generate_bytecode(Bytecode::Generator& generator) const
  573. {
  574. m_argument->generate_bytecode(generator);
  575. generator.emit<Bytecode::Op::Throw>();
  576. }
  577. }