diff options
| -rw-r--r-- | lfunc.c | 7 | ||||
| -rw-r--r-- | lvm.c | 9 |
2 files changed, 9 insertions, 7 deletions
| @@ -202,13 +202,12 @@ void luaF_unlinkupval (UpVal *uv) { | |||
| 202 | int luaF_close (lua_State *L, StkId level, int status) { | 202 | int luaF_close (lua_State *L, StkId level, int status) { |
| 203 | UpVal *uv; | 203 | UpVal *uv; |
| 204 | while ((uv = L->openupval) != NULL && uplevel(uv) >= level) { | 204 | while ((uv = L->openupval) != NULL && uplevel(uv) >= level) { |
| 205 | StkId upl = uplevel(uv); | ||
| 206 | TValue *slot = &uv->u.value; /* new position for value */ | 205 | TValue *slot = &uv->u.value; /* new position for value */ |
| 207 | lua_assert(upl < L->top); | 206 | lua_assert(uplevel(uv) < L->top); |
| 208 | if (uv->tt == LUA_TUPVALTBC && status != NOCLOSINGMETH) { | 207 | if (uv->tt == LUA_TUPVALTBC && status != NOCLOSINGMETH) { |
| 209 | /* must run closing method */ | 208 | /* must run closing method, which may change the stack */ |
| 210 | ptrdiff_t levelrel = savestack(L, level); | 209 | ptrdiff_t levelrel = savestack(L, level); |
| 211 | status = callclosemth(L, upl, status); /* may change the stack */ | 210 | status = callclosemth(L, uplevel(uv), status); |
| 212 | level = restorestack(L, levelrel); | 211 | level = restorestack(L, levelrel); |
| 213 | } | 212 | } |
| 214 | luaF_unlinkupval(uv); | 213 | luaF_unlinkupval(uv); |
| @@ -1574,8 +1574,10 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
| 1574 | savepc(ci); /* some calls here can raise errors */ | 1574 | savepc(ci); /* some calls here can raise errors */ |
| 1575 | if (TESTARG_k(i)) { | 1575 | if (TESTARG_k(i)) { |
| 1576 | /* close upvalues from current call; the compiler ensures | 1576 | /* close upvalues from current call; the compiler ensures |
| 1577 | that there are no to-be-closed variables here */ | 1577 | that there are no to-be-closed variables here, so this |
| 1578 | call cannot change the stack */ | ||
| 1578 | luaF_close(L, base, NOCLOSINGMETH); | 1579 | luaF_close(L, base, NOCLOSINGMETH); |
| 1580 | lua_assert(base == ci->func + 1); | ||
| 1579 | } | 1581 | } |
| 1580 | if (!ttisfunction(s2v(ra))) { /* not a function? */ | 1582 | if (!ttisfunction(s2v(ra))) { /* not a function? */ |
| 1581 | luaD_tryfuncTM(L, ra); /* try '__call' metamethod */ | 1583 | luaD_tryfuncTM(L, ra); /* try '__call' metamethod */ |
| @@ -1602,10 +1604,11 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
| 1602 | if (n < 0) /* not fixed? */ | 1604 | if (n < 0) /* not fixed? */ |
| 1603 | n = cast_int(L->top - ra); /* get what is available */ | 1605 | n = cast_int(L->top - ra); /* get what is available */ |
| 1604 | savepc(ci); | 1606 | savepc(ci); |
| 1605 | if (TESTARG_k(i)) { | 1607 | if (TESTARG_k(i)) { /* may there be open upvalues? */ |
| 1606 | if (L->top < ci->top) | 1608 | if (L->top < ci->top) |
| 1607 | L->top = ci->top; | 1609 | L->top = ci->top; |
| 1608 | luaF_close(L, base, LUA_OK); /* there may be open upvalues */ | 1610 | luaF_close(L, base, LUA_OK); |
| 1611 | updatetrap(ci); | ||
| 1609 | updatestack(ci); | 1612 | updatestack(ci); |
| 1610 | } | 1613 | } |
| 1611 | if (nparams1) /* vararg function? */ | 1614 | if (nparams1) /* vararg function? */ |
