diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-10-07 10:42:00 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-10-12 12:29:09 -0300 |
commit | 171dcd7d745566e69c61845599705707500a104e (patch) | |
tree | 129d0c97107e75e2308ab93d4100cc089ec2a5c4 | |
parent | 5aa36e894f5a0348dfd19bd9cdcdd27ce8aa5f05 (diff) | |
download | lua-171dcd7d745566e69c61845599705707500a104e.tar.gz lua-171dcd7d745566e69c61845599705707500a104e.tar.bz2 lua-171dcd7d745566e69c61845599705707500a104e.zip |
'recover' finish of 'luaD_pcall' should follow the original
-rw-r--r-- | ldo.c | 6 | ||||
-rw-r--r-- | testes/coroutine.lua | 26 |
2 files changed, 25 insertions, 7 deletions
@@ -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 | |||
128 | local function func2close (f) | ||
129 | return setmetatable({}, {__close = f}) | ||
130 | end | ||
131 | |||
127 | do | 132 | do |
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 | ||
193 | end | 194 | end |
194 | 195 | ||
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 | |||
195 | 213 | ||
196 | -- yielding across C boundaries | 214 | -- yielding across C boundaries |
197 | 215 | ||