/* * Copyright (c) 2023, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include namespace JS::JIT { struct BytecodeMapping { size_t native_offset; size_t block_index; size_t bytecode_offset; // Special block index for labels outside any blocks. static constexpr auto EXECUTABLE = NumericLimits::max(); static constexpr auto EXECUTABLE_LABELS = AK::Array { "entry"sv, "common_exit"sv }; }; class NativeExecutable { AK_MAKE_NONCOPYABLE(NativeExecutable); AK_MAKE_NONMOVABLE(NativeExecutable); public: NativeExecutable(void* code, size_t size, Vector, Optional> gdb_object = {}); ~NativeExecutable(); void run(VM&, size_t entry_point) const; void dump_disassembly(Bytecode::Executable const& executable) const; BytecodeMapping const& find_mapping_entry(size_t native_offset) const; Optional get_source_range(Bytecode::Executable const& executable, FlatPtr address) const; ReadonlyBytes code_bytes() const { return { m_code, m_size }; } private: void* m_code { nullptr }; size_t m_size { 0 }; Vector m_mapping; Vector m_block_entry_points; mutable OwnPtr m_instruction_stream_iterator; Optional> m_gdb_object; }; }