MCPcopy Create free account
hub / github.com/ObEngine/ObEngine / usertype_allocate

Function usertype_allocate

extlibs/sol3/include/sol/sol.hpp:9499–9561  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

9497
9498 template <typename T>
9499 T* usertype_allocate(lua_State* L) {
9500 typedef std::integral_constant<bool,
9501#if defined(SOL_NO_MEMORY_ALIGNMENT) && SOL_NO_MEMORY_ALIGNMENT
9502 false
9503#else
9504 (std::alignment_of<T*>::value > 1 || std::alignment_of<T>::value > 1)
9505#endif
9506 >
9507 use_align;
9508 if (!use_align::value) {
9509 T** pointerpointer = static_cast<T**>(lua_newuserdata(L, sizeof(T*) + sizeof(T)));
9510 T*& pointerreference = *pointerpointer;
9511 T* allocationtarget = reinterpret_cast<T*>(pointerpointer + 1);
9512 pointerreference = allocationtarget;
9513 return allocationtarget;
9514 }
9515
9516 /* the assumption is that `lua_newuserdata` -- unless someone
9517 passes a specific lua_Alloc that gives us bogus, un-aligned pointers
9518 -- uses malloc, which tends to hand out more or less aligned pointers to memory
9519 (most of the time, anyhow)
9520
9521 but it's not guaranteed, so we have to do a post-adjustment check and increase padding
9522
9523 we do this preliminarily with compile-time stuff, to see
9524 if we strike lucky with the allocator and alignment values
9525
9526 otherwise, we have to re-allocate the userdata and
9527 over-allocate some space for additional padding because
9528 compilers are optimized for aligned reads/writes
9529 (and clang will barf UBsan errors on us for not being aligned)
9530 */
9531 static const std::size_t initial_size = aligned_space_for<T*, T>(nullptr);
9532 static const std::size_t misaligned_size = aligned_space_for<T*, T>(reinterpret_cast<void*>(0x1));
9533
9534 void* pointer_adjusted;
9535 void* data_adjusted;
9536 bool result
9537 = attempt_alloc(L, std::alignment_of_v<T*>, sizeof(T*), std::alignment_of_v<T>, sizeof(T), initial_size, pointer_adjusted, data_adjusted);
9538 if (!result) {
9539 // we're likely to get something that fails to perform the proper allocation a second time,
9540 // so we use the suggested_new_size bump to help us out here
9541 pointer_adjusted = nullptr;
9542 data_adjusted = nullptr;
9543 result = attempt_alloc(
9544 L, std::alignment_of_v<T*>, sizeof(T*), std::alignment_of_v<T>, sizeof(T), misaligned_size, pointer_adjusted, data_adjusted);
9545 if (!result) {
9546 if (pointer_adjusted == nullptr) {
9547 luaL_error(L, "aligned allocation of userdata block (pointer section) for '%s' failed", detail::demangle<T>().c_str());
9548 }
9549 else {
9550 luaL_error(L, "aligned allocation of userdata block (data section) for '%s' failed", detail::demangle<T>().c_str());
9551 }
9552 return nullptr;
9553 }
9554 }
9555
9556 T** pointerpointer = reinterpret_cast<T**>(pointer_adjusted);

Callers

nothing calls this directly

Calls 3

attempt_allocFunction · 0.85
luaL_errorFunction · 0.85
c_strMethod · 0.45

Tested by

no test coverage detected