Skip to content

Commit 5798813

Browse files
committed
Add support for lua.atPanic()
1 parent 6204de1 commit 5798813

File tree

3 files changed

+35
-14
lines changed

3 files changed

+35
-14
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ lua.doString(
7878

7979
| API | Support |
8080
|---|---|
81-
| Lua C API (`lua_*`) | 58% available (54/92) | <!-- 58.69% - Add 1.07 per -->
81+
| Lua C API (`lua_*`) | 58% available (55/92) | <!-- 59.76% - Add 1.07 per -->
8282
| Auxilary Library (`luaL_*`) | 6% available (3/48) | <!-- Always 2% * n, for n up to 48 -->
8383
| LuaJIT Extensions | *No plans to implement.* |
8484

@@ -106,7 +106,7 @@ pattern has changed, such as using the Zig `init()` function pattern instead of
106106

107107
| C API Symbols | Available in `zig-luajit` |
108108
|--------------|---------------------------|
109-
| `lua_atpanic`||
109+
| `lua_atpanic`| ☑️ `lua.atPanic()` |
110110
| `lua_call`| ☑️ `lua.call()` |
111111
| `lua_checkstack`| ☑️ `lua.checkStack()` |
112112
| `lua_close`| ☑️📢 `lua.deinit()` |

src/lua_api.zig

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,6 @@
44
// This file contains brainstorming and draft translations of the C API to Lua.
55

66

7-
/// Sets a new panic function and returns the old one. If an error happens outside any protected environment,
8-
/// Lua calls a panic function and then calls exit(EXIT_FAILURE), thus exiting the host application.
9-
/// Your panic function can avoid this exit by never returning (e.g., doing a long jump).
10-
/// The panic function can access the error message at the top of the stack.
11-
///
12-
/// From: `lua_CFunction lua_atpanic(lua_State *L, lua_CFunction panicf);`
13-
/// Refer to: https://www.lua.org/manual/5.1/manual.html#lua_atpanic
14-
/// Stack Behavior: `[-0, +0, -]`
15-
pub fn atPanic(lua: *Lua, panicf: CFunction) CFunction;
16-
177
/// Dumps a function as a binary chunk. Receives a Lua function on the top of the stack and produces a
188
/// binary chunk that, if loaded again, results in a function equivalent to the one dumped. As it produces
199
/// parts of the chunk, lua_dump calls function writer (see https://www.lua.org/manual/5.1/manual.html#lua_Writer)

src/root.zig

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,18 @@ pub const Lua = opaque {
9898
return if (lua) |p| p else error.OutOfMemory;
9999
}
100100

101+
/// Sets a new panic function and returns the old one. If an error happens outside any protected environment,
102+
/// Lua calls a panic function and then calls exit(EXIT_FAILURE), thus exiting the host application.
103+
/// Your panic function can avoid this exit by never returning (e.g., doing a long jump).
104+
/// The panic function can access the error message at the top of the stack.
105+
///
106+
/// From: `lua_CFunction lua_atpanic(lua_State *L, lua_CFunction panicf);`
107+
/// Refer to: https://www.lua.org/manual/5.1/manual.html#lua_atpanic
108+
/// Stack Behavior: `[-0, +0, -]`
109+
pub fn atPanic(lua: *Lua, f: ?CFunction) ?CFunction {
110+
return @ptrCast(c.lua_atpanic(asState(lua), @ptrCast(f)));
111+
}
112+
101113
/// Returns the memory-allocation function and user data configured in the given lua instance.
102114
/// If userdata is not null, Lua internally saves the user data pointer passed to `lua_newstate`.
103115
///
@@ -1120,8 +1132,8 @@ pub const Lua = opaque {
11201132
/// From: `int lua_cpcall(lua_State *L, lua_CFunction func, void *ud);`
11211133
/// Refer to: https://www.lua.org/manual/5.1/manual.html#lua_cpcall
11221134
/// Stack Behavior: `[-0, +(0|1), -]`
1123-
pub fn protectedCallCFunction(lua: *Lua, func: CFunction, ud: ?*anyopaque) ProtectedCallError!void {
1124-
const res = c.lua_cpcall(asState(lua), @ptrCast(func), ud);
1135+
pub fn protectedCallCFunction(lua: *Lua, f: CFunction, ud: ?*anyopaque) ProtectedCallError!void {
1136+
const res = c.lua_cpcall(asState(lua), @ptrCast(f), ud);
11251137
assert(Status.is_status(res)); // Expected the status to be one of the "thread status" values defined in lua.h
11261138

11271139
return parseCallStatus(res);
@@ -2062,3 +2074,22 @@ test "proctected call for c functions" {
20622074
try std.testing.expectError(Lua.CallError.Runtime, actual);
20632075
try std.testing.expectEqualSlices(u8, "EXPECTED ERROR 123", try lua.toLString(-1));
20642076
}
2077+
2078+
fn newPanicFunction(lua: *Lua) callconv(.c) i32 {
2079+
_ = lua;
2080+
return 0;
2081+
}
2082+
2083+
test "override error function with atpanic" {
2084+
const lua = try Lua.init(std.testing.allocator);
2085+
defer lua.deinit();
2086+
2087+
// This test case is actually kind of useless, I don't want to hack doing a long jump into these tests
2088+
// to avoid application exit. So we will just call the function and make sure the application doesn't
2089+
// crash. But it's not really testing that the panic function gets called in any way right now.
2090+
2091+
const actual = lua.atPanic(newPanicFunction);
2092+
try std.testing.expect(actual == null);
2093+
const new = lua.atPanic(actual);
2094+
try std.testing.expect(new.? == newPanicFunction);
2095+
}

0 commit comments

Comments
 (0)