@@ -5157,21 +5157,30 @@ pub const Buffer = struct {
51575157
51585158// Helper functions to make the zlua API easier to use
51595159
5160- const Tuple = std .meta .Tuple ;
5161-
51625160fn TypeOfWrap (comptime function : anytype ) type {
5163- const Args = std .meta .ArgsTuple (@TypeOf (function ));
5164- return switch (Args ) {
5165- Tuple (&.{* Lua }) = > CFn ,
5166- Tuple (&.{ * Lua , Event , * DebugInfo }) = > CHookFn ,
5167- Tuple (&.{ * Lua , Status , Context }) = > CContFn ,
5168- Tuple (&.{ * Lua , * anyopaque }) = > CReaderFn ,
5169- Tuple (&.{* anyopaque }) = > CUserdataDtorFn ,
5170- Tuple (&.{ * Lua , i32 }) = > CInterruptCallbackFn ,
5171- Tuple (&.{[]const u8 }) = > CUserAtomCallbackFn ,
5172- Tuple (&.{ ? * anyopaque , []const u8 , bool }) = > CWarnFn ,
5173- Tuple (&.{ * Lua , []const u8 , * anyopaque }) = > CWriterFn ,
5174- else = > @compileError ("Unsupported function given to wrap '" ++ @typeName (@TypeOf (function )) ++ "'" ),
5161+ const params = @typeInfo (@TypeOf (function )).@"fn" .params ;
5162+ if (params .len == 1 ) {
5163+ if (params [0 ].type .? == * Lua ) return CFn ;
5164+ if (params [0 ].type .? == []const u8 ) return CUserAtomCallbackFn ;
5165+ if (params [0 ].type .? == * anyopaque ) return CUserdataDtorFn ;
5166+ }
5167+ if (params .len == 2 ) {
5168+ if (params [0 ].type .? == * Lua ) {
5169+ if (params [1 ].type .? == i32 ) return CInterruptCallbackFn ;
5170+ if (params [1 ].type .? == * anyopaque ) return CReaderFn ;
5171+ }
5172+ }
5173+ if (params .len == 3 ) {
5174+ if (params [0 ].type .? == ? * anyopaque and params [1 ].type .? == []const u8 and params [2 ].type .? == bool ) return CWarnFn ;
5175+ if (params [0 ].type .? == * Lua ) {
5176+ if (params [1 ].type .? == Event and params [2 ].type .? == * DebugInfo ) return CHookFn ;
5177+ if (params [1 ].type .? == Status and params [2 ].type .? == Context ) return CContFn ;
5178+ if (params [1 ].type .? == []const u8 and params [2 ].type .? == * anyopaque ) return CWriterFn ;
5179+ }
5180+ }
5181+ return {
5182+ @compileLog (@TypeOf (function ));
5183+ @compileError ("Unsupported function given to wrap." );
51755184 };
51765185}
51775186
@@ -5190,169 +5199,139 @@ fn TypeOfWrap(comptime function: anytype) type {
51905199/// Functions that accept a `*Lua` pointer also support returning error unions. For example,
51915200/// wrap also supports `fn (lua: *Lua) !i32` for a `CFn`.
51925201pub fn wrap (comptime function : anytype ) TypeOfWrap (function ) {
5193- const info = @typeInfo (@TypeOf (function ));
5194- if (info != .@"fn" ) {
5195- @compileError ("Wrap only accepts functions" );
5196- }
5197-
5198- const has_error_union = @typeInfo (info .@"fn" .return_type .? ) == .error_union ;
5199-
5200- const Args = std .meta .ArgsTuple (@TypeOf (function ));
5201- switch (Args ) {
5202- // CFn
5203- Tuple (&.{* Lua }) = > {
5204- return struct {
5205- fn inner (state : ? * LuaState ) callconv (.c ) c_int {
5206- // this is called by Lua, state should never be null
5207- var lua : * Lua = @ptrCast (state .? );
5208- if (has_error_union ) {
5209- return @call (.always_inline , function , .{lua }) catch | err | {
5210- lua .raiseErrorStr (@errorName (err ), .{});
5211- };
5212- } else {
5213- return @call (.always_inline , function , .{lua });
5214- }
5202+ const info = @typeInfo (@TypeOf (function )).@"fn" ;
5203+
5204+ const has_error_union = @typeInfo (info .return_type .? ) == .error_union ;
5205+
5206+ const Return = TypeOfWrap (function );
5207+ return switch (Return ) {
5208+ CFn = > struct {
5209+ fn inner (state : ? * LuaState ) callconv (.c ) c_int {
5210+ // this is called by Lua, state should never be null
5211+ var lua : * Lua = @ptrCast (state .? );
5212+ if (has_error_union ) {
5213+ return @call (.always_inline , function , .{lua }) catch | err | {
5214+ lua .raiseErrorStr (@errorName (err ), .{});
5215+ };
5216+ } else {
5217+ return @call (.always_inline , function , .{lua });
52155218 }
5216- }.inner ;
5217- },
5218- // CHookFn
5219- Tuple (&.{ * Lua , Event , * DebugInfo }) = > {
5220- return struct {
5221- fn inner (state : ? * LuaState , ar : ? * Debug ) callconv (.c ) void {
5222- // this is called by Lua, state should never be null
5223- var lua : * Lua = @ptrCast (state .? );
5224- var debug_info : DebugInfo = .{
5225- .current_line = if (ar .? .currentline == -1 ) null else ar .? .currentline ,
5226- .private = switch (lang ) {
5227- .lua51 , .luajit = > ar .? .i_ci ,
5228- else = > @ptrCast (ar .? .i_ci ),
5229- },
5219+ }
5220+ }.inner ,
5221+ CHookFn = > struct {
5222+ fn inner (state : ? * LuaState , ar : ? * Debug ) callconv (.c ) void {
5223+ // this is called by Lua, state should never be null
5224+ var lua : * Lua = @ptrCast (state .? );
5225+ var debug_info : DebugInfo = .{
5226+ .current_line = if (ar .? .currentline == -1 ) null else ar .? .currentline ,
5227+ .private = switch (lang ) {
5228+ .lua51 , .luajit = > ar .? .i_ci ,
5229+ else = > @ptrCast (ar .? .i_ci ),
5230+ },
5231+ };
5232+ if (has_error_union ) {
5233+ @call (.always_inline , function , .{ lua , @as (Event , @enumFromInt (ar .? .event )), & debug_info }) catch | err | {
5234+ lua .raiseErrorStr (@errorName (err ), .{});
52305235 };
5231- if (has_error_union ) {
5232- @call (.always_inline , function , .{ lua , @as (Event , @enumFromInt (ar .? .event )), & debug_info }) catch | err | {
5233- lua .raiseErrorStr (@errorName (err ), .{});
5234- };
5235- } else {
5236- @call (.always_inline , function , .{ lua , @as (Event , @enumFromInt (ar .? .event )), & debug_info });
5237- }
5236+ } else {
5237+ @call (.always_inline , function , .{ lua , @as (Event , @enumFromInt (ar .? .event )), & debug_info });
52385238 }
5239- }.inner ;
5240- },
5241- // CContFn
5242- Tuple (&.{ * Lua , Status , Context }) = > {
5243- return struct {
5244- fn inner (state : ? * LuaState , status : c_int , ctx : Context ) callconv (.c ) c_int {
5245- // this is called by Lua, state should never be null
5246- var lua : * Lua = @ptrCast (state .? );
5247- if (has_error_union ) {
5248- return @call (.always_inline , function , .{ lua , @as (Status , @enumFromInt (status )), ctx }) catch | err | {
5249- lua .raiseErrorStr (@errorName (err ), .{});
5250- };
5251- } else {
5252- return @call (.always_inline , function , .{ lua , @as (Status , @enumFromInt (status )), ctx });
5253- }
5239+ }
5240+ }.inner ,
5241+ CContFn = > struct {
5242+ fn inner (state : ? * LuaState , status : c_int , ctx : Context ) callconv (.c ) c_int {
5243+ // this is called by Lua, state should never be null
5244+ var lua : * Lua = @ptrCast (state .? );
5245+ if (has_error_union ) {
5246+ return @call (.always_inline , function , .{ lua , @as (Status , @enumFromInt (status )), ctx }) catch | err | {
5247+ lua .raiseErrorStr (@errorName (err ), .{});
5248+ };
5249+ } else {
5250+ return @call (.always_inline , function , .{ lua , @as (Status , @enumFromInt (status )), ctx });
52545251 }
5255- }.inner ;
5256- },
5257- // CReaderFn
5258- Tuple (&.{ * Lua , * anyopaque }) = > {
5259- return struct {
5260- fn inner (state : ? * LuaState , data : ? * anyopaque , size : [* c ]usize ) callconv (.c ) [* c ]const u8 {
5261- // this is called by Lua, state should never be null
5262- var lua : * Lua = @ptrCast (state .? );
5263- if (has_error_union ) {
5264- const result = @call (.always_inline , function , .{ lua , data .? }) catch | err | {
5265- lua .raiseErrorStr (@errorName (err ), .{});
5266- };
5267- if (result ) | buffer | {
5268- size .* = buffer .len ;
5269- return buffer .ptr ;
5270- } else {
5271- size .* = 0 ;
5272- return null ;
5273- }
5252+ }
5253+ }.inner ,
5254+ CReaderFn = > struct {
5255+ fn inner (state : ? * LuaState , data : ? * anyopaque , size : [* c ]usize ) callconv (.c ) [* c ]const u8 {
5256+ // this is called by Lua, state should never be null
5257+ var lua : * Lua = @ptrCast (state .? );
5258+ if (has_error_union ) {
5259+ const result = @call (.always_inline , function , .{ lua , data .? }) catch | err | {
5260+ lua .raiseErrorStr (@errorName (err ), .{});
5261+ };
5262+ if (result ) | buffer | {
5263+ size .* = buffer .len ;
5264+ return buffer .ptr ;
52745265 } else {
5275- if (@call (.always_inline , function , .{ lua , data .? })) | buffer | {
5276- size .* = buffer .len ;
5277- return buffer .ptr ;
5278- } else {
5279- size .* = 0 ;
5280- return null ;
5281- }
5266+ size .* = 0 ;
5267+ return null ;
52825268 }
5283- }
5284- }.inner ;
5285- },
5286- // CUserdataDtorFn
5287- Tuple (&.{* anyopaque }) = > {
5288- return struct {
5289- fn inner (userdata : * anyopaque ) callconv (.c ) void {
5290- return @call (.always_inline , function , .{userdata });
5291- }
5292- }.inner ;
5293- },
5294- // CInterruptCallbackFn
5295- Tuple (&.{ * Lua , i32 }) = > {
5296- return struct {
5297- fn inner (state : ? * LuaState , gc : c_int ) callconv (.c ) void {
5298- // this is called by Lua, state should never be null
5299- var lua : * Lua = @ptrCast (state .? );
5300- if (has_error_union ) {
5301- @call (.always_inline , function , .{ lua , gc }) catch | err | {
5302- lua .raiseErrorStr (@errorName (err ), .{});
5303- };
5269+ } else {
5270+ if (@call (.always_inline , function , .{ lua , data .? })) | buffer | {
5271+ size .* = buffer .len ;
5272+ return buffer .ptr ;
53045273 } else {
5305- @call (.always_inline , function , .{ lua , gc });
5274+ size .* = 0 ;
5275+ return null ;
53065276 }
53075277 }
5308- }.inner ;
5309- },
5310- // CUserAtomCallbackFn
5311- Tuple (&.{[]const u8 }) = > {
5312- return struct {
5313- fn inner (str : [* c ]const u8 , len : usize ) callconv (.c ) i16 {
5314- if (str ) | s | {
5315- const buf = s [0.. len ];
5316- return @call (.always_inline , function , .{buf });
5317- }
5318- return -1 ;
5278+ }
5279+ }.inner ,
5280+ CUserdataDtorFn = > struct {
5281+ fn inner (userdata : * anyopaque ) callconv (.c ) void {
5282+ return @call (.always_inline , function , .{userdata });
5283+ }
5284+ }.inner ,
5285+ CInterruptCallbackFn = > struct {
5286+ fn inner (state : ? * LuaState , gc : c_int ) callconv (.c ) void {
5287+ // this is called by Lua, state should never be null
5288+ var lua : * Lua = @ptrCast (state .? );
5289+ if (has_error_union ) {
5290+ @call (.always_inline , function , .{ lua , gc }) catch | err | {
5291+ lua .raiseErrorStr (@errorName (err ), .{});
5292+ };
5293+ } else {
5294+ @call (.always_inline , function , .{ lua , gc });
53195295 }
5320- }.inner ;
5321- },
5322- // CWarnFn
5323- Tuple (&.{ ? * anyopaque , []const u8 , bool }) = > {
5324- return struct {
5325- fn inner (data : ? * anyopaque , msg : [* c ]const u8 , to_cont : c_int ) callconv (.c ) void {
5326- // warning messages emitted from Lua should be null-terminated for display
5327- const message = std .mem .span (@as ([* :0 ]const u8 , @ptrCast (msg )));
5328- @call (.always_inline , function , .{ data , message , to_cont != 0 });
5296+ }
5297+ }.inner ,
5298+ CUserAtomCallbackFn = > struct {
5299+ fn inner (str : [* c ]const u8 , len : usize ) callconv (.c ) i16 {
5300+ if (str ) | s | {
5301+ const buf = s [0.. len ];
5302+ return @call (.always_inline , function , .{buf });
53295303 }
5330- }.inner ;
5331- },
5332- // CWriterFn
5333- Tuple (&.{ * Lua , []const u8 , * anyopaque }) = > {
5334- return struct {
5335- fn inner (state : ? * LuaState , buf : ? * const anyopaque , size : usize , data : ? * anyopaque ) callconv (.c ) c_int {
5336- // this is called by Lua, state should never be null
5337- var lua : * Lua = @ptrCast (state .? );
5338- const buffer = @as ([* ]const u8 , @ptrCast (buf ))[0.. size ];
5339-
5340- const result = if (has_error_union ) blk : {
5341- break :blk @call (.always_inline , function , .{ lua , buffer , data .? }) catch | err | {
5342- lua .raiseErrorStr (@errorName (err ), .{});
5343- };
5344- } else blk : {
5345- break :blk @call (.always_inline , function , .{ lua , buffer , data .? });
5304+ return -1 ;
5305+ }
5306+ }.inner ,
5307+ CWarnFn = > struct {
5308+ fn inner (data : ? * anyopaque , msg : [* c ]const u8 , to_cont : c_int ) callconv (.c ) void {
5309+ // warning messages emitted from Lua should be null-terminated for display
5310+ const message = std .mem .span (@as ([* :0 ]const u8 , @ptrCast (msg )));
5311+ @call (.always_inline , function , .{ data , message , to_cont != 0 });
5312+ }
5313+ }.inner ,
5314+ CWriterFn = > struct {
5315+ fn inner (state : ? * LuaState , buf : ? * const anyopaque , size : usize , data : ? * anyopaque ) callconv (.c ) c_int {
5316+ // this is called by Lua, state should never be null
5317+ var lua : * Lua = @ptrCast (state .? );
5318+ const buffer = @as ([* ]const u8 , @ptrCast (buf ))[0.. size ];
5319+
5320+ const result = if (has_error_union ) blk : {
5321+ break :blk @call (.always_inline , function , .{ lua , buffer , data .? }) catch | err | {
5322+ lua .raiseErrorStr (@errorName (err ), .{});
53465323 };
5324+ } else blk : {
5325+ break :blk @call (.always_inline , function , .{ lua , buffer , data .? });
5326+ };
53475327
5348- // it makes more sense for the inner writer function to return false for failure,
5349- // so negate the result here
5350- return @intFromBool (! result );
5351- }
5352- }.inner ;
5353- },
5354- else = > @compileError ("Unsupported function given to wrap '" ++ @typeName (@TypeOf (function )) ++ "'" ),
5355- }
5328+ // it makes more sense for the inner writer function to return false for failure,
5329+ // so negate the result here
5330+ return @intFromBool (! result );
5331+ }
5332+ }.inner ,
5333+ else = > unreachable ,
5334+ };
53565335}
53575336
53585337/// Zig wrapper for Luau lua_CompileOptions that uses the same defaults as Luau if
0 commit comments