mirror of
https://github.com/ziglang/zig.git
synced 2026-02-14 13:30:45 +00:00
wasm linker: implement __wasm_call_ctors
This commit is contained in:
parent
9ccf500508
commit
a4bee3009a
@ -378,6 +378,7 @@ pub const OutputFunctionIndex = enum(u32) {
|
||||
}
|
||||
|
||||
pub fn fromSymbolName(wasm: *const Wasm, name: String) OutputFunctionIndex {
|
||||
if (wasm.flush_buffer.function_imports.getIndex(name)) |i| return @enumFromInt(i);
|
||||
return fromFunctionIndex(wasm, FunctionIndex.fromSymbolName(wasm, name).?);
|
||||
}
|
||||
};
|
||||
@ -3002,6 +3003,10 @@ pub fn prelink(wasm: *Wasm, prog_node: std.Progress.Node) link.File.FlushError!v
|
||||
try markFunctionImport(wasm, name, import, @enumFromInt(i));
|
||||
}
|
||||
}
|
||||
// Also treat init functions as roots.
|
||||
for (wasm.object_init_funcs.items) |init_func| {
|
||||
try markFunction(wasm, init_func.function_index);
|
||||
}
|
||||
wasm.functions_end_prelink = @intCast(wasm.functions.entries.len);
|
||||
wasm.function_exports_len = @intCast(wasm.function_exports.items.len);
|
||||
|
||||
|
||||
@ -679,7 +679,11 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
|
||||
for (wasm.functions.keys()) |resolution| switch (resolution.unpack(wasm)) {
|
||||
.unresolved => unreachable,
|
||||
.__wasm_apply_global_tls_relocs => @panic("TODO lower __wasm_apply_global_tls_relocs"),
|
||||
.__wasm_call_ctors => @panic("TODO lower __wasm_call_ctors"),
|
||||
.__wasm_call_ctors => {
|
||||
const code_start = try reserveSize(gpa, binary_bytes);
|
||||
defer replaceSize(binary_bytes, code_start);
|
||||
try emitCallCtorsFunction(wasm, binary_bytes);
|
||||
},
|
||||
.__wasm_init_memory => @panic("TODO lower __wasm_init_memory "),
|
||||
.__wasm_init_tls => @panic("TODO lower __wasm_init_tls "),
|
||||
.object_function => |i| {
|
||||
@ -1559,3 +1563,27 @@ fn reloc_leb_table(code: []u8, table: Wasm.TableIndex) void {
|
||||
fn reloc_leb_type(code: []u8, index: Wasm.FunctionType.Index) void {
|
||||
leb.writeUnsignedFixed(5, code[0..5], @intFromEnum(index));
|
||||
}
|
||||
|
||||
fn emitCallCtorsFunction(wasm: *const Wasm, binary_bytes: *std.ArrayListUnmanaged(u8)) Allocator.Error!void {
|
||||
const gpa = wasm.base.comp.gpa;
|
||||
|
||||
try binary_bytes.ensureUnusedCapacity(gpa, 5 + 1);
|
||||
leb.writeUleb128(binary_bytes.fixedWriter(), @as(u32, 0)) catch unreachable; // no locals
|
||||
|
||||
for (wasm.object_init_funcs.items) |init_func| {
|
||||
const func = init_func.function_index.ptr(wasm);
|
||||
const ty = func.type_index.ptr(wasm);
|
||||
const n_returns = ty.returns.slice(wasm).len;
|
||||
|
||||
// Call function by its function index
|
||||
try binary_bytes.ensureUnusedCapacity(gpa, 1 + 5 + n_returns + 1);
|
||||
const call_index: Wasm.OutputFunctionIndex = .fromObjectFunction(wasm, init_func.function_index);
|
||||
binary_bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.call));
|
||||
leb.writeUleb128(binary_bytes.fixedWriter(), @intFromEnum(call_index)) catch unreachable;
|
||||
|
||||
// drop all returned values from the stack as __wasm_call_ctors has no return value
|
||||
binary_bytes.appendNTimesAssumeCapacity(@intFromEnum(std.wasm.Opcode.drop), n_returns);
|
||||
}
|
||||
|
||||
binary_bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.end)); // end function body
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user