65816-llvm-mos/tests/lua
2026-09-29 15:54:23 -05:00
..
lua-5.1.5 Optimizations 2026-05-25 21:00:32 -05:00
build.sh Docs updated. 2026-06-30 13:07:45 -05:00
lua-5.1.5.tar.gz Optimizations 2026-05-25 21:00:32 -05:00
luaStubs.c Optimizations 2026-05-25 21:00:32 -05:00
luaTest.c Optimizations 2026-05-25 21:00:32 -05:00
luaTest.manifest.json More code generation fixes. 32 bit operations improved. 2026-09-29 15:54:23 -05:00
README.md Far pointer code is now more efficient. More code gen errors fixed. 2026-09-28 21:04:28 -05:00
runLuaTest.sh Optimizations 2026-05-25 21:00:32 -05:00

Lua 5.1.5 — substantial real-world C test

Lua's reference C implementation (17K lines, 24 source files) compiled for the W65816 / Apple IIgs target. Serves as a "real-world C" stress test for the backend — exercises every major language feature, dispatch- heavy VM, deep recursion, GC walks, etc.

Build

bash tests/lua/build.sh        # compile all 24 Lua sources + stubs
bash tests/lua/runLuaTest.sh   # build + link the test wrapper

What works

  • All 24 Lua source files compile cleanly under our backend.
  • Links into a multi-segment binary via link816 --segment-cap. Five segments at ~40KB each (with gc-sections enabled — drops to one segment when only the API entry points are used).
  • Loads in MAME (verified via direct mame ... -autoboot_script).

Caveats

A few functions (symbexec in ldebug.c, auxsort in ltablib.c, luaV_execute in lvm.c, plus lstrlib.c under --layer2) exceed what LLVM's greedy allocator can place with the 65816's single accumulator and abort with ran out of registers during register allocation. This is a hardware constraint, not a miscompile. build.sh handles it automatically: it compiles through scripts/ccRegallocFallback.sh, which retries an affected TU with -mllvm -regalloc=basic (the simpler, always-terminating allocator) only when greedy fails. No per-file list is maintained; a newly register-heavy TU is handled transparently.

These functions are the largest in Lua and exhibit unusual register pressure (luaV_execute is a 30+ case VM dispatch). See the regalloc discussion in ../../LLVM_65816_DESIGN.md.

Runtime execution status

runLuaTest.sh passes: the API smoke test (create a state, push three integers, sum them, check a string, pop, close) writes the 0xC0DE sentinel under MAME.

It used to crash, and not because of any sandbox. The link is multi-segment (--segment-cap, five segments), and clang forms a function pointer as a 16-bit offset plus the bank in DP $BE -- bank 0. link816 only redirected pointers to seg2+ functions through bank-0 JML trampolines for GS/OS ExpressLoad links, so here Lua's allocator (the first thing lua_newstate calls, through a pointer) was called in bank 0, landed in vfprintf, and the machine ran wild; MAME itself then died of the I/O the runaway stack wrote. link816 now builds the trampolines for every multi-segment link (fixed bank bases: the absolute target is baked in).

Files

  • lua-5.1.5/ — vendored Lua 5.1.5 source tree (from www.lua.org)
  • build.sh — compile script (auto-falls-back to basic regalloc via scripts/ccRegallocFallback.sh when greedy can't place a TU)
  • luaStubs.c — strcoll, strxfrm, freopen stubs for missing libc
  • luaTest.c — minimal Lua API test (sentinel 0xC0DE if pass)
  • runLuaTest.sh — full build + run wrapper