Replace upvalue-based shell dispatch with OP_LUSH opcode

Add a dedicated OP_LUSH A B instruction that loads shell C functions
directly from the registry, eliminating the need for upvalue allocation
in mainfunc(), upvalue population in lua_load(), and the fragile
LUSH_NUM_UPVALS heuristic. Every chunk no longer carries 4 extra
upvalues.
This commit is contained in:
Cormac Shannon
2026-03-12 22:47:25 +00:00
parent f88b17959f
commit f09a033160
9 changed files with 46 additions and 78 deletions

22
lapi.c
View File

@@ -29,7 +29,6 @@
#include "ltm.h"
#include "lundump.h"
#include "lvm.h"
#include "lcmd.h"
@@ -1136,27 +1135,6 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
setobj(L, f->upvals[0]->v.p, &gt);
luaC_barrier(L, f->upvals[0], &gt);
}
if (f->nupvalues >= LUSH_NUM_UPVALS) { /* has lush upvalues? */
/* populate shell function upvalues from registry */
Table *regt = hvalue(&G(L)->l_registry);
TValue lushtv;
lu_byte tag = luaH_getint(regt, LUA_RIDX_LUSH, &lushtv);
if (novariant(tag) == LUA_TTABLE) {
static const char *const fields[] = {
"command", "interactive", "getenv", "setenv"
};
Table *lusht = hvalue(&lushtv);
int i;
for (i = 0; i < 4; i++) {
TValue val;
TString *key = luaS_new(L, fields[i]);
if (luaH_getstr(lusht, key, &val) != LUA_TNIL) {
setobj(L, f->upvals[i + 1]->v.p, &val);
luaC_barrier(L, f->upvals[i + 1], &val);
}
}
}
}
}
lua_unlock(L);
return APIstatus(status);