summaryrefslogtreecommitdiff
path: root/src/lua_runtime.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/lua_runtime.zig')
-rw-r--r--src/lua_runtime.zig19
1 files changed, 15 insertions, 4 deletions
diff --git a/src/lua_runtime.zig b/src/lua_runtime.zig
index 797b97b..e26d017 100644
--- a/src/lua_runtime.zig
+++ b/src/lua_runtime.zig
@@ -263,7 +263,7 @@ pub const LuaRuntime = struct {
// so its return value naturally lands above it; calling pcall then
// consumes both in the right order.
const L = self.L;
- _ = c.lua_getglobal(L, "panto");
+ lua_bridge.pushPantoTable(L);
_ = c.lua_getfield(L, -1, "ext");
_ = c.lua_getfield(L, -1, "register_tool");
// Stack: ..., panto, ext, register_tool. Collapse to just
@@ -974,7 +974,7 @@ fn invokeCoroutineSync(
/// stores into the matching slot.
fn installRecordResult(self: *LuaRuntime) !void {
const L = self.L;
- _ = c.lua_getglobal(L, "panto");
+ lua_bridge.pushPantoTable(L);
if (c.lua_type(L, -1) != lua_bridge.T_TABLE) {
c.lua_settop(L, c.lua_gettop(L) - 1);
return RuntimeError.LuaInitFailed;
@@ -1038,7 +1038,10 @@ fn recordResultC(L: ?*c.lua_State) callconv(.c) c_int {
/// Stored in the Lua registry under `self.wrapper_ref`.
fn installWrapperClosure(self: *LuaRuntime) !void {
const L = self.L;
+ // `panto` is not a global, so the wrapper closes over the table
+ // (passed as an argument) rather than looking it up globally.
const snippet =
+ \\local panto = ...
\\return function(idx, handler, input)
\\ local ok, val = pcall(handler, input)
\\ panto._record_result(idx, ok, val)
@@ -1049,7 +1052,9 @@ fn installWrapperClosure(self: *LuaRuntime) !void {
c.lua_settop(L, c.lua_gettop(L) - 1);
return RuntimeError.LuaInitFailed;
}
- if (c.lua_pcallk(L, 0, 1, 0, 0, null) != 0) {
+ // Pass the `panto` table as the chunk's vararg argument.
+ lua_bridge.pushPantoTable(L);
+ if (c.lua_pcallk(L, 1, 1, 0, 0, null) != 0) {
logTopAsError(L, "panto-lua: wrapper closure failed to evaluate");
c.lua_settop(L, c.lua_gettop(L) - 1);
return RuntimeError.LuaInitFailed;
@@ -1153,7 +1158,12 @@ fn freeResults(results: []panto.ToolCallResult) void {
}
fn writeTempScript(dir: Io.Dir, name: []const u8, source: []const u8) ![]const u8 {
- try dir.writeFile(testing.io, .{ .sub_path = name, .data = source });
+ // `panto` is not a global; extensions reach it via `require('panto')`.
+ // Prepend the require so these tests exercise the real preload path
+ // without each script repeating the boilerplate.
+ var src_buf: [16384]u8 = undefined;
+ const data = try std.fmt.bufPrint(&src_buf, "local panto = require(\"panto\")\n{s}", .{source});
+ try dir.writeFile(testing.io, .{ .sub_path = name, .data = data });
var buf: [std.fs.max_path_bytes]u8 = undefined;
const n = try dir.realPathFile(testing.io, name, &buf);
return testing.allocator.dupe(u8, buf[0..n]);
@@ -1428,6 +1438,7 @@ test "directory-style extension can require sibling modules" {
try tmp.dir.writeFile(testing.io, .{
.sub_path = "ext/init.lua",
.data =
+ \\local panto = require("panto")
\\local util = require("util")
\\panto.ext.register_tool {
\\ name = "shout", description = "uppercase + bang",