From d5a2ee7e2a46163a2871d4eec3e963433f910e97 Mon Sep 17 00:00:00 2001 From: Nathaniel Wesley Filardo Date: Thu, 22 Dec 2022 20:55:40 +0000 Subject: [PATCH] app/lua53: catch up to lua 5.3.6 (#3415) Adapt https://www.lua.org/work/diffs-lua-5.3.5-lua-5.3.6.html to NodeMCU. Mostly a straight application, but some small tweaks were required and, in lundump.c, some changes were elided and some additional diff reduction applied, as we have heavily diverged from upstream. --- app/lua53/host/liolib.c | 2 ++ app/lua53/lapi.c | 12 ++++++------ app/lua53/lauxlib.c | 11 ++++++++--- app/lua53/lcode.c | 2 +- app/lua53/ldebug.c | 9 +++++---- app/lua53/llex.c | 31 +++++++++++++++++-------------- app/lua53/lobject.c | 2 +- app/lua53/lparser.c | 3 +++ app/lua53/lua.h | 6 +++--- app/lua53/lundump.c | 22 +++++++++++++++------- 10 files changed, 61 insertions(+), 39 deletions(-) diff --git a/app/lua53/host/liolib.c b/app/lua53/host/liolib.c index 8a9e75cd..027d4bd0 100644 --- a/app/lua53/host/liolib.c +++ b/app/lua53/host/liolib.c @@ -277,6 +277,8 @@ static int io_popen (lua_State *L) { const char *filename = luaL_checkstring(L, 1); const char *mode = luaL_optstring(L, 2, "r"); LStream *p = newprefile(L); + luaL_argcheck(L, ((mode[0] == 'r' || mode[0] == 'w') && mode[1] == '\0'), + 2, "invalid mode"); p->f = l_popen(L, filename, mode); p->closef = &io_pclose; return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; diff --git a/app/lua53/lapi.c b/app/lua53/lapi.c index 1b468b95..5dab7cd7 100644 --- a/app/lua53/lapi.c +++ b/app/lua53/lapi.c @@ -1303,13 +1303,12 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { } -static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) { +static UpVal **getupvalref (lua_State *L, int fidx, int n) { LClosure *f; StkId fi = index2addr(L, fidx); api_check(L, ttisLclosure(fi), "Lua function expected"); f = clLvalue(fi); api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index"); - if (pf) *pf = f; return &f->upvals[n - 1]; /* get its upvalue pointer */ } @@ -1318,7 +1317,7 @@ LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { StkId fi = index2addr(L, fidx); switch (ttype(fi)) { case LUA_TLCL: { /* lua closure */ - return *getupvalref(L, fidx, n, NULL); + return *getupvalref(L, fidx, n); } case LUA_TCCL: { /* C closure */ CClosure *f = clCvalue(fi); @@ -1335,9 +1334,10 @@ LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1, int fidx2, int n2) { - LClosure *f1; - UpVal **up1 = getupvalref(L, fidx1, n1, &f1); - UpVal **up2 = getupvalref(L, fidx2, n2, NULL); + UpVal **up1 = getupvalref(L, fidx1, n1); + UpVal **up2 = getupvalref(L, fidx2, n2); + if (*up1 == *up2) + return; luaC_upvdeccount(L, *up1); *up1 = *up2; (*up1)->refcount++; diff --git a/app/lua53/lauxlib.c b/app/lua53/lauxlib.c index adc50028..343cf23d 100644 --- a/app/lua53/lauxlib.c +++ b/app/lua53/lauxlib.c @@ -651,7 +651,7 @@ LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { } -LUALIB_API void (luaL_reref) (lua_State *L, int t, int *ref) { +LUALIB_API void luaL_reref (lua_State *L, int t, int *ref) { /* * If the ref is positive and the entry in table t exists then * overwrite the value otherwise fall through to luaL_ref() @@ -1100,8 +1100,13 @@ static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { free(ptr); return NULL; } - else - return realloc(ptr, nsize); + else { /* cannot fail when shrinking a block */ + void *newptr = realloc(ptr, nsize); + if (newptr == NULL && ptr != NULL && nsize <= osize) + return ptr; /* keep the original block */ + else /* no fail or not shrinking */ + return newptr; /* use the new block */ + } } diff --git a/app/lua53/lcode.c b/app/lua53/lcode.c index 7529f2a8..668547be 100644 --- a/app/lua53/lcode.c +++ b/app/lua53/lcode.c @@ -1059,7 +1059,7 @@ static void codecomp (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) { /* -** Aplly prefix operation 'op' to expression 'e'. +** Apply prefix operation 'op' to expression 'e'. */ void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) { static const expdesc ef = {VKINT, {0}, NO_JUMP, NO_JUMP}; diff --git a/app/lua53/ldebug.c b/app/lua53/ldebug.c index 7f02f78c..37a1d0bc 100644 --- a/app/lua53/ldebug.c +++ b/app/lua53/ldebug.c @@ -37,6 +37,7 @@ /* Active Lua function (given call info) */ #define ci_func(ci) (clLvalue((ci)->func)) + static const char *funcnamefromcode (lua_State *L, CallInfo *ci, const char **name); @@ -132,10 +133,11 @@ static const char *upvalname (Proto *p, int uv) { static const char *findvararg (CallInfo *ci, int n, StkId *pos) { int nparams = getnumparams(clLvalue(ci->func)->p); - if (n >= cast_int(ci->u.l.base - ci->func) - nparams) + int nvararg = cast_int(ci->u.l.base - ci->func) - nparams; + if (n <= -nvararg) return NULL; /* no such vararg */ else { - *pos = ci->func + nparams + n; + *pos = ci->func + nparams - n; return "(*vararg)"; /* generic name for any vararg */ } } @@ -147,7 +149,7 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n, StkId base; if (isLua(ci)) { if (n < 0) /* access to vararg values? */ - return findvararg(ci, -n, pos); + return findvararg(ci, n, pos); else { base = ci->u.l.base; name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci)); @@ -707,7 +709,6 @@ l_noret luaG_runerror (lua_State *L, const char *fmt, ...) { CallInfo *ci = L->ci; const char *msg; va_list argp; - luaC_checkGC(L); /* error message uses memory */ va_start(argp, fmt); msg = luaO_pushvfstring(L, fmt, argp); /* format message */ diff --git a/app/lua53/llex.c b/app/lua53/llex.c index a582b9f5..492310c0 100644 --- a/app/lua53/llex.c +++ b/app/lua53/llex.c @@ -256,12 +256,12 @@ static int read_numeral (LexState *ls, SemInfo *seminfo) { /* -** skip a sequence '[=*[' or ']=*]'; if sequence is well formed, return -** its number of '='s; otherwise, return a negative number (-1 iff there -** are no '='s after initial bracket) +** reads a sequence '[=*[' or ']=*]', leaving the last bracket. +** If sequence is well formed, return its number of '='s + 2; otherwise, +** return 1 if there is no '='s or 0 otherwise (an unfinished '[==...'). */ -static int skip_sep (LexState *ls) { - int count = 0; +static size_t skip_sep (LexState *ls) { + size_t count = 0; int s = ls->current; lua_assert(s == '[' || s == ']'); save_and_next(ls); @@ -269,11 +269,14 @@ static int skip_sep (LexState *ls) { save_and_next(ls); count++; } - return (ls->current == s) ? count : (-count) - 1; + return (ls->current == s) ? count + 2 + : (count == 0) ? 1 + : 0; + } -static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { +static void read_long_string (LexState *ls, SemInfo *seminfo, size_t sep) { int line = ls->linenumber; /* initial line (for error message) */ save_and_next(ls); /* skip 2nd '[' */ if (currIsNewline(ls)) /* string starts with a newline? */ @@ -307,8 +310,8 @@ static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { } } endloop: if (seminfo) - seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep), - luaZ_bufflen(ls->buff) - 2*(2 + sep)); + seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + sep, + luaZ_bufflen(ls->buff) - 2 * sep); } @@ -456,9 +459,9 @@ static int llex (LexState *ls, SemInfo *seminfo) { /* else is a comment */ next(ls); if (ls->current == '[') { /* long comment? */ - int sep = skip_sep(ls); + size_t sep = skip_sep(ls); luaZ_resetbuffer(ls->buff); /* 'skip_sep' may dirty the buffer */ - if (sep >= 0) { + if (sep >= 2) { read_long_string(ls, NULL, sep); /* skip long comment */ luaZ_resetbuffer(ls->buff); /* previous call may dirty the buff. */ break; @@ -470,12 +473,12 @@ static int llex (LexState *ls, SemInfo *seminfo) { break; } case '[': { /* long string or simply '[' */ - int sep = skip_sep(ls); - if (sep >= 0) { + size_t sep = skip_sep(ls); + if (sep >= 2) { read_long_string(ls, seminfo, sep); return TK_STRING; } - else if (sep != -1) /* '[=...' missing second bracket */ + else if (sep == 0) /* '[=...' missing second bracket */ lexerror(ls, "invalid long string delimiter", TK_STRING); return '['; } diff --git a/app/lua53/lobject.c b/app/lua53/lobject.c index 384c765c..c705366e 100644 --- a/app/lua53/lobject.c +++ b/app/lua53/lobject.c @@ -274,7 +274,7 @@ static const char *l_str2dloc (const char *s, lua_Number *result, int mode) { ** - 'n'/'N' means 'inf' or 'nan' (which should be rejected) ** - '.' just optimizes the search for the common case (nothing special) ** This function accepts both the current locale or a dot as the radix -** mark. If the convertion fails, it may mean number has a dot but +** mark. If the conversion fails, it may mean number has a dot but ** locale accepts something else. In that case, the code copies 's' ** to a buffer (because 's' is read-only), changes the dot to the ** current locale radix mark, and tries to convert again. diff --git a/app/lua53/lparser.c b/app/lua53/lparser.c index d65a5869..fff62db2 100644 --- a/app/lua53/lparser.c +++ b/app/lua53/lparser.c @@ -545,6 +545,7 @@ static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { fs->bl = NULL; f = fs->f; f->source = ls->source; + luaC_objbarrier(ls->L, f, f->source); f->maxstacksize = 2; /* registers 0/1 are always valid */ f->lineinfo = 0; fs->sizelineinfo = 0; @@ -1626,6 +1627,7 @@ static void mainfunc (LexState *ls, FuncState *fs) { fs->f->is_vararg = 1; /* main function is always declared vararg */ init_exp(&v, VLOCAL, 0); /* create and... */ newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */ + luaC_objbarrier(ls->L, fs->f, ls->envn); luaX_next(ls); /* read first token */ statlist(ls); /* parse main body */ check(ls, TK_EOS); @@ -1651,6 +1653,7 @@ LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, sethvalue(L, L->top, lexstate.h); /* anchor it */ luaD_inctop(L); funcstate.f = cl->p = luaF_newproto(L); + luaC_objbarrier(L, cl, cl->p); funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ lua_assert(iswhite(funcstate.f)); /* do not need barrier here */ lexstate.buff = buff; diff --git a/app/lua53/lua.h b/app/lua53/lua.h index 58eb5a40..25b6f773 100644 --- a/app/lua53/lua.h +++ b/app/lua53/lua.h @@ -19,11 +19,11 @@ #define LUA_VERSION_MAJOR "5" #define LUA_VERSION_MINOR "3" #define LUA_VERSION_NUM 503 -#define LUA_VERSION_RELEASE "5" +#define LUA_VERSION_RELEASE "6" #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-2018 Lua.org, PUC-Rio" +#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2020 Lua.org, PUC-Rio" #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" @@ -508,7 +508,7 @@ LUALIB_API void (lua_debugbreak)(void); /* }====================================================================== */ /****************************************************************************** -* Copyright (C) 1994-2018 Lua.org, PUC-Rio. +* Copyright (C) 1994-2020 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/app/lua53/lundump.c b/app/lua53/lundump.c index 3ec6bd40..e627d6f5 100644 --- a/app/lua53/lundump.c +++ b/app/lua53/lundump.c @@ -210,19 +210,23 @@ static lua_Integer LoadInteger (LoadState *S, lu_byte tt_data) { return (tt_data & LUAU_TMASK) == LUAU_TNUMNINT ? -x-1 : x; } static TString *LoadString_ (LoadState *S, int prelen) { - TString *ts; - char buff[LUAI_MAXSHORTLEN]; + lua_State *L = S->L; int n = LoadInteger(S, (prelen < 0 ? LoadByte(S) : prelen)) - 1; + TString *ts; if (n < 0) return NULL; if (S->useStrRefs) ts = S->TS[n]; else if (n <= LUAI_MAXSHORTLEN) { /* short string? */ + char buff[LUAI_MAXSHORTLEN]; LoadVector(S, buff, n); - ts = luaS_newlstr(S->L, buff, n); + ts = luaS_newlstr(L, buff, n); } else { /* long string */ - ts = luaS_createlngstrobj(S->L, n); + ts = luaS_createlngstrobj(L, n); + setsvalue2s(L, L->top, ts); /* anchor it ('loadVector' can GC) */ + luaD_inctop(L); LoadVector(S, getstr(ts), n); /* load directly in final place */ + L->top--; /* pop string */ } return ts; } @@ -299,8 +303,11 @@ static void LoadProtos (LoadState *S, Proto *f) { f->p = p; f->sizep = n; memset (p, 0, n * sizeof(*p)); - for (i = 0; i < n; i++) - p[i] = LoadFunction(S, luaF_newproto(S->L), f->source); + for (i = 0; i < n; i++) { + p[i] = luaF_newproto(S->L); + luaC_objbarrier(S->L, f, p[i]); + p[i] = LoadFunction(S, p[i], f->source); + } if (S->mode != MODE_RAM) { f->p = StoreAV(S, cast(void **, p), n); luaM_freearray(S->L, p, n); @@ -438,7 +445,8 @@ LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) { setclLvalue(L, L->top, cl); luaD_inctop(L); cl->p = luaF_newproto(L); - LoadFunction(&S, cl->p, NULL); + luaC_objbarrier(L, cl, cl->p); + cl->p = LoadFunction(&S, cl->p, NULL); lua_assert(cl->nupvalues == cl->p->sizeupvalues); return cl; }