Commit 4d14374a66
Changed files (3)
src
link
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 {
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");
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 => {