| ... | ... | @@ -226,8 +226,8 @@ pub const SymbolLoc = struct { |
| 226 | 226 | return new_loc.getSymbol(wasm_file); |
| 227 | 227 | } |
| 228 | 228 | if (loc.file) |object_index| { |
| 229 | | const object = wasm_file.objects.items[object_index]; |
| 230 | | return &object.symtable[loc.index]; |
| 229 | const obj_file = wasm_file.file(@enumFromInt(object_index)).?; |
| 230 | return obj_file.symbol(loc.index); |
| 231 | 231 | } |
| 232 | 232 | return &wasm_file.synthetic_symbols.items[loc.index]; |
| 233 | 233 | } |
| ... | ... | @@ -238,8 +238,8 @@ pub const SymbolLoc = struct { |
| 238 | 238 | return new_loc.getName(wasm_file); |
| 239 | 239 | } |
| 240 | 240 | if (loc.file) |object_index| { |
| 241 | | const object = wasm_file.objects.items[object_index]; |
| 242 | | return object.string_table.get(object.symtable[loc.index].name); |
| 241 | const obj_file = wasm_file.file(@enumFromInt(object_index)).?; |
| 242 | return obj_file.symbolName(loc.index); |
| 243 | 243 | } |
| 244 | 244 | return wasm_file.string_table.get(wasm_file.synthetic_symbols.items[loc.index].name); |
| 245 | 245 | } |
| ... | ... | @@ -581,12 +581,13 @@ pub fn createEmpty( |
| 581 | 581 | return wasm; |
| 582 | 582 | } |
| 583 | 583 | |
| 584 | | pub fn file(wasm: *Wasm, index: File.Index) ?File { |
| 585 | | const tag = wasm.files.items(.tags)[index]; |
| 584 | pub fn file(wasm: *const Wasm, index: File.Index) ?File { |
| 585 | if (index == .null) return null; |
| 586 | const tag = wasm.files.items(.tags)[@intFromEnum(index)]; |
| 586 | 587 | return switch (tag) { |
| 587 | 588 | .null => null, |
| 588 | | .zig_object => .{ .zig_object = &wasm.files.items(.data)[index].zig_object }, |
| 589 | | .object => .{ .object = &wasm.files.items(.data)[index].object }, |
| 589 | .zig_object => .{ .zig_object = &wasm.files.items(.data)[@intFromEnum(index)].zig_object }, |
| 590 | .object => .{ .object = &wasm.files.items(.data)[@intFromEnum(index)].object }, |
| 590 | 591 | }; |
| 591 | 592 | } |
| 592 | 593 | |
| ... | ... | @@ -678,7 +679,7 @@ pub fn createAtom(wasm: *Wasm, sym_index: u32, file_index: File.Index) !Atom.Ind |
| 678 | 679 | const gpa = wasm.base.comp.gpa; |
| 679 | 680 | const index: Atom.Index = @intCast(wasm.managed_atoms.items.len); |
| 680 | 681 | const atom = try wasm.managed_atoms.addOne(gpa); |
| 681 | | atom.* = .{ .file_index = file_index, .sym_index = sym_index }; |
| 682 | atom.* = .{ .file = file_index, .sym_index = sym_index }; |
| 682 | 683 | try wasm.symbol_atom.putNoClobber(gpa, .{ .file = null, .index = sym_index }, index); |
| 683 | 684 | |
| 684 | 685 | return index; |
| ... | ... | @@ -755,18 +756,18 @@ fn requiresTLSReloc(wasm: *const Wasm) bool { |
| 755 | 756 | return false; |
| 756 | 757 | } |
| 757 | 758 | |
| 758 | | fn resolveSymbolsInObject(wasm: *Wasm, object_index: u16) !void { |
| 759 | fn resolveSymbolsInObject(wasm: *Wasm, file_index: File.Index) !void { |
| 759 | 760 | const gpa = wasm.base.comp.gpa; |
| 760 | | const object: Object = wasm.objects.items[object_index]; |
| 761 | | log.debug("Resolving symbols in object: '{s}'", .{object.name}); |
| 761 | const obj_file = wasm.file(file_index).?; |
| 762 | log.debug("Resolving symbols in object: '{s}'", .{obj_file.path()}); |
| 762 | 763 | |
| 763 | | for (object.symtable, 0..) |symbol, i| { |
| 764 | | const sym_index = @as(u32, @intCast(i)); |
| 764 | for (obj_file.symbols(), 0..) |symbol, i| { |
| 765 | const sym_index: u32 = @intCast(i); |
| 765 | 766 | const location: SymbolLoc = .{ |
| 766 | | .file = object_index, |
| 767 | .file = @intFromEnum(file_index), |
| 767 | 768 | .index = sym_index, |
| 768 | 769 | }; |
| 769 | | const sym_name = object.string_table.get(symbol.name); |
| 770 | const sym_name = obj_file.string(symbol.name); |
| 770 | 771 | if (mem.eql(u8, sym_name, "__indirect_function_table")) { |
| 771 | 772 | continue; |
| 772 | 773 | } |
| ... | ... | @@ -775,7 +776,7 @@ fn resolveSymbolsInObject(wasm: *Wasm, object_index: u16) !void { |
| 775 | 776 | if (symbol.isLocal()) { |
| 776 | 777 | if (symbol.isUndefined()) { |
| 777 | 778 | log.err("Local symbols are not allowed to reference imports", .{}); |
| 778 | | log.err(" symbol '{s}' defined in '{s}'", .{ sym_name, object.name }); |
| 779 | log.err(" symbol '{s}' defined in '{s}'", .{ sym_name, obj_file.path() }); |
| 779 | 780 | return error.UndefinedLocal; |
| 780 | 781 | } |
| 781 | 782 | try wasm.resolved_symbols.putNoClobber(gpa, location, {}); |
| ... | ... | @@ -796,9 +797,10 @@ fn resolveSymbolsInObject(wasm: *Wasm, object_index: u16) !void { |
| 796 | 797 | const existing_loc = maybe_existing.value_ptr.*; |
| 797 | 798 | const existing_sym: *Symbol = existing_loc.getSymbol(wasm); |
| 798 | 799 | |
| 799 | | const existing_file_path = if (existing_loc.file) |file_index| blk: { |
| 800 | | break :blk wasm.objects.items[file_index].name; |
| 801 | | } else wasm.name; |
| 800 | const existing_file_path = if (existing_loc.file) |existing_file_index| |
| 801 | wasm.file(@enumFromInt(existing_file_index)).?.path() |
| 802 | else |
| 803 | wasm.name; |
| 802 | 804 | |
| 803 | 805 | if (!existing_sym.isUndefined()) outer: { |
| 804 | 806 | if (!symbol.isUndefined()) inner: { |
| ... | ... | @@ -811,7 +813,7 @@ fn resolveSymbolsInObject(wasm: *Wasm, object_index: u16) !void { |
| 811 | 813 | // both are defined and weak, we have a symbol collision. |
| 812 | 814 | log.err("symbol '{s}' defined multiple times", .{sym_name}); |
| 813 | 815 | log.err(" first definition in '{s}'", .{existing_file_path}); |
| 814 | | log.err(" next definition in '{s}'", .{object.name}); |
| 816 | log.err(" next definition in '{s}'", .{obj_file.path()}); |
| 815 | 817 | return error.SymbolCollision; |
| 816 | 818 | } |
| 817 | 819 | |
| ... | ... | @@ -822,24 +824,24 @@ fn resolveSymbolsInObject(wasm: *Wasm, object_index: u16) !void { |
| 822 | 824 | if (symbol.tag != existing_sym.tag) { |
| 823 | 825 | log.err("symbol '{s}' mismatching type '{s}", .{ sym_name, @tagName(symbol.tag) }); |
| 824 | 826 | log.err(" first definition in '{s}'", .{existing_file_path}); |
| 825 | | log.err(" next definition in '{s}'", .{object.name}); |
| 827 | log.err(" next definition in '{s}'", .{obj_file.path()}); |
| 826 | 828 | return error.SymbolMismatchingType; |
| 827 | 829 | } |
| 828 | 830 | |
| 829 | 831 | if (existing_sym.isUndefined() and symbol.isUndefined()) { |
| 830 | 832 | // only verify module/import name for function symbols |
| 831 | 833 | if (symbol.tag == .function) { |
| 832 | | const existing_name = if (existing_loc.file) |file_index| blk: { |
| 833 | | const obj = wasm.objects.items[file_index]; |
| 834 | | const name_index = obj.findImport(symbol.tag.externalType(), existing_sym.index).module_name; |
| 835 | | break :blk obj.string_table.get(name_index); |
| 834 | const existing_name = if (existing_loc.file) |existing_file_index| blk: { |
| 835 | const existing_obj = wasm.file(@enumFromInt(existing_file_index)).?; |
| 836 | const imp = existing_obj.import(existing_loc.index); |
| 837 | break :blk existing_obj.string(imp.module_name); |
| 836 | 838 | } else blk: { |
| 837 | 839 | const name_index = wasm.imports.get(existing_loc).?.module_name; |
| 838 | 840 | break :blk wasm.string_table.get(name_index); |
| 839 | 841 | }; |
| 840 | 842 | |
| 841 | | const module_index = object.findImport(symbol.tag.externalType(), symbol.index).module_name; |
| 842 | | const module_name = object.string_table.get(module_index); |
| 843 | const imp = obj_file.import(sym_index); |
| 844 | const module_name = obj_file.string(imp.module_name); |
| 843 | 845 | if (!mem.eql(u8, existing_name, module_name)) { |
| 844 | 846 | log.err("symbol '{s}' module name mismatch. Expected '{s}', but found '{s}'", .{ |
| 845 | 847 | sym_name, |
| ... | ... | @@ -847,7 +849,7 @@ fn resolveSymbolsInObject(wasm: *Wasm, object_index: u16) !void { |
| 847 | 849 | module_name, |
| 848 | 850 | }); |
| 849 | 851 | log.err(" first definition in '{s}'", .{existing_file_path}); |
| 850 | | log.err(" next definition in '{s}'", .{object.name}); |
| 852 | log.err(" next definition in '{s}'", .{obj_file.path()}); |
| 851 | 853 | return error.ModuleNameMismatch; |
| 852 | 854 | } |
| 853 | 855 | } |
| ... | ... | @@ -863,7 +865,7 @@ fn resolveSymbolsInObject(wasm: *Wasm, object_index: u16) !void { |
| 863 | 865 | if (existing_ty.mutable != new_ty.mutable or existing_ty.valtype != new_ty.valtype) { |
| 864 | 866 | log.err("symbol '{s}' mismatching global types", .{sym_name}); |
| 865 | 867 | log.err(" first definition in '{s}'", .{existing_file_path}); |
| 866 | | log.err(" next definition in '{s}'", .{object.name}); |
| 868 | log.err(" next definition in '{s}'", .{obj_file.path()}); |
| 867 | 869 | return error.GlobalTypeMismatch; |
| 868 | 870 | } |
| 869 | 871 | } |
| ... | ... | @@ -875,7 +877,7 @@ fn resolveSymbolsInObject(wasm: *Wasm, object_index: u16) !void { |
| 875 | 877 | log.err("symbol '{s}' mismatching function signatures.", .{sym_name}); |
| 876 | 878 | log.err(" expected signature {}, but found signature {}", .{ existing_ty, new_ty }); |
| 877 | 879 | log.err(" first definition in '{s}'", .{existing_file_path}); |
| 878 | | log.err(" next definition in '{s}'", .{object.name}); |
| 880 | log.err(" next definition in '{s}'", .{obj_file.path()}); |
| 879 | 881 | return error.FunctionSignatureMismatch; |
| 880 | 882 | } |
| 881 | 883 | } |
| ... | ... | @@ -891,7 +893,7 @@ fn resolveSymbolsInObject(wasm: *Wasm, object_index: u16) !void { |
| 891 | 893 | // simply overwrite with the new symbol |
| 892 | 894 | log.debug("Overwriting symbol '{s}'", .{sym_name}); |
| 893 | 895 | log.debug(" old definition in '{s}'", .{existing_file_path}); |
| 894 | | log.debug(" new definition in '{s}'", .{object.name}); |
| 896 | log.debug(" new definition in '{s}'", .{obj_file.path()}); |
| 895 | 897 | try wasm.discarded.putNoClobber(gpa, existing_loc, location); |
| 896 | 898 | maybe_existing.value_ptr.* = location; |
| 897 | 899 | try wasm.globals.put(gpa, sym_name_index, location); |
| ... | ... | @@ -1190,7 +1192,7 @@ fn validateFeatures( |
| 1190 | 1192 | // extract all the used, disallowed and required features from each |
| 1191 | 1193 | // linked object file so we can test them. |
| 1192 | 1194 | for (wasm.objects.items) |file_index| { |
| 1193 | | const object: Object = wasm.files.items(.data)[file_index].object; |
| 1195 | const object: Object = wasm.files.items(.data)[@intFromEnum(file_index)].object; |
| 1194 | 1196 | for (object.features) |feature| { |
| 1195 | 1197 | const value = @as(u16, @intFromEnum(file_index)) << 1 | @as(u1, 1); |
| 1196 | 1198 | switch (feature.prefix) { |
| ... | ... | @@ -1260,7 +1262,7 @@ fn validateFeatures( |
| 1260 | 1262 | // For each linked object, validate the required and disallowed features |
| 1261 | 1263 | for (wasm.objects.items) |file_index| { |
| 1262 | 1264 | var object_used_features = [_]bool{false} ** known_features_count; |
| 1263 | | const object = wasm.files.items(.data)[file_index].object; |
| 1265 | const object = wasm.files.items(.data)[@intFromEnum(file_index)].object; |
| 1264 | 1266 | for (object.features) |feature| { |
| 1265 | 1267 | if (feature.prefix == .disallowed) continue; // already defined in 'disallowed' set. |
| 1266 | 1268 | // from here a feature is always used |
| ... | ... | @@ -1362,7 +1364,7 @@ fn checkUndefinedSymbols(wasm: *const Wasm) !void { |
| 1362 | 1364 | if (symbol.tag == .data) { |
| 1363 | 1365 | found_undefined_symbols = true; |
| 1364 | 1366 | const file_name = if (undef.file) |file_index| |
| 1365 | | wasm.file(file_index).?.path() |
| 1367 | wasm.file(@enumFromInt(file_index)).?.path() |
| 1366 | 1368 | else |
| 1367 | 1369 | wasm.name; |
| 1368 | 1370 | const symbol_name = undef.getName(wasm); |
| ... | ... | @@ -1386,7 +1388,7 @@ pub fn deinit(wasm: *Wasm) void { |
| 1386 | 1388 | gpa.free(segment_info.name); |
| 1387 | 1389 | } |
| 1388 | 1390 | if (wasm.zigObjectPtr()) |zig_obj| { |
| 1389 | | zig_obj.deinit(gpa); |
| 1391 | zig_obj.deinit(wasm); |
| 1390 | 1392 | } |
| 1391 | 1393 | for (wasm.objects.items) |obj_index| { |
| 1392 | 1394 | wasm.file(obj_index).?.object.deinit(gpa); |
| ... | ... | @@ -1623,8 +1625,8 @@ fn allocateAtoms(wasm: *Wasm) !void { |
| 1623 | 1625 | // Ensure we get the original symbol, so we verify the correct symbol on whether |
| 1624 | 1626 | // it is dead or not and ensure an atom is removed when dead. |
| 1625 | 1627 | // This is required as we may have parsed aliases into atoms. |
| 1626 | | const sym = if (symbol_loc.file) |object_index| |
| 1627 | | wasm.file(object_index).?.symbol(symbol_loc.index).* |
| 1628 | const sym = if (symbol_loc.file) |file_index| |
| 1629 | wasm.file(@enumFromInt(file_index)).?.symbol(symbol_loc.index).* |
| 1628 | 1630 | else |
| 1629 | 1631 | wasm.synthetic_symbols.items[symbol_loc.index]; |
| 1630 | 1632 | |
| ... | ... | @@ -1672,8 +1674,8 @@ fn allocateVirtualAddresses(wasm: *Wasm) void { |
| 1672 | 1674 | |
| 1673 | 1675 | const atom = wasm.getAtom(atom_index); |
| 1674 | 1676 | const merge_segment = wasm.base.comp.config.output_mode != .Obj; |
| 1675 | | const segment_info = if (atom.file) |object_index| |
| 1676 | | wasm.file(object_index).?.segmentInfo() |
| 1677 | const segment_info = if (atom.file != .null) |
| 1678 | wasm.file(atom.file).?.segmentInfo() |
| 1677 | 1679 | else |
| 1678 | 1680 | wasm.segment_info.values(); |
| 1679 | 1681 | const segment_name = segment_info[symbol.index].outputName(merge_segment); |
| ... | ... | @@ -1731,16 +1733,17 @@ fn sortDataSegments(wasm: *Wasm) !void { |
| 1731 | 1733 | /// contain any parameters. |
| 1732 | 1734 | fn setupInitFunctions(wasm: *Wasm) !void { |
| 1733 | 1735 | const gpa = wasm.base.comp.gpa; |
| 1736 | // There's no constructors for Zig so we can simply search through linked object files only. |
| 1734 | 1737 | for (wasm.objects.items) |file_index| { |
| 1735 | | const object = wasm.files.items(.data)[file_index].object; |
| 1738 | const object: Object = wasm.files.items(.data)[@intFromEnum(file_index)].object; |
| 1736 | 1739 | try wasm.init_funcs.ensureUnusedCapacity(gpa, object.init_funcs.len); |
| 1737 | 1740 | for (object.init_funcs) |init_func| { |
| 1738 | 1741 | const symbol = object.symtable[init_func.symbol_index]; |
| 1739 | 1742 | const ty: std.wasm.Type = if (symbol.isUndefined()) ty: { |
| 1740 | | const imp: types.Import = object.findImport(.function, symbol.index); |
| 1743 | const imp: types.Import = object.findImport(symbol); |
| 1741 | 1744 | break :ty object.func_types[imp.kind.function]; |
| 1742 | 1745 | } else ty: { |
| 1743 | | const func_index = symbol.index - object.importedCountByKind(.function); |
| 1746 | const func_index = symbol.index - object.imported_functions_count; |
| 1744 | 1747 | const func = object.functions[func_index]; |
| 1745 | 1748 | break :ty object.func_types[func.type_index]; |
| 1746 | 1749 | }; |
| ... | ... | @@ -1751,10 +1754,10 @@ fn setupInitFunctions(wasm: *Wasm) !void { |
| 1751 | 1754 | log.debug("appended init func '{s}'\n", .{object.string_table.get(symbol.name)}); |
| 1752 | 1755 | wasm.init_funcs.appendAssumeCapacity(.{ |
| 1753 | 1756 | .index = init_func.symbol_index, |
| 1754 | | .file = @as(u16, @intCast(file_index)), |
| 1757 | .file = @intFromEnum(file_index), |
| 1755 | 1758 | .priority = init_func.priority, |
| 1756 | 1759 | }); |
| 1757 | | try wasm.mark(.{ .index = init_func.symbol_index, .file = @intCast(file_index) }); |
| 1760 | try wasm.mark(.{ .index = init_func.symbol_index, .file = @intFromEnum(file_index) }); |
| 1758 | 1761 | } |
| 1759 | 1762 | } |
| 1760 | 1763 | |
| ... | ... | @@ -1993,7 +1996,7 @@ fn setupImports(wasm: *Wasm) !void { |
| 1993 | 1996 | } |
| 1994 | 1997 | |
| 1995 | 1998 | log.debug("Symbol '{s}' will be imported from the host", .{symbol_loc.getName(wasm)}); |
| 1996 | | const obj_file = wasm.file(file_index).?; |
| 1999 | const obj_file = wasm.file(@enumFromInt(file_index)).?; |
| 1997 | 2000 | const import = obj_file.import(symbol_loc.index); |
| 1998 | 2001 | |
| 1999 | 2002 | // We copy the import to a new import to ensure the names contain references |
| ... | ... | @@ -2058,7 +2061,7 @@ fn mergeSections(wasm: *Wasm) !void { |
| 2058 | 2061 | }; |
| 2059 | 2062 | |
| 2060 | 2063 | const obj_file = wasm.file(@enumFromInt(file_index)).?; |
| 2061 | | const symbol = obj_file.symbol[sym_loc.index]; |
| 2064 | const symbol = obj_file.symbol(sym_loc.index); |
| 2062 | 2065 | |
| 2063 | 2066 | if (symbol.isDead() or symbol.isUndefined()) { |
| 2064 | 2067 | // Skip undefined symbols as they go in the `import` section |
| ... | ... | @@ -2422,7 +2425,7 @@ pub fn getMatchingSegment(wasm: *Wasm, file_index: File.Index, symbol_index: u32 |
| 2422 | 2425 | break :blk index; |
| 2423 | 2426 | }, |
| 2424 | 2427 | .section => { |
| 2425 | | const section_name = file.symbolName(symbol.index); |
| 2428 | const section_name = obj_file.symbolName(symbol.index); |
| 2426 | 2429 | if (mem.eql(u8, section_name, ".debug_info")) { |
| 2427 | 2430 | return wasm.debug_info_index orelse blk: { |
| 2428 | 2431 | wasm.debug_info_index = index; |
| ... | ... | @@ -2705,8 +2708,8 @@ fn linkWithZld(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) lin |
| 2705 | 2708 | |
| 2706 | 2709 | try wasm.parseInputFiles(positionals.items); |
| 2707 | 2710 | |
| 2708 | | for (wasm.objects.items, 0..) |_, object_index| { |
| 2709 | | try wasm.resolveSymbolsInObject(@as(u16, @intCast(object_index))); |
| 2711 | for (wasm.objects.items) |object_index| { |
| 2712 | try wasm.resolveSymbolsInObject(object_index); |
| 2710 | 2713 | } |
| 2711 | 2714 | |
| 2712 | 2715 | var emit_features_count: u32 = 0; |
| ... | ... | @@ -2788,8 +2791,8 @@ pub fn flushModule(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) |
| 2788 | 2791 | |
| 2789 | 2792 | try wasm.parseInputFiles(positionals.items); |
| 2790 | 2793 | |
| 2791 | | for (wasm.objects.items, 0..) |_, object_index| { |
| 2792 | | try wasm.resolveSymbolsInObject(@as(u16, @intCast(object_index))); |
| 2794 | for (wasm.objects.items) |object_index| { |
| 2795 | try wasm.resolveSymbolsInObject(object_index); |
| 2793 | 2796 | } |
| 2794 | 2797 | |
| 2795 | 2798 | var emit_features_count: u32 = 0; |