'recover' finish of 'luaD_pcall' should follow the original
diff --git a/ldo.c b/ldo.c
index 3202490..5729b19 100644
--- a/ldo.c
+++ b/ldo.c
@@ -641,11 +641,11 @@
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 955f677..5b92715 100644
--- a/testes/coroutine.lua
+++ b/testes/coroutine.lua
@@ -124,6 +124,11 @@
-- 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 @@
-- 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 @@
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