Hello Roberto!
I found a bug introduced in commit 36c1f6d9 ("Small correction in luaP_opmodes", 2026-04-29) which removed the IT bit from
OP_VARARGPREP. The commit message states "OP_VARARGPREP neither sets nor uses L->top", but
luaT_adjustvarargs reads L->top on its first line to compute
totalargs:
int totalargs = cast_int(L->top.p - ci->func.p) - 1;
Without the IT flag, the debug assert in luaV_execute resets L->top = base before
OP_VARARGPREP runs, causing totalargs to always be 0. This means fixed parameters in vararg functions receive the wrong stack slot values.
How to reproduce:
Build with the test library enabled:
make TESTS='-DLUA_USER_H='"'"'"ltests.h"'"'"' -Og -g'
Then:
$ ./lua -e 'local function f(p, ...) print(type(p), p) end f("hello")'
function function: 0x...
Expected output is string hello. The parameter p gets the function object itself instead of the passed argument.
Any C library function that type-checks its argument will trigger an assertion failure in
currentpc():
$ ./lua -e 'local function f(p, ...) string.len(p) end f("hi")'
lua: ldebug.c:45: currentpc: Assertion `...' failed.
Aborted
The full test suite (make test per the instructions in the makefile) also fails during
main.lua for the same reason.
Patch:
lopcodes.c:
- ,opmode(0, 0, 0, 0, 0, iABC) /* OP_VARARGPREP */
+ ,opmode(0, 0, 1, 0, 0, iABC) /* OP_VARARGPREP */
This restores the IT bit that was present before 36c1f6d9. The parent commit (0da6d320) passes all tests.
Note: only debug/test builds are affected. In release builds lua_assert compiles out, so
L->top is never clobbered and the VM works by accident.
Best regards,
payonel