diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-07-18 11:26:03 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-07-18 11:26:03 -0300 |
commit | 024a6071cac749504e0b26a915bda4f52c41a892 (patch) | |
tree | 564572b784d477d1ba460012031caf277bf89a74 /lfunc.c | |
parent | 4eefef07ab1c136f901d816822c79336fa89336d (diff) | |
download | lua-024a6071cac749504e0b26a915bda4f52c41a892.tar.gz lua-024a6071cac749504e0b26a915bda4f52c41a892.tar.bz2 lua-024a6071cac749504e0b26a915bda4f52c41a892.zip |
Small bug with stack reallocation
OP_RETURN must update trap before updating stack. (Bug detected with
-DHARDSTACKTESTS). Also, in 'luaF_close', do not create a variable
with 'uplevel(uv)', as the stack may change and invalidate this
value. (This is not a bug, but could become one if 'upl' was used
again.)
Diffstat (limited to 'lfunc.c')
-rw-r--r-- | lfunc.c | 7 |
1 files changed, 3 insertions, 4 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); |