Simpler code for 'traversetable'

Check the mode in a separate function (getmode), instead of using
comma expressions inside the 'if' condition.
This commit is contained in:
Roberto Ierusalimschy
2025-06-16 15:50:12 -03:00
parent 0cecf1ab6d
commit 8cd7ae7da0
2 changed files with 35 additions and 17 deletions

47
lgc.c
View File

@@ -589,25 +589,38 @@ static void traversestrongtable (global_State *g, Table *h) {
} }
static l_mem traversetable (global_State *g, Table *h) { /*
const char *weakkey, *weakvalue; ** (result & 1) iff weak values; (result & 2) iff weak keys.
*/
static int getmode (global_State *g, Table *h) {
const TValue *mode = gfasttm(g, h->metatable, TM_MODE); const TValue *mode = gfasttm(g, h->metatable, TM_MODE);
TString *smode; if (mode == NULL || !ttisshrstring(mode))
markobjectN(g, h->metatable); return 0; /* ignore non-(short)string modes */
if (mode && ttisshrstring(mode) && /* is there a weak mode? */ else {
(cast_void(smode = tsvalue(mode)), const char *smode = getshrstr(tsvalue(mode));
cast_void(weakkey = strchr(getshrstr(smode), 'k')), const char *weakkey = strchr(smode, 'k');
cast_void(weakvalue = strchr(getshrstr(smode), 'v')), const char *weakvalue = strchr(smode, 'v');
(weakkey || weakvalue))) { /* is really weak? */ return ((weakkey != NULL) << 1) | (weakvalue != NULL);
if (!weakkey) /* strong keys? */ }
traverseweakvalue(g, h); }
else if (!weakvalue) /* strong values? */
traverseephemeron(g, h, 0);
else /* all weak */ static l_mem traversetable (global_State *g, Table *h) {
linkgclist(h, g->allweak); /* nothing to traverse now */ markobjectN(g, h->metatable);
switch (getmode(g, h)) {
case 0: /* not weak */
traversestrongtable(g, h);
break;
case 1: /* weak values */
traverseweakvalue(g, h);
break;
case 2: /* weak keys */
traverseephemeron(g, h, 0);
break;
case 3: /* all weak */
linkgclist(h, g->allweak); /* nothing to traverse now */
break;
} }
else /* not weak */
traversestrongtable(g, h);
return 1 + 2*sizenode(h) + h->asize; return 1 + 2*sizenode(h) + h->asize;
} }

View File

@@ -288,6 +288,11 @@ x,y,z=nil
collectgarbage() collectgarbage()
assert(next(a) == string.rep('$', 11)) assert(next(a) == string.rep('$', 11))
do -- invalid mode
local a = setmetatable({}, {__mode = 34})
collectgarbage()
end
-- 'bug' in 5.1 -- 'bug' in 5.1
a = {} a = {}