aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2020-10-07 10:42:00 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2020-10-12 12:29:09 -0300
commit171dcd7d745566e69c61845599705707500a104e (patch)
tree129d0c97107e75e2308ab93d4100cc089ec2a5c4
parent5aa36e894f5a0348dfd19bd9cdcdd27ce8aa5f05 (diff)
downloadlua-171dcd7d745566e69c61845599705707500a104e.tar.gz
lua-171dcd7d745566e69c61845599705707500a104e.tar.bz2
lua-171dcd7d745566e69c61845599705707500a104e.zip
'recover' finish of 'luaD_pcall' should follow the original
-rw-r--r--ldo.c6
-rw-r--r--testes/coroutine.lua26
2 files changed, 25 insertions, 7 deletions
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) {
641 if (ci == NULL) return 0; /* no recovery point */ 641 if (ci == NULL) return 0; /* no recovery point */
642 /* "finish" luaD_pcall */ 642 /* "finish" luaD_pcall */
643 oldtop = restorestack(L, ci->u2.funcidx); 643 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);
647 L->ci = ci; 644 L->ci = ci;
648 L->allowhook = getoah(ci->callstatus); /* restore original 'allowhook' */ 645 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);
649 luaD_shrinkstack(L); /* restore stack size in case of overflow */ 649 luaD_shrinkstack(L); /* restore stack size in case of overflow */
650 L->errfunc = ci->u.c.old_errfunc; 650 L->errfunc = ci->u.c.old_errfunc;
651 return 1; /* continue running the coroutine */ 651 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
124 124
125 125
126-- coroutine closing 126-- coroutine closing
127
128local function func2close (f)
129 return setmetatable({}, {__close = f})
130end
131
127do 132do
128 -- ok to close a dead coroutine 133 -- ok to close a dead coroutine
129 local co = coroutine.create(print) 134 local co = coroutine.create(print)
@@ -146,10 +151,6 @@ do
146 -- to-be-closed variables in coroutines 151 -- to-be-closed variables in coroutines
147 local X 152 local X
148 153
149 local function func2close (f)
150 return setmetatable({}, {__close = f})
151 end
152
153 co = coroutine.create(function () 154 co = coroutine.create(function ()
154 local x <close> = func2close(function (self, err) 155 local x <close> = func2close(function (self, err)
155 assert(err == nil); X = false 156 assert(err == nil); X = false
@@ -192,6 +193,23 @@ do
192 193
193end 194end
194 195
196do
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")
211end
212
195 213
196-- yielding across C boundaries 214-- yielding across C boundaries
197 215