authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-12-16 15:34:00-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-01-15 15:11:35-08:00
log761387dc556e065e39d021bf96fb4d4c8873a145
treeac16bdf0970469411e2b1ea73334a543adbc5cfc
parent70414c1f434dea4d749f1d1445816dffc88a7a68

wasm linker: implement type index method


2 files changed, 28 insertions(+), 14 deletions(-)

src/link/Wasm.zig+28-11
...@@ -199,7 +199,7 @@ global_exports_len: u32 = 0,...@@ -199,7 +199,7 @@ global_exports_len: u32 = 0,
199functions: std.AutoArrayHashMapUnmanaged(FunctionImport.Resolution, void) = .empty,199functions: std.AutoArrayHashMapUnmanaged(FunctionImport.Resolution, void) = .empty,
200/// Tracks the value at the end of prelink, at which point `functions`200/// Tracks the value at the end of prelink, at which point `functions`
201/// contains only object file functions, and nothing from the Zcu yet.201/// contains only object file functions, and nothing from the Zcu yet.
202functions_len: u32 = 0,202functions_end_prelink: u32 = 0,
203/// Immutable after prelink. The undefined functions coming only from all object files.203/// Immutable after prelink. The undefined functions coming only from all object files.
204/// The Zcu must satisfy these.204/// The Zcu must satisfy these.
205function_imports_init_keys: []String = &.{},205function_imports_init_keys: []String = &.{},
...@@ -214,7 +214,7 @@ function_imports: std.AutoArrayHashMapUnmanaged(String, FunctionImportId) = .emp...@@ -214,7 +214,7 @@ function_imports: std.AutoArrayHashMapUnmanaged(String, FunctionImportId) = .emp
214globals: std.AutoArrayHashMapUnmanaged(GlobalImport.Resolution, void) = .empty,214globals: std.AutoArrayHashMapUnmanaged(GlobalImport.Resolution, void) = .empty,
215/// Tracks the value at the end of prelink, at which point `globals`215/// Tracks the value at the end of prelink, at which point `globals`
216/// contains only object file globals, and nothing from the Zcu yet.216/// contains only object file globals, and nothing from the Zcu yet.
217globals_len: u32 = 0,217globals_end_prelink: u32 = 0,
218global_imports_init_keys: []String = &.{},218global_imports_init_keys: []String = &.{},
219global_imports_init_vals: []GlobalImportId = &.{},219global_imports_init_vals: []GlobalImportId = &.{},
220global_imports: std.AutoArrayHashMapUnmanaged(String, GlobalImportId) = .empty,220global_imports: std.AutoArrayHashMapUnmanaged(String, GlobalImportId) = .empty,
...@@ -620,6 +620,17 @@ pub const ZcuFunc = extern struct {...@@ -620,6 +620,17 @@ pub const ZcuFunc = extern struct {
620 const nav = ip.getNav(func.owner_nav);620 const nav = ip.getNav(func.owner_nav);
621 return nav.fqn.toSlice(ip);621 return nav.fqn.toSlice(ip);
622 }622 }
623
624 pub fn typeIndex(i: @This(), wasm: *Wasm) ?FunctionType.Index {
625 const comp = wasm.base.comp;
626 const zcu = comp.zcu.?;
627 const target = &comp.root_mod.resolved_target.result;
628 const ip = &zcu.intern_pool;
629 const func = ip.toFunc(i.key(wasm).*);
630 const fn_ty = zcu.navValue(func.owner_nav).typeOf(zcu);
631 const fn_info = zcu.typeToFunc(fn_ty).?;
632 return wasm.getExistingFunctionType(fn_info.cc, fn_info.param_types.get(ip), .fromInterned(fn_info.return_type), target);
633 }
623 };634 };
624};635};
625636
...@@ -730,7 +741,7 @@ pub const FunctionImport = extern struct {...@@ -730,7 +741,7 @@ pub const FunctionImport = extern struct {
730 };741 };
731 }742 }
732743
733 pub fn typeIndex(r: Resolution, wasm: *const Wasm) FunctionType.Index {744 pub fn typeIndex(r: Resolution, wasm: *Wasm) FunctionType.Index {
734 return switch (unpack(r, wasm)) {745 return switch (unpack(r, wasm)) {
735 .unresolved => unreachable,746 .unresolved => unreachable,
736 .__wasm_apply_global_tls_relocs => @panic("TODO"),747 .__wasm_apply_global_tls_relocs => @panic("TODO"),
...@@ -739,7 +750,7 @@ pub const FunctionImport = extern struct {...@@ -739,7 +750,7 @@ pub const FunctionImport = extern struct {
739 .__wasm_init_tls => @panic("TODO"),750 .__wasm_init_tls => @panic("TODO"),
740 .__zig_error_names => @panic("TODO"),751 .__zig_error_names => @panic("TODO"),
741 .object_function => |i| i.ptr(wasm).type_index,752 .object_function => |i| i.ptr(wasm).type_index,
742 .zcu_func => @panic("TODO"),753 .zcu_func => |i| i.typeIndex(wasm).?,
743 };754 };
744 }755 }
745756
...@@ -2247,7 +2258,7 @@ pub fn prelink(wasm: *Wasm, prog_node: std.Progress.Node) link.File.FlushError!v...@@ -2247,7 +2258,7 @@ pub fn prelink(wasm: *Wasm, prog_node: std.Progress.Node) link.File.FlushError!v
2247 try markFunction(wasm, name, import, @enumFromInt(i));2258 try markFunction(wasm, name, import, @enumFromInt(i));
2248 }2259 }
2249 }2260 }
2250 wasm.functions_len = @intCast(wasm.functions.entries.len);2261 wasm.functions_end_prelink = @intCast(wasm.functions.entries.len);
2251 wasm.function_imports_init_keys = try gpa.dupe(String, wasm.function_imports.keys());2262 wasm.function_imports_init_keys = try gpa.dupe(String, wasm.function_imports.keys());
2252 wasm.function_imports_init_vals = try gpa.dupe(FunctionImportId, wasm.function_imports.values());2263 wasm.function_imports_init_vals = try gpa.dupe(FunctionImportId, wasm.function_imports.values());
2253 wasm.function_exports_len = @intCast(wasm.function_exports.items.len);2264 wasm.function_exports_len = @intCast(wasm.function_exports.items.len);
...@@ -2257,7 +2268,7 @@ pub fn prelink(wasm: *Wasm, prog_node: std.Progress.Node) link.File.FlushError!v...@@ -2257,7 +2268,7 @@ pub fn prelink(wasm: *Wasm, prog_node: std.Progress.Node) link.File.FlushError!v
2257 try markGlobal(wasm, name, import, @enumFromInt(i));2268 try markGlobal(wasm, name, import, @enumFromInt(i));
2258 }2269 }
2259 }2270 }
2260 wasm.globals_len = @intCast(wasm.globals.entries.len);2271 wasm.globals_end_prelink = @intCast(wasm.globals.entries.len);
2261 wasm.global_imports_init_keys = try gpa.dupe(String, wasm.global_imports.keys());2272 wasm.global_imports_init_keys = try gpa.dupe(String, wasm.global_imports.keys());
2262 wasm.global_imports_init_vals = try gpa.dupe(GlobalImportId, wasm.global_imports.values());2273 wasm.global_imports_init_vals = try gpa.dupe(GlobalImportId, wasm.global_imports.values());
2263 wasm.global_exports_len = @intCast(wasm.global_exports.items.len);2274 wasm.global_exports_len = @intCast(wasm.global_exports.items.len);
...@@ -2451,7 +2462,14 @@ pub fn flushModule(...@@ -2451,7 +2462,14 @@ pub fn flushModule(
2451 const sub_prog_node = prog_node.start("Wasm Flush", 0);2462 const sub_prog_node = prog_node.start("Wasm Flush", 0);
2452 defer sub_prog_node.end();2463 defer sub_prog_node.end();
24532464
2465 const functions_end_zcu: u32 = @intCast(wasm.functions.entries.len);
2466 defer wasm.functions.shrinkRetainingCapacity(functions_end_zcu);
2467
2468 const globals_end_zcu: u32 = @intCast(wasm.globals.entries.len);
2469 defer wasm.globals.shrinkRetainingCapacity(globals_end_zcu);
2470
2454 wasm.flush_buffer.clear();2471 wasm.flush_buffer.clear();
2472
2455 return wasm.flush_buffer.finish(wasm) catch |err| switch (err) {2473 return wasm.flush_buffer.finish(wasm) catch |err| switch (err) {
2456 error.OutOfMemory => return error.OutOfMemory,2474 error.OutOfMemory => return error.OutOfMemory,
2457 error.LinkFailure => return error.LinkFailure,2475 error.LinkFailure => return error.LinkFailure,
...@@ -2932,7 +2950,7 @@ pub fn addFuncType(wasm: *Wasm, ft: FunctionType) Allocator.Error!FunctionType.I...@@ -2932,7 +2950,7 @@ pub fn addFuncType(wasm: *Wasm, ft: FunctionType) Allocator.Error!FunctionType.I
2932 return @enumFromInt(gop.index);2950 return @enumFromInt(gop.index);
2933}2951}
29342952
2935pub fn getExistingFuncType(wasm: *Wasm, ft: FunctionType) ?FunctionType.Index {2953pub fn getExistingFuncType(wasm: *const Wasm, ft: FunctionType) ?FunctionType.Index {
2936 const index = wasm.func_types.getIndex(ft) orelse return null;2954 const index = wasm.func_types.getIndex(ft) orelse return null;
2937 return @enumFromInt(index);2955 return @enumFromInt(index);
2938}2956}
...@@ -2944,7 +2962,7 @@ pub fn internFunctionType(...@@ -2944,7 +2962,7 @@ pub fn internFunctionType(
2944 return_type: ZcuType,2962 return_type: ZcuType,
2945 target: *const std.Target,2963 target: *const std.Target,
2946) Allocator.Error!FunctionType.Index {2964) Allocator.Error!FunctionType.Index {
2947 try convertZcuFnType(wasm, cc, params, return_type, target, &wasm.params_scratch, &wasm.returns_scratch);2965 try convertZcuFnType(wasm.base.comp, cc, params, return_type, target, &wasm.params_scratch, &wasm.returns_scratch);
2948 return wasm.addFuncType(.{2966 return wasm.addFuncType(.{
2949 .params = try wasm.internValtypeList(wasm.params_scratch.items),2967 .params = try wasm.internValtypeList(wasm.params_scratch.items),
2950 .returns = try wasm.internValtypeList(wasm.returns_scratch.items),2968 .returns = try wasm.internValtypeList(wasm.returns_scratch.items),
...@@ -2958,7 +2976,7 @@ pub fn getExistingFunctionType(...@@ -2958,7 +2976,7 @@ pub fn getExistingFunctionType(
2958 return_type: ZcuType,2976 return_type: ZcuType,
2959 target: *const std.Target,2977 target: *const std.Target,
2960) ?FunctionType.Index {2978) ?FunctionType.Index {
2961 convertZcuFnType(wasm, cc, params, return_type, target, &wasm.params_scratch, &wasm.returns_scratch) catch |err| switch (err) {2979 convertZcuFnType(wasm.base.comp, cc, params, return_type, target, &wasm.params_scratch, &wasm.returns_scratch) catch |err| switch (err) {
2962 error.OutOfMemory => return null,2980 error.OutOfMemory => return null,
2963 };2981 };
2964 return wasm.getExistingFuncType(.{2982 return wasm.getExistingFuncType(.{
...@@ -3008,7 +3026,7 @@ pub fn navSymbolIndex(wasm: *Wasm, nav_index: InternPool.Nav.Index) Allocator.Er...@@ -3008,7 +3026,7 @@ pub fn navSymbolIndex(wasm: *Wasm, nav_index: InternPool.Nav.Index) Allocator.Er
3008}3026}
30093027
3010fn convertZcuFnType(3028fn convertZcuFnType(
3011 wasm: *Wasm,3029 comp: *Compilation,
3012 cc: std.builtin.CallingConvention,3030 cc: std.builtin.CallingConvention,
3013 params: []const InternPool.Index,3031 params: []const InternPool.Index,
3014 return_type: ZcuType,3032 return_type: ZcuType,
...@@ -3019,7 +3037,6 @@ fn convertZcuFnType(...@@ -3019,7 +3037,6 @@ fn convertZcuFnType(
3019 params_buffer.clearRetainingCapacity();3037 params_buffer.clearRetainingCapacity();
3020 returns_buffer.clearRetainingCapacity();3038 returns_buffer.clearRetainingCapacity();
30213039
3022 const comp = wasm.base.comp;
3023 const gpa = comp.gpa;3040 const gpa = comp.gpa;
3024 const zcu = comp.zcu.?;3041 const zcu = comp.zcu.?;
30253042
src/link/Wasm/Flush.zig-3
...@@ -129,9 +129,6 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {...@@ -129,9 +129,6 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
129129
130 if (diags.hasErrors()) return error.LinkFailure;130 if (diags.hasErrors()) return error.LinkFailure;
131131
132 wasm.functions.shrinkRetainingCapacity(wasm.functions_len);
133 wasm.globals.shrinkRetainingCapacity(wasm.globals_len);
134
135 // TODO only include init functions for objects with must_link=true or132 // TODO only include init functions for objects with must_link=true or
136 // which have any alive functions inside them.133 // which have any alive functions inside them.
137 if (wasm.object_init_funcs.items.len > 0) {134 if (wasm.object_init_funcs.items.len > 0) {