diff --git a/test/link.zig b/test/link.zig index e30e0cf0ae..124a30a3b6 100644 --- a/test/link.zig +++ b/test/link.zig @@ -58,6 +58,11 @@ fn addWasmCases(cases: *tests.StandaloneContext) void { .requires_stage2 = true, }); + cases.addBuildFile("test/link/wasm/function-table/build.zig", .{ + .build_modes = true, + .requires_stage2 = true, + }); + cases.addBuildFile("test/link/wasm/infer-features/build.zig", .{ .requires_stage2 = true, }); diff --git a/test/link/wasm/function-table/build.zig b/test/link/wasm/function-table/build.zig new file mode 100644 index 0000000000..f7572bd6b1 --- /dev/null +++ b/test/link/wasm/function-table/build.zig @@ -0,0 +1,63 @@ +const std = @import("std"); +const Builder = std.build.Builder; + +pub fn build(b: *Builder) void { + const mode = b.standardReleaseOptions(); + + const test_step = b.step("test", "Test"); + test_step.dependOn(b.getInstallStep()); + + const import_table = b.addSharedLibrary("lib", "lib.zig", .unversioned); + import_table.setBuildMode(mode); + import_table.setTarget(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }); + import_table.use_llvm = false; + import_table.use_lld = false; + import_table.import_table = true; + + const export_table = b.addSharedLibrary("lib", "lib.zig", .unversioned); + export_table.setBuildMode(mode); + export_table.setTarget(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }); + export_table.use_llvm = false; + export_table.use_lld = false; + export_table.export_table = true; + + const regular_table = b.addSharedLibrary("lib", "lib.zig", .unversioned); + regular_table.setBuildMode(mode); + regular_table.setTarget(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }); + regular_table.use_llvm = false; + regular_table.use_lld = false; + + const check_import = import_table.checkObject(.wasm); + const check_export = export_table.checkObject(.wasm); + const check_regular = regular_table.checkObject(.wasm); + + check_import.checkStart("Section import"); + check_import.checkNext("entries 1"); + check_import.checkNext("module env"); + check_import.checkNext("name __indirect_function_table"); + check_import.checkNext("kind table"); + check_import.checkNext("type funcref"); + check_import.checkNext("min 1"); // 1 function pointer + check_import.checkNotPresent("max"); // when importing, we do not provide a max + check_import.checkNotPresent("Section table"); // we're importing it + + check_export.checkStart("Section export"); + check_export.checkNext("entries 2"); + check_export.checkNext("name __indirect_function_table"); // as per linker specification + check_export.checkNext("kind table"); + + check_regular.checkStart("Section table"); + check_regular.checkNext("entries 1"); + check_regular.checkNext("type funcref"); + check_regular.checkNext("min 2"); // index starts at 1 & 1 function pointer = 2. + check_regular.checkNext("max 2"); + check_regular.checkStart("Section element"); + check_regular.checkNext("entries 1"); + check_regular.checkNext("table index 0"); + check_regular.checkNext("i32.const 1"); // we want to start function indexes at 1 + check_regular.checkNext("indexes 1"); // 1 function pointer + + test_step.dependOn(&check_import.step); + test_step.dependOn(&check_export.step); + test_step.dependOn(&check_regular.step); +} diff --git a/test/link/wasm/function-table/lib.zig b/test/link/wasm/function-table/lib.zig new file mode 100644 index 0000000000..ed7a85b2db --- /dev/null +++ b/test/link/wasm/function-table/lib.zig @@ -0,0 +1,7 @@ +var func: *const fn () void = &bar; + +export fn foo() void { + func(); +} + +fn bar() void {}