mirror of
https://github.com/lua/lua.git
synced 2025-01-14 05:43:00 +08:00
'recover' finish of 'luaD_pcall' should follow the original
This commit is contained in:
parent
5aa36e894f
commit
171dcd7d74
6
ldo.c
6
ldo.c
@ -641,11 +641,11 @@ static int recover (lua_State *L, int status) {
|
|||||||
if (ci == NULL) return 0; /* no recovery point */
|
if (ci == NULL) return 0; /* no recovery point */
|
||||||
/* "finish" luaD_pcall */
|
/* "finish" luaD_pcall */
|
||||||
oldtop = restorestack(L, ci->u2.funcidx);
|
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->ci = ci;
|
||||||
L->allowhook = getoah(ci->callstatus); /* restore original 'allowhook' */
|
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 */
|
luaD_shrinkstack(L); /* restore stack size in case of overflow */
|
||||||
L->errfunc = ci->u.c.old_errfunc;
|
L->errfunc = ci->u.c.old_errfunc;
|
||||||
return 1; /* continue running the coroutine */
|
return 1; /* continue running the coroutine */
|
||||||
|
@ -124,6 +124,11 @@ x, a = nil
|
|||||||
|
|
||||||
|
|
||||||
-- coroutine closing
|
-- coroutine closing
|
||||||
|
|
||||||
|
local function func2close (f)
|
||||||
|
return setmetatable({}, {__close = f})
|
||||||
|
end
|
||||||
|
|
||||||
do
|
do
|
||||||
-- ok to close a dead coroutine
|
-- ok to close a dead coroutine
|
||||||
local co = coroutine.create(print)
|
local co = coroutine.create(print)
|
||||||
@ -146,10 +151,6 @@ do
|
|||||||
-- to-be-closed variables in coroutines
|
-- to-be-closed variables in coroutines
|
||||||
local X
|
local X
|
||||||
|
|
||||||
local function func2close (f)
|
|
||||||
return setmetatable({}, {__close = f})
|
|
||||||
end
|
|
||||||
|
|
||||||
co = coroutine.create(function ()
|
co = coroutine.create(function ()
|
||||||
local x <close> = func2close(function (self, err)
|
local x <close> = func2close(function (self, err)
|
||||||
assert(err == nil); X = false
|
assert(err == nil); X = false
|
||||||
@ -192,6 +193,23 @@ do
|
|||||||
|
|
||||||
end
|
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
|
-- yielding across C boundaries
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user