diff options
| author | Luuk de Gram <luuk@degram.dev> | 2024-01-21 15:20:24 +0100 |
|---|---|---|
| committer | Luuk de Gram <luuk@degram.dev> | 2024-02-29 15:23:04 +0100 |
| commit | 4d14374a668f6caca7490a136030dbc73507f233 (patch) | |
| tree | b5807abb96e09bb5d60c9fa22df7c3877ae2b02f /src/link | |
| parent | 0a030d6598a42eae6f6af829e03bba053336b51c (diff) | |
| download | zig-4d14374a668f6caca7490a136030dbc73507f233.tar.gz zig-4d14374a668f6caca7490a136030dbc73507f233.zip | |
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.
Diffstat (limited to 'src/link')
| -rw-r--r-- | src/link/Wasm.zig | 35 | ||||
| -rw-r--r-- | src/link/Wasm/ZigObject.zig | 29 | ||||
| -rw-r--r-- | src/link/Wasm/file.zig | 13 |
3 files changed, 40 insertions, 37 deletions
diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index a81c7e7629..c8ed59f307 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -1481,7 +1481,7 @@ fn getFunctionSignature(wasm: *const Wasm, loc: SymbolLoc) std.wasm.Type { const ty_index = obj_file.import(loc.index).kind.function; return obj_file.funcTypes()[ty_index]; } - const type_index = obj_file.functions()[symbol.index - obj_file.importedFunctions()].type_index; + const type_index = obj_file.function(loc.index).type_index; return obj_file.funcTypes()[type_index]; } if (is_undefined) { @@ -1850,9 +1850,7 @@ fn createSyntheticFunction( } /// Unlike `createSyntheticFunction` this function is to be called by -/// the codegeneration backend. This will not allocate the created Atom yet, -/// but will instead be appended to `synthetic_functions` list and will be -/// parsed at the end of code generation. +/// the codegeneration backend. This will not allocate the created Atom yet. /// Returns the index of the symbol. pub fn createFunction( wasm: *Wasm, @@ -1861,31 +1859,7 @@ pub fn createFunction( function_body: *std.ArrayList(u8), relocations: *std.ArrayList(Relocation), ) !u32 { - const gpa = wasm.base.comp.gpa; - const loc = try wasm.createSyntheticSymbol(symbol_name, .function); - - const atom_index = try wasm.createAtom(loc.index, wasm.zig_object_index); - const atom = wasm.getAtomPtr(atom_index); - atom.code = function_body.moveToUnmanaged(); - atom.relocs = relocations.moveToUnmanaged(); - atom.size = @intCast(function_body.items.len); - const symbol = loc.getSymbol(wasm); - symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN); // ensure function does not get exported - - const section_index = wasm.code_section_index orelse idx: { - const index = @as(u32, @intCast(wasm.segments.items.len)); - try wasm.appendDummySegment(); - break :idx index; - }; - try wasm.appendAtomAtIndex(section_index, atom_index); - try wasm.zigObjectPtr().?.atom_types.put( - gpa, - atom_index, - try wasm.zigObjectPtr().?.putOrGetFuncType(gpa, func_ty), - ); - try wasm.synthetic_functions.append(gpa, atom_index); - - return loc.index; + return wasm.zigObjectPtr().?.createFunction(wasm, symbol_name, func_ty, function_body, relocations); } /// If required, sets the function index in the `start` section. @@ -2050,7 +2024,6 @@ fn mergeSections(wasm: *Wasm) !void { switch (symbol.tag) { .function => { - const index = symbol.index - obj_file.importedFunctions(); const gop = try wasm.functions.getOrPut( gpa, .{ .file = sym_loc.file, .index = symbol.index }, @@ -2068,7 +2041,7 @@ fn mergeSections(wasm: *Wasm) !void { try removed_duplicates.append(sym_loc); continue; } - gop.value_ptr.* = .{ .func = obj_file.functions()[index], .sym_index = sym_loc.index }; + gop.value_ptr.* = .{ .func = obj_file.function(sym_loc.index), .sym_index = sym_loc.index }; symbol.index = @as(u32, @intCast(gop.index)) + wasm.imported_functions_count; }, .global => { diff --git a/src/link/Wasm/ZigObject.zig b/src/link/Wasm/ZigObject.zig index 1de15b3f4c..f6261ba90a 100644 --- a/src/link/Wasm/ZigObject.zig +++ b/src/link/Wasm/ZigObject.zig @@ -13,7 +13,7 @@ decls: std.AutoHashMapUnmanaged(InternPool.DeclIndex, Atom.Index) = .{}, func_types: std.ArrayListUnmanaged(std.wasm.Type) = .{}, /// List of `std.wasm.Func`. Each entry contains the function signature, /// rather than the actual body. -functions: std.ArrayListUnmanaged(std.wasm.Func) = .{}, +functions: std.AutoHashMapUnmanaged(u32, std.wasm.Func) = .{}, /// Map of symbol locations, represented by its `types.Import`. imports: std.AutoHashMapUnmanaged(u32, types.Import) = .{}, /// List of WebAssembly globals. @@ -1189,6 +1189,33 @@ pub fn parseSymbolIntoAtom(zig_object: *ZigObject, wasm_file: *Wasm, index: u32) return atom_index; } +/// Creates a new Wasm function with a given symbol name and body. +/// Returns the symbol index of the new function. +pub fn createFunction( + zig_object: *ZigObject, + wasm_file: *Wasm, + symbol_name: []const u8, + func_ty: std.wasm.Type, + function_body: *std.ArrayList(u8), + relocations: *std.ArrayList(types.Relocation), +) !u32 { + const gpa = wasm_file.base.comp.gpa; + const sym_index = try zig_object.allocateSymbol(gpa); + const sym = &zig_object.symbols.items[sym_index]; + sym.tag = .function; + sym.name = try zig_object.string_table.insert(gpa, symbol_name); + const type_index = try zig_object.putOrGetFuncType(gpa, func_ty); + try zig_object.functions.putNoClobber(gpa, sym_index, .{ .type_index = type_index }); + + const atom_index = try wasm_file.createAtom(sym_index, zig_object.index); + const atom = wasm_file.getAtomPtr(atom_index); + atom.size = @intCast(function_body.items.len); + atom.code = function_body.moveToUnmanaged(); + atom.relocs = relocations.moveToUnmanaged(); + + return sym_index; +} + const build_options = @import("build_options"); const builtin = @import("builtin"); const codegen = @import("../../codegen.zig"); diff --git a/src/link/Wasm/file.zig b/src/link/Wasm/file.zig index e9190bd8ca..79b4fd0e36 100644 --- a/src/link/Wasm/file.zig +++ b/src/link/Wasm/file.zig @@ -89,11 +89,14 @@ pub const File = union(enum) { }; } - pub fn functions(file: File) []const std.wasm.Func { - return switch (file) { - .zig_object => |obj| obj.functions.items, - .object => |obj| obj.functions, - }; + pub fn function(file: File, sym_index: u32) std.wasm.Func { + switch (file) { + .zig_object => |obj| return obj.functions.get(sym_index).?, + .object => |obj| { + const sym = obj.symtable[sym_index]; + return obj.functions[sym.index - obj.imported_functions_count]; + }, + } } pub fn globals(file: File) []const std.wasm.Global { |
