aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/c
diff options
context:
space:
mode:
authorJacob Young <jacobly0@users.noreply.github.com>2024-04-11 23:40:15 -0400
committerJacob Young <jacobly0@users.noreply.github.com>2024-04-13 01:35:20 -0400
commitf1c0f42cddd344d6ac56569decb42eab2dfc07e5 (patch)
treeef0f626df3ac7339da7ba6394aecbd5770474874 /src/codegen/c
parent05d9755766e45e454a16440bfc9f98abef992247 (diff)
downloadzig-f1c0f42cddd344d6ac56569decb42eab2dfc07e5.tar.gz
zig-f1c0f42cddd344d6ac56569decb42eab2dfc07e5.zip
cbe: fix optional codegen
Also reduce ctype pool string memory usage, remove self assignments, and enable more warnings.
Diffstat (limited to 'src/codegen/c')
-rw-r--r--src/codegen/c/Type.zig328
1 files changed, 213 insertions, 115 deletions
diff --git a/src/codegen/c/Type.zig b/src/codegen/c/Type.zig
index 83d28dcb4f..357677522c 100644
--- a/src/codegen/c/Type.zig
+++ b/src/codegen/c/Type.zig
@@ -1,13 +1,33 @@
index: CType.Index,
+pub const @"void": CType = .{ .index = .void };
+pub const @"bool": CType = .{ .index = .bool };
+pub const @"i8": CType = .{ .index = .int8_t };
+pub const @"u8": CType = .{ .index = .uint8_t };
+pub const @"i16": CType = .{ .index = .int16_t };
+pub const @"u16": CType = .{ .index = .uint16_t };
+pub const @"i32": CType = .{ .index = .int32_t };
+pub const @"u32": CType = .{ .index = .uint32_t };
+pub const @"i64": CType = .{ .index = .int64_t };
+pub const @"u64": CType = .{ .index = .uint64_t };
+pub const @"i128": CType = .{ .index = .zig_i128 };
+pub const @"u128": CType = .{ .index = .zig_u128 };
+pub const @"isize": CType = .{ .index = .intptr_t };
+pub const @"usize": CType = .{ .index = .uintptr_t };
+pub const @"f16": CType = .{ .index = .zig_f16 };
+pub const @"f32": CType = .{ .index = .zig_f32 };
+pub const @"f64": CType = .{ .index = .zig_f64 };
+pub const @"f80": CType = .{ .index = .zig_f80 };
+pub const @"f128": CType = .{ .index = .zig_f128 };
+
pub fn fromPoolIndex(pool_index: usize) CType {
return .{ .index = @enumFromInt(CType.Index.first_pool_index + pool_index) };
}
pub fn toPoolIndex(ctype: CType) ?u32 {
- const pool_index, const is_basic =
+ const pool_index, const is_null =
@subWithOverflow(@intFromEnum(ctype.index), CType.Index.first_pool_index);
- return switch (is_basic) {
+ return switch (is_null) {
0 => pool_index,
1 => null,
};
@@ -710,20 +730,6 @@ pub const Kind = enum {
}
};
-pub const String = struct {
- index: String.Index,
-
- const Index = enum(u32) {
- _,
- };
-
- pub fn slice(string: String, pool: *const Pool) []const u8 {
- const start = pool.string_indices.items[@intFromEnum(string.index)];
- const end = pool.string_indices.items[@intFromEnum(string.index) + 1];
- return pool.string_bytes.items[start..end];
- }
-};
-
pub const Info = union(enum) {
basic: CType.Index,
pointer: Pointer,
@@ -766,7 +772,7 @@ pub const Info = union(enum) {
pub const AggregateTag = enum { @"enum", @"struct", @"union" };
pub const Field = struct {
- name: String,
+ name: Pool.String,
ctype: CType,
alignas: AlignAs,
@@ -812,12 +818,15 @@ pub const Info = union(enum) {
rhs_pool: *const Pool,
pool_adapter: anytype,
) bool {
- return std.meta.eql(lhs_field.alignas, rhs_field.alignas) and
- pool_adapter.eql(lhs_field.ctype, rhs_field.ctype) and std.mem.eql(
- u8,
- lhs_field.name.slice(lhs_pool),
- rhs_field.name.slice(rhs_pool),
- );
+ if (!std.meta.eql(lhs_field.alignas, rhs_field.alignas)) return false;
+ if (!pool_adapter.eql(lhs_field.ctype, rhs_field.ctype)) return false;
+ return if (lhs_field.name.toPoolSlice(lhs_pool)) |lhs_name|
+ if (rhs_field.name.toPoolSlice(rhs_pool)) |rhs_name|
+ std.mem.eql(u8, lhs_name, rhs_name)
+ else
+ false
+ else
+ lhs_field.name.index == rhs_field.name.index;
}
};
@@ -918,6 +927,86 @@ pub const Pool = struct {
const Map = std.AutoArrayHashMapUnmanaged(void, void);
+ pub const String = struct {
+ index: String.Index,
+
+ const FormatData = struct { string: String, pool: *const Pool };
+ fn format(
+ data: FormatData,
+ comptime fmt_str: []const u8,
+ _: std.fmt.FormatOptions,
+ writer: anytype,
+ ) @TypeOf(writer).Error!void {
+ if (fmt_str.len > 0) @compileError("invalid format string '" ++ fmt_str ++ "'");
+ if (data.string.toSlice(data.pool)) |slice|
+ try writer.writeAll(slice)
+ else
+ try writer.print("f{d}", .{@intFromEnum(data.string.index)});
+ }
+ pub fn fmt(str: String, pool: *const Pool) std.fmt.Formatter(format) {
+ return .{ .data = .{ .string = str, .pool = pool } };
+ }
+
+ fn fromUnnamed(index: u31) String {
+ return .{ .index = @enumFromInt(index) };
+ }
+
+ fn isNamed(str: String) bool {
+ return @intFromEnum(str.index) >= String.Index.first_named_index;
+ }
+
+ pub fn toSlice(str: String, pool: *const Pool) ?[]const u8 {
+ return str.toPoolSlice(pool) orelse if (str.isNamed()) @tagName(str.index) else null;
+ }
+
+ fn toPoolSlice(str: String, pool: *const Pool) ?[]const u8 {
+ if (str.toPoolIndex()) |pool_index| {
+ const start = pool.string_indices.items[pool_index + 0];
+ const end = pool.string_indices.items[pool_index + 1];
+ return pool.string_bytes.items[start..end];
+ } else return null;
+ }
+
+ fn fromPoolIndex(pool_index: usize) String {
+ return .{ .index = @enumFromInt(String.Index.first_pool_index + pool_index) };
+ }
+
+ fn toPoolIndex(str: String) ?u32 {
+ const pool_index, const is_null =
+ @subWithOverflow(@intFromEnum(str.index), String.Index.first_pool_index);
+ return switch (is_null) {
+ 0 => pool_index,
+ 1 => null,
+ };
+ }
+
+ const Index = enum(u32) {
+ array = first_named_index,
+ @"error",
+ is_null,
+ len,
+ payload,
+ ptr,
+ tag,
+ _,
+
+ const first_named_index: u32 = 1 << 31;
+ const first_pool_index: u32 = first_named_index + @typeInfo(String.Index).Enum.fields.len;
+ };
+
+ const Adapter = struct {
+ pool: *const Pool,
+ pub fn hash(_: @This(), slice: []const u8) Map.Hash {
+ return @truncate(Hasher.Impl.hash(1, slice));
+ }
+ pub fn eql(string_adapter: @This(), lhs_slice: []const u8, _: void, rhs_index: usize) bool {
+ const rhs_string = String.fromPoolIndex(rhs_index);
+ const rhs_slice = rhs_string.toPoolSlice(string_adapter.pool).?;
+ return std.mem.eql(u8, lhs_slice, rhs_slice);
+ }
+ };
+ };
+
pub const empty: Pool = .{
.map = .{},
.items = .{},
@@ -1200,26 +1289,26 @@ pub const Pool = struct {
kind: Kind,
) !CType {
switch (int_info.bits) {
- 0 => return .{ .index = .void },
+ 0 => return CType.void,
1...8 => switch (int_info.signedness) {
- .unsigned => return .{ .index = .uint8_t },
- .signed => return .{ .index = .int8_t },
+ .signed => return CType.i8,
+ .unsigned => return CType.u8,
},
9...16 => switch (int_info.signedness) {
- .unsigned => return .{ .index = .uint16_t },
- .signed => return .{ .index = .int16_t },
+ .signed => return CType.i16,
+ .unsigned => return CType.u16,
},
17...32 => switch (int_info.signedness) {
- .unsigned => return .{ .index = .uint32_t },
- .signed => return .{ .index = .int32_t },
+ .signed => return CType.i32,
+ .unsigned => return CType.u32,
},
33...64 => switch (int_info.signedness) {
- .unsigned => return .{ .index = .uint64_t },
- .signed => return .{ .index = .int64_t },
+ .signed => return CType.i64,
+ .unsigned => return CType.u64,
},
65...128 => switch (int_info.signedness) {
- .unsigned => return .{ .index = .zig_u128 },
- .signed => return .{ .index = .zig_i128 },
+ .signed => return CType.i128,
+ .unsigned => return CType.u128,
},
else => {
const target = &mod.resolved_target.result;
@@ -1235,7 +1324,7 @@ pub const Pool = struct {
if (!kind.isParameter()) return array_ctype;
var fields = [_]Info.Field{
.{
- .name = try pool.string(allocator, "array"),
+ .name = .{ .index = .array },
.ctype = array_ctype,
.alignas = AlignAs.fromAbiAlignment(abi_align),
},
@@ -1267,19 +1356,19 @@ pub const Pool = struct {
.null_type,
.undefined_type,
.enum_literal_type,
- => return .{ .index = .void },
- .u1_type, .u8_type => return .{ .index = .uint8_t },
- .i8_type => return .{ .index = .int8_t },
- .u16_type => return .{ .index = .uint16_t },
- .i16_type => return .{ .index = .int16_t },
- .u29_type, .u32_type => return .{ .index = .uint32_t },
- .i32_type => return .{ .index = .int32_t },
- .u64_type => return .{ .index = .uint64_t },
- .i64_type => return .{ .index = .int64_t },
- .u80_type, .u128_type => return .{ .index = .zig_u128 },
- .i128_type => return .{ .index = .zig_i128 },
- .usize_type => return .{ .index = .uintptr_t },
- .isize_type => return .{ .index = .intptr_t },
+ => return CType.void,
+ .u1_type, .u8_type => return CType.u8,
+ .i8_type => return CType.i8,
+ .u16_type => return CType.u16,
+ .i16_type => return CType.i16,
+ .u29_type, .u32_type => return CType.u32,
+ .i32_type => return CType.i32,
+ .u64_type => return CType.u64,
+ .i64_type => return CType.i64,
+ .u80_type, .u128_type => return CType.u128,
+ .i128_type => return CType.i128,
+ .usize_type => return CType.usize,
+ .isize_type => return CType.isize,
.c_char_type => return .{ .index = .char },
.c_short_type => return .{ .index = .short },
.c_ushort_type => return .{ .index = .@"unsigned short" },
@@ -1290,12 +1379,12 @@ pub const Pool = struct {
.c_longlong_type => return .{ .index = .@"long long" },
.c_ulonglong_type => return .{ .index = .@"unsigned long long" },
.c_longdouble_type => return .{ .index = .@"long double" },
- .f16_type => return .{ .index = .zig_f16 },
- .f32_type => return .{ .index = .zig_f32 },
- .f64_type => return .{ .index = .zig_f64 },
- .f80_type => return .{ .index = .zig_f80 },
- .f128_type => return .{ .index = .zig_f128 },
- .bool_type, .optional_noreturn_type => return .{ .index = .bool },
+ .f16_type => return CType.f16,
+ .f32_type => return CType.f32,
+ .f64_type => return CType.f64,
+ .f80_type => return CType.f80,
+ .f128_type => return CType.f128,
+ .bool_type, .optional_noreturn_type => return CType.bool,
.noreturn_type,
.anyframe_type,
.generic_poison_type,
@@ -1324,17 +1413,17 @@ pub const Pool = struct {
}, mod, kind),
.manyptr_u8_type,
=> return pool.getPointer(allocator, .{
- .elem_ctype = .{ .index = .uint8_t },
+ .elem_ctype = CType.u8,
}),
.manyptr_const_u8_type,
.manyptr_const_u8_sentinel_0_type,
=> return pool.getPointer(allocator, .{
- .elem_ctype = .{ .index = .uint8_t },
+ .elem_ctype = CType.u8,
.@"const" = true,
}),
.single_const_pointer_to_comptime_int_type,
=> return pool.getPointer(allocator, .{
- .elem_ctype = .{ .index = .void },
+ .elem_ctype = CType.void,
.@"const" = true,
}),
.slice_const_u8_type,
@@ -1343,16 +1432,16 @@ pub const Pool = struct {
const target = &mod.resolved_target.result;
var fields = [_]Info.Field{
.{
- .name = try pool.string(allocator, "ptr"),
+ .name = .{ .index = .ptr },
.ctype = try pool.getPointer(allocator, .{
- .elem_ctype = .{ .index = .uint8_t },
+ .elem_ctype = CType.u8,
.@"const" = true,
}),
.alignas = AlignAs.fromAbiAlignment(Type.ptrAbiAlignment(target.*)),
},
.{
- .name = try pool.string(allocator, "len"),
- .ctype = .{ .index = .uintptr_t },
+ .name = .{ .index = .len },
+ .ctype = CType.usize,
.alignas = AlignAs.fromAbiAlignment(
Type.intAbiAlignment(target.ptrBitWidth(), target.*),
),
@@ -1442,7 +1531,7 @@ pub const Pool = struct {
const target = &mod.resolved_target.result;
var fields = [_]Info.Field{
.{
- .name = try pool.string(allocator, "ptr"),
+ .name = .{ .index = .ptr },
.ctype = try pool.fromType(
allocator,
scratch,
@@ -1454,8 +1543,8 @@ pub const Pool = struct {
.alignas = AlignAs.fromAbiAlignment(Type.ptrAbiAlignment(target.*)),
},
.{
- .name = try pool.string(allocator, "len"),
- .ctype = .{ .index = .uintptr_t },
+ .name = .{ .index = .len },
+ .ctype = CType.usize,
.alignas = AlignAs.fromAbiAlignment(
Type.intAbiAlignment(target.ptrBitWidth(), target.*),
),
@@ -1466,7 +1555,7 @@ pub const Pool = struct {
},
.array_type => |array_info| {
const len = array_info.lenIncludingSentinel();
- if (len == 0) return .{ .index = .void };
+ if (len == 0) return CType.void;
const elem_type = Type.fromInterned(array_info.child);
const elem_ctype = try pool.fromType(
allocator,
@@ -1476,7 +1565,7 @@ pub const Pool = struct {
mod,
kind.noParameter(),
);
- if (elem_ctype.index == .void) return .{ .index = .void };
+ if (elem_ctype.index == .void) return CType.void;
const array_ctype = try pool.getArray(allocator, .{
.elem_ctype = elem_ctype,
.len = len,
@@ -1484,7 +1573,7 @@ pub const Pool = struct {
if (!kind.isParameter()) return array_ctype;
var fields = [_]Info.Field{
.{
- .name = try pool.string(allocator, "array"),
+ .name = .{ .index = .array },
.ctype = array_ctype,
.alignas = AlignAs.fromAbiAlignment(elem_type.abiAlignment(zcu)),
},
@@ -1492,7 +1581,7 @@ pub const Pool = struct {
return pool.fromFields(allocator, .@"struct", &fields, kind);
},
.vector_type => |vector_info| {
- if (vector_info.len == 0) return .{ .index = .void };
+ if (vector_info.len == 0) return CType.void;
const elem_type = Type.fromInterned(vector_info.child);
const elem_ctype = try pool.fromType(
allocator,
@@ -1502,7 +1591,7 @@ pub const Pool = struct {
mod,
kind.noParameter(),
);
- if (elem_ctype.index == .void) return .{ .index = .void };
+ if (elem_ctype.index == .void) return CType.void;
const vector_ctype = try pool.getVector(allocator, .{
.elem_ctype = elem_ctype,
.len = vector_info.len,
@@ -1510,7 +1599,7 @@ pub const Pool = struct {
if (!kind.isParameter()) return vector_ctype;
var fields = [_]Info.Field{
.{
- .name = try pool.string(allocator, "array"),
+ .name = .{ .index = .array },
.ctype = vector_ctype,
.alignas = AlignAs.fromAbiAlignment(elem_type.abiAlignment(zcu)),
},
@@ -1518,7 +1607,7 @@ pub const Pool = struct {
return pool.fromFields(allocator, .@"struct", &fields, kind);
},
.opt_type => |payload_type| {
- if (ip.isNoReturn(payload_type)) return .{ .index = .void };
+ if (ip.isNoReturn(payload_type)) return CType.void;
const payload_ctype = try pool.fromType(
allocator,
scratch,
@@ -1527,7 +1616,7 @@ pub const Pool = struct {
mod,
kind.noParameter(),
);
- if (payload_ctype.index == .void) return .{ .index = .bool };
+ if (payload_ctype.index == .void) return CType.bool;
switch (payload_type) {
.anyerror_type => return payload_ctype,
else => switch (ip.indexToKey(payload_type)) {
@@ -1539,12 +1628,12 @@ pub const Pool = struct {
}
var fields = [_]Info.Field{
.{
- .name = try pool.string(allocator, "is_null"),
- .ctype = .{ .index = .bool },
+ .name = .{ .index = .is_null },
+ .ctype = CType.bool,
.alignas = AlignAs.fromAbiAlignment(.@"1"),
},
.{
- .name = try pool.string(allocator, "payload"),
+ .name = .{ .index = .payload },
.ctype = payload_ctype,
.alignas = AlignAs.fromAbiAlignment(
Type.fromInterned(payload_type).abiAlignment(zcu),
@@ -1574,14 +1663,14 @@ pub const Pool = struct {
const target = &mod.resolved_target.result;
var fields = [_]Info.Field{
.{
- .name = try pool.string(allocator, "error"),
+ .name = .{ .index = .@"error" },
.ctype = error_set_ctype,
.alignas = AlignAs.fromAbiAlignment(
Type.intAbiAlignment(error_set_bits, target.*),
),
},
.{
- .name = try pool.string(allocator, "payload"),
+ .name = .{ .index = .payload },
.ctype = payload_ctype,
.alignas = AlignAs.fromAbiAlignment(payload_type.abiAlignment(zcu)),
},
@@ -1600,7 +1689,7 @@ pub const Pool = struct {
if (kind.isForward()) return if (ty.hasRuntimeBitsIgnoreComptime(zcu))
fwd_decl
else
- .{ .index = .void };
+ CType.void;
const scratch_top = scratch.items.len;
defer scratch.shrinkRetainingCapacity(scratch_top);
try scratch.ensureUnusedCapacity(
@@ -1627,7 +1716,7 @@ pub const Pool = struct {
.unwrap()) |field_name|
try pool.string(allocator, field_name.toSlice(ip))
else
- try pool.fmt(allocator, "f{d}", .{field_index});
+ String.fromUnnamed(@intCast(field_index));
const field_alignas = AlignAs.fromAlignment(.{
.@"align" = loaded_struct.fieldAlign(ip, field_index),
.abi = field_type.abiAlignment(zcu),
@@ -1644,7 +1733,7 @@ pub const Pool = struct {
scratch.items.len - scratch_top,
@typeInfo(Field).Struct.fields.len,
));
- if (fields_len == 0) return .{ .index = .void };
+ if (fields_len == 0) return CType.void;
try pool.ensureUnusedCapacity(allocator, 1);
const extra_index = try pool.addHashedExtra(allocator, &hasher, Aggregate, .{
.fwd_decl = fwd_decl.index,
@@ -1700,7 +1789,7 @@ pub const Pool = struct {
scratch.items.len - scratch_top,
@typeInfo(Field).Struct.fields.len,
));
- if (fields_len == 0) return .{ .index = .void };
+ if (fields_len == 0) return CType.void;
if (kind.isForward()) {
try pool.ensureUnusedCapacity(allocator, 1);
const extra_index = try pool.addHashedExtra(
@@ -1739,7 +1828,7 @@ pub const Pool = struct {
if (kind.isForward()) return if (ty.hasRuntimeBitsIgnoreComptime(zcu))
fwd_decl
else
- .{ .index = .void };
+ CType.void;
const loaded_tag = loaded_union.loadTagType(ip);
const scratch_top = scratch.items.len;
defer scratch.shrinkRetainingCapacity(scratch_top);
@@ -1786,7 +1875,7 @@ pub const Pool = struct {
@typeInfo(Field).Struct.fields.len,
));
if (!has_tag) {
- if (fields_len == 0) return .{ .index = .void };
+ if (fields_len == 0) return CType.void;
try pool.ensureUnusedCapacity(allocator, 1);
const extra_index = try pool.addHashedExtra(
allocator,
@@ -1813,7 +1902,7 @@ pub const Pool = struct {
);
if (tag_ctype.index != .void) {
struct_fields[struct_fields_len] = .{
- .name = try pool.string(allocator, "tag"),
+ .name = .{ .index = .tag },
.ctype = tag_ctype,
.alignas = AlignAs.fromAbiAlignment(tag_type.abiAlignment(zcu)),
};
@@ -1846,14 +1935,14 @@ pub const Pool = struct {
};
if (payload_ctype.index != .void) {
struct_fields[struct_fields_len] = .{
- .name = try pool.string(allocator, "payload"),
+ .name = .{ .index = .payload },
.ctype = payload_ctype,
.alignas = AlignAs.fromAbiAlignment(payload_align),
};
struct_fields_len += 1;
}
}
- if (struct_fields_len == 0) return .{ .index = .void };
+ if (struct_fields_len == 0) return CType.void;
sortFields(struct_fields[0..struct_fields_len]);
return pool.getAggregate(allocator, .{
.tag = .@"struct",
@@ -1867,7 +1956,7 @@ pub const Pool = struct {
}, mod, kind),
}
},
- .opaque_type => return .{ .index = .void },
+ .opaque_type => return CType.void,
.enum_type => return pool.fromType(
allocator,
scratch,
@@ -1876,7 +1965,7 @@ pub const Pool = struct {
mod,
kind,
),
- .func_type => |func_info| if (func_info.is_generic) return .{ .index = .void } else {
+ .func_type => |func_info| if (func_info.is_generic) return CType.void else {
const scratch_top = scratch.items.len;
defer scratch.shrinkRetainingCapacity(scratch_top);
try scratch.ensureUnusedCapacity(allocator, func_info.param_types.len);
@@ -1890,7 +1979,7 @@ pub const Pool = struct {
zcu,
mod,
kind.asParameter(),
- ) else .{ .index = .void };
+ ) else CType.void;
for (0..func_info.param_types.len) |param_index| {
const param_type = Type.fromInterned(
func_info.param_types.get(ip)[param_index],
@@ -2024,7 +2113,10 @@ pub const Pool = struct {
});
for (0..fields.len) |field_index| {
const field = fields.at(field_index, source_pool);
- const field_name = try pool.string(allocator, field.name.slice(source_pool));
+ const field_name = if (field.name.toPoolSlice(source_pool)) |slice|
+ try pool.string(allocator, slice)
+ else
+ field.name;
pool.addExtraAssumeCapacity(Field, .{
.name = field_name.index,
.ctype = pool_adapter.copy(field.ctype).index,
@@ -2054,7 +2146,10 @@ pub const Pool = struct {
});
for (0..aggregate_info.fields.len) |field_index| {
const field = aggregate_info.fields.at(field_index, source_pool);
- const field_name = try pool.string(allocator, field.name.slice(source_pool));
+ const field_name = if (field.name.toPoolSlice(source_pool)) |slice|
+ try pool.string(allocator, slice)
+ else
+ field.name;
pool.addExtraAssumeCapacity(Field, .{
.name = field_name.index,
.ctype = pool_adapter.copy(field.ctype).index,
@@ -2082,8 +2177,8 @@ pub const Pool = struct {
return .{ ctype, gop.found_existing };
}
- pub fn string(pool: *Pool, allocator: std.mem.Allocator, str: []const u8) !String {
- try pool.string_bytes.appendSlice(allocator, str);
+ pub fn string(pool: *Pool, allocator: std.mem.Allocator, slice: []const u8) !String {
+ try pool.string_bytes.appendSlice(allocator, slice);
return pool.trailingString(allocator);
}
@@ -2111,12 +2206,15 @@ pub const Pool = struct {
fn updateExtra(hasher: *Hasher, comptime Extra: type, extra: Extra, pool: *const Pool) void {
inline for (@typeInfo(Extra).Struct.fields) |field| {
const value = @field(extra, field.name);
- hasher.update(switch (field.type) {
+ switch (field.type) {
Pool.Tag, String, CType => unreachable,
- CType.Index => (CType{ .index = value }).hash(pool),
- String.Index => (String{ .index = value }).slice(pool),
- else => value,
- });
+ CType.Index => hasher.update((CType{ .index = value }).hash(pool)),
+ String.Index => if ((String{ .index = value }).toPoolSlice(pool)) |slice|
+ hasher.update(slice)
+ else
+ hasher.update(@intFromEnum(value)),
+ else => hasher.update(value),
+ }
}
}
fn update(hasher: *Hasher, data: anytype) void {
@@ -2231,30 +2329,30 @@ pub const Pool = struct {
}
fn trailingString(pool: *Pool, allocator: std.mem.Allocator) !String {
- const StringAdapter = struct {
- pool: *const Pool,
- pub fn hash(_: @This(), slice: []const u8) Map.Hash {
- return @truncate(Hasher.Impl.hash(1, slice));
- }
- pub fn eql(string_adapter: @This(), lhs_slice: []const u8, _: void, rhs_index: usize) bool {
- const rhs_string: String = .{ .index = @enumFromInt(rhs_index) };
- const rhs_slice = rhs_string.slice(string_adapter.pool);
- return std.mem.eql(u8, lhs_slice, rhs_slice);
- }
- };
+ const start = pool.string_indices.getLast();
+ const slice: []const u8 = pool.string_bytes.items[start..];
+ if (slice.len >= 2 and slice[0] == 'f' and switch (slice[1]) {
+ '0' => slice.len == 2,
+ '1'...'9' => true,
+ else => false,
+ }) if (std.fmt.parseInt(u31, slice[1..], 10)) |unnamed| {
+ pool.string_bytes.shrinkRetainingCapacity(start);
+ return String.fromUnnamed(unnamed);
+ } else |_| {};
+ if (std.meta.stringToEnum(String.Index, slice)) |index| {
+ pool.string_bytes.shrinkRetainingCapacity(start);
+ return .{ .index = index };
+ }
+
try pool.string_map.ensureUnusedCapacity(allocator, 1);
try pool.string_indices.ensureUnusedCapacity(allocator, 1);
- const start = pool.string_indices.getLast();
- const gop = pool.string_map.getOrPutAssumeCapacityAdapted(
- @as([]const u8, pool.string_bytes.items[start..]),
- StringAdapter{ .pool = pool },
- );
+ const gop = pool.string_map.getOrPutAssumeCapacityAdapted(slice, String.Adapter{ .pool = pool });
if (gop.found_existing)
pool.string_bytes.shrinkRetainingCapacity(start)
else
pool.string_indices.appendAssumeCapacity(@intCast(pool.string_bytes.items.len));
- return .{ .index = @enumFromInt(gop.index) };
+ return String.fromPoolIndex(gop.index);
}
const Item = struct {