From e370aaee562af634fa762d740f75eb051d0fc3df Mon Sep 17 00:00:00 2001 From: DarioS Date: Tue, 1 Sep 2026 11:56:08 +0200 Subject: [PATCH] lua 5.4.9 : - ricompilazione per nuova versione. --- lapi.c | 1 + lauxlib.c | 17 +++++++++++++++-- ldo.c | 21 ++++++++++++++++++++- ldo.h | 1 + lgc.c | 15 ++++++++++----- lparser.c | 2 ++ lstate.c | 17 +++++++++++------ lstate.h | 2 +- lstrlib.c | 3 +-- lua.c | 3 ++- lua.h | 8 ++++---- lua.rc | Bin 10346 -> 10346 bytes lutf8lib.c | 4 +++- lvm.c | 7 ++++++- 14 files changed, 77 insertions(+), 24 deletions(-) diff --git a/lapi.c b/lapi.c index 04e09cf..588ab33 100644 --- a/lapi.c +++ b/lapi.c @@ -1089,6 +1089,7 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, ZIO z; int status; lua_lock(L); + luaC_checkGC(L); if (!chunkname) chunkname = "?"; luaZ_init(L, &z, reader, data); status = luaD_protectedparser(L, &z, chunkname, mode); diff --git a/lauxlib.c b/lauxlib.c index a00c83c..e07c4dc 100644 --- a/lauxlib.c +++ b/lauxlib.c @@ -509,12 +509,25 @@ static const luaL_Reg boxmt[] = { /* box metamethods */ }; +/* +** Get/create metatable (MT) for boxes +*/ +static void getBoxMT (lua_State *L) { + const char *BOXMT = "_UBOX*"; /* key for the metatable */ + if (luaL_getmetatable(L, BOXMT) == LUA_TNIL) { /* MT not created yet? */ + luaL_newlibtable(L, boxmt); /* create it */ + luaL_setfuncs(L, boxmt, 0); /* initialize it */ + lua_copy(L, -1, -2); /* change stack from nil,MT to MT,MT */ + lua_setfield(L, LUA_REGISTRYINDEX, BOXMT); /* store MT in the registry */ + } +} + + static void newbox (lua_State *L) { UBox *box = (UBox *)lua_newuserdatauv(L, sizeof(UBox), 0); box->box = NULL; box->bsize = 0; - if (luaL_newmetatable(L, "_UBOX*")) /* creating metatable? */ - luaL_setfuncs(L, boxmt, 0); /* set its metamethods */ + getBoxMT(L); lua_setmetatable(L, -2); } diff --git a/ldo.c b/ldo.c index c92573d..8085b73 100644 --- a/ldo.c +++ b/ldo.c @@ -205,6 +205,25 @@ l_noret luaD_errerr (lua_State *L) { } +/* +** Check whether stacks have enough space to run a simple function (such +** as a finalizer): At least BASIC_STACK_SIZE in the Lua stack, two +** available CallInfos, and two "slots" in the C stack. +*/ +int luaD_checkminstack (lua_State *L) { + if (getCcalls(L) >= LUAI_MAXCCALLS - 2) + return 0; /* not enough C-stack slots */ + if (L->ci->next == NULL && luaE_extendCI(L, 0) == NULL) + return 0; /* unable to allocate first ci */ + if (L->ci->next->next == NULL && luaE_extendCI(L, 0) == NULL) + return 0; /* unable to allocate second ci */ + if (L->stack_last.p - L->top.p >= BASIC_STACK_SIZE) + return 1; /* enough (BASIC_STACK_SIZE) free slots in the Lua stack */ + else /* try to grow stack to a size with enough free slots */ + return luaD_growstack(L, BASIC_STACK_SIZE, 0); +} + + /* ** 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 @@ -503,7 +522,7 @@ void luaD_poscall (lua_State *L, CallInfo *ci, int nres) { -#define next_ci(L) (L->ci->next ? L->ci->next : luaE_extendCI(L)) +#define next_ci(L) (L->ci->next ? L->ci->next : luaE_extendCI(L, 1)) l_sinline CallInfo *prepCallInfo (lua_State *L, StkId func, int nret, diff --git a/ldo.h b/ldo.h index 4de9540..4c8db86 100644 --- a/ldo.h +++ b/ldo.h @@ -80,6 +80,7 @@ LUAI_FUNC int luaD_reallocstack (lua_State *L, int newsize, int raiseerror); LUAI_FUNC int luaD_growstack (lua_State *L, int n, int raiseerror); LUAI_FUNC void luaD_shrinkstack (lua_State *L); LUAI_FUNC void luaD_inctop (lua_State *L); +LUAI_FUNC int luaD_checkminstack (lua_State *L); LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode); LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); diff --git a/lgc.c b/lgc.c index 5817f9e..52cea24 100644 --- a/lgc.c +++ b/lgc.c @@ -553,8 +553,12 @@ static lu_mem traversetable (global_State *g, Table *h) { traverseweakvalue(g, h); else if (!weakvalue) /* strong values? */ traverseephemeron(g, h, 0); - else /* all weak */ - linkgclist(h, g->allweak); /* nothing to traverse now */ + else { /* all weak */ + if (g->gcstate == GCSpropagate) + linkgclist(h, g->grayagain); /* must visit again its metatable */ + else + linkgclist(h, g->allweak); /* must clear collected entries */ + } } else /* not weak */ traversestrongtable(g, h); @@ -1238,7 +1242,7 @@ static void finishgencycle (lua_State *L, global_State *g) { correctgraylists(g); checkSizes(L, g); g->gcstate = GCSpropagate; /* skip restart */ - if (!g->gcemergency) + if (g->tobefnz != NULL && !g->gcemergency && luaD_checkminstack(L)) callallpendingfinalizers(L); } @@ -1628,11 +1632,12 @@ static lu_mem singlestep (lua_State *L) { break; } case GCScallfin: { /* call remaining finalizers */ - if (g->tobefnz && !g->gcemergency) { + if (g->tobefnz && !g->gcemergency && luaD_checkminstack(L)) { g->gcstopem = 0; /* ok collections during finalizers */ work = runafewfinalizers(L, GCFINMAX) * GCFINALIZECOST; } - else { /* emergency mode or no more finalizers */ + else { /* no more finalizers or emergency mode or no enough stack + to run finalizers */ g->gcstate = GCSpause; /* finish collection */ work = 0; } diff --git a/lparser.c b/lparser.c index 1ac8299..f4bfc96 100644 --- a/lparser.c +++ b/lparser.c @@ -940,6 +940,8 @@ static void constructor (LexState *ls, expdesc *t) { if (ls->t.token == '}') break; closelistfield(fs, &cc); field(ls, &cc); + checklimit(fs, cc.tostore + cc.na + cc.nh, INT_MAX/2, + "items in a constructor"); } while (testnext(ls, ',') || testnext(ls, ';')); check_match(ls, '}', '{', line); lastlistfield(fs, &cc); diff --git a/lstate.c b/lstate.c index f3f2ccf..059be80 100644 --- a/lstate.c +++ b/lstate.c @@ -102,14 +102,19 @@ LUA_API int lua_setcstacklimit (lua_State *L, unsigned int limit) { } -CallInfo *luaE_extendCI (lua_State *L) { +CallInfo *luaE_extendCI (lua_State *L, int err) { CallInfo *ci; - lua_assert(L->ci->next == NULL); - ci = luaM_new(L, CallInfo); - lua_assert(L->ci->next == NULL); - L->ci->next = ci; + ci = luaM_reallocvector(L, NULL, 0, 1, CallInfo); + if (l_unlikely(ci == NULL)) { /* allocation failed? */ + if (err) + luaM_error(L); /* raise the error */ + return NULL; /* else only report it */ + } + ci->next = L->ci->next; ci->previous = L->ci; - ci->next = NULL; + L->ci->next = ci; + if (ci->next) + ci->next->previous = ci; ci->u.l.trap = 0; L->nci++; return ci; diff --git a/lstate.h b/lstate.h index 007704c..97bb3e8 100644 --- a/lstate.h +++ b/lstate.h @@ -395,7 +395,7 @@ union GCUnion { LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt); LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); -LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); +LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L, int err); LUAI_FUNC void luaE_shrinkCI (lua_State *L); LUAI_FUNC void luaE_checkcstack (lua_State *L); LUAI_FUNC void luaE_incCstack (lua_State *L); diff --git a/lstrlib.c b/lstrlib.c index 0316716..f748bf8 100644 --- a/lstrlib.c +++ b/lstrlib.c @@ -757,7 +757,6 @@ static int nospecials (const char *p, size_t l) { static void prepstate (MatchState *ms, lua_State *L, const char *s, size_t ls, const char *p, size_t lp) { ms->L = L; - ms->matchdepth = MAXCCALLS; ms->src_init = s; ms->src_end = s + ls; ms->p_end = p + lp; @@ -765,8 +764,8 @@ static void prepstate (MatchState *ms, lua_State *L, static void reprepstate (MatchState *ms) { + ms->matchdepth = MAXCCALLS; ms->level = 0; - lua_assert(ms->matchdepth == MAXCCALLS); } diff --git a/lua.c b/lua.c index 4a90e55..8055b70 100644 --- a/lua.c +++ b/lua.c @@ -302,7 +302,8 @@ static int collectargs (char **argv, int *first) { case '-': /* '--' */ if (argv[i][2] != '\0') /* extra characters after '--'? */ return has_error; /* invalid option */ - *first = i + 1; + /* if there is a script name, it comes after '--' */ + *first = (argv[i + 1] != NULL) ? i + 1 : 0; return args; case '\0': /* '-' */ return args; /* script "name" is '-' */ diff --git a/lua.h b/lua.h index f3ea590..211b97c 100644 --- a/lua.h +++ b/lua.h @@ -18,14 +18,14 @@ #define LUA_VERSION_MAJOR "5" #define LUA_VERSION_MINOR "4" -#define LUA_VERSION_RELEASE "8" +#define LUA_VERSION_RELEASE "9" #define LUA_VERSION_NUM 504 -#define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + 8) +#define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + 9) #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-2025 Lua.org, PUC-Rio" +#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2026 Lua.org, PUC-Rio" #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" @@ -497,7 +497,7 @@ struct lua_Debug { /****************************************************************************** -* Copyright (C) 1994-2025 Lua.org, PUC-Rio. +* Copyright (C) 1994-2026 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 --git a/lua.rc b/lua.rc index bb1ec922e5b6be41cf7b9fbd77e6a384c7f54732..1188b75ab86363a93cbb8d2a8f3b6c119430bb1c 100644 GIT binary patch delta 100 zcmaDA@G4-#H#SDg%@cVunI= 0xfe) /* c >= 1111 1110b ? */ + return NULL; /* would need six or more continuation bytes */ else { int count = 0; /* to count number of continuation bytes */ for (; c & 0x40; c <<= 1) { /* while it needs continuation bytes... */ @@ -74,7 +76,7 @@ static const char *utf8_decode (const char *s, utfint *val, int strict) { res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */ } res |= ((utfint)(c & 0x7F) << (count * 5)); /* add first byte */ - if (count > 5 || res > MAXUTF || res < limits[count]) + if (res > MAXUTF || res < limits[count]) return NULL; /* invalid byte sequence */ s += count; /* skip continuation bytes read */ } diff --git a/lvm.c b/lvm.c index 7023a04..bbadf0a 100644 --- a/lvm.c +++ b/lvm.c @@ -361,7 +361,12 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key, } t = tm; /* else repeat assignment over 'tm' */ if (luaV_fastget(L, t, key, slot, luaH_get)) { - luaV_finishfastset(L, t, slot, val); + /* execute 'luaV_finishfastset', but preserving the original 't' + for the barrier. 't' and 'slot' can point to the same value, + and so the assignment can change 't' value */ + GCObject *h = gcvalue(t); + setobj2t(L, cast(TValue *,slot), val); + luaC_barrierback(L, h, val); return; /* done */ } /* else 'return luaV_finishset(L, t, key, val, slot)' (loop) */