| ... | ... | @@ -1478,15 +1478,17 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { |
| 1478 | 1478 | .get_union_tag => self.airGetUnionTag(inst), |
| 1479 | 1479 | |
| 1480 | 1480 | // TODO |
| 1481 | | .dbg_stmt, |
| 1482 | 1481 | .dbg_inline_begin, |
| 1483 | 1482 | .dbg_inline_end, |
| 1484 | 1483 | .dbg_block_begin, |
| 1485 | 1484 | .dbg_block_end, |
| 1486 | | .dbg_var_ptr, |
| 1487 | | .dbg_var_val, |
| 1488 | 1485 | => WValue.none, |
| 1489 | 1486 | |
| 1487 | .dbg_var_ptr => self.airDbgVar(inst, true), |
| 1488 | .dbg_var_val => self.airDbgVar(inst, false), |
| 1489 | |
| 1490 | .dbg_stmt => self.airDbgStmt(inst), |
| 1491 | |
| 1490 | 1492 | .call => self.airCall(inst, .auto), |
| 1491 | 1493 | .call_always_tail => self.airCall(inst, .always_tail), |
| 1492 | 1494 | .call_never_tail => self.airCall(inst, .never_tail), |
| ... | ... | @@ -4277,3 +4279,57 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| 4277 | 4279 | try self.addLabel(.local_set, result.local); |
| 4278 | 4280 | return result; |
| 4279 | 4281 | } |
| 4282 | |
| 4283 | fn airDbgVar(self: *Self, inst: Air.Inst.Index, is_ptr: bool) !WValue { |
| 4284 | if (self.debug_output != .dwarf) return WValue{ .none = {} }; |
| 4285 | |
| 4286 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 4287 | const ty = self.air.typeOf(pl_op.operand); |
| 4288 | const operand = try self.resolveInst(pl_op.operand); |
| 4289 | const op_ty = if (is_ptr) ty.childType() else ty; |
| 4290 | |
| 4291 | log.debug("airDbgVar: %{d}: {}, {}", .{ inst, op_ty.fmtDebug(), operand }); |
| 4292 | |
| 4293 | const name = self.air.nullTerminatedString(pl_op.payload); |
| 4294 | log.debug(" var name = ({s})", .{name}); |
| 4295 | |
| 4296 | const dbg_info = &self.debug_output.dwarf.dbg_info; |
| 4297 | try dbg_info.append(@enumToInt(link.File.Dwarf.AbbrevKind.variable)); |
| 4298 | switch (operand) { |
| 4299 | .local => |local| { |
| 4300 | const leb_size = link.File.Wasm.getULEB128Size(local); |
| 4301 | try dbg_info.ensureUnusedCapacity(2 + leb_size); |
| 4302 | // wasm locals are encoded as follow: |
| 4303 | // DW_OP_WASM_location wasm-op |
| 4304 | // where wasm-op is defined as |
| 4305 | // wasm-op := wasm-local | wasm-global | wasm-operand_stack |
| 4306 | // where wasm-local is encoded as |
| 4307 | // wasm-local := 0x00 i:uleb128 |
| 4308 | dbg_info.appendSliceAssumeCapacity(&.{ |
| 4309 | std.dwarf.OP.WASM_location, |
| 4310 | std.dwarf.OP.WASM_local, |
| 4311 | }); |
| 4312 | leb.writeULEB128(dbg_info.writer(), local) catch unreachable; |
| 4313 | }, |
| 4314 | else => {}, // TODO |
| 4315 | } |
| 4316 | |
| 4317 | try dbg_info.ensureUnusedCapacity(5 + name.len + 1); |
| 4318 | try self.addDbgInfoTypeReloc(op_ty); |
| 4319 | dbg_info.appendSliceAssumeCapacity(name); |
| 4320 | dbg_info.appendAssumeCapacity(0); |
| 4321 | try return WValue{ .none = {} }; |
| 4322 | } |
| 4323 | |
| 4324 | fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !WValue { |
| 4325 | if (self.debug_output != .dwarf) return WValue{ .none = {} }; |
| 4326 | |
| 4327 | const dbg_stmt = self.air.instructions.items(.data)[inst].dbg_stmt; |
| 4328 | try self.addInst(.{ .tag = .dbg_line, .data = .{ |
| 4329 | .payload = try self.addExtra(Mir.DbgLineColumn{ |
| 4330 | .line = dbg_stmt.line, |
| 4331 | .column = dbg_stmt.column, |
| 4332 | }), |
| 4333 | } }); |
| 4334 | return WValue{ .none = {} }; |
| 4335 | } |