3#if defined(SKSE_SUPPORT_XBYAK) 
   15        using deleter_type = std::function<void(
void* a_mem, std::size_t a_size)>;
 
   32            if (
this != std::addressof(a_rhs)) {
 
   33                move_from(std::move(a_rhs));
 
 
   38        void create(std::size_t a_size) { 
return create(a_size, 
nullptr); }
 
   39        void create(std::size_t a_size, 
void* a_module);
 
   43            auto trampoline = 
static_cast<std::byte*
>(a_trampoline);
 
   45                constexpr auto INT3 = 
static_cast<int>(0xCC);
 
   46                std::memset(trampoline, INT3, a_size);
 
   51            _deleter = std::move(a_deleter);
 
 
   59        [[nodiscard]] 
void* 
allocate(std::size_t a_size)
 
   61            auto result = do_allocate(a_size);
 
 
   66#ifdef SKSE_SUPPORT_XBYAK 
   67        [[nodiscard]] 
void* 
allocate(Xbyak::CodeGenerator& a_code);
 
   73            return static_cast<T*
>(
allocate(
sizeof(T)));
 
 
   76        [[nodiscard]] 
constexpr std::size_t 
empty() const noexcept { 
return _capacity == 0; }
 
   77        [[nodiscard]] 
constexpr std::size_t 
capacity() const noexcept { 
return _capacity; }
 
   78        [[nodiscard]] 
constexpr std::size_t 
allocated_size() const noexcept { 
return _size; }
 
   79        [[nodiscard]] 
constexpr std::size_t 
free_size() const noexcept { 
return _capacity - _size; }
 
   81        template <std::
size_t N>
 
   82        std::uintptr_t 
write_branch(std::uintptr_t a_src, std::uintptr_t a_dst)
 
   84            std::uint8_t data = 0;
 
   85            if constexpr (N == 5) {
 
   89            } 
else if constexpr (N == 6) {
 
   94                static_assert(
false && N, 
"invalid branch size");
 
   97            return write_branch<N>(a_src, a_dst, data);
 
 
  100        template <std::
size_t N, 
class F>
 
  103            return write_branch<N>(a_src, stl::unrestricted_cast<std::uintptr_t>(a_dst));
 
 
  106        template <std::
size_t N>
 
  107        std::uintptr_t 
write_call(std::uintptr_t a_src, std::uintptr_t a_dst)
 
  109            std::uint8_t data = 0;
 
  110            if constexpr (N == 5) {
 
  114            } 
else if constexpr (N == 6) {
 
  119                static_assert(
false && N, 
"invalid call size");
 
  122            return write_branch<N>(a_src, a_dst, data);
 
 
  125        template <std::
size_t N, 
class F>
 
  128            return write_call<N>(a_src, stl::unrestricted_cast<std::uintptr_t>(a_dst));
 
 
  132        [[nodiscard]] 
void* do_create(std::size_t a_size, std::uintptr_t a_address);
 
  133        [[nodiscard]] 
void* do_allocate(std::size_t a_size);
 
  135        void write_5branch(std::uintptr_t a_src, std::uintptr_t a_dst, std::uint8_t a_opcode);
 
  136        void write_6branch(std::uintptr_t a_src, std::uintptr_t a_dst, std::uint8_t a_modrm);
 
  138        template <std::
size_t N>
 
  139        [[nodiscard]] std::uintptr_t 
write_branch(std::uintptr_t a_src, std::uintptr_t a_dst, std::uint8_t a_data)
 
  141            const auto isNop = *
reinterpret_cast<std::int8_t*
>(a_src) == 0x90;
 
  142            const auto disp = 
reinterpret_cast<std::int32_t*
>(a_src + N - 4);
 
  143            const auto nextOp = a_src + N;
 
  144            const auto func = isNop ? 0 : nextOp + *disp;
 
  146            if constexpr (N == 5) {
 
  147                write_5branch(a_src, a_dst, a_data);
 
  148            } 
else if constexpr (N == 6) {
 
  149                write_6branch(a_src, a_dst, a_data);
 
  151                static_assert(
false && N, 
"invalid branch size");
 
  159            _5branches = std::move(a_rhs._5branches);
 
  160            _6branches = std::move(a_rhs._6branches);
 
  161            _name = std::move(a_rhs._name);
 
  163            _deleter = std::move(a_rhs._deleter);
 
  166            a_rhs._data = 
nullptr;
 
  168            _capacity = a_rhs._capacity;
 
  175        void log_stats() 
const;
 
  177        [[nodiscard]] 
bool in_range(std::ptrdiff_t a_disp)
 const 
  179            constexpr auto min = std::numeric_limits<std::int32_t>::min();
 
  180            constexpr auto max = std::numeric_limits<std::int32_t>::max();
 
  182            return min <= a_disp && a_disp <= 
max;
 
  187            if (_data && _deleter) {
 
  188                _deleter(_data, _capacity);
 
  198        std::map<std::uintptr_t, std::byte*> _5branches;
 
  199        std::map<std::uintptr_t, std::byte*> _6branches;
 
  200        std::string                          _name{ 
"Default Trampoline"sv };
 
  202        std::byte*                           _data{ 
nullptr };
 
  203        std::size_t                          _capacity{ 0 };
 
  204        std::size_t                          _size{ 0 };
 
 
Definition Trampoline.h:13
std::uintptr_t write_call(std::uintptr_t a_src, std::uintptr_t a_dst)
Definition Trampoline.h:107
constexpr std::size_t allocated_size() const noexcept
Definition Trampoline.h:78
T * allocate()
Definition Trampoline.h:71
std::function< void(void *a_mem, std::size_t a_size)> deleter_type
Definition Trampoline.h:15
void * allocate(std::size_t a_size)
Definition Trampoline.h:59
~Trampoline()
Definition Trampoline.h:26
std::uintptr_t write_branch(std::uintptr_t a_src, std::uintptr_t a_dst)
Definition Trampoline.h:82
Trampoline(std::string_view a_name)
Definition Trampoline.h:22
Trampoline & operator=(const Trampoline &)=delete
Trampoline & operator=(Trampoline &&a_rhs) noexcept
Definition Trampoline.h:30
Trampoline(const Trampoline &)=delete
void set_trampoline(void *a_trampoline, std::size_t a_size, deleter_type a_deleter={})
Definition Trampoline.h:41
Trampoline(Trampoline &&a_rhs) noexcept
Definition Trampoline.h:20
std::uintptr_t write_branch(std::uintptr_t a_src, F a_dst)
Definition Trampoline.h:101
void create(std::size_t a_size)
Definition Trampoline.h:38
constexpr std::size_t capacity() const noexcept
Definition Trampoline.h:77
std::uintptr_t write_call(std::uintptr_t a_src, F a_dst)
Definition Trampoline.h:126
constexpr std::size_t empty() const noexcept
Definition Trampoline.h:76
constexpr std::size_t free_size() const noexcept
Definition Trampoline.h:79
void create(std::size_t a_size, void *a_module)
NiColor min(const NiColor &a_lhs, const NiColor &a_rhs)
Definition ColorUtil.h:63
NiColor max(const NiColor &a_lhs, const NiColor &a_rhs)
Definition ColorUtil.h:71
Trampoline & GetTrampoline()