mirror of
https://github.com/ziglang/zig.git
synced 2026-02-14 13:30:45 +00:00
wasm: Debug information for locals
Implements very basic debug information for locals. For now it only implements debug info when the variable is stored within a Wasm local. The goal is to support those that live in the data section (virtual stack).
This commit is contained in:
parent
33b2f4f382
commit
d46cdb5396
@ -1478,15 +1478,17 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
|
||||
.get_union_tag => self.airGetUnionTag(inst),
|
||||
|
||||
// TODO
|
||||
.dbg_stmt,
|
||||
.dbg_inline_begin,
|
||||
.dbg_inline_end,
|
||||
.dbg_block_begin,
|
||||
.dbg_block_end,
|
||||
.dbg_var_ptr,
|
||||
.dbg_var_val,
|
||||
=> WValue.none,
|
||||
|
||||
.dbg_var_ptr => self.airDbgVar(inst, true),
|
||||
.dbg_var_val => self.airDbgVar(inst, false),
|
||||
|
||||
.dbg_stmt => self.airDbgStmt(inst),
|
||||
|
||||
.call => self.airCall(inst, .auto),
|
||||
.call_always_tail => self.airCall(inst, .always_tail),
|
||||
.call_never_tail => self.airCall(inst, .never_tail),
|
||||
@ -4277,3 +4279,57 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
|
||||
try self.addLabel(.local_set, result.local);
|
||||
return result;
|
||||
}
|
||||
|
||||
fn airDbgVar(self: *Self, inst: Air.Inst.Index, is_ptr: bool) !WValue {
|
||||
if (self.debug_output != .dwarf) return WValue{ .none = {} };
|
||||
|
||||
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
|
||||
const ty = self.air.typeOf(pl_op.operand);
|
||||
const operand = try self.resolveInst(pl_op.operand);
|
||||
const op_ty = if (is_ptr) ty.childType() else ty;
|
||||
|
||||
log.debug("airDbgVar: %{d}: {}, {}", .{ inst, op_ty.fmtDebug(), operand });
|
||||
|
||||
const name = self.air.nullTerminatedString(pl_op.payload);
|
||||
log.debug(" var name = ({s})", .{name});
|
||||
|
||||
const dbg_info = &self.debug_output.dwarf.dbg_info;
|
||||
try dbg_info.append(@enumToInt(link.File.Dwarf.AbbrevKind.variable));
|
||||
switch (operand) {
|
||||
.local => |local| {
|
||||
const leb_size = link.File.Wasm.getULEB128Size(local);
|
||||
try dbg_info.ensureUnusedCapacity(2 + leb_size);
|
||||
// wasm locals are encoded as follow:
|
||||
// DW_OP_WASM_location wasm-op
|
||||
// where wasm-op is defined as
|
||||
// wasm-op := wasm-local | wasm-global | wasm-operand_stack
|
||||
// where wasm-local is encoded as
|
||||
// wasm-local := 0x00 i:uleb128
|
||||
dbg_info.appendSliceAssumeCapacity(&.{
|
||||
std.dwarf.OP.WASM_location,
|
||||
std.dwarf.OP.WASM_local,
|
||||
});
|
||||
leb.writeULEB128(dbg_info.writer(), local) catch unreachable;
|
||||
},
|
||||
else => {}, // TODO
|
||||
}
|
||||
|
||||
try dbg_info.ensureUnusedCapacity(5 + name.len + 1);
|
||||
try self.addDbgInfoTypeReloc(op_ty);
|
||||
dbg_info.appendSliceAssumeCapacity(name);
|
||||
dbg_info.appendAssumeCapacity(0);
|
||||
try return WValue{ .none = {} };
|
||||
}
|
||||
|
||||
fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !WValue {
|
||||
if (self.debug_output != .dwarf) return WValue{ .none = {} };
|
||||
|
||||
const dbg_stmt = self.air.instructions.items(.data)[inst].dbg_stmt;
|
||||
try self.addInst(.{ .tag = .dbg_line, .data = .{
|
||||
.payload = try self.addExtra(Mir.DbgLineColumn{
|
||||
.line = dbg_stmt.line,
|
||||
.column = dbg_stmt.column,
|
||||
}),
|
||||
} });
|
||||
return WValue{ .none = {} };
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user