aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2020-12-28 16:34:07 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2020-12-28 16:34:07 -0300
commit6188f3a654c0380db08eb40a5465ce8e71c784f5 (patch)
tree1a94cd5c0d815a2c23e3ebb967b3019c55c7a128
parent7af27ef59da4051914d93d8b63efac663b64765a (diff)
downloadlua-6188f3a654c0380db08eb40a5465ce8e71c784f5.tar.gz
lua-6188f3a654c0380db08eb40a5465ce8e71c784f5.tar.bz2
lua-6188f3a654c0380db08eb40a5465ce8e71c784f5.zip
Reset thread before panicking
Before panicking, it is simpler to reset the thread instead of closing its variables and adjust the top manually.
-rw-r--r--ldo.c6
-rw-r--r--lstate.c22
-rw-r--r--lstate.h1
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) {
119 } 119 }
120 else { /* thread has no error handler */ 120 else { /* thread has no error handler */
121 global_State *g = G(L); 121 global_State *g = G(L);
122 errcode = luaD_closeprotected(L, 0, errcode); /* close all upvalues */ 122 errcode = luaE_resetthread(L, errcode); /* close all upvalues */
123 L->status = cast_byte(errcode); /* mark it as dead */
124 if (g->mainthread->errorJmp) { /* main thread has a handler? */ 123 if (g->mainthread->errorJmp) { /* main thread has a handler? */
125 setobjs2s(L, g->mainthread->top++, L->top - 1); /* copy error obj. */ 124 setobjs2s(L, g->mainthread->top++, L->top - 1); /* copy error obj. */
126 luaD_throw(g->mainthread, errcode); /* re-throw in main thread */ 125 luaD_throw(g->mainthread, errcode); /* re-throw in main thread */
127 } 126 }
128 else { /* no handler at all; abort */ 127 else { /* no handler at all; abort */
129 if (g->panic) { /* panic function? */ 128 if (g->panic) { /* panic function? */
130 luaD_seterrorobj(L, errcode, L->top); /* assume EXTRA_STACK */
131 if (L->ci->top < L->top)
132 L->ci->top = L->top; /* pushing msg. can break this invariant */
133 lua_unlock(L); 129 lua_unlock(L);
134 g->panic(L); /* call panic function (last chance to jump out) */ 130 g->panic(L); /* call panic function (last chance to jump out) */
135 } 131 }
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) {
321} 321}
322 322
323 323
324int lua_resetthread (lua_State *L) { 324int luaE_resetthread (lua_State *L, int status) {
325 CallInfo *ci; 325 CallInfo *ci = L->ci = &L->base_ci; /* unwind CallInfo list */
326 int status = L->status;
327 lua_lock(L);
328 L->ci = ci = &L->base_ci; /* unwind CallInfo list */
329 setnilvalue(s2v(L->stack)); /* 'function' entry for basic 'ci' */ 326 setnilvalue(s2v(L->stack)); /* 'function' entry for basic 'ci' */
330 ci->func = L->stack; 327 ci->func = L->stack;
331 ci->callstatus = CIST_C; 328 ci->callstatus = CIST_C;
@@ -334,12 +331,19 @@ int lua_resetthread (lua_State *L) {
334 status = luaD_closeprotected(L, 0, status); 331 status = luaD_closeprotected(L, 0, status);
335 if (status != LUA_OK) /* errors? */ 332 if (status != LUA_OK) /* errors? */
336 luaD_seterrorobj(L, status, L->stack + 1); 333 luaD_seterrorobj(L, status, L->stack + 1);
337 else { 334 else
338 status = LUA_OK;
339 L->top = L->stack + 1; 335 L->top = L->stack + 1;
340 }
341 ci->top = L->top + LUA_MINSTACK; 336 ci->top = L->top + LUA_MINSTACK;
342 L->status = status; 337 L->status = cast_byte(status);
338 luaD_reallocstack(L, cast_int(ci->top - L->stack), 0);
339 return status;
340}
341
342
343LUA_API int lua_resetthread (lua_State *L) {
344 int status;
345 lua_lock(L);
346 status = luaE_resetthread(L, L->status);
343 lua_unlock(L); 347 lua_unlock(L);
344 return status; 348 return status;
345} 349}
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);
359LUAI_FUNC void luaE_incCstack (lua_State *L); 359LUAI_FUNC void luaE_incCstack (lua_State *L);
360LUAI_FUNC void luaE_warning (lua_State *L, const char *msg, int tocont); 360LUAI_FUNC void luaE_warning (lua_State *L, const char *msg, int tocont);
361LUAI_FUNC void luaE_warnerror (lua_State *L, const char *where); 361LUAI_FUNC void luaE_warnerror (lua_State *L, const char *where);
362LUAI_FUNC int luaE_resetthread (lua_State *L, int status);
362 363
363 364
364#endif 365#endif