|
|
|
@ -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;
|
|
|
|
|
}}
|
|
|
|
|