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.
This commit is contained in:
Luuk de Gram 2024-01-21 15:20:24 +01:00
parent 0a030d6598
commit 4d14374a66
No known key found for this signature in database
GPG Key ID: A8CFE58E4DC7D664
3 changed files with 40 additions and 37 deletions

View File

@ -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 => {

View File

@ -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");

View File

@ -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 {