diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2024-12-20 20:18:22 -0800 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2025-01-15 15:11:36 -0800 |
| commit | 2dbf66dd698601ae8aaee86d5ba6a9078dda0a8e (patch) | |
| tree | 99a3638fd838df2472dd1e051e0ec0b9838e6605 /src | |
| parent | d1cde847a367c526c63d65714583189fa2912731 (diff) | |
| download | zig-2dbf66dd698601ae8aaee86d5ba6a9078dda0a8e.tar.gz zig-2dbf66dd698601ae8aaee86d5ba6a9078dda0a8e.zip | |
wasm linker: implement stack pointer global
Diffstat (limited to 'src')
| -rw-r--r-- | src/Compilation.zig | 2 | ||||
| -rw-r--r-- | src/link/Wasm.zig | 15 | ||||
| -rw-r--r-- | src/link/Wasm/Flush.zig | 10 |
3 files changed, 22 insertions, 5 deletions
diff --git a/src/Compilation.zig b/src/Compilation.zig index 33868ef195..4dfae7c893 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -118,6 +118,8 @@ link_task_queue_safety: std.debug.SafetyLock = .{}, link_task_queue_postponed: std.ArrayListUnmanaged(link.Task) = .empty, /// Initialized with how many link input tasks are expected. After this reaches zero /// the linker will begin the prelink phase. +/// Initialized in the Compilation main thread before the pipeline; modified only in +/// the linker task thread. remaining_prelink_tasks: u32, work_queues: [ diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index c495025856..313ff9c62d 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -361,12 +361,13 @@ pub const OutputFunctionIndex = enum(u32) { pub const GlobalIndex = enum(u32) { _, - /// This is only accurate when there is a Zcu. + /// This is only accurate when not emitting an object and there is a Zcu. pub const stack_pointer: GlobalIndex = @enumFromInt(0); /// Same as `stack_pointer` but with a safety assertion. pub fn stackPointer(wasm: *const Wasm) Global.Index { const comp = wasm.base.comp; + assert(comp.config.output_mode != .Obj); assert(comp.zcu != null); return .stack_pointer; } @@ -2450,7 +2451,7 @@ pub fn updateNav(wasm: *Wasm, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index .variable => |variable| .{ variable.init, variable.owner_nav }, else => .{ nav.status.resolved.val, nav_index }, }; - log.debug("updateNav {} {}", .{ nav.fqn.fmt(ip), chased_nav_index }); + //log.debug("updateNav {} {}", .{ nav.fqn.fmt(ip), chased_nav_index }); assert(!wasm.imports.contains(chased_nav_index)); if (nav_init != .none and !Value.fromInterned(nav_init).typeOf(zcu).hasRuntimeBits(zcu)) { @@ -2578,6 +2579,7 @@ pub fn prelink(wasm: *Wasm, prog_node: std.Progress.Node) link.File.FlushError!v const comp = wasm.base.comp; const gpa = comp.gpa; const rdynamic = comp.config.rdynamic; + const is_obj = comp.config.output_mode == .Obj; assert(wasm.missing_exports.entries.len == 0); for (wasm.export_symbol_names) |exp_name| { @@ -2614,8 +2616,13 @@ pub fn prelink(wasm: *Wasm, prog_node: std.Progress.Node) link.File.FlushError!v if (comp.zcu != null) { // Zig always depends on a stack pointer global. - try wasm.globals.put(gpa, .__stack_pointer, {}); - assert(wasm.globals.entries.len - 1 == @intFromEnum(GlobalIndex.stack_pointer)); + // If emitting an object, it's an import. Otherwise, the linker synthesizes it. + if (is_obj) { + @panic("TODO"); + } else { + try wasm.globals.put(gpa, .__stack_pointer, {}); + assert(wasm.globals.entries.len - 1 == @intFromEnum(GlobalIndex.stack_pointer)); + } } // These loops do both recursive marking of alive symbols well as checking for undefined symbols. diff --git a/src/link/Wasm/Flush.zig b/src/link/Wasm/Flush.zig index 4a9e21d7be..4a8a53e739 100644 --- a/src/link/Wasm/Flush.zig +++ b/src/link/Wasm/Flush.zig @@ -565,7 +565,15 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { .unresolved => unreachable, .__heap_base => @panic("TODO"), .__heap_end => @panic("TODO"), - .__stack_pointer => @panic("TODO"), + .__stack_pointer => { + try binary_bytes.appendSlice(gpa, &.{ + @intFromEnum(std.wasm.Valtype.i32), + @intFromBool(true), // mutable + @intFromEnum(std.wasm.Opcode.i32_const), + 0, // leb128 init value + @intFromEnum(std.wasm.Opcode.end), + }); + }, .__tls_align => @panic("TODO"), .__tls_base => @panic("TODO"), .__tls_size => @panic("TODO"), |
