New conceptual model for vararg

Conceptually, all functions get their vararg arguments in a vararg
table. The storing of vararg arguments in the stack is always treated
as an optimization.
This commit is contained in:
Roberto I
2025-11-26 11:18:29 -03:00
parent d94f7ba304
commit f33cc4ddec
11 changed files with 155 additions and 70 deletions

View File

@@ -1056,9 +1056,8 @@ static void constructor (LexState *ls, expdesc *t) {
/* }====================================================================== */
static void setvararg (FuncState *fs, int kind) {
lua_assert(kind & PF_ISVARARG);
fs->f->flag |= cast_byte(kind);
static void setvararg (FuncState *fs) {
fs->f->flag |= PF_ISVARARG;
luaK_codeABC(fs, OP_VARARGPREP, 0, 0, 0);
}
@@ -1078,12 +1077,12 @@ static void parlist (LexState *ls) {
break;
}
case TK_DOTS: {
varargk |= PF_ISVARARG;
varargk = 1;
luaX_next(ls); /* skip '...' */
if (ls->t.token == TK_NAME) {
if (ls->t.token == TK_NAME)
new_varkind(ls, str_checkname(ls), RDKVAVAR);
varargk |= PF_VAVAR;
}
else
new_localvarliteral(ls, "(vararg table)");
break;
}
default: luaX_syntaxerror(ls, "<name> or '...' expected");
@@ -1092,10 +1091,9 @@ static void parlist (LexState *ls) {
}
adjustlocalvars(ls, nparams);
f->numparams = cast_byte(fs->nactvar);
if (varargk != 0) {
setvararg(fs, varargk); /* declared vararg */
if (varargk & PF_VAVAR)
adjustlocalvars(ls, 1); /* vararg parameter */
if (varargk) {
setvararg(fs); /* declared vararg */
adjustlocalvars(ls, 1); /* vararg parameter */
}
/* reserve registers for parameters (plus vararg parameter, if present) */
luaK_reserveregs(fs, fs->nactvar);
@@ -1287,7 +1285,7 @@ static void simpleexp (LexState *ls, expdesc *v) {
FuncState *fs = ls->fs;
check_condition(ls, fs->f->flag & PF_ISVARARG,
"cannot use '...' outside a vararg function");
init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 0, 1));
init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, fs->f->numparams, 1));
break;
}
case '{' /*}*/: { /* constructor */
@@ -2153,7 +2151,7 @@ static void mainfunc (LexState *ls, FuncState *fs) {
BlockCnt bl;
Upvaldesc *env;
open_func(ls, fs, &bl);
setvararg(fs, PF_ISVARARG); /* main function is always vararg */
setvararg(fs); /* main function is always vararg */
env = allocupvalue(fs); /* ...set environment upvalue */
env->instack = 1;
env->idx = 0;