/* * Copyright (c) 2021-2024, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace JS::Bytecode { class Generator { public: VM& vm() { return m_vm; } enum class SurroundingScopeKind { Global, Function, Block, }; enum class MustPropagateCompletion { No, Yes, }; static CodeGenerationErrorOr> generate_from_ast_node(VM&, ASTNode const&, FunctionKind = FunctionKind::Normal); static CodeGenerationErrorOr> generate_from_function(VM&, ECMAScriptFunctionObject const& function); CodeGenerationErrorOr emit_function_declaration_instantiation(ECMAScriptFunctionObject const& function); [[nodiscard]] ScopedOperand allocate_register(); [[nodiscard]] ScopedOperand local(u32 local_index); [[nodiscard]] ScopedOperand accumulator(); [[nodiscard]] ScopedOperand this_value(); void free_register(Register); void set_local_initialized(u32 local_index); [[nodiscard]] bool is_local_initialized(u32 local_index) const; class SourceLocationScope { public: SourceLocationScope(Generator&, ASTNode const& node); ~SourceLocationScope(); private: Generator& m_generator; ASTNode const* m_previous_node { nullptr }; }; class UnwindContext { public: UnwindContext(Generator&, Optional