diff options
| author | Taylan Kammer <taylan.kammer@gmail.com> | 2026-06-04 18:43:55 +0200 |
|---|---|---|
| committer | Taylan Kammer <taylan.kammer@gmail.com> | 2026-06-04 18:43:55 +0200 |
| commit | a2315e8df140d8cc58da39942f471e9b8df19ba7 (patch) | |
| tree | edc47f0c55f8e7c292905e4e0af30a2ef61e0511 | |
| parent | 3281cb8192d5dad2625ae5a106f6a6d1a2a975c7 (diff) | |
Improve short string packing/unpacking.
| -rw-r--r-- | src/zisp/value.zig | 39 | ||||
| -rw-r--r-- | src/zisp/value/rune.zig | 12 | ||||
| -rw-r--r-- | src/zisp/value/sstr.zig | 12 |
3 files changed, 36 insertions, 27 deletions
diff --git a/src/zisp/value.zig b/src/zisp/value.zig index 3450bfd..4ecc70f 100644 --- a/src/zisp/value.zig +++ b/src/zisp/value.zig @@ -272,6 +272,22 @@ pub const Value = packed union { _: u13 = non_ptr, }, + /// For initializing and reading short strings. + sstr: packed struct { + // actually [6]u8 but packed struct cannot contain arrays + bytes: u48, + _tag: u3 = 0b001, + _: u13 = non_ptr, + }, + + /// For initializing and reading small rats (rational numbers). + srat: packed struct { + q: u24, + p: u25, + _tag: u2 = 0b01, + _: u13 = non_ptr, + }, + // TODO: Use a general Small Value type registration mechanism. /// For initializing and reading characters. char: packed struct { @@ -290,22 +306,6 @@ pub const Value = packed union { _: u13 = non_ptr, }, - /// For initializing and reading short strings. - sstr: packed struct { - // actually [6]u8 but packed struct cannot contain arrays - string: u48, - _tag: u3 = 0b001, - _: u13 = non_ptr, - }, - - /// For initializing and reading small rats (rational numbers). - srat: packed struct { - q: u24, - p: u25, - _tag: u2 = 0b01, - _: u13 = non_ptr, - }, - // Disjoint masks where a specific bit or bit-group are set. // zig fmt: off const mask_sign: u64 = 1 << 63 ; // 1 sign bit @@ -329,7 +329,12 @@ pub const Value = packed union { } /// To treat the 64-bit value as an 8-byte array. - pub fn bytes(v: *const Value) *const [8]u8 { + pub fn bufRO(v: *const Value) *const [8]u8 { + return @ptrCast(v); + } + + /// To treat the 64-bit value as an 8-byte array. + pub fn bufRW(v: *Value) *[8]u8 { return @ptrCast(v); } diff --git a/src/zisp/value/rune.zig b/src/zisp/value/rune.zig index 6ce1bc3..89f6467 100644 --- a/src/zisp/value/rune.zig +++ b/src/zisp/value/rune.zig @@ -38,18 +38,20 @@ pub fn pack(s: []const u8) Value { return packForced(s); } +const Rune = @FieldType(Value, "rune"); +const ofs = @offsetOf(Rune, "name"); + pub fn packForced(s: []const u8) Value { std.debug.assert(s.len <= 6); - var buf: [6]u8 = @splat(0); - @memcpy(buf[0..s.len], s); - return .{ .rune = .{ .name = @bitCast(buf) } }; + var v = Value{ .rune = .{ .name = 0 } }; + @memcpy(v.bufRW()[ofs .. ofs + s.len], s); + return v; } pub fn unpack(v: *const Value) []const u8 { assert(v.*); - const buf = v.bytes(); const len = value.sstrLen(v.bits); - return buf[0..len]; + return v.bufRO()[ofs .. ofs + len]; } // Zisp API diff --git a/src/zisp/value/sstr.zig b/src/zisp/value/sstr.zig index 2c4db4b..edc61a8 100644 --- a/src/zisp/value/sstr.zig +++ b/src/zisp/value/sstr.zig @@ -30,18 +30,20 @@ fn assertValidSstr(s: []const u8) void { } } +const Sstr = @FieldType(Value, "sstr"); +const ofs = @offsetOf(Sstr, "bytes"); + pub fn pack(s: []const u8) Value { assertValidSstr(s); - var buf: [6]u8 = @splat(0); - @memcpy(buf[0..s.len], s); - return .{ .sstr = .{ .string = @bitCast(buf) } }; + var v = Value{ .sstr = .{ .bytes = 0 } }; + @memcpy(v.bufRW()[ofs .. ofs + s.len], s); + return v; } pub fn unpack(v: *const Value) []const u8 { assert(v.*); - const buf = v.bytes(); const len = value.sstrLen(v.bits); - return buf[0..len]; + return v.bufRO()[ofs .. ofs + len]; } // No Zisp API for sstr specifically, since it's a string. See string.zig. |
