mirror of
https://github.com/ziglang/zig.git
synced 2026-02-20 08:14:48 +00:00
wasm: move error_name lowering to Emit phase
This commit is contained in:
parent
d45e5ac5eb
commit
c443a7a57f
@ -5900,12 +5900,7 @@ fn airBitReverse(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
||||
|
||||
fn airErrorName(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
||||
const un_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
|
||||
|
||||
const operand = try cg.resolveInst(un_op);
|
||||
// First retrieve the symbol index to the error name table
|
||||
// that will be used to emit a relocation for the pointer
|
||||
// to the error name table.
|
||||
//
|
||||
// Each entry to this table is a slice (ptr+len).
|
||||
// The operand in this instruction represents the index within this table.
|
||||
// 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 {
|
||||
// As the names are global and the slice elements are constant, we do not have
|
||||
// to make a copy of the ptr+value but can point towards them directly.
|
||||
const pt = cg.pt;
|
||||
const error_table_symbol = try cg.wasm.getErrorTableSymbol(pt);
|
||||
const name_ty = Type.slice_const_u8_sentinel_0;
|
||||
const abi_size = name_ty.abiSize(pt.zcu);
|
||||
|
||||
const error_name_value: WValue = .{ .memory = error_table_symbol }; // emitting this will create a relocation
|
||||
try cg.emitWValue(error_name_value);
|
||||
// Lowers to a i32.const or i64.const with the error table memory address.
|
||||
try cg.addTag(.error_name_table_ref);
|
||||
try cg.emitWValue(operand);
|
||||
switch (cg.ptr_size) {
|
||||
.wasm32 => {
|
||||
|
||||
@ -27,6 +27,8 @@ pub fn lowerToCode(emit: *Emit) Error!void {
|
||||
const comp = wasm.base.comp;
|
||||
const gpa = comp.gpa;
|
||||
const is_obj = comp.config.output_mode == .Obj;
|
||||
const target = &comp.root_mod.resolved_target.result;
|
||||
const is_wasm32 = target.cpu.arch == .wasm32;
|
||||
|
||||
const tags = mir.instructions.items(.tag);
|
||||
const datas = mir.instructions.items(.data);
|
||||
@ -56,12 +58,12 @@ pub fn lowerToCode(emit: *Emit) Error!void {
|
||||
continue :loop tags[inst];
|
||||
},
|
||||
.nav_ref => {
|
||||
try navRefOff(wasm, code, .{ .ip_index = datas[inst].ip_index, .offset = 0 });
|
||||
try navRefOff(wasm, code, .{ .ip_index = datas[inst].ip_index, .offset = 0 }, is_wasm32);
|
||||
inst += 1;
|
||||
continue :loop tags[inst];
|
||||
},
|
||||
.nav_ref_off => {
|
||||
try navRefOff(wasm, code, mir.extraData(Mir.NavRefOff, datas[inst].payload).data);
|
||||
try navRefOff(wasm, code, mir.extraData(Mir.NavRefOff, datas[inst].payload).data, is_wasm32);
|
||||
inst += 1;
|
||||
continue :loop tags[inst];
|
||||
},
|
||||
@ -80,6 +82,29 @@ pub fn lowerToCode(emit: *Emit) Error!void {
|
||||
inst += 1;
|
||||
continue :loop tags[inst];
|
||||
},
|
||||
.error_name_table_ref => {
|
||||
try code.ensureUnusedCapacity(gpa, 11);
|
||||
const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const;
|
||||
code.appendAssumeCapacity(@intFromEnum(opcode));
|
||||
if (is_obj) {
|
||||
try wasm.out_relocs.append(gpa, .{
|
||||
.offset = @intCast(code.items.len),
|
||||
.index = try wasm.errorNameTableSymbolIndex(),
|
||||
.tag = if (is_wasm32) .MEMORY_ADDR_LEB else .MEMORY_ADDR_LEB64,
|
||||
.addend = 0,
|
||||
});
|
||||
code.appendNTimesAssumeCapacity(0, if (is_wasm32) 5 else 10);
|
||||
|
||||
inst += 1;
|
||||
continue :loop tags[inst];
|
||||
} else {
|
||||
const addr = try wasm.errorNameTableAddr();
|
||||
leb.writeIleb128(code.fixedWriter(), addr) catch unreachable;
|
||||
|
||||
inst += 1;
|
||||
continue :loop tags[inst];
|
||||
}
|
||||
},
|
||||
.br_if, .br, .memory_grow, .memory_size => {
|
||||
try code.ensureUnusedCapacity(gpa, 11);
|
||||
code.appendAssumeCapacity(@intFromEnum(tags[inst]));
|
||||
@ -607,11 +632,9 @@ fn encodeMemArg(code: *std.ArrayListUnmanaged(u8), mem_arg: Mir.MemArg) void {
|
||||
leb.writeUleb128(code.fixedWriter(), mem_arg.offset) catch unreachable;
|
||||
}
|
||||
|
||||
fn uavRefOff(wasm: *link.File.Wasm, code: *std.ArrayListUnmanaged(u8), data: Mir.UavRefOff) !void {
|
||||
fn uavRefOff(wasm: *link.File.Wasm, code: *std.ArrayListUnmanaged(u8), data: Mir.UavRefOff, is_wasm32: bool) !void {
|
||||
const comp = wasm.base.comp;
|
||||
const gpa = comp.gpa;
|
||||
const target = comp.root_mod.resolved_target.result;
|
||||
const is_wasm32 = target.cpu.arch == .wasm32;
|
||||
const is_obj = comp.config.output_mode == .Obj;
|
||||
const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const;
|
||||
|
||||
@ -636,13 +659,12 @@ fn uavRefOff(wasm: *link.File.Wasm, code: *std.ArrayListUnmanaged(u8), data: Mir
|
||||
leb.writeUleb128(code.fixedWriter(), addr + data.offset) catch unreachable;
|
||||
}
|
||||
|
||||
fn navRefOff(wasm: *link.File.Wasm, code: *std.ArrayListUnmanaged(u8), data: Mir.NavRefOff) !void {
|
||||
fn navRefOff(wasm: *link.File.Wasm, code: *std.ArrayListUnmanaged(u8), data: Mir.NavRefOff, is_wasm32: bool) !void {
|
||||
const comp = wasm.base.comp;
|
||||
const zcu = comp.zcu.?;
|
||||
const ip = &zcu.intern_pool;
|
||||
const gpa = comp.gpa;
|
||||
const is_obj = comp.config.output_mode == .Obj;
|
||||
const target = &comp.root_mod.resolved_target.result;
|
||||
const nav_ty = ip.getNav(data.nav_index).typeOf(ip);
|
||||
|
||||
try code.ensureUnusedCapacity(gpa, 11);
|
||||
@ -663,7 +685,6 @@ fn navRefOff(wasm: *link.File.Wasm, code: *std.ArrayListUnmanaged(u8), data: Mir
|
||||
leb.writeUleb128(code.fixedWriter(), addr + data.offset) catch unreachable;
|
||||
}
|
||||
} else {
|
||||
const is_wasm32 = target.cpu.arch == .wasm32;
|
||||
const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const;
|
||||
code.appendAssumeCapacity(@intFromEnum(opcode));
|
||||
if (is_obj) {
|
||||
|
||||
@ -88,6 +88,12 @@ pub const Inst = struct {
|
||||
/// names.
|
||||
/// Uses `tag`.
|
||||
errors_len,
|
||||
/// Lowers to an i32_const (wasm32) or i64_const (wasm64) containing
|
||||
/// the base address of the table of error code names, with each
|
||||
/// element being a null-terminated slice.
|
||||
///
|
||||
/// Uses `tag`.
|
||||
error_name_table_ref,
|
||||
/// Represents the end of a function body or an initialization expression
|
||||
///
|
||||
/// Uses `tag` (no additional data).
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user