Skip to content

Commit 5fb36d2

Browse files
authored
Merge pull request #24557 from pavelverigo/wasm-try-ptr
2 parents b8955a2 + 4328f71 commit 5fb36d2

File tree

4 files changed

+99
-22
lines changed

4 files changed

+99
-22
lines changed

src/arch/wasm/CodeGen.zig

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1886,8 +1886,10 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
18861886
.call_never_tail => cg.airCall(inst, .never_tail),
18871887
.call_never_inline => cg.airCall(inst, .never_inline),
18881888

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),
18911893

18921894
.is_null => cg.airIsNull(inst, .i32_eq, .value),
18931895
.is_non_null => cg.airIsNull(inst, .i32_ne, .value),
@@ -1970,8 +1972,6 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
19701972
.runtime_nav_ptr => cg.airRuntimeNavPtr(inst),
19711973

19721974
.assembly,
1973-
.is_err_ptr,
1974-
.is_non_err_ptr,
19751975

19761976
.err_return_trace,
19771977
.set_err_return_trace,
@@ -4105,7 +4105,7 @@ fn airSwitchDispatch(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
41054105
return cg.finishAir(inst, .none, &.{br.operand});
41064106
}
41074107

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 {
41094109
const zcu = cg.pt.zcu;
41104110
const un_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
41114111
const operand = try cg.resolveInst(un_op);
@@ -4122,7 +4122,7 @@ fn airIsErr(cg: *CodeGen, inst: Air.Inst.Index, opcode: std.wasm.Opcode) InnerEr
41224122
}
41234123

41244124
try cg.emitWValue(operand);
4125-
if (pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
4125+
if (op_kind == .ptr or pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
41264126
try cg.addMemArg(.i32_load16_u, .{
41274127
.offset = operand.offset() + @as(u32, @intCast(errUnionErrorOffset(pl_ty, zcu))),
41284128
.alignment = @intCast(Type.anyerror.abiAlignment(zcu).toByteUnits().?),
@@ -6462,9 +6462,6 @@ fn lowerTry(
64626462
operand_is_ptr: bool,
64636463
) InnerError!WValue {
64646464
const zcu = cg.pt.zcu;
6465-
if (operand_is_ptr) {
6466-
return cg.fail("TODO: lowerTry for pointers", .{});
6467-
}
64686465

64696466
const pl_ty = err_union_ty.errorUnionPayload(zcu);
64706467
const pl_has_bits = pl_ty.hasRuntimeBitsIgnoreComptime(zcu);
@@ -6475,7 +6472,7 @@ fn lowerTry(
64756472

64766473
// check if the error tag is set for the error union.
64776474
try cg.emitWValue(err_union);
6478-
if (pl_has_bits) {
6475+
if (pl_has_bits or operand_is_ptr) {
64796476
const err_offset: u32 = @intCast(errUnionErrorOffset(pl_ty, zcu));
64806477
try cg.addMemArg(.i32_load16_u, .{
64816478
.offset = err_union.offset() + err_offset,
@@ -6497,12 +6494,12 @@ fn lowerTry(
64976494
}
64986495

64996496
// 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) {
65016498
return .none;
65026499
}
65036500

65046501
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)) {
65066503
return buildPointerOffset(cg, err_union, pl_offset, .new);
65076504
}
65086505
const payload = try cg.load(err_union, pl_ty, pl_offset);

test/behavior/try.zig

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,82 @@ test "'return try' through conditional" {
121121
comptime std.debug.assert(result == 123);
122122
}
123123
}
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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,8 @@ const TestManifestConfigDefaults = struct {
800800
}
801801
// Windows
802802
defaults = defaults ++ "x86_64-windows" ++ ",";
803+
// Wasm
804+
defaults = defaults ++ "wasm32-wasi";
803805
break :blk defaults;
804806
};
805807
} else if (std.mem.eql(u8, key, "output_mode")) {

test/tests.zig

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1369,16 +1369,15 @@ const test_targets = blk: {
13691369

13701370
// WASI Targets
13711371

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+
},
13821381
.{
13831382
.target = .{
13841383
.cpu_arch = .wasm32,

0 commit comments

Comments
 (0)