mirror of
https://github.com/ziglang/zig.git
synced 2025-12-25 07:33:08 +00:00
wasm linker: implement data fixups
one hash table lookup per fixup
This commit is contained in:
parent
5fac6f380e
commit
4f8a6b0888
@ -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),
|
||||
});
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user