authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2024-02-07 06:57:32+01:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2024-02-29 15:24:04+01:00
logc99ef23862573269ae4052bd2236f9803f9e36a2
treeb654129c194e960bf29fad6a4acaab757a0ef94b
parent5aec88fa4102e87295bf60971209d114c6ae6733
signaturelock-open Commit is signed but in an unrecognized format.

wasm: consolidate flushModule and linkWithZld

We now use a single function to use the in-house WebAssembly linker rather than wasm-ld. For both incremental compilation and traditional linking we use the same codepath.

2 files changed, 32 insertions(+), 307 deletions(-)

src/link/Wasm.zig+26-299
...@@ -177,10 +177,6 @@ undefs: std.AutoArrayHashMapUnmanaged(u32, SymbolLoc) = .{},...@@ -177,10 +177,6 @@ undefs: std.AutoArrayHashMapUnmanaged(u32, SymbolLoc) = .{},
177/// data of a symbol, such as its size, or its offset to perform a relocation.177/// data of a symbol, such as its size, or its offset to perform a relocation.
178/// Undefined (and synthetic) symbols do not have an Atom and therefore cannot be mapped.178/// Undefined (and synthetic) symbols do not have an Atom and therefore cannot be mapped.
179symbol_atom: std.AutoHashMapUnmanaged(SymbolLoc, Atom.Index) = .{},179symbol_atom: std.AutoHashMapUnmanaged(SymbolLoc, Atom.Index) = .{},
180/// Maps a symbol's location to its export name, which may differ from the decl's name
181/// which does the exporting.
182/// Note: The value represents the offset into the string table, rather than the actual string.
183export_names: std.AutoHashMapUnmanaged(SymbolLoc, u32) = .{},
184180
185/// List of atom indexes of functions that are generated by the backend,181/// List of atom indexes of functions that are generated by the backend,
186/// rather than by the linker.182/// rather than by the linker.
...@@ -1398,7 +1394,6 @@ pub fn deinit(wasm: *Wasm) void {...@@ -1398,7 +1394,6 @@ pub fn deinit(wasm: *Wasm) void {
1398 wasm.undefs.deinit(gpa);1394 wasm.undefs.deinit(gpa);
1399 wasm.discarded.deinit(gpa);1395 wasm.discarded.deinit(gpa);
1400 wasm.symbol_atom.deinit(gpa);1396 wasm.symbol_atom.deinit(gpa);
1401 wasm.export_names.deinit(gpa);
1402 wasm.atoms.deinit(gpa);1397 wasm.atoms.deinit(gpa);
1403 wasm.managed_atoms.deinit(gpa);1398 wasm.managed_atoms.deinit(gpa);
1404 wasm.segments.deinit(gpa);1399 wasm.segments.deinit(gpa);
...@@ -2133,10 +2128,10 @@ fn setupExports(wasm: *Wasm) !void {...@@ -2133,10 +2128,10 @@ fn setupExports(wasm: *Wasm) !void {
2133 if (!symbol.isExported(comp.config.rdynamic)) continue;2128 if (!symbol.isExported(comp.config.rdynamic)) continue;
21342129
2135 const sym_name = sym_loc.getName(wasm);2130 const sym_name = sym_loc.getName(wasm);
2136 const export_name = if (wasm.export_names.get(sym_loc)) |name| name else blk: {2131 const export_name = if (sym_loc.file == .null)
2137 if (sym_loc.file == .null) break :blk symbol.name;2132 symbol.name
2138 break :blk try wasm.string_table.put(gpa, sym_name);2133 else
2139 };2134 try wasm.string_table.put(gpa, sym_name);
2140 const exp: types.Export = if (symbol.tag == .data) exp: {2135 const exp: types.Export = if (symbol.tag == .data) exp: {
2141 const global_index = @as(u32, @intCast(wasm.imported_globals_count + wasm.wasm_globals.items.len));2136 const global_index = @as(u32, @intCast(wasm.imported_globals_count + wasm.wasm_globals.items.len));
2142 try wasm.wasm_globals.append(gpa, .{2137 try wasm.wasm_globals.append(gpa, .{
...@@ -2437,168 +2432,45 @@ fn appendDummySegment(wasm: *Wasm) !void {...@@ -2437,168 +2432,45 @@ fn appendDummySegment(wasm: *Wasm) !void {
2437 });2432 });
2438}2433}
24392434
2440fn resetState(wasm: *Wasm) void {
2441 const gpa = wasm.base.comp.gpa;
2442
2443 for (wasm.segment_info.values()) |segment_info| {
2444 gpa.free(segment_info.name);
2445 }
2446
2447 // TODO: Revisit
2448 // var atom_it = wasm.decls.valueIterator();
2449 // while (atom_it.next()) |atom_index| {
2450 // const atom = wasm.getAtomPtr(atom_index.*);
2451 // atom.next = null;
2452 // atom.prev = null;
2453
2454 // for (atom.locals.items) |local_atom_index| {
2455 // const local_atom = wasm.getAtomPtr(local_atom_index);
2456 // local_atom.next = null;
2457 // local_atom.prev = null;
2458 // }
2459 // }
2460
2461 wasm.functions.clearRetainingCapacity();
2462 wasm.exports.clearRetainingCapacity();
2463 wasm.segments.clearRetainingCapacity();
2464 wasm.segment_info.clearRetainingCapacity();
2465 wasm.data_segments.clearRetainingCapacity();
2466 wasm.atoms.clearRetainingCapacity();
2467 wasm.symbol_atom.clearRetainingCapacity();
2468 wasm.code_section_index = null;
2469 wasm.debug_info_index = null;
2470 wasm.debug_line_index = null;
2471 wasm.debug_loc_index = null;
2472 wasm.debug_str_index = null;
2473 wasm.debug_ranges_index = null;
2474 wasm.debug_abbrev_index = null;
2475 wasm.debug_pubnames_index = null;
2476 wasm.debug_pubtypes_index = null;
2477}
2478
2479pub fn flush(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {2435pub fn flush(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
2480 const comp = wasm.base.comp;2436 const comp = wasm.base.comp;
2481 const use_lld = build_options.have_llvm and comp.config.use_lld;2437 const use_lld = build_options.have_llvm and comp.config.use_lld;
2482 const use_llvm = comp.config.use_llvm;
24832438
2484 if (use_lld) {2439 if (use_lld) {
2485 return wasm.linkWithLLD(arena, prog_node);2440 return wasm.linkWithLLD(arena, prog_node);
2486 } else if (use_llvm) {
2487 return wasm.linkWithZld(arena, prog_node);
2488 } else {
2489 return wasm.flushModule(arena, prog_node);
2490 }2441 }
2442 return wasm.flushModule(arena, prog_node);
2491}2443}
24922444
2493/// Uses the in-house linker to link one or multiple object -and archive files into a WebAssembly binary.2445/// Uses the in-house linker to link one or multiple object -and archive files into a WebAssembly binary.
2494fn linkWithZld(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {2446pub fn flushModule(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
2495 const tracy = trace(@src());2447 const tracy = trace(@src());
2496 defer tracy.end();2448 defer tracy.end();
24972449
2498 const comp = wasm.base.comp;2450 const comp = wasm.base.comp;
2499 const shared_memory = comp.config.shared_memory;2451 if (wasm.llvm_object) |llvm_object| {
2500 const import_memory = comp.config.import_memory;2452 try wasm.base.emitLlvmObject(arena, llvm_object, prog_node);
2453 const use_lld = build_options.have_llvm and comp.config.use_lld;
2454 if (use_lld) return;
2455 }
2456
2457 var sub_prog_node = prog_node.start("Wasm Flush", 0);
2458 sub_prog_node.activate();
2459 defer sub_prog_node.end();
25012460
2502 const directory = wasm.base.emit.directory; // Just an alias to make it shorter to type.2461 const directory = wasm.base.emit.directory; // Just an alias to make it shorter to type.
2503 const full_out_path = try directory.join(arena, &[_][]const u8{wasm.base.emit.sub_path});2462 const full_out_path = try directory.join(arena, &[_][]const u8{wasm.base.emit.sub_path});
2504 const opt_zcu = comp.module;2463 const module_obj_path: ?[]const u8 = if (wasm.base.zcu_object_sub_path) |path| blk: {
2505 const use_llvm = comp.config.use_llvm;
2506
2507 // If there is no Zig code to compile, then we should skip flushing the output file because it
2508 // will not be part of the linker line anyway.
2509 const module_obj_path: ?[]const u8 = if (opt_zcu != null) blk: {
2510 assert(use_llvm); // `linkWithZld` should never be called when the Wasm backend is used
2511 try wasm.flushModule(arena, prog_node);
2512
2513 if (fs.path.dirname(full_out_path)) |dirname| {2464 if (fs.path.dirname(full_out_path)) |dirname| {
2514 break :blk try fs.path.join(arena, &.{ dirname, wasm.base.zcu_object_sub_path.? });2465 break :blk try fs.path.join(arena, &.{ dirname, path });
2515 } else {2466 } else {
2516 break :blk wasm.base.zcu_object_sub_path.?;2467 break :blk path;
2517 }2468 }
2518 } else null;2469 } else null;
25192470
2520 var sub_prog_node = prog_node.start("Wasm Flush", 0);
2521 sub_prog_node.activate();
2522 defer sub_prog_node.end();
2523
2524 const compiler_rt_path: ?[]const u8 = blk: {
2525 if (comp.compiler_rt_obj) |obj| break :blk obj.full_object_path;
2526 if (comp.compiler_rt_lib) |lib| break :blk lib.full_object_path;
2527 break :blk null;
2528 };
2529
2530 const id_symlink_basename = "zld.id";
2531
2532 var man: Cache.Manifest = undefined;
2533 defer if (!wasm.base.disable_lld_caching) man.deinit();
2534 var digest: [Cache.hex_digest_len]u8 = undefined;
2535
2536 const objects = comp.objects;
2537
2538 // NOTE: The following section must be maintained to be equal
2539 // as the section defined in `linkWithLLD`
2540 if (!wasm.base.disable_lld_caching) {
2541 man = comp.cache_parent.obtain();
2542
2543 // We are about to obtain this lock, so here we give other processes a chance first.
2544 wasm.base.releaseLock();
2545
2546 comptime assert(Compilation.link_hash_implementation_version == 12);
2547
2548 for (objects) |obj| {
2549 _ = try man.addFile(obj.path, null);
2550 man.hash.add(obj.must_link);
2551 }
2552 for (comp.c_object_table.keys()) |key| {
2553 _ = try man.addFile(key.status.success.object_path, null);
2554 }
2555 try man.addOptionalFile(module_obj_path);
2556 try man.addOptionalFile(compiler_rt_path);
2557 man.hash.addOptionalBytes(wasm.entry_name);
2558 man.hash.add(wasm.base.stack_size);
2559 man.hash.add(wasm.base.build_id);
2560 man.hash.add(import_memory);
2561 man.hash.add(shared_memory);
2562 man.hash.add(wasm.import_table);
2563 man.hash.add(wasm.export_table);
2564 man.hash.addOptional(wasm.initial_memory);
2565 man.hash.addOptional(wasm.max_memory);
2566 man.hash.addOptional(wasm.global_base);
2567 man.hash.addListOfBytes(wasm.export_symbol_names);
2568 // strip does not need to go into the linker hash because it is part of the hash namespace
2569
2570 // We don't actually care whether it's a cache hit or miss; we just need the digest and the lock.
2571 _ = try man.hit();
2572 digest = man.final();
2573
2574 var prev_digest_buf: [digest.len]u8 = undefined;
2575 const prev_digest: []u8 = Cache.readSmallFile(
2576 directory.handle,
2577 id_symlink_basename,
2578 &prev_digest_buf,
2579 ) catch |err| blk: {
2580 log.debug("WASM LLD new_digest={s} error: {s}", .{ std.fmt.fmtSliceHexLower(&digest), @errorName(err) });
2581 // Handle this as a cache miss.
2582 break :blk prev_digest_buf[0..0];
2583 };
2584 if (mem.eql(u8, prev_digest, &digest)) {
2585 log.debug("WASM LLD digest={s} match - skipping invocation", .{std.fmt.fmtSliceHexLower(&digest)});
2586 // Hot diggity dog! The output binary is already there.
2587 wasm.base.lock = man.toOwnedLock();
2588 return;
2589 }
2590 log.debug("WASM LLD prev_digest={s} new_digest={s}", .{ std.fmt.fmtSliceHexLower(prev_digest), std.fmt.fmtSliceHexLower(&digest) });
2591
2592 // We are about to change the output file to be different, so we invalidate the build hash now.
2593 directory.handle.deleteFile(id_symlink_basename) catch |err| switch (err) {
2594 error.FileNotFound => {},
2595 else => |e| return e,
2596 };
2597 }
2598
2599 // Positional arguments to the linker such as object files and static archives.2471 // Positional arguments to the linker such as object files and static archives.
2600 var positionals = std.ArrayList([]const u8).init(arena);2472 var positionals = std.ArrayList([]const u8).init(arena);
2601 try positionals.ensureUnusedCapacity(objects.len);2473 try positionals.ensureUnusedCapacity(comp.objects.len);
26022474
2603 const target = comp.root_mod.resolved_target.result;2475 const target = comp.root_mod.resolved_target.result;
2604 const output_mode = comp.config.output_mode;2476 const output_mode = comp.config.output_mode;
...@@ -2607,6 +2479,10 @@ fn linkWithZld(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) lin...@@ -2607,6 +2479,10 @@ fn linkWithZld(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) lin
2607 const link_libcpp = comp.config.link_libcpp;2479 const link_libcpp = comp.config.link_libcpp;
2608 const wasi_exec_model = comp.config.wasi_exec_model;2480 const wasi_exec_model = comp.config.wasi_exec_model;
26092481
2482 if (wasm.zigObjectPtr()) |zig_object| {
2483 try zig_object.flushModule(wasm);
2484 }
2485
2610 // When the target os is WASI, we allow linking with WASI-LIBC2486 // When the target os is WASI, we allow linking with WASI-LIBC
2611 if (target.os.tag == .wasi) {2487 if (target.os.tag == .wasi) {
2612 const is_exe_or_dyn_lib = output_mode == .Exe or2488 const is_exe_or_dyn_lib = output_mode == .Exe or
...@@ -2638,7 +2514,7 @@ fn linkWithZld(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) lin...@@ -2638,7 +2514,7 @@ fn linkWithZld(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) lin
2638 try positionals.append(path);2514 try positionals.append(path);
2639 }2515 }
26402516
2641 for (objects) |object| {2517 for (comp.objects) |object| {
2642 try positionals.append(object.path);2518 try positionals.append(object.path);
2643 }2519 }
26442520
...@@ -2651,93 +2527,6 @@ fn linkWithZld(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) lin...@@ -2651,93 +2527,6 @@ fn linkWithZld(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) lin
26512527
2652 try wasm.parseInputFiles(positionals.items);2528 try wasm.parseInputFiles(positionals.items);
26532529
2654 for (wasm.objects.items) |object_index| {
2655 try wasm.resolveSymbolsInObject(object_index);
2656 }
2657
2658 var emit_features_count: u32 = 0;
2659 var enabled_features: [@typeInfo(types.Feature.Tag).Enum.fields.len]bool = undefined;
2660 try wasm.validateFeatures(&enabled_features, &emit_features_count);
2661 try wasm.resolveSymbolsInArchives();
2662 try wasm.resolveLazySymbols();
2663 try wasm.checkUndefinedSymbols();
2664
2665 try wasm.setupInitFunctions();
2666 try wasm.setupStart();
2667
2668 try wasm.markReferences();
2669 try wasm.setupImports();
2670 try wasm.mergeSections();
2671 try wasm.mergeTypes();
2672 try wasm.allocateAtoms();
2673 try wasm.setupMemory();
2674 wasm.allocateVirtualAddresses();
2675 wasm.mapFunctionTable();
2676 try wasm.initializeCallCtorsFunction();
2677 try wasm.setupInitMemoryFunction();
2678 try wasm.setupTLSRelocationsFunction();
2679 try wasm.initializeTLSFunction();
2680 try wasm.setupStartSection();
2681 try wasm.setupExports();
2682 try wasm.writeToFile(enabled_features, emit_features_count, arena);
2683
2684 if (!wasm.base.disable_lld_caching) {
2685 // Update the file with the digest. If it fails we can continue; it only
2686 // means that the next invocation will have an unnecessary cache miss.
2687 Cache.writeSmallFile(directory.handle, id_symlink_basename, &digest) catch |err| {
2688 log.warn("failed to save linking hash digest symlink: {s}", .{@errorName(err)});
2689 };
2690 // Again failure here only means an unnecessary cache miss.
2691 man.writeManifest() catch |err| {
2692 log.warn("failed to write cache manifest when linking: {s}", .{@errorName(err)});
2693 };
2694 // We hang on to this lock so that the output file path can be used without
2695 // other processes clobbering it.
2696 wasm.base.lock = man.toOwnedLock();
2697 }
2698}
2699
2700pub fn flushModule(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
2701 const tracy = trace(@src());
2702 defer tracy.end();
2703
2704 const comp = wasm.base.comp;
2705
2706 if (wasm.llvm_object) |llvm_object| {
2707 try wasm.base.emitLlvmObject(arena, llvm_object, prog_node);
2708 return;
2709 }
2710
2711 var sub_prog_node = prog_node.start("Wasm Flush", 0);
2712 sub_prog_node.activate();
2713 defer sub_prog_node.end();
2714
2715 if (wasm.zigObjectPtr()) |zig_object| {
2716 try zig_object.flushModule(wasm);
2717 }
2718
2719 // ensure the error names table is populated when an error name is referenced
2720 // try wasm.populateErrorNameTable();
2721
2722 const objects = comp.objects;
2723
2724 // Positional arguments to the linker such as object files and static archives.
2725 var positionals = std.ArrayList([]const u8).init(arena);
2726 try positionals.ensureUnusedCapacity(objects.len);
2727
2728 for (objects) |object| {
2729 positionals.appendAssumeCapacity(object.path);
2730 }
2731
2732 for (comp.c_object_table.keys()) |c_object| {
2733 try positionals.append(c_object.status.success.object_path);
2734 }
2735
2736 if (comp.compiler_rt_lib) |lib| try positionals.append(lib.full_object_path);
2737 if (comp.compiler_rt_obj) |obj| try positionals.append(obj.full_object_path);
2738
2739 try wasm.parseInputFiles(positionals.items);
2740
2741 if (wasm.zig_object_index != .null) {2530 if (wasm.zig_object_index != .null) {
2742 try wasm.resolveSymbolsInObject(wasm.zig_object_index);2531 try wasm.resolveSymbolsInObject(wasm.zig_object_index);
2743 }2532 }
...@@ -2752,73 +2541,11 @@ pub fn flushModule(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node)...@@ -2752,73 +2541,11 @@ pub fn flushModule(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node)
2752 try wasm.resolveLazySymbols();2541 try wasm.resolveLazySymbols();
2753 try wasm.checkUndefinedSymbols();2542 try wasm.checkUndefinedSymbols();
27542543
2755 // When we finish/error we reset the state of the linker
2756 // So we can rebuild the binary file on each incremental update
2757 defer wasm.resetState();
2758 try wasm.setupInitFunctions();2544 try wasm.setupInitFunctions();
2759 try wasm.setupStart();2545 try wasm.setupStart();
2546
2760 try wasm.markReferences();2547 try wasm.markReferences();
2761 // try wasm.setupErrorsLen();
2762 try wasm.setupImports();2548 try wasm.setupImports();
2763 // if (comp.module) |mod| {
2764 // var decl_it = wasm.decls.iterator();
2765 // while (decl_it.next()) |entry| {
2766 // const decl = mod.declPtr(entry.key_ptr.*);
2767 // if (decl.isExtern(mod)) continue;
2768 // const atom_index = entry.value_ptr.*;
2769 // const atom = wasm.getAtomPtr(atom_index);
2770 // if (decl.ty.zigTypeTag(mod) == .Fn) {
2771 // try wasm.parseAtom(atom_index, .function);
2772 // } else if (decl.getOwnedVariable(mod)) |variable| {
2773 // if (variable.is_const) {
2774 // try wasm.parseAtom(atom_index, .{ .data = .read_only });
2775 // } else if (Value.fromInterned(variable.init).isUndefDeep(mod)) {
2776 // // for safe build modes, we store the atom in the data segment,
2777 // // whereas for unsafe build modes we store it in bss.
2778 // const decl_namespace = mod.namespacePtr(decl.src_namespace);
2779 // const optimize_mode = decl_namespace.file_scope.mod.optimize_mode;
2780 // const is_initialized = switch (optimize_mode) {
2781 // .Debug, .ReleaseSafe => true,
2782 // .ReleaseFast, .ReleaseSmall => false,
2783 // };
2784 // try wasm.parseAtom(atom_index, .{ .data = if (is_initialized) .initialized else .uninitialized });
2785 // } else {
2786 // // when the decl is all zeroes, we store the atom in the bss segment,
2787 // // in all other cases it will be in the data segment.
2788 // const is_zeroes = for (atom.code.items) |byte| {
2789 // if (byte != 0) break false;
2790 // } else true;
2791 // try wasm.parseAtom(atom_index, .{ .data = if (is_zeroes) .uninitialized else .initialized });
2792 // }
2793 // } else {
2794 // try wasm.parseAtom(atom_index, .{ .data = .read_only });
2795 // }
2796
2797 // // also parse atoms for a decl's locals
2798 // for (atom.locals.items) |local_atom_index| {
2799 // try wasm.parseAtom(local_atom_index, .{ .data = .read_only });
2800 // }
2801 // }
2802 // // parse anonymous declarations
2803 // for (wasm.anon_decls.keys(), wasm.anon_decls.values()) |decl_val, atom_index| {
2804 // const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val));
2805 // if (ty.zigTypeTag(mod) == .Fn) {
2806 // try wasm.parseAtom(atom_index, .function);
2807 // } else {
2808 // try wasm.parseAtom(atom_index, .{ .data = .read_only });
2809 // }
2810 // }
2811
2812 // // also parse any backend-generated functions
2813 // for (wasm.synthetic_functions.items) |atom_index| {
2814 // try wasm.parseAtom(atom_index, .function);
2815 // }
2816
2817 // if (wasm.dwarf) |*dwarf| {
2818 // try dwarf.flushModule(comp.module.?);
2819 // }
2820 // }
2821
2822 try wasm.mergeSections();2549 try wasm.mergeSections();
2823 try wasm.mergeTypes();2550 try wasm.mergeTypes();
2824 try wasm.allocateAtoms();2551 try wasm.allocateAtoms();
...@@ -4032,7 +3759,7 @@ fn emitSymbolTable(wasm: *Wasm, binary_bytes: *std.ArrayList(u8), symbol_table:...@@ -4032,7 +3759,7 @@ fn emitSymbolTable(wasm: *Wasm, binary_bytes: *std.ArrayList(u8), symbol_table:
4032 try leb.writeULEB128(writer, @intFromEnum(symbol.tag));3759 try leb.writeULEB128(writer, @intFromEnum(symbol.tag));
4033 try leb.writeULEB128(writer, symbol.flags);3760 try leb.writeULEB128(writer, symbol.flags);
40343761
4035 const sym_name = if (wasm.export_names.get(sym_loc)) |exp_name| wasm.string_table.get(exp_name) else sym_loc.getName(wasm);3762 const sym_name = sym_loc.getName(wasm);
4036 switch (symbol.tag) {3763 switch (symbol.tag) {
4037 .data => {3764 .data => {
4038 try leb.writeULEB128(writer, @as(u32, @intCast(sym_name.len)));3765 try leb.writeULEB128(writer, @as(u32, @intCast(sym_name.len)));
src/link/Wasm/ZigObject.zig+6-8
...@@ -670,17 +670,15 @@ pub fn addOrUpdateImport(...@@ -670,17 +670,15 @@ pub fn addOrUpdateImport(
670670
671 if (type_index) |ty_index| {671 if (type_index) |ty_index| {
672 const gop = try zig_object.imports.getOrPut(gpa, symbol_index);672 const gop = try zig_object.imports.getOrPut(gpa, symbol_index);
673 const module_name = if (lib_name) |l_name| blk: {673 const module_name = if (lib_name) |l_name| l_name else wasm_file.host_name;
674 break :blk l_name;
675 } else wasm_file.host_name;
676 if (!gop.found_existing) {674 if (!gop.found_existing) {
677 gop.value_ptr.* = .{
678 .module_name = try zig_object.string_table.insert(gpa, module_name),
679 .name = try zig_object.string_table.insert(gpa, name),
680 .kind = .{ .function = ty_index },
681 };
682 zig_object.imported_functions_count += 1;675 zig_object.imported_functions_count += 1;
683 }676 }
677 gop.value_ptr.* = .{
678 .module_name = try zig_object.string_table.insert(gpa, module_name),
679 .name = try zig_object.string_table.insert(gpa, name),
680 .kind = .{ .function = ty_index },
681 };
684 sym.tag = .function;682 sym.tag = .function;
685 } else {683 } else {
686 sym.tag = .data;684 sym.tag = .data;