zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 66bcc55e0196bd43746a09a79668c7c495bd1f89 (tree)
parent bd32206b4449e329c9ef6ba4fd19746234f474f8
Author: Luuk de Gram <luuk@degram.dev>
Date:   Tue,  1 Nov 2022 15:05:09 +0100

llvm: mangle extern Wasm functions

When Wasm extern functions contain the same name, but have a
different module name such as `extern "a"` vs `extern "b"` LLVM will
currently resolve the two functions to the same symbol. By mangling
the name of the symbol, we ensure the functions are resolved
seperately. We mangle the name by applying <name>|<module> where
module is also known as the library name.

Diffstat:
Msrc/codegen/llvm.zig | 14++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig @@ -1279,8 +1279,18 @@ pub const Object = struct { const llvm_global = self.decl_map.get(decl_index) orelse return; const decl = module.declPtr(decl_index); if (decl.isExtern()) { - llvm_global.setValueName(decl.name); - if (self.getLlvmGlobal(decl.name)) |other_global| { + const is_wasm_fn = module.getTarget().isWasm() and try decl.isFunction(); + const mangle_name = is_wasm_fn and + decl.getExternFn().?.lib_name != null and + !std.mem.eql(u8, std.mem.sliceTo(decl.getExternFn().?.lib_name.?, 0), "c"); + const decl_name = if (mangle_name) name: { + const tmp = try std.fmt.allocPrintZ(module.gpa, "{s}|{s}", .{ decl.name, decl.getExternFn().?.lib_name.? }); + break :name tmp.ptr; + } else decl.name; + defer if (mangle_name) module.gpa.free(std.mem.sliceTo(decl_name, 0)); + + llvm_global.setValueName(decl_name); + if (self.getLlvmGlobal(decl_name)) |other_global| { if (other_global != llvm_global) { log.debug("updateDeclExports isExtern()=true setValueName({s}) conflict", .{decl.name}); try self.extern_collisions.put(module.gpa, decl_index, {});