diff --git a/Userland/Libraries/LibJS/AST.h b/Userland/Libraries/LibJS/AST.h index 4e156ef655..5dc8e73911 100644 --- a/Userland/Libraries/LibJS/AST.h +++ b/Userland/Libraries/LibJS/AST.h @@ -351,6 +351,7 @@ public: virtual Value execute(Interpreter&, GlobalObject&) const override; virtual void dump(int indent) const override; + virtual Optional generate_bytecode(Bytecode::Generator&) const override; private: NonnullRefPtr m_predicate; diff --git a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp index 18d4e24700..e53658f2ca 100644 --- a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp +++ b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp @@ -187,4 +187,26 @@ Optional ReturnStatement::generate_bytecode(Bytecode::Genera return argument_reg; } +Optional IfStatement::generate_bytecode(Bytecode::Generator& generator) const +{ + auto predicate_reg = m_predicate->generate_bytecode(generator); + auto& if_jump = generator.emit(*predicate_reg); + auto& else_jump = generator.emit(*predicate_reg); + + if_jump.set_target(generator.make_label()); + (void)m_consequent->generate_bytecode(generator); + auto& end_jump = generator.emit(); + + else_jump.set_target(generator.make_label()); + if (m_alternate) { + (void)m_alternate->generate_bytecode(generator); + } + + end_jump.set_target(generator.make_label()); + + // FIXME: Do we need IfStatement to return the consequent/alternate result value? + // (That's what the AST interpreter currently does) + return {}; +} + } diff --git a/Userland/Libraries/LibJS/Bytecode/Op.cpp b/Userland/Libraries/LibJS/Bytecode/Op.cpp index 869dd169ce..0297533b11 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Op.cpp @@ -72,7 +72,7 @@ void PutById::execute(Bytecode::Interpreter& interpreter) const void Jump::execute(Bytecode::Interpreter& interpreter) const { - interpreter.jump(m_target); + interpreter.jump(*m_target); } void JumpIfFalse::execute(Bytecode::Interpreter& interpreter) const @@ -196,7 +196,7 @@ String GetById::to_string() const String Jump::to_string() const { - return String::formatted("Jump {}", m_target); + return String::formatted("Jump {}", *m_target); } String JumpIfFalse::to_string() const diff --git a/Userland/Libraries/LibJS/Bytecode/Op.h b/Userland/Libraries/LibJS/Bytecode/Op.h index 1d57fed10b..9769a6b5a6 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.h +++ b/Userland/Libraries/LibJS/Bytecode/Op.h @@ -214,17 +214,19 @@ private: class Jump final : public Instruction { public: - explicit Jump(Label target) - : m_target(target) + explicit Jump(Optional