aboutsummaryrefslogtreecommitdiff
path: root/lcorolib.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-05-09 11:13:45 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-05-09 11:13:45 -0300
commit389116d8abcc96db3cfe2f3cc25789c089fe12d6 (patch)
treef3d07b50c17f28ba09cf547d5a67519ffe3271a4 /lcorolib.c
parent01bded3d8cd88a2d7f472b45f706565f1a9ef3b1 (diff)
downloadlua-389116d8abcc96db3cfe2f3cc25789c089fe12d6.tar.gz
lua-389116d8abcc96db3cfe2f3cc25789c089fe12d6.tar.bz2
lua-389116d8abcc96db3cfe2f3cc25789c089fe12d6.zip
Coroutines do not unwind the stack in case of errors
Back to how it was, a coroutine does not unwind its stack in case of errors (and therefore do not close its to-be-closed variables). This allows the stack to be examined after the error. The program can use 'coroutine.kill' to close the variables. The function created by 'coroutine.wrap', however, closes the coroutine's variables in case of errors, as it is impossible to examine the stack any way.
Diffstat (limited to 'lcorolib.c')
-rw-r--r--lcorolib.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/lcorolib.c b/lcorolib.c
index f7c9e165..a21880d5 100644
--- a/lcorolib.c
+++ b/lcorolib.c
@@ -25,6 +25,10 @@ static lua_State *getco (lua_State *L) {
25} 25}
26 26
27 27
28/*
29** Resumes a coroutine. Returns the number of results for non-error
30** cases or -1 for errors.
31*/
28static int auxresume (lua_State *L, lua_State *co, int narg) { 32static int auxresume (lua_State *L, lua_State *co, int narg) {
29 int status, nres; 33 int status, nres;
30 if (!lua_checkstack(co, narg)) { 34 if (!lua_checkstack(co, narg)) {
@@ -74,8 +78,14 @@ static int luaB_auxwrap (lua_State *L) {
74 lua_State *co = lua_tothread(L, lua_upvalueindex(1)); 78 lua_State *co = lua_tothread(L, lua_upvalueindex(1));
75 int r = auxresume(L, co, lua_gettop(L)); 79 int r = auxresume(L, co, lua_gettop(L));
76 if (r < 0) { 80 if (r < 0) {
81 int stat = lua_status(co);
82 if (stat != LUA_OK && stat != LUA_YIELD) {
83 stat = lua_resetthread(co); /* close variables in case of errors */
84 if (stat != LUA_OK) /* error closing variables? */
85 lua_xmove(co, L, 1); /* get new error object */
86 }
77 if (lua_type(L, -1) == LUA_TSTRING) { /* error object is a string? */ 87 if (lua_type(L, -1) == LUA_TSTRING) { /* error object is a string? */
78 luaL_where(L, 1); /* add extra info */ 88 luaL_where(L, 1); /* add extra info, if available */
79 lua_insert(L, -2); 89 lua_insert(L, -2);
80 lua_concat(L, 2); 90 lua_concat(L, 2);
81 } 91 }