mirror of https://github.com/rusefi/lua.git
Free bit 7 of GC 'marked' field
Tables were using this bit to indicate their array sizes were real ('isrealasize'), but this bit can be useful for tests. Instead, they can use bit 7 of their 'flag' field for that purpose. (There are only six fast-access metamethods.) This 'flag' field only exists in tables, so this use does not affect other types.
This commit is contained in:
parent
68109afcdb
commit
7c3cb71fa4
3
lgc.h
3
lgc.h
|
@ -69,8 +69,7 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Layout for bit use in 'marked' field. First three bits are
|
** Layout for bit use in 'marked' field. First three bits are
|
||||||
** used for object "age" in generational mode. Last bit is free
|
** used for object "age" in generational mode.
|
||||||
** to be used by respective objects.
|
|
||||||
*/
|
*/
|
||||||
#define WHITE0BIT 3 /* object is white (type 0) */
|
#define WHITE0BIT 3 /* object is white (type 0) */
|
||||||
#define WHITE1BIT 4 /* object is white (type 1) */
|
#define WHITE1BIT 4 /* object is white (type 1) */
|
||||||
|
|
|
@ -704,9 +704,9 @@ typedef union Node {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define BITRAS (1 << 7)
|
#define BITRAS (1 << 7)
|
||||||
#define isrealasize(t) (!((t)->marked & BITRAS))
|
#define isrealasize(t) (!((t)->flags & BITRAS))
|
||||||
#define setrealasize(t) ((t)->marked &= cast_byte(~BITRAS))
|
#define setrealasize(t) ((t)->flags &= cast_byte(~BITRAS))
|
||||||
#define setnorealasize(t) ((t)->marked |= BITRAS)
|
#define setnorealasize(t) ((t)->flags |= BITRAS)
|
||||||
|
|
||||||
|
|
||||||
typedef struct Table {
|
typedef struct Table {
|
||||||
|
|
2
ltable.c
2
ltable.c
|
@ -583,7 +583,7 @@ Table *luaH_new (lua_State *L) {
|
||||||
GCObject *o = luaC_newobj(L, LUA_VTABLE, sizeof(Table));
|
GCObject *o = luaC_newobj(L, LUA_VTABLE, sizeof(Table));
|
||||||
Table *t = gco2t(o);
|
Table *t = gco2t(o);
|
||||||
t->metatable = NULL;
|
t->metatable = NULL;
|
||||||
t->flags = cast_byte(~0);
|
t->flags = cast_byte(maskflags); /* table has no metamethod fields */
|
||||||
t->array = NULL;
|
t->array = NULL;
|
||||||
t->alimit = 0;
|
t->alimit = 0;
|
||||||
setnodevector(L, t, 0);
|
setnodevector(L, t, 0);
|
||||||
|
|
7
ltable.h
7
ltable.h
|
@ -15,7 +15,12 @@
|
||||||
#define gnext(n) ((n)->u.next)
|
#define gnext(n) ((n)->u.next)
|
||||||
|
|
||||||
|
|
||||||
#define invalidateTMcache(t) ((t)->flags = 0)
|
/*
|
||||||
|
** Clear all bits of fast-access metamethods, which means that the table
|
||||||
|
** may have any of these metamethods. (First access that fails after the
|
||||||
|
** clearing will set the bit again.)
|
||||||
|
*/
|
||||||
|
#define invalidateTMcache(t) ((t)->flags &= ~maskflags)
|
||||||
|
|
||||||
|
|
||||||
/* true when 't' is using 'dummynode' as its hash part */
|
/* true when 't' is using 'dummynode' as its hash part */
|
||||||
|
|
9
ltm.h
9
ltm.h
|
@ -45,6 +45,15 @@ typedef enum {
|
||||||
} TMS;
|
} TMS;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Mask with 1 in all fast-access methods. A 1 in any of these bits
|
||||||
|
** in the flag of a (meta)table means the metatable does not have the
|
||||||
|
** corresponding metamethod field. (Bit 7 of the flag is used for
|
||||||
|
** 'isrealasize'.)
|
||||||
|
*/
|
||||||
|
#define maskflags (~(~0u << (TM_EQ + 1)))
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Test whether there is no tagmethod.
|
** Test whether there is no tagmethod.
|
||||||
** (Because tagmethods use raw accesses, the result may be an "empty" nil.)
|
** (Because tagmethods use raw accesses, the result may be an "empty" nil.)
|
||||||
|
|
|
@ -305,6 +305,17 @@ t[Set{1,3,5}] = 1
|
||||||
assert(t[Set{1,3,5}] == undef)
|
assert(t[Set{1,3,5}] == undef)
|
||||||
|
|
||||||
|
|
||||||
|
do -- test invalidating flags
|
||||||
|
local mt = {__eq = true}
|
||||||
|
local a = setmetatable({10}, mt)
|
||||||
|
local b = setmetatable({10}, mt)
|
||||||
|
mt.__eq = nil
|
||||||
|
assert(a ~= b) -- no metamethod
|
||||||
|
mt.__eq = function (x,y) return x[1] == y[1] end
|
||||||
|
assert(a == b) -- must use metamethod now
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
if not T then
|
if not T then
|
||||||
(Message or print)('\n >>> testC not active: skipping tests for \z
|
(Message or print)('\n >>> testC not active: skipping tests for \z
|
||||||
userdata <<<\n')
|
userdata <<<\n')
|
||||||
|
|
Loading…
Reference in New Issue