diff --git a/Userland/Libraries/LibJS/AST.h b/Userland/Libraries/LibJS/AST.h index d243453aeb..9b84e6d74f 100644 --- a/Userland/Libraries/LibJS/AST.h +++ b/Userland/Libraries/LibJS/AST.h @@ -440,6 +440,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: RefPtr m_init; diff --git a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp index 8b56fa54ce..bd8363e4de 100644 --- a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp +++ b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp @@ -333,6 +333,31 @@ Optional DoWhileStatement::generate_bytecode(Bytecode::Gener return body_result_reg; } +Optional ForStatement::generate_bytecode(Bytecode::Generator& generator) const +{ + Bytecode::Op::Jump* test_jump { nullptr }; + + if (m_init) { + [[maybe_unused]] auto init_result_reg = m_init->generate_bytecode(generator); + } + generator.begin_continuable_scope(); + auto jump_label = generator.make_label(); + if (m_test) { + auto test_result_reg = m_test->generate_bytecode(generator); + VERIFY(test_result_reg.has_value()); + test_jump = &generator.emit(*test_result_reg); + } + auto body_result_reg = m_body->generate_bytecode(generator); + if (m_update) { + [[maybe_unused]] auto update_result_reg = m_update->generate_bytecode(generator); + } + generator.emit(jump_label); + if (m_test) + test_jump->set_target(generator.make_label()); + generator.end_continuable_scope(); + return body_result_reg; +} + Optional ObjectExpression::generate_bytecode(Bytecode::Generator& generator) const { auto reg = generator.allocate_register();