aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lstate.c3
-rw-r--r--testes/coroutine.lua19
2 files changed, 22 insertions, 0 deletions
diff --git a/lstate.c b/lstate.c
index 89c8b6ad..f3f2ccfd 100644
--- a/lstate.c
+++ b/lstate.c
@@ -272,7 +272,9 @@ static void close_state (lua_State *L) {
272 luaC_freeallobjects(L); /* just collect its objects */ 272 luaC_freeallobjects(L); /* just collect its objects */
273 else { /* closing a fully built state */ 273 else { /* closing a fully built state */
274 L->ci = &L->base_ci; /* unwind CallInfo list */ 274 L->ci = &L->base_ci; /* unwind CallInfo list */
275 L->errfunc = 0; /* stack unwind can "throw away" the error function */
275 luaD_closeprotected(L, 1, LUA_OK); /* close all upvalues */ 276 luaD_closeprotected(L, 1, LUA_OK); /* close all upvalues */
277 L->top.p = L->stack.p + 1; /* empty the stack to run finalizers */
276 luaC_freeallobjects(L); /* collect all objects */ 278 luaC_freeallobjects(L); /* collect all objects */
277 luai_userstateclose(L); 279 luai_userstateclose(L);
278 } 280 }
@@ -328,6 +330,7 @@ int luaE_resetthread (lua_State *L, int status) {
328 if (status == LUA_YIELD) 330 if (status == LUA_YIELD)
329 status = LUA_OK; 331 status = LUA_OK;
330 L->status = LUA_OK; /* so it can run __close metamethods */ 332 L->status = LUA_OK; /* so it can run __close metamethods */
333 L->errfunc = 0; /* stack unwind can "throw away" the error function */
331 status = luaD_closeprotected(L, 1, status); 334 status = luaD_closeprotected(L, 1, status);
332 if (status != LUA_OK) /* errors? */ 335 if (status != LUA_OK) /* errors? */
333 luaD_seterrorobj(L, status, L->stack.p + 1); 336 luaD_seterrorobj(L, status, L->stack.p + 1);
diff --git a/testes/coroutine.lua b/testes/coroutine.lua
index e566c86e..03e04451 100644
--- a/testes/coroutine.lua
+++ b/testes/coroutine.lua
@@ -493,6 +493,25 @@ assert(not pcall(a, a))
493a = nil 493a = nil
494 494
495 495
496do
497 -- bug in 5.4: thread can use message handler higher in the stack
498 -- than the variable being closed
499 local c = coroutine.create(function()
500 local clo <close> = setmetatable({}, {__close=function()
501 local x = 134 -- will overwrite message handler
502 error(x)
503 end})
504 -- yields coroutine but leaves a new message handler for it,
505 -- that would be used when closing the coroutine (except that it
506 -- will be overwritten)
507 xpcall(coroutine.yield, function() return "XXX" end)
508 end)
509
510 assert(coroutine.resume(c)) -- start coroutine
511 local st, msg = coroutine.close(c)
512 assert(not st and msg == 134)
513end
514
496-- access to locals of erroneous coroutines 515-- access to locals of erroneous coroutines
497local x = coroutine.create (function () 516local x = coroutine.create (function ()
498 local a = 10 517 local a = 10