| ... | @@ -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. |
| 179 | symbol_atom: std.AutoHashMapUnmanaged(SymbolLoc, Atom.Index) = .{}, | 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 | /// 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; |
| 2134 | | 2129 | |
| 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 | } |
| 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 | pub fn flush(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void { | 2435 | pub 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; | | |
| 2483 | | 2438 | |
| 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 | } |
| 2492 | | 2444 | |
| 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. |
| 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 | const tracy = trace(@src()); | 2447 | const tracy = trace(@src()); |
| 2496 | defer tracy.end(); | 2448 | defer tracy.end(); |
| 2497 | | 2449 | |
| 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(); |
| 2501 | | 2460 | |
| 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; |
| 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 | // 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); |
| 2602 | | 2474 | |
| 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; |
| 2609 | | 2481 | |
| | 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-LIBC | 2486 | // 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 or | 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,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 | } |
| 2640 | | 2516 | |
| 2641 | for (objects) |object| { | 2517 | for (comp.objects) |object| { |
| 2642 | try positionals.append(object.path); | 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,93 +2527,6 @@ fn linkWithZld(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) lin |
| 2651 | | 2527 | |
| 2652 | try wasm.parseInputFiles(positionals.items); | 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 | 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(); |
| 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 | 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); |
| 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 | 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))); |