Lua diffs-lua-5.5.0-rc1-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.

doc/contents.html

88c88,89
< <LI><A HREF="manual.html#3.4.12">3.4.12 &ndash; Lists of expressions, multiple results, and adjustment<A>
> <LI><A HREF="manual.html#3.4.12">3.4.12 &ndash; Lists of Expressions, Multiple Results, and Adjustment</A>
> </UL>

97c98
< <LI><A HREF="manual.html#4.1.3">4.1.3 &ndash; Pointers to strings</A>
> <LI><A HREF="manual.html#4.1.3">4.1.3 &ndash; Pointers to Strings</A>

677c678
< Sat Nov 15 00:51:05 UTC 2025
> Mon Dec  1 13:57:23 UTC 2025

doc/manual.html

2704c2704
< is syntactic sugar for <code>v.name(v,<em>args</em>)</code>,
> is syntactic sugar for <code>v.name(v, <em>args</em>)</code>,

2888,2895c2888,2891
< to the function through a <em>vararg expression</em> and,
< if present, a <em>vararg table</em>.
< 
< 
< <p>
< 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 <a href="#3.4.12">&sect;3.4.12</a>).
> to the function through a <em>vararg table</em>.
> In that table,
> the values at indices 1, 2, etc. are the extra arguments,
> and the value at index "<code>n</code>" is the number of extra arguments.

2907c2903
< to the vararg expression:
> to the vararg table:

2918,2921c2914,2917
<      g(3)             a=3, b=nil, ... -&gt;  (nothing)
<      g(3, 4)          a=3, b=4,   ... -&gt;  (nothing)
<      g(3, 4, 5, 8)    a=3, b=4,   ... -&gt;  5  8
<      g(5, r())        a=5, b=1,   ... -&gt;  2  3
>      g(3)             a=3, b=nil, va. table -&gt;  {n = 0}
>      g(3, 4)          a=3, b=4,   va. table -&gt;  {n = 0}
>      g(3, 4, 5, 8)    a=3, b=4,   va. table -&gt;  {5, 8, n = 2}
>      g(5, r())        a=5, b=1,   va. table -&gt;  {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 "<code>n</code>" 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 <a href="#pdf-table.pack"><code>table.pack</code></a>:
> 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.
> 
> 
> <p>
> 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 "<code>n</code>".
> (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 <a href="#3.4.12">&sect;3.4.12</a>).

2937,2939d2938
< <pre>
<      local &lt;const&gt; name = table.pack(...)
< </pre>

2943,2944c2942
< if the vararg table is used only as a base in indexing expressions
< (the <code>t</code> in <code>t[exp]</code> or <code>t.id</code>) 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 <code>t[exp]</code> or <code>t.id</code>).
> Note that an anonymous vararg table always satisfy these conditions.

2954,2955c2959
< <h3>3.4.12 &ndash; <a name="3.4.12">Lists of expressions, multiple results,
< and adjustment</a></h3>
> <h3>3.4.12 &ndash; <a name="3.4.12">Lists of Expressions, Multiple Results, and Adjustment</a></h3>

3259c3263
< <h3>4.1.3 &ndash; <a name="4.1.3">Pointers to strings</a></h3>
> <h3>4.1.3 &ndash; <a name="4.1.3">Pointers to Strings</a></h3>

3754c3758
< <code>realloc(NULL,size)</code> is equivalent to <code>malloc(size)</code>.
> <code>realloc(NULL, size)</code> is equivalent to <code>malloc(size)</code>.

5115a5120,5123
> <p>
> The function returns a pointer to the string (that is, <code>s</code>).
> 
> 

10729c10737
< <hr><h3><a name="pdf-math.ldexp"><code>math.ldexp(m, e)</code></a></h3>
> <hr><h3><a name="pdf-math.ldexp"><code>math.ldexp (m, e)</code></a></h3>

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.
> 
> 
> <p>

12488c12502
< Sat Nov 15 00:41:28 UTC 2025
> Mon Dec  1 13:38:36 UTC 2025

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 */

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]);

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))

src/ldo.c

490c490
<       if (p->flag & PF_ISVARARG)
>       if (p->flag & PF_VAHID)

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)

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.

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 */

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);

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);

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),

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));