ASTCodegen.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859
  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. if (generator.is_current_block_terminated())
  25. break;
  26. }
  27. }
  28. void EmptyStatement::generate_bytecode(Bytecode::Generator&) const
  29. {
  30. }
  31. void ExpressionStatement::generate_bytecode(Bytecode::Generator& generator) const
  32. {
  33. m_expression->generate_bytecode(generator);
  34. }
  35. void BinaryExpression::generate_bytecode(Bytecode::Generator& generator) const
  36. {
  37. m_lhs->generate_bytecode(generator);
  38. auto lhs_reg = generator.allocate_register();
  39. generator.emit<Bytecode::Op::Store>(lhs_reg);
  40. m_rhs->generate_bytecode(generator);
  41. switch (m_op) {
  42. case BinaryOp::Addition:
  43. generator.emit<Bytecode::Op::Add>(lhs_reg);
  44. break;
  45. case BinaryOp::Subtraction:
  46. generator.emit<Bytecode::Op::Sub>(lhs_reg);
  47. break;
  48. case BinaryOp::Multiplication:
  49. generator.emit<Bytecode::Op::Mul>(lhs_reg);
  50. break;
  51. case BinaryOp::Division:
  52. generator.emit<Bytecode::Op::Div>(lhs_reg);
  53. break;
  54. case BinaryOp::Modulo:
  55. generator.emit<Bytecode::Op::Mod>(lhs_reg);
  56. break;
  57. case BinaryOp::Exponentiation:
  58. generator.emit<Bytecode::Op::Exp>(lhs_reg);
  59. break;
  60. case BinaryOp::GreaterThan:
  61. generator.emit<Bytecode::Op::GreaterThan>(lhs_reg);
  62. break;
  63. case BinaryOp::GreaterThanEquals:
  64. generator.emit<Bytecode::Op::GreaterThanEquals>(lhs_reg);
  65. break;
  66. case BinaryOp::LessThan:
  67. generator.emit<Bytecode::Op::LessThan>(lhs_reg);
  68. break;
  69. case BinaryOp::LessThanEquals:
  70. generator.emit<Bytecode::Op::LessThanEquals>(lhs_reg);
  71. break;
  72. case BinaryOp::AbstractInequals:
  73. generator.emit<Bytecode::Op::AbstractInequals>(lhs_reg);
  74. break;
  75. case BinaryOp::AbstractEquals:
  76. generator.emit<Bytecode::Op::AbstractEquals>(lhs_reg);
  77. break;
  78. case BinaryOp::TypedInequals:
  79. generator.emit<Bytecode::Op::TypedInequals>(lhs_reg);
  80. break;
  81. case BinaryOp::TypedEquals:
  82. generator.emit<Bytecode::Op::TypedEquals>(lhs_reg);
  83. break;
  84. case BinaryOp::BitwiseAnd:
  85. generator.emit<Bytecode::Op::BitwiseAnd>(lhs_reg);
  86. break;
  87. case BinaryOp::BitwiseOr:
  88. generator.emit<Bytecode::Op::BitwiseOr>(lhs_reg);
  89. break;
  90. case BinaryOp::BitwiseXor:
  91. generator.emit<Bytecode::Op::BitwiseXor>(lhs_reg);
  92. break;
  93. case BinaryOp::LeftShift:
  94. generator.emit<Bytecode::Op::LeftShift>(lhs_reg);
  95. break;
  96. case BinaryOp::RightShift:
  97. generator.emit<Bytecode::Op::RightShift>(lhs_reg);
  98. break;
  99. case BinaryOp::UnsignedRightShift:
  100. generator.emit<Bytecode::Op::UnsignedRightShift>(lhs_reg);
  101. break;
  102. case BinaryOp::In:
  103. generator.emit<Bytecode::Op::In>(lhs_reg);
  104. break;
  105. case BinaryOp::InstanceOf:
  106. generator.emit<Bytecode::Op::InstanceOf>(lhs_reg);
  107. break;
  108. default:
  109. VERIFY_NOT_REACHED();
  110. }
  111. }
  112. void LogicalExpression::generate_bytecode(Bytecode::Generator& generator) const
  113. {
  114. m_lhs->generate_bytecode(generator);
  115. // lhs
  116. // jump op (true) end (false) rhs
  117. // rhs
  118. // jump always (true) end
  119. // end
  120. auto& rhs_block = generator.make_block();
  121. auto& end_block = generator.make_block();
  122. switch (m_op) {
  123. case LogicalOp::And:
  124. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  125. Bytecode::Label { rhs_block },
  126. Bytecode::Label { end_block });
  127. break;
  128. case LogicalOp::Or:
  129. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  130. Bytecode::Label { end_block },
  131. Bytecode::Label { rhs_block });
  132. break;
  133. case LogicalOp::NullishCoalescing:
  134. generator.emit<Bytecode::Op::JumpNullish>().set_targets(
  135. Bytecode::Label { rhs_block },
  136. Bytecode::Label { end_block });
  137. break;
  138. default:
  139. VERIFY_NOT_REACHED();
  140. }
  141. generator.switch_to_basic_block(rhs_block);
  142. m_rhs->generate_bytecode(generator);
  143. generator.emit<Bytecode::Op::Jump>().set_targets(
  144. Bytecode::Label { end_block },
  145. {});
  146. generator.switch_to_basic_block(end_block);
  147. }
  148. void UnaryExpression::generate_bytecode(Bytecode::Generator& generator) const
  149. {
  150. m_lhs->generate_bytecode(generator);
  151. switch (m_op) {
  152. case UnaryOp::BitwiseNot:
  153. generator.emit<Bytecode::Op::BitwiseNot>();
  154. break;
  155. case UnaryOp::Not:
  156. generator.emit<Bytecode::Op::Not>();
  157. break;
  158. case UnaryOp::Plus:
  159. generator.emit<Bytecode::Op::UnaryPlus>();
  160. break;
  161. case UnaryOp::Minus:
  162. generator.emit<Bytecode::Op::UnaryMinus>();
  163. break;
  164. case UnaryOp::Typeof:
  165. generator.emit<Bytecode::Op::Typeof>();
  166. break;
  167. case UnaryOp::Void:
  168. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  169. break;
  170. default:
  171. TODO();
  172. }
  173. }
  174. void NumericLiteral::generate_bytecode(Bytecode::Generator& generator) const
  175. {
  176. generator.emit<Bytecode::Op::LoadImmediate>(m_value);
  177. }
  178. void BooleanLiteral::generate_bytecode(Bytecode::Generator& generator) const
  179. {
  180. generator.emit<Bytecode::Op::LoadImmediate>(Value(m_value));
  181. }
  182. void NullLiteral::generate_bytecode(Bytecode::Generator& generator) const
  183. {
  184. generator.emit<Bytecode::Op::LoadImmediate>(js_null());
  185. }
  186. void BigIntLiteral::generate_bytecode(Bytecode::Generator& generator) const
  187. {
  188. generator.emit<Bytecode::Op::NewBigInt>(Crypto::SignedBigInteger::from_base10(m_value.substring(0, m_value.length() - 1)));
  189. }
  190. void StringLiteral::generate_bytecode(Bytecode::Generator& generator) const
  191. {
  192. generator.emit<Bytecode::Op::NewString>(generator.intern_string(m_value));
  193. }
  194. void Identifier::generate_bytecode(Bytecode::Generator& generator) const
  195. {
  196. generator.emit<Bytecode::Op::GetVariable>(generator.intern_string(m_string));
  197. }
  198. void AssignmentExpression::generate_bytecode(Bytecode::Generator& generator) const
  199. {
  200. if (is<Identifier>(*m_lhs)) {
  201. auto& identifier = static_cast<Identifier const&>(*m_lhs);
  202. if (m_op == AssignmentOp::Assignment) {
  203. m_rhs->generate_bytecode(generator);
  204. generator.emit<Bytecode::Op::SetVariable>(generator.intern_string(identifier.string()));
  205. return;
  206. }
  207. m_lhs->generate_bytecode(generator);
  208. Bytecode::BasicBlock* rhs_block_ptr { nullptr };
  209. Bytecode::BasicBlock* end_block_ptr { nullptr };
  210. // Logical assignments short circuit.
  211. if (m_op == AssignmentOp::AndAssignment) { // &&=
  212. rhs_block_ptr = &generator.make_block();
  213. end_block_ptr = &generator.make_block();
  214. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  215. Bytecode::Label { *rhs_block_ptr },
  216. Bytecode::Label { *end_block_ptr });
  217. } else if (m_op == AssignmentOp::OrAssignment) { // ||=
  218. rhs_block_ptr = &generator.make_block();
  219. end_block_ptr = &generator.make_block();
  220. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  221. Bytecode::Label { *end_block_ptr },
  222. Bytecode::Label { *rhs_block_ptr });
  223. } else if (m_op == AssignmentOp::NullishAssignment) { // ??=
  224. rhs_block_ptr = &generator.make_block();
  225. end_block_ptr = &generator.make_block();
  226. generator.emit<Bytecode::Op::JumpNullish>().set_targets(
  227. Bytecode::Label { *rhs_block_ptr },
  228. Bytecode::Label { *end_block_ptr });
  229. }
  230. if (rhs_block_ptr)
  231. generator.switch_to_basic_block(*rhs_block_ptr);
  232. // lhs_reg is a part of the rhs_block because the store isn't necessary
  233. // if the logical assignment condition fails.
  234. auto lhs_reg = generator.allocate_register();
  235. generator.emit<Bytecode::Op::Store>(lhs_reg);
  236. m_rhs->generate_bytecode(generator);
  237. switch (m_op) {
  238. case AssignmentOp::AdditionAssignment:
  239. generator.emit<Bytecode::Op::Add>(lhs_reg);
  240. break;
  241. case AssignmentOp::SubtractionAssignment:
  242. generator.emit<Bytecode::Op::Sub>(lhs_reg);
  243. break;
  244. case AssignmentOp::MultiplicationAssignment:
  245. generator.emit<Bytecode::Op::Mul>(lhs_reg);
  246. break;
  247. case AssignmentOp::DivisionAssignment:
  248. generator.emit<Bytecode::Op::Div>(lhs_reg);
  249. break;
  250. case AssignmentOp::ModuloAssignment:
  251. generator.emit<Bytecode::Op::Mod>(lhs_reg);
  252. break;
  253. case AssignmentOp::ExponentiationAssignment:
  254. generator.emit<Bytecode::Op::Exp>(lhs_reg);
  255. break;
  256. case AssignmentOp::BitwiseAndAssignment:
  257. generator.emit<Bytecode::Op::BitwiseAnd>(lhs_reg);
  258. break;
  259. case AssignmentOp::BitwiseOrAssignment:
  260. generator.emit<Bytecode::Op::BitwiseOr>(lhs_reg);
  261. break;
  262. case AssignmentOp::BitwiseXorAssignment:
  263. generator.emit<Bytecode::Op::BitwiseXor>(lhs_reg);
  264. break;
  265. case AssignmentOp::LeftShiftAssignment:
  266. generator.emit<Bytecode::Op::LeftShift>(lhs_reg);
  267. break;
  268. case AssignmentOp::RightShiftAssignment:
  269. generator.emit<Bytecode::Op::RightShift>(lhs_reg);
  270. break;
  271. case AssignmentOp::UnsignedRightShiftAssignment:
  272. generator.emit<Bytecode::Op::UnsignedRightShift>(lhs_reg);
  273. break;
  274. case AssignmentOp::AndAssignment:
  275. case AssignmentOp::OrAssignment:
  276. case AssignmentOp::NullishAssignment:
  277. break; // These are handled above.
  278. default:
  279. TODO();
  280. }
  281. generator.emit<Bytecode::Op::SetVariable>(generator.intern_string(identifier.string()));
  282. if (end_block_ptr) {
  283. generator.emit<Bytecode::Op::Jump>().set_targets(
  284. Bytecode::Label { *end_block_ptr },
  285. {});
  286. generator.switch_to_basic_block(*end_block_ptr);
  287. }
  288. return;
  289. }
  290. if (is<MemberExpression>(*m_lhs)) {
  291. auto& expression = static_cast<MemberExpression const&>(*m_lhs);
  292. expression.object().generate_bytecode(generator);
  293. auto object_reg = generator.allocate_register();
  294. generator.emit<Bytecode::Op::Store>(object_reg);
  295. if (expression.is_computed()) {
  296. TODO();
  297. } else {
  298. VERIFY(is<Identifier>(expression.property()));
  299. m_rhs->generate_bytecode(generator);
  300. auto identifier_table_ref = generator.intern_string(static_cast<Identifier const&>(expression.property()).string());
  301. generator.emit<Bytecode::Op::PutById>(object_reg, identifier_table_ref);
  302. return;
  303. }
  304. }
  305. TODO();
  306. }
  307. void WhileStatement::generate_bytecode(Bytecode::Generator& generator) const
  308. {
  309. // test
  310. // jump if_false (true) end (false) body
  311. // body
  312. // jump always (true) test
  313. // end
  314. auto& test_block = generator.make_block();
  315. auto& body_block = generator.make_block();
  316. auto& end_block = generator.make_block();
  317. // Init result register
  318. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  319. auto result_reg = generator.allocate_register();
  320. generator.emit<Bytecode::Op::Store>(result_reg);
  321. // jump to the test block
  322. generator.emit<Bytecode::Op::Jump>().set_targets(
  323. Bytecode::Label { test_block },
  324. {});
  325. generator.switch_to_basic_block(test_block);
  326. m_test->generate_bytecode(generator);
  327. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  328. Bytecode::Label { body_block },
  329. Bytecode::Label { end_block });
  330. generator.switch_to_basic_block(body_block);
  331. generator.begin_continuable_scope(Bytecode::Label { test_block });
  332. generator.begin_breakable_scope(Bytecode::Label { end_block });
  333. m_body->generate_bytecode(generator);
  334. if (!generator.is_current_block_terminated()) {
  335. generator.emit<Bytecode::Op::Jump>().set_targets(
  336. Bytecode::Label { test_block },
  337. {});
  338. generator.end_continuable_scope();
  339. generator.end_breakable_scope();
  340. generator.switch_to_basic_block(end_block);
  341. generator.emit<Bytecode::Op::Load>(result_reg);
  342. }
  343. }
  344. void DoWhileStatement::generate_bytecode(Bytecode::Generator& generator) const
  345. {
  346. // jump always (true) body
  347. // test
  348. // jump if_false (true) end (false) body
  349. // body
  350. // jump always (true) test
  351. // end
  352. auto& test_block = generator.make_block();
  353. auto& body_block = generator.make_block();
  354. auto& end_block = generator.make_block();
  355. // Init result register
  356. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  357. auto result_reg = generator.allocate_register();
  358. generator.emit<Bytecode::Op::Store>(result_reg);
  359. // jump to the body block
  360. generator.emit<Bytecode::Op::Jump>().set_targets(
  361. Bytecode::Label { body_block },
  362. {});
  363. generator.switch_to_basic_block(test_block);
  364. m_test->generate_bytecode(generator);
  365. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  366. Bytecode::Label { body_block },
  367. Bytecode::Label { end_block });
  368. generator.switch_to_basic_block(body_block);
  369. generator.begin_continuable_scope(Bytecode::Label { test_block });
  370. generator.begin_breakable_scope(Bytecode::Label { end_block });
  371. m_body->generate_bytecode(generator);
  372. if (!generator.is_current_block_terminated()) {
  373. generator.emit<Bytecode::Op::Jump>().set_targets(
  374. Bytecode::Label { test_block },
  375. {});
  376. generator.end_continuable_scope();
  377. generator.end_breakable_scope();
  378. generator.switch_to_basic_block(end_block);
  379. generator.emit<Bytecode::Op::Load>(result_reg);
  380. }
  381. }
  382. void ForStatement::generate_bytecode(Bytecode::Generator& generator) const
  383. {
  384. // init
  385. // jump always (true) test
  386. // test
  387. // jump if_true (true) body (false) end
  388. // body
  389. // jump always (true) update
  390. // update
  391. // jump always (true) test
  392. // end
  393. // If 'test' is missing, fuse the 'test' and 'body' basic blocks
  394. // If 'update' is missing, fuse the 'body' and 'update' basic blocks
  395. Bytecode::BasicBlock* test_block_ptr { nullptr };
  396. Bytecode::BasicBlock* body_block_ptr { nullptr };
  397. Bytecode::BasicBlock* update_block_ptr { nullptr };
  398. auto& end_block = generator.make_block();
  399. if (m_init)
  400. m_init->generate_bytecode(generator);
  401. body_block_ptr = &generator.make_block();
  402. if (m_test)
  403. test_block_ptr = &generator.make_block();
  404. else
  405. test_block_ptr = body_block_ptr;
  406. if (m_update)
  407. update_block_ptr = &generator.make_block();
  408. else
  409. update_block_ptr = body_block_ptr;
  410. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  411. auto result_reg = generator.allocate_register();
  412. generator.emit<Bytecode::Op::Store>(result_reg);
  413. generator.emit<Bytecode::Op::Jump>().set_targets(
  414. Bytecode::Label { *test_block_ptr },
  415. {});
  416. if (m_test) {
  417. generator.switch_to_basic_block(*test_block_ptr);
  418. m_test->generate_bytecode(generator);
  419. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  420. Bytecode::Label { *body_block_ptr },
  421. Bytecode::Label { end_block });
  422. }
  423. generator.switch_to_basic_block(*body_block_ptr);
  424. generator.begin_continuable_scope(Bytecode::Label { *update_block_ptr });
  425. generator.begin_breakable_scope(Bytecode::Label { end_block });
  426. m_body->generate_bytecode(generator);
  427. generator.end_continuable_scope();
  428. if (!generator.is_current_block_terminated()) {
  429. if (m_update) {
  430. generator.emit<Bytecode::Op::Jump>().set_targets(
  431. Bytecode::Label { *update_block_ptr },
  432. {});
  433. generator.switch_to_basic_block(*update_block_ptr);
  434. m_update->generate_bytecode(generator);
  435. }
  436. generator.emit<Bytecode::Op::Jump>().set_targets(
  437. Bytecode::Label { *test_block_ptr },
  438. {});
  439. generator.end_breakable_scope();
  440. generator.switch_to_basic_block(end_block);
  441. generator.emit<Bytecode::Op::Load>(result_reg);
  442. }
  443. }
  444. void ObjectExpression::generate_bytecode(Bytecode::Generator& generator) const
  445. {
  446. generator.emit<Bytecode::Op::NewObject>();
  447. if (!m_properties.is_empty())
  448. TODO();
  449. }
  450. void ArrayExpression::generate_bytecode(Bytecode::Generator& generator) const
  451. {
  452. Vector<Bytecode::Register> element_regs;
  453. for (auto& element : m_elements) {
  454. if (element) {
  455. element->generate_bytecode(generator);
  456. if (is<SpreadExpression>(*element)) {
  457. TODO();
  458. continue;
  459. }
  460. } else {
  461. generator.emit<Bytecode::Op::LoadImmediate>(Value {});
  462. }
  463. auto element_reg = generator.allocate_register();
  464. generator.emit<Bytecode::Op::Store>(element_reg);
  465. element_regs.append(element_reg);
  466. }
  467. generator.emit_with_extra_register_slots<Bytecode::Op::NewArray>(element_regs.size(), element_regs);
  468. }
  469. void MemberExpression::generate_bytecode(Bytecode::Generator& generator) const
  470. {
  471. object().generate_bytecode(generator);
  472. if (is_computed()) {
  473. TODO();
  474. } else {
  475. VERIFY(is<Identifier>(property()));
  476. auto identifier_table_ref = generator.intern_string(static_cast<Identifier const&>(property()).string());
  477. generator.emit<Bytecode::Op::GetById>(identifier_table_ref);
  478. }
  479. }
  480. void FunctionDeclaration::generate_bytecode(Bytecode::Generator&) const
  481. {
  482. }
  483. void VariableDeclaration::generate_bytecode(Bytecode::Generator&) const
  484. {
  485. }
  486. void CallExpression::generate_bytecode(Bytecode::Generator& generator) const
  487. {
  488. m_callee->generate_bytecode(generator);
  489. auto callee_reg = generator.allocate_register();
  490. generator.emit<Bytecode::Op::Store>(callee_reg);
  491. // FIXME: Load the correct 'this' value into 'this_reg'.
  492. auto this_reg = generator.allocate_register();
  493. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  494. generator.emit<Bytecode::Op::Store>(this_reg);
  495. Vector<Bytecode::Register> argument_registers;
  496. for (auto& arg : m_arguments) {
  497. arg.value->generate_bytecode(generator);
  498. auto arg_reg = generator.allocate_register();
  499. generator.emit<Bytecode::Op::Store>(arg_reg);
  500. argument_registers.append(arg_reg);
  501. }
  502. generator.emit_with_extra_register_slots<Bytecode::Op::Call>(argument_registers.size(), callee_reg, this_reg, argument_registers);
  503. }
  504. void ReturnStatement::generate_bytecode(Bytecode::Generator& generator) const
  505. {
  506. if (m_argument)
  507. m_argument->generate_bytecode(generator);
  508. generator.emit<Bytecode::Op::Return>();
  509. }
  510. void IfStatement::generate_bytecode(Bytecode::Generator& generator) const
  511. {
  512. // test
  513. // jump if_true (true) true (false) false
  514. // true
  515. // jump always (true) end
  516. // false
  517. // jump always (true) end
  518. // end
  519. // If the 'false' branch doesn't exist, we're just gonna substitute it for 'end' and elide the last two entries above.
  520. auto& true_block = generator.make_block();
  521. auto& false_block = generator.make_block();
  522. m_predicate->generate_bytecode(generator);
  523. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  524. Bytecode::Label { true_block },
  525. Bytecode::Label { false_block });
  526. Bytecode::Op::Jump* true_block_jump { nullptr };
  527. generator.switch_to_basic_block(true_block);
  528. m_consequent->generate_bytecode(generator);
  529. if (!generator.is_current_block_terminated())
  530. true_block_jump = &generator.emit<Bytecode::Op::Jump>();
  531. generator.switch_to_basic_block(false_block);
  532. if (m_alternate) {
  533. auto& end_block = generator.make_block();
  534. m_alternate->generate_bytecode(generator);
  535. if (!generator.is_current_block_terminated())
  536. generator.emit<Bytecode::Op::Jump>().set_targets(
  537. Bytecode::Label { end_block },
  538. {});
  539. if (true_block_jump)
  540. true_block_jump->set_targets(
  541. Bytecode::Label { end_block },
  542. {});
  543. generator.switch_to_basic_block(end_block);
  544. } else {
  545. if (true_block_jump)
  546. true_block_jump->set_targets(
  547. Bytecode::Label { false_block },
  548. {});
  549. }
  550. }
  551. void ContinueStatement::generate_bytecode(Bytecode::Generator& generator) const
  552. {
  553. generator.emit<Bytecode::Op::Jump>().set_targets(
  554. generator.nearest_continuable_scope(),
  555. {});
  556. }
  557. void DebuggerStatement::generate_bytecode(Bytecode::Generator&) const
  558. {
  559. }
  560. void ConditionalExpression::generate_bytecode(Bytecode::Generator& generator) const
  561. {
  562. // test
  563. // jump if_true (true) true (false) false
  564. // true
  565. // jump always (true) end
  566. // false
  567. // jump always (true) end
  568. // end
  569. auto& true_block = generator.make_block();
  570. auto& false_block = generator.make_block();
  571. auto& end_block = generator.make_block();
  572. m_test->generate_bytecode(generator);
  573. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  574. Bytecode::Label { true_block },
  575. Bytecode::Label { false_block });
  576. generator.switch_to_basic_block(true_block);
  577. m_consequent->generate_bytecode(generator);
  578. generator.emit<Bytecode::Op::Jump>().set_targets(
  579. Bytecode::Label { end_block },
  580. {});
  581. generator.switch_to_basic_block(false_block);
  582. m_alternate->generate_bytecode(generator);
  583. generator.emit<Bytecode::Op::Jump>().set_targets(
  584. Bytecode::Label { end_block },
  585. {});
  586. generator.switch_to_basic_block(end_block);
  587. }
  588. void SequenceExpression::generate_bytecode(Bytecode::Generator& generator) const
  589. {
  590. for (auto& expression : m_expressions)
  591. expression.generate_bytecode(generator);
  592. }
  593. void TemplateLiteral::generate_bytecode(Bytecode::Generator& generator) const
  594. {
  595. auto string_reg = generator.allocate_register();
  596. for (size_t i = 0; i < m_expressions.size(); i++) {
  597. m_expressions[i].generate_bytecode(generator);
  598. if (i == 0) {
  599. generator.emit<Bytecode::Op::Store>(string_reg);
  600. } else {
  601. generator.emit<Bytecode::Op::ConcatString>(string_reg);
  602. }
  603. }
  604. generator.emit<Bytecode::Op::Load>(string_reg);
  605. }
  606. void TaggedTemplateLiteral::generate_bytecode(Bytecode::Generator& generator) const
  607. {
  608. m_tag->generate_bytecode(generator);
  609. auto tag_reg = generator.allocate_register();
  610. generator.emit<Bytecode::Op::Store>(tag_reg);
  611. Vector<Bytecode::Register> string_regs;
  612. auto& expressions = m_template_literal->expressions();
  613. for (size_t i = 0; i < expressions.size(); ++i) {
  614. if (i % 2 != 0)
  615. continue;
  616. expressions[i].generate_bytecode(generator);
  617. auto string_reg = generator.allocate_register();
  618. generator.emit<Bytecode::Op::Store>(string_reg);
  619. string_regs.append(string_reg);
  620. }
  621. generator.emit_with_extra_register_slots<Bytecode::Op::NewArray>(string_regs.size(), string_regs);
  622. auto strings_reg = generator.allocate_register();
  623. generator.emit<Bytecode::Op::Store>(strings_reg);
  624. Vector<Bytecode::Register> argument_regs;
  625. argument_regs.append(strings_reg);
  626. for (size_t i = 0; i < expressions.size(); ++i) {
  627. if (i % 2 == 0)
  628. continue;
  629. expressions[i].generate_bytecode(generator);
  630. auto string_reg = generator.allocate_register();
  631. generator.emit<Bytecode::Op::Store>(string_reg);
  632. argument_regs.append(string_reg);
  633. }
  634. Vector<Bytecode::Register> raw_string_regs;
  635. for (auto& raw_string : m_template_literal->raw_strings()) {
  636. raw_string.generate_bytecode(generator);
  637. auto raw_string_reg = generator.allocate_register();
  638. generator.emit<Bytecode::Op::Store>(raw_string_reg);
  639. raw_string_regs.append(raw_string_reg);
  640. }
  641. generator.emit_with_extra_register_slots<Bytecode::Op::NewArray>(raw_string_regs.size(), raw_string_regs);
  642. auto raw_strings_reg = generator.allocate_register();
  643. generator.emit<Bytecode::Op::Store>(raw_strings_reg);
  644. generator.emit<Bytecode::Op::Load>(strings_reg);
  645. generator.emit<Bytecode::Op::PutById>(raw_strings_reg, generator.intern_string("raw"));
  646. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  647. auto this_reg = generator.allocate_register();
  648. generator.emit<Bytecode::Op::Store>(this_reg);
  649. generator.emit_with_extra_register_slots<Bytecode::Op::Call>(argument_regs.size(), tag_reg, this_reg, move(argument_regs));
  650. }
  651. void UpdateExpression::generate_bytecode(Bytecode::Generator& generator) const
  652. {
  653. if (is<Identifier>(*m_argument)) {
  654. auto& identifier = static_cast<Identifier const&>(*m_argument);
  655. generator.emit<Bytecode::Op::GetVariable>(generator.intern_string(identifier.string()));
  656. Optional<Bytecode::Register> previous_value_for_postfix_reg;
  657. if (!m_prefixed) {
  658. previous_value_for_postfix_reg = generator.allocate_register();
  659. generator.emit<Bytecode::Op::Store>(*previous_value_for_postfix_reg);
  660. }
  661. if (m_op == UpdateOp::Increment)
  662. generator.emit<Bytecode::Op::Increment>();
  663. else
  664. generator.emit<Bytecode::Op::Decrement>();
  665. generator.emit<Bytecode::Op::SetVariable>(generator.intern_string(identifier.string()));
  666. if (!m_prefixed)
  667. generator.emit<Bytecode::Op::Load>(*previous_value_for_postfix_reg);
  668. return;
  669. }
  670. TODO();
  671. }
  672. void ThrowStatement::generate_bytecode(Bytecode::Generator& generator) const
  673. {
  674. m_argument->generate_bytecode(generator);
  675. generator.emit<Bytecode::Op::Throw>();
  676. }
  677. void BreakStatement::generate_bytecode(Bytecode::Generator& generator) const
  678. {
  679. generator.emit<Bytecode::Op::Jump>().set_targets(
  680. generator.nearest_breakable_scope(),
  681. {});
  682. }
  683. void TryStatement::generate_bytecode(Bytecode::Generator& generator) const
  684. {
  685. auto& saved_block = generator.current_block();
  686. Optional<Bytecode::Label> handler_target;
  687. Optional<Bytecode::Label> finalizer_target;
  688. Bytecode::BasicBlock* next_block { nullptr };
  689. if (m_finalizer) {
  690. auto& finalizer_block = generator.make_block();
  691. generator.switch_to_basic_block(finalizer_block);
  692. m_finalizer->generate_bytecode(generator);
  693. if (!generator.is_current_block_terminated()) {
  694. next_block = &generator.make_block();
  695. auto next_target = Bytecode::Label { *next_block };
  696. generator.emit<Bytecode::Op::ContinuePendingUnwind>(next_target);
  697. }
  698. finalizer_target = Bytecode::Label { finalizer_block };
  699. }
  700. if (m_handler) {
  701. auto& handler_block = generator.make_block();
  702. generator.switch_to_basic_block(handler_block);
  703. if (!m_finalizer)
  704. generator.emit<Bytecode::Op::LeaveUnwindContext>();
  705. if (!m_handler->parameter().is_empty()) {
  706. // FIXME: We need a separate LexicalEnvironment here
  707. generator.emit<Bytecode::Op::SetVariable>(generator.intern_string(m_handler->parameter()));
  708. }
  709. m_handler->body().generate_bytecode(generator);
  710. handler_target = Bytecode::Label { handler_block };
  711. if (!generator.is_current_block_terminated()) {
  712. if (m_finalizer) {
  713. generator.emit<Bytecode::Op::LeaveUnwindContext>();
  714. generator.emit<Bytecode::Op::Jump>(finalizer_target);
  715. } else {
  716. VERIFY(!next_block);
  717. next_block = &generator.make_block();
  718. auto next_target = Bytecode::Label { *next_block };
  719. generator.emit<Bytecode::Op::Jump>(next_target);
  720. }
  721. }
  722. }
  723. generator.switch_to_basic_block(saved_block);
  724. generator.emit<Bytecode::Op::EnterUnwindContext>(handler_target, finalizer_target);
  725. m_block->generate_bytecode(generator);
  726. if (m_finalizer && !generator.is_current_block_terminated())
  727. generator.emit<Bytecode::Op::Jump>(finalizer_target);
  728. generator.switch_to_basic_block(next_block ? *next_block : saved_block);
  729. }
  730. }