ASTCodegen.cpp 33 KB

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