Skip to content

Commit 71def45

Browse files
authored
Add support for lua.getHook(), lua.getHookMask(), lua.getHookCount(); fix example project (#10)
1 parent 6dfe267 commit 71def45

File tree

4 files changed

+109
-9
lines changed

4 files changed

+109
-9
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ you.
8787
|-----------------------------|---------------------------------------|
8888
| Lua C API (`lua_*`) | 🎉 100% coverage<sup>†</sup> (92/92) |
8989
| Auxilary Library (`luaL_*`) | 🤩 100% coverage (48/48) |
90-
| Debug API (`lua_Debug`) | 32% coverage (4/12) |
90+
| Debug API (`lua_Debug`) | 56% coverage (7/12) |
9191
| LuaJIT Extensions | *No plans to implement.* |
9292

9393
*†: Coroutine yield/resume is not yet part of the public `zig-luajit` Zig API, see [#6][ISSUE-6].*
@@ -279,9 +279,9 @@ This section describes the current status of Zig language bindings ("the Zig API
279279
| C API Symbol | Available in `zig-luajit` |
280280
|----------------------------|-------------------------------------|
281281
| `lua_getinfo` | ☑️ `lua.getInfo()` |
282-
| `lua_gethookcount` ||
283-
| `lua_gethookmask` ||
284-
| `lua_gethook` ||
282+
| `lua_gethookcount` | ☑️ `lua.getHookCount()` |
283+
| `lua_gethookmask` | ☑️ `lua.getHookMask()` |
284+
| `lua_gethook` | ☑️ `lua.getHook()` |
285285
| `lua_getlocal` ||
286286
| `lua_getstack` | ☑️ `lua.getStack()` |
287287
| `lua_getupvalue` ||

examples/simple-repl/build.zig.zon

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
.version = "0.0.0",
44
.dependencies = .{
55
.luajit = .{
6-
.url = "git+https://github.com/sackosoft/zig-luajit#acadbe23b91afc429eb8a39ffbf8db0845dcc4e4",
7-
.hash = "12202f16fd460b199280f3c6191002c3c69843bf388622da671fbd16f3fcc5d045e4",
6+
.path = "../.."
87
},
98
},
109
.paths = .{

examples/simple-repl/main.zig

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,21 @@ pub fn main() !void {
1717
const stdin = std.io.getStdIn();
1818
const stdout = std.io.getStdOut();
1919

20-
var buf: [1024]u8 = undefined;
20+
var buf: [1025]u8 = undefined;
21+
const read_slice = buf[0..1024];
2122

2223
while (true) {
2324
try stdout.writeAll("> ");
2425

25-
const input = try stdin.reader().readUntilDelimiter(&buf, '\n');
26+
const input = try stdin.reader().readUntilDelimiter(read_slice, '\n');
2627
if (input.len == 0) continue;
2728

2829
if (std.mem.eql(u8, input, "exit")) break;
2930

30-
lua.doString(input) catch |err| {
31+
buf[input.len] = 0;
32+
const actual = buf[0..input.len :0];
33+
34+
lua.doString(actual) catch |err| {
3135
std.debug.print("Error: {}\n", .{err});
3236
continue;
3337
};

src/root.zig

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2939,6 +2939,8 @@ pub const Lua = opaque {
29392939
pub const HookMask = packed struct(u32) {
29402940
/// Used as the `mask` parameter to `setHook()` in order to disable a hook.
29412941
pub const disabled: HookMask = .{};
2942+
pub const call_only: HookMask = .{ .on_call = true };
2943+
pub const call_and_return: HookMask = .{ .on_call = true, .on_return = true };
29422944

29432945
/// Indicates that the hook function should be invoked when the Lua runtime calls a function.
29442946
on_call: bool = false,
@@ -2984,9 +2986,37 @@ pub const Lua = opaque {
29842986
/// Refer to: https://www.lua.org/manual/5.1/manual.html#lua_sethook
29852987
/// Stack Behavior: `[-0, +0, -]`
29862988
pub fn setHook(lua: *Lua, f: HookFunction, mask: HookMask, count: i32) void {
2989+
assert(count >= 0);
29872990
const res = c.lua_sethook(asState(lua), @ptrCast(f), @bitCast(mask), count);
29882991
assert(1 == res);
29892992
}
2993+
2994+
/// Returns the current hook function.
2995+
///
2996+
/// From: `lua_Hook lua_gethook(lua_State *L);`
2997+
/// Refer to: https://www.lua.org/manual/5.1/manual.html#lua_gethook
2998+
/// Stack Behavior: `[-0, +0, -]`
2999+
pub fn getHook(lua: *Lua) ?HookFunction {
3000+
return @ptrCast(c.lua_gethook(asState(lua)));
3001+
}
3002+
3003+
/// Returns the current hook count.
3004+
///
3005+
/// From: `int lua_gethookcount(lua_State *L);`
3006+
/// Refer to: https://www.lua.org/manual/5.1/manual.html#lua_gethookcount
3007+
/// Stack Behavior: `[-0, +0, -]`
3008+
pub fn getHookCount(lua: *Lua) i32 {
3009+
return c.lua_gethookcount(asState(lua));
3010+
}
3011+
3012+
/// Returns the current hook mask.
3013+
///
3014+
/// From: `int lua_gethookmask(lua_State *L);`
3015+
/// Refer to: https://www.lua.org/manual/5.1/manual.html#lua_gethookmask
3016+
/// Stack Behavior: `[-0, +0, -]`
3017+
pub fn getHookMask(lua: *Lua) HookMask {
3018+
return @bitCast(c.lua_gethookmask(asState(lua)));
3019+
}
29903020
};
29913021

29923022
test "Lua can be initialized with an allocator" {
@@ -5658,3 +5688,70 @@ test "setHook() can be used register a callback to intercept function calls" {
56585688
try std.testing.expect(lua.isInteger(-1));
56595689
try std.testing.expectEqual(1, try lua.toIntegerStrict(-1));
56605690
}
5691+
5692+
test "getHook() can be used check the current hook function" {
5693+
const lua = try Lua.init(std.testing.allocator);
5694+
defer lua.deinit();
5695+
5696+
const T = struct {
5697+
fn hook(l: *Lua, info: *Lua.DebugInfo) callconv(.c) void {
5698+
_ = l;
5699+
_ = info;
5700+
}
5701+
};
5702+
5703+
lua.setHook(T.hook, .{ .on_call = true }, 0);
5704+
try std.testing.expectEqual(T.hook, lua.getHook());
5705+
}
5706+
5707+
test "getHookMask() can be used check the current hook function subscription" {
5708+
const lua = try Lua.init(std.testing.allocator);
5709+
defer lua.deinit();
5710+
5711+
const T = struct {
5712+
fn hook(l: *Lua, info: *Lua.DebugInfo) callconv(.c) void {
5713+
_ = l;
5714+
_ = info;
5715+
}
5716+
};
5717+
5718+
const e1 = Lua.HookMask{};
5719+
lua.setHook(T.hook, e1, 0);
5720+
try std.testing.expectEqual(e1, lua.getHookMask());
5721+
5722+
const e2 = Lua.HookMask{ .on_call = true };
5723+
lua.setHook(T.hook, e2, 0);
5724+
try std.testing.expectEqual(e2, lua.getHookMask());
5725+
5726+
const e3 = Lua.HookMask{ .on_call = true, .on_return = true };
5727+
lua.setHook(T.hook, e3, 0);
5728+
try std.testing.expectEqual(e3, lua.getHookMask());
5729+
5730+
const e4 = Lua.HookMask{ .on_line = true };
5731+
lua.setHook(T.hook, e4, 0);
5732+
try std.testing.expectEqual(e4, lua.getHookMask());
5733+
5734+
const e5 = Lua.HookMask{ .on_call = true, .on_return = true, .on_line = true, .on_count = true };
5735+
lua.setHook(T.hook, e5, 0);
5736+
try std.testing.expectEqual(e5, lua.getHookMask());
5737+
}
5738+
5739+
test "getHookCount() can be used check the current hook function count" {
5740+
const lua = try Lua.init(std.testing.allocator);
5741+
defer lua.deinit();
5742+
5743+
const T = struct {
5744+
fn hook(l: *Lua, info: *Lua.DebugInfo) callconv(.c) void {
5745+
_ = l;
5746+
_ = info;
5747+
}
5748+
};
5749+
5750+
const e1 = 0;
5751+
lua.setHook(T.hook, Lua.HookMask.call_and_return, 0);
5752+
try std.testing.expectEqual(e1, lua.getHookCount());
5753+
5754+
const e2 = 42;
5755+
lua.setHook(T.hook, Lua.HookMask.call_and_return, 42);
5756+
try std.testing.expectEqual(e2, lua.getHookCount());
5757+
}

0 commit comments

Comments
 (0)