ASTCodegen.cpp 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958
  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. auto callee_reg = generator.allocate_register();
  539. auto this_reg = generator.allocate_register();
  540. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  541. generator.emit<Bytecode::Op::Store>(this_reg);
  542. if (is<NewExpression>(this)) {
  543. m_callee->generate_bytecode(generator);
  544. generator.emit<Bytecode::Op::Store>(callee_reg);
  545. } else if (is<SuperExpression>(*m_callee)) {
  546. TODO();
  547. } else if (is<MemberExpression>(*m_callee)) {
  548. auto& member_expression = static_cast<const MemberExpression&>(*m_callee);
  549. if (is<SuperExpression>(member_expression.object())) {
  550. TODO();
  551. } else {
  552. member_expression.object().generate_bytecode(generator);
  553. generator.emit<Bytecode::Op::Store>(this_reg);
  554. // FIXME: Don't copy this logic here, make MemberExpression generate it.
  555. if (!is<Identifier>(member_expression.property()))
  556. TODO();
  557. auto identifier_table_ref = generator.intern_string(static_cast<Identifier const&>(member_expression.property()).string());
  558. generator.emit<Bytecode::Op::GetById>(identifier_table_ref);
  559. generator.emit<Bytecode::Op::Store>(callee_reg);
  560. }
  561. } else {
  562. // FIXME: this = global object in sloppy mode.
  563. m_callee->generate_bytecode(generator);
  564. generator.emit<Bytecode::Op::Store>(callee_reg);
  565. }
  566. Vector<Bytecode::Register> argument_registers;
  567. for (auto& arg : m_arguments) {
  568. arg.value->generate_bytecode(generator);
  569. auto arg_reg = generator.allocate_register();
  570. generator.emit<Bytecode::Op::Store>(arg_reg);
  571. argument_registers.append(arg_reg);
  572. }
  573. Bytecode::Op::Call::CallType call_type;
  574. if (is<NewExpression>(*this)) {
  575. call_type = Bytecode::Op::Call::CallType::Construct;
  576. } else {
  577. call_type = Bytecode::Op::Call::CallType::Call;
  578. }
  579. generator.emit_with_extra_register_slots<Bytecode::Op::Call>(argument_registers.size(), call_type, callee_reg, this_reg, argument_registers);
  580. }
  581. void ReturnStatement::generate_bytecode(Bytecode::Generator& generator) const
  582. {
  583. if (m_argument)
  584. m_argument->generate_bytecode(generator);
  585. if (generator.is_in_generator_function())
  586. generator.emit<Bytecode::Op::Yield>(nullptr);
  587. else
  588. generator.emit<Bytecode::Op::Return>();
  589. }
  590. void YieldExpression::generate_bytecode(Bytecode::Generator& generator) const
  591. {
  592. VERIFY(generator.is_in_generator_function());
  593. if (m_argument)
  594. m_argument->generate_bytecode(generator);
  595. auto& continuation_block = generator.make_block();
  596. generator.emit<Bytecode::Op::Yield>(Bytecode::Label { continuation_block });
  597. generator.switch_to_basic_block(continuation_block);
  598. }
  599. void IfStatement::generate_bytecode(Bytecode::Generator& generator) const
  600. {
  601. // test
  602. // jump if_true (true) true (false) false
  603. // true
  604. // jump always (true) end
  605. // false
  606. // jump always (true) end
  607. // end
  608. // If the 'false' branch doesn't exist, we're just gonna substitute it for 'end' and elide the last two entries above.
  609. auto& true_block = generator.make_block();
  610. auto& false_block = generator.make_block();
  611. m_predicate->generate_bytecode(generator);
  612. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  613. Bytecode::Label { true_block },
  614. Bytecode::Label { false_block });
  615. Bytecode::Op::Jump* true_block_jump { nullptr };
  616. generator.switch_to_basic_block(true_block);
  617. m_consequent->generate_bytecode(generator);
  618. if (!generator.is_current_block_terminated())
  619. true_block_jump = &generator.emit<Bytecode::Op::Jump>();
  620. generator.switch_to_basic_block(false_block);
  621. if (m_alternate) {
  622. auto& end_block = generator.make_block();
  623. m_alternate->generate_bytecode(generator);
  624. if (!generator.is_current_block_terminated())
  625. generator.emit<Bytecode::Op::Jump>().set_targets(
  626. Bytecode::Label { end_block },
  627. {});
  628. if (true_block_jump)
  629. true_block_jump->set_targets(
  630. Bytecode::Label { end_block },
  631. {});
  632. generator.switch_to_basic_block(end_block);
  633. } else {
  634. if (true_block_jump)
  635. true_block_jump->set_targets(
  636. Bytecode::Label { false_block },
  637. {});
  638. }
  639. }
  640. void ContinueStatement::generate_bytecode(Bytecode::Generator& generator) const
  641. {
  642. generator.emit<Bytecode::Op::Jump>().set_targets(
  643. generator.nearest_continuable_scope(),
  644. {});
  645. }
  646. void DebuggerStatement::generate_bytecode(Bytecode::Generator&) const
  647. {
  648. }
  649. void ConditionalExpression::generate_bytecode(Bytecode::Generator& generator) const
  650. {
  651. // test
  652. // jump if_true (true) true (false) false
  653. // true
  654. // jump always (true) end
  655. // false
  656. // jump always (true) end
  657. // end
  658. auto& true_block = generator.make_block();
  659. auto& false_block = generator.make_block();
  660. auto& end_block = generator.make_block();
  661. m_test->generate_bytecode(generator);
  662. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  663. Bytecode::Label { true_block },
  664. Bytecode::Label { false_block });
  665. generator.switch_to_basic_block(true_block);
  666. m_consequent->generate_bytecode(generator);
  667. generator.emit<Bytecode::Op::Jump>().set_targets(
  668. Bytecode::Label { end_block },
  669. {});
  670. generator.switch_to_basic_block(false_block);
  671. m_alternate->generate_bytecode(generator);
  672. generator.emit<Bytecode::Op::Jump>().set_targets(
  673. Bytecode::Label { end_block },
  674. {});
  675. generator.switch_to_basic_block(end_block);
  676. }
  677. void SequenceExpression::generate_bytecode(Bytecode::Generator& generator) const
  678. {
  679. for (auto& expression : m_expressions)
  680. expression.generate_bytecode(generator);
  681. }
  682. void TemplateLiteral::generate_bytecode(Bytecode::Generator& generator) const
  683. {
  684. auto string_reg = generator.allocate_register();
  685. for (size_t i = 0; i < m_expressions.size(); i++) {
  686. m_expressions[i].generate_bytecode(generator);
  687. if (i == 0) {
  688. generator.emit<Bytecode::Op::Store>(string_reg);
  689. } else {
  690. generator.emit<Bytecode::Op::ConcatString>(string_reg);
  691. }
  692. }
  693. generator.emit<Bytecode::Op::Load>(string_reg);
  694. }
  695. void TaggedTemplateLiteral::generate_bytecode(Bytecode::Generator& generator) const
  696. {
  697. m_tag->generate_bytecode(generator);
  698. auto tag_reg = generator.allocate_register();
  699. generator.emit<Bytecode::Op::Store>(tag_reg);
  700. Vector<Bytecode::Register> string_regs;
  701. auto& expressions = m_template_literal->expressions();
  702. for (size_t i = 0; i < expressions.size(); ++i) {
  703. if (i % 2 != 0)
  704. continue;
  705. expressions[i].generate_bytecode(generator);
  706. auto string_reg = generator.allocate_register();
  707. generator.emit<Bytecode::Op::Store>(string_reg);
  708. string_regs.append(string_reg);
  709. }
  710. generator.emit_with_extra_register_slots<Bytecode::Op::NewArray>(string_regs.size(), string_regs);
  711. auto strings_reg = generator.allocate_register();
  712. generator.emit<Bytecode::Op::Store>(strings_reg);
  713. Vector<Bytecode::Register> argument_regs;
  714. argument_regs.append(strings_reg);
  715. for (size_t i = 0; i < expressions.size(); ++i) {
  716. if (i % 2 == 0)
  717. continue;
  718. expressions[i].generate_bytecode(generator);
  719. auto string_reg = generator.allocate_register();
  720. generator.emit<Bytecode::Op::Store>(string_reg);
  721. argument_regs.append(string_reg);
  722. }
  723. Vector<Bytecode::Register> raw_string_regs;
  724. for (auto& raw_string : m_template_literal->raw_strings()) {
  725. raw_string.generate_bytecode(generator);
  726. auto raw_string_reg = generator.allocate_register();
  727. generator.emit<Bytecode::Op::Store>(raw_string_reg);
  728. raw_string_regs.append(raw_string_reg);
  729. }
  730. generator.emit_with_extra_register_slots<Bytecode::Op::NewArray>(raw_string_regs.size(), raw_string_regs);
  731. auto raw_strings_reg = generator.allocate_register();
  732. generator.emit<Bytecode::Op::Store>(raw_strings_reg);
  733. generator.emit<Bytecode::Op::Load>(strings_reg);
  734. generator.emit<Bytecode::Op::PutById>(raw_strings_reg, generator.intern_string("raw"));
  735. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  736. auto this_reg = generator.allocate_register();
  737. generator.emit<Bytecode::Op::Store>(this_reg);
  738. generator.emit_with_extra_register_slots<Bytecode::Op::Call>(argument_regs.size(), Bytecode::Op::Call::CallType::Call, tag_reg, this_reg, move(argument_regs));
  739. }
  740. void UpdateExpression::generate_bytecode(Bytecode::Generator& generator) const
  741. {
  742. if (is<Identifier>(*m_argument)) {
  743. auto& identifier = static_cast<Identifier const&>(*m_argument);
  744. generator.emit<Bytecode::Op::GetVariable>(generator.intern_string(identifier.string()));
  745. Optional<Bytecode::Register> previous_value_for_postfix_reg;
  746. if (!m_prefixed) {
  747. previous_value_for_postfix_reg = generator.allocate_register();
  748. generator.emit<Bytecode::Op::Store>(*previous_value_for_postfix_reg);
  749. }
  750. if (m_op == UpdateOp::Increment)
  751. generator.emit<Bytecode::Op::Increment>();
  752. else
  753. generator.emit<Bytecode::Op::Decrement>();
  754. generator.emit<Bytecode::Op::SetVariable>(generator.intern_string(identifier.string()));
  755. if (!m_prefixed)
  756. generator.emit<Bytecode::Op::Load>(*previous_value_for_postfix_reg);
  757. return;
  758. }
  759. TODO();
  760. }
  761. void ThrowStatement::generate_bytecode(Bytecode::Generator& generator) const
  762. {
  763. m_argument->generate_bytecode(generator);
  764. generator.emit<Bytecode::Op::Throw>();
  765. }
  766. void BreakStatement::generate_bytecode(Bytecode::Generator& generator) const
  767. {
  768. generator.emit<Bytecode::Op::Jump>().set_targets(
  769. generator.nearest_breakable_scope(),
  770. {});
  771. }
  772. void TryStatement::generate_bytecode(Bytecode::Generator& generator) const
  773. {
  774. auto& saved_block = generator.current_block();
  775. Optional<Bytecode::Label> handler_target;
  776. Optional<Bytecode::Label> finalizer_target;
  777. Bytecode::BasicBlock* next_block { nullptr };
  778. if (m_finalizer) {
  779. auto& finalizer_block = generator.make_block();
  780. generator.switch_to_basic_block(finalizer_block);
  781. m_finalizer->generate_bytecode(generator);
  782. if (!generator.is_current_block_terminated()) {
  783. next_block = &generator.make_block();
  784. auto next_target = Bytecode::Label { *next_block };
  785. generator.emit<Bytecode::Op::ContinuePendingUnwind>(next_target);
  786. }
  787. finalizer_target = Bytecode::Label { finalizer_block };
  788. }
  789. if (m_handler) {
  790. auto& handler_block = generator.make_block();
  791. generator.switch_to_basic_block(handler_block);
  792. if (!m_finalizer)
  793. generator.emit<Bytecode::Op::LeaveUnwindContext>();
  794. if (!m_handler->parameter().is_empty()) {
  795. // FIXME: We need a separate LexicalEnvironment here
  796. generator.emit<Bytecode::Op::SetVariable>(generator.intern_string(m_handler->parameter()));
  797. }
  798. m_handler->body().generate_bytecode(generator);
  799. handler_target = Bytecode::Label { handler_block };
  800. if (!generator.is_current_block_terminated()) {
  801. if (m_finalizer) {
  802. generator.emit<Bytecode::Op::LeaveUnwindContext>();
  803. generator.emit<Bytecode::Op::Jump>(finalizer_target);
  804. } else {
  805. VERIFY(!next_block);
  806. next_block = &generator.make_block();
  807. auto next_target = Bytecode::Label { *next_block };
  808. generator.emit<Bytecode::Op::Jump>(next_target);
  809. }
  810. }
  811. }
  812. generator.switch_to_basic_block(saved_block);
  813. generator.emit<Bytecode::Op::EnterUnwindContext>(handler_target, finalizer_target);
  814. m_block->generate_bytecode(generator);
  815. if (m_finalizer && !generator.is_current_block_terminated())
  816. generator.emit<Bytecode::Op::Jump>(finalizer_target);
  817. generator.switch_to_basic_block(next_block ? *next_block : saved_block);
  818. }
  819. }