diff -u -r lua-5.4.7/Makefile lua-5.4.8/Makefile --- lua-5.4.7/Makefile 2024-05-08 18:47:12.000000000 -0300 +++ lua-5.4.8/Makefile 2025-05-21 13:56:52.164597685 -0300 @@ -46,7 +46,7 @@ # Lua version and release. V= 5.4 -R= $V.7 +R= $V.8 # Targets start here. all: $(PLAT) diff -u -r lua-5.4.7/README lua-5.4.8/README --- lua-5.4.7/README 2024-06-13 19:16:31.000000000 -0300 +++ lua-5.4.8/README 2025-05-21 18:12:27.263738782 -0300 @@ -1,5 +1,5 @@ -This is Lua 5.4.7, released on 13 Jun 2024. +This is Lua 5.4.8, released on 21 May 2025. For installation instructions, license details, and further information about Lua, see doc/readme.html. diff -u -r lua-5.4.7/doc/contents.html lua-5.4.8/doc/contents.html --- lua-5.4.7/doc/contents.html 2024-05-09 11:47:10.000000000 -0300 +++ lua-5.4.8/doc/contents.html 2025-05-21 18:11:34.516653622 -0300 @@ -32,7 +32,7 @@

-Copyright © 2020–2024 Lua.org, PUC-Rio. +Copyright © 2020–2025 Lua.org, PUC-Rio. Freely available under the terms of the Lua license. @@ -668,10 +668,10 @@

diff -u -r lua-5.4.7/doc/manual.html lua-5.4.8/doc/manual.html --- lua-5.4.7/doc/manual.html 2024-06-13 19:15:52.000000000 -0300 +++ lua-5.4.8/doc/manual.html 2025-05-21 18:09:59.662097177 -0300 @@ -19,7 +19,7 @@

-Copyright © 2020–2024 Lua.org, PUC-Rio. +Copyright © 2020–2025 Lua.org, PUC-Rio. Freely available under the terms of the Lua license. @@ -12050,10 +12050,10 @@

