Skip to content

Commit 53bf07d

Browse files
committed
Add tests and promote lua.checkUserdata() to stable API
1 parent d92b49f commit 53bf07d

File tree

2 files changed

+54
-3
lines changed

2 files changed

+54
-3
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ The `zig-luajit` project has not yet reached the 1.0 release, the API is subject
243243
| `luaL_checkstack` | ☑️📢 `lua.checkStackOrError()` |
244244
| `luaL_checkstring` | ☑️ `lua.checkString()` |
245245
| `luaL_checktype` | ☑️ `lua.checkType()` |
246-
| `luaL_checkudata` | `lua.checkUserdata()`|
246+
| `luaL_checkudata` | ☑️ `lua.checkUserdata()`|
247247
| `luaL_dofile` | ☑️ `lua.doFile()` |
248248
| `luaL_dostring` | ☑️ `lua.doString()` |
249249
| `luaL_error` | ☑️📢 `lua.raiseErrorFormat()` |

src/root.zig

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1184,7 +1184,7 @@ pub const Lua = opaque {
11841184
/// Stack Behavior: `[-1, +0, -]`
11851185
pub fn setMetatable(lua: *Lua, index: i32) void {
11861186
lua.validateStackIndex(index);
1187-
assert(lua.isTable(index));
1187+
assert(lua.isTable(-1));
11881188

11891189
const res = c.lua_setmetatable(asState(lua), index);
11901190
assert(1 == res);
@@ -2289,7 +2289,7 @@ pub const Lua = opaque {
22892289
/// Refer to: https://www.lua.org/manual/5.1/manual.html#luaL_checkudata
22902290
/// Stack Behavior: `[-0, +0, v]`
22912291
pub fn checkUserdata(lua: *Lua, arg_n: i32, type_name: [:0]const u8) ?*anyopaque {
2292-
return c.luaL_checkudata(asState(lua), arg_n, @ptrCast(type_name.ptr));
2292+
return c.luaL_checkudata(asState(lua), arg_n, type_name.ptr);
22932293
}
22942294

22952295
/// Used by C functions to validate received arguments.
@@ -4438,6 +4438,57 @@ test "checkArgument() should return error when argument is invalid and succeed w
44384438
try std.testing.expectEqualSlices(u8, "bad argument #1 to '?' (FOOBAR)", message);
44394439
}
44404440

4441+
test "checkUserdata() will accept user data with the correct metatable type" {
4442+
const lua = try Lua.init(std.testing.allocator);
4443+
defer lua.deinit();
4444+
4445+
const T = struct {
4446+
fn EchoUserdata(l: *Lua) callconv(.c) i32 {
4447+
const val = l.checkUserdata(1, "MyUserdataType");
4448+
l.pushLightUserdata(val);
4449+
return 1;
4450+
}
4451+
};
4452+
4453+
lua.pushCFunction(T.EchoUserdata);
4454+
4455+
const expected = lua.newUserdata(32);
4456+
try std.testing.expect(lua.newMetatable("MyUserdataType"));
4457+
lua.setMetatable(-2);
4458+
try std.testing.expectEqual(2, lua.getTop());
4459+
try std.testing.expect(lua.isFunction(1));
4460+
try std.testing.expect(lua.isUserdata(2));
4461+
4462+
try lua.callProtected(1, 1, 0);
4463+
4464+
try std.testing.expectEqual(1, lua.getTop());
4465+
try std.testing.expect(lua.isUserdata(-1));
4466+
try std.testing.expectEqual(expected, lua.toUserdata(-1));
4467+
}
4468+
4469+
test "checkUserdata() will reject user data with the wrong metatable type" {
4470+
const lua = try Lua.init(std.testing.allocator);
4471+
defer lua.deinit();
4472+
4473+
const T = struct {
4474+
fn EchoUserdata(l: *Lua) callconv(.c) i32 {
4475+
const val = l.checkUserdata(1, "MyUserdataType");
4476+
l.pushLightUserdata(val);
4477+
return 1;
4478+
}
4479+
};
4480+
4481+
lua.pushCFunction(T.EchoUserdata);
4482+
4483+
_ = lua.newUserdata(32);
4484+
try std.testing.expectEqual(2, lua.getTop());
4485+
try std.testing.expect(lua.isFunction(1));
4486+
try std.testing.expect(lua.isUserdata(2));
4487+
4488+
try std.testing.expectError(error.Runtime, lua.callProtected(1, 1, 0));
4489+
try std.testing.expectEqualStrings("bad argument #1 to '?' (MyUserdataType expected, got userdata)", try lua.toLString(-1));
4490+
}
4491+
44414492
test "checkArgument() should return handle null message" {
44424493
const lua = try Lua.init(std.testing.allocator);
44434494
defer lua.deinit();

0 commit comments

Comments
 (0)