authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-11-02 14:10:07-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-11-02 14:10:07-04:00
log57dbeb90affb81501d18210db0075620e40dfefb
tree0cd16da2f626ea37276ed065dfaa3775897fdbc5
parentc22f17e15f79fdc97b6c5482c796649529eb61d7
parentef0df24626cc6c3cfe0b87164d481eeb26cc57fb
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #13396 from Luukdegram/fix-12880

llvm: mangle extern function names for Wasm target

6 files changed, 49 insertions(+), 2 deletions(-)

src/codegen/llvm.zig+12-2
......@@ -1279,8 +1279,18 @@ pub const Object = struct {
12791279 const llvm_global = self.decl_map.get(decl_index) orelse return;
12801280 const decl = module.declPtr(decl_index);
12811281 if (decl.isExtern()) {
1282 llvm_global.setValueName(decl.name);
1283 if (self.getLlvmGlobal(decl.name)) |other_global| {
1282 const is_wasm_fn = module.getTarget().isWasm() and try decl.isFunction();
1283 const mangle_name = is_wasm_fn and
1284 decl.getExternFn().?.lib_name != null and
1285 !std.mem.eql(u8, std.mem.sliceTo(decl.getExternFn().?.lib_name.?, 0), "c");
1286 const decl_name = if (mangle_name) name: {
1287 const tmp = try std.fmt.allocPrintZ(module.gpa, "{s}|{s}", .{ decl.name, decl.getExternFn().?.lib_name.? });
1288 break :name tmp.ptr;
1289 } else decl.name;
1290 defer if (mangle_name) module.gpa.free(std.mem.sliceTo(decl_name, 0));
1291
1292 llvm_global.setValueName(decl_name);
1293 if (self.getLlvmGlobal(decl_name)) |other_global| {
12841294 if (other_global != llvm_global) {
12851295 log.debug("updateDeclExports isExtern()=true setValueName({s}) conflict", .{decl.name});
12861296 try self.extern_collisions.put(module.gpa, decl_index, {});
test/link.zig+5
......@@ -48,6 +48,11 @@ fn addWasmCases(cases: *tests.StandaloneContext) void {
4848 .use_emulation = true,
4949 });
5050
51 cases.addBuildFile("test/link/wasm/extern-mangle/build.zig", .{
52 .build_modes = true,
53 .requires_stage2 = true,
54 });
55
5156 cases.addBuildFile("test/link/wasm/infer-features/build.zig", .{
5257 .requires_stage2 = true,
5358 });
test/link/wasm/extern-mangle/a.zig created+1
......@@ -0,0 +1 @@
1pub extern "a" fn hello() i32;
test/link/wasm/extern-mangle/b.zig created+1
......@@ -0,0 +1 @@
1pub extern "b" fn hello() i32;
test/link/wasm/extern-mangle/build.zig created+24
......@@ -0,0 +1,24 @@
1const std = @import("std");
2const Builder = std.build.Builder;
3
4pub fn build(b: *Builder) void {
5 const mode = b.standardReleaseOptions();
6
7 const test_step = b.step("test", "Test");
8 test_step.dependOn(b.getInstallStep());
9
10 const lib = b.addSharedLibrary("lib", "lib.zig", .unversioned);
11 lib.setBuildMode(mode);
12 lib.setTarget(.{ .cpu_arch = .wasm32, .os_tag = .freestanding });
13 lib.install();
14
15 const check_lib = lib.checkObject(.wasm);
16 check_lib.checkStart("Section import");
17 check_lib.checkNext("entries 2"); // a.hello & b.hello
18 check_lib.checkNext("module a");
19 check_lib.checkNext("name hello");
20 check_lib.checkNext("module b");
21 check_lib.checkNext("name hello");
22
23 test_step.dependOn(&check_lib.step);
24}
test/link/wasm/extern-mangle/lib.zig created+6
......@@ -0,0 +1,6 @@
1const a = @import("a.zig").hello;
2const b = @import("b.zig").hello;
3export fn foo() void {
4 _ = a();
5 _ = b();
6}