Quellcode durchsuchen

'recover' finish of 'luaD_pcall' should follow the original

Roberto Ierusalimschy vor 4 Jahren
Ursprung
Commit
171dcd7d74
2 geänderte Dateien mit 25 neuen und 7 gelöschten Zeilen
  1. 3 3
      ldo.c
  2. 22 4
      testes/coroutine.lua

+ 3 - 3
ldo.c

@@ -641,11 +641,11 @@ static int recover (lua_State *L, int status) {
   if (ci == NULL) return 0;  /* no recovery point */
   /* "finish" luaD_pcall */
   oldtop = restorestack(L, ci->u2.funcidx);
-  luaF_close(L, oldtop, status);  /* may change the stack */
-  oldtop = restorestack(L, ci->u2.funcidx);
-  luaD_seterrorobj(L, status, oldtop);
   L->ci = ci;
   L->allowhook = getoah(ci->callstatus);  /* restore original 'allowhook' */
+  status = luaF_close(L, oldtop, status);  /* may change the stack */
+  oldtop = restorestack(L, ci->u2.funcidx);
+  luaD_seterrorobj(L, status, oldtop);
   luaD_shrinkstack(L);   /* restore stack size in case of overflow */
   L->errfunc = ci->u.c.old_errfunc;
   return 1;  /* continue running the coroutine */

+ 22 - 4
testes/coroutine.lua

@@ -124,6 +124,11 @@ x, a = nil
 
 
 -- coroutine closing
+
+local function func2close (f)
+  return setmetatable({}, {__close = f})
+end
+
 do
   -- ok to close a dead coroutine
   local co = coroutine.create(print)
@@ -146,10 +151,6 @@ do
   -- to-be-closed variables in coroutines
   local X
 
-  local function func2close (f)
-    return setmetatable({}, {__close = f})
-  end
-
   co = coroutine.create(function ()
     local x <close> = func2close(function (self, err)
       assert(err == nil); X = false
@@ -192,6 +193,23 @@ do
 
 end
 
+do
+  -- <close> versus pcall in coroutines
+  local X = false
+  local Y = false
+  function foo ()
+    local x <close> = func2close(function (self, err)
+      Y = debug.getinfo(2)
+      X = err
+    end)
+    error(43)
+  end
+  co = coroutine.create(function () return pcall(foo) end)
+  local st1, st2, err = coroutine.resume(co)
+  assert(st1 and not st2 and err == 43)
+  assert(X == 43 and Y.name == "pcall")
+end
+
 
 -- yielding across C boundaries