ASTCodegen.cpp 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282
  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. * Copyright (c) 2021, Marcin Gasperowicz <xnooga@gmail.com>
  6. *
  7. * SPDX-License-Identifier: BSD-2-Clause
  8. */
  9. #include <AK/Format.h>
  10. #include <LibJS/AST.h>
  11. #include <LibJS/Bytecode/Generator.h>
  12. #include <LibJS/Bytecode/Instruction.h>
  13. #include <LibJS/Bytecode/Op.h>
  14. #include <LibJS/Bytecode/Register.h>
  15. #include <LibJS/Bytecode/StringTable.h>
  16. #include <LibJS/Runtime/Environment.h>
  17. namespace JS {
  18. void ASTNode::generate_bytecode(Bytecode::Generator&) const
  19. {
  20. dbgln("Missing generate_bytecode() in {}", class_name());
  21. TODO();
  22. }
  23. void ScopeNode::generate_bytecode(Bytecode::Generator& generator) const
  24. {
  25. // FIXME: This is an ad-hoc fix but should be done as the spec says in
  26. // {Global, Block, Function, Eval}DeclarationInstantiation.
  27. for (auto& function : m_functions_hoistable_with_annexB_extension) {
  28. generator.emit<Bytecode::Op::NewFunction>(function);
  29. generator.emit<Bytecode::Op::SetVariable>(generator.intern_identifier(function.name()));
  30. }
  31. HashTable<FlyString> functions_initialized;
  32. for_each_var_function_declaration_in_reverse_order([&](FunctionDeclaration const& function) {
  33. if (functions_initialized.set(function.name()) != AK::HashSetResult::InsertedNewEntry)
  34. return;
  35. generator.emit<Bytecode::Op::NewFunction>(function);
  36. generator.emit<Bytecode::Op::SetVariable>(generator.intern_identifier(function.name()));
  37. });
  38. // FIXME: Register lexical and variable scope declarations
  39. for (auto& child : children()) {
  40. child.generate_bytecode(generator);
  41. if (generator.is_current_block_terminated())
  42. break;
  43. }
  44. }
  45. void EmptyStatement::generate_bytecode(Bytecode::Generator&) const
  46. {
  47. }
  48. void ExpressionStatement::generate_bytecode(Bytecode::Generator& generator) const
  49. {
  50. m_expression->generate_bytecode(generator);
  51. }
  52. void BinaryExpression::generate_bytecode(Bytecode::Generator& generator) const
  53. {
  54. m_lhs->generate_bytecode(generator);
  55. auto lhs_reg = generator.allocate_register();
  56. generator.emit<Bytecode::Op::Store>(lhs_reg);
  57. m_rhs->generate_bytecode(generator);
  58. switch (m_op) {
  59. case BinaryOp::Addition:
  60. generator.emit<Bytecode::Op::Add>(lhs_reg);
  61. break;
  62. case BinaryOp::Subtraction:
  63. generator.emit<Bytecode::Op::Sub>(lhs_reg);
  64. break;
  65. case BinaryOp::Multiplication:
  66. generator.emit<Bytecode::Op::Mul>(lhs_reg);
  67. break;
  68. case BinaryOp::Division:
  69. generator.emit<Bytecode::Op::Div>(lhs_reg);
  70. break;
  71. case BinaryOp::Modulo:
  72. generator.emit<Bytecode::Op::Mod>(lhs_reg);
  73. break;
  74. case BinaryOp::Exponentiation:
  75. generator.emit<Bytecode::Op::Exp>(lhs_reg);
  76. break;
  77. case BinaryOp::GreaterThan:
  78. generator.emit<Bytecode::Op::GreaterThan>(lhs_reg);
  79. break;
  80. case BinaryOp::GreaterThanEquals:
  81. generator.emit<Bytecode::Op::GreaterThanEquals>(lhs_reg);
  82. break;
  83. case BinaryOp::LessThan:
  84. generator.emit<Bytecode::Op::LessThan>(lhs_reg);
  85. break;
  86. case BinaryOp::LessThanEquals:
  87. generator.emit<Bytecode::Op::LessThanEquals>(lhs_reg);
  88. break;
  89. case BinaryOp::LooselyInequals:
  90. generator.emit<Bytecode::Op::LooselyInequals>(lhs_reg);
  91. break;
  92. case BinaryOp::LooselyEquals:
  93. generator.emit<Bytecode::Op::LooselyEquals>(lhs_reg);
  94. break;
  95. case BinaryOp::StrictlyInequals:
  96. generator.emit<Bytecode::Op::StrictlyInequals>(lhs_reg);
  97. break;
  98. case BinaryOp::StrictlyEquals:
  99. generator.emit<Bytecode::Op::StrictlyEquals>(lhs_reg);
  100. break;
  101. case BinaryOp::BitwiseAnd:
  102. generator.emit<Bytecode::Op::BitwiseAnd>(lhs_reg);
  103. break;
  104. case BinaryOp::BitwiseOr:
  105. generator.emit<Bytecode::Op::BitwiseOr>(lhs_reg);
  106. break;
  107. case BinaryOp::BitwiseXor:
  108. generator.emit<Bytecode::Op::BitwiseXor>(lhs_reg);
  109. break;
  110. case BinaryOp::LeftShift:
  111. generator.emit<Bytecode::Op::LeftShift>(lhs_reg);
  112. break;
  113. case BinaryOp::RightShift:
  114. generator.emit<Bytecode::Op::RightShift>(lhs_reg);
  115. break;
  116. case BinaryOp::UnsignedRightShift:
  117. generator.emit<Bytecode::Op::UnsignedRightShift>(lhs_reg);
  118. break;
  119. case BinaryOp::In:
  120. generator.emit<Bytecode::Op::In>(lhs_reg);
  121. break;
  122. case BinaryOp::InstanceOf:
  123. generator.emit<Bytecode::Op::InstanceOf>(lhs_reg);
  124. break;
  125. default:
  126. VERIFY_NOT_REACHED();
  127. }
  128. }
  129. void LogicalExpression::generate_bytecode(Bytecode::Generator& generator) const
  130. {
  131. m_lhs->generate_bytecode(generator);
  132. // lhs
  133. // jump op (true) end (false) rhs
  134. // rhs
  135. // jump always (true) end
  136. // end
  137. auto& rhs_block = generator.make_block();
  138. auto& end_block = generator.make_block();
  139. switch (m_op) {
  140. case LogicalOp::And:
  141. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  142. Bytecode::Label { rhs_block },
  143. Bytecode::Label { end_block });
  144. break;
  145. case LogicalOp::Or:
  146. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  147. Bytecode::Label { end_block },
  148. Bytecode::Label { rhs_block });
  149. break;
  150. case LogicalOp::NullishCoalescing:
  151. generator.emit<Bytecode::Op::JumpNullish>().set_targets(
  152. Bytecode::Label { rhs_block },
  153. Bytecode::Label { end_block });
  154. break;
  155. default:
  156. VERIFY_NOT_REACHED();
  157. }
  158. generator.switch_to_basic_block(rhs_block);
  159. m_rhs->generate_bytecode(generator);
  160. generator.emit<Bytecode::Op::Jump>().set_targets(
  161. Bytecode::Label { end_block },
  162. {});
  163. generator.switch_to_basic_block(end_block);
  164. }
  165. void UnaryExpression::generate_bytecode(Bytecode::Generator& generator) const
  166. {
  167. m_lhs->generate_bytecode(generator);
  168. switch (m_op) {
  169. case UnaryOp::BitwiseNot:
  170. generator.emit<Bytecode::Op::BitwiseNot>();
  171. break;
  172. case UnaryOp::Not:
  173. generator.emit<Bytecode::Op::Not>();
  174. break;
  175. case UnaryOp::Plus:
  176. generator.emit<Bytecode::Op::UnaryPlus>();
  177. break;
  178. case UnaryOp::Minus:
  179. generator.emit<Bytecode::Op::UnaryMinus>();
  180. break;
  181. case UnaryOp::Typeof:
  182. generator.emit<Bytecode::Op::Typeof>();
  183. break;
  184. case UnaryOp::Void:
  185. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  186. break;
  187. default:
  188. TODO();
  189. }
  190. }
  191. void NumericLiteral::generate_bytecode(Bytecode::Generator& generator) const
  192. {
  193. generator.emit<Bytecode::Op::LoadImmediate>(m_value);
  194. }
  195. void BooleanLiteral::generate_bytecode(Bytecode::Generator& generator) const
  196. {
  197. generator.emit<Bytecode::Op::LoadImmediate>(Value(m_value));
  198. }
  199. void NullLiteral::generate_bytecode(Bytecode::Generator& generator) const
  200. {
  201. generator.emit<Bytecode::Op::LoadImmediate>(js_null());
  202. }
  203. void BigIntLiteral::generate_bytecode(Bytecode::Generator& generator) const
  204. {
  205. generator.emit<Bytecode::Op::NewBigInt>(Crypto::SignedBigInteger::from_base(10, m_value.substring(0, m_value.length() - 1)));
  206. }
  207. void StringLiteral::generate_bytecode(Bytecode::Generator& generator) const
  208. {
  209. generator.emit<Bytecode::Op::NewString>(generator.intern_string(m_value));
  210. }
  211. void RegExpLiteral::generate_bytecode(Bytecode::Generator& generator) const
  212. {
  213. auto source_index = generator.intern_string(m_pattern);
  214. auto flags_index = generator.intern_string(m_flags);
  215. generator.emit<Bytecode::Op::NewRegExp>(source_index, flags_index);
  216. }
  217. void Identifier::generate_bytecode(Bytecode::Generator& generator) const
  218. {
  219. generator.emit<Bytecode::Op::GetVariable>(generator.intern_identifier(m_string));
  220. }
  221. void AssignmentExpression::generate_bytecode(Bytecode::Generator& generator) const
  222. {
  223. // FIXME: Implement this for BindingPatterns too.
  224. auto& lhs = m_lhs.get<NonnullRefPtr<Expression>>();
  225. if (m_op == AssignmentOp::Assignment) {
  226. m_rhs->generate_bytecode(generator);
  227. generator.emit_store_to_reference(lhs);
  228. return;
  229. }
  230. generator.emit_load_from_reference(lhs);
  231. Bytecode::BasicBlock* rhs_block_ptr { nullptr };
  232. Bytecode::BasicBlock* end_block_ptr { nullptr };
  233. // Logical assignments short circuit.
  234. if (m_op == AssignmentOp::AndAssignment) { // &&=
  235. rhs_block_ptr = &generator.make_block();
  236. end_block_ptr = &generator.make_block();
  237. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  238. Bytecode::Label { *rhs_block_ptr },
  239. Bytecode::Label { *end_block_ptr });
  240. } else if (m_op == AssignmentOp::OrAssignment) { // ||=
  241. rhs_block_ptr = &generator.make_block();
  242. end_block_ptr = &generator.make_block();
  243. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  244. Bytecode::Label { *end_block_ptr },
  245. Bytecode::Label { *rhs_block_ptr });
  246. } else if (m_op == AssignmentOp::NullishAssignment) { // ??=
  247. rhs_block_ptr = &generator.make_block();
  248. end_block_ptr = &generator.make_block();
  249. generator.emit<Bytecode::Op::JumpNullish>().set_targets(
  250. Bytecode::Label { *rhs_block_ptr },
  251. Bytecode::Label { *end_block_ptr });
  252. }
  253. if (rhs_block_ptr)
  254. generator.switch_to_basic_block(*rhs_block_ptr);
  255. // lhs_reg is a part of the rhs_block because the store isn't necessary
  256. // if the logical assignment condition fails.
  257. auto lhs_reg = generator.allocate_register();
  258. generator.emit<Bytecode::Op::Store>(lhs_reg);
  259. m_rhs->generate_bytecode(generator);
  260. switch (m_op) {
  261. case AssignmentOp::AdditionAssignment:
  262. generator.emit<Bytecode::Op::Add>(lhs_reg);
  263. break;
  264. case AssignmentOp::SubtractionAssignment:
  265. generator.emit<Bytecode::Op::Sub>(lhs_reg);
  266. break;
  267. case AssignmentOp::MultiplicationAssignment:
  268. generator.emit<Bytecode::Op::Mul>(lhs_reg);
  269. break;
  270. case AssignmentOp::DivisionAssignment:
  271. generator.emit<Bytecode::Op::Div>(lhs_reg);
  272. break;
  273. case AssignmentOp::ModuloAssignment:
  274. generator.emit<Bytecode::Op::Mod>(lhs_reg);
  275. break;
  276. case AssignmentOp::ExponentiationAssignment:
  277. generator.emit<Bytecode::Op::Exp>(lhs_reg);
  278. break;
  279. case AssignmentOp::BitwiseAndAssignment:
  280. generator.emit<Bytecode::Op::BitwiseAnd>(lhs_reg);
  281. break;
  282. case AssignmentOp::BitwiseOrAssignment:
  283. generator.emit<Bytecode::Op::BitwiseOr>(lhs_reg);
  284. break;
  285. case AssignmentOp::BitwiseXorAssignment:
  286. generator.emit<Bytecode::Op::BitwiseXor>(lhs_reg);
  287. break;
  288. case AssignmentOp::LeftShiftAssignment:
  289. generator.emit<Bytecode::Op::LeftShift>(lhs_reg);
  290. break;
  291. case AssignmentOp::RightShiftAssignment:
  292. generator.emit<Bytecode::Op::RightShift>(lhs_reg);
  293. break;
  294. case AssignmentOp::UnsignedRightShiftAssignment:
  295. generator.emit<Bytecode::Op::UnsignedRightShift>(lhs_reg);
  296. break;
  297. case AssignmentOp::AndAssignment:
  298. case AssignmentOp::OrAssignment:
  299. case AssignmentOp::NullishAssignment:
  300. break; // These are handled above.
  301. default:
  302. TODO();
  303. }
  304. generator.emit_store_to_reference(lhs);
  305. if (end_block_ptr) {
  306. generator.emit<Bytecode::Op::Jump>().set_targets(
  307. Bytecode::Label { *end_block_ptr },
  308. {});
  309. generator.switch_to_basic_block(*end_block_ptr);
  310. }
  311. }
  312. void WhileStatement::generate_bytecode(Bytecode::Generator& generator) const
  313. {
  314. // test
  315. // jump if_false (true) end (false) body
  316. // body
  317. // jump always (true) test
  318. // end
  319. auto& test_block = generator.make_block();
  320. auto& body_block = generator.make_block();
  321. auto& end_block = generator.make_block();
  322. // Init result register
  323. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  324. auto result_reg = generator.allocate_register();
  325. generator.emit<Bytecode::Op::Store>(result_reg);
  326. // jump to the test block
  327. generator.emit<Bytecode::Op::Jump>().set_targets(
  328. Bytecode::Label { test_block },
  329. {});
  330. generator.switch_to_basic_block(test_block);
  331. m_test->generate_bytecode(generator);
  332. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  333. Bytecode::Label { body_block },
  334. Bytecode::Label { end_block });
  335. generator.switch_to_basic_block(body_block);
  336. generator.begin_continuable_scope(Bytecode::Label { test_block });
  337. generator.begin_breakable_scope(Bytecode::Label { end_block });
  338. m_body->generate_bytecode(generator);
  339. if (!generator.is_current_block_terminated()) {
  340. generator.emit<Bytecode::Op::Jump>().set_targets(
  341. Bytecode::Label { test_block },
  342. {});
  343. generator.end_continuable_scope();
  344. generator.end_breakable_scope();
  345. generator.switch_to_basic_block(end_block);
  346. generator.emit<Bytecode::Op::Load>(result_reg);
  347. }
  348. }
  349. void DoWhileStatement::generate_bytecode(Bytecode::Generator& generator) const
  350. {
  351. // jump always (true) body
  352. // test
  353. // jump if_false (true) end (false) body
  354. // body
  355. // jump always (true) test
  356. // end
  357. auto& test_block = generator.make_block();
  358. auto& body_block = generator.make_block();
  359. auto& end_block = generator.make_block();
  360. // Init result register
  361. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  362. auto result_reg = generator.allocate_register();
  363. generator.emit<Bytecode::Op::Store>(result_reg);
  364. // jump to the body block
  365. generator.emit<Bytecode::Op::Jump>().set_targets(
  366. Bytecode::Label { body_block },
  367. {});
  368. generator.switch_to_basic_block(test_block);
  369. m_test->generate_bytecode(generator);
  370. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  371. Bytecode::Label { body_block },
  372. Bytecode::Label { end_block });
  373. generator.switch_to_basic_block(body_block);
  374. generator.begin_continuable_scope(Bytecode::Label { test_block });
  375. generator.begin_breakable_scope(Bytecode::Label { end_block });
  376. m_body->generate_bytecode(generator);
  377. if (!generator.is_current_block_terminated()) {
  378. generator.emit<Bytecode::Op::Jump>().set_targets(
  379. Bytecode::Label { test_block },
  380. {});
  381. generator.end_continuable_scope();
  382. generator.end_breakable_scope();
  383. generator.switch_to_basic_block(end_block);
  384. generator.emit<Bytecode::Op::Load>(result_reg);
  385. }
  386. }
  387. void ForStatement::generate_bytecode(Bytecode::Generator& generator) const
  388. {
  389. // init
  390. // jump always (true) test
  391. // test
  392. // jump if_true (true) body (false) end
  393. // body
  394. // jump always (true) update
  395. // update
  396. // jump always (true) test
  397. // end
  398. // If 'test' is missing, fuse the 'test' and 'body' basic blocks
  399. // If 'update' is missing, fuse the 'body' and 'update' basic blocks
  400. Bytecode::BasicBlock* test_block_ptr { nullptr };
  401. Bytecode::BasicBlock* body_block_ptr { nullptr };
  402. Bytecode::BasicBlock* update_block_ptr { nullptr };
  403. auto& end_block = generator.make_block();
  404. if (m_init)
  405. m_init->generate_bytecode(generator);
  406. body_block_ptr = &generator.make_block();
  407. if (m_test)
  408. test_block_ptr = &generator.make_block();
  409. else
  410. test_block_ptr = body_block_ptr;
  411. if (m_update)
  412. update_block_ptr = &generator.make_block();
  413. else
  414. update_block_ptr = body_block_ptr;
  415. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  416. auto result_reg = generator.allocate_register();
  417. generator.emit<Bytecode::Op::Store>(result_reg);
  418. generator.emit<Bytecode::Op::Jump>().set_targets(
  419. Bytecode::Label { *test_block_ptr },
  420. {});
  421. if (m_test) {
  422. generator.switch_to_basic_block(*test_block_ptr);
  423. m_test->generate_bytecode(generator);
  424. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  425. Bytecode::Label { *body_block_ptr },
  426. Bytecode::Label { end_block });
  427. }
  428. generator.switch_to_basic_block(*body_block_ptr);
  429. generator.begin_continuable_scope(Bytecode::Label { *update_block_ptr });
  430. generator.begin_breakable_scope(Bytecode::Label { end_block });
  431. m_body->generate_bytecode(generator);
  432. generator.end_continuable_scope();
  433. if (!generator.is_current_block_terminated()) {
  434. if (m_update) {
  435. generator.emit<Bytecode::Op::Jump>().set_targets(
  436. Bytecode::Label { *update_block_ptr },
  437. {});
  438. generator.switch_to_basic_block(*update_block_ptr);
  439. m_update->generate_bytecode(generator);
  440. }
  441. generator.emit<Bytecode::Op::Jump>().set_targets(
  442. Bytecode::Label { *test_block_ptr },
  443. {});
  444. generator.end_breakable_scope();
  445. generator.switch_to_basic_block(end_block);
  446. generator.emit<Bytecode::Op::Load>(result_reg);
  447. }
  448. }
  449. void ObjectExpression::generate_bytecode(Bytecode::Generator& generator) const
  450. {
  451. generator.emit<Bytecode::Op::NewObject>();
  452. if (m_properties.is_empty())
  453. return;
  454. auto object_reg = generator.allocate_register();
  455. generator.emit<Bytecode::Op::Store>(object_reg);
  456. for (auto& property : m_properties) {
  457. if (property.type() != ObjectProperty::Type::KeyValue)
  458. TODO();
  459. if (is<StringLiteral>(property.key())) {
  460. auto& string_literal = static_cast<StringLiteral const&>(property.key());
  461. Bytecode::IdentifierTableIndex key_name = generator.intern_identifier(string_literal.value());
  462. property.value().generate_bytecode(generator);
  463. generator.emit<Bytecode::Op::PutById>(object_reg, key_name);
  464. } else {
  465. property.key().generate_bytecode(generator);
  466. auto property_reg = generator.allocate_register();
  467. generator.emit<Bytecode::Op::Store>(property_reg);
  468. property.value().generate_bytecode(generator);
  469. generator.emit<Bytecode::Op::PutByValue>(object_reg, property_reg);
  470. }
  471. }
  472. generator.emit<Bytecode::Op::Load>(object_reg);
  473. }
  474. void ArrayExpression::generate_bytecode(Bytecode::Generator& generator) const
  475. {
  476. Vector<Bytecode::Register> element_regs;
  477. for (auto& element : m_elements) {
  478. if (element) {
  479. element->generate_bytecode(generator);
  480. if (is<SpreadExpression>(*element)) {
  481. TODO();
  482. continue;
  483. }
  484. } else {
  485. generator.emit<Bytecode::Op::LoadImmediate>(Value {});
  486. }
  487. auto element_reg = generator.allocate_register();
  488. generator.emit<Bytecode::Op::Store>(element_reg);
  489. element_regs.append(element_reg);
  490. }
  491. generator.emit_with_extra_register_slots<Bytecode::Op::NewArray>(element_regs.size(), element_regs);
  492. }
  493. void MemberExpression::generate_bytecode(Bytecode::Generator& generator) const
  494. {
  495. generator.emit_load_from_reference(*this);
  496. }
  497. void FunctionDeclaration::generate_bytecode(Bytecode::Generator&) const
  498. {
  499. }
  500. void FunctionExpression::generate_bytecode(Bytecode::Generator& generator) const
  501. {
  502. generator.emit<Bytecode::Op::NewFunction>(*this);
  503. }
  504. static void generate_binding_pattern_bytecode(Bytecode::Generator& generator, BindingPattern const& pattern, Bytecode::Register const& value_reg);
  505. static void generate_object_binding_pattern_bytecode(Bytecode::Generator& generator, BindingPattern const& pattern, Bytecode::Register const& value_reg)
  506. {
  507. Vector<Bytecode::Register> excluded_property_names;
  508. auto has_rest = false;
  509. if (pattern.entries.size() > 0)
  510. has_rest = pattern.entries[pattern.entries.size() - 1].is_rest;
  511. for (auto& [name, alias, initializer, is_rest] : pattern.entries) {
  512. if (is_rest) {
  513. VERIFY(name.has<NonnullRefPtr<Identifier>>());
  514. VERIFY(alias.has<Empty>());
  515. VERIFY(!initializer);
  516. auto identifier = name.get<NonnullRefPtr<Identifier>>()->string();
  517. auto interned_identifier = generator.intern_identifier(identifier);
  518. generator.emit_with_extra_register_slots<Bytecode::Op::CopyObjectExcludingProperties>(excluded_property_names.size(), value_reg, excluded_property_names);
  519. generator.emit<Bytecode::Op::SetVariable>(interned_identifier);
  520. return;
  521. }
  522. Bytecode::StringTableIndex name_index;
  523. if (name.has<NonnullRefPtr<Identifier>>()) {
  524. auto identifier = name.get<NonnullRefPtr<Identifier>>()->string();
  525. name_index = generator.intern_string(identifier);
  526. if (has_rest) {
  527. auto excluded_name_reg = generator.allocate_register();
  528. excluded_property_names.append(excluded_name_reg);
  529. generator.emit<Bytecode::Op::NewString>(name_index);
  530. generator.emit<Bytecode::Op::Store>(excluded_name_reg);
  531. }
  532. generator.emit<Bytecode::Op::Load>(value_reg);
  533. generator.emit<Bytecode::Op::GetById>(generator.intern_identifier(identifier));
  534. } else {
  535. auto expression = name.get<NonnullRefPtr<Expression>>();
  536. expression->generate_bytecode(generator);
  537. if (has_rest) {
  538. auto excluded_name_reg = generator.allocate_register();
  539. excluded_property_names.append(excluded_name_reg);
  540. generator.emit<Bytecode::Op::Store>(excluded_name_reg);
  541. }
  542. generator.emit<Bytecode::Op::GetByValue>(value_reg);
  543. }
  544. if (initializer) {
  545. auto& if_undefined_block = generator.make_block();
  546. auto& if_not_undefined_block = generator.make_block();
  547. generator.emit<Bytecode::Op::JumpUndefined>().set_targets(
  548. Bytecode::Label { if_undefined_block },
  549. Bytecode::Label { if_not_undefined_block });
  550. generator.switch_to_basic_block(if_undefined_block);
  551. initializer->generate_bytecode(generator);
  552. generator.emit<Bytecode::Op::Jump>().set_targets(
  553. Bytecode::Label { if_not_undefined_block },
  554. {});
  555. generator.switch_to_basic_block(if_not_undefined_block);
  556. }
  557. if (alias.has<NonnullRefPtr<BindingPattern>>()) {
  558. auto& binding_pattern = *alias.get<NonnullRefPtr<BindingPattern>>();
  559. auto nested_value_reg = generator.allocate_register();
  560. generator.emit<Bytecode::Op::Store>(nested_value_reg);
  561. generate_binding_pattern_bytecode(generator, binding_pattern, nested_value_reg);
  562. } else if (alias.has<Empty>()) {
  563. if (name.has<NonnullRefPtr<Expression>>()) {
  564. // This needs some sort of SetVariableByValue opcode, as it's a runtime binding
  565. TODO();
  566. }
  567. auto& identifier = alias.get<NonnullRefPtr<Identifier>>()->string();
  568. generator.emit<Bytecode::Op::SetVariable>(generator.intern_identifier(identifier));
  569. } else {
  570. auto& identifier = alias.get<NonnullRefPtr<Identifier>>()->string();
  571. generator.emit<Bytecode::Op::SetVariable>(generator.intern_identifier(identifier));
  572. }
  573. }
  574. }
  575. static void generate_array_binding_pattern_bytecode(Bytecode::Generator& generator, BindingPattern const& pattern, Bytecode::Register const& value_reg)
  576. {
  577. /*
  578. * Consider the following destructuring assignment:
  579. *
  580. * let [a, b, c, d, e] = o;
  581. *
  582. * It would be fairly trivial to just loop through this iterator, getting the value
  583. * at each step and assigning them to the binding sequentially. However, this is not
  584. * correct: once an iterator is exhausted, it must not be called again. This complicates
  585. * the bytecode. In order to accomplish this, we do the following:
  586. *
  587. * - Reserve a special boolean register which holds 'true' if the iterator is exhausted,
  588. * and false otherwise
  589. * - When we are retrieving the value which should be bound, we first check this register.
  590. * If it is 'true', we load undefined into the accumulator. Otherwise, we grab the next
  591. * value from the iterator and store it into the accumulator.
  592. *
  593. * Note that the is_exhausted register does not need to be loaded with false because the
  594. * first IteratorNext bytecode is _not_ proceeded by an exhausted check, as it is
  595. * unnecessary.
  596. */
  597. auto is_iterator_exhausted_register = generator.allocate_register();
  598. auto iterator_reg = generator.allocate_register();
  599. generator.emit<Bytecode::Op::Load>(value_reg);
  600. generator.emit<Bytecode::Op::GetIterator>();
  601. generator.emit<Bytecode::Op::Store>(iterator_reg);
  602. bool first = true;
  603. auto temp_iterator_result_reg = generator.allocate_register();
  604. auto assign_accumulator_to_alias = [&](auto& alias) {
  605. alias.visit(
  606. [&](Empty) {
  607. // This element is an elision
  608. },
  609. [&](NonnullRefPtr<Identifier> const& identifier) {
  610. auto interned_index = generator.intern_identifier(identifier->string());
  611. generator.emit<Bytecode::Op::SetVariable>(interned_index);
  612. },
  613. [&](NonnullRefPtr<BindingPattern> const& pattern) {
  614. // Store the accumulator value in a permanent register
  615. auto target_reg = generator.allocate_register();
  616. generator.emit<Bytecode::Op::Store>(target_reg);
  617. generate_binding_pattern_bytecode(generator, pattern, target_reg);
  618. },
  619. [&](NonnullRefPtr<MemberExpression> const&) {
  620. TODO();
  621. });
  622. };
  623. for (auto& [name, alias, initializer, is_rest] : pattern.entries) {
  624. VERIFY(name.has<Empty>());
  625. if (is_rest) {
  626. if (first) {
  627. // The iterator has not been called, and is thus known to be not exhausted
  628. generator.emit<Bytecode::Op::Load>(iterator_reg);
  629. generator.emit<Bytecode::Op::IteratorToArray>();
  630. } else {
  631. auto& if_exhausted_block = generator.make_block();
  632. auto& if_not_exhausted_block = generator.make_block();
  633. auto& continuation_block = generator.make_block();
  634. generator.emit<Bytecode::Op::Load>(is_iterator_exhausted_register);
  635. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  636. Bytecode::Label { if_exhausted_block },
  637. Bytecode::Label { if_not_exhausted_block });
  638. generator.switch_to_basic_block(if_exhausted_block);
  639. generator.emit<Bytecode::Op::NewArray>();
  640. generator.emit<Bytecode::Op::Jump>().set_targets(
  641. Bytecode::Label { continuation_block },
  642. {});
  643. generator.switch_to_basic_block(if_not_exhausted_block);
  644. generator.emit<Bytecode::Op::Load>(iterator_reg);
  645. generator.emit<Bytecode::Op::IteratorToArray>();
  646. generator.emit<Bytecode::Op::Jump>().set_targets(
  647. Bytecode::Label { continuation_block },
  648. {});
  649. generator.switch_to_basic_block(continuation_block);
  650. }
  651. assign_accumulator_to_alias(alias);
  652. return;
  653. }
  654. // In the first iteration of the loop, a few things are true which can save
  655. // us some bytecode:
  656. // - the iterator result is still in the accumulator, so we can avoid a load
  657. // - the iterator is not yet exhausted, which can save us a jump and some
  658. // creation
  659. auto& iterator_is_exhausted_block = generator.make_block();
  660. if (!first) {
  661. auto& iterator_is_not_exhausted_block = generator.make_block();
  662. generator.emit<Bytecode::Op::Load>(is_iterator_exhausted_register);
  663. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  664. Bytecode::Label { iterator_is_exhausted_block },
  665. Bytecode::Label { iterator_is_not_exhausted_block });
  666. generator.switch_to_basic_block(iterator_is_not_exhausted_block);
  667. generator.emit<Bytecode::Op::Load>(iterator_reg);
  668. }
  669. generator.emit<Bytecode::Op::IteratorNext>();
  670. generator.emit<Bytecode::Op::Store>(temp_iterator_result_reg);
  671. generator.emit<Bytecode::Op::IteratorResultDone>();
  672. generator.emit<Bytecode::Op::Store>(is_iterator_exhausted_register);
  673. // We still have to check for exhaustion here. If the iterator is exhausted,
  674. // we need to bail before trying to get the value
  675. auto& no_bail_block = generator.make_block();
  676. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  677. Bytecode::Label { iterator_is_exhausted_block },
  678. Bytecode::Label { no_bail_block });
  679. generator.switch_to_basic_block(no_bail_block);
  680. // Get the next value in the iterator
  681. generator.emit<Bytecode::Op::Load>(temp_iterator_result_reg);
  682. generator.emit<Bytecode::Op::IteratorResultValue>();
  683. auto& create_binding_block = generator.make_block();
  684. generator.emit<Bytecode::Op::Jump>().set_targets(
  685. Bytecode::Label { create_binding_block },
  686. {});
  687. // The iterator is exhausted, so we just load undefined and continue binding
  688. generator.switch_to_basic_block(iterator_is_exhausted_block);
  689. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  690. generator.emit<Bytecode::Op::Jump>().set_targets(
  691. Bytecode::Label { create_binding_block },
  692. {});
  693. // Create the actual binding. The value which this entry must bind is now in the
  694. // accumulator. We can proceed, processing the alias as a nested destructuring
  695. // pattern if necessary.
  696. generator.switch_to_basic_block(create_binding_block);
  697. assign_accumulator_to_alias(alias);
  698. first = false;
  699. }
  700. }
  701. static void generate_binding_pattern_bytecode(Bytecode::Generator& generator, BindingPattern const& pattern, Bytecode::Register const& value_reg)
  702. {
  703. if (pattern.kind == BindingPattern::Kind::Object) {
  704. generate_object_binding_pattern_bytecode(generator, pattern, value_reg);
  705. } else {
  706. generate_array_binding_pattern_bytecode(generator, pattern, value_reg);
  707. }
  708. };
  709. void VariableDeclaration::generate_bytecode(Bytecode::Generator& generator) const
  710. {
  711. for (auto& declarator : m_declarations) {
  712. if (declarator.init())
  713. declarator.init()->generate_bytecode(generator);
  714. else
  715. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  716. declarator.target().visit(
  717. [&](NonnullRefPtr<Identifier> const& id) {
  718. generator.emit<Bytecode::Op::SetVariable>(generator.intern_identifier(id->string()));
  719. },
  720. [&](NonnullRefPtr<BindingPattern> const& pattern) {
  721. auto value_register = generator.allocate_register();
  722. generator.emit<Bytecode::Op::Store>(value_register);
  723. generate_binding_pattern_bytecode(generator, pattern, value_register);
  724. });
  725. }
  726. }
  727. void CallExpression::generate_bytecode(Bytecode::Generator& generator) const
  728. {
  729. auto callee_reg = generator.allocate_register();
  730. auto this_reg = generator.allocate_register();
  731. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  732. generator.emit<Bytecode::Op::Store>(this_reg);
  733. if (is<NewExpression>(this)) {
  734. m_callee->generate_bytecode(generator);
  735. generator.emit<Bytecode::Op::Store>(callee_reg);
  736. } else if (is<SuperExpression>(*m_callee)) {
  737. TODO();
  738. } else if (is<MemberExpression>(*m_callee)) {
  739. auto& member_expression = static_cast<const MemberExpression&>(*m_callee);
  740. if (is<SuperExpression>(member_expression.object())) {
  741. TODO();
  742. } else {
  743. member_expression.object().generate_bytecode(generator);
  744. generator.emit<Bytecode::Op::Store>(this_reg);
  745. if (member_expression.is_computed()) {
  746. member_expression.property().generate_bytecode(generator);
  747. generator.emit<Bytecode::Op::GetByValue>(this_reg);
  748. } else {
  749. auto identifier_table_ref = generator.intern_identifier(verify_cast<Identifier>(member_expression.property()).string());
  750. generator.emit<Bytecode::Op::GetById>(identifier_table_ref);
  751. }
  752. generator.emit<Bytecode::Op::Store>(callee_reg);
  753. }
  754. } else {
  755. // FIXME: this = global object in sloppy mode.
  756. m_callee->generate_bytecode(generator);
  757. generator.emit<Bytecode::Op::Store>(callee_reg);
  758. }
  759. Vector<Bytecode::Register> argument_registers;
  760. for (auto& arg : m_arguments) {
  761. arg.value->generate_bytecode(generator);
  762. auto arg_reg = generator.allocate_register();
  763. generator.emit<Bytecode::Op::Store>(arg_reg);
  764. argument_registers.append(arg_reg);
  765. }
  766. Bytecode::Op::Call::CallType call_type;
  767. if (is<NewExpression>(*this)) {
  768. call_type = Bytecode::Op::Call::CallType::Construct;
  769. } else {
  770. call_type = Bytecode::Op::Call::CallType::Call;
  771. }
  772. generator.emit_with_extra_register_slots<Bytecode::Op::Call>(argument_registers.size(), call_type, callee_reg, this_reg, argument_registers);
  773. }
  774. void ReturnStatement::generate_bytecode(Bytecode::Generator& generator) const
  775. {
  776. if (m_argument)
  777. m_argument->generate_bytecode(generator);
  778. if (generator.is_in_generator_or_async_function())
  779. generator.emit<Bytecode::Op::Yield>(nullptr);
  780. else
  781. generator.emit<Bytecode::Op::Return>();
  782. }
  783. void YieldExpression::generate_bytecode(Bytecode::Generator& generator) const
  784. {
  785. VERIFY(generator.is_in_generator_function());
  786. if (m_is_yield_from)
  787. TODO();
  788. if (m_argument)
  789. m_argument->generate_bytecode(generator);
  790. auto& continuation_block = generator.make_block();
  791. generator.emit<Bytecode::Op::Yield>(Bytecode::Label { continuation_block });
  792. generator.switch_to_basic_block(continuation_block);
  793. }
  794. void IfStatement::generate_bytecode(Bytecode::Generator& generator) const
  795. {
  796. // test
  797. // jump if_true (true) true (false) false
  798. // true
  799. // jump always (true) end
  800. // false
  801. // jump always (true) end
  802. // end
  803. auto& true_block = generator.make_block();
  804. auto& false_block = generator.make_block();
  805. m_predicate->generate_bytecode(generator);
  806. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  807. Bytecode::Label { true_block },
  808. Bytecode::Label { false_block });
  809. Bytecode::Op::Jump* true_block_jump { nullptr };
  810. generator.switch_to_basic_block(true_block);
  811. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  812. m_consequent->generate_bytecode(generator);
  813. if (!generator.is_current_block_terminated())
  814. true_block_jump = &generator.emit<Bytecode::Op::Jump>();
  815. generator.switch_to_basic_block(false_block);
  816. auto& end_block = generator.make_block();
  817. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  818. if (m_alternate)
  819. m_alternate->generate_bytecode(generator);
  820. if (!generator.is_current_block_terminated())
  821. generator.emit<Bytecode::Op::Jump>().set_targets(Bytecode::Label { end_block }, {});
  822. if (true_block_jump)
  823. true_block_jump->set_targets(Bytecode::Label { end_block }, {});
  824. generator.switch_to_basic_block(end_block);
  825. }
  826. void ContinueStatement::generate_bytecode(Bytecode::Generator& generator) const
  827. {
  828. generator.emit<Bytecode::Op::Jump>().set_targets(
  829. generator.nearest_continuable_scope(),
  830. {});
  831. }
  832. void DebuggerStatement::generate_bytecode(Bytecode::Generator&) const
  833. {
  834. }
  835. void ConditionalExpression::generate_bytecode(Bytecode::Generator& generator) const
  836. {
  837. // test
  838. // jump if_true (true) true (false) false
  839. // true
  840. // jump always (true) end
  841. // false
  842. // jump always (true) end
  843. // end
  844. auto& true_block = generator.make_block();
  845. auto& false_block = generator.make_block();
  846. auto& end_block = generator.make_block();
  847. m_test->generate_bytecode(generator);
  848. generator.emit<Bytecode::Op::JumpConditional>().set_targets(
  849. Bytecode::Label { true_block },
  850. Bytecode::Label { false_block });
  851. generator.switch_to_basic_block(true_block);
  852. m_consequent->generate_bytecode(generator);
  853. generator.emit<Bytecode::Op::Jump>().set_targets(
  854. Bytecode::Label { end_block },
  855. {});
  856. generator.switch_to_basic_block(false_block);
  857. m_alternate->generate_bytecode(generator);
  858. generator.emit<Bytecode::Op::Jump>().set_targets(
  859. Bytecode::Label { end_block },
  860. {});
  861. generator.switch_to_basic_block(end_block);
  862. }
  863. void SequenceExpression::generate_bytecode(Bytecode::Generator& generator) const
  864. {
  865. for (auto& expression : m_expressions)
  866. expression.generate_bytecode(generator);
  867. }
  868. void TemplateLiteral::generate_bytecode(Bytecode::Generator& generator) const
  869. {
  870. auto string_reg = generator.allocate_register();
  871. for (size_t i = 0; i < m_expressions.size(); i++) {
  872. m_expressions[i].generate_bytecode(generator);
  873. if (i == 0) {
  874. generator.emit<Bytecode::Op::Store>(string_reg);
  875. } else {
  876. generator.emit<Bytecode::Op::ConcatString>(string_reg);
  877. }
  878. }
  879. generator.emit<Bytecode::Op::Load>(string_reg);
  880. }
  881. void TaggedTemplateLiteral::generate_bytecode(Bytecode::Generator& generator) const
  882. {
  883. m_tag->generate_bytecode(generator);
  884. auto tag_reg = generator.allocate_register();
  885. generator.emit<Bytecode::Op::Store>(tag_reg);
  886. Vector<Bytecode::Register> string_regs;
  887. auto& expressions = m_template_literal->expressions();
  888. for (size_t i = 0; i < expressions.size(); ++i) {
  889. if (i % 2 != 0)
  890. continue;
  891. expressions[i].generate_bytecode(generator);
  892. auto string_reg = generator.allocate_register();
  893. generator.emit<Bytecode::Op::Store>(string_reg);
  894. string_regs.append(string_reg);
  895. }
  896. generator.emit_with_extra_register_slots<Bytecode::Op::NewArray>(string_regs.size(), string_regs);
  897. auto strings_reg = generator.allocate_register();
  898. generator.emit<Bytecode::Op::Store>(strings_reg);
  899. Vector<Bytecode::Register> argument_regs;
  900. argument_regs.append(strings_reg);
  901. for (size_t i = 0; i < expressions.size(); ++i) {
  902. if (i % 2 == 0)
  903. continue;
  904. expressions[i].generate_bytecode(generator);
  905. auto string_reg = generator.allocate_register();
  906. generator.emit<Bytecode::Op::Store>(string_reg);
  907. argument_regs.append(string_reg);
  908. }
  909. Vector<Bytecode::Register> raw_string_regs;
  910. for (auto& raw_string : m_template_literal->raw_strings()) {
  911. raw_string.generate_bytecode(generator);
  912. auto raw_string_reg = generator.allocate_register();
  913. generator.emit<Bytecode::Op::Store>(raw_string_reg);
  914. raw_string_regs.append(raw_string_reg);
  915. }
  916. generator.emit_with_extra_register_slots<Bytecode::Op::NewArray>(raw_string_regs.size(), raw_string_regs);
  917. auto raw_strings_reg = generator.allocate_register();
  918. generator.emit<Bytecode::Op::Store>(raw_strings_reg);
  919. generator.emit<Bytecode::Op::Load>(strings_reg);
  920. generator.emit<Bytecode::Op::PutById>(raw_strings_reg, generator.intern_identifier("raw"));
  921. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  922. auto this_reg = generator.allocate_register();
  923. generator.emit<Bytecode::Op::Store>(this_reg);
  924. generator.emit_with_extra_register_slots<Bytecode::Op::Call>(argument_regs.size(), Bytecode::Op::Call::CallType::Call, tag_reg, this_reg, move(argument_regs));
  925. }
  926. void UpdateExpression::generate_bytecode(Bytecode::Generator& generator) const
  927. {
  928. generator.emit_load_from_reference(*m_argument);
  929. Optional<Bytecode::Register> previous_value_for_postfix_reg;
  930. if (!m_prefixed) {
  931. previous_value_for_postfix_reg = generator.allocate_register();
  932. generator.emit<Bytecode::Op::Store>(*previous_value_for_postfix_reg);
  933. }
  934. if (m_op == UpdateOp::Increment)
  935. generator.emit<Bytecode::Op::Increment>();
  936. else
  937. generator.emit<Bytecode::Op::Decrement>();
  938. generator.emit_store_to_reference(*m_argument);
  939. if (!m_prefixed)
  940. generator.emit<Bytecode::Op::Load>(*previous_value_for_postfix_reg);
  941. }
  942. void ThrowStatement::generate_bytecode(Bytecode::Generator& generator) const
  943. {
  944. m_argument->generate_bytecode(generator);
  945. generator.emit<Bytecode::Op::Throw>();
  946. }
  947. void BreakStatement::generate_bytecode(Bytecode::Generator& generator) const
  948. {
  949. generator.emit<Bytecode::Op::Jump>().set_targets(
  950. generator.nearest_breakable_scope(),
  951. {});
  952. }
  953. void TryStatement::generate_bytecode(Bytecode::Generator& generator) const
  954. {
  955. auto& saved_block = generator.current_block();
  956. Optional<Bytecode::Label> handler_target;
  957. Optional<Bytecode::Label> finalizer_target;
  958. Bytecode::BasicBlock* next_block { nullptr };
  959. if (m_finalizer) {
  960. auto& finalizer_block = generator.make_block();
  961. generator.switch_to_basic_block(finalizer_block);
  962. m_finalizer->generate_bytecode(generator);
  963. if (!generator.is_current_block_terminated()) {
  964. next_block = &generator.make_block();
  965. auto next_target = Bytecode::Label { *next_block };
  966. generator.emit<Bytecode::Op::ContinuePendingUnwind>(next_target);
  967. }
  968. finalizer_target = Bytecode::Label { finalizer_block };
  969. }
  970. if (m_handler) {
  971. auto& handler_block = generator.make_block();
  972. generator.switch_to_basic_block(handler_block);
  973. if (!m_finalizer)
  974. generator.emit<Bytecode::Op::LeaveUnwindContext>();
  975. m_handler->parameter().visit(
  976. [&](FlyString const& parameter) {
  977. if (!parameter.is_empty()) {
  978. // FIXME: We need a separate DeclarativeEnvironment here
  979. generator.emit<Bytecode::Op::SetVariable>(generator.intern_identifier(parameter));
  980. }
  981. },
  982. [&](NonnullRefPtr<BindingPattern> const&) {
  983. // FIXME: Implement this path when the above DeclarativeEnvironment issue is dealt with.
  984. TODO();
  985. });
  986. m_handler->body().generate_bytecode(generator);
  987. handler_target = Bytecode::Label { handler_block };
  988. if (!generator.is_current_block_terminated()) {
  989. if (m_finalizer) {
  990. generator.emit<Bytecode::Op::LeaveUnwindContext>();
  991. generator.emit<Bytecode::Op::Jump>(finalizer_target);
  992. } else {
  993. VERIFY(!next_block);
  994. next_block = &generator.make_block();
  995. auto next_target = Bytecode::Label { *next_block };
  996. generator.emit<Bytecode::Op::Jump>(next_target);
  997. }
  998. }
  999. }
  1000. auto& target_block = generator.make_block();
  1001. generator.switch_to_basic_block(saved_block);
  1002. generator.emit<Bytecode::Op::EnterUnwindContext>(Bytecode::Label { target_block }, handler_target, finalizer_target);
  1003. generator.switch_to_basic_block(target_block);
  1004. m_block->generate_bytecode(generator);
  1005. if (!generator.is_current_block_terminated()) {
  1006. if (m_finalizer) {
  1007. generator.emit<Bytecode::Op::Jump>(finalizer_target);
  1008. } else {
  1009. auto& block = generator.make_block();
  1010. generator.emit<Bytecode::Op::FinishUnwind>(Bytecode::Label { block });
  1011. next_block = &block;
  1012. }
  1013. }
  1014. generator.switch_to_basic_block(next_block ? *next_block : saved_block);
  1015. }
  1016. void SwitchStatement::generate_bytecode(Bytecode::Generator& generator) const
  1017. {
  1018. auto discriminant_reg = generator.allocate_register();
  1019. m_discriminant->generate_bytecode(generator);
  1020. generator.emit<Bytecode::Op::Store>(discriminant_reg);
  1021. Vector<Bytecode::BasicBlock&> case_blocks;
  1022. Bytecode::BasicBlock* default_block { nullptr };
  1023. Bytecode::BasicBlock* next_test_block = &generator.make_block();
  1024. generator.emit<Bytecode::Op::Jump>().set_targets(Bytecode::Label { *next_test_block }, {});
  1025. for (auto& switch_case : m_cases) {
  1026. auto& case_block = generator.make_block();
  1027. if (switch_case.test()) {
  1028. generator.switch_to_basic_block(*next_test_block);
  1029. switch_case.test()->generate_bytecode(generator);
  1030. generator.emit<Bytecode::Op::StrictlyEquals>(discriminant_reg);
  1031. next_test_block = &generator.make_block();
  1032. generator.emit<Bytecode::Op::JumpConditional>().set_targets(Bytecode::Label { case_block }, Bytecode::Label { *next_test_block });
  1033. } else {
  1034. default_block = &case_block;
  1035. }
  1036. case_blocks.append(case_block);
  1037. }
  1038. generator.switch_to_basic_block(*next_test_block);
  1039. auto& end_block = generator.make_block();
  1040. if (default_block != nullptr) {
  1041. generator.emit<Bytecode::Op::Jump>().set_targets(Bytecode::Label { *default_block }, {});
  1042. } else {
  1043. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  1044. generator.emit<Bytecode::Op::Jump>().set_targets(Bytecode::Label { end_block }, {});
  1045. }
  1046. auto current_block = case_blocks.begin();
  1047. generator.begin_breakable_scope(Bytecode::Label { end_block });
  1048. for (auto& switch_case : m_cases) {
  1049. generator.switch_to_basic_block(*current_block);
  1050. generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
  1051. for (auto& statement : switch_case.children()) {
  1052. statement.generate_bytecode(generator);
  1053. }
  1054. if (!generator.is_current_block_terminated()) {
  1055. auto next_block = current_block;
  1056. next_block++;
  1057. if (next_block.is_end()) {
  1058. generator.emit<Bytecode::Op::Jump>().set_targets(Bytecode::Label { end_block }, {});
  1059. } else {
  1060. generator.emit<Bytecode::Op::Jump>().set_targets(Bytecode::Label { *next_block }, {});
  1061. }
  1062. }
  1063. current_block++;
  1064. }
  1065. generator.end_breakable_scope();
  1066. generator.switch_to_basic_block(end_block);
  1067. }
  1068. void ClassDeclaration::generate_bytecode(Bytecode::Generator& generator) const
  1069. {
  1070. generator.emit<Bytecode::Op::NewClass>(m_class_expression);
  1071. generator.emit<Bytecode::Op::SetVariable>(generator.intern_identifier(m_class_expression.ptr()->name()));
  1072. }
  1073. void ThisExpression::generate_bytecode(Bytecode::Generator& generator) const
  1074. {
  1075. generator.emit<Bytecode::Op::ResolveThisBinding>();
  1076. }
  1077. void AwaitExpression::generate_bytecode(Bytecode::Generator& generator) const
  1078. {
  1079. VERIFY(generator.is_in_async_function());
  1080. // Transform `await expr` to `yield expr`
  1081. m_argument->generate_bytecode(generator);
  1082. auto& continuation_block = generator.make_block();
  1083. generator.emit<Bytecode::Op::Yield>(Bytecode::Label { continuation_block });
  1084. generator.switch_to_basic_block(continuation_block);
  1085. }
  1086. }