From 37e7bed7798f15dc6974b4dec0fee5acb9509ad7 Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Fri, 20 Mar 2020 09:41:58 -0500 Subject: [PATCH] add df.global:_field method. add test case to check for overlapping globals. --- library/LuaTypes.cpp | 17 +++++++++++++++++ test/library/structures.lua | 23 +++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 test/library/structures.lua diff --git a/library/LuaTypes.cpp b/library/LuaTypes.cpp index d289984ff..ad0f3e5e4 100644 --- a/library/LuaTypes.cpp +++ b/library/LuaTypes.cpp @@ -633,6 +633,20 @@ static int meta_struct_field_reference(lua_State *state) 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. */ @@ -1410,7 +1424,10 @@ void struct_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); + SetStructMethod(state, base+1, base+2, meta_global_field_reference, "_field"); + SetPtrMethods(state, base+1, base+2); } /** diff --git a/test/library/structures.lua b/test/library/structures.lua new file mode 100644 index 000000000..62f3cd635 --- /dev/null +++ b/test/library/structures.lua @@ -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