authorgravatar for mattnite@protonmail.comMatt Knight <mattnite@protonmail.com> 2023-02-18 14:10:27-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-02-18 21:10:27+02:00
log07630eb696a4c7097fadf9e0261411d591a82038
tree3ab641d04111e157d1f6d2b7c5fe53a0e1b0d24f
parentc993af62347faf124e97b16801356d34322a216e
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Value: implement writeToMemory for packed unions


2 files changed, 37 insertions(+), 0 deletions(-)

src/value.zig+19
...@@ -1340,6 +1340,14 @@ pub const Value = extern union {...@@ -1340,6 +1340,14 @@ pub const Value = extern union {
1340 const int = mod.global_error_set.get(val.castTag(.@"error").?.data.name).?;1340 const int = mod.global_error_set.get(val.castTag(.@"error").?.data.name).?;
1341 std.mem.writeInt(Int, buffer[0..@sizeOf(Int)], @intCast(Int, int), endian);1341 std.mem.writeInt(Int, buffer[0..@sizeOf(Int)], @intCast(Int, int), endian);
1342 },1342 },
1343 .Union => switch (ty.containerLayout()) {
1344 .Auto => unreachable,
1345 .Extern => @panic("TODO implement writeToMemory for extern unions"),
1346 .Packed => {
1347 const byte_count = (@intCast(usize, ty.bitSize(target)) + 7) / 8;
1348 writeToPackedMemory(val, ty, mod, buffer[0..byte_count], 0);
1349 },
1350 },
1343 else => @panic("TODO implement writeToMemory for more types"),1351 else => @panic("TODO implement writeToMemory for more types"),
1344 }1352 }
1345 }1353 }
...@@ -1430,6 +1438,17 @@ pub const Value = extern union {...@@ -1430,6 +1438,17 @@ pub const Value = extern union {
1430 }1438 }
1431 },1439 },
1432 },1440 },
1441 .Union => switch (ty.containerLayout()) {
1442 .Auto => unreachable, // Sema is supposed to have emitted a compile error already
1443 .Extern => unreachable, // Handled in non-packed writeToMemory
1444 .Packed => {
1445 const field_index = ty.unionTagFieldIndex(val.unionTag(), mod);
1446 const field_type = ty.unionFields().values()[field_index.?].ty;
1447 const field_val = val.fieldValue(field_type, field_index.?);
1448
1449 field_val.writeToPackedMemory(field_type, mod, buffer, bit_offset);
1450 },
1451 },
1433 else => @panic("TODO implement writeToPackedMemory for more types"),1452 else => @panic("TODO implement writeToPackedMemory for more types"),
1434 }1453 }
1435 }1454 }
test/behavior/comptime_memory.zig+18
...@@ -394,3 +394,21 @@ test "accessing reinterpreted memory of parent object" {...@@ -394,3 +394,21 @@ test "accessing reinterpreted memory of parent object" {
394 try testing.expect(b == expected);394 try testing.expect(b == expected);
395 }395 }
396}396}
397
398test "bitcast packed union to integer" {
399 const U = packed union {
400 x: u1,
401 y: u2,
402 };
403
404 comptime {
405 const a = U{ .x = 1 };
406 const b = U{ .y = 2 };
407 const cast_a = @bitCast(u2, a);
408 const cast_b = @bitCast(u2, b);
409
410 // truncated because the upper bit is garbage memory that we don't care about
411 try testing.expectEqual(@as(u1, 1), @truncate(u1, cast_a));
412 try testing.expectEqual(@as(u2, 2), cast_b);
413 }
414}