ASTCodegen.cpp 31 KB

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