emilua: fix fallback allocator on aarch64-linux

Assisted-by: Codex:gpt-5.5
This commit is contained in:
Sam Estep
2026-05-15 13:04:30 -04:00
parent eef00dfd8a
commit eb9859ba29
2 changed files with 78 additions and 0 deletions
@@ -73,6 +73,19 @@ stdenv.mkDerivation (finalAttrs: {
(lib.mesonOption "version_suffix" "-nixpkgs1")
];
patches = [
# https://gitlab.com/emilua/emilua/-/commit/9f3964f22b2289c98b64a1af729712a862459aeb
# The above commit added a fallback allocator that just calls `realloc` from
# libc, which is fine on x86 because Linux userspace pointers are 47 bits on
# x86-64 and that aligns perfectly with LuaJIT's NaN-tagging representation:
# https://github.com/LuaJIT/LuaJIT/issues/49
# But on ARM64, Linux userspace pointers are 48 bits, so libc does not
# provide an allocator that can be safely used for LuaJIT. To fix that, we
# delete the libc-based allocator and instead use LuaJIT's own default
# allocator as the fallback, which is what Emilua did before the regression.
./use-luajit-default-allocator.patch
];
postPatch = ''
patchShebangs src/emilua_gperf.awk --interpreter '${lib.getExe gawk} -f'
'';
@@ -0,0 +1,65 @@
diff --git a/src/allocator.cpp b/src/allocator.cpp
index cb80c99..c41ed4e 100644
--- a/src/allocator.cpp
+++ b/src/allocator.cpp
@@ -9,25 +9,6 @@ namespace emilua {
namespace interprocess = boost::interprocess;
-static inline
-void* do_std_alloc(void* ptr, std::size_t osize, std::size_t nsize)
-{
- if (nsize == 0) {
- // free_sized only appeared in C23
- free(ptr);
- return nullptr;
- } else {
- // even in C23, we don't have realloc_sized() to pass osize along
- auto ret = realloc(ptr, nsize);
- if (nsize <= osize) {
- // According to Programming in Lua 3rd edition § 32.1 ¶ 8, Lua is
- // unable to recover from allocation shrinking failures.
- assert(ret);
- }
- return ret;
- }
-}
-
general_purpose_allocator::general_purpose_allocator(
std::shared_ptr<void> block, std::size_t block_size)
: block{std::move(block)}
@@ -50,17 +31,8 @@ lua_Alloc general_purpose_allocator::get_lua_allocator()
ptr, osize, nsize);
};
- static constexpr auto use_c_allocator = [](
- void* /*ud*/, void* ptr, std::size_t osize, std::size_t nsize
- ) -> void* {
- return do_std_alloc(ptr, osize, nsize);
- };
-
- if (allocator) {
- return use_boost_allocator;
- } else {
- return use_c_allocator;
- }
+ assert(allocator);
+ return use_boost_allocator;
}
void general_purpose_allocator::allow_reserved_zone()
diff --git a/src/core.cpp b/src/core.cpp
index 8cb4365..fb63706 100644
--- a/src/core.cpp
+++ b/src/core.cpp
@@ -183,7 +183,9 @@ vm_context::vm_context(
, lua_errmem(false)
, exit_request(false)
, alloc{memory_resource, memory_resource_size}
- , L_(lua_newstate(alloc.get_lua_allocator(), &alloc))
+ , L_(memory_resource
+ ? lua_newstate(alloc.get_lua_allocator(), &alloc)
+ : luaL_newstate())
, current_fiber_(nullptr)
{
if (!L_)