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 committed 2025-06-16 15:50:12 -03:00
1 parent 0cecf1ab6d
commit 8cd7ae7da0
2 files changed
+31 -13

No files matched your search

+26 -13
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))
return 0; /* ignore non-(short)string modes */
else {
const char *smode = getshrstr(tsvalue(mode));
const char *weakkey = strchr(smode, 'k');
const char *weakvalue = strchr(smode, 'v');
return ((weakkey != NULL) << 1) | (weakvalue != NULL);
}
}
static l_mem traversetable (global_State *g, Table *h) {
markobjectN(g, h->metatable); markobjectN(g, h->metatable);
if (mode && ttisshrstring(mode) && /* is there a weak mode? */ switch (getmode(g, h)) {
(cast_void(smode = tsvalue(mode)), case 0: /* not weak */
cast_void(weakkey = strchr(getshrstr(smode), 'k')), traversestrongtable(g, h);
cast_void(weakvalue = strchr(getshrstr(smode), 'v')), break;
(weakkey || weakvalue))) { /* is really weak? */ case 1: /* weak values */
if (!weakkey) /* strong keys? */
traverseweakvalue(g, h); traverseweakvalue(g, h);
else if (!weakvalue) /* strong values? */ break;
case 2: /* weak keys */
traverseephemeron(g, h, 0); traverseephemeron(g, h, 0);
else /* all weak */ break;
case 3: /* all weak */
linkgclist(h, g->allweak); /* nothing to traverse now */ 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;
} }
+5
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 = {}