aboutsummaryrefslogtreecommitdiff
path: root/lfunc.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-06-05 13:16:25 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-06-05 13:16:25 -0300
commitb4d5dff8ec4f1c8a44db66d368e95d359b04aea7 (patch)
treee87fbd3bcbf8a271429ee31f32eaf928058ab376 /lfunc.c
parent14edd364c3abcb758e74c68a2bdd4ddaeefdae2a (diff)
downloadlua-b4d5dff8ec4f1c8a44db66d368e95d359b04aea7.tar.gz
lua-b4d5dff8ec4f1c8a44db66d368e95d359b04aea7.tar.bz2
lua-b4d5dff8ec4f1c8a44db66d368e95d359b04aea7.zip
Multiple errors in '__toclose' report the first one
When there are multiple errors when closing objects, the error reported by the protected call is the first one, for two reasons: First, other errors may be caused by this one; second, the first error is handled in the original execution context, and therefore has the full traceback.
Diffstat (limited to 'lfunc.c')
-rw-r--r--lfunc.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/lfunc.c b/lfunc.c
index 3e044b65..55114992 100644
--- a/lfunc.c
+++ b/lfunc.c
@@ -144,13 +144,16 @@ static int callclosemth (lua_State *L, TValue *uv, StkId level, int status) {
144 luaG_runerror(L, "attempt to close non-closable variable '%s'", vname); 144 luaG_runerror(L, "attempt to close non-closable variable '%s'", vname);
145 } 145 }
146 } 146 }
147 else { /* there was an error */ 147 else { /* must close the object in protected mode */
148 ptrdiff_t oldtop = savestack(L, level + 1);
148 /* save error message and set stack top to 'level + 1' */ 149 /* save error message and set stack top to 'level + 1' */
149 luaD_seterrorobj(L, status, level); 150 luaD_seterrorobj(L, status, level);
150 if (prepclosingmethod(L, uv, s2v(level))) { /* something to call? */ 151 if (prepclosingmethod(L, uv, s2v(level))) { /* something to call? */
151 int newstatus = luaD_pcall(L, callclose, NULL, savestack(L, level), 0); 152 int newstatus = luaD_pcall(L, callclose, NULL, oldtop, 0);
152 if (newstatus != LUA_OK) /* another error when closing? */ 153 if (newstatus != LUA_OK && status == CLOSEPROTECT) /* first error? */
153 status = newstatus; /* this will be the new error */ 154 status = newstatus; /* this will be the new error */
155 else /* leave original error (or nil) on top */
156 L->top = restorestack(L, oldtop);
154 } 157 }
155 /* else no metamethod; ignore this case and keep original error */ 158 /* else no metamethod; ignore this case and keep original error */
156 } 159 }