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:
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);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 = {}
|
||||||
|
|||||||
Reference in New Issue
Block a user