From 0e0740fddf26a849c97c26bd8e6dcb6cf58b9bf9 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Tue, 10 Apr 2012 10:34:03 +0400 Subject: [PATCH] Stop printall(df.global) from breaking if there are unknown addresses. --- LUA_API.rst | 5 +++++ Lua API.html | 4 ++++ library/LuaTypes.cpp | 15 +++++++++------ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/LUA_API.rst b/LUA_API.rst index 71cb6030f..3ce10c766 100644 --- a/LUA_API.rst +++ b/LUA_API.rst @@ -68,6 +68,11 @@ All typed objects have the following built-in features: and values. Fields are enumerated in memory order. Methods and lua wrapper properties are not included in the iteration. + **WARNING**: a few of the data structures (like ui_look_list) + contain unions with pointers to different types with vtables. + Using pairs on such structs is an almost sure way to crash with + an access violation. + * ``ref._kind`` Returns one of: ``primitive``, ``struct``, ``container``, diff --git a/Lua API.html b/Lua API.html index 569940f56..82943fadf 100644 --- a/Lua API.html +++ b/Lua API.html @@ -395,6 +395,10 @@ Every structured field access produces a new userdata instance.

Returns an iterator for the sequence of actual C++ field names and values. Fields are enumerated in memory order. Methods and lua wrapper properties are not included in the iteration.

+

WARNING: a few of the data structures (like ui_look_list) +contain unions with pointers to different types with vtables. +Using pairs on such structs is an almost sure way to crash with +an access violation.

  • ref._kind

    Returns one of: primitive, struct, container, diff --git a/library/LuaTypes.cpp b/library/LuaTypes.cpp index 4213499eb..2f9ef9e81 100644 --- a/library/LuaTypes.cpp +++ b/library/LuaTypes.cpp @@ -1072,10 +1072,10 @@ void LuaWrapper::SetFunctionWrappers(lua_State *state, const FunctionReg *reg) /** * Add fields in the array to the UPVAL_FIELDTABLE candidates on the stack. */ -static void IndexFields(lua_State *state, int base, struct_identity *pstruct) +static void IndexFields(lua_State *state, int base, struct_identity *pstruct, bool globals) { if (pstruct->getParent()) - IndexFields(state, base, pstruct->getParent()); + IndexFields(state, base, pstruct->getParent(), globals); auto fields = pstruct->getFields(); if (!fields) @@ -1105,7 +1105,10 @@ static void IndexFields(lua_State *state, int base, struct_identity *pstruct) break; default: - AssociateId(state, base+3, ++cnt, name.c_str()); + // Do not add invalid globals to the enumeration order + if (!globals || *(void**)fields[i].offset) + AssociateId(state, base+3, ++cnt, name.c_str()); + lua_pushlightuserdata(state, (void*)&fields[i]); lua_setfield(state, base+2, name.c_str()); break; @@ -1143,7 +1146,7 @@ void LuaWrapper::IndexStatics(lua_State *state, int meta_idx, int ftable_idx, st * Make a struct-style object metatable. */ static void MakeFieldMetatable(lua_State *state, struct_identity *pstruct, - lua_CFunction reader, lua_CFunction writer) + lua_CFunction reader, lua_CFunction writer, bool globals = false) { int base = lua_gettop(state); @@ -1152,7 +1155,7 @@ static void MakeFieldMetatable(lua_State *state, struct_identity *pstruct, // Index the fields lua_newtable(state); - IndexFields(state, base, pstruct); + IndexFields(state, base, pstruct, globals); // Add the iteration metamethods PushStructMethod(state, base+1, base+3, meta_struct_next); @@ -1304,7 +1307,7 @@ void struct_identity::build_metatable(lua_State *state) void global_identity::build_metatable(lua_State *state) { - MakeFieldMetatable(state, this, meta_global_index, meta_global_newindex); + MakeFieldMetatable(state, this, meta_global_index, meta_global_newindex, true); } /**