diff options
Diffstat (limited to '')
-rw-r--r-- | src/allocator.hpp | 39 |
1 files changed, 33 insertions, 6 deletions
diff --git a/src/allocator.hpp b/src/allocator.hpp index fa48c46..4fec044 100644 --- a/src/allocator.hpp +++ b/src/allocator.hpp | |||
@@ -9,22 +9,30 @@ namespace lanes { | |||
9 | // everything we need to provide to lua_newstate() | 9 | // everything we need to provide to lua_newstate() |
10 | class AllocatorDefinition | 10 | class AllocatorDefinition |
11 | { | 11 | { |
12 | public: | 12 | private: |
13 | // xxh64 of string "kAllocatorVersion_1" generated at https://www.pelock.com/products/hash-calculator | 13 | // xxh64 of string "kAllocatorVersion_1" generated at https://www.pelock.com/products/hash-calculator |
14 | static constexpr uintptr_t kAllocatorVersion{ static_cast<uintptr_t>(0xCF9D321B0DFB5715ull) }; | 14 | static constexpr auto kAllocatorVersion{ static_cast<uintptr_t>(0xCF9D321B0DFB5715ull) }; |
15 | uintptr_t version{ kAllocatorVersion }; | 15 | |
16 | public: | ||
17 | using version_t = std::remove_const_t<decltype(kAllocatorVersion)>; | ||
18 | |||
19 | private: | ||
20 | // can't make these members const because we need to be able to copy an AllocatorDefinition into another | ||
21 | // so the members are not const, but they are private to avoid accidents. | ||
22 | version_t version{ kAllocatorVersion }; | ||
16 | lua_Alloc allocF{ nullptr }; | 23 | lua_Alloc allocF{ nullptr }; |
17 | void* allocUD{ nullptr }; | 24 | void* allocUD{ nullptr }; |
18 | 25 | ||
26 | public: | ||
27 | |||
19 | [[nodiscard]] static void* operator new(size_t const size_) noexcept = delete; // can't create one outside of a Lua state | 28 | [[nodiscard]] static void* operator new(size_t const size_) noexcept = delete; // can't create one outside of a Lua state |
20 | [[nodiscard]] static void* operator new(size_t const size_, lua_State* const L_) noexcept { return lua_newuserdatauv(L_, size_, UserValueCount{ 0 }); } | 29 | [[nodiscard]] static void* operator new(size_t const size_, lua_State* const L_) noexcept { return lua_newuserdatauv(L_, size_, UserValueCount{ 0 }); } |
21 | // always embedded somewhere else or "in-place constructed" as a full userdata | 30 | // always embedded somewhere else or "in-place constructed" as a full userdata |
22 | // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception | 31 | // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception |
23 | static void operator delete([[maybe_unused]] void* const p_, [[maybe_unused]] lua_State* const L_) {} | 32 | static void operator delete([[maybe_unused]] void* const p_, [[maybe_unused]] lua_State* const L_) {} |
24 | 33 | ||
25 | AllocatorDefinition(uintptr_t const version_, lua_Alloc const allocF_, void* const allocUD_) noexcept | 34 | AllocatorDefinition(lua_Alloc const allocF_, void* const allocUD_) noexcept |
26 | : version{ version_ } | 35 | : allocF{ allocF_ } |
27 | , allocF{ allocF_ } | ||
28 | , allocUD{ allocUD_ } | 36 | , allocUD{ allocUD_ } |
29 | { | 37 | { |
30 | } | 38 | } |
@@ -36,16 +44,35 @@ namespace lanes { | |||
36 | AllocatorDefinition& operator=(AllocatorDefinition const& rhs_) = default; | 44 | AllocatorDefinition& operator=(AllocatorDefinition const& rhs_) = default; |
37 | AllocatorDefinition& operator=(AllocatorDefinition&& rhs_) = default; | 45 | AllocatorDefinition& operator=(AllocatorDefinition&& rhs_) = default; |
38 | 46 | ||
47 | static AllocatorDefinition& Validated(lua_State* L_, StackIndex idx_); | ||
48 | |||
39 | void initFrom(lua_State* const L_) | 49 | void initFrom(lua_State* const L_) |
40 | { | 50 | { |
41 | allocF = lua_getallocf(L_, &allocUD); | 51 | allocF = lua_getallocf(L_, &allocUD); |
42 | } | 52 | } |
43 | 53 | ||
54 | void installIn(lua_State* const L_) const | ||
55 | { | ||
56 | if (allocF) { | ||
57 | lua_setallocf(L_, allocF, allocUD); | ||
58 | } | ||
59 | } | ||
60 | |||
61 | lua_State* newState() const | ||
62 | { | ||
63 | return lua_newstate(allocF, allocUD); | ||
64 | } | ||
65 | |||
44 | void* alloc(size_t const nsize_) | 66 | void* alloc(size_t const nsize_) |
45 | { | 67 | { |
46 | return allocF(allocUD, nullptr, 0, nsize_); | 68 | return allocF(allocUD, nullptr, 0, nsize_); |
47 | } | 69 | } |
48 | 70 | ||
71 | void* alloc(void* const ptr_, size_t const osize_, size_t const nsize_) | ||
72 | { | ||
73 | return allocF(allocUD, ptr_, osize_, nsize_); | ||
74 | } | ||
75 | |||
49 | void free(void* const ptr_, size_t const osize_) | 76 | void free(void* const ptr_, size_t const osize_) |
50 | { | 77 | { |
51 | std::ignore = allocF(allocUD, ptr_, osize_, 0); | 78 | std::ignore = allocF(allocUD, ptr_, osize_, 0); |