| ... | ... | @@ -101,8 +101,8 @@ exports: std.ArrayListUnmanaged(types.Export) = .{}, |
| 101 | 101 | /// When this is non-zero, we must emit a table entry, |
| 102 | 102 | /// as well as an 'elements' section. |
| 103 | 103 | /// |
| 104 | | /// Note: Key is symbol index, value represents the index into the table |
| 105 | | function_table: std.AutoHashMapUnmanaged(u32, u32) = .{}, |
| 104 | /// Note: Key is symbol location, value represents the index into the table |
| 105 | function_table: std.AutoHashMapUnmanaged(SymbolLoc, u32) = .{}, |
| 106 | 106 | |
| 107 | 107 | /// All object files and their data which are linked into the final binary |
| 108 | 108 | objects: std.ArrayListUnmanaged(Object) = .{}, |
| ... | ... | @@ -363,6 +363,9 @@ fn resolveSymbolsInObject(self: *Wasm, object_index: u16) !void { |
| 363 | 363 | .index = sym_index, |
| 364 | 364 | }; |
| 365 | 365 | const sym_name = object.string_table.get(symbol.name); |
| 366 | if (mem.eql(u8, sym_name, "__indirect_function_table")) { |
| 367 | continue; |
| 368 | } |
| 366 | 369 | const sym_name_index = try self.string_table.put(self.base.allocator, sym_name); |
| 367 | 370 | |
| 368 | 371 | if (symbol.isLocal()) { |
| ... | ... | @@ -837,7 +840,7 @@ pub fn freeDecl(self: *Wasm, decl: *Module.Decl) void { |
| 837 | 840 | /// Appends a new entry to the indirect function table |
| 838 | 841 | pub fn addTableFunction(self: *Wasm, symbol_index: u32) !void { |
| 839 | 842 | const index = @intCast(u32, self.function_table.count()); |
| 840 | | try self.function_table.put(self.base.allocator, symbol_index, index); |
| 843 | try self.function_table.put(self.base.allocator, .{ .file = null, .index = symbol_index }, index); |
| 841 | 844 | } |
| 842 | 845 | |
| 843 | 846 | /// Assigns indexes to all indirect functions. |
| ... | ... | @@ -1017,6 +1020,9 @@ fn setupImports(self: *Wasm) !void { |
| 1017 | 1020 | } |
| 1018 | 1021 | |
| 1019 | 1022 | const symbol = symbol_loc.getSymbol(self); |
| 1023 | if (std.mem.eql(u8, symbol_loc.getName(self), "__indirect_function_table")) { |
| 1024 | continue; |
| 1025 | } |
| 1020 | 1026 | if (symbol.tag == .data or !symbol.requiresImport()) { |
| 1021 | 1027 | continue; |
| 1022 | 1028 | } |
| ... | ... | @@ -1166,13 +1172,20 @@ fn setupExports(self: *Wasm) !void { |
| 1166 | 1172 | if (!symbol.isExported()) continue; |
| 1167 | 1173 | |
| 1168 | 1174 | const sym_name = sym_loc.getName(self); |
| 1169 | | const export_name = if (self.export_names.get(sym_loc)) |name| name else symbol.name; |
| 1175 | const export_name = if (self.export_names.get(sym_loc)) |name| name else blk: { |
| 1176 | if (sym_loc.file == null) break :blk symbol.name; |
| 1177 | break :blk try self.string_table.put(self.base.allocator, sym_name); |
| 1178 | }; |
| 1170 | 1179 | const exp: types.Export = .{ |
| 1171 | 1180 | .name = export_name, |
| 1172 | 1181 | .kind = symbol.tag.externalType(), |
| 1173 | 1182 | .index = symbol.index, |
| 1174 | 1183 | }; |
| 1175 | | log.debug("Exporting symbol '{s}' as '{s}' at index: ({d})", .{ sym_name, self.string_table.get(exp.name), exp.index }); |
| 1184 | log.debug("Exporting symbol '{s}' as '{s}' at index: ({d})", .{ |
| 1185 | sym_name, |
| 1186 | self.string_table.get(exp.name), |
| 1187 | exp.index, |
| 1188 | }); |
| 1176 | 1189 | try self.exports.append(self.base.allocator, exp); |
| 1177 | 1190 | } |
| 1178 | 1191 | |
| ... | ... | @@ -1767,8 +1780,8 @@ pub fn flushModule(self: *Wasm, comp: *Compilation) !void { |
| 1767 | 1780 | try leb.writeULEB128(writer, @as(u8, 0)); |
| 1768 | 1781 | try leb.writeULEB128(writer, @intCast(u32, self.function_table.count())); |
| 1769 | 1782 | var symbol_it = self.function_table.keyIterator(); |
| 1770 | | while (symbol_it.next()) |symbol_index_ptr| { |
| 1771 | | try leb.writeULEB128(writer, self.symbols.items[symbol_index_ptr.*].index); |
| 1783 | while (symbol_it.next()) |symbol_loc_ptr| { |
| 1784 | try leb.writeULEB128(writer, symbol_loc_ptr.*.getSymbol(self).index); |
| 1772 | 1785 | } |
| 1773 | 1786 | |
| 1774 | 1787 | try writeVecSectionHeader( |