diff -u -r lua-5.4.7/doc/readme.html lua-5.4.8/doc/readme.html --- lua-5.4.7/doc/readme.html 2024-05-08 18:56:16.000000000 -0300 +++ lua-5.4.8/doc/readme.html 2025-05-21 18:12:02.002655797 -0300 @@ -109,7 +109,7 @@
  1. Open a terminal window and move to -the top-level directory, which is named lua-5.4.7. +the top-level directory, which is named lua-5.4.8. The Makefile there controls both the build process and the installation process.

  2. @@ -302,7 +302,7 @@ license page.
    -Copyright © 1994–2024 Lua.org, PUC-Rio. +Copyright © 1994–2025 Lua.org, PUC-Rio.

    Permission is hereby granted, free of charge, to any person obtaining a copy @@ -329,10 +329,10 @@

    diff -u -r lua-5.4.7/src/lapi.c lua-5.4.8/src/lapi.c --- lua-5.4.7/src/lapi.c 2024-06-13 19:15:09.000000000 -0300 +++ lua-5.4.8/src/lapi.c 2025-05-21 18:09:15.092715201 -0300 @@ -1343,7 +1343,7 @@ LUA_API void *lua_newuserdatauv (lua_State *L, size_t size, int nuvalue) { Udata *u; lua_lock(L); - api_check(L, 0 <= nuvalue && nuvalue < USHRT_MAX, "invalid value"); + api_check(L, 0 <= nuvalue && nuvalue < SHRT_MAX, "invalid value"); u = luaS_newudata(L, size, nuvalue); setuvalue(L, s2v(L->top.p), u); api_incr_top(L); diff -u -r lua-5.4.7/src/lcode.c lua-5.4.8/src/lcode.c --- lua-5.4.7/src/lcode.c 2024-06-13 19:15:09.000000000 -0300 +++ lua-5.4.8/src/lcode.c 2025-05-21 18:09:15.363705363 -0300 @@ -35,6 +35,7 @@ #define MAXREGS 255 +/* (note that expressions VJMP also have jumps.) */ #define hasjumps(e) ((e)->t != (e)->f) @@ -985,7 +986,7 @@ ** or it is a constant. */ void luaK_exp2val (FuncState *fs, expdesc *e) { - if (hasjumps(e)) + if (e->k == VJMP || hasjumps(e)) luaK_exp2anyreg(fs, e); else luaK_dischargevars(fs, e); diff -u -r lua-5.4.7/src/ldebug.c lua-5.4.8/src/ldebug.c --- lua-5.4.7/src/ldebug.c 2024-06-13 19:15:09.000000000 -0300 +++ lua-5.4.8/src/ldebug.c 2025-05-21 18:09:15.705692947 -0300 @@ -37,6 +37,9 @@ static const char *funcnamefromcall (lua_State *L, CallInfo *ci, const char **name); +static const char strlocal[] = "local"; +static const char strupval[] = "upvalue"; + static int currentpc (CallInfo *ci) { lua_assert(isLua(ci)); @@ -497,7 +500,7 @@ int pc = *ppc; *name = luaF_getlocalname(p, reg + 1, pc); if (*name) /* is a local? */ - return "local"; + return strlocal; /* else try symbolic execution */ *ppc = pc = findsetreg(p, pc, reg); if (pc != -1) { /* could find instruction? */ @@ -512,7 +515,7 @@ } case OP_GETUPVAL: { *name = upvalname(p, GETARG_B(i)); - return "upvalue"; + return strupval; } case OP_LOADK: return kname(p, GETARG_Bx(i), name); case OP_LOADKX: return kname(p, GETARG_Ax(p->code[pc + 1]), name); @@ -547,15 +550,21 @@ /* ** Check whether table being indexed by instruction 'i' is the -** environment '_ENV' +** environment '_ENV'. If the table is an upvalue, get its name; +** otherwise, find some "name" for the table and check whether +** that name is the name of a local variable (and not, for instance, +** a string). Then check that, if there is a name, it is '_ENV'. */ static const char *isEnv (const Proto *p, int pc, Instruction i, int isup) { int t = GETARG_B(i); /* table index */ const char *name; /* name of indexed variable */ if (isup) /* is 't' an upvalue? */ name = upvalname(p, t); - else /* 't' is a register */ - basicgetobjname(p, &pc, t, &name); + else { /* 't' is a register */ + const char *what = basicgetobjname(p, &pc, t, &name); + if (what != strlocal && what != strupval) + name = NULL; /* cannot be the variable _ENV */ + } return (name && strcmp(name, LUA_ENV) == 0) ? "global" : "field"; } @@ -701,7 +710,7 @@ for (i = 0; i < c->nupvalues; i++) { if (c->upvals[i]->v.p == o) { *name = upvalname(c->p, i); - return "upvalue"; + return strupval; } } return NULL; diff -u -r lua-5.4.7/src/ldo.c lua-5.4.8/src/ldo.c --- lua-5.4.7/src/ldo.c 2024-06-13 19:15:09.000000000 -0300 +++ lua-5.4.8/src/ldo.c 2025-05-21 18:09:15.754691168 -0300 @@ -94,10 +94,6 @@ setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */ break; } - case LUA_ERRERR: { - setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling")); - break; - } case LUA_OK: { /* special case only for closing upvalues */ setnilvalue(s2v(oldtop)); /* no error message */ break; @@ -120,6 +116,7 @@ else { /* thread has no error handler */ global_State *g = G(L); errcode = luaE_resetthread(L, errcode); /* close all upvalues */ + L->status = errcode; if (g->mainthread->errorJmp) { /* main thread has a handler? */ setobjs2s(L, g->mainthread->top.p++, L->top.p - 1); /* copy error obj. */ luaD_throw(g->mainthread, errcode); /* re-throw in main thread */ @@ -198,6 +195,16 @@ /* some space for error handling */ #define ERRORSTACKSIZE (LUAI_MAXSTACK + 200) + +/* raise an error while running the message handler */ +l_noret luaD_errerr (lua_State *L) { + TString *msg = luaS_newliteral(L, "error in error handling"); + setsvalue2s(L, L->top.p, msg); + L->top.p++; /* assume EXTRA_STACK */ + luaD_throw(L, LUA_ERRERR); +} + + /* ** Reallocate the stack to a new size, correcting all pointers into it. ** In ISO C, any pointer use after the pointer has been deallocated is @@ -247,7 +254,7 @@ a stack error; cannot grow further than that. */ lua_assert(stacksize(L) == ERRORSTACKSIZE); if (raiseerror) - luaD_throw(L, LUA_ERRERR); /* error inside message handler */ + luaD_errerr(L); /* error inside message handler */ return 0; /* if not 'raiseerror', just signal it */ } else if (n < LUAI_MAXSTACK) { /* avoids arithmetic overflows */ diff -u -r lua-5.4.7/src/ldo.h lua-5.4.8/src/ldo.h --- lua-5.4.7/src/ldo.h 2024-06-13 19:15:09.000000000 -0300 +++ lua-5.4.8/src/ldo.h 2025-05-21 18:09:15.793689752 -0300 @@ -60,6 +60,7 @@ /* type of protected functions, to be ran by 'runprotected' */ typedef void (*Pfunc) (lua_State *L, void *ud); +LUAI_FUNC l_noret luaD_errerr (lua_State *L); LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop); LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, const char *mode); diff -u -r lua-5.4.7/src/lparser.c lua-5.4.8/src/lparser.c --- lua-5.4.7/src/lparser.c 2024-06-13 19:15:09.000000000 -0300 +++ lua-5.4.8/src/lparser.c 2025-05-21 18:09:16.386668225 -0300 @@ -198,7 +198,7 @@ checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal, MAXVARS, "local variables"); luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1, - dyd->actvar.size, Vardesc, USHRT_MAX, "local variables"); + dyd->actvar.size, Vardesc, SHRT_MAX, "local variables"); var = &dyd->actvar.arr[dyd->actvar.n++]; var->vd.kind = VDKREG; /* default */ var->vd.name = name; @@ -849,12 +849,11 @@ FuncState *fs = ls->fs; int reg = ls->fs->freereg; expdesc tab, key, val; - if (ls->t.token == TK_NAME) { - checklimit(fs, cc->nh, MAX_INT, "items in a constructor"); + if (ls->t.token == TK_NAME) codename(ls, &key); - } else /* ls->t.token == '[' */ yindex(ls, &key); + checklimit(fs, cc->nh, MAX_INT, "items in a constructor"); cc->nh++; checknext(ls, '='); tab = *cc->t; diff -u -r lua-5.4.7/src/lstate.c lua-5.4.8/src/lstate.c --- lua-5.4.7/src/lstate.c 2024-06-13 19:15:09.000000000 -0300 +++ lua-5.4.8/src/lstate.c 2025-05-21 18:09:16.408667427 -0300 @@ -166,7 +166,7 @@ if (getCcalls(L) == LUAI_MAXCCALLS) luaG_runerror(L, "C stack overflow"); else if (getCcalls(L) >= (LUAI_MAXCCALLS / 10 * 11)) - luaD_throw(L, LUA_ERRERR); /* error while handling stack error */ + luaD_errerr(L); /* error while handling stack error */ } @@ -272,7 +272,9 @@ luaC_freeallobjects(L); /* just collect its objects */ else { /* closing a fully built state */ L->ci = &L->base_ci; /* unwind CallInfo list */ + L->errfunc = 0; /* stack unwind can "throw away" the error function */ luaD_closeprotected(L, 1, LUA_OK); /* close all upvalues */ + L->top.p = L->stack.p + 1; /* empty the stack to run finalizers */ luaC_freeallobjects(L); /* collect all objects */ luai_userstateclose(L); } @@ -328,6 +330,7 @@ if (status == LUA_YIELD) status = LUA_OK; L->status = LUA_OK; /* so it can run __close metamethods */ + L->errfunc = 0; /* stack unwind can "throw away" the error function */ status = luaD_closeprotected(L, 1, status); if (status != LUA_OK) /* errors? */ luaD_seterrorobj(L, status, L->stack.p + 1); diff -u -r lua-5.4.7/src/lua.c lua-5.4.8/src/lua.c --- lua-5.4.7/src/lua.c 2024-06-13 19:15:10.000000000 -0300 +++ lua-5.4.8/src/lua.c 2025-05-21 18:09:16.694657045 -0300 @@ -490,10 +490,8 @@ if (status == LUA_ERRSYNTAX) { size_t lmsg; const char *msg = lua_tolstring(L, -1, &lmsg); - if (lmsg >= marklen && strcmp(msg + lmsg - marklen, EOFMARK) == 0) { - lua_pop(L, 1); + if (lmsg >= marklen && strcmp(msg + lmsg - marklen, EOFMARK) == 0) return 1; - } } return 0; /* else... */ } @@ -508,9 +506,9 @@ size_t l; const char *prmt = get_prompt(L, firstline); int readstatus = lua_readline(L, b, prmt); - if (readstatus == 0) - return 0; /* no input (prompt will be popped by caller) */ lua_pop(L, 1); /* remove prompt */ + if (readstatus == 0) + return 0; /* no input */ l = strlen(b); if (l > 0 && b[l-1] == '\n') /* line ends with newline? */ b[--l] = '\0'; /* remove it */ @@ -552,8 +550,9 @@ int status = luaL_loadbuffer(L, line, len, "=stdin"); /* try it */ if (!incomplete(L, status) || !pushline(L, 0)) { lua_saveline(L, line); /* keep history */ - return status; /* cannot or should not try to add continuation line */ + return status; /* should not or cannot try to add continuation line */ } + lua_remove(L, -2); /* remove error message (from incomplete line) */ lua_pushliteral(L, "\n"); /* add newline... */ lua_insert(L, -2); /* ...between the two lines */ lua_concat(L, 3); /* join them */ diff -u -r lua-5.4.7/src/lua.h lua-5.4.8/src/lua.h --- lua-5.4.7/src/lua.h 2024-06-13 19:15:10.000000000 -0300 +++ lua-5.4.8/src/lua.h 2025-05-21 18:09:16.732655664 -0300 @@ -18,14 +18,14 @@ #define LUA_VERSION_MAJOR "5" #define LUA_VERSION_MINOR "4" -#define LUA_VERSION_RELEASE "7" +#define LUA_VERSION_RELEASE "8" #define LUA_VERSION_NUM 504 -#define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + 7) +#define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + 8) #define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR #define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE -#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2024 Lua.org, PUC-Rio" +#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2025 Lua.org, PUC-Rio" #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" @@ -497,7 +497,7 @@ /****************************************************************************** -* Copyright (C) 1994-2024 Lua.org, PUC-Rio. +* Copyright (C) 1994-2025 Lua.org, PUC-Rio. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the diff -u -r lua-5.4.7/src/lvm.c lua-5.4.8/src/lvm.c --- lua-5.4.7/src/lvm.c 2024-06-13 19:15:10.000000000 -0300 +++ lua-5.4.8/src/lvm.c 2025-05-21 18:09:16.913649094 -0300 @@ -339,7 +339,10 @@ lua_assert(isempty(slot)); /* slot must be empty */ tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */ if (tm == NULL) { /* no metamethod? */ + sethvalue2s(L, L->top.p, h); /* anchor 't' */ + L->top.p++; /* assume EXTRA_STACK */ luaH_finishset(L, h, key, slot, val); /* set new value */ + L->top.p--; invalidateTMcache(h); luaC_barrierback(L, obj2gco(h), val); return;