ASTCodegen.cpp 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971
  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. expression.property().generate_bytecode(generator);
  334. auto property_reg = generator.allocate_register();
  335. generator.emit<Bytecode::Op::Store>(property_reg);
  336. m_rhs->generate_bytecode(generator);
  337. generator.emit<Bytecode::Op::PutByValue>(object_reg, property_reg);
  338. } else {
  339. VERIFY(is<Identifier>(expression.property()));
  340. m_rhs->generate_bytecode(generator);
  341. auto identifier_table_ref = generator.intern_string(static_cast<Identifier const&>(expression.property()).string());
  342. generator.emit<Bytecode::Op::PutById>(object_reg, identifier_table_ref);
  343. }
  344. return;
  345. }
  346. TODO();
  347. }
  348. void WhileStatement::generate_bytecode(Bytecode::Generator& generator) const
  349. {
  350. // test
  351. // jump if_false (true) end (false) body
  352. // body
  353. // jump always (true) test
  354. // end
  355. auto& test_block = generator.make_block();
  356. auto& body_block = generator.make_block();
  357. auto& end_block = generator.make_block();
  358. // Init result register
  359. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  360. auto result_reg = generator.allocate_register();
  361. generator.emit<Bytecode::Op::Store>(result_reg);
  362. // jump to the test block
  363. generator.emit<Bytecode::Op::Jump>().set_targets(
  364. Bytecode::Label { test_block },
  365. {});
  366. generator.switch_to_basic_block(test_block);
  367. m_test->generate_bytecode(generator);
  368. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  369. Bytecode::Label { body_block },
  370. Bytecode::Label { end_block });
  371. generator.switch_to_basic_block(body_block);
  372. generator.begin_continuable_scope(Bytecode::Label { test_block });
  373. generator.begin_breakable_scope(Bytecode::Label { end_block });
  374. m_body->generate_bytecode(generator);
  375. if (!generator.is_current_block_terminated()) {
  376. generator.emit<Bytecode::Op::Jump>().set_targets(
  377. Bytecode::Label { test_block },
  378. {});
  379. generator.end_continuable_scope();
  380. generator.end_breakable_scope();
  381. generator.switch_to_basic_block(end_block);
  382. generator.emit<Bytecode::Op::Load>(result_reg);
  383. }
  384. }
  385. void DoWhileStatement::generate_bytecode(Bytecode::Generator& generator) const
  386. {
  387. // jump always (true) body
  388. // test
  389. // jump if_false (true) end (false) body
  390. // body
  391. // jump always (true) test
  392. // end
  393. auto& test_block = generator.make_block();
  394. auto& body_block = generator.make_block();
  395. auto& end_block = generator.make_block();
  396. // Init result register
  397. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  398. auto result_reg = generator.allocate_register();
  399. generator.emit<Bytecode::Op::Store>(result_reg);
  400. // jump to the body block
  401. generator.emit<Bytecode::Op::Jump>().set_targets(
  402. Bytecode::Label { body_block },
  403. {});
  404. generator.switch_to_basic_block(test_block);
  405. m_test->generate_bytecode(generator);
  406. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  407. Bytecode::Label { body_block },
  408. Bytecode::Label { end_block });
  409. generator.switch_to_basic_block(body_block);
  410. generator.begin_continuable_scope(Bytecode::Label { test_block });
  411. generator.begin_breakable_scope(Bytecode::Label { end_block });
  412. m_body->generate_bytecode(generator);
  413. if (!generator.is_current_block_terminated()) {
  414. generator.emit<Bytecode::Op::Jump>().set_targets(
  415. Bytecode::Label { test_block },
  416. {});
  417. generator.end_continuable_scope();
  418. generator.end_breakable_scope();
  419. generator.switch_to_basic_block(end_block);
  420. generator.emit<Bytecode::Op::Load>(result_reg);
  421. }
  422. }
  423. void ForStatement::generate_bytecode(Bytecode::Generator& generator) const
  424. {
  425. // init
  426. // jump always (true) test
  427. // test
  428. // jump if_true (true) body (false) end
  429. // body
  430. // jump always (true) update
  431. // update
  432. // jump always (true) test
  433. // end
  434. // If 'test' is missing, fuse the 'test' and 'body' basic blocks
  435. // If 'update' is missing, fuse the 'body' and 'update' basic blocks
  436. Bytecode::BasicBlock* test_block_ptr { nullptr };
  437. Bytecode::BasicBlock* body_block_ptr { nullptr };
  438. Bytecode::BasicBlock* update_block_ptr { nullptr };
  439. auto& end_block = generator.make_block();
  440. if (m_init)
  441. m_init->generate_bytecode(generator);
  442. body_block_ptr = &generator.make_block();
  443. if (m_test)
  444. test_block_ptr = &generator.make_block();
  445. else
  446. test_block_ptr = body_block_ptr;
  447. if (m_update)
  448. update_block_ptr = &generator.make_block();
  449. else
  450. update_block_ptr = body_block_ptr;
  451. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  452. auto result_reg = generator.allocate_register();
  453. generator.emit<Bytecode::Op::Store>(result_reg);
  454. generator.emit<Bytecode::Op::Jump>().set_targets(
  455. Bytecode::Label { *test_block_ptr },
  456. {});
  457. if (m_test) {
  458. generator.switch_to_basic_block(*test_block_ptr);
  459. m_test->generate_bytecode(generator);
  460. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  461. Bytecode::Label { *body_block_ptr },
  462. Bytecode::Label { end_block });
  463. }
  464. generator.switch_to_basic_block(*body_block_ptr);
  465. generator.begin_continuable_scope(Bytecode::Label { *update_block_ptr });
  466. generator.begin_breakable_scope(Bytecode::Label { end_block });
  467. m_body->generate_bytecode(generator);
  468. generator.end_continuable_scope();
  469. if (!generator.is_current_block_terminated()) {
  470. if (m_update) {
  471. generator.emit<Bytecode::Op::Jump>().set_targets(
  472. Bytecode::Label { *update_block_ptr },
  473. {});
  474. generator.switch_to_basic_block(*update_block_ptr);
  475. m_update->generate_bytecode(generator);
  476. }
  477. generator.emit<Bytecode::Op::Jump>().set_targets(
  478. Bytecode::Label { *test_block_ptr },
  479. {});
  480. generator.end_breakable_scope();
  481. generator.switch_to_basic_block(end_block);
  482. generator.emit<Bytecode::Op::Load>(result_reg);
  483. }
  484. }
  485. void ObjectExpression::generate_bytecode(Bytecode::Generator& generator) const
  486. {
  487. generator.emit<Bytecode::Op::NewObject>();
  488. if (!m_properties.is_empty())
  489. TODO();
  490. }
  491. void ArrayExpression::generate_bytecode(Bytecode::Generator& generator) const
  492. {
  493. Vector<Bytecode::Register> element_regs;
  494. for (auto& element : m_elements) {
  495. if (element) {
  496. element->generate_bytecode(generator);
  497. if (is<SpreadExpression>(*element)) {
  498. TODO();
  499. continue;
  500. }
  501. } else {
  502. generator.emit<Bytecode::Op::LoadImmediate>(Value {});
  503. }
  504. auto element_reg = generator.allocate_register();
  505. generator.emit<Bytecode::Op::Store>(element_reg);
  506. element_regs.append(element_reg);
  507. }
  508. generator.emit_with_extra_register_slots<Bytecode::Op::NewArray>(element_regs.size(), element_regs);
  509. }
  510. void MemberExpression::generate_bytecode(Bytecode::Generator& generator) const
  511. {
  512. object().generate_bytecode(generator);
  513. if (is_computed()) {
  514. auto object_reg = generator.allocate_register();
  515. generator.emit<Bytecode::Op::Store>(object_reg);
  516. property().generate_bytecode(generator);
  517. generator.emit<Bytecode::Op::GetByValue>(object_reg);
  518. } else {
  519. VERIFY(is<Identifier>(property()));
  520. auto identifier_table_ref = generator.intern_string(static_cast<Identifier const&>(property()).string());
  521. generator.emit<Bytecode::Op::GetById>(identifier_table_ref);
  522. }
  523. }
  524. void FunctionDeclaration::generate_bytecode(Bytecode::Generator&) const
  525. {
  526. }
  527. void FunctionExpression::generate_bytecode(Bytecode::Generator& generator) const
  528. {
  529. generator.emit<Bytecode::Op::NewFunction>(*this);
  530. }
  531. void VariableDeclaration::generate_bytecode(Bytecode::Generator& generator) const
  532. {
  533. for (auto& declarator : m_declarations) {
  534. if (declarator.init())
  535. declarator.init()->generate_bytecode(generator);
  536. else
  537. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  538. declarator.target().visit(
  539. [&](const NonnullRefPtr<Identifier>& id) {
  540. generator.emit<Bytecode::Op::SetVariable>(generator.intern_string(id->string()));
  541. },
  542. [&](const NonnullRefPtr<BindingPattern>&) {
  543. TODO();
  544. });
  545. }
  546. }
  547. void CallExpression::generate_bytecode(Bytecode::Generator& generator) const
  548. {
  549. auto callee_reg = generator.allocate_register();
  550. auto this_reg = generator.allocate_register();
  551. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  552. generator.emit<Bytecode::Op::Store>(this_reg);
  553. if (is<NewExpression>(this)) {
  554. m_callee->generate_bytecode(generator);
  555. generator.emit<Bytecode::Op::Store>(callee_reg);
  556. } else if (is<SuperExpression>(*m_callee)) {
  557. TODO();
  558. } else if (is<MemberExpression>(*m_callee)) {
  559. auto& member_expression = static_cast<const MemberExpression&>(*m_callee);
  560. if (is<SuperExpression>(member_expression.object())) {
  561. TODO();
  562. } else {
  563. member_expression.object().generate_bytecode(generator);
  564. generator.emit<Bytecode::Op::Store>(this_reg);
  565. // FIXME: Don't copy this logic here, make MemberExpression generate it.
  566. if (!is<Identifier>(member_expression.property()))
  567. TODO();
  568. auto identifier_table_ref = generator.intern_string(static_cast<Identifier const&>(member_expression.property()).string());
  569. generator.emit<Bytecode::Op::GetById>(identifier_table_ref);
  570. generator.emit<Bytecode::Op::Store>(callee_reg);
  571. }
  572. } else {
  573. // FIXME: this = global object in sloppy mode.
  574. m_callee->generate_bytecode(generator);
  575. generator.emit<Bytecode::Op::Store>(callee_reg);
  576. }
  577. Vector<Bytecode::Register> argument_registers;
  578. for (auto& arg : m_arguments) {
  579. arg.value->generate_bytecode(generator);
  580. auto arg_reg = generator.allocate_register();
  581. generator.emit<Bytecode::Op::Store>(arg_reg);
  582. argument_registers.append(arg_reg);
  583. }
  584. Bytecode::Op::Call::CallType call_type;
  585. if (is<NewExpression>(*this)) {
  586. call_type = Bytecode::Op::Call::CallType::Construct;
  587. } else {
  588. call_type = Bytecode::Op::Call::CallType::Call;
  589. }
  590. generator.emit_with_extra_register_slots<Bytecode::Op::Call>(argument_registers.size(), call_type, callee_reg, this_reg, argument_registers);
  591. }
  592. void ReturnStatement::generate_bytecode(Bytecode::Generator& generator) const
  593. {
  594. if (m_argument)
  595. m_argument->generate_bytecode(generator);
  596. if (generator.is_in_generator_function())
  597. generator.emit<Bytecode::Op::Yield>(nullptr);
  598. else
  599. generator.emit<Bytecode::Op::Return>();
  600. }
  601. void YieldExpression::generate_bytecode(Bytecode::Generator& generator) const
  602. {
  603. VERIFY(generator.is_in_generator_function());
  604. if (m_argument)
  605. m_argument->generate_bytecode(generator);
  606. auto& continuation_block = generator.make_block();
  607. generator.emit<Bytecode::Op::Yield>(Bytecode::Label { continuation_block });
  608. generator.switch_to_basic_block(continuation_block);
  609. }
  610. void IfStatement::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. // If the 'false' branch doesn't exist, we're just gonna substitute it for 'end' and elide the last two entries above.
  620. auto& true_block = generator.make_block();
  621. auto& false_block = generator.make_block();
  622. m_predicate->generate_bytecode(generator);
  623. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  624. Bytecode::Label { true_block },
  625. Bytecode::Label { false_block });
  626. Bytecode::Op::Jump* true_block_jump { nullptr };
  627. generator.switch_to_basic_block(true_block);
  628. m_consequent->generate_bytecode(generator);
  629. if (!generator.is_current_block_terminated())
  630. true_block_jump = &generator.emit<Bytecode::Op::Jump>();
  631. generator.switch_to_basic_block(false_block);
  632. if (m_alternate) {
  633. auto& end_block = generator.make_block();
  634. m_alternate->generate_bytecode(generator);
  635. if (!generator.is_current_block_terminated())
  636. generator.emit<Bytecode::Op::Jump>().set_targets(
  637. Bytecode::Label { end_block },
  638. {});
  639. if (true_block_jump)
  640. true_block_jump->set_targets(
  641. Bytecode::Label { end_block },
  642. {});
  643. generator.switch_to_basic_block(end_block);
  644. } else {
  645. if (true_block_jump)
  646. true_block_jump->set_targets(
  647. Bytecode::Label { false_block },
  648. {});
  649. }
  650. }
  651. void ContinueStatement::generate_bytecode(Bytecode::Generator& generator) const
  652. {
  653. generator.emit<Bytecode::Op::Jump>().set_targets(
  654. generator.nearest_continuable_scope(),
  655. {});
  656. }
  657. void DebuggerStatement::generate_bytecode(Bytecode::Generator&) const
  658. {
  659. }
  660. void ConditionalExpression::generate_bytecode(Bytecode::Generator& generator) const
  661. {
  662. // test
  663. // jump if_true (true) true (false) false
  664. // true
  665. // jump always (true) end
  666. // false
  667. // jump always (true) end
  668. // end
  669. auto& true_block = generator.make_block();
  670. auto& false_block = generator.make_block();
  671. auto& end_block = generator.make_block();
  672. m_test->generate_bytecode(generator);
  673. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  674. Bytecode::Label { true_block },
  675. Bytecode::Label { false_block });
  676. generator.switch_to_basic_block(true_block);
  677. m_consequent->generate_bytecode(generator);
  678. generator.emit<Bytecode::Op::Jump>().set_targets(
  679. Bytecode::Label { end_block },
  680. {});
  681. generator.switch_to_basic_block(false_block);
  682. m_alternate->generate_bytecode(generator);
  683. generator.emit<Bytecode::Op::Jump>().set_targets(
  684. Bytecode::Label { end_block },
  685. {});
  686. generator.switch_to_basic_block(end_block);
  687. }
  688. void SequenceExpression::generate_bytecode(Bytecode::Generator& generator) const
  689. {
  690. for (auto& expression : m_expressions)
  691. expression.generate_bytecode(generator);
  692. }
  693. void TemplateLiteral::generate_bytecode(Bytecode::Generator& generator) const
  694. {
  695. auto string_reg = generator.allocate_register();
  696. for (size_t i = 0; i < m_expressions.size(); i++) {
  697. m_expressions[i].generate_bytecode(generator);
  698. if (i == 0) {
  699. generator.emit<Bytecode::Op::Store>(string_reg);
  700. } else {
  701. generator.emit<Bytecode::Op::ConcatString>(string_reg);
  702. }
  703. }
  704. generator.emit<Bytecode::Op::Load>(string_reg);
  705. }
  706. void TaggedTemplateLiteral::generate_bytecode(Bytecode::Generator& generator) const
  707. {
  708. m_tag->generate_bytecode(generator);
  709. auto tag_reg = generator.allocate_register();
  710. generator.emit<Bytecode::Op::Store>(tag_reg);
  711. Vector<Bytecode::Register> string_regs;
  712. auto& expressions = m_template_literal->expressions();
  713. for (size_t i = 0; i < expressions.size(); ++i) {
  714. if (i % 2 != 0)
  715. continue;
  716. expressions[i].generate_bytecode(generator);
  717. auto string_reg = generator.allocate_register();
  718. generator.emit<Bytecode::Op::Store>(string_reg);
  719. string_regs.append(string_reg);
  720. }
  721. generator.emit_with_extra_register_slots<Bytecode::Op::NewArray>(string_regs.size(), string_regs);
  722. auto strings_reg = generator.allocate_register();
  723. generator.emit<Bytecode::Op::Store>(strings_reg);
  724. Vector<Bytecode::Register> argument_regs;
  725. argument_regs.append(strings_reg);
  726. for (size_t i = 0; i < expressions.size(); ++i) {
  727. if (i % 2 == 0)
  728. continue;
  729. expressions[i].generate_bytecode(generator);
  730. auto string_reg = generator.allocate_register();
  731. generator.emit<Bytecode::Op::Store>(string_reg);
  732. argument_regs.append(string_reg);
  733. }
  734. Vector<Bytecode::Register> raw_string_regs;
  735. for (auto& raw_string : m_template_literal->raw_strings()) {
  736. raw_string.generate_bytecode(generator);
  737. auto raw_string_reg = generator.allocate_register();
  738. generator.emit<Bytecode::Op::Store>(raw_string_reg);
  739. raw_string_regs.append(raw_string_reg);
  740. }
  741. generator.emit_with_extra_register_slots<Bytecode::Op::NewArray>(raw_string_regs.size(), raw_string_regs);
  742. auto raw_strings_reg = generator.allocate_register();
  743. generator.emit<Bytecode::Op::Store>(raw_strings_reg);
  744. generator.emit<Bytecode::Op::Load>(strings_reg);
  745. generator.emit<Bytecode::Op::PutById>(raw_strings_reg, generator.intern_string("raw"));
  746. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  747. auto this_reg = generator.allocate_register();
  748. generator.emit<Bytecode::Op::Store>(this_reg);
  749. generator.emit_with_extra_register_slots<Bytecode::Op::Call>(argument_regs.size(), Bytecode::Op::Call::CallType::Call, tag_reg, this_reg, move(argument_regs));
  750. }
  751. void UpdateExpression::generate_bytecode(Bytecode::Generator& generator) const
  752. {
  753. if (is<Identifier>(*m_argument)) {
  754. auto& identifier = static_cast<Identifier const&>(*m_argument);
  755. generator.emit<Bytecode::Op::GetVariable>(generator.intern_string(identifier.string()));
  756. Optional<Bytecode::Register> previous_value_for_postfix_reg;
  757. if (!m_prefixed) {
  758. previous_value_for_postfix_reg = generator.allocate_register();
  759. generator.emit<Bytecode::Op::Store>(*previous_value_for_postfix_reg);
  760. }
  761. if (m_op == UpdateOp::Increment)
  762. generator.emit<Bytecode::Op::Increment>();
  763. else
  764. generator.emit<Bytecode::Op::Decrement>();
  765. generator.emit<Bytecode::Op::SetVariable>(generator.intern_string(identifier.string()));
  766. if (!m_prefixed)
  767. generator.emit<Bytecode::Op::Load>(*previous_value_for_postfix_reg);
  768. return;
  769. }
  770. TODO();
  771. }
  772. void ThrowStatement::generate_bytecode(Bytecode::Generator& generator) const
  773. {
  774. m_argument->generate_bytecode(generator);
  775. generator.emit<Bytecode::Op::Throw>();
  776. }
  777. void BreakStatement::generate_bytecode(Bytecode::Generator& generator) const
  778. {
  779. generator.emit<Bytecode::Op::Jump>().set_targets(
  780. generator.nearest_breakable_scope(),
  781. {});
  782. }
  783. void TryStatement::generate_bytecode(Bytecode::Generator& generator) const
  784. {
  785. auto& saved_block = generator.current_block();
  786. Optional<Bytecode::Label> handler_target;
  787. Optional<Bytecode::Label> finalizer_target;
  788. Bytecode::BasicBlock* next_block { nullptr };
  789. if (m_finalizer) {
  790. auto& finalizer_block = generator.make_block();
  791. generator.switch_to_basic_block(finalizer_block);
  792. m_finalizer->generate_bytecode(generator);
  793. if (!generator.is_current_block_terminated()) {
  794. next_block = &generator.make_block();
  795. auto next_target = Bytecode::Label { *next_block };
  796. generator.emit<Bytecode::Op::ContinuePendingUnwind>(next_target);
  797. }
  798. finalizer_target = Bytecode::Label { finalizer_block };
  799. }
  800. if (m_handler) {
  801. auto& handler_block = generator.make_block();
  802. generator.switch_to_basic_block(handler_block);
  803. if (!m_finalizer)
  804. generator.emit<Bytecode::Op::LeaveUnwindContext>();
  805. if (!m_handler->parameter().is_empty()) {
  806. // FIXME: We need a separate LexicalEnvironment here
  807. generator.emit<Bytecode::Op::SetVariable>(generator.intern_string(m_handler->parameter()));
  808. }
  809. m_handler->body().generate_bytecode(generator);
  810. handler_target = Bytecode::Label { handler_block };
  811. if (!generator.is_current_block_terminated()) {
  812. if (m_finalizer) {
  813. generator.emit<Bytecode::Op::LeaveUnwindContext>();
  814. generator.emit<Bytecode::Op::Jump>(finalizer_target);
  815. } else {
  816. VERIFY(!next_block);
  817. next_block = &generator.make_block();
  818. auto next_target = Bytecode::Label { *next_block };
  819. generator.emit<Bytecode::Op::Jump>(next_target);
  820. }
  821. }
  822. }
  823. generator.switch_to_basic_block(saved_block);
  824. generator.emit<Bytecode::Op::EnterUnwindContext>(handler_target, finalizer_target);
  825. m_block->generate_bytecode(generator);
  826. if (m_finalizer && !generator.is_current_block_terminated())
  827. generator.emit<Bytecode::Op::Jump>(finalizer_target);
  828. generator.switch_to_basic_block(next_block ? *next_block : saved_block);
  829. }
  830. }