authorgravatar for paul.verigo@gmail.comPavel Verigo <paul.verigo@gmail.com> 2026-08-17 11:08:23+02:00
committergravatar for paul.verigo@gmail.comPavel Verigo <paul.verigo@gmail.com> 2026-08-17 11:08:23+02:00
log6716bf52e70791104caf057af3fece674f0ac3dd
treee03eb1aeb75bfb8d6e5070f94bd7a5186e5c90e1
parent7b02ab758845d553ef4399548274ef2e23eaeb2f
parent46af37a1ad8bcff989ae18624b02760ab7a5bfa5

Merge pull request 'wasm: enable incremental tests for selfhosted' (#36534) from pavelverigo/zig:wasm-incr-tests-enable into master

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/36534

5 files changed, 73 insertions(+), 7 deletions(-)

build.zig+1-1
...@@ -772,7 +772,7 @@ pub fn build(b: *std.Build) !void {...@@ -772,7 +772,7 @@ pub fn build(b: *std.Build) !void {
772 }772 }
773773
774 const test_incremental_step = b.step("test-incremental", "Run the incremental compilation test cases");774 const test_incremental_step = b.step("test-incremental", "Run the incremental compilation test cases");
775 try tests.addIncrementalTests(b, test_incremental_step, test_filters);775 try tests.addIncrementalTests(b, test_incremental_step, test_filters, test_target_filters);
776 if (!skip_test_incremental) test_step.dependOn(test_incremental_step);776 if (!skip_test_incremental) test_step.dependOn(test_incremental_step);
777777
778 if (tests.addLibcTestNszTests(b, .{778 if (tests.addLibcTestNszTests(b, .{
src/link/Wasm.zig-3
...@@ -3754,9 +3754,6 @@ pub fn updateExports(...@@ -3754,9 +3754,6 @@ pub fn updateExports(
3754 const ip = &zcu.intern_pool;3754 const ip = &zcu.intern_pool;
3755 const is_obj = wasm.base.comp.config.output_mode == .Obj;3755 const is_obj = wasm.base.comp.config.output_mode == .Obj;
37563756
3757 wasm.nav_exports.clearRetainingCapacity();
3758 wasm.uav_exports.clearRetainingCapacity();
3759
3760 for (export_indices) |export_idx| {3757 for (export_indices) |export_idx| {
3761 const exp = export_idx.ptr(zcu);3758 const exp = export_idx.ptr(zcu);
3762 const name_slice = exp.opts.name.toSlice(ip);3759 const name_slice = exp.opts.name.toSlice(ip);
src/link/Wasm/Flush.zig+9
...@@ -249,6 +249,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {...@@ -249,6 +249,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
249 };249 };
250 const is_obj = comp.config.output_mode == .Obj;250 const is_obj = comp.config.output_mode == .Obj;
251 const allow_undefined = is_obj or wasm.import_symbols;251 const allow_undefined = is_obj or wasm.import_symbols;
252 const zcu_references = if (comp.zcu) |zcu| try zcu.resolveReferences() else null;
252253
253 const entry_name = if (wasm.entry_resolution.isNavOrUnresolved(wasm)) wasm.entry_name else .none;254 const entry_name = if (wasm.entry_resolution.isNavOrUnresolved(wasm)) wasm.entry_name else .none;
254255
...@@ -1223,6 +1224,14 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {...@@ -1223,6 +1224,14 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
1223 try emitTagIndexFunction(wasm, binary_bytes, ip_index);1224 try emitTagIndexFunction(wasm, binary_bytes, ip_index);
1224 },1225 },
1225 else => {1226 else => {
1227 if (!zcu_references.?.contains(.wrap(.{ .func = ip_index }))) {
1228 try binary_bytes.appendSlice(gpa, &.{
1229 0, // no locals
1230 @backingInt(std.wasm.Opcode.@"unreachable"),
1231 @backingInt(std.wasm.Opcode.end),
1232 });
1233 continue;
1234 }
1226 const func = i.value(wasm).function;1235 const func = i.value(wasm).function;
1227 const mir: Mir = .{1236 const mir: Mir = .{
1228 .instructions = wasm.mir_instructions.slice().subslice(func.instructions_off, func.instructions_len),1237 .instructions = wasm.mir_instructions.slice().subslice(func.instructions_off, func.instructions_len),
test/incremental/remove_function_with_changed_callee created+50
...@@ -0,0 +1,50 @@
1#update=initial version
2#file=main.zig
3const std = @import("std");
4const io = std.Io.Threaded.global_single_threaded.io();
5
6const A = enum(u32) {
7 zero,
8 one,
9};
10
11fn foo() !void {
12 try bar(.zero);
13}
14
15fn bar(a: A) !void {
16 const msg = switch (a) {
17 .zero => "0",
18 .one => "1",
19 };
20 try std.Io.File.stdout().writeStreamingAll(io, msg);
21}
22
23pub fn main() !void {
24 try foo();
25}
26#expect_stdout="0"
27#update=remove foo and change bar wasm function type
28#file=main.zig
29//! This update must preserve `bar` `InternPool.Index` value, while changing its wasm function type.
30//! If `foo` code is preserved in the binary without any changes, wasm type checking will fail.
31const std = @import("std");
32const io = std.Io.Threaded.global_single_threaded.io();
33
34const A = enum(u64) {
35 zero,
36 one,
37};
38
39fn bar(a: A) !void {
40 const msg = switch (a) {
41 .zero => "0",
42 .one => "1",
43 };
44 try std.Io.File.stdout().writeStreamingAll(io, msg);
45}
46
47pub fn main() !void {
48 try bar(.one);
49}
50#expect_stdout="1"
test/tests.zig+13-3
...@@ -2266,8 +2266,7 @@ const incremental_targets: []const []const u8 = &.{...@@ -2266,8 +2266,7 @@ const incremental_targets: []const []const u8 = &.{
2266 "x86_64-linux-selfhosted",2266 "x86_64-linux-selfhosted",
2267 // https://codeberg.org/ziglang/zig/issues/317732267 // https://codeberg.org/ziglang/zig/issues/31773
2268 //"x86_64-windows-selfhosted",2268 //"x86_64-windows-selfhosted",
2269 // https://codeberg.org/ziglang/zig/issues/318102269 "wasm32-wasi-selfhosted",
2270 //"wasm32-wasi-selfhosted",
2271};2270};
22722271
2273fn compatible32bitArch(host: *const std.Target) ?std.Target.Cpu.Arch {2272fn compatible32bitArch(host: *const std.Target) ?std.Target.Cpu.Arch {
...@@ -3282,7 +3281,12 @@ pub fn addDebuggerTests(b: *std.Build, options: DebuggerContext.Options) ?*Step...@@ -3282,7 +3281,12 @@ pub fn addDebuggerTests(b: *std.Build, options: DebuggerContext.Options) ?*Step
3282 return step;3281 return step;
3283}3282}
32843283
3285pub fn addIncrementalTests(b: *std.Build, test_step: *Step, test_filters: []const []const u8) !void {3284pub fn addIncrementalTests(
3285 b: *std.Build,
3286 test_step: *Step,
3287 test_filters: []const []const u8,
3288 test_target_filters: []const []const u8,
3289) !void {
3286 const io = b.graph.io;3290 const io = b.graph.io;
32873291
3288 const incr_check = b.addExecutable(.{3292 const incr_check = b.addExecutable(.{
...@@ -3317,6 +3321,12 @@ pub fn addIncrementalTests(b: *std.Build, test_step: *Step, test_filters: []cons...@@ -3317,6 +3321,12 @@ pub fn addIncrementalTests(b: *std.Build, test_step: *Step, test_filters: []cons
3317 b.dependOnFileContents(b.path(b.pathJoin(&.{ "test", "incremental", entry.path })));3321 b.dependOnFileContents(b.path(b.pathJoin(&.{ "test", "incremental", entry.path })));
33183322
3319 for (incremental_targets) |target_str| {3323 for (incremental_targets) |target_str| {
3324 if (test_target_filters.len > 0) {
3325 for (test_target_filters) |filter| {
3326 if (std.mem.find(u8, target_str, filter) != null) break;
3327 } else continue;
3328 }
3329
3320 const run = b.addRunArtifact(incr_check);3330 const run = b.addRunArtifact(incr_check);
3321 run.setName(b.fmt("incr-check {s} '{s}'", .{ target_str, entry.basename }));3331 run.setName(b.fmt("incr-check {s} '{s}'", .{ target_str, entry.basename }));
33223332