diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-07-19 12:13:00 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-07-19 12:13:00 -0300 |
commit | 440a5ee78c8592230780310c9c8d8c2ba1700cb1 (patch) | |
tree | 30d361cbe23eb652f8874e580750ca65fcca5b52 /lfunc.c | |
parent | dc07719b0dbc4f2df0f42e34e18be1e0ac4fa2c3 (diff) | |
download | lua-440a5ee78c8592230780310c9c8d8c2ba1700cb1.tar.gz lua-440a5ee78c8592230780310c9c8d8c2ba1700cb1.tar.bz2 lua-440a5ee78c8592230780310c9c8d8c2ba1700cb1.zip |
Fixed bug for emergency collection in upvalue creation
When creating an upvalue, an emergency collection can collect the
previous upvalue where the new one would be linked. The following
code can trigger the bug, using valgrind on Lua compiled with the
-DHARDMEMTESTS option:
local x; local y
(function () return y end)();
(function () return x end)()
Diffstat (limited to 'lfunc.c')
-rw-r--r-- | lfunc.c | 14 |
1 files changed, 8 insertions, 6 deletions
@@ -82,20 +82,22 @@ static UpVal *newupval (lua_State *L, int tbc, StkId level, UpVal **prev) { | |||
82 | 82 | ||
83 | 83 | ||
84 | /* | 84 | /* |
85 | ** Find and reuse, or create if it does not exist, a regular upvalue | 85 | ** Find and reuse, or create if it does not exist, an upvalue |
86 | ** at the given level. | 86 | ** at the given level and set it to the given slot. |
87 | */ | 87 | */ |
88 | UpVal *luaF_findupval (lua_State *L, StkId level) { | 88 | void luaF_setupval (lua_State *L, StkId level, UpVal **slot) { |
89 | UpVal **pp = &L->openupval; | 89 | UpVal **pp = &L->openupval; |
90 | UpVal *p; | 90 | UpVal *p; |
91 | lua_assert(isintwups(L) || L->openupval == NULL); | 91 | lua_assert(isintwups(L) || L->openupval == NULL); |
92 | while ((p = *pp) != NULL && uplevel(p) >= level) { /* search for it */ | 92 | while ((p = *pp) != NULL && uplevel(p) >= level) { /* search for it */ |
93 | *slot = p; | ||
93 | if (uplevel(p) == level && !isdead(G(L), p)) /* corresponding upvalue? */ | 94 | if (uplevel(p) == level && !isdead(G(L), p)) /* corresponding upvalue? */ |
94 | return p; /* return it */ | 95 | return; /* found it */ |
95 | pp = &p->u.open.next; | 96 | pp = &p->u.open.next; |
96 | } | 97 | } |
97 | /* not found: create a new upvalue after 'pp' */ | 98 | /* not found: create a new upvalue after 'pp' (which is |
98 | return newupval(L, 0, level, pp); | 99 | anchored in 'slot', in case of an emergency collection) */ |
100 | *slot = newupval(L, 0, level, pp); | ||
99 | } | 101 | } |
100 | 102 | ||
101 | 103 | ||