mirror of
https://github.com/ziglang/zig.git
synced 2026-01-07 14:03:26 +00:00
wasm linker: implement stack pointer global
This commit is contained in:
parent
d1cde847a3
commit
2dbf66dd69
@ -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: [
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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"),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user