diff --git a/library/LuaTypes.cpp b/library/LuaTypes.cpp index 306538f51..4e90265ce 100644 --- a/library/LuaTypes.cpp +++ b/library/LuaTypes.cpp @@ -536,6 +536,7 @@ static void field_reference(lua_State *state, const struct_field_info *field, vo case struct_field_info::PRIMITIVE: case struct_field_info::SUBSTRUCT: push_object_internal(state, field->type, ptr); + get_object_ref_header(state, -1)->field_info = field; return; case struct_field_info::POINTER: @@ -706,6 +707,16 @@ static type_identity *find_primitive_field(lua_State *state, int field, const ch */ static int meta_primitive_index(lua_State *state) { + const char *attr = lua_tostring(state, -1); + if (attr == std::string("ref_target")) { + const struct_field_info *field_info = get_object_ref_header(state, 1)->field_info; + if (field_info && field_info->extra && field_info->extra->ref_target) { + LookupInTable(state, field_info->extra->ref_target, &DFHACK_TYPEID_TABLE_TOKEN); + } else { + lua_pushnil(state); + } + return 1; + } uint8_t *ptr = get_object_addr(state, 1, 2, "read"); auto type = find_primitive_field(state, 2, "read", &ptr); if (!type) diff --git a/library/LuaWrapper.cpp b/library/LuaWrapper.cpp index 497addd5c..05c4db789 100644 --- a/library/LuaWrapper.cpp +++ b/library/LuaWrapper.cpp @@ -170,18 +170,24 @@ void LuaWrapper::push_object_ref(lua_State *state, void *ptr) // stack: [metatable] auto ref = (DFRefHeader*)lua_newuserdata(state, sizeof(DFRefHeader)); ref->ptr = ptr; + ref->field_info = NULL; lua_swap(state); lua_setmetatable(state, -2); // stack: [userdata] } -void *LuaWrapper::get_object_ref(lua_State *state, int val_index) +DFRefHeader *LuaWrapper::get_object_ref_header(lua_State *state, int val_index) { assert(!lua_islightuserdata(state, val_index)); auto ref = (DFRefHeader*)lua_touserdata(state, val_index); - return ref->ptr; + return ref; +} + +void *LuaWrapper::get_object_ref(lua_State *state, int val_index) +{ + return get_object_ref_header(state, val_index)->ptr; } /** diff --git a/library/include/LuaWrapper.h b/library/include/LuaWrapper.h index 4cbf9d34f..b23e1f912 100644 --- a/library/include/LuaWrapper.h +++ b/library/include/LuaWrapper.h @@ -126,6 +126,7 @@ namespace LuaWrapper { */ struct DFRefHeader { void *ptr; + const struct_field_info *field_info; }; /** @@ -133,15 +134,7 @@ namespace LuaWrapper { */ void push_object_ref(lua_State *state, void *ptr); DFHACK_EXPORT void *get_object_ref(lua_State *state, int val_index); - - /* - * The system might be extended to carry some simple - * objects inline inside the reference buffer. - */ - inline bool is_self_contained(DFRefHeader *ptr) { - void **pp = &ptr->ptr; - return **(void****)pp == (pp + 1); - } + DFHACK_EXPORT DFRefHeader *get_object_ref_header(lua_State *state, int val_index); /** * Report an error while accessing a field (index = field name).