InternPool: use separate key for slices

This change eliminates some problematic recursive logic in InternPool,
and provides a safer API.
This commit is contained in:
mlugg
2024-02-01 16:58:52 +00:00
committed by Matthew Lugg
parent 5a3ae38f3b
commit 9eda6ccefc
11 changed files with 540 additions and 553 deletions

View File

@@ -1207,50 +1207,35 @@ pub const DeclGen = struct {
try writer.print("{x}", .{try dg.fmtIntLiteral(repr_ty, repr_val, location)});
if (!empty) try writer.writeByte(')');
},
.ptr => |ptr| {
if (ptr.len != .none) {
if (!location.isInitializer()) {
try writer.writeByte('(');
try dg.renderType(writer, ty);
try writer.writeByte(')');
}
try writer.writeByte('{');
}
const ptr_location = switch (ptr.len) {
.none => location,
else => initializer_type,
};
const ptr_ty = switch (ptr.len) {
.none => ty,
else => ty.slicePtrFieldType(mod),
};
const ptr_val = switch (ptr.len) {
.none => val,
else => val.slicePtr(mod),
};
switch (ptr.addr) {
.decl => |d| try dg.renderDeclValue(writer, ptr_ty, ptr_val, d, ptr_location),
.mut_decl => |md| try dg.renderDeclValue(writer, ptr_ty, ptr_val, md.decl, ptr_location),
.anon_decl => |decl_val| try dg.renderAnonDeclValue(writer, ptr_ty, ptr_val, decl_val, ptr_location),
.int => |int| {
try writer.writeAll("((");
try dg.renderType(writer, ptr_ty);
try writer.print("){x})", .{
try dg.fmtIntLiteral(Type.usize, Value.fromInterned(int), ptr_location),
});
},
.eu_payload,
.opt_payload,
.elem,
.field,
=> try dg.renderParentPtr(writer, ptr_val.ip_index, ptr_location),
.comptime_field => unreachable,
}
if (ptr.len != .none) {
try writer.writeAll(", ");
try dg.renderValue(writer, Type.usize, Value.fromInterned(ptr.len), initializer_type);
try writer.writeByte('}');
.slice => |slice| {
if (!location.isInitializer()) {
try writer.writeByte('(');
try dg.renderType(writer, ty);
try writer.writeByte(')');
}
try writer.writeByte('{');
try dg.renderValue(writer, ty.slicePtrFieldType(mod), Value.fromInterned(slice.ptr), initializer_type);
try writer.writeAll(", ");
try dg.renderValue(writer, Type.usize, Value.fromInterned(slice.len), initializer_type);
try writer.writeByte('}');
},
.ptr => |ptr| switch (ptr.addr) {
.decl => |d| try dg.renderDeclValue(writer, ty, val, d, location),
.mut_decl => |md| try dg.renderDeclValue(writer, ty, val, md.decl, location),
.anon_decl => |decl_val| try dg.renderAnonDeclValue(writer, ty, val, decl_val, location),
.int => |int| {
try writer.writeAll("((");
try dg.renderType(writer, ty);
try writer.print("){x})", .{
try dg.fmtIntLiteral(Type.usize, Value.fromInterned(int), location),
});
},
.eu_payload,
.opt_payload,
.elem,
.field,
=> try dg.renderParentPtr(writer, val.ip_index, location),
.comptime_field => unreachable,
},
.opt => |opt| {
const payload_ty = ty.optionalChild(mod);

View File

@@ -3644,6 +3644,7 @@ pub const Object = struct {
.empty_enum_value,
.float,
.ptr,
.slice,
.opt,
.aggregate,
.un,
@@ -3872,30 +3873,22 @@ pub const Object = struct {
128 => try o.builder.fp128Const(val.toFloat(f128, mod)),
else => unreachable,
},
.ptr => |ptr| {
const ptr_ty = switch (ptr.len) {
.none => ty,
else => ty.slicePtrFieldType(mod),
};
const ptr_val = switch (ptr.addr) {
.decl => |decl| try o.lowerDeclRefValue(ptr_ty, decl),
.mut_decl => |mut_decl| try o.lowerDeclRefValue(ptr_ty, mut_decl.decl),
.anon_decl => |anon_decl| try o.lowerAnonDeclRef(ptr_ty, anon_decl),
.int => |int| try o.lowerIntAsPtr(int),
.eu_payload,
.opt_payload,
.elem,
.field,
=> try o.lowerParentPtr(val),
.comptime_field => unreachable,
};
switch (ptr.len) {
.none => return ptr_val,
else => return o.builder.structConst(try o.lowerType(ty), &.{
ptr_val, try o.lowerValue(ptr.len),
}),
}
.ptr => |ptr| return switch (ptr.addr) {
.decl => |decl| try o.lowerDeclRefValue(ty, decl),
.mut_decl => |mut_decl| try o.lowerDeclRefValue(ty, mut_decl.decl),
.anon_decl => |anon_decl| try o.lowerAnonDeclRef(ty, anon_decl),
.int => |int| try o.lowerIntAsPtr(int),
.eu_payload,
.opt_payload,
.elem,
.field,
=> try o.lowerParentPtr(val),
.comptime_field => unreachable,
},
.slice => |slice| return o.builder.structConst(try o.lowerType(ty), &.{
try o.lowerValue(slice.ptr),
try o.lowerValue(slice.len),
}),
.opt => |opt| {
comptime assert(optional_layout_version == 3);
const payload_ty = ty.optionalChild(mod);

View File

@@ -855,18 +855,12 @@ const DeclGen = struct {
const int_ty = ty.intTagType(mod);
return try self.constant(int_ty, int_val, repr);
},
.ptr => |ptr| {
const ptr_ty = switch (ptr.len) {
.none => ty,
else => ty.slicePtrFieldType(mod),
};
const ptr_id = try self.constantPtr(ptr_ty, val);
if (ptr.len == .none) {
return ptr_id;
}
const len_id = try self.constant(Type.usize, Value.fromInterned(ptr.len), .indirect);
return try self.constructStruct(
.ptr => return self.constantPtr(ty, val),
.slice => |slice| {
const ptr_ty = ty.slicePtrFieldType(mod);
const ptr_id = try self.constantPtr(ptr_ty, Value.fromInterned(slice.ptr));
const len_id = try self.constant(Type.usize, Value.fromInterned(slice.len), .indirect);
return self.constructStruct(
ty,
&.{ ptr_ty, Type.usize },
&.{ ptr_id, len_id },