From fdc25a1ebfe9968dcec390dd556375105aa0be40 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Thu, 13 Dec 2018 13:07:53 -0200 Subject: New functions 'lua_resetthread' and 'coroutine.kill' New functions to reset/kill a thread/coroutine, mainly (only?) to close any pending to-be-closed variable. ('lua_resetthread' also allows a thread to be reused...) --- lfunc.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'lfunc.c') diff --git a/lfunc.c b/lfunc.c index 11d2850f..bdf3cd25 100644 --- a/lfunc.c +++ b/lfunc.c @@ -127,17 +127,18 @@ static int prepclosingmethod (lua_State *L, TValue *obj, TValue *err) { /* -** Prepare and call a closing method. If status is OK, code is -** still inside the original protected call, and so any error -** will be handled there. Otherwise, a previous error already -** activated original protected call, and so the call to the -** closing method must be protected here. +** Prepare and call a closing method. If status is OK, code is still +** inside the original protected call, and so any error will be handled +** there. Otherwise, a previous error already activated original +** protected call, and so the call to the closing method must be +** protected here. (A status = CLOSEPROTECT behaves like a previous +** error, to also run the closing method in protected mode). ** If status is OK, the call to the closing method will be pushed ** at the top of the stack. Otherwise, values are pushed after ** the 'level' of the upvalue being closed, as everything after ** that won't be used again. */ -static int closeupval (lua_State *L, TValue *uv, StkId level, int status) { +static int callclosemth (lua_State *L, TValue *uv, StkId level, int status) { if (likely(status == LUA_OK)) { if (prepclosingmethod(L, uv, &G(L)->nilvalue)) /* something to call? */ callclose(L, NULL); /* call closing method */ @@ -207,9 +208,10 @@ int luaF_close (lua_State *L, StkId level, int status) { if (!iswhite(uv)) gray2black(uv); /* closed upvalues cannot be gray */ luaC_barrier(L, uv, slot); - if (status >= 0 && uv->tt == LUA_TUPVALTBC) { /* must be closed? */ + if (uv->tt == LUA_TUPVALTBC && status != NOCLOSINGMETH) { + /* must run closing method */ ptrdiff_t levelrel = savestack(L, level); - status = closeupval(L, uv->v, upl, status); /* may realloc. the stack */ + status = callclosemth(L, uv->v, upl, status); /* may change the stack */ level = restorestack(L, levelrel); } } -- cgit v1.2.3-55-g6feb