authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2024-01-21 15:20:24+01:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2024-02-29 15:23:04+01:00
log4d14374a668f6caca7490a136030dbc73507f233
treeb5807abb96e09bb5d60c9fa22df7c3877ae2b02f
parent0a030d6598a42eae6f6af829e03bba053336b51c
signaturelock-open Commit is signed but in an unrecognized format.

wasm: Move `createFunction` to `ZigObject`

This function was previously only called by the backend which generates a synthetical function that is not represented by any AIR or Zig code. For this reason, the ownership is moved to the zig-object and stored there so it can be linked with the other object files without the driver having to specialize it.

3 files changed, 40 insertions(+), 37 deletions(-)

src/link/Wasm.zig+4-31
...@@ -1481,7 +1481,7 @@ fn getFunctionSignature(wasm: *const Wasm, loc: SymbolLoc) std.wasm.Type {...@@ -1481,7 +1481,7 @@ fn getFunctionSignature(wasm: *const Wasm, loc: SymbolLoc) std.wasm.Type {
1481 const ty_index = obj_file.import(loc.index).kind.function;1481 const ty_index = obj_file.import(loc.index).kind.function;
1482 return obj_file.funcTypes()[ty_index];1482 return obj_file.funcTypes()[ty_index];
1483 }1483 }
1484 const type_index = obj_file.functions()[symbol.index - obj_file.importedFunctions()].type_index;1484 const type_index = obj_file.function(loc.index).type_index;
1485 return obj_file.funcTypes()[type_index];1485 return obj_file.funcTypes()[type_index];
1486 }1486 }
1487 if (is_undefined) {1487 if (is_undefined) {
...@@ -1850,9 +1850,7 @@ fn createSyntheticFunction(...@@ -1850,9 +1850,7 @@ fn createSyntheticFunction(
1850}1850}
18511851
1852/// Unlike `createSyntheticFunction` this function is to be called by1852/// Unlike `createSyntheticFunction` this function is to be called by
1853/// the codegeneration backend. This will not allocate the created Atom yet,1853/// the codegeneration backend. This will not allocate the created Atom yet.
1854/// but will instead be appended to `synthetic_functions` list and will be
1855/// parsed at the end of code generation.
1856/// Returns the index of the symbol.1854/// Returns the index of the symbol.
1857pub fn createFunction(1855pub fn createFunction(
1858 wasm: *Wasm,1856 wasm: *Wasm,
...@@ -1861,31 +1859,7 @@ pub fn createFunction(...@@ -1861,31 +1859,7 @@ pub fn createFunction(
1861 function_body: *std.ArrayList(u8),1859 function_body: *std.ArrayList(u8),
1862 relocations: *std.ArrayList(Relocation),1860 relocations: *std.ArrayList(Relocation),
1863) !u32 {1861) !u32 {
1864 const gpa = wasm.base.comp.gpa;1862 return wasm.zigObjectPtr().?.createFunction(wasm, symbol_name, func_ty, function_body, relocations);
1865 const loc = try wasm.createSyntheticSymbol(symbol_name, .function);
1866
1867 const atom_index = try wasm.createAtom(loc.index, wasm.zig_object_index);
1868 const atom = wasm.getAtomPtr(atom_index);
1869 atom.code = function_body.moveToUnmanaged();
1870 atom.relocs = relocations.moveToUnmanaged();
1871 atom.size = @intCast(function_body.items.len);
1872 const symbol = loc.getSymbol(wasm);
1873 symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN); // ensure function does not get exported
1874
1875 const section_index = wasm.code_section_index orelse idx: {
1876 const index = @as(u32, @intCast(wasm.segments.items.len));
1877 try wasm.appendDummySegment();
1878 break :idx index;
1879 };
1880 try wasm.appendAtomAtIndex(section_index, atom_index);
1881 try wasm.zigObjectPtr().?.atom_types.put(
1882 gpa,
1883 atom_index,
1884 try wasm.zigObjectPtr().?.putOrGetFuncType(gpa, func_ty),
1885 );
1886 try wasm.synthetic_functions.append(gpa, atom_index);
1887
1888 return loc.index;
1889}1863}
18901864
1891/// If required, sets the function index in the `start` section.1865/// If required, sets the function index in the `start` section.
...@@ -2050,7 +2024,6 @@ fn mergeSections(wasm: *Wasm) !void {...@@ -2050,7 +2024,6 @@ fn mergeSections(wasm: *Wasm) !void {
20502024
2051 switch (symbol.tag) {2025 switch (symbol.tag) {
2052 .function => {2026 .function => {
2053 const index = symbol.index - obj_file.importedFunctions();
2054 const gop = try wasm.functions.getOrPut(2027 const gop = try wasm.functions.getOrPut(
2055 gpa,2028 gpa,
2056 .{ .file = sym_loc.file, .index = symbol.index },2029 .{ .file = sym_loc.file, .index = symbol.index },
...@@ -2068,7 +2041,7 @@ fn mergeSections(wasm: *Wasm) !void {...@@ -2068,7 +2041,7 @@ fn mergeSections(wasm: *Wasm) !void {
2068 try removed_duplicates.append(sym_loc);2041 try removed_duplicates.append(sym_loc);
2069 continue;2042 continue;
2070 }2043 }
2071 gop.value_ptr.* = .{ .func = obj_file.functions()[index], .sym_index = sym_loc.index };2044 gop.value_ptr.* = .{ .func = obj_file.function(sym_loc.index), .sym_index = sym_loc.index };
2072 symbol.index = @as(u32, @intCast(gop.index)) + wasm.imported_functions_count;2045 symbol.index = @as(u32, @intCast(gop.index)) + wasm.imported_functions_count;
2073 },2046 },
2074 .global => {2047 .global => {
src/link/Wasm/ZigObject.zig+28-1
...@@ -13,7 +13,7 @@ decls: std.AutoHashMapUnmanaged(InternPool.DeclIndex, Atom.Index) = .{},...@@ -13,7 +13,7 @@ decls: std.AutoHashMapUnmanaged(InternPool.DeclIndex, Atom.Index) = .{},
13func_types: std.ArrayListUnmanaged(std.wasm.Type) = .{},13func_types: std.ArrayListUnmanaged(std.wasm.Type) = .{},
14/// List of `std.wasm.Func`. Each entry contains the function signature,14/// List of `std.wasm.Func`. Each entry contains the function signature,
15/// rather than the actual body.15/// rather than the actual body.
16functions: std.ArrayListUnmanaged(std.wasm.Func) = .{},16functions: std.AutoHashMapUnmanaged(u32, std.wasm.Func) = .{},
17/// Map of symbol locations, represented by its `types.Import`.17/// Map of symbol locations, represented by its `types.Import`.
18imports: std.AutoHashMapUnmanaged(u32, types.Import) = .{},18imports: std.AutoHashMapUnmanaged(u32, types.Import) = .{},
19/// List of WebAssembly globals.19/// List of WebAssembly globals.
...@@ -1189,6 +1189,33 @@ pub fn parseSymbolIntoAtom(zig_object: *ZigObject, wasm_file: *Wasm, index: u32)...@@ -1189,6 +1189,33 @@ pub fn parseSymbolIntoAtom(zig_object: *ZigObject, wasm_file: *Wasm, index: u32)
1189 return atom_index;1189 return atom_index;
1190}1190}
11911191
1192/// Creates a new Wasm function with a given symbol name and body.
1193/// Returns the symbol index of the new function.
1194pub fn createFunction(
1195 zig_object: *ZigObject,
1196 wasm_file: *Wasm,
1197 symbol_name: []const u8,
1198 func_ty: std.wasm.Type,
1199 function_body: *std.ArrayList(u8),
1200 relocations: *std.ArrayList(types.Relocation),
1201) !u32 {
1202 const gpa = wasm_file.base.comp.gpa;
1203 const sym_index = try zig_object.allocateSymbol(gpa);
1204 const sym = &zig_object.symbols.items[sym_index];
1205 sym.tag = .function;
1206 sym.name = try zig_object.string_table.insert(gpa, symbol_name);
1207 const type_index = try zig_object.putOrGetFuncType(gpa, func_ty);
1208 try zig_object.functions.putNoClobber(gpa, sym_index, .{ .type_index = type_index });
1209
1210 const atom_index = try wasm_file.createAtom(sym_index, zig_object.index);
1211 const atom = wasm_file.getAtomPtr(atom_index);
1212 atom.size = @intCast(function_body.items.len);
1213 atom.code = function_body.moveToUnmanaged();
1214 atom.relocs = relocations.moveToUnmanaged();
1215
1216 return sym_index;
1217}
1218
1192const build_options = @import("build_options");1219const build_options = @import("build_options");
1193const builtin = @import("builtin");1220const builtin = @import("builtin");
1194const codegen = @import("../../codegen.zig");1221const codegen = @import("../../codegen.zig");
src/link/Wasm/file.zig+8-5
...@@ -89,11 +89,14 @@ pub const File = union(enum) {...@@ -89,11 +89,14 @@ pub const File = union(enum) {
89 };89 };
90 }90 }
9191
92 pub fn functions(file: File) []const std.wasm.Func {92 pub fn function(file: File, sym_index: u32) std.wasm.Func {
93 return switch (file) {93 switch (file) {
94 .zig_object => |obj| obj.functions.items,94 .zig_object => |obj| return obj.functions.get(sym_index).?,
95 .object => |obj| obj.functions,95 .object => |obj| {
96 };96 const sym = obj.symtable[sym_index];
97 return obj.functions[sym.index - obj.imported_functions_count];
98 },
99 }
97 }100 }
98101
99 pub fn globals(file: File) []const std.wasm.Global {102 pub fn globals(file: File) []const std.wasm.Global {