mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-07 14:24:43 +00:00
stage2-wasm: pass behavior test, disable one not passing before
This commit is contained in:
parent
337762114f
commit
c1f8fa0043
8 changed files with 215 additions and 48 deletions
|
|
@ -1230,12 +1230,17 @@ pub fn generate(
|
||||||
fn generateInner(cg: *CodeGen, any_returns: bool) InnerError!Mir {
|
fn generateInner(cg: *CodeGen, any_returns: bool) InnerError!Mir {
|
||||||
const zcu = cg.pt.zcu;
|
const zcu = cg.pt.zcu;
|
||||||
try cg.branches.append(cg.gpa, .{});
|
try cg.branches.append(cg.gpa, .{});
|
||||||
// clean up outer branch
|
defer {
|
||||||
|
var const_branch = cg.branches.pop().?;
|
||||||
|
const_branch.deinit(cg.gpa);
|
||||||
|
assert(cg.branches.items.len == 0); // missing branch merge
|
||||||
|
}
|
||||||
|
try cg.branches.append(cg.gpa, .{});
|
||||||
defer {
|
defer {
|
||||||
var outer_branch = cg.branches.pop().?;
|
var outer_branch = cg.branches.pop().?;
|
||||||
outer_branch.deinit(cg.gpa);
|
outer_branch.deinit(cg.gpa);
|
||||||
assert(cg.branches.items.len == 0); // missing branch merge
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate MIR for function body
|
// Generate MIR for function body
|
||||||
try cg.genBody(cg.air.getMainBody());
|
try cg.genBody(cg.air.getMainBody());
|
||||||
|
|
||||||
|
|
@ -1384,7 +1389,7 @@ fn lowerArg(cg: *CodeGen, cc: std.builtin.CallingConvention, ty: Type, value: WV
|
||||||
return cg.lowerToStack(value);
|
return cg.lowerToStack(value);
|
||||||
} else {
|
} else {
|
||||||
switch (value) {
|
switch (value) {
|
||||||
.nav_ref, .stack_offset => _ = try cg.load(value, scalar_type, 0),
|
.nav_ref, .uav_ref, .stack_offset => _ = try cg.load(value, scalar_type, 0),
|
||||||
.dead => unreachable,
|
.dead => unreachable,
|
||||||
else => try cg.emitWValue(value),
|
else => try cg.emitWValue(value),
|
||||||
}
|
}
|
||||||
|
|
@ -2401,6 +2406,7 @@ fn store(cg: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErr
|
||||||
} else if (abi_size > 16) {
|
} else if (abi_size > 16) {
|
||||||
assert(offset == 0);
|
assert(offset == 0);
|
||||||
try cg.memcpy(lhs, rhs, .{ .imm32 = @as(u32, @intCast(ty.abiSize(zcu))) });
|
try cg.memcpy(lhs, rhs, .{ .imm32 = @as(u32, @intCast(ty.abiSize(zcu))) });
|
||||||
|
return;
|
||||||
},
|
},
|
||||||
else => if (abi_size > 8) {
|
else => if (abi_size > 8) {
|
||||||
return cg.fail("TODO: `store` for type `{f}` with abisize `{d}`", .{ ty.fmt(pt), abi_size });
|
return cg.fail("TODO: `store` for type `{f}` with abisize `{d}`", .{ ty.fmt(pt), abi_size });
|
||||||
|
|
@ -2450,7 +2456,8 @@ fn airLoad(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
||||||
const loaded = try cg.load(operand, ty, 0);
|
const loaded = try cg.load(operand, ty, 0);
|
||||||
const ty_size = ty.abiSize(zcu);
|
const ty_size = ty.abiSize(zcu);
|
||||||
if (ty.isAbiInt(zcu) and ty_size * 8 > ty.bitSize(zcu)) {
|
if (ty.isAbiInt(zcu) and ty_size * 8 > ty.bitSize(zcu)) {
|
||||||
const int_elem_ty = try pt.intType(.unsigned, @intCast(ty_size * 8));
|
const int_info = ty.intInfo(zcu);
|
||||||
|
const int_elem_ty = try pt.intType(int_info.signedness, @intCast(ty_size * 8));
|
||||||
break :result try cg.trunc(loaded, ty, int_elem_ty);
|
break :result try cg.trunc(loaded, ty, int_elem_ty);
|
||||||
} else {
|
} else {
|
||||||
break :result loaded;
|
break :result loaded;
|
||||||
|
|
@ -2496,11 +2503,15 @@ fn load(cg: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValue
|
||||||
}
|
}
|
||||||
|
|
||||||
const abi_size: u8 = @intCast(ty.abiSize(zcu));
|
const abi_size: u8 = @intCast(ty.abiSize(zcu));
|
||||||
|
const is_signed = switch (ty.zigTypeTag(zcu)) {
|
||||||
|
.int, .@"struct", .@"enum" => ty.intInfo(zcu).signedness == .signed,
|
||||||
|
else => false,
|
||||||
|
};
|
||||||
const opcode = buildOpcode(.{
|
const opcode = buildOpcode(.{
|
||||||
.valtype1 = typeToValtype(ty, zcu, cg.target),
|
.valtype1 = typeToValtype(ty, zcu, cg.target),
|
||||||
.width = abi_size * 8,
|
.width = abi_size * 8,
|
||||||
.op = .load,
|
.op = .load,
|
||||||
.signedness = if (ty.isSignedInt(zcu)) .signed else .unsigned,
|
.signedness = if (is_signed) .signed else .unsigned,
|
||||||
});
|
});
|
||||||
|
|
||||||
try cg.addMemArg(
|
try cg.addMemArg(
|
||||||
|
|
@ -3026,10 +3037,15 @@ fn wrapOperand(cg: *CodeGen, operand: WValue, ty: Type) InnerError!WValue {
|
||||||
|
|
||||||
if (wasm_bits == int_bits) return operand;
|
if (wasm_bits == int_bits) return operand;
|
||||||
|
|
||||||
|
const is_signed = switch (ty.zigTypeTag(zcu)) {
|
||||||
|
.int, .@"struct", .@"enum" => ty.intInfo(zcu).signedness == .signed,
|
||||||
|
else => false,
|
||||||
|
};
|
||||||
|
|
||||||
switch (wasm_bits) {
|
switch (wasm_bits) {
|
||||||
32 => {
|
32 => {
|
||||||
try cg.emitWValue(operand);
|
try cg.emitWValue(operand);
|
||||||
if (ty.isSignedInt(zcu)) {
|
if (is_signed) {
|
||||||
try cg.addImm32(32 - int_bits);
|
try cg.addImm32(32 - int_bits);
|
||||||
try cg.addTag(.i32_shl);
|
try cg.addTag(.i32_shl);
|
||||||
try cg.addImm32(32 - int_bits);
|
try cg.addImm32(32 - int_bits);
|
||||||
|
|
@ -3042,7 +3058,7 @@ fn wrapOperand(cg: *CodeGen, operand: WValue, ty: Type) InnerError!WValue {
|
||||||
},
|
},
|
||||||
64 => {
|
64 => {
|
||||||
try cg.emitWValue(operand);
|
try cg.emitWValue(operand);
|
||||||
if (ty.isSignedInt(zcu)) {
|
if (is_signed) {
|
||||||
try cg.addImm64(64 - int_bits);
|
try cg.addImm64(64 - int_bits);
|
||||||
try cg.addTag(.i64_shl);
|
try cg.addTag(.i64_shl);
|
||||||
try cg.addImm64(64 - int_bits);
|
try cg.addImm64(64 - int_bits);
|
||||||
|
|
@ -3063,7 +3079,7 @@ fn wrapOperand(cg: *CodeGen, operand: WValue, ty: Type) InnerError!WValue {
|
||||||
|
|
||||||
try cg.emitWValue(result);
|
try cg.emitWValue(result);
|
||||||
_ = try cg.load(operand, Type.u64, 8);
|
_ = try cg.load(operand, Type.u64, 8);
|
||||||
if (ty.isSignedInt(zcu)) {
|
if (is_signed) {
|
||||||
try cg.addImm64(128 - int_bits);
|
try cg.addImm64(128 - int_bits);
|
||||||
try cg.addTag(.i64_shl);
|
try cg.addTag(.i64_shl);
|
||||||
try cg.addImm64(128 - int_bits);
|
try cg.addImm64(128 - int_bits);
|
||||||
|
|
@ -3083,12 +3099,41 @@ fn wrapOperand(cg: *CodeGen, operand: WValue, ty: Type) InnerError!WValue {
|
||||||
fn lowerPtr(cg: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerError!WValue {
|
fn lowerPtr(cg: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerError!WValue {
|
||||||
const pt = cg.pt;
|
const pt = cg.pt;
|
||||||
const zcu = pt.zcu;
|
const zcu = pt.zcu;
|
||||||
const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr;
|
const ip = &zcu.intern_pool;
|
||||||
|
const ptr = ip.indexToKey(ptr_val).ptr;
|
||||||
const offset: u64 = prev_offset + ptr.byte_offset;
|
const offset: u64 = prev_offset + ptr.byte_offset;
|
||||||
return switch (ptr.base_addr) {
|
return switch (ptr.base_addr) {
|
||||||
.nav => |nav| return .{ .nav_ref = .{ .nav_index = nav, .offset = @intCast(offset) } },
|
.nav => |nav| {
|
||||||
.uav => |uav| return .{ .uav_ref = .{ .ip_index = uav.val, .offset = @intCast(offset), .orig_ptr_ty = uav.orig_ty } },
|
const nav_val = ip.getNav(nav);
|
||||||
.int => return cg.lowerConstant(try pt.intValue(Type.usize, offset), Type.usize),
|
const nav_ty = Type.fromInterned(nav_val.typeOf(ip));
|
||||||
|
const is_fn_body = nav_ty.zigTypeTag(zcu) == .@"fn";
|
||||||
|
|
||||||
|
if (!is_fn_body and !nav_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||||
|
return switch (cg.ptr_size) {
|
||||||
|
.wasm32 => .{ .imm32 = 0xaaaaaaaa },
|
||||||
|
.wasm64 => .{ .imm64 = 0xaaaaaaaaaaaaaaaa },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return .{ .nav_ref = .{ .nav_index = nav, .offset = @intCast(offset) } };
|
||||||
|
},
|
||||||
|
.uav => |uav| {
|
||||||
|
const uav_ty = Type.fromInterned(ip.typeOf(uav.val));
|
||||||
|
const is_fn_body = uav_ty.zigTypeTag(zcu) == .@"fn";
|
||||||
|
|
||||||
|
if (!is_fn_body and !uav_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||||
|
return switch (cg.ptr_size) {
|
||||||
|
.wasm32 => .{ .imm32 = 0xaaaaaaaa },
|
||||||
|
.wasm64 => .{ .imm64 = 0xaaaaaaaaaaaaaaaa },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return .{ .uav_ref = .{ .ip_index = uav.val, .offset = @intCast(offset), .orig_ptr_ty = uav.orig_ty } };
|
||||||
|
},
|
||||||
|
.int => return switch (cg.ptr_size) {
|
||||||
|
.wasm32 => .{ .imm32 = @intCast(offset) },
|
||||||
|
.wasm64 => .{ .imm64 = offset },
|
||||||
|
},
|
||||||
.eu_payload => |eu_ptr| try cg.lowerPtr(
|
.eu_payload => |eu_ptr| try cg.lowerPtr(
|
||||||
eu_ptr,
|
eu_ptr,
|
||||||
offset + codegen.errUnionPayloadOffset(
|
offset + codegen.errUnionPayloadOffset(
|
||||||
|
|
@ -7116,7 +7161,7 @@ fn airTagName(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
||||||
|
|
||||||
const result_ptr = try cg.allocStack(cg.typeOfIndex(inst));
|
const result_ptr = try cg.allocStack(cg.typeOfIndex(inst));
|
||||||
try cg.lowerToStack(result_ptr);
|
try cg.lowerToStack(result_ptr);
|
||||||
try cg.emitWValue(operand);
|
try cg.lowerToStack(operand);
|
||||||
try cg.addInst(.{ .tag = .call_tag_name, .data = .{ .ip_index = enum_ty.toIntern() } });
|
try cg.addInst(.{ .tag = .call_tag_name, .data = .{ .ip_index = enum_ty.toIntern() } });
|
||||||
|
|
||||||
return cg.finishAir(inst, result_ptr, &.{un_op});
|
return cg.finishAir(inst, result_ptr, &.{un_op});
|
||||||
|
|
|
||||||
|
|
@ -201,6 +201,7 @@ pub const Env = enum {
|
||||||
.wasm => switch (feature) {
|
.wasm => switch (feature) {
|
||||||
.stdio_listen,
|
.stdio_listen,
|
||||||
.incremental,
|
.incremental,
|
||||||
|
.legalize,
|
||||||
.wasm_backend,
|
.wasm_backend,
|
||||||
.wasm_linker,
|
.wasm_linker,
|
||||||
=> true,
|
=> true,
|
||||||
|
|
|
||||||
|
|
@ -1853,7 +1853,6 @@ fn emitTagNameFunction(
|
||||||
) !void {
|
) !void {
|
||||||
const comp = wasm.base.comp;
|
const comp = wasm.base.comp;
|
||||||
const gpa = comp.gpa;
|
const gpa = comp.gpa;
|
||||||
const diags = &comp.link_diags;
|
|
||||||
const zcu = comp.zcu.?;
|
const zcu = comp.zcu.?;
|
||||||
const ip = &zcu.intern_pool;
|
const ip = &zcu.intern_pool;
|
||||||
const enum_type = ip.loadEnumType(enum_type_ip);
|
const enum_type = ip.loadEnumType(enum_type_ip);
|
||||||
|
|
@ -1884,52 +1883,74 @@ fn emitTagNameFunction(
|
||||||
appendReservedUleb32(code, 0);
|
appendReservedUleb32(code, 0);
|
||||||
} else {
|
} else {
|
||||||
const int_info = Zcu.Type.intInfo(.fromInterned(enum_type.tag_ty), zcu);
|
const int_info = Zcu.Type.intInfo(.fromInterned(enum_type.tag_ty), zcu);
|
||||||
const outer_block_type: std.wasm.BlockType = switch (int_info.bits) {
|
const is_big_int = int_info.bits > 64;
|
||||||
0...32 => .i32,
|
|
||||||
33...64 => .i64,
|
|
||||||
else => return diags.fail("wasm linker does not yet implement @tagName for sparse enums with more than 64 bit integer tag types", .{}),
|
|
||||||
};
|
|
||||||
|
|
||||||
code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.local_get));
|
code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.local_get));
|
||||||
appendReservedUleb32(code, 0);
|
appendReservedUleb32(code, 0);
|
||||||
|
|
||||||
// Outer block that computes table offset.
|
// Outer block that computes table offset.
|
||||||
|
// use i32 block type since we're computing a table offset
|
||||||
code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.block));
|
code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.block));
|
||||||
code.appendAssumeCapacity(@intFromEnum(outer_block_type));
|
code.appendAssumeCapacity(@intFromEnum(std.wasm.BlockType.i32));
|
||||||
|
|
||||||
for (tag_values, 0..) |tag_value, tag_index| {
|
for (tag_values, 0..) |tag_value, tag_index| {
|
||||||
// block for this if case
|
// block for this if case
|
||||||
code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.block));
|
code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.block));
|
||||||
code.appendAssumeCapacity(@intFromEnum(std.wasm.BlockType.empty));
|
code.appendAssumeCapacity(@intFromEnum(std.wasm.BlockType.empty));
|
||||||
|
|
||||||
|
const val: Zcu.Value = .fromInterned(tag_value);
|
||||||
|
if (is_big_int) {
|
||||||
|
var val_space: Zcu.Value.BigIntSpace = undefined;
|
||||||
|
const val_bigint = val.toBigInt(&val_space, zcu);
|
||||||
|
const num_limbs = (int_info.bits + 63) / 64;
|
||||||
|
|
||||||
|
const limbs = try gpa.alloc(u64, num_limbs);
|
||||||
|
defer gpa.free(limbs);
|
||||||
|
val_bigint.writeTwosComplement(@ptrCast(limbs), .little);
|
||||||
|
|
||||||
|
try code.ensureUnusedCapacity(gpa, 7 * 5 + 6 + 1 * 6 + 20 * num_limbs);
|
||||||
|
|
||||||
|
for (0..num_limbs) |limb_index| {
|
||||||
|
// load the limb from memory (local 1 is pointer)
|
||||||
|
code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.local_get));
|
||||||
|
appendReservedUleb32(code, 1);
|
||||||
|
|
||||||
|
code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i64_load));
|
||||||
|
appendReservedUleb32(code, @ctz(@as(u32, 8))); // alignment for i64
|
||||||
|
appendReservedUleb32(code, @intCast(limb_index * 8));
|
||||||
|
|
||||||
|
appendReservedI64Const(code, limbs[limb_index]);
|
||||||
|
code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i64_ne));
|
||||||
|
|
||||||
|
// if not equal, break out of current case block
|
||||||
|
code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.br_if));
|
||||||
|
appendReservedUleb32(code, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
// Tag value whose name should be returned.
|
// Tag value whose name should be returned.
|
||||||
code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.local_get));
|
code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.local_get));
|
||||||
appendReservedUleb32(code, 1);
|
appendReservedUleb32(code, 1);
|
||||||
|
|
||||||
const val: Zcu.Value = .fromInterned(tag_value);
|
if (int_info.bits <= 32) {
|
||||||
switch (outer_block_type) {
|
|
||||||
.i32 => {
|
|
||||||
const x: u32 = switch (int_info.signedness) {
|
const x: u32 = switch (int_info.signedness) {
|
||||||
.signed => @bitCast(@as(i32, @intCast(val.toSignedInt(zcu)))),
|
.signed => @bitCast(@as(i32, @intCast(val.toSignedInt(zcu)))),
|
||||||
.unsigned => @intCast(val.toUnsignedInt(zcu)),
|
.unsigned => @intCast(val.toUnsignedInt(zcu)),
|
||||||
};
|
};
|
||||||
appendReservedI32Const(code, x);
|
appendReservedI32Const(code, x);
|
||||||
code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i32_ne));
|
code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i32_ne));
|
||||||
},
|
} else {
|
||||||
.i64 => {
|
|
||||||
const x: u64 = switch (int_info.signedness) {
|
const x: u64 = switch (int_info.signedness) {
|
||||||
.signed => @bitCast(val.toSignedInt(zcu)),
|
.signed => @bitCast(val.toSignedInt(zcu)),
|
||||||
.unsigned => val.toUnsignedInt(zcu),
|
.unsigned => val.toUnsignedInt(zcu),
|
||||||
};
|
};
|
||||||
appendReservedI64Const(code, x);
|
appendReservedI64Const(code, x);
|
||||||
code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i64_ne));
|
code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i64_ne));
|
||||||
},
|
|
||||||
else => unreachable,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if they're not equal, break out of current branch
|
// if they're not equal, break out of current branch
|
||||||
code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.br_if));
|
code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.br_if));
|
||||||
appendReservedUleb32(code, 0);
|
appendReservedUleb32(code, 0);
|
||||||
|
}
|
||||||
|
|
||||||
// Put the table offset of the result on the stack.
|
// Put the table offset of the result on the stack.
|
||||||
appendReservedI32Const(code, @intCast(tag_index * slice_abi_size));
|
appendReservedI32Const(code, @intCast(tag_index * slice_abi_size));
|
||||||
|
|
@ -1962,7 +1983,7 @@ fn appendReservedI32Const(bytes: *ArrayList(u8), val: u32) void {
|
||||||
bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i32_const));
|
bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i32_const));
|
||||||
var w: std.Io.Writer = .fromArrayList(bytes);
|
var w: std.Io.Writer = .fromArrayList(bytes);
|
||||||
defer bytes.* = w.toArrayList();
|
defer bytes.* = w.toArrayList();
|
||||||
return w.writeSleb128(val) catch |err| switch (err) {
|
return w.writeSleb128(@as(i32, @bitCast(val))) catch |err| switch (err) {
|
||||||
error.WriteFailed => unreachable,
|
error.WriteFailed => unreachable,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -1972,7 +1993,7 @@ fn appendReservedI64Const(bytes: *ArrayList(u8), val: u64) void {
|
||||||
bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i64_const));
|
bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i64_const));
|
||||||
var w: std.Io.Writer = .fromArrayList(bytes);
|
var w: std.Io.Writer = .fromArrayList(bytes);
|
||||||
defer bytes.* = w.toArrayList();
|
defer bytes.* = w.toArrayList();
|
||||||
return w.writeSleb128(val) catch |err| switch (err) {
|
return w.writeSleb128(@as(i64, @bitCast(val))) catch |err| switch (err) {
|
||||||
error.WriteFailed => unreachable,
|
error.WriteFailed => unreachable,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1084,6 +1084,102 @@ test "tag name with large enum values" {
|
||||||
try expect(mem.eql(u8, @tagName(kdf), "argon2id"));
|
try expect(mem.eql(u8, @tagName(kdf), "argon2id"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "@tagName with exotic integer enum types" {
|
||||||
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
|
||||||
|
|
||||||
|
const S = struct {
|
||||||
|
fn testEnumSigned(comptime T: type) !void {
|
||||||
|
{
|
||||||
|
const E1 = enum(T) {
|
||||||
|
a = -125,
|
||||||
|
b = 125,
|
||||||
|
c = std.math.minInt(T),
|
||||||
|
d = std.math.maxInt(T),
|
||||||
|
};
|
||||||
|
|
||||||
|
var e: E1 = .a;
|
||||||
|
try expect(mem.eql(u8, @tagName(e), "a"));
|
||||||
|
e = .b;
|
||||||
|
try expect(mem.eql(u8, @tagName(e), "b"));
|
||||||
|
e = .c;
|
||||||
|
try expect(mem.eql(u8, @tagName(e), "c"));
|
||||||
|
e = .d;
|
||||||
|
try expect(mem.eql(u8, @tagName(e), "d"));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const E2 = enum(T) {
|
||||||
|
a = -125,
|
||||||
|
b = 125,
|
||||||
|
c = std.math.minInt(T),
|
||||||
|
d = std.math.maxInt(T),
|
||||||
|
_,
|
||||||
|
};
|
||||||
|
|
||||||
|
var e: E2 = .a;
|
||||||
|
try expect(mem.eql(u8, @tagName(e), "a"));
|
||||||
|
e = .b;
|
||||||
|
try expect(mem.eql(u8, @tagName(e), "b"));
|
||||||
|
e = .c;
|
||||||
|
try expect(mem.eql(u8, @tagName(e), "c"));
|
||||||
|
e = .d;
|
||||||
|
try expect(mem.eql(u8, @tagName(e), "d"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn testEnumUnsigned(comptime T: type) !void {
|
||||||
|
{
|
||||||
|
const E1 = enum(T) {
|
||||||
|
a = std.math.maxInt(T) - 125,
|
||||||
|
b = 125,
|
||||||
|
c = std.math.minInt(T),
|
||||||
|
d = std.math.maxInt(T),
|
||||||
|
};
|
||||||
|
|
||||||
|
var e: E1 = .a;
|
||||||
|
try expect(mem.eql(u8, @tagName(e), "a"));
|
||||||
|
e = .b;
|
||||||
|
try expect(mem.eql(u8, @tagName(e), "b"));
|
||||||
|
e = .c;
|
||||||
|
try expect(mem.eql(u8, @tagName(e), "c"));
|
||||||
|
e = .d;
|
||||||
|
try expect(mem.eql(u8, @tagName(e), "d"));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const E2 = enum(T) {
|
||||||
|
a = std.math.maxInt(T) - 125,
|
||||||
|
b = 125,
|
||||||
|
c = std.math.minInt(T),
|
||||||
|
d = std.math.maxInt(T),
|
||||||
|
_,
|
||||||
|
};
|
||||||
|
|
||||||
|
var e: E2 = .a;
|
||||||
|
try expect(mem.eql(u8, @tagName(e), "a"));
|
||||||
|
e = .b;
|
||||||
|
try expect(mem.eql(u8, @tagName(e), "b"));
|
||||||
|
e = .c;
|
||||||
|
try expect(mem.eql(u8, @tagName(e), "c"));
|
||||||
|
e = .d;
|
||||||
|
try expect(mem.eql(u8, @tagName(e), "d"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn doTheTest() !void {
|
||||||
|
try testEnumSigned(i33);
|
||||||
|
try testEnumSigned(i95);
|
||||||
|
try testEnumSigned(i127);
|
||||||
|
|
||||||
|
try testEnumUnsigned(u33);
|
||||||
|
try testEnumUnsigned(u95);
|
||||||
|
try testEnumUnsigned(u127);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
try S.doTheTest();
|
||||||
|
try comptime S.doTheTest();
|
||||||
|
}
|
||||||
|
|
||||||
test "@tagName in callconv(.c) function" {
|
test "@tagName in callconv(.c) function" {
|
||||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||||
|
|
|
||||||
|
|
@ -1033,6 +1033,7 @@ test "@fieldParentPtr packed struct first zero-bit field" {
|
||||||
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
|
||||||
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
||||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
|
||||||
|
|
||||||
const C = packed struct {
|
const C = packed struct {
|
||||||
a: u0 = 0,
|
a: u0 = 0,
|
||||||
|
|
@ -1139,6 +1140,7 @@ test "@fieldParentPtr packed struct middle zero-bit field" {
|
||||||
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
|
||||||
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
||||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
|
||||||
|
|
||||||
const C = packed struct {
|
const C = packed struct {
|
||||||
a: f32 = 3.14,
|
a: f32 = 3.14,
|
||||||
|
|
@ -1245,6 +1247,7 @@ test "@fieldParentPtr packed struct last zero-bit field" {
|
||||||
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
|
||||||
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
||||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
|
||||||
|
|
||||||
const C = packed struct {
|
const C = packed struct {
|
||||||
a: f32 = 3.14,
|
a: f32 = 3.14,
|
||||||
|
|
|
||||||
|
|
@ -749,6 +749,7 @@ test "packed struct with fp fields" {
|
||||||
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
|
||||||
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
||||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
|
||||||
|
|
||||||
const S = packed struct {
|
const S = packed struct {
|
||||||
data0: f32,
|
data0: f32,
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ const expectEqual = std.testing.expectEqual;
|
||||||
test "implicit cast vector to array - bool" {
|
test "implicit cast vector to array - bool" {
|
||||||
if (builtin.cpu.arch == .aarch64_be and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
|
if (builtin.cpu.arch == .aarch64_be and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
|
||||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
|
||||||
|
|
||||||
const S = struct {
|
const S = struct {
|
||||||
fn doTheTest() !void {
|
fn doTheTest() !void {
|
||||||
|
|
@ -32,6 +33,7 @@ test "implicit cast vector to array - bool" {
|
||||||
|
|
||||||
test "implicit cast array to vector - bool" {
|
test "implicit cast array to vector - bool" {
|
||||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
|
||||||
|
|
||||||
const S = struct {
|
const S = struct {
|
||||||
fn doTheTest() !void {
|
fn doTheTest() !void {
|
||||||
|
|
|
||||||
|
|
@ -1366,18 +1366,16 @@ const test_targets = blk: {
|
||||||
|
|
||||||
// WASI Targets
|
// WASI Targets
|
||||||
|
|
||||||
// Disabled due to no active maintainer (feel free to fix the failures
|
.{
|
||||||
// and then re-enable at any time). The failures occur due to backend
|
.target = .{
|
||||||
// miscompilation of different AIR from the frontend.
|
.cpu_arch = .wasm32,
|
||||||
//.{
|
.os_tag = .wasi,
|
||||||
// .target = .{
|
.abi = .none,
|
||||||
// .cpu_arch = .wasm32,
|
},
|
||||||
// .os_tag = .wasi,
|
.skip_modules = &.{ "compiler-rt", "std" },
|
||||||
// .abi = .none,
|
.use_llvm = false,
|
||||||
// },
|
.use_lld = false,
|
||||||
// .use_llvm = false,
|
},
|
||||||
// .use_lld = false,
|
|
||||||
//},
|
|
||||||
.{
|
.{
|
||||||
.target = .{
|
.target = .{
|
||||||
.cpu_arch = .wasm32,
|
.cpu_arch = .wasm32,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue