aboutsummaryrefslogtreecommitdiff
path: root/lfunc.c
diff options
context:
space:
mode:
Diffstat (limited to 'lfunc.c')
-rw-r--r--lfunc.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/lfunc.c b/lfunc.c
index 68d0632a..cd85cc1f 100644
--- a/lfunc.c
+++ b/lfunc.c
@@ -133,7 +133,8 @@ static int prepclosingmethod (lua_State *L, TValue *obj, TValue *err) {
133** the 'level' of the upvalue being closed, as everything after 133** the 'level' of the upvalue being closed, as everything after
134** that won't be used again. 134** that won't be used again.
135*/ 135*/
136static int callclosemth (lua_State *L, TValue *uv, StkId level, int status) { 136static int callclosemth (lua_State *L, StkId level, int status) {
137 TValue *uv = s2v(level); /* value being closed */
137 if (likely(status == LUA_OK)) { 138 if (likely(status == LUA_OK)) {
138 if (prepclosingmethod(L, uv, &G(L)->nilvalue)) /* something to call? */ 139 if (prepclosingmethod(L, uv, &G(L)->nilvalue)) /* something to call? */
139 callclose(L, NULL); /* call closing method */ 140 callclose(L, NULL); /* call closing method */
@@ -145,9 +146,10 @@ static int callclosemth (lua_State *L, TValue *uv, StkId level, int status) {
145 } 146 }
146 } 147 }
147 else { /* must close the object in protected mode */ 148 else { /* must close the object in protected mode */
148 ptrdiff_t oldtop = savestack(L, level + 1); 149 ptrdiff_t oldtop;
149 /* save error message and set stack top to 'level + 1' */ 150 level++; /* space for error message */
150 luaD_seterrorobj(L, status, level); 151 oldtop = savestack(L, level + 1); /* top will be after that */
152 luaD_seterrorobj(L, status, level); /* set error message */
151 if (prepclosingmethod(L, uv, s2v(level))) { /* something to call? */ 153 if (prepclosingmethod(L, uv, s2v(level))) { /* something to call? */
152 int newstatus = luaD_pcall(L, callclose, NULL, oldtop, 0); 154 int newstatus = luaD_pcall(L, callclose, NULL, oldtop, 0);
153 if (newstatus != LUA_OK && status == CLOSEPROTECT) /* first error? */ 155 if (newstatus != LUA_OK && status == CLOSEPROTECT) /* first error? */
@@ -203,18 +205,18 @@ int luaF_close (lua_State *L, StkId level, int status) {
203 StkId upl = uplevel(uv); 205 StkId upl = uplevel(uv);
204 TValue *slot = &uv->u.value; /* new position for value */ 206 TValue *slot = &uv->u.value; /* new position for value */
205 lua_assert(upl < L->top); 207 lua_assert(upl < L->top);
208 if (uv->tt == LUA_TUPVALTBC && status != NOCLOSINGMETH) {
209 /* must run closing method */
210 ptrdiff_t levelrel = savestack(L, level);
211 status = callclosemth(L, upl, status); /* may change the stack */
212 level = restorestack(L, levelrel);
213 }
206 luaF_unlinkupval(uv); 214 luaF_unlinkupval(uv);
207 setobj(L, slot, uv->v); /* move value to upvalue slot */ 215 setobj(L, slot, uv->v); /* move value to upvalue slot */
208 uv->v = slot; /* now current value lives here */ 216 uv->v = slot; /* now current value lives here */
209 if (!iswhite(uv)) 217 if (!iswhite(uv))
210 gray2black(uv); /* closed upvalues cannot be gray */ 218 gray2black(uv); /* closed upvalues cannot be gray */
211 luaC_barrier(L, uv, slot); 219 luaC_barrier(L, uv, slot);
212 if (uv->tt == LUA_TUPVALTBC && status != NOCLOSINGMETH) {
213 /* must run closing method */
214 ptrdiff_t levelrel = savestack(L, level);
215 status = callclosemth(L, uv->v, upl, status); /* may change the stack */
216 level = restorestack(L, levelrel);
217 }
218 } 220 }
219 return status; 221 return status;
220} 222}