mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-04-14 19:45:49 +00:00
lib: lib.Struct can convert packed structs to extern structs
This commit is contained in:
@@ -1,6 +1,17 @@
|
||||
const std = @import("std");
|
||||
const testing = std.testing;
|
||||
const Target = @import("target.zig").Target;
|
||||
|
||||
/// Create a struct type that is C ABI compatible from a Zig struct type.
|
||||
///
|
||||
/// When the target is `.zig`, the original struct type is returned as-is.
|
||||
/// When the target is `.c`, the struct is recreated with an `extern` layout,
|
||||
/// ensuring a stable, C-compatible memory layout.
|
||||
///
|
||||
/// This handles packed structs by resolving zero alignments to the natural
|
||||
/// alignment of each field's type, since extern structs require explicit
|
||||
/// alignment. This means packed struct fields like `bool` will take up
|
||||
/// their full size (1 byte) rather than being bit-packed.
|
||||
pub fn Struct(
|
||||
comptime target: Target,
|
||||
comptime Zig: type,
|
||||
@@ -16,7 +27,7 @@ pub fn Struct(
|
||||
.type = field.type,
|
||||
.default_value_ptr = field.default_value_ptr,
|
||||
.is_comptime = field.is_comptime,
|
||||
.alignment = field.alignment,
|
||||
.alignment = if (field.alignment > 0) field.alignment else @alignOf(field.type),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -29,3 +40,20 @@ pub fn Struct(
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
test "packed struct converts to extern with full-size bools" {
|
||||
const Packed = packed struct {
|
||||
flag1: bool,
|
||||
flag2: bool,
|
||||
value: u8,
|
||||
};
|
||||
|
||||
const C = Struct(.c, Packed);
|
||||
const info = @typeInfo(C).@"struct";
|
||||
|
||||
try testing.expectEqual(.@"extern", info.layout);
|
||||
try testing.expectEqual(@as(usize, 1), @sizeOf(@FieldType(C, "flag1")));
|
||||
try testing.expectEqual(@as(usize, 1), @sizeOf(@FieldType(C, "flag2")));
|
||||
try testing.expectEqual(@as(usize, 1), @sizeOf(@FieldType(C, "value")));
|
||||
try testing.expectEqual(@as(usize, 3), @sizeOf(C));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user