mirror of
https://github.com/lua/lua.git
synced 2025-02-04 06:13:04 +08:00
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.
This commit is contained in:
parent
2d8d5c74b5
commit
664bda02ba
1
ldo.c
1
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 */
|
||||
|
10
ltests.c
10
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) {
|
||||
|
@ -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[[
|
||||
|
Loading…
x
Reference in New Issue
Block a user