]> granicus.if.org Git - nethack/commitdiff
patch from ToxicFrog
authorRebecca Kelly <bk@ancilla.ca>
Tue, 31 May 2022 23:09:52 +0000 (19:09 -0400)
committernhmall <nhmall@nethack.org>
Tue, 31 May 2022 23:09:52 +0000 (19:09 -0400)
src/nhlobj.c
src/nhlsel.c

index becdd497680143dea0ca7624e1562af928c11352..3cbc08fc1256e431ed62daeec4b086e525a46d1a 100644 (file)
@@ -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;
 }
+
index 48bd6b2e51a64f09200ad7edca7a2b92d2f3dff4..db8463643f7082e1897dca282526a1f967380781 100644 (file)
@@ -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;