11#include "ll/api/base/FixedString.h"
12#include "ll/api/base/Macro.h"
13#include "ll/api/base/StdInt.h"
14#include "ll/api/memory/Signature.h"
15#include "ll/api/memory/Symbol.h"
16#include "mc/platform/brstd/function_ref.h"
18namespace Bedrock::Memory {
27 requires(
sizeof(T) ==
sizeof(FuncPtr))
28constexpr FuncPtr toFuncPtr(T t) {
38 requires(std::is_member_function_pointer_v<T> &&
sizeof(T) ==
sizeof(FuncPtr) +
sizeof(ptrdiff_t))
39constexpr FuncPtr toFuncPtr(T t) {
55LLNDAPI std::optional<uint> getVtableIndex(FuncPtr virtualFunction)
noexcept;
58 requires std::is_member_function_pointer_v<T>
59[[nodiscard]]
inline std::optional<uint> getVtableIndex(T t)
noexcept {
60#if defined(_WIN32) && defined(_MSC_VER) && defined(__clang__) && defined(_M_X64)
61 if constexpr (
sizeof(T) ==
sizeof(FuncPtr)) {
62 return getVtableIndex(toFuncPtr(t));
69inline void memcpy_t(
void* dst,
void const* src,
size_t count) {
70 memcpy(dst, src, count *
sizeof(T));
74inline void memcpy_t(
void* dst,
void const* src) {
75 memcpy(dst, src,
sizeof(T));
84LLAPI
void modify(
void* ptr,
size_t len, brstd::function_ref<
void()> callback);
87inline void modify(T& ref, brstd::function_ref<
void(std::remove_cv_t<T>&)> f) {
88 modify((
void*)std::addressof(ref),
sizeof(T), [&] { f((std::remove_cv_t<T>&)(ref)); });
91template <
class R = void,
class... Args>
92constexpr auto addressCall(
void const* address,
auto&&... args) -> R {
93 return ((R (*)(Args...))address)(std::forward<decltype(args)>(args)...);
96template <
class R = void,
class... Args>
97constexpr auto virtualCall(
void const* self, ptrdiff_t vIndex,
auto&&... args) -> R {
98 return (*(R(**)(
void const*, Args...))(*(uintptr_t**)self + vIndex))(self, std::forward<decltype(args)>(args)...);
102[[nodiscard]]
constexpr T& dAccess(
void* ptr, ptrdiff_t off) {
103 return *(T*)((uintptr_t)((uintptr_t)ptr + off));
107[[nodiscard]]
constexpr T
const& dAccess(
void const* ptr, ptrdiff_t off) {
108 return *(T*)((uintptr_t)((uintptr_t)ptr + off));
112constexpr void destruct(
void* ptr, ptrdiff_t off)
noexcept {
113 std::destroy_at(std::launder(
reinterpret_cast<T*
>((uintptr_t)((uintptr_t)ptr + off))));
116template <
class T,
class... Args>
117constexpr auto construct(
void* ptr, ptrdiff_t off, Args&&... args) {
118 return std::construct_at(
119 std::launder(
reinterpret_cast<T*
>((uintptr_t)((uintptr_t)ptr + off))),
120 std::forward<Args>(args)...
124LLNDAPI ::Bedrock::Memory::IMemoryAllocator& getDefaultAllocator();
126[[noreturn]] LLAPI
void throwMemoryException(
size_t);
128LLNDAPI
size_t getUsableSize(
void* ptr);
130template <
class T,
class D>
131[[nodiscard]]
inline size_t getUsableSize(std::unique_ptr<T, D>& ptr) {
135 return getUsableSize(ptr.get());
139template <
template <
class>
class P,
class T>
140[[nodiscard]]
inline size_t getUsableSize(P<T>& ptr)
141 requires(std::derived_from<P<T>, std::_Ptr_base<T>>)
143 auto& refc = dAccess<std::_Ref_count_base*>(std::addressof(ptr), 8);
147 auto& rawptr = dAccess<T*>(std::addressof(ptr), 0);
151 if constexpr (!std::is_array_v<T>) {
152 if (rawptr == dAccess<T*>(refc, 8 + 4 * 2)) {
153 return getUsableSize(rawptr);
157 return getUsableSize(refc
161 (std::is_array_v<T> ? 8 : 0)
174 LLAPI
void alloc(
size_t size);
177 DualMapping() =
default;
179 DualMapping(
size_t size) { alloc(size); }
181 ~DualMapping() { free(); }
183 size_t size()
const {
return memSize; }
185 void* writable()
const {
return rw; }
186 void* executable()
const {
return rx; }
Definition IMemoryAllocator.h:7