| ... | ... | @@ -177,10 +177,6 @@ undefs: std.AutoArrayHashMapUnmanaged(u32, SymbolLoc) = .{}, |
| 177 | 177 | /// data of a symbol, such as its size, or its offset to perform a relocation. |
| 178 | 178 | /// Undefined (and synthetic) symbols do not have an Atom and therefore cannot be mapped. |
| 179 | 179 | symbol_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. |
| 183 | | export_names: std.AutoHashMapUnmanaged(SymbolLoc, u32) = .{}, |
| 184 | 180 | |
| 185 | 181 | /// List of atom indexes of functions that are generated by the backend, |
| 186 | 182 | /// rather than by the linker. |
| ... | ... | @@ -1398,7 +1394,6 @@ pub fn deinit(wasm: *Wasm) void { |
| 1398 | 1394 | wasm.undefs.deinit(gpa); |
| 1399 | 1395 | wasm.discarded.deinit(gpa); |
| 1400 | 1396 | wasm.symbol_atom.deinit(gpa); |
| 1401 | | wasm.export_names.deinit(gpa); |
| 1402 | 1397 | wasm.atoms.deinit(gpa); |
| 1403 | 1398 | wasm.managed_atoms.deinit(gpa); |
| 1404 | 1399 | wasm.segments.deinit(gpa); |
| ... | ... | @@ -2133,10 +2128,10 @@ fn setupExports(wasm: *Wasm) !void { |
| 2133 | 2128 | if (!symbol.isExported(comp.config.rdynamic)) continue; |
| 2134 | 2129 | |
| 2135 | 2130 | const sym_name = sym_loc.getName(wasm); |
| 2136 | | const export_name = if (wasm.export_names.get(sym_loc)) |name| name else blk: { |
| 2137 | | if (sym_loc.file == .null) break :blk symbol.name; |
| 2138 | | break :blk try wasm.string_table.put(gpa, sym_name); |
| 2139 | | }; |
| 2131 | const export_name = if (sym_loc.file == .null) |
| 2132 | symbol.name |
| 2133 | else |
| 2134 | try wasm.string_table.put(gpa, sym_name); |
| 2140 | 2135 | const exp: types.Export = if (symbol.tag == .data) exp: { |
| 2141 | 2136 | const global_index = @as(u32, @intCast(wasm.imported_globals_count + wasm.wasm_globals.items.len)); |
| 2142 | 2137 | try wasm.wasm_globals.append(gpa, .{ |
| ... | ... | @@ -2437,168 +2432,45 @@ fn appendDummySegment(wasm: *Wasm) !void { |
| 2437 | 2432 | }); |
| 2438 | 2433 | } |
| 2439 | 2434 | |
| 2440 | | fn 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 | | |
| 2479 | 2435 | pub fn flush(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void { |
| 2480 | 2436 | const comp = wasm.base.comp; |
| 2481 | 2437 | const use_lld = build_options.have_llvm and comp.config.use_lld; |
| 2482 | | const use_llvm = comp.config.use_llvm; |
| 2483 | 2438 | |
| 2484 | 2439 | if (use_lld) { |
| 2485 | 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 | } |
| 2492 | 2444 | |
| 2493 | 2445 | /// Uses the in-house linker to link one or multiple object -and archive files into a WebAssembly binary. |
| 2494 | | fn linkWithZld(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void { |
| 2446 | pub fn flushModule(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void { |
| 2495 | 2447 | const tracy = trace(@src()); |
| 2496 | 2448 | defer tracy.end(); |
| 2497 | 2449 | |
| 2498 | 2450 | const comp = wasm.base.comp; |
| 2499 | | const shared_memory = comp.config.shared_memory; |
| 2500 | | const import_memory = comp.config.import_memory; |
| 2451 | if (wasm.llvm_object) |llvm_object| { |
| 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(); |
| 2501 | 2460 | |
| 2502 | 2461 | const directory = wasm.base.emit.directory; // Just an alias to make it shorter to type. |
| 2503 | 2462 | const full_out_path = try directory.join(arena, &[_][]const u8{wasm.base.emit.sub_path}); |
| 2504 | | const opt_zcu = comp.module; |
| 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 | | |
| 2463 | const module_obj_path: ?[]const u8 = if (wasm.base.zcu_object_sub_path) |path| blk: { |
| 2513 | 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 | 2466 | } else { |
| 2516 | | break :blk wasm.base.zcu_object_sub_path.?; |
| 2467 | break :blk path; |
| 2517 | 2468 | } |
| 2518 | 2469 | } else null; |
| 2519 | 2470 | |
| 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 | 2471 | // Positional arguments to the linker such as object files and static archives. |
| 2600 | 2472 | var positionals = std.ArrayList([]const u8).init(arena); |
| 2601 | | try positionals.ensureUnusedCapacity(objects.len); |
| 2473 | try positionals.ensureUnusedCapacity(comp.objects.len); |
| 2602 | 2474 | |
| 2603 | 2475 | const target = comp.root_mod.resolved_target.result; |
| 2604 | 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 | 2479 | const link_libcpp = comp.config.link_libcpp; |
| 2608 | 2480 | const wasi_exec_model = comp.config.wasi_exec_model; |
| 2609 | 2481 | |
| 2482 | if (wasm.zigObjectPtr()) |zig_object| { |
| 2483 | try zig_object.flushModule(wasm); |
| 2484 | } |
| 2485 | |
| 2610 | 2486 | // When the target os is WASI, we allow linking with WASI-LIBC |
| 2611 | 2487 | if (target.os.tag == .wasi) { |
| 2612 | 2488 | 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 | 2514 | try positionals.append(path); |
| 2639 | 2515 | } |
| 2640 | 2516 | |
| 2641 | | for (objects) |object| { |
| 2517 | for (comp.objects) |object| { |
| 2642 | 2518 | try positionals.append(object.path); |
| 2643 | 2519 | } |
| 2644 | 2520 | |
| ... | ... | @@ -2651,93 +2527,6 @@ fn linkWithZld(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) lin |
| 2651 | 2527 | |
| 2652 | 2528 | try wasm.parseInputFiles(positionals.items); |
| 2653 | 2529 | |
| 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 | | |
| 2700 | | pub 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 | 2530 | if (wasm.zig_object_index != .null) { |
| 2742 | 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 | 2541 | try wasm.resolveLazySymbols(); |
| 2753 | 2542 | try wasm.checkUndefinedSymbols(); |
| 2754 | 2543 | |
| 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 | 2544 | try wasm.setupInitFunctions(); |
| 2759 | 2545 | try wasm.setupStart(); |
| 2546 | |
| 2760 | 2547 | try wasm.markReferences(); |
| 2761 | | // try wasm.setupErrorsLen(); |
| 2762 | 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 | 2549 | try wasm.mergeSections(); |
| 2823 | 2550 | try wasm.mergeTypes(); |
| 2824 | 2551 | try wasm.allocateAtoms(); |
| ... | ... | @@ -4032,7 +3759,7 @@ fn emitSymbolTable(wasm: *Wasm, binary_bytes: *std.ArrayList(u8), symbol_table: |
| 4032 | 3759 | try leb.writeULEB128(writer, @intFromEnum(symbol.tag)); |
| 4033 | 3760 | try leb.writeULEB128(writer, symbol.flags); |
| 4034 | 3761 | |
| 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 | 3763 | switch (symbol.tag) { |
| 4037 | 3764 | .data => { |
| 4038 | 3765 | try leb.writeULEB128(writer, @as(u32, @intCast(sym_name.len))); |