From 6188f3a654c0380db08eb40a5465ce8e71c784f5 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Mon, 28 Dec 2020 16:34:07 -0300 Subject: Reset thread before panicking Before panicking, it is simpler to reset the thread instead of closing its variables and adjust the top manually. --- ldo.c | 6 +----- lstate.c | 22 +++++++++++++--------- lstate.h | 1 + 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/ldo.c b/ldo.c index 59391f7b..d39edab0 100644 --- a/ldo.c +++ b/ldo.c @@ -119,17 +119,13 @@ l_noret luaD_throw (lua_State *L, int errcode) { } else { /* thread has no error handler */ global_State *g = G(L); - errcode = luaD_closeprotected(L, 0, errcode); /* close all upvalues */ - L->status = cast_byte(errcode); /* mark it as dead */ + errcode = luaE_resetthread(L, errcode); /* close all upvalues */ if (g->mainthread->errorJmp) { /* main thread has a handler? */ setobjs2s(L, g->mainthread->top++, L->top - 1); /* copy error obj. */ luaD_throw(g->mainthread, errcode); /* re-throw in main thread */ } else { /* no handler at all; abort */ if (g->panic) { /* panic function? */ - luaD_seterrorobj(L, errcode, L->top); /* assume EXTRA_STACK */ - if (L->ci->top < L->top) - L->ci->top = L->top; /* pushing msg. can break this invariant */ lua_unlock(L); g->panic(L); /* call panic function (last chance to jump out) */ } diff --git a/lstate.c b/lstate.c index e01a7e7b..a6ef82a3 100644 --- a/lstate.c +++ b/lstate.c @@ -321,11 +321,8 @@ void luaE_freethread (lua_State *L, lua_State *L1) { } -int lua_resetthread (lua_State *L) { - CallInfo *ci; - int status = L->status; - lua_lock(L); - L->ci = ci = &L->base_ci; /* unwind CallInfo list */ +int luaE_resetthread (lua_State *L, int status) { + CallInfo *ci = L->ci = &L->base_ci; /* unwind CallInfo list */ setnilvalue(s2v(L->stack)); /* 'function' entry for basic 'ci' */ ci->func = L->stack; ci->callstatus = CIST_C; @@ -334,12 +331,19 @@ int lua_resetthread (lua_State *L) { status = luaD_closeprotected(L, 0, status); if (status != LUA_OK) /* errors? */ luaD_seterrorobj(L, status, L->stack + 1); - else { - status = LUA_OK; + else L->top = L->stack + 1; - } ci->top = L->top + LUA_MINSTACK; - L->status = status; + L->status = cast_byte(status); + luaD_reallocstack(L, cast_int(ci->top - L->stack), 0); + return status; +} + + +LUA_API int lua_resetthread (lua_State *L) { + int status; + lua_lock(L); + status = luaE_resetthread(L, L->status); lua_unlock(L); return status; } diff --git a/lstate.h b/lstate.h index cbcf07e2..38a6c9b6 100644 --- a/lstate.h +++ b/lstate.h @@ -359,6 +359,7 @@ LUAI_FUNC void luaE_checkcstack (lua_State *L); LUAI_FUNC void luaE_incCstack (lua_State *L); LUAI_FUNC void luaE_warning (lua_State *L, const char *msg, int tocont); LUAI_FUNC void luaE_warnerror (lua_State *L, const char *where); +LUAI_FUNC int luaE_resetthread (lua_State *L, int status); #endif -- cgit v1.2.3-55-g6feb