From: Rebecca Kelly Date: Tue, 31 May 2022 23:09:52 +0000 (-0400) Subject: patch from ToxicFrog X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=78658e960902ba1e2e34d440523744b97c43451d;p=nethack patch from ToxicFrog --- diff --git a/src/nhlobj.c b/src/nhlobj.c index becdd4976..3cbc08fc1 100644 --- a/src/nhlobj.c +++ b/src/nhlobj.c @@ -608,30 +608,28 @@ static const luaL_Reg l_obj_meta[] = { int l_obj_register(lua_State *L) { - int lib_id, meta_id; - - /* newclass = {} */ - lua_createtable(L, 0, 0); - lib_id = lua_gettop(L); + /* Table of instance methods (e.g. an_object:isnull()) + and static methods (e.g. obj.new("dagger")). */ + luaL_newlib(L, l_obj_methods); - /* metatable = {} */ + /* metatable = { __name = "obj", __gc = l_obj_gc } */ luaL_newmetatable(L, "obj"); - meta_id = lua_gettop(L); luaL_setfuncs(L, l_obj_meta, 0); + /* metatable.__index points at the object method table. */ + lua_pushvalue(L, -2); + lua_setfield(L, -2, "__index"); - /* metatable.__index = _methods */ - luaL_newlib(L, l_obj_methods); - lua_setfield(L, meta_id, "__index"); - - /* metatable.__metatable = _meta */ + /* Don't let lua code mess with the real metatable. + Instead offer a fake one that only contains __gc. */ luaL_newlib(L, l_obj_meta); - lua_setfield(L, meta_id, "__metatable"); + lua_setfield(L, -2, "__metatable"); - /* class.__metatable = metatable */ - lua_setmetatable(L, lib_id); + /* We don't need the metatable anymore. It's safe in the + Lua registry for use by luaL_setmetatable. */ + lua_pop(L, 1); - /* _G["obj"] = newclass */ + /* global obj = the method table we created at the start */ lua_setglobal(L, "obj"); - return 0; } + diff --git a/src/nhlsel.c b/src/nhlsel.c index 48bd6b2e5..db8463643 100644 --- a/src/nhlsel.c +++ b/src/nhlsel.c @@ -874,29 +874,27 @@ static const luaL_Reg l_selection_meta[] = { int l_selection_register(lua_State *L) { - int lib_id, meta_id; - - /* newclass = {} */ - lua_createtable(L, 0, 0); - lib_id = lua_gettop(L); + /* Table of instance methods and static methods. */ + luaL_newlib(L, l_selection_methods); - /* metatable = {} */ + /* metatable = { __name = "selection", __gc = l_selection_gc } */ luaL_newmetatable(L, "selection"); - meta_id = lua_gettop(L); luaL_setfuncs(L, l_selection_meta, 0); - /* metatable.__index = _methods */ - luaL_newlib(L, l_selection_methods); - lua_setfield(L, meta_id, "__index"); + /* metatable.__index points at the selection method table. */ + lua_pushvalue(L, -2); + lua_setfield(L, -2, "__index"); - /* metatable.__metatable = _meta */ + /* Don't let lua code mess with the real metatable. + Instead offer a fake one that only contains __gc. */ luaL_newlib(L, l_selection_meta); - lua_setfield(L, meta_id, "__metatable"); + lua_setfield(L, -2, "__metatable"); - /* class.__metatable = metatable */ - lua_setmetatable(L, lib_id); + /* We don't need the metatable anymore. It's safe in the + Lua registry for use by luaL_setmetatable. */ + lua_pop(L, 1); - /* _G["selection"] = newclass */ + /* global selection = the method table we created at the start */ lua_setglobal(L, "selection"); return 0;