Commit 4f8a6b0888
Changed files (3)
src
src/link/Wasm/Flush.zig
@@ -60,6 +60,11 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
const import_memory = comp.config.import_memory;
const export_memory = comp.config.export_memory;
const target = &comp.root_mod.resolved_target.result;
+ const is64 = switch (target.cpu.arch) {
+ .wasm32 => false,
+ .wasm64 => true,
+ else => unreachable,
+ };
const is_obj = comp.config.output_mode == .Obj;
const allow_undefined = is_obj or wasm.import_symbols;
const zcu = wasm.base.comp.zcu.?;
@@ -650,6 +655,27 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
section_index += 1;
}
+ if (!is_obj) {
+ for (wasm.uav_fixups.items) |uav_fixup| {
+ const ds_id: Wasm.DataSegment.Id = .pack(wasm, .{ .uav_exe = uav_fixup.uavs_exe_index });
+ const vaddr = f.data_segments.get(ds_id).?;
+ if (!is64) {
+ mem.writeInt(u32, wasm.string_bytes.items[uav_fixup.offset..][0..4], vaddr, .little);
+ } else {
+ mem.writeInt(u64, wasm.string_bytes.items[uav_fixup.offset..][0..8], vaddr, .little);
+ }
+ }
+ for (wasm.nav_fixups.items) |nav_fixup| {
+ const ds_id: Wasm.DataSegment.Id = .pack(wasm, .{ .nav_exe = nav_fixup.navs_exe_index });
+ const vaddr = f.data_segments.get(ds_id).?;
+ if (!is64) {
+ mem.writeInt(u32, wasm.string_bytes.items[nav_fixup.offset..][0..4], vaddr, .little);
+ } else {
+ mem.writeInt(u64, wasm.string_bytes.items[nav_fixup.offset..][0..8], vaddr, .little);
+ }
+ }
+ }
+
// Data section.
if (f.data_segment_groups.items.len != 0) {
const header_offset = try reserveVecSectionHeader(gpa, binary_bytes);
src/link/Wasm.zig
@@ -259,13 +259,13 @@ params_scratch: std.ArrayListUnmanaged(std.wasm.Valtype) = .empty,
returns_scratch: std.ArrayListUnmanaged(std.wasm.Valtype) = .empty,
pub const UavFixup = extern struct {
- ip_index: InternPool.Index,
+ uavs_exe_index: UavsExeIndex,
/// Index into `string_bytes`.
offset: u32,
};
pub const NavFixup = extern struct {
- nav_index: InternPool.Nav.Index,
+ navs_exe_index: NavsExeIndex,
/// Index into `string_bytes`.
offset: u32,
};
@@ -2379,7 +2379,7 @@ pub fn updateNav(wasm: *Wasm, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index
const gop = try wasm.navs_exe.getOrPut(gpa, nav_index);
gop.value_ptr.* = .{
.code = zcu_data.code,
- .count = 0,
+ .count = if (gop.found_existing) gop.value_ptr.count else 0,
};
wasm.data_segments.putAssumeCapacity(.pack(wasm, .{ .nav_exe = @enumFromInt(gop.index) }), {});
}
@@ -3376,6 +3376,24 @@ pub fn refUavExe(wasm: *Wasm, pt: Zcu.PerThread, ip_index: InternPool.Index) !Ua
return uav_index;
}
+pub fn refNavExe(wasm: *Wasm, nav_index: InternPool.Nav.Index) !NavsExeIndex {
+ const comp = wasm.base.comp;
+ const gpa = comp.gpa;
+ assert(comp.config.output_mode != .Obj);
+ const gop = try wasm.navs_exe.getOrPut(gpa, nav_index);
+ if (gop.found_existing) {
+ gop.value_ptr.count += 1;
+ } else {
+ gop.value_ptr.* = .{
+ .code = undefined,
+ .count = 1,
+ };
+ }
+ const navs_exe_index: NavsExeIndex = @enumFromInt(gop.index);
+ try wasm.data_segments.put(gpa, .pack(wasm, .{ .nav_exe = navs_exe_index }), {});
+ return navs_exe_index;
+}
+
/// Asserts it is called after `Flush.data_segments` is fully populated and sorted.
pub fn uavAddr(wasm: *Wasm, uav_index: UavsExeIndex) u32 {
assert(wasm.flush_buffer.memory_layout_finished);
src/codegen.zig
@@ -674,8 +674,9 @@ fn lowerUavRef(
.addend = @intCast(offset),
});
} else {
- try wasm.uav_fixups.append(gpa, .{
- .ip_index = uav.val,
+ try wasm.uav_fixups.ensureUnusedCapacity(gpa, 1);
+ wasm.uav_fixups.appendAssumeCapacity(.{
+ .uavs_exe_index = try wasm.refUavExe(pt, uav.val),
.offset = @intCast(code.items.len),
});
}
@@ -745,8 +746,9 @@ fn lowerNavRef(
.addend = @intCast(offset),
});
} else {
- try wasm.nav_fixups.append(gpa, .{
- .nav_index = nav_index,
+ try wasm.nav_fixups.ensureUnusedCapacity(gpa, 1);
+ wasm.nav_fixups.appendAssumeCapacity(.{
+ .navs_exe_index = try wasm.refNavExe(nav_index),
.offset = @intCast(code.items.len),
});
}