| author | |
| committer | |
| log | 5fb36d2600b686a5132b42c4824f99dc2412f037 |
| tree | 18e3f648542d574c893d1cfd04ce1bfbefbdabb2 |
| parent | b8955a2e0aea692b6c76dc39962b3620649b6e1f |
| parent | 4328f71d9fbb67b1e9949b5c398578eab6f59314 |
| signature |
4 files changed, 99 insertions(+), 22 deletions(-)
src/arch/wasm/CodeGen.zig+9-12| ... | ... | @@ -1886,8 +1886,10 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 1886 | 1886 | .call_never_tail => cg.airCall(inst, .never_tail), |
| 1887 | 1887 | .call_never_inline => cg.airCall(inst, .never_inline), |
| 1888 | 1888 | |
| 1889 | .is_err => cg.airIsErr(inst, .i32_ne), | |
| 1890 | .is_non_err => cg.airIsErr(inst, .i32_eq), | |
| 1889 | .is_err => cg.airIsErr(inst, .i32_ne, .value), | |
| 1890 | .is_non_err => cg.airIsErr(inst, .i32_eq, .value), | |
| 1891 | .is_err_ptr => cg.airIsErr(inst, .i32_ne, .ptr), | |
| 1892 | .is_non_err_ptr => cg.airIsErr(inst, .i32_eq, .ptr), | |
| 1891 | 1893 | |
| 1892 | 1894 | .is_null => cg.airIsNull(inst, .i32_eq, .value), |
| 1893 | 1895 | .is_non_null => cg.airIsNull(inst, .i32_ne, .value), |
| ... | ... | @@ -1970,8 +1972,6 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 1970 | 1972 | .runtime_nav_ptr => cg.airRuntimeNavPtr(inst), |
| 1971 | 1973 | |
| 1972 | 1974 | .assembly, |
| 1973 | .is_err_ptr, | |
| 1974 | .is_non_err_ptr, | |
| 1975 | 1975 | |
| 1976 | 1976 | .err_return_trace, |
| 1977 | 1977 | .set_err_return_trace, |
| ... | ... | @@ -4105,7 +4105,7 @@ fn airSwitchDispatch(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4105 | 4105 | return cg.finishAir(inst, .none, &.{br.operand}); |
| 4106 | 4106 | } |
| 4107 | 4107 | |
| 4108 | fn airIsErr(cg: *CodeGen, inst: Air.Inst.Index, opcode: std.wasm.Opcode) InnerError!void { | |
| 4108 | fn airIsErr(cg: *CodeGen, inst: Air.Inst.Index, opcode: std.wasm.Opcode, op_kind: enum { value, ptr }) InnerError!void { | |
| 4109 | 4109 | const zcu = cg.pt.zcu; |
| 4110 | 4110 | const un_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4111 | 4111 | const operand = try cg.resolveInst(un_op); |
| ... | ... | @@ -4122,7 +4122,7 @@ fn airIsErr(cg: *CodeGen, inst: Air.Inst.Index, opcode: std.wasm.Opcode) InnerEr |
| 4122 | 4122 | } |
| 4123 | 4123 | |
| 4124 | 4124 | try cg.emitWValue(operand); |
| 4125 | if (pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 4125 | if (op_kind == .ptr or pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 4126 | 4126 | try cg.addMemArg(.i32_load16_u, .{ |
| 4127 | 4127 | .offset = operand.offset() + @as(u32, @intCast(errUnionErrorOffset(pl_ty, zcu))), |
| 4128 | 4128 | .alignment = @intCast(Type.anyerror.abiAlignment(zcu).toByteUnits().?), |
| ... | ... | @@ -6462,9 +6462,6 @@ fn lowerTry( |
| 6462 | 6462 | operand_is_ptr: bool, |
| 6463 | 6463 | ) InnerError!WValue { |
| 6464 | 6464 | const zcu = cg.pt.zcu; |
| 6465 | if (operand_is_ptr) { | |
| 6466 | return cg.fail("TODO: lowerTry for pointers", .{}); | |
| 6467 | } | |
| 6468 | 6465 | |
| 6469 | 6466 | const pl_ty = err_union_ty.errorUnionPayload(zcu); |
| 6470 | 6467 | const pl_has_bits = pl_ty.hasRuntimeBitsIgnoreComptime(zcu); |
| ... | ... | @@ -6475,7 +6472,7 @@ fn lowerTry( |
| 6475 | 6472 | |
| 6476 | 6473 | // check if the error tag is set for the error union. |
| 6477 | 6474 | try cg.emitWValue(err_union); |
| 6478 | if (pl_has_bits) { | |
| 6475 | if (pl_has_bits or operand_is_ptr) { | |
| 6479 | 6476 | const err_offset: u32 = @intCast(errUnionErrorOffset(pl_ty, zcu)); |
| 6480 | 6477 | try cg.addMemArg(.i32_load16_u, .{ |
| 6481 | 6478 | .offset = err_union.offset() + err_offset, |
| ... | ... | @@ -6497,12 +6494,12 @@ fn lowerTry( |
| 6497 | 6494 | } |
| 6498 | 6495 | |
| 6499 | 6496 | // if we reach here it means error was not set, and we want the payload |
| 6500 | if (!pl_has_bits) { | |
| 6497 | if (!pl_has_bits and !operand_is_ptr) { | |
| 6501 | 6498 | return .none; |
| 6502 | 6499 | } |
| 6503 | 6500 | |
| 6504 | 6501 | const pl_offset: u32 = @intCast(errUnionPayloadOffset(pl_ty, zcu)); |
| 6505 | if (isByRef(pl_ty, zcu, cg.target)) { | |
| 6502 | if (operand_is_ptr or isByRef(pl_ty, zcu, cg.target)) { | |
| 6506 | 6503 | return buildPointerOffset(cg, err_union, pl_offset, .new); |
| 6507 | 6504 | } |
| 6508 | 6505 | const payload = try cg.load(err_union, pl_ty, pl_offset); |
test/behavior/try.zig+79| ... | ... | @@ -121,3 +121,82 @@ test "'return try' through conditional" { |
| 121 | 121 | comptime std.debug.assert(result == 123); |
| 122 | 122 | } |
| 123 | 123 | } |
| 124 | ||
| 125 | test "try ptr propagation const" { | |
| 126 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | |
| 127 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | |
| 128 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | |
| 129 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; | |
| 130 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | |
| 131 | ||
| 132 | const S = struct { | |
| 133 | fn foo0() !u32 { | |
| 134 | return 0; | |
| 135 | } | |
| 136 | ||
| 137 | fn foo1() error{Bad}!u32 { | |
| 138 | return 1; | |
| 139 | } | |
| 140 | ||
| 141 | fn foo2() anyerror!u32 { | |
| 142 | return 2; | |
| 143 | } | |
| 144 | ||
| 145 | fn doTheTest() !void { | |
| 146 | const res0: *const u32 = &(try foo0()); | |
| 147 | const res1: *const u32 = &(try foo1()); | |
| 148 | const res2: *const u32 = &(try foo2()); | |
| 149 | try expect(res0.* == 0); | |
| 150 | try expect(res1.* == 1); | |
| 151 | try expect(res2.* == 2); | |
| 152 | } | |
| 153 | }; | |
| 154 | try S.doTheTest(); | |
| 155 | try comptime S.doTheTest(); | |
| 156 | } | |
| 157 | ||
| 158 | test "try ptr propagation mutate" { | |
| 159 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | |
| 160 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | |
| 161 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | |
| 162 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; | |
| 163 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | |
| 164 | ||
| 165 | const S = struct { | |
| 166 | fn foo0() !u32 { | |
| 167 | return 0; | |
| 168 | } | |
| 169 | ||
| 170 | fn foo1() error{Bad}!u32 { | |
| 171 | return 1; | |
| 172 | } | |
| 173 | ||
| 174 | fn foo2() anyerror!u32 { | |
| 175 | return 2; | |
| 176 | } | |
| 177 | ||
| 178 | fn doTheTest() !void { | |
| 179 | var f0 = foo0(); | |
| 180 | var f1 = foo1(); | |
| 181 | var f2 = foo2(); | |
| 182 | ||
| 183 | const res0: *u32 = &(try f0); | |
| 184 | const res1: *u32 = &(try f1); | |
| 185 | const res2: *u32 = &(try f2); | |
| 186 | ||
| 187 | res0.* += 1; | |
| 188 | res1.* += 1; | |
| 189 | res2.* += 1; | |
| 190 | ||
| 191 | try expect(f0 catch unreachable == 1); | |
| 192 | try expect(f1 catch unreachable == 2); | |
| 193 | try expect(f2 catch unreachable == 3); | |
| 194 | ||
| 195 | try expect(res0.* == 1); | |
| 196 | try expect(res1.* == 2); | |
| 197 | try expect(res2.* == 3); | |
| 198 | } | |
| 199 | }; | |
| 200 | try S.doTheTest(); | |
| 201 | try comptime S.doTheTest(); | |
| 202 | } |
test/src/Cases.zig+2| ... | ... | @@ -800,6 +800,8 @@ const TestManifestConfigDefaults = struct { |
| 800 | 800 | } |
| 801 | 801 | // Windows |
| 802 | 802 | defaults = defaults ++ "x86_64-windows" ++ ","; |
| 803 | // Wasm | |
| 804 | defaults = defaults ++ "wasm32-wasi"; | |
| 803 | 805 | break :blk defaults; |
| 804 | 806 | }; |
| 805 | 807 | } else if (std.mem.eql(u8, key, "output_mode")) { |
test/tests.zig+9-10| ... | ... | @@ -1369,16 +1369,15 @@ const test_targets = blk: { |
| 1369 | 1369 | |
| 1370 | 1370 | // WASI Targets |
| 1371 | 1371 | |
| 1372 | // TODO: lowerTry for pointers | |
| 1373 | //.{ | |
| 1374 | // .target = .{ | |
| 1375 | // .cpu_arch = .wasm32, | |
| 1376 | // .os_tag = .wasi, | |
| 1377 | // .abi = .none, | |
| 1378 | // }, | |
| 1379 | // .use_llvm = false, | |
| 1380 | // .use_lld = false, | |
| 1381 | //}, | |
| 1372 | .{ | |
| 1373 | .target = .{ | |
| 1374 | .cpu_arch = .wasm32, | |
| 1375 | .os_tag = .wasi, | |
| 1376 | .abi = .none, | |
| 1377 | }, | |
| 1378 | .use_llvm = false, | |
| 1379 | .use_lld = false, | |
| 1380 | }, | |
| 1382 | 1381 | .{ |
| 1383 | 1382 | .target = .{ |
| 1384 | 1383 | .cpu_arch = .wasm32, |