lua

A copy of the Lua development repository
Log | Files | Refs | README

commit 664bda02ba4bd167728a2acbe658cc4a9dd9b0b5
parent 2d8d5c74b5ef3d333314feede0165df7c3d13811
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date:   Thu, 16 Jan 2025 16:07:12 -0300

fixing 'lua_status' in panic.

'luaD_throw' may call 'luaE_resetthread', which returns an error code
but clears 'L->status'; so, 'luaD_throw' should set that status again.

Diffstat:
Mldo.c | 1+
Mltests.c | 10++++++++--
Mtestes/api.lua | 19+++++++++++++++++++
3 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/ldo.c b/ldo.c @@ -133,6 +133,7 @@ l_noret luaD_throw (lua_State *L, int errcode) { else { /* thread has no error handler */ global_State *g = G(L); errcode = luaE_resetthread(L, errcode); /* close all upvalues */ + L->status = cast_byte(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 */ diff --git a/ltests.c b/ltests.c @@ -1367,7 +1367,7 @@ static int checkpanic (lua_State *L) { b.L = L; L1 = lua_newstate(f, ud, 0); /* create new state */ if (L1 == NULL) { /* error? */ - lua_pushnil(L); + lua_pushstring(L, MEMERRMSG); return 1; } lua_atpanic(L1, panicback); /* set its panic function */ @@ -1507,7 +1507,7 @@ static int getindex_aux (lua_State *L, lua_State *L1, const char **pc) { static const char *const statcodes[] = {"OK", "YIELD", "ERRRUN", - "ERRSYNTAX", MEMERRMSG, "ERRGCMM", "ERRERR"}; + "ERRSYNTAX", MEMERRMSG, "ERRERR"}; /* ** Avoid these stat codes from being collected, to avoid possible @@ -1806,6 +1806,12 @@ static int runC (lua_State *L, lua_State *L1, const char *pc) { int level = getnum; luaL_traceback(L1, L1, msg, level); } + else if EQ("threadstatus") { + lua_pushstring(L1, statcodes[lua_status(L1)]); + } + else if EQ("alloccount") { + l_memcontrol.countlimit = cast_uint(getnum); + } else if EQ("return") { int n = getnum; if (L1 != L) { diff --git a/testes/api.lua b/testes/api.lua @@ -416,6 +416,10 @@ do -- trivial error assert(T.checkpanic("pushstring hi; error") == "hi") + -- thread status inside panic (bug in 5.4.4) + assert(T.checkpanic("pushstring hi; error", "threadstatus; return 2") == + "ERRRUN") + -- using the stack inside panic assert(T.checkpanic("pushstring hi; error;", [[checkstack 5 XX @@ -433,6 +437,21 @@ do assert(T.checkpanic("newuserdata 20000") == MEMERRMSG) T.totalmem(0) -- restore high limit + -- memory error + thread status + local x = T.checkpanic( + [[ alloccount 0 # force a memory error in next line + newtable + ]], + [[ + alloccount -1 # allow free allocations again + pushstring XX + threadstatus + concat 2 # to make sure message came from here + return 1 + ]]) + T.alloccount() + assert(x == "XX" .. "not enough memory") + -- stack error if not _soft then local msg = T.checkpanic[[