/* * Copyright (c) 2021, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include namespace JS::Bytecode { struct UnwindInfo { Executable const* executable; BasicBlock const* handler; BasicBlock const* finalizer; JS::GCPtr lexical_environment; bool handler_called { false }; }; class BasicBlock { AK_MAKE_NONCOPYABLE(BasicBlock); public: static NonnullOwnPtr create(DeprecatedString name); ~BasicBlock(); void dump(Executable const&) const; ReadonlyBytes instruction_stream() const { return m_buffer.span(); } u8* data() { return m_buffer.data(); } u8 const* data() const { return m_buffer.data(); } size_t size() const { return m_buffer.size(); } void grow(size_t additional_size); void terminate(Badge) { m_terminated = true; } bool is_terminated() const { return m_terminated; } DeprecatedString const& name() const { return m_name; } // ============================================================== // FIXME: This is JIT state and shouldn't be part of BasicBlock itself. // Offset into the instruction stream where this code block starts. size_t offset { 0 }; // Offsets into the instruction stream where we have RIP-relative jump offsets to here that need patching. Vector jumps_to_here; // ============================================================== private: explicit BasicBlock(DeprecatedString name); Vector m_buffer; DeprecatedString m_name; bool m_terminated { false }; }; }