Переглянути джерело

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.
Roberto Ierusalimschy 6 місяців тому
батько
коміт
664bda02ba
3 змінених файлів з 28 додано та 2 видалено
  1. 1 0
      ldo.c
  2. 8 2
      ltests.c
  3. 19 0
      testes/api.lua

+ 1 - 0
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 */

+ 8 - 2
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) {

+ 19 - 0
testes/api.lua

@@ -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[[