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