@@ -1115,19 +1115,6 @@ pub const Lua = opaque {
11151115 return c .lua_rawseti (asState (lua ), index , n );
11161116 }
11171117
1118- /// Pushes onto the stack the metatable of the value at the given acceptable index. If the index is not
1119- /// valid, or if the value does not have a metatable, the function returns `false` and pushes nothing on
1120- /// the stack.
1121- ///
1122- /// From: `int lua_getmetatable(lua_State *L, int index);`
1123- /// Refer to: https://www.lua.org/manual/5.1/manual.html#lua_getmetatable
1124- /// Stack Behavior: `[-0, +(0|1), -]`
1125- pub fn getMetatable (lua : * Lua , index : i32 ) bool {
1126- lua .validateStackIndex (index );
1127-
1128- return 1 == c .lua_getmetatable (asState (lua ), index );
1129- }
1130-
11311118 /// Pushes onto the stack the value `t[k]`, where `t` is the value at the given valid index. As in Lua, this function
11321119 /// may trigger a metamethod for the "index" event (see https://www.lua.org/manual/5.1/manual.html#2.8).
11331120 ///
@@ -1142,7 +1129,7 @@ pub const Lua = opaque {
11421129 return lua .getType (-1 );
11431130 }
11441131
1145- /// Does the equivalent to `t[k ] = v`, where `t` is the value at the given valid index and `v` is the value at the
1132+ /// Does the equivalent to `t[key ] = v`, where `t` is the value at the given valid index and `v` is the value at the
11461133 /// top of the stack. This function pops the value from the stack. As in Lua, this function may trigger a
11471134 /// metamethod for the "newindex" event (see https://www.lua.org/manual/5.1/manual.html#2.8).
11481135 ///
@@ -1176,6 +1163,19 @@ pub const Lua = opaque {
11761163
11771164 return c .lua_setglobal (asState (lua ), asCString (name ));
11781165 }
1166+
1167+ /// Creates a new table to be used as a metatable for userdata, adds it to the registry with key `tname`, and
1168+ /// returns `true`. If the registry already has the key `tname`, returns `false` instead.
1169+ ///
1170+ /// In both cases, pushes onto the stack the final value associated with `tname` in the registry.
1171+ ///
1172+ /// From: `int luaL_newmetatable(lua_State *L, const char *tname);`
1173+ /// Refer to: https://www.lua.org/manual/5.1/manual.html#luaL_newmetatable
1174+ /// Stack Behavior: `[-0, +1, m]`
1175+ pub fn newMetatable (lua : * Lua , tname : [:0 ]const u8 ) bool {
1176+ return 1 == c .luaL_newmetatable (asState (lua ), tname .ptr );
1177+ }
1178+
11791179 /// Pops a table from the top of the stack and sets it as the metatable for the value at the
11801180 /// given acceptable index.
11811181 ///
@@ -1190,6 +1190,43 @@ pub const Lua = opaque {
11901190 assert (1 == res );
11911191 }
11921192
1193+ /// Pushes onto the stack the metatable of the value at the given acceptable index. If the index is not
1194+ /// valid, or if the value does not have a metatable, the function returns `false` and pushes nothing on
1195+ /// the stack.
1196+ ///
1197+ /// From: `int lua_getmetatable(lua_State *L, int index);`
1198+ /// Refer to: https://www.lua.org/manual/5.1/manual.html#lua_getmetatable
1199+ /// Stack Behavior: `[-0, +(0|1), -]`
1200+ pub fn getMetatable (lua : * Lua , index : i32 ) bool {
1201+ lua .validateStackIndex (index );
1202+
1203+ return 1 == c .lua_getmetatable (asState (lua ), index );
1204+ }
1205+
1206+ /// Pushes onto the stack the metatable associated with name `name` in the registry.
1207+ ///
1208+ /// Useful in combination with `newMetatable()`.
1209+ ///
1210+ /// From: `void luaL_getmetatable(lua_State *L, const char *tname);`
1211+ /// Refer to: https://www.lua.org/manual/5.1/manual.html#luaL_getmetatable
1212+ /// Stack Behavior: `[-0, +1, -]`
1213+ pub fn getMetatableRegistry (lua : * Lua , name : [:0 ]const u8 ) void {
1214+ return c .luaL_getmetatable (asState (lua ), name .ptr );
1215+ }
1216+
1217+ /// Pushes onto the stack the field `field_name` from the metatable of the object at index `index`. Returns `true`
1218+ /// when the metatable exists and the requested field has been pushed on the stack. Otherwise, if the object does
1219+ /// not have a metatable, or if the metatable does not have this field, returns `false` and pushes nothing.
1220+ ///
1221+ /// From: `int luaL_getmetafield(lua_State *L, int obj, const char *e);`
1222+ /// Refer to: https://www.lua.org/manual/5.1/manual.html#luaL_getmetafield
1223+ /// Stack Behavior: `[-0, +(0|1), m]`
1224+ pub fn getMetaField (lua : * Lua , index : i32 , field_name : [:0 ]const u8 ) bool {
1225+ lua .validateStackIndex (index );
1226+
1227+ return 1 == c .luaL_getmetafield (asState (lua ), index , field_name .ptr );
1228+ }
1229+
11931230 /// Creates a new execution context within the given Lua instance, pushes it on the stack, and returns a `*Lua` pointer
11941231 /// that represents this new thread. Do not confuse Lua threads with operating-system threads. Lua supports coroutines
11951232 /// on all systems, even those that do not support threads.
@@ -4269,3 +4306,30 @@ test "gsub" {
42694306 try std .testing .expectEqualStrings (expected , try lua .toLString (-1 ));
42704307 try std .testing .expectEqualStrings (expected , actual );
42714308}
4309+
4310+ test "metatables in the registry" {
4311+ const lua = try Lua .init (std .testing .allocator );
4312+ defer lua .deinit ();
4313+
4314+ try std .testing .expect (lua .newMetatable ("test" ));
4315+ lua .pushInteger (42 );
4316+ lua .setField (-2 , "bar" );
4317+ try std .testing .expect (! lua .newMetatable ("test" ));
4318+
4319+ try std .testing .expectEqual (2 , lua .getTop ());
4320+ try std .testing .expectEqual (lua .toPointer (-1 ), lua .toPointer (-2 ));
4321+ lua .pop (1 );
4322+
4323+ lua .getMetatableRegistry ("test" );
4324+ try std .testing .expectEqual (2 , lua .getTop ());
4325+ try std .testing .expectEqual (lua .toPointer (-1 ), lua .toPointer (-2 ));
4326+ lua .pop (1 );
4327+
4328+ lua .newTable ();
4329+ lua .insert (-2 );
4330+ lua .setMetatable (-2 );
4331+ try std .testing .expectEqual (1 , lua .getTop ());
4332+
4333+ try std .testing .expect (lua .getMetaField (-1 , "bar" ));
4334+ try std .testing .expectEqual (42 , try lua .toIntegerStrict (-1 ));
4335+ }
0 commit comments