Zcu: introduce PerThread and pass to all the functions
This commit is contained in:
@@ -54,46 +54,44 @@ pub const MutableValue = union(enum) {
|
||||
payload: *MutableValue,
|
||||
};
|
||||
|
||||
pub fn intern(mv: MutableValue, zcu: *Zcu, arena: Allocator) Allocator.Error!Value {
|
||||
const ip = &zcu.intern_pool;
|
||||
const gpa = zcu.gpa;
|
||||
pub fn intern(mv: MutableValue, pt: Zcu.PerThread, arena: Allocator) Allocator.Error!Value {
|
||||
return Value.fromInterned(switch (mv) {
|
||||
.interned => |ip_index| ip_index,
|
||||
.eu_payload => |sv| try ip.get(gpa, .{ .error_union = .{
|
||||
.eu_payload => |sv| try pt.intern(.{ .error_union = .{
|
||||
.ty = sv.ty,
|
||||
.val = .{ .payload = (try sv.child.intern(zcu, arena)).toIntern() },
|
||||
.val = .{ .payload = (try sv.child.intern(pt, arena)).toIntern() },
|
||||
} }),
|
||||
.opt_payload => |sv| try ip.get(gpa, .{ .opt = .{
|
||||
.opt_payload => |sv| try pt.intern(.{ .opt = .{
|
||||
.ty = sv.ty,
|
||||
.val = (try sv.child.intern(zcu, arena)).toIntern(),
|
||||
.val = (try sv.child.intern(pt, arena)).toIntern(),
|
||||
} }),
|
||||
.repeated => |sv| try ip.get(gpa, .{ .aggregate = .{
|
||||
.repeated => |sv| try pt.intern(.{ .aggregate = .{
|
||||
.ty = sv.ty,
|
||||
.storage = .{ .repeated_elem = (try sv.child.intern(zcu, arena)).toIntern() },
|
||||
.storage = .{ .repeated_elem = (try sv.child.intern(pt, arena)).toIntern() },
|
||||
} }),
|
||||
.bytes => |b| try ip.get(gpa, .{ .aggregate = .{
|
||||
.bytes => |b| try pt.intern(.{ .aggregate = .{
|
||||
.ty = b.ty,
|
||||
.storage = .{ .bytes = try ip.getOrPutString(gpa, b.data, .maybe_embedded_nulls) },
|
||||
.storage = .{ .bytes = try pt.zcu.intern_pool.getOrPutString(pt.zcu.gpa, b.data, .maybe_embedded_nulls) },
|
||||
} }),
|
||||
.aggregate => |a| {
|
||||
const elems = try arena.alloc(InternPool.Index, a.elems.len);
|
||||
for (a.elems, elems) |mut_elem, *interned_elem| {
|
||||
interned_elem.* = (try mut_elem.intern(zcu, arena)).toIntern();
|
||||
interned_elem.* = (try mut_elem.intern(pt, arena)).toIntern();
|
||||
}
|
||||
return Value.fromInterned(try ip.get(gpa, .{ .aggregate = .{
|
||||
return Value.fromInterned(try pt.intern(.{ .aggregate = .{
|
||||
.ty = a.ty,
|
||||
.storage = .{ .elems = elems },
|
||||
} }));
|
||||
},
|
||||
.slice => |s| try ip.get(gpa, .{ .slice = .{
|
||||
.slice => |s| try pt.intern(.{ .slice = .{
|
||||
.ty = s.ty,
|
||||
.ptr = (try s.ptr.intern(zcu, arena)).toIntern(),
|
||||
.len = (try s.len.intern(zcu, arena)).toIntern(),
|
||||
.ptr = (try s.ptr.intern(pt, arena)).toIntern(),
|
||||
.len = (try s.len.intern(pt, arena)).toIntern(),
|
||||
} }),
|
||||
.un => |u| try ip.get(gpa, .{ .un = .{
|
||||
.un => |u| try pt.intern(.{ .un = .{
|
||||
.ty = u.ty,
|
||||
.tag = u.tag,
|
||||
.val = (try u.payload.intern(zcu, arena)).toIntern(),
|
||||
.val = (try u.payload.intern(pt, arena)).toIntern(),
|
||||
} }),
|
||||
});
|
||||
}
|
||||
@@ -108,13 +106,13 @@ pub const MutableValue = union(enum) {
|
||||
/// If `!allow_repeated`, the `repeated` representation will not be used.
|
||||
pub fn unintern(
|
||||
mv: *MutableValue,
|
||||
zcu: *Zcu,
|
||||
pt: Zcu.PerThread,
|
||||
arena: Allocator,
|
||||
allow_bytes: bool,
|
||||
allow_repeated: bool,
|
||||
) Allocator.Error!void {
|
||||
const zcu = pt.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
const gpa = zcu.gpa;
|
||||
switch (mv.*) {
|
||||
.interned => |ip_index| switch (ip.indexToKey(ip_index)) {
|
||||
.opt => |opt| if (opt.val != .none) {
|
||||
@@ -170,7 +168,7 @@ pub const MutableValue = union(enum) {
|
||||
} else {
|
||||
const mut_elems = try arena.alloc(MutableValue, len);
|
||||
for (bytes.toSlice(len, ip), mut_elems) |b, *mut_elem| {
|
||||
mut_elem.* = .{ .interned = try ip.get(gpa, .{ .int = .{
|
||||
mut_elem.* = .{ .interned = try pt.intern(.{ .int = .{
|
||||
.ty = .u8_type,
|
||||
.storage = .{ .u64 = b },
|
||||
} }) };
|
||||
@@ -221,12 +219,12 @@ pub const MutableValue = union(enum) {
|
||||
switch (type_tag) {
|
||||
.Array, .Vector => {
|
||||
const elem_ty = ip.childType(ty_ip);
|
||||
const undef_elem = try ip.get(gpa, .{ .undef = elem_ty });
|
||||
const undef_elem = try pt.intern(.{ .undef = elem_ty });
|
||||
@memset(elems[0..@intCast(len_no_sent)], .{ .interned = undef_elem });
|
||||
},
|
||||
.Struct => for (elems[0..@intCast(len_no_sent)], 0..) |*mut_elem, i| {
|
||||
const field_ty = ty.structFieldType(i, zcu).toIntern();
|
||||
mut_elem.* = .{ .interned = try ip.get(gpa, .{ .undef = field_ty }) };
|
||||
mut_elem.* = .{ .interned = try pt.intern(.{ .undef = field_ty }) };
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
@@ -238,7 +236,7 @@ pub const MutableValue = union(enum) {
|
||||
} else {
|
||||
const repeated_val = try arena.create(MutableValue);
|
||||
repeated_val.* = .{
|
||||
.interned = try ip.get(gpa, .{ .undef = ip.childType(ty_ip) }),
|
||||
.interned = try pt.intern(.{ .undef = ip.childType(ty_ip) }),
|
||||
};
|
||||
mv.* = .{ .repeated = .{
|
||||
.ty = ty_ip,
|
||||
@@ -248,11 +246,8 @@ pub const MutableValue = union(enum) {
|
||||
},
|
||||
.Union => {
|
||||
const payload = try arena.create(MutableValue);
|
||||
const backing_ty = try Type.fromInterned(ty_ip).unionBackingType(zcu);
|
||||
payload.* = .{ .interned = try ip.get(
|
||||
gpa,
|
||||
.{ .undef = backing_ty.toIntern() },
|
||||
) };
|
||||
const backing_ty = try Type.fromInterned(ty_ip).unionBackingType(pt);
|
||||
payload.* = .{ .interned = try pt.intern(.{ .undef = backing_ty.toIntern() }) };
|
||||
mv.* = .{ .un = .{
|
||||
.ty = ty_ip,
|
||||
.tag = .none,
|
||||
@@ -264,8 +259,8 @@ pub const MutableValue = union(enum) {
|
||||
if (ptr_ty.flags.size != .Slice) return;
|
||||
const ptr = try arena.create(MutableValue);
|
||||
const len = try arena.create(MutableValue);
|
||||
ptr.* = .{ .interned = try ip.get(gpa, .{ .undef = ip.slicePtrType(ty_ip) }) };
|
||||
len.* = .{ .interned = try ip.get(gpa, .{ .undef = .usize_type }) };
|
||||
ptr.* = .{ .interned = try pt.intern(.{ .undef = ip.slicePtrType(ty_ip) }) };
|
||||
len.* = .{ .interned = try pt.intern(.{ .undef = .usize_type }) };
|
||||
mv.* = .{ .slice = .{
|
||||
.ty = ty_ip,
|
||||
.ptr = ptr,
|
||||
@@ -279,7 +274,7 @@ pub const MutableValue = union(enum) {
|
||||
.bytes => |bytes| if (!allow_bytes) {
|
||||
const elems = try arena.alloc(MutableValue, bytes.data.len);
|
||||
for (bytes.data, elems) |byte, *interned_byte| {
|
||||
interned_byte.* = .{ .interned = try ip.get(gpa, .{ .int = .{
|
||||
interned_byte.* = .{ .interned = try pt.intern(.{ .int = .{
|
||||
.ty = .u8_type,
|
||||
.storage = .{ .u64 = byte },
|
||||
} }) };
|
||||
@@ -298,22 +293,22 @@ pub const MutableValue = union(enum) {
|
||||
/// The returned pointer is valid until the representation of `mv` changes.
|
||||
pub fn elem(
|
||||
mv: *MutableValue,
|
||||
zcu: *Zcu,
|
||||
pt: Zcu.PerThread,
|
||||
arena: Allocator,
|
||||
field_idx: usize,
|
||||
) Allocator.Error!*MutableValue {
|
||||
const zcu = pt.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
const gpa = zcu.gpa;
|
||||
// Convert to the `aggregate` representation.
|
||||
switch (mv.*) {
|
||||
.eu_payload, .opt_payload, .un => unreachable,
|
||||
.interned => {
|
||||
try mv.unintern(zcu, arena, false, false);
|
||||
try mv.unintern(pt, arena, false, false);
|
||||
},
|
||||
.bytes => |bytes| {
|
||||
const elems = try arena.alloc(MutableValue, bytes.data.len);
|
||||
for (bytes.data, elems) |byte, *interned_byte| {
|
||||
interned_byte.* = .{ .interned = try ip.get(gpa, .{ .int = .{
|
||||
interned_byte.* = .{ .interned = try pt.intern(.{ .int = .{
|
||||
.ty = .u8_type,
|
||||
.storage = .{ .u64 = byte },
|
||||
} }) };
|
||||
@@ -351,14 +346,15 @@ pub const MutableValue = union(enum) {
|
||||
/// For slices, uses `Value.slice_ptr_index` and `Value.slice_len_index`.
|
||||
pub fn setElem(
|
||||
mv: *MutableValue,
|
||||
zcu: *Zcu,
|
||||
pt: Zcu.PerThread,
|
||||
arena: Allocator,
|
||||
field_idx: usize,
|
||||
field_val: MutableValue,
|
||||
) Allocator.Error!void {
|
||||
const zcu = pt.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
const is_trivial_int = field_val.isTrivialInt(zcu);
|
||||
try mv.unintern(zcu, arena, is_trivial_int, true);
|
||||
try mv.unintern(pt, arena, is_trivial_int, true);
|
||||
switch (mv.*) {
|
||||
.interned,
|
||||
.eu_payload,
|
||||
@@ -373,7 +369,7 @@ pub const MutableValue = union(enum) {
|
||||
.bytes => |b| {
|
||||
assert(is_trivial_int);
|
||||
assert(field_val.typeOf(zcu).toIntern() == .u8_type);
|
||||
b.data[field_idx] = @intCast(Value.fromInterned(field_val.interned).toUnsignedInt(zcu));
|
||||
b.data[field_idx] = @intCast(Value.fromInterned(field_val.interned).toUnsignedInt(pt));
|
||||
},
|
||||
.repeated => |r| {
|
||||
if (field_val.eqlTrivial(r.child.*)) return;
|
||||
@@ -386,9 +382,9 @@ pub const MutableValue = union(enum) {
|
||||
{
|
||||
// We can use the `bytes` representation.
|
||||
const bytes = try arena.alloc(u8, @intCast(len_inc_sent));
|
||||
const repeated_byte = Value.fromInterned(r.child.interned).toUnsignedInt(zcu);
|
||||
const repeated_byte = Value.fromInterned(r.child.interned).toUnsignedInt(pt);
|
||||
@memset(bytes, @intCast(repeated_byte));
|
||||
bytes[field_idx] = @intCast(Value.fromInterned(field_val.interned).toUnsignedInt(zcu));
|
||||
bytes[field_idx] = @intCast(Value.fromInterned(field_val.interned).toUnsignedInt(pt));
|
||||
mv.* = .{ .bytes = .{
|
||||
.ty = r.ty,
|
||||
.data = bytes,
|
||||
@@ -435,7 +431,7 @@ pub const MutableValue = union(enum) {
|
||||
} else {
|
||||
const bytes = try arena.alloc(u8, a.elems.len);
|
||||
for (a.elems, bytes) |elem_val, *b| {
|
||||
b.* = @intCast(Value.fromInterned(elem_val.interned).toUnsignedInt(zcu));
|
||||
b.* = @intCast(Value.fromInterned(elem_val.interned).toUnsignedInt(pt));
|
||||
}
|
||||
mv.* = .{ .bytes = .{
|
||||
.ty = a.ty,
|
||||
@@ -451,7 +447,7 @@ pub const MutableValue = union(enum) {
|
||||
/// For slices, uses `Value.slice_ptr_index` and `Value.slice_len_index`.
|
||||
pub fn getElem(
|
||||
mv: MutableValue,
|
||||
zcu: *Zcu,
|
||||
pt: Zcu.PerThread,
|
||||
field_idx: usize,
|
||||
) Allocator.Error!MutableValue {
|
||||
return switch (mv) {
|
||||
@@ -459,16 +455,16 @@ pub const MutableValue = union(enum) {
|
||||
.opt_payload,
|
||||
=> unreachable,
|
||||
.interned => |ip_index| {
|
||||
const ty = Type.fromInterned(zcu.intern_pool.typeOf(ip_index));
|
||||
switch (ty.zigTypeTag(zcu)) {
|
||||
.Array, .Vector => return .{ .interned = (try Value.fromInterned(ip_index).elemValue(zcu, field_idx)).toIntern() },
|
||||
.Struct, .Union => return .{ .interned = (try Value.fromInterned(ip_index).fieldValue(zcu, field_idx)).toIntern() },
|
||||
const ty = Type.fromInterned(pt.zcu.intern_pool.typeOf(ip_index));
|
||||
switch (ty.zigTypeTag(pt.zcu)) {
|
||||
.Array, .Vector => return .{ .interned = (try Value.fromInterned(ip_index).elemValue(pt, field_idx)).toIntern() },
|
||||
.Struct, .Union => return .{ .interned = (try Value.fromInterned(ip_index).fieldValue(pt, field_idx)).toIntern() },
|
||||
.Pointer => {
|
||||
assert(ty.isSlice(zcu));
|
||||
assert(ty.isSlice(pt.zcu));
|
||||
return switch (field_idx) {
|
||||
Value.slice_ptr_index => .{ .interned = Value.fromInterned(ip_index).slicePtr(zcu).toIntern() },
|
||||
Value.slice_len_index => .{ .interned = switch (zcu.intern_pool.indexToKey(ip_index)) {
|
||||
.undef => try zcu.intern(.{ .undef = .usize_type }),
|
||||
Value.slice_ptr_index => .{ .interned = Value.fromInterned(ip_index).slicePtr(pt.zcu).toIntern() },
|
||||
Value.slice_len_index => .{ .interned = switch (pt.zcu.intern_pool.indexToKey(ip_index)) {
|
||||
.undef => try pt.intern(.{ .undef = .usize_type }),
|
||||
.slice => |s| s.len,
|
||||
else => unreachable,
|
||||
} },
|
||||
@@ -487,7 +483,7 @@ pub const MutableValue = union(enum) {
|
||||
Value.slice_len_index => s.len.*,
|
||||
else => unreachable,
|
||||
},
|
||||
.bytes => |b| .{ .interned = try zcu.intern(.{ .int = .{
|
||||
.bytes => |b| .{ .interned = try pt.intern(.{ .int = .{
|
||||
.ty = .u8_type,
|
||||
.storage = .{ .u64 = b.data[field_idx] },
|
||||
} }) },
|
||||
|
||||
Reference in New Issue
Block a user