mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-03-08 01:24:49 +01:00
compiler: get everything building
Several backends are crashing right now. I'll need to fix at least the C backend before this branch is ready to PR.
This commit is contained in:
parent
a249aec54d
commit
738a3d3360
14 changed files with 300 additions and 429 deletions
|
|
@ -518,10 +518,13 @@ pub fn intAlignment(target: *const std.Target, bits: u16) u16 {
|
|||
33...64 => 8,
|
||||
else => 16,
|
||||
},
|
||||
else => return @min(
|
||||
std.math.ceilPowerOfTwoPromote(u16, @as(u16, @intCast((@as(u17, bits) + 7) / 8))),
|
||||
target.cMaxIntAlignment(),
|
||||
),
|
||||
else => switch (bits) {
|
||||
0 => 1,
|
||||
else => @min(
|
||||
std.math.ceilPowerOfTwoPromote(u16, @intCast((@as(u17, bits) + 7) / 8)),
|
||||
target.cMaxIntAlignment(),
|
||||
),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2791,9 +2791,9 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
|||
} else return isel.fail("invalid constraint: '{s}'", .{constraint});
|
||||
}
|
||||
|
||||
const clobbers_val: Value = .fromInterned(unwrapped_asm.clobbers);
|
||||
const clobbers_val: Constant = .fromInterned(unwrapped_asm.clobbers);
|
||||
const clobbers_ty = clobbers_val.typeOf(zcu);
|
||||
var clobbers_bigint_buf: Value.BigIntSpace = undefined;
|
||||
var clobbers_bigint_buf: Constant.BigIntSpace = undefined;
|
||||
const clobbers_bigint = clobbers_val.toBigInt(&clobbers_bigint_buf, zcu);
|
||||
for (0..clobbers_ty.structFieldCount(zcu)) |field_index| {
|
||||
assert(clobbers_ty.fieldType(field_index, zcu).toIntern() == .bool_type);
|
||||
|
|
@ -2818,7 +2818,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
|||
for (0..clobbers_ty.structFieldCount(zcu)) |field_index| {
|
||||
const limb_bits = @bitSizeOf(std.math.big.Limb);
|
||||
if (field_index / limb_bits >= clobbers_bigint.limbs.len) continue; // field is false
|
||||
switch (@as(u1, @truncate(clobbers_bigint.limbs[field_index / limb_bits] >> field_index % limb_bits))) {
|
||||
switch (@as(u1, @truncate(clobbers_bigint.limbs[field_index / limb_bits] >> @intCast(field_index % limb_bits)))) {
|
||||
0 => continue, // field is false
|
||||
1 => {}, // field is true
|
||||
}
|
||||
|
|
@ -2871,7 +2871,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
|||
for (0..clobbers_ty.structFieldCount(zcu)) |field_index| {
|
||||
const limb_bits = @bitSizeOf(std.math.big.Limb);
|
||||
if (field_index / limb_bits >= clobbers_bigint.limbs.len) continue; // field is false
|
||||
switch (@as(u1, @truncate(clobbers_bigint.limbs[field_index / limb_bits] >> field_index % limb_bits))) {
|
||||
switch (@as(u1, @truncate(clobbers_bigint.limbs[field_index / limb_bits] >> @intCast(field_index % limb_bits)))) {
|
||||
0 => continue, // field is false
|
||||
1 => {}, // field is true
|
||||
}
|
||||
|
|
@ -3283,8 +3283,8 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
|||
} else if (dst_ty.isSliceAtRuntime(zcu) and src_ty.isSliceAtRuntime(zcu)) {
|
||||
try dst_vi.value.move(isel, ty_op.operand);
|
||||
} else if (dst_tag == .error_union and src_tag == .error_union) {
|
||||
assert(dst_ty.errorUnionSet(zcu).hasRuntimeBitsIgnoreComptime(zcu) ==
|
||||
src_ty.errorUnionSet(zcu).hasRuntimeBitsIgnoreComptime(zcu));
|
||||
assert(dst_ty.errorUnionSet(zcu).hasRuntimeBits(zcu) ==
|
||||
src_ty.errorUnionSet(zcu).hasRuntimeBits(zcu));
|
||||
if (dst_ty.errorUnionPayload(zcu).toIntern() == src_ty.errorUnionPayload(zcu).toIntern()) {
|
||||
try dst_vi.value.move(isel, ty_op.operand);
|
||||
} else return isel.fail("bad {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) });
|
||||
|
|
@ -4562,7 +4562,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
|||
}
|
||||
if (case.ranges.len == 0 and case.items.len == 1 and Constant.fromInterned(
|
||||
case.items[0].toInterned().?,
|
||||
).orderAgainstZero(zcu).compare(.eq)) {
|
||||
).compareHetero(.eq, .zero_comptime_int, zcu)) {
|
||||
try isel.emit(.cbnz(
|
||||
cond_reg,
|
||||
@intCast((isel.instructions.items.len + 1 - next_label) << 2),
|
||||
|
|
@ -6893,11 +6893,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
|||
var field_it = loaded_struct.iterateRuntimeOrder(ip);
|
||||
while (field_it.next()) |field_index| {
|
||||
const field_ty: ZigType = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
|
||||
field_offset = field_ty.structFieldAlignment(
|
||||
loaded_struct.fieldAlign(ip, field_index),
|
||||
loaded_struct.layout,
|
||||
zcu,
|
||||
).forward(field_offset);
|
||||
field_offset = loaded_struct.field_offsets.get(ip)[field_index];
|
||||
const field_size = field_ty.abiSize(zcu);
|
||||
if (field_size == 0) continue;
|
||||
var agg_part_it = agg_vi.value.field(agg_ty, field_offset, field_size);
|
||||
|
|
@ -6905,7 +6901,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
|||
try agg_part_vi.?.move(isel, elems[field_index]);
|
||||
field_offset += field_size;
|
||||
}
|
||||
assert(loaded_struct.flagsUnordered(ip).alignment.forward(field_offset) == agg_vi.value.size(isel));
|
||||
assert(loaded_struct.alignment.forward(field_offset) == agg_vi.value.size(isel));
|
||||
},
|
||||
.tuple_type => |tuple_type| {
|
||||
const elems: []const Air.Inst.Ref =
|
||||
|
|
@ -6947,23 +6943,23 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
|||
const union_layout = ZigType.getUnionLayout(loaded_union, zcu);
|
||||
|
||||
if (union_layout.tag_size > 0) unused_tag: {
|
||||
const loaded_tag = loaded_union.loadTagType(ip);
|
||||
const loaded_tag = ip.loadEnumType(loaded_union.enum_tag_type);
|
||||
var tag_it = union_vi.value.field(union_ty, union_layout.tagOffset(), union_layout.tag_size);
|
||||
const tag_vi = try tag_it.only(isel);
|
||||
const tag_ra = try tag_vi.?.defReg(isel) orelse break :unused_tag;
|
||||
switch (union_layout.tag_size) {
|
||||
0 => unreachable,
|
||||
1...4 => try isel.movImmediate(tag_ra.w(), @as(u32, switch (loaded_tag.values.len) {
|
||||
1...4 => try isel.movImmediate(tag_ra.w(), @as(u32, switch (loaded_tag.field_values.len) {
|
||||
0 => extra.field_index,
|
||||
else => switch (ip.indexToKey(loaded_tag.values.get(ip)[extra.field_index]).int.storage) {
|
||||
else => switch (ip.indexToKey(loaded_tag.field_values.get(ip)[extra.field_index]).int.storage) {
|
||||
.u64 => |imm| @intCast(imm),
|
||||
.i64 => |imm| @bitCast(@as(i32, @intCast(imm))),
|
||||
else => unreachable,
|
||||
},
|
||||
})),
|
||||
5...8 => try isel.movImmediate(tag_ra.x(), switch (loaded_tag.values.len) {
|
||||
5...8 => try isel.movImmediate(tag_ra.x(), switch (loaded_tag.field_values.len) {
|
||||
0 => extra.field_index,
|
||||
else => switch (ip.indexToKey(loaded_tag.values.get(ip)[extra.field_index]).int.storage) {
|
||||
else => switch (ip.indexToKey(loaded_tag.field_values.get(ip)[extra.field_index]).int.storage) {
|
||||
.u64 => |imm| imm,
|
||||
.i64 => |imm| @bitCast(imm),
|
||||
else => unreachable,
|
||||
|
|
@ -10391,7 +10387,7 @@ pub const Value = struct {
|
|||
switch (loaded_struct.layout) {
|
||||
.auto, .@"extern" => {},
|
||||
.@"packed" => continue :type_key .{
|
||||
.int_type = ip.indexToKey(loaded_struct.backingIntTypeUnordered(ip)).int_type,
|
||||
.int_type = ip.indexToKey(loaded_struct.packed_backing_int_type).int_type,
|
||||
},
|
||||
}
|
||||
const min_part_log2_stride: u5 = if (size > 16) 4 else if (size > 8) 3 else 0;
|
||||
|
|
@ -10406,7 +10402,7 @@ pub const Value = struct {
|
|||
var field_it = loaded_struct.iterateRuntimeOrder(ip);
|
||||
while (field_it.next()) |field_index| {
|
||||
const field_ty: ZigType = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
|
||||
const field_begin = switch (loaded_struct.fieldAlign(ip, field_index)) {
|
||||
const field_begin = switch (loaded_struct.field_aligns.getOrNone(ip, field_index)) {
|
||||
.none => field_ty.abiAlignment(zcu),
|
||||
else => |field_align| field_align,
|
||||
}.forward(field_end);
|
||||
|
|
@ -10504,7 +10500,7 @@ pub const Value = struct {
|
|||
},
|
||||
.union_type => {
|
||||
const loaded_union = ip.loadUnionType(ty.toIntern());
|
||||
switch (loaded_union.flagsUnordered(ip).layout) {
|
||||
switch (loaded_union.layout) {
|
||||
.auto, .@"extern" => {},
|
||||
.@"packed" => continue :type_key .{ .int_type = .{
|
||||
.signedness = .unsigned,
|
||||
|
|
@ -10539,12 +10535,13 @@ pub const Value = struct {
|
|||
const field_signedness = field_signedness: switch (field) {
|
||||
.tag => {
|
||||
if (offset >= field_begin and offset + size <= field_begin + field_size) {
|
||||
ty = .fromInterned(loaded_union.enum_tag_ty);
|
||||
ty = .fromInterned(loaded_union.enum_tag_type);
|
||||
ty_size = field_size;
|
||||
offset -= field_begin;
|
||||
continue :type_key ip.indexToKey(loaded_union.enum_tag_ty);
|
||||
continue :type_key ip.indexToKey(loaded_union.enum_tag_type);
|
||||
}
|
||||
break :field_signedness ip.indexToKey(loaded_union.loadTagType(ip).tag_ty).int_type.signedness;
|
||||
const loaded_enum = ip.loadEnumType(loaded_union.enum_tag_type);
|
||||
break :field_signedness ip.indexToKey(loaded_enum.int_tag_type).int_type.signedness;
|
||||
},
|
||||
.payload => null,
|
||||
};
|
||||
|
|
@ -10574,7 +10571,7 @@ pub const Value = struct {
|
|||
}
|
||||
},
|
||||
.opaque_type, .func_type => continue :type_key .{ .simple_type = .anyopaque },
|
||||
.enum_type => continue :type_key ip.indexToKey(ip.loadEnumType(ty.toIntern()).tag_ty),
|
||||
.enum_type => continue :type_key ip.indexToKey(ip.loadEnumType(ty.toIntern()).int_tag_type),
|
||||
.error_set_type,
|
||||
.inferred_error_set_type,
|
||||
=> continue :type_key .{ .simple_type = .anyerror },
|
||||
|
|
@ -10740,7 +10737,7 @@ pub const Value = struct {
|
|||
.storage = .{ .u64 = 0 },
|
||||
} },
|
||||
},
|
||||
.int => |int| break :free storage: switch (int.storage) {
|
||||
.int => |int| break :free switch (int.storage) {
|
||||
.u64 => |imm| try isel.movImmediate(switch (size) {
|
||||
else => unreachable,
|
||||
1...4 => mat.ra.w(),
|
||||
|
|
@ -10772,12 +10769,6 @@ pub const Value = struct {
|
|||
}
|
||||
try isel.movImmediate(mat.ra.x(), imm);
|
||||
},
|
||||
.lazy_align => |ty| continue :storage .{
|
||||
.u64 = ZigType.fromInterned(ty).abiAlignment(zcu).toByteUnits().?,
|
||||
},
|
||||
.lazy_size => |ty| continue :storage .{
|
||||
.u64 = ZigType.fromInterned(ty).abiSize(zcu),
|
||||
},
|
||||
},
|
||||
.err => |err| continue :constant_key .{ .int = .{
|
||||
.ty = err.ty,
|
||||
|
|
@ -11084,13 +11075,9 @@ pub const Value = struct {
|
|||
var field_offset: u64 = 0;
|
||||
var field_it = loaded_struct.iterateRuntimeOrder(ip);
|
||||
while (field_it.next()) |field_index| {
|
||||
if (loaded_struct.fieldIsComptime(ip, field_index)) continue;
|
||||
if (loaded_struct.field_is_comptime_bits.get(ip, field_index)) continue;
|
||||
const field_ty: ZigType = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
|
||||
field_offset = field_ty.structFieldAlignment(
|
||||
loaded_struct.fieldAlign(ip, field_index),
|
||||
loaded_struct.layout,
|
||||
zcu,
|
||||
).forward(field_offset);
|
||||
field_offset = loaded_struct.field_offsets.get(ip)[field_index];
|
||||
const field_size = field_ty.abiSize(zcu);
|
||||
if (offset >= field_offset and offset + size <= field_offset + field_size) {
|
||||
offset -= field_offset;
|
||||
|
|
@ -11132,7 +11119,7 @@ pub const Value = struct {
|
|||
.un => |un| {
|
||||
const loaded_union = ip.loadUnionType(un.ty);
|
||||
const union_layout = ZigType.getUnionLayout(loaded_union, zcu);
|
||||
if (loaded_union.hasTag(ip)) {
|
||||
if (loaded_union.has_runtime_tag) {
|
||||
const tag_offset = union_layout.tagOffset();
|
||||
if (offset >= tag_offset and offset + size <= tag_offset + union_layout.tag_size) {
|
||||
offset -= tag_offset;
|
||||
|
|
@ -11477,13 +11464,9 @@ fn writeKeyToMemory(isel: *Select, constant_key: InternPool.Key, buffer: []u8) e
|
|||
var field_offset: u64 = 0;
|
||||
var field_it = loaded_struct.iterateRuntimeOrder(ip);
|
||||
while (field_it.next()) |field_index| {
|
||||
if (loaded_struct.fieldIsComptime(ip, field_index)) continue;
|
||||
if (loaded_struct.field_is_comptime_bits.get(ip, field_index)) continue;
|
||||
const field_ty: ZigType = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
|
||||
field_offset = field_ty.structFieldAlignment(
|
||||
loaded_struct.fieldAlign(ip, field_index),
|
||||
loaded_struct.layout,
|
||||
zcu,
|
||||
).forward(field_offset);
|
||||
field_offset = loaded_struct.field_offsets.get(ip)[field_index];
|
||||
const field_size = field_ty.abiSize(zcu);
|
||||
if (!try isel.writeToMemory(.fromInterned(switch (aggregate.storage) {
|
||||
.bytes => unreachable,
|
||||
|
|
@ -12082,7 +12065,7 @@ pub const CallAbiIterator = struct {
|
|||
const zcu = isel.pt.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
|
||||
if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) return null;
|
||||
if (!ty.hasRuntimeBits(zcu)) return null;
|
||||
try isel.values.ensureUnusedCapacity(zcu.gpa, Value.max_parts);
|
||||
const wip_vi = isel.initValue(ty);
|
||||
type_key: switch (ip.indexToKey(ty.toIntern())) {
|
||||
|
|
@ -12186,7 +12169,7 @@ pub const CallAbiIterator = struct {
|
|||
switch (loaded_struct.layout) {
|
||||
.auto, .@"extern" => {},
|
||||
.@"packed" => continue :type_key .{
|
||||
.int_type = ip.indexToKey(loaded_struct.backingIntTypeUnordered(ip)).int_type,
|
||||
.int_type = ip.indexToKey(loaded_struct.packed_backing_int_type).int_type,
|
||||
},
|
||||
}
|
||||
const size = wip_vi.size(isel);
|
||||
|
|
@ -12210,7 +12193,7 @@ pub const CallAbiIterator = struct {
|
|||
const field_end = next_field_end;
|
||||
const next_field_begin = if (field_it.next()) |field_index| next_field_begin: {
|
||||
const field_ty: ZigType = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
|
||||
const next_field_begin = switch (loaded_struct.fieldAlign(ip, field_index)) {
|
||||
const next_field_begin = switch (loaded_struct.field_aligns.getOrNone(ip, field_index)) {
|
||||
.none => field_ty.abiAlignment(zcu),
|
||||
else => |field_align| field_align,
|
||||
}.forward(field_end);
|
||||
|
|
@ -12276,7 +12259,7 @@ pub const CallAbiIterator = struct {
|
|||
},
|
||||
.union_type => {
|
||||
const loaded_union = ip.loadUnionType(ty.toIntern());
|
||||
switch (loaded_union.flagsUnordered(ip).layout) {
|
||||
switch (loaded_union.layout) {
|
||||
.auto, .@"extern" => {},
|
||||
.@"packed" => continue :type_key .{ .int_type = .{
|
||||
.signedness = .unsigned,
|
||||
|
|
@ -12309,7 +12292,9 @@ pub const CallAbiIterator = struct {
|
|||
}
|
||||
},
|
||||
.opaque_type, .func_type => continue :type_key .{ .simple_type = .anyopaque },
|
||||
.enum_type => continue :type_key ip.indexToKey(ip.loadEnumType(ty.toIntern()).tag_ty),
|
||||
.enum_type => continue :type_key .{
|
||||
.int_type = ip.indexToKey(ip.loadEnumType(ty.toIntern()).int_tag_type).int_type,
|
||||
},
|
||||
.error_set_type,
|
||||
.inferred_error_set_type,
|
||||
=> continue :type_key .{ .simple_type = .anyerror },
|
||||
|
|
@ -12414,8 +12399,8 @@ pub const CallAbiIterator = struct {
|
|||
const ip = &zcu.intern_pool;
|
||||
var common_fdt: ?FundamentalDataType = null;
|
||||
for (0.., loaded_struct.field_types.get(ip)) |field_index, field_ty| {
|
||||
if (loaded_struct.fieldIsComptime(ip, field_index)) continue;
|
||||
if (loaded_struct.fieldAlign(ip, field_index) != .none) return null;
|
||||
if (loaded_struct.field_is_comptime_bits.get(ip, field_index)) continue;
|
||||
if (loaded_struct.field_aligns.getOrNone(ip, field_index) != .none) return null;
|
||||
if (!ZigType.fromInterned(field_ty).hasRuntimeBits(zcu)) continue;
|
||||
const fdt = homogeneousAggregateBaseType(zcu, field_ty);
|
||||
if (common_fdt == null) common_fdt = fdt else if (fdt != common_fdt) return null;
|
||||
|
|
|
|||
|
|
@ -1052,17 +1052,7 @@ pub const DeclGen = struct {
|
|||
.func,
|
||||
.enum_literal,
|
||||
=> unreachable, // non-runtime values
|
||||
.int => |int| switch (int.storage) {
|
||||
.u64, .i64, .big_int => try w.print("{f}", .{try dg.fmtIntLiteralDec(val, location)}),
|
||||
.lazy_align, .lazy_size => {
|
||||
try w.writeAll("((");
|
||||
try dg.renderCType(w, ctype);
|
||||
try w.print("){f})", .{try dg.fmtIntLiteralHex(
|
||||
try pt.intValue(.usize, val.toUnsignedInt(zcu)),
|
||||
.Other,
|
||||
)});
|
||||
},
|
||||
},
|
||||
.int => try w.print("{f}", .{try dg.fmtIntLiteralDec(val, location)}),
|
||||
.err => |err| try dg.renderErrorName(w, err.name),
|
||||
.error_union => |error_union| switch (ctype.info(ctype_pool)) {
|
||||
.basic => switch (error_union.val) {
|
||||
|
|
@ -1338,7 +1328,7 @@ pub const DeclGen = struct {
|
|||
const comptime_val = tuple.values.get(ip)[field_index];
|
||||
if (comptime_val != .none) continue;
|
||||
const field_ty: Type = .fromInterned(tuple.types.get(ip)[field_index]);
|
||||
if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
|
||||
if (!field_ty.hasRuntimeBits(zcu)) continue;
|
||||
|
||||
if (!empty) try w.writeByte(',');
|
||||
|
||||
|
|
@ -1373,7 +1363,7 @@ pub const DeclGen = struct {
|
|||
var need_comma = false;
|
||||
while (field_it.next()) |field_index| {
|
||||
const field_ty: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
|
||||
if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
|
||||
if (!field_ty.hasRuntimeBits(zcu)) continue;
|
||||
|
||||
if (need_comma) try w.writeByte(',');
|
||||
need_comma = true;
|
||||
|
|
@ -1396,7 +1386,7 @@ pub const DeclGen = struct {
|
|||
const loaded_union = ip.loadUnionType(ty.toIntern());
|
||||
if (un.tag == .none) {
|
||||
const backing_ty = try ty.externUnionBackingType(pt);
|
||||
assert(loaded_union.flagsUnordered(ip).layout == .@"extern");
|
||||
assert(loaded_union.layout == .@"extern");
|
||||
if (location == .StaticInitializer) {
|
||||
return dg.fail("TODO: C backend: implement extern union backing type rendering in static initializers", .{});
|
||||
}
|
||||
|
|
@ -1418,9 +1408,9 @@ pub const DeclGen = struct {
|
|||
|
||||
const field_index = zcu.unionTagFieldIndex(loaded_union, Value.fromInterned(un.tag)).?;
|
||||
const field_ty: Type = .fromInterned(loaded_union.field_types.get(ip)[field_index]);
|
||||
const field_name = loaded_union.loadTagType(ip).names.get(ip)[field_index];
|
||||
const field_name = ip.loadEnumType(loaded_union.enum_tag_type).field_names.get(ip)[field_index];
|
||||
|
||||
const has_tag = loaded_union.hasTag(ip);
|
||||
const has_tag = loaded_union.has_runtime_tag;
|
||||
if (has_tag) try w.writeByte('{');
|
||||
const aggregate = ctype.info(ctype_pool).aggregate;
|
||||
for (0..if (has_tag) aggregate.fields.len else 1) |outer_field_index| {
|
||||
|
|
@ -1597,7 +1587,7 @@ pub const DeclGen = struct {
|
|||
var need_comma = false;
|
||||
while (field_it.next()) |field_index| {
|
||||
const field_ty: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
|
||||
if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
|
||||
if (!field_ty.hasRuntimeBits(zcu)) continue;
|
||||
|
||||
if (need_comma) try w.writeByte(',');
|
||||
need_comma = true;
|
||||
|
|
@ -1620,7 +1610,7 @@ pub const DeclGen = struct {
|
|||
for (0..tuple_info.types.len) |field_index| {
|
||||
if (tuple_info.values.get(ip)[field_index] != .none) continue;
|
||||
const field_ty: Type = .fromInterned(tuple_info.types.get(ip)[field_index]);
|
||||
if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
|
||||
if (!field_ty.hasRuntimeBits(zcu)) continue;
|
||||
|
||||
if (need_comma) try w.writeByte(',');
|
||||
need_comma = true;
|
||||
|
|
@ -1630,7 +1620,7 @@ pub const DeclGen = struct {
|
|||
},
|
||||
.union_type => {
|
||||
const loaded_union = ip.loadUnionType(ty.toIntern());
|
||||
switch (loaded_union.flagsUnordered(ip).layout) {
|
||||
switch (loaded_union.layout) {
|
||||
.auto, .@"extern" => {
|
||||
if (!location.isInitializer()) {
|
||||
try w.writeByte('(');
|
||||
|
|
@ -1638,7 +1628,7 @@ pub const DeclGen = struct {
|
|||
try w.writeByte(')');
|
||||
}
|
||||
|
||||
const has_tag = loaded_union.hasTag(ip);
|
||||
const has_tag = loaded_union.has_runtime_tag;
|
||||
if (has_tag) try w.writeByte('{');
|
||||
const aggregate = ctype.info(ctype_pool).aggregate;
|
||||
for (0..if (has_tag) aggregate.fields.len else 1) |outer_field_index| {
|
||||
|
|
@ -1649,7 +1639,7 @@ pub const DeclGen = struct {
|
|||
.payload) {
|
||||
.tag => try dg.renderUndefValue(
|
||||
w,
|
||||
.fromInterned(loaded_union.enum_tag_ty),
|
||||
.fromInterned(loaded_union.enum_tag_type),
|
||||
initializer_type,
|
||||
),
|
||||
.payload => {
|
||||
|
|
@ -1760,6 +1750,7 @@ pub const DeclGen = struct {
|
|||
.opt,
|
||||
.aggregate,
|
||||
.un,
|
||||
.bitpack,
|
||||
.memoized_call,
|
||||
=> unreachable, // values, not types
|
||||
},
|
||||
|
|
@ -2797,7 +2788,7 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn
|
|||
} });
|
||||
|
||||
try w.print("case {f}: {{", .{
|
||||
try o.dg.fmtIntLiteralDec(try tag_val.intFromEnum(enum_ty, pt), .Other),
|
||||
try o.dg.fmtIntLiteralDec(tag_val.intFromEnum(zcu), .Other),
|
||||
});
|
||||
o.indent();
|
||||
try o.newline();
|
||||
|
|
@ -3599,10 +3590,7 @@ fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
|
|||
const zcu = f.object.dg.pt.zcu;
|
||||
const inst_ty = f.typeOfIndex(inst);
|
||||
const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
|
||||
if (!inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
|
||||
return .none;
|
||||
}
|
||||
assert(inst_ty.hasRuntimeBits(zcu));
|
||||
|
||||
const ptr = try f.resolveInst(bin_op.lhs);
|
||||
const index = try f.resolveInst(bin_op.rhs);
|
||||
|
|
@ -3629,7 +3617,7 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
|
|||
|
||||
const inst_ty = f.typeOfIndex(inst);
|
||||
const ptr_ty = f.typeOf(bin_op.lhs);
|
||||
const elem_has_bits = ptr_ty.indexableElem(zcu).hasRuntimeBitsIgnoreComptime(zcu);
|
||||
assert(ptr_ty.indexableElem(zcu).hasRuntimeBits(zcu));
|
||||
|
||||
const ptr = try f.resolveInst(bin_op.lhs);
|
||||
const index = try f.resolveInst(bin_op.rhs);
|
||||
|
|
@ -3643,16 +3631,14 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
|
|||
try w.writeByte('(');
|
||||
try f.renderType(w, inst_ty);
|
||||
try w.writeByte(')');
|
||||
if (elem_has_bits) try w.writeByte('&');
|
||||
if (elem_has_bits and ptr_ty.ptrSize(zcu) == .one) {
|
||||
try w.writeByte('&');
|
||||
if (ptr_ty.ptrSize(zcu) == .one) {
|
||||
// It's a pointer to an array, so we need to de-reference.
|
||||
try f.writeCValueDeref(w, ptr);
|
||||
} else try f.writeCValue(w, ptr, .Other);
|
||||
if (elem_has_bits) {
|
||||
try w.writeByte('[');
|
||||
try f.writeCValue(w, index, .Other);
|
||||
try w.writeByte(']');
|
||||
}
|
||||
try w.writeByte('[');
|
||||
try f.writeCValue(w, index, .Other);
|
||||
try w.writeByte(']');
|
||||
try a.end(f, w);
|
||||
return local;
|
||||
}
|
||||
|
|
@ -3661,10 +3647,7 @@ fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
|
|||
const zcu = f.object.dg.pt.zcu;
|
||||
const inst_ty = f.typeOfIndex(inst);
|
||||
const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
|
||||
if (!inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
|
||||
return .none;
|
||||
}
|
||||
assert(inst_ty.hasRuntimeBits(zcu));
|
||||
|
||||
const slice = try f.resolveInst(bin_op.lhs);
|
||||
const index = try f.resolveInst(bin_op.rhs);
|
||||
|
|
@ -3692,7 +3675,7 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
|
|||
const inst_ty = f.typeOfIndex(inst);
|
||||
const slice_ty = f.typeOf(bin_op.lhs);
|
||||
const elem_ty = slice_ty.childType(zcu);
|
||||
const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime(zcu);
|
||||
assert(elem_ty.hasRuntimeBits(zcu));
|
||||
|
||||
const slice = try f.resolveInst(bin_op.lhs);
|
||||
const index = try f.resolveInst(bin_op.rhs);
|
||||
|
|
@ -3703,13 +3686,11 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
|
|||
const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));
|
||||
try f.writeCValue(w, local, .Other);
|
||||
try a.assign(f, w);
|
||||
if (elem_has_bits) try w.writeByte('&');
|
||||
try w.writeByte('&');
|
||||
try f.writeCValueMember(w, slice, .{ .identifier = "ptr" });
|
||||
if (elem_has_bits) {
|
||||
try w.writeByte('[');
|
||||
try f.writeCValue(w, index, .Other);
|
||||
try w.writeByte(']');
|
||||
}
|
||||
try w.writeByte('[');
|
||||
try f.writeCValue(w, index, .Other);
|
||||
try w.writeByte(']');
|
||||
try a.end(f, w);
|
||||
return local;
|
||||
}
|
||||
|
|
@ -3718,10 +3699,7 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
|
|||
const zcu = f.object.dg.pt.zcu;
|
||||
const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
|
||||
const inst_ty = f.typeOfIndex(inst);
|
||||
if (!inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
|
||||
return .none;
|
||||
}
|
||||
assert(inst_ty.hasRuntimeBits(zcu));
|
||||
|
||||
const array = try f.resolveInst(bin_op.lhs);
|
||||
const index = try f.resolveInst(bin_op.rhs);
|
||||
|
|
@ -3853,10 +3831,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
|
|||
// bit-pointers we see here are vector element pointers.
|
||||
assert(ptr_info.packed_offset.host_size == 0 or ptr_info.flags.vector_index != .none);
|
||||
|
||||
if (!src_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
try reap(f, inst, &.{ty_op.operand});
|
||||
return .none;
|
||||
}
|
||||
assert(src_ty.hasRuntimeBits(zcu));
|
||||
|
||||
const operand = try f.resolveInst(ty_op.operand);
|
||||
|
||||
|
|
@ -4456,7 +4431,7 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
|
|||
const inst_ty = f.typeOfIndex(inst);
|
||||
const inst_scalar_ty = inst_ty.scalarType(zcu);
|
||||
const elem_ty = inst_scalar_ty.indexableElem(zcu);
|
||||
if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) return f.moveCValue(inst, inst_ty, lhs);
|
||||
assert(elem_ty.hasRuntimeBits(zcu));
|
||||
const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete);
|
||||
|
||||
const local = try f.allocLocal(inst, inst_ty);
|
||||
|
|
@ -4787,7 +4762,7 @@ fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index)
|
|||
const w = &f.object.code.writer;
|
||||
|
||||
const inst_ty = f.typeOfIndex(inst);
|
||||
const result = if (inst_ty.hasRuntimeBitsIgnoreComptime(zcu) and !f.liveness.isUnused(inst))
|
||||
const result = if (inst_ty.hasRuntimeBits(zcu) and !f.liveness.isUnused(inst))
|
||||
try f.allocLocal(inst, inst_ty)
|
||||
else
|
||||
.none;
|
||||
|
|
@ -4853,7 +4828,7 @@ fn lowerTry(
|
|||
const liveness_condbr = f.liveness.getCondBr(inst);
|
||||
const w = &f.object.code.writer;
|
||||
const payload_ty = err_union_ty.errorUnionPayload(zcu);
|
||||
const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(zcu);
|
||||
const payload_has_bits = payload_ty.hasRuntimeBits(zcu);
|
||||
|
||||
if (!err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) {
|
||||
try w.writeAll("if (");
|
||||
|
|
@ -5393,7 +5368,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
|
|||
const result = result: {
|
||||
const w = &f.object.code.writer;
|
||||
const inst_ty = f.typeOfIndex(inst);
|
||||
const inst_local = if (inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) local: {
|
||||
const inst_local = if (inst_ty.hasRuntimeBits(zcu)) local: {
|
||||
const inst_local = try f.allocLocalValue(.{
|
||||
.ctype = try f.ctypeFromType(inst_ty, .complete),
|
||||
.alignas = CType.AlignAs.fromAbiAlignment(inst_ty.abiAlignment(zcu)),
|
||||
|
|
@ -5820,12 +5795,12 @@ fn fieldLocation(
|
|||
.struct_type => {
|
||||
const loaded_struct = ip.loadStructType(container_ty.toIntern());
|
||||
return switch (loaded_struct.layout) {
|
||||
.auto, .@"extern" => if (!container_ty.hasRuntimeBitsIgnoreComptime(zcu))
|
||||
.auto, .@"extern" => if (!container_ty.hasRuntimeBits(zcu))
|
||||
.begin
|
||||
else if (!field_ptr_ty.childType(zcu).hasRuntimeBitsIgnoreComptime(zcu))
|
||||
.{ .byte_offset = loaded_struct.offsets.get(ip)[field_index] }
|
||||
else if (!field_ptr_ty.childType(zcu).hasRuntimeBits(zcu))
|
||||
.{ .byte_offset = loaded_struct.field_offsets.get(ip)[field_index] }
|
||||
else
|
||||
.{ .field = .{ .identifier = loaded_struct.fieldName(ip, field_index).toSlice(ip) } },
|
||||
.{ .field = .{ .identifier = loaded_struct.field_names.get(ip)[field_index].toSlice(ip) } },
|
||||
.@"packed" => if (field_ptr_ty.ptrInfo(zcu).packed_offset.host_size == 0)
|
||||
.{ .byte_offset = @divExact(zcu.structPackedFieldBitOffset(loaded_struct, field_index) +
|
||||
container_ptr_ty.ptrInfo(zcu).packed_offset.bit_offset, 8) }
|
||||
|
|
@ -5833,24 +5808,24 @@ fn fieldLocation(
|
|||
.begin,
|
||||
};
|
||||
},
|
||||
.tuple_type => return if (!container_ty.hasRuntimeBitsIgnoreComptime(zcu))
|
||||
.tuple_type => return if (!container_ty.hasRuntimeBits(zcu))
|
||||
.begin
|
||||
else if (!field_ptr_ty.childType(zcu).hasRuntimeBitsIgnoreComptime(zcu))
|
||||
else if (!field_ptr_ty.childType(zcu).hasRuntimeBits(zcu))
|
||||
.{ .byte_offset = container_ty.structFieldOffset(field_index, zcu) }
|
||||
else
|
||||
.{ .field = .{ .field = field_index } },
|
||||
.union_type => {
|
||||
const loaded_union = ip.loadUnionType(container_ty.toIntern());
|
||||
switch (loaded_union.flagsUnordered(ip).layout) {
|
||||
switch (loaded_union.layout) {
|
||||
.auto, .@"extern" => {
|
||||
const field_ty: Type = .fromInterned(loaded_union.field_types.get(ip)[field_index]);
|
||||
if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu))
|
||||
if (!field_ty.hasRuntimeBits(zcu))
|
||||
return if (loaded_union.has_runtime_tag and !container_ty.unionHasAllZeroBitFieldTypes(zcu))
|
||||
.{ .field = .{ .identifier = "payload" } }
|
||||
else
|
||||
.begin;
|
||||
const field_name = loaded_union.loadTagType(ip).names.get(ip)[field_index];
|
||||
return .{ .field = if (loaded_union.hasTag(ip))
|
||||
const field_name = ip.loadEnumType(loaded_union.enum_tag_type).field_names.get(ip)[field_index];
|
||||
return .{ .field = if (loaded_union.has_runtime_tag)
|
||||
.{ .payload_identifier = field_name.toSlice(ip) }
|
||||
else
|
||||
.{ .identifier = field_name.toSlice(ip) } };
|
||||
|
|
@ -5996,10 +5971,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
|
|||
const extra = f.air.extraData(Air.StructField, ty_pl.payload).data;
|
||||
|
||||
const inst_ty = f.typeOfIndex(inst);
|
||||
if (!inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
try reap(f, inst, &.{extra.struct_operand});
|
||||
return .none;
|
||||
}
|
||||
assert(inst_ty.hasRuntimeBits(zcu));
|
||||
|
||||
const struct_byval = try f.resolveInst(extra.struct_operand);
|
||||
try reap(f, inst, &.{extra.struct_operand});
|
||||
|
|
@ -6014,9 +5986,9 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
|
|||
.struct_type => .{ .identifier = struct_ty.structFieldName(extra.field_index, zcu).unwrap().?.toSlice(ip) },
|
||||
.union_type => name: {
|
||||
const union_type = ip.loadUnionType(struct_ty.toIntern());
|
||||
const enum_tag_ty: Type = .fromInterned(union_type.enum_tag_ty);
|
||||
const enum_tag_ty: Type = .fromInterned(union_type.enum_tag_type);
|
||||
const field_name_str = enum_tag_ty.enumFieldName(extra.field_index, zcu).toSlice(ip);
|
||||
if (union_type.hasTag(ip)) {
|
||||
if (union_type.has_runtime_tag) {
|
||||
break :name .{ .payload_identifier = field_name_str };
|
||||
} else {
|
||||
break :name .{ .identifier = field_name_str };
|
||||
|
|
@ -6161,7 +6133,7 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
|
|||
|
||||
const inst_ty = f.typeOfIndex(inst);
|
||||
const payload_ty = inst_ty.errorUnionPayload(zcu);
|
||||
const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(zcu);
|
||||
const repr_is_err = !payload_ty.hasRuntimeBits(zcu);
|
||||
const err_ty = inst_ty.errorUnionSet(zcu);
|
||||
const err = try f.resolveInst(ty_op.operand);
|
||||
try reap(f, inst, &.{ty_op.operand});
|
||||
|
|
@ -6210,7 +6182,7 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
|
|||
try reap(f, inst, &.{ty_op.operand});
|
||||
|
||||
// First, set the non-error value.
|
||||
if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (!payload_ty.hasRuntimeBits(zcu)) {
|
||||
const a = try Assignment.start(f, w, try f.ctypeFromType(operand_ty, .complete));
|
||||
try f.writeCValueDeref(w, operand);
|
||||
try a.assign(f, w);
|
||||
|
|
@ -6262,13 +6234,13 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
|
|||
const inst_ty = f.typeOfIndex(inst);
|
||||
const payload_ty = inst_ty.errorUnionPayload(zcu);
|
||||
const payload = try f.resolveInst(ty_op.operand);
|
||||
const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(zcu);
|
||||
assert(payload_ty.hasRuntimeBits(zcu));
|
||||
const err_ty = inst_ty.errorUnionSet(zcu);
|
||||
try reap(f, inst, &.{ty_op.operand});
|
||||
|
||||
const w = &f.object.code.writer;
|
||||
const local = try f.allocLocal(inst, inst_ty);
|
||||
if (!repr_is_err) {
|
||||
{
|
||||
const a = try Assignment.start(f, w, try f.ctypeFromType(payload_ty, .complete));
|
||||
try f.writeCValueMember(w, local, .{ .identifier = "payload" });
|
||||
try a.assign(f, w);
|
||||
|
|
@ -6277,10 +6249,7 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
|
|||
}
|
||||
{
|
||||
const a = try Assignment.start(f, w, try f.ctypeFromType(err_ty, .complete));
|
||||
if (repr_is_err)
|
||||
try f.writeCValue(w, local, .Other)
|
||||
else
|
||||
try f.writeCValueMember(w, local, .{ .identifier = "error" });
|
||||
try f.writeCValueMember(w, local, .{ .identifier = "error" });
|
||||
try a.assign(f, w);
|
||||
try f.object.dg.renderValue(w, try pt.intValue(try pt.errorIntType(), 0), .Other);
|
||||
try a.end(f, w);
|
||||
|
|
@ -7411,10 +7380,10 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
|
|||
var field_it = loaded_struct.iterateRuntimeOrder(ip);
|
||||
while (field_it.next()) |field_index| {
|
||||
const field_ty: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
|
||||
if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
|
||||
if (!field_ty.hasRuntimeBits(zcu)) continue;
|
||||
|
||||
const a = try Assignment.start(f, w, try f.ctypeFromType(field_ty, .complete));
|
||||
try f.writeCValueMember(w, local, .{ .identifier = loaded_struct.fieldName(ip, field_index).toSlice(ip) });
|
||||
try f.writeCValueMember(w, local, .{ .identifier = loaded_struct.field_names.get(ip)[field_index].toSlice(ip) });
|
||||
try a.assign(f, w);
|
||||
try f.writeCValue(w, resolved_elements[field_index], .Other);
|
||||
try a.end(f, w);
|
||||
|
|
@ -7426,7 +7395,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
|
|||
.tuple_type => |tuple_info| for (0..tuple_info.types.len) |field_index| {
|
||||
if (tuple_info.values.get(ip)[field_index] != .none) continue;
|
||||
const field_ty: Type = .fromInterned(tuple_info.types.get(ip)[field_index]);
|
||||
if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
|
||||
if (!field_ty.hasRuntimeBits(zcu)) continue;
|
||||
|
||||
const a = try Assignment.start(f, w, try f.ctypeFromType(field_ty, .complete));
|
||||
try f.writeCValueMember(w, local, .{ .field = field_index });
|
||||
|
|
@ -7449,13 +7418,13 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
|
|||
|
||||
const union_ty = f.typeOfIndex(inst);
|
||||
const loaded_union = ip.loadUnionType(union_ty.toIntern());
|
||||
const field_name = loaded_union.loadTagType(ip).names.get(ip)[extra.field_index];
|
||||
const field_name = ip.loadEnumType(loaded_union.enum_tag_type).field_names.get(ip)[extra.field_index];
|
||||
const payload_ty = f.typeOf(extra.init);
|
||||
const payload = try f.resolveInst(extra.init);
|
||||
try reap(f, inst, &.{extra.init});
|
||||
|
||||
const w = &f.object.code.writer;
|
||||
if (loaded_union.flagsUnordered(ip).layout == .@"packed") return f.moveCValue(inst, union_ty, payload);
|
||||
if (loaded_union.layout == .@"packed") return f.moveCValue(inst, union_ty, payload);
|
||||
|
||||
const local = try f.allocLocal(inst, union_ty);
|
||||
|
||||
|
|
@ -7466,7 +7435,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
|
|||
const a = try Assignment.start(f, w, try f.ctypeFromType(tag_ty, .complete));
|
||||
try f.writeCValueMember(w, local, .{ .identifier = "tag" });
|
||||
try a.assign(f, w);
|
||||
try w.print("{f}", .{try f.fmtIntLiteralDec(try tag_val.intFromEnum(tag_ty, pt))});
|
||||
try w.print("{f}", .{try f.fmtIntLiteralDec(tag_val.intFromEnum(zcu))});
|
||||
try a.end(f, w);
|
||||
break :field .{ .payload_identifier = field_name.toSlice(ip) };
|
||||
} else .{ .identifier = field_name.toSlice(ip) };
|
||||
|
|
|
|||
|
|
@ -2558,7 +2558,7 @@ pub const Pool = struct {
|
|||
.tag = .@"struct",
|
||||
.name = .{ .index = ip_index },
|
||||
});
|
||||
if (kind.isForward()) return if (ty.hasRuntimeBitsIgnoreComptime(zcu))
|
||||
if (kind.isForward()) return if (ty.hasRuntimeBits(zcu))
|
||||
fwd_decl
|
||||
else
|
||||
.void;
|
||||
|
|
@ -2584,9 +2584,9 @@ pub const Pool = struct {
|
|||
kind.noParameter(),
|
||||
);
|
||||
if (field_ctype.index == .void) continue;
|
||||
const field_name = try pool.string(allocator, loaded_struct.fieldName(ip, field_index).toSlice(ip));
|
||||
const field_name = try pool.string(allocator, loaded_struct.field_names.get(ip)[field_index].toSlice(ip));
|
||||
const field_alignas = AlignAs.fromAlignment(.{
|
||||
.@"align" = loaded_struct.fieldAlign(ip, field_index),
|
||||
.@"align" = loaded_struct.field_aligns.getOrNone(ip, field_index),
|
||||
.abi = field_type.abiAlignment(zcu),
|
||||
});
|
||||
pool.addHashedExtraAssumeCapacityTo(scratch, &hasher, Field, .{
|
||||
|
|
@ -2613,7 +2613,7 @@ pub const Pool = struct {
|
|||
.@"packed" => return pool.fromType(
|
||||
allocator,
|
||||
scratch,
|
||||
Type.fromInterned(loaded_struct.backingIntTypeUnordered(ip)),
|
||||
.fromInterned(loaded_struct.packed_backing_int_type),
|
||||
pt,
|
||||
mod,
|
||||
kind,
|
||||
|
|
@ -2682,17 +2682,17 @@ pub const Pool = struct {
|
|||
},
|
||||
.union_type => {
|
||||
const loaded_union = ip.loadUnionType(ip_index);
|
||||
switch (loaded_union.flagsUnordered(ip).layout) {
|
||||
switch (loaded_union.layout) {
|
||||
.auto, .@"extern" => {
|
||||
const fwd_decl = try pool.getFwdDecl(allocator, .{
|
||||
.tag = if (loaded_union.has_runtime_tag) .@"struct" else .@"union",
|
||||
.name = .{ .index = ip_index },
|
||||
});
|
||||
if (kind.isForward()) return if (ty.hasRuntimeBitsIgnoreComptime(zcu))
|
||||
if (kind.isForward()) return if (ty.hasRuntimeBits(zcu))
|
||||
fwd_decl
|
||||
else
|
||||
.void;
|
||||
const loaded_tag = loaded_union.loadTagType(ip);
|
||||
const loaded_tag = ip.loadEnumType(loaded_union.enum_tag_type);
|
||||
const scratch_top = scratch.items.len;
|
||||
defer scratch.shrinkRetainingCapacity(scratch_top);
|
||||
try scratch.ensureUnusedCapacity(
|
||||
|
|
@ -2718,10 +2718,10 @@ pub const Pool = struct {
|
|||
if (field_ctype.index == .void) continue;
|
||||
const field_name = try pool.string(
|
||||
allocator,
|
||||
loaded_tag.names.get(ip)[field_index].toSlice(ip),
|
||||
loaded_tag.field_names.get(ip)[field_index].toSlice(ip),
|
||||
);
|
||||
const field_alignas = AlignAs.fromAlignment(.{
|
||||
.@"align" = loaded_union.fieldAlign(ip, field_index),
|
||||
.@"align" = loaded_union.field_aligns.getOrNone(ip, field_index),
|
||||
.abi = field_type.abiAlignment(zcu),
|
||||
});
|
||||
pool.addHashedExtraAssumeCapacityTo(scratch, &hasher, Field, .{
|
||||
|
|
@ -2753,24 +2753,22 @@ pub const Pool = struct {
|
|||
try pool.ensureUnusedCapacity(allocator, 2);
|
||||
var struct_fields: [2]Info.Field = undefined;
|
||||
var struct_fields_len: usize = 0;
|
||||
if (loaded_tag.tag_ty != .comptime_int_type) {
|
||||
const tag_type = Type.fromInterned(loaded_tag.tag_ty);
|
||||
const tag_ctype: CType = try pool.fromType(
|
||||
allocator,
|
||||
scratch,
|
||||
tag_type,
|
||||
pt,
|
||||
mod,
|
||||
kind.noParameter(),
|
||||
);
|
||||
if (tag_ctype.index != .void) {
|
||||
struct_fields[struct_fields_len] = .{
|
||||
.name = .{ .index = .tag },
|
||||
.ctype = tag_ctype,
|
||||
.alignas = AlignAs.fromAbiAlignment(tag_type.abiAlignment(zcu)),
|
||||
};
|
||||
struct_fields_len += 1;
|
||||
}
|
||||
const tag_type = Type.fromInterned(loaded_tag.int_tag_type);
|
||||
const tag_ctype: CType = try pool.fromType(
|
||||
allocator,
|
||||
scratch,
|
||||
tag_type,
|
||||
pt,
|
||||
mod,
|
||||
kind.noParameter(),
|
||||
);
|
||||
if (tag_ctype.index != .void) {
|
||||
struct_fields[struct_fields_len] = .{
|
||||
.name = .{ .index = .tag },
|
||||
.ctype = tag_ctype,
|
||||
.alignas = AlignAs.fromAbiAlignment(tag_type.abiAlignment(zcu)),
|
||||
};
|
||||
struct_fields_len += 1;
|
||||
}
|
||||
if (fields_len > 0) {
|
||||
const payload_ctype = payload_ctype: {
|
||||
|
|
@ -2823,12 +2821,14 @@ pub const Pool = struct {
|
|||
.enum_type => return pool.fromType(
|
||||
allocator,
|
||||
scratch,
|
||||
Type.fromInterned(ip.loadEnumType(ip_index).tag_ty),
|
||||
.fromInterned(ip.loadEnumType(ip_index).int_tag_type),
|
||||
pt,
|
||||
mod,
|
||||
kind,
|
||||
),
|
||||
.func_type => |func_info| if (func_info.is_generic) return .void else {
|
||||
.func_type => |func_info| {
|
||||
if (!ty.fnHasRuntimeBits(zcu)) return .void;
|
||||
|
||||
const scratch_top = scratch.items.len;
|
||||
defer scratch.shrinkRetainingCapacity(scratch_top);
|
||||
try scratch.ensureUnusedCapacity(allocator, func_info.param_types.len);
|
||||
|
|
@ -2894,6 +2894,7 @@ pub const Pool = struct {
|
|||
.opt,
|
||||
.aggregate,
|
||||
.un,
|
||||
.bitpack,
|
||||
.memoized_call,
|
||||
=> unreachable, // values, not types
|
||||
},
|
||||
|
|
|
|||
|
|
@ -3257,7 +3257,7 @@ fn airOptionalPayload(func: *Func, inst: Air.Inst.Index) !void {
|
|||
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
|
||||
const result: MCValue = result: {
|
||||
const pl_ty = func.typeOfIndex(inst);
|
||||
if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;
|
||||
if (!pl_ty.hasRuntimeBits(zcu)) break :result .none;
|
||||
|
||||
const opt_mcv = try func.resolveInst(ty_op.operand);
|
||||
if (func.reuseOperand(inst, ty_op.operand, 0, opt_mcv)) {
|
||||
|
|
@ -3331,7 +3331,7 @@ fn airUnwrapErrErr(func: *Func, inst: Air.Inst.Index) !void {
|
|||
break :result .{ .immediate = 0 };
|
||||
}
|
||||
|
||||
if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (!payload_ty.hasRuntimeBits(zcu)) {
|
||||
break :result operand;
|
||||
}
|
||||
|
||||
|
|
@ -3384,7 +3384,7 @@ fn genUnwrapErrUnionPayloadMir(
|
|||
const payload_ty = err_union_ty.errorUnionPayload(zcu);
|
||||
|
||||
const result: MCValue = result: {
|
||||
if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;
|
||||
if (!payload_ty.hasRuntimeBits(zcu)) break :result .none;
|
||||
|
||||
const payload_off: u31 = @intCast(errUnionPayloadOffset(payload_ty, zcu));
|
||||
switch (err_union) {
|
||||
|
|
@ -3547,7 +3547,7 @@ fn airWrapErrUnionPayload(func: *Func, inst: Air.Inst.Index) !void {
|
|||
const operand = try func.resolveInst(ty_op.operand);
|
||||
|
||||
const result: MCValue = result: {
|
||||
if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .{ .immediate = 0 };
|
||||
if (!pl_ty.hasRuntimeBits(zcu)) break :result .{ .immediate = 0 };
|
||||
|
||||
const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(eu_ty, zcu));
|
||||
const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, zcu));
|
||||
|
|
@ -3571,7 +3571,7 @@ fn airWrapErrUnionErr(func: *Func, inst: Air.Inst.Index) !void {
|
|||
const err_ty = eu_ty.errorUnionSet(zcu);
|
||||
|
||||
const result: MCValue = result: {
|
||||
if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result try func.resolveInst(ty_op.operand);
|
||||
if (!pl_ty.hasRuntimeBits(zcu)) break :result try func.resolveInst(ty_op.operand);
|
||||
|
||||
const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(eu_ty, zcu));
|
||||
const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, zcu));
|
||||
|
|
@ -3761,7 +3761,7 @@ fn airSliceElemVal(func: *Func, inst: Air.Inst.Index) !void {
|
|||
|
||||
const result: MCValue = result: {
|
||||
const elem_ty = func.typeOfIndex(inst);
|
||||
if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;
|
||||
assert(elem_ty.hasRuntimeBits(zcu));
|
||||
|
||||
const slice_ty = func.typeOf(bin_op.lhs);
|
||||
const slice_ptr_field_type = slice_ty.slicePtrFieldType(zcu);
|
||||
|
|
@ -3914,7 +3914,7 @@ fn airPtrElemVal(func: *Func, inst: Air.Inst.Index) !void {
|
|||
|
||||
const result: MCValue = if (!is_volatile and func.liveness.isUnused(inst)) .unreach else result: {
|
||||
const elem_ty = base_ptr_ty.indexableElem(zcu);
|
||||
if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;
|
||||
assert(elem_ty.hasRuntimeBits(zcu));
|
||||
const base_ptr_mcv = try func.resolveInst(bin_op.lhs);
|
||||
const base_ptr_lock: ?RegisterLock = switch (base_ptr_mcv) {
|
||||
.register => |reg| func.register_manager.lockRegAssumeUnused(reg),
|
||||
|
|
@ -4617,7 +4617,7 @@ fn airStructFieldVal(func: *Func, inst: Air.Inst.Index) !void {
|
|||
const src_mcv = try func.resolveInst(operand);
|
||||
const struct_ty = func.typeOf(operand);
|
||||
const field_ty = struct_ty.fieldType(index, zcu);
|
||||
if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;
|
||||
assert(field_ty.hasRuntimeBits(zcu));
|
||||
|
||||
const field_off: u32 = switch (struct_ty.containerLayout(zcu)) {
|
||||
.auto, .@"extern" => @intCast(struct_ty.structFieldOffset(index, zcu) * 8),
|
||||
|
|
@ -5126,7 +5126,6 @@ fn airCmp(func: *Func, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
|
|||
const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
|
||||
const pt = func.pt;
|
||||
const zcu = pt.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
|
||||
const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {
|
||||
const lhs_ty = func.typeOf(bin_op.lhs);
|
||||
|
|
@ -5140,28 +5139,23 @@ fn airCmp(func: *Func, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
|
|||
.optional,
|
||||
.@"struct",
|
||||
=> {
|
||||
const int_ty = switch (lhs_ty.zigTypeTag(zcu)) {
|
||||
const int_ty: Type = switch (lhs_ty.zigTypeTag(zcu)) {
|
||||
.@"enum" => lhs_ty.intTagType(zcu),
|
||||
.int => lhs_ty,
|
||||
.bool => Type.u1,
|
||||
.pointer => Type.u64,
|
||||
.error_set => Type.anyerror,
|
||||
.bool => .u1,
|
||||
.pointer => .u64,
|
||||
.error_set => .anyerror,
|
||||
.optional => blk: {
|
||||
const payload_ty = lhs_ty.optionalChild(zcu);
|
||||
if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
break :blk Type.u1;
|
||||
if (!payload_ty.hasRuntimeBits(zcu)) {
|
||||
break :blk .u1;
|
||||
} else if (lhs_ty.isPtrLikeOptional(zcu)) {
|
||||
break :blk Type.u64;
|
||||
break :blk .u64;
|
||||
} else {
|
||||
return func.fail("TODO riscv cmp non-pointer optionals", .{});
|
||||
}
|
||||
},
|
||||
.@"struct" => blk: {
|
||||
const struct_obj = ip.loadStructType(lhs_ty.toIntern());
|
||||
assert(struct_obj.layout == .@"packed");
|
||||
const backing_index = struct_obj.backingIntTypeUnordered(ip);
|
||||
break :blk Type.fromInterned(backing_index);
|
||||
},
|
||||
.@"struct", .@"union" => lhs_ty.bitpackBackingInt(zcu),
|
||||
else => unreachable,
|
||||
};
|
||||
|
||||
|
|
@ -5925,8 +5919,7 @@ fn airBr(func: *Func, inst: Air.Inst.Index) !void {
|
|||
const br = func.air.instructions.items(.data)[@intFromEnum(inst)].br;
|
||||
|
||||
const block_ty = func.typeOfIndex(br.block_inst);
|
||||
const block_unused =
|
||||
!block_ty.hasRuntimeBitsIgnoreComptime(zcu) or func.liveness.isUnused(br.block_inst);
|
||||
const block_unused = !block_ty.hasRuntimeBits(zcu) or func.liveness.isUnused(br.block_inst);
|
||||
const block_tracking = func.inst_tracking.getPtr(br.block_inst).?;
|
||||
const block_data = func.blocks.getPtr(br.block_inst).?;
|
||||
const first_br = block_data.relocs.items.len == 0;
|
||||
|
|
@ -8249,7 +8242,7 @@ fn resolveCallingConventionValues(
|
|||
// Return values
|
||||
if (ret_ty.zigTypeTag(zcu) == .noreturn) {
|
||||
result.return_value = InstTracking.init(.unreach);
|
||||
} else if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
} else if (!ret_ty.hasRuntimeBits(zcu)) {
|
||||
result.return_value = InstTracking.init(.none);
|
||||
} else {
|
||||
var ret_tracking: [2]InstTracking = undefined;
|
||||
|
|
@ -8300,7 +8293,7 @@ fn resolveCallingConventionValues(
|
|||
var param_float_reg_i: usize = 0;
|
||||
|
||||
for (param_types, result.args) |ty, *arg| {
|
||||
if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (!ty.hasRuntimeBits(zcu)) {
|
||||
assert(cc == .auto);
|
||||
arg.* = .none;
|
||||
continue;
|
||||
|
|
@ -8415,10 +8408,10 @@ fn hasFeature(func: *Func, feature: Target.riscv.Feature) bool {
|
|||
}
|
||||
|
||||
pub fn errUnionPayloadOffset(payload_ty: Type, zcu: *Zcu) u64 {
|
||||
if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return 0;
|
||||
if (!payload_ty.hasRuntimeBits(zcu)) return 0;
|
||||
const payload_align = payload_ty.abiAlignment(zcu);
|
||||
const error_align = Type.anyerror.abiAlignment(zcu);
|
||||
if (payload_align.compare(.gte, error_align) or !payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (payload_align.compare(.gte, error_align) or !payload_ty.hasRuntimeBits(zcu)) {
|
||||
return 0;
|
||||
} else {
|
||||
return payload_align.forward(Type.anyerror.abiSize(zcu));
|
||||
|
|
@ -8426,10 +8419,10 @@ pub fn errUnionPayloadOffset(payload_ty: Type, zcu: *Zcu) u64 {
|
|||
}
|
||||
|
||||
pub fn errUnionErrorOffset(payload_ty: Type, zcu: *Zcu) u64 {
|
||||
if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return 0;
|
||||
if (!payload_ty.hasRuntimeBits(zcu)) return 0;
|
||||
const payload_align = payload_ty.abiAlignment(zcu);
|
||||
const error_align = Type.anyerror.abiAlignment(zcu);
|
||||
if (payload_align.compare(.gte, error_align) and payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (payload_align.compare(.gte, error_align) and payload_ty.hasRuntimeBits(zcu)) {
|
||||
return error_align.forward(payload_ty.abiSize(zcu));
|
||||
} else {
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -1102,7 +1102,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
|
|||
fn lowerBlock(self: *Self, inst: Air.Inst.Index, body: []const Air.Inst.Index) !void {
|
||||
try self.blocks.putNoClobber(self.gpa, inst, .{
|
||||
// A block is a setup to be able to jump to the end.
|
||||
.relocs = .{},
|
||||
.relocs = .empty,
|
||||
// It also acts as a receptacle for break operands.
|
||||
// Here we use `MCValue.none` to represent a null value so that the first
|
||||
// break instruction will choose a MCValue for the block result and overwrite
|
||||
|
|
@ -1376,19 +1376,19 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
|
|||
const rhs = try self.resolveInst(bin_op.rhs);
|
||||
const lhs_ty = self.typeOf(bin_op.lhs);
|
||||
|
||||
const int_ty = switch (lhs_ty.zigTypeTag(zcu)) {
|
||||
const int_ty: Type = switch (lhs_ty.zigTypeTag(zcu)) {
|
||||
.vector => unreachable, // Handled by cmp_vector.
|
||||
.@"enum" => lhs_ty.intTagType(zcu),
|
||||
.int => lhs_ty,
|
||||
.bool => Type.u1,
|
||||
.pointer => Type.usize,
|
||||
.error_set => Type.u16,
|
||||
.bool => .u1,
|
||||
.pointer => .usize,
|
||||
.error_set => .u16,
|
||||
.optional => blk: {
|
||||
const payload_ty = lhs_ty.optionalChild(zcu);
|
||||
if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
break :blk Type.u1;
|
||||
if (!payload_ty.hasRuntimeBits(zcu)) {
|
||||
break :blk .u1;
|
||||
} else if (lhs_ty.isPtrLikeOptional(zcu)) {
|
||||
break :blk Type.usize;
|
||||
break :blk .usize;
|
||||
} else {
|
||||
return self.fail("TODO SPARCv9 cmp non-pointer optionals", .{});
|
||||
}
|
||||
|
|
@ -3452,8 +3452,8 @@ fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type)
|
|||
if (err_ty.errorSetIsEmpty(zcu)) {
|
||||
return error_union_mcv;
|
||||
}
|
||||
if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
return MCValue.none;
|
||||
if (!payload_ty.hasRuntimeBits(zcu)) {
|
||||
return .none;
|
||||
}
|
||||
|
||||
const payload_offset: u32 = @intCast(errUnionPayloadOffset(payload_ty, zcu));
|
||||
|
|
@ -4481,7 +4481,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
|
|||
const ty = self.typeOf(ref);
|
||||
|
||||
// If the type has no codegen bits, no need to store it.
|
||||
if (!ty.hasRuntimeBitsIgnoreComptime(pt.zcu)) return .none;
|
||||
if (!ty.hasRuntimeBits(pt.zcu)) return .none;
|
||||
|
||||
if (ref.toIndex()) |inst| {
|
||||
return self.getResolvedInstValue(inst);
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void {
|
|||
try cg.args.ensureUnusedCapacity(gpa, fn_info.param_types.len);
|
||||
for (fn_info.param_types.get(ip)) |param_ty_index| {
|
||||
const param_ty: Type = .fromInterned(param_ty_index);
|
||||
if (!param_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
|
||||
if (!param_ty.hasRuntimeBits(zcu)) continue;
|
||||
|
||||
const param_type_id = try cg.resolveType(param_ty, .direct);
|
||||
const arg_result_id = cg.module.allocId();
|
||||
|
|
@ -884,7 +884,7 @@ fn constant(cg: *CodeGen, ty: Type, val: Value, repr: Repr) Error!Id {
|
|||
return try cg.constructComposite(comp_ty_id, &constituents);
|
||||
},
|
||||
.enum_tag => {
|
||||
const int_val = try val.intFromEnum(ty, pt);
|
||||
const int_val = val.intFromEnum(zcu);
|
||||
const int_ty = ty.intTagType(zcu);
|
||||
break :cache try cg.constant(int_ty, int_val, repr);
|
||||
},
|
||||
|
|
@ -959,18 +959,7 @@ fn constant(cg: *CodeGen, ty: Type, val: Value, repr: Repr) Error!Id {
|
|||
},
|
||||
.struct_type => {
|
||||
const struct_type = zcu.typeToStruct(ty).?;
|
||||
|
||||
if (struct_type.layout == .@"packed") {
|
||||
// TODO: composite int
|
||||
// TODO: endianness
|
||||
const bits: u16 = @intCast(ty.bitSize(zcu));
|
||||
const bytes = std.mem.alignForward(u16, cg.module.backingIntBits(bits).@"0", 8) / 8;
|
||||
var limbs: [8]u8 = undefined;
|
||||
@memset(&limbs, 0);
|
||||
val.writeToPackedMemory(pt, limbs[0..bytes], 0) catch unreachable;
|
||||
const backing_ty: Type = .fromInterned(struct_type.backingIntTypeUnordered(ip));
|
||||
return try cg.constInt(backing_ty, @as(u64, @bitCast(limbs)));
|
||||
}
|
||||
assert(struct_type.layout != .@"packed"); // packed structs use `bitpack`
|
||||
|
||||
var types = std.array_list.Managed(Type).init(gpa);
|
||||
defer types.deinit();
|
||||
|
|
@ -981,7 +970,7 @@ fn constant(cg: *CodeGen, ty: Type, val: Value, repr: Repr) Error!Id {
|
|||
var it = struct_type.iterateRuntimeOrder(ip);
|
||||
while (it.next()) |field_index| {
|
||||
const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]);
|
||||
if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (!field_ty.hasRuntimeBits(zcu)) {
|
||||
// This is a zero-bit field - we only needed it for the alignment.
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1001,20 +990,24 @@ fn constant(cg: *CodeGen, ty: Type, val: Value, repr: Repr) Error!Id {
|
|||
else => unreachable,
|
||||
},
|
||||
.un => |un| {
|
||||
assert(ty.containerLayout(zcu) != .@"packed"); // packed unions use `bitpack`
|
||||
if (un.tag == .none) {
|
||||
assert(ty.containerLayout(zcu) == .@"packed"); // TODO
|
||||
const int_ty = try pt.intType(.unsigned, @intCast(ty.bitSize(zcu)));
|
||||
return try cg.constInt(int_ty, Value.toUnsignedInt(.fromInterned(un.val), zcu));
|
||||
@panic("TODO");
|
||||
}
|
||||
const active_field = ty.unionTagFieldIndex(.fromInterned(un.tag), zcu).?;
|
||||
const union_obj = zcu.typeToUnion(ty).?;
|
||||
const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[active_field]);
|
||||
const payload = if (field_ty.hasRuntimeBitsIgnoreComptime(zcu))
|
||||
const payload = if (field_ty.hasRuntimeBits(zcu))
|
||||
try cg.constant(field_ty, .fromInterned(un.val), .direct)
|
||||
else
|
||||
null;
|
||||
return try cg.unionInit(ty, active_field, payload);
|
||||
},
|
||||
.bitpack => |bitpack| {
|
||||
const int_val: Value = .fromInterned(bitpack.backing_int_val);
|
||||
break :cache try cg.constant(int_val.typeOf(zcu), int_val, repr);
|
||||
},
|
||||
|
||||
.memoized_call => unreachable,
|
||||
}
|
||||
};
|
||||
|
|
@ -1255,17 +1248,16 @@ fn resolveTypeName(cg: *CodeGen, ty: Type) ![]const u8 {
|
|||
fn resolveUnionType(cg: *CodeGen, ty: Type) !Id {
|
||||
const gpa = cg.module.gpa;
|
||||
const zcu = cg.module.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
const union_obj = zcu.typeToUnion(ty).?;
|
||||
|
||||
if (union_obj.flagsUnordered(ip).layout == .@"packed") {
|
||||
if (union_obj.layout == .@"packed") {
|
||||
return try cg.module.intType(.unsigned, @intCast(ty.bitSize(zcu)));
|
||||
}
|
||||
|
||||
const layout = cg.unionLayout(ty);
|
||||
if (!layout.has_payload) {
|
||||
// No payload, so represent this as just the tag type.
|
||||
return try cg.resolveType(.fromInterned(union_obj.enum_tag_ty), .indirect);
|
||||
return try cg.resolveType(.fromInterned(union_obj.enum_tag_type), .indirect);
|
||||
}
|
||||
|
||||
var member_types: [4]Id = undefined;
|
||||
|
|
@ -1274,7 +1266,7 @@ fn resolveUnionType(cg: *CodeGen, ty: Type) !Id {
|
|||
const u8_ty_id = try cg.resolveType(.u8, .direct);
|
||||
|
||||
if (layout.tag_size != 0) {
|
||||
const tag_ty_id = try cg.resolveType(.fromInterned(union_obj.enum_tag_ty), .indirect);
|
||||
const tag_ty_id = try cg.resolveType(.fromInterned(union_obj.enum_tag_type), .indirect);
|
||||
member_types[layout.tag_index] = tag_ty_id;
|
||||
member_names[layout.tag_index] = "(tag)";
|
||||
}
|
||||
|
|
@ -1315,7 +1307,7 @@ fn resolveUnionType(cg: *CodeGen, ty: Type) !Id {
|
|||
|
||||
fn resolveFnReturnType(cg: *CodeGen, ret_ty: Type) !Id {
|
||||
const zcu = cg.module.zcu;
|
||||
if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (!ret_ty.hasRuntimeBits(zcu)) {
|
||||
// If the return type is an error set or an error union, then we make this
|
||||
// anyerror return type instead, so that it can be coerced into a function
|
||||
// pointer type which has anyerror as the return type.
|
||||
|
|
@ -1389,7 +1381,7 @@ fn resolveType(cg: *CodeGen, ty: Type, repr: Repr) Error!Id {
|
|||
return cg.fail("array type of {} elements is too large", .{ty.arrayLenIncludingSentinel(zcu)});
|
||||
};
|
||||
|
||||
if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (!elem_ty.hasRuntimeBits(zcu)) {
|
||||
assert(repr == .indirect);
|
||||
if (target.os.tag != .opencl) return cg.fail("cannot generate opaque type", .{});
|
||||
return try cg.module.opaqueType("zero-sized-array");
|
||||
|
|
@ -1453,7 +1445,7 @@ fn resolveType(cg: *CodeGen, ty: Type, repr: Repr) Error!Id {
|
|||
var param_index: usize = 0;
|
||||
for (fn_info.param_types.get(ip)) |param_ty_index| {
|
||||
const param_ty: Type = .fromInterned(param_ty_index);
|
||||
if (!param_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
|
||||
if (!param_ty.hasRuntimeBits(zcu)) continue;
|
||||
|
||||
param_ty_ids[param_index] = try cg.resolveType(param_ty, .direct);
|
||||
param_index += 1;
|
||||
|
|
@ -1518,7 +1510,7 @@ fn resolveType(cg: *CodeGen, ty: Type, repr: Repr) Error!Id {
|
|||
};
|
||||
|
||||
if (struct_type.layout == .@"packed") {
|
||||
return try cg.resolveType(.fromInterned(struct_type.backingIntTypeUnordered(ip)), .direct);
|
||||
return try cg.resolveType(.fromInterned(struct_type.packed_backing_int_type), .direct);
|
||||
}
|
||||
|
||||
var member_types = std.array_list.Managed(Id).init(gpa);
|
||||
|
|
@ -1533,9 +1525,9 @@ fn resolveType(cg: *CodeGen, ty: Type, repr: Repr) Error!Id {
|
|||
var it = struct_type.iterateRuntimeOrder(ip);
|
||||
while (it.next()) |field_index| {
|
||||
const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]);
|
||||
if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
|
||||
if (!field_ty.hasRuntimeBits(zcu)) continue;
|
||||
|
||||
const field_name = struct_type.fieldName(ip, field_index);
|
||||
const field_name = struct_type.field_names.get(ip)[field_index];
|
||||
try member_types.append(try cg.resolveType(field_ty, .indirect));
|
||||
try member_names.append(field_name.toSlice(ip));
|
||||
try member_offsets.append(@intCast(ty.structFieldOffset(field_index, zcu)));
|
||||
|
|
@ -1556,7 +1548,7 @@ fn resolveType(cg: *CodeGen, ty: Type, repr: Repr) Error!Id {
|
|||
},
|
||||
.optional => {
|
||||
const payload_ty = ty.optionalChild(zcu);
|
||||
if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (!payload_ty.hasRuntimeBits(zcu)) {
|
||||
// Just use a bool.
|
||||
// Note: Always generate the bool with indirect format, to save on some sanity
|
||||
// Perform the conversion to a direct bool when the field is extracted.
|
||||
|
|
@ -1653,7 +1645,7 @@ fn errorUnionLayout(cg: *CodeGen, payload_ty: Type) ErrorUnionLayout {
|
|||
|
||||
const error_first = error_align.compare(.gt, payload_align);
|
||||
return .{
|
||||
.payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(zcu),
|
||||
.payload_has_bits = payload_ty.hasRuntimeBits(zcu),
|
||||
.error_first = error_first,
|
||||
};
|
||||
}
|
||||
|
|
@ -3724,7 +3716,6 @@ fn cmp(
|
|||
const gpa = cg.module.gpa;
|
||||
const pt = cg.pt;
|
||||
const zcu = cg.module.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
const scalar_ty = lhs.ty.scalarType(zcu);
|
||||
const is_vector = lhs.ty.isVector(zcu);
|
||||
|
||||
|
|
@ -3737,7 +3728,7 @@ fn cmp(
|
|||
},
|
||||
.@"struct" => {
|
||||
const struct_ty = zcu.typeToPackedStruct(scalar_ty).?;
|
||||
const ty: Type = .fromInterned(struct_ty.backingIntTypeUnordered(ip));
|
||||
const ty: Type = .fromInterned(struct_ty.packed_backing_int_type);
|
||||
return try cg.cmp(op, lhs.pun(ty), rhs.pun(ty));
|
||||
},
|
||||
.error_set => {
|
||||
|
|
@ -3778,7 +3769,7 @@ fn cmp(
|
|||
|
||||
const payload_ty = ty.optionalChild(zcu);
|
||||
if (ty.optionalReprIsPayload(zcu)) {
|
||||
assert(payload_ty.hasRuntimeBitsIgnoreComptime(zcu));
|
||||
assert(payload_ty.hasRuntimeBits(zcu));
|
||||
assert(!payload_ty.isSlice(zcu));
|
||||
|
||||
return try cg.cmp(op, lhs.pun(payload_ty), rhs.pun(payload_ty));
|
||||
|
|
@ -3787,12 +3778,12 @@ fn cmp(
|
|||
const lhs_id = try lhs.materialize(cg);
|
||||
const rhs_id = try rhs.materialize(cg);
|
||||
|
||||
const lhs_valid_id = if (payload_ty.hasRuntimeBitsIgnoreComptime(zcu))
|
||||
const lhs_valid_id = if (payload_ty.hasRuntimeBits(zcu))
|
||||
try cg.extractField(.bool, lhs_id, 1)
|
||||
else
|
||||
try cg.convertToDirect(.bool, lhs_id);
|
||||
|
||||
const rhs_valid_id = if (payload_ty.hasRuntimeBitsIgnoreComptime(zcu))
|
||||
const rhs_valid_id = if (payload_ty.hasRuntimeBits(zcu))
|
||||
try cg.extractField(.bool, rhs_id, 1)
|
||||
else
|
||||
try cg.convertToDirect(.bool, rhs_id);
|
||||
|
|
@ -3800,7 +3791,7 @@ fn cmp(
|
|||
const lhs_valid: Temporary = .init(.bool, lhs_valid_id);
|
||||
const rhs_valid: Temporary = .init(.bool, rhs_valid_id);
|
||||
|
||||
if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (!payload_ty.hasRuntimeBits(zcu)) {
|
||||
return try cg.cmp(op, lhs_valid, rhs_valid);
|
||||
}
|
||||
|
||||
|
|
@ -4138,7 +4129,7 @@ fn airArrayToSlice(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
|||
const array_ptr_id = try cg.resolve(ty_op.operand);
|
||||
const len_id = try cg.constInt(.usize, array_ty.arrayLen(zcu));
|
||||
|
||||
const elem_ptr_id = if (!array_ty.hasRuntimeBitsIgnoreComptime(zcu))
|
||||
const elem_ptr_id = if (!array_ty.hasRuntimeBits(zcu))
|
||||
// Note: The pointer is something like *opaque{}, so we need to bitcast it to the element type.
|
||||
try cg.bitCast(elem_ptr_ty, array_ptr_ty, array_ptr_id)
|
||||
else
|
||||
|
|
@ -4174,12 +4165,12 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
|||
.@"struct" => {
|
||||
if (zcu.typeToPackedStruct(result_ty)) |struct_type| {
|
||||
comptime assert(Type.packed_struct_layout_version == 2);
|
||||
const backing_int_ty: Type = .fromInterned(struct_type.backingIntTypeUnordered(ip));
|
||||
const backing_int_ty: Type = .fromInterned(struct_type.packed_backing_int_type);
|
||||
var running_int_id = try cg.constInt(backing_int_ty, 0);
|
||||
var running_bits: u16 = 0;
|
||||
for (struct_type.field_types.get(ip), elements) |field_ty_ip, element| {
|
||||
const field_ty: Type = .fromInterned(field_ty_ip);
|
||||
if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
|
||||
if (!field_ty.hasRuntimeBits(zcu)) continue;
|
||||
const field_id = try cg.resolve(element);
|
||||
const ty_bit_size: u16 = @intCast(field_ty.bitSize(zcu));
|
||||
const field_int_ty = try cg.pt.intType(.unsigned, ty_bit_size);
|
||||
|
|
@ -4239,7 +4230,7 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
|||
const field_index = it.next().?;
|
||||
if ((try result_ty.structFieldValueComptime(pt, i)) != null) continue;
|
||||
const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]);
|
||||
assert(field_ty.hasRuntimeBitsIgnoreComptime(zcu));
|
||||
assert(field_ty.hasRuntimeBits(zcu));
|
||||
|
||||
const id = try cg.resolve(element);
|
||||
types[index] = field_ty;
|
||||
|
|
@ -4399,10 +4390,7 @@ fn airPtrElemPtr(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
|||
const elem_ty = src_ptr_ty.childType(zcu);
|
||||
const ptr_id = try cg.resolve(bin_op.lhs);
|
||||
|
||||
if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
const dst_ptr_ty = cg.typeOfIndex(inst);
|
||||
return try cg.bitCast(dst_ptr_ty, src_ptr_ty, ptr_id);
|
||||
}
|
||||
assert(elem_ty.hasRuntimeBits(zcu));
|
||||
|
||||
const index_id = try cg.resolve(bin_op.rhs);
|
||||
return try cg.ptrElemPtr(src_ptr_ty, ptr_id, index_id);
|
||||
|
|
@ -4526,13 +4514,13 @@ fn unionInit(
|
|||
const zcu = cg.module.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
const union_ty = zcu.typeToUnion(ty).?;
|
||||
const tag_ty: Type = .fromInterned(union_ty.enum_tag_ty);
|
||||
const tag_ty: Type = .fromInterned(union_ty.enum_tag_type);
|
||||
|
||||
const layout = cg.unionLayout(ty);
|
||||
const payload_ty: Type = .fromInterned(union_ty.field_types.get(ip)[active_field]);
|
||||
|
||||
if (union_ty.flagsUnordered(ip).layout == .@"packed") {
|
||||
if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (union_ty.layout == .@"packed") {
|
||||
if (!payload_ty.hasRuntimeBits(zcu)) {
|
||||
const int_ty = try pt.intType(.unsigned, @intCast(ty.bitSize(zcu)));
|
||||
return cg.constInt(int_ty, 0);
|
||||
}
|
||||
|
|
@ -4558,7 +4546,7 @@ fn unionInit(
|
|||
|
||||
const tag_int = if (layout.tag_size != 0) blk: {
|
||||
const tag_val = try pt.enumValueFieldIndex(tag_ty, active_field);
|
||||
const tag_int_val = try tag_val.intFromEnum(tag_ty, pt);
|
||||
const tag_int_val = tag_val.intFromEnum(zcu);
|
||||
break :blk tag_int_val.toUnsignedInt(zcu);
|
||||
} else 0;
|
||||
|
||||
|
|
@ -4577,7 +4565,7 @@ fn unionInit(
|
|||
try cg.store(tag_ty, ptr_id, tag_id, .{});
|
||||
}
|
||||
|
||||
if (payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (payload_ty.hasRuntimeBits(zcu)) {
|
||||
const layout_payload_ty_id = try cg.resolveType(layout.payload_ty, .indirect);
|
||||
const pl_ptr_ty_id = try cg.module.ptrType(layout_payload_ty_id, .function);
|
||||
const pl_ptr_id = try cg.accessChain(pl_ptr_ty_id, tmp_id, &.{layout.payload_index});
|
||||
|
|
@ -4613,7 +4601,7 @@ fn airUnionInit(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
|||
|
||||
const union_obj = zcu.typeToUnion(ty).?;
|
||||
const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[extra.field_index]);
|
||||
const payload = if (field_ty.hasRuntimeBitsIgnoreComptime(zcu))
|
||||
const payload = if (field_ty.hasRuntimeBits(zcu))
|
||||
try cg.resolve(extra.init)
|
||||
else
|
||||
null;
|
||||
|
|
@ -4631,7 +4619,7 @@ fn airStructFieldVal(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
|||
const field_index = struct_field.field_index;
|
||||
const field_ty = object_ty.fieldType(field_index, zcu);
|
||||
|
||||
if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) return null;
|
||||
assert(field_ty.hasRuntimeBits(zcu));
|
||||
|
||||
switch (object_ty.zigTypeTag(zcu)) {
|
||||
.@"struct" => switch (object_ty.containerLayout(zcu)) {
|
||||
|
|
@ -5332,7 +5320,7 @@ fn airRet(cg: *CodeGen, inst: Air.Inst.Index) !void {
|
|||
const zcu = cg.module.zcu;
|
||||
const operand = cg.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
|
||||
const ret_ty = cg.typeOf(operand);
|
||||
if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (!ret_ty.hasRuntimeBits(zcu)) {
|
||||
const fn_info = zcu.typeToFunc(zcu.navValue(cg.owner_nav).typeOf(zcu)).?;
|
||||
if (Type.fromInterned(fn_info.return_type).isError(zcu)) {
|
||||
// Functions with an empty error set are emitted with an error code
|
||||
|
|
@ -5356,7 +5344,7 @@ fn airRetLoad(cg: *CodeGen, inst: Air.Inst.Index) !void {
|
|||
const ptr_ty = cg.typeOf(un_op);
|
||||
const ret_ty = ptr_ty.childType(zcu);
|
||||
|
||||
if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (!ret_ty.hasRuntimeBits(zcu)) {
|
||||
const fn_info = zcu.typeToFunc(zcu.navValue(cg.owner_nav).typeOf(zcu)).?;
|
||||
if (Type.fromInterned(fn_info.return_type).isError(zcu)) {
|
||||
// Functions with an empty error set are emitted with an error code
|
||||
|
|
@ -5573,7 +5561,7 @@ fn airIsNull(cg: *CodeGen, inst: Air.Inst.Index, is_pointer: bool, pred: enum {
|
|||
|
||||
const is_non_null_id = blk: {
|
||||
if (is_pointer) {
|
||||
if (payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (payload_ty.hasRuntimeBits(zcu)) {
|
||||
const storage_class = cg.module.storageClass(operand_ty.ptrAddressSpace(zcu));
|
||||
const bool_indirect_ty_id = try cg.resolveType(.bool, .indirect);
|
||||
const bool_ptr_ty_id = try cg.module.ptrType(bool_indirect_ty_id, storage_class);
|
||||
|
|
@ -5584,7 +5572,7 @@ fn airIsNull(cg: *CodeGen, inst: Air.Inst.Index, is_pointer: bool, pred: enum {
|
|||
break :blk try cg.load(.bool, operand_id, .{});
|
||||
}
|
||||
|
||||
break :blk if (payload_ty.hasRuntimeBitsIgnoreComptime(zcu))
|
||||
break :blk if (payload_ty.hasRuntimeBits(zcu))
|
||||
try cg.extractField(.bool, operand_id, 1)
|
||||
else
|
||||
// Optional representation is bool indicating whether the optional is set
|
||||
|
|
@ -5653,7 +5641,7 @@ fn airUnwrapOptional(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
|||
const optional_ty = cg.typeOf(ty_op.operand);
|
||||
const payload_ty = cg.typeOfIndex(inst);
|
||||
|
||||
if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return null;
|
||||
if (!payload_ty.hasRuntimeBits(zcu)) return null;
|
||||
|
||||
if (optional_ty.optionalReprIsPayload(zcu)) {
|
||||
return operand_id;
|
||||
|
|
@ -5672,7 +5660,7 @@ fn airUnwrapOptionalPtr(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
|||
const result_ty = cg.typeOfIndex(inst);
|
||||
const result_ty_id = try cg.resolveType(result_ty, .direct);
|
||||
|
||||
if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (!payload_ty.hasRuntimeBits(zcu)) {
|
||||
// There is no payload, but we still need to return a valid pointer.
|
||||
// We can just return anything here, so just return a pointer to the operand.
|
||||
return try cg.bitCast(result_ty, operand_ty, operand_id);
|
||||
|
|
@ -5691,9 +5679,7 @@ fn airWrapOptional(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
|||
const ty_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
|
||||
const payload_ty = cg.typeOf(ty_op.operand);
|
||||
|
||||
if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
return try cg.constBool(true, .indirect);
|
||||
}
|
||||
assert(payload_ty.hasRuntimeBits(zcu));
|
||||
|
||||
const operand_id = try cg.resolve(ty_op.operand);
|
||||
|
||||
|
|
@ -5789,8 +5775,7 @@ fn airSwitchBr(cg: *CodeGen, inst: Air.Inst.Index) !void {
|
|||
const int_val: u64 = switch (cond_ty.zigTypeTag(zcu)) {
|
||||
.bool, .int => if (cond_ty.isSignedInt(zcu)) @bitCast(value.toSignedInt(zcu)) else value.toUnsignedInt(zcu),
|
||||
.@"enum" => blk: {
|
||||
// TODO: figure out of cond_ty is correct (something with enum literals)
|
||||
break :blk (try value.intFromEnum(cond_ty, pt)).toUnsignedInt(zcu); // TODO: composite integer constants
|
||||
break :blk value.intFromEnum(zcu).toUnsignedInt(zcu); // TODO: composite integer constants
|
||||
},
|
||||
.error_set => value.getErrorInt(zcu),
|
||||
.pointer => value.toUnsignedInt(zcu),
|
||||
|
|
@ -6067,7 +6052,7 @@ fn airCall(cg: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifie
|
|||
// before starting to emit OpFunctionCall instructions. Hence the
|
||||
// temporary params buffer.
|
||||
const arg_ty = cg.typeOf(arg);
|
||||
if (!arg_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
|
||||
if (!arg_ty.hasRuntimeBits(zcu)) continue;
|
||||
const arg_id = try cg.resolve(arg);
|
||||
|
||||
params[n_params] = arg_id;
|
||||
|
|
@ -6081,7 +6066,7 @@ fn airCall(cg: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifie
|
|||
.id_ref_3 = params[0..n_params],
|
||||
});
|
||||
|
||||
if (cg.liveness.isUnused(inst) or !Type.fromInterned(return_type).hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (cg.liveness.isUnused(inst) or !Type.fromInterned(return_type).hasRuntimeBits(zcu)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -759,7 +759,7 @@ fn resolveInst(cg: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue {
|
|||
const zcu = pt.zcu;
|
||||
const val = (try cg.air.value(ref, pt)).?;
|
||||
const ty = cg.typeOf(ref);
|
||||
if (!ty.hasRuntimeBitsIgnoreComptime(zcu) and !ty.isInt(zcu) and !ty.isError(zcu)) {
|
||||
if (!ty.hasRuntimeBits(zcu) and !ty.isInt(zcu) and !ty.isError(zcu)) {
|
||||
gop.value_ptr.* = .none;
|
||||
return .none;
|
||||
}
|
||||
|
|
@ -773,7 +773,7 @@ fn resolveInst(cg: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue {
|
|||
const result: WValue = if (isByRef(ty, zcu, cg.target))
|
||||
.{ .uav_ref = .{ .ip_index = val.toIntern() } }
|
||||
else
|
||||
try cg.lowerConstant(val, ty);
|
||||
try cg.lowerConstant(val);
|
||||
|
||||
gop.value_ptr.* = result;
|
||||
return result;
|
||||
|
|
@ -786,7 +786,7 @@ fn resolveValue(cg: *CodeGen, val: Value) InnerError!WValue {
|
|||
return if (isByRef(ty, zcu, cg.target))
|
||||
.{ .uav_ref = .{ .ip_index = val.toIntern() } }
|
||||
else
|
||||
try cg.lowerConstant(val, ty);
|
||||
try cg.lowerConstant(val);
|
||||
}
|
||||
|
||||
/// NOTE: if result == .stack, it will be stored in .local
|
||||
|
|
@ -980,7 +980,6 @@ fn addExtraAssumeCapacity(cg: *CodeGen, extra: anytype) error{OutOfMemory}!u32 {
|
|||
|
||||
/// For `std.builtin.CallingConvention.auto`.
|
||||
pub fn typeToValtype(ty: Type, zcu: *const Zcu, target: *const std.Target) std.wasm.Valtype {
|
||||
const ip = &zcu.intern_pool;
|
||||
return switch (ty.zigTypeTag(zcu)) {
|
||||
.float => switch (ty.floatBits(target)) {
|
||||
16 => .i32, // stored/loaded as u16
|
||||
|
|
@ -994,25 +993,13 @@ pub fn typeToValtype(ty: Type, zcu: *const Zcu, target: *const std.Target) std.w
|
|||
33...64 => .i64,
|
||||
else => .i32,
|
||||
},
|
||||
.@"struct" => blk: {
|
||||
if (zcu.typeToPackedStruct(ty)) |packed_struct| {
|
||||
const backing_int_ty = Type.fromInterned(packed_struct.backingIntTypeUnordered(ip));
|
||||
break :blk typeToValtype(backing_int_ty, zcu, target);
|
||||
} else {
|
||||
break :blk .i32;
|
||||
}
|
||||
},
|
||||
.vector => switch (CodeGen.determineSimdStoreStrategy(ty, zcu, target)) {
|
||||
.direct => .v128,
|
||||
.unrolled => .i32,
|
||||
},
|
||||
.@"union" => switch (ty.containerLayout(zcu)) {
|
||||
.@"packed" => switch (ty.bitSize(zcu)) {
|
||||
0...32 => .i32,
|
||||
33...64 => .i64,
|
||||
else => .i32,
|
||||
},
|
||||
else => .i32,
|
||||
.@"union", .@"struct" => switch (ty.containerLayout(zcu)) {
|
||||
.@"packed" => typeToValtype(ty.bitpackBackingInt(zcu), zcu, target),
|
||||
.auto, .@"extern" => .i32,
|
||||
},
|
||||
else => .i32, // all represented as reference/immediate
|
||||
};
|
||||
|
|
@ -1185,7 +1172,7 @@ pub fn generate(
|
|||
const fn_ty = zcu.navValue(cg.owner_nav).typeOf(zcu);
|
||||
const fn_info = zcu.typeToFunc(fn_ty).?;
|
||||
const ret_ty: Type = .fromInterned(fn_info.return_type);
|
||||
const any_returns = !firstParamSRet(fn_info.cc, ret_ty, zcu, target) and ret_ty.hasRuntimeBitsIgnoreComptime(zcu);
|
||||
const any_returns = !firstParamSRet(fn_info.cc, ret_ty, zcu, target) and ret_ty.hasRuntimeBits(zcu);
|
||||
|
||||
var cc_result = try resolveCallingConventionValues(zcu, fn_ty, target);
|
||||
defer cc_result.deinit(gpa);
|
||||
|
|
@ -1244,7 +1231,7 @@ fn generateInner(cg: *CodeGen, any_returns: bool) InnerError!Mir {
|
|||
if (any_returns and cg.air.instructions.len > 0) {
|
||||
const inst: Air.Inst.Index = @enumFromInt(cg.air.instructions.len - 1);
|
||||
const last_inst_ty = cg.typeOfIndex(inst);
|
||||
if (!last_inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (!last_inst_ty.hasRuntimeBits(zcu)) {
|
||||
try cg.addTag(.@"unreachable");
|
||||
}
|
||||
}
|
||||
|
|
@ -1316,7 +1303,7 @@ fn resolveCallingConventionValues(
|
|||
switch (cc) {
|
||||
.auto => {
|
||||
for (fn_info.param_types.get(ip)) |ty| {
|
||||
if (!Type.fromInterned(ty).hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (!Type.fromInterned(ty).hasRuntimeBits(zcu)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -1326,7 +1313,7 @@ fn resolveCallingConventionValues(
|
|||
},
|
||||
.wasm_mvp => {
|
||||
for (fn_info.param_types.get(ip)) |ty| {
|
||||
if (!Type.fromInterned(ty).hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (!Type.fromInterned(ty).hasRuntimeBits(zcu)) {
|
||||
continue;
|
||||
}
|
||||
switch (abi.classifyType(.fromInterned(ty), zcu)) {
|
||||
|
|
@ -1357,7 +1344,7 @@ pub fn firstParamSRet(
|
|||
zcu: *const Zcu,
|
||||
target: *const std.Target,
|
||||
) bool {
|
||||
if (!return_type.hasRuntimeBitsIgnoreComptime(zcu)) return false;
|
||||
if (!return_type.hasRuntimeBits(zcu)) return false;
|
||||
switch (cc) {
|
||||
.@"inline" => unreachable,
|
||||
.auto => return isByRef(return_type, zcu, target),
|
||||
|
|
@ -1457,7 +1444,7 @@ fn restoreStackPointer(cg: *CodeGen) !void {
|
|||
fn allocStack(cg: *CodeGen, ty: Type) !WValue {
|
||||
const pt = cg.pt;
|
||||
const zcu = pt.zcu;
|
||||
assert(ty.hasRuntimeBitsIgnoreComptime(zcu));
|
||||
assert(ty.hasRuntimeBits(zcu));
|
||||
if (cg.initial_stack_value == .none) {
|
||||
try cg.initializeStack();
|
||||
}
|
||||
|
|
@ -1491,7 +1478,7 @@ fn allocStackPtr(cg: *CodeGen, inst: Air.Inst.Index) !WValue {
|
|||
try cg.initializeStack();
|
||||
}
|
||||
|
||||
if (!pointee_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (!pointee_ty.hasRuntimeBits(zcu)) {
|
||||
return cg.allocStack(Type.usize); // create a value containing just the stack pointer.
|
||||
}
|
||||
|
||||
|
|
@ -1676,7 +1663,6 @@ fn ptrSize(cg: *const CodeGen) u16 {
|
|||
/// For a given `Type`, will return true when the type will be passed
|
||||
/// by reference, rather than by value
|
||||
fn isByRef(ty: Type, zcu: *const Zcu, target: *const std.Target) bool {
|
||||
const ip = &zcu.intern_pool;
|
||||
switch (ty.zigTypeTag(zcu)) {
|
||||
.type,
|
||||
.comptime_int,
|
||||
|
|
@ -1697,20 +1683,10 @@ fn isByRef(ty: Type, zcu: *const Zcu, target: *const std.Target) bool {
|
|||
|
||||
.array,
|
||||
.frame,
|
||||
=> return ty.hasRuntimeBitsIgnoreComptime(zcu),
|
||||
.@"union" => {
|
||||
if (zcu.typeToUnion(ty)) |union_obj| {
|
||||
if (union_obj.flagsUnordered(ip).layout == .@"packed") {
|
||||
return ty.abiSize(zcu) > 8;
|
||||
}
|
||||
}
|
||||
return ty.hasRuntimeBitsIgnoreComptime(zcu);
|
||||
},
|
||||
.@"struct" => {
|
||||
if (zcu.typeToPackedStruct(ty)) |packed_struct| {
|
||||
return isByRef(Type.fromInterned(packed_struct.backingIntTypeUnordered(ip)), zcu, target);
|
||||
}
|
||||
return ty.hasRuntimeBitsIgnoreComptime(zcu);
|
||||
=> return ty.hasRuntimeBits(zcu),
|
||||
.@"struct", .@"union" => switch (ty.containerLayout(zcu)) {
|
||||
.@"packed" => return isByRef(ty.bitpackBackingInt(zcu), zcu, target),
|
||||
.@"extern", .auto => return ty.hasRuntimeBits(zcu),
|
||||
},
|
||||
.vector => return determineSimdStoreStrategy(ty, zcu, target) == .unrolled,
|
||||
.int => return ty.intInfo(zcu).bits > 64,
|
||||
|
|
@ -1718,7 +1694,7 @@ fn isByRef(ty: Type, zcu: *const Zcu, target: *const std.Target) bool {
|
|||
.float => return ty.floatBits(target) > 64,
|
||||
.error_union => {
|
||||
const pl_ty = ty.errorUnionPayload(zcu);
|
||||
if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (!pl_ty.hasRuntimeBits(zcu)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -1727,7 +1703,7 @@ fn isByRef(ty: Type, zcu: *const Zcu, target: *const std.Target) bool {
|
|||
if (ty.isPtrLikeOptional(zcu)) return false;
|
||||
const pl_type = ty.optionalChild(zcu);
|
||||
if (pl_type.zigTypeTag(zcu) == .error_set) return false;
|
||||
return pl_type.hasRuntimeBitsIgnoreComptime(zcu);
|
||||
return pl_type.hasRuntimeBits(zcu);
|
||||
},
|
||||
.pointer => {
|
||||
// Slices act like struct and will be passed by reference
|
||||
|
|
@ -2069,7 +2045,7 @@ fn airRet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
|||
// to the stack instead
|
||||
if (cg.return_value != .none) {
|
||||
try cg.store(cg.return_value, operand, ret_ty, 0);
|
||||
} else if (fn_info.cc == .wasm_mvp and ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
} else if (fn_info.cc == .wasm_mvp and ret_ty.hasRuntimeBits(zcu)) {
|
||||
switch (abi.classifyType(ret_ty, zcu)) {
|
||||
.direct => |scalar_type| {
|
||||
assert(!abi.lowerAsDoubleI64(scalar_type, zcu));
|
||||
|
|
@ -2082,7 +2058,7 @@ fn airRet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
|||
.indirect => unreachable,
|
||||
}
|
||||
} else {
|
||||
if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu) and ret_ty.isError(zcu)) {
|
||||
if (!ret_ty.hasRuntimeBits(zcu) and ret_ty.isError(zcu)) {
|
||||
try cg.addImm32(0);
|
||||
} else {
|
||||
try cg.emitWValue(operand);
|
||||
|
|
@ -2121,7 +2097,7 @@ fn airRetLoad(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
|||
const ret_ty = cg.typeOf(un_op).childType(zcu);
|
||||
|
||||
const fn_info = zcu.typeToFunc(zcu.navValue(cg.owner_nav).typeOf(zcu)).?;
|
||||
if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (!ret_ty.hasRuntimeBits(zcu)) {
|
||||
if (ret_ty.isError(zcu)) {
|
||||
try cg.addImm32(0);
|
||||
}
|
||||
|
|
@ -2177,7 +2153,7 @@ fn airCall(cg: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifie
|
|||
const arg_val = try cg.resolveInst(arg);
|
||||
|
||||
const arg_ty = cg.typeOf(arg);
|
||||
if (!arg_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
|
||||
if (!arg_ty.hasRuntimeBits(zcu)) continue;
|
||||
|
||||
try cg.lowerArg(zcu.typeToFunc(fn_ty).?.cc, arg_ty, arg_val);
|
||||
}
|
||||
|
|
@ -2199,7 +2175,7 @@ fn airCall(cg: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifie
|
|||
}
|
||||
|
||||
const result_value = result_value: {
|
||||
if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu) and !ret_ty.isError(zcu)) {
|
||||
if (!ret_ty.hasRuntimeBits(zcu) and !ret_ty.isError(zcu)) {
|
||||
break :result_value .none;
|
||||
} else if (first_param_sret) {
|
||||
break :result_value sret;
|
||||
|
|
@ -2320,12 +2296,12 @@ fn store(cg: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErr
|
|||
const zcu = pt.zcu;
|
||||
const abi_size = ty.abiSize(zcu);
|
||||
|
||||
if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) return;
|
||||
if (!ty.hasRuntimeBits(zcu)) return;
|
||||
|
||||
switch (ty.zigTypeTag(zcu)) {
|
||||
.error_union => {
|
||||
const pl_ty = ty.errorUnionPayload(zcu);
|
||||
if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (!pl_ty.hasRuntimeBits(zcu)) {
|
||||
return cg.store(lhs, rhs, Type.anyerror, offset);
|
||||
}
|
||||
|
||||
|
|
@ -2338,7 +2314,7 @@ fn store(cg: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErr
|
|||
return cg.store(lhs, rhs, Type.usize, offset);
|
||||
}
|
||||
const pl_ty = ty.optionalChild(zcu);
|
||||
if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (!pl_ty.hasRuntimeBits(zcu)) {
|
||||
return cg.store(lhs, rhs, Type.u8, offset);
|
||||
}
|
||||
if (pl_ty.zigTypeTag(zcu) == .error_set) {
|
||||
|
|
@ -2438,7 +2414,7 @@ fn airLoad(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
|||
const ptr_ty = cg.typeOf(ty_op.operand);
|
||||
const ptr_info = ptr_ty.ptrInfo(zcu);
|
||||
|
||||
if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) return cg.finishAir(inst, .none, &.{ty_op.operand});
|
||||
if (!ty.hasRuntimeBits(zcu)) return cg.finishAir(inst, .none, &.{ty_op.operand});
|
||||
|
||||
const result = result: {
|
||||
if (isByRef(ty, zcu, cg.target)) {
|
||||
|
|
@ -3089,7 +3065,7 @@ fn lowerPtr(cg: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerErro
|
|||
return switch (ptr.base_addr) {
|
||||
.nav => |nav| return .{ .nav_ref = .{ .nav_index = nav, .offset = @intCast(offset) } },
|
||||
.uav => |uav| return .{ .uav_ref = .{ .ip_index = uav.val, .offset = @intCast(offset), .orig_ptr_ty = uav.orig_ty } },
|
||||
.int => return cg.lowerConstant(try pt.intValue(Type.usize, offset), Type.usize),
|
||||
.int => return cg.lowerConstant(try pt.intValue(.usize, offset)),
|
||||
.eu_payload => |eu_ptr| try cg.lowerPtr(
|
||||
eu_ptr,
|
||||
offset + codegen.errUnionPayloadOffset(
|
||||
|
|
@ -3126,10 +3102,11 @@ fn lowerPtr(cg: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerErro
|
|||
};
|
||||
}
|
||||
|
||||
/// Asserts that `isByRef` returns `false` for `ty`.
|
||||
fn lowerConstant(cg: *CodeGen, val: Value, ty: Type) InnerError!WValue {
|
||||
/// Asserts that `isByRef` returns `false` for `val.typeOf(zcu)`.
|
||||
fn lowerConstant(cg: *CodeGen, val: Value) InnerError!WValue {
|
||||
const pt = cg.pt;
|
||||
const zcu = pt.zcu;
|
||||
const ty = val.typeOf(zcu);
|
||||
assert(!isByRef(ty, zcu, cg.target));
|
||||
const ip = &zcu.intern_pool;
|
||||
if (val.isUndef(zcu)) return cg.emitUndefined(ty);
|
||||
|
|
@ -3191,31 +3168,22 @@ fn lowerConstant(cg: *CodeGen, val: Value, ty: Type) InnerError!WValue {
|
|||
},
|
||||
.error_union => |error_union| {
|
||||
const err_int_ty = try pt.errorIntType();
|
||||
const err_ty, const err_val = switch (error_union.val) {
|
||||
.err_name => |err_name| .{
|
||||
ty.errorUnionSet(zcu),
|
||||
Value.fromInterned(try pt.intern(.{ .err = .{
|
||||
.ty = ty.errorUnionSet(zcu).toIntern(),
|
||||
.name = err_name,
|
||||
} })),
|
||||
},
|
||||
.payload => .{
|
||||
err_int_ty,
|
||||
try pt.intValue(err_int_ty, 0),
|
||||
},
|
||||
const err_val: Value = switch (error_union.val) {
|
||||
.err_name => |err_name| .fromInterned(try pt.intern(.{ .err = .{
|
||||
.ty = ty.errorUnionSet(zcu).toIntern(),
|
||||
.name = err_name,
|
||||
} })),
|
||||
.payload => try pt.intValue(err_int_ty, 0),
|
||||
};
|
||||
const payload_type = ty.errorUnionPayload(zcu);
|
||||
if (!payload_type.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (!payload_type.hasRuntimeBits(zcu)) {
|
||||
// We use the error type directly as the type.
|
||||
return cg.lowerConstant(err_val, err_ty);
|
||||
return cg.lowerConstant(err_val);
|
||||
}
|
||||
|
||||
return cg.fail("Wasm TODO: lowerConstant error union with non-zero-bit payload type", .{});
|
||||
},
|
||||
.enum_tag => |enum_tag| {
|
||||
const int_tag_ty = ip.typeOf(enum_tag.int);
|
||||
return cg.lowerConstant(Value.fromInterned(enum_tag.int), Type.fromInterned(int_tag_ty));
|
||||
},
|
||||
.enum_tag => |enum_tag| return cg.lowerConstant(.fromInterned(enum_tag.int)),
|
||||
.float => |float| switch (float.storage) {
|
||||
.f16 => |f16_val| return .{ .imm32 = @as(u16, @bitCast(f16_val)) },
|
||||
.f32 => |f32_val| return .{ .float32 = f32_val },
|
||||
|
|
@ -3225,9 +3193,8 @@ fn lowerConstant(cg: *CodeGen, val: Value, ty: Type) InnerError!WValue {
|
|||
.slice => unreachable, // isByRef == true
|
||||
.ptr => return cg.lowerPtr(val.toIntern(), 0),
|
||||
.opt => if (ty.optionalReprIsPayload(zcu)) {
|
||||
const pl_ty = ty.optionalChild(zcu);
|
||||
if (val.optionalValue(zcu)) |payload| {
|
||||
return cg.lowerConstant(payload, pl_ty);
|
||||
return cg.lowerConstant(payload);
|
||||
} else {
|
||||
return .{ .imm32 = 0 };
|
||||
}
|
||||
|
|
@ -3242,33 +3209,11 @@ fn lowerConstant(cg: *CodeGen, val: Value, ty: Type) InnerError!WValue {
|
|||
val.writeToMemory(pt, &buf) catch unreachable;
|
||||
return cg.storeSimdImmd(buf);
|
||||
},
|
||||
.struct_type => {
|
||||
const struct_type = ip.loadStructType(ty.toIntern());
|
||||
// non-packed structs are not handled in this function because they
|
||||
// are by-ref types.
|
||||
assert(struct_type.layout == .@"packed");
|
||||
var buf: [8]u8 = .{0} ** 8; // zero the buffer so we do not read 0xaa as integer
|
||||
val.writeToPackedMemory(pt, &buf, 0) catch unreachable;
|
||||
const backing_int_ty = Type.fromInterned(struct_type.backingIntTypeUnordered(ip));
|
||||
const int_val = try pt.intValue(
|
||||
backing_int_ty,
|
||||
mem.readInt(u64, &buf, .little),
|
||||
);
|
||||
return cg.lowerConstant(int_val, backing_int_ty);
|
||||
},
|
||||
.struct_type => unreachable, // packed structs use `bitpack`
|
||||
else => unreachable,
|
||||
},
|
||||
.un => {
|
||||
const int_type = try pt.intType(.unsigned, @intCast(ty.bitSize(zcu)));
|
||||
|
||||
var buf: [8]u8 = .{0} ** 8; // zero the buffer so we do not read 0xaa as integer
|
||||
val.writeToPackedMemory(pt, &buf, 0) catch unreachable;
|
||||
const int_val = try pt.intValue(
|
||||
int_type,
|
||||
mem.readInt(u64, &buf, .little),
|
||||
);
|
||||
return cg.lowerConstant(int_val, int_type);
|
||||
},
|
||||
.un => unreachable, // packed unions use `bitpack`
|
||||
.bitpack => |bitpack| return cg.lowerConstant(.fromInterned(bitpack.backing_int_val)),
|
||||
.memoized_call => unreachable,
|
||||
}
|
||||
}
|
||||
|
|
@ -3283,7 +3228,6 @@ fn storeSimdImmd(cg: *CodeGen, value: [16]u8) !WValue {
|
|||
|
||||
fn emitUndefined(cg: *CodeGen, ty: Type) InnerError!WValue {
|
||||
const zcu = cg.pt.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
switch (ty.zigTypeTag(zcu)) {
|
||||
.bool, .error_set => return .{ .imm32 = 0xaaaaaaaa },
|
||||
.int, .@"enum" => switch (ty.intInfo(zcu).bits) {
|
||||
|
|
@ -3311,17 +3255,9 @@ fn emitUndefined(cg: *CodeGen, ty: Type) InnerError!WValue {
|
|||
.error_union => {
|
||||
return .{ .imm32 = 0xaaaaaaaa };
|
||||
},
|
||||
.@"struct" => {
|
||||
const packed_struct = zcu.typeToPackedStruct(ty).?;
|
||||
return cg.emitUndefined(Type.fromInterned(packed_struct.backingIntTypeUnordered(ip)));
|
||||
},
|
||||
.@"union" => switch (ty.containerLayout(zcu)) {
|
||||
.@"packed" => switch (ty.bitSize(zcu)) {
|
||||
0...32 => return .{ .imm32 = 0xaaaaaaaa },
|
||||
33...64 => return .{ .imm64 = 0xaaaaaaaaaaaaaaaa },
|
||||
else => unreachable,
|
||||
},
|
||||
else => unreachable,
|
||||
.@"struct", .@"union" => {
|
||||
const backing_int_ty = ty.bitpackBackingInt(zcu);
|
||||
return cg.emitUndefined(backing_int_ty);
|
||||
},
|
||||
else => return cg.fail("Wasm TODO: emitUndefined for type: {t}\n", .{ty.zigTypeTag(zcu)}),
|
||||
}
|
||||
|
|
@ -3335,7 +3271,7 @@ fn airBlock(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
|||
fn lowerBlock(cg: *CodeGen, inst: Air.Inst.Index, block_ty: Type, body: []const Air.Inst.Index) InnerError!void {
|
||||
const zcu = cg.pt.zcu;
|
||||
// if wasm_block_ty is non-empty, we create a register to store the temporary value
|
||||
const block_result: WValue = if (block_ty.hasRuntimeBitsIgnoreComptime(zcu))
|
||||
const block_result: WValue = if (block_ty.hasRuntimeBits(zcu))
|
||||
try cg.allocLocal(block_ty)
|
||||
else
|
||||
.none;
|
||||
|
|
@ -3449,7 +3385,7 @@ fn cmp(cg: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareOpe
|
|||
const zcu = cg.pt.zcu;
|
||||
if (ty.zigTypeTag(zcu) == .optional and !ty.optionalReprIsPayload(zcu)) {
|
||||
const payload_ty = ty.optionalChild(zcu);
|
||||
if (payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (payload_ty.hasRuntimeBits(zcu)) {
|
||||
// When we hit this case, we must check the value of optionals
|
||||
// that are not pointers. This means first checking against non-null for
|
||||
// both lhs and rhs, as well as checking the payload are matching of lhs and rhs
|
||||
|
|
@ -3792,7 +3728,6 @@ fn structFieldPtr(
|
|||
fn airStructFieldVal(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
||||
const pt = cg.pt;
|
||||
const zcu = pt.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
const ty_pl = cg.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
|
||||
const struct_field = cg.air.extraData(Air.StructField, ty_pl.payload).data;
|
||||
|
||||
|
|
@ -3800,14 +3735,14 @@ fn airStructFieldVal(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
|||
const operand = try cg.resolveInst(struct_field.struct_operand);
|
||||
const field_index = struct_field.field_index;
|
||||
const field_ty = struct_ty.fieldType(field_index, zcu);
|
||||
if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) return cg.finishAir(inst, .none, &.{struct_field.struct_operand});
|
||||
if (!field_ty.hasRuntimeBits(zcu)) return cg.finishAir(inst, .none, &.{struct_field.struct_operand});
|
||||
|
||||
const result: WValue = switch (struct_ty.containerLayout(zcu)) {
|
||||
.@"packed" => switch (struct_ty.zigTypeTag(zcu)) {
|
||||
.@"struct" => result: {
|
||||
const packed_struct = zcu.typeToPackedStruct(struct_ty).?;
|
||||
const offset = zcu.structPackedFieldBitOffset(packed_struct, field_index);
|
||||
const backing_ty = Type.fromInterned(packed_struct.backingIntTypeUnordered(ip));
|
||||
const backing_ty = Type.fromInterned(packed_struct.packed_backing_int_type);
|
||||
const host_bits = backing_ty.intInfo(zcu).bits;
|
||||
|
||||
const const_wvalue: WValue = if (33 <= host_bits and host_bits <= 64)
|
||||
|
|
@ -3885,7 +3820,7 @@ fn airSwitchBr(cg: *CodeGen, inst: Air.Inst.Index, is_dispatch_loop: bool) Inner
|
|||
const switch_br = cg.air.unwrapSwitch(inst);
|
||||
const target_ty = cg.typeOf(switch_br.operand);
|
||||
|
||||
assert(target_ty.hasRuntimeBitsIgnoreComptime(zcu));
|
||||
assert(target_ty.hasRuntimeBits(zcu));
|
||||
|
||||
// swap target value with placeholder local, for dispatching
|
||||
const target = if (is_dispatch_loop) target: {
|
||||
|
|
@ -4119,7 +4054,7 @@ fn airIsErr(cg: *CodeGen, inst: Air.Inst.Index, opcode: std.wasm.Opcode, op_kind
|
|||
}
|
||||
|
||||
try cg.emitWValue(operand);
|
||||
if (op_kind == .ptr or pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (op_kind == .ptr or pl_ty.hasRuntimeBits(zcu)) {
|
||||
try cg.addMemArg(.i32_load16_u, .{
|
||||
.offset = operand.offset() + @as(u32, @intCast(errUnionErrorOffset(pl_ty, zcu))),
|
||||
.alignment = @intCast(Type.anyerror.abiAlignment(zcu).toByteUnits().?),
|
||||
|
|
@ -4146,7 +4081,7 @@ fn airUnwrapErrUnionPayload(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool)
|
|||
const payload_ty = eu_ty.errorUnionPayload(zcu);
|
||||
|
||||
const result: WValue = result: {
|
||||
if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (!payload_ty.hasRuntimeBits(zcu)) {
|
||||
if (op_is_ptr) {
|
||||
break :result cg.reuseOperand(ty_op.operand, operand);
|
||||
} else {
|
||||
|
|
@ -4166,7 +4101,7 @@ fn airUnwrapErrUnionPayload(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool)
|
|||
}
|
||||
|
||||
/// E!T -> E op_is_ptr == false
|
||||
/// *(E!T) -> E op_is_prt == true
|
||||
/// *(E!T) -> E op_is_ptr == true
|
||||
/// NOTE: op_is_ptr will not change return type
|
||||
fn airUnwrapErrUnionError(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void {
|
||||
const zcu = cg.pt.zcu;
|
||||
|
|
@ -4186,7 +4121,7 @@ fn airUnwrapErrUnionError(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) I
|
|||
if (op_is_ptr or isByRef(eu_ty, zcu, cg.target)) {
|
||||
break :result try cg.load(operand, Type.anyerror, err_offset);
|
||||
} else {
|
||||
assert(!payload_ty.hasRuntimeBitsIgnoreComptime(zcu));
|
||||
assert(!payload_ty.hasRuntimeBits(zcu));
|
||||
break :result cg.reuseOperand(ty_op.operand, operand);
|
||||
}
|
||||
};
|
||||
|
|
@ -4202,7 +4137,7 @@ fn airWrapErrUnionPayload(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
|||
|
||||
const pl_ty = cg.typeOf(ty_op.operand);
|
||||
const result = result: {
|
||||
if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (!pl_ty.hasRuntimeBits(zcu)) {
|
||||
break :result cg.reuseOperand(ty_op.operand, operand);
|
||||
}
|
||||
|
||||
|
|
@ -4232,7 +4167,7 @@ fn airWrapErrUnionErr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
|||
const pl_ty = err_ty.errorUnionPayload(zcu);
|
||||
|
||||
const result = result: {
|
||||
if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (!pl_ty.hasRuntimeBits(zcu)) {
|
||||
break :result cg.reuseOperand(ty_op.operand, operand);
|
||||
}
|
||||
|
||||
|
|
@ -4348,7 +4283,7 @@ fn isNull(cg: *CodeGen, operand: WValue, optional_ty: Type, opcode: std.wasm.Opc
|
|||
if (!optional_ty.optionalReprIsPayload(zcu)) {
|
||||
// When payload is zero-bits, we can treat operand as a value, rather than
|
||||
// a pointer to the stack value
|
||||
if (payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (payload_ty.hasRuntimeBits(zcu)) {
|
||||
const offset = std.math.cast(u32, payload_ty.abiSize(zcu)) orelse {
|
||||
return cg.fail("Optional type {f} too big to fit into stack frame", .{optional_ty.fmt(pt)});
|
||||
};
|
||||
|
|
@ -4373,7 +4308,7 @@ fn airOptionalPayload(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
|||
const ty_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
|
||||
const opt_ty = cg.typeOf(ty_op.operand);
|
||||
const payload_ty = cg.typeOfIndex(inst);
|
||||
if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (!payload_ty.hasRuntimeBits(zcu)) {
|
||||
return cg.finishAir(inst, .none, &.{ty_op.operand});
|
||||
}
|
||||
|
||||
|
|
@ -4398,7 +4333,7 @@ fn airOptionalPayloadPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
|||
|
||||
const result = result: {
|
||||
const payload_ty = opt_ty.optionalChild(zcu);
|
||||
if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu) or opt_ty.optionalReprIsPayload(zcu)) {
|
||||
if (!payload_ty.hasRuntimeBits(zcu) or opt_ty.optionalReprIsPayload(zcu)) {
|
||||
break :result cg.reuseOperand(ty_op.operand, operand);
|
||||
}
|
||||
|
||||
|
|
@ -4438,7 +4373,7 @@ fn airWrapOptional(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
|||
const zcu = pt.zcu;
|
||||
|
||||
const result = result: {
|
||||
if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (!payload_ty.hasRuntimeBits(zcu)) {
|
||||
const non_null_bit = try cg.allocStack(Type.u1);
|
||||
try cg.emitWValue(non_null_bit);
|
||||
try cg.addImm32(1);
|
||||
|
|
@ -4606,7 +4541,7 @@ fn airArrayToSlice(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
|||
const slice_local = try cg.allocStack(slice_ty);
|
||||
|
||||
// store the array ptr in the slice
|
||||
if (array_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (array_ty.hasRuntimeBits(zcu)) {
|
||||
try cg.store(slice_local, operand, Type.usize, 0);
|
||||
}
|
||||
|
||||
|
|
@ -5105,7 +5040,7 @@ fn airShuffleOne(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
|||
try cg.emitWValue(dest_alloc);
|
||||
const elem_val = switch (mask_elem.unwrap()) {
|
||||
.elem => |idx| try cg.load(operand, elem_ty, @intCast(elem_size * idx)),
|
||||
.value => |val| try cg.lowerConstant(.fromInterned(val), elem_ty),
|
||||
.value => |val| try cg.lowerConstant(.fromInterned(val)),
|
||||
};
|
||||
try cg.store(.stack, elem_val, elem_ty, @intCast(dest_alloc.offset() + elem_size * out_idx));
|
||||
}
|
||||
|
|
@ -5246,7 +5181,7 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
|||
}
|
||||
const packed_struct = zcu.typeToPackedStruct(result_ty).?;
|
||||
const field_types = packed_struct.field_types;
|
||||
const backing_type = Type.fromInterned(packed_struct.backingIntTypeUnordered(ip));
|
||||
const backing_type = Type.fromInterned(packed_struct.packed_backing_int_type);
|
||||
|
||||
// ensure the result is zero'd
|
||||
const result = try cg.allocLocal(backing_type);
|
||||
|
|
@ -5259,7 +5194,7 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
|||
var current_bit: u16 = 0;
|
||||
for (elements, 0..) |elem, elem_index| {
|
||||
const field_ty = Type.fromInterned(field_types.get(ip)[elem_index]);
|
||||
if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
|
||||
if (!field_ty.hasRuntimeBits(zcu)) continue;
|
||||
|
||||
const shift_val: WValue = if (backing_type.bitSize(zcu) <= 32)
|
||||
.{ .imm32 = current_bit }
|
||||
|
|
@ -5332,13 +5267,13 @@ fn airUnionInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
|||
const layout = union_ty.unionGetLayout(zcu);
|
||||
const union_obj = zcu.typeToUnion(union_ty).?;
|
||||
const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]);
|
||||
const field_name = union_obj.loadTagType(ip).names.get(ip)[extra.field_index];
|
||||
const field_name = ip.loadEnumType(union_obj.enum_tag_type).field_names.get(ip)[extra.field_index];
|
||||
|
||||
const tag_int = blk: {
|
||||
const tag_ty = union_ty.unionTagTypeRuntime(zcu).?;
|
||||
const tag_ty = union_ty.unionTagTypeHypothetical(zcu);
|
||||
const enum_field_index = tag_ty.enumFieldIndex(field_name, zcu).?;
|
||||
const tag_val = try pt.enumValueFieldIndex(tag_ty, enum_field_index);
|
||||
break :blk try cg.lowerConstant(tag_val, tag_ty);
|
||||
break :blk try cg.lowerConstant(tag_val);
|
||||
};
|
||||
if (layout.payload_size == 0) {
|
||||
if (layout.tag_size == 0) {
|
||||
|
|
@ -5360,7 +5295,7 @@ fn airUnionInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
|||
}
|
||||
|
||||
if (layout.tag_size > 0) {
|
||||
try cg.store(result_ptr, tag_int, Type.fromInterned(union_obj.enum_tag_ty), 0);
|
||||
try cg.store(result_ptr, tag_int, .fromInterned(union_obj.enum_tag_type), 0);
|
||||
}
|
||||
} else {
|
||||
try cg.store(result_ptr, payload, field_ty, 0);
|
||||
|
|
@ -5368,7 +5303,7 @@ fn airUnionInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
|||
try cg.store(
|
||||
result_ptr,
|
||||
tag_int,
|
||||
Type.fromInterned(union_obj.enum_tag_ty),
|
||||
.fromInterned(union_obj.enum_tag_type),
|
||||
@intCast(layout.payload_size),
|
||||
);
|
||||
}
|
||||
|
|
@ -5415,7 +5350,7 @@ fn airWasmMemoryGrow(cg: *CodeGen, inst: Air.Inst.Index) !void {
|
|||
|
||||
fn cmpOptionals(cg: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std.math.CompareOperator) InnerError!WValue {
|
||||
const zcu = cg.pt.zcu;
|
||||
assert(operand_ty.hasRuntimeBitsIgnoreComptime(zcu));
|
||||
assert(operand_ty.hasRuntimeBits(zcu));
|
||||
assert(op == .eq or op == .neq);
|
||||
const payload_ty = operand_ty.optionalChild(zcu);
|
||||
assert(!isByRef(payload_ty, zcu, cg.target));
|
||||
|
|
@ -5669,7 +5604,7 @@ fn airErrUnionPayloadPtrSet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void
|
|||
);
|
||||
|
||||
const result = result: {
|
||||
if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (!payload_ty.hasRuntimeBits(zcu)) {
|
||||
break :result cg.reuseOperand(ty_op.operand, operand);
|
||||
}
|
||||
|
||||
|
|
@ -6458,7 +6393,7 @@ fn lowerTry(
|
|||
const zcu = cg.pt.zcu;
|
||||
|
||||
const pl_ty = err_union_ty.errorUnionPayload(zcu);
|
||||
const pl_has_bits = pl_ty.hasRuntimeBitsIgnoreComptime(zcu);
|
||||
const pl_has_bits = pl_ty.hasRuntimeBits(zcu);
|
||||
|
||||
if (!err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) {
|
||||
// Block we can jump out of when error is not set
|
||||
|
|
@ -7096,13 +7031,13 @@ fn callIntrinsic(
|
|||
// Lower all arguments to the stack before we call our function
|
||||
for (args, 0..) |arg, arg_i| {
|
||||
assert(!(want_sret_param and arg == .stack));
|
||||
assert(Type.fromInterned(param_types[arg_i]).hasRuntimeBitsIgnoreComptime(zcu));
|
||||
assert(Type.fromInterned(param_types[arg_i]).hasRuntimeBits(zcu));
|
||||
try cg.lowerArg(.{ .wasm_mvp = .{} }, Type.fromInterned(param_types[arg_i]), arg);
|
||||
}
|
||||
|
||||
try cg.addInst(.{ .tag = .call_intrinsic, .data = .{ .intrinsic = intrinsic } });
|
||||
|
||||
if (!return_type.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
if (!return_type.hasRuntimeBits(zcu)) {
|
||||
return .none;
|
||||
} else if (want_sret_param) {
|
||||
return sret;
|
||||
|
|
|
|||
|
|
@ -561,7 +561,7 @@ fn reportUndefSymbol(self: Atom, rel: Relocation, macho_file: *MachO) !bool {
|
|||
defer macho_file.undefs_mutex.unlock(io);
|
||||
const gop = try macho_file.undefs.getOrPut(gpa, file.getGlobals()[rel.target]);
|
||||
if (!gop.found_existing) {
|
||||
gop.value_ptr.* = .{ .refs = .{} };
|
||||
gop.value_ptr.* = .{ .refs = .empty };
|
||||
}
|
||||
try gop.value_ptr.refs.append(gpa, .{ .index = self.atom_index, .file = self.file });
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ fn newAtom(self: *ZigObject, allocator: Allocator, name: MachO.String, macho_fil
|
|||
atom.name = name;
|
||||
|
||||
const relocs_index = @as(u32, @intCast(self.relocs.items.len));
|
||||
self.relocs.addOneAssumeCapacity().* = .{};
|
||||
self.relocs.addOneAssumeCapacity().* = .empty;
|
||||
atom.addExtra(.{ .rel_index = relocs_index, .rel_count = 0 }, macho_file);
|
||||
|
||||
return index;
|
||||
|
|
|
|||
|
|
@ -258,7 +258,7 @@ pub const File = union(enum) {
|
|||
|
||||
const gop = try macho_file.dupes.getOrPut(gpa, file.getGlobals()[i]);
|
||||
if (!gop.found_existing) {
|
||||
gop.value_ptr.* = .{};
|
||||
gop.value_ptr.* = .empty;
|
||||
}
|
||||
try gop.value_ptr.append(gpa, file.getIndex());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4226,7 +4226,7 @@ fn convertZcuFnType(
|
|||
|
||||
if (CodeGen.firstParamSRet(cc, return_type, zcu, target)) {
|
||||
try params_buffer.append(gpa, .i32); // memory address is always a 32-bit handle
|
||||
} else if (return_type.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
} else if (return_type.hasRuntimeBits(zcu)) {
|
||||
if (cc == .wasm_mvp) {
|
||||
switch (abi.classifyType(return_type, zcu)) {
|
||||
.direct => |scalar_ty| {
|
||||
|
|
@ -4245,7 +4245,7 @@ fn convertZcuFnType(
|
|||
// param types
|
||||
for (params) |param_type_ip| {
|
||||
const param_type = Zcu.Type.fromInterned(param_type_ip);
|
||||
if (!param_type.hasRuntimeBitsIgnoreComptime(zcu)) continue;
|
||||
if (!param_type.hasRuntimeBits(zcu)) continue;
|
||||
|
||||
switch (cc) {
|
||||
.wasm_mvp => {
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
|
|||
.type_index = try wasm.internFunctionType(.auto, &.{int_tag_ty.ip_index}, .slice_const_u8_sentinel_0, target),
|
||||
.table_index = @intCast(wasm.tag_name_offs.items.len),
|
||||
} };
|
||||
const tag_names = ip.loadEnumType(data.ip_index).names;
|
||||
const tag_names = ip.loadEnumType(data.ip_index).field_names;
|
||||
for (tag_names.get(ip)) |tag_name| {
|
||||
const slice = tag_name.toSlice(ip);
|
||||
try wasm.tag_name_offs.append(gpa, @intCast(wasm.tag_name_bytes.items.len));
|
||||
|
|
@ -1869,7 +1869,7 @@ fn emitTagNameFunction(
|
|||
const zcu = comp.zcu.?;
|
||||
const ip = &zcu.intern_pool;
|
||||
const enum_type = ip.loadEnumType(enum_type_ip);
|
||||
const tag_values = enum_type.values.get(ip);
|
||||
const tag_values = enum_type.field_values.get(ip);
|
||||
|
||||
const slice_abi_size = 8;
|
||||
const encoded_alignment = @ctz(@as(u32, 4));
|
||||
|
|
@ -1908,7 +1908,7 @@ fn emitTagNameFunction(
|
|||
return;
|
||||
}
|
||||
|
||||
const int_info = Zcu.Type.intInfo(.fromInterned(enum_type.tag_ty), zcu);
|
||||
const int_info = Zcu.Type.intInfo(.fromInterned(enum_type.int_tag_type), zcu);
|
||||
const outer_block_type: std.wasm.BlockType = switch (int_info.bits) {
|
||||
0...32 => .i32,
|
||||
33...64 => .i64,
|
||||
|
|
|
|||
|
|
@ -530,7 +530,7 @@ const Parser = struct {
|
|||
fn leaf_value(self: *Parser) ParseError!*Node {
|
||||
const node = try self.allocator.create(Node.Value);
|
||||
errdefer self.allocator.destroy(node);
|
||||
node.* = .{ .string_value = .{} };
|
||||
node.* = .{ .string_value = .empty };
|
||||
node.base.tree = self.tree;
|
||||
node.base.start = self.token_it.pos;
|
||||
errdefer node.string_value.deinit(self.allocator);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue