Reset thread before panicking

Before panicking, it is simpler to reset the thread instead of closing
its variables and adjust the top manually.
This commit is contained in:
Roberto Ierusalimschy 2020-12-28 16:34:07 -03:00
parent 7af27ef59d
commit 6188f3a654
3 changed files with 15 additions and 14 deletions

6
ldo.c
View File

@ -119,17 +119,13 @@ l_noret luaD_throw (lua_State *L, int errcode) {
} }
else { /* thread has no error handler */ else { /* thread has no error handler */
global_State *g = G(L); global_State *g = G(L);
errcode = luaD_closeprotected(L, 0, errcode); /* close all upvalues */ errcode = luaE_resetthread(L, errcode); /* close all upvalues */
L->status = cast_byte(errcode); /* mark it as dead */
if (g->mainthread->errorJmp) { /* main thread has a handler? */ if (g->mainthread->errorJmp) { /* main thread has a handler? */
setobjs2s(L, g->mainthread->top++, L->top - 1); /* copy error obj. */ setobjs2s(L, g->mainthread->top++, L->top - 1); /* copy error obj. */
luaD_throw(g->mainthread, errcode); /* re-throw in main thread */ luaD_throw(g->mainthread, errcode); /* re-throw in main thread */
} }
else { /* no handler at all; abort */ else { /* no handler at all; abort */
if (g->panic) { /* panic function? */ 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); lua_unlock(L);
g->panic(L); /* call panic function (last chance to jump out) */ g->panic(L); /* call panic function (last chance to jump out) */
} }

View File

@ -321,11 +321,8 @@ void luaE_freethread (lua_State *L, lua_State *L1) {
} }
int lua_resetthread (lua_State *L) { int luaE_resetthread (lua_State *L, int status) {
CallInfo *ci; CallInfo *ci = L->ci = &L->base_ci; /* unwind CallInfo list */
int status = L->status;
lua_lock(L);
L->ci = ci = &L->base_ci; /* unwind CallInfo list */
setnilvalue(s2v(L->stack)); /* 'function' entry for basic 'ci' */ setnilvalue(s2v(L->stack)); /* 'function' entry for basic 'ci' */
ci->func = L->stack; ci->func = L->stack;
ci->callstatus = CIST_C; ci->callstatus = CIST_C;
@ -334,12 +331,19 @@ int lua_resetthread (lua_State *L) {
status = luaD_closeprotected(L, 0, status); status = luaD_closeprotected(L, 0, status);
if (status != LUA_OK) /* errors? */ if (status != LUA_OK) /* errors? */
luaD_seterrorobj(L, status, L->stack + 1); luaD_seterrorobj(L, status, L->stack + 1);
else { else
status = LUA_OK;
L->top = L->stack + 1; L->top = L->stack + 1;
}
ci->top = L->top + LUA_MINSTACK; 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); lua_unlock(L);
return status; return status;
} }

View File

@ -359,6 +359,7 @@ LUAI_FUNC void luaE_checkcstack (lua_State *L);
LUAI_FUNC void luaE_incCstack (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_warning (lua_State *L, const char *msg, int tocont);
LUAI_FUNC void luaE_warnerror (lua_State *L, const char *where); LUAI_FUNC void luaE_warnerror (lua_State *L, const char *where);
LUAI_FUNC int luaE_resetthread (lua_State *L, int status);
#endif #endif