Skip to content

Instantly share code, notes, and snippets.

@nddrylliog
Last active July 29, 2021 18:24
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nddrylliog/8722197 to your computer and use it in GitHub Desktop.
Save nddrylliog/8722197 to your computer and use it in GitHub Desktop.
LuaJIT modifications needed to re-enable custom 64-bit allocators.
diff --git a/src/lib_aux.c b/src/lib_aux.c
index 05fa6b1..c618094 100644
--- a/src/lib_aux.c
+++ b/src/lib_aux.c
@@ -346,9 +346,11 @@ LUALIB_API lua_State *luaL_newstate(void)
#if LJ_64
LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud)
{
- UNUSED(f); UNUSED(ud);
- fputs("Must use luaL_newstate() for 64 bit target\n", stderr);
- return NULL;
+ /* Re-enable custom 64-bit allocators */
+ lua_State *L;
+ L = lj_state_newstate(f, ud);
+ if (L) G(L)->panic = panic;
+ return L;
}
#endif
@nddrylliog
Copy link
Author

cf. http://hacksoflife.blogspot.fr/2012/12/integrating-luajit-with-x-plane-64-bit.html for an explanation.

Mostly:

LuaJIT on an x86_64 machine has an odd quirk: it requires all of Lua's allocations to be in the first 2 GB of address space. This requirement comes from its use of offset addresses, which apparently have a signed 32-bit range.

Normally on OS X 64-bit the only special work you have to do is customize the zero page region, as OS X defaults the zero page to the entire bottom 4 GB of memory. (I can only speculate that having the entire 32-bit address range be off limits helps catch programming errors where pointers are truncated to 32-bits because any truncated pointer will point to an illegal page.)

This last step required a modification to LuaJIT itself; the shipping 2.0 code has the API for custom allocators disabled in 64-bits (probably under the assumption that client code wouldn't follow the "bottom 2 GB" requirement.) Fortunately the stub-out is just a series of #defines and the full API functionality is easily restored.

@Qix-
Copy link

Qix- commented Jan 3, 2019

Old gist, I know - but I don't quite understand why they're using signed memory offsets. I understand that using signed types gives you trapability whereas unsigned will silently overflow, but that's a poor reason to use signed types for memory offsets, especially when it cuts out a widely used architecture.

Further, the mmap implementation they provide simply does not work on the three machines I tried it on. I have no idea how they got it to work elsewhere. It receives a failure code from the call to mmap() and it doesn't specify why it fails.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment