aboutsummaryrefslogtreecommitdiff
path: root/lfunc.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-07-19 12:13:00 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-07-19 12:13:00 -0300
commit440a5ee78c8592230780310c9c8d8c2ba1700cb1 (patch)
tree30d361cbe23eb652f8874e580750ca65fcca5b52 /lfunc.c
parentdc07719b0dbc4f2df0f42e34e18be1e0ac4fa2c3 (diff)
downloadlua-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.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/lfunc.c b/lfunc.c
index 9f91ad4f..f7edf56b 100644
--- a/lfunc.c
+++ b/lfunc.c
@@ -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*/
88UpVal *luaF_findupval (lua_State *L, StkId level) { 88void 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