diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-12-13 13:07:53 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-12-13 13:07:53 -0200 |
| commit | fdc25a1ebfe9968dcec390dd556375105aa0be40 (patch) | |
| tree | 43759131636a501ec92475d453fd1a1c73bc8090 /lfunc.c | |
| parent | 3b06f983ae0e57b90cdeb500c84bb524e5c3635b (diff) | |
| download | lua-fdc25a1ebfe9968dcec390dd556375105aa0be40.tar.gz lua-fdc25a1ebfe9968dcec390dd556375105aa0be40.tar.bz2 lua-fdc25a1ebfe9968dcec390dd556375105aa0be40.zip | |
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...)
Diffstat (limited to 'lfunc.c')
| -rw-r--r-- | lfunc.c | 18 |
1 files changed, 10 insertions, 8 deletions
| @@ -127,17 +127,18 @@ static int prepclosingmethod (lua_State *L, TValue *obj, TValue *err) { | |||
| 127 | 127 | ||
| 128 | 128 | ||
| 129 | /* | 129 | /* |
| 130 | ** Prepare and call a closing method. If status is OK, code is | 130 | ** Prepare and call a closing method. If status is OK, code is still |
| 131 | ** still inside the original protected call, and so any error | 131 | ** inside the original protected call, and so any error will be handled |
| 132 | ** will be handled there. Otherwise, a previous error already | 132 | ** there. Otherwise, a previous error already activated original |
| 133 | ** activated original protected call, and so the call to the | 133 | ** protected call, and so the call to the closing method must be |
| 134 | ** closing method must be protected here. | 134 | ** protected here. (A status = CLOSEPROTECT behaves like a previous |
| 135 | ** error, to also run the closing method in protected mode). | ||
| 135 | ** If status is OK, the call to the closing method will be pushed | 136 | ** If status is OK, the call to the closing method will be pushed |
| 136 | ** at the top of the stack. Otherwise, values are pushed after | 137 | ** at the top of the stack. Otherwise, values are pushed after |
| 137 | ** the 'level' of the upvalue being closed, as everything after | 138 | ** the 'level' of the upvalue being closed, as everything after |
| 138 | ** that won't be used again. | 139 | ** that won't be used again. |
| 139 | */ | 140 | */ |
| 140 | static int closeupval (lua_State *L, TValue *uv, StkId level, int status) { | 141 | static int callclosemth (lua_State *L, TValue *uv, StkId level, int status) { |
| 141 | if (likely(status == LUA_OK)) { | 142 | if (likely(status == LUA_OK)) { |
| 142 | if (prepclosingmethod(L, uv, &G(L)->nilvalue)) /* something to call? */ | 143 | if (prepclosingmethod(L, uv, &G(L)->nilvalue)) /* something to call? */ |
| 143 | callclose(L, NULL); /* call closing method */ | 144 | callclose(L, NULL); /* call closing method */ |
| @@ -207,9 +208,10 @@ int luaF_close (lua_State *L, StkId level, int status) { | |||
| 207 | if (!iswhite(uv)) | 208 | if (!iswhite(uv)) |
| 208 | gray2black(uv); /* closed upvalues cannot be gray */ | 209 | gray2black(uv); /* closed upvalues cannot be gray */ |
| 209 | luaC_barrier(L, uv, slot); | 210 | luaC_barrier(L, uv, slot); |
| 210 | if (status >= 0 && uv->tt == LUA_TUPVALTBC) { /* must be closed? */ | 211 | if (uv->tt == LUA_TUPVALTBC && status != NOCLOSINGMETH) { |
| 212 | /* must run closing method */ | ||
| 211 | ptrdiff_t levelrel = savestack(L, level); | 213 | ptrdiff_t levelrel = savestack(L, level); |
| 212 | status = closeupval(L, uv->v, upl, status); /* may realloc. the stack */ | 214 | status = callclosemth(L, uv->v, upl, status); /* may change the stack */ |
| 213 | level = restorestack(L, levelrel); | 215 | level = restorestack(L, levelrel); |
| 214 | } | 216 | } |
| 215 | } | 217 | } |
