ASTCodegen.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  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. generator.emit<Bytecode::Op::EnterScope>(*this);
  20. for (auto& child : children()) {
  21. [[maybe_unused]] auto reg = child.generate_bytecode(generator);
  22. }
  23. return {};
  24. }
  25. Optional<Bytecode::Register> ExpressionStatement::generate_bytecode(Bytecode::Generator& generator) const
  26. {
  27. return m_expression->generate_bytecode(generator);
  28. }
  29. Optional<Bytecode::Register> BinaryExpression::generate_bytecode(Bytecode::Generator& generator) const
  30. {
  31. auto lhs_reg = m_lhs->generate_bytecode(generator);
  32. auto rhs_reg = m_rhs->generate_bytecode(generator);
  33. VERIFY(lhs_reg.has_value());
  34. VERIFY(rhs_reg.has_value());
  35. auto dst_reg = generator.allocate_register();
  36. switch (m_op) {
  37. case BinaryOp::Addition:
  38. generator.emit<Bytecode::Op::Add>(dst_reg, *lhs_reg, *rhs_reg);
  39. return dst_reg;
  40. case BinaryOp::Subtraction:
  41. generator.emit<Bytecode::Op::Sub>(dst_reg, *lhs_reg, *rhs_reg);
  42. return dst_reg;
  43. case BinaryOp::LessThan:
  44. generator.emit<Bytecode::Op::LessThan>(dst_reg, *lhs_reg, *rhs_reg);
  45. return dst_reg;
  46. case BinaryOp::AbstractInequals:
  47. generator.emit<Bytecode::Op::AbstractInequals>(dst_reg, *lhs_reg, *rhs_reg);
  48. return dst_reg;
  49. default:
  50. TODO();
  51. }
  52. }
  53. Optional<Bytecode::Register> NumericLiteral::generate_bytecode(Bytecode::Generator& generator) const
  54. {
  55. auto dst = generator.allocate_register();
  56. generator.emit<Bytecode::Op::Load>(dst, m_value);
  57. return dst;
  58. }
  59. Optional<Bytecode::Register> StringLiteral::generate_bytecode(Bytecode::Generator& generator) const
  60. {
  61. auto dst = generator.allocate_register();
  62. generator.emit<Bytecode::Op::NewString>(dst, m_value);
  63. return dst;
  64. }
  65. Optional<Bytecode::Register> Identifier::generate_bytecode(Bytecode::Generator& generator) const
  66. {
  67. auto reg = generator.allocate_register();
  68. generator.emit<Bytecode::Op::GetVariable>(reg, m_string);
  69. return reg;
  70. }
  71. Optional<Bytecode::Register> AssignmentExpression::generate_bytecode(Bytecode::Generator& generator) const
  72. {
  73. if (is<Identifier>(*m_lhs)) {
  74. auto& identifier = static_cast<Identifier const&>(*m_lhs);
  75. auto rhs_reg = m_rhs->generate_bytecode(generator);
  76. VERIFY(rhs_reg.has_value());
  77. generator.emit<Bytecode::Op::SetVariable>(identifier.string(), *rhs_reg);
  78. return rhs_reg;
  79. }
  80. if (is<MemberExpression>(*m_lhs)) {
  81. auto& expression = static_cast<MemberExpression const&>(*m_lhs);
  82. auto object_reg = expression.object().generate_bytecode(generator);
  83. if (expression.is_computed()) {
  84. TODO();
  85. } else {
  86. VERIFY(is<Identifier>(expression.property()));
  87. auto rhs_reg = m_rhs->generate_bytecode(generator);
  88. generator.emit<Bytecode::Op::PutById>(*object_reg, static_cast<Identifier const&>(expression.property()).string(), *rhs_reg);
  89. return rhs_reg;
  90. }
  91. }
  92. TODO();
  93. }
  94. Optional<Bytecode::Register> WhileStatement::generate_bytecode(Bytecode::Generator& generator) const
  95. {
  96. auto test_label = generator.make_label();
  97. auto test_result_reg = m_test->generate_bytecode(generator);
  98. VERIFY(test_result_reg.has_value());
  99. auto& test_jump = generator.emit<Bytecode::Op::JumpIfFalse>(*test_result_reg);
  100. auto body_result_reg = m_body->generate_bytecode(generator);
  101. generator.emit<Bytecode::Op::Jump>(test_label);
  102. test_jump.set_target(generator.make_label());
  103. return body_result_reg;
  104. }
  105. Optional<Bytecode::Register> DoWhileStatement::generate_bytecode(Bytecode::Generator& generator) const
  106. {
  107. auto head_label = generator.make_label();
  108. auto body_result_reg = m_body->generate_bytecode(generator);
  109. auto test_result_reg = m_test->generate_bytecode(generator);
  110. VERIFY(test_result_reg.has_value());
  111. generator.emit<Bytecode::Op::JumpIfTrue>(*test_result_reg, head_label);
  112. return body_result_reg;
  113. }
  114. Optional<Bytecode::Register> ObjectExpression::generate_bytecode(Bytecode::Generator& generator) const
  115. {
  116. auto reg = generator.allocate_register();
  117. generator.emit<Bytecode::Op::NewObject>(reg);
  118. if (!m_properties.is_empty()) {
  119. TODO();
  120. }
  121. return reg;
  122. }
  123. Optional<Bytecode::Register> MemberExpression::generate_bytecode(Bytecode::Generator& generator) const
  124. {
  125. auto object_reg = object().generate_bytecode(generator);
  126. if (is_computed()) {
  127. TODO();
  128. } else {
  129. VERIFY(is<Identifier>(property()));
  130. auto dst_reg = generator.allocate_register();
  131. generator.emit<Bytecode::Op::GetById>(dst_reg, *object_reg, static_cast<Identifier const&>(property()).string());
  132. return dst_reg;
  133. }
  134. }
  135. Optional<Bytecode::Register> FunctionDeclaration::generate_bytecode(Bytecode::Generator&) const
  136. {
  137. return {};
  138. }
  139. Optional<Bytecode::Register> CallExpression::generate_bytecode(Bytecode::Generator& generator) const
  140. {
  141. auto callee_reg = m_callee->generate_bytecode(generator);
  142. // FIXME: Load the correct 'this' value into 'this_reg'.
  143. auto this_reg = generator.allocate_register();
  144. generator.emit<Bytecode::Op::Load>(this_reg, js_undefined());
  145. Vector<Bytecode::Register> argument_registers;
  146. for (auto& arg : m_arguments)
  147. argument_registers.append(*arg.value->generate_bytecode(generator));
  148. auto dst_reg = generator.allocate_register();
  149. generator.emit<Bytecode::Op::Call>(dst_reg, *callee_reg, this_reg, argument_registers);
  150. return dst_reg;
  151. }
  152. Optional<Bytecode::Register> ReturnStatement::generate_bytecode(Bytecode::Generator& generator) const
  153. {
  154. Optional<Bytecode::Register> argument_reg;
  155. if (m_argument)
  156. argument_reg = m_argument->generate_bytecode(generator);
  157. generator.emit<Bytecode::Op::Return>(argument_reg);
  158. return argument_reg;
  159. }
  160. }