#ptrFromInt bug?

1 messages · Page 1 of 1 (latest)

solar grail
#

I have a function, that casts bytes to a type; well I'm slowly working on it. While working with pointer casting and giving up on slices (if []u8 has a defined memory layout correct me.) i tried also [*c]u8, which in comptime works just fine, but for runtime values, returns null. Is there any fancy pointer checking/ signing going on?

#
const std = @import("std");

pub fn bitCast(comptime T: type, bytes: []const u8, offset: usize, endian: std.builtin.Endian) ?T {
    const type_info = @typeInfo(T);
    const type_size = @bitSizeOf(T);
    std.debug.assert(bytes.len * 8 >= offset + type_size);

    switch (type_info) {
        .@"anyframe",
        // ...
        => @compileError(std.fmt.comptimePrint(
            "Type `{}` doesn't have a defined memory layout",
            .{T},
        )),
        .type => return type,
        .void => return void{},
        .bool => return std.mem.readPackedInt(u1, bytes, offset, endian) == 1,
        .int => return std.mem.readPackedInt(T, bytes, offset, endian),
        .float => |fi| return @bitCast(std.mem.readPackedInt(std.meta.Int(.unsigned, fi.bits), bytes, offset, endian)),
        .pointer => |pi| {
            if (pi.size == .slice) @compileError("Slices aren't allowed");
            const val = std.mem.readPackedInt(usize, bytes, offset, endian);
            if ((!pi.is_allowzero) and val == 0) return null;
            return @ptrFromInt(val);
        },
        else => {
            // @compileLog(type_info, type_size);
            unreachable;
        },
    }
}

test "bitCast" {
   const a =
        @as(?[*c]u8, @as([*c]u8, @ptrFromInt(1)));
    // when b is evaluated in runtime it always returns null only for [*c]u8 type
    const b =
        // comptime // if we force b, to be calculated in comptime everything works, and the following test passes.
        bitCast([*c]u8, &.{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, 0, .big);
    std.log.err("{?*} {?*}", .{ a, b });
    try std.testing.expectEqual(a, b);
}