Skip to content

Conversation

@kaid
Copy link
Contributor

@kaid kaid commented Jan 30, 2026

This PR adds support for the latest Lua 5.5 release and improves Zig 0.16 nightly compatibility(0.16.0-dev.2349+204fa8959).

Lua 5.5 Support

  • Add Lua 5.5 as a new language target - Full integration with build system and package management
  • Update lua_newstate signature - Lua 5.5 adds a new misize parameter for minimum stack size; handle with conditional compilation
  • Add DebugInfo55 structure - New debug interface with private field for internal state
  • Extend version compatibility - Add .lua55 to all relevant version switches:
    • ArithOperator, Event, DebugInfo, dump, equal, gc* functions
    • Stream, StreamFn, yieldCont continuation signatures
    • openCoro, openUtf8 library loaders
  • Add Lua 5.5 source files - Include ldo.c, lctype.c, lcorolib.c, lutf8lib.c in build
  • System library linking - Support lua5.5 system library when using use_system_lua

Zig 0.16 Nightly Compatibility

  • Fix build/patch.zig entry point - Update from legacy pub fn main() !void to new pub fn main(init: std.process.Init.Minimal) !void signature
  • Modernize argument parsing - Replace std.process.argsAlloc with iterator-based init.args.iterate() API
  • Fix pointer cast syntax - Update @ptrCast usage for stricter Zig 0.16 type checking in various FFI calls

LuaJIT Fixes

Bit Library Improvements

Note: This is a bit of a hack to resolve immediate symbol errors. LuaJIT's bit library and Lua 5.2's bit32 have behavioral differences (different module names, slightly different APIs). A more elegant solution might be to expose them as separate functions or handle the differences at the API level rather than conflating them in openBit32.

  • Refactor openBit32 - Use explicit switch statement for clarity:
    • Lua 5.2: use luaopen_bit32
    • LuaJIT: use luaopen_bit (LuaJIT's bit library)
    • Other versions: no-op (they don't have bit32)
  • Simplify test conditions - Explicitly check for lua52 and luajit instead of excluding multiple versions

Files Changed

  • build.zig - Update version handling
  • build.zig.zon - Add Lua 5.5 package reference
  • build/lua.zig - Add Lua 5.5 build configuration
  • build/luajit.zig - Remove Darwin unwind workaround, restore external unwind
  • build/patch.zig - Fix Zig 0.16 pointer cast syntax
  • src/lib.zig - Add Lua 5.5 compatibility, fix error messages and pointer casts, improve bit library handling
  • src/tests.zig - Fix tests for LuaJIT and Zig 0.16 compatibility, simplify bit32 test conditions
  • readme.md - Update documentation

kaid added 11 commits January 29, 2026 16:47
- Add lua55 dependency to build.zig.zon (lua-5.5.0.tar.gz)
- Add lua55 variant to Language enum in build/lua.zig
- Add lua55 source files list (same structure as 5.4)
- Update build.zig to handle lua55 system library linking

API changes for Lua 5.5 compatibility:
- Add DebugInfo55 with i32 first_transfer/num_transfer (changed from u16)
- Update lua_newstate() to accept third parameter (seed) for 5.5
- Add null buffer check in CWriterFn wrap (Lua 5.5 calls writer with null at end)
- Update all version switches to include .lua55
- Fix @ptrCast type inference in openLibs()

Test updates:
- Add version check for Lua 5.5 (505)
- Update resumeThread calls for 5.4/5.5 (requires num_results parameter)
- Update userdata tests to handle 5.5 user_values API
- Skip dump/load test for 5.5 (format changed)
- Update GC, compare, and concat tests for 5.5 behavior

All tests pass for lua52, lua53, lua54, and lua55.
- Replace deprecated std.process.argsAlloc with std.process.Init.Minimal
- Update main() signature to use std.process.Init.Minimal parameter
- Use init.args.iterate() instead of argsAlloc for command line parsing

This fixes the build for Lua 5.1 which uses the patch tool to apply
CVE-2014-5461 security fix to ldo.c.
Remove the separate code path for Lua 5.5 in the compare test since
the equal() and lessThan() functions now work correctly for all versions.

This reduces code duplication and makes the test more maintainable.
The root cause was that LuaJIT was unconditionally compiled with external
unwind mode (LUAJIT_UNWIND_EXTERNAL), which requires all frames in the
call chain to have proper unwind info. When external unwind fails to
propagate (err_raise_ext returns), LuaJIT calls panic and exits.

Changes:
- Remove LUAJIT_UNWIND_EXTERNAL macro and unwind library linking from
  build/luajit.zig to use LuaJIT's default internal error handling
- Fix registerFns error message to use consistent format for all Lua versions
- Add LuaJIT to the exclusion list for openBit32 (LuaJIT doesn't have bit32)
- Fix pointer cast order in userdata dtor test (@ptrCast(@alignCast) for
  Zig 0.16 compatibility)

All tests now pass.
Remove the LJ_NO_UNWIND=1 workaround for Darwin now that the Zig compiler
bug (https://codeberg.org/ziglang/zig/issues/30669) has been fixed by
Andrew Kelley in Zig master:
https://codeberg.org/ziglang/zig/commit/63f345a75afdf4f956b136c06776f109f5c567af

The bug caused stack check to be incorrectly enabled for external unwind,
which made err_raise_ext fail and return instead of properly unwinding.
Refactor openBit32 to use explicit switch statement for clarity:
- Lua 5.2: use luaopen_bit32
- LuaJIT: use luaopen_bit (LuaJIT's bit library)
- Other versions: no-op (they don't have bit32)

Also simplify the test condition to explicitly check for lua52 and luajit
instead of excluding multiple versions.
Previously removed the LUA_QS branch in registerFns to work around a
c-translate error on Zig nightly. After investigating, this is caused by
an upstream bug in Zig's translate-c:
https://codeberg.org/ziglang/translate-c/issues/282

The bug affects LUA_QL macro parsing, which breaks LUA_QS (as it expands
to LUA_QL). Since this is a confirmed upstream issue and the makefile
already disables lua51/luajit tests on nightly due to the same bug,
restore the original LUA_QS branch for non-Luau languages.

Changes:
- Restore LUA_QS usage for lua51-lua54 and luajit in registerFns
- Add lua55 test target to test_zig_nightly and test_zig_stable
- Remove skip for Lua 5.5 dump test - it works correctly
- Fix closeThread call: pass null instead of lua as "from" parameter
  When L==from, Lua 5.5 treats this as "thread closing itself" which
  only works inside a resume. Pass null to reset thread normally.
  See: https://www.lua.org/manual/5.5/manual.html#lua_closethread
The yielding test has an early return for non-5.3/5.4/5.5 versions,
so the else block handling Lua 5.1/LuaJIT was unreachable code.

- Change "else if (lua52 or lua53)" to "else" since only 5.3 remains
- Remove dead code for 5.1/LuaJIT that could never execute
- gc test: include lua55 in gcSetGenerational check
- userdata test: include lua55 in setUserValue/getUserValue check
- resuming test: remove lua54 skip, refactor to use switch for clarity
Include lua55 in the upvalueId error test case (same behavior as lua54).
Copy link
Collaborator

@robbielyman robbielyman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks very much! I'm going to go ahead and make the openBit change I suggested.

src/lib.zig Outdated
lua.requireF(c.LUA_BITLIBNAME, c.luaopen_bit32, true);
if (lang == .lua52 or lang == .lua53 or lang == .lua54) lua.pop(1);
switch (lang) {
.lua52 => lua.requireF(c.LUA_BITLIBNAME, c.luaopen_bit32, true),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the library is available in Lua 5.3, probably we should require it if the user asks for it. Maybe the openBit32 function should instead be named openBit and use the indicated functions for lua 5.2, 5.3 and luajit, and otherwise be a compile error?

@robbielyman robbielyman merged commit cf0e794 into natecraddock:main Jan 30, 2026
19 of 24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants