diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-12-28 16:34:07 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-12-28 16:34:07 -0300 |
| commit | 6188f3a654c0380db08eb40a5465ce8e71c784f5 (patch) | |
| tree | 1a94cd5c0d815a2c23e3ebb967b3019c55c7a128 | |
| parent | 7af27ef59da4051914d93d8b63efac663b64765a (diff) | |
| download | lua-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.c | 6 | ||||
| -rw-r--r-- | lstate.c | 22 | ||||
| -rw-r--r-- | lstate.h | 1 |
3 files changed, 15 insertions, 14 deletions
| @@ -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 | } |
| @@ -321,11 +321,8 @@ void luaE_freethread (lua_State *L, lua_State *L1) { | |||
| 321 | } | 321 | } |
| 322 | 322 | ||
| 323 | 323 | ||
| 324 | int lua_resetthread (lua_State *L) { | 324 | int 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 | |||
| 343 | LUA_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 | } |
| @@ -359,6 +359,7 @@ LUAI_FUNC void luaE_checkcstack (lua_State *L); | |||
| 359 | LUAI_FUNC void luaE_incCstack (lua_State *L); | 359 | LUAI_FUNC void luaE_incCstack (lua_State *L); |
| 360 | LUAI_FUNC void luaE_warning (lua_State *L, const char *msg, int tocont); | 360 | LUAI_FUNC void luaE_warning (lua_State *L, const char *msg, int tocont); |
| 361 | LUAI_FUNC void luaE_warnerror (lua_State *L, const char *where); | 361 | LUAI_FUNC void luaE_warnerror (lua_State *L, const char *where); |
| 362 | LUAI_FUNC int luaE_resetthread (lua_State *L, int status); | ||
| 362 | 363 | ||
| 363 | 364 | ||
| 364 | #endif | 365 | #endif |
