diff --git a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp index 526b7a1b76..ca96f4924c 100644 --- a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp +++ b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp @@ -344,24 +344,25 @@ Optional ReturnStatement::generate_bytecode(Bytecode::Genera Optional IfStatement::generate_bytecode(Bytecode::Generator& generator) const { + auto result_reg = generator.allocate_register(); 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 consequent_reg = m_consequent->generate_bytecode(generator); + generator.emit(result_reg, *consequent_reg); auto& end_jump = generator.emit(); else_jump.set_target(generator.make_label()); if (m_alternate) { - (void)m_alternate->generate_bytecode(generator); + auto alternative_reg = m_alternate->generate_bytecode(generator); + generator.emit(result_reg, *alternative_reg); } 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 {}; + return result_reg; } Optional ContinueStatement::generate_bytecode(Bytecode::Generator& generator) const diff --git a/Userland/Libraries/LibJS/Bytecode/Instruction.h b/Userland/Libraries/LibJS/Bytecode/Instruction.h index 87863be573..8ec107e220 100644 --- a/Userland/Libraries/LibJS/Bytecode/Instruction.h +++ b/Userland/Libraries/LibJS/Bytecode/Instruction.h @@ -11,6 +11,7 @@ #define ENUMERATE_BYTECODE_OPS(O) \ O(Load) \ + O(LoadRegister) \ O(Add) \ O(Sub) \ O(Mul) \ diff --git a/Userland/Libraries/LibJS/Bytecode/Op.cpp b/Userland/Libraries/LibJS/Bytecode/Op.cpp index c15da0073b..2a71384d3a 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Op.cpp @@ -52,6 +52,11 @@ void Load::execute(Bytecode::Interpreter& interpreter) const interpreter.reg(m_dst) = m_value; } +void LoadRegister::execute(Bytecode::Interpreter& interpreter) const +{ + interpreter.reg(m_dst) = interpreter.reg(m_src); +} + void Add::execute(Bytecode::Interpreter& interpreter) const { interpreter.reg(m_dst) = add(interpreter.global_object(), interpreter.reg(m_src1), interpreter.reg(m_src2)); @@ -284,6 +289,11 @@ String Load::to_string() const return String::formatted("Load dst:{}, value:{}", m_dst, m_value.to_string_without_side_effects()); } +String LoadRegister::to_string() const +{ + return String::formatted("LoadRegister dst:{}, src:{}", m_dst, m_src); +} + String Add::to_string() const { return String::formatted("Add dst:{}, src1:{}, src2:{}", m_dst, m_src1, m_src2); diff --git a/Userland/Libraries/LibJS/Bytecode/Op.h b/Userland/Libraries/LibJS/Bytecode/Op.h index 1d2bbe656f..5d5da53eda 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.h +++ b/Userland/Libraries/LibJS/Bytecode/Op.h @@ -32,6 +32,23 @@ private: Value m_value; }; +class LoadRegister final : public Instruction { +public: + LoadRegister(Register dst, Register src) + : Instruction(Type::LoadRegister) + , m_dst(dst) + , m_src(src) + { + } + + void execute(Bytecode::Interpreter&) const; + String to_string() const; + +private: + Register m_dst; + Register m_src; +}; + class Add final : public Instruction { public: Add(Register dst, Register src1, Register src2)