From a2315e8df140d8cc58da39942f471e9b8df19ba7 Mon Sep 17 00:00:00 2001 From: Taylan Kammer Date: Thu, 4 Jun 2026 18:43:55 +0200 Subject: Improve short string packing/unpacking. --- src/zisp/value.zig | 39 ++++++++++++++++++++++----------------- src/zisp/value/rune.zig | 12 +++++++----- src/zisp/value/sstr.zig | 12 +++++++----- 3 files changed, 36 insertions(+), 27 deletions(-) (limited to 'src') 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. -- cgit v1.2.3