block: descriptor can be statically allocated

This commit is contained in:
Mitchell Hashimoto 2023-10-21 11:31:23 -07:00
parent 38835ef322
commit a38331cb6e
No known key found for this signature in database
GPG key ID: 523D5DC389D273BC

View file

@ -36,7 +36,13 @@ pub fn Block(
const Self = @This(); const Self = @This();
const captures_info = @typeInfo(Captures).Struct; const captures_info = @typeInfo(Captures).Struct;
const InvokeFn = FnType(anyopaque); const InvokeFn = FnType(anyopaque);
const signature: [:0]const u8 = objc.comptimeEncode(InvokeFn); const descriptor: Descriptor = .{
.reserved = 0,
.size = @sizeOf(Context),
.copy_helper = &descCopyHelper,
.dispose_helper = &descDisposeHelper,
.signature = objc.comptimeEncode(InvokeFn).ptr,
};
/// This is the function type that is called back. /// This is the function type that is called back.
pub const Fn = FnType(Context); pub const Fn = FnType(Context);
@ -61,21 +67,11 @@ pub fn Block(
ctx.isa = NSConcreteStackBlock; ctx.isa = NSConcreteStackBlock;
ctx.flags = @bitCast(flags); ctx.flags = @bitCast(flags);
ctx.invoke = @ptrCast(func); ctx.invoke = @ptrCast(func);
ctx.descriptor = &descriptor;
inline for (captures_info.fields) |field| { inline for (captures_info.fields) |field| {
@field(ctx, field.name) = @field(captures, field.name); @field(ctx, field.name) = @field(captures, field.name);
} }
var descriptor = try alloc.create(Descriptor);
errdefer alloc.destroy(descriptor);
descriptor.* = .{
.reserved = 0,
.size = @sizeOf(Context),
.copy_helper = &descCopyHelper,
.dispose_helper = &descDisposeHelper,
.signature = signature.ptr,
};
ctx.descriptor = descriptor;
return .{ .context = ctx }; return .{ .context = ctx };
} }
@ -111,7 +107,6 @@ pub fn Block(
_Block_object_dispose(@field(real_src, field.name), 3); _Block_object_dispose(@field(real_src, field.name), 3);
} }
} }
alloc.destroy(real_src.descriptor);
} }
/// Creates a function type for the invocation function, but alters /// Creates a function type for the invocation function, but alters
@ -173,7 +168,7 @@ fn BlockContext(comptime Captures: type, comptime InvokeFn: type) type {
}; };
fields[4] = .{ fields[4] = .{
.name = "descriptor", .name = "descriptor",
.type = *Descriptor, .type = *const Descriptor,
.default_value = null, .default_value = null,
.is_comptime = false, .is_comptime = false,
.alignment = @alignOf(*Descriptor), .alignment = @alignOf(*Descriptor),