authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-12-07 14:42:30-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-01-15 15:11:35-08:00
logc443a7a57fab7118a9793b7f77b7ab817235a896
tree66e61304cc2a267ef0a4eee82ba1d15ad3968967
parentd45e5ac5eb125c0dc69d29e8a0fbb363a18ebeb6

wasm: move error_name lowering to Emit phase


3 files changed, 37 insertions(+), 16 deletions(-)

src/arch/wasm/CodeGen.zig+2-8
...@@ -5900,12 +5900,7 @@ fn airBitReverse(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5900,12 +5900,7 @@ fn airBitReverse(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
59005900
5901fn airErrorName(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {5901fn airErrorName(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5902 const un_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].un_op;5902 const un_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
5903
5904 const operand = try cg.resolveInst(un_op);5903 const operand = try cg.resolveInst(un_op);
5905 // First retrieve the symbol index to the error name table
5906 // that will be used to emit a relocation for the pointer
5907 // to the error name table.
5908 //
5909 // Each entry to this table is a slice (ptr+len).5904 // Each entry to this table is a slice (ptr+len).
5910 // The operand in this instruction represents the index within this table.5905 // The operand in this instruction represents the index within this table.
5911 // This means to get the final name, we emit the base pointer and then perform5906 // This means to get the final name, we emit the base pointer and then perform
...@@ -5914,12 +5909,11 @@ fn airErrorName(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5914,12 +5909,11 @@ fn airErrorName(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5914 // As the names are global and the slice elements are constant, we do not have5909 // As the names are global and the slice elements are constant, we do not have
5915 // to make a copy of the ptr+value but can point towards them directly.5910 // to make a copy of the ptr+value but can point towards them directly.
5916 const pt = cg.pt;5911 const pt = cg.pt;
5917 const error_table_symbol = try cg.wasm.getErrorTableSymbol(pt);
5918 const name_ty = Type.slice_const_u8_sentinel_0;5912 const name_ty = Type.slice_const_u8_sentinel_0;
5919 const abi_size = name_ty.abiSize(pt.zcu);5913 const abi_size = name_ty.abiSize(pt.zcu);
59205914
5921 const error_name_value: WValue = .{ .memory = error_table_symbol }; // emitting this will create a relocation5915 // Lowers to a i32.const or i64.const with the error table memory address.
5922 try cg.emitWValue(error_name_value);5916 try cg.addTag(.error_name_table_ref);
5923 try cg.emitWValue(operand);5917 try cg.emitWValue(operand);
5924 switch (cg.ptr_size) {5918 switch (cg.ptr_size) {
5925 .wasm32 => {5919 .wasm32 => {
src/arch/wasm/Emit.zig+29-8
...@@ -27,6 +27,8 @@ pub fn lowerToCode(emit: *Emit) Error!void {...@@ -27,6 +27,8 @@ pub fn lowerToCode(emit: *Emit) Error!void {
27 const comp = wasm.base.comp;27 const comp = wasm.base.comp;
28 const gpa = comp.gpa;28 const gpa = comp.gpa;
29 const is_obj = comp.config.output_mode == .Obj;29 const is_obj = comp.config.output_mode == .Obj;
30 const target = &comp.root_mod.resolved_target.result;
31 const is_wasm32 = target.cpu.arch == .wasm32;
3032
31 const tags = mir.instructions.items(.tag);33 const tags = mir.instructions.items(.tag);
32 const datas = mir.instructions.items(.data);34 const datas = mir.instructions.items(.data);
...@@ -56,12 +58,12 @@ pub fn lowerToCode(emit: *Emit) Error!void {...@@ -56,12 +58,12 @@ pub fn lowerToCode(emit: *Emit) Error!void {
56 continue :loop tags[inst];58 continue :loop tags[inst];
57 },59 },
58 .nav_ref => {60 .nav_ref => {
59 try navRefOff(wasm, code, .{ .ip_index = datas[inst].ip_index, .offset = 0 });61 try navRefOff(wasm, code, .{ .ip_index = datas[inst].ip_index, .offset = 0 }, is_wasm32);
60 inst += 1;62 inst += 1;
61 continue :loop tags[inst];63 continue :loop tags[inst];
62 },64 },
63 .nav_ref_off => {65 .nav_ref_off => {
64 try navRefOff(wasm, code, mir.extraData(Mir.NavRefOff, datas[inst].payload).data);66 try navRefOff(wasm, code, mir.extraData(Mir.NavRefOff, datas[inst].payload).data, is_wasm32);
65 inst += 1;67 inst += 1;
66 continue :loop tags[inst];68 continue :loop tags[inst];
67 },69 },
...@@ -80,6 +82,29 @@ pub fn lowerToCode(emit: *Emit) Error!void {...@@ -80,6 +82,29 @@ pub fn lowerToCode(emit: *Emit) Error!void {
80 inst += 1;82 inst += 1;
81 continue :loop tags[inst];83 continue :loop tags[inst];
82 },84 },
85 .error_name_table_ref => {
86 try code.ensureUnusedCapacity(gpa, 11);
87 const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const;
88 code.appendAssumeCapacity(@intFromEnum(opcode));
89 if (is_obj) {
90 try wasm.out_relocs.append(gpa, .{
91 .offset = @intCast(code.items.len),
92 .index = try wasm.errorNameTableSymbolIndex(),
93 .tag = if (is_wasm32) .MEMORY_ADDR_LEB else .MEMORY_ADDR_LEB64,
94 .addend = 0,
95 });
96 code.appendNTimesAssumeCapacity(0, if (is_wasm32) 5 else 10);
97
98 inst += 1;
99 continue :loop tags[inst];
100 } else {
101 const addr = try wasm.errorNameTableAddr();
102 leb.writeIleb128(code.fixedWriter(), addr) catch unreachable;
103
104 inst += 1;
105 continue :loop tags[inst];
106 }
107 },
83 .br_if, .br, .memory_grow, .memory_size => {108 .br_if, .br, .memory_grow, .memory_size => {
84 try code.ensureUnusedCapacity(gpa, 11);109 try code.ensureUnusedCapacity(gpa, 11);
85 code.appendAssumeCapacity(@intFromEnum(tags[inst]));110 code.appendAssumeCapacity(@intFromEnum(tags[inst]));
...@@ -607,11 +632,9 @@ fn encodeMemArg(code: *std.ArrayListUnmanaged(u8), mem_arg: Mir.MemArg) void {...@@ -607,11 +632,9 @@ fn encodeMemArg(code: *std.ArrayListUnmanaged(u8), mem_arg: Mir.MemArg) void {
607 leb.writeUleb128(code.fixedWriter(), mem_arg.offset) catch unreachable;632 leb.writeUleb128(code.fixedWriter(), mem_arg.offset) catch unreachable;
608}633}
609634
610fn uavRefOff(wasm: *link.File.Wasm, code: *std.ArrayListUnmanaged(u8), data: Mir.UavRefOff) !void {635fn uavRefOff(wasm: *link.File.Wasm, code: *std.ArrayListUnmanaged(u8), data: Mir.UavRefOff, is_wasm32: bool) !void {
611 const comp = wasm.base.comp;636 const comp = wasm.base.comp;
612 const gpa = comp.gpa;637 const gpa = comp.gpa;
613 const target = comp.root_mod.resolved_target.result;
614 const is_wasm32 = target.cpu.arch == .wasm32;
615 const is_obj = comp.config.output_mode == .Obj;638 const is_obj = comp.config.output_mode == .Obj;
616 const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const;639 const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const;
617640
...@@ -636,13 +659,12 @@ fn uavRefOff(wasm: *link.File.Wasm, code: *std.ArrayListUnmanaged(u8), data: Mir...@@ -636,13 +659,12 @@ fn uavRefOff(wasm: *link.File.Wasm, code: *std.ArrayListUnmanaged(u8), data: Mir
636 leb.writeUleb128(code.fixedWriter(), addr + data.offset) catch unreachable;659 leb.writeUleb128(code.fixedWriter(), addr + data.offset) catch unreachable;
637}660}
638661
639fn navRefOff(wasm: *link.File.Wasm, code: *std.ArrayListUnmanaged(u8), data: Mir.NavRefOff) !void {662fn navRefOff(wasm: *link.File.Wasm, code: *std.ArrayListUnmanaged(u8), data: Mir.NavRefOff, is_wasm32: bool) !void {
640 const comp = wasm.base.comp;663 const comp = wasm.base.comp;
641 const zcu = comp.zcu.?;664 const zcu = comp.zcu.?;
642 const ip = &zcu.intern_pool;665 const ip = &zcu.intern_pool;
643 const gpa = comp.gpa;666 const gpa = comp.gpa;
644 const is_obj = comp.config.output_mode == .Obj;667 const is_obj = comp.config.output_mode == .Obj;
645 const target = &comp.root_mod.resolved_target.result;
646 const nav_ty = ip.getNav(data.nav_index).typeOf(ip);668 const nav_ty = ip.getNav(data.nav_index).typeOf(ip);
647669
648 try code.ensureUnusedCapacity(gpa, 11);670 try code.ensureUnusedCapacity(gpa, 11);
...@@ -663,7 +685,6 @@ fn navRefOff(wasm: *link.File.Wasm, code: *std.ArrayListUnmanaged(u8), data: Mir...@@ -663,7 +685,6 @@ fn navRefOff(wasm: *link.File.Wasm, code: *std.ArrayListUnmanaged(u8), data: Mir
663 leb.writeUleb128(code.fixedWriter(), addr + data.offset) catch unreachable;685 leb.writeUleb128(code.fixedWriter(), addr + data.offset) catch unreachable;
664 }686 }
665 } else {687 } else {
666 const is_wasm32 = target.cpu.arch == .wasm32;
667 const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const;688 const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const;
668 code.appendAssumeCapacity(@intFromEnum(opcode));689 code.appendAssumeCapacity(@intFromEnum(opcode));
669 if (is_obj) {690 if (is_obj) {
src/arch/wasm/Mir.zig+6
...@@ -88,6 +88,12 @@ pub const Inst = struct {...@@ -88,6 +88,12 @@ pub const Inst = struct {
88 /// names.88 /// names.
89 /// Uses `tag`.89 /// Uses `tag`.
90 errors_len,90 errors_len,
91 /// Lowers to an i32_const (wasm32) or i64_const (wasm64) containing
92 /// the base address of the table of error code names, with each
93 /// element being a null-terminated slice.
94 ///
95 /// Uses `tag`.
96 error_name_table_ref,
91 /// Represents the end of a function body or an initialization expression97 /// Represents the end of a function body or an initialization expression
92 ///98 ///
93 /// Uses `tag` (no additional data).99 /// Uses `tag` (no additional data).