| ... | ... | @@ -546,6 +546,8 @@ block_depth: u32 = 0, |
| 546 | 546 | air: Air, |
| 547 | 547 | liveness: Liveness, |
| 548 | 548 | gpa: mem.Allocator, |
| 549 | debug_output: codegen.DebugInfoOutput, |
| 550 | mod_fn: *const Module.Fn, |
| 549 | 551 | /// Table to save `WValue`'s generated by an `Air.Inst` |
| 550 | 552 | values: ValueTable, |
| 551 | 553 | /// Mapping from Air.Inst.Index to block ids |
| ... | ... | @@ -856,6 +858,8 @@ pub fn generate( |
| 856 | 858 | .locals = .{}, |
| 857 | 859 | .target = bin_file.options.target, |
| 858 | 860 | .bin_file = bin_file.cast(link.File.Wasm).?, |
| 861 | .debug_output = debug_output, |
| 862 | .mod_fn = func, |
| 859 | 863 | }; |
| 860 | 864 | defer code_gen.deinit(); |
| 861 | 865 | |
| ... | ... | @@ -1022,6 +1026,23 @@ fn firstParamSRet(fn_info: Type.Payload.Function.Data, target: std.Target) bool |
| 1022 | 1026 | } |
| 1023 | 1027 | } |
| 1024 | 1028 | |
| 1029 | /// For a given `Type`, add debug information to .debug_info at the current position. |
| 1030 | /// The actual bytes will be written to the position after relocation. |
| 1031 | fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void { |
| 1032 | switch (self.debug_output) { |
| 1033 | .dwarf => |dwarf| { |
| 1034 | assert(ty.hasRuntimeBitsIgnoreComptime()); |
| 1035 | const dbg_info = &dwarf.dbg_info; |
| 1036 | const index = dbg_info.items.len; |
| 1037 | try dbg_info.resize(index + 4); |
| 1038 | const atom = &self.decl.link.wasm.dbg_info_atom; |
| 1039 | try dwarf.addTypeReloc(atom, ty, @intCast(u32, index), null); |
| 1040 | }, |
| 1041 | .plan9 => unreachable, |
| 1042 | .none => {}, |
| 1043 | } |
| 1044 | } |
| 1045 | |
| 1025 | 1046 | /// Lowers a Zig type and its value based on a given calling convention to ensure |
| 1026 | 1047 | /// it matches the ABI. |
| 1027 | 1048 | fn lowerArg(self: *Self, cc: std.builtin.CallingConvention, ty: Type, value: WValue) !void { |
| ... | ... | @@ -1873,7 +1894,8 @@ fn load(self: *Self, operand: WValue, ty: Type, offset: u32) InnerError!WValue { |
| 1873 | 1894 | } |
| 1874 | 1895 | |
| 1875 | 1896 | fn airArg(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| 1876 | | const arg = self.args[self.arg_index]; |
| 1897 | const arg_index = self.arg_index; |
| 1898 | const arg = self.args[arg_index]; |
| 1877 | 1899 | const cc = self.decl.ty.fnInfo().cc; |
| 1878 | 1900 | if (cc == .C) { |
| 1879 | 1901 | const ty = self.air.typeOfIndex(inst); |
| ... | ... | @@ -1886,6 +1908,32 @@ fn airArg(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| 1886 | 1908 | } else { |
| 1887 | 1909 | self.arg_index += 1; |
| 1888 | 1910 | } |
| 1911 | |
| 1912 | switch (self.debug_output) { |
| 1913 | .dwarf => |dwarf| { |
| 1914 | // TODO: Get the original arg index rather than wasm arg index |
| 1915 | const name = self.mod_fn.getParamName(arg_index); |
| 1916 | const leb_size = link.File.Wasm.getULEB128Size(arg.local); |
| 1917 | const dbg_info = &dwarf.dbg_info; |
| 1918 | try dbg_info.ensureUnusedCapacity(3 + leb_size + 5 + name.len + 1); |
| 1919 | // wasm locations are encoded as follow: |
| 1920 | // DW_OP_WASM_location wasm-op |
| 1921 | // where wasm-op is defined as |
| 1922 | // wasm-op := wasm-local | wasm-global | wasm-operand_stack |
| 1923 | // where each argument is encoded as |
| 1924 | // <opcode> i:uleb128 |
| 1925 | dbg_info.appendSliceAssumeCapacity(&.{ |
| 1926 | @enumToInt(link.File.Dwarf.AbbrevKind.parameter), |
| 1927 | std.dwarf.OP.WASM_location, |
| 1928 | std.dwarf.OP.WASM_local, |
| 1929 | }); |
| 1930 | leb.writeULEB128(dbg_info.writer(), arg.local) catch unreachable; |
| 1931 | try self.addDbgInfoTypeReloc(self.air.typeOfIndex(inst)); |
| 1932 | dbg_info.appendSliceAssumeCapacity(name); |
| 1933 | dbg_info.appendAssumeCapacity(0); |
| 1934 | }, |
| 1935 | else => {}, |
| 1936 | } |
| 1889 | 1937 | return arg; |
| 1890 | 1938 | } |
| 1891 | 1939 | |