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:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 },
|
||||
|
||||
Reference in New Issue
Block a user