ASTCodegen.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /*
  2. * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <LibJS/AST.h>
  7. #include <LibJS/Bytecode/Generator.h>
  8. #include <LibJS/Bytecode/Instruction.h>
  9. #include <LibJS/Bytecode/Op.h>
  10. #include <LibJS/Bytecode/Register.h>
  11. namespace JS {
  12. Optional<Bytecode::Register> ASTNode::generate_bytecode(Bytecode::Generator&) const
  13. {
  14. dbgln("Missing generate_bytecode()");
  15. TODO();
  16. }
  17. Optional<Bytecode::Register> ScopeNode::generate_bytecode(Bytecode::Generator& generator) const
  18. {
  19. for (auto& child : children()) {
  20. [[maybe_unused]] auto reg = child.generate_bytecode(generator);
  21. }
  22. return {};
  23. }
  24. Optional<Bytecode::Register> ExpressionStatement::generate_bytecode(Bytecode::Generator& generator) const
  25. {
  26. return m_expression->generate_bytecode(generator);
  27. }
  28. Optional<Bytecode::Register> BinaryExpression::generate_bytecode(Bytecode::Generator& generator) const
  29. {
  30. auto lhs_reg = m_lhs->generate_bytecode(generator);
  31. auto rhs_reg = m_rhs->generate_bytecode(generator);
  32. VERIFY(lhs_reg.has_value());
  33. VERIFY(rhs_reg.has_value());
  34. auto dst_reg = generator.allocate_register();
  35. switch (m_op) {
  36. case BinaryOp::Addition:
  37. generator.emit<Bytecode::Op::Add>(dst_reg, *lhs_reg, *rhs_reg);
  38. return dst_reg;
  39. case BinaryOp::Subtraction:
  40. generator.emit<Bytecode::Op::Sub>(dst_reg, *lhs_reg, *rhs_reg);
  41. return dst_reg;
  42. case BinaryOp::LessThan:
  43. generator.emit<Bytecode::Op::LessThan>(dst_reg, *lhs_reg, *rhs_reg);
  44. return dst_reg;
  45. case BinaryOp::AbstractInequals:
  46. generator.emit<Bytecode::Op::AbstractInequals>(dst_reg, *lhs_reg, *rhs_reg);
  47. return dst_reg;
  48. default:
  49. TODO();
  50. }
  51. }
  52. Optional<Bytecode::Register> NumericLiteral::generate_bytecode(Bytecode::Generator& generator) const
  53. {
  54. auto dst = generator.allocate_register();
  55. generator.emit<Bytecode::Op::Load>(dst, m_value);
  56. return dst;
  57. }
  58. Optional<Bytecode::Register> StringLiteral::generate_bytecode(Bytecode::Generator& generator) const
  59. {
  60. auto dst = generator.allocate_register();
  61. generator.emit<Bytecode::Op::NewString>(dst, m_value);
  62. return dst;
  63. }
  64. Optional<Bytecode::Register> Identifier::generate_bytecode(Bytecode::Generator& generator) const
  65. {
  66. auto reg = generator.allocate_register();
  67. generator.emit<Bytecode::Op::GetVariable>(reg, m_string);
  68. return reg;
  69. }
  70. Optional<Bytecode::Register> AssignmentExpression::generate_bytecode(Bytecode::Generator& generator) const
  71. {
  72. if (is<Identifier>(*m_lhs)) {
  73. auto& identifier = static_cast<Identifier const&>(*m_lhs);
  74. auto rhs_reg = m_rhs->generate_bytecode(generator);
  75. VERIFY(rhs_reg.has_value());
  76. generator.emit<Bytecode::Op::SetVariable>(identifier.string(), *rhs_reg);
  77. return rhs_reg;
  78. }
  79. TODO();
  80. }
  81. Optional<Bytecode::Register> WhileStatement::generate_bytecode(Bytecode::Generator& generator) const
  82. {
  83. auto test_label = generator.make_label();
  84. auto test_result_reg = m_test->generate_bytecode(generator);
  85. VERIFY(test_result_reg.has_value());
  86. auto& test_jump = generator.emit<Bytecode::Op::JumpIfFalse>(*test_result_reg);
  87. auto body_result_reg = m_body->generate_bytecode(generator);
  88. generator.emit<Bytecode::Op::Jump>(test_label);
  89. test_jump.set_target(generator.make_label());
  90. return body_result_reg;
  91. }
  92. Optional<Bytecode::Register> DoWhileStatement::generate_bytecode(Bytecode::Generator& generator) const
  93. {
  94. auto head_label = generator.make_label();
  95. auto body_result_reg = m_body->generate_bytecode(generator);
  96. auto test_result_reg = m_test->generate_bytecode(generator);
  97. VERIFY(test_result_reg.has_value());
  98. generator.emit<Bytecode::Op::JumpIfTrue>(*test_result_reg, head_label);
  99. return body_result_reg;
  100. }
  101. Optional<Bytecode::Register> ObjectExpression::generate_bytecode(Bytecode::Generator& generator) const
  102. {
  103. auto reg = generator.allocate_register();
  104. generator.emit<Bytecode::Op::NewObject>(reg);
  105. if (!m_properties.is_empty()) {
  106. TODO();
  107. }
  108. return reg;
  109. }
  110. }