| ... | @@ -813,7 +813,12 @@ fn checkUndefinedSymbols(wasm: *const Wasm) !void { | ... | @@ -813,7 +813,12 @@ fn checkUndefinedSymbols(wasm: *const Wasm) !void { |
| 813 | const file_name = if (undef.file) |file_index| name: { | 813 | const file_name = if (undef.file) |file_index| name: { |
| 814 | break :name wasm.objects.items[file_index].name; | 814 | break :name wasm.objects.items[file_index].name; |
| 815 | } else wasm.name; | 815 | } else wasm.name; |
| 816 | log.err("could not resolve undefined symbol '{s}'", .{undef.getName(wasm)}); | 816 | const import_name = if (undef.file) |file_index| name: { |
| | 817 | const obj = wasm.objects.items[file_index]; |
| | 818 | const name_index = obj.findImport(symbol.tag.externalType(), symbol.index).name; |
| | 819 | break :name obj.string_table.get(name_index); |
| | 820 | } else wasm.string_table.get(wasm.imports.get(undef).?.name); |
| | 821 | log.err("could not resolve undefined symbol '{s}'", .{import_name}); |
| 817 | log.err(" defined in '{s}'", .{file_name}); | 822 | log.err(" defined in '{s}'", .{file_name}); |
| 818 | } | 823 | } |
| 819 | } | 824 | } |
| ... | @@ -1430,18 +1435,31 @@ pub fn addOrUpdateImport( | ... | @@ -1430,18 +1435,31 @@ pub fn addOrUpdateImport( |
| 1430 | type_index: ?u32, | 1435 | type_index: ?u32, |
| 1431 | ) !void { | 1436 | ) !void { |
| 1432 | assert(symbol_index != 0); | 1437 | assert(symbol_index != 0); |
| 1433 | // For the import name itwasm, we use the decl's name, rather than the fully qualified name | 1438 | // For the import name, we use the decl's name, rather than the fully qualified name |
| 1434 | const decl_name_index = try wasm.string_table.put(wasm.base.allocator, name); | 1439 | // Also mangle the name when the lib name is set and not equal to "C" so imports with the same |
| | 1440 | // name but different module can be resolved correctly. |
| | 1441 | const mangle_name = lib_name != null and |
| | 1442 | !std.mem.eql(u8, std.mem.sliceTo(lib_name.?, 0), "c"); |
| | 1443 | const full_name = if (mangle_name) full_name: { |
| | 1444 | break :full_name try std.fmt.allocPrint(wasm.base.allocator, "{s}|{s}", .{ name, lib_name.? }); |
| | 1445 | } else name; |
| | 1446 | defer if (mangle_name) wasm.base.allocator.free(full_name); |
| | 1447 | |
| | 1448 | const decl_name_index = try wasm.string_table.put(wasm.base.allocator, full_name); |
| 1435 | const symbol: *Symbol = &wasm.symbols.items[symbol_index]; | 1449 | const symbol: *Symbol = &wasm.symbols.items[symbol_index]; |
| 1436 | symbol.setUndefined(true); | 1450 | symbol.setUndefined(true); |
| 1437 | symbol.setGlobal(true); | 1451 | symbol.setGlobal(true); |
| 1438 | symbol.name = decl_name_index; | 1452 | symbol.name = decl_name_index; |
| | 1453 | if (mangle_name) { |
| | 1454 | // we specified a specific name for the symbol that does not match the import name |
| | 1455 | symbol.setFlag(.WASM_SYM_EXPLICIT_NAME); |
| | 1456 | } |
| 1439 | const global_gop = try wasm.globals.getOrPut(wasm.base.allocator, decl_name_index); | 1457 | const global_gop = try wasm.globals.getOrPut(wasm.base.allocator, decl_name_index); |
| 1440 | if (!global_gop.found_existing) { | 1458 | if (!global_gop.found_existing) { |
| 1441 | const loc: SymbolLoc = .{ .file = null, .index = symbol_index }; | 1459 | const loc: SymbolLoc = .{ .file = null, .index = symbol_index }; |
| 1442 | global_gop.value_ptr.* = loc; | 1460 | global_gop.value_ptr.* = loc; |
| 1443 | try wasm.resolved_symbols.put(wasm.base.allocator, loc, {}); | 1461 | try wasm.resolved_symbols.put(wasm.base.allocator, loc, {}); |
| 1444 | try wasm.undefs.putNoClobber(wasm.base.allocator, name, loc); | 1462 | try wasm.undefs.putNoClobber(wasm.base.allocator, full_name, loc); |
| 1445 | } | 1463 | } |
| 1446 | | 1464 | |
| 1447 | if (type_index) |ty_index| { | 1465 | if (type_index) |ty_index| { |
| ... | @@ -1452,7 +1470,7 @@ pub fn addOrUpdateImport( | ... | @@ -1452,7 +1470,7 @@ pub fn addOrUpdateImport( |
| 1452 | if (!gop.found_existing) { | 1470 | if (!gop.found_existing) { |
| 1453 | gop.value_ptr.* = .{ | 1471 | gop.value_ptr.* = .{ |
| 1454 | .module_name = try wasm.string_table.put(wasm.base.allocator, module_name), | 1472 | .module_name = try wasm.string_table.put(wasm.base.allocator, module_name), |
| 1455 | .name = decl_name_index, | 1473 | .name = try wasm.string_table.put(wasm.base.allocator, name), |
| 1456 | .kind = .{ .function = ty_index }, | 1474 | .kind = .{ .function = ty_index }, |
| 1457 | }; | 1475 | }; |
| 1458 | } | 1476 | } |
| ... | @@ -3130,11 +3148,7 @@ fn emitNameSection(wasm: *Wasm, binary_bytes: *std.ArrayList(u8), arena: std.mem | ... | @@ -3130,11 +3148,7 @@ fn emitNameSection(wasm: *Wasm, binary_bytes: *std.ArrayList(u8), arena: std.mem |
| 3130 | | 3148 | |
| 3131 | for (wasm.resolved_symbols.keys()) |sym_loc| { | 3149 | for (wasm.resolved_symbols.keys()) |sym_loc| { |
| 3132 | const symbol = sym_loc.getSymbol(wasm).*; | 3150 | const symbol = sym_loc.getSymbol(wasm).*; |
| 3133 | const name = if (symbol.isUndefined()) blk: { | 3151 | const name = sym_loc.getName(wasm); |
| 3134 | if (symbol.tag == .data) continue; | | |
| 3135 | const imp = wasm.imports.get(sym_loc) orelse continue; | | |
| 3136 | break :blk wasm.string_table.get(imp.name); | | |
| 3137 | } else sym_loc.getName(wasm); | | |
| 3138 | switch (symbol.tag) { | 3152 | switch (symbol.tag) { |
| 3139 | .function => { | 3153 | .function => { |
| 3140 | const gop = funcs.getOrPutAssumeCapacity(symbol.index); | 3154 | const gop = funcs.getOrPutAssumeCapacity(symbol.index); |