diff --git a/src/block.zig b/src/block.zig index 19591d3..20c0f15 100644 --- a/src/block.zig +++ b/src/block.zig @@ -86,8 +86,8 @@ pub fn Block( }; ctx.invoke = @ptrCast(func); ctx.descriptor = &descriptor; - inline for (captures_info.fields) |field| { - @field(ctx, field.name) = @field(captures, field.name); + inline for (captures_info.field_names) |field_name| { + @field(ctx, field_name) = @field(captures, field_name); } return ctx; @@ -123,11 +123,11 @@ pub fn Block( fn descCopyHelper(dst: *anyopaque, src: *anyopaque) callconv(.c) void { const real_dst: *Context = @ptrCast(@alignCast(dst)); const real_src: *Context = @ptrCast(@alignCast(src)); - inline for (captures_info.fields) |field| { - if (field.type == objc.c.id) { + inline for (captures_info.field_names, captures_info.field_types) |field_name, field_type| { + if (field_type == objc.c.id) { _Block_object_assign( - @ptrCast(&@field(real_dst, field.name)), - @field(real_src, field.name), + @ptrCast(&@field(real_dst, field_name)), + @field(real_src, field_name), .object, ); } @@ -136,10 +136,10 @@ pub fn Block( fn descDisposeHelper(src: *anyopaque) callconv(.c) void { const real_src: *Context = @ptrCast(@alignCast(src)); - inline for (captures_info.fields) |field| { - if (field.type == objc.c.id) { + inline for (captures_info.field_names, captures_info.field_types) |field_name, field_type| { + if (field_type == objc.c.id) { _Block_object_dispose( - @field(real_src, field.name), + @field(real_src, field_name), .object, ); } @@ -163,59 +163,66 @@ pub fn Block( /// argument to any block invocation. See Block. fn BlockContext(comptime Captures: type, comptime InvokeFn: type) type { const captures_info = @typeInfo(Captures).@"struct"; - var fields: [captures_info.fields.len + 5]std.builtin.Type.StructField = undefined; - fields[0] = .{ - .name = "isa", - .type = ?*anyopaque, + const field_count = captures_info.field_types.len + 5; + + var field_names: [field_count][]const u8 = undefined; + var field_types: [field_count]type = undefined; + var field_attrs: [field_count]std.lang.Type.Struct.FieldAttributes = undefined; + + field_names[0] = "isa"; + field_types[0] = ?*anyopaque; + field_attrs[0] = .{ .default_value_ptr = null, - .is_comptime = false, - .alignment = @alignOf(*anyopaque), + .@"comptime" = false, + .@"align" = @alignOf(*anyopaque), }; - fields[1] = .{ - .name = "flags", - .type = BlockFlags, + field_names[1] = "flags"; + field_types[1] = BlockFlags; + field_attrs[1] = .{ .default_value_ptr = null, - .is_comptime = false, - .alignment = @alignOf(c_int), + .@"comptime" = false, + .@"align" = @alignOf(c_int), }; - fields[2] = .{ - .name = "reserved", - .type = c_int, + field_names[2] = "reserved"; + field_types[2] = c_int; + field_attrs[2] = .{ .default_value_ptr = null, - .is_comptime = false, - .alignment = @alignOf(c_int), + .@"comptime" = false, + .@"align" = @alignOf(c_int), }; - fields[3] = .{ - .name = "invoke", - .type = *const InvokeFn, + field_names[3] = "invoke"; + field_types[3] = *const InvokeFn; + field_attrs[3] = .{ .default_value_ptr = null, - .is_comptime = false, - .alignment = @typeInfo(*const InvokeFn).pointer.alignment, + .@"comptime" = false, + .@"align" = @typeInfo(*const InvokeFn).pointer.attrs.@"align", }; - fields[4] = .{ - .name = "descriptor", - .type = *const Descriptor, + field_names[4] = "descriptor"; + field_types[4] = *const Descriptor; + field_attrs[4] = .{ .default_value_ptr = null, - .is_comptime = false, - .alignment = @alignOf(*Descriptor), + .@"comptime" = false, + .@"align" = @alignOf(*Descriptor), }; - for (captures_info.fields, 5..) |capture, i| { - switch (capture.type) { + for ( + captures_info.field_names, + captures_info.field_types, + captures_info.field_attrs, + 5.., + ) |field_name, field_type, field_attr, i| { + switch (field_type) { comptime_int => @compileError("capture should not be a comptime_int, try using @as"), comptime_float => @compileError("capture should not be a comptime_float, try using @as"), else => {}, } - fields[i] = .{ .name = capture.name, .type = capture.type, .default_value_ptr = null, .is_comptime = false, .alignment = capture.alignment }; - } - - var field_names: [fields.len][]const u8 = undefined; - var field_types: [fields.len]type = undefined; - var field_attrs: [fields.len]std.builtin.Type.StructField.Attributes = undefined; - for (fields, 0..) |field, i| { - field_names[i] = field.name; - field_types[i] = field.type; - field_attrs[i] = .{ .@"align" = field.alignment }; + field_names[i] = field_name; + field_types[i] = field_type; + field_attrs[i] = .{ + .default_value_ptr = null, + .@"comptime" = false, + .@"align" = field_attr.@"align", + }; } return @Struct(.@"extern", null, &field_names, &field_types, &field_attrs); diff --git a/src/class.zig b/src/class.zig index 34feea1..e543996 100644 --- a/src/class.zig +++ b/src/class.zig @@ -58,11 +58,11 @@ pub const Class = struct { // whose first two arguments are a `c.id` and a `c.SEL`. pub fn replaceMethod(self: Class, name: [:0]const u8, imp: anytype) void { const fn_info = @typeInfo(@TypeOf(imp)).@"fn"; - assert(std.meta.eql(fn_info.calling_convention, std.builtin.CallingConvention.c)); - assert(fn_info.is_var_args == false); - assert(fn_info.params.len >= 2); - assert(fn_info.params[0].type == c.id); - assert(fn_info.params[1].type == c.SEL); + assert(std.meta.eql(fn_info.attrs.@"callconv", std.lang.CallingConvention.c)); + assert(fn_info.attrs.varargs == false); + assert(fn_info.param_types.len >= 2); + assert(fn_info.param_types[0] == c.id); + assert(fn_info.param_types[1] == c.SEL); _ = c.class_replaceMethod(self.value, objc.sel(name).value, @ptrCast(&imp), null); } @@ -72,11 +72,11 @@ pub const Class = struct { pub fn addMethod(self: Class, name: [:0]const u8, imp: anytype) bool { const Fn = @TypeOf(imp); const fn_info = @typeInfo(Fn).@"fn"; - assert(std.meta.eql(fn_info.calling_convention, std.builtin.CallingConvention.c)); - assert(fn_info.is_var_args == false); - assert(fn_info.params.len >= 2); - assert(fn_info.params[0].type == c.id); - assert(fn_info.params[1].type == c.SEL); + assert(std.meta.eql(fn_info.attrs.@"callconv", std.lang.CallingConvention.c)); + assert(fn_info.attrs.varargs == false); + assert(fn_info.param_types.len >= 2); + assert(fn_info.param_types[0] == c.id); + assert(fn_info.param_types[1] == c.SEL); const encoding = comptime objc.comptimeEncode(Fn); return boolResult(c.class_addMethod( self.value, diff --git a/src/encoding.zig b/src/encoding.zig index 271fc7f..8c7cdd1 100644 --- a/src/encoding.zig +++ b/src/encoding.zig @@ -145,8 +145,8 @@ pub const Encoding = union(enum) { // of the struct (determined by levels of pointer indirection) if (s.show_type_spec) { try writer.writeAll("="); - inline for (struct_info.@"struct".fields) |field| { - const field_encode = init(field.type); + inline for (struct_info.@"struct".field_types) |field_type| { + const field_encode = init(field_type); try field_encode.format(writer); } } @@ -167,8 +167,8 @@ pub const Encoding = union(enum) { // of the Union (determined by levels of pointer indirection) if (u.show_type_spec) { try writer.writeAll("="); - inline for (union_info.@"union".fields) |field| { - const field_encode = init(field.type); + inline for (union_info.@"union".field_types) |field_type| { + const field_encode = init(field_type); try field_encode.format(writer); } } @@ -210,13 +210,13 @@ pub const Encoding = union(enum) { } }, .function => |fn_info| { - assert(std.meta.eql(fn_info.calling_convention, std.builtin.CallingConvention.c)); + assert(std.meta.eql(fn_info.attrs.@"callconv", std.builtin.CallingConvention.c)); // Return type is first in a method encoding const ret_type_enc = init(fn_info.return_type.?); try ret_type_enc.format(writer); - inline for (fn_info.params) |param| { - const param_enc = init(param.type.?); + inline for (fn_info.param_types) |param_type| { + const param_enc = init(param_type.?); try param_enc.format(writer); } }, diff --git a/src/iterator.zig b/src/iterator.zig index c28bfee..f95baec 100644 --- a/src/iterator.zig +++ b/src/iterator.zig @@ -6,7 +6,7 @@ const NSFastEnumerationState = extern struct { state: c_ulong = 0, itemsPtr: ?[*]objc.c.id = null, mutationsPtr: ?*c_ulong = null, - extra: [5]c_ulong = [_]c_ulong{0} ** 5, + extra: [5]c_ulong = @splat(0), }; /// An iterator that uses the fast enumeration protocol[1] to iterate over @@ -20,7 +20,7 @@ pub const Iterator = struct { state: NSFastEnumerationState = .{}, initial_mutations_value: ?c_ulong = null, // Clang compiles `for…in` loops with a size 16 buffer. - buffer: [16]objc.c.id = [_]objc.c.id{null} ** 16, + buffer: [16]objc.c.id = @splat(null), slice: []const objc.c.id = &.{}, pub fn init(object: objc.Object) Iterator { diff --git a/src/msg_send.zig b/src/msg_send.zig index 44b069b..932d909 100644 --- a/src/msg_send.zig +++ b/src/msg_send.zig @@ -195,18 +195,18 @@ fn MsgSendFn( assert(@sizeOf(Target) == @sizeOf(c.id)); // Build up our argument types for @Fn - var param_types: [argsInfo.fields.len + 2]type = undefined; + var param_types: [argsInfo.field_types.len + 2]type = undefined; param_types[0] = Target; param_types[1] = c.SEL; - for (argsInfo.fields, 0..) |field, i| param_types[i + 2] = unwrapType(field.type); + for (argsInfo.field_types, 0..) |field_type, i| param_types[i + 2] = unwrapType(field_type); return @Fn(¶m_types, &@splat(.{}), Return, .{ .@"callconv" = .c }); } fn UnwrappedArgs(comptime Args: type) type { - const fields = @typeInfo(Args).@"struct".fields; - var types: [fields.len]type = undefined; - for (fields, 0..) |field, i| types[i] = unwrapType(field.type); + const field_types = @typeInfo(Args).@"struct".field_types; + var types: [field_types.len]type = undefined; + for (field_types, 0..) |field_type, i| types[i] = unwrapType(field_type); return @Tuple(&types); } @@ -221,9 +221,9 @@ fn unwrapType(comptime T: type) type { // rather than c.id, since Class and Sel have distinct pointer types. if (@typeInfo(T) == .@"struct") { const info = @typeInfo(T).@"struct"; - for (info.fields) |field| { - if (std.mem.eql(u8, field.name, "value") and @sizeOf(field.type) == @sizeOf(c.id)) { - return field.type; + for (info.field_names, info.field_types) |field_name, field_type| { + if (std.mem.eql(u8, field_name, "value") and @sizeOf(field_type) == @sizeOf(c.id)) { + return field_type; } } } @@ -255,9 +255,9 @@ fn unwrapType(comptime T: type) type { } inline fn buildUnwrappedArgs(args: anytype) UnwrappedArgs(@TypeOf(args)) { - const fields = @typeInfo(@TypeOf(args)).@"struct".fields; + const field_types = @typeInfo(@TypeOf(args)).@"struct".field_types; var result: UnwrappedArgs(@TypeOf(args)) = undefined; - inline for (fields, 0..) |_, i| { + inline for (field_types, 0..) |_, i| { result[i] = if (unwrapType(@TypeOf(args[i])) != @TypeOf(args[i])) args[i].value else