diff options
Diffstat (limited to 'src/allocator.h')
-rw-r--r-- | src/allocator.h | 84 |
1 files changed, 44 insertions, 40 deletions
diff --git a/src/allocator.h b/src/allocator.h index 9a9c245..e09ab38 100644 --- a/src/allocator.h +++ b/src/allocator.h | |||
@@ -2,46 +2,50 @@ | |||
2 | 2 | ||
3 | // ################################################################################################# | 3 | // ################################################################################################# |
4 | 4 | ||
5 | // everything we need to provide to lua_newstate() | 5 | namespace lanes { |
6 | class AllocatorDefinition | ||
7 | { | ||
8 | public: | ||
9 | // xxh64 of string "kAllocatorVersion_1" generated at https://www.pelock.com/products/hash-calculator | ||
10 | static constexpr uintptr_t kAllocatorVersion{ static_cast<uintptr_t>(0xCF9D321B0DFB5715ull) }; | ||
11 | uintptr_t version{ kAllocatorVersion }; | ||
12 | lua_Alloc allocF{ nullptr }; | ||
13 | void* allocUD{ nullptr }; | ||
14 | |||
15 | [[nodiscard]] static void* operator new(size_t size_) noexcept = delete; // can't create one outside of a Lua state | ||
16 | [[nodiscard]] static void* operator new(size_t size_, lua_State* L_) noexcept { return lua_newuserdatauv(L_, size_, 0); } | ||
17 | // always embedded somewhere else or "in-place constructed" as a full userdata | ||
18 | // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception | ||
19 | static void operator delete([[maybe_unused]] void* p_, [[maybe_unused]] lua_State* L_) {} | ||
20 | |||
21 | AllocatorDefinition(uintptr_t const version_, lua_Alloc const allocF_, void* const allocUD_) noexcept | ||
22 | : version{ version_ } | ||
23 | , allocF{ allocF_ } | ||
24 | , allocUD{ allocUD_ } | ||
25 | { | ||
26 | } | ||
27 | AllocatorDefinition() = default; | ||
28 | AllocatorDefinition(AllocatorDefinition const& rhs_) = default; | ||
29 | AllocatorDefinition(AllocatorDefinition&& rhs_) = default; | ||
30 | AllocatorDefinition& operator=(AllocatorDefinition const& rhs_) = default; | ||
31 | AllocatorDefinition& operator=(AllocatorDefinition&& rhs_) = default; | ||
32 | |||
33 | void initFrom(lua_State* L_) | ||
34 | { | ||
35 | allocF = lua_getallocf(L_, &allocUD); | ||
36 | } | ||
37 | 6 | ||
38 | void* alloc(size_t nsize_) | 7 | // everything we need to provide to lua_newstate() |
8 | class AllocatorDefinition | ||
39 | { | 9 | { |
40 | return allocF(allocUD, nullptr, 0, nsize_); | 10 | public: |
41 | } | 11 | // xxh64 of string "kAllocatorVersion_1" generated at https://www.pelock.com/products/hash-calculator |
12 | static constexpr uintptr_t kAllocatorVersion{ static_cast<uintptr_t>(0xCF9D321B0DFB5715ull) }; | ||
13 | uintptr_t version{ kAllocatorVersion }; | ||
14 | lua_Alloc allocF{ nullptr }; | ||
15 | void* allocUD{ nullptr }; | ||
42 | 16 | ||
43 | void free(void* ptr_, size_t osize_) | 17 | [[nodiscard]] static void* operator new(size_t size_) noexcept = delete; // can't create one outside of a Lua state |
44 | { | 18 | [[nodiscard]] static void* operator new(size_t size_, lua_State* L_) noexcept { return lua_newuserdatauv(L_, size_, 0); } |
45 | std::ignore = allocF(allocUD, ptr_, osize_, 0); | 19 | // always embedded somewhere else or "in-place constructed" as a full userdata |
46 | } | 20 | // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception |
47 | }; | 21 | static void operator delete([[maybe_unused]] void* p_, [[maybe_unused]] lua_State* L_) {} |
22 | |||
23 | AllocatorDefinition(uintptr_t const version_, lua_Alloc const allocF_, void* const allocUD_) noexcept | ||
24 | : version{ version_ } | ||
25 | , allocF{ allocF_ } | ||
26 | , allocUD{ allocUD_ } | ||
27 | { | ||
28 | } | ||
29 | AllocatorDefinition() = default; | ||
30 | AllocatorDefinition(AllocatorDefinition const& rhs_) = default; | ||
31 | AllocatorDefinition(AllocatorDefinition&& rhs_) = default; | ||
32 | AllocatorDefinition& operator=(AllocatorDefinition const& rhs_) = default; | ||
33 | AllocatorDefinition& operator=(AllocatorDefinition&& rhs_) = default; | ||
34 | |||
35 | void initFrom(lua_State* L_) | ||
36 | { | ||
37 | allocF = lua_getallocf(L_, &allocUD); | ||
38 | } | ||
39 | |||
40 | void* alloc(size_t nsize_) | ||
41 | { | ||
42 | return allocF(allocUD, nullptr, 0, nsize_); | ||
43 | } | ||
44 | |||
45 | void free(void* ptr_, size_t osize_) | ||
46 | { | ||
47 | std::ignore = allocF(allocUD, ptr_, osize_, 0); | ||
48 | } | ||
49 | }; | ||
50 | |||
51 | } // namespace lanes | ||