diff --git a/ldo.c b/ldo.c index 3202490e..5729b190 100644 --- a/ldo.c +++ b/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 */ diff --git a/testes/coroutine.lua b/testes/coroutine.lua index 955f6776..5b927151 100644 --- a/testes/coroutine.lua +++ b/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 = func2close(function (self, err) assert(err == nil); X = false @@ -192,6 +193,23 @@ do end +do + -- versus pcall in coroutines + local X = false + local Y = false + function foo () + local x = 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