Skip to content

Commit 837048b

Browse files
committedFeb 18, 2023
feat: add registerFns to 5.1 api
This is for the luaL_register function
1 parent b6dec0d commit 837048b

File tree

2 files changed

+50
-21
lines changed

2 files changed

+50
-21
lines changed
 

‎src/ziglua-5.1/lib.zig

+20-21
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ pub const Event = enum(u3) {
106106
/// Type for arrays of functions to be registered
107107
pub const FnReg = struct {
108108
name: [:0]const u8,
109-
func: ?CFn,
109+
func: CFn,
110110
};
111111

112112
/// The index of the global environment table
@@ -1407,28 +1407,27 @@ pub const Lua = struct {
14071407
}
14081408

14091409
/// Opens a library
1410-
/// TODO: finish this function
1411-
// pub fn registerFns(lua: *Lua, libname: ?[:0]const u8, funcs: []const FnReg) void {
1412-
// if (libname) |name| {
1413-
// lua.findTable
1414-
// }
1415-
1416-
// }
1417-
1418-
/// Registers all functions in the array `fns` into the table on the top of the stack
1419-
/// All functions are created with `num_upvalues` upvalues
1420-
pub fn setFuncs(lua: *Lua, funcs: []const FnReg, num_upvalues: i32) void {
1421-
lua.checkStackAux(num_upvalues, "too many upvalues");
1410+
pub fn registerFns(lua: *Lua, libname: ?[:0]const u8, funcs: []const FnReg) void {
1411+
// translated from the implementation of luaI_openlib so we can use a slice of
1412+
// FnReg without requiring a sentinel end value
1413+
if (libname) |name| {
1414+
_ = c.luaL_findtable(lua.state, registry_index, "_LOADED", 1);
1415+
lua.getField(-1, name);
1416+
if (!lua.isTable(-1)) {
1417+
lua.pop(1);
1418+
if (c.luaL_findtable(lua.state, globals_index, name, @intCast(c_int, funcs.len))) |_| {
1419+
lua.raiseErrorAux("name conflict for module " ++ c.LUA_QS, .{name.ptr});
1420+
}
1421+
lua.pushValue(-1);
1422+
lua.setField(-3, name);
1423+
}
1424+
lua.remove(-2);
1425+
lua.insert(-1);
1426+
}
14221427
for (funcs) |f| {
1423-
if (f.func) |func| {
1424-
var i: i32 = 0;
1425-
// copy upvalues to the top
1426-
while (i < num_upvalues) : (i += 1) lua.pushValue(-num_upvalues);
1427-
lua.pushClosure(func, num_upvalues);
1428-
} else lua.pushBoolean(false); // register a placeholder
1429-
lua.setField(-(num_upvalues + 2), f.name);
1428+
lua.pushFunction(f.func);
1429+
lua.setField(-2, f.name);
14301430
}
1431-
lua.pop(num_upvalues);
14321431
}
14331432

14341433
/// Raises a type error for the argument `arg` of the C function

‎src/ziglua-5.1/tests.zig

+30
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,36 @@ test "string buffers" {
395395
lua.pop(1);
396396
}
397397

398+
test "function registration" {
399+
var lua = try Lua.init(testing.allocator);
400+
defer lua.deinit();
401+
402+
// register all functions as part of a table
403+
const funcs = [_]ziglua.FnReg{
404+
.{ .name = "add", .func = ziglua.wrap(add) },
405+
};
406+
lua.newTable();
407+
lua.registerFns(null, &funcs);
408+
409+
lua.getField(-1, "add");
410+
lua.pushInteger(1);
411+
lua.pushInteger(2);
412+
try lua.protectedCall(2, 1, 0);
413+
try expectEqual(@as(Integer, 3), lua.toInteger(-1));
414+
lua.setTop(0);
415+
416+
// register functions as globals in a library table
417+
lua.registerFns("testlib", &funcs);
418+
419+
// testlib.add(1, 2)
420+
lua.getGlobal("testlib");
421+
lua.getField(-1, "add");
422+
lua.pushInteger(1);
423+
lua.pushInteger(2);
424+
try lua.protectedCall(2, 1, 0);
425+
try expectEqual(@as(Integer, 3), lua.toInteger(-1));
426+
}
427+
398428
test "panic fn" {
399429
var lua = try Lua.init(testing.allocator);
400430
defer lua.deinit();

0 commit comments

Comments
 (0)