add df.global:_field method. add test case to check for overlapping globals.

develop
Ben Lubar 2020-03-20 09:41:58 -05:00
parent 44b45ce43f
commit 37e7bed779
No known key found for this signature in database
GPG Key ID: 92939677AB59EDA4
2 changed files with 40 additions and 0 deletions

@ -633,6 +633,20 @@ static int meta_struct_field_reference(lua_State *state)
return 1; return 1;
} }
/**
* Method: _field for df.global.
*/
static int meta_global_field_reference(lua_State *state)
{
if (lua_gettop(state) != 2)
luaL_error(state, "Usage: object._field(name)");
auto field = (struct_field_info*)find_field(state, 2, "reference");
if (!field)
field_error(state, 2, "builtin property or method", "reference");
field_reference(state, field, *(void**)field->offset);
return 1;
}
/** /**
* Metamethod: __newindex for structures. * Metamethod: __newindex for structures.
*/ */
@ -1410,7 +1424,10 @@ void struct_identity::build_metatable(lua_State *state)
void global_identity::build_metatable(lua_State *state) void global_identity::build_metatable(lua_State *state)
{ {
int base = lua_gettop(state);
MakeFieldMetatable(state, this, meta_global_index, meta_global_newindex, true); MakeFieldMetatable(state, this, meta_global_index, meta_global_newindex, true);
SetStructMethod(state, base+1, base+2, meta_global_field_reference, "_field");
SetPtrMethods(state, base+1, base+2);
} }
/** /**

@ -0,0 +1,23 @@
function test.overlappingGlobals()
local globals = {}
for name, _ in pairs(df.global) do
local gvar = df.global:_field(name)
local size, addr = gvar:sizeof()
table.insert(globals, {
name = name,
first = addr,
last = addr + size - 1
})
end
table.sort(globals, function(a, b)
return a.first < b.first
end)
for i = 2, #globals do
local prev = globals[i - 1]
local cur = globals[i]
expect.true_(prev.last < cur.first, "global variable " .. prev.name .. " overlaps global variable " .. cur.name)
end
end