diff -Nr lua-5.5.0-rc1/README lua-5.5.0-rc2/README 2c2 < This is Lua 5.5.0, released on 14 Nov 2025. --- > This is Lua 5.5.0, released on 01 Dec 2025. diff -Nr lua-5.5.0-rc1/doc/contents.html lua-5.5.0-rc2/doc/contents.html 88c88,89 <
  • 3.4.12 – Lists of expressions, multiple results, and adjustment --- >
  • 3.4.12 – Lists of Expressions, Multiple Results, and Adjustment > 97c98 <
  • 4.1.3 – Pointers to strings --- >
  • 4.1.3 – Pointers to Strings 677c678 < Sat Nov 15 00:51:05 UTC 2025 --- > Mon Dec 1 13:57:23 UTC 2025 diff -Nr lua-5.5.0-rc1/doc/manual.html lua-5.5.0-rc2/doc/manual.html 2704c2704 < is syntactic sugar for v.name(v,args), --- > is syntactic sugar for v.name(v, args), 2888,2895c2888,2891 < to the function through a vararg expression and, < if present, a vararg table. < < <

    < A vararg expression is also written as three dots, < and its value is a list of all actual extra arguments, < similar to a function with multiple results (see §3.4.12). --- > to the function through a vararg table. > In that table, > the values at indices 1, 2, etc. are the extra arguments, > and the value at index "n" is the number of extra arguments. 2907c2903 < to the vararg expression: --- > to the vararg table: 2918,2921c2914,2917 < g(3) a=3, b=nil, ... -> (nothing) < g(3, 4) a=3, b=4, ... -> (nothing) < g(3, 4, 5, 8) a=3, b=4, ... -> 5 8 < g(5, r()) a=5, b=1, ... -> 2 3 --- > g(3) a=3, b=nil, va. table -> {n = 0} > g(3, 4) a=3, b=4, va. table -> {n = 0} > g(3, 4, 5, 8) a=3, b=4, va. table -> {5, 8, n = 2} > g(5, r()) a=5, b=1, va. table -> {2, 3, n = 2} 2925,2926c2921,2922 < The presence of a varag table in a variadic function is indicated < by a name after the three dots. --- > A vararg table in a variadic function can have an optional name, > given after the three dots. 2928,2935c2924,2937 < a vararg table behaves like a read-only local variable < with the given name that is initialized with a table. < In that table, < the values at indices 1, 2, etc. are the extra arguments, < and the value at index "n" is the number of extra arguments. < In other words, the code behaves as if the function started with < the following statement, < assuming the standard behavior of table.pack: --- > that name denotes a read-only local variable that > refers to the vararg table. > If the vararg table does not have a name, > it can only be accessed through a vararg expression. > > >

    > A vararg expression is also written as three dots, > and its value is a list of the values in the vararg table, > from 1 to the integer value at index "n". > (Therefore, if the code does not modify the vararg table, > this list corresponds to the extra arguments in the function call.) > This list behaves like the results from a > function with multiple results (see §3.4.12). 2937,2939d2938 <

    <      local <const> name = table.pack(...)
    < 
    2943,2944c2942 < if the vararg table is used only as a base in indexing expressions < (the t in t[exp] or t.id) and it is not an upvalue, --- > if the vararg table satisfies some conditions, 2946c2944,2951 < the indexing expressions into accesses to the internal vararg data. --- > the indexing expressions and the vararg expressions > into accesses to the internal vararg data. > The conditions are as follows: > If the vararg table has a name, > that name is not an upvalue in a nested function > and it is used only as the base table > in the syntactic constructions t[exp] or t.id). > Note that an anonymous vararg table always satisfy these conditions. 2954,2955c2959 <

    3.4.12 – Lists of expressions, multiple results, < and adjustment

    --- >

    3.4.12 – Lists of Expressions, Multiple Results, and Adjustment

    3259c3263 <

    4.1.3 – Pointers to strings

    --- >

    4.1.3 – Pointers to Strings

    3754c3758 < realloc(NULL,size) is equivalent to malloc(size). --- > realloc(NULL, size) is equivalent to malloc(size). 5115a5120,5123 >

    > The function returns a pointer to the string (that is, s). > > 10729c10737 <


    math.ldexp(m, e)

    --- >

    math.ldexp (m, e)

    11796a11805,11810 > These negative indices are only available when the vararg table > has been optimized away; > otherwise, the vararg arguments are available in the vararg table. > > >

    12488c12502 < Sat Nov 15 00:41:28 UTC 2025 --- > Mon Dec 1 13:38:36 UTC 2025 diff -Nr lua-5.5.0-rc1/src/lcode.c lua-5.5.0-rc2/src/lcode.c 809c809 < fs->f->flag |= PF_VATAB; /* function will need a vararg table */ --- > needvatab(fs->f); /* function will need a vararg table */ 1130c1130 < fs->f->flag |= PF_VATAB; /* function will need a vararg table */ --- > needvatab(fs->f); /* function will need a vararg table */ 1929a1930,1931 > if (p->flag & PF_VATAB) /* will it use a vararg table? */ > p->flag &= cast_byte(~PF_VAHID); /* then it will not use hidden args. */ 1937c1939 < if (!(fs->needclose || (p->flag & PF_ISVARARG))) --- > if (!(fs->needclose || (p->flag & PF_VAHID))) 1945,1946c1947,1948 < if (p->flag & PF_ISVARARG) < SETARG_C(*pc, p->numparams + 1); /* signal that it is vararg */ --- > if (p->flag & PF_VAHID) /* does it use hidden arguments? */ > SETARG_C(*pc, p->numparams + 1); /* signal that */ 1951a1954,1958 > break; > } > case OP_VARARG: { > if (p->flag & PF_VATAB) /* function has a vararg table? */ > SETARG_k(*pc, 1); /* must get vararg there */ diff -Nr lua-5.5.0-rc1/src/lcorolib.c lua-5.5.0-rc2/src/lcorolib.c 192c192,194 < case COS_RUN: /* running coroutine? */ --- > case COS_NORM: > return luaL_error(L, "cannot close a %s coroutine", statname[status]); > case COS_RUN: 197c199,201 < lua_assert(0); /* previous call does not return */ --- > /* previous call does not return *//* FALLTHROUGH */ > default: > lua_assert(0); 199,200d202 < default: /* normal or running coroutine */ < return luaL_error(L, "cannot close a %s coroutine", statname[status]); diff -Nr lua-5.5.0-rc1/src/ldebug.c lua-5.5.0-rc2/src/ldebug.c 187c187 < if (clLvalue(s2v(ci->func.p))->p->flag & PF_ISVARARG) { --- > if (clLvalue(s2v(ci->func.p))->p->flag & PF_VAHID) { 307c307 < if (!(p->flag & PF_ISVARARG)) /* regular function? */ --- > if (!(isvararg(p))) /* regular function? */ 351c351 < ar->isvararg = (f->l.p->flag & PF_ISVARARG) ? 1 : 0; --- > ar->isvararg = (isvararg(f->l.p)) ? 1 : 0; 915c915 < if (p->flag & PF_ISVARARG) --- > if (isvararg(p)) diff -Nr lua-5.5.0-rc1/src/ldo.c lua-5.5.0-rc2/src/ldo.c 490c490 < if (p->flag & PF_ISVARARG) --- > if (p->flag & PF_VAHID) diff -Nr lua-5.5.0-rc1/src/lobject.h lua-5.5.0-rc2/src/lobject.h 586,589c586,588 < #define PF_ISVARARG 1 /* function is vararg */ < #define PF_VAVAR 2 /* function has vararg parameter */ < #define PF_VATAB 4 /* function has vararg table */ < #define PF_FIXED 8 /* prototype has parts in fixed memory */ --- > #define PF_VAHID 1 /* function has hidden vararg arguments */ > #define PF_VATAB 2 /* function has vararg table */ > #define PF_FIXED 4 /* prototype has parts in fixed memory */ 590a590,597 > /* a vararg function either has hidden args. or a vararg table */ > #define isvararg(p) ((p)->flag & (PF_VAHID | PF_VATAB)) > > /* > ** mark that a function needs a vararg table. (The flag PF_VAHID will > ** be cleared later.) > */ > #define needvatab(p) ((p)->flag |= PF_VATAB) diff -Nr lua-5.5.0-rc1/src/lopcodes.h lua-5.5.0-rc2/src/lopcodes.h 227,228c227,228 < ** Grep "ORDER OP" if you change these enums. Opcodes marked with a (*) < ** has extra descriptions in the notes after the enumeration. --- > ** Grep "ORDER OP" if you change this enum. > ** See "Notes" below for more information about some instructions. 241c241 < OP_LFALSESKIP,/*A R[A] := false; pc++ (*) */ --- > OP_LFALSESKIP,/*A R[A] := false; pc++ */ 292c292 < OP_MMBIN,/* A B C call C metamethod over R[A] and R[B] (*) */ --- > OP_MMBIN,/* A B C call C metamethod over R[A] and R[B] */ 318c318 < OP_TESTSET,/* A B k if (not R[B] == k) then pc++ else R[A] := R[B] (*) */ --- > OP_TESTSET,/* A B k if (not R[B] == k) then pc++ else R[A] := R[B] */ 323c323 < OP_RETURN,/* A B C k return R[A], ... ,R[A+B-2] (see note) */ --- > OP_RETURN,/* A B C k return R[A], ... ,R[A+B-2] */ 339c339 < OP_VARARG,/* A C R[A], R[A+1], ..., R[A+C-2] = vararg */ --- > OP_VARARG,/* A B C k R[A], ..., R[A+C-2] = varargs */ 343c343 < OP_ERRNNIL,/* A Bx raise error if R[A] ~= nil (K[Bx] is global name)*/ --- > OP_ERRNNIL,/* A Bx raise error if R[A] ~= nil (K[Bx - 1] is global name)*/ 345c345 < OP_VARARGPREP,/* (adjust vararg parameters) */ --- > OP_VARARGPREP,/* (adjust varargs) */ 374c374,375 < set top (like in OP_CALL with C == 0). --- > set top (like in OP_CALL with C == 0). 'k' means function has a > vararg table, which is in R[B]. 388a390,392 > (*) In OP_ERRNNIL, (Bx == 0) means index of global name doesn't > fit in Bx. (So, that name is not available for the error message.) > 393c397 < (the constant is the first operand). --- > (the constant is the first operand). 395c399,400 < (*) All 'skips' (pc++) assume that next instruction is a jump. --- > (*) All comparison and test instructions assume that the instruction > being skipped (pc++) is a jump. 399,400c404,406 < the function is vararg, so that its 'func' must be corrected before < returning; in this case, (C - 1) is its number of fixed parameters. --- > the function has hidden vararg arguments, so that its 'func' must be > corrected before returning; in this case, (C - 1) is its number of > fixed parameters. diff -Nr lua-5.5.0-rc1/src/lparser.c lua-5.5.0-rc2/src/lparser.c 307c307 < fs->f->flag |= PF_VATAB; /* function will need a vararg table */ --- > needvatab(fs->f); /* function will need a vararg table */ 1059,1061c1059,1060 < 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_VAHID; /* by default, use hidden vararg arguments */ 1081c1080 < varargk |= PF_ISVARARG; --- > varargk = 1; 1083c1082 < if (ls->t.token == TK_NAME) { --- > if (ls->t.token == TK_NAME) 1085,1086c1084,1085 < varargk |= PF_VAVAR; < } --- > else > new_localvarliteral(ls, "(vararg table)"); 1095,1098c1094,1096 < 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 */ 1288c1286 < check_condition(ls, fs->f->flag & PF_ISVARARG, --- > check_condition(ls, isvararg(fs->f), 1290c1288 < 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)); 2156c2154 < setvararg(fs, PF_ISVARARG); /* main function is always vararg */ --- > setvararg(fs); /* main function is always vararg */ diff -Nr lua-5.5.0-rc1/src/ltm.c lua-5.5.0-rc2/src/ltm.c 244a245 > luaC_checkGC(L); 252c253 < ** ^ ci->func ^ L->top --- > ** ^ ci->func 254c255,256 < void luaT_adjustvarargs (lua_State *L, CallInfo *ci, const Proto *p) { --- > static void buildhiddenargs (lua_State *L, CallInfo *ci, const Proto *p, > int totalargs, int nfixparams, int nextra) { 256,258d257 < int totalargs = cast_int(L->top.p - ci->func.p) - 1; < int nfixparams = p->numparams; < int nextra = totalargs - nfixparams; /* number of extra arguments */ 261c260 < /* copy function to the top of the stack */ --- > /* copy function to the top of the stack, after extra arguments */ 263c262 < /* move fixed parameters to the top of the stack */ --- > /* move fixed parameters to after the copied function */ 268,274c267 < if (p->flag & PF_VAVAR) { /* is there a vararg parameter? */ < if (p->flag & PF_VATAB) /* does it need a vararg table? */ < createvarargtab(L, ci->func.p + nfixparams + 1, nextra); < else /* no table; set parameter to nil */ < setnilvalue(s2v(L->top.p)); < } < ci->func.p += totalargs + 1; --- > ci->func.p += totalargs + 1; /* 'func' now lives after hidden arguments */ 276c269,288 < lua_assert(L->top.p <= ci->top.p && ci->top.p <= L->stack_last.p); --- > } > > > void luaT_adjustvarargs (lua_State *L, CallInfo *ci, const Proto *p) { > int totalargs = cast_int(L->top.p - ci->func.p) - 1; > int nfixparams = p->numparams; > int nextra = totalargs - nfixparams; /* number of extra arguments */ > if (p->flag & PF_VATAB) { /* does it need a vararg table? */ > lua_assert(!(p->flag & PF_VAHID)); > createvarargtab(L, ci->func.p + nfixparams + 1, nextra); > /* move table to proper place (last parameter) */ > setobjs2s(L, ci->func.p + nfixparams + 1, L->top.p - 1); > } > else { /* no table */ > lua_assert(p->flag & PF_VAHID); > buildhiddenargs(L, ci, p, totalargs, nfixparams, nextra); > /* set vararg parameter to nil */ > setnilvalue(s2v(ci->func.p + nfixparams + 1)); > lua_assert(L->top.p <= ci->top.p && ci->top.p <= L->stack_last.p); > } 302,304c314,342 < void luaT_getvarargs (lua_State *L, CallInfo *ci, StkId where, int wanted) { < int i; < int nextra = ci->u.l.nextraargs; --- > /* > ** Get the number of extra arguments in a vararg function. If vararg > ** table has been optimized away, that number is in the call info. > ** Otherwise, get the field 'n' from the vararg table and check that it > ** has a proper value (non-negative integer not larger than the stack > ** limit). > */ > static int getnumargs (lua_State *L, CallInfo *ci, Table *h) { > if (h == NULL) /* no vararg table? */ > return ci->u.l.nextraargs; > else { > TValue res; > if (luaH_getshortstr(h, luaS_new(L, "n"), &res) != LUA_VNUMINT || > l_castS2U(ivalue(&res)) > cast_uint(INT_MAX/2)) > luaG_runerror(L, "vararg table has no proper 'n'"); > return cast_int(ivalue(&res)); > } > } > > > /* > ** Get 'wanted' vararg arguments and put them in 'where'. 'vatab' is > ** the register of the vararg table or -1 if there is no vararg table. > */ > void luaT_getvarargs (lua_State *L, CallInfo *ci, StkId where, int wanted, > int vatab) { > Table *h = (vatab < 0) ? NULL : hvalue(s2v(ci->func.p + vatab + 1)); > int nargs = getnumargs(L, ci, h); /* number of available vararg args. */ > int i, touse; /* 'touse' is minimum between 'wanted' and 'nargs' */ 306,308c344,359 < wanted = nextra; /* get all extra arguments available */ < checkstackp(L, nextra, where); /* ensure stack space */ < L->top.p = where + nextra; /* next instruction will need top */ --- > touse = wanted = nargs; /* get all extra arguments available */ > checkstackp(L, nargs, where); /* ensure stack space */ > L->top.p = where + nargs; /* next instruction will need top */ > } > else > touse = (nargs > wanted) ? wanted : nargs; > if (h == NULL) { /* no vararg table? */ > for (i = 0; i < touse; i++) /* get vararg values from the stack */ > setobjs2s(L, where + i, ci->func.p - nargs + i); > } > else { /* get vararg values from vararg table */ > for (i = 0; i < touse; i++) { > lu_byte tag = luaH_getint(h, i + 1, s2v(where + i)); > if (tagisempty(tag)) > setnilvalue(s2v(where + i)); > } 310,311d360 < for (i = 0; i < wanted && i < nextra; i++) < setobjs2s(L, where + i, ci->func.p - nextra + i); diff -Nr lua-5.5.0-rc1/src/ltm.h lua-5.5.0-rc2/src/ltm.h 101,102c101,102 < LUAI_FUNC void luaT_getvarargs (lua_State *L, struct CallInfo *ci, < StkId where, int wanted); --- > LUAI_FUNC void luaT_getvarargs (lua_State *L, struct CallInfo *ci, StkId where, > int wanted, int vatab); diff -Nr lua-5.5.0-rc1/src/luac.c lua-5.5.0-rc2/src/luac.c 349a350,351 > int vb=GETARG_vB(i); > int vc=GETARG_vC(i); 431,432c433,434 < printf("%d %d %d",a,b,c); < printf(COMMENT "%d",c+EXTRAARGC); --- > printf("%d %d %d%s",a,vb,vc,ISK); > printf(COMMENT "%d",vc+EXTRAARGC); 636c638 < printf("%d %d %d",a,b,c); --- > printf("%d %d %d%s",a,vb,vc,ISK); 644c646 < printf("%d %d",a,c); --- > printf("%d %d %d%s",a,b,c,ISK); 653c655,656 < printf(COMMENT); PrintConstant(f,bx); --- > printf(COMMENT); > if (bx==0) printf("?"); else PrintConstant(f,bx-1); 689c692 < (int)(f->numparams),(f->flag & PF_ISVARARG)?"+":"",SS(f->numparams), --- > (int)(f->numparams),isvararg(f)?"+":"",SS(f->numparams), diff -Nr lua-5.5.0-rc1/src/lvm.c lua-5.5.0-rc2/src/lvm.c 1938,1939c1938,1940 < int n = GETARG_C(i) - 1; /* required results */ < Protect(luaT_getvarargs(L, ci, ra, n)); --- > int n = GETARG_C(i) - 1; /* required results (-1 means all) */ > int vatab = GETARG_k(i) ? GETARG_B(i) : -1; > Protect(luaT_getvarargs(L, ci, ra, n, vatab));