Skip to content

Commit

Permalink
instruction: Fixup instruction data transmute
Browse files Browse the repository at this point in the history
#### 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.
  • Loading branch information
joncinque committed Nov 9, 2024
1 parent 87d40df commit d35d951
Showing 1 changed file with 27 additions and 1 deletion.
28 changes: 27 additions & 1 deletion src/instruction.zig
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,38 @@ pub const Instruction = extern struct {
/// .data = data.asBytes(),
/// });
pub fn InstructionData(comptime Discriminant: type, comptime Data: type) type {
comptime {
if (@bitSizeOf(Discriminant) % 8 != 0) {
@panic("Discriminant bit size is not divisible by 8");
}
if (@bitSizeOf(Data) % 8 != 0) {
@panic("Data bit size is not divisible by 8");
}
}
return packed struct {
discriminant: Discriminant,
data: Data,
const Self = @This();
fn asBytes(self: *const Self) []const u8 {
return std.mem.asBytes(self)[0..(@sizeOf(Discriminant) + @sizeOf(Data))];
return std.mem.asBytes(self)[0..((@bitSizeOf(Discriminant) + @bitSizeOf(Data)) / 8)];
}
};
}

test "instruction: data transmute" {
const Discriminant = enum(u32) {
zero,
one,
two,
three,
};

const Data = packed struct {
a: u8,
b: u16,
c: u64,
};

const instruction = InstructionData(Discriminant, Data){ .discriminant = Discriminant.three, .data = Data{ .a = 1, .b = 2, .c = 3 } };
try std.testing.expectEqualSlices(u8, instruction.asBytes(), &[_]u8{ 3, 0, 0, 0, 1, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0 });
}

0 comments on commit d35d951

Please sign in to comment.