Skip to content

Commit 171dcd7

Browse files
committed
'recover' finish of 'luaD_pcall' should follow the original
1 parent 5aa36e8 commit 171dcd7

2 files changed

Lines changed: 25 additions & 7 deletions

File tree

ldo.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -641,11 +641,11 @@ static int recover (lua_State *L, int status) {
641641
if (ci == NULL) return 0; /* no recovery point */
642642
/* "finish" luaD_pcall */
643643
oldtop = restorestack(L, ci->u2.funcidx);
644-
luaF_close(L, oldtop, status); /* may change the stack */
645-
oldtop = restorestack(L, ci->u2.funcidx);
646-
luaD_seterrorobj(L, status, oldtop);
647644
L->ci = ci;
648645
L->allowhook = getoah(ci->callstatus); /* restore original 'allowhook' */
646+
status = luaF_close(L, oldtop, status); /* may change the stack */
647+
oldtop = restorestack(L, ci->u2.funcidx);
648+
luaD_seterrorobj(L, status, oldtop);
649649
luaD_shrinkstack(L); /* restore stack size in case of overflow */
650650
L->errfunc = ci->u.c.old_errfunc;
651651
return 1; /* continue running the coroutine */

testes/coroutine.lua

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,11 @@ x, a = nil
124124

125125

126126
-- coroutine closing
127+
128+
local function func2close (f)
129+
return setmetatable({}, {__close = f})
130+
end
131+
127132
do
128133
-- ok to close a dead coroutine
129134
local co = coroutine.create(print)
@@ -146,10 +151,6 @@ do
146151
-- to-be-closed variables in coroutines
147152
local X
148153

149-
local function func2close (f)
150-
return setmetatable({}, {__close = f})
151-
end
152-
153154
co = coroutine.create(function ()
154155
local x <close> = func2close(function (self, err)
155156
assert(err == nil); X = false
@@ -192,6 +193,23 @@ do
192193

193194
end
194195

196+
do
197+
-- <close> versus pcall in coroutines
198+
local X = false
199+
local Y = false
200+
function foo ()
201+
local x <close> = func2close(function (self, err)
202+
Y = debug.getinfo(2)
203+
X = err
204+
end)
205+
error(43)
206+
end
207+
co = coroutine.create(function () return pcall(foo) end)
208+
local st1, st2, err = coroutine.resume(co)
209+
assert(st1 and not st2 and err == 43)
210+
assert(X == 43 and Y.name == "pcall")
211+
end
212+
195213

196214
-- yielding across C boundaries
197215

0 commit comments

Comments
 (0)