Skip to content

Commit d35d951

Browse files
committed
instruction: Fixup instruction data transmute
#### Problem The `InstructionData` helper creator doesn't work for all possible types, since the `@sizeOf` macro does not use packed size. #### Summary of changes Use `@bitSizeOf` instead, and add a test.
1 parent 87d40df commit d35d951

File tree

1 file changed

+27
-1
lines changed

1 file changed

+27
-1
lines changed

src/instruction.zig

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,38 @@ pub const Instruction = extern struct {
7272
/// .data = data.asBytes(),
7373
/// });
7474
pub fn InstructionData(comptime Discriminant: type, comptime Data: type) type {
75+
comptime {
76+
if (@bitSizeOf(Discriminant) % 8 != 0) {
77+
@panic("Discriminant bit size is not divisible by 8");
78+
}
79+
if (@bitSizeOf(Data) % 8 != 0) {
80+
@panic("Data bit size is not divisible by 8");
81+
}
82+
}
7583
return packed struct {
7684
discriminant: Discriminant,
7785
data: Data,
7886
const Self = @This();
7987
fn asBytes(self: *const Self) []const u8 {
80-
return std.mem.asBytes(self)[0..(@sizeOf(Discriminant) + @sizeOf(Data))];
88+
return std.mem.asBytes(self)[0..((@bitSizeOf(Discriminant) + @bitSizeOf(Data)) / 8)];
8189
}
8290
};
8391
}
92+
93+
test "instruction: data transmute" {
94+
const Discriminant = enum(u32) {
95+
zero,
96+
one,
97+
two,
98+
three,
99+
};
100+
101+
const Data = packed struct {
102+
a: u8,
103+
b: u16,
104+
c: u64,
105+
};
106+
107+
const instruction = InstructionData(Discriminant, Data){ .discriminant = Discriminant.three, .data = Data{ .a = 1, .b = 2, .c = 3 } };
108+
try std.testing.expectEqualSlices(u8, instruction.asBytes(), &[_]u8{ 3, 0, 0, 0, 1, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0 });
109+
}

0 commit comments

Comments
 (0)