From f66984164a008b03eae732c48d05404275db644d Mon Sep 17 00:00:00 2001 From: Rafael Ristovski Date: Sat, 10 Dec 2022 17:02:51 +0100 Subject: [PATCH] Update to latest Zig master (`0.11.0-dev.863+4809e0ea7`) --- build.zig | 2 +- src/lua.zig | 67 +++++++++++++++++++++++++-------------------------- src/tests.zig | 42 ++++++++++++++++---------------- 3 files changed, 55 insertions(+), 56 deletions(-) diff --git a/build.zig b/build.zig index 456a6b4..601ff1f 100644 --- a/build.zig +++ b/build.zig @@ -42,7 +42,7 @@ pub fn addLuaLibrary(exe: *std.build.LibExeObjStep, installPath: [] const u8) vo // Lua headers + required source files var path = std.fmt.bufPrint(buf[0..], "{s}{s}", .{ installPath, "src/lua-5.4.3/src"}) catch unreachable; - exe.addIncludeDir(path); + exe.addIncludePath(path); // C compile flags const flags = [_][]const u8{ "-std=c99", diff --git a/src/lua.zig b/src/lua.zig index a46bd9e..a0fa7dd 100644 --- a/src/lua.zig +++ b/src/lua.zig @@ -127,7 +127,7 @@ pub const Lua = struct { inline while (idx < len) : (idx += 1) { args[idx] = @field(params, fields_info[idx].name); } - ptr.* = @call(.{}, T.init, args); + ptr.* = @call(.auto, T.init, args); // (4) check and store the callback table //_ = lua.luaL_checktype(L, 1, lua.LUA_TTABLE); _ = lualib.lua_pushvalue(self.L, 1); @@ -141,11 +141,12 @@ pub const Lua = struct { _ = allocateDeallocateHelper(@TypeOf(v), true, self.ud.allocator, v); } - pub fn newUserType(self: *Lua, comptime T: type) !void { + // Zig 0.10.0+ returns a fully qualified struct name, so require an explicit UserType name + pub fn newUserType(self: *Lua, comptime T: type, comptime name: []const u8) !void { comptime var hasInit: bool = false; comptime var hasDestroy: bool = false; comptime var metaTblName: [1024]u8 = undefined; - _ = comptime try std.fmt.bufPrint(metaTblName[0..], "{s}", .{@typeName(T)}); + _ = comptime try std.fmt.bufPrint(metaTblName[0..], "{s}", .{name}); // Init Lua states comptime var allocFuns = struct { fn new(L: ?*lualib.lua_State) callconv(.C) c_int { @@ -189,20 +190,15 @@ pub const Lua = struct { switch (@typeInfo(T)) { .Struct => |StructInfo| { inline for (StructInfo.decls) |decl| { - switch (decl.data) { - .Fn => |_| { - if (comptime std.mem.eql(u8, decl.name, "init") == true) { - hasInit = true; - } else if (comptime std.mem.eql(u8, decl.name, "destroy") == true) { - hasDestroy = true; - } else if (decl.is_pub) { - comptime var field = @field(T, decl.name); - const Caller = ZigCallHelper(@TypeOf(field)); - Caller.pushFunctor(self.L, field) catch unreachable; - lualib.lua_setfield(self.L, -2, @ptrCast([*c]const u8, decl.name)); - } - }, - else => {}, + if (comptime std.mem.eql(u8, decl.name, "init") == true) { + hasInit = true; + } else if (comptime std.mem.eql(u8, decl.name, "destroy") == true) { + hasDestroy = true; + } else if (decl.is_pub) { + comptime var field = @field(T, decl.name); + const Caller = ZigCallHelper(@TypeOf(field)); + Caller.pushFunctor(self.L, field) catch unreachable; + lualib.lua_setfield(self.L, -2, @ptrCast([*c]const u8, decl.name)); } } }, @@ -228,10 +224,16 @@ pub const Lua = struct { pub fn Function(comptime T: type) type { const FuncType = T; - const RetType = - switch (@typeInfo(FuncType)) { - .Fn => |FunctionInfo| FunctionInfo.return_type, - else => @compileError("Unsupported type."), + const RetType = blk: { + const FuncInfo = @typeInfo(FuncType); + if (FuncInfo == .Pointer) { + const PointerInfo = @typeInfo(FuncInfo.Pointer.child); + if (PointerInfo == .Fn) { + break :blk PointerInfo.Fn.return_type; + } + } + + @compileError("Unsupported type"); }; return struct { const Self = @This(); @@ -621,7 +623,8 @@ pub const Lua = struct { fn prepareArgs(self: *Self, L: ?*lualib.lua_State) !void { // Prepare arguments - comptime var i = self.args.len - 1; + if (self.args.len <= 0) return; + comptime var i: i32 = self.args.len - 1; inline while (i > -1) : (i -= 1) { if (comptime allocateDeallocateHelper(@TypeOf(self.args[i]), false, null, null)) { self.args[i] = popResource(@TypeOf(self.args[i]), L.?) catch unreachable; @@ -631,8 +634,8 @@ pub const Lua = struct { } } - fn call(self: *Self, func: funcType) !void { - self.result = @call(.{}, func, self.args); + fn call(self: *Self, func: *const funcType) !void { + self.result = @call(.auto, func, self.args); } fn pushResult(self: *Self, L: ?*lualib.lua_State) !void { @@ -642,7 +645,8 @@ pub const Lua = struct { } fn destroyArgs(self: *Self, L: ?*lualib.lua_State) !void { - comptime var i = self.args.len - 1; + if (self.args.len <= 0) return; + comptime var i:i32 = self.args.len - 1; inline while (i > -1) : (i -= 1) { _ = allocateDeallocateHelper(@TypeOf(self.args[i]), true, getAllocator(L), self.args[i]); } @@ -650,7 +654,7 @@ pub const Lua = struct { } }; - pub fn pushFunctor(L: ?*lualib.lua_State, func: funcType) !void { + pub fn pushFunctor(L: ?*lualib.lua_State, func: *const funcType) !void { const funcPtrAsInt = @intCast(c_longlong, @ptrToInt(func)); lualib.lua_pushinteger(L, funcPtrAsInt); @@ -661,7 +665,7 @@ pub const Lua = struct { f.prepareArgs(_L) catch unreachable; // Get func pointer upvalue as int => convert to func ptr then call var ptr = lualib.lua_tointegerx(_L, lualib.lua_upvalueindex(1), null); - f.call(@intToPtr(funcType, @intCast(usize, ptr))) catch unreachable; + f.call(@intToPtr(*const funcType, @intCast(usize, ptr))) catch unreachable; // The end f.pushResult(_L) catch unreachable; // Release arguments @@ -691,12 +695,7 @@ pub const Lua = struct { const userData = @ptrCast(*Lua.LuaUserData, @alignCast(@alignOf(Lua.LuaUserData), ud)); if (@ptrCast(?[*]align(c_alignment) u8, @alignCast(c_alignment, ptr))) |previous_pointer| { const previous_slice = previous_pointer[0..osize]; - if (osize >= nsize) { - // Lua assumes that the allocator never fails when osize >= nsize. - return userData.allocator.alignedShrink(previous_slice, c_alignment, nsize).ptr; - } else { - return (userData.allocator.reallocAdvanced(previous_slice, c_alignment, nsize, .exact) catch return null).ptr; - } + return (userData.allocator.realloc(previous_slice, nsize) catch return null).ptr; } else { // osize is any of LUA_TSTRING, LUA_TTABLE, LUA_TFUNCTION, LUA_TUSERDATA, or LUA_TTHREAD // when (and only when) Lua is creating a new object of that type. @@ -707,7 +706,7 @@ pub const Lua = struct { }; pub fn main() anyerror!void { - var lua = try Lua.init(std.testing.allocator); + var lua = try Lua.init(std.heap.c_allocator); defer lua.destroy(); lua.openLibs(); diff --git a/src/tests.zig b/src/tests.zig index b4a4e97..c12706e 100644 --- a/src/tests.zig +++ b/src/tests.zig @@ -136,19 +136,19 @@ test "simple Zig => Lua function call" { lua.run(lua_command); - var fun1 = try lua.getResource(Lua.Function(fn () void), "test_1"); + var fun1 = try lua.getResource(Lua.Function(*const fn () void), "test_1"); defer lua.release(fun1); - var fun2 = try lua.getResource(Lua.Function(fn (a: i32) void), "test_2"); + var fun2 = try lua.getResource(Lua.Function(*const fn (a: i32) void), "test_2"); defer lua.release(fun2); - var fun3_1 = try lua.getResource(Lua.Function(fn (a: i32) i32), "test_3"); + var fun3_1 = try lua.getResource(Lua.Function(*const fn (a: i32) i32), "test_3"); defer lua.release(fun3_1); - var fun3_2 = try lua.getResource(Lua.Function(fn (a: []const u8) []const u8), "test_3"); + var fun3_2 = try lua.getResource(Lua.Function(*const fn (a: []const u8) []const u8), "test_3"); defer lua.release(fun3_2); - var fun4 = try lua.getResource(Lua.Function(fn (a: i32, b: i32) i32), "test_4"); + var fun4 = try lua.getResource(Lua.Function(*const fn (a: i32, b: i32) i32), "test_4"); defer lua.release(fun4); try fun1.call(.{}); @@ -249,10 +249,10 @@ test "simple Zig => Lua => Zig function call" { lua.run("function luaTestFun4(a) return testFun4(a); end"); lua.run("function luaTestFun5(a,b) return testFun5(a,b); end"); - var fun4 = try lua.getResource(Lua.Function(fn (a: []const u8) []const u8), "luaTestFun4"); + var fun4 = try lua.getResource(Lua.Function(*const fn (a: []const u8) []const u8), "luaTestFun4"); defer lua.release(fun4); - var fun5 = try lua.getResource(Lua.Function(fn (a: i32, b: i32) i32), "luaTestFun5"); + var fun5 = try lua.getResource(Lua.Function(*const fn (a: i32, b: i32) i32), "luaTestFun5"); defer lua.release(fun5); var res4 = try fun4.call(.{"macika"}); @@ -262,7 +262,7 @@ test "simple Zig => Lua => Zig function call" { try std.testing.expect(res5 == 41); } -fn testLuaInnerFun(fun: Lua.Function(fn (a: i32) i32)) i32 { +fn testLuaInnerFun(fun: Lua.Function(*const fn (a: i32) i32)) i32 { var res = fun.call(.{42}) catch unreachable; return res; } @@ -274,7 +274,7 @@ test "Lua function injection into Zig function" { lua.openLibs(); // Binding on Zig side lua.run("function getInt(a) return a+1; end"); - var luafun = try lua.getResource(Lua.Function(fn (a: i32) i32), "getInt"); + var luafun = try lua.getResource(Lua.Function(*const fn (a: i32) i32), "getInt"); defer lua.release(luafun); var result = testLuaInnerFun(luafun); @@ -456,7 +456,7 @@ test "Lua.Table inner table tests" { str = try retInner2Table.get([]const u8, "str"); int = try retInner2Table.get(i32, "int32"); - var func = try retInner2Table.getResource(Lua.Function(fn (a: i32) i32), "fn"); + var func = try retInner2Table.getResource(Lua.Function(*const fn (a: i32) i32), "fn"); defer lua.release(func); var funcRes = try func.call(.{42}); @@ -492,7 +492,7 @@ test "Function with Lua.Table argument" { lua.set("sumFn", testLuaTableArg); lua.run("function test() return sumFn({a=1, b=2}); end"); - var luaFun = try lua.getResource(Lua.Function(fn () i32), "test"); + var luaFun = try lua.getResource(Lua.Function(*const fn () i32), "test"); defer lua.release(luaFun); var luaRes = try luaFun.call(.{}); @@ -527,7 +527,7 @@ test "Function with Lua.Table result" { //lua.run("function test() tbl = tblFn({}); return tbl[1] + tbl[2]; end"); lua.run("function test() tbl = tblFn({}); return tbl[1] + tbl[2]; end"); - var luaFun = try lua.getResource(Lua.Function(fn () i32), "test"); + var luaFun = try lua.getResource(Lua.Function(*const fn () i32), "test"); defer lua.release(luaFun); var luaRes = try luaFun.call(.{}); @@ -587,7 +587,7 @@ test "Custom types I: allocless in/out member functions arguments" { defer lua.destroy(); lua.openLibs(); - try lua.newUserType(TestCustomType); + try lua.newUserType(TestCustomType, "TestCustomType"); const cmd = \\o = TestCustomType.new(42, 42.0, "life", true) @@ -600,22 +600,22 @@ test "Custom types I: allocless in/out member functions arguments" { ; lua.run(cmd); - var getA = try lua.getResource(Lua.Function(fn () i32), "getA"); + var getA = try lua.getResource(Lua.Function(*const fn () i32), "getA"); defer lua.release(getA); - var getB = try lua.getResource(Lua.Function(fn () f32), "getB"); + var getB = try lua.getResource(Lua.Function(*const fn () f32), "getB"); defer lua.release(getB); - var getC = try lua.getResource(Lua.Function(fn () []const u8), "getC"); + var getC = try lua.getResource(Lua.Function(*const fn () []const u8), "getC"); defer lua.release(getC); - var getD = try lua.getResource(Lua.Function(fn () bool), "getD"); + var getD = try lua.getResource(Lua.Function(*const fn () bool), "getD"); defer lua.release(getD); - var reset = try lua.getResource(Lua.Function(fn () void), "reset"); + var reset = try lua.getResource(Lua.Function(*const fn () void), "reset"); defer lua.release(reset); - var store = try lua.getResource(Lua.Function(fn (_a: i32, _b: f32, _c: []const u8, _d: bool) void), "store"); + var store = try lua.getResource(Lua.Function(*const fn (_a: i32, _b: f32, _c: []const u8, _d: bool) void), "store"); defer lua.release(store); var resA0 = try getA.call(.{}); @@ -664,7 +664,7 @@ test "Custom types II: set as global, get without ownership" { defer lua.destroy(); lua.openLibs(); - _ = try lua.newUserType(TestCustomType); + _ = try lua.newUserType(TestCustomType, "TestCustomType"); // Creation from Zig var ojjectum = try lua.createUserType(TestCustomType, .{42, 42.0, "life", true}); defer lua.release(ojjectum); @@ -714,7 +714,7 @@ test "Custom types III: Zig function with custom user type arguments" { defer lua.destroy(); lua.openLibs(); - _ = try lua.newUserType(TestCustomType); + _ = try lua.newUserType(TestCustomType, "TestCustomType"); lua.set("swap", testCustomTypeSwap); const cmd =