| ... | ... | @@ -130,6 +130,63 @@ const Writer = struct { |
| 130 | 130 | recurse_decls: bool, |
| 131 | 131 | recurse_blocks: bool, |
| 132 | 132 | |
| 133 | /// Using `std.zig.findLineColumn` whenever we need to resolve a source location makes ZIR |
| 134 | /// printing O(N^2), which can have drastic effects - taking a ZIR dump from a few seconds to |
| 135 | /// many minutes. Since we're usually resolving source locations close to one another, |
| 136 | /// preserving state across source location resolutions speeds things up a lot. |
| 137 | line_col_cursor: struct { |
| 138 | line: usize = 0, |
| 139 | column: usize = 0, |
| 140 | line_start: usize = 0, |
| 141 | off: usize = 0, |
| 142 | |
| 143 | fn find(cur: *@This(), source: []const u8, want_offset: usize) std.zig.Loc { |
| 144 | if (want_offset < cur.off) { |
| 145 | // Go back to the start of this line |
| 146 | cur.off = cur.line_start; |
| 147 | cur.column = 0; |
| 148 | |
| 149 | while (want_offset < cur.off) { |
| 150 | // Go back to the newline |
| 151 | cur.off -= 1; |
| 152 | |
| 153 | // Seek to the start of the previous line |
| 154 | while (cur.off > 0 and source[cur.off - 1] != '\n') { |
| 155 | cur.off -= 1; |
| 156 | } |
| 157 | cur.line_start = cur.off; |
| 158 | cur.line -= 1; |
| 159 | } |
| 160 | } |
| 161 | |
| 162 | // The cursor is now positioned before `want_offset`. |
| 163 | // Seek forward as in `std.zig.findLineColumn`. |
| 164 | |
| 165 | while (cur.off < want_offset) : (cur.off += 1) { |
| 166 | switch (source[cur.off]) { |
| 167 | '\n' => { |
| 168 | cur.line += 1; |
| 169 | cur.column = 0; |
| 170 | cur.line_start = cur.off + 1; |
| 171 | }, |
| 172 | else => { |
| 173 | cur.column += 1; |
| 174 | }, |
| 175 | } |
| 176 | } |
| 177 | |
| 178 | while (cur.off < source.len and source[cur.off] != '\n') { |
| 179 | cur.off += 1; |
| 180 | } |
| 181 | |
| 182 | return .{ |
| 183 | .line = cur.line, |
| 184 | .column = cur.column, |
| 185 | .source_line = source[cur.line_start..cur.off], |
| 186 | }; |
| 187 | } |
| 188 | } = .{}, |
| 189 | |
| 133 | 190 | fn relativeToNodeIndex(self: *Writer, offset: i32) Ast.Node.Index { |
| 134 | 191 | return @as(Ast.Node.Index, @bitCast(offset + @as(i32, @bitCast(self.parent_decl_node)))); |
| 135 | 192 | } |
| ... | ... | @@ -2590,8 +2647,8 @@ const Writer = struct { |
| 2590 | 2647 | .lazy = src, |
| 2591 | 2648 | }; |
| 2592 | 2649 | const src_span = src_loc.span(self.gpa) catch unreachable; |
| 2593 | | const start = std.zig.findLineColumn(tree.source, src_span.start); |
| 2594 | | const end = std.zig.findLineColumn(tree.source, src_span.end); |
| 2650 | const start = self.line_col_cursor.find(tree.source, src_span.start); |
| 2651 | const end = self.line_col_cursor.find(tree.source, src_span.end); |
| 2595 | 2652 | try stream.print("{s}:{d}:{d} to :{d}:{d}", .{ |
| 2596 | 2653 | @tagName(src), start.line + 1, start.column + 1, |
| 2597 | 2654 | end.line + 1, end.column + 1, |