diff --git a/library/LuaTypes.cpp b/library/LuaTypes.cpp index 550dc2390..6d5961f8d 100644 --- a/library/LuaTypes.cpp +++ b/library/LuaTypes.cpp @@ -1032,7 +1032,7 @@ static int meta_call_function(lua_State *state) static void AddMethodWrapper(lua_State *state, int meta_idx, int field_idx, const char *name, function_identity_base *fun) { - lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_TYPETABLE_NAME); + lua_rawgetp(state, LUA_REGISTRYINDEX, &DFHACK_TYPETABLE_TOKEN); lua_pushvalue(state, meta_idx); lua_pushfstring(state, "%s()", name); lua_pushlightuserdata(state, fun); @@ -1331,7 +1331,7 @@ void LuaWrapper::push_adhoc_pointer(lua_State *state, void *ptr, type_identity * return; } - LookupInTable(state, target, DFHACK_PTR_IDTABLE_NAME); + LookupInTable(state, target, &DFHACK_PTR_IDTABLE_TOKEN); type_identity *id = (type_identity*)lua_touserdata(state, -1); lua_pop(state, 1); @@ -1347,7 +1347,7 @@ void LuaWrapper::push_adhoc_pointer(lua_State *state, void *ptr, type_identity * void *newobj = lua_newuserdata(state, sizeof(pointer_identity)); id = new (newobj) pointer_identity(target); - SaveInTable(state, target, DFHACK_PTR_IDTABLE_NAME); + SaveInTable(state, target, &DFHACK_PTR_IDTABLE_TOKEN); lua_pop(state, 1); } diff --git a/library/LuaWrapper.cpp b/library/LuaWrapper.cpp index 00d0ff64c..1148d3fcd 100644 --- a/library/LuaWrapper.cpp +++ b/library/LuaWrapper.cpp @@ -93,9 +93,9 @@ static void freeze_table(lua_State *state, bool leave_metatable = false, const c lua_pop(state, 1); } -static void LookupInTable(lua_State *state, const char *tname) +static void LookupInTable(lua_State *state, LuaToken *tname) { - lua_getfield(state, LUA_REGISTRYINDEX, tname); + lua_rawgetp(state, LUA_REGISTRYINDEX, tname); lua_swap(state); lua_rawget(state, -2); lua_remove(state, -2); @@ -115,7 +115,7 @@ bool LuaWrapper::LookupTypeInfo(lua_State *state, bool in_method) } else { - LookupInTable(state, DFHACK_TYPETABLE_NAME); + LookupInTable(state, &DFHACK_TYPETABLE_TOKEN); } // stack: [info] @@ -129,17 +129,17 @@ bool LuaWrapper::LookupTypeInfo(lua_State *state, bool in_method) return true; } -void LuaWrapper::LookupInTable(lua_State *state, void *id, const char *tname) +void LuaWrapper::LookupInTable(lua_State *state, void *id, LuaToken *tname) { - lua_getfield(state, LUA_REGISTRYINDEX, tname); + lua_rawgetp(state, LUA_REGISTRYINDEX, tname); lua_rawgetp(state, -1, id); lua_remove(state, -2); } -void LuaWrapper::SaveInTable(lua_State *state, void *node, const char *tname) +void LuaWrapper::SaveInTable(lua_State *state, void *node, LuaToken *tname) { // stack: [info] - lua_getfield(state, LUA_REGISTRYINDEX, tname); + lua_rawgetp(state, LUA_REGISTRYINDEX, tname); lua_pushvalue(state, -2); lua_rawsetp(state, -2, node); @@ -154,7 +154,7 @@ void LuaWrapper::SaveInTable(lua_State *state, void *node, const char *tname) void LuaWrapper::SaveTypeInfo(lua_State *state, void *node) { - SaveInTable(state, node, DFHACK_TYPETABLE_NAME); + SaveInTable(state, node, &DFHACK_TYPETABLE_TOKEN); } static void BuildTypeMetatable(lua_State *state, type_identity *type); @@ -309,7 +309,7 @@ bool LuaWrapper::is_type_compatible(lua_State *state, type_identity *type1, int static bool is_type_compatible(lua_State *state, type_identity *type1, int meta1, int meta2, bool exact_equal) { - lua_getfield(state, meta2, "_identity"); + lua_rawgetp(state, meta2, &DFHACK_IDENTITY_FIELD_TOKEN); auto type2 = (type_identity*)lua_touserdata(state, -1); lua_pop(state, 1); @@ -321,7 +321,7 @@ static bool is_type_compatible(lua_State *state, int meta1, int meta2, bool exac if (lua_rawequal(state, meta1, meta2)) return true; - lua_getfield(state, meta1, "_identity"); + lua_rawgetp(state, meta1, &DFHACK_IDENTITY_FIELD_TOKEN); auto type1 = (type_identity*)lua_touserdata(state, -1); lua_pop(state, 1); @@ -394,7 +394,7 @@ static bool is_valid_metatable(lua_State *state, int objidx, int metaidx) else { lua_pushvalue(state, objidx); - LookupInTable(state, DFHACK_TYPEID_TABLE_NAME); + LookupInTable(state, &DFHACK_TYPEID_TABLE_TOKEN); } bool ok = !lua_isnil(state, -1); @@ -419,7 +419,7 @@ type_identity *LuaWrapper::get_object_identity(lua_State *state, int objidx, luaL_error(state, "Invalid object metatable in %s", ctx); // Extract identity from metatable - lua_getfield(state, -1, "_identity"); + lua_rawgetp(state, -1, &DFHACK_IDENTITY_FIELD_TOKEN); type_identity *id = (type_identity*)lua_touserdata(state, -1); if (!id) @@ -894,9 +894,9 @@ void LuaWrapper::MakeMetatable(lua_State *state, type_identity *type, const char lua_setfield(state, base+1, "__metatable"); lua_pushlightuserdata(state, type); - lua_setfield(state, base+1, "_identity"); + lua_rawsetp(state, base+1, &DFHACK_IDENTITY_FIELD_TOKEN); - LookupInTable(state, type, DFHACK_TYPEID_TABLE_NAME); + LookupInTable(state, type, &DFHACK_TYPEID_TABLE_TOKEN); if (lua_isnil(state, -1)) { // Copy the string from __metatable if no real type @@ -929,7 +929,7 @@ void LuaWrapper::SetPtrMethods(lua_State *state, int meta_idx, int read_idx) lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_COMPARE_NAME); lua_setfield(state, meta_idx, "__eq"); - lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_TYPETABLE_NAME); + lua_rawgetp(state, LUA_REGISTRYINDEX, &DFHACK_TYPETABLE_TOKEN); lua_pushvalue(state, meta_idx); lua_pushcclosure(state, meta_ptr_tostring, 2); lua_setfield(state, meta_idx, "__tostring"); @@ -981,7 +981,7 @@ void LuaWrapper::SetPairsMethod(lua_State *state, int meta_idx, const char *name void LuaWrapper::PushStructMethod(lua_State *state, int meta_idx, int ftable_idx, lua_CFunction function) { - lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_TYPETABLE_NAME); + lua_rawgetp(state, LUA_REGISTRYINDEX, &DFHACK_TYPETABLE_TOKEN); lua_pushvalue(state, meta_idx); lua_pushvalue(state, ftable_idx); lua_pushcclosure(state, function, 3); @@ -1004,7 +1004,7 @@ void LuaWrapper::PushContainerMethod(lua_State *state, int meta_idx, int ftable_ lua_CFunction function, type_identity *container, type_identity *item, int count) { - lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_TYPETABLE_NAME); + lua_rawgetp(state, LUA_REGISTRYINDEX, &DFHACK_TYPETABLE_TOKEN); lua_pushvalue(state, meta_idx); lua_pushvalue(state, ftable_idx); @@ -1037,10 +1037,10 @@ void LuaWrapper::AttachEnumKeys(lua_State *state, int meta_idx, int ftable_idx, { EnableMetaField(state, ftable_idx, "_enum"); - LookupInTable(state, ienum, DFHACK_TYPEID_TABLE_NAME); + LookupInTable(state, ienum, &DFHACK_TYPEID_TABLE_TOKEN); lua_setfield(state, meta_idx, "_enum"); - LookupInTable(state, ienum, DFHACK_ENUM_TABLE_NAME); + LookupInTable(state, ienum, &DFHACK_ENUM_TABLE_TOKEN); if (!lua_isnil(state, -1)) { @@ -1053,7 +1053,7 @@ void LuaWrapper::AttachEnumKeys(lua_State *state, int meta_idx, int ftable_idx, else { lua_pop(state, 1); - lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_EMPTY_TABLE_NAME); + lua_rawgetp(state, LUA_REGISTRYINDEX, &DFHACK_EMPTY_TABLE_TOKEN); } lua_dup(state); @@ -1111,12 +1111,12 @@ static void FillEnumKeys(lua_State *state, int ftable, enum_identity *eid) lua_setfield(state, base+1, "_last_item"); } - SaveInTable(state, eid, DFHACK_ENUM_TABLE_NAME); + SaveInTable(state, eid, &DFHACK_ENUM_TABLE_TOKEN); // Add an attribute table if any if (eid->getAttrs()) { - lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_TYPETABLE_NAME); + lua_rawgetp(state, LUA_REGISTRYINDEX, &DFHACK_TYPETABLE_TOKEN); lua_pushlightuserdata(state, eid); lua_pushvalue(state, base+1); lua_pushcclosure(state, meta_enum_attr_index, 3); @@ -1152,7 +1152,7 @@ static void FillBitfieldKeys(lua_State *state, int ftable, bitfield_identity *ei lua_pushinteger(state, eid->getNumBits()-1); lua_setfield(state, base+1, "_last_item"); - SaveInTable(state, eid, DFHACK_ENUM_TABLE_NAME); + SaveInTable(state, eid, &DFHACK_ENUM_TABLE_TOKEN); lua_setfield(state, base, "__index"); lua_setmetatable(state, ftable); @@ -1169,7 +1169,7 @@ static void RenderType(lua_State *state, compound_identity *node) if (!lua_checkstack(state, 20)) return; - SaveInTable(state, node, DFHACK_TYPEID_TABLE_NAME); + SaveInTable(state, node, &DFHACK_TYPEID_TABLE_TOKEN); // metatable lua_newtable(state); @@ -1184,7 +1184,7 @@ static void RenderType(lua_State *state, compound_identity *node) lua_setfield(state, base+2, "__tostring"); lua_pushlightuserdata(state, node); - lua_setfield(state, base+2, "_identity"); + lua_rawsetp(state, base+2, &DFHACK_IDENTITY_FIELD_TOKEN); // inner table lua_newtable(state); @@ -1272,16 +1272,16 @@ static int DoAttach(lua_State *state) int base = lua_gettop(state); lua_newtable(state); - lua_setfield(state, LUA_REGISTRYINDEX, DFHACK_PTR_IDTABLE_NAME); + lua_rawsetp(state, LUA_REGISTRYINDEX, &DFHACK_PTR_IDTABLE_TOKEN); lua_newtable(state); - lua_setfield(state, LUA_REGISTRYINDEX, DFHACK_TYPEID_TABLE_NAME); + lua_rawsetp(state, LUA_REGISTRYINDEX, &DFHACK_TYPEID_TABLE_TOKEN); lua_newtable(state); - lua_setfield(state, LUA_REGISTRYINDEX, DFHACK_ENUM_TABLE_NAME); + lua_rawsetp(state, LUA_REGISTRYINDEX, &DFHACK_ENUM_TABLE_TOKEN); lua_newtable(state); - lua_setfield(state, LUA_REGISTRYINDEX, DFHACK_EMPTY_TABLE_NAME); + lua_rawsetp(state, LUA_REGISTRYINDEX, &DFHACK_EMPTY_TABLE_TOKEN); lua_pushcfunction(state, change_error); lua_setfield(state, LUA_REGISTRYINDEX, DFHACK_CHANGEERROR_NAME); @@ -1292,27 +1292,27 @@ static int DoAttach(lua_State *state) lua_pushcfunction(state, meta_type_tostring); lua_setfield(state, LUA_REGISTRYINDEX, DFHACK_TYPE_TOSTRING_NAME); - lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_TYPETABLE_NAME); + lua_rawgetp(state, LUA_REGISTRYINDEX, &DFHACK_TYPETABLE_TOKEN); lua_pushcclosure(state, meta_sizeof, 1); lua_setfield(state, LUA_REGISTRYINDEX, DFHACK_SIZEOF_NAME); - lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_TYPETABLE_NAME); + lua_rawgetp(state, LUA_REGISTRYINDEX, &DFHACK_TYPETABLE_TOKEN); lua_pushcclosure(state, meta_displace, 1); lua_setfield(state, LUA_REGISTRYINDEX, DFHACK_DISPLACE_NAME); - lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_TYPETABLE_NAME); + lua_rawgetp(state, LUA_REGISTRYINDEX, &DFHACK_TYPETABLE_TOKEN); lua_pushcclosure(state, meta_new, 1); lua_setfield(state, LUA_REGISTRYINDEX, DFHACK_NEW_NAME); - lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_TYPETABLE_NAME); + lua_rawgetp(state, LUA_REGISTRYINDEX, &DFHACK_TYPETABLE_TOKEN); lua_pushcclosure(state, meta_assign, 1); lua_setfield(state, LUA_REGISTRYINDEX, DFHACK_ASSIGN_NAME); - lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_TYPETABLE_NAME); + lua_rawgetp(state, LUA_REGISTRYINDEX, &DFHACK_TYPETABLE_TOKEN); lua_pushcclosure(state, meta_is_instance, 1); lua_setfield(state, LUA_REGISTRYINDEX, DFHACK_IS_INSTANCE_NAME); - lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_TYPETABLE_NAME); + lua_rawgetp(state, LUA_REGISTRYINDEX, &DFHACK_TYPETABLE_TOKEN); lua_pushcclosure(state, meta_delete, 1); lua_setfield(state, LUA_REGISTRYINDEX, DFHACK_DELETE_NAME); @@ -1353,11 +1353,29 @@ static int DoAttach(lua_State *state) */ void LuaWrapper::AttachDFGlobals(lua_State *state) { - if (luaL_newmetatable(state, DFHACK_TYPETABLE_NAME)) + lua_rawgetp(state, LUA_REGISTRYINDEX, &DFHACK_TYPETABLE_TOKEN); + + if (lua_isnil(state, -1)) { + lua_pop(state, 1); + lua_newtable(state); + lua_dup(state); + lua_rawsetp(state, LUA_REGISTRYINDEX, &DFHACK_TYPETABLE_TOKEN); + luaL_requiref(state, "df", DoAttach, 1); lua_pop(state, 1); } lua_pop(state, 1); } + +namespace DFHack { namespace LuaWrapper { + struct LuaToken { int reserved; }; + + LuaToken DFHACK_IDENTITY_FIELD_TOKEN; + LuaToken DFHACK_TYPETABLE_TOKEN; + LuaToken DFHACK_TYPEID_TABLE_TOKEN; + LuaToken DFHACK_ENUM_TABLE_TOKEN; + LuaToken DFHACK_PTR_IDTABLE_TOKEN; + LuaToken DFHACK_EMPTY_TABLE_TOKEN; +}} diff --git a/library/include/LuaWrapper.h b/library/include/LuaWrapper.h index 9cd7b5018..72aa0e12e 100644 --- a/library/include/LuaWrapper.h +++ b/library/include/LuaWrapper.h @@ -39,26 +39,32 @@ distribution. */ namespace DFHack { namespace LuaWrapper { + struct LuaToken; -/* - * Registry name: hash of type metatables <-> type identities. - */ -#define DFHACK_TYPETABLE_NAME "DFHack::DFTypes" + /** + * Metatable pkey: type identity of the object + */ + extern LuaToken DFHACK_IDENTITY_FIELD_TOKEN; -/* - * Registry name: hash of type identity -> node in df.etc... - */ -#define DFHACK_TYPEID_TABLE_NAME "DFHack::DFTypeIds" + /** + * Registry pkey: hash of type metatables <-> type identities. + */ + extern LuaToken DFHACK_TYPETABLE_TOKEN; -/* - * Registry name: hash of enum/bitfield identity -> index lookup table - */ -#define DFHACK_ENUM_TABLE_NAME "DFHack::DFEnums" + /** + * Registry pkey: hash of type identity -> node in df.etc... + */ + extern LuaToken DFHACK_TYPEID_TABLE_TOKEN; -/* - * Registry name: hash of pointer target identity <-> adhoc pointer identity userdata. - */ -#define DFHACK_PTR_IDTABLE_NAME "DFHack::PtrDFTypes" + /** + * Registry pkey: hash of enum/bitfield identity -> index lookup table + */ + extern LuaToken DFHACK_ENUM_TABLE_TOKEN; + + /** + * Registry pkey: hash of pointer target identity <-> adhoc pointer identity userdata. + */ + extern LuaToken DFHACK_PTR_IDTABLE_TOKEN; // Function registry names #define DFHACK_CHANGEERROR_NAME "DFHack::ChangeError" @@ -70,7 +76,8 @@ namespace DFHack { namespace LuaWrapper { #define DFHACK_ASSIGN_NAME "DFHack::Assign" #define DFHACK_IS_INSTANCE_NAME "DFHack::IsInstance" #define DFHACK_DELETE_NAME "DFHack::Delete" -#define DFHACK_EMPTY_TABLE_NAME "DFHack::EmptyTable" + + extern LuaToken DFHACK_EMPTY_TABLE_TOKEN; /* * Upvalue: contents of DFHACK_TYPETABLE_NAME @@ -158,8 +165,8 @@ namespace DFHack { namespace LuaWrapper { const char *ctx, bool allow_type = false, bool keep_metatable = false); - void LookupInTable(lua_State *state, void *id, const char *tname); - void SaveInTable(lua_State *state, void *node, const char *tname); + void LookupInTable(lua_State *state, void *id, LuaToken *tname); + void SaveInTable(lua_State *state, void *node, LuaToken *tname); void SaveTypeInfo(lua_State *state, void *node); void AssociateId(lua_State *state, int table, int val, const char *name);