ASTCodegen.cpp 21 KB

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