/* * 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 #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 GC::Ref generate_from_ast_node(VM&, ASTNode const&, FunctionKind = FunctionKind::Normal); static GC::Ref generate_from_function(VM&, GC::Ref shared_function_instance_data, BuiltinAbstractOperationsEnabled builtin_abstract_operations_enabled = BuiltinAbstractOperationsEnabled::No); void emit_function_declaration_instantiation(SharedFunctionInstanceData const& shared_function_instance_data); [[nodiscard]] ScopedOperand allocate_register(); [[nodiscard]] ScopedOperand local(Identifier::Local const&); [[nodiscard]] ScopedOperand local(FunctionLocal const&); [[nodiscard]] ScopedOperand accumulator(); [[nodiscard]] ScopedOperand this_value(); void free_register(Register); void set_local_initialized(Identifier::Local const&); void set_local_initialized(FunctionLocal const&); [[nodiscard]] bool is_local_initialized(u32 local_index) const; [[nodiscard]] bool is_local_initialized(Identifier::Local const&) const; [[nodiscard]] bool is_local_lexically_declared(Identifier::Local const& local) const; void emit_tdz_check_if_needed(Identifier 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