mirror of
https://github.com/lua/lua.git
synced 2026-01-31 03:45:52 +00:00
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:
parent
0cecf1ab6d
commit
8cd7ae7da0
47
lgc.c
47
lgc.c
@ -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);
|
||||
TString *smode;
|
||||
markobjectN(g, h->metatable);
|
||||
if (mode && ttisshrstring(mode) && /* is there a weak mode? */
|
||||
(cast_void(smode = tsvalue(mode)),
|
||||
cast_void(weakkey = strchr(getshrstr(smode), 'k')),
|
||||
cast_void(weakvalue = strchr(getshrstr(smode), 'v')),
|
||||
(weakkey || weakvalue))) { /* is really weak? */
|
||||
if (!weakkey) /* strong keys? */
|
||||
traverseweakvalue(g, h);
|
||||
else if (!weakvalue) /* strong values? */
|
||||
traverseephemeron(g, h, 0);
|
||||
else /* all weak */
|
||||
linkgclist(h, g->allweak); /* nothing to traverse now */
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@ -288,6 +288,11 @@ x,y,z=nil
|
||||
collectgarbage()
|
||||
assert(next(a) == string.rep('$', 11))
|
||||
|
||||
do -- invalid mode
|
||||
local a = setmetatable({}, {__mode = 34})
|
||||
collectgarbage()
|
||||
end
|
||||
|
||||
|
||||
-- 'bug' in 5.1
|
||||
a = {}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user