| author | |
| committer | |
| log | 1e2aab2f97843572138076b21e2efb568e060a33 |
| tree | d80cc061081c998926b4707035df03b6495cc854 |
| parent | 3c98e2c826e1a8650090a889cf3a1560335b2968 |
147 files changed, 3557 insertions(+), 4007 deletions(-)
lib/compiler/aro/aro/Diagnostics.zig+3-3| ... | ... | @@ -535,13 +535,13 @@ fn tagKind(d: *Diagnostics, tag: Tag, langopts: LangOpts) Kind { |
| 535 | 535 | } |
| 536 | 536 | |
| 537 | 537 | const MsgWriter = struct { |
| 538 | w: std.io.BufferedWriter(4096, std.fs.File.Writer), | |
| 538 | w: *std.fs.File.Writer, | |
| 539 | 539 | config: std.io.tty.Config, |
| 540 | 540 | |
| 541 | fn init(config: std.io.tty.Config) MsgWriter { | |
| 541 | fn init(config: std.io.tty.Config, buffer: []u8) MsgWriter { | |
| 542 | 542 | std.debug.lockStdErr(); |
| 543 | 543 | return .{ |
| 544 | .w = std.io.bufferedWriter(std.io.getStdErr().writer()), | |
| 544 | .w = std.fs.stderr().writer(buffer), | |
| 545 | 545 | .config = config, |
| 546 | 546 | }; |
| 547 | 547 | } |
lib/compiler/build_runner.zig+9-8| ... | ... | @@ -12,6 +12,7 @@ const Watch = std.Build.Watch; |
| 12 | 12 | const Fuzz = std.Build.Fuzz; |
| 13 | 13 | const Allocator = std.mem.Allocator; |
| 14 | 14 | const fatal = std.process.fatal; |
| 15 | const Writer = std.io.Writer; | |
| 15 | 16 | const runner = @This(); |
| 16 | 17 | |
| 17 | 18 | pub const root = @import("@build"); |
| ... | ... | @@ -773,7 +774,7 @@ const PrintNode = struct { |
| 773 | 774 | last: bool = false, |
| 774 | 775 | }; |
| 775 | 776 | |
| 776 | fn printPrefix(node: *PrintNode, stderr: *std.io.BufferedWriter, ttyconf: std.io.tty.Config) !void { | |
| 777 | fn printPrefix(node: *PrintNode, stderr: *Writer, ttyconf: std.io.tty.Config) !void { | |
| 777 | 778 | const parent = node.parent orelse return; |
| 778 | 779 | if (parent.parent == null) return; |
| 779 | 780 | try printPrefix(parent, stderr, ttyconf); |
| ... | ... | @@ -787,7 +788,7 @@ fn printPrefix(node: *PrintNode, stderr: *std.io.BufferedWriter, ttyconf: std.io |
| 787 | 788 | } |
| 788 | 789 | } |
| 789 | 790 | |
| 790 | fn printChildNodePrefix(stderr: *std.io.BufferedWriter, ttyconf: std.io.tty.Config) !void { | |
| 791 | fn printChildNodePrefix(stderr: *Writer, ttyconf: std.io.tty.Config) !void { | |
| 791 | 792 | try stderr.writeAll(switch (ttyconf) { |
| 792 | 793 | .no_color, .windows_api => "+- ", |
| 793 | 794 | .escape_codes => "\x1B\x28\x30\x6d\x71\x1B\x28\x42 ", // └─ |
| ... | ... | @@ -796,7 +797,7 @@ fn printChildNodePrefix(stderr: *std.io.BufferedWriter, ttyconf: std.io.tty.Conf |
| 796 | 797 | |
| 797 | 798 | fn printStepStatus( |
| 798 | 799 | s: *Step, |
| 799 | stderr: *std.io.BufferedWriter, | |
| 800 | stderr: *Writer, | |
| 800 | 801 | ttyconf: std.io.tty.Config, |
| 801 | 802 | run: *const Run, |
| 802 | 803 | ) !void { |
| ... | ... | @@ -876,7 +877,7 @@ fn printStepStatus( |
| 876 | 877 | |
| 877 | 878 | fn printStepFailure( |
| 878 | 879 | s: *Step, |
| 879 | stderr: *std.io.BufferedWriter, | |
| 880 | stderr: *Writer, | |
| 880 | 881 | ttyconf: std.io.tty.Config, |
| 881 | 882 | ) !void { |
| 882 | 883 | if (s.result_error_bundle.errorMessageCount() > 0) { |
| ... | ... | @@ -930,7 +931,7 @@ fn printTreeStep( |
| 930 | 931 | b: *std.Build, |
| 931 | 932 | s: *Step, |
| 932 | 933 | run: *const Run, |
| 933 | stderr: *std.io.BufferedWriter, | |
| 934 | stderr: *Writer, | |
| 934 | 935 | ttyconf: std.io.tty.Config, |
| 935 | 936 | parent_node: *PrintNode, |
| 936 | 937 | step_stack: *std.AutoArrayHashMapUnmanaged(*Step, void), |
| ... | ... | @@ -1188,7 +1189,7 @@ pub fn printErrorMessages( |
| 1188 | 1189 | gpa: Allocator, |
| 1189 | 1190 | failing_step: *Step, |
| 1190 | 1191 | options: std.zig.ErrorBundle.RenderOptions, |
| 1191 | stderr: *std.io.BufferedWriter, | |
| 1192 | stderr: *Writer, | |
| 1192 | 1193 | prominent_compile_errors: bool, |
| 1193 | 1194 | ) !void { |
| 1194 | 1195 | // Provide context for where these error messages are coming from by |
| ... | ... | @@ -1241,7 +1242,7 @@ pub fn printErrorMessages( |
| 1241 | 1242 | } |
| 1242 | 1243 | } |
| 1243 | 1244 | |
| 1244 | fn steps(builder: *std.Build, bw: *std.io.BufferedWriter) !void { | |
| 1245 | fn steps(builder: *std.Build, bw: *Writer) !void { | |
| 1245 | 1246 | const allocator = builder.allocator; |
| 1246 | 1247 | for (builder.top_level_steps.values()) |top_level_step| { |
| 1247 | 1248 | const name = if (&top_level_step.step == builder.default_step) |
| ... | ... | @@ -1254,7 +1255,7 @@ fn steps(builder: *std.Build, bw: *std.io.BufferedWriter) !void { |
| 1254 | 1255 | |
| 1255 | 1256 | var stdio_buffer: [256]u8 = undefined; |
| 1256 | 1257 | |
| 1257 | fn usage(b: *std.Build, bw: *std.io.BufferedWriter) !void { | |
| 1258 | fn usage(b: *std.Build, bw: *Writer) !void { | |
| 1258 | 1259 | try bw.print( |
| 1259 | 1260 | \\Usage: {s} build [steps] [options] |
| 1260 | 1261 | \\ |
lib/docs/wasm/main.zig+2-1| ... | ... | @@ -5,6 +5,7 @@ const Ast = std.zig.Ast; |
| 5 | 5 | const Walk = @import("Walk"); |
| 6 | 6 | const markdown = @import("markdown.zig"); |
| 7 | 7 | const Decl = Walk.Decl; |
| 8 | const Writer = std.io.Writer; | |
| 8 | 9 | |
| 9 | 10 | const fileSourceHtml = @import("html_render.zig").fileSourceHtml; |
| 10 | 11 | const appendEscaped = @import("html_render.zig").appendEscaped; |
| ... | ... | @@ -702,7 +703,7 @@ fn render_docs( |
| 702 | 703 | r: markdown.Render, |
| 703 | 704 | doc: markdown.Document, |
| 704 | 705 | node: markdown.Document.Node.Index, |
| 705 | writer: *std.io.BufferedWriter, | |
| 706 | writer: *Writer, | |
| 706 | 707 | ) !void { |
| 707 | 708 | const decl_index_ptr: *const Decl.Index = @alignCast(@ptrCast(r.context)); |
| 708 | 709 | const data = doc.nodes.items(.data)[@intFromEnum(node)]; |
lib/docs/wasm/markdown/Document.zig+2-1| ... | ... | @@ -5,6 +5,7 @@ const builtin = @import("builtin"); |
| 5 | 5 | const assert = std.debug.assert; |
| 6 | 6 | const Allocator = std.mem.Allocator; |
| 7 | 7 | const Render = @import("Render.zig"); |
| 8 | const Writer = std.io.Writer; | |
| 8 | 9 | |
| 9 | 10 | nodes: Node.List.Slice, |
| 10 | 11 | extra: []u32, |
| ... | ... | @@ -160,7 +161,7 @@ pub fn deinit(doc: *Document, allocator: Allocator) void { |
| 160 | 161 | } |
| 161 | 162 | |
| 162 | 163 | /// Renders a document directly to a writer using the default renderer. |
| 163 | pub fn render(doc: Document, writer: *std.io.BufferedWriter) @TypeOf(writer).Error!void { | |
| 164 | pub fn render(doc: Document, writer: *Writer) Writer.Error!void { | |
| 164 | 165 | const renderer: Render(@TypeOf(writer), void) = .{ .context = {} }; |
| 165 | 166 | try renderer.render(doc, writer); |
| 166 | 167 | } |
lib/docs/wasm/markdown/Render.zig+10-8| ... | ... | @@ -5,6 +5,8 @@ |
| 5 | 5 | //! for node types for which they require no special rendering. |
| 6 | 6 | |
| 7 | 7 | const std = @import("std"); |
| 8 | const Writer = std.io.Writer; | |
| 9 | ||
| 8 | 10 | const Document = @import("Document.zig"); |
| 9 | 11 | const Node = Document.Node; |
| 10 | 12 | const Render = @This(); |
| ... | ... | @@ -14,10 +16,10 @@ renderFn: *const fn ( |
| 14 | 16 | r: Render, |
| 15 | 17 | doc: Document, |
| 16 | 18 | node: Node.Index, |
| 17 | writer: *std.io.BufferedWriter, | |
| 18 | ) std.io.Writer.Error!void = renderDefault, | |
| 19 | writer: *Writer, | |
| 20 | ) Writer.Error!void = renderDefault, | |
| 19 | 21 | |
| 20 | pub fn render(r: Render, doc: Document, writer: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 22 | pub fn render(r: Render, doc: Document, writer: *Writer) Writer.Error!void { | |
| 21 | 23 | try r.renderFn(r, doc, .root, writer); |
| 22 | 24 | } |
| 23 | 25 | |
| ... | ... | @@ -25,8 +27,8 @@ pub fn renderDefault( |
| 25 | 27 | r: Render, |
| 26 | 28 | doc: Document, |
| 27 | 29 | node: Node.Index, |
| 28 | writer: *std.io.BufferedWriter, | |
| 29 | ) std.io.Writer.Error!void { | |
| 30 | writer: *Writer, | |
| 31 | ) Writer.Error!void { | |
| 30 | 32 | const data = doc.nodes.items(.data)[@intFromEnum(node)]; |
| 31 | 33 | switch (doc.nodes.items(.tag)[@intFromEnum(node)]) { |
| 32 | 34 | .root => { |
| ... | ... | @@ -183,8 +185,8 @@ pub fn renderDefault( |
| 183 | 185 | pub fn renderInlineNodeText( |
| 184 | 186 | doc: Document, |
| 185 | 187 | node: Node.Index, |
| 186 | writer: *std.io.BufferedWriter, | |
| 187 | ) std.io.Writer.Error!void { | |
| 188 | writer: *Writer, | |
| 189 | ) Writer.Error!void { | |
| 188 | 190 | const data = doc.nodes.items(.data)[@intFromEnum(node)]; |
| 189 | 191 | switch (doc.nodes.items(.tag)[@intFromEnum(node)]) { |
| 190 | 192 | .root, |
| ... | ... | @@ -229,7 +231,7 @@ pub fn fmtHtml(bytes: []const u8) std.fmt.Formatter(formatHtml) { |
| 229 | 231 | return .{ .data = bytes }; |
| 230 | 232 | } |
| 231 | 233 | |
| 232 | fn formatHtml(bytes: []const u8, writer: *std.io.BufferedWriter, comptime fmt: []const u8) !void { | |
| 234 | fn formatHtml(bytes: []const u8, writer: *Writer, comptime fmt: []const u8) !void { | |
| 233 | 235 | _ = fmt; |
| 234 | 236 | for (bytes) |b| { |
| 235 | 237 | switch (b) { |
lib/std/Build/Cache.zig+2-3| ... | ... | @@ -286,9 +286,8 @@ pub const HashHelper = struct { |
| 286 | 286 | |
| 287 | 287 | pub fn binToHex(bin_digest: BinDigest) HexDigest { |
| 288 | 288 | var out_digest: HexDigest = undefined; |
| 289 | var bw: std.io.BufferedWriter = undefined; | |
| 290 | bw.initFixed(&out_digest); | |
| 291 | bw.printHex(&bin_digest, .lower) catch unreachable; | |
| 289 | var w: std.io.Writer = .fixed(&out_digest); | |
| 290 | w.printHex(&bin_digest, .lower) catch unreachable; | |
| 292 | 291 | return out_digest; |
| 293 | 292 | } |
| 294 | 293 |
lib/std/Build/Cache/Directory.zig+3-7| ... | ... | @@ -55,15 +55,11 @@ pub fn closeAndFree(self: *Directory, gpa: Allocator) void { |
| 55 | 55 | self.* = undefined; |
| 56 | 56 | } |
| 57 | 57 | |
| 58 | pub fn format( | |
| 59 | self: Directory, | |
| 60 | bw: *std.io.BufferedWriter, | |
| 61 | comptime fmt_string: []const u8, | |
| 62 | ) !void { | |
| 58 | pub fn format(self: Directory, w: *std.io.Writer, comptime fmt_string: []const u8) !void { | |
| 63 | 59 | if (fmt_string.len != 0) fmt.invalidFmtError(fmt_string, self); |
| 64 | 60 | if (self.path) |p| { |
| 65 | try bw.writeAll(p); | |
| 66 | try bw.writeAll(fs.path.sep_str); | |
| 61 | try w.writeAll(p); | |
| 62 | try w.writeAll(fs.path.sep_str); | |
| 67 | 63 | } |
| 68 | 64 | } |
| 69 | 65 |
lib/std/Build/Cache/Path.zig+10-14| ... | ... | @@ -140,11 +140,7 @@ pub fn toStringZ(p: Path, allocator: Allocator) Allocator.Error![:0]u8 { |
| 140 | 140 | return std.fmt.allocPrintZ(allocator, "{f}", .{p}); |
| 141 | 141 | } |
| 142 | 142 | |
| 143 | pub fn format( | |
| 144 | self: Path, | |
| 145 | bw: *std.io.BufferedWriter, | |
| 146 | comptime fmt_string: []const u8, | |
| 147 | ) !void { | |
| 143 | pub fn format(self: Path, w: *std.io.Writer, comptime fmt_string: []const u8) !void { | |
| 148 | 144 | if (fmt_string.len == 1) { |
| 149 | 145 | // Quote-escape the string. |
| 150 | 146 | const stringEscape = std.zig.stringEscape; |
| ... | ... | @@ -154,33 +150,33 @@ pub fn format( |
| 154 | 150 | else => @compileError("unsupported format string: " ++ fmt_string), |
| 155 | 151 | }; |
| 156 | 152 | if (self.root_dir.path) |p| { |
| 157 | try stringEscape(p, bw, f); | |
| 158 | if (self.sub_path.len > 0) try stringEscape(fs.path.sep_str, bw, f); | |
| 153 | try stringEscape(p, w, f); | |
| 154 | if (self.sub_path.len > 0) try stringEscape(fs.path.sep_str, w, f); | |
| 159 | 155 | } |
| 160 | 156 | if (self.sub_path.len > 0) { |
| 161 | try stringEscape(self.sub_path, bw, f); | |
| 157 | try stringEscape(self.sub_path, w, f); | |
| 162 | 158 | } |
| 163 | 159 | return; |
| 164 | 160 | } |
| 165 | 161 | if (fmt_string.len > 0) |
| 166 | 162 | std.fmt.invalidFmtError(fmt_string, self); |
| 167 | 163 | if (std.fs.path.isAbsolute(self.sub_path)) { |
| 168 | try bw.writeAll(self.sub_path); | |
| 164 | try w.writeAll(self.sub_path); | |
| 169 | 165 | return; |
| 170 | 166 | } |
| 171 | 167 | if (self.root_dir.path) |p| { |
| 172 | try bw.writeAll(p); | |
| 168 | try w.writeAll(p); | |
| 173 | 169 | if (self.sub_path.len > 0) { |
| 174 | try bw.writeAll(fs.path.sep_str); | |
| 175 | try bw.writeAll(self.sub_path); | |
| 170 | try w.writeAll(fs.path.sep_str); | |
| 171 | try w.writeAll(self.sub_path); | |
| 176 | 172 | } |
| 177 | 173 | return; |
| 178 | 174 | } |
| 179 | 175 | if (self.sub_path.len > 0) { |
| 180 | try bw.writeAll(self.sub_path); | |
| 176 | try w.writeAll(self.sub_path); | |
| 181 | 177 | return; |
| 182 | 178 | } |
| 183 | try bw.writeByte('.'); | |
| 179 | try w.writeByte('.'); | |
| 184 | 180 | } |
| 185 | 181 | |
| 186 | 182 | pub fn eql(self: Path, other: Path) bool { |
lib/std/Build/Step/CheckObject.zig+39-44| ... | ... | @@ -6,6 +6,7 @@ const macho = std.macho; |
| 6 | 6 | const math = std.math; |
| 7 | 7 | const mem = std.mem; |
| 8 | 8 | const testing = std.testing; |
| 9 | const Writer = std.io.Writer; | |
| 9 | 10 | |
| 10 | 11 | const CheckObject = @This(); |
| 11 | 12 | |
| ... | ... | @@ -231,7 +232,7 @@ const ComputeCompareExpected = struct { |
| 231 | 232 | |
| 232 | 233 | pub fn format( |
| 233 | 234 | value: ComputeCompareExpected, |
| 234 | bw: *std.io.BufferedWriter, | |
| 235 | bw: *Writer, | |
| 235 | 236 | comptime fmt: []const u8, |
| 236 | 237 | ) !void { |
| 237 | 238 | if (fmt.len != 0) std.fmt.invalidFmtError(fmt, value); |
| ... | ... | @@ -619,7 +620,7 @@ fn make(step: *Step, make_options: Step.MakeOptions) !void { |
| 619 | 620 | |
| 620 | 621 | fn formatMessageString( |
| 621 | 622 | ctx: Ctx, |
| 622 | bw: *std.io.BufferedWriter, | |
| 623 | bw: *Writer, | |
| 623 | 624 | comptime unused_fmt_string: []const u8, |
| 624 | 625 | ) !void { |
| 625 | 626 | _ = unused_fmt_string; |
| ... | ... | @@ -813,7 +814,7 @@ const MachODumper = struct { |
| 813 | 814 | return null; |
| 814 | 815 | } |
| 815 | 816 | |
| 816 | fn dumpHeader(hdr: macho.mach_header_64, bw: *std.io.BufferedWriter) !void { | |
| 817 | fn dumpHeader(hdr: macho.mach_header_64, bw: *Writer) !void { | |
| 817 | 818 | const cputype = switch (hdr.cputype) { |
| 818 | 819 | macho.CPU_TYPE_ARM64 => "ARM64", |
| 819 | 820 | macho.CPU_TYPE_X86_64 => "X86_64", |
| ... | ... | @@ -881,7 +882,7 @@ const MachODumper = struct { |
| 881 | 882 | try bw.writeByte('\n'); |
| 882 | 883 | } |
| 883 | 884 | |
| 884 | fn dumpLoadCommand(lc: macho.LoadCommandIterator.LoadCommand, index: usize, bw: *std.io.BufferedWriter) !void { | |
| 885 | fn dumpLoadCommand(lc: macho.LoadCommandIterator.LoadCommand, index: usize, bw: *Writer) !void { | |
| 885 | 886 | // print header first |
| 886 | 887 | try bw.print( |
| 887 | 888 | \\LC {d} |
| ... | ... | @@ -1107,7 +1108,7 @@ const MachODumper = struct { |
| 1107 | 1108 | } |
| 1108 | 1109 | } |
| 1109 | 1110 | |
| 1110 | fn dumpSymtab(ctx: ObjectContext, bw: *std.io.BufferedWriter) !void { | |
| 1111 | fn dumpSymtab(ctx: ObjectContext, bw: *Writer) !void { | |
| 1111 | 1112 | try bw.writeAll(symtab_label ++ "\n"); |
| 1112 | 1113 | |
| 1113 | 1114 | for (ctx.symtab.items) |sym| { |
| ... | ... | @@ -1178,7 +1179,7 @@ const MachODumper = struct { |
| 1178 | 1179 | } |
| 1179 | 1180 | } |
| 1180 | 1181 | |
| 1181 | fn dumpIndirectSymtab(ctx: ObjectContext, bw: *std.io.BufferedWriter) !void { | |
| 1182 | fn dumpIndirectSymtab(ctx: ObjectContext, bw: *Writer) !void { | |
| 1182 | 1183 | try bw.writeAll(indirect_symtab_label ++ "\n"); |
| 1183 | 1184 | |
| 1184 | 1185 | var sects_buffer: [3]macho.section_64 = undefined; |
| ... | ... | @@ -1227,7 +1228,7 @@ const MachODumper = struct { |
| 1227 | 1228 | } |
| 1228 | 1229 | } |
| 1229 | 1230 | |
| 1230 | fn dumpRebaseInfo(ctx: ObjectContext, data: []const u8, bw: *std.io.BufferedWriter) !void { | |
| 1231 | fn dumpRebaseInfo(ctx: ObjectContext, data: []const u8, bw: *Writer) !void { | |
| 1231 | 1232 | var rebases: std.ArrayList(u64) = .init(ctx.gpa); |
| 1232 | 1233 | defer rebases.deinit(); |
| 1233 | 1234 | try ctx.parseRebaseInfo(data, &rebases); |
| ... | ... | @@ -1324,7 +1325,7 @@ const MachODumper = struct { |
| 1324 | 1325 | }; |
| 1325 | 1326 | }; |
| 1326 | 1327 | |
| 1327 | fn dumpBindInfo(ctx: ObjectContext, data: []const u8, bw: *std.io.BufferedWriter) !void { | |
| 1328 | fn dumpBindInfo(ctx: ObjectContext, data: []const u8, bw: *Writer) !void { | |
| 1328 | 1329 | var bindings: std.ArrayList(Binding) = .init(ctx.gpa); |
| 1329 | 1330 | defer { |
| 1330 | 1331 | for (bindings.items) |*b| { |
| ... | ... | @@ -1348,8 +1349,7 @@ const MachODumper = struct { |
| 1348 | 1349 | } |
| 1349 | 1350 | |
| 1350 | 1351 | fn parseBindInfo(ctx: ObjectContext, data: []const u8, bindings: *std.ArrayList(Binding)) !void { |
| 1351 | var br: std.io.Reader = undefined; | |
| 1352 | br.initFixed(@constCast(data)); | |
| 1352 | var br: std.io.Reader = .fixed(data); | |
| 1353 | 1353 | |
| 1354 | 1354 | var seg_id: ?u8 = null; |
| 1355 | 1355 | var tag: Binding.Tag = .self; |
| ... | ... | @@ -1439,15 +1439,14 @@ const MachODumper = struct { |
| 1439 | 1439 | } else |_| {} |
| 1440 | 1440 | } |
| 1441 | 1441 | |
| 1442 | fn dumpExportsTrie(ctx: ObjectContext, data: []const u8, bw: *std.io.BufferedWriter) !void { | |
| 1442 | fn dumpExportsTrie(ctx: ObjectContext, data: []const u8, bw: *Writer) !void { | |
| 1443 | 1443 | const seg = ctx.getSegmentByName("__TEXT") orelse return; |
| 1444 | 1444 | |
| 1445 | 1445 | var arena = std.heap.ArenaAllocator.init(ctx.gpa); |
| 1446 | 1446 | defer arena.deinit(); |
| 1447 | 1447 | |
| 1448 | 1448 | var exports: std.ArrayList(Export) = .init(arena.allocator()); |
| 1449 | var br: std.io.Reader = undefined; | |
| 1450 | br.initFixed(@constCast(data)); | |
| 1449 | var br: std.io.Reader = .fixed(data); | |
| 1451 | 1450 | try parseTrieNode(arena.allocator(), &br, "", &exports); |
| 1452 | 1451 | |
| 1453 | 1452 | mem.sort(Export, exports.items, {}, Export.lessThan); |
| ... | ... | @@ -1577,7 +1576,7 @@ const MachODumper = struct { |
| 1577 | 1576 | } |
| 1578 | 1577 | } |
| 1579 | 1578 | |
| 1580 | fn dumpSection(ctx: ObjectContext, sect: macho.section_64, bw: *std.io.BufferedWriter) !void { | |
| 1579 | fn dumpSection(ctx: ObjectContext, sect: macho.section_64, bw: *Writer) !void { | |
| 1581 | 1580 | const data = ctx.data[sect.offset..][0..sect.size]; |
| 1582 | 1581 | try bw.print("{s}", .{data}); |
| 1583 | 1582 | } |
| ... | ... | @@ -1704,8 +1703,7 @@ const ElfDumper = struct { |
| 1704 | 1703 | |
| 1705 | 1704 | fn parseAndDumpArchive(step: *Step, check: Check, bytes: []const u8) ![]const u8 { |
| 1706 | 1705 | const gpa = step.owner.allocator; |
| 1707 | var br: std.io.Reader = undefined; | |
| 1708 | br.initFixed(@constCast(bytes)); | |
| 1706 | var br: std.io.Reader = .fixed(bytes); | |
| 1709 | 1707 | |
| 1710 | 1708 | if (!mem.eql(u8, try br.takeArray(elf.ARMAG.len), elf.ARMAG)) return error.InvalidArchiveMagicNumber; |
| 1711 | 1709 | |
| ... | ... | @@ -1779,8 +1777,7 @@ const ElfDumper = struct { |
| 1779 | 1777 | } |
| 1780 | 1778 | |
| 1781 | 1779 | fn parseSymtab(ctx: *ArchiveContext, data: []const u8, ptr_width: enum { p32, p64 }) !void { |
| 1782 | var br: std.io.Reader = undefined; | |
| 1783 | br.initFixed(@constCast(data)); | |
| 1780 | var br: std.io.Reader = .fixed(data); | |
| 1784 | 1781 | const num = switch (ptr_width) { |
| 1785 | 1782 | .p32 => try br.takeInt(u32, .big), |
| 1786 | 1783 | .p64 => try br.takeInt(u64, .big), |
| ... | ... | @@ -1807,7 +1804,7 @@ const ElfDumper = struct { |
| 1807 | 1804 | } |
| 1808 | 1805 | } |
| 1809 | 1806 | |
| 1810 | fn dumpSymtab(ctx: ArchiveContext, bw: *std.io.BufferedWriter) !void { | |
| 1807 | fn dumpSymtab(ctx: ArchiveContext, bw: *Writer) !void { | |
| 1811 | 1808 | var symbols: std.AutoArrayHashMap(usize, std.ArrayList([]const u8)) = .init(ctx.gpa); |
| 1812 | 1809 | defer { |
| 1813 | 1810 | for (symbols.values()) |*value| value.deinit(); |
| ... | ... | @@ -1827,7 +1824,7 @@ const ElfDumper = struct { |
| 1827 | 1824 | } |
| 1828 | 1825 | } |
| 1829 | 1826 | |
| 1830 | fn dumpObjects(ctx: ArchiveContext, step: *Step, check: Check, bw: *std.io.BufferedWriter) !void { | |
| 1827 | fn dumpObjects(ctx: ArchiveContext, step: *Step, check: Check, bw: *Writer) !void { | |
| 1831 | 1828 | for (ctx.objects.values()) |object| { |
| 1832 | 1829 | try bw.print("object {s}\n", .{object.name}); |
| 1833 | 1830 | const output = try parseAndDumpObject(step, check, object.data); |
| ... | ... | @@ -1850,8 +1847,7 @@ const ElfDumper = struct { |
| 1850 | 1847 | |
| 1851 | 1848 | fn parseAndDumpObject(step: *Step, check: Check, bytes: []const u8) ![]const u8 { |
| 1852 | 1849 | const gpa = step.owner.allocator; |
| 1853 | var br: std.io.Reader = undefined; | |
| 1854 | br.initFixed(@constCast(bytes)); | |
| 1850 | var br: std.io.Reader = .fixed(bytes); | |
| 1855 | 1851 | |
| 1856 | 1852 | const hdr = try br.takeStruct(elf.Elf64_Ehdr); |
| 1857 | 1853 | if (!mem.eql(u8, hdr.e_ident[0..4], "\x7fELF")) return error.InvalidMagicNumber; |
| ... | ... | @@ -1944,13 +1940,13 @@ const ElfDumper = struct { |
| 1944 | 1940 | symtab: Symtab, |
| 1945 | 1941 | dysymtab: Symtab, |
| 1946 | 1942 | |
| 1947 | fn dumpHeader(ctx: ObjectContext, bw: *std.io.BufferedWriter) !void { | |
| 1943 | fn dumpHeader(ctx: ObjectContext, bw: *Writer) !void { | |
| 1948 | 1944 | try bw.writeAll("header\n"); |
| 1949 | 1945 | try bw.print("type {s}\n", .{@tagName(ctx.hdr.e_type)}); |
| 1950 | 1946 | try bw.print("entry {x}\n", .{ctx.hdr.e_entry}); |
| 1951 | 1947 | } |
| 1952 | 1948 | |
| 1953 | fn dumpPhdrs(ctx: ObjectContext, bw: *std.io.BufferedWriter) !void { | |
| 1949 | fn dumpPhdrs(ctx: ObjectContext, bw: *Writer) !void { | |
| 1954 | 1950 | if (ctx.phdrs.len == 0) return; |
| 1955 | 1951 | |
| 1956 | 1952 | try bw.writeAll("program headers\n"); |
| ... | ... | @@ -1989,7 +1985,7 @@ const ElfDumper = struct { |
| 1989 | 1985 | } |
| 1990 | 1986 | } |
| 1991 | 1987 | |
| 1992 | fn dumpShdrs(ctx: ObjectContext, bw: *std.io.BufferedWriter) !void { | |
| 1988 | fn dumpShdrs(ctx: ObjectContext, bw: *Writer) !void { | |
| 1993 | 1989 | if (ctx.shdrs.len == 0) return; |
| 1994 | 1990 | |
| 1995 | 1991 | try bw.writeAll("section headers\n"); |
| ... | ... | @@ -2006,7 +2002,7 @@ const ElfDumper = struct { |
| 2006 | 2002 | } |
| 2007 | 2003 | } |
| 2008 | 2004 | |
| 2009 | fn dumpDynamicSection(ctx: ObjectContext, shndx: usize, bw: *std.io.BufferedWriter) !void { | |
| 2005 | fn dumpDynamicSection(ctx: ObjectContext, shndx: usize, bw: *Writer) !void { | |
| 2010 | 2006 | const shdr = ctx.shdrs[shndx]; |
| 2011 | 2007 | const strtab = ctx.getSectionContents(shdr.sh_link); |
| 2012 | 2008 | const data = ctx.getSectionContents(shndx); |
| ... | ... | @@ -2144,7 +2140,7 @@ const ElfDumper = struct { |
| 2144 | 2140 | } |
| 2145 | 2141 | } |
| 2146 | 2142 | |
| 2147 | fn dumpSymtab(ctx: ObjectContext, comptime @"type": enum { symtab, dysymtab }, bw: *std.io.BufferedWriter) !void { | |
| 2143 | fn dumpSymtab(ctx: ObjectContext, comptime @"type": enum { symtab, dysymtab }, bw: *Writer) !void { | |
| 2148 | 2144 | const symtab = switch (@"type") { |
| 2149 | 2145 | .symtab => ctx.symtab, |
| 2150 | 2146 | .dysymtab => ctx.dysymtab, |
| ... | ... | @@ -2226,7 +2222,7 @@ const ElfDumper = struct { |
| 2226 | 2222 | } |
| 2227 | 2223 | } |
| 2228 | 2224 | |
| 2229 | fn dumpSection(ctx: ObjectContext, shndx: usize, bw: *std.io.BufferedWriter) !void { | |
| 2225 | fn dumpSection(ctx: ObjectContext, shndx: usize, bw: *Writer) !void { | |
| 2230 | 2226 | const data = ctx.getSectionContents(shndx); |
| 2231 | 2227 | try bw.print("{s}", .{data}); |
| 2232 | 2228 | } |
| ... | ... | @@ -2276,7 +2272,7 @@ const ElfDumper = struct { |
| 2276 | 2272 | |
| 2277 | 2273 | fn formatShType( |
| 2278 | 2274 | sh_type: u32, |
| 2279 | bw: *std.io.BufferedWriter, | |
| 2275 | bw: *Writer, | |
| 2280 | 2276 | comptime unused_fmt_string: []const u8, |
| 2281 | 2277 | ) !void { |
| 2282 | 2278 | _ = unused_fmt_string; |
| ... | ... | @@ -2321,7 +2317,7 @@ const ElfDumper = struct { |
| 2321 | 2317 | |
| 2322 | 2318 | fn formatPhType( |
| 2323 | 2319 | ph_type: u32, |
| 2324 | bw: *std.io.BufferedWriter, | |
| 2320 | bw: *Writer, | |
| 2325 | 2321 | comptime unused_fmt_string: []const u8, |
| 2326 | 2322 | ) !void { |
| 2327 | 2323 | _ = unused_fmt_string; |
| ... | ... | @@ -2353,8 +2349,7 @@ const WasmDumper = struct { |
| 2353 | 2349 | |
| 2354 | 2350 | fn parseAndDump(step: *Step, check: Check, bytes: []const u8) ![]const u8 { |
| 2355 | 2351 | const gpa = step.owner.allocator; |
| 2356 | var br: std.io.Reader = undefined; | |
| 2357 | br.initFixed(@constCast(bytes)); | |
| 2352 | var br: std.io.Reader = .fixed(bytes); | |
| 2358 | 2353 | |
| 2359 | 2354 | const buf = try br.takeArray(8); |
| 2360 | 2355 | if (!mem.eql(u8, buf[0..4], &std.wasm.magic)) return error.InvalidMagicByte; |
| ... | ... | @@ -2376,12 +2371,12 @@ const WasmDumper = struct { |
| 2376 | 2371 | step: *Step, |
| 2377 | 2372 | check: Check, |
| 2378 | 2373 | br: *std.io.Reader, |
| 2379 | bw: *std.io.BufferedWriter, | |
| 2374 | bw: *Writer, | |
| 2380 | 2375 | ) !void { |
| 2381 | 2376 | var section_br: std.io.Reader = undefined; |
| 2382 | 2377 | switch (check.kind) { |
| 2383 | 2378 | .headers => while (br.takeEnum(std.wasm.Section, .little)) |section| { |
| 2384 | section_br.initFixed(try br.take(try br.takeLeb128(u32))); | |
| 2379 | section_br = .fixed(try br.take(try br.takeLeb128(u32))); | |
| 2385 | 2380 | try parseAndDumpSection(step, section, &section_br, bw); |
| 2386 | 2381 | } else |err| switch (err) { |
| 2387 | 2382 | error.InvalidEnumTag => return step.fail("invalid section id", .{}), |
| ... | ... | @@ -2396,7 +2391,7 @@ const WasmDumper = struct { |
| 2396 | 2391 | step: *Step, |
| 2397 | 2392 | section: std.wasm.Section, |
| 2398 | 2393 | br: *std.io.Reader, |
| 2399 | bw: *std.io.BufferedWriter, | |
| 2394 | bw: *Writer, | |
| 2400 | 2395 | ) !void { |
| 2401 | 2396 | try bw.print( |
| 2402 | 2397 | \\Section {s} |
| ... | ... | @@ -2444,7 +2439,7 @@ const WasmDumper = struct { |
| 2444 | 2439 | } |
| 2445 | 2440 | } |
| 2446 | 2441 | |
| 2447 | fn parseSection(step: *Step, section: std.wasm.Section, br: *std.io.Reader, entries: u32, bw: *std.io.BufferedWriter) !void { | |
| 2442 | fn parseSection(step: *Step, section: std.wasm.Section, br: *std.io.Reader, entries: u32, bw: *Writer) !void { | |
| 2448 | 2443 | switch (section) { |
| 2449 | 2444 | .type => { |
| 2450 | 2445 | var i: u32 = 0; |
| ... | ... | @@ -2575,7 +2570,7 @@ const WasmDumper = struct { |
| 2575 | 2570 | } |
| 2576 | 2571 | } |
| 2577 | 2572 | |
| 2578 | fn parseDumpType(step: *Step, comptime E: type, br: *std.io.Reader, bw: *std.io.BufferedWriter) !E { | |
| 2573 | fn parseDumpType(step: *Step, comptime E: type, br: *std.io.Reader, bw: *Writer) !E { | |
| 2579 | 2574 | const tag = br.takeEnum(E, .little) catch |err| switch (err) { |
| 2580 | 2575 | error.InvalidEnumTag => return step.fail("invalid wasm type value", .{}), |
| 2581 | 2576 | else => |e| return e, |
| ... | ... | @@ -2584,7 +2579,7 @@ const WasmDumper = struct { |
| 2584 | 2579 | return tag; |
| 2585 | 2580 | } |
| 2586 | 2581 | |
| 2587 | fn parseDumpLimits(br: *std.io.Reader, bw: *std.io.BufferedWriter) !void { | |
| 2582 | fn parseDumpLimits(br: *std.io.Reader, bw: *Writer) !void { | |
| 2588 | 2583 | const flags = try br.takeLeb128(u8); |
| 2589 | 2584 | const min = try br.takeLeb128(u32); |
| 2590 | 2585 | |
| ... | ... | @@ -2592,7 +2587,7 @@ const WasmDumper = struct { |
| 2592 | 2587 | if (flags != 0) try bw.print("max {x}\n", .{try br.takeLeb128(u32)}); |
| 2593 | 2588 | } |
| 2594 | 2589 | |
| 2595 | fn parseDumpInit(step: *Step, br: *std.io.Reader, bw: *std.io.BufferedWriter) !void { | |
| 2590 | fn parseDumpInit(step: *Step, br: *std.io.Reader, bw: *Writer) !void { | |
| 2596 | 2591 | const opcode = br.takeEnum(std.wasm.Opcode, .little) catch |err| switch (err) { |
| 2597 | 2592 | error.InvalidEnumTag => return step.fail("invalid wasm opcode", .{}), |
| 2598 | 2593 | else => |e| return e, |
| ... | ... | @@ -2612,14 +2607,14 @@ const WasmDumper = struct { |
| 2612 | 2607 | } |
| 2613 | 2608 | |
| 2614 | 2609 | /// https://webassembly.github.io/spec/core/appendix/custom.html |
| 2615 | fn parseDumpNames(step: *Step, br: *std.io.Reader, bw: *std.io.BufferedWriter) !void { | |
| 2610 | fn parseDumpNames(step: *Step, br: *std.io.Reader, bw: *Writer) !void { | |
| 2616 | 2611 | var subsection_br: std.io.Reader = undefined; |
| 2617 | 2612 | while (br.seek < br.buffer.len) { |
| 2618 | 2613 | switch (try parseDumpType(step, std.wasm.NameSubsection, br, bw)) { |
| 2619 | 2614 | // The module name subsection ... consists of a single name |
| 2620 | 2615 | // that is assigned to the module itself. |
| 2621 | 2616 | .module => { |
| 2622 | subsection_br.initFixed(try br.take(try br.takeLeb128(u32))); | |
| 2617 | subsection_br = .fixed(try br.take(try br.takeLeb128(u32))); | |
| 2623 | 2618 | const name = try subsection_br.take(try subsection_br.takeLeb128(u32)); |
| 2624 | 2619 | try bw.print( |
| 2625 | 2620 | \\name {s} |
| ... | ... | @@ -2631,7 +2626,7 @@ const WasmDumper = struct { |
| 2631 | 2626 | // The function name subsection ... consists of a name map |
| 2632 | 2627 | // assigning function names to function indices. |
| 2633 | 2628 | .function, .global, .data_segment => { |
| 2634 | subsection_br.initFixed(try br.take(try br.takeLeb128(u32))); | |
| 2629 | subsection_br = .fixed(try br.take(try br.takeLeb128(u32))); | |
| 2635 | 2630 | const entries = try br.takeLeb128(u32); |
| 2636 | 2631 | try bw.print( |
| 2637 | 2632 | \\names {d} |
| ... | ... | @@ -2661,7 +2656,7 @@ const WasmDumper = struct { |
| 2661 | 2656 | } |
| 2662 | 2657 | } |
| 2663 | 2658 | |
| 2664 | fn parseDumpProducers(br: *std.io.Reader, bw: *std.io.BufferedWriter) !void { | |
| 2659 | fn parseDumpProducers(br: *std.io.Reader, bw: *Writer) !void { | |
| 2665 | 2660 | const field_count = try br.takeLeb128(u32); |
| 2666 | 2661 | try bw.print( |
| 2667 | 2662 | \\fields {d} |
| ... | ... | @@ -2689,7 +2684,7 @@ const WasmDumper = struct { |
| 2689 | 2684 | } |
| 2690 | 2685 | } |
| 2691 | 2686 | |
| 2692 | fn parseDumpFeatures(br: *std.io.Reader, bw: *std.io.BufferedWriter) !void { | |
| 2687 | fn parseDumpFeatures(br: *std.io.Reader, bw: *Writer) !void { | |
| 2693 | 2688 | const feature_count = try br.takeLeb128(u32); |
| 2694 | 2689 | try bw.print( |
| 2695 | 2690 | \\features {d} |
lib/std/Build/Step/ConfigHeader.zig+8-7| ... | ... | @@ -2,6 +2,7 @@ const std = @import("std"); |
| 2 | 2 | const ConfigHeader = @This(); |
| 3 | 3 | const Step = std.Build.Step; |
| 4 | 4 | const Allocator = std.mem.Allocator; |
| 5 | const Writer = std.io.Writer; | |
| 5 | 6 | |
| 6 | 7 | pub const Style = union(enum) { |
| 7 | 8 | /// A configure format supported by autotools that uses `#undef foo` to |
| ... | ... | @@ -277,7 +278,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 277 | 278 | fn render_autoconf_undef( |
| 278 | 279 | step: *Step, |
| 279 | 280 | contents: []const u8, |
| 280 | bw: *std.io.BufferedWriter, | |
| 281 | bw: *Writer, | |
| 281 | 282 | values: std.StringArrayHashMap(Value), |
| 282 | 283 | src_path: []const u8, |
| 283 | 284 | ) !void { |
| ... | ... | @@ -382,7 +383,7 @@ fn render_autoconf_at( |
| 382 | 383 | fn render_cmake( |
| 383 | 384 | step: *Step, |
| 384 | 385 | contents: []const u8, |
| 385 | bw: *std.io.BufferedWriter, | |
| 386 | bw: *Writer, | |
| 386 | 387 | values: std.StringArrayHashMap(Value), |
| 387 | 388 | src_path: []const u8, |
| 388 | 389 | ) !void { |
| ... | ... | @@ -508,7 +509,7 @@ fn render_cmake( |
| 508 | 509 | |
| 509 | 510 | fn render_blank( |
| 510 | 511 | gpa: std.mem.Allocator, |
| 511 | bw: *std.io.BufferedWriter, | |
| 512 | bw: *Writer, | |
| 512 | 513 | defines: std.StringArrayHashMap(Value), |
| 513 | 514 | include_path: []const u8, |
| 514 | 515 | include_guard_override: ?[]const u8, |
| ... | ... | @@ -541,11 +542,11 @@ fn render_blank( |
| 541 | 542 | , .{include_guard_name}); |
| 542 | 543 | } |
| 543 | 544 | |
| 544 | fn render_nasm(bw: *std.io.BufferedWriter, defines: std.StringArrayHashMap(Value)) !void { | |
| 545 | fn render_nasm(bw: *Writer, defines: std.StringArrayHashMap(Value)) !void { | |
| 545 | 546 | for (defines.keys(), defines.values()) |name, value| try renderValueNasm(bw, name, value); |
| 546 | 547 | } |
| 547 | 548 | |
| 548 | fn renderValueC(bw: *std.io.BufferedWriter, name: []const u8, value: Value) !void { | |
| 549 | fn renderValueC(bw: *Writer, name: []const u8, value: Value) !void { | |
| 549 | 550 | switch (value) { |
| 550 | 551 | .undef => try bw.print("/* #undef {s} */\n", .{name}), |
| 551 | 552 | .defined => try bw.print("#define {s}\n", .{name}), |
| ... | ... | @@ -557,7 +558,7 @@ fn renderValueC(bw: *std.io.BufferedWriter, name: []const u8, value: Value) !voi |
| 557 | 558 | } |
| 558 | 559 | } |
| 559 | 560 | |
| 560 | fn renderValueNasm(bw: *std.io.BufferedWriter, name: []const u8, value: Value) !void { | |
| 561 | fn renderValueNasm(bw: *Writer, name: []const u8, value: Value) !void { | |
| 561 | 562 | switch (value) { |
| 562 | 563 | .undef => try bw.print("; %undef {s}\n", .{name}), |
| 563 | 564 | .defined => try bw.print("%define {s}\n", .{name}), |
| ... | ... | @@ -570,7 +571,7 @@ fn renderValueNasm(bw: *std.io.BufferedWriter, name: []const u8, value: Value) ! |
| 570 | 571 | } |
| 571 | 572 | |
| 572 | 573 | fn expand_variables_autoconf_at( |
| 573 | bw: *std.io.BufferedWriter, | |
| 574 | bw: *Writer, | |
| 574 | 575 | contents: []const u8, |
| 575 | 576 | values: std.StringArrayHashMap(Value), |
| 576 | 577 | used: []bool, |
lib/std/Build/Step/Run.zig+7-11| ... | ... | @@ -1015,18 +1015,14 @@ fn populateGeneratedPaths( |
| 1015 | 1015 | } |
| 1016 | 1016 | } |
| 1017 | 1017 | |
| 1018 | fn formatTerm( | |
| 1019 | term: ?std.process.Child.Term, | |
| 1020 | bw: *std.io.BufferedWriter, | |
| 1021 | comptime fmt: []const u8, | |
| 1022 | ) !void { | |
| 1023 | _ = fmt; | |
| 1018 | fn formatTerm(term: ?std.process.Child.Term, w: *std.io.Writer, comptime fmt: []const u8) !void { | |
| 1019 | comptime assert(fmt.len == 0); | |
| 1024 | 1020 | if (term) |t| switch (t) { |
| 1025 | .Exited => |code| try bw.print("exited with code {}", .{code}), | |
| 1026 | .Signal => |sig| try bw.print("terminated with signal {}", .{sig}), | |
| 1027 | .Stopped => |sig| try bw.print("stopped with signal {}", .{sig}), | |
| 1028 | .Unknown => |code| try bw.print("terminated for unknown reason with code {}", .{code}), | |
| 1029 | } else try bw.writeAll("exited with any code"); | |
| 1021 | .Exited => |code| try w.print("exited with code {}", .{code}), | |
| 1022 | .Signal => |sig| try w.print("terminated with signal {}", .{sig}), | |
| 1023 | .Stopped => |sig| try w.print("stopped with signal {}", .{sig}), | |
| 1024 | .Unknown => |code| try w.print("terminated for unknown reason with code {}", .{code}), | |
| 1025 | } else try w.writeAll("exited with any code"); | |
| 1030 | 1026 | } |
| 1031 | 1027 | fn fmtTerm(term: ?std.process.Child.Term) std.fmt.Formatter(formatTerm) { |
| 1032 | 1028 | return .{ .data = term }; |
lib/std/Progress.zig+4-3| ... | ... | @@ -9,6 +9,7 @@ const Progress = @This(); |
| 9 | 9 | const posix = std.posix; |
| 10 | 10 | const is_big_endian = builtin.cpu.arch.endian() == .big; |
| 11 | 11 | const is_windows = builtin.os.tag == .windows; |
| 12 | const Writer = std.io.Writer; | |
| 12 | 13 | |
| 13 | 14 | /// `null` if the current node (and its children) should |
| 14 | 15 | /// not print on update() |
| ... | ... | @@ -607,7 +608,7 @@ pub fn unlockStdErr() void { |
| 607 | 608 | } |
| 608 | 609 | |
| 609 | 610 | /// Protected by `stderr_mutex`. |
| 610 | var stderr_buffered_writer: std.io.BufferedWriter = .{ | |
| 611 | var stderr_buffered_writer: Writer = .{ | |
| 611 | 612 | .unbuffered_writer = stderr_file_writer.interface(), |
| 612 | 613 | .buffer = &.{}, |
| 613 | 614 | }; |
| ... | ... | @@ -617,13 +618,13 @@ var stderr_file_writer: std.fs.File.Writer = .{ |
| 617 | 618 | .mode = .streaming, |
| 618 | 619 | }; |
| 619 | 620 | |
| 620 | /// Allows the caller to freely write to the returned `std.io.BufferedWriter`, | |
| 621 | /// Allows the caller to freely write to the returned `Writer`, | |
| 621 | 622 | /// initialized with `buffer`, until `unlockStderrWriter` is called. |
| 622 | 623 | /// |
| 623 | 624 | /// During the lock, any `std.Progress` information is cleared from the terminal. |
| 624 | 625 | /// |
| 625 | 626 | /// The lock is recursive; the same thread may hold the lock multiple times. |
| 626 | pub fn lockStderrWriter(buffer: []u8) *std.io.BufferedWriter { | |
| 627 | pub fn lockStderrWriter(buffer: []u8) *Writer { | |
| 627 | 628 | stderr_mutex.lock(); |
| 628 | 629 | clearWrittenWithEscapeCodes() catch {}; |
| 629 | 630 | if (is_windows) stderr_file_writer.file = .stderr(); |
lib/std/SemanticVersion.zig+1-1| ... | ... | @@ -152,7 +152,7 @@ fn parseNum(text: []const u8) error{ InvalidVersion, Overflow }!usize { |
| 152 | 152 | |
| 153 | 153 | pub fn format( |
| 154 | 154 | self: Version, |
| 155 | bw: *std.io.BufferedWriter, | |
| 155 | bw: *std.io.Writer, | |
| 156 | 156 | comptime fmt: []const u8, |
| 157 | 157 | ) !void { |
| 158 | 158 | if (fmt.len != 0) std.fmt.invalidFmtError(fmt, self); |
lib/std/Target.zig+1-1| ... | ... | @@ -301,7 +301,7 @@ pub const Os = struct { |
| 301 | 301 | |
| 302 | 302 | /// This function is defined to serialize a Zig source code representation of this |
| 303 | 303 | /// type, that, when parsed, will deserialize into the same data. |
| 304 | pub fn format(ver: WindowsVersion, bw: *std.io.BufferedWriter, comptime fmt_str: []const u8) std.io.Writer.Error!void { | |
| 304 | pub fn format(ver: WindowsVersion, bw: *std.io.Writer, comptime fmt_str: []const u8) std.io.Writer.Error!void { | |
| 305 | 305 | const maybe_name = std.enums.tagName(WindowsVersion, ver); |
| 306 | 306 | if (comptime std.mem.eql(u8, fmt_str, "s")) { |
| 307 | 307 | if (maybe_name) |name| |
lib/std/Uri.zig+7-7| ... | ... | @@ -5,6 +5,7 @@ const std = @import("std.zig"); |
| 5 | 5 | const testing = std.testing; |
| 6 | 6 | const Allocator = std.mem.Allocator; |
| 7 | 7 | const assert = std.debug.assert; |
| 8 | const Writer = std.io.Writer; | |
| 8 | 9 | |
| 9 | 10 | const Uri = @This(); |
| 10 | 11 | |
| ... | ... | @@ -84,7 +85,7 @@ pub const Component = union(enum) { |
| 84 | 85 | }; |
| 85 | 86 | } |
| 86 | 87 | |
| 87 | pub fn format(component: Component, bw: *std.io.BufferedWriter, comptime fmt: []const u8) std.io.Writer.Error!void { | |
| 88 | pub fn format(component: Component, bw: *Writer, comptime fmt: []const u8) Writer.Error!void { | |
| 88 | 89 | if (fmt.len == 0) { |
| 89 | 90 | try bw.print("std.Uri.Component{{ .{s} = \"{}\" }}", .{ |
| 90 | 91 | @tagName(component), |
| ... | ... | @@ -136,10 +137,10 @@ pub const Component = union(enum) { |
| 136 | 137 | } |
| 137 | 138 | |
| 138 | 139 | pub fn percentEncode( |
| 139 | bw: *std.io.BufferedWriter, | |
| 140 | bw: *Writer, | |
| 140 | 141 | raw: []const u8, |
| 141 | 142 | comptime isValidChar: fn (u8) bool, |
| 142 | ) std.io.Writer.Error!void { | |
| 143 | ) Writer.Error!void { | |
| 143 | 144 | var start: usize = 0; |
| 144 | 145 | for (raw, 0..) |char, index| { |
| 145 | 146 | if (isValidChar(char)) continue; |
| ... | ... | @@ -280,7 +281,7 @@ pub const WriteToStreamOptions = struct { |
| 280 | 281 | port: bool = true, |
| 281 | 282 | }; |
| 282 | 283 | |
| 283 | pub fn writeToStream(uri: Uri, options: WriteToStreamOptions, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 284 | pub fn writeToStream(uri: Uri, options: WriteToStreamOptions, bw: *Writer) Writer.Error!void { | |
| 284 | 285 | if (options.scheme) { |
| 285 | 286 | try bw.print("{s}:", .{uri.scheme}); |
| 286 | 287 | if (options.authority and uri.host != null) { |
| ... | ... | @@ -317,7 +318,7 @@ pub fn writeToStream(uri: Uri, options: WriteToStreamOptions, bw: *std.io.Buffer |
| 317 | 318 | } |
| 318 | 319 | } |
| 319 | 320 | |
| 320 | pub fn format(uri: Uri, bw: *std.io.BufferedWriter, comptime fmt: []const u8) std.io.Writer.Error!void { | |
| 321 | pub fn format(uri: Uri, bw: *Writer, comptime fmt: []const u8) Writer.Error!void { | |
| 321 | 322 | const scheme = comptime std.mem.indexOfScalar(u8, fmt, ';') != null or fmt.len == 0; |
| 322 | 323 | const authentication = comptime std.mem.indexOfScalar(u8, fmt, '@') != null or fmt.len == 0; |
| 323 | 324 | const authority = comptime std.mem.indexOfScalar(u8, fmt, '+') != null or fmt.len == 0; |
| ... | ... | @@ -461,8 +462,7 @@ test remove_dot_segments { |
| 461 | 462 | |
| 462 | 463 | /// 5.2.3. Merge Paths |
| 463 | 464 | fn merge_paths(base: Component, new: []u8, aux_buf: *[]u8) error{NoSpaceLeft}!Component { |
| 464 | var aux: std.io.BufferedWriter = undefined; | |
| 465 | aux.initFixed(aux_buf.*); | |
| 465 | var aux: Writer = .fixed(aux_buf.*); | |
| 466 | 466 | if (!base.isEmpty()) { |
| 467 | 467 | aux.print("{fpath}", .{base}) catch return error.NoSpaceLeft; |
| 468 | 468 | aux.end = std.mem.lastIndexOfScalar(u8, aux.getWritten(), '/') orelse |
lib/std/array_list.zig+5-7| ... | ... | @@ -905,20 +905,18 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?mem.Alig |
| 905 | 905 | pub fn print(self: *Self, gpa: Allocator, comptime fmt: []const u8, args: anytype) error{OutOfMemory}!void { |
| 906 | 906 | comptime assert(T == u8); |
| 907 | 907 | try self.ensureUnusedCapacity(gpa, fmt.len); |
| 908 | var aw: std.io.AllocatingWriter = undefined; | |
| 909 | const bw = aw.fromArrayList(gpa, self); | |
| 908 | var aw: std.io.AllocatingWriter = .fromArrayList(gpa, self); | |
| 910 | 909 | defer self.* = aw.toArrayList(); |
| 911 | return bw.print(fmt, args) catch |err| switch (err) { | |
| 910 | return aw.interface.print(fmt, args) catch |err| switch (err) { | |
| 912 | 911 | error.WriteFailed => return error.OutOfMemory, |
| 913 | 912 | }; |
| 914 | 913 | } |
| 915 | 914 | |
| 916 | 915 | pub fn printAssumeCapacity(self: *Self, comptime fmt: []const u8, args: anytype) void { |
| 917 | 916 | comptime assert(T == u8); |
| 918 | var bw: std.io.BufferedWriter = undefined; | |
| 919 | bw.initFixed(self.unusedCapacitySlice()); | |
| 920 | bw.print(fmt, args) catch unreachable; | |
| 921 | self.items.len += bw.end; | |
| 917 | var w: std.io.Writer = .fixed(self.unusedCapacitySlice()); | |
| 918 | w.print(fmt, args) catch unreachable; | |
| 919 | self.items.len += w.end; | |
| 922 | 920 | } |
| 923 | 921 | |
| 924 | 922 | /// Append a value to the list `n` times. |
lib/std/builtin.zig+1-1| ... | ... | @@ -34,7 +34,7 @@ pub const StackTrace = struct { |
| 34 | 34 | index: usize, |
| 35 | 35 | instruction_addresses: []usize, |
| 36 | 36 | |
| 37 | pub fn format(st: StackTrace, bw: *std.io.BufferedWriter, comptime fmt: []const u8) !void { | |
| 37 | pub fn format(st: StackTrace, bw: *std.io.Writer, comptime fmt: []const u8) !void { | |
| 38 | 38 | comptime if (fmt.len != 0) unreachable; |
| 39 | 39 | |
| 40 | 40 | // TODO: re-evaluate whether to use format() methods at all. |
lib/std/compress/flate.zig+22-41| ... | ... | @@ -1,6 +1,7 @@ |
| 1 | 1 | const builtin = @import("builtin"); |
| 2 | 2 | const std = @import("../std.zig"); |
| 3 | 3 | const testing = std.testing; |
| 4 | const Writer = std.io.Writer; | |
| 4 | 5 | |
| 5 | 6 | /// Container of the deflate bit stream body. Container adds header before |
| 6 | 7 | /// deflate bit stream and footer after. It can bi gzip, zlib or raw (no header, |
| ... | ... | @@ -106,7 +107,7 @@ pub const Container = enum { |
| 106 | 107 | } |
| 107 | 108 | } |
| 108 | 109 | |
| 109 | pub fn writeFooter(hasher: *Hasher, writer: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 110 | pub fn writeFooter(hasher: *Hasher, writer: *Writer) Writer.Error!void { | |
| 110 | 111 | var bits: [4]u8 = undefined; |
| 111 | 112 | switch (hasher.*) { |
| 112 | 113 | .gzip => |*gzip| { |
| ... | ... | @@ -230,8 +231,7 @@ test "compress/decompress" { |
| 230 | 231 | // compress original stream to compressed stream |
| 231 | 232 | { |
| 232 | 233 | var original: std.io.Reader = .fixed(data); |
| 233 | var compressed: std.io.BufferedWriter = undefined; | |
| 234 | compressed.initFixed(&cmp_buf); | |
| 234 | var compressed: Writer = .fixed(&cmp_buf); | |
| 235 | 235 | var compress: Compress = .init(&original, .raw); |
| 236 | 236 | var compress_br = compress.readable(&.{}); |
| 237 | 237 | const n = try compress_br.readRemaining(&compressed, .{ .level = level }); |
| ... | ... | @@ -246,16 +246,14 @@ test "compress/decompress" { |
| 246 | 246 | // decompress compressed stream to decompressed stream |
| 247 | 247 | { |
| 248 | 248 | var compressed: std.io.Reader = .fixed(cmp_buf[0..compressed_size]); |
| 249 | var decompressed: std.io.BufferedWriter = undefined; | |
| 250 | decompressed.initFixed(&dcm_buf); | |
| 249 | var decompressed: Writer = .fixed(&dcm_buf); | |
| 251 | 250 | try Decompress.pump(container, &compressed, &decompressed); |
| 252 | 251 | try testing.expectEqualSlices(u8, data, decompressed.getWritten()); |
| 253 | 252 | } |
| 254 | 253 | |
| 255 | 254 | // compressor writer interface |
| 256 | 255 | { |
| 257 | var compressed: std.io.BufferedWriter = undefined; | |
| 258 | compressed.initFixed(&cmp_buf); | |
| 256 | var compressed: Writer = .fixed(&cmp_buf); | |
| 259 | 257 | var cmp = try Compress.init(container, &compressed, .{ .level = level }); |
| 260 | 258 | var cmp_wrt = cmp.writer(); |
| 261 | 259 | try cmp_wrt.writeAll(data); |
| ... | ... | @@ -285,8 +283,7 @@ test "compress/decompress" { |
| 285 | 283 | // compress original stream to compressed stream |
| 286 | 284 | { |
| 287 | 285 | var original: std.io.Reader = .fixed(data); |
| 288 | var compressed: std.io.BufferedWriter = undefined; | |
| 289 | compressed.initFixed(&cmp_buf); | |
| 286 | var compressed: Writer = .fixed(&cmp_buf); | |
| 290 | 287 | var cmp = try Compress.Huffman.init(container, &compressed); |
| 291 | 288 | try cmp.compress(original.reader()); |
| 292 | 289 | try cmp.finish(); |
| ... | ... | @@ -300,8 +297,7 @@ test "compress/decompress" { |
| 300 | 297 | // decompress compressed stream to decompressed stream |
| 301 | 298 | { |
| 302 | 299 | var compressed: std.io.Reader = .fixed(cmp_buf[0..compressed_size]); |
| 303 | var decompressed: std.io.BufferedWriter = undefined; | |
| 304 | decompressed.initFixed(&dcm_buf); | |
| 300 | var decompressed: Writer = .fixed(&dcm_buf); | |
| 305 | 301 | try Decompress.pump(container, &compressed, &decompressed); |
| 306 | 302 | try testing.expectEqualSlices(u8, data, decompressed.getWritten()); |
| 307 | 303 | } |
| ... | ... | @@ -319,8 +315,7 @@ test "compress/decompress" { |
| 319 | 315 | // compress original stream to compressed stream |
| 320 | 316 | { |
| 321 | 317 | var original: std.io.Reader = .fixed(data); |
| 322 | var compressed: std.io.BufferedWriter = undefined; | |
| 323 | compressed.initFixed(&cmp_buf); | |
| 318 | var compressed: Writer = .fixed(&cmp_buf); | |
| 324 | 319 | var cmp = try Compress.SimpleCompressor(.store, container).init(&compressed); |
| 325 | 320 | try cmp.compress(original.reader()); |
| 326 | 321 | try cmp.finish(); |
| ... | ... | @@ -335,8 +330,7 @@ test "compress/decompress" { |
| 335 | 330 | // decompress compressed stream to decompressed stream |
| 336 | 331 | { |
| 337 | 332 | var compressed: std.io.Reader = .fixed(cmp_buf[0..compressed_size]); |
| 338 | var decompressed: std.io.BufferedWriter = undefined; | |
| 339 | decompressed.initFixed(&dcm_buf); | |
| 333 | var decompressed: Writer = .fixed(&dcm_buf); | |
| 340 | 334 | try Decompress.pump(container, &compressed, &decompressed); |
| 341 | 335 | try testing.expectEqualSlices(u8, data, decompressed.getWritten()); |
| 342 | 336 | } |
| ... | ... | @@ -491,8 +485,7 @@ fn testInterface(comptime pkg: type, gzip_data: []const u8, plain_data: []const |
| 491 | 485 | |
| 492 | 486 | // decompress |
| 493 | 487 | { |
| 494 | var plain: std.io.BufferedWriter = undefined; | |
| 495 | plain.initFixed(&buffer2); | |
| 488 | var plain: Writer = .fixed(&buffer2); | |
| 496 | 489 | |
| 497 | 490 | var in: std.io.Reader = .fixed(gzip_data); |
| 498 | 491 | try pkg.decompress(&in, &plain); |
| ... | ... | @@ -501,10 +494,8 @@ fn testInterface(comptime pkg: type, gzip_data: []const u8, plain_data: []const |
| 501 | 494 | |
| 502 | 495 | // compress/decompress |
| 503 | 496 | { |
| 504 | var plain: std.io.BufferedWriter = undefined; | |
| 505 | plain.initFixed(&buffer2); | |
| 506 | var compressed: std.io.BufferedWriter = undefined; | |
| 507 | compressed.initFixed(&buffer1); | |
| 497 | var plain: Writer = .fixed(&buffer2); | |
| 498 | var compressed: Writer = .fixed(&buffer1); | |
| 508 | 499 | |
| 509 | 500 | var in: std.io.Reader = .fixed(plain_data); |
| 510 | 501 | try pkg.compress(&in, &compressed, .{}); |
| ... | ... | @@ -516,10 +507,8 @@ fn testInterface(comptime pkg: type, gzip_data: []const u8, plain_data: []const |
| 516 | 507 | |
| 517 | 508 | // compressor/decompressor |
| 518 | 509 | { |
| 519 | var plain: std.io.BufferedWriter = undefined; | |
| 520 | plain.initFixed(&buffer2); | |
| 521 | var compressed: std.io.BufferedWriter = undefined; | |
| 522 | compressed.initFixed(&buffer1); | |
| 510 | var plain: Writer = .fixed(&buffer2); | |
| 511 | var compressed: Writer = .fixed(&buffer1); | |
| 523 | 512 | |
| 524 | 513 | var in: std.io.Reader = .fixed(plain_data); |
| 525 | 514 | var cmp = try pkg.compressor(&compressed, .{}); |
| ... | ... | @@ -536,10 +525,8 @@ fn testInterface(comptime pkg: type, gzip_data: []const u8, plain_data: []const |
| 536 | 525 | { |
| 537 | 526 | // huffman compress/decompress |
| 538 | 527 | { |
| 539 | var plain: std.io.BufferedWriter = undefined; | |
| 540 | plain.initFixed(&buffer2); | |
| 541 | var compressed: std.io.BufferedWriter = undefined; | |
| 542 | compressed.initFixed(&buffer1); | |
| 528 | var plain: Writer = .fixed(&buffer2); | |
| 529 | var compressed: Writer = .fixed(&buffer1); | |
| 543 | 530 | |
| 544 | 531 | var in: std.io.Reader = .fixed(plain_data); |
| 545 | 532 | try pkg.huffman.compress(&in, &compressed); |
| ... | ... | @@ -551,10 +538,8 @@ fn testInterface(comptime pkg: type, gzip_data: []const u8, plain_data: []const |
| 551 | 538 | |
| 552 | 539 | // huffman compressor/decompressor |
| 553 | 540 | { |
| 554 | var plain: std.io.BufferedWriter = undefined; | |
| 555 | plain.initFixed(&buffer2); | |
| 556 | var compressed: std.io.BufferedWriter = undefined; | |
| 557 | compressed.initFixed(&buffer1); | |
| 541 | var plain: Writer = .fixed(&buffer2); | |
| 542 | var compressed: Writer = .fixed(&buffer1); | |
| 558 | 543 | |
| 559 | 544 | var in: std.io.Reader = .fixed(plain_data); |
| 560 | 545 | var cmp = try pkg.huffman.compressor(&compressed); |
| ... | ... | @@ -571,10 +556,8 @@ fn testInterface(comptime pkg: type, gzip_data: []const u8, plain_data: []const |
| 571 | 556 | { |
| 572 | 557 | // store compress/decompress |
| 573 | 558 | { |
| 574 | var plain: std.io.BufferedWriter = undefined; | |
| 575 | plain.initFixed(&buffer2); | |
| 576 | var compressed: std.io.BufferedWriter = undefined; | |
| 577 | compressed.initFixed(&buffer1); | |
| 559 | var plain: Writer = .fixed(&buffer2); | |
| 560 | var compressed: Writer = .fixed(&buffer1); | |
| 578 | 561 | |
| 579 | 562 | var in: std.io.Reader = .fixed(plain_data); |
| 580 | 563 | try pkg.store.compress(&in, &compressed); |
| ... | ... | @@ -586,10 +569,8 @@ fn testInterface(comptime pkg: type, gzip_data: []const u8, plain_data: []const |
| 586 | 569 | |
| 587 | 570 | // store compressor/decompressor |
| 588 | 571 | { |
| 589 | var plain: std.io.BufferedWriter = undefined; | |
| 590 | plain.initFixed(&buffer2); | |
| 591 | var compressed: std.io.BufferedWriter = undefined; | |
| 592 | compressed.initFixed(&buffer1); | |
| 572 | var plain: Writer = .fixed(&buffer2); | |
| 573 | var compressed: Writer = .fixed(&buffer1); | |
| 593 | 574 | |
| 594 | 575 | var in: std.io.Reader = .fixed(plain_data); |
| 595 | 576 | var cmp = try pkg.store.compressor(&compressed); |
lib/std/compress/flate/BlockWriter.zig+14-13| ... | ... | @@ -3,6 +3,7 @@ |
| 3 | 3 | const std = @import("std"); |
| 4 | 4 | const io = std.io; |
| 5 | 5 | const assert = std.debug.assert; |
| 6 | const Writer = std.io.Writer; | |
| 6 | 7 | |
| 7 | 8 | const BlockWriter = @This(); |
| 8 | 9 | const flate = @import("../flate.zig"); |
| ... | ... | @@ -13,7 +14,7 @@ const Token = @import("Token.zig"); |
| 13 | 14 | const codegen_order = huffman.codegen_order; |
| 14 | 15 | const end_code_mark = 255; |
| 15 | 16 | |
| 16 | output: *std.io.BufferedWriter, | |
| 17 | output: *Writer, | |
| 17 | 18 | |
| 18 | 19 | codegen_freq: [huffman.codegen_code_count]u16 = undefined, |
| 19 | 20 | literal_freq: [huffman.max_num_lit]u16 = undefined, |
| ... | ... | @@ -26,7 +27,7 @@ fixed_literal_encoding: Compress.LiteralEncoder, |
| 26 | 27 | fixed_distance_encoding: Compress.DistanceEncoder, |
| 27 | 28 | huff_distance: Compress.DistanceEncoder, |
| 28 | 29 | |
| 29 | pub fn init(output: *std.io.BufferedWriter) BlockWriter { | |
| 30 | pub fn init(output: *Writer) BlockWriter { | |
| 30 | 31 | return .{ |
| 31 | 32 | .output = output, |
| 32 | 33 | .fixed_literal_encoding = Compress.fixedLiteralEncoder(), |
| ... | ... | @@ -41,15 +42,15 @@ pub fn init(output: *std.io.BufferedWriter) BlockWriter { |
| 41 | 42 | /// That is after final block; when last byte could be incomplete or |
| 42 | 43 | /// after stored block; which is aligned to the byte boundary (it has x |
| 43 | 44 | /// padding bits after first 3 bits). |
| 44 | pub fn flush(self: *BlockWriter) std.io.Writer.Error!void { | |
| 45 | pub fn flush(self: *BlockWriter) Writer.Error!void { | |
| 45 | 46 | try self.bit_writer.flush(); |
| 46 | 47 | } |
| 47 | 48 | |
| 48 | pub fn setWriter(self: *BlockWriter, new_writer: *std.io.BufferedWriter) void { | |
| 49 | pub fn setWriter(self: *BlockWriter, new_writer: *Writer) void { | |
| 49 | 50 | self.bit_writer.setWriter(new_writer); |
| 50 | 51 | } |
| 51 | 52 | |
| 52 | fn writeCode(self: *BlockWriter, c: Compress.HuffCode) std.io.Writer.Error!void { | |
| 53 | fn writeCode(self: *BlockWriter, c: Compress.HuffCode) Writer.Error!void { | |
| 53 | 54 | try self.bit_writer.writeBits(c.code, c.len); |
| 54 | 55 | } |
| 55 | 56 | |
| ... | ... | @@ -231,7 +232,7 @@ fn dynamicHeader( |
| 231 | 232 | num_distances: u32, |
| 232 | 233 | num_codegens: u32, |
| 233 | 234 | eof: bool, |
| 234 | ) std.io.Writer.Error!void { | |
| 235 | ) Writer.Error!void { | |
| 235 | 236 | const first_bits: u32 = if (eof) 5 else 4; |
| 236 | 237 | try self.bit_writer.writeBits(first_bits, 3); |
| 237 | 238 | try self.bit_writer.writeBits(num_literals - 257, 5); |
| ... | ... | @@ -271,7 +272,7 @@ fn dynamicHeader( |
| 271 | 272 | } |
| 272 | 273 | } |
| 273 | 274 | |
| 274 | fn storedHeader(self: *BlockWriter, length: usize, eof: bool) std.io.Writer.Error!void { | |
| 275 | fn storedHeader(self: *BlockWriter, length: usize, eof: bool) Writer.Error!void { | |
| 275 | 276 | assert(length <= 65535); |
| 276 | 277 | const flag: u32 = if (eof) 1 else 0; |
| 277 | 278 | try self.bit_writer.writeBits(flag, 3); |
| ... | ... | @@ -281,7 +282,7 @@ fn storedHeader(self: *BlockWriter, length: usize, eof: bool) std.io.Writer.Erro |
| 281 | 282 | try self.bit_writer.writeBits(~l, 16); |
| 282 | 283 | } |
| 283 | 284 | |
| 284 | fn fixedHeader(self: *BlockWriter, eof: bool) std.io.Writer.Error!void { | |
| 285 | fn fixedHeader(self: *BlockWriter, eof: bool) Writer.Error!void { | |
| 285 | 286 | // Indicate that we are a fixed Huffman block |
| 286 | 287 | var value: u32 = 2; |
| 287 | 288 | if (eof) { |
| ... | ... | @@ -295,7 +296,7 @@ fn fixedHeader(self: *BlockWriter, eof: bool) std.io.Writer.Error!void { |
| 295 | 296 | // is larger than the original bytes, the data will be written as a |
| 296 | 297 | // stored block. |
| 297 | 298 | // If the input is null, the tokens will always be Huffman encoded. |
| 298 | pub fn write(self: *BlockWriter, tokens: []const Token, eof: bool, input: ?[]const u8) std.io.Writer.Error!void { | |
| 299 | pub fn write(self: *BlockWriter, tokens: []const Token, eof: bool, input: ?[]const u8) Writer.Error!void { | |
| 299 | 300 | const lit_and_dist = self.indexTokens(tokens); |
| 300 | 301 | const num_literals = lit_and_dist.num_literals; |
| 301 | 302 | const num_distances = lit_and_dist.num_distances; |
| ... | ... | @@ -373,7 +374,7 @@ pub fn write(self: *BlockWriter, tokens: []const Token, eof: bool, input: ?[]con |
| 373 | 374 | try self.writeTokens(tokens, &literal_encoding.codes, &distance_encoding.codes); |
| 374 | 375 | } |
| 375 | 376 | |
| 376 | pub fn storedBlock(self: *BlockWriter, input: []const u8, eof: bool) std.io.Writer.Error!void { | |
| 377 | pub fn storedBlock(self: *BlockWriter, input: []const u8, eof: bool) Writer.Error!void { | |
| 377 | 378 | try self.storedHeader(input.len, eof); |
| 378 | 379 | try self.bit_writer.writeBytes(input); |
| 379 | 380 | } |
| ... | ... | @@ -388,7 +389,7 @@ fn dynamicBlock( |
| 388 | 389 | tokens: []const Token, |
| 389 | 390 | eof: bool, |
| 390 | 391 | input: ?[]const u8, |
| 391 | ) std.io.Writer.Error!void { | |
| 392 | ) Writer.Error!void { | |
| 392 | 393 | const total_tokens = self.indexTokens(tokens); |
| 393 | 394 | const num_literals = total_tokens.num_literals; |
| 394 | 395 | const num_distances = total_tokens.num_distances; |
| ... | ... | @@ -485,7 +486,7 @@ fn writeTokens( |
| 485 | 486 | tokens: []const Token, |
| 486 | 487 | le_codes: []Compress.HuffCode, |
| 487 | 488 | oe_codes: []Compress.HuffCode, |
| 488 | ) std.io.Writer.Error!void { | |
| 489 | ) Writer.Error!void { | |
| 489 | 490 | for (tokens) |t| { |
| 490 | 491 | if (t.kind == Token.Kind.literal) { |
| 491 | 492 | try self.writeCode(le_codes[t.literal()]); |
| ... | ... | @@ -512,7 +513,7 @@ fn writeTokens( |
| 512 | 513 | |
| 513 | 514 | // Encodes a block of bytes as either Huffman encoded literals or uncompressed bytes |
| 514 | 515 | // if the results only gains very little from compression. |
| 515 | pub fn huffmanBlock(self: *BlockWriter, input: []const u8, eof: bool) std.io.Writer.Error!void { | |
| 516 | pub fn huffmanBlock(self: *BlockWriter, input: []const u8, eof: bool) Writer.Error!void { | |
| 516 | 517 | // Add everything as literals |
| 517 | 518 | histogram(input, &self.literal_freq); |
| 518 | 519 |
lib/std/compress/flate/Compress.zig+15-16| ... | ... | @@ -47,6 +47,7 @@ const testing = std.testing; |
| 47 | 47 | const expect = testing.expect; |
| 48 | 48 | const mem = std.mem; |
| 49 | 49 | const math = std.math; |
| 50 | const Writer = std.io.Writer; | |
| 50 | 51 | |
| 51 | 52 | const Compress = @This(); |
| 52 | 53 | const Token = @import("Token.zig"); |
| ... | ... | @@ -142,7 +143,7 @@ const FlushOption = enum { none, flush, final }; |
| 142 | 143 | /// flush tokens to the token writer. |
| 143 | 144 | /// |
| 144 | 145 | /// Returns number of bytes consumed from `lh`. |
| 145 | fn tokenizeSlice(c: *Compress, bw: *std.io.BufferedWriter, limit: std.io.Limit, lh: []const u8) !usize { | |
| 146 | fn tokenizeSlice(c: *Compress, bw: *Writer, limit: std.io.Limit, lh: []const u8) !usize { | |
| 146 | 147 | _ = bw; |
| 147 | 148 | _ = limit; |
| 148 | 149 | if (true) @panic("TODO"); |
| ... | ... | @@ -299,7 +300,7 @@ pub fn finish(c: *Compress) !void { |
| 299 | 300 | |
| 300 | 301 | /// Use another writer while preserving history. Most probably flush |
| 301 | 302 | /// should be called on old writer before setting new. |
| 302 | pub fn setWriter(self: *Compress, new_writer: *std.io.BufferedWriter) void { | |
| 303 | pub fn setWriter(self: *Compress, new_writer: *Writer) void { | |
| 303 | 304 | self.block_writer.setWriter(new_writer); |
| 304 | 305 | self.output = new_writer; |
| 305 | 306 | } |
| ... | ... | @@ -767,7 +768,7 @@ fn byFreq(context: void, a: LiteralNode, b: LiteralNode) bool { |
| 767 | 768 | |
| 768 | 769 | fn read( |
| 769 | 770 | context: ?*anyopaque, |
| 770 | bw: *std.io.BufferedWriter, | |
| 771 | bw: *Writer, | |
| 771 | 772 | limit: std.io.Limit, |
| 772 | 773 | ) std.io.Reader.StreamError!usize { |
| 773 | 774 | const c: *Compress = @ptrCast(@alignCast(context)); |
| ... | ... | @@ -1147,8 +1148,7 @@ test "file tokenization" { |
| 1147 | 1148 | const data = case.data; |
| 1148 | 1149 | |
| 1149 | 1150 | for (levels, 0..) |level, i| { // for each compression level |
| 1150 | var original: std.io.Reader = undefined; | |
| 1151 | original.initFixed(data); | |
| 1151 | var original: std.io.Reader = .fixed(data); | |
| 1152 | 1152 | |
| 1153 | 1153 | // buffer for decompressed data |
| 1154 | 1154 | var al = std.ArrayList(u8).init(testing.allocator); |
| ... | ... | @@ -1181,10 +1181,10 @@ test "file tokenization" { |
| 1181 | 1181 | } |
| 1182 | 1182 | |
| 1183 | 1183 | const TokenDecoder = struct { |
| 1184 | output: *std.io.BufferedWriter, | |
| 1184 | output: *Writer, | |
| 1185 | 1185 | tokens_count: usize, |
| 1186 | 1186 | |
| 1187 | pub fn init(output: *std.io.BufferedWriter) TokenDecoder { | |
| 1187 | pub fn init(output: *Writer) TokenDecoder { | |
| 1188 | 1188 | return .{ |
| 1189 | 1189 | .output = output, |
| 1190 | 1190 | .tokens_count = 0, |
| ... | ... | @@ -1222,8 +1222,7 @@ test "store simple compressor" { |
| 1222 | 1222 | //0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21, |
| 1223 | 1223 | }; |
| 1224 | 1224 | |
| 1225 | var fbs: std.io.Reader = undefined; | |
| 1226 | fbs.initFixed(data); | |
| 1225 | var fbs: std.io.Reader = .fixed(data); | |
| 1227 | 1226 | var al = std.ArrayList(u8).init(testing.allocator); |
| 1228 | 1227 | defer al.deinit(); |
| 1229 | 1228 | |
| ... | ... | @@ -1232,7 +1231,7 @@ test "store simple compressor" { |
| 1232 | 1231 | try cmp.finish(); |
| 1233 | 1232 | try testing.expectEqualSlices(u8, &expected, al.items); |
| 1234 | 1233 | |
| 1235 | fbs.initFixed(data); | |
| 1234 | fbs = .fixed(data); | |
| 1236 | 1235 | try al.resize(0); |
| 1237 | 1236 | |
| 1238 | 1237 | // huffman only compresoor will also emit store block for this small sample |
| ... | ... | @@ -1244,7 +1243,7 @@ test "store simple compressor" { |
| 1244 | 1243 | |
| 1245 | 1244 | test "sliding window match" { |
| 1246 | 1245 | const data = "Blah blah blah blah blah!"; |
| 1247 | var win: std.io.BufferedWriter = .{}; | |
| 1246 | var win: Writer = .{}; | |
| 1248 | 1247 | try expect(win.write(data) == data.len); |
| 1249 | 1248 | try expect(win.wp == data.len); |
| 1250 | 1249 | try expect(win.rp == 0); |
| ... | ... | @@ -1263,9 +1262,9 @@ test "sliding window match" { |
| 1263 | 1262 | } |
| 1264 | 1263 | |
| 1265 | 1264 | test "sliding window slide" { |
| 1266 | var win: std.io.BufferedWriter = .{}; | |
| 1267 | win.wp = std.io.BufferedWriter.buffer_len - 11; | |
| 1268 | win.rp = std.io.BufferedWriter.buffer_len - 111; | |
| 1265 | var win: Writer = .{}; | |
| 1266 | win.wp = Writer.buffer_len - 11; | |
| 1267 | win.rp = Writer.buffer_len - 111; | |
| 1269 | 1268 | win.buffer[win.rp] = 0xab; |
| 1270 | 1269 | try expect(win.lookahead().len == 100); |
| 1271 | 1270 | try expect(win.tokensBuffer().?.len == win.rp); |
| ... | ... | @@ -1273,8 +1272,8 @@ test "sliding window slide" { |
| 1273 | 1272 | const n = win.slide(); |
| 1274 | 1273 | try expect(n == 32757); |
| 1275 | 1274 | try expect(win.buffer[win.rp] == 0xab); |
| 1276 | try expect(win.rp == std.io.BufferedWriter.hist_len - 111); | |
| 1277 | try expect(win.wp == std.io.BufferedWriter.hist_len - 11); | |
| 1275 | try expect(win.rp == Writer.hist_len - 111); | |
| 1276 | try expect(win.wp == Writer.hist_len - 11); | |
| 1278 | 1277 | try expect(win.lookahead().len == 100); |
| 1279 | 1278 | try expect(win.tokensBuffer() == null); |
| 1280 | 1279 | } |
lib/std/compress/flate/Decompress.zig+10-15| ... | ... | @@ -23,6 +23,7 @@ const Container = flate.Container; |
| 23 | 23 | const Token = @import("Token.zig"); |
| 24 | 24 | const testing = std.testing; |
| 25 | 25 | const Decompress = @This(); |
| 26 | const Writer = std.io.Writer; | |
| 26 | 27 | |
| 27 | 28 | input: *std.io.Reader, |
| 28 | 29 | // Hashes, produces checksum, of uncompressed data for gzip/zlib footer. |
| ... | ... | @@ -141,7 +142,7 @@ fn decodeSymbol(self: *Decompress, decoder: anytype) !Symbol { |
| 141 | 142 | |
| 142 | 143 | pub fn read( |
| 143 | 144 | context: ?*anyopaque, |
| 144 | bw: *std.io.BufferedWriter, | |
| 145 | bw: *Writer, | |
| 145 | 146 | limit: std.io.Limit, |
| 146 | 147 | ) std.io.Reader.StreamError!usize { |
| 147 | 148 | const d: *Decompress = @alignCast(@ptrCast(context)); |
| ... | ... | @@ -159,7 +160,7 @@ pub fn read( |
| 159 | 160 | |
| 160 | 161 | fn readInner( |
| 161 | 162 | d: *Decompress, |
| 162 | bw: *std.io.BufferedWriter, | |
| 163 | bw: *Writer, | |
| 163 | 164 | limit: std.io.Limit, |
| 164 | 165 | ) (Error || error{ WriteFailed, EndOfStream })!usize { |
| 165 | 166 | const in = d.input; |
| ... | ... | @@ -347,7 +348,7 @@ fn readInner( |
| 347 | 348 | |
| 348 | 349 | /// Write match (back-reference to the same data slice) starting at `distance` |
| 349 | 350 | /// back from current write position, and `length` of bytes. |
| 350 | fn writeMatch(bw: *std.io.BufferedWriter, length: u16, distance: u16) !void { | |
| 351 | fn writeMatch(bw: *Writer, length: u16, distance: u16) !void { | |
| 351 | 352 | _ = bw; |
| 352 | 353 | _ = length; |
| 353 | 354 | _ = distance; |
| ... | ... | @@ -727,8 +728,7 @@ test "decompress" { |
| 727 | 728 | }, |
| 728 | 729 | }; |
| 729 | 730 | for (cases) |c| { |
| 730 | var fb: std.io.Reader = undefined; | |
| 731 | fb.initFixed(@constCast(c.in)); | |
| 731 | var fb: std.io.Reader = .fixed(c.in); | |
| 732 | 732 | var aw: std.io.AllocatingWriter = undefined; |
| 733 | 733 | aw.init(testing.allocator); |
| 734 | 734 | defer aw.deinit(); |
| ... | ... | @@ -788,8 +788,7 @@ test "gzip decompress" { |
| 788 | 788 | }, |
| 789 | 789 | }; |
| 790 | 790 | for (cases) |c| { |
| 791 | var fb: std.io.Reader = undefined; | |
| 792 | fb.initFixed(@constCast(c.in)); | |
| 791 | var fb: std.io.Reader = .fixed(c.in); | |
| 793 | 792 | var aw: std.io.AllocatingWriter = undefined; |
| 794 | 793 | aw.init(testing.allocator); |
| 795 | 794 | defer aw.deinit(); |
| ... | ... | @@ -818,8 +817,7 @@ test "zlib decompress" { |
| 818 | 817 | }, |
| 819 | 818 | }; |
| 820 | 819 | for (cases) |c| { |
| 821 | var fb: std.io.Reader = undefined; | |
| 822 | fb.initFixed(@constCast(c.in)); | |
| 820 | var fb: std.io.Reader = .fixed(c.in); | |
| 823 | 821 | var aw: std.io.AllocatingWriter = undefined; |
| 824 | 822 | aw.init(testing.allocator); |
| 825 | 823 | defer aw.deinit(); |
| ... | ... | @@ -880,8 +878,7 @@ test "fuzzing tests" { |
| 880 | 878 | }; |
| 881 | 879 | |
| 882 | 880 | inline for (cases, 0..) |c, case_no| { |
| 883 | var in: std.io.Reader = undefined; | |
| 884 | in.initFixed(@constCast(@embedFile("testdata/fuzz/" ++ c.input ++ ".input"))); | |
| 881 | var in: std.io.Reader = .fixed(@embedFile("testdata/fuzz/" ++ c.input ++ ".input")); | |
| 885 | 882 | var aw: std.io.AllocatingWriter = undefined; |
| 886 | 883 | aw.init(testing.allocator); |
| 887 | 884 | defer aw.deinit(); |
| ... | ... | @@ -903,8 +900,7 @@ test "bug 18966" { |
| 903 | 900 | const input = @embedFile("testdata/fuzz/bug_18966.input"); |
| 904 | 901 | const expect = @embedFile("testdata/fuzz/bug_18966.expect"); |
| 905 | 902 | |
| 906 | var in: std.io.Reader = undefined; | |
| 907 | in.initFixed(@constCast(input)); | |
| 903 | var in: std.io.Reader = .fixed(input); | |
| 908 | 904 | var aw: std.io.AllocatingWriter = undefined; |
| 909 | 905 | aw.init(testing.allocator); |
| 910 | 906 | defer aw.deinit(); |
| ... | ... | @@ -921,8 +917,7 @@ test "reading into empty buffer" { |
| 921 | 917 | 0b0000_0001, 0b0000_1100, 0x00, 0b1111_0011, 0xff, // deflate fixed buffer header len, nlen |
| 922 | 918 | 'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', 0x0a, // non compressed data |
| 923 | 919 | }; |
| 924 | var in: std.io.Reader = undefined; | |
| 925 | in.initFixed(@constCast(input)); | |
| 920 | var in: std.io.Reader = .fixed(input); | |
| 926 | 921 | var decomp: Decompress = .init(&in, .raw); |
| 927 | 922 | var decompress_br = decomp.readable(&.{}); |
| 928 | 923 | var buf: [0]u8 = undefined; |
lib/std/compress/lzma.zig+11-12| ... | ... | @@ -6,6 +6,7 @@ const Allocator = std.mem.Allocator; |
| 6 | 6 | const testing = std.testing; |
| 7 | 7 | const expectEqualSlices = std.testing.expectEqualSlices; |
| 8 | 8 | const expectError = std.testing.expectError; |
| 9 | const Writer = std.io.Writer; | |
| 9 | 10 | |
| 10 | 11 | pub const RangeDecoder = struct { |
| 11 | 12 | range: u32, |
| ... | ... | @@ -320,7 +321,7 @@ pub const Decode = struct { |
| 320 | 321 | self: *Decode, |
| 321 | 322 | allocator: Allocator, |
| 322 | 323 | br: *std.io.Reader, |
| 323 | bw: *std.io.BufferedWriter, | |
| 324 | bw: *Writer, | |
| 324 | 325 | buffer: anytype, |
| 325 | 326 | decoder: *RangeDecoder, |
| 326 | 327 | bytes_read: *usize, |
| ... | ... | @@ -417,7 +418,7 @@ pub const Decode = struct { |
| 417 | 418 | self: *Decode, |
| 418 | 419 | allocator: Allocator, |
| 419 | 420 | br: *std.io.Reader, |
| 420 | bw: *std.io.BufferedWriter, | |
| 421 | bw: *Writer, | |
| 421 | 422 | buffer: anytype, |
| 422 | 423 | decoder: *RangeDecoder, |
| 423 | 424 | bytes_read: *usize, |
| ... | ... | @@ -429,7 +430,7 @@ pub const Decode = struct { |
| 429 | 430 | self: *Decode, |
| 430 | 431 | allocator: Allocator, |
| 431 | 432 | br: *std.io.Reader, |
| 432 | bw: *std.io.BufferedWriter, | |
| 433 | bw: *Writer, | |
| 433 | 434 | buffer: anytype, |
| 434 | 435 | decoder: *RangeDecoder, |
| 435 | 436 | bytes_read: *usize, |
| ... | ... | @@ -667,8 +668,8 @@ const LzCircularBuffer = struct { |
| 667 | 668 | self: *Self, |
| 668 | 669 | allocator: Allocator, |
| 669 | 670 | lit: u8, |
| 670 | bw: *std.io.BufferedWriter, | |
| 671 | ) std.io.Writer.Error!void { | |
| 671 | bw: *Writer, | |
| 672 | ) Writer.Error!void { | |
| 672 | 673 | try self.set(allocator, self.cursor, lit); |
| 673 | 674 | self.cursor += 1; |
| 674 | 675 | self.len += 1; |
| ... | ... | @@ -686,8 +687,8 @@ const LzCircularBuffer = struct { |
| 686 | 687 | allocator: Allocator, |
| 687 | 688 | len: usize, |
| 688 | 689 | dist: usize, |
| 689 | bw: *std.io.BufferedWriter, | |
| 690 | ) std.io.Writer.Error!void { | |
| 690 | bw: *Writer, | |
| 691 | ) Writer.Error!void { | |
| 691 | 692 | if (dist > self.dict_size or dist > self.len) { |
| 692 | 693 | return error.CorruptInput; |
| 693 | 694 | } |
| ... | ... | @@ -704,7 +705,7 @@ const LzCircularBuffer = struct { |
| 704 | 705 | } |
| 705 | 706 | } |
| 706 | 707 | |
| 707 | pub fn finish(self: *Self, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 708 | pub fn finish(self: *Self, bw: *Writer) Writer.Error!void { | |
| 708 | 709 | if (self.cursor > 0) { |
| 709 | 710 | try bw.writeAll(self.buf.items[0..self.cursor]); |
| 710 | 711 | self.cursor = 0; |
| ... | ... | @@ -839,8 +840,7 @@ test "Vec2D get addition overflow" { |
| 839 | 840 | |
| 840 | 841 | fn testDecompress(compressed: []const u8) ![]u8 { |
| 841 | 842 | const allocator = std.testing.allocator; |
| 842 | var br: std.io.Reader = undefined; | |
| 843 | br.initFixed(compressed); | |
| 843 | var br: std.io.Reader = .fixed(compressed); | |
| 844 | 844 | var decompressor = try Decompress.initOptions(allocator, &br, .{}); |
| 845 | 845 | defer decompressor.deinit(); |
| 846 | 846 | const reader = decompressor.reader(); |
| ... | ... | @@ -927,8 +927,7 @@ test "too small uncompressed size in header" { |
| 927 | 927 | |
| 928 | 928 | test "reading one byte" { |
| 929 | 929 | const compressed = @embedFile("testdata/good-known_size-with_eopm.lzma"); |
| 930 | var br: std.io.Reader = undefined; | |
| 931 | br.initFixed(compressed); | |
| 930 | var br: std.io.Reader = .fixed(compressed); | |
| 932 | 931 | var decompressor = try Decompress.initOptions(std.testing.allocator, &br, .{}); |
| 933 | 932 | defer decompressor.deinit(); |
| 934 | 933 | var buffer = [1]u8{0}; |
lib/std/compress/lzma2.zig+6-6| ... | ... | @@ -1,8 +1,9 @@ |
| 1 | 1 | const std = @import("../std.zig"); |
| 2 | 2 | const Allocator = std.mem.Allocator; |
| 3 | 3 | const lzma = std.compress.lzma; |
| 4 | const Writer = std.io.Writer; | |
| 4 | 5 | |
| 5 | pub fn decompress(gpa: Allocator, reader: *std.io.Reader, writer: *std.io.BufferedWriter) std.io.Reader.StreamError!void { | |
| 6 | pub fn decompress(gpa: Allocator, reader: *std.io.Reader, writer: *Writer) std.io.Reader.StreamError!void { | |
| 6 | 7 | var decoder = try Decode.init(gpa); |
| 7 | 8 | defer decoder.deinit(gpa); |
| 8 | 9 | return decoder.decompress(gpa, reader, writer); |
| ... | ... | @@ -34,7 +35,7 @@ pub const Decode = struct { |
| 34 | 35 | self: *Decode, |
| 35 | 36 | allocator: Allocator, |
| 36 | 37 | reader: *std.io.Reader, |
| 37 | writer: *std.io.BufferedWriter, | |
| 38 | writer: *Writer, | |
| 38 | 39 | ) !void { |
| 39 | 40 | var accum = LzAccumBuffer.init(std.math.maxInt(usize)); |
| 40 | 41 | defer accum.deinit(allocator); |
| ... | ... | @@ -57,7 +58,7 @@ pub const Decode = struct { |
| 57 | 58 | self: *Decode, |
| 58 | 59 | allocator: Allocator, |
| 59 | 60 | br: *std.io.Reader, |
| 60 | writer: *std.io.BufferedWriter, | |
| 61 | writer: *Writer, | |
| 61 | 62 | accum: *LzAccumBuffer, |
| 62 | 63 | status: u8, |
| 63 | 64 | ) !void { |
| ... | ... | @@ -150,7 +151,7 @@ pub const Decode = struct { |
| 150 | 151 | fn parseUncompressed( |
| 151 | 152 | allocator: Allocator, |
| 152 | 153 | reader: *std.io.Reader, |
| 153 | writer: *std.io.BufferedWriter, | |
| 154 | writer: *Writer, | |
| 154 | 155 | accum: *LzAccumBuffer, |
| 155 | 156 | reset_dict: bool, |
| 156 | 157 | ) !void { |
| ... | ... | @@ -276,8 +277,7 @@ test decompress { |
| 276 | 277 | 0x01, 0x00, 0x05, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x02, |
| 277 | 278 | 0x00, 0x06, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, |
| 278 | 279 | }; |
| 279 | var stream: std.io.Reader = undefined; | |
| 280 | stream.initFixed(&compressed); | |
| 280 | var stream: std.io.Reader = .fixed(&compressed); | |
| 281 | 281 | var decomp: std.io.AllocatingWriter = undefined; |
| 282 | 282 | const decomp_bw = decomp.init(std.testing.allocator); |
| 283 | 283 | defer decomp.deinit(); |
lib/std/compress/zstd/Decompress.zig+5-6| ... | ... | @@ -3,8 +3,8 @@ const std = @import("std"); |
| 3 | 3 | const assert = std.debug.assert; |
| 4 | 4 | const Reader = std.io.Reader; |
| 5 | 5 | const Limit = std.io.Limit; |
| 6 | const BufferedWriter = std.io.BufferedWriter; | |
| 7 | 6 | const zstd = @import("../zstd.zig"); |
| 7 | const Writer = std.io.Writer; | |
| 8 | 8 | |
| 9 | 9 | input: *Reader, |
| 10 | 10 | state: State, |
| ... | ... | @@ -77,7 +77,7 @@ pub fn reader(self: *Decompress) Reader { |
| 77 | 77 | }; |
| 78 | 78 | } |
| 79 | 79 | |
| 80 | fn read(context: ?*anyopaque, bw: *BufferedWriter, limit: Limit) Reader.StreamError!usize { | |
| 80 | fn read(context: ?*anyopaque, bw: *Writer, limit: Limit) Reader.StreamError!usize { | |
| 81 | 81 | const d: *Decompress = @ptrCast(@alignCast(context)); |
| 82 | 82 | const in = d.input; |
| 83 | 83 | |
| ... | ... | @@ -139,7 +139,7 @@ fn initFrame(d: *Decompress, window_size_max: usize, magic: Frame.Magic) !void { |
| 139 | 139 | } |
| 140 | 140 | } |
| 141 | 141 | |
| 142 | fn readInFrame(d: *Decompress, bw: *BufferedWriter, limit: Limit, state: *State.InFrame) !usize { | |
| 142 | fn readInFrame(d: *Decompress, bw: *Writer, limit: Limit, state: *State.InFrame) !usize { | |
| 143 | 143 | const in = d.input; |
| 144 | 144 | |
| 145 | 145 | const header_bytes = try in.takeArray(3); |
| ... | ... | @@ -649,8 +649,7 @@ pub const Frame = struct { |
| 649 | 649 | |
| 650 | 650 | if (decode.literal_written_count + literal_length > decode.literal_header.regenerated_size) |
| 651 | 651 | return error.MalformedLiteralsLength; |
| 652 | var sub_bw: BufferedWriter = undefined; | |
| 653 | sub_bw.initFixed(dest[write_pos..]); | |
| 652 | var sub_bw: Writer = .fixed(dest[write_pos..]); | |
| 654 | 653 | try decodeLiterals(decode, &sub_bw, literal_length); |
| 655 | 654 | decode.literal_written_count += literal_length; |
| 656 | 655 | // This is not a @memmove; it intentionally repeats patterns |
| ... | ... | @@ -698,7 +697,7 @@ pub const Frame = struct { |
| 698 | 697 | } |
| 699 | 698 | |
| 700 | 699 | /// Decode `len` bytes of literals into `dest`. |
| 701 | fn decodeLiterals(self: *Decode, dest: *BufferedWriter, len: usize) !void { | |
| 700 | fn decodeLiterals(self: *Decode, dest: *Writer, len: usize) !void { | |
| 702 | 701 | switch (self.literal_header.block_type) { |
| 703 | 702 | .raw => { |
| 704 | 703 | try dest.writeAll(self.literal_streams.one[self.literal_written_count..][0..len]); |
lib/std/crypto/Sha1.zig+9-11| ... | ... | @@ -7,6 +7,7 @@ const std = @import("../std.zig"); |
| 7 | 7 | const mem = std.mem; |
| 8 | 8 | const math = std.math; |
| 9 | 9 | const assert = std.debug.assert; |
| 10 | const Writer = std.io.Writer; | |
| 10 | 11 | |
| 11 | 12 | pub const block_length = 64; |
| 12 | 13 | pub const digest_length = 20; |
| ... | ... | @@ -252,21 +253,18 @@ pub fn round(d_s: *[5]u32, b: *const [64]u8) void { |
| 252 | 253 | d_s[4] +%= v[4]; |
| 253 | 254 | } |
| 254 | 255 | |
| 255 | pub fn writable(sha1: *Sha1, buffer: []u8) std.io.BufferedWriter { | |
| 256 | pub fn writer(sha1: *Sha1, buffer: []u8) Writer { | |
| 256 | 257 | return .{ |
| 257 | .unbuffered_writer = .{ | |
| 258 | .context = sha1, | |
| 259 | .vtable = &.{ | |
| 260 | .writeSplat = writeSplat, | |
| 261 | .writeFile = std.io.Writer.unimplementedWriteFile, | |
| 262 | }, | |
| 263 | }, | |
| 258 | .context = sha1, | |
| 259 | .vtable = &.{ .drain = drain }, | |
| 264 | 260 | .buffer = buffer, |
| 265 | 261 | }; |
| 266 | 262 | } |
| 267 | 263 | |
| 268 | fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) std.io.Writer.Error!usize { | |
| 269 | const sha1: *Sha1 = @ptrCast(@alignCast(context)); | |
| 264 | fn drain(w: *Writer, data: []const []const u8, splat: usize) Writer.Error!usize { | |
| 265 | const sha1: *Sha1 = @ptrCast(@alignCast(w.context)); | |
| 266 | sha1.update(w.buffered()); | |
| 267 | w.end = 0; | |
| 270 | 268 | const start_total = sha1.total_len; |
| 271 | 269 | if (sha1.buf_end == 0) { |
| 272 | 270 | try writeSplatAligned(sha1, data, splat); |
| ... | ... | @@ -299,7 +297,7 @@ fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) std. |
| 299 | 297 | return @intCast(sha1.total_len - start_total); |
| 300 | 298 | } |
| 301 | 299 | |
| 302 | fn writeSplatAligned(sha1: *Sha1, data: []const []const u8, splat: usize) std.io.Writer.Error!void { | |
| 300 | fn writeSplatAligned(sha1: *Sha1, data: []const []const u8, splat: usize) Writer.Error!void { | |
| 303 | 301 | assert(sha1.buf_end == 0); |
| 304 | 302 | for (data[0 .. data.len - 1]) |slice| { |
| 305 | 303 | var off: usize = 0; |
lib/std/crypto/codecs/asn1.zig+4-1| ... | ... | @@ -1,5 +1,8 @@ |
| 1 | 1 | //! ASN.1 types for public consumption. |
| 2 | ||
| 2 | 3 | const std = @import("std"); |
| 4 | const Writer = std.io.Writer; | |
| 5 | ||
| 3 | 6 | pub const der = @import("./asn1/der.zig"); |
| 4 | 7 | pub const Oid = @import("./asn1/Oid.zig"); |
| 5 | 8 | |
| ... | ... | @@ -90,7 +93,7 @@ pub const Tag = struct { |
| 90 | 93 | }; |
| 91 | 94 | } |
| 92 | 95 | |
| 93 | pub fn encode(self: Tag, writer: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 96 | pub fn encode(self: Tag, writer: *Writer) Writer.Error!void { | |
| 94 | 97 | var tag1: FirstTag = .{ |
| 95 | 98 | .number = undefined, |
| 96 | 99 | .constructed = self.constructed, |
lib/std/crypto/codecs/asn1/Oid.zig+5-6| ... | ... | @@ -9,7 +9,7 @@ pub const EncodeError = error{ |
| 9 | 9 | MissingPrefix, |
| 10 | 10 | }; |
| 11 | 11 | |
| 12 | pub fn encode(dot_notation: []const u8, out: *std.io.BufferedWriter) EncodeError!void { | |
| 12 | pub fn encode(dot_notation: []const u8, out: *Writer) EncodeError!void { | |
| 13 | 13 | var split = std.mem.splitScalar(u8, dot_notation, '.'); |
| 14 | 14 | const first_str = split.next() orelse return error.MissingPrefix; |
| 15 | 15 | const second_str = split.next() orelse return error.MissingPrefix; |
| ... | ... | @@ -41,8 +41,7 @@ pub fn encode(dot_notation: []const u8, out: *std.io.BufferedWriter) EncodeError |
| 41 | 41 | pub const InitError = std.fmt.ParseIntError || error{ MissingPrefix, BufferTooSmall }; |
| 42 | 42 | |
| 43 | 43 | pub fn fromDot(dot_notation: []const u8, out: []u8) InitError!Oid { |
| 44 | var bw: std.io.BufferedWriter = undefined; | |
| 45 | bw.initFixed(out); | |
| 44 | var bw: Writer = .fixed(out); | |
| 46 | 45 | encode(dot_notation, &bw) catch |err| switch (err) { |
| 47 | 46 | error.WriteFailed => return error.BufferTooSmall, |
| 48 | 47 | else => |e| return e, |
| ... | ... | @@ -58,7 +57,7 @@ test fromDot { |
| 58 | 57 | } |
| 59 | 58 | } |
| 60 | 59 | |
| 61 | pub fn toDot(self: Oid, writer: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 60 | pub fn toDot(self: Oid, writer: *Writer) Writer.Error!void { | |
| 62 | 61 | const encoded = self.encoded; |
| 63 | 62 | const first = @divTrunc(encoded[0], 40); |
| 64 | 63 | const second = encoded[0] - first * 40; |
| ... | ... | @@ -90,8 +89,7 @@ test toDot { |
| 90 | 89 | var buf: [256]u8 = undefined; |
| 91 | 90 | |
| 92 | 91 | for (test_cases) |t| { |
| 93 | var bw: std.io.BufferedWriter = undefined; | |
| 94 | bw.initFixed(&buf); | |
| 92 | var bw: Writer = .fixed(&buf); | |
| 95 | 93 | try toDot(Oid{ .encoded = t.encoded }, &bw); |
| 96 | 94 | try std.testing.expectEqualStrings(t.dot_notation, bw.getWritten()); |
| 97 | 95 | } |
| ... | ... | @@ -219,3 +217,4 @@ const encoding_base = 128; |
| 219 | 217 | const Allocator = std.mem.Allocator; |
| 220 | 218 | const der = @import("der.zig"); |
| 221 | 219 | const asn1 = @import("../asn1.zig"); |
| 220 | const Writer = std.io.Writer; |
lib/std/crypto/ecdsa.zig+2-2| ... | ... | @@ -6,6 +6,7 @@ const io = std.io; |
| 6 | 6 | const mem = std.mem; |
| 7 | 7 | const sha3 = crypto.hash.sha3; |
| 8 | 8 | const testing = std.testing; |
| 9 | const Writer = std.io.Writer; | |
| 9 | 10 | |
| 10 | 11 | const EncodingError = crypto.errors.EncodingError; |
| 11 | 12 | const IdentityElementError = crypto.errors.IdentityElementError; |
| ... | ... | @@ -135,8 +136,7 @@ pub fn Ecdsa(comptime Curve: type, comptime Hash: type) type { |
| 135 | 136 | /// The maximum length of the DER encoding is der_encoded_length_max. |
| 136 | 137 | /// The function returns a slice, that can be shorter than der_encoded_length_max. |
| 137 | 138 | pub fn toDer(sig: Signature, buf: *[der_encoded_length_max]u8) []u8 { |
| 138 | var w: std.io.BufferedWriter = undefined; | |
| 139 | w.initFixed(buf); | |
| 139 | var w: Writer = .fixed(buf); | |
| 140 | 140 | const r_len = @as(u8, @intCast(sig.r.len + (sig.r[0] >> 7))); |
| 141 | 141 | const s_len = @as(u8, @intCast(sig.s.len + (sig.s[0] >> 7))); |
| 142 | 142 | const seq_len = @as(u8, @intCast(2 + r_len + 2 + s_len)); |
lib/std/crypto/phc_encoding.zig+6-6| ... | ... | @@ -5,6 +5,7 @@ const fmt = std.fmt; |
| 5 | 5 | const io = std.io; |
| 6 | 6 | const mem = std.mem; |
| 7 | 7 | const meta = std.meta; |
| 8 | const Writer = std.io.Writer; | |
| 8 | 9 | |
| 9 | 10 | const fields_delimiter = "$"; |
| 10 | 11 | const fields_delimiter_scalar = '$'; |
| ... | ... | @@ -188,16 +189,15 @@ pub fn deserialize(comptime HashResult: type, str: []const u8) Error!HashResult |
| 188 | 189 | /// |
| 189 | 190 | /// `params` can also include any additional parameters. |
| 190 | 191 | pub fn serialize(params: anytype, str: []u8) Error![]const u8 { |
| 191 | var bw: std.io.BufferedWriter = undefined; | |
| 192 | bw.initFixed(str); | |
| 193 | try serializeTo(params, &bw); | |
| 194 | return bw.getWritten(); | |
| 192 | var w: Writer = .fixed(str); | |
| 193 | try serializeTo(params, &w); | |
| 194 | return w.buffered(); | |
| 195 | 195 | } |
| 196 | 196 | |
| 197 | 197 | /// Compute the number of bytes required to serialize `params` |
| 198 | 198 | pub fn calcSize(params: anytype) usize { |
| 199 | 199 | var trash: [128]u8 = undefined; |
| 200 | var bw: std.io.BufferedWriter = .{ | |
| 200 | var bw: Writer = .{ | |
| 201 | 201 | .unbuffered_writer = .discarding, |
| 202 | 202 | .buffer = &trash, |
| 203 | 203 | }; |
| ... | ... | @@ -205,7 +205,7 @@ pub fn calcSize(params: anytype) usize { |
| 205 | 205 | return bw.count; |
| 206 | 206 | } |
| 207 | 207 | |
| 208 | fn serializeTo(params: anytype, out: *std.io.BufferedWriter) !void { | |
| 208 | fn serializeTo(params: anytype, out: *Writer) !void { | |
| 209 | 209 | const HashResult = @TypeOf(params); |
| 210 | 210 | |
| 211 | 211 | if (@hasField(HashResult, version_param_name)) { |
lib/std/crypto/scrypt.zig+8-11| ... | ... | @@ -10,6 +10,7 @@ const math = std.math; |
| 10 | 10 | const mem = std.mem; |
| 11 | 11 | const meta = std.meta; |
| 12 | 12 | const pwhash = crypto.pwhash; |
| 13 | const Writer = std.io.Writer; | |
| 13 | 14 | |
| 14 | 15 | const phc_format = @import("phc_encoding.zig"); |
| 15 | 16 | |
| ... | ... | @@ -304,26 +305,22 @@ const crypt_format = struct { |
| 304 | 305 | |
| 305 | 306 | /// Serialize parameters into a string in modular crypt format. |
| 306 | 307 | pub fn serialize(params: anytype, str: []u8) EncodingError![]const u8 { |
| 307 | var bw: std.io.BufferedWriter = undefined; | |
| 308 | bw.initFixed(str); | |
| 309 | try serializeTo(params, &bw); | |
| 310 | return bw.getWritten(); | |
| 308 | var w: Writer = .fixed(str); | |
| 309 | try serializeTo(params, &w); | |
| 310 | return w.getWritten(); | |
| 311 | 311 | } |
| 312 | 312 | |
| 313 | 313 | /// Compute the number of bytes required to serialize `params` |
| 314 | 314 | pub fn calcSize(params: anytype) usize { |
| 315 | 315 | var trash: [64]u8 = undefined; |
| 316 | var bw: std.io.BufferedWriter = .{ | |
| 317 | .unbuffered_writer = .discarding, | |
| 318 | .buffer = &trash, | |
| 319 | }; | |
| 320 | serializeTo(params, &bw) catch |err| switch (err) { | |
| 316 | var w: std.io.Writer = .discarding(&trash); | |
| 317 | serializeTo(params, &w) catch |err| switch (err) { | |
| 321 | 318 | error.WriteFailed => unreachable, |
| 322 | 319 | }; |
| 323 | return bw.count; | |
| 320 | return w.count; | |
| 324 | 321 | } |
| 325 | 322 | |
| 326 | fn serializeTo(params: anytype, out: *std.io.BufferedWriter) !void { | |
| 323 | fn serializeTo(params: anytype, out: *Writer) !void { | |
| 327 | 324 | var header: [14]u8 = undefined; |
| 328 | 325 | header[0..3].* = prefix.*; |
| 329 | 326 | Codec.intEncode(header[3..4], params.ln); |
lib/std/crypto/sha2.zig+4-3| ... | ... | @@ -18,6 +18,7 @@ const builtin = @import("builtin"); |
| 18 | 18 | const mem = std.mem; |
| 19 | 19 | const math = std.math; |
| 20 | 20 | const htest = @import("test.zig"); |
| 21 | const Writer = std.io.Writer; | |
| 21 | 22 | |
| 22 | 23 | pub const Sha224 = Sha2x32(iv224, 224); |
| 23 | 24 | pub const Sha256 = Sha2x32(iv256, 256); |
| ... | ... | @@ -382,20 +383,20 @@ fn Sha2x32(comptime iv: Iv32, digest_bits: comptime_int) type { |
| 382 | 383 | for (&d.s, v) |*dv, vv| dv.* +%= vv; |
| 383 | 384 | } |
| 384 | 385 | |
| 385 | pub fn writable(this: *@This(), buffer: []u8) std.io.BufferedWriter { | |
| 386 | pub fn writable(this: *@This(), buffer: []u8) Writer { | |
| 386 | 387 | return .{ |
| 387 | 388 | .unbuffered_writer = .{ |
| 388 | 389 | .context = this, |
| 389 | 390 | .vtable = &.{ |
| 390 | 391 | .writeSplat = writeSplat, |
| 391 | .writeFile = std.io.Writer.unimplementedWriteFile, | |
| 392 | .writeFile = Writer.unimplementedWriteFile, | |
| 392 | 393 | }, |
| 393 | 394 | }, |
| 394 | 395 | .buffer = buffer, |
| 395 | 396 | }; |
| 396 | 397 | } |
| 397 | 398 | |
| 398 | fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) std.io.Writer.Error!usize { | |
| 399 | fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) Writer.Error!usize { | |
| 399 | 400 | const this: *@This() = @ptrCast(@alignCast(context)); |
| 400 | 401 | const start_total = this.total_len; |
| 401 | 402 | for (data[0 .. data.len - 1]) |slice| this.update(slice); |
lib/std/crypto/tls/Client.zig+5-5| ... | ... | @@ -25,7 +25,7 @@ input: *std.io.Reader, |
| 25 | 25 | |
| 26 | 26 | /// The encrypted stream from the client to the server. Bytes are pushed here |
| 27 | 27 | /// via `writer`. |
| 28 | output: *std.io.BufferedWriter, | |
| 28 | output: *Writer, | |
| 29 | 29 | |
| 30 | 30 | /// Populated when `error.TlsAlert` is returned. |
| 31 | 31 | alert: ?tls.Alert = null, |
| ... | ... | @@ -72,7 +72,7 @@ pub const SslKeyLog = struct { |
| 72 | 72 | client_key_seq: u64, |
| 73 | 73 | server_key_seq: u64, |
| 74 | 74 | client_random: [32]u8, |
| 75 | writer: *std.io.BufferedWriter, | |
| 75 | writer: *Writer, | |
| 76 | 76 | |
| 77 | 77 | fn clientCounter(key_log: *@This()) u64 { |
| 78 | 78 | defer key_log.client_key_seq += 1; |
| ... | ... | @@ -176,7 +176,7 @@ const InitError = error{ |
| 176 | 176 | pub fn init( |
| 177 | 177 | client: *Client, |
| 178 | 178 | input: *std.io.Reader, |
| 179 | output: *std.io.BufferedWriter, | |
| 179 | output: *Writer, | |
| 180 | 180 | options: Options, |
| 181 | 181 | ) InitError!void { |
| 182 | 182 | assert(input.buffer.len >= min_buffer_len); |
| ... | ... | @@ -1043,7 +1043,7 @@ pub fn eof(c: Client) bool { |
| 1043 | 1043 | return c.received_close_notify; |
| 1044 | 1044 | } |
| 1045 | 1045 | |
| 1046 | fn read(context: ?*anyopaque, bw: *std.io.BufferedWriter, limit: std.io.Limit) Reader.StreamError!usize { | |
| 1046 | fn read(context: ?*anyopaque, bw: *Writer, limit: std.io.Limit) Reader.StreamError!usize { | |
| 1047 | 1047 | const c: *Client = @ptrCast(@alignCast(context)); |
| 1048 | 1048 | if (c.eof()) return error.EndOfStream; |
| 1049 | 1049 | const input = c.input; |
| ... | ... | @@ -1226,7 +1226,7 @@ fn failRead(c: *Client, err: ReadError) error{ReadFailed} { |
| 1226 | 1226 | return error.ReadFailed; |
| 1227 | 1227 | } |
| 1228 | 1228 | |
| 1229 | fn logSecrets(bw: *std.io.BufferedWriter, context: anytype, secrets: anytype) void { | |
| 1229 | fn logSecrets(bw: *Writer, context: anytype, secrets: anytype) void { | |
| 1230 | 1230 | inline for (@typeInfo(@TypeOf(secrets)).@"struct".fields) |field| bw.print("{s}" ++ |
| 1231 | 1231 | (if (@hasField(@TypeOf(context), "counter")) "_{d}" else "") ++ " {x} {x}\n", .{field.name} ++ |
| 1232 | 1232 | (if (@hasField(@TypeOf(context), "counter")) .{context.counter} else .{}) ++ .{ |
lib/std/debug.zig+18-18| ... | ... | @@ -12,6 +12,7 @@ const windows = std.os.windows; |
| 12 | 12 | const native_arch = builtin.cpu.arch; |
| 13 | 13 | const native_os = builtin.os.tag; |
| 14 | 14 | const native_endian = native_arch.endian(); |
| 15 | const Writer = std.io.Writer; | |
| 15 | 16 | |
| 16 | 17 | pub const MemoryAccessor = @import("debug/MemoryAccessor.zig"); |
| 17 | 18 | pub const FixedBufferReader = @import("debug/FixedBufferReader.zig"); |
| ... | ... | @@ -208,9 +209,9 @@ pub fn unlockStdErr() void { |
| 208 | 209 | /// |
| 209 | 210 | /// During the lock, any `std.Progress` information is cleared from the terminal. |
| 210 | 211 | /// |
| 211 | /// Returns a `std.io.BufferedWriter` with empty buffer, meaning that it is | |
| 212 | /// Returns a `Writer` with empty buffer, meaning that it is | |
| 212 | 213 | /// in fact unbuffered and does not need to be flushed. |
| 213 | pub fn lockStderrWriter(buffer: []u8) *std.io.BufferedWriter { | |
| 214 | pub fn lockStderrWriter(buffer: []u8) *Writer { | |
| 214 | 215 | return std.Progress.lockStderrWriter(buffer); |
| 215 | 216 | } |
| 216 | 217 | |
| ... | ... | @@ -252,7 +253,7 @@ pub fn dumpHex(bytes: []const u8) void { |
| 252 | 253 | } |
| 253 | 254 | |
| 254 | 255 | /// Prints a hexadecimal view of the bytes, returning any error that occurs. |
| 255 | pub fn dumpHexFallible(bw: *std.io.BufferedWriter, ttyconf: std.io.tty.Config, bytes: []const u8) !void { | |
| 256 | pub fn dumpHexFallible(bw: *Writer, ttyconf: std.io.tty.Config, bytes: []const u8) !void { | |
| 256 | 257 | var chunks = mem.window(u8, bytes, 16, 16); |
| 257 | 258 | while (chunks.next()) |window| { |
| 258 | 259 | // 1. Print the address. |
| ... | ... | @@ -329,7 +330,7 @@ pub fn dumpCurrentStackTrace(start_addr: ?usize) void { |
| 329 | 330 | } |
| 330 | 331 | |
| 331 | 332 | /// Prints the current stack trace to the provided writer. |
| 332 | pub fn dumpCurrentStackTraceToWriter(start_addr: ?usize, writer: *std.io.BufferedWriter) !void { | |
| 333 | pub fn dumpCurrentStackTraceToWriter(start_addr: ?usize, writer: *Writer) !void { | |
| 333 | 334 | if (builtin.target.cpu.arch.isWasm()) { |
| 334 | 335 | if (native_os == .wasi) { |
| 335 | 336 | try writer.writeAll("Unable to dump stack trace: not implemented for Wasm\n"); |
| ... | ... | @@ -413,7 +414,7 @@ pub inline fn getContext(context: *ThreadContext) bool { |
| 413 | 414 | /// Tries to print the stack trace starting from the supplied base pointer to stderr, |
| 414 | 415 | /// unbuffered, and ignores any error returned. |
| 415 | 416 | /// TODO multithreaded awareness |
| 416 | pub fn dumpStackTraceFromBase(context: *ThreadContext, stderr: *std.io.BufferedWriter) void { | |
| 417 | pub fn dumpStackTraceFromBase(context: *ThreadContext, stderr: *Writer) void { | |
| 417 | 418 | nosuspend { |
| 418 | 419 | if (builtin.target.cpu.arch.isWasm()) { |
| 419 | 420 | if (native_os == .wasi) { |
| ... | ... | @@ -584,8 +585,7 @@ pub fn panicExtra( |
| 584 | 585 | const size = 0x1000; |
| 585 | 586 | const trunc_msg = "(msg truncated)"; |
| 586 | 587 | var buf: [size + trunc_msg.len]u8 = undefined; |
| 587 | var bw: std.io.BufferedWriter = undefined; | |
| 588 | bw.initFixed(buf[0..size]); | |
| 588 | var bw: Writer = .fixed(buf[0..size]); | |
| 589 | 589 | // a minor annoyance with this is that it will result in the NoSpaceLeft |
| 590 | 590 | // error being part of the @panic stack trace (but that error should |
| 591 | 591 | // only happen rarely) |
| ... | ... | @@ -733,7 +733,7 @@ fn waitForOtherThreadToFinishPanicking() void { |
| 733 | 733 | |
| 734 | 734 | pub fn writeStackTrace( |
| 735 | 735 | stack_trace: std.builtin.StackTrace, |
| 736 | writer: *std.io.BufferedWriter, | |
| 736 | writer: *Writer, | |
| 737 | 737 | debug_info: *SelfInfo, |
| 738 | 738 | tty_config: io.tty.Config, |
| 739 | 739 | ) !void { |
| ... | ... | @@ -964,7 +964,7 @@ pub const StackIterator = struct { |
| 964 | 964 | }; |
| 965 | 965 | |
| 966 | 966 | pub fn writeCurrentStackTrace( |
| 967 | writer: *std.io.BufferedWriter, | |
| 967 | writer: *Writer, | |
| 968 | 968 | debug_info: *SelfInfo, |
| 969 | 969 | tty_config: io.tty.Config, |
| 970 | 970 | start_addr: ?usize, |
| ... | ... | @@ -1052,7 +1052,7 @@ pub noinline fn walkStackWindows(addresses: []usize, existing_context: ?*const w |
| 1052 | 1052 | } |
| 1053 | 1053 | |
| 1054 | 1054 | pub fn writeStackTraceWindows( |
| 1055 | writer: *std.io.BufferedWriter, | |
| 1055 | writer: *Writer, | |
| 1056 | 1056 | debug_info: *SelfInfo, |
| 1057 | 1057 | tty_config: io.tty.Config, |
| 1058 | 1058 | context: *const windows.CONTEXT, |
| ... | ... | @@ -1072,7 +1072,7 @@ pub fn writeStackTraceWindows( |
| 1072 | 1072 | } |
| 1073 | 1073 | } |
| 1074 | 1074 | |
| 1075 | fn printUnknownSource(debug_info: *SelfInfo, writer: *std.io.BufferedWriter, address: usize, tty_config: io.tty.Config) !void { | |
| 1075 | fn printUnknownSource(debug_info: *SelfInfo, writer: *Writer, address: usize, tty_config: io.tty.Config) !void { | |
| 1076 | 1076 | const module_name = debug_info.getModuleNameForAddress(address); |
| 1077 | 1077 | return printLineInfo( |
| 1078 | 1078 | writer, |
| ... | ... | @@ -1085,14 +1085,14 @@ fn printUnknownSource(debug_info: *SelfInfo, writer: *std.io.BufferedWriter, add |
| 1085 | 1085 | ); |
| 1086 | 1086 | } |
| 1087 | 1087 | |
| 1088 | fn printLastUnwindError(it: *StackIterator, debug_info: *SelfInfo, writer: *std.io.BufferedWriter, tty_config: io.tty.Config) void { | |
| 1088 | fn printLastUnwindError(it: *StackIterator, debug_info: *SelfInfo, writer: *Writer, tty_config: io.tty.Config) void { | |
| 1089 | 1089 | if (!have_ucontext) return; |
| 1090 | 1090 | if (it.getLastError()) |unwind_error| { |
| 1091 | 1091 | printUnwindError(debug_info, writer, unwind_error.address, unwind_error.err, tty_config) catch {}; |
| 1092 | 1092 | } |
| 1093 | 1093 | } |
| 1094 | 1094 | |
| 1095 | fn printUnwindError(debug_info: *SelfInfo, writer: *std.io.BufferedWriter, address: usize, err: UnwindError, tty_config: io.tty.Config) !void { | |
| 1095 | fn printUnwindError(debug_info: *SelfInfo, writer: *Writer, address: usize, err: UnwindError, tty_config: io.tty.Config) !void { | |
| 1096 | 1096 | const module_name = debug_info.getModuleNameForAddress(address) orelse "???"; |
| 1097 | 1097 | try tty_config.setColor(writer, .dim); |
| 1098 | 1098 | if (err == error.MissingDebugInfo) { |
| ... | ... | @@ -1103,7 +1103,7 @@ fn printUnwindError(debug_info: *SelfInfo, writer: *std.io.BufferedWriter, addre |
| 1103 | 1103 | try tty_config.setColor(writer, .reset); |
| 1104 | 1104 | } |
| 1105 | 1105 | |
| 1106 | pub fn printSourceAtAddress(debug_info: *SelfInfo, writer: *std.io.BufferedWriter, address: usize, tty_config: io.tty.Config) !void { | |
| 1106 | pub fn printSourceAtAddress(debug_info: *SelfInfo, writer: *Writer, address: usize, tty_config: io.tty.Config) !void { | |
| 1107 | 1107 | const module = debug_info.getModuleForAddress(address) catch |err| switch (err) { |
| 1108 | 1108 | error.MissingDebugInfo, error.InvalidDebugInfo => return printUnknownSource(debug_info, writer, address, tty_config), |
| 1109 | 1109 | else => return err, |
| ... | ... | @@ -1127,7 +1127,7 @@ pub fn printSourceAtAddress(debug_info: *SelfInfo, writer: *std.io.BufferedWrite |
| 1127 | 1127 | } |
| 1128 | 1128 | |
| 1129 | 1129 | fn printLineInfo( |
| 1130 | writer: *std.io.BufferedWriter, | |
| 1130 | writer: *Writer, | |
| 1131 | 1131 | source_location: ?SourceLocation, |
| 1132 | 1132 | address: usize, |
| 1133 | 1133 | symbol_name: []const u8, |
| ... | ... | @@ -1174,7 +1174,7 @@ fn printLineInfo( |
| 1174 | 1174 | } |
| 1175 | 1175 | } |
| 1176 | 1176 | |
| 1177 | fn printLineFromFileAnyOs(writer: *std.io.BufferedWriter, source_location: SourceLocation) !void { | |
| 1177 | fn printLineFromFileAnyOs(writer: *Writer, source_location: SourceLocation) !void { | |
| 1178 | 1178 | // Need this to always block even in async I/O mode, because this could potentially |
| 1179 | 1179 | // be called from e.g. the event loop code crashing. |
| 1180 | 1180 | var f = try fs.cwd().openFile(source_location.file_name, .{}); |
| ... | ... | @@ -1567,7 +1567,7 @@ fn handleSegfaultWindowsExtra(info: *windows.EXCEPTION_POINTERS, msg: u8, label: |
| 1567 | 1567 | posix.abort(); |
| 1568 | 1568 | } |
| 1569 | 1569 | |
| 1570 | fn dumpSegfaultInfoWindows(info: *windows.EXCEPTION_POINTERS, msg: u8, label: ?[]const u8, stderr: *std.io.BufferedWriter) void { | |
| 1570 | fn dumpSegfaultInfoWindows(info: *windows.EXCEPTION_POINTERS, msg: u8, label: ?[]const u8, stderr: *Writer) void { | |
| 1571 | 1571 | _ = switch (msg) { |
| 1572 | 1572 | 0 => stderr.print("{s}\n", .{label.?}), |
| 1573 | 1573 | 1 => stderr.print("Segmentation fault at address 0x{x}\n", .{info.ExceptionRecord.ExceptionInformation[1]}), |
| ... | ... | @@ -1699,7 +1699,7 @@ pub fn ConfigurableTrace(comptime size: usize, comptime stack_frame_count: usize |
| 1699 | 1699 | t: @This(), |
| 1700 | 1700 | comptime fmt: []const u8, |
| 1701 | 1701 | options: std.fmt.FormatOptions, |
| 1702 | writer: *std.io.BufferedWriter, | |
| 1702 | writer: *Writer, | |
| 1703 | 1703 | ) !void { |
| 1704 | 1704 | if (fmt.len != 0) std.fmt.invalidFmtError(fmt, t); |
| 1705 | 1705 | _ = options; |
lib/std/debug/Dwarf/expression.zig+28-27| ... | ... | @@ -9,6 +9,7 @@ const abi = std.debug.Dwarf.abi; |
| 9 | 9 | const mem = std.mem; |
| 10 | 10 | const assert = std.debug.assert; |
| 11 | 11 | const Allocator = std.mem.Allocator; |
| 12 | const Writer = std.io.Writer; | |
| 12 | 13 | |
| 13 | 14 | /// Expressions can be evaluated in different contexts, each requiring its own set of inputs. |
| 14 | 15 | /// Callers should specify all the fields relevant to their context. If a field is required |
| ... | ... | @@ -826,7 +827,7 @@ pub fn Builder(comptime options: Options) type { |
| 826 | 827 | |
| 827 | 828 | return struct { |
| 828 | 829 | /// Zero-operand instructions |
| 829 | pub fn writeOpcode(writer: *std.io.BufferedWriter, comptime opcode: u8) !void { | |
| 830 | pub fn writeOpcode(writer: *Writer, comptime opcode: u8) !void { | |
| 830 | 831 | if (options.call_frame_context and !comptime isOpcodeValidInCFA(opcode)) return error.InvalidCFAOpcode; |
| 831 | 832 | switch (opcode) { |
| 832 | 833 | OP.dup, |
| ... | ... | @@ -867,14 +868,14 @@ pub fn Builder(comptime options: Options) type { |
| 867 | 868 | } |
| 868 | 869 | |
| 869 | 870 | // 2.5.1.1: Literal Encodings |
| 870 | pub fn writeLiteral(writer: *std.io.BufferedWriter, literal: u8) !void { | |
| 871 | pub fn writeLiteral(writer: *Writer, literal: u8) !void { | |
| 871 | 872 | switch (literal) { |
| 872 | 873 | 0...31 => |n| try writer.writeByte(n + OP.lit0), |
| 873 | 874 | else => return error.InvalidLiteral, |
| 874 | 875 | } |
| 875 | 876 | } |
| 876 | 877 | |
| 877 | pub fn writeConst(writer: *std.io.BufferedWriter, comptime T: type, value: T) !void { | |
| 878 | pub fn writeConst(writer: *Writer, comptime T: type, value: T) !void { | |
| 878 | 879 | if (@typeInfo(T) != .int) @compileError("Constants must be integers"); |
| 879 | 880 | |
| 880 | 881 | switch (T) { |
| ... | ... | @@ -906,12 +907,12 @@ pub fn Builder(comptime options: Options) type { |
| 906 | 907 | } |
| 907 | 908 | } |
| 908 | 909 | |
| 909 | pub fn writeConstx(writer: *std.io.BufferedWriter, debug_addr_offset: anytype) !void { | |
| 910 | pub fn writeConstx(writer: *Writer, debug_addr_offset: anytype) !void { | |
| 910 | 911 | try writer.writeByte(OP.constx); |
| 911 | 912 | try leb.writeUleb128(writer, debug_addr_offset); |
| 912 | 913 | } |
| 913 | 914 | |
| 914 | pub fn writeConstType(writer: *std.io.BufferedWriter, die_offset: anytype, value_bytes: []const u8) !void { | |
| 915 | pub fn writeConstType(writer: *Writer, die_offset: anytype, value_bytes: []const u8) !void { | |
| 915 | 916 | if (options.call_frame_context) return error.InvalidCFAOpcode; |
| 916 | 917 | if (value_bytes.len > 0xff) return error.InvalidTypeLength; |
| 917 | 918 | try writer.writeByte(OP.const_type); |
| ... | ... | @@ -920,36 +921,36 @@ pub fn Builder(comptime options: Options) type { |
| 920 | 921 | try writer.writeAll(value_bytes); |
| 921 | 922 | } |
| 922 | 923 | |
| 923 | pub fn writeAddr(writer: *std.io.BufferedWriter, value: Address) !void { | |
| 924 | pub fn writeAddr(writer: *Writer, value: Address) !void { | |
| 924 | 925 | try writer.writeByte(OP.addr); |
| 925 | 926 | try writer.writeInt(Address, value, options.endian); |
| 926 | 927 | } |
| 927 | 928 | |
| 928 | pub fn writeAddrx(writer: *std.io.BufferedWriter, debug_addr_offset: anytype) !void { | |
| 929 | pub fn writeAddrx(writer: *Writer, debug_addr_offset: anytype) !void { | |
| 929 | 930 | if (options.call_frame_context) return error.InvalidCFAOpcode; |
| 930 | 931 | try writer.writeByte(OP.addrx); |
| 931 | 932 | try leb.writeUleb128(writer, debug_addr_offset); |
| 932 | 933 | } |
| 933 | 934 | |
| 934 | 935 | // 2.5.1.2: Register Values |
| 935 | pub fn writeFbreg(writer: *std.io.BufferedWriter, offset: anytype) !void { | |
| 936 | pub fn writeFbreg(writer: *Writer, offset: anytype) !void { | |
| 936 | 937 | try writer.writeByte(OP.fbreg); |
| 937 | 938 | try leb.writeIleb128(writer, offset); |
| 938 | 939 | } |
| 939 | 940 | |
| 940 | pub fn writeBreg(writer: *std.io.BufferedWriter, register: u8, offset: anytype) !void { | |
| 941 | pub fn writeBreg(writer: *Writer, register: u8, offset: anytype) !void { | |
| 941 | 942 | if (register > 31) return error.InvalidRegister; |
| 942 | 943 | try writer.writeByte(OP.breg0 + register); |
| 943 | 944 | try leb.writeIleb128(writer, offset); |
| 944 | 945 | } |
| 945 | 946 | |
| 946 | pub fn writeBregx(writer: *std.io.BufferedWriter, register: anytype, offset: anytype) !void { | |
| 947 | pub fn writeBregx(writer: *Writer, register: anytype, offset: anytype) !void { | |
| 947 | 948 | try writer.writeByte(OP.bregx); |
| 948 | 949 | try leb.writeUleb128(writer, register); |
| 949 | 950 | try leb.writeIleb128(writer, offset); |
| 950 | 951 | } |
| 951 | 952 | |
| 952 | pub fn writeRegvalType(writer: *std.io.BufferedWriter, register: anytype, offset: anytype) !void { | |
| 953 | pub fn writeRegvalType(writer: *Writer, register: anytype, offset: anytype) !void { | |
| 953 | 954 | if (options.call_frame_context) return error.InvalidCFAOpcode; |
| 954 | 955 | try writer.writeByte(OP.regval_type); |
| 955 | 956 | try leb.writeUleb128(writer, register); |
| ... | ... | @@ -957,29 +958,29 @@ pub fn Builder(comptime options: Options) type { |
| 957 | 958 | } |
| 958 | 959 | |
| 959 | 960 | // 2.5.1.3: Stack Operations |
| 960 | pub fn writePick(writer: *std.io.BufferedWriter, index: u8) !void { | |
| 961 | pub fn writePick(writer: *Writer, index: u8) !void { | |
| 961 | 962 | try writer.writeByte(OP.pick); |
| 962 | 963 | try writer.writeByte(index); |
| 963 | 964 | } |
| 964 | 965 | |
| 965 | pub fn writeDerefSize(writer: *std.io.BufferedWriter, size: u8) !void { | |
| 966 | pub fn writeDerefSize(writer: *Writer, size: u8) !void { | |
| 966 | 967 | try writer.writeByte(OP.deref_size); |
| 967 | 968 | try writer.writeByte(size); |
| 968 | 969 | } |
| 969 | 970 | |
| 970 | pub fn writeXDerefSize(writer: *std.io.BufferedWriter, size: u8) !void { | |
| 971 | pub fn writeXDerefSize(writer: *Writer, size: u8) !void { | |
| 971 | 972 | try writer.writeByte(OP.xderef_size); |
| 972 | 973 | try writer.writeByte(size); |
| 973 | 974 | } |
| 974 | 975 | |
| 975 | pub fn writeDerefType(writer: *std.io.BufferedWriter, size: u8, die_offset: anytype) !void { | |
| 976 | pub fn writeDerefType(writer: *Writer, size: u8, die_offset: anytype) !void { | |
| 976 | 977 | if (options.call_frame_context) return error.InvalidCFAOpcode; |
| 977 | 978 | try writer.writeByte(OP.deref_type); |
| 978 | 979 | try writer.writeByte(size); |
| 979 | 980 | try leb.writeUleb128(writer, die_offset); |
| 980 | 981 | } |
| 981 | 982 | |
| 982 | pub fn writeXDerefType(writer: *std.io.BufferedWriter, size: u8, die_offset: anytype) !void { | |
| 983 | pub fn writeXDerefType(writer: *Writer, size: u8, die_offset: anytype) !void { | |
| 983 | 984 | try writer.writeByte(OP.xderef_type); |
| 984 | 985 | try writer.writeByte(size); |
| 985 | 986 | try leb.writeUleb128(writer, die_offset); |
| ... | ... | @@ -987,24 +988,24 @@ pub fn Builder(comptime options: Options) type { |
| 987 | 988 | |
| 988 | 989 | // 2.5.1.4: Arithmetic and Logical Operations |
| 989 | 990 | |
| 990 | pub fn writePlusUconst(writer: *std.io.BufferedWriter, uint_value: anytype) !void { | |
| 991 | pub fn writePlusUconst(writer: *Writer, uint_value: anytype) !void { | |
| 991 | 992 | try writer.writeByte(OP.plus_uconst); |
| 992 | 993 | try leb.writeUleb128(writer, uint_value); |
| 993 | 994 | } |
| 994 | 995 | |
| 995 | 996 | // 2.5.1.5: Control Flow Operations |
| 996 | 997 | |
| 997 | pub fn writeSkip(writer: *std.io.BufferedWriter, offset: i16) !void { | |
| 998 | pub fn writeSkip(writer: *Writer, offset: i16) !void { | |
| 998 | 999 | try writer.writeByte(OP.skip); |
| 999 | 1000 | try writer.writeInt(i16, offset, options.endian); |
| 1000 | 1001 | } |
| 1001 | 1002 | |
| 1002 | pub fn writeBra(writer: *std.io.BufferedWriter, offset: i16) !void { | |
| 1003 | pub fn writeBra(writer: *Writer, offset: i16) !void { | |
| 1003 | 1004 | try writer.writeByte(OP.bra); |
| 1004 | 1005 | try writer.writeInt(i16, offset, options.endian); |
| 1005 | 1006 | } |
| 1006 | 1007 | |
| 1007 | pub fn writeCall(writer: *std.io.BufferedWriter, comptime T: type, offset: T) !void { | |
| 1008 | pub fn writeCall(writer: *Writer, comptime T: type, offset: T) !void { | |
| 1008 | 1009 | if (options.call_frame_context) return error.InvalidCFAOpcode; |
| 1009 | 1010 | switch (T) { |
| 1010 | 1011 | u16 => try writer.writeByte(OP.call2), |
| ... | ... | @@ -1015,19 +1016,19 @@ pub fn Builder(comptime options: Options) type { |
| 1015 | 1016 | try writer.writeInt(T, offset, options.endian); |
| 1016 | 1017 | } |
| 1017 | 1018 | |
| 1018 | pub fn writeCallRef(writer: *std.io.BufferedWriter, comptime is_64: bool, value: if (is_64) u64 else u32) !void { | |
| 1019 | pub fn writeCallRef(writer: *Writer, comptime is_64: bool, value: if (is_64) u64 else u32) !void { | |
| 1019 | 1020 | if (options.call_frame_context) return error.InvalidCFAOpcode; |
| 1020 | 1021 | try writer.writeByte(OP.call_ref); |
| 1021 | 1022 | try writer.writeInt(if (is_64) u64 else u32, value, options.endian); |
| 1022 | 1023 | } |
| 1023 | 1024 | |
| 1024 | pub fn writeConvert(writer: *std.io.BufferedWriter, die_offset: anytype) !void { | |
| 1025 | pub fn writeConvert(writer: *Writer, die_offset: anytype) !void { | |
| 1025 | 1026 | if (options.call_frame_context) return error.InvalidCFAOpcode; |
| 1026 | 1027 | try writer.writeByte(OP.convert); |
| 1027 | 1028 | try leb.writeUleb128(writer, die_offset); |
| 1028 | 1029 | } |
| 1029 | 1030 | |
| 1030 | pub fn writeReinterpret(writer: *std.io.BufferedWriter, die_offset: anytype) !void { | |
| 1031 | pub fn writeReinterpret(writer: *Writer, die_offset: anytype) !void { | |
| 1031 | 1032 | if (options.call_frame_context) return error.InvalidCFAOpcode; |
| 1032 | 1033 | try writer.writeByte(OP.reinterpret); |
| 1033 | 1034 | try leb.writeUleb128(writer, die_offset); |
| ... | ... | @@ -1035,23 +1036,23 @@ pub fn Builder(comptime options: Options) type { |
| 1035 | 1036 | |
| 1036 | 1037 | // 2.5.1.7: Special Operations |
| 1037 | 1038 | |
| 1038 | pub fn writeEntryValue(writer: *std.io.BufferedWriter, expression: []const u8) !void { | |
| 1039 | pub fn writeEntryValue(writer: *Writer, expression: []const u8) !void { | |
| 1039 | 1040 | try writer.writeByte(OP.entry_value); |
| 1040 | 1041 | try leb.writeUleb128(writer, expression.len); |
| 1041 | 1042 | try writer.writeAll(expression); |
| 1042 | 1043 | } |
| 1043 | 1044 | |
| 1044 | 1045 | // 2.6: Location Descriptions |
| 1045 | pub fn writeReg(writer: *std.io.BufferedWriter, register: u8) !void { | |
| 1046 | pub fn writeReg(writer: *Writer, register: u8) !void { | |
| 1046 | 1047 | try writer.writeByte(OP.reg0 + register); |
| 1047 | 1048 | } |
| 1048 | 1049 | |
| 1049 | pub fn writeRegx(writer: *std.io.BufferedWriter, register: anytype) !void { | |
| 1050 | pub fn writeRegx(writer: *Writer, register: anytype) !void { | |
| 1050 | 1051 | try writer.writeByte(OP.regx); |
| 1051 | 1052 | try leb.writeUleb128(writer, register); |
| 1052 | 1053 | } |
| 1053 | 1054 | |
| 1054 | pub fn writeImplicitValue(writer: *std.io.BufferedWriter, value_bytes: []const u8) !void { | |
| 1055 | pub fn writeImplicitValue(writer: *Writer, value_bytes: []const u8) !void { | |
| 1055 | 1056 | try writer.writeByte(OP.implicit_value); |
| 1056 | 1057 | try leb.writeUleb128(writer, value_bytes.len); |
| 1057 | 1058 | try writer.writeAll(value_bytes); |
lib/std/debug/FixedBufferReader.zig+1-2| ... | ... | @@ -52,8 +52,7 @@ pub fn readIntChecked( |
| 52 | 52 | } |
| 53 | 53 | |
| 54 | 54 | pub fn readLeb128(fbr: *FixedBufferReader, comptime T: type) Error!T { |
| 55 | var br: std.io.Reader = undefined; | |
| 56 | br.initFixed(@constCast(fbr.buf)); | |
| 55 | var br: std.io.Reader = .fixed(fbr.buf); | |
| 57 | 56 | br.seek = fbr.pos; |
| 58 | 57 | const result = br.takeLeb128(T); |
| 59 | 58 | fbr.pos = br.seek; |
lib/std/fmt.zig+10-12| ... | ... | @@ -13,6 +13,7 @@ const lossyCast = math.lossyCast; |
| 13 | 13 | const expectFmt = std.testing.expectFmt; |
| 14 | 14 | const testing = std.testing; |
| 15 | 15 | const Allocator = std.mem.Allocator; |
| 16 | const Writer = std.io.Writer; | |
| 16 | 17 | |
| 17 | 18 | pub const float = @import("fmt/float.zig"); |
| 18 | 19 | |
| ... | ... | @@ -92,7 +93,7 @@ pub const Options = struct { |
| 92 | 93 | /// A user type may be a `struct`, `vector`, `union` or `enum` type. |
| 93 | 94 | /// |
| 94 | 95 | /// To print literal curly braces, escape them by writing them twice, e.g. `{{` or `}}`. |
| 95 | pub fn format(bw: *std.io.BufferedWriter, comptime fmt: []const u8, args: anytype) std.io.Writer.Error!void { | |
| 96 | pub fn format(bw: *Writer, comptime fmt: []const u8, args: anytype) Writer.Error!void { | |
| 96 | 97 | const ArgsType = @TypeOf(args); |
| 97 | 98 | const args_type_info = @typeInfo(ArgsType); |
| 98 | 99 | if (args_type_info != .@"struct") { |
| ... | ... | @@ -452,7 +453,7 @@ fn SliceEscape(comptime case: Case) type { |
| 452 | 453 | return struct { |
| 453 | 454 | pub fn format( |
| 454 | 455 | bytes: []const u8, |
| 455 | bw: *std.io.BufferedWriter, | |
| 456 | bw: *Writer, | |
| 456 | 457 | comptime fmt: []const u8, |
| 457 | 458 | ) !void { |
| 458 | 459 | _ = fmt; |
| ... | ... | @@ -494,8 +495,7 @@ pub fn fmtSliceEscapeUpper(bytes: []const u8) std.fmt.Formatter(formatSliceEscap |
| 494 | 495 | /// Asserts the rendered integer value fits in `buffer`. |
| 495 | 496 | /// Returns the end index within `buffer`. |
| 496 | 497 | pub fn printInt(buffer: []u8, value: anytype, base: u8, case: Case, options: Options) usize { |
| 497 | var bw: std.io.BufferedWriter = undefined; | |
| 498 | bw.initFixed(buffer); | |
| 498 | var bw: Writer = .fixed(buffer); | |
| 499 | 499 | bw.printIntOptions(value, base, case, options) catch unreachable; |
| 500 | 500 | return bw.end; |
| 501 | 501 | } |
| ... | ... | @@ -532,7 +532,7 @@ pub fn Formatter(comptime formatFn: anytype) type { |
| 532 | 532 | const Data = @typeInfo(@TypeOf(formatFn)).@"fn".params[0].type.?; |
| 533 | 533 | return struct { |
| 534 | 534 | data: Data, |
| 535 | pub fn format(self: @This(), writer: *std.io.BufferedWriter, comptime fmt: []const u8) std.io.Writer.Error!void { | |
| 535 | pub fn format(self: @This(), writer: *Writer, comptime fmt: []const u8) Writer.Error!void { | |
| 536 | 536 | try formatFn(self.data, writer, fmt); |
| 537 | 537 | } |
| 538 | 538 | }; |
| ... | ... | @@ -830,8 +830,7 @@ pub const BufPrintError = error{ |
| 830 | 830 | |
| 831 | 831 | /// Print a Formatter string into `buf`. Returns a slice of the bytes printed. |
| 832 | 832 | pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: anytype) BufPrintError![]u8 { |
| 833 | var bw: std.io.BufferedWriter = undefined; | |
| 834 | bw.initFixed(buf); | |
| 833 | var bw: Writer = .fixed(buf); | |
| 835 | 834 | bw.print(fmt, args) catch |err| switch (err) { |
| 836 | 835 | error.WriteFailed => return error.NoSpaceLeft, |
| 837 | 836 | }; |
| ... | ... | @@ -846,7 +845,7 @@ pub fn bufPrintZ(buf: []u8, comptime fmt: []const u8, args: anytype) BufPrintErr |
| 846 | 845 | /// Count the characters needed for format. |
| 847 | 846 | pub fn count(comptime fmt: []const u8, args: anytype) usize { |
| 848 | 847 | var trash_buffer: [64]u8 = undefined; |
| 849 | var bw: std.io.BufferedWriter = .{ | |
| 848 | var bw: Writer = .{ | |
| 850 | 849 | .unbuffered_writer = .discarding, |
| 851 | 850 | .buffer = &trash_buffer, |
| 852 | 851 | }; |
| ... | ... | @@ -1018,16 +1017,15 @@ test "int.padded" { |
| 1018 | 1017 | test "buffer" { |
| 1019 | 1018 | { |
| 1020 | 1019 | var buf1: [32]u8 = undefined; |
| 1021 | var bw: std.io.BufferedWriter = undefined; | |
| 1022 | bw.initFixed(&buf1); | |
| 1020 | var bw: Writer = .fixed(&buf1); | |
| 1023 | 1021 | try bw.printValue("", .{}, 1234, std.options.fmt_max_depth); |
| 1024 | 1022 | try std.testing.expectEqualStrings("1234", bw.getWritten()); |
| 1025 | 1023 | |
| 1026 | bw.initFixed(&buf1); | |
| 1024 | bw = .fixed(&buf1); | |
| 1027 | 1025 | try bw.printValue("c", .{}, 'a', std.options.fmt_max_depth); |
| 1028 | 1026 | try std.testing.expectEqualStrings("a", bw.getWritten()); |
| 1029 | 1027 | |
| 1030 | bw.initFixed(&buf1); | |
| 1028 | bw = .fixed(&buf1); | |
| 1031 | 1029 | try bw.printValue("b", .{}, 0b1100, std.options.fmt_max_depth); |
| 1032 | 1030 | try std.testing.expectEqualStrings("1100", bw.getWritten()); |
| 1033 | 1031 | } |
lib/std/fs/File.zig+26-27| ... | ... | @@ -844,7 +844,7 @@ pub fn write(self: File, bytes: []const u8) WriteError!usize { |
| 844 | 844 | return posix.write(self.handle, bytes); |
| 845 | 845 | } |
| 846 | 846 | |
| 847 | /// One-shot alternative to `std.io.BufferedWriter.writeAll` via `writer`. | |
| 847 | /// One-shot alternative to `std.io.Writer.writeAll` via `writer`. | |
| 848 | 848 | pub fn writeAll(self: File, bytes: []const u8) WriteError!void { |
| 849 | 849 | var index: usize = 0; |
| 850 | 850 | while (index < bytes.len) { |
| ... | ... | @@ -1029,7 +1029,7 @@ pub const Reader = struct { |
| 1029 | 1029 | |
| 1030 | 1030 | fn stream( |
| 1031 | 1031 | io_reader: *std.io.Reader, |
| 1032 | bw: *BufferedWriter, | |
| 1032 | bw: *std.io.Writer, | |
| 1033 | 1033 | limit: std.io.Limit, |
| 1034 | 1034 | ) std.io.Reader.StreamError!usize { |
| 1035 | 1035 | const r: *Reader = @fieldParentPtr("interface", io_reader); |
| ... | ... | @@ -1180,6 +1180,12 @@ pub const Reader = struct { |
| 1180 | 1180 | .failure => return error.ReadFailed, |
| 1181 | 1181 | } |
| 1182 | 1182 | } |
| 1183 | ||
| 1184 | pub fn atEnd(r: *Reader) bool { | |
| 1185 | // Even if stat fails, size is set when end is encountered. | |
| 1186 | const size = r.getSize() orelse return false; | |
| 1187 | return size - r.pos == 0; | |
| 1188 | } | |
| 1183 | 1189 | }; |
| 1184 | 1190 | |
| 1185 | 1191 | pub const Writer = struct { |
| ... | ... | @@ -1189,6 +1195,7 @@ pub const Writer = struct { |
| 1189 | 1195 | pos: u64 = 0, |
| 1190 | 1196 | sendfile_err: ?SendfileError = null, |
| 1191 | 1197 | seek_err: ?SeekError = null, |
| 1198 | interface: std.io.Writer, | |
| 1192 | 1199 | |
| 1193 | 1200 | pub const Mode = Reader.Mode; |
| 1194 | 1201 | |
| ... | ... | @@ -1205,20 +1212,20 @@ pub const Writer = struct { |
| 1205 | 1212 | /// vectors through the underlying write calls as possible. |
| 1206 | 1213 | const max_buffers_len = 16; |
| 1207 | 1214 | |
| 1208 | pub fn interface(w: *Writer) std.io.Writer { | |
| 1215 | pub fn init(file: File, buffer: []u8) std.io.Writer { | |
| 1209 | 1216 | return .{ |
| 1210 | .context = w, | |
| 1211 | .vtable = &.{ | |
| 1212 | .writeSplat = writeSplat, | |
| 1213 | .writeFile = writeFile, | |
| 1217 | .file = file, | |
| 1218 | .interface = .{ | |
| 1219 | .context = undefined, | |
| 1220 | .vtable = &.{ | |
| 1221 | .drain = drain, | |
| 1222 | .sendFile = sendFile, | |
| 1223 | }, | |
| 1224 | .buffer = buffer, | |
| 1214 | 1225 | }, |
| 1215 | 1226 | }; |
| 1216 | 1227 | } |
| 1217 | 1228 | |
| 1218 | pub fn writable(w: *Writer, buffer: []u8) std.io.BufferedWriter { | |
| 1219 | return interface(w).buffered(buffer); | |
| 1220 | } | |
| 1221 | ||
| 1222 | 1229 | pub fn moveToReader(w: *Writer) Reader { |
| 1223 | 1230 | defer w.* = undefined; |
| 1224 | 1231 | return .{ |
| ... | ... | @@ -1229,9 +1236,10 @@ pub const Writer = struct { |
| 1229 | 1236 | }; |
| 1230 | 1237 | } |
| 1231 | 1238 | |
| 1232 | pub fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) std.io.Writer.Error!usize { | |
| 1233 | const w: *Writer = @ptrCast(@alignCast(context)); | |
| 1239 | pub fn drain(io_writer: *std.io.Writer, data: []const []const u8, splat: usize) std.io.Writer.Error!usize { | |
| 1240 | const w: *Writer = @fieldParentPtr("interface", io_writer); | |
| 1234 | 1241 | const handle = w.file.handle; |
| 1242 | if (true) @panic("update to check for buffered data"); | |
| 1235 | 1243 | var splat_buffer: [256]u8 = undefined; |
| 1236 | 1244 | if (is_windows) { |
| 1237 | 1245 | if (data.len == 1 and splat == 0) return 0; |
| ... | ... | @@ -1282,14 +1290,8 @@ pub const Writer = struct { |
| 1282 | 1290 | }; |
| 1283 | 1291 | } |
| 1284 | 1292 | |
| 1285 | pub fn writeFile( | |
| 1286 | context: ?*anyopaque, | |
| 1287 | file_reader: *Reader, | |
| 1288 | limit: std.io.Limit, | |
| 1289 | headers_and_trailers: []const []const u8, | |
| 1290 | headers_len: usize, | |
| 1291 | ) std.io.Writer.FileError!usize { | |
| 1292 | const w: *Writer = @ptrCast(@alignCast(context)); | |
| 1293 | pub fn sendFile(io_writer: *Writer, file_reader: *Reader, limit: std.io.Limit) std.io.Writer.FileError!usize { | |
| 1294 | const w: *Writer = @fieldParentPtr("interface", io_writer); | |
| 1293 | 1295 | const out_fd = w.file.handle; |
| 1294 | 1296 | const in_fd = file_reader.file.handle; |
| 1295 | 1297 | // TODO try using copy_file_range on Linux |
| ... | ... | @@ -1299,9 +1301,8 @@ pub const Writer = struct { |
| 1299 | 1301 | if (native_os == .linux and w.mode == .streaming) sf: { |
| 1300 | 1302 | // Try using sendfile on Linux. |
| 1301 | 1303 | if (w.sendfile_err != null) break :sf; |
| 1302 | // Linux sendfile does not support headers or trailers but it does | |
| 1303 | // support a streaming read from in_file. | |
| 1304 | if (headers_len > 0) return writeSplat(context, headers_and_trailers[0..headers_len], 1); | |
| 1304 | // Linux sendfile does not support headers. | |
| 1305 | if (io_writer.end != 0) return drain(io_writer, &.{""}, 1); | |
| 1305 | 1306 | const max_count = 0x7ffff000; // Avoid EINVAL. |
| 1306 | 1307 | var off: std.os.linux.off_t = undefined; |
| 1307 | 1308 | const off_ptr: ?*std.os.linux.off_t, const count: usize = switch (file_reader.mode) { |
| ... | ... | @@ -1315,8 +1316,7 @@ pub const Writer = struct { |
| 1315 | 1316 | } |
| 1316 | 1317 | return 0; |
| 1317 | 1318 | }; |
| 1318 | off = std.math.cast(std.os.linux.off_t, file_reader.pos) orelse | |
| 1319 | return writeSplat(context, headers_and_trailers, 1); | |
| 1319 | off = std.math.cast(std.os.linux.off_t, file_reader.pos) orelse return error.ReadFailed; | |
| 1320 | 1320 | break :o .{ &off, @min(@intFromEnum(limit), size - file_reader.pos, max_count) }; |
| 1321 | 1321 | }, |
| 1322 | 1322 | .streaming => .{ null, limit.minInt(max_count) }, |
| ... | ... | @@ -1576,4 +1576,3 @@ const linux = std.os.linux; |
| 1576 | 1576 | const windows = std.os.windows; |
| 1577 | 1577 | const maxInt = std.math.maxInt; |
| 1578 | 1578 | const Alignment = std.mem.Alignment; |
| 1579 | const BufferedWriter = std.io.BufferedWriter; |
lib/std/fs/path.zig+2-2| ... | ... | @@ -150,8 +150,8 @@ pub fn fmtJoin(paths: []const []const u8) std.fmt.Formatter(formatJoin) { |
| 150 | 150 | return .{ .data = paths }; |
| 151 | 151 | } |
| 152 | 152 | |
| 153 | fn formatJoin(paths: []const []const u8, bw: *std.io.BufferedWriter, comptime fmt: []const u8) !void { | |
| 154 | _ = fmt; | |
| 153 | fn formatJoin(paths: []const []const u8, bw: *std.io.Writer, comptime fmt: []const u8) !void { | |
| 154 | comptime assert(fmt.len == 0); | |
| 155 | 155 | |
| 156 | 156 | const first_path_idx = for (paths, 0..) |p, idx| { |
| 157 | 157 | if (p.len != 0) break idx; |
lib/std/hash/crc.zig+8-10| ... | ... | @@ -1,4 +1,5 @@ |
| 1 | 1 | const std = @import("../std.zig"); |
| 2 | const Writer = std.io.Writer; | |
| 2 | 3 | |
| 3 | 4 | pub fn Generic(comptime W: type, comptime algorithm: Algorithm(W)) type { |
| 4 | 5 | return struct { |
| ... | ... | @@ -79,21 +80,18 @@ pub fn Generic(comptime W: type, comptime algorithm: Algorithm(W)) type { |
| 79 | 80 | return c.final(); |
| 80 | 81 | } |
| 81 | 82 | |
| 82 | pub fn writable(self: *Self, buffer: []u8) std.io.BufferedWriter { | |
| 83 | pub fn writer(self: *Self, buffer: []u8) Writer { | |
| 83 | 84 | return .{ |
| 84 | .unbuffered_writer = .{ | |
| 85 | .context = self, | |
| 86 | .vtable = &.{ | |
| 87 | .writeSplat = writeSplat, | |
| 88 | .writeFile = std.io.Writer.unimplementedWriteFile, | |
| 89 | }, | |
| 90 | }, | |
| 85 | .context = self, | |
| 86 | .vtable = &.{ .drain = drain }, | |
| 91 | 87 | .buffer = buffer, |
| 92 | 88 | }; |
| 93 | 89 | } |
| 94 | 90 | |
| 95 | fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) std.io.Writer.Error!usize { | |
| 96 | const self: *Self = @ptrCast(@alignCast(context)); | |
| 91 | fn drain(w: *Writer, data: []const []const u8, splat: usize) Writer.Error!usize { | |
| 92 | const self: *Self = @ptrCast(@alignCast(w.context)); | |
| 93 | self.update(w.buffered()); | |
| 94 | w.end = 0; | |
| 97 | 95 | var n: usize = 0; |
| 98 | 96 | for (data[0 .. data.len - 1]) |slice| { |
| 99 | 97 | self.update(slice); |
lib/std/http.zig+70-129| ... | ... | @@ -1,6 +1,8 @@ |
| 1 | 1 | const builtin = @import("builtin"); |
| 2 | 2 | const std = @import("std.zig"); |
| 3 | 3 | const assert = std.debug.assert; |
| 4 | const Writer = std.io.Writer; | |
| 5 | const File = std.fs.File; | |
| 4 | 6 | |
| 5 | 7 | pub const Client = @import("http/Client.zig"); |
| 6 | 8 | pub const Server = @import("http/Server.zig"); |
| ... | ... | @@ -504,7 +506,7 @@ pub const Reader = struct { |
| 504 | 506 | |
| 505 | 507 | fn contentLengthRead( |
| 506 | 508 | ctx: ?*anyopaque, |
| 507 | bw: *std.io.BufferedWriter, | |
| 509 | bw: *Writer, | |
| 508 | 510 | limit: std.io.Limit, |
| 509 | 511 | ) std.io.Reader.StreamError!usize { |
| 510 | 512 | const reader: *Reader = @alignCast(@ptrCast(ctx)); |
| ... | ... | @@ -534,7 +536,7 @@ pub const Reader = struct { |
| 534 | 536 | |
| 535 | 537 | fn chunkedRead( |
| 536 | 538 | ctx: ?*anyopaque, |
| 537 | bw: *std.io.BufferedWriter, | |
| 539 | bw: *Writer, | |
| 538 | 540 | limit: std.io.Limit, |
| 539 | 541 | ) std.io.Reader.StreamError!usize { |
| 540 | 542 | const reader: *Reader = @alignCast(@ptrCast(ctx)); |
| ... | ... | @@ -559,7 +561,7 @@ pub const Reader = struct { |
| 559 | 561 | |
| 560 | 562 | fn chunkedReadEndless( |
| 561 | 563 | reader: *Reader, |
| 562 | bw: *std.io.BufferedWriter, | |
| 564 | bw: *Writer, | |
| 563 | 565 | limit: std.io.Limit, |
| 564 | 566 | chunk_len_ptr: *RemainingChunkLen, |
| 565 | 567 | ) (BodyError || std.io.Reader.StreamError)!usize { |
| ... | ... | @@ -747,11 +749,12 @@ pub const Decompressor = struct { |
| 747 | 749 | pub const BodyWriter = struct { |
| 748 | 750 | /// Until the lifetime of `BodyWriter` ends, it is illegal to modify the |
| 749 | 751 | /// state of this other than via methods of `BodyWriter`. |
| 750 | http_protocol_output: *std.io.BufferedWriter, | |
| 752 | http_protocol_output: *Writer, | |
| 751 | 753 | state: State, |
| 752 | 754 | elide: bool, |
| 755 | interface: Writer, | |
| 753 | 756 | |
| 754 | pub const WriteError = std.io.Writer.Error; | |
| 757 | pub const Error = Writer.Error; | |
| 755 | 758 | |
| 756 | 759 | /// How many zeroes to reserve for hex-encoded chunk length. |
| 757 | 760 | const chunk_len_digits = 8; |
| ... | ... | @@ -787,7 +790,7 @@ pub const BodyWriter = struct { |
| 787 | 790 | }; |
| 788 | 791 | |
| 789 | 792 | /// Sends all buffered data across `BodyWriter.http_protocol_output`. |
| 790 | pub fn flush(w: *BodyWriter) WriteError!void { | |
| 793 | pub fn flush(w: *BodyWriter) Error!void { | |
| 791 | 794 | const out = w.http_protocol_output; |
| 792 | 795 | switch (w.state) { |
| 793 | 796 | .end, .none, .content_length => return out.flush(), |
| ... | ... | @@ -820,7 +823,7 @@ pub const BodyWriter = struct { |
| 820 | 823 | /// See also: |
| 821 | 824 | /// * `endUnflushed` |
| 822 | 825 | /// * `endChunked` |
| 823 | pub fn end(w: *BodyWriter) WriteError!void { | |
| 826 | pub fn end(w: *BodyWriter) Error!void { | |
| 824 | 827 | try endUnflushed(w); |
| 825 | 828 | try w.http_protocol_output.flush(); |
| 826 | 829 | } |
| ... | ... | @@ -836,7 +839,7 @@ pub const BodyWriter = struct { |
| 836 | 839 | /// See also: |
| 837 | 840 | /// * `end` |
| 838 | 841 | /// * `endChunked` |
| 839 | pub fn endUnflushed(w: *BodyWriter) WriteError!void { | |
| 842 | pub fn endUnflushed(w: *BodyWriter) Error!void { | |
| 840 | 843 | switch (w.state) { |
| 841 | 844 | .end => unreachable, |
| 842 | 845 | .content_length => |len| { |
| ... | ... | @@ -862,7 +865,7 @@ pub const BodyWriter = struct { |
| 862 | 865 | /// See also: |
| 863 | 866 | /// * `endChunkedUnflushed` |
| 864 | 867 | /// * `end` |
| 865 | pub fn endChunked(w: *BodyWriter, options: EndChunkedOptions) WriteError!void { | |
| 868 | pub fn endChunked(w: *BodyWriter, options: EndChunkedOptions) Error!void { | |
| 866 | 869 | try endChunkedUnflushed(w, options); |
| 867 | 870 | try w.http_protocol_output.flush(); |
| 868 | 871 | } |
| ... | ... | @@ -879,7 +882,7 @@ pub const BodyWriter = struct { |
| 879 | 882 | /// * `endChunked` |
| 880 | 883 | /// * `endUnflushed` |
| 881 | 884 | /// * `end` |
| 882 | pub fn endChunkedUnflushed(w: *BodyWriter, options: EndChunkedOptions) WriteError!void { | |
| 885 | pub fn endChunkedUnflushed(w: *BodyWriter, options: EndChunkedOptions) Error!void { | |
| 883 | 886 | const chunked = &w.state.chunked; |
| 884 | 887 | if (w.elide) { |
| 885 | 888 | w.state = .end; |
| ... | ... | @@ -910,138 +913,78 @@ pub const BodyWriter = struct { |
| 910 | 913 | w.state = .end; |
| 911 | 914 | } |
| 912 | 915 | |
| 913 | fn contentLengthWriteSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) WriteError!usize { | |
| 914 | const w: *BodyWriter = @alignCast(@ptrCast(context)); | |
| 915 | const n = if (w.elide) countSplat(data, splat) else try w.http_protocol_output.writeSplat(data, splat); | |
| 916 | fn contentLengthDrain(w: *Writer, data: []const []const u8, splat: usize) Error!usize { | |
| 917 | const bw: *BodyWriter = @fieldParentPtr("interface", w); | |
| 918 | assert(!bw.elide); | |
| 919 | const out = w.http_protocol_output; | |
| 920 | const n = try w.drainTo(out, data, splat); | |
| 916 | 921 | w.state.content_length -= n; |
| 917 | 922 | return n; |
| 918 | 923 | } |
| 919 | 924 | |
| 920 | fn noneWriteSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) WriteError!usize { | |
| 921 | const w: *BodyWriter = @alignCast(@ptrCast(context)); | |
| 922 | if (w.elide) return countSplat(data, splat); | |
| 923 | return w.http_protocol_output.writeSplat(data, splat); | |
| 924 | } | |
| 925 | ||
| 926 | fn countSplat(data: []const []const u8, splat: usize) usize { | |
| 927 | if (data.len == 0) return 0; | |
| 928 | var total: usize = 0; | |
| 929 | for (data[0 .. data.len - 1]) |buf| total += buf.len; | |
| 930 | total += data[data.len - 1].len * splat; | |
| 931 | return total; | |
| 932 | } | |
| 933 | ||
| 934 | fn elideWriteFile( | |
| 935 | file_reader: *std.fs.File.Reader, | |
| 936 | limit: std.io.Limit, | |
| 937 | headers_and_trailers: []const []const u8, | |
| 938 | headers_len: usize, | |
| 939 | ) error{ReadFailed}!usize { | |
| 940 | var source = file_reader.readable(&.{}); | |
| 941 | var n = source.discard(limit) catch |err| switch (err) { | |
| 942 | error.ReadFailed => return error.ReadFailed, | |
| 943 | error.EndOfStream => { | |
| 944 | var n: usize = 0; | |
| 945 | for (headers_and_trailers) |bytes| n += bytes.len; | |
| 946 | return n; | |
| 947 | }, | |
| 948 | }; | |
| 949 | if (file_reader.size) |size| { | |
| 950 | if (size - file_reader.pos == 0) { | |
| 951 | // End of file reached. | |
| 952 | for (headers_and_trailers) |bytes| n += bytes.len; | |
| 953 | return n; | |
| 954 | } | |
| 955 | } | |
| 956 | for (headers_and_trailers[0..headers_len]) |bytes| n += bytes.len; | |
| 957 | return n; | |
| 925 | fn noneDrain(w: *Writer, data: []const []const u8, splat: usize) Error!usize { | |
| 926 | const bw: *BodyWriter = @fieldParentPtr("interface", w); | |
| 927 | assert(!bw.elide); | |
| 928 | const out = w.http_protocol_output; | |
| 929 | return try w.drainTo(out, data, splat); | |
| 958 | 930 | } |
| 959 | 931 | |
| 960 | 932 | /// Returns `null` if size cannot be computed without making any syscalls. |
| 961 | fn countWriteFile( | |
| 962 | file_reader: *std.fs.File.Reader, | |
| 963 | limit: std.io.Limit, | |
| 964 | headers_and_trailers: []const []const u8, | |
| 965 | ) ?usize { | |
| 966 | var total: u64 = @min(@intFromEnum(limit), file_reader.getSize() orelse return null); | |
| 967 | for (headers_and_trailers) |bytes| total += bytes.len; | |
| 968 | return std.math.lossyCast(usize, total); | |
| 969 | } | |
| 970 | ||
| 971 | fn noneWriteFile( | |
| 972 | context: ?*anyopaque, | |
| 973 | file_reader: *std.fs.File.Reader, | |
| 974 | limit: std.io.Limit, | |
| 975 | headers_and_trailers: []const []const u8, | |
| 976 | headers_len: usize, | |
| 977 | ) std.io.Writer.FileError!usize { | |
| 978 | const w: *BodyWriter = @alignCast(@ptrCast(context)); | |
| 979 | if (w.elide) return elideWriteFile(file_reader, limit, headers_and_trailers, headers_len); | |
| 980 | return w.http_protocol_output.writeFile(file_reader, limit, headers_and_trailers, headers_len); | |
| 933 | fn noneSendFile(w: *Writer, file_reader: *File.Reader, limit: std.io.Limit) Writer.FileError!usize { | |
| 934 | const bw: *BodyWriter = @fieldParentPtr("interface", w); | |
| 935 | assert(!bw.elide); | |
| 936 | return w.sendFileTo(bw.http_protocol_output, file_reader, limit); | |
| 981 | 937 | } |
| 982 | 938 | |
| 983 | fn contentLengthWriteFile( | |
| 984 | context: ?*anyopaque, | |
| 985 | file_reader: *std.fs.File.Reader, | |
| 986 | limit: std.io.Limit, | |
| 987 | headers_and_trailers: []const []const u8, | |
| 988 | headers_len: usize, | |
| 989 | ) std.io.Writer.FileError!usize { | |
| 990 | const w: *BodyWriter = @alignCast(@ptrCast(context)); | |
| 991 | if (w.elide) return elideWriteFile(file_reader, limit, headers_and_trailers, headers_len); | |
| 992 | const n = try w.http_protocol_output.writeFile(file_reader, limit, headers_and_trailers, headers_len); | |
| 993 | w.state.content_length -= n; | |
| 939 | fn contentLengthSendFile(w: *Writer, file_reader: *File.Reader, limit: std.io.Limit) Writer.FileError!usize { | |
| 940 | const bw: *BodyWriter = @fieldParentPtr("interface", w); | |
| 941 | assert(!bw.elide); | |
| 942 | const n = try w.sendFileTo(bw.http_protocol_output, file_reader, limit); | |
| 943 | bw.state.content_length -= n; | |
| 994 | 944 | return n; |
| 995 | 945 | } |
| 996 | 946 | |
| 997 | fn chunkedWriteFile( | |
| 998 | context: ?*anyopaque, | |
| 999 | file_reader: *std.fs.File.Reader, | |
| 1000 | limit: std.io.Limit, | |
| 1001 | headers_and_trailers: []const []const u8, | |
| 1002 | headers_len: usize, | |
| 1003 | ) std.io.Writer.FileError!usize { | |
| 1004 | const w: *BodyWriter = @alignCast(@ptrCast(context)); | |
| 1005 | if (w.elide) return elideWriteFile(file_reader, limit, headers_and_trailers, headers_len); | |
| 1006 | if (limit == .nothing) return chunkedWriteSplat(context, headers_and_trailers, 1); | |
| 1007 | const data_len = countWriteFile(file_reader, headers_and_trailers) orelse { | |
| 947 | fn chunkedSendFile(w: *Writer, file_reader: *File.Reader, limit: std.io.Limit) Writer.FileError!usize { | |
| 948 | const bw: *BodyWriter = @fieldParentPtr("interface", w); | |
| 949 | assert(!bw.elide); | |
| 950 | const data_len = w.countSendFileUpperBound(file_reader, limit) orelse { | |
| 1008 | 951 | // If the file size is unknown, we cannot lower to a `writeFile` since we would |
| 1009 | 952 | // have to flush the chunk header before knowing the chunk length. |
| 1010 | 953 | return error.Unimplemented; |
| 1011 | 954 | }; |
| 1012 | const bw = w.http_protocol_output; | |
| 1013 | const chunked = &w.state.chunked; | |
| 955 | const out = bw.http_protocol_output; | |
| 956 | const chunked = &bw.state.chunked; | |
| 1014 | 957 | state: switch (chunked.*) { |
| 1015 | 958 | .offset => |off| { |
| 1016 | 959 | // TODO: is it better perf to read small files into the buffer? |
| 1017 | const buffered_len = bw.end - off - chunk_header_template.len; | |
| 960 | const buffered_len = out.end - off - chunk_header_template.len; | |
| 1018 | 961 | const chunk_len = data_len + buffered_len; |
| 1019 | writeHex(bw.buffer[off..][0..chunk_len_digits], chunk_len); | |
| 1020 | const n = try bw.writeFile(file_reader, limit, headers_and_trailers, headers_len); | |
| 962 | writeHex(out.buffer[off..][0..chunk_len_digits], chunk_len); | |
| 963 | const n = try w.sendFileTo(out, file_reader, limit); | |
| 1021 | 964 | chunked.* = .{ .chunk_len = data_len + 2 - n }; |
| 1022 | 965 | return n; |
| 1023 | 966 | }, |
| 1024 | 967 | .chunk_len => |chunk_len| l: switch (chunk_len) { |
| 1025 | 968 | 0 => { |
| 1026 | const off = bw.end; | |
| 1027 | const header_buf = try bw.writableArray(chunk_header_template.len); | |
| 969 | const off = out.end; | |
| 970 | const header_buf = try out.writableArray(chunk_header_template.len); | |
| 1028 | 971 | @memcpy(header_buf, chunk_header_template); |
| 1029 | 972 | chunked.* = .{ .offset = off }; |
| 1030 | 973 | continue :state .{ .offset = off }; |
| 1031 | 974 | }, |
| 1032 | 975 | 1 => { |
| 1033 | try bw.writeByte('\n'); | |
| 976 | try out.writeByte('\n'); | |
| 1034 | 977 | chunked.chunk_len = 0; |
| 1035 | 978 | continue :l 0; |
| 1036 | 979 | }, |
| 1037 | 980 | 2 => { |
| 1038 | try bw.writeByte('\r'); | |
| 981 | try out.writeByte('\r'); | |
| 1039 | 982 | chunked.chunk_len = 1; |
| 1040 | 983 | continue :l 1; |
| 1041 | 984 | }, |
| 1042 | 985 | else => { |
| 1043 | 986 | const new_limit = limit.min(.limited(chunk_len - 2)); |
| 1044 | const n = try bw.writeFile(file_reader, new_limit, headers_and_trailers, headers_len); | |
| 987 | const n = try w.sendFileTo(out, file_reader, new_limit); | |
| 1045 | 988 | chunked.chunk_len = chunk_len - n; |
| 1046 | 989 | return n; |
| 1047 | 990 | }, |
| ... | ... | @@ -1049,47 +992,45 @@ pub const BodyWriter = struct { |
| 1049 | 992 | } |
| 1050 | 993 | } |
| 1051 | 994 | |
| 1052 | fn chunkedWriteSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) WriteError!usize { | |
| 1053 | const w: *BodyWriter = @alignCast(@ptrCast(context)); | |
| 1054 | const data_len = countSplat(data, splat); | |
| 1055 | if (w.elide) return data_len; | |
| 1056 | ||
| 1057 | const bw = w.http_protocol_output; | |
| 1058 | const chunked = &w.state.chunked; | |
| 1059 | ||
| 995 | fn chunkedDrain(w: *Writer, data: []const []const u8, splat: usize) Error!usize { | |
| 996 | const bw: *BodyWriter = @fieldParentPtr("interface", w); | |
| 997 | assert(!bw.elide); | |
| 998 | const out = w.http_protocol_output; | |
| 999 | const data_len = Writer.countSplat(w.end, data, splat); | |
| 1000 | const chunked = &bw.state.chunked; | |
| 1060 | 1001 | state: switch (chunked.*) { |
| 1061 | 1002 | .offset => |offset| { |
| 1062 | if (bw.unusedCapacitySlice().len >= data_len) { | |
| 1063 | assert(data_len == (bw.writeSplat(data, splat) catch unreachable)); | |
| 1003 | if (out.unusedCapacityLen() >= data_len) { | |
| 1004 | assert(data_len == (w.drainTo(out, data, splat) catch unreachable)); | |
| 1064 | 1005 | return data_len; |
| 1065 | 1006 | } |
| 1066 | const buffered_len = bw.end - offset - chunk_header_template.len; | |
| 1007 | const buffered_len = out.end - offset - chunk_header_template.len; | |
| 1067 | 1008 | const chunk_len = data_len + buffered_len; |
| 1068 | writeHex(bw.buffer[offset..][0..chunk_len_digits], chunk_len); | |
| 1069 | const n = try bw.writeSplat(data, splat); | |
| 1009 | writeHex(out.buffer[offset..][0..chunk_len_digits], chunk_len); | |
| 1010 | const n = try w.drainTo(w, data, splat); | |
| 1070 | 1011 | chunked.* = .{ .chunk_len = data_len + 2 - n }; |
| 1071 | 1012 | return n; |
| 1072 | 1013 | }, |
| 1073 | 1014 | .chunk_len => |chunk_len| l: switch (chunk_len) { |
| 1074 | 1015 | 0 => { |
| 1075 | const offset = bw.end; | |
| 1076 | const header_buf = try bw.writableArray(chunk_header_template.len); | |
| 1016 | const offset = out.end; | |
| 1017 | const header_buf = try out.writableArray(chunk_header_template.len); | |
| 1077 | 1018 | @memcpy(header_buf, chunk_header_template); |
| 1078 | 1019 | chunked.* = .{ .offset = offset }; |
| 1079 | 1020 | continue :state .{ .offset = offset }; |
| 1080 | 1021 | }, |
| 1081 | 1022 | 1 => { |
| 1082 | try bw.writeByte('\n'); | |
| 1023 | try out.writeByte('\n'); | |
| 1083 | 1024 | chunked.chunk_len = 0; |
| 1084 | 1025 | continue :l 0; |
| 1085 | 1026 | }, |
| 1086 | 1027 | 2 => { |
| 1087 | try bw.writeByte('\r'); | |
| 1028 | try out.writeByte('\r'); | |
| 1088 | 1029 | chunked.chunk_len = 1; |
| 1089 | 1030 | continue :l 1; |
| 1090 | 1031 | }, |
| 1091 | 1032 | else => { |
| 1092 | const n = try bw.writeSplatLimit(data, splat, .limited(chunk_len - 2)); | |
| 1033 | const n = try w.drainToLimit(data, splat, .limited(chunk_len - 2)); | |
| 1093 | 1034 | chunked.chunk_len = chunk_len - n; |
| 1094 | 1035 | return n; |
| 1095 | 1036 | }, |
| ... | ... | @@ -1112,21 +1053,21 @@ pub const BodyWriter = struct { |
| 1112 | 1053 | } |
| 1113 | 1054 | } |
| 1114 | 1055 | |
| 1115 | pub fn writer(w: *BodyWriter) std.io.Writer { | |
| 1116 | return .{ | |
| 1056 | pub fn writer(w: *BodyWriter) Writer { | |
| 1057 | return if (w.elide) .discarding else .{ | |
| 1117 | 1058 | .context = w, |
| 1118 | 1059 | .vtable = switch (w.state) { |
| 1119 | 1060 | .none => &.{ |
| 1120 | .writeSplat = noneWriteSplat, | |
| 1121 | .writeFile = noneWriteFile, | |
| 1061 | .drain = noneDrain, | |
| 1062 | .sendFile = noneSendFile, | |
| 1122 | 1063 | }, |
| 1123 | 1064 | .content_length => &.{ |
| 1124 | .writeSplat = contentLengthWriteSplat, | |
| 1125 | .writeFile = contentLengthWriteFile, | |
| 1065 | .drain = contentLengthDrain, | |
| 1066 | .sendFile = contentLengthSendFile, | |
| 1126 | 1067 | }, |
| 1127 | 1068 | .chunked => &.{ |
| 1128 | .writeSplat = chunkedWriteSplat, | |
| 1129 | .writeFile = chunkedWriteFile, | |
| 1069 | .drain = chunkedDrain, | |
| 1070 | .sendFile = chunkedSendFile, | |
| 1130 | 1071 | }, |
| 1131 | 1072 | .end => unreachable, |
| 1132 | 1073 | }, |
lib/std/http/Client.zig+14-15| ... | ... | @@ -13,6 +13,7 @@ const net = std.net; |
| 13 | 13 | const Uri = std.Uri; |
| 14 | 14 | const Allocator = mem.Allocator; |
| 15 | 15 | const assert = std.debug.assert; |
| 16 | const Writer = std.io.Writer; | |
| 16 | 17 | |
| 17 | 18 | const Client = @This(); |
| 18 | 19 | |
| ... | ... | @@ -229,7 +230,7 @@ pub const Connection = struct { |
| 229 | 230 | stream_reader: net.Stream.Reader, |
| 230 | 231 | /// HTTP protocol from client to server. |
| 231 | 232 | /// This either goes directly to `stream_writer`, or to a TLS client. |
| 232 | writer: std.io.BufferedWriter, | |
| 233 | writer: Writer, | |
| 233 | 234 | /// HTTP protocol from server to client. |
| 234 | 235 | /// This either comes directly from `stream_reader`, or from a TLS client. |
| 235 | 236 | reader: std.io.Reader, |
| ... | ... | @@ -297,7 +298,7 @@ pub const Connection = struct { |
| 297 | 298 | |
| 298 | 299 | const Tls = struct { |
| 299 | 300 | /// Data from `client` to `Connection.stream`. |
| 300 | writer: std.io.BufferedWriter, | |
| 301 | writer: Writer, | |
| 301 | 302 | /// Data from `Connection.stream` to `client`. |
| 302 | 303 | reader: std.io.Reader, |
| 303 | 304 | client: std.crypto.tls.Client, |
| ... | ... | @@ -403,7 +404,7 @@ pub const Connection = struct { |
| 403 | 404 | } |
| 404 | 405 | } |
| 405 | 406 | |
| 406 | pub fn flush(c: *Connection) std.io.Writer.Error!void { | |
| 407 | pub fn flush(c: *Connection) Writer.Error!void { | |
| 407 | 408 | try c.writer.flush(); |
| 408 | 409 | if (c.protocol == .tls) { |
| 409 | 410 | if (disable_tls) unreachable; |
| ... | ... | @@ -415,7 +416,7 @@ pub const Connection = struct { |
| 415 | 416 | /// If the connection is a TLS connection, sends the close_notify alert. |
| 416 | 417 | /// |
| 417 | 418 | /// Flushes all buffers. |
| 418 | pub fn end(c: *Connection) std.io.Writer.Error!void { | |
| 419 | pub fn end(c: *Connection) Writer.Error!void { | |
| 419 | 420 | try c.writer.flush(); |
| 420 | 421 | if (c.protocol == .tls) { |
| 421 | 422 | if (disable_tls) unreachable; |
| ... | ... | @@ -818,13 +819,13 @@ pub const Request = struct { |
| 818 | 819 | } |
| 819 | 820 | |
| 820 | 821 | /// Sends and flushes a complete request as only HTTP head, no body. |
| 821 | pub fn sendBodiless(r: *Request) std.io.Writer.Error!void { | |
| 822 | pub fn sendBodiless(r: *Request) Writer.Error!void { | |
| 822 | 823 | try sendBodilessUnflushed(r); |
| 823 | 824 | try r.connection.?.flush(); |
| 824 | 825 | } |
| 825 | 826 | |
| 826 | 827 | /// Sends but does not flush a complete request as only HTTP head, no body. |
| 827 | pub fn sendBodilessUnflushed(r: *Request) std.io.Writer.Error!void { | |
| 828 | pub fn sendBodilessUnflushed(r: *Request) Writer.Error!void { | |
| 828 | 829 | assert(r.transfer_encoding == .none); |
| 829 | 830 | assert(!r.method.requestHasBody()); |
| 830 | 831 | try sendHead(r); |
| ... | ... | @@ -834,7 +835,7 @@ pub const Request = struct { |
| 834 | 835 | /// |
| 835 | 836 | /// See also: |
| 836 | 837 | /// * `sendBodyUnflushed` |
| 837 | pub fn sendBody(r: *Request) std.io.Writer.Error!http.BodyWriter { | |
| 838 | pub fn sendBody(r: *Request) Writer.Error!http.BodyWriter { | |
| 838 | 839 | const result = try sendBodyUnflushed(r); |
| 839 | 840 | try r.connection.?.flush(); |
| 840 | 841 | return result; |
| ... | ... | @@ -845,7 +846,7 @@ pub const Request = struct { |
| 845 | 846 | /// |
| 846 | 847 | /// See also: |
| 847 | 848 | /// * `sendBody` |
| 848 | pub fn sendBodyUnflushed(r: *Request) std.io.Writer.Error!http.BodyWriter { | |
| 849 | pub fn sendBodyUnflushed(r: *Request) Writer.Error!http.BodyWriter { | |
| 849 | 850 | assert(r.method.requestHasBody()); |
| 850 | 851 | try sendHead(r); |
| 851 | 852 | return .{ |
| ... | ... | @@ -860,7 +861,7 @@ pub const Request = struct { |
| 860 | 861 | } |
| 861 | 862 | |
| 862 | 863 | /// Sends HTTP headers without flushing. |
| 863 | fn sendHead(r: *Request) std.io.Writer.Error!void { | |
| 864 | fn sendHead(r: *Request) Writer.Error!void { | |
| 864 | 865 | const uri = r.uri; |
| 865 | 866 | const connection = r.connection.?; |
| 866 | 867 | const w = &connection.writer; |
| ... | ... | @@ -1134,7 +1135,7 @@ pub const Request = struct { |
| 1134 | 1135 | |
| 1135 | 1136 | /// Returns true if the default behavior is required, otherwise handles |
| 1136 | 1137 | /// writing (or not writing) the header. |
| 1137 | fn emitOverridableHeader(prefix: []const u8, v: Headers.Value, bw: *std.io.BufferedWriter) std.io.Writer.Error!bool { | |
| 1138 | fn emitOverridableHeader(prefix: []const u8, v: Headers.Value, bw: *Writer) Writer.Error!bool { | |
| 1138 | 1139 | switch (v) { |
| 1139 | 1140 | .default => return true, |
| 1140 | 1141 | .omit => return false, |
| ... | ... | @@ -1242,16 +1243,14 @@ pub const basic_authorization = struct { |
| 1242 | 1243 | } |
| 1243 | 1244 | |
| 1244 | 1245 | pub fn value(uri: Uri, out: []u8) []u8 { |
| 1245 | var bw: std.io.BufferedWriter = undefined; | |
| 1246 | bw.initFixed(out); | |
| 1246 | var bw: Writer = .fixed(out); | |
| 1247 | 1247 | write(uri, &bw) catch unreachable; |
| 1248 | 1248 | return bw.getWritten(); |
| 1249 | 1249 | } |
| 1250 | 1250 | |
| 1251 | pub fn write(uri: Uri, out: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 1251 | pub fn write(uri: Uri, out: *Writer) Writer.Error!void { | |
| 1252 | 1252 | var buf: [max_user_len + ":".len + max_password_len]u8 = undefined; |
| 1253 | var bw: std.io.BufferedWriter = undefined; | |
| 1254 | bw.initFixed(&buf); | |
| 1253 | var bw: Writer = .fixed(&buf); | |
| 1255 | 1254 | bw.print("{fuser}:{fpassword}", .{ |
| 1256 | 1255 | uri.user orelse Uri.Component.empty, |
| 1257 | 1256 | uri.password orelse Uri.Component.empty, |
lib/std/http/Server.zig+11-10| ... | ... | @@ -6,11 +6,12 @@ const mem = std.mem; |
| 6 | 6 | const Uri = std.Uri; |
| 7 | 7 | const assert = std.debug.assert; |
| 8 | 8 | const testing = std.testing; |
| 9 | const Writer = std.io.Writer; | |
| 9 | 10 | |
| 10 | 11 | const Server = @This(); |
| 11 | 12 | |
| 12 | 13 | /// Data from the HTTP server to the HTTP client. |
| 13 | out: *std.io.BufferedWriter, | |
| 14 | out: *Writer, | |
| 14 | 15 | reader: http.Reader, |
| 15 | 16 | |
| 16 | 17 | /// Initialize an HTTP server that can respond to multiple requests on the same |
| ... | ... | @@ -20,7 +21,7 @@ reader: http.Reader, |
| 20 | 21 | /// header, otherwise `receiveHead` returns `error.HttpHeadersOversize`. |
| 21 | 22 | /// |
| 22 | 23 | /// The returned `Server` is ready for `receiveHead` to be called. |
| 23 | pub fn init(in: *std.io.Reader, out: *std.io.BufferedWriter) Server { | |
| 24 | pub fn init(in: *std.io.Reader, out: *Writer) Server { | |
| 24 | 25 | return .{ |
| 25 | 26 | .reader = .{ |
| 26 | 27 | .in = in, |
| ... | ... | @@ -397,7 +398,7 @@ pub const Request = struct { |
| 397 | 398 | /// be done to satisfy the request. |
| 398 | 399 | /// |
| 399 | 400 | /// Asserts status is not `continue`. |
| 400 | pub fn respondStreaming(request: *Request, options: RespondStreamingOptions) std.io.Writer.Error!http.BodyWriter { | |
| 401 | pub fn respondStreaming(request: *Request, options: RespondStreamingOptions) Writer.Error!http.BodyWriter { | |
| 401 | 402 | try writeExpectContinue(request); |
| 402 | 403 | const o = options.respond_options; |
| 403 | 404 | assert(o.status != .@"continue"); |
| ... | ... | @@ -485,7 +486,7 @@ pub const Request = struct { |
| 485 | 486 | |
| 486 | 487 | /// The header is not guaranteed to be sent until `WebSocket.flush` is |
| 487 | 488 | /// called on the returned struct. |
| 488 | pub fn respondWebSocket(request: *Request, options: WebSocketOptions) std.io.Writer.Error!WebSocket { | |
| 489 | pub fn respondWebSocket(request: *Request, options: WebSocketOptions) Writer.Error!WebSocket { | |
| 489 | 490 | if (request.head.expect != null) return error.HttpExpectationFailed; |
| 490 | 491 | |
| 491 | 492 | const out = request.server.out; |
| ... | ... | @@ -611,7 +612,7 @@ pub const Request = struct { |
| 611 | 612 | pub const WebSocket = struct { |
| 612 | 613 | key: []const u8, |
| 613 | 614 | input: *std.io.Reader, |
| 614 | output: *std.io.BufferedWriter, | |
| 615 | output: *Writer, | |
| 615 | 616 | |
| 616 | 617 | pub const Header0 = packed struct(u8) { |
| 617 | 618 | opcode: Opcode, |
| ... | ... | @@ -701,21 +702,21 @@ pub const WebSocket = struct { |
| 701 | 702 | } |
| 702 | 703 | } |
| 703 | 704 | |
| 704 | pub fn writeMessage(ws: *WebSocket, data: []const u8, op: Opcode) std.io.Writer.Error!void { | |
| 705 | pub fn writeMessage(ws: *WebSocket, data: []const u8, op: Opcode) Writer.Error!void { | |
| 705 | 706 | try writeMessageVecUnflushed(ws, &.{data}, op); |
| 706 | 707 | try ws.output.flush(); |
| 707 | 708 | } |
| 708 | 709 | |
| 709 | pub fn writeMessageUnflushed(ws: *WebSocket, data: []const u8, op: Opcode) std.io.Writer.Error!void { | |
| 710 | pub fn writeMessageUnflushed(ws: *WebSocket, data: []const u8, op: Opcode) Writer.Error!void { | |
| 710 | 711 | try writeMessageVecUnflushed(ws, &.{data}, op); |
| 711 | 712 | } |
| 712 | 713 | |
| 713 | pub fn writeMessageVec(ws: *WebSocket, data: []const []const u8, op: Opcode) std.io.Writer.Error!void { | |
| 714 | pub fn writeMessageVec(ws: *WebSocket, data: []const []const u8, op: Opcode) Writer.Error!void { | |
| 714 | 715 | try writeMessageVecUnflushed(ws, data, op); |
| 715 | 716 | try ws.output.flush(); |
| 716 | 717 | } |
| 717 | 718 | |
| 718 | pub fn writeMessageVecUnflushed(ws: *WebSocket, data: []const []const u8, op: Opcode) std.io.Writer.Error!void { | |
| 719 | pub fn writeMessageVecUnflushed(ws: *WebSocket, data: []const []const u8, op: Opcode) Writer.Error!void { | |
| 719 | 720 | const total_len = l: { |
| 720 | 721 | var total_len: u64 = 0; |
| 721 | 722 | for (data) |iovec| total_len += iovec.len; |
| ... | ... | @@ -749,7 +750,7 @@ pub const WebSocket = struct { |
| 749 | 750 | try out.writeVecAll(data); |
| 750 | 751 | } |
| 751 | 752 | |
| 752 | pub fn flush(ws: *WebSocket) std.io.Writer.Error!void { | |
| 753 | pub fn flush(ws: *WebSocket) Writer.Error!void { | |
| 753 | 754 | try ws.output.flush(); |
| 754 | 755 | } |
| 755 | 756 | }; |
lib/std/io.zig-3| ... | ... | @@ -72,8 +72,6 @@ pub const Limit = enum(usize) { |
| 72 | 72 | pub const Reader = @import("io/Reader.zig"); |
| 73 | 73 | pub const Writer = @import("io/Writer.zig"); |
| 74 | 74 | |
| 75 | pub const AllocatingWriter = @import("io/AllocatingWriter.zig"); | |
| 76 | ||
| 77 | 75 | pub const ChangeDetectionStream = @import("io/change_detection_stream.zig").ChangeDetectionStream; |
| 78 | 76 | pub const changeDetectionStream = @import("io/change_detection_stream.zig").changeDetectionStream; |
| 79 | 77 | |
| ... | ... | @@ -485,7 +483,6 @@ pub fn PollFiles(comptime StreamEnum: type) type { |
| 485 | 483 | } |
| 486 | 484 | |
| 487 | 485 | test { |
| 488 | _ = AllocatingWriter; | |
| 489 | 486 | _ = Reader; |
| 490 | 487 | _ = Writer; |
| 491 | 488 | _ = @import("io/test.zig"); |
lib/std/io/AllocatingWriter.zig deleted-215| ... | ... | @@ -1,215 +0,0 @@ |
| 1 | //! While it is possible to use `std.ArrayList` as the underlying writer when | |
| 2 | //! using `std.io.BufferedWriter` by populating the `std.io.Writer` interface | |
| 3 | //! and then using an empty buffer, it means that every use of | |
| 4 | //! `std.io.BufferedWriter` will go through the vtable, including for | |
| 5 | //! functions such as `writeByte`. This API instead maintains | |
| 6 | //! `std.io.BufferedWriter` state such that it writes to the unused capacity of | |
| 7 | //! an array list, filling it up completely before making a call through the | |
| 8 | //! vtable, causing a resize. Consequently, the same, optimized, non-generic | |
| 9 | //! machine code that uses `std.io.Reader`, such as formatted printing, | |
| 10 | //! takes the hot paths when using this API. | |
| 11 | ||
| 12 | const std = @import("../std.zig"); | |
| 13 | const AllocatingWriter = @This(); | |
| 14 | const assert = std.debug.assert; | |
| 15 | ||
| 16 | /// This is missing the data stored in `buffered_writer`. See `getWritten` for | |
| 17 | /// returning a slice that includes both. | |
| 18 | written: []u8, | |
| 19 | allocator: std.mem.Allocator, | |
| 20 | /// When using this API, it is not necessary to call | |
| 21 | /// `std.io.BufferedWriter.flush`. | |
| 22 | buffered_writer: std.io.BufferedWriter, | |
| 23 | ||
| 24 | const vtable: std.io.Writer.VTable = .{ | |
| 25 | .writeSplat = writeSplat, | |
| 26 | .writeFile = writeFile, | |
| 27 | }; | |
| 28 | ||
| 29 | /// Sets the `AllocatingWriter` to an empty state. | |
| 30 | pub fn init(aw: *AllocatingWriter, allocator: std.mem.Allocator) void { | |
| 31 | aw.initOwnedSlice(allocator, &.{}); | |
| 32 | } | |
| 33 | ||
| 34 | pub fn initCapacity(aw: *AllocatingWriter, allocator: std.mem.Allocator, capacity: usize) error{OutOfMemory}!void { | |
| 35 | const initial_buffer = try allocator.alloc(u8, capacity); | |
| 36 | aw.initOwnedSlice(allocator, initial_buffer); | |
| 37 | } | |
| 38 | ||
| 39 | pub fn initOwnedSlice(aw: *AllocatingWriter, allocator: std.mem.Allocator, slice: []u8) void { | |
| 40 | aw.* = .{ | |
| 41 | .written = slice[0..0], | |
| 42 | .allocator = allocator, | |
| 43 | .buffered_writer = .{ | |
| 44 | .unbuffered_writer = .{ | |
| 45 | .context = aw, | |
| 46 | .vtable = &vtable, | |
| 47 | }, | |
| 48 | .buffer = slice, | |
| 49 | }, | |
| 50 | }; | |
| 51 | } | |
| 52 | ||
| 53 | pub fn deinit(aw: *AllocatingWriter) void { | |
| 54 | const written = aw.written; | |
| 55 | aw.allocator.free(written.ptr[0 .. written.len + aw.buffered_writer.buffer.len]); | |
| 56 | aw.* = undefined; | |
| 57 | } | |
| 58 | ||
| 59 | /// Replaces `array_list` with empty, taking ownership of the memory. | |
| 60 | pub fn fromArrayList( | |
| 61 | aw: *AllocatingWriter, | |
| 62 | allocator: std.mem.Allocator, | |
| 63 | array_list: *std.ArrayListUnmanaged(u8), | |
| 64 | ) *std.io.BufferedWriter { | |
| 65 | aw.* = .{ | |
| 66 | .written = array_list.items, | |
| 67 | .allocator = allocator, | |
| 68 | .buffered_writer = .{ | |
| 69 | .unbuffered_writer = .{ | |
| 70 | .context = aw, | |
| 71 | .vtable = &vtable, | |
| 72 | }, | |
| 73 | .buffer = array_list.unusedCapacitySlice(), | |
| 74 | }, | |
| 75 | }; | |
| 76 | array_list.* = .empty; | |
| 77 | return &aw.buffered_writer; | |
| 78 | } | |
| 79 | ||
| 80 | /// Returns an array list that takes ownership of the allocated memory. | |
| 81 | /// Resets the `AllocatingWriter` to an empty state. | |
| 82 | pub fn toArrayList(aw: *AllocatingWriter) std.ArrayListUnmanaged(u8) { | |
| 83 | const bw = &aw.buffered_writer; | |
| 84 | const written = aw.written; | |
| 85 | const result: std.ArrayListUnmanaged(u8) = .{ | |
| 86 | .items = written.ptr[0 .. written.len + bw.end], | |
| 87 | .capacity = written.len + bw.buffer.len, | |
| 88 | }; | |
| 89 | aw.written = &.{}; | |
| 90 | bw.buffer = &.{}; | |
| 91 | bw.end = 0; | |
| 92 | return result; | |
| 93 | } | |
| 94 | ||
| 95 | pub fn toOwnedSlice(aw: *AllocatingWriter) error{OutOfMemory}![]u8 { | |
| 96 | var list = aw.toArrayList(); | |
| 97 | return list.toOwnedSlice(aw.allocator); | |
| 98 | } | |
| 99 | ||
| 100 | pub fn toOwnedSliceSentinel(aw: *AllocatingWriter, comptime sentinel: u8) error{OutOfMemory}![:sentinel]u8 { | |
| 101 | const gpa = aw.allocator; | |
| 102 | var list = toArrayList(aw); | |
| 103 | return list.toOwnedSliceSentinel(gpa, sentinel); | |
| 104 | } | |
| 105 | ||
| 106 | fn setArrayList(aw: *AllocatingWriter, list: std.ArrayListUnmanaged(u8)) void { | |
| 107 | aw.written = list.items; | |
| 108 | aw.buffered_writer.buffer = list.unusedCapacitySlice(); | |
| 109 | } | |
| 110 | ||
| 111 | pub fn getWritten(aw: *AllocatingWriter) []u8 { | |
| 112 | const bw = &aw.buffered_writer; | |
| 113 | const end = aw.buffered_writer.end; | |
| 114 | const written = aw.written.ptr[0 .. aw.written.len + end]; | |
| 115 | aw.written = written; | |
| 116 | bw.buffer = bw.buffer[end..]; | |
| 117 | bw.end = 0; | |
| 118 | return written; | |
| 119 | } | |
| 120 | ||
| 121 | pub fn shrinkRetainingCapacity(aw: *AllocatingWriter, new_len: usize) void { | |
| 122 | const bw = &aw.buffered_writer; | |
| 123 | bw.buffer = aw.written.ptr[new_len .. aw.written.len + bw.buffer.len]; | |
| 124 | bw.end = 0; | |
| 125 | aw.written.len = new_len; | |
| 126 | } | |
| 127 | ||
| 128 | pub fn clearRetainingCapacity(aw: *AllocatingWriter) void { | |
| 129 | aw.shrinkRetainingCapacity(0); | |
| 130 | } | |
| 131 | ||
| 132 | fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) std.io.Writer.Error!usize { | |
| 133 | assert(data.len != 0); | |
| 134 | const aw: *AllocatingWriter = @alignCast(@ptrCast(context)); | |
| 135 | const start_len = aw.written.len; | |
| 136 | const bw = &aw.buffered_writer; | |
| 137 | const skip_first = data[0].ptr == aw.written.ptr + start_len; | |
| 138 | const items_len = if (skip_first) start_len + data[0].len else start_len; | |
| 139 | var list: std.ArrayListUnmanaged(u8) = .{ | |
| 140 | .items = aw.written.ptr[0..items_len], | |
| 141 | .capacity = start_len + bw.buffer.len, | |
| 142 | }; | |
| 143 | defer setArrayList(aw, list); | |
| 144 | const rest = if (splat == 0) data[1 .. data.len - 1] else data[1..]; | |
| 145 | const pattern = data[data.len - 1]; | |
| 146 | const remaining_splat = splat - 1; | |
| 147 | var new_capacity: usize = list.capacity + pattern.len * remaining_splat; | |
| 148 | for (rest) |bytes| new_capacity += bytes.len; | |
| 149 | list.ensureTotalCapacity(aw.allocator, new_capacity + 1) catch return error.WriteFailed; | |
| 150 | for (rest) |bytes| list.appendSliceAssumeCapacity(bytes); | |
| 151 | if (pattern.len == 1) { | |
| 152 | list.appendNTimesAssumeCapacity(pattern[0], remaining_splat); | |
| 153 | } else { | |
| 154 | for (0..remaining_splat) |_| list.appendSliceAssumeCapacity(pattern); | |
| 155 | } | |
| 156 | aw.written = list.items; | |
| 157 | bw.buffer = list.unusedCapacitySlice(); | |
| 158 | return list.items.len - start_len; | |
| 159 | } | |
| 160 | ||
| 161 | fn writeFile( | |
| 162 | context: ?*anyopaque, | |
| 163 | file_reader: *std.fs.File.Reader, | |
| 164 | limit: std.io.Limit, | |
| 165 | headers_and_trailers_full: []const []const u8, | |
| 166 | headers_len_full: usize, | |
| 167 | ) std.io.Writer.FileError!usize { | |
| 168 | if (std.fs.File.Handle == void) return error.Unimplemented; | |
| 169 | const aw: *AllocatingWriter = @alignCast(@ptrCast(context)); | |
| 170 | const gpa = aw.allocator; | |
| 171 | var list = aw.toArrayList(); | |
| 172 | defer setArrayList(aw, list); | |
| 173 | const start_len = list.items.len; | |
| 174 | const headers_and_trailers, const headers_len = if (headers_len_full >= 1) b: { | |
| 175 | assert(headers_and_trailers_full[0].ptr == list.items.ptr + start_len); | |
| 176 | list.items.len += headers_and_trailers_full[0].len; | |
| 177 | break :b .{ headers_and_trailers_full[1..], headers_len_full - 1 }; | |
| 178 | } else .{ headers_and_trailers_full, headers_len_full }; | |
| 179 | const trailers = headers_and_trailers[headers_len..]; | |
| 180 | const pos = file_reader.pos; | |
| 181 | ||
| 182 | const additional = if (file_reader.getSize()) |size| size - pos else |_| std.atomic.cache_line; | |
| 183 | var new_capacity: usize = list.capacity + limit.minInt(additional); | |
| 184 | for (headers_and_trailers) |bytes| new_capacity += bytes.len; | |
| 185 | list.ensureTotalCapacity(gpa, new_capacity) catch return error.WriteFailed; | |
| 186 | for (headers_and_trailers[0..headers_len]) |bytes| list.appendSliceAssumeCapacity(bytes); | |
| 187 | const dest = limit.slice(list.items.ptr[list.items.len..list.capacity]); | |
| 188 | const n = file_reader.read(dest) catch |err| switch (err) { | |
| 189 | error.ReadFailed => return error.ReadFailed, | |
| 190 | error.EndOfStream => 0, | |
| 191 | }; | |
| 192 | const is_end = if (file_reader.getSize()) |size| n >= size - pos else |_| n == 0; | |
| 193 | if (is_end) { | |
| 194 | new_capacity = list.capacity; | |
| 195 | for (trailers) |bytes| new_capacity += bytes.len; | |
| 196 | list.ensureTotalCapacity(gpa, new_capacity) catch return error.WriteFailed; | |
| 197 | for (trailers) |bytes| list.appendSliceAssumeCapacity(bytes); | |
| 198 | } else { | |
| 199 | list.items.len += n; | |
| 200 | } | |
| 201 | return list.items.len - start_len; | |
| 202 | } | |
| 203 | ||
| 204 | test AllocatingWriter { | |
| 205 | var aw: AllocatingWriter = undefined; | |
| 206 | aw.init(std.testing.allocator); | |
| 207 | defer aw.deinit(); | |
| 208 | const bw = &aw.buffered_writer; | |
| 209 | ||
| 210 | const x: i32 = 42; | |
| 211 | const y: i32 = 1234; | |
| 212 | try bw.print("x: {}\ny: {}\n", .{ x, y }); | |
| 213 | ||
| 214 | try std.testing.expectEqualSlices(u8, "x: 42\ny: 1234\n", aw.getWritten()); | |
| 215 | } |
lib/std/io/BufferedWriter.zig deleted-1859| ... | ... | @@ -1,1859 +0,0 @@ |
| 1 | const std = @import("../std.zig"); | |
| 2 | const BufferedWriter = @This(); | |
| 3 | const assert = std.debug.assert; | |
| 4 | const native_endian = @import("builtin").target.cpu.arch.endian(); | |
| 5 | const Writer = std.io.Writer; | |
| 6 | const Allocator = std.mem.Allocator; | |
| 7 | const testing = std.testing; | |
| 8 | const Limit = std.io.Limit; | |
| 9 | const File = std.fs.File; | |
| 10 | ||
| 11 | /// Underlying stream to send bytes to. | |
| 12 | /// | |
| 13 | /// A write will only be sent here if it could not fit into `buffer`, or if it | |
| 14 | /// is a `writeFile`. | |
| 15 | /// | |
| 16 | /// `unbuffered_writer` may modify `buffer` if the number of bytes returned | |
| 17 | /// equals number of bytes provided. This property is exploited by | |
| 18 | /// `std.io.AllocatingWriter` for example. | |
| 19 | unbuffered_writer: Writer, | |
| 20 | /// If this has length zero, the writer is unbuffered, and `flush` is a no-op. | |
| 21 | buffer: []u8, | |
| 22 | /// In `buffer` before this are buffered bytes, after this is `undefined`. | |
| 23 | end: usize = 0, | |
| 24 | /// Tracks total number of bytes written to this `BufferedWriter`. This value | |
| 25 | /// only increases. In the case of fixed mode, this value always equals `end`. | |
| 26 | count: usize = 0, | |
| 27 | ||
| 28 | /// Number of slices to store on the stack, when trying to send as many byte | |
| 29 | /// vectors through the underlying write calls as possible. | |
| 30 | pub const max_buffers_len = 8; | |
| 31 | ||
| 32 | /// Although `BufferedWriter` can easily satisfy the `Writer` interface, it's | |
| 33 | /// generally more practical to pass a `BufferedWriter` instance itself around, | |
| 34 | /// since it will result in fewer calls across vtable boundaries. | |
| 35 | pub fn writer(bw: *BufferedWriter) Writer { | |
| 36 | return .{ | |
| 37 | .context = bw, | |
| 38 | .vtable = &.{ | |
| 39 | .writeSplat = passthruWriteSplat, | |
| 40 | .writeFile = passthruWriteFile, | |
| 41 | }, | |
| 42 | }; | |
| 43 | } | |
| 44 | ||
| 45 | const fixed_vtable: Writer.VTable = .{ | |
| 46 | .writeSplat = fixedWriteSplat, | |
| 47 | .writeFile = Writer.unimplementedWriteFile, | |
| 48 | }; | |
| 49 | ||
| 50 | /// Replaces the `BufferedWriter` with one that writes to `buffer` and returns | |
| 51 | /// `error.WriteFailed` when it is full. `end` and `count` will always be | |
| 52 | /// equal. | |
| 53 | pub fn initFixed(bw: *BufferedWriter, buffer: []u8) void { | |
| 54 | bw.* = .{ | |
| 55 | .unbuffered_writer = .{ | |
| 56 | .context = bw, | |
| 57 | .vtable = &fixed_vtable, | |
| 58 | }, | |
| 59 | .buffer = buffer, | |
| 60 | }; | |
| 61 | } | |
| 62 | ||
| 63 | pub fn hashed(bw: *BufferedWriter, hasher: anytype) Writer.Hashed(@TypeOf(hasher)) { | |
| 64 | return .{ .out = bw, .hasher = hasher }; | |
| 65 | } | |
| 66 | ||
| 67 | /// This function is available when using `initFixed`. | |
| 68 | pub fn getWritten(bw: *const BufferedWriter) []u8 { | |
| 69 | assert(bw.unbuffered_writer.vtable == &fixed_vtable); | |
| 70 | return bw.buffer[0..bw.end]; | |
| 71 | } | |
| 72 | ||
| 73 | /// This function is available when using `initFixed`. | |
| 74 | pub fn reset(bw: *BufferedWriter) void { | |
| 75 | assert(bw.unbuffered_writer.vtable == &fixed_vtable); | |
| 76 | bw.end = 0; | |
| 77 | bw.count = 0; | |
| 78 | } | |
| 79 | ||
| 80 | pub fn flush(bw: *BufferedWriter) Writer.Error!void { | |
| 81 | const send_buffer = bw.buffer[0..bw.end]; | |
| 82 | var index: usize = 0; | |
| 83 | while (index < send_buffer.len) index += try bw.unbuffered_writer.writeVec(&.{send_buffer[index..]}); | |
| 84 | bw.end = 0; | |
| 85 | } | |
| 86 | ||
| 87 | pub fn flushLimit(bw: *BufferedWriter, limit: Limit) Writer.Error!void { | |
| 88 | const buffer = limit.slice(bw.buffer[0..bw.end]); | |
| 89 | var index: usize = 0; | |
| 90 | while (index < buffer.len) index += try bw.unbuffered_writer.writeVec(&.{buffer[index..]}); | |
| 91 | const remainder = bw.buffer[index..]; | |
| 92 | std.mem.copyForwards(u8, bw.buffer[0..remainder.len], remainder); | |
| 93 | bw.end = remainder.len; | |
| 94 | } | |
| 95 | ||
| 96 | pub fn unusedCapacitySlice(bw: *const BufferedWriter) []u8 { | |
| 97 | return bw.buffer[bw.end..]; | |
| 98 | } | |
| 99 | ||
| 100 | /// Asserts the provided buffer has total capacity enough for `len`. | |
| 101 | /// | |
| 102 | /// Advances the buffer end position by `len`. | |
| 103 | pub fn writableArray(bw: *BufferedWriter, comptime len: usize) Writer.Error!*[len]u8 { | |
| 104 | const big_slice = try bw.writableSliceGreedy(len); | |
| 105 | advance(bw, len); | |
| 106 | return big_slice[0..len]; | |
| 107 | } | |
| 108 | ||
| 109 | /// Asserts the provided buffer has total capacity enough for `len`. | |
| 110 | /// | |
| 111 | /// Advances the buffer end position by `len`. | |
| 112 | pub fn writableSlice(bw: *BufferedWriter, len: usize) Writer.Error![]u8 { | |
| 113 | const big_slice = try bw.writableSliceGreedy(len); | |
| 114 | advance(bw, len); | |
| 115 | return big_slice[0..len]; | |
| 116 | } | |
| 117 | ||
| 118 | /// Asserts the provided buffer has total capacity enough for `minimum_length`. | |
| 119 | /// | |
| 120 | /// Does not `advance` the buffer end position. | |
| 121 | /// | |
| 122 | /// If `minimum_length` is zero, this is equivalent to `unusedCapacitySlice`. | |
| 123 | pub fn writableSliceGreedy(bw: *BufferedWriter, minimum_length: usize) Writer.Error![]u8 { | |
| 124 | assert(bw.buffer.len >= minimum_length); | |
| 125 | const cap_slice = bw.buffer[bw.end..]; | |
| 126 | if (cap_slice.len >= minimum_length) { | |
| 127 | @branchHint(.likely); | |
| 128 | return cap_slice; | |
| 129 | } | |
| 130 | const buffer = bw.buffer[0..bw.end]; | |
| 131 | const n = try bw.unbuffered_writer.writeVec(&.{buffer}); | |
| 132 | if (n == buffer.len) { | |
| 133 | @branchHint(.likely); | |
| 134 | bw.end = 0; | |
| 135 | return bw.buffer; | |
| 136 | } | |
| 137 | if (n > 0) { | |
| 138 | const remainder = buffer[n..]; | |
| 139 | std.mem.copyForwards(u8, buffer[0..remainder.len], remainder); | |
| 140 | bw.end = remainder.len; | |
| 141 | } | |
| 142 | return bw.buffer[bw.end..]; | |
| 143 | } | |
| 144 | ||
| 145 | pub fn ensureUnusedCapacity(bw: *BufferedWriter, n: usize) Writer.Error!void { | |
| 146 | _ = try writableSliceGreedy(bw, n); | |
| 147 | } | |
| 148 | ||
| 149 | pub fn undo(bw: *BufferedWriter, n: usize) void { | |
| 150 | bw.end -= n; | |
| 151 | bw.count -= n; | |
| 152 | } | |
| 153 | ||
| 154 | /// After calling `writableSliceGreedy`, this function tracks how many bytes | |
| 155 | /// were written to it. | |
| 156 | /// | |
| 157 | /// This is not needed when using `writableSlice` or `writableArray`. | |
| 158 | pub fn advance(bw: *BufferedWriter, n: usize) void { | |
| 159 | const new_end = bw.end + n; | |
| 160 | assert(new_end <= bw.buffer.len); | |
| 161 | bw.end = new_end; | |
| 162 | bw.count += n; | |
| 163 | } | |
| 164 | ||
| 165 | /// The `data` parameter is mutable because this function needs to mutate the | |
| 166 | /// fields in order to handle partial writes from `Writer.VTable.writeSplat`. | |
| 167 | pub fn writeVecAll(bw: *BufferedWriter, data: [][]const u8) Writer.Error!void { | |
| 168 | var index: usize = 0; | |
| 169 | var truncate: usize = 0; | |
| 170 | while (index < data.len) { | |
| 171 | { | |
| 172 | const untruncated = data[index]; | |
| 173 | data[index] = untruncated[truncate..]; | |
| 174 | defer data[index] = untruncated; | |
| 175 | truncate += try bw.writeVec(data[index..]); | |
| 176 | } | |
| 177 | while (index < data.len and truncate >= data[index].len) { | |
| 178 | truncate -= data[index].len; | |
| 179 | index += 1; | |
| 180 | } | |
| 181 | } | |
| 182 | } | |
| 183 | ||
| 184 | /// The `data` parameter is mutable because this function needs to mutate the | |
| 185 | /// fields in order to handle partial writes from `Writer.VTable.writeSplat`. | |
| 186 | pub fn writeSplatAll(bw: *BufferedWriter, data: [][]const u8, splat: usize) Writer.Error!void { | |
| 187 | var index: usize = 0; | |
| 188 | var truncate: usize = 0; | |
| 189 | var remaining_splat = splat; | |
| 190 | while (index + 1 < data.len) { | |
| 191 | { | |
| 192 | const untruncated = data[index]; | |
| 193 | data[index] = untruncated[truncate..]; | |
| 194 | defer data[index] = untruncated; | |
| 195 | truncate += try bw.writeSplat(data[index..], remaining_splat); | |
| 196 | } | |
| 197 | while (truncate >= data[index].len) { | |
| 198 | if (index + 1 < data.len) { | |
| 199 | truncate -= data[index].len; | |
| 200 | index += 1; | |
| 201 | } else { | |
| 202 | const last = data[data.len - 1]; | |
| 203 | remaining_splat -= @divExact(truncate, last.len); | |
| 204 | while (remaining_splat > 0) { | |
| 205 | const n = try bw.writeSplat(data[data.len - 1 ..][0..1], remaining_splat); | |
| 206 | remaining_splat -= @divExact(n, last.len); | |
| 207 | } | |
| 208 | return; | |
| 209 | } | |
| 210 | } | |
| 211 | } | |
| 212 | } | |
| 213 | ||
| 214 | /// If the number of bytes to write based on `data` and `splat` fits inside | |
| 215 | /// `unusedCapacitySlice`, this function is guaranteed to not fail, not call | |
| 216 | /// into the underlying writer, and return the full number of bytes. | |
| 217 | pub fn writeSplat(bw: *BufferedWriter, data: []const []const u8, splat: usize) Writer.Error!usize { | |
| 218 | return passthruWriteSplat(bw, data, splat); | |
| 219 | } | |
| 220 | ||
| 221 | /// If the total number of bytes of `data` fits inside `unusedCapacitySlice`, | |
| 222 | /// this function is guaranteed to not fail, not call into the underlying | |
| 223 | /// writer, and return the total bytes inside `data`. | |
| 224 | pub fn writeVec(bw: *BufferedWriter, data: []const []const u8) Writer.Error!usize { | |
| 225 | return passthruWriteSplat(bw, data, 1); | |
| 226 | } | |
| 227 | ||
| 228 | /// Equivalent to `writeSplat` but writes at most `limit` bytes. | |
| 229 | pub fn writeSplatLimit( | |
| 230 | bw: *BufferedWriter, | |
| 231 | data: []const []const u8, | |
| 232 | splat: usize, | |
| 233 | limit: Limit, | |
| 234 | ) Writer.Error!usize { | |
| 235 | _ = bw; | |
| 236 | _ = data; | |
| 237 | _ = splat; | |
| 238 | _ = limit; | |
| 239 | @panic("TODO"); | |
| 240 | } | |
| 241 | ||
| 242 | fn passthruWriteSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) Writer.Error!usize { | |
| 243 | const bw: *BufferedWriter = @alignCast(@ptrCast(context)); | |
| 244 | const buffer = bw.buffer; | |
| 245 | const start_end = bw.end; | |
| 246 | ||
| 247 | var buffers: [max_buffers_len][]const u8 = undefined; | |
| 248 | var end = start_end; | |
| 249 | for (data, 0..) |bytes, i| { | |
| 250 | const new_end = end + bytes.len; | |
| 251 | if (new_end <= buffer.len) { | |
| 252 | @branchHint(.likely); | |
| 253 | @memcpy(buffer[end..new_end], bytes); | |
| 254 | end = new_end; | |
| 255 | continue; | |
| 256 | } | |
| 257 | if (end == 0) return track(&bw.count, try bw.unbuffered_writer.writeSplat(data, splat)); | |
| 258 | buffers[0] = buffer[0..end]; | |
| 259 | const remaining_data = data[i..]; | |
| 260 | const remaining_buffers = buffers[1..]; | |
| 261 | const len: usize = @min(remaining_data.len, remaining_buffers.len); | |
| 262 | @memcpy(remaining_buffers[0..len], remaining_data[0..len]); | |
| 263 | const send_buffers = buffers[0 .. len + 1]; | |
| 264 | if (len >= remaining_data.len) { | |
| 265 | @branchHint(.likely); | |
| 266 | // Made it past the headers, so we can enable splatting. | |
| 267 | const n = try bw.unbuffered_writer.writeSplat(send_buffers, splat); | |
| 268 | if (n < end) { | |
| 269 | @branchHint(.unlikely); | |
| 270 | const remainder = buffer[n..end]; | |
| 271 | std.mem.copyForwards(u8, buffer[0..remainder.len], remainder); | |
| 272 | bw.end = remainder.len; | |
| 273 | return track(&bw.count, end - start_end); | |
| 274 | } | |
| 275 | bw.end = 0; | |
| 276 | return track(&bw.count, n - start_end); | |
| 277 | } | |
| 278 | const n = try bw.unbuffered_writer.writeSplat(send_buffers, 1); | |
| 279 | if (n < end) { | |
| 280 | @branchHint(.unlikely); | |
| 281 | const remainder = buffer[n..end]; | |
| 282 | std.mem.copyForwards(u8, buffer[0..remainder.len], remainder); | |
| 283 | bw.end = remainder.len; | |
| 284 | return track(&bw.count, end - start_end); | |
| 285 | } | |
| 286 | bw.end = 0; | |
| 287 | return track(&bw.count, n - start_end); | |
| 288 | } | |
| 289 | ||
| 290 | const pattern = data[data.len - 1]; | |
| 291 | ||
| 292 | if (splat == 0) { | |
| 293 | @branchHint(.unlikely); | |
| 294 | // It was added in the loop above; undo it here. | |
| 295 | end -= pattern.len; | |
| 296 | bw.end = end; | |
| 297 | return track(&bw.count, end - start_end); | |
| 298 | } | |
| 299 | ||
| 300 | const remaining_splat = splat - 1; | |
| 301 | ||
| 302 | switch (pattern.len) { | |
| 303 | 0 => { | |
| 304 | bw.end = end; | |
| 305 | return track(&bw.count, end - start_end); | |
| 306 | }, | |
| 307 | 1 => { | |
| 308 | const new_end = end + remaining_splat; | |
| 309 | if (new_end <= buffer.len) { | |
| 310 | @branchHint(.likely); | |
| 311 | @memset(buffer[end..new_end], pattern[0]); | |
| 312 | bw.end = new_end; | |
| 313 | return track(&bw.count, new_end - start_end); | |
| 314 | } | |
| 315 | buffers[0] = buffer[0..end]; | |
| 316 | buffers[1] = pattern; | |
| 317 | const n = try bw.unbuffered_writer.writeSplat(buffers[0..2], remaining_splat); | |
| 318 | if (n < end) { | |
| 319 | @branchHint(.unlikely); | |
| 320 | const remainder = buffer[n..end]; | |
| 321 | std.mem.copyForwards(u8, buffer[0..remainder.len], remainder); | |
| 322 | bw.end = remainder.len; | |
| 323 | return track(&bw.count, end - start_end); | |
| 324 | } | |
| 325 | bw.end = 0; | |
| 326 | return track(&bw.count, n - start_end); | |
| 327 | }, | |
| 328 | else => { | |
| 329 | const new_end = end + pattern.len * remaining_splat; | |
| 330 | if (new_end <= buffer.len) { | |
| 331 | @branchHint(.likely); | |
| 332 | while (end < new_end) : (end += pattern.len) { | |
| 333 | @memcpy(buffer[end..][0..pattern.len], pattern); | |
| 334 | } | |
| 335 | bw.end = new_end; | |
| 336 | return track(&bw.count, new_end - start_end); | |
| 337 | } | |
| 338 | buffers[0] = buffer[0..end]; | |
| 339 | buffers[1] = pattern; | |
| 340 | const n = try bw.unbuffered_writer.writeSplat(buffers[0..2], remaining_splat); | |
| 341 | if (n < end) { | |
| 342 | @branchHint(.unlikely); | |
| 343 | const remainder = buffer[n..end]; | |
| 344 | std.mem.copyForwards(u8, buffer[0..remainder.len], remainder); | |
| 345 | bw.end = remainder.len; | |
| 346 | return track(&bw.count, end - start_end); | |
| 347 | } | |
| 348 | bw.end = 0; | |
| 349 | return track(&bw.count, n - start_end); | |
| 350 | }, | |
| 351 | } | |
| 352 | } | |
| 353 | ||
| 354 | fn track(count: *usize, n: usize) usize { | |
| 355 | count.* += n; | |
| 356 | return n; | |
| 357 | } | |
| 358 | ||
| 359 | /// When this function is called it means the buffer got full, so it's time | |
| 360 | /// to return an error. However, we still need to make sure all of the | |
| 361 | /// available buffer has been filled. | |
| 362 | fn fixedWriteSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) Writer.Error!usize { | |
| 363 | const bw: *BufferedWriter = @alignCast(@ptrCast(context)); | |
| 364 | for (data) |bytes| { | |
| 365 | const dest = bw.buffer[bw.end..]; | |
| 366 | if (dest.len == 0) return error.WriteFailed; | |
| 367 | const len = @min(bytes.len, dest.len); | |
| 368 | @memcpy(dest[0..len], bytes[0..len]); | |
| 369 | bw.end += len; | |
| 370 | bw.count = bw.end; | |
| 371 | } | |
| 372 | const pattern = data[data.len - 1]; | |
| 373 | const dest = bw.buffer[bw.end..]; | |
| 374 | switch (pattern.len) { | |
| 375 | 0 => unreachable, | |
| 376 | 1 => @memset(dest, pattern[0]), | |
| 377 | else => for (0..splat - 1) |i| @memcpy(dest[i * pattern.len ..][0..pattern.len], pattern), | |
| 378 | } | |
| 379 | bw.end = bw.buffer.len; | |
| 380 | bw.count = bw.end; | |
| 381 | return error.WriteFailed; | |
| 382 | } | |
| 383 | ||
| 384 | pub fn write(bw: *BufferedWriter, bytes: []const u8) Writer.Error!usize { | |
| 385 | const buffer = bw.buffer; | |
| 386 | const end = bw.end; | |
| 387 | const new_end = end + bytes.len; | |
| 388 | if (new_end > buffer.len) { | |
| 389 | var data: [2][]const u8 = .{ buffer[0..end], bytes }; | |
| 390 | const n = try bw.unbuffered_writer.writeVec(&data); | |
| 391 | if (n < end) { | |
| 392 | @branchHint(.unlikely); | |
| 393 | const remainder = buffer[n..end]; | |
| 394 | std.mem.copyForwards(u8, buffer[0..remainder.len], remainder); | |
| 395 | bw.end = remainder.len; | |
| 396 | return 0; | |
| 397 | } | |
| 398 | bw.end = 0; | |
| 399 | return track(&bw.count, n - end); | |
| 400 | } | |
| 401 | @memcpy(buffer[end..new_end], bytes); | |
| 402 | bw.end = new_end; | |
| 403 | return track(&bw.count, bytes.len); | |
| 404 | } | |
| 405 | ||
| 406 | /// Calls `write` as many times as necessary such that all of `bytes` are | |
| 407 | /// transferred. | |
| 408 | pub fn writeAll(bw: *BufferedWriter, bytes: []const u8) Writer.Error!void { | |
| 409 | var index: usize = 0; | |
| 410 | while (index < bytes.len) index += try bw.write(bytes[index..]); | |
| 411 | } | |
| 412 | ||
| 413 | pub fn print(bw: *BufferedWriter, comptime format: []const u8, args: anytype) Writer.Error!void { | |
| 414 | try std.fmt.format(bw, format, args); | |
| 415 | } | |
| 416 | ||
| 417 | pub fn writeByte(bw: *BufferedWriter, byte: u8) Writer.Error!void { | |
| 418 | const buffer = bw.buffer[0..bw.end]; | |
| 419 | if (buffer.len < bw.buffer.len) { | |
| 420 | @branchHint(.likely); | |
| 421 | buffer.ptr[buffer.len] = byte; | |
| 422 | bw.end = buffer.len + 1; | |
| 423 | bw.count += 1; | |
| 424 | return; | |
| 425 | } | |
| 426 | var buffers: [2][]const u8 = .{ buffer, &.{byte} }; | |
| 427 | while (true) { | |
| 428 | const n = try bw.unbuffered_writer.writeVec(&buffers); | |
| 429 | if (n == 0) { | |
| 430 | @branchHint(.unlikely); | |
| 431 | continue; | |
| 432 | } | |
| 433 | bw.count += 1; | |
| 434 | if (n >= buffer.len) { | |
| 435 | @branchHint(.likely); | |
| 436 | if (n > buffer.len) { | |
| 437 | @branchHint(.likely); | |
| 438 | bw.end = 0; | |
| 439 | return; | |
| 440 | } else { | |
| 441 | buffer[0] = byte; | |
| 442 | bw.end = 1; | |
| 443 | return; | |
| 444 | } | |
| 445 | } | |
| 446 | const remainder = buffer[n..]; | |
| 447 | std.mem.copyForwards(u8, buffer[0..remainder.len], remainder); | |
| 448 | buffer[remainder.len] = byte; | |
| 449 | bw.end = remainder.len + 1; | |
| 450 | return; | |
| 451 | } | |
| 452 | } | |
| 453 | ||
| 454 | /// Writes the same byte many times, performing the underlying write call as | |
| 455 | /// many times as necessary. | |
| 456 | pub fn splatByteAll(bw: *BufferedWriter, byte: u8, n: usize) Writer.Error!void { | |
| 457 | var remaining: usize = n; | |
| 458 | while (remaining > 0) remaining -= try bw.splatByte(byte, remaining); | |
| 459 | } | |
| 460 | ||
| 461 | /// Writes the same byte many times, allowing short writes. | |
| 462 | /// | |
| 463 | /// Does maximum of one underlying `Writer.VTable.writeSplat`. | |
| 464 | pub fn splatByte(bw: *BufferedWriter, byte: u8, n: usize) Writer.Error!usize { | |
| 465 | return passthruWriteSplat(bw, &.{&.{byte}}, n); | |
| 466 | } | |
| 467 | ||
| 468 | /// Writes the same slice many times, performing the underlying write call as | |
| 469 | /// many times as necessary. | |
| 470 | pub fn splatBytesAll(bw: *BufferedWriter, bytes: []const u8, splat: usize) Writer.Error!void { | |
| 471 | var remaining_bytes: usize = bytes.len * splat; | |
| 472 | remaining_bytes -= try bw.splatBytes(bytes, splat); | |
| 473 | while (remaining_bytes > 0) { | |
| 474 | const leftover = remaining_bytes % bytes.len; | |
| 475 | const buffers: [2][]const u8 = .{ bytes[bytes.len - leftover ..], bytes }; | |
| 476 | remaining_bytes -= try bw.splatBytes(&buffers, splat); | |
| 477 | } | |
| 478 | } | |
| 479 | ||
| 480 | /// Writes the same slice many times, allowing short writes. | |
| 481 | /// | |
| 482 | /// Does maximum of one underlying `Writer.VTable.writeSplat`. | |
| 483 | pub fn splatBytes(bw: *BufferedWriter, bytes: []const u8, n: usize) Writer.Error!usize { | |
| 484 | return passthruWriteSplat(bw, &.{bytes}, n); | |
| 485 | } | |
| 486 | ||
| 487 | /// Asserts the `buffer` was initialized with a capacity of at least `@sizeOf(T)` bytes. | |
| 488 | pub inline fn writeInt(bw: *BufferedWriter, comptime T: type, value: T, endian: std.builtin.Endian) Writer.Error!void { | |
| 489 | var bytes: [@divExact(@typeInfo(T).int.bits, 8)]u8 = undefined; | |
| 490 | std.mem.writeInt(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value, endian); | |
| 491 | return bw.writeAll(&bytes); | |
| 492 | } | |
| 493 | ||
| 494 | pub fn writeStruct(bw: *BufferedWriter, value: anytype) Writer.Error!void { | |
| 495 | // Only extern and packed structs have defined in-memory layout. | |
| 496 | comptime assert(@typeInfo(@TypeOf(value)).@"struct".layout != .auto); | |
| 497 | return bw.writeAll(std.mem.asBytes(&value)); | |
| 498 | } | |
| 499 | ||
| 500 | /// The function is inline to avoid the dead code in case `endian` is | |
| 501 | /// comptime-known and matches host endianness. | |
| 502 | /// TODO: make sure this value is not a reference type | |
| 503 | pub inline fn writeStructEndian(bw: *BufferedWriter, value: anytype, endian: std.builtin.Endian) Writer.Error!void { | |
| 504 | if (native_endian == endian) { | |
| 505 | return bw.writeStruct(value); | |
| 506 | } else { | |
| 507 | var copy = value; | |
| 508 | std.mem.byteSwapAllFields(@TypeOf(value), &copy); | |
| 509 | return bw.writeStruct(copy); | |
| 510 | } | |
| 511 | } | |
| 512 | ||
| 513 | pub inline fn writeSliceEndian( | |
| 514 | bw: *BufferedWriter, | |
| 515 | Elem: type, | |
| 516 | slice: []const Elem, | |
| 517 | endian: std.builtin.Endian, | |
| 518 | ) Writer.Error!void { | |
| 519 | if (native_endian == endian) { | |
| 520 | return writeAll(bw, @ptrCast(slice)); | |
| 521 | } else { | |
| 522 | return bw.writeArraySwap(bw, Elem, slice); | |
| 523 | } | |
| 524 | } | |
| 525 | ||
| 526 | /// Asserts that the buffer storage capacity is at least enough to store `@sizeOf(Elem)` | |
| 527 | pub fn writeSliceSwap(bw: *BufferedWriter, Elem: type, slice: []const Elem) Writer.Error!void { | |
| 528 | // copy to storage first, then swap in place | |
| 529 | _ = bw; | |
| 530 | _ = slice; | |
| 531 | @panic("TODO"); | |
| 532 | } | |
| 533 | ||
| 534 | /// Unlike `writeSplat` and `writeVec`, this function will call into the | |
| 535 | /// underlying writer even if there is enough buffer capacity for the file | |
| 536 | /// contents. | |
| 537 | /// | |
| 538 | /// Although it would be possible to eliminate `error.Unimplemented` from | |
| 539 | /// the error set by reading directly into the buffer in such case, | |
| 540 | /// this is not done because it is more efficient to do it in `writeFileAll` | |
| 541 | /// so that the error does not occur with each write. | |
| 542 | /// | |
| 543 | /// See `writeFileReading` for an alternative that does not have | |
| 544 | /// `error.Unimplemented` in the error set. | |
| 545 | pub fn writeFile( | |
| 546 | bw: *BufferedWriter, | |
| 547 | file_reader: *File.Reader, | |
| 548 | limit: Limit, | |
| 549 | headers_and_trailers: []const []const u8, | |
| 550 | headers_len: usize, | |
| 551 | ) Writer.FileError!usize { | |
| 552 | return passthruWriteFile(bw, file_reader, limit, headers_and_trailers, headers_len); | |
| 553 | } | |
| 554 | ||
| 555 | /// Returning zero bytes means end of stream. | |
| 556 | /// | |
| 557 | /// Asserts nonzero buffer capacity. | |
| 558 | pub fn writeFileReading( | |
| 559 | bw: *BufferedWriter, | |
| 560 | file_reader: *File.Reader, | |
| 561 | limit: Limit, | |
| 562 | ) Writer.ReadingFileError!usize { | |
| 563 | const dest = limit.slice(try bw.writableSliceGreedy(1)); | |
| 564 | const n = file_reader.read(dest) catch |err| switch (err) { | |
| 565 | error.EndOfStream => 0, | |
| 566 | error.ReadFailed => return error.ReadFailed, | |
| 567 | }; | |
| 568 | bw.advance(n); | |
| 569 | return n; | |
| 570 | } | |
| 571 | ||
| 572 | fn passthruWriteFile( | |
| 573 | context: ?*anyopaque, | |
| 574 | file_reader: *File.Reader, | |
| 575 | limit: Limit, | |
| 576 | headers_and_trailers: []const []const u8, | |
| 577 | headers_len: usize, | |
| 578 | ) Writer.FileError!usize { | |
| 579 | const bw: *BufferedWriter = @alignCast(@ptrCast(context)); | |
| 580 | const buffer = bw.buffer; | |
| 581 | if (buffer.len == 0) return track( | |
| 582 | &bw.count, | |
| 583 | try bw.unbuffered_writer.writeFile(file_reader, limit, headers_and_trailers, headers_len), | |
| 584 | ); | |
| 585 | const start_end = bw.end; | |
| 586 | const headers = headers_and_trailers[0..headers_len]; | |
| 587 | const trailers = headers_and_trailers[headers_len..]; | |
| 588 | var buffers: [max_buffers_len][]const u8 = undefined; | |
| 589 | var end = start_end; | |
| 590 | for (headers, 0..) |header, i| { | |
| 591 | const new_end = end + header.len; | |
| 592 | if (new_end <= buffer.len) { | |
| 593 | @branchHint(.likely); | |
| 594 | @memcpy(buffer[end..new_end], header); | |
| 595 | end = new_end; | |
| 596 | continue; | |
| 597 | } | |
| 598 | buffers[0] = buffer[0..end]; | |
| 599 | const remaining_headers = headers[i..]; | |
| 600 | const remaining_buffers = buffers[1..]; | |
| 601 | const buffers_len: usize = @min(remaining_headers.len, remaining_buffers.len); | |
| 602 | @memcpy(remaining_buffers[0..buffers_len], remaining_headers[0..buffers_len]); | |
| 603 | if (buffers_len >= remaining_headers.len) { | |
| 604 | // Made it past the headers, so we can call `writeFile`. | |
| 605 | const remaining_buffers_for_trailers = remaining_buffers[buffers_len..]; | |
| 606 | const send_trailers_len: usize = @min(trailers.len, remaining_buffers_for_trailers.len); | |
| 607 | @memcpy(remaining_buffers_for_trailers[0..send_trailers_len], trailers[0..send_trailers_len]); | |
| 608 | const send_headers_len = 1 + buffers_len; | |
| 609 | const send_buffers = buffers[0 .. send_headers_len + send_trailers_len]; | |
| 610 | const n = try bw.unbuffered_writer.writeFile(file_reader, limit, send_buffers, send_headers_len); | |
| 611 | if (n < end) { | |
| 612 | @branchHint(.unlikely); | |
| 613 | const remainder = buffer[n..end]; | |
| 614 | std.mem.copyForwards(u8, buffer[0..remainder.len], remainder); | |
| 615 | bw.end = remainder.len; | |
| 616 | return track(&bw.count, end - start_end); | |
| 617 | } | |
| 618 | bw.end = 0; | |
| 619 | return track(&bw.count, n - start_end); | |
| 620 | } | |
| 621 | // Have not made it past the headers yet; must call `writeVec`. | |
| 622 | const n = try bw.unbuffered_writer.writeVec(buffers[0 .. buffers_len + 1]); | |
| 623 | if (n < end) { | |
| 624 | @branchHint(.unlikely); | |
| 625 | const remainder = buffer[n..end]; | |
| 626 | std.mem.copyForwards(u8, buffer[0..remainder.len], remainder); | |
| 627 | bw.end = remainder.len; | |
| 628 | return track(&bw.count, end - start_end); | |
| 629 | } | |
| 630 | bw.end = 0; | |
| 631 | return track(&bw.count, n - start_end); | |
| 632 | } | |
| 633 | // All headers written to buffer. | |
| 634 | buffers[0] = buffer[0..end]; | |
| 635 | const remaining_buffers = buffers[1..]; | |
| 636 | const send_trailers_len: usize = @min(trailers.len, remaining_buffers.len); | |
| 637 | @memcpy(remaining_buffers[0..send_trailers_len], trailers[0..send_trailers_len]); | |
| 638 | const send_headers_len = @intFromBool(end != 0); | |
| 639 | const send_buffers = buffers[1 - send_headers_len .. 1 + send_trailers_len]; | |
| 640 | const n = try bw.unbuffered_writer.writeFile(file_reader, limit, send_buffers, send_headers_len); | |
| 641 | if (n < end) { | |
| 642 | @branchHint(.unlikely); | |
| 643 | const remainder = buffer[n..end]; | |
| 644 | std.mem.copyForwards(u8, buffer[0..remainder.len], remainder); | |
| 645 | bw.end = remainder.len; | |
| 646 | return track(&bw.count, end - start_end); | |
| 647 | } | |
| 648 | bw.end = 0; | |
| 649 | return track(&bw.count, n - start_end); | |
| 650 | } | |
| 651 | ||
| 652 | pub const WriteFileOptions = struct { | |
| 653 | limit: Limit = .unlimited, | |
| 654 | /// Headers and trailers must be passed together so that in case `len` is | |
| 655 | /// zero, they can be forwarded directly to `Writer.VTable.writeSplat`. | |
| 656 | /// | |
| 657 | /// The parameter is mutable because this function needs to mutate the | |
| 658 | /// fields in order to handle partial writes from `Writer.VTable.writeFile`. | |
| 659 | headers_and_trailers: [][]const u8 = &.{}, | |
| 660 | /// The number of trailers is inferred from | |
| 661 | /// `headers_and_trailers.len - headers_len`. | |
| 662 | headers_len: usize = 0, | |
| 663 | }; | |
| 664 | ||
| 665 | pub fn writeFileAll( | |
| 666 | bw: *BufferedWriter, | |
| 667 | file_reader: *std.fs.File.Reader, | |
| 668 | options: WriteFileOptions, | |
| 669 | ) Writer.ReadingFileError!void { | |
| 670 | const headers_and_trailers = options.headers_and_trailers; | |
| 671 | const headers = headers_and_trailers[0..options.headers_len]; | |
| 672 | var remaining = options.limit; | |
| 673 | var i: usize = 0; | |
| 674 | while (true) { | |
| 675 | const before_pos = file_reader.pos; | |
| 676 | var n = bw.writeFile(file_reader, remaining, headers_and_trailers[i..], headers.len - i) catch |err| switch (err) { | |
| 677 | error.ReadFailed => return error.ReadFailed, | |
| 678 | error.WriteFailed => return error.WriteFailed, | |
| 679 | error.Unimplemented => { | |
| 680 | file_reader.mode = file_reader.mode.toReading(); | |
| 681 | try bw.writeVecAll(headers[i..]); | |
| 682 | try bw.writeFileReadingAll(file_reader, remaining); | |
| 683 | try bw.writeVecAll(headers_and_trailers[headers.len..]); | |
| 684 | return; | |
| 685 | }, | |
| 686 | }; | |
| 687 | while (i < headers.len and n >= headers[i].len) { | |
| 688 | n -= headers[i].len; | |
| 689 | i += 1; | |
| 690 | } | |
| 691 | if (i < headers.len) { | |
| 692 | headers[i] = headers[i][n..]; | |
| 693 | continue; | |
| 694 | } | |
| 695 | const file_bytes_consumed = file_reader.pos - before_pos; | |
| 696 | remaining = remaining.subtract(file_bytes_consumed).?; | |
| 697 | const size = file_reader.size orelse continue; // End of file not yet reached. | |
| 698 | if (file_reader.pos < size) continue; // End of file not yet reached. | |
| 699 | n -= file_bytes_consumed; // Trailers reached. | |
| 700 | while (i < headers_and_trailers.len and n >= headers_and_trailers[i].len) { | |
| 701 | n -= headers_and_trailers[i].len; | |
| 702 | i += 1; | |
| 703 | } | |
| 704 | if (i < headers_and_trailers.len) { | |
| 705 | headers_and_trailers[i] = headers_and_trailers[i][n..]; | |
| 706 | try bw.writeVecAll(headers_and_trailers[i..]); | |
| 707 | return; | |
| 708 | } | |
| 709 | return; | |
| 710 | } | |
| 711 | } | |
| 712 | ||
| 713 | /// Equivalent to `writeFileAll` but uses direct `pread` and `read` calls on | |
| 714 | /// `file` rather than `Writer.writeFile`. This is generally used as a fallback | |
| 715 | /// when the underlying implementation returns `error.Unimplemented`, which is | |
| 716 | /// why that error code does not appear in this function's error set. | |
| 717 | /// | |
| 718 | /// Asserts nonzero buffer capacity. | |
| 719 | pub fn writeFileReadingAll( | |
| 720 | bw: *BufferedWriter, | |
| 721 | file_reader: *File.Reader, | |
| 722 | limit: Limit, | |
| 723 | ) Writer.ReadingFileError!void { | |
| 724 | var remaining = limit; | |
| 725 | while (remaining.nonzero()) { | |
| 726 | const n = try writeFileReading(bw, file_reader, remaining); | |
| 727 | if (n == 0) return; | |
| 728 | remaining = remaining.subtract(n).?; | |
| 729 | } | |
| 730 | } | |
| 731 | ||
| 732 | pub fn alignBuffer( | |
| 733 | bw: *BufferedWriter, | |
| 734 | buffer: []const u8, | |
| 735 | width: usize, | |
| 736 | alignment: std.fmt.Alignment, | |
| 737 | fill: u8, | |
| 738 | ) Writer.Error!void { | |
| 739 | const padding = if (buffer.len < width) width - buffer.len else 0; | |
| 740 | if (padding == 0) { | |
| 741 | @branchHint(.likely); | |
| 742 | return bw.writeAll(buffer); | |
| 743 | } | |
| 744 | switch (alignment) { | |
| 745 | .left => { | |
| 746 | try bw.writeAll(buffer); | |
| 747 | try bw.splatByteAll(fill, padding); | |
| 748 | }, | |
| 749 | .center => { | |
| 750 | const left_padding = padding / 2; | |
| 751 | const right_padding = (padding + 1) / 2; | |
| 752 | try bw.splatByteAll(fill, left_padding); | |
| 753 | try bw.writeAll(buffer); | |
| 754 | try bw.splatByteAll(fill, right_padding); | |
| 755 | }, | |
| 756 | .right => { | |
| 757 | try bw.splatByteAll(fill, padding); | |
| 758 | try bw.writeAll(buffer); | |
| 759 | }, | |
| 760 | } | |
| 761 | } | |
| 762 | ||
| 763 | pub fn alignBufferOptions(bw: *BufferedWriter, buffer: []const u8, options: std.fmt.Options) Writer.Error!void { | |
| 764 | return bw.alignBuffer(buffer, options.width orelse buffer.len, options.alignment, options.fill); | |
| 765 | } | |
| 766 | ||
| 767 | pub fn printAddress(bw: *BufferedWriter, value: anytype) Writer.Error!void { | |
| 768 | const T = @TypeOf(value); | |
| 769 | switch (@typeInfo(T)) { | |
| 770 | .pointer => |info| { | |
| 771 | try bw.writeAll(@typeName(info.child) ++ "@"); | |
| 772 | if (info.size == .slice) | |
| 773 | try bw.printIntOptions(@intFromPtr(value.ptr), 16, .lower, .{}) | |
| 774 | else | |
| 775 | try bw.printIntOptions(@intFromPtr(value), 16, .lower, .{}); | |
| 776 | return; | |
| 777 | }, | |
| 778 | .optional => |info| { | |
| 779 | if (@typeInfo(info.child) == .pointer) { | |
| 780 | try bw.writeAll(@typeName(info.child) ++ "@"); | |
| 781 | try bw.printIntOptions(@intFromPtr(value), 16, .lower, .{}); | |
| 782 | return; | |
| 783 | } | |
| 784 | }, | |
| 785 | else => {}, | |
| 786 | } | |
| 787 | ||
| 788 | @compileError("cannot format non-pointer type " ++ @typeName(T) ++ " with * specifier"); | |
| 789 | } | |
| 790 | ||
| 791 | pub fn printValue( | |
| 792 | bw: *BufferedWriter, | |
| 793 | comptime fmt: []const u8, | |
| 794 | options: std.fmt.Options, | |
| 795 | value: anytype, | |
| 796 | max_depth: usize, | |
| 797 | ) Writer.Error!void { | |
| 798 | const T = @TypeOf(value); | |
| 799 | ||
| 800 | if (comptime std.mem.eql(u8, fmt, "*")) { | |
| 801 | return bw.printAddress(value); | |
| 802 | } | |
| 803 | ||
| 804 | const is_any = comptime std.mem.eql(u8, fmt, ANY); | |
| 805 | if (!is_any and std.meta.hasMethod(T, "format")) { | |
| 806 | if (fmt.len > 0 and fmt[0] == 'f') { | |
| 807 | return value.format(bw, fmt[1..]); | |
| 808 | } else if (fmt.len == 0) { | |
| 809 | // after 0.15.0 is tagged, delete the hasMethod condition and this compile error | |
| 810 | @compileError("ambiguous format string; specify {f} to call format method, or {any} to skip it"); | |
| 811 | } | |
| 812 | } | |
| 813 | ||
| 814 | switch (@typeInfo(T)) { | |
| 815 | .float, .comptime_float => return bw.printFloat(if (is_any) "d" else fmt, options, value), | |
| 816 | .int, .comptime_int => return bw.printInt(if (is_any) "d" else fmt, options, value), | |
| 817 | .bool => { | |
| 818 | if (!is_any and fmt.len != 0) invalidFmtError(fmt, value); | |
| 819 | return bw.alignBufferOptions(if (value) "true" else "false", options); | |
| 820 | }, | |
| 821 | .void => { | |
| 822 | if (!is_any and fmt.len != 0) invalidFmtError(fmt, value); | |
| 823 | return bw.alignBufferOptions("void", options); | |
| 824 | }, | |
| 825 | .optional => { | |
| 826 | const remaining_fmt = comptime if (fmt.len > 0 and fmt[0] == '?') | |
| 827 | stripOptionalOrErrorUnionSpec(fmt) | |
| 828 | else if (is_any) | |
| 829 | ANY | |
| 830 | else | |
| 831 | @compileError("cannot print optional without a specifier (i.e. {?} or {any})"); | |
| 832 | if (value) |payload| { | |
| 833 | return bw.printValue(remaining_fmt, options, payload, max_depth); | |
| 834 | } else { | |
| 835 | return bw.alignBufferOptions("null", options); | |
| 836 | } | |
| 837 | }, | |
| 838 | .error_union => { | |
| 839 | const remaining_fmt = comptime if (fmt.len > 0 and fmt[0] == '!') | |
| 840 | stripOptionalOrErrorUnionSpec(fmt) | |
| 841 | else if (is_any) | |
| 842 | ANY | |
| 843 | else | |
| 844 | @compileError("cannot print error union without a specifier (i.e. {!} or {any})"); | |
| 845 | if (value) |payload| { | |
| 846 | return bw.printValue(remaining_fmt, options, payload, max_depth); | |
| 847 | } else |err| { | |
| 848 | return bw.printValue("", options, err, max_depth); | |
| 849 | } | |
| 850 | }, | |
| 851 | .error_set => { | |
| 852 | if (fmt.len == 1 and fmt[0] == 's') return bw.writeAll(@errorName(value)); | |
| 853 | if (!is_any and fmt.len != 0) invalidFmtError(fmt, value); | |
| 854 | try printErrorSet(bw, value); | |
| 855 | }, | |
| 856 | .@"enum" => { | |
| 857 | if (fmt.len == 1 and fmt[0] == 's') { | |
| 858 | try bw.writeAll(@tagName(value)); | |
| 859 | return; | |
| 860 | } | |
| 861 | if (!is_any) { | |
| 862 | if (fmt.len != 0) return printValue(bw, fmt, options, @intFromEnum(value), max_depth); | |
| 863 | return printValue(bw, ANY, options, value, max_depth); | |
| 864 | } | |
| 865 | const enum_info = @typeInfo(T).@"enum"; | |
| 866 | if (enum_info.is_exhaustive) { | |
| 867 | var vecs: [3][]const u8 = .{ @typeName(T), ".", @tagName(value) }; | |
| 868 | try bw.writeVecAll(&vecs); | |
| 869 | return; | |
| 870 | } | |
| 871 | try bw.writeAll(@typeName(T)); | |
| 872 | @setEvalBranchQuota(3 * enum_info.fields.len); | |
| 873 | inline for (enum_info.fields) |field| { | |
| 874 | if (@intFromEnum(value) == field.value) { | |
| 875 | try bw.writeAll("."); | |
| 876 | try bw.writeAll(@tagName(value)); | |
| 877 | return; | |
| 878 | } | |
| 879 | } | |
| 880 | try bw.writeByte('('); | |
| 881 | try bw.printValue(ANY, options, @intFromEnum(value), max_depth); | |
| 882 | try bw.writeByte(')'); | |
| 883 | }, | |
| 884 | .@"union" => |info| { | |
| 885 | if (!is_any) { | |
| 886 | if (fmt.len != 0) invalidFmtError(fmt, value); | |
| 887 | return printValue(bw, ANY, options, value, max_depth); | |
| 888 | } | |
| 889 | try bw.writeAll(@typeName(T)); | |
| 890 | if (max_depth == 0) { | |
| 891 | try bw.writeAll("{ ... }"); | |
| 892 | return; | |
| 893 | } | |
| 894 | if (info.tag_type) |UnionTagType| { | |
| 895 | try bw.writeAll("{ ."); | |
| 896 | try bw.writeAll(@tagName(@as(UnionTagType, value))); | |
| 897 | try bw.writeAll(" = "); | |
| 898 | inline for (info.fields) |u_field| { | |
| 899 | if (value == @field(UnionTagType, u_field.name)) { | |
| 900 | try bw.printValue(ANY, options, @field(value, u_field.name), max_depth - 1); | |
| 901 | } | |
| 902 | } | |
| 903 | try bw.writeAll(" }"); | |
| 904 | } else { | |
| 905 | try bw.writeByte('@'); | |
| 906 | try bw.printIntOptions(@intFromPtr(&value), 16, .lower, options); | |
| 907 | } | |
| 908 | }, | |
| 909 | .@"struct" => |info| { | |
| 910 | if (!is_any) { | |
| 911 | if (fmt.len != 0) invalidFmtError(fmt, value); | |
| 912 | return printValue(bw, ANY, options, value, max_depth); | |
| 913 | } | |
| 914 | if (info.is_tuple) { | |
| 915 | // Skip the type and field names when formatting tuples. | |
| 916 | if (max_depth == 0) { | |
| 917 | try bw.writeAll("{ ... }"); | |
| 918 | return; | |
| 919 | } | |
| 920 | try bw.writeAll("{"); | |
| 921 | inline for (info.fields, 0..) |f, i| { | |
| 922 | if (i == 0) { | |
| 923 | try bw.writeAll(" "); | |
| 924 | } else { | |
| 925 | try bw.writeAll(", "); | |
| 926 | } | |
| 927 | try bw.printValue(ANY, options, @field(value, f.name), max_depth - 1); | |
| 928 | } | |
| 929 | try bw.writeAll(" }"); | |
| 930 | return; | |
| 931 | } | |
| 932 | try bw.writeAll(@typeName(T)); | |
| 933 | if (max_depth == 0) { | |
| 934 | try bw.writeAll("{ ... }"); | |
| 935 | return; | |
| 936 | } | |
| 937 | try bw.writeAll("{"); | |
| 938 | inline for (info.fields, 0..) |f, i| { | |
| 939 | if (i == 0) { | |
| 940 | try bw.writeAll(" ."); | |
| 941 | } else { | |
| 942 | try bw.writeAll(", ."); | |
| 943 | } | |
| 944 | try bw.writeAll(f.name); | |
| 945 | try bw.writeAll(" = "); | |
| 946 | try bw.printValue(ANY, options, @field(value, f.name), max_depth - 1); | |
| 947 | } | |
| 948 | try bw.writeAll(" }"); | |
| 949 | }, | |
| 950 | .pointer => |ptr_info| switch (ptr_info.size) { | |
| 951 | .one => switch (@typeInfo(ptr_info.child)) { | |
| 952 | .array, .@"enum", .@"union", .@"struct" => { | |
| 953 | return bw.printValue(fmt, options, value.*, max_depth); | |
| 954 | }, | |
| 955 | else => { | |
| 956 | var buffers: [2][]const u8 = .{ @typeName(ptr_info.child), "@" }; | |
| 957 | try bw.writeVecAll(&buffers); | |
| 958 | try bw.printIntOptions(@intFromPtr(value), 16, .lower, options); | |
| 959 | return; | |
| 960 | }, | |
| 961 | }, | |
| 962 | .many, .c => { | |
| 963 | if (ptr_info.sentinel() != null) | |
| 964 | return bw.printValue(fmt, options, std.mem.span(value), max_depth); | |
| 965 | if (fmt.len == 1 and fmt[0] == 's' and ptr_info.child == u8) | |
| 966 | return bw.alignBufferOptions(std.mem.span(value), options); | |
| 967 | if (!is_any and fmt.len == 0) | |
| 968 | @compileError("cannot format pointer without a specifier (i.e. {s} or {*})"); | |
| 969 | if (!is_any and fmt.len != 0) | |
| 970 | invalidFmtError(fmt, value); | |
| 971 | try bw.printAddress(value); | |
| 972 | }, | |
| 973 | .slice => { | |
| 974 | if (!is_any and fmt.len == 0) | |
| 975 | @compileError("cannot format slice without a specifier (i.e. {s}, {x}, {b64}, or {any})"); | |
| 976 | if (max_depth == 0) | |
| 977 | return bw.writeAll("{ ... }"); | |
| 978 | if (ptr_info.child == u8) switch (fmt.len) { | |
| 979 | 1 => switch (fmt[0]) { | |
| 980 | 's' => return bw.alignBufferOptions(value, options), | |
| 981 | 'x' => return bw.printHex(value, .lower), | |
| 982 | 'X' => return bw.printHex(value, .upper), | |
| 983 | else => {}, | |
| 984 | }, | |
| 985 | 3 => if (fmt[0] == 'b' and fmt[1] == '6' and fmt[2] == '4') { | |
| 986 | return bw.printBase64(value); | |
| 987 | }, | |
| 988 | else => {}, | |
| 989 | }; | |
| 990 | try bw.writeAll("{ "); | |
| 991 | for (value, 0..) |elem, i| { | |
| 992 | try bw.printValue(fmt, options, elem, max_depth - 1); | |
| 993 | if (i != value.len - 1) { | |
| 994 | try bw.writeAll(", "); | |
| 995 | } | |
| 996 | } | |
| 997 | try bw.writeAll(" }"); | |
| 998 | }, | |
| 999 | }, | |
| 1000 | .array => |info| { | |
| 1001 | if (fmt.len == 0) | |
| 1002 | @compileError("cannot format array without a specifier (i.e. {s} or {any})"); | |
| 1003 | if (max_depth == 0) { | |
| 1004 | return bw.writeAll("{ ... }"); | |
| 1005 | } | |
| 1006 | if (info.child == u8) { | |
| 1007 | if (fmt[0] == 's') { | |
| 1008 | return bw.alignBufferOptions(&value, options); | |
| 1009 | } else if (fmt[0] == 'x') { | |
| 1010 | return bw.printHex(&value, .lower); | |
| 1011 | } else if (fmt[0] == 'X') { | |
| 1012 | return bw.printHex(&value, .upper); | |
| 1013 | } | |
| 1014 | } | |
| 1015 | try bw.writeAll("{ "); | |
| 1016 | for (value, 0..) |elem, i| { | |
| 1017 | try bw.printValue(fmt, options, elem, max_depth - 1); | |
| 1018 | if (i < value.len - 1) { | |
| 1019 | try bw.writeAll(", "); | |
| 1020 | } | |
| 1021 | } | |
| 1022 | try bw.writeAll(" }"); | |
| 1023 | }, | |
| 1024 | .vector => |info| { | |
| 1025 | if (max_depth == 0) { | |
| 1026 | return bw.writeAll("{ ... }"); | |
| 1027 | } | |
| 1028 | try bw.writeAll("{ "); | |
| 1029 | var i: usize = 0; | |
| 1030 | while (i < info.len) : (i += 1) { | |
| 1031 | try bw.printValue(fmt, options, value[i], max_depth - 1); | |
| 1032 | if (i < info.len - 1) { | |
| 1033 | try bw.writeAll(", "); | |
| 1034 | } | |
| 1035 | } | |
| 1036 | try bw.writeAll(" }"); | |
| 1037 | }, | |
| 1038 | .@"fn" => @compileError("unable to format function body type, use '*const " ++ @typeName(T) ++ "' for a function pointer type"), | |
| 1039 | .type => { | |
| 1040 | if (!is_any and fmt.len != 0) invalidFmtError(fmt, value); | |
| 1041 | return bw.alignBufferOptions(@typeName(value), options); | |
| 1042 | }, | |
| 1043 | .enum_literal => { | |
| 1044 | if (!is_any and fmt.len != 0) invalidFmtError(fmt, value); | |
| 1045 | const buffer = [_]u8{'.'} ++ @tagName(value); | |
| 1046 | return bw.alignBufferOptions(buffer, options); | |
| 1047 | }, | |
| 1048 | .null => { | |
| 1049 | if (!is_any and fmt.len != 0) invalidFmtError(fmt, value); | |
| 1050 | return bw.alignBufferOptions("null", options); | |
| 1051 | }, | |
| 1052 | else => @compileError("unable to format type '" ++ @typeName(T) ++ "'"), | |
| 1053 | } | |
| 1054 | } | |
| 1055 | ||
| 1056 | fn printErrorSet(bw: *BufferedWriter, error_set: anyerror) Writer.Error!void { | |
| 1057 | var vecs: [2][]const u8 = .{ "error.", @errorName(error_set) }; | |
| 1058 | try bw.writeVecAll(&vecs); | |
| 1059 | } | |
| 1060 | ||
| 1061 | pub fn printInt( | |
| 1062 | bw: *BufferedWriter, | |
| 1063 | comptime fmt: []const u8, | |
| 1064 | options: std.fmt.Options, | |
| 1065 | value: anytype, | |
| 1066 | ) Writer.Error!void { | |
| 1067 | const int_value = if (@TypeOf(value) == comptime_int) blk: { | |
| 1068 | const Int = std.math.IntFittingRange(value, value); | |
| 1069 | break :blk @as(Int, value); | |
| 1070 | } else value; | |
| 1071 | ||
| 1072 | switch (fmt.len) { | |
| 1073 | 0 => return bw.printIntOptions(int_value, 10, .lower, options), | |
| 1074 | 1 => switch (fmt[0]) { | |
| 1075 | 'd' => return bw.printIntOptions(int_value, 10, .lower, options), | |
| 1076 | 'c' => { | |
| 1077 | if (@typeInfo(@TypeOf(int_value)).int.bits <= 8) { | |
| 1078 | return bw.printAsciiChar(@as(u8, int_value), options); | |
| 1079 | } else { | |
| 1080 | @compileError("cannot print integer that is larger than 8 bits as an ASCII character"); | |
| 1081 | } | |
| 1082 | }, | |
| 1083 | 'u' => { | |
| 1084 | if (@typeInfo(@TypeOf(int_value)).int.bits <= 21) { | |
| 1085 | return bw.printUnicodeCodepoint(@as(u21, int_value), options); | |
| 1086 | } else { | |
| 1087 | @compileError("cannot print integer that is larger than 21 bits as an UTF-8 sequence"); | |
| 1088 | } | |
| 1089 | }, | |
| 1090 | 'b' => return bw.printIntOptions(int_value, 2, .lower, options), | |
| 1091 | 'x' => return bw.printIntOptions(int_value, 16, .lower, options), | |
| 1092 | 'X' => return bw.printIntOptions(int_value, 16, .upper, options), | |
| 1093 | 'o' => return bw.printIntOptions(int_value, 8, .lower, options), | |
| 1094 | 'B' => return bw.printByteSize(int_value, .decimal, options), | |
| 1095 | 'D' => return bw.printDuration(int_value, options), | |
| 1096 | else => invalidFmtError(fmt, value), | |
| 1097 | }, | |
| 1098 | 2 => { | |
| 1099 | if (fmt[0] == 'B' and fmt[1] == 'i') { | |
| 1100 | return bw.printByteSize(int_value, .binary, options); | |
| 1101 | } else { | |
| 1102 | invalidFmtError(fmt, value); | |
| 1103 | } | |
| 1104 | }, | |
| 1105 | else => invalidFmtError(fmt, value), | |
| 1106 | } | |
| 1107 | comptime unreachable; | |
| 1108 | } | |
| 1109 | ||
| 1110 | pub fn printAsciiChar(bw: *BufferedWriter, c: u8, options: std.fmt.Options) Writer.Error!void { | |
| 1111 | return bw.alignBufferOptions(@as(*const [1]u8, &c), options); | |
| 1112 | } | |
| 1113 | ||
| 1114 | pub fn printAscii(bw: *BufferedWriter, bytes: []const u8, options: std.fmt.Options) Writer.Error!void { | |
| 1115 | return bw.alignBufferOptions(bytes, options); | |
| 1116 | } | |
| 1117 | ||
| 1118 | pub fn printUnicodeCodepoint(bw: *BufferedWriter, c: u21, options: std.fmt.Options) Writer.Error!void { | |
| 1119 | var buf: [4]u8 = undefined; | |
| 1120 | const len = try std.unicode.utf8Encode(c, &buf); | |
| 1121 | return bw.alignBufferOptions(buf[0..len], options); | |
| 1122 | } | |
| 1123 | ||
| 1124 | pub fn printIntOptions( | |
| 1125 | bw: *BufferedWriter, | |
| 1126 | value: anytype, | |
| 1127 | base: u8, | |
| 1128 | case: std.fmt.Case, | |
| 1129 | options: std.fmt.Options, | |
| 1130 | ) Writer.Error!void { | |
| 1131 | assert(base >= 2); | |
| 1132 | ||
| 1133 | const int_value = if (@TypeOf(value) == comptime_int) blk: { | |
| 1134 | const Int = std.math.IntFittingRange(value, value); | |
| 1135 | break :blk @as(Int, value); | |
| 1136 | } else value; | |
| 1137 | ||
| 1138 | const value_info = @typeInfo(@TypeOf(int_value)).int; | |
| 1139 | ||
| 1140 | // The type must have the same size as `base` or be wider in order for the | |
| 1141 | // division to work | |
| 1142 | const min_int_bits = comptime @max(value_info.bits, 8); | |
| 1143 | const MinInt = std.meta.Int(.unsigned, min_int_bits); | |
| 1144 | ||
| 1145 | const abs_value = @abs(int_value); | |
| 1146 | // The worst case in terms of space needed is base 2, plus 1 for the sign | |
| 1147 | var buf: [1 + @max(@as(comptime_int, value_info.bits), 1)]u8 = undefined; | |
| 1148 | ||
| 1149 | var a: MinInt = abs_value; | |
| 1150 | var index: usize = buf.len; | |
| 1151 | ||
| 1152 | if (base == 10) { | |
| 1153 | while (a >= 100) : (a = @divTrunc(a, 100)) { | |
| 1154 | index -= 2; | |
| 1155 | buf[index..][0..2].* = std.fmt.digits2(@intCast(a % 100)); | |
| 1156 | } | |
| 1157 | ||
| 1158 | if (a < 10) { | |
| 1159 | index -= 1; | |
| 1160 | buf[index] = '0' + @as(u8, @intCast(a)); | |
| 1161 | } else { | |
| 1162 | index -= 2; | |
| 1163 | buf[index..][0..2].* = std.fmt.digits2(@intCast(a)); | |
| 1164 | } | |
| 1165 | } else { | |
| 1166 | while (true) { | |
| 1167 | const digit = a % base; | |
| 1168 | index -= 1; | |
| 1169 | buf[index] = std.fmt.digitToChar(@intCast(digit), case); | |
| 1170 | a /= base; | |
| 1171 | if (a == 0) break; | |
| 1172 | } | |
| 1173 | } | |
| 1174 | ||
| 1175 | if (value_info.signedness == .signed) { | |
| 1176 | if (value < 0) { | |
| 1177 | // Negative integer | |
| 1178 | index -= 1; | |
| 1179 | buf[index] = '-'; | |
| 1180 | } else if (options.width == null or options.width.? == 0) { | |
| 1181 | // Positive integer, omit the plus sign | |
| 1182 | } else { | |
| 1183 | // Positive integer | |
| 1184 | index -= 1; | |
| 1185 | buf[index] = '+'; | |
| 1186 | } | |
| 1187 | } | |
| 1188 | ||
| 1189 | return bw.alignBufferOptions(buf[index..], options); | |
| 1190 | } | |
| 1191 | ||
| 1192 | pub fn printFloat( | |
| 1193 | bw: *BufferedWriter, | |
| 1194 | comptime fmt: []const u8, | |
| 1195 | options: std.fmt.Options, | |
| 1196 | value: anytype, | |
| 1197 | ) Writer.Error!void { | |
| 1198 | var buf: [std.fmt.float.bufferSize(.decimal, f64)]u8 = undefined; | |
| 1199 | ||
| 1200 | if (fmt.len > 1) invalidFmtError(fmt, value); | |
| 1201 | switch (if (fmt.len == 0) 'e' else fmt[0]) { | |
| 1202 | 'e' => { | |
| 1203 | const s = std.fmt.float.render(&buf, value, .{ .mode = .scientific, .precision = options.precision }) catch |err| switch (err) { | |
| 1204 | error.BufferTooSmall => "(float)", | |
| 1205 | }; | |
| 1206 | return bw.alignBufferOptions(s, options); | |
| 1207 | }, | |
| 1208 | 'd' => { | |
| 1209 | const s = std.fmt.float.render(&buf, value, .{ .mode = .decimal, .precision = options.precision }) catch |err| switch (err) { | |
| 1210 | error.BufferTooSmall => "(float)", | |
| 1211 | }; | |
| 1212 | return bw.alignBufferOptions(s, options); | |
| 1213 | }, | |
| 1214 | 'x' => { | |
| 1215 | var sub_bw: BufferedWriter = undefined; | |
| 1216 | sub_bw.initFixed(&buf); | |
| 1217 | sub_bw.printFloatHexadecimal(value, options.precision) catch unreachable; | |
| 1218 | return bw.alignBufferOptions(sub_bw.getWritten(), options); | |
| 1219 | }, | |
| 1220 | else => invalidFmtError(fmt, value), | |
| 1221 | } | |
| 1222 | } | |
| 1223 | ||
| 1224 | pub fn printFloatHexadecimal(bw: *BufferedWriter, value: anytype, opt_precision: ?usize) Writer.Error!void { | |
| 1225 | if (std.math.signbit(value)) try bw.writeByte('-'); | |
| 1226 | if (std.math.isNan(value)) return bw.writeAll("nan"); | |
| 1227 | if (std.math.isInf(value)) return bw.writeAll("inf"); | |
| 1228 | ||
| 1229 | const T = @TypeOf(value); | |
| 1230 | const TU = std.meta.Int(.unsigned, @bitSizeOf(T)); | |
| 1231 | ||
| 1232 | const mantissa_bits = std.math.floatMantissaBits(T); | |
| 1233 | const fractional_bits = std.math.floatFractionalBits(T); | |
| 1234 | const exponent_bits = std.math.floatExponentBits(T); | |
| 1235 | const mantissa_mask = (1 << mantissa_bits) - 1; | |
| 1236 | const exponent_mask = (1 << exponent_bits) - 1; | |
| 1237 | const exponent_bias = (1 << (exponent_bits - 1)) - 1; | |
| 1238 | ||
| 1239 | const as_bits: TU = @bitCast(value); | |
| 1240 | var mantissa = as_bits & mantissa_mask; | |
| 1241 | var exponent: i32 = @as(u16, @truncate((as_bits >> mantissa_bits) & exponent_mask)); | |
| 1242 | ||
| 1243 | const is_denormal = exponent == 0 and mantissa != 0; | |
| 1244 | const is_zero = exponent == 0 and mantissa == 0; | |
| 1245 | ||
| 1246 | if (is_zero) { | |
| 1247 | // Handle this case here to simplify the logic below. | |
| 1248 | try bw.writeAll("0x0"); | |
| 1249 | if (opt_precision) |precision| { | |
| 1250 | if (precision > 0) { | |
| 1251 | try bw.writeAll("."); | |
| 1252 | try bw.splatByteAll('0', precision); | |
| 1253 | } | |
| 1254 | } else { | |
| 1255 | try bw.writeAll(".0"); | |
| 1256 | } | |
| 1257 | try bw.writeAll("p0"); | |
| 1258 | return; | |
| 1259 | } | |
| 1260 | ||
| 1261 | if (is_denormal) { | |
| 1262 | // Adjust the exponent for printing. | |
| 1263 | exponent += 1; | |
| 1264 | } else { | |
| 1265 | if (fractional_bits == mantissa_bits) | |
| 1266 | mantissa |= 1 << fractional_bits; // Add the implicit integer bit. | |
| 1267 | } | |
| 1268 | ||
| 1269 | const mantissa_digits = (fractional_bits + 3) / 4; | |
| 1270 | // Fill in zeroes to round the fraction width to a multiple of 4. | |
| 1271 | mantissa <<= mantissa_digits * 4 - fractional_bits; | |
| 1272 | ||
| 1273 | if (opt_precision) |precision| { | |
| 1274 | // Round if needed. | |
| 1275 | if (precision < mantissa_digits) { | |
| 1276 | // We always have at least 4 extra bits. | |
| 1277 | var extra_bits = (mantissa_digits - precision) * 4; | |
| 1278 | // The result LSB is the Guard bit, we need two more (Round and | |
| 1279 | // Sticky) to round the value. | |
| 1280 | while (extra_bits > 2) { | |
| 1281 | mantissa = (mantissa >> 1) | (mantissa & 1); | |
| 1282 | extra_bits -= 1; | |
| 1283 | } | |
| 1284 | // Round to nearest, tie to even. | |
| 1285 | mantissa |= @intFromBool(mantissa & 0b100 != 0); | |
| 1286 | mantissa += 1; | |
| 1287 | // Drop the excess bits. | |
| 1288 | mantissa >>= 2; | |
| 1289 | // Restore the alignment. | |
| 1290 | mantissa <<= @as(std.math.Log2Int(TU), @intCast((mantissa_digits - precision) * 4)); | |
| 1291 | ||
| 1292 | const overflow = mantissa & (1 << 1 + mantissa_digits * 4) != 0; | |
| 1293 | // Prefer a normalized result in case of overflow. | |
| 1294 | if (overflow) { | |
| 1295 | mantissa >>= 1; | |
| 1296 | exponent += 1; | |
| 1297 | } | |
| 1298 | } | |
| 1299 | } | |
| 1300 | ||
| 1301 | // +1 for the decimal part. | |
| 1302 | var buf: [1 + mantissa_digits]u8 = undefined; | |
| 1303 | assert(std.fmt.printInt(&buf, mantissa, 16, .lower, .{ .fill = '0', .width = 1 + mantissa_digits }) == buf.len); | |
| 1304 | ||
| 1305 | try bw.writeAll("0x"); | |
| 1306 | try bw.writeByte(buf[0]); | |
| 1307 | const trimmed = std.mem.trimRight(u8, buf[1..], "0"); | |
| 1308 | if (opt_precision) |precision| { | |
| 1309 | if (precision > 0) try bw.writeAll("."); | |
| 1310 | } else if (trimmed.len > 0) { | |
| 1311 | try bw.writeAll("."); | |
| 1312 | } | |
| 1313 | try bw.writeAll(trimmed); | |
| 1314 | // Add trailing zeros if explicitly requested. | |
| 1315 | if (opt_precision) |precision| if (precision > 0) { | |
| 1316 | if (precision > trimmed.len) | |
| 1317 | try bw.splatByteAll('0', precision - trimmed.len); | |
| 1318 | }; | |
| 1319 | try bw.writeAll("p"); | |
| 1320 | try bw.printIntOptions(exponent - exponent_bias, 10, .lower, .{}); | |
| 1321 | } | |
| 1322 | ||
| 1323 | pub const ByteSizeUnits = enum { | |
| 1324 | /// This formatter represents the number as multiple of 1000 and uses the SI | |
| 1325 | /// measurement units (kB, MB, GB, ...). | |
| 1326 | decimal, | |
| 1327 | /// This formatter represents the number as multiple of 1024 and uses the IEC | |
| 1328 | /// measurement units (KiB, MiB, GiB, ...). | |
| 1329 | binary, | |
| 1330 | }; | |
| 1331 | ||
| 1332 | /// Format option `precision` is ignored when `value` is less than 1kB | |
| 1333 | pub fn printByteSize( | |
| 1334 | bw: *std.io.BufferedWriter, | |
| 1335 | value: u64, | |
| 1336 | comptime units: ByteSizeUnits, | |
| 1337 | options: std.fmt.Options, | |
| 1338 | ) Writer.Error!void { | |
| 1339 | if (value == 0) return bw.alignBufferOptions("0B", options); | |
| 1340 | // The worst case in terms of space needed is 32 bytes + 3 for the suffix. | |
| 1341 | var buf: [std.fmt.float.min_buffer_size + 3]u8 = undefined; | |
| 1342 | ||
| 1343 | const mags_si = " kMGTPEZY"; | |
| 1344 | const mags_iec = " KMGTPEZY"; | |
| 1345 | ||
| 1346 | const log2 = std.math.log2(value); | |
| 1347 | const base = switch (units) { | |
| 1348 | .decimal => 1000, | |
| 1349 | .binary => 1024, | |
| 1350 | }; | |
| 1351 | const magnitude = switch (units) { | |
| 1352 | .decimal => @min(log2 / comptime std.math.log2(1000), mags_si.len - 1), | |
| 1353 | .binary => @min(log2 / 10, mags_iec.len - 1), | |
| 1354 | }; | |
| 1355 | const new_value = std.math.lossyCast(f64, value) / std.math.pow(f64, std.math.lossyCast(f64, base), std.math.lossyCast(f64, magnitude)); | |
| 1356 | const suffix = switch (units) { | |
| 1357 | .decimal => mags_si[magnitude], | |
| 1358 | .binary => mags_iec[magnitude], | |
| 1359 | }; | |
| 1360 | ||
| 1361 | const s = switch (magnitude) { | |
| 1362 | 0 => buf[0..std.fmt.printInt(&buf, value, 10, .lower, .{})], | |
| 1363 | else => std.fmt.float.render(&buf, new_value, .{ .mode = .decimal, .precision = options.precision }) catch |err| switch (err) { | |
| 1364 | error.BufferTooSmall => unreachable, | |
| 1365 | }, | |
| 1366 | }; | |
| 1367 | ||
| 1368 | var i: usize = s.len; | |
| 1369 | if (suffix == ' ') { | |
| 1370 | buf[i] = 'B'; | |
| 1371 | i += 1; | |
| 1372 | } else switch (units) { | |
| 1373 | .decimal => { | |
| 1374 | buf[i..][0..2].* = [_]u8{ suffix, 'B' }; | |
| 1375 | i += 2; | |
| 1376 | }, | |
| 1377 | .binary => { | |
| 1378 | buf[i..][0..3].* = [_]u8{ suffix, 'i', 'B' }; | |
| 1379 | i += 3; | |
| 1380 | }, | |
| 1381 | } | |
| 1382 | ||
| 1383 | return bw.alignBufferOptions(buf[0..i], options); | |
| 1384 | } | |
| 1385 | ||
| 1386 | // This ANY const is a workaround for: https://github.com/ziglang/zig/issues/7948 | |
| 1387 | const ANY = "any"; | |
| 1388 | ||
| 1389 | fn stripOptionalOrErrorUnionSpec(comptime fmt: []const u8) []const u8 { | |
| 1390 | return if (std.mem.eql(u8, fmt[1..], ANY)) | |
| 1391 | ANY | |
| 1392 | else | |
| 1393 | fmt[1..]; | |
| 1394 | } | |
| 1395 | ||
| 1396 | pub fn invalidFmtError(comptime fmt: []const u8, value: anytype) noreturn { | |
| 1397 | @compileError("invalid format string '" ++ fmt ++ "' for type '" ++ @typeName(@TypeOf(value)) ++ "'"); | |
| 1398 | } | |
| 1399 | ||
| 1400 | pub fn printDurationSigned(bw: *BufferedWriter, ns: i64) Writer.Error!void { | |
| 1401 | if (ns < 0) try bw.writeByte('-'); | |
| 1402 | return bw.printDurationUnsigned(@abs(ns)); | |
| 1403 | } | |
| 1404 | ||
| 1405 | pub fn printDurationUnsigned(bw: *BufferedWriter, ns: u64) Writer.Error!void { | |
| 1406 | var ns_remaining = ns; | |
| 1407 | inline for (.{ | |
| 1408 | .{ .ns = 365 * std.time.ns_per_day, .sep = 'y' }, | |
| 1409 | .{ .ns = std.time.ns_per_week, .sep = 'w' }, | |
| 1410 | .{ .ns = std.time.ns_per_day, .sep = 'd' }, | |
| 1411 | .{ .ns = std.time.ns_per_hour, .sep = 'h' }, | |
| 1412 | .{ .ns = std.time.ns_per_min, .sep = 'm' }, | |
| 1413 | }) |unit| { | |
| 1414 | if (ns_remaining >= unit.ns) { | |
| 1415 | const units = ns_remaining / unit.ns; | |
| 1416 | try bw.printIntOptions(units, 10, .lower, .{}); | |
| 1417 | try bw.writeByte(unit.sep); | |
| 1418 | ns_remaining -= units * unit.ns; | |
| 1419 | if (ns_remaining == 0) return; | |
| 1420 | } | |
| 1421 | } | |
| 1422 | ||
| 1423 | inline for (.{ | |
| 1424 | .{ .ns = std.time.ns_per_s, .sep = "s" }, | |
| 1425 | .{ .ns = std.time.ns_per_ms, .sep = "ms" }, | |
| 1426 | .{ .ns = std.time.ns_per_us, .sep = "us" }, | |
| 1427 | }) |unit| { | |
| 1428 | const kunits = ns_remaining * 1000 / unit.ns; | |
| 1429 | if (kunits >= 1000) { | |
| 1430 | try bw.printIntOptions(kunits / 1000, 10, .lower, .{}); | |
| 1431 | const frac = kunits % 1000; | |
| 1432 | if (frac > 0) { | |
| 1433 | // Write up to 3 decimal places | |
| 1434 | var decimal_buf = [_]u8{ '.', 0, 0, 0 }; | |
| 1435 | var inner: BufferedWriter = undefined; | |
| 1436 | inner.initFixed(decimal_buf[1..]); | |
| 1437 | inner.printIntOptions(frac, 10, .lower, .{ .fill = '0', .width = 3 }) catch unreachable; | |
| 1438 | var end: usize = 4; | |
| 1439 | while (end > 1) : (end -= 1) { | |
| 1440 | if (decimal_buf[end - 1] != '0') break; | |
| 1441 | } | |
| 1442 | try bw.writeAll(decimal_buf[0..end]); | |
| 1443 | } | |
| 1444 | return bw.writeAll(unit.sep); | |
| 1445 | } | |
| 1446 | } | |
| 1447 | ||
| 1448 | try bw.printIntOptions(ns_remaining, 10, .lower, .{}); | |
| 1449 | try bw.writeAll("ns"); | |
| 1450 | } | |
| 1451 | ||
| 1452 | /// Writes number of nanoseconds according to its signed magnitude: | |
| 1453 | /// `[#y][#w][#d][#h][#m]#[.###][n|u|m]s` | |
| 1454 | /// `nanoseconds` must be an integer that coerces into `u64` or `i64`. | |
| 1455 | pub fn printDuration(bw: *BufferedWriter, nanoseconds: anytype, options: std.fmt.Options) Writer.Error!void { | |
| 1456 | // worst case: "-XXXyXXwXXdXXhXXmXX.XXXs".len = 24 | |
| 1457 | var buf: [24]u8 = undefined; | |
| 1458 | var sub_bw: BufferedWriter = undefined; | |
| 1459 | sub_bw.initFixed(&buf); | |
| 1460 | switch (@typeInfo(@TypeOf(nanoseconds)).int.signedness) { | |
| 1461 | .signed => sub_bw.printDurationSigned(nanoseconds) catch unreachable, | |
| 1462 | .unsigned => sub_bw.printDurationUnsigned(nanoseconds) catch unreachable, | |
| 1463 | } | |
| 1464 | return bw.alignBufferOptions(sub_bw.getWritten(), options); | |
| 1465 | } | |
| 1466 | ||
| 1467 | pub fn printHex(bw: *BufferedWriter, bytes: []const u8, case: std.fmt.Case) Writer.Error!void { | |
| 1468 | const charset = switch (case) { | |
| 1469 | .upper => "0123456789ABCDEF", | |
| 1470 | .lower => "0123456789abcdef", | |
| 1471 | }; | |
| 1472 | for (bytes) |c| { | |
| 1473 | try bw.writeByte(charset[c >> 4]); | |
| 1474 | try bw.writeByte(charset[c & 15]); | |
| 1475 | } | |
| 1476 | } | |
| 1477 | ||
| 1478 | pub fn printBase64(bw: *BufferedWriter, bytes: []const u8) Writer.Error!void { | |
| 1479 | var chunker = std.mem.window(u8, bytes, 3, 3); | |
| 1480 | var temp: [5]u8 = undefined; | |
| 1481 | while (chunker.next()) |chunk| { | |
| 1482 | try bw.writeAll(std.base64.standard.Encoder.encode(&temp, chunk)); | |
| 1483 | } | |
| 1484 | } | |
| 1485 | ||
| 1486 | /// Write a single unsigned integer as LEB128 to the given writer. | |
| 1487 | pub fn writeUleb128(bw: *BufferedWriter, value: anytype) Writer.Error!void { | |
| 1488 | try bw.writeLeb128(switch (@typeInfo(@TypeOf(value))) { | |
| 1489 | .comptime_int => @as(std.math.IntFittingRange(0, @abs(value)), value), | |
| 1490 | .int => |value_info| switch (value_info.signedness) { | |
| 1491 | .signed => @as(@Type(.{ .int = .{ .signedness = .unsigned, .bits = value_info.bits -| 1 } }), @intCast(value)), | |
| 1492 | .unsigned => value, | |
| 1493 | }, | |
| 1494 | else => comptime unreachable, | |
| 1495 | }); | |
| 1496 | } | |
| 1497 | ||
| 1498 | /// Write a single signed integer as LEB128 to the given writer. | |
| 1499 | pub fn writeSleb128(bw: *BufferedWriter, value: anytype) Writer.Error!void { | |
| 1500 | try bw.writeLeb128(switch (@typeInfo(@TypeOf(value))) { | |
| 1501 | .comptime_int => @as(std.math.IntFittingRange(@min(value, -1), @max(0, value)), value), | |
| 1502 | .int => |value_info| switch (value_info.signedness) { | |
| 1503 | .signed => value, | |
| 1504 | .unsigned => @as(@Type(.{ .int = .{ .signedness = .signed, .bits = value_info.bits + 1 } }), value), | |
| 1505 | }, | |
| 1506 | else => comptime unreachable, | |
| 1507 | }); | |
| 1508 | } | |
| 1509 | ||
| 1510 | /// Write a single integer as LEB128 to the given writer. | |
| 1511 | pub fn writeLeb128(bw: *BufferedWriter, value: anytype) Writer.Error!void { | |
| 1512 | const value_info = @typeInfo(@TypeOf(value)).int; | |
| 1513 | try bw.writeMultipleOf7Leb128(@as(@Type(.{ .int = .{ | |
| 1514 | .signedness = value_info.signedness, | |
| 1515 | .bits = std.mem.alignForwardAnyAlign(u16, value_info.bits, 7), | |
| 1516 | } }), value)); | |
| 1517 | } | |
| 1518 | ||
| 1519 | fn writeMultipleOf7Leb128(bw: *BufferedWriter, value: anytype) Writer.Error!void { | |
| 1520 | const value_info = @typeInfo(@TypeOf(value)).int; | |
| 1521 | comptime assert(value_info.bits % 7 == 0); | |
| 1522 | var remaining = value; | |
| 1523 | while (true) { | |
| 1524 | const buffer: []packed struct(u8) { bits: u7, more: bool } = @ptrCast(try bw.writableSliceGreedy(1)); | |
| 1525 | for (buffer, 1..) |*byte, len| { | |
| 1526 | const more = switch (value_info.signedness) { | |
| 1527 | .signed => remaining >> 6 != remaining >> (value_info.bits - 1), | |
| 1528 | .unsigned => remaining > std.math.maxInt(u7), | |
| 1529 | }; | |
| 1530 | byte.* = if (@inComptime()) @typeInfo(@TypeOf(buffer)).pointer.child{ | |
| 1531 | .bits = @bitCast(@as(@Type(.{ .int = .{ | |
| 1532 | .signedness = value_info.signedness, | |
| 1533 | .bits = 7, | |
| 1534 | } }), @truncate(remaining))), | |
| 1535 | .more = more, | |
| 1536 | } else .{ | |
| 1537 | .bits = @bitCast(@as(@Type(.{ .int = .{ | |
| 1538 | .signedness = value_info.signedness, | |
| 1539 | .bits = 7, | |
| 1540 | } }), @truncate(remaining))), | |
| 1541 | .more = more, | |
| 1542 | }; | |
| 1543 | if (value_info.bits > 7) remaining >>= 7; | |
| 1544 | if (!more) return bw.advance(len); | |
| 1545 | } | |
| 1546 | bw.advance(buffer.len); | |
| 1547 | } | |
| 1548 | } | |
| 1549 | ||
| 1550 | test "formatValue max_depth" { | |
| 1551 | const Vec2 = struct { | |
| 1552 | const SelfType = @This(); | |
| 1553 | x: f32, | |
| 1554 | y: f32, | |
| 1555 | ||
| 1556 | pub fn format( | |
| 1557 | self: SelfType, | |
| 1558 | comptime fmt: []const u8, | |
| 1559 | options: std.fmt.Options, | |
| 1560 | bw: *BufferedWriter, | |
| 1561 | ) Writer.Error!void { | |
| 1562 | _ = options; | |
| 1563 | if (fmt.len == 0) { | |
| 1564 | return bw.print("({d:.3},{d:.3})", .{ self.x, self.y }); | |
| 1565 | } else { | |
| 1566 | @compileError("unknown format string: '" ++ fmt ++ "'"); | |
| 1567 | } | |
| 1568 | } | |
| 1569 | }; | |
| 1570 | const E = enum { | |
| 1571 | One, | |
| 1572 | Two, | |
| 1573 | Three, | |
| 1574 | }; | |
| 1575 | const TU = union(enum) { | |
| 1576 | const SelfType = @This(); | |
| 1577 | float: f32, | |
| 1578 | int: u32, | |
| 1579 | ptr: ?*SelfType, | |
| 1580 | }; | |
| 1581 | const S = struct { | |
| 1582 | const SelfType = @This(); | |
| 1583 | a: ?*SelfType, | |
| 1584 | tu: TU, | |
| 1585 | e: E, | |
| 1586 | vec: Vec2, | |
| 1587 | }; | |
| 1588 | ||
| 1589 | var inst = S{ | |
| 1590 | .a = null, | |
| 1591 | .tu = TU{ .ptr = null }, | |
| 1592 | .e = E.Two, | |
| 1593 | .vec = Vec2{ .x = 10.2, .y = 2.22 }, | |
| 1594 | }; | |
| 1595 | inst.a = &inst; | |
| 1596 | inst.tu.ptr = &inst.tu; | |
| 1597 | ||
| 1598 | var buf: [1000]u8 = undefined; | |
| 1599 | var bw: BufferedWriter = undefined; | |
| 1600 | bw.initFixed(&buf); | |
| 1601 | try bw.printValue("", .{}, inst, 0); | |
| 1602 | try testing.expectEqualStrings("io.BufferedWriter.test.printValue max_depth.S{ ... }", bw.getWritten()); | |
| 1603 | ||
| 1604 | bw.reset(); | |
| 1605 | try bw.printValue("", .{}, inst, 1); | |
| 1606 | try testing.expectEqualStrings("io.BufferedWriter.test.printValue max_depth.S{ .a = io.BufferedWriter.test.printValue max_depth.S{ ... }, .tu = io.BufferedWriter.test.printValue max_depth.TU{ ... }, .e = io.BufferedWriter.test.printValue max_depth.E.Two, .vec = (10.200,2.220) }", bw.getWritten()); | |
| 1607 | ||
| 1608 | bw.reset(); | |
| 1609 | try bw.printValue("", .{}, inst, 2); | |
| 1610 | try testing.expectEqualStrings("io.BufferedWriter.test.printValue max_depth.S{ .a = io.BufferedWriter.test.printValue max_depth.S{ .a = io.BufferedWriter.test.printValue max_depth.S{ ... }, .tu = io.BufferedWriter.test.printValue max_depth.TU{ ... }, .e = io.BufferedWriter.test.printValue max_depth.E.Two, .vec = (10.200,2.220) }, .tu = io.BufferedWriter.test.printValue max_depth.TU{ .ptr = io.BufferedWriter.test.printValue max_depth.TU{ ... } }, .e = io.BufferedWriter.test.printValue max_depth.E.Two, .vec = (10.200,2.220) }", bw.getWritten()); | |
| 1611 | ||
| 1612 | bw.reset(); | |
| 1613 | try bw.printValue("", .{}, inst, 3); | |
| 1614 | try testing.expectEqualStrings("io.BufferedWriter.test.printValue max_depth.S{ .a = io.BufferedWriter.test.printValue max_depth.S{ .a = io.BufferedWriter.test.printValue max_depth.S{ .a = io.BufferedWriter.test.printValue max_depth.S{ ... }, .tu = io.BufferedWriter.test.printValue max_depth.TU{ ... }, .e = io.BufferedWriter.test.printValue max_depth.E.Two, .vec = (10.200,2.220) }, .tu = io.BufferedWriter.test.printValue max_depth.TU{ .ptr = io.BufferedWriter.test.printValue max_depth.TU{ ... } }, .e = io.BufferedWriter.test.printValue max_depth.E.Two, .vec = (10.200,2.220) }, .tu = io.BufferedWriter.test.printValue max_depth.TU{ .ptr = io.BufferedWriter.test.printValue max_depth.TU{ .ptr = io.BufferedWriter.test.printValue max_depth.TU{ ... } } }, .e = io.BufferedWriter.test.printValue max_depth.E.Two, .vec = (10.200,2.220) }", bw.getWritten()); | |
| 1615 | ||
| 1616 | const vec: @Vector(4, i32) = .{ 1, 2, 3, 4 }; | |
| 1617 | bw.reset(); | |
| 1618 | try bw.printValue("", .{}, vec, 0); | |
| 1619 | try testing.expectEqualStrings("{ ... }", bw.getWritten()); | |
| 1620 | ||
| 1621 | bw.reset(); | |
| 1622 | try bw.printValue("", .{}, vec, 1); | |
| 1623 | try testing.expectEqualStrings("{ 1, 2, 3, 4 }", bw.getWritten()); | |
| 1624 | } | |
| 1625 | ||
| 1626 | test printDuration { | |
| 1627 | testDurationCase("0ns", 0); | |
| 1628 | testDurationCase("1ns", 1); | |
| 1629 | testDurationCase("999ns", std.time.ns_per_us - 1); | |
| 1630 | testDurationCase("1us", std.time.ns_per_us); | |
| 1631 | testDurationCase("1.45us", 1450); | |
| 1632 | testDurationCase("1.5us", 3 * std.time.ns_per_us / 2); | |
| 1633 | testDurationCase("14.5us", 14500); | |
| 1634 | testDurationCase("145us", 145000); | |
| 1635 | testDurationCase("999.999us", std.time.ns_per_ms - 1); | |
| 1636 | testDurationCase("1ms", std.time.ns_per_ms + 1); | |
| 1637 | testDurationCase("1.5ms", 3 * std.time.ns_per_ms / 2); | |
| 1638 | testDurationCase("1.11ms", 1110000); | |
| 1639 | testDurationCase("1.111ms", 1111000); | |
| 1640 | testDurationCase("1.111ms", 1111100); | |
| 1641 | testDurationCase("999.999ms", std.time.ns_per_s - 1); | |
| 1642 | testDurationCase("1s", std.time.ns_per_s); | |
| 1643 | testDurationCase("59.999s", std.time.ns_per_min - 1); | |
| 1644 | testDurationCase("1m", std.time.ns_per_min); | |
| 1645 | testDurationCase("1h", std.time.ns_per_hour); | |
| 1646 | testDurationCase("1d", std.time.ns_per_day); | |
| 1647 | testDurationCase("1w", std.time.ns_per_week); | |
| 1648 | testDurationCase("1y", 365 * std.time.ns_per_day); | |
| 1649 | testDurationCase("1y52w23h59m59.999s", 730 * std.time.ns_per_day - 1); // 365d = 52w1 | |
| 1650 | testDurationCase("1y1h1.001s", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_s + std.time.ns_per_ms); | |
| 1651 | testDurationCase("1y1h1s", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_s + 999 * std.time.ns_per_us); | |
| 1652 | testDurationCase("1y1h999.999us", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms - 1); | |
| 1653 | testDurationCase("1y1h1ms", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms); | |
| 1654 | testDurationCase("1y1h1ms", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms + 1); | |
| 1655 | testDurationCase("1y1m999ns", 365 * std.time.ns_per_day + std.time.ns_per_min + 999); | |
| 1656 | testDurationCase("584y49w23h34m33.709s", std.math.maxInt(u64)); | |
| 1657 | ||
| 1658 | testing.expectFmt("=======0ns", "{D:=>10}", .{0}); | |
| 1659 | testing.expectFmt("1ns=======", "{D:=<10}", .{1}); | |
| 1660 | testing.expectFmt(" 999ns ", "{D:^10}", .{std.time.ns_per_us - 1}); | |
| 1661 | } | |
| 1662 | ||
| 1663 | test printDurationSigned { | |
| 1664 | testDurationCaseSigned("0ns", 0); | |
| 1665 | testDurationCaseSigned("1ns", 1); | |
| 1666 | testDurationCaseSigned("-1ns", -(1)); | |
| 1667 | testDurationCaseSigned("999ns", std.time.ns_per_us - 1); | |
| 1668 | testDurationCaseSigned("-999ns", -(std.time.ns_per_us - 1)); | |
| 1669 | testDurationCaseSigned("1us", std.time.ns_per_us); | |
| 1670 | testDurationCaseSigned("-1us", -(std.time.ns_per_us)); | |
| 1671 | testDurationCaseSigned("1.45us", 1450); | |
| 1672 | testDurationCaseSigned("-1.45us", -(1450)); | |
| 1673 | testDurationCaseSigned("1.5us", 3 * std.time.ns_per_us / 2); | |
| 1674 | testDurationCaseSigned("-1.5us", -(3 * std.time.ns_per_us / 2)); | |
| 1675 | testDurationCaseSigned("14.5us", 14500); | |
| 1676 | testDurationCaseSigned("-14.5us", -(14500)); | |
| 1677 | testDurationCaseSigned("145us", 145000); | |
| 1678 | testDurationCaseSigned("-145us", -(145000)); | |
| 1679 | testDurationCaseSigned("999.999us", std.time.ns_per_ms - 1); | |
| 1680 | testDurationCaseSigned("-999.999us", -(std.time.ns_per_ms - 1)); | |
| 1681 | testDurationCaseSigned("1ms", std.time.ns_per_ms + 1); | |
| 1682 | testDurationCaseSigned("-1ms", -(std.time.ns_per_ms + 1)); | |
| 1683 | testDurationCaseSigned("1.5ms", 3 * std.time.ns_per_ms / 2); | |
| 1684 | testDurationCaseSigned("-1.5ms", -(3 * std.time.ns_per_ms / 2)); | |
| 1685 | testDurationCaseSigned("1.11ms", 1110000); | |
| 1686 | testDurationCaseSigned("-1.11ms", -(1110000)); | |
| 1687 | testDurationCaseSigned("1.111ms", 1111000); | |
| 1688 | testDurationCaseSigned("-1.111ms", -(1111000)); | |
| 1689 | testDurationCaseSigned("1.111ms", 1111100); | |
| 1690 | testDurationCaseSigned("-1.111ms", -(1111100)); | |
| 1691 | testDurationCaseSigned("999.999ms", std.time.ns_per_s - 1); | |
| 1692 | testDurationCaseSigned("-999.999ms", -(std.time.ns_per_s - 1)); | |
| 1693 | testDurationCaseSigned("1s", std.time.ns_per_s); | |
| 1694 | testDurationCaseSigned("-1s", -(std.time.ns_per_s)); | |
| 1695 | testDurationCaseSigned("59.999s", std.time.ns_per_min - 1); | |
| 1696 | testDurationCaseSigned("-59.999s", -(std.time.ns_per_min - 1)); | |
| 1697 | testDurationCaseSigned("1m", std.time.ns_per_min); | |
| 1698 | testDurationCaseSigned("-1m", -(std.time.ns_per_min)); | |
| 1699 | testDurationCaseSigned("1h", std.time.ns_per_hour); | |
| 1700 | testDurationCaseSigned("-1h", -(std.time.ns_per_hour)); | |
| 1701 | testDurationCaseSigned("1d", std.time.ns_per_day); | |
| 1702 | testDurationCaseSigned("-1d", -(std.time.ns_per_day)); | |
| 1703 | testDurationCaseSigned("1w", std.time.ns_per_week); | |
| 1704 | testDurationCaseSigned("-1w", -(std.time.ns_per_week)); | |
| 1705 | testDurationCaseSigned("1y", 365 * std.time.ns_per_day); | |
| 1706 | testDurationCaseSigned("-1y", -(365 * std.time.ns_per_day)); | |
| 1707 | testDurationCaseSigned("1y52w23h59m59.999s", 730 * std.time.ns_per_day - 1); // 365d = 52w1d | |
| 1708 | testDurationCaseSigned("-1y52w23h59m59.999s", -(730 * std.time.ns_per_day - 1)); // 365d = 52w1d | |
| 1709 | testDurationCaseSigned("1y1h1.001s", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_s + std.time.ns_per_ms); | |
| 1710 | testDurationCaseSigned("-1y1h1.001s", -(365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_s + std.time.ns_per_ms)); | |
| 1711 | testDurationCaseSigned("1y1h1s", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_s + 999 * std.time.ns_per_us); | |
| 1712 | testDurationCaseSigned("-1y1h1s", -(365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_s + 999 * std.time.ns_per_us)); | |
| 1713 | testDurationCaseSigned("1y1h999.999us", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms - 1); | |
| 1714 | testDurationCaseSigned("-1y1h999.999us", -(365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms - 1)); | |
| 1715 | testDurationCaseSigned("1y1h1ms", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms); | |
| 1716 | testDurationCaseSigned("-1y1h1ms", -(365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms)); | |
| 1717 | testDurationCaseSigned("1y1h1ms", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms + 1); | |
| 1718 | testDurationCaseSigned("-1y1h1ms", -(365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms + 1)); | |
| 1719 | testDurationCaseSigned("1y1m999ns", 365 * std.time.ns_per_day + std.time.ns_per_min + 999); | |
| 1720 | testDurationCaseSigned("-1y1m999ns", -(365 * std.time.ns_per_day + std.time.ns_per_min + 999)); | |
| 1721 | testDurationCaseSigned("292y24w3d23h47m16.854s", std.math.maxInt(i64)); | |
| 1722 | testDurationCaseSigned("-292y24w3d23h47m16.854s", std.math.minInt(i64) + 1); | |
| 1723 | testDurationCaseSigned("-292y24w3d23h47m16.854s", std.math.minInt(i64)); | |
| 1724 | ||
| 1725 | testing.expectFmt("=======0ns", "{s:=>10}", .{0}); | |
| 1726 | testing.expectFmt("1ns=======", "{s:=<10}", .{1}); | |
| 1727 | testing.expectFmt("-1ns======", "{s:=<10}", .{-(1)}); | |
| 1728 | testing.expectFmt(" -999ns ", "{s:^10}", .{-(std.time.ns_per_us - 1)}); | |
| 1729 | } | |
| 1730 | ||
| 1731 | fn testDurationCase(expected: []const u8, input: u64) !void { | |
| 1732 | var buf: [24]u8 = undefined; | |
| 1733 | var bw: BufferedWriter = undefined; | |
| 1734 | bw.initFixed(&buf); | |
| 1735 | try bw.printDurationUnsigned(input); | |
| 1736 | try testing.expectEqualStrings(expected, bw.getWritten()); | |
| 1737 | } | |
| 1738 | ||
| 1739 | fn testDurationCaseSigned(expected: []const u8, input: i64) !void { | |
| 1740 | var buf: [24]u8 = undefined; | |
| 1741 | var bw: BufferedWriter = undefined; | |
| 1742 | bw.initFixed(&buf); | |
| 1743 | try bw.printDurationSigned(input); | |
| 1744 | try testing.expectEqualStrings(expected, bw.getWritten()); | |
| 1745 | } | |
| 1746 | ||
| 1747 | test printIntOptions { | |
| 1748 | try testPrintIntCase("-1", @as(i1, -1), 10, .lower, .{}); | |
| 1749 | ||
| 1750 | try testPrintIntCase("-101111000110000101001110", @as(i32, -12345678), 2, .lower, .{}); | |
| 1751 | try testPrintIntCase("-12345678", @as(i32, -12345678), 10, .lower, .{}); | |
| 1752 | try testPrintIntCase("-bc614e", @as(i32, -12345678), 16, .lower, .{}); | |
| 1753 | try testPrintIntCase("-BC614E", @as(i32, -12345678), 16, .upper, .{}); | |
| 1754 | ||
| 1755 | try testPrintIntCase("12345678", @as(u32, 12345678), 10, .upper, .{}); | |
| 1756 | ||
| 1757 | try testPrintIntCase(" 666", @as(u32, 666), 10, .lower, .{ .width = 6 }); | |
| 1758 | try testPrintIntCase(" 1234", @as(u32, 0x1234), 16, .lower, .{ .width = 6 }); | |
| 1759 | try testPrintIntCase("1234", @as(u32, 0x1234), 16, .lower, .{ .width = 1 }); | |
| 1760 | ||
| 1761 | try testPrintIntCase("+42", @as(i32, 42), 10, .lower, .{ .width = 3 }); | |
| 1762 | try testPrintIntCase("-42", @as(i32, -42), 10, .lower, .{ .width = 3 }); | |
| 1763 | } | |
| 1764 | ||
| 1765 | test "printInt with comptime_int" { | |
| 1766 | var buf: [20]u8 = undefined; | |
| 1767 | var bw: BufferedWriter = undefined; | |
| 1768 | bw.initFixed(&buf); | |
| 1769 | try bw.printInt(@as(comptime_int, 123456789123456789), "", .{}); | |
| 1770 | try std.testing.expectEqualStrings("123456789123456789", bw.getWritten()); | |
| 1771 | } | |
| 1772 | ||
| 1773 | test "printFloat with comptime_float" { | |
| 1774 | var buf: [20]u8 = undefined; | |
| 1775 | var bw: BufferedWriter = undefined; | |
| 1776 | bw.initFixed(&buf); | |
| 1777 | try bw.printFloat("", .{}, @as(comptime_float, 1.0)); | |
| 1778 | try std.testing.expectEqualStrings(bw.getWritten(), "1e0"); | |
| 1779 | try std.testing.expectFmt("1e0", "{}", .{1.0}); | |
| 1780 | } | |
| 1781 | ||
| 1782 | fn testPrintIntCase(expected: []const u8, value: anytype, base: u8, case: std.fmt.Case, options: std.fmt.Options) !void { | |
| 1783 | var buffer: [100]u8 = undefined; | |
| 1784 | var bw: BufferedWriter = undefined; | |
| 1785 | bw.initFixed(&buffer); | |
| 1786 | bw.printIntOptions(value, base, case, options); | |
| 1787 | try testing.expectEqualStrings(expected, bw.getWritten()); | |
| 1788 | } | |
| 1789 | ||
| 1790 | test printByteSize { | |
| 1791 | try testing.expectFmt("file size: 42B\n", "file size: {B}\n", .{42}); | |
| 1792 | try testing.expectFmt("file size: 42B\n", "file size: {Bi}\n", .{42}); | |
| 1793 | try testing.expectFmt("file size: 63MB\n", "file size: {B}\n", .{63 * 1000 * 1000}); | |
| 1794 | try testing.expectFmt("file size: 63MiB\n", "file size: {Bi}\n", .{63 * 1024 * 1024}); | |
| 1795 | try testing.expectFmt("file size: 42B\n", "file size: {B:.2}\n", .{42}); | |
| 1796 | try testing.expectFmt("file size: 42B\n", "file size: {B:>9.2}\n", .{42}); | |
| 1797 | try testing.expectFmt("file size: 66.06MB\n", "file size: {B:.2}\n", .{63 * 1024 * 1024}); | |
| 1798 | try testing.expectFmt("file size: 60.08MiB\n", "file size: {Bi:.2}\n", .{63 * 1000 * 1000}); | |
| 1799 | try testing.expectFmt("file size: =66.06MB=\n", "file size: {B:=^9.2}\n", .{63 * 1024 * 1024}); | |
| 1800 | try testing.expectFmt("file size: 66.06MB\n", "file size: {B: >9.2}\n", .{63 * 1024 * 1024}); | |
| 1801 | try testing.expectFmt("file size: 66.06MB \n", "file size: {B: <9.2}\n", .{63 * 1024 * 1024}); | |
| 1802 | try testing.expectFmt("file size: 0.01844674407370955ZB\n", "file size: {B}\n", .{std.math.maxInt(u64)}); | |
| 1803 | } | |
| 1804 | ||
| 1805 | test "bytes.hex" { | |
| 1806 | const some_bytes = "\xCA\xFE\xBA\xBE"; | |
| 1807 | try std.testing.expectFmt("lowercase: cafebabe\n", "lowercase: {x}\n", .{some_bytes}); | |
| 1808 | try std.testing.expectFmt("uppercase: CAFEBABE\n", "uppercase: {X}\n", .{some_bytes}); | |
| 1809 | try std.testing.expectFmt("uppercase: CAFE\n", "uppercase: {X}\n", .{some_bytes[0..2]}); | |
| 1810 | try std.testing.expectFmt("lowercase: babe\n", "lowercase: {x}\n", .{some_bytes[2..]}); | |
| 1811 | const bytes_with_zeros = "\x00\x0E\xBA\xBE"; | |
| 1812 | try std.testing.expectFmt("lowercase: 000ebabe\n", "lowercase: {x}\n", .{bytes_with_zeros}); | |
| 1813 | } | |
| 1814 | ||
| 1815 | test initFixed { | |
| 1816 | { | |
| 1817 | var buf: [255]u8 = undefined; | |
| 1818 | var bw: BufferedWriter = undefined; | |
| 1819 | bw.initFixed(&buf); | |
| 1820 | try bw.print("{s}{s}!", .{ "Hello", "World" }); | |
| 1821 | try testing.expectEqualStrings("HelloWorld!", bw.getWritten()); | |
| 1822 | } | |
| 1823 | ||
| 1824 | comptime { | |
| 1825 | var buf: [255]u8 = undefined; | |
| 1826 | var bw: BufferedWriter = undefined; | |
| 1827 | bw.initFixed(&buf); | |
| 1828 | try bw.print("{s}{s}!", .{ "Hello", "World" }); | |
| 1829 | try testing.expectEqualStrings("HelloWorld!", bw.getWritten()); | |
| 1830 | } | |
| 1831 | } | |
| 1832 | ||
| 1833 | test "fixed output" { | |
| 1834 | var buffer: [10]u8 = undefined; | |
| 1835 | var bw: BufferedWriter = undefined; | |
| 1836 | bw.initFixed(&buffer); | |
| 1837 | ||
| 1838 | try bw.writeAll("Hello"); | |
| 1839 | try testing.expect(std.mem.eql(u8, bw.getWritten(), "Hello")); | |
| 1840 | ||
| 1841 | try bw.writeAll("world"); | |
| 1842 | try testing.expect(std.mem.eql(u8, bw.getWritten(), "Helloworld")); | |
| 1843 | ||
| 1844 | try testing.expectError(error.WriteStreamEnd, bw.writeAll("!")); | |
| 1845 | try testing.expect(std.mem.eql(u8, bw.getWritten(), "Helloworld")); | |
| 1846 | ||
| 1847 | bw.reset(); | |
| 1848 | try testing.expect(bw.getWritten().len == 0); | |
| 1849 | ||
| 1850 | try testing.expectError(error.WriteStreamEnd, bw.writeAll("Hello world!")); | |
| 1851 | try testing.expect(std.mem.eql(u8, bw.getWritten(), "Hello worl")); | |
| 1852 | ||
| 1853 | try bw.seekTo((try bw.getEndPos()) + 1); | |
| 1854 | try testing.expectError(error.WriteStreamEnd, bw.writeAll("H")); | |
| 1855 | } | |
| 1856 | ||
| 1857 | test flushLimit { | |
| 1858 | return error.Unimplemented; | |
| 1859 | } |
lib/std/io/Reader.zig+3-6| ... | ... | @@ -1149,8 +1149,7 @@ pub fn restitute(r: *Reader, n: usize) void { |
| 1149 | 1149 | } |
| 1150 | 1150 | |
| 1151 | 1151 | test fixed { |
| 1152 | var r: Reader = undefined; | |
| 1153 | r.initFixed("a\x02"); | |
| 1152 | var r: Reader = .fixed("a\x02"); | |
| 1154 | 1153 | try testing.expect((try r.takeByte()) == 'a'); |
| 1155 | 1154 | try testing.expect((try r.takeEnum(enum(u8) { |
| 1156 | 1155 | a = 0, |
| ... | ... | @@ -1186,8 +1185,7 @@ test peekArray { |
| 1186 | 1185 | } |
| 1187 | 1186 | |
| 1188 | 1187 | test discardAll { |
| 1189 | var r: Reader = undefined; | |
| 1190 | r.initFixed("foobar"); | |
| 1188 | var r: Reader = .fixed("foobar"); | |
| 1191 | 1189 | try r.discard(3); |
| 1192 | 1190 | try testing.expectEqualStrings("bar", try r.take(3)); |
| 1193 | 1191 | try r.discard(0); |
| ... | ... | @@ -1300,8 +1298,7 @@ test readVec { |
| 1300 | 1298 | |
| 1301 | 1299 | test "expected error.EndOfStream" { |
| 1302 | 1300 | // Unit test inspired by https://github.com/ziglang/zig/issues/17733 |
| 1303 | var r: std.io.Reader = undefined; | |
| 1304 | r.initFixed(""); | |
| 1301 | var r: std.io.Reader = .fixed(""); | |
| 1305 | 1302 | try std.testing.expectError(error.EndOfStream, r.readEnum(enum(u8) { a, b }, .little)); |
| 1306 | 1303 | try std.testing.expectError(error.EndOfStream, r.isBytes("foo")); |
| 1307 | 1304 | } |
lib/std/io/Reader/Limited.zig+3-3| ... | ... | @@ -2,7 +2,7 @@ const Limited = @This(); |
| 2 | 2 | |
| 3 | 3 | const std = @import("../../std.zig"); |
| 4 | 4 | const Reader = std.io.Reader; |
| 5 | const BufferedWriter = std.io.BufferedWriter; | |
| 5 | const Writer = std.io.Writer; | |
| 6 | 6 | const Limit = std.io.Limit; |
| 7 | 7 | |
| 8 | 8 | unlimited: *Reader, |
| ... | ... | @@ -25,10 +25,10 @@ pub fn init(reader: *Reader, limit: Limit, buffer: []u8) Limited { |
| 25 | 25 | }; |
| 26 | 26 | } |
| 27 | 27 | |
| 28 | fn stream(context: ?*anyopaque, bw: *BufferedWriter, limit: Limit) Reader.StreamError!usize { | |
| 28 | fn stream(context: ?*anyopaque, w: *Writer, limit: Limit) Reader.StreamError!usize { | |
| 29 | 29 | const l: *Limited = @alignCast(@ptrCast(context)); |
| 30 | 30 | const combined_limit = limit.min(l.remaining); |
| 31 | const n = try l.unlimited_reader.read(bw, combined_limit); | |
| 31 | const n = try l.unlimited_reader.read(w, combined_limit); | |
| 32 | 32 | l.remaining = l.remaining.subtract(n).?; |
| 33 | 33 | return n; |
| 34 | 34 | } |
lib/std/io/Writer.zig+1836-130| ... | ... | @@ -1,51 +1,71 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const native_endian = builtin.target.cpu.arch.endian(); | |
| 3 | ||
| 4 | const Writer = @This(); | |
| 1 | 5 | const std = @import("../std.zig"); |
| 2 | 6 | const assert = std.debug.assert; |
| 3 | const Writer = @This(); | |
| 4 | 7 | const Limit = std.io.Limit; |
| 5 | 8 | const File = std.fs.File; |
| 9 | const testing = std.testing; | |
| 10 | const Allocator = std.mem.Allocator; | |
| 6 | 11 | |
| 7 | 12 | context: ?*anyopaque, |
| 8 | 13 | vtable: *const VTable, |
| 14 | /// If this has length zero, the writer is unbuffered, and `flush` is a no-op. | |
| 15 | buffer: []u8, | |
| 16 | /// In `buffer` before this are buffered bytes, after this is `undefined`. | |
| 17 | end: usize = 0, | |
| 18 | /// Tracks total number of bytes written to this `Writer`. This value | |
| 19 | /// only increases. In the case of fixed mode, this value always equals `end`. | |
| 20 | /// | |
| 21 | /// This value is maintained by the interface; `VTable` function | |
| 22 | /// implementations need not modify it. | |
| 23 | count: usize = 0, | |
| 9 | 24 | |
| 10 | 25 | pub const VTable = struct { |
| 11 | /// Each slice in `data` is written in order. | |
| 26 | /// Sends bytes to the logical sink. A write will only be sent here if it | |
| 27 | /// could not fit into `buffer`. | |
| 28 | /// | |
| 29 | /// `buffer[0..end]` is consumed first, followed by each slice of `data` in | |
| 30 | /// order. Elements of `data` may alias each other but may not alias | |
| 31 | /// `buffer`. | |
| 32 | /// | |
| 33 | /// This function modifies `Writer` state. | |
| 12 | 34 | /// |
| 13 | 35 | /// `data.len` must be greater than zero, and the last element of `data` is |
| 14 | 36 | /// special. It is repeated as necessary so that it is written `splat` |
| 15 | /// number of times. | |
| 37 | /// number of times, which may be zero. | |
| 16 | 38 | /// |
| 17 | /// Number of bytes actually written is returned. | |
| 39 | /// Number of bytes actually written is returned, excluding bytes from | |
| 40 | /// `buffer`. Bytes from `buffer` are tracked by modifying `end`. | |
| 18 | 41 | /// |
| 19 | 42 | /// Number of bytes returned may be zero, which does not mean |
| 20 | /// end-of-stream. A subsequent call may return nonzero, or may signal end | |
| 21 | /// of stream via `error.WriteFailed`. | |
| 22 | writeSplat: *const fn (ctx: ?*anyopaque, data: []const []const u8, splat: usize) Error!usize, | |
| 43 | /// end-of-stream. A subsequent call may return nonzero, or signal end of | |
| 44 | /// stream via `error.WriteFailed`. | |
| 45 | drain: *const fn (w: *Writer, data: []const []const u8, splat: usize) Error!usize, | |
| 23 | 46 | |
| 24 | /// Writes contents from an open file. `headers` are written first, then | |
| 25 | /// `limit` bytes of `file` starting from `offset`, then `trailers`. | |
| 47 | /// Copies contents from an open file to the logical sink. `buffer[0..end]` | |
| 48 | /// is consumed first, followed by `limit` bytes from `file_reader`. | |
| 26 | 49 | /// |
| 27 | /// Number of bytes actually written is returned, which may lie within | |
| 28 | /// headers, the file, trailers, or anywhere in between. | |
| 50 | /// Number of bytes actually written is returned, excluding bytes from | |
| 51 | /// `buffer`. Bytes from `buffer` are tracked by modifying `end`. | |
| 29 | 52 | /// |
| 30 | /// Number of bytes returned may be zero, which does not mean | |
| 31 | /// end-of-stream. A subsequent call may return nonzero, or may signal end | |
| 32 | /// of stream via `error.WriteFailed`. | |
| 53 | /// Number of bytes returned may be zero, which does not necessarily mean | |
| 54 | /// end-of-stream. A subsequent call may return nonzero, or signal end of | |
| 55 | /// stream via `error.WriteFailed`. Caller must check `file_reader` state | |
| 56 | /// (`File.Reader.atEnd`) to disambiguate between a zero-length read or | |
| 57 | /// write, and whether the file reached the end. | |
| 33 | 58 | /// |
| 34 | 59 | /// `error.Unimplemented` indicates the callee cannot offer a more |
| 35 | 60 | /// efficient implementation than the caller performing its own reads. |
| 36 | writeFile: *const fn ( | |
| 37 | ctx: ?*anyopaque, | |
| 61 | sendFile: *const fn ( | |
| 62 | w: *Writer, | |
| 38 | 63 | file_reader: *File.Reader, |
| 39 | 64 | /// Maximum amount of bytes to read from the file. Implementations may |
| 40 | /// assume that the file size does not exceed this amount. | |
| 41 | /// | |
| 42 | /// `headers_and_trailers` do not count towards this limit. | |
| 65 | /// assume that the file size does not exceed this amount. Data from | |
| 66 | /// `buffer` does not count towards this limit. | |
| 43 | 67 | limit: Limit, |
| 44 | /// Headers and trailers must be passed together so that in case `len` is | |
| 45 | /// zero, they can be forwarded directly as one contiguous slice of memory. | |
| 46 | headers_and_trailers: []const []const u8, | |
| 47 | headers_len: usize, | |
| 48 | ) FileError!usize, | |
| 68 | ) FileError!usize = unimplementedSendFile, | |
| 49 | 69 | }; |
| 50 | 70 | |
| 51 | 71 | pub const Error = error{ |
| ... | ... | @@ -70,97 +90,1602 @@ pub const FileError = error{ |
| 70 | 90 | Unimplemented, |
| 71 | 91 | }; |
| 72 | 92 | |
| 73 | pub fn writeVec(w: Writer, data: []const []const u8) Error!usize { | |
| 93 | /// Writes to `buffer` and returns `error.WriteFailed` when it is full. Unless | |
| 94 | /// modified externally, `count` will always equal `end`. | |
| 95 | pub fn fixed(buffer: []u8) Writer { | |
| 96 | return .{ | |
| 97 | .context = undefined, | |
| 98 | .vtable = &.{ .drain = fixedDrain }, | |
| 99 | .buffer = buffer, | |
| 100 | }; | |
| 101 | } | |
| 102 | ||
| 103 | pub fn hashed(w: *Writer, hasher: anytype) Hashed(@TypeOf(hasher)) { | |
| 104 | return .{ .out = w, .hasher = hasher }; | |
| 105 | } | |
| 106 | ||
| 107 | pub const failing: Writer = .{ | |
| 108 | .context = undefined, | |
| 109 | .vtable = &.{ | |
| 110 | .drain = failingDrain, | |
| 111 | .sendFile = failingSendFile, | |
| 112 | }, | |
| 113 | }; | |
| 114 | ||
| 115 | pub fn discarding(buffer: []u8) Writer { | |
| 116 | return .{ | |
| 117 | .context = undefined, | |
| 118 | .vtable = &.{ | |
| 119 | .drain = discardingDrain, | |
| 120 | .sendFile = discardingSendFile, | |
| 121 | }, | |
| 122 | .buffer = buffer, | |
| 123 | }; | |
| 124 | } | |
| 125 | ||
| 126 | /// Returns the contents not yet drained. | |
| 127 | pub fn buffered(w: *const Writer) []u8 { | |
| 128 | return w.buffer[0..w.end]; | |
| 129 | } | |
| 130 | ||
| 131 | pub fn countSplat(n: usize, data: []const []const u8, splat: usize) usize { | |
| 74 | 132 | assert(data.len > 0); |
| 75 | return w.vtable.writeSplat(w.context, data, 1); | |
| 133 | var total: usize = n; | |
| 134 | for (data[0 .. data.len - 1]) |buf| total += buf.len; | |
| 135 | total += data[data.len - 1].len * splat; | |
| 136 | return total; | |
| 76 | 137 | } |
| 77 | 138 | |
| 78 | pub fn writeSplat(w: Writer, data: []const []const u8, splat: usize) Error!usize { | |
| 139 | pub fn countSendFileUpperBound(n: usize, file_reader: *File.Reader, limit: Limit) ?usize { | |
| 140 | const total: u64 = @min(@intFromEnum(limit), file_reader.getSize() orelse return null); | |
| 141 | return std.math.lossyCast(usize, total + n); | |
| 142 | } | |
| 143 | ||
| 144 | /// If the total number of bytes of `data` fits inside `unusedCapacitySlice`, | |
| 145 | /// this function is guaranteed to not fail, not call into `VTable`, and return | |
| 146 | /// the total bytes inside `data`. | |
| 147 | pub fn writeVec(w: *Writer, data: []const []const u8) Error!usize { | |
| 148 | return writeSplat(w, data, 1); | |
| 149 | } | |
| 150 | ||
| 151 | /// If the number of bytes to write based on `data` and `splat` fits inside | |
| 152 | /// `unusedCapacitySlice`, this function is guaranteed to not fail, not call | |
| 153 | /// into `VTable`, and return the full number of bytes. | |
| 154 | pub fn writeSplat(w: *Writer, data: []const []const u8, splat: usize) Error!usize { | |
| 79 | 155 | assert(data.len > 0); |
| 80 | return w.vtable.writeSplat(w.context, data, splat); | |
| 156 | const buffer = w.buffer; | |
| 157 | const count = countSplat(0, data, splat); | |
| 158 | if (w.end + count > buffer.len) { | |
| 159 | const end = w.end; | |
| 160 | const n = try w.vtable.drain(w, data, splat); | |
| 161 | return n -| end; | |
| 162 | } | |
| 163 | w.count += count; | |
| 164 | for (data) |bytes| { | |
| 165 | @memcpy(buffer[w.end..][0..bytes.len], bytes); | |
| 166 | w.end += bytes.len; | |
| 167 | } | |
| 168 | const pattern = data[data.len - 1]; | |
| 169 | if (splat == 0) { | |
| 170 | @branchHint(.unlikely); | |
| 171 | // It was added in the loop above; undo it here. | |
| 172 | w.end -= pattern.len; | |
| 173 | return count; | |
| 174 | } | |
| 175 | const remaining_splat = splat - 1; | |
| 176 | switch (pattern.len) { | |
| 177 | 0 => {}, | |
| 178 | 1 => { | |
| 179 | @memset(buffer[w.end..][0..remaining_splat], pattern[0]); | |
| 180 | w.end += remaining_splat; | |
| 181 | }, | |
| 182 | else => { | |
| 183 | const new_end = w.end + pattern.len * remaining_splat; | |
| 184 | while (w.end < new_end) : (w.end += pattern.len) { | |
| 185 | @memcpy(buffer[w.end..][0..pattern.len], pattern); | |
| 186 | } | |
| 187 | }, | |
| 188 | } | |
| 189 | return count; | |
| 81 | 190 | } |
| 82 | 191 | |
| 83 | pub fn writeFile( | |
| 84 | w: Writer, | |
| 85 | file_reader: *File.Reader, | |
| 192 | /// Equivalent to `writeSplat` but writes at most `limit` bytes. | |
| 193 | pub fn writeSplatLimit( | |
| 194 | w: *Writer, | |
| 195 | data: []const []const u8, | |
| 196 | splat: usize, | |
| 86 | 197 | limit: Limit, |
| 87 | headers_and_trailers: []const []const u8, | |
| 88 | headers_len: usize, | |
| 89 | ) FileError!usize { | |
| 90 | return w.vtable.writeFile(w.context, file_reader, limit, headers_and_trailers, headers_len); | |
| 198 | ) Error!usize { | |
| 199 | _ = w; | |
| 200 | _ = data; | |
| 201 | _ = splat; | |
| 202 | _ = limit; | |
| 203 | @panic("TODO"); | |
| 91 | 204 | } |
| 92 | 205 | |
| 93 | pub fn buffered(w: Writer, buffer: []u8) std.io.BufferedWriter { | |
| 94 | return .{ | |
| 95 | .buffer = buffer, | |
| 96 | .unbuffered_writer = w, | |
| 206 | /// Drains all remaining buffered data. | |
| 207 | pub fn flush(w: *Writer) Error!void { | |
| 208 | const drainFn = w.vtable.drain; | |
| 209 | // This implementation allows for drain functions that do not modify `end`, | |
| 210 | // such as `fixedDrain`. | |
| 211 | var remaining = w.end; | |
| 212 | while (remaining != 0) remaining -= try drainFn(w, &.{""}, 1); | |
| 213 | } | |
| 214 | ||
| 215 | pub fn unusedCapacitySlice(w: *const Writer) []u8 { | |
| 216 | return w.buffer[w.end..]; | |
| 217 | } | |
| 218 | ||
| 219 | pub fn unusedCapacityLen(w: *const Writer) usize { | |
| 220 | return w.buffer.len - w.end; | |
| 221 | } | |
| 222 | ||
| 223 | /// Asserts the provided buffer has total capacity enough for `len`. | |
| 224 | /// | |
| 225 | /// Advances the buffer end position by `len`. | |
| 226 | pub fn writableArray(w: *Writer, comptime len: usize) Error!*[len]u8 { | |
| 227 | const big_slice = try w.writableSliceGreedy(len); | |
| 228 | advance(w, len); | |
| 229 | return big_slice[0..len]; | |
| 230 | } | |
| 231 | ||
| 232 | /// Asserts the provided buffer has total capacity enough for `len`. | |
| 233 | /// | |
| 234 | /// Advances the buffer end position by `len`. | |
| 235 | pub fn writableSlice(w: *Writer, len: usize) Error![]u8 { | |
| 236 | const big_slice = try w.writableSliceGreedy(len); | |
| 237 | advance(w, len); | |
| 238 | return big_slice[0..len]; | |
| 239 | } | |
| 240 | ||
| 241 | /// Asserts the provided buffer has total capacity enough for `minimum_length`. | |
| 242 | /// | |
| 243 | /// Does not `advance` the buffer end position. | |
| 244 | /// | |
| 245 | /// If `minimum_length` is zero, this is equivalent to `unusedCapacitySlice`. | |
| 246 | pub fn writableSliceGreedy(w: *Writer, minimum_length: usize) Error![]u8 { | |
| 247 | assert(w.buffer.len >= minimum_length); | |
| 248 | const cap_slice = w.buffer[w.end..]; | |
| 249 | if (cap_slice.len >= minimum_length) { | |
| 250 | @branchHint(.likely); | |
| 251 | return cap_slice; | |
| 252 | } | |
| 253 | const buffer = w.buffer[0..w.end]; | |
| 254 | const n = try w.unbuffered_writer.writeVec(&.{buffer}); | |
| 255 | if (n == buffer.len) { | |
| 256 | @branchHint(.likely); | |
| 257 | w.end = 0; | |
| 258 | return w.buffer; | |
| 259 | } | |
| 260 | if (n > 0) { | |
| 261 | const remainder = buffer[n..]; | |
| 262 | std.mem.copyForwards(u8, buffer[0..remainder.len], remainder); | |
| 263 | w.end = remainder.len; | |
| 264 | } | |
| 265 | return w.buffer[w.end..]; | |
| 266 | } | |
| 267 | ||
| 268 | pub fn ensureUnusedCapacity(w: *Writer, n: usize) Error!void { | |
| 269 | _ = try writableSliceGreedy(w, n); | |
| 270 | } | |
| 271 | ||
| 272 | pub fn undo(w: *Writer, n: usize) void { | |
| 273 | w.end -= n; | |
| 274 | w.count -= n; | |
| 275 | } | |
| 276 | ||
| 277 | /// After calling `writableSliceGreedy`, this function tracks how many bytes | |
| 278 | /// were written to it. | |
| 279 | /// | |
| 280 | /// This is not needed when using `writableSlice` or `writableArray`. | |
| 281 | pub fn advance(w: *Writer, n: usize) void { | |
| 282 | const new_end = w.end + n; | |
| 283 | assert(new_end <= w.buffer.len); | |
| 284 | w.end = new_end; | |
| 285 | w.count += n; | |
| 286 | } | |
| 287 | ||
| 288 | /// The `data` parameter is mutable because this function needs to mutate the | |
| 289 | /// fields in order to handle partial writes from `VTable.writeSplat`. | |
| 290 | pub fn writeVecAll(w: *Writer, data: [][]const u8) Error!void { | |
| 291 | var index: usize = 0; | |
| 292 | var truncate: usize = 0; | |
| 293 | while (index < data.len) { | |
| 294 | { | |
| 295 | const untruncated = data[index]; | |
| 296 | data[index] = untruncated[truncate..]; | |
| 297 | defer data[index] = untruncated; | |
| 298 | truncate += try w.writeVec(data[index..]); | |
| 299 | } | |
| 300 | while (index < data.len and truncate >= data[index].len) { | |
| 301 | truncate -= data[index].len; | |
| 302 | index += 1; | |
| 303 | } | |
| 304 | } | |
| 305 | } | |
| 306 | ||
| 307 | /// The `data` parameter is mutable because this function needs to mutate the | |
| 308 | /// fields in order to handle partial writes from `VTable.writeSplat`. | |
| 309 | pub fn writeSplatAll(w: *Writer, data: [][]const u8, splat: usize) Error!void { | |
| 310 | var index: usize = 0; | |
| 311 | var truncate: usize = 0; | |
| 312 | var remaining_splat = splat; | |
| 313 | while (index + 1 < data.len) { | |
| 314 | { | |
| 315 | const untruncated = data[index]; | |
| 316 | data[index] = untruncated[truncate..]; | |
| 317 | defer data[index] = untruncated; | |
| 318 | truncate += try w.writeSplat(data[index..], remaining_splat); | |
| 319 | } | |
| 320 | while (truncate >= data[index].len) { | |
| 321 | if (index + 1 < data.len) { | |
| 322 | truncate -= data[index].len; | |
| 323 | index += 1; | |
| 324 | } else { | |
| 325 | const last = data[data.len - 1]; | |
| 326 | remaining_splat -= @divExact(truncate, last.len); | |
| 327 | while (remaining_splat > 0) { | |
| 328 | const n = try w.writeSplat(data[data.len - 1 ..][0..1], remaining_splat); | |
| 329 | remaining_splat -= @divExact(n, last.len); | |
| 330 | } | |
| 331 | return; | |
| 332 | } | |
| 333 | } | |
| 334 | } | |
| 335 | } | |
| 336 | ||
| 337 | pub fn write(w: *Writer, bytes: []const u8) Error!usize { | |
| 338 | if (w.end + bytes.len <= w.buffer.len) { | |
| 339 | @memcpy(w.buffer[w.end..][0..bytes.len], bytes); | |
| 340 | w.end += bytes.len; | |
| 341 | w.count += bytes.len; | |
| 342 | return bytes.len; | |
| 343 | } | |
| 344 | const end = w.end; | |
| 345 | const n = try w.vtable.drain(w, &.{bytes}, 1); | |
| 346 | return n -| end; | |
| 347 | } | |
| 348 | ||
| 349 | /// Calls `write` as many times as necessary such that all of `bytes` are | |
| 350 | /// transferred. | |
| 351 | pub fn writeAll(w: *Writer, bytes: []const u8) Error!void { | |
| 352 | var index: usize = 0; | |
| 353 | while (index < bytes.len) index += try w.write(bytes[index..]); | |
| 354 | } | |
| 355 | ||
| 356 | pub fn print(w: *Writer, comptime format: []const u8, args: anytype) Error!void { | |
| 357 | try std.fmt.format(w, format, args); | |
| 358 | } | |
| 359 | ||
| 360 | pub fn writeByte(w: *Writer, byte: u8) Error!void { | |
| 361 | const buffer = w.buffer[0..w.end]; | |
| 362 | if (buffer.len < w.buffer.len) { | |
| 363 | @branchHint(.likely); | |
| 364 | buffer.ptr[buffer.len] = byte; | |
| 365 | w.end = buffer.len + 1; | |
| 366 | w.count += 1; | |
| 367 | return; | |
| 368 | } | |
| 369 | var buffers: [2][]const u8 = .{ buffer, &.{byte} }; | |
| 370 | while (true) { | |
| 371 | const n = try w.unbuffered_writer.writeVec(&buffers); | |
| 372 | if (n == 0) { | |
| 373 | @branchHint(.unlikely); | |
| 374 | continue; | |
| 375 | } | |
| 376 | w.count += 1; | |
| 377 | if (n >= buffer.len) { | |
| 378 | @branchHint(.likely); | |
| 379 | if (n > buffer.len) { | |
| 380 | @branchHint(.likely); | |
| 381 | w.end = 0; | |
| 382 | return; | |
| 383 | } else { | |
| 384 | buffer[0] = byte; | |
| 385 | w.end = 1; | |
| 386 | return; | |
| 387 | } | |
| 388 | } | |
| 389 | const remainder = buffer[n..]; | |
| 390 | std.mem.copyForwards(u8, buffer[0..remainder.len], remainder); | |
| 391 | buffer[remainder.len] = byte; | |
| 392 | w.end = remainder.len + 1; | |
| 393 | return; | |
| 394 | } | |
| 395 | } | |
| 396 | ||
| 397 | /// Writes the same byte many times, performing the underlying write call as | |
| 398 | /// many times as necessary. | |
| 399 | pub fn splatByteAll(w: *Writer, byte: u8, n: usize) Error!void { | |
| 400 | var remaining: usize = n; | |
| 401 | while (remaining > 0) remaining -= try w.splatByte(byte, remaining); | |
| 402 | } | |
| 403 | ||
| 404 | /// Writes the same byte many times, allowing short writes. | |
| 405 | /// | |
| 406 | /// Does maximum of one underlying `VTable.drain`. | |
| 407 | pub fn splatByte(w: *Writer, byte: u8, n: usize) Error!usize { | |
| 408 | return writeSplat(w, &.{&.{byte}}, n); | |
| 409 | } | |
| 410 | ||
| 411 | /// Writes the same slice many times, performing the underlying write call as | |
| 412 | /// many times as necessary. | |
| 413 | pub fn splatBytesAll(w: *Writer, bytes: []const u8, splat: usize) Error!void { | |
| 414 | var remaining_bytes: usize = bytes.len * splat; | |
| 415 | remaining_bytes -= try w.splatBytes(bytes, splat); | |
| 416 | while (remaining_bytes > 0) { | |
| 417 | const leftover = remaining_bytes % bytes.len; | |
| 418 | const buffers: [2][]const u8 = .{ bytes[bytes.len - leftover ..], bytes }; | |
| 419 | remaining_bytes -= try w.splatBytes(&buffers, splat); | |
| 420 | } | |
| 421 | } | |
| 422 | ||
| 423 | /// Writes the same slice many times, allowing short writes. | |
| 424 | /// | |
| 425 | /// Does maximum of one underlying `VTable.writeSplat`. | |
| 426 | pub fn splatBytes(w: *Writer, bytes: []const u8, n: usize) Error!usize { | |
| 427 | return writeSplat(w, &.{bytes}, n); | |
| 428 | } | |
| 429 | ||
| 430 | /// Asserts the `buffer` was initialized with a capacity of at least `@sizeOf(T)` bytes. | |
| 431 | pub inline fn writeInt(w: *Writer, comptime T: type, value: T, endian: std.builtin.Endian) Error!void { | |
| 432 | var bytes: [@divExact(@typeInfo(T).int.bits, 8)]u8 = undefined; | |
| 433 | std.mem.writeInt(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value, endian); | |
| 434 | return w.writeAll(&bytes); | |
| 435 | } | |
| 436 | ||
| 437 | pub fn writeStruct(w: *Writer, value: anytype) Error!void { | |
| 438 | // Only extern and packed structs have defined in-memory layout. | |
| 439 | comptime assert(@typeInfo(@TypeOf(value)).@"struct".layout != .auto); | |
| 440 | return w.writeAll(std.mem.asBytes(&value)); | |
| 441 | } | |
| 442 | ||
| 443 | /// The function is inline to avoid the dead code in case `endian` is | |
| 444 | /// comptime-known and matches host endianness. | |
| 445 | /// TODO: make sure this value is not a reference type | |
| 446 | pub inline fn writeStructEndian(w: *Writer, value: anytype, endian: std.builtin.Endian) Error!void { | |
| 447 | if (native_endian == endian) { | |
| 448 | return w.writeStruct(value); | |
| 449 | } else { | |
| 450 | var copy = value; | |
| 451 | std.mem.byteSwapAllFields(@TypeOf(value), &copy); | |
| 452 | return w.writeStruct(copy); | |
| 453 | } | |
| 454 | } | |
| 455 | ||
| 456 | pub inline fn writeSliceEndian( | |
| 457 | w: *Writer, | |
| 458 | Elem: type, | |
| 459 | slice: []const Elem, | |
| 460 | endian: std.builtin.Endian, | |
| 461 | ) Error!void { | |
| 462 | if (native_endian == endian) { | |
| 463 | return writeAll(w, @ptrCast(slice)); | |
| 464 | } else { | |
| 465 | return w.writeArraySwap(w, Elem, slice); | |
| 466 | } | |
| 467 | } | |
| 468 | ||
| 469 | /// Asserts that the buffer storage capacity is at least enough to store `@sizeOf(Elem)` | |
| 470 | pub fn writeSliceSwap(w: *Writer, Elem: type, slice: []const Elem) Error!void { | |
| 471 | // copy to storage first, then swap in place | |
| 472 | _ = w; | |
| 473 | _ = slice; | |
| 474 | @panic("TODO"); | |
| 475 | } | |
| 476 | ||
| 477 | /// Unlike `writeSplat` and `writeVec`, this function will call into `VTable` | |
| 478 | /// even if there is enough buffer capacity for the file contents. | |
| 479 | /// | |
| 480 | /// Although it would be possible to eliminate `error.Unimplemented` from the | |
| 481 | /// error set by reading directly into the buffer in such case, this is not | |
| 482 | /// done because it is more efficient to do it higher up the call stack so that | |
| 483 | /// the error does not occur with each write. | |
| 484 | /// | |
| 485 | /// See `sendFileReading` for an alternative that does not have | |
| 486 | /// `error.Unimplemented` in the error set. | |
| 487 | pub fn sendFile(w: *Writer, file_reader: *File.Reader, limit: Limit) FileError!usize { | |
| 488 | const end = w.end; | |
| 489 | const n = try w.vtable.sendFile(w, file_reader, limit); | |
| 490 | return n -| end; | |
| 491 | } | |
| 492 | ||
| 493 | /// Asserts nonzero buffer capacity. | |
| 494 | pub fn sendFileReading(w: *Writer, file_reader: *File.Reader, limit: Limit) ReadingFileError!usize { | |
| 495 | const dest = limit.slice(try w.writableSliceGreedy(1)); | |
| 496 | const n = file_reader.read(dest) catch |err| switch (err) { | |
| 497 | error.EndOfStream => 0, | |
| 498 | error.ReadFailed => return error.ReadFailed, | |
| 97 | 499 | }; |
| 500 | w.advance(n); | |
| 501 | return n; | |
| 502 | } | |
| 503 | ||
| 504 | pub fn sendFileAll(w: *Writer, file_reader: *File.Reader, limit: Limit) ReadingFileError!usize { | |
| 505 | var remaining = @intFromEnum(limit); | |
| 506 | while (remaining > 0) { | |
| 507 | const n = sendFile(w, file_reader, .limited(remaining)) catch |err| switch (err) { | |
| 508 | error.EndOfStream => return 0, | |
| 509 | error.ReadFailed => return error.ReadFailed, | |
| 510 | error.WriteFailed => return error.WriteFailed, | |
| 511 | error.Unimplemented => { | |
| 512 | file_reader.mode = file_reader.mode.toReading(); | |
| 513 | try w.sendFileReadingAll(file_reader, remaining); | |
| 514 | return; | |
| 515 | }, | |
| 516 | }; | |
| 517 | remaining -= n; | |
| 518 | } | |
| 519 | return @intFromEnum(limit) - remaining; | |
| 520 | } | |
| 521 | ||
| 522 | /// Equivalent to `sendFileAll` but uses direct `pread` and `read` calls on | |
| 523 | /// `file` rather than `sendFile`. This is generally used as a fallback when | |
| 524 | /// the underlying implementation returns `error.Unimplemented`, which is why | |
| 525 | /// that error code does not appear in this function's error set. | |
| 526 | /// | |
| 527 | /// Asserts nonzero buffer capacity. | |
| 528 | pub fn sendFileReadingAll(w: *Writer, file_reader: *File.Reader, limit: Limit) ReadingFileError!void { | |
| 529 | var remaining = limit; | |
| 530 | while (remaining.nonzero()) { | |
| 531 | const n = try sendFileReading(w, file_reader, remaining); | |
| 532 | if (n == 0) return; | |
| 533 | remaining = remaining.subtract(n).?; | |
| 534 | } | |
| 535 | } | |
| 536 | ||
| 537 | pub fn alignBuffer( | |
| 538 | w: *Writer, | |
| 539 | buffer: []const u8, | |
| 540 | width: usize, | |
| 541 | alignment: std.fmt.Alignment, | |
| 542 | fill: u8, | |
| 543 | ) Error!void { | |
| 544 | const padding = if (buffer.len < width) width - buffer.len else 0; | |
| 545 | if (padding == 0) { | |
| 546 | @branchHint(.likely); | |
| 547 | return w.writeAll(buffer); | |
| 548 | } | |
| 549 | switch (alignment) { | |
| 550 | .left => { | |
| 551 | try w.writeAll(buffer); | |
| 552 | try w.splatByteAll(fill, padding); | |
| 553 | }, | |
| 554 | .center => { | |
| 555 | const left_padding = padding / 2; | |
| 556 | const right_padding = (padding + 1) / 2; | |
| 557 | try w.splatByteAll(fill, left_padding); | |
| 558 | try w.writeAll(buffer); | |
| 559 | try w.splatByteAll(fill, right_padding); | |
| 560 | }, | |
| 561 | .right => { | |
| 562 | try w.splatByteAll(fill, padding); | |
| 563 | try w.writeAll(buffer); | |
| 564 | }, | |
| 565 | } | |
| 566 | } | |
| 567 | ||
| 568 | pub fn alignBufferOptions(w: *Writer, buffer: []const u8, options: std.fmt.Options) Error!void { | |
| 569 | return w.alignBuffer(buffer, options.width orelse buffer.len, options.alignment, options.fill); | |
| 570 | } | |
| 571 | ||
| 572 | pub fn printAddress(w: *Writer, value: anytype) Error!void { | |
| 573 | const T = @TypeOf(value); | |
| 574 | switch (@typeInfo(T)) { | |
| 575 | .pointer => |info| { | |
| 576 | try w.writeAll(@typeName(info.child) ++ "@"); | |
| 577 | if (info.size == .slice) | |
| 578 | try w.printIntOptions(@intFromPtr(value.ptr), 16, .lower, .{}) | |
| 579 | else | |
| 580 | try w.printIntOptions(@intFromPtr(value), 16, .lower, .{}); | |
| 581 | return; | |
| 582 | }, | |
| 583 | .optional => |info| { | |
| 584 | if (@typeInfo(info.child) == .pointer) { | |
| 585 | try w.writeAll(@typeName(info.child) ++ "@"); | |
| 586 | try w.printIntOptions(@intFromPtr(value), 16, .lower, .{}); | |
| 587 | return; | |
| 588 | } | |
| 589 | }, | |
| 590 | else => {}, | |
| 591 | } | |
| 592 | ||
| 593 | @compileError("cannot format non-pointer type " ++ @typeName(T) ++ " with * specifier"); | |
| 594 | } | |
| 595 | ||
| 596 | pub fn printValue( | |
| 597 | w: *Writer, | |
| 598 | comptime fmt: []const u8, | |
| 599 | options: std.fmt.Options, | |
| 600 | value: anytype, | |
| 601 | max_depth: usize, | |
| 602 | ) Error!void { | |
| 603 | const T = @TypeOf(value); | |
| 604 | ||
| 605 | if (comptime std.mem.eql(u8, fmt, "*")) { | |
| 606 | return w.printAddress(value); | |
| 607 | } | |
| 608 | ||
| 609 | const is_any = comptime std.mem.eql(u8, fmt, ANY); | |
| 610 | if (!is_any and std.meta.hasMethod(T, "format")) { | |
| 611 | if (fmt.len > 0 and fmt[0] == 'f') { | |
| 612 | return value.format(w, fmt[1..]); | |
| 613 | } else if (fmt.len == 0) { | |
| 614 | // after 0.15.0 is tagged, delete the hasMethod condition and this compile error | |
| 615 | @compileError("ambiguous format string; specify {f} to call format method, or {any} to skip it"); | |
| 616 | } | |
| 617 | } | |
| 618 | ||
| 619 | switch (@typeInfo(T)) { | |
| 620 | .float, .comptime_float => return w.printFloat(if (is_any) "d" else fmt, options, value), | |
| 621 | .int, .comptime_int => return w.printInt(if (is_any) "d" else fmt, options, value), | |
| 622 | .bool => { | |
| 623 | if (!is_any and fmt.len != 0) invalidFmtError(fmt, value); | |
| 624 | return w.alignBufferOptions(if (value) "true" else "false", options); | |
| 625 | }, | |
| 626 | .void => { | |
| 627 | if (!is_any and fmt.len != 0) invalidFmtError(fmt, value); | |
| 628 | return w.alignBufferOptions("void", options); | |
| 629 | }, | |
| 630 | .optional => { | |
| 631 | const remaining_fmt = comptime if (fmt.len > 0 and fmt[0] == '?') | |
| 632 | stripOptionalOrErrorUnionSpec(fmt) | |
| 633 | else if (is_any) | |
| 634 | ANY | |
| 635 | else | |
| 636 | @compileError("cannot print optional without a specifier (i.e. {?} or {any})"); | |
| 637 | if (value) |payload| { | |
| 638 | return w.printValue(remaining_fmt, options, payload, max_depth); | |
| 639 | } else { | |
| 640 | return w.alignBufferOptions("null", options); | |
| 641 | } | |
| 642 | }, | |
| 643 | .error_union => { | |
| 644 | const remaining_fmt = comptime if (fmt.len > 0 and fmt[0] == '!') | |
| 645 | stripOptionalOrErrorUnionSpec(fmt) | |
| 646 | else if (is_any) | |
| 647 | ANY | |
| 648 | else | |
| 649 | @compileError("cannot print error union without a specifier (i.e. {!} or {any})"); | |
| 650 | if (value) |payload| { | |
| 651 | return w.printValue(remaining_fmt, options, payload, max_depth); | |
| 652 | } else |err| { | |
| 653 | return w.printValue("", options, err, max_depth); | |
| 654 | } | |
| 655 | }, | |
| 656 | .error_set => { | |
| 657 | if (fmt.len == 1 and fmt[0] == 's') return w.writeAll(@errorName(value)); | |
| 658 | if (!is_any and fmt.len != 0) invalidFmtError(fmt, value); | |
| 659 | try printErrorSet(w, value); | |
| 660 | }, | |
| 661 | .@"enum" => { | |
| 662 | if (fmt.len == 1 and fmt[0] == 's') { | |
| 663 | try w.writeAll(@tagName(value)); | |
| 664 | return; | |
| 665 | } | |
| 666 | if (!is_any) { | |
| 667 | if (fmt.len != 0) return printValue(w, fmt, options, @intFromEnum(value), max_depth); | |
| 668 | return printValue(w, ANY, options, value, max_depth); | |
| 669 | } | |
| 670 | const enum_info = @typeInfo(T).@"enum"; | |
| 671 | if (enum_info.is_exhaustive) { | |
| 672 | var vecs: [3][]const u8 = .{ @typeName(T), ".", @tagName(value) }; | |
| 673 | try w.writeVecAll(&vecs); | |
| 674 | return; | |
| 675 | } | |
| 676 | try w.writeAll(@typeName(T)); | |
| 677 | @setEvalBranchQuota(3 * enum_info.fields.len); | |
| 678 | inline for (enum_info.fields) |field| { | |
| 679 | if (@intFromEnum(value) == field.value) { | |
| 680 | try w.writeAll("."); | |
| 681 | try w.writeAll(@tagName(value)); | |
| 682 | return; | |
| 683 | } | |
| 684 | } | |
| 685 | try w.writeByte('('); | |
| 686 | try w.printValue(ANY, options, @intFromEnum(value), max_depth); | |
| 687 | try w.writeByte(')'); | |
| 688 | }, | |
| 689 | .@"union" => |info| { | |
| 690 | if (!is_any) { | |
| 691 | if (fmt.len != 0) invalidFmtError(fmt, value); | |
| 692 | return printValue(w, ANY, options, value, max_depth); | |
| 693 | } | |
| 694 | try w.writeAll(@typeName(T)); | |
| 695 | if (max_depth == 0) { | |
| 696 | try w.writeAll("{ ... }"); | |
| 697 | return; | |
| 698 | } | |
| 699 | if (info.tag_type) |UnionTagType| { | |
| 700 | try w.writeAll("{ ."); | |
| 701 | try w.writeAll(@tagName(@as(UnionTagType, value))); | |
| 702 | try w.writeAll(" = "); | |
| 703 | inline for (info.fields) |u_field| { | |
| 704 | if (value == @field(UnionTagType, u_field.name)) { | |
| 705 | try w.printValue(ANY, options, @field(value, u_field.name), max_depth - 1); | |
| 706 | } | |
| 707 | } | |
| 708 | try w.writeAll(" }"); | |
| 709 | } else { | |
| 710 | try w.writeByte('@'); | |
| 711 | try w.printIntOptions(@intFromPtr(&value), 16, .lower, options); | |
| 712 | } | |
| 713 | }, | |
| 714 | .@"struct" => |info| { | |
| 715 | if (!is_any) { | |
| 716 | if (fmt.len != 0) invalidFmtError(fmt, value); | |
| 717 | return printValue(w, ANY, options, value, max_depth); | |
| 718 | } | |
| 719 | if (info.is_tuple) { | |
| 720 | // Skip the type and field names when formatting tuples. | |
| 721 | if (max_depth == 0) { | |
| 722 | try w.writeAll("{ ... }"); | |
| 723 | return; | |
| 724 | } | |
| 725 | try w.writeAll("{"); | |
| 726 | inline for (info.fields, 0..) |f, i| { | |
| 727 | if (i == 0) { | |
| 728 | try w.writeAll(" "); | |
| 729 | } else { | |
| 730 | try w.writeAll(", "); | |
| 731 | } | |
| 732 | try w.printValue(ANY, options, @field(value, f.name), max_depth - 1); | |
| 733 | } | |
| 734 | try w.writeAll(" }"); | |
| 735 | return; | |
| 736 | } | |
| 737 | try w.writeAll(@typeName(T)); | |
| 738 | if (max_depth == 0) { | |
| 739 | try w.writeAll("{ ... }"); | |
| 740 | return; | |
| 741 | } | |
| 742 | try w.writeAll("{"); | |
| 743 | inline for (info.fields, 0..) |f, i| { | |
| 744 | if (i == 0) { | |
| 745 | try w.writeAll(" ."); | |
| 746 | } else { | |
| 747 | try w.writeAll(", ."); | |
| 748 | } | |
| 749 | try w.writeAll(f.name); | |
| 750 | try w.writeAll(" = "); | |
| 751 | try w.printValue(ANY, options, @field(value, f.name), max_depth - 1); | |
| 752 | } | |
| 753 | try w.writeAll(" }"); | |
| 754 | }, | |
| 755 | .pointer => |ptr_info| switch (ptr_info.size) { | |
| 756 | .one => switch (@typeInfo(ptr_info.child)) { | |
| 757 | .array, .@"enum", .@"union", .@"struct" => { | |
| 758 | return w.printValue(fmt, options, value.*, max_depth); | |
| 759 | }, | |
| 760 | else => { | |
| 761 | var buffers: [2][]const u8 = .{ @typeName(ptr_info.child), "@" }; | |
| 762 | try w.writeVecAll(&buffers); | |
| 763 | try w.printIntOptions(@intFromPtr(value), 16, .lower, options); | |
| 764 | return; | |
| 765 | }, | |
| 766 | }, | |
| 767 | .many, .c => { | |
| 768 | if (ptr_info.sentinel() != null) | |
| 769 | return w.printValue(fmt, options, std.mem.span(value), max_depth); | |
| 770 | if (fmt.len == 1 and fmt[0] == 's' and ptr_info.child == u8) | |
| 771 | return w.alignBufferOptions(std.mem.span(value), options); | |
| 772 | if (!is_any and fmt.len == 0) | |
| 773 | @compileError("cannot format pointer without a specifier (i.e. {s} or {*})"); | |
| 774 | if (!is_any and fmt.len != 0) | |
| 775 | invalidFmtError(fmt, value); | |
| 776 | try w.printAddress(value); | |
| 777 | }, | |
| 778 | .slice => { | |
| 779 | if (!is_any and fmt.len == 0) | |
| 780 | @compileError("cannot format slice without a specifier (i.e. {s}, {x}, {b64}, or {any})"); | |
| 781 | if (max_depth == 0) | |
| 782 | return w.writeAll("{ ... }"); | |
| 783 | if (ptr_info.child == u8) switch (fmt.len) { | |
| 784 | 1 => switch (fmt[0]) { | |
| 785 | 's' => return w.alignBufferOptions(value, options), | |
| 786 | 'x' => return w.printHex(value, .lower), | |
| 787 | 'X' => return w.printHex(value, .upper), | |
| 788 | else => {}, | |
| 789 | }, | |
| 790 | 3 => if (fmt[0] == 'b' and fmt[1] == '6' and fmt[2] == '4') { | |
| 791 | return w.printBase64(value); | |
| 792 | }, | |
| 793 | else => {}, | |
| 794 | }; | |
| 795 | try w.writeAll("{ "); | |
| 796 | for (value, 0..) |elem, i| { | |
| 797 | try w.printValue(fmt, options, elem, max_depth - 1); | |
| 798 | if (i != value.len - 1) { | |
| 799 | try w.writeAll(", "); | |
| 800 | } | |
| 801 | } | |
| 802 | try w.writeAll(" }"); | |
| 803 | }, | |
| 804 | }, | |
| 805 | .array => |info| { | |
| 806 | if (fmt.len == 0) | |
| 807 | @compileError("cannot format array without a specifier (i.e. {s} or {any})"); | |
| 808 | if (max_depth == 0) { | |
| 809 | return w.writeAll("{ ... }"); | |
| 810 | } | |
| 811 | if (info.child == u8) { | |
| 812 | if (fmt[0] == 's') { | |
| 813 | return w.alignBufferOptions(&value, options); | |
| 814 | } else if (fmt[0] == 'x') { | |
| 815 | return w.printHex(&value, .lower); | |
| 816 | } else if (fmt[0] == 'X') { | |
| 817 | return w.printHex(&value, .upper); | |
| 818 | } | |
| 819 | } | |
| 820 | try w.writeAll("{ "); | |
| 821 | for (value, 0..) |elem, i| { | |
| 822 | try w.printValue(fmt, options, elem, max_depth - 1); | |
| 823 | if (i < value.len - 1) { | |
| 824 | try w.writeAll(", "); | |
| 825 | } | |
| 826 | } | |
| 827 | try w.writeAll(" }"); | |
| 828 | }, | |
| 829 | .vector => |info| { | |
| 830 | if (max_depth == 0) { | |
| 831 | return w.writeAll("{ ... }"); | |
| 832 | } | |
| 833 | try w.writeAll("{ "); | |
| 834 | var i: usize = 0; | |
| 835 | while (i < info.len) : (i += 1) { | |
| 836 | try w.printValue(fmt, options, value[i], max_depth - 1); | |
| 837 | if (i < info.len - 1) { | |
| 838 | try w.writeAll(", "); | |
| 839 | } | |
| 840 | } | |
| 841 | try w.writeAll(" }"); | |
| 842 | }, | |
| 843 | .@"fn" => @compileError("unable to format function body type, use '*const " ++ @typeName(T) ++ "' for a function pointer type"), | |
| 844 | .type => { | |
| 845 | if (!is_any and fmt.len != 0) invalidFmtError(fmt, value); | |
| 846 | return w.alignBufferOptions(@typeName(value), options); | |
| 847 | }, | |
| 848 | .enum_literal => { | |
| 849 | if (!is_any and fmt.len != 0) invalidFmtError(fmt, value); | |
| 850 | const buffer = [_]u8{'.'} ++ @tagName(value); | |
| 851 | return w.alignBufferOptions(buffer, options); | |
| 852 | }, | |
| 853 | .null => { | |
| 854 | if (!is_any and fmt.len != 0) invalidFmtError(fmt, value); | |
| 855 | return w.alignBufferOptions("null", options); | |
| 856 | }, | |
| 857 | else => @compileError("unable to format type '" ++ @typeName(T) ++ "'"), | |
| 858 | } | |
| 98 | 859 | } |
| 99 | 860 | |
| 100 | pub fn unbuffered(w: Writer) std.io.BufferedWriter { | |
| 101 | return w.buffered(&.{}); | |
| 861 | fn printErrorSet(w: *Writer, error_set: anyerror) Error!void { | |
| 862 | var vecs: [2][]const u8 = .{ "error.", @errorName(error_set) }; | |
| 863 | try w.writeVecAll(&vecs); | |
| 102 | 864 | } |
| 103 | 865 | |
| 104 | pub fn failingWriteSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) Error!usize { | |
| 105 | _ = context; | |
| 866 | pub fn printInt( | |
| 867 | w: *Writer, | |
| 868 | comptime fmt: []const u8, | |
| 869 | options: std.fmt.Options, | |
| 870 | value: anytype, | |
| 871 | ) Error!void { | |
| 872 | const int_value = if (@TypeOf(value) == comptime_int) blk: { | |
| 873 | const Int = std.math.IntFittingRange(value, value); | |
| 874 | break :blk @as(Int, value); | |
| 875 | } else value; | |
| 876 | ||
| 877 | switch (fmt.len) { | |
| 878 | 0 => return w.printIntOptions(int_value, 10, .lower, options), | |
| 879 | 1 => switch (fmt[0]) { | |
| 880 | 'd' => return w.printIntOptions(int_value, 10, .lower, options), | |
| 881 | 'c' => { | |
| 882 | if (@typeInfo(@TypeOf(int_value)).int.bits <= 8) { | |
| 883 | return w.printAsciiChar(@as(u8, int_value), options); | |
| 884 | } else { | |
| 885 | @compileError("cannot print integer that is larger than 8 bits as an ASCII character"); | |
| 886 | } | |
| 887 | }, | |
| 888 | 'u' => { | |
| 889 | if (@typeInfo(@TypeOf(int_value)).int.bits <= 21) { | |
| 890 | return w.printUnicodeCodepoint(@as(u21, int_value), options); | |
| 891 | } else { | |
| 892 | @compileError("cannot print integer that is larger than 21 bits as an UTF-8 sequence"); | |
| 893 | } | |
| 894 | }, | |
| 895 | 'b' => return w.printIntOptions(int_value, 2, .lower, options), | |
| 896 | 'x' => return w.printIntOptions(int_value, 16, .lower, options), | |
| 897 | 'X' => return w.printIntOptions(int_value, 16, .upper, options), | |
| 898 | 'o' => return w.printIntOptions(int_value, 8, .lower, options), | |
| 899 | 'B' => return w.printByteSize(int_value, .decimal, options), | |
| 900 | 'D' => return w.printDuration(int_value, options), | |
| 901 | else => invalidFmtError(fmt, value), | |
| 902 | }, | |
| 903 | 2 => { | |
| 904 | if (fmt[0] == 'B' and fmt[1] == 'i') { | |
| 905 | return w.printByteSize(int_value, .binary, options); | |
| 906 | } else { | |
| 907 | invalidFmtError(fmt, value); | |
| 908 | } | |
| 909 | }, | |
| 910 | else => invalidFmtError(fmt, value), | |
| 911 | } | |
| 912 | comptime unreachable; | |
| 913 | } | |
| 914 | ||
| 915 | pub fn printAsciiChar(w: *Writer, c: u8, options: std.fmt.Options) Error!void { | |
| 916 | return w.alignBufferOptions(@as(*const [1]u8, &c), options); | |
| 917 | } | |
| 918 | ||
| 919 | pub fn printAscii(w: *Writer, bytes: []const u8, options: std.fmt.Options) Error!void { | |
| 920 | return w.alignBufferOptions(bytes, options); | |
| 921 | } | |
| 922 | ||
| 923 | pub fn printUnicodeCodepoint(w: *Writer, c: u21, options: std.fmt.Options) Error!void { | |
| 924 | var buf: [4]u8 = undefined; | |
| 925 | const len = try std.unicode.utf8Encode(c, &buf); | |
| 926 | return w.alignBufferOptions(buf[0..len], options); | |
| 927 | } | |
| 928 | ||
| 929 | pub fn printIntOptions( | |
| 930 | w: *Writer, | |
| 931 | value: anytype, | |
| 932 | base: u8, | |
| 933 | case: std.fmt.Case, | |
| 934 | options: std.fmt.Options, | |
| 935 | ) Error!void { | |
| 936 | assert(base >= 2); | |
| 937 | ||
| 938 | const int_value = if (@TypeOf(value) == comptime_int) blk: { | |
| 939 | const Int = std.math.IntFittingRange(value, value); | |
| 940 | break :blk @as(Int, value); | |
| 941 | } else value; | |
| 942 | ||
| 943 | const value_info = @typeInfo(@TypeOf(int_value)).int; | |
| 944 | ||
| 945 | // The type must have the same size as `base` or be wider in order for the | |
| 946 | // division to work | |
| 947 | const min_int_bits = comptime @max(value_info.bits, 8); | |
| 948 | const MinInt = std.meta.Int(.unsigned, min_int_bits); | |
| 949 | ||
| 950 | const abs_value = @abs(int_value); | |
| 951 | // The worst case in terms of space needed is base 2, plus 1 for the sign | |
| 952 | var buf: [1 + @max(@as(comptime_int, value_info.bits), 1)]u8 = undefined; | |
| 953 | ||
| 954 | var a: MinInt = abs_value; | |
| 955 | var index: usize = buf.len; | |
| 956 | ||
| 957 | if (base == 10) { | |
| 958 | while (a >= 100) : (a = @divTrunc(a, 100)) { | |
| 959 | index -= 2; | |
| 960 | buf[index..][0..2].* = std.fmt.digits2(@intCast(a % 100)); | |
| 961 | } | |
| 962 | ||
| 963 | if (a < 10) { | |
| 964 | index -= 1; | |
| 965 | buf[index] = '0' + @as(u8, @intCast(a)); | |
| 966 | } else { | |
| 967 | index -= 2; | |
| 968 | buf[index..][0..2].* = std.fmt.digits2(@intCast(a)); | |
| 969 | } | |
| 970 | } else { | |
| 971 | while (true) { | |
| 972 | const digit = a % base; | |
| 973 | index -= 1; | |
| 974 | buf[index] = std.fmt.digitToChar(@intCast(digit), case); | |
| 975 | a /= base; | |
| 976 | if (a == 0) break; | |
| 977 | } | |
| 978 | } | |
| 979 | ||
| 980 | if (value_info.signedness == .signed) { | |
| 981 | if (value < 0) { | |
| 982 | // Negative integer | |
| 983 | index -= 1; | |
| 984 | buf[index] = '-'; | |
| 985 | } else if (options.width == null or options.width.? == 0) { | |
| 986 | // Positive integer, omit the plus sign | |
| 987 | } else { | |
| 988 | // Positive integer | |
| 989 | index -= 1; | |
| 990 | buf[index] = '+'; | |
| 991 | } | |
| 992 | } | |
| 993 | ||
| 994 | return w.alignBufferOptions(buf[index..], options); | |
| 995 | } | |
| 996 | ||
| 997 | pub fn printFloat( | |
| 998 | w: *Writer, | |
| 999 | comptime fmt: []const u8, | |
| 1000 | options: std.fmt.Options, | |
| 1001 | value: anytype, | |
| 1002 | ) Error!void { | |
| 1003 | var buf: [std.fmt.float.bufferSize(.decimal, f64)]u8 = undefined; | |
| 1004 | ||
| 1005 | if (fmt.len > 1) invalidFmtError(fmt, value); | |
| 1006 | switch (if (fmt.len == 0) 'e' else fmt[0]) { | |
| 1007 | 'e' => { | |
| 1008 | const s = std.fmt.float.render(&buf, value, .{ .mode = .scientific, .precision = options.precision }) catch |err| switch (err) { | |
| 1009 | error.BufferTooSmall => "(float)", | |
| 1010 | }; | |
| 1011 | return w.alignBufferOptions(s, options); | |
| 1012 | }, | |
| 1013 | 'd' => { | |
| 1014 | const s = std.fmt.float.render(&buf, value, .{ .mode = .decimal, .precision = options.precision }) catch |err| switch (err) { | |
| 1015 | error.BufferTooSmall => "(float)", | |
| 1016 | }; | |
| 1017 | return w.alignBufferOptions(s, options); | |
| 1018 | }, | |
| 1019 | 'x' => { | |
| 1020 | var sub_bw: Writer = .fixed(&buf); | |
| 1021 | sub_bw.printFloatHexadecimal(value, options.precision) catch unreachable; | |
| 1022 | return w.alignBufferOptions(sub_bw.buffered(), options); | |
| 1023 | }, | |
| 1024 | else => invalidFmtError(fmt, value), | |
| 1025 | } | |
| 1026 | } | |
| 1027 | ||
| 1028 | pub fn printFloatHexadecimal(w: *Writer, value: anytype, opt_precision: ?usize) Error!void { | |
| 1029 | if (std.math.signbit(value)) try w.writeByte('-'); | |
| 1030 | if (std.math.isNan(value)) return w.writeAll("nan"); | |
| 1031 | if (std.math.isInf(value)) return w.writeAll("inf"); | |
| 1032 | ||
| 1033 | const T = @TypeOf(value); | |
| 1034 | const TU = std.meta.Int(.unsigned, @bitSizeOf(T)); | |
| 1035 | ||
| 1036 | const mantissa_bits = std.math.floatMantissaBits(T); | |
| 1037 | const fractional_bits = std.math.floatFractionalBits(T); | |
| 1038 | const exponent_bits = std.math.floatExponentBits(T); | |
| 1039 | const mantissa_mask = (1 << mantissa_bits) - 1; | |
| 1040 | const exponent_mask = (1 << exponent_bits) - 1; | |
| 1041 | const exponent_bias = (1 << (exponent_bits - 1)) - 1; | |
| 1042 | ||
| 1043 | const as_bits: TU = @bitCast(value); | |
| 1044 | var mantissa = as_bits & mantissa_mask; | |
| 1045 | var exponent: i32 = @as(u16, @truncate((as_bits >> mantissa_bits) & exponent_mask)); | |
| 1046 | ||
| 1047 | const is_denormal = exponent == 0 and mantissa != 0; | |
| 1048 | const is_zero = exponent == 0 and mantissa == 0; | |
| 1049 | ||
| 1050 | if (is_zero) { | |
| 1051 | // Handle this case here to simplify the logic below. | |
| 1052 | try w.writeAll("0x0"); | |
| 1053 | if (opt_precision) |precision| { | |
| 1054 | if (precision > 0) { | |
| 1055 | try w.writeAll("."); | |
| 1056 | try w.splatByteAll('0', precision); | |
| 1057 | } | |
| 1058 | } else { | |
| 1059 | try w.writeAll(".0"); | |
| 1060 | } | |
| 1061 | try w.writeAll("p0"); | |
| 1062 | return; | |
| 1063 | } | |
| 1064 | ||
| 1065 | if (is_denormal) { | |
| 1066 | // Adjust the exponent for printing. | |
| 1067 | exponent += 1; | |
| 1068 | } else { | |
| 1069 | if (fractional_bits == mantissa_bits) | |
| 1070 | mantissa |= 1 << fractional_bits; // Add the implicit integer bit. | |
| 1071 | } | |
| 1072 | ||
| 1073 | const mantissa_digits = (fractional_bits + 3) / 4; | |
| 1074 | // Fill in zeroes to round the fraction width to a multiple of 4. | |
| 1075 | mantissa <<= mantissa_digits * 4 - fractional_bits; | |
| 1076 | ||
| 1077 | if (opt_precision) |precision| { | |
| 1078 | // Round if needed. | |
| 1079 | if (precision < mantissa_digits) { | |
| 1080 | // We always have at least 4 extra bits. | |
| 1081 | var extra_bits = (mantissa_digits - precision) * 4; | |
| 1082 | // The result LSB is the Guard bit, we need two more (Round and | |
| 1083 | // Sticky) to round the value. | |
| 1084 | while (extra_bits > 2) { | |
| 1085 | mantissa = (mantissa >> 1) | (mantissa & 1); | |
| 1086 | extra_bits -= 1; | |
| 1087 | } | |
| 1088 | // Round to nearest, tie to even. | |
| 1089 | mantissa |= @intFromBool(mantissa & 0b100 != 0); | |
| 1090 | mantissa += 1; | |
| 1091 | // Drop the excess bits. | |
| 1092 | mantissa >>= 2; | |
| 1093 | // Restore the alignment. | |
| 1094 | mantissa <<= @as(std.math.Log2Int(TU), @intCast((mantissa_digits - precision) * 4)); | |
| 1095 | ||
| 1096 | const overflow = mantissa & (1 << 1 + mantissa_digits * 4) != 0; | |
| 1097 | // Prefer a normalized result in case of overflow. | |
| 1098 | if (overflow) { | |
| 1099 | mantissa >>= 1; | |
| 1100 | exponent += 1; | |
| 1101 | } | |
| 1102 | } | |
| 1103 | } | |
| 1104 | ||
| 1105 | // +1 for the decimal part. | |
| 1106 | var buf: [1 + mantissa_digits]u8 = undefined; | |
| 1107 | assert(std.fmt.printInt(&buf, mantissa, 16, .lower, .{ .fill = '0', .width = 1 + mantissa_digits }) == buf.len); | |
| 1108 | ||
| 1109 | try w.writeAll("0x"); | |
| 1110 | try w.writeByte(buf[0]); | |
| 1111 | const trimmed = std.mem.trimRight(u8, buf[1..], "0"); | |
| 1112 | if (opt_precision) |precision| { | |
| 1113 | if (precision > 0) try w.writeAll("."); | |
| 1114 | } else if (trimmed.len > 0) { | |
| 1115 | try w.writeAll("."); | |
| 1116 | } | |
| 1117 | try w.writeAll(trimmed); | |
| 1118 | // Add trailing zeros if explicitly requested. | |
| 1119 | if (opt_precision) |precision| if (precision > 0) { | |
| 1120 | if (precision > trimmed.len) | |
| 1121 | try w.splatByteAll('0', precision - trimmed.len); | |
| 1122 | }; | |
| 1123 | try w.writeAll("p"); | |
| 1124 | try w.printIntOptions(exponent - exponent_bias, 10, .lower, .{}); | |
| 1125 | } | |
| 1126 | ||
| 1127 | pub const ByteSizeUnits = enum { | |
| 1128 | /// This formatter represents the number as multiple of 1000 and uses the SI | |
| 1129 | /// measurement units (kB, MB, GB, ...). | |
| 1130 | decimal, | |
| 1131 | /// This formatter represents the number as multiple of 1024 and uses the IEC | |
| 1132 | /// measurement units (KiB, MiB, GiB, ...). | |
| 1133 | binary, | |
| 1134 | }; | |
| 1135 | ||
| 1136 | /// Format option `precision` is ignored when `value` is less than 1kB | |
| 1137 | pub fn printByteSize( | |
| 1138 | w: *std.io.Writer, | |
| 1139 | value: u64, | |
| 1140 | comptime units: ByteSizeUnits, | |
| 1141 | options: std.fmt.Options, | |
| 1142 | ) Error!void { | |
| 1143 | if (value == 0) return w.alignBufferOptions("0B", options); | |
| 1144 | // The worst case in terms of space needed is 32 bytes + 3 for the suffix. | |
| 1145 | var buf: [std.fmt.float.min_buffer_size + 3]u8 = undefined; | |
| 1146 | ||
| 1147 | const mags_si = " kMGTPEZY"; | |
| 1148 | const mags_iec = " KMGTPEZY"; | |
| 1149 | ||
| 1150 | const log2 = std.math.log2(value); | |
| 1151 | const base = switch (units) { | |
| 1152 | .decimal => 1000, | |
| 1153 | .binary => 1024, | |
| 1154 | }; | |
| 1155 | const magnitude = switch (units) { | |
| 1156 | .decimal => @min(log2 / comptime std.math.log2(1000), mags_si.len - 1), | |
| 1157 | .binary => @min(log2 / 10, mags_iec.len - 1), | |
| 1158 | }; | |
| 1159 | const new_value = std.math.lossyCast(f64, value) / std.math.pow(f64, std.math.lossyCast(f64, base), std.math.lossyCast(f64, magnitude)); | |
| 1160 | const suffix = switch (units) { | |
| 1161 | .decimal => mags_si[magnitude], | |
| 1162 | .binary => mags_iec[magnitude], | |
| 1163 | }; | |
| 1164 | ||
| 1165 | const s = switch (magnitude) { | |
| 1166 | 0 => buf[0..std.fmt.printInt(&buf, value, 10, .lower, .{})], | |
| 1167 | else => std.fmt.float.render(&buf, new_value, .{ .mode = .decimal, .precision = options.precision }) catch |err| switch (err) { | |
| 1168 | error.BufferTooSmall => unreachable, | |
| 1169 | }, | |
| 1170 | }; | |
| 1171 | ||
| 1172 | var i: usize = s.len; | |
| 1173 | if (suffix == ' ') { | |
| 1174 | buf[i] = 'B'; | |
| 1175 | i += 1; | |
| 1176 | } else switch (units) { | |
| 1177 | .decimal => { | |
| 1178 | buf[i..][0..2].* = [_]u8{ suffix, 'B' }; | |
| 1179 | i += 2; | |
| 1180 | }, | |
| 1181 | .binary => { | |
| 1182 | buf[i..][0..3].* = [_]u8{ suffix, 'i', 'B' }; | |
| 1183 | i += 3; | |
| 1184 | }, | |
| 1185 | } | |
| 1186 | ||
| 1187 | return w.alignBufferOptions(buf[0..i], options); | |
| 1188 | } | |
| 1189 | ||
| 1190 | // This ANY const is a workaround for: https://github.com/ziglang/zig/issues/7948 | |
| 1191 | const ANY = "any"; | |
| 1192 | ||
| 1193 | fn stripOptionalOrErrorUnionSpec(comptime fmt: []const u8) []const u8 { | |
| 1194 | return if (std.mem.eql(u8, fmt[1..], ANY)) | |
| 1195 | ANY | |
| 1196 | else | |
| 1197 | fmt[1..]; | |
| 1198 | } | |
| 1199 | ||
| 1200 | pub fn invalidFmtError(comptime fmt: []const u8, value: anytype) noreturn { | |
| 1201 | @compileError("invalid format string '" ++ fmt ++ "' for type '" ++ @typeName(@TypeOf(value)) ++ "'"); | |
| 1202 | } | |
| 1203 | ||
| 1204 | pub fn printDurationSigned(w: *Writer, ns: i64) Error!void { | |
| 1205 | if (ns < 0) try w.writeByte('-'); | |
| 1206 | return w.printDurationUnsigned(@abs(ns)); | |
| 1207 | } | |
| 1208 | ||
| 1209 | pub fn printDurationUnsigned(w: *Writer, ns: u64) Error!void { | |
| 1210 | var ns_remaining = ns; | |
| 1211 | inline for (.{ | |
| 1212 | .{ .ns = 365 * std.time.ns_per_day, .sep = 'y' }, | |
| 1213 | .{ .ns = std.time.ns_per_week, .sep = 'w' }, | |
| 1214 | .{ .ns = std.time.ns_per_day, .sep = 'd' }, | |
| 1215 | .{ .ns = std.time.ns_per_hour, .sep = 'h' }, | |
| 1216 | .{ .ns = std.time.ns_per_min, .sep = 'm' }, | |
| 1217 | }) |unit| { | |
| 1218 | if (ns_remaining >= unit.ns) { | |
| 1219 | const units = ns_remaining / unit.ns; | |
| 1220 | try w.printIntOptions(units, 10, .lower, .{}); | |
| 1221 | try w.writeByte(unit.sep); | |
| 1222 | ns_remaining -= units * unit.ns; | |
| 1223 | if (ns_remaining == 0) return; | |
| 1224 | } | |
| 1225 | } | |
| 1226 | ||
| 1227 | inline for (.{ | |
| 1228 | .{ .ns = std.time.ns_per_s, .sep = "s" }, | |
| 1229 | .{ .ns = std.time.ns_per_ms, .sep = "ms" }, | |
| 1230 | .{ .ns = std.time.ns_per_us, .sep = "us" }, | |
| 1231 | }) |unit| { | |
| 1232 | const kunits = ns_remaining * 1000 / unit.ns; | |
| 1233 | if (kunits >= 1000) { | |
| 1234 | try w.printIntOptions(kunits / 1000, 10, .lower, .{}); | |
| 1235 | const frac = kunits % 1000; | |
| 1236 | if (frac > 0) { | |
| 1237 | // Write up to 3 decimal places | |
| 1238 | var decimal_buf = [_]u8{ '.', 0, 0, 0 }; | |
| 1239 | var inner: Writer = .fixed(decimal_buf[1..]); | |
| 1240 | inner.printIntOptions(frac, 10, .lower, .{ .fill = '0', .width = 3 }) catch unreachable; | |
| 1241 | var end: usize = 4; | |
| 1242 | while (end > 1) : (end -= 1) { | |
| 1243 | if (decimal_buf[end - 1] != '0') break; | |
| 1244 | } | |
| 1245 | try w.writeAll(decimal_buf[0..end]); | |
| 1246 | } | |
| 1247 | return w.writeAll(unit.sep); | |
| 1248 | } | |
| 1249 | } | |
| 1250 | ||
| 1251 | try w.printIntOptions(ns_remaining, 10, .lower, .{}); | |
| 1252 | try w.writeAll("ns"); | |
| 1253 | } | |
| 1254 | ||
| 1255 | /// Writes number of nanoseconds according to its signed magnitude: | |
| 1256 | /// `[#y][#w][#d][#h][#m]#[.###][n|u|m]s` | |
| 1257 | /// `nanoseconds` must be an integer that coerces into `u64` or `i64`. | |
| 1258 | pub fn printDuration(w: *Writer, nanoseconds: anytype, options: std.fmt.Options) Error!void { | |
| 1259 | // worst case: "-XXXyXXwXXdXXhXXmXX.XXXs".len = 24 | |
| 1260 | var buf: [24]u8 = undefined; | |
| 1261 | var sub_bw: Writer = .fixed(&buf); | |
| 1262 | switch (@typeInfo(@TypeOf(nanoseconds)).int.signedness) { | |
| 1263 | .signed => sub_bw.printDurationSigned(nanoseconds) catch unreachable, | |
| 1264 | .unsigned => sub_bw.printDurationUnsigned(nanoseconds) catch unreachable, | |
| 1265 | } | |
| 1266 | return w.alignBufferOptions(sub_bw.buffered(), options); | |
| 1267 | } | |
| 1268 | ||
| 1269 | pub fn printHex(w: *Writer, bytes: []const u8, case: std.fmt.Case) Error!void { | |
| 1270 | const charset = switch (case) { | |
| 1271 | .upper => "0123456789ABCDEF", | |
| 1272 | .lower => "0123456789abcdef", | |
| 1273 | }; | |
| 1274 | for (bytes) |c| { | |
| 1275 | try w.writeByte(charset[c >> 4]); | |
| 1276 | try w.writeByte(charset[c & 15]); | |
| 1277 | } | |
| 1278 | } | |
| 1279 | ||
| 1280 | pub fn printBase64(w: *Writer, bytes: []const u8) Error!void { | |
| 1281 | var chunker = std.mem.window(u8, bytes, 3, 3); | |
| 1282 | var temp: [5]u8 = undefined; | |
| 1283 | while (chunker.next()) |chunk| { | |
| 1284 | try w.writeAll(std.base64.standard.Encoder.encode(&temp, chunk)); | |
| 1285 | } | |
| 1286 | } | |
| 1287 | ||
| 1288 | /// Write a single unsigned integer as LEB128 to the given writer. | |
| 1289 | pub fn writeUleb128(w: *Writer, value: anytype) Error!void { | |
| 1290 | try w.writeLeb128(switch (@typeInfo(@TypeOf(value))) { | |
| 1291 | .comptime_int => @as(std.math.IntFittingRange(0, @abs(value)), value), | |
| 1292 | .int => |value_info| switch (value_info.signedness) { | |
| 1293 | .signed => @as(@Type(.{ .int = .{ .signedness = .unsigned, .bits = value_info.bits -| 1 } }), @intCast(value)), | |
| 1294 | .unsigned => value, | |
| 1295 | }, | |
| 1296 | else => comptime unreachable, | |
| 1297 | }); | |
| 1298 | } | |
| 1299 | ||
| 1300 | /// Write a single signed integer as LEB128 to the given writer. | |
| 1301 | pub fn writeSleb128(w: *Writer, value: anytype) Error!void { | |
| 1302 | try w.writeLeb128(switch (@typeInfo(@TypeOf(value))) { | |
| 1303 | .comptime_int => @as(std.math.IntFittingRange(@min(value, -1), @max(0, value)), value), | |
| 1304 | .int => |value_info| switch (value_info.signedness) { | |
| 1305 | .signed => value, | |
| 1306 | .unsigned => @as(@Type(.{ .int = .{ .signedness = .signed, .bits = value_info.bits + 1 } }), value), | |
| 1307 | }, | |
| 1308 | else => comptime unreachable, | |
| 1309 | }); | |
| 1310 | } | |
| 1311 | ||
| 1312 | /// Write a single integer as LEB128 to the given writer. | |
| 1313 | pub fn writeLeb128(w: *Writer, value: anytype) Error!void { | |
| 1314 | const value_info = @typeInfo(@TypeOf(value)).int; | |
| 1315 | try w.writeMultipleOf7Leb128(@as(@Type(.{ .int = .{ | |
| 1316 | .signedness = value_info.signedness, | |
| 1317 | .bits = std.mem.alignForwardAnyAlign(u16, value_info.bits, 7), | |
| 1318 | } }), value)); | |
| 1319 | } | |
| 1320 | ||
| 1321 | fn writeMultipleOf7Leb128(w: *Writer, value: anytype) Error!void { | |
| 1322 | const value_info = @typeInfo(@TypeOf(value)).int; | |
| 1323 | comptime assert(value_info.bits % 7 == 0); | |
| 1324 | var remaining = value; | |
| 1325 | while (true) { | |
| 1326 | const buffer: []packed struct(u8) { bits: u7, more: bool } = @ptrCast(try w.writableSliceGreedy(1)); | |
| 1327 | for (buffer, 1..) |*byte, len| { | |
| 1328 | const more = switch (value_info.signedness) { | |
| 1329 | .signed => remaining >> 6 != remaining >> (value_info.bits - 1), | |
| 1330 | .unsigned => remaining > std.math.maxInt(u7), | |
| 1331 | }; | |
| 1332 | byte.* = if (@inComptime()) @typeInfo(@TypeOf(buffer)).pointer.child{ | |
| 1333 | .bits = @bitCast(@as(@Type(.{ .int = .{ | |
| 1334 | .signedness = value_info.signedness, | |
| 1335 | .bits = 7, | |
| 1336 | } }), @truncate(remaining))), | |
| 1337 | .more = more, | |
| 1338 | } else .{ | |
| 1339 | .bits = @bitCast(@as(@Type(.{ .int = .{ | |
| 1340 | .signedness = value_info.signedness, | |
| 1341 | .bits = 7, | |
| 1342 | } }), @truncate(remaining))), | |
| 1343 | .more = more, | |
| 1344 | }; | |
| 1345 | if (value_info.bits > 7) remaining >>= 7; | |
| 1346 | if (!more) return w.advance(len); | |
| 1347 | } | |
| 1348 | w.advance(buffer.len); | |
| 1349 | } | |
| 1350 | } | |
| 1351 | ||
| 1352 | test "formatValue max_depth" { | |
| 1353 | const Vec2 = struct { | |
| 1354 | const SelfType = @This(); | |
| 1355 | x: f32, | |
| 1356 | y: f32, | |
| 1357 | ||
| 1358 | pub fn format( | |
| 1359 | self: SelfType, | |
| 1360 | comptime fmt: []const u8, | |
| 1361 | options: std.fmt.Options, | |
| 1362 | w: *Writer, | |
| 1363 | ) Error!void { | |
| 1364 | _ = options; | |
| 1365 | if (fmt.len == 0) { | |
| 1366 | return w.print("({d:.3},{d:.3})", .{ self.x, self.y }); | |
| 1367 | } else { | |
| 1368 | @compileError("unknown format string: '" ++ fmt ++ "'"); | |
| 1369 | } | |
| 1370 | } | |
| 1371 | }; | |
| 1372 | const E = enum { | |
| 1373 | One, | |
| 1374 | Two, | |
| 1375 | Three, | |
| 1376 | }; | |
| 1377 | const TU = union(enum) { | |
| 1378 | const SelfType = @This(); | |
| 1379 | float: f32, | |
| 1380 | int: u32, | |
| 1381 | ptr: ?*SelfType, | |
| 1382 | }; | |
| 1383 | const S = struct { | |
| 1384 | const SelfType = @This(); | |
| 1385 | a: ?*SelfType, | |
| 1386 | tu: TU, | |
| 1387 | e: E, | |
| 1388 | vec: Vec2, | |
| 1389 | }; | |
| 1390 | ||
| 1391 | var inst = S{ | |
| 1392 | .a = null, | |
| 1393 | .tu = TU{ .ptr = null }, | |
| 1394 | .e = E.Two, | |
| 1395 | .vec = Vec2{ .x = 10.2, .y = 2.22 }, | |
| 1396 | }; | |
| 1397 | inst.a = &inst; | |
| 1398 | inst.tu.ptr = &inst.tu; | |
| 1399 | ||
| 1400 | var buf: [1000]u8 = undefined; | |
| 1401 | var w: Writer = .fixed(&buf); | |
| 1402 | try w.printValue("", .{}, inst, 0); | |
| 1403 | try testing.expectEqualStrings("io.Writer.test.printValue max_depth.S{ ... }", w.buffered()); | |
| 1404 | ||
| 1405 | w.reset(); | |
| 1406 | try w.printValue("", .{}, inst, 1); | |
| 1407 | try testing.expectEqualStrings("io.Writer.test.printValue max_depth.S{ .a = io.Writer.test.printValue max_depth.S{ ... }, .tu = io.Writer.test.printValue max_depth.TU{ ... }, .e = io.Writer.test.printValue max_depth.E.Two, .vec = (10.200,2.220) }", w.buffered()); | |
| 1408 | ||
| 1409 | w.reset(); | |
| 1410 | try w.printValue("", .{}, inst, 2); | |
| 1411 | try testing.expectEqualStrings("io.Writer.test.printValue max_depth.S{ .a = io.Writer.test.printValue max_depth.S{ .a = io.Writer.test.printValue max_depth.S{ ... }, .tu = io.Writer.test.printValue max_depth.TU{ ... }, .e = io.Writer.test.printValue max_depth.E.Two, .vec = (10.200,2.220) }, .tu = io.Writer.test.printValue max_depth.TU{ .ptr = io.Writer.test.printValue max_depth.TU{ ... } }, .e = io.Writer.test.printValue max_depth.E.Two, .vec = (10.200,2.220) }", w.buffered()); | |
| 1412 | ||
| 1413 | w.reset(); | |
| 1414 | try w.printValue("", .{}, inst, 3); | |
| 1415 | try testing.expectEqualStrings("io.Writer.test.printValue max_depth.S{ .a = io.Writer.test.printValue max_depth.S{ .a = io.Writer.test.printValue max_depth.S{ .a = io.Writer.test.printValue max_depth.S{ ... }, .tu = io.Writer.test.printValue max_depth.TU{ ... }, .e = io.Writer.test.printValue max_depth.E.Two, .vec = (10.200,2.220) }, .tu = io.Writer.test.printValue max_depth.TU{ .ptr = io.Writer.test.printValue max_depth.TU{ ... } }, .e = io.Writer.test.printValue max_depth.E.Two, .vec = (10.200,2.220) }, .tu = io.Writer.test.printValue max_depth.TU{ .ptr = io.Writer.test.printValue max_depth.TU{ .ptr = io.Writer.test.printValue max_depth.TU{ ... } } }, .e = io.Writer.test.printValue max_depth.E.Two, .vec = (10.200,2.220) }", w.buffered()); | |
| 1416 | ||
| 1417 | const vec: @Vector(4, i32) = .{ 1, 2, 3, 4 }; | |
| 1418 | w.reset(); | |
| 1419 | try w.printValue("", .{}, vec, 0); | |
| 1420 | try testing.expectEqualStrings("{ ... }", w.buffered()); | |
| 1421 | ||
| 1422 | w.reset(); | |
| 1423 | try w.printValue("", .{}, vec, 1); | |
| 1424 | try testing.expectEqualStrings("{ 1, 2, 3, 4 }", w.buffered()); | |
| 1425 | } | |
| 1426 | ||
| 1427 | test printDuration { | |
| 1428 | testDurationCase("0ns", 0); | |
| 1429 | testDurationCase("1ns", 1); | |
| 1430 | testDurationCase("999ns", std.time.ns_per_us - 1); | |
| 1431 | testDurationCase("1us", std.time.ns_per_us); | |
| 1432 | testDurationCase("1.45us", 1450); | |
| 1433 | testDurationCase("1.5us", 3 * std.time.ns_per_us / 2); | |
| 1434 | testDurationCase("14.5us", 14500); | |
| 1435 | testDurationCase("145us", 145000); | |
| 1436 | testDurationCase("999.999us", std.time.ns_per_ms - 1); | |
| 1437 | testDurationCase("1ms", std.time.ns_per_ms + 1); | |
| 1438 | testDurationCase("1.5ms", 3 * std.time.ns_per_ms / 2); | |
| 1439 | testDurationCase("1.11ms", 1110000); | |
| 1440 | testDurationCase("1.111ms", 1111000); | |
| 1441 | testDurationCase("1.111ms", 1111100); | |
| 1442 | testDurationCase("999.999ms", std.time.ns_per_s - 1); | |
| 1443 | testDurationCase("1s", std.time.ns_per_s); | |
| 1444 | testDurationCase("59.999s", std.time.ns_per_min - 1); | |
| 1445 | testDurationCase("1m", std.time.ns_per_min); | |
| 1446 | testDurationCase("1h", std.time.ns_per_hour); | |
| 1447 | testDurationCase("1d", std.time.ns_per_day); | |
| 1448 | testDurationCase("1w", std.time.ns_per_week); | |
| 1449 | testDurationCase("1y", 365 * std.time.ns_per_day); | |
| 1450 | testDurationCase("1y52w23h59m59.999s", 730 * std.time.ns_per_day - 1); // 365d = 52w1 | |
| 1451 | testDurationCase("1y1h1.001s", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_s + std.time.ns_per_ms); | |
| 1452 | testDurationCase("1y1h1s", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_s + 999 * std.time.ns_per_us); | |
| 1453 | testDurationCase("1y1h999.999us", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms - 1); | |
| 1454 | testDurationCase("1y1h1ms", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms); | |
| 1455 | testDurationCase("1y1h1ms", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms + 1); | |
| 1456 | testDurationCase("1y1m999ns", 365 * std.time.ns_per_day + std.time.ns_per_min + 999); | |
| 1457 | testDurationCase("584y49w23h34m33.709s", std.math.maxInt(u64)); | |
| 1458 | ||
| 1459 | testing.expectFmt("=======0ns", "{D:=>10}", .{0}); | |
| 1460 | testing.expectFmt("1ns=======", "{D:=<10}", .{1}); | |
| 1461 | testing.expectFmt(" 999ns ", "{D:^10}", .{std.time.ns_per_us - 1}); | |
| 1462 | } | |
| 1463 | ||
| 1464 | test printDurationSigned { | |
| 1465 | testDurationCaseSigned("0ns", 0); | |
| 1466 | testDurationCaseSigned("1ns", 1); | |
| 1467 | testDurationCaseSigned("-1ns", -(1)); | |
| 1468 | testDurationCaseSigned("999ns", std.time.ns_per_us - 1); | |
| 1469 | testDurationCaseSigned("-999ns", -(std.time.ns_per_us - 1)); | |
| 1470 | testDurationCaseSigned("1us", std.time.ns_per_us); | |
| 1471 | testDurationCaseSigned("-1us", -(std.time.ns_per_us)); | |
| 1472 | testDurationCaseSigned("1.45us", 1450); | |
| 1473 | testDurationCaseSigned("-1.45us", -(1450)); | |
| 1474 | testDurationCaseSigned("1.5us", 3 * std.time.ns_per_us / 2); | |
| 1475 | testDurationCaseSigned("-1.5us", -(3 * std.time.ns_per_us / 2)); | |
| 1476 | testDurationCaseSigned("14.5us", 14500); | |
| 1477 | testDurationCaseSigned("-14.5us", -(14500)); | |
| 1478 | testDurationCaseSigned("145us", 145000); | |
| 1479 | testDurationCaseSigned("-145us", -(145000)); | |
| 1480 | testDurationCaseSigned("999.999us", std.time.ns_per_ms - 1); | |
| 1481 | testDurationCaseSigned("-999.999us", -(std.time.ns_per_ms - 1)); | |
| 1482 | testDurationCaseSigned("1ms", std.time.ns_per_ms + 1); | |
| 1483 | testDurationCaseSigned("-1ms", -(std.time.ns_per_ms + 1)); | |
| 1484 | testDurationCaseSigned("1.5ms", 3 * std.time.ns_per_ms / 2); | |
| 1485 | testDurationCaseSigned("-1.5ms", -(3 * std.time.ns_per_ms / 2)); | |
| 1486 | testDurationCaseSigned("1.11ms", 1110000); | |
| 1487 | testDurationCaseSigned("-1.11ms", -(1110000)); | |
| 1488 | testDurationCaseSigned("1.111ms", 1111000); | |
| 1489 | testDurationCaseSigned("-1.111ms", -(1111000)); | |
| 1490 | testDurationCaseSigned("1.111ms", 1111100); | |
| 1491 | testDurationCaseSigned("-1.111ms", -(1111100)); | |
| 1492 | testDurationCaseSigned("999.999ms", std.time.ns_per_s - 1); | |
| 1493 | testDurationCaseSigned("-999.999ms", -(std.time.ns_per_s - 1)); | |
| 1494 | testDurationCaseSigned("1s", std.time.ns_per_s); | |
| 1495 | testDurationCaseSigned("-1s", -(std.time.ns_per_s)); | |
| 1496 | testDurationCaseSigned("59.999s", std.time.ns_per_min - 1); | |
| 1497 | testDurationCaseSigned("-59.999s", -(std.time.ns_per_min - 1)); | |
| 1498 | testDurationCaseSigned("1m", std.time.ns_per_min); | |
| 1499 | testDurationCaseSigned("-1m", -(std.time.ns_per_min)); | |
| 1500 | testDurationCaseSigned("1h", std.time.ns_per_hour); | |
| 1501 | testDurationCaseSigned("-1h", -(std.time.ns_per_hour)); | |
| 1502 | testDurationCaseSigned("1d", std.time.ns_per_day); | |
| 1503 | testDurationCaseSigned("-1d", -(std.time.ns_per_day)); | |
| 1504 | testDurationCaseSigned("1w", std.time.ns_per_week); | |
| 1505 | testDurationCaseSigned("-1w", -(std.time.ns_per_week)); | |
| 1506 | testDurationCaseSigned("1y", 365 * std.time.ns_per_day); | |
| 1507 | testDurationCaseSigned("-1y", -(365 * std.time.ns_per_day)); | |
| 1508 | testDurationCaseSigned("1y52w23h59m59.999s", 730 * std.time.ns_per_day - 1); // 365d = 52w1d | |
| 1509 | testDurationCaseSigned("-1y52w23h59m59.999s", -(730 * std.time.ns_per_day - 1)); // 365d = 52w1d | |
| 1510 | testDurationCaseSigned("1y1h1.001s", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_s + std.time.ns_per_ms); | |
| 1511 | testDurationCaseSigned("-1y1h1.001s", -(365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_s + std.time.ns_per_ms)); | |
| 1512 | testDurationCaseSigned("1y1h1s", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_s + 999 * std.time.ns_per_us); | |
| 1513 | testDurationCaseSigned("-1y1h1s", -(365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_s + 999 * std.time.ns_per_us)); | |
| 1514 | testDurationCaseSigned("1y1h999.999us", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms - 1); | |
| 1515 | testDurationCaseSigned("-1y1h999.999us", -(365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms - 1)); | |
| 1516 | testDurationCaseSigned("1y1h1ms", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms); | |
| 1517 | testDurationCaseSigned("-1y1h1ms", -(365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms)); | |
| 1518 | testDurationCaseSigned("1y1h1ms", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms + 1); | |
| 1519 | testDurationCaseSigned("-1y1h1ms", -(365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms + 1)); | |
| 1520 | testDurationCaseSigned("1y1m999ns", 365 * std.time.ns_per_day + std.time.ns_per_min + 999); | |
| 1521 | testDurationCaseSigned("-1y1m999ns", -(365 * std.time.ns_per_day + std.time.ns_per_min + 999)); | |
| 1522 | testDurationCaseSigned("292y24w3d23h47m16.854s", std.math.maxInt(i64)); | |
| 1523 | testDurationCaseSigned("-292y24w3d23h47m16.854s", std.math.minInt(i64) + 1); | |
| 1524 | testDurationCaseSigned("-292y24w3d23h47m16.854s", std.math.minInt(i64)); | |
| 1525 | ||
| 1526 | testing.expectFmt("=======0ns", "{s:=>10}", .{0}); | |
| 1527 | testing.expectFmt("1ns=======", "{s:=<10}", .{1}); | |
| 1528 | testing.expectFmt("-1ns======", "{s:=<10}", .{-(1)}); | |
| 1529 | testing.expectFmt(" -999ns ", "{s:^10}", .{-(std.time.ns_per_us - 1)}); | |
| 1530 | } | |
| 1531 | ||
| 1532 | fn testDurationCase(expected: []const u8, input: u64) !void { | |
| 1533 | var buf: [24]u8 = undefined; | |
| 1534 | var w: Writer = .fixed(&buf); | |
| 1535 | try w.printDurationUnsigned(input); | |
| 1536 | try testing.expectEqualStrings(expected, w.buffered()); | |
| 1537 | } | |
| 1538 | ||
| 1539 | fn testDurationCaseSigned(expected: []const u8, input: i64) !void { | |
| 1540 | var buf: [24]u8 = undefined; | |
| 1541 | var w: Writer = .fixed(&buf); | |
| 1542 | try w.printDurationSigned(input); | |
| 1543 | try testing.expectEqualStrings(expected, w.buffered()); | |
| 1544 | } | |
| 1545 | ||
| 1546 | test printIntOptions { | |
| 1547 | try testPrintIntCase("-1", @as(i1, -1), 10, .lower, .{}); | |
| 1548 | ||
| 1549 | try testPrintIntCase("-101111000110000101001110", @as(i32, -12345678), 2, .lower, .{}); | |
| 1550 | try testPrintIntCase("-12345678", @as(i32, -12345678), 10, .lower, .{}); | |
| 1551 | try testPrintIntCase("-bc614e", @as(i32, -12345678), 16, .lower, .{}); | |
| 1552 | try testPrintIntCase("-BC614E", @as(i32, -12345678), 16, .upper, .{}); | |
| 1553 | ||
| 1554 | try testPrintIntCase("12345678", @as(u32, 12345678), 10, .upper, .{}); | |
| 1555 | ||
| 1556 | try testPrintIntCase(" 666", @as(u32, 666), 10, .lower, .{ .width = 6 }); | |
| 1557 | try testPrintIntCase(" 1234", @as(u32, 0x1234), 16, .lower, .{ .width = 6 }); | |
| 1558 | try testPrintIntCase("1234", @as(u32, 0x1234), 16, .lower, .{ .width = 1 }); | |
| 1559 | ||
| 1560 | try testPrintIntCase("+42", @as(i32, 42), 10, .lower, .{ .width = 3 }); | |
| 1561 | try testPrintIntCase("-42", @as(i32, -42), 10, .lower, .{ .width = 3 }); | |
| 1562 | } | |
| 1563 | ||
| 1564 | test "printInt with comptime_int" { | |
| 1565 | var buf: [20]u8 = undefined; | |
| 1566 | var w: Writer = .fixed(&buf); | |
| 1567 | try w.printInt(@as(comptime_int, 123456789123456789), "", .{}); | |
| 1568 | try std.testing.expectEqualStrings("123456789123456789", w.buffered()); | |
| 1569 | } | |
| 1570 | ||
| 1571 | test "printFloat with comptime_float" { | |
| 1572 | var buf: [20]u8 = undefined; | |
| 1573 | var w: Writer = .fixed(&buf); | |
| 1574 | try w.printFloat("", .{}, @as(comptime_float, 1.0)); | |
| 1575 | try std.testing.expectEqualStrings(w.buffered(), "1e0"); | |
| 1576 | try std.testing.expectFmt("1e0", "{}", .{1.0}); | |
| 1577 | } | |
| 1578 | ||
| 1579 | fn testPrintIntCase(expected: []const u8, value: anytype, base: u8, case: std.fmt.Case, options: std.fmt.Options) !void { | |
| 1580 | var buffer: [100]u8 = undefined; | |
| 1581 | var w: Writer = .fixed(&buffer); | |
| 1582 | w.printIntOptions(value, base, case, options); | |
| 1583 | try testing.expectEqualStrings(expected, w.buffered()); | |
| 1584 | } | |
| 1585 | ||
| 1586 | test printByteSize { | |
| 1587 | try testing.expectFmt("file size: 42B\n", "file size: {B}\n", .{42}); | |
| 1588 | try testing.expectFmt("file size: 42B\n", "file size: {Bi}\n", .{42}); | |
| 1589 | try testing.expectFmt("file size: 63MB\n", "file size: {B}\n", .{63 * 1000 * 1000}); | |
| 1590 | try testing.expectFmt("file size: 63MiB\n", "file size: {Bi}\n", .{63 * 1024 * 1024}); | |
| 1591 | try testing.expectFmt("file size: 42B\n", "file size: {B:.2}\n", .{42}); | |
| 1592 | try testing.expectFmt("file size: 42B\n", "file size: {B:>9.2}\n", .{42}); | |
| 1593 | try testing.expectFmt("file size: 66.06MB\n", "file size: {B:.2}\n", .{63 * 1024 * 1024}); | |
| 1594 | try testing.expectFmt("file size: 60.08MiB\n", "file size: {Bi:.2}\n", .{63 * 1000 * 1000}); | |
| 1595 | try testing.expectFmt("file size: =66.06MB=\n", "file size: {B:=^9.2}\n", .{63 * 1024 * 1024}); | |
| 1596 | try testing.expectFmt("file size: 66.06MB\n", "file size: {B: >9.2}\n", .{63 * 1024 * 1024}); | |
| 1597 | try testing.expectFmt("file size: 66.06MB \n", "file size: {B: <9.2}\n", .{63 * 1024 * 1024}); | |
| 1598 | try testing.expectFmt("file size: 0.01844674407370955ZB\n", "file size: {B}\n", .{std.math.maxInt(u64)}); | |
| 1599 | } | |
| 1600 | ||
| 1601 | test "bytes.hex" { | |
| 1602 | const some_bytes = "\xCA\xFE\xBA\xBE"; | |
| 1603 | try std.testing.expectFmt("lowercase: cafebabe\n", "lowercase: {x}\n", .{some_bytes}); | |
| 1604 | try std.testing.expectFmt("uppercase: CAFEBABE\n", "uppercase: {X}\n", .{some_bytes}); | |
| 1605 | try std.testing.expectFmt("uppercase: CAFE\n", "uppercase: {X}\n", .{some_bytes[0..2]}); | |
| 1606 | try std.testing.expectFmt("lowercase: babe\n", "lowercase: {x}\n", .{some_bytes[2..]}); | |
| 1607 | const bytes_with_zeros = "\x00\x0E\xBA\xBE"; | |
| 1608 | try std.testing.expectFmt("lowercase: 000ebabe\n", "lowercase: {x}\n", .{bytes_with_zeros}); | |
| 1609 | } | |
| 1610 | ||
| 1611 | test fixed { | |
| 1612 | { | |
| 1613 | var buf: [255]u8 = undefined; | |
| 1614 | var w: Writer = .fixed(&buf); | |
| 1615 | try w.print("{s}{s}!", .{ "Hello", "World" }); | |
| 1616 | try testing.expectEqualStrings("HelloWorld!", w.buffered()); | |
| 1617 | } | |
| 1618 | ||
| 1619 | comptime { | |
| 1620 | var buf: [255]u8 = undefined; | |
| 1621 | var w: Writer = .fixed(&buf); | |
| 1622 | try w.print("{s}{s}!", .{ "Hello", "World" }); | |
| 1623 | try testing.expectEqualStrings("HelloWorld!", w.buffered()); | |
| 1624 | } | |
| 1625 | } | |
| 1626 | ||
| 1627 | test "fixed output" { | |
| 1628 | var buffer: [10]u8 = undefined; | |
| 1629 | var w: Writer = .fixed(&buffer); | |
| 1630 | ||
| 1631 | try w.writeAll("Hello"); | |
| 1632 | try testing.expect(std.mem.eql(u8, w.buffered(), "Hello")); | |
| 1633 | ||
| 1634 | try w.writeAll("world"); | |
| 1635 | try testing.expect(std.mem.eql(u8, w.buffered(), "Helloworld")); | |
| 1636 | ||
| 1637 | try testing.expectError(error.WriteStreamEnd, w.writeAll("!")); | |
| 1638 | try testing.expect(std.mem.eql(u8, w.buffered(), "Helloworld")); | |
| 1639 | ||
| 1640 | w.reset(); | |
| 1641 | try testing.expect(w.buffered().len == 0); | |
| 1642 | ||
| 1643 | try testing.expectError(error.WriteStreamEnd, w.writeAll("Hello world!")); | |
| 1644 | try testing.expect(std.mem.eql(u8, w.buffered(), "Hello worl")); | |
| 1645 | ||
| 1646 | try w.seekTo((try w.getEndPos()) + 1); | |
| 1647 | try testing.expectError(error.WriteStreamEnd, w.writeAll("H")); | |
| 1648 | } | |
| 1649 | ||
| 1650 | pub fn failingDrain(w: *Writer, data: []const []const u8, splat: usize) Error!usize { | |
| 1651 | _ = w; | |
| 106 | 1652 | _ = data; |
| 107 | 1653 | _ = splat; |
| 108 | 1654 | return error.WriteFailed; |
| 109 | 1655 | } |
| 110 | 1656 | |
| 111 | pub fn failingWriteFile( | |
| 112 | context: ?*anyopaque, | |
| 113 | file_reader: *File.Reader, | |
| 114 | limit: Limit, | |
| 115 | headers_and_trailers: []const []const u8, | |
| 116 | headers_len: usize, | |
| 117 | ) FileError!usize { | |
| 118 | _ = context; | |
| 1657 | pub fn failingSendFile(w: *Writer, file_reader: *File.Reader, limit: Limit) FileError!usize { | |
| 1658 | _ = w; | |
| 119 | 1659 | _ = file_reader; |
| 120 | 1660 | _ = limit; |
| 121 | _ = headers_and_trailers; | |
| 122 | _ = headers_len; | |
| 123 | 1661 | return error.WriteFailed; |
| 124 | 1662 | } |
| 125 | 1663 | |
| 126 | pub const failing: Writer = .{ | |
| 127 | .context = undefined, | |
| 128 | .vtable = &.{ | |
| 129 | .writeSplat = failingWriteSplat, | |
| 130 | .writeFile = failingWriteFile, | |
| 131 | }, | |
| 132 | }; | |
| 133 | ||
| 134 | pub fn discardingWriteSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) Error!usize { | |
| 135 | _ = context; | |
| 136 | const headers = data[0 .. data.len - 1]; | |
| 137 | const pattern = data[headers.len..]; | |
| 1664 | pub fn discardingDrain(w: *Writer, data: []const []const u8, splat: usize) Error!usize { | |
| 1665 | const slice = data[0 .. data.len - 1]; | |
| 1666 | const pattern = data[slice.len..]; | |
| 138 | 1667 | var written: usize = pattern.len * splat; |
| 139 | for (headers) |bytes| written += bytes.len; | |
| 1668 | for (slice) |bytes| written += bytes.len; | |
| 1669 | w.end = 0; | |
| 140 | 1670 | return written; |
| 141 | 1671 | } |
| 142 | 1672 | |
| 143 | pub fn discardingWriteFile( | |
| 144 | context: ?*anyopaque, | |
| 145 | file_reader: *std.fs.File.Reader, | |
| 146 | limit: Limit, | |
| 147 | headers_and_trailers: []const []const u8, | |
| 148 | headers_len: usize, | |
| 149 | ) Writer.FileError!usize { | |
| 150 | _ = context; | |
| 151 | if (file_reader.getSize()) |size| { | |
| 152 | const remaining = size - file_reader.pos; | |
| 153 | const seek_amt = limit.minInt(remaining); | |
| 154 | // Error is observable on `file_reader` instance, and is safe to ignore | |
| 155 | // depending on the caller's needs. Caller can make that decision. | |
| 156 | file_reader.seekBy(@intCast(seek_amt)) catch {}; | |
| 157 | var n: usize = seek_amt; | |
| 158 | for (headers_and_trailers[0..headers_len]) |bytes| n += bytes.len; | |
| 159 | if (seek_amt == remaining) { | |
| 160 | // Since we made it all the way through the file, the trailers are | |
| 161 | // also included. | |
| 162 | for (headers_and_trailers[headers_len..]) |bytes| n += bytes.len; | |
| 1673 | pub fn discardingSendFile(w: *Writer, file_reader: *File.Reader, limit: Limit) FileError!usize { | |
| 1674 | if (File.Handle == void) return error.Unimplemented; | |
| 1675 | if (w.end != 0) { | |
| 1676 | if (@intFromEnum(limit) >= w.end) { | |
| 1677 | w.end = 0; | |
| 1678 | } else { | |
| 1679 | const remaining = w.buffer[@intFromEnum(limit)..w.end]; | |
| 1680 | @memmove(w.buffer[0..remaining.len], remaining); | |
| 1681 | w.end = remaining.len; | |
| 163 | 1682 | } |
| 1683 | return 0; | |
| 1684 | } | |
| 1685 | if (file_reader.getSize()) |size| { | |
| 1686 | const n = limit.minInt(size - file_reader.pos); | |
| 1687 | file_reader.seekBy(@intCast(n)) catch return error.Unimplemented; | |
| 1688 | w.end = 0; | |
| 164 | 1689 | return n; |
| 165 | 1690 | } else |_| { |
| 166 | 1691 | // Error is observable on `file_reader` instance, and it is better to |
| ... | ... | @@ -169,33 +1694,52 @@ pub fn discardingWriteFile( |
| 169 | 1694 | } |
| 170 | 1695 | } |
| 171 | 1696 | |
| 172 | pub const discarding: Writer = .{ | |
| 173 | .context = undefined, | |
| 174 | .vtable = &.{ | |
| 175 | .writeSplat = discardingWriteSplat, | |
| 176 | .writeFile = discardingWriteFile, | |
| 177 | }, | |
| 178 | }; | |
| 179 | ||
| 180 | 1697 | /// For use when the `Writer` implementation can cannot offer a more efficient |
| 181 | 1698 | /// implementation than a basic read/write loop on the file. |
| 182 | pub fn unimplementedWriteFile( | |
| 183 | context: ?*anyopaque, | |
| 184 | file_reader: *File.Reader, | |
| 185 | limit: Limit, | |
| 186 | headers_and_trailers: []const []const u8, | |
| 187 | headers_len: usize, | |
| 188 | ) FileError!usize { | |
| 189 | _ = context; | |
| 1699 | pub fn unimplementedSendFile(w: *Writer, file_reader: *File.Reader, limit: Limit) FileError!usize { | |
| 1700 | _ = w; | |
| 190 | 1701 | _ = file_reader; |
| 191 | 1702 | _ = limit; |
| 192 | _ = headers_and_trailers; | |
| 193 | _ = headers_len; | |
| 194 | 1703 | return error.Unimplemented; |
| 195 | 1704 | } |
| 196 | 1705 | |
| 1706 | /// When this function is called it usually means the buffer got full, so it's | |
| 1707 | /// time to return an error. However, we still need to make sure all of the | |
| 1708 | /// available buffer has been filled. Also, it may be called from `flush` in | |
| 1709 | /// which case it should return successfully. | |
| 1710 | fn fixedDrain(w: *Writer, data: []const []const u8, splat: usize) Error!usize { | |
| 1711 | for (data[0 .. data.len - 1]) |bytes| { | |
| 1712 | const dest = w.buffer[w.end..]; | |
| 1713 | const len = @min(bytes.len, dest.len); | |
| 1714 | @memcpy(dest[0..len], bytes[0..len]); | |
| 1715 | w.end += len; | |
| 1716 | if (bytes.len > dest.len) return error.WriteFailed; | |
| 1717 | } | |
| 1718 | const pattern = data[data.len - 1]; | |
| 1719 | const dest = w.buffer[w.end..]; | |
| 1720 | switch (pattern.len) { | |
| 1721 | 0 => return w.end, | |
| 1722 | 1 => { | |
| 1723 | assert(splat >= dest.len); | |
| 1724 | @memset(dest, pattern[0]); | |
| 1725 | w.end += dest.len; | |
| 1726 | return error.WriteFailed; | |
| 1727 | }, | |
| 1728 | else => { | |
| 1729 | for (0..splat) |i| { | |
| 1730 | const remaining = dest[i * pattern.len ..]; | |
| 1731 | const len = @min(pattern.len, remaining.len); | |
| 1732 | @memcpy(remaining[0..len], pattern[0..len]); | |
| 1733 | w.end += len; | |
| 1734 | if (pattern.len > remaining.len) return error.WriteFailed; | |
| 1735 | } | |
| 1736 | unreachable; | |
| 1737 | }, | |
| 1738 | } | |
| 1739 | } | |
| 1740 | ||
| 197 | 1741 | /// Provides a `Writer` implementation based on calling `Hasher.update`, sending |
| 198 | /// all data also to an underlying `std.io.BufferedWriter`. | |
| 1742 | /// all data also to an underlying `Writer`. | |
| 199 | 1743 | /// |
| 200 | 1744 | /// When using this, the underlying writer is best unbuffered because all |
| 201 | 1745 | /// writes are passed on directly to it. |
| ... | ... | @@ -206,27 +1750,35 @@ pub fn unimplementedWriteFile( |
| 206 | 1750 | /// details. |
| 207 | 1751 | pub fn Hashed(comptime Hasher: type) type { |
| 208 | 1752 | return struct { |
| 209 | out: *std.io.BufferedWriter, | |
| 1753 | out: *Writer, | |
| 210 | 1754 | hasher: Hasher, |
| 1755 | interface: Writer, | |
| 211 | 1756 | |
| 212 | pub fn writable(this: *@This(), buffer: []u8) std.io.BufferedWriter { | |
| 1757 | pub fn init(out: *Writer) @This() { | |
| 213 | 1758 | return .{ |
| 214 | .unbuffered_writer = .{ | |
| 215 | .context = this, | |
| 216 | .vtable = &.{ | |
| 217 | .writeSplat = @This().writeSplat, | |
| 218 | .writeFile = Writer.unimplementedWriteFile, | |
| 219 | }, | |
| 1759 | .out = out, | |
| 1760 | .hasher = .{}, | |
| 1761 | .interface = .{ | |
| 1762 | .context = undefined, | |
| 1763 | .vtable = &.{@This().drain}, | |
| 220 | 1764 | }, |
| 221 | .buffer = buffer, | |
| 222 | 1765 | }; |
| 223 | 1766 | } |
| 224 | 1767 | |
| 225 | fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) Writer.Error!usize { | |
| 226 | const this: *@This() = @alignCast(@ptrCast(context)); | |
| 227 | const n = try this.out.writeSplat(data, splat); | |
| 228 | const short_data = data[0 .. data.len - @intFromBool(splat == 0)]; | |
| 1768 | fn drain(w: *Writer, data: []const []const u8, splat: usize) Error!usize { | |
| 1769 | const this: *@This() = @alignCast(@fieldParentPtr("interface", w)); | |
| 1770 | const aux_n = try this.out.writeSplatAux(w.buffered(), data, splat); | |
| 1771 | if (aux_n <= w.end) { | |
| 1772 | this.hasher.update(w.buffer[0..aux_n]); | |
| 1773 | const remaining = w.buffer[aux_n..w.end]; | |
| 1774 | @memmove(w.buffer[0..remaining.len], remaining); | |
| 1775 | w.end = remaining.len; | |
| 1776 | return 0; | |
| 1777 | } | |
| 1778 | const n = aux_n - w.end; | |
| 1779 | w.end = 0; | |
| 229 | 1780 | var remaining: usize = n; |
| 1781 | const short_data = data[0 .. data.len - @intFromBool(splat == 0)]; | |
| 230 | 1782 | for (short_data) |slice| { |
| 231 | 1783 | if (remaining < slice.len) { |
| 232 | 1784 | this.hasher.update(slice[0..remaining]); |
| ... | ... | @@ -243,31 +1795,185 @@ pub fn Hashed(comptime Hasher: type) type { |
| 243 | 1795 | }, |
| 244 | 1796 | else => splat - 1, |
| 245 | 1797 | }; |
| 246 | const last = data[data.len - 1]; | |
| 247 | assert(remaining == remaining_splat * last.len); | |
| 248 | switch (last.len) { | |
| 1798 | const pattern = data[data.len - 1]; | |
| 1799 | assert(remaining == remaining_splat * pattern.len); | |
| 1800 | switch (pattern.len) { | |
| 249 | 1801 | 0 => { |
| 250 | 1802 | assert(remaining == 0); |
| 251 | return n; | |
| 252 | 1803 | }, |
| 253 | 1804 | 1 => { |
| 254 | 1805 | var buffer: [64]u8 = undefined; |
| 255 | @memset(&buffer, last[0]); | |
| 1806 | @memset(&buffer, pattern[0]); | |
| 256 | 1807 | while (remaining > 0) { |
| 257 | 1808 | const update_len = @min(remaining, buffer.len); |
| 258 | 1809 | this.hasher.update(buffer[0..update_len]); |
| 259 | 1810 | remaining -= update_len; |
| 260 | 1811 | } |
| 261 | return n; | |
| 262 | 1812 | }, |
| 263 | else => {}, | |
| 264 | } | |
| 265 | while (remaining > 0) { | |
| 266 | const update_len = @min(remaining, last.len); | |
| 267 | this.hasher.update(last[0..update_len]); | |
| 268 | remaining -= update_len; | |
| 1813 | else => { | |
| 1814 | while (remaining > 0) { | |
| 1815 | const update_len = @min(remaining, pattern.len); | |
| 1816 | this.hasher.update(pattern[0..update_len]); | |
| 1817 | remaining -= update_len; | |
| 1818 | } | |
| 1819 | }, | |
| 269 | 1820 | } |
| 270 | 1821 | return n; |
| 271 | 1822 | } |
| 272 | 1823 | }; |
| 273 | 1824 | } |
| 1825 | ||
| 1826 | /// Maintains `Writer` state such that it writes to the unused capacity of an | |
| 1827 | /// array list, filling it up completely before making a call through the | |
| 1828 | /// vtable, causing a resize. Consequently, the same, optimized, non-generic | |
| 1829 | /// machine code that uses `std.io.Reader`, such as formatted printing, takes | |
| 1830 | /// the hot paths when using this API. | |
| 1831 | /// | |
| 1832 | /// When using this API, it is not necessary to call `flush`. | |
| 1833 | pub const Allocating = struct { | |
| 1834 | allocator: Allocator, | |
| 1835 | interface: Writer, | |
| 1836 | ||
| 1837 | pub fn init(allocator: Allocator) Allocating { | |
| 1838 | return .{ | |
| 1839 | .allocator = allocator, | |
| 1840 | .interface = init_interface, | |
| 1841 | .buffer = &.{}, | |
| 1842 | }; | |
| 1843 | } | |
| 1844 | ||
| 1845 | pub fn initCapacity(allocator: Allocator, capacity: usize) error{OutOfMemory}!Allocating { | |
| 1846 | return .{ | |
| 1847 | .allocator = allocator, | |
| 1848 | .interface = init_interface, | |
| 1849 | .buffer = try allocator.alloc(u8, capacity), | |
| 1850 | }; | |
| 1851 | } | |
| 1852 | ||
| 1853 | pub fn initOwnedSlice(allocator: Allocator, slice: []u8) Allocating { | |
| 1854 | return .{ | |
| 1855 | .allocator = allocator, | |
| 1856 | .interface = init_interface, | |
| 1857 | .buffer = slice, | |
| 1858 | }; | |
| 1859 | } | |
| 1860 | ||
| 1861 | /// Replaces `array_list` with empty, taking ownership of the memory. | |
| 1862 | pub fn fromArrayList(allocator: Allocator, array_list: *std.ArrayListUnmanaged(u8)) Allocating { | |
| 1863 | defer array_list.* = .empty; | |
| 1864 | return .{ | |
| 1865 | .allocator = allocator, | |
| 1866 | .interface = init_interface, | |
| 1867 | .buffer = array_list.allocatedSlice(), | |
| 1868 | .end = array_list.items.len, | |
| 1869 | }; | |
| 1870 | } | |
| 1871 | ||
| 1872 | const init_interface: Writer = .{ | |
| 1873 | .interface = .{ | |
| 1874 | .context = undefined, | |
| 1875 | .vtable = &.{ | |
| 1876 | .drain = Allocating.drain, | |
| 1877 | .sendFile = Allocating.sendFile, | |
| 1878 | }, | |
| 1879 | }, | |
| 1880 | }; | |
| 1881 | ||
| 1882 | pub fn deinit(a: *Allocating) void { | |
| 1883 | a.allocator.free(a.buffer); | |
| 1884 | a.* = undefined; | |
| 1885 | } | |
| 1886 | ||
| 1887 | /// Returns an array list that takes ownership of the allocated memory. | |
| 1888 | /// Resets the `Allocating` to an empty state. | |
| 1889 | pub fn toArrayList(a: *Allocating) std.ArrayListUnmanaged(u8) { | |
| 1890 | const w = &a.interface; | |
| 1891 | const result: std.ArrayListUnmanaged(u8) = .{ | |
| 1892 | .items = w.buffer[0..w.end], | |
| 1893 | .capacity = w.buffer.len, | |
| 1894 | }; | |
| 1895 | w.buffer = &.{}; | |
| 1896 | w.end = 0; | |
| 1897 | return result; | |
| 1898 | } | |
| 1899 | ||
| 1900 | pub fn toOwnedSlice(a: *Allocating) error{OutOfMemory}![]u8 { | |
| 1901 | var list = a.toArrayList(); | |
| 1902 | return list.toOwnedSlice(a.allocator); | |
| 1903 | } | |
| 1904 | ||
| 1905 | pub fn toOwnedSliceSentinel(a: *Allocating, comptime sentinel: u8) error{OutOfMemory}![:sentinel]u8 { | |
| 1906 | const gpa = a.allocator; | |
| 1907 | var list = toArrayList(a); | |
| 1908 | return list.toOwnedSliceSentinel(gpa, sentinel); | |
| 1909 | } | |
| 1910 | ||
| 1911 | pub fn getWritten(a: *Allocating) []u8 { | |
| 1912 | return a.interface.buffered(); | |
| 1913 | } | |
| 1914 | ||
| 1915 | pub fn shrinkRetainingCapacity(a: *Allocating, new_len: usize) void { | |
| 1916 | const shrink_by = a.interface.end - new_len; | |
| 1917 | a.interface.end = new_len; | |
| 1918 | a.interface.count -= shrink_by; | |
| 1919 | } | |
| 1920 | ||
| 1921 | pub fn clearRetainingCapacity(a: *Allocating) void { | |
| 1922 | a.shrinkRetainingCapacity(0); | |
| 1923 | } | |
| 1924 | ||
| 1925 | fn drain(w: *Writer, data: []const []const u8, splat: usize) Error!usize { | |
| 1926 | const a: *Allocating = @fieldParentPtr("interface", w); | |
| 1927 | const gpa = a.allocator; | |
| 1928 | const pattern = data[data.len - 1]; | |
| 1929 | const splat_len = pattern.len * splat; | |
| 1930 | var list = a.toArrayList(); | |
| 1931 | defer setArrayList(a, list); | |
| 1932 | const start_len = list.items.len; | |
| 1933 | for (data[0 .. data.len - 1]) |bytes| { | |
| 1934 | list.ensureUnusedCapacity(gpa, bytes.len + splat_len) catch return error.WriteFailed; | |
| 1935 | list.appendSliceAssumeCapacity(bytes); | |
| 1936 | } | |
| 1937 | switch (pattern.len) { | |
| 1938 | 0 => {}, | |
| 1939 | 1 => list.appendNTimesAssumeCapacity(pattern[0], splat), | |
| 1940 | else => for (0..splat) |_| list.appendSliceAssumeCapacity(pattern), | |
| 1941 | } | |
| 1942 | return list.items.len - start_len; | |
| 1943 | } | |
| 1944 | ||
| 1945 | fn sendFile(w: *Writer, file_reader: *File.Reader, limit: std.io.Limit) FileError!usize { | |
| 1946 | if (File.Handle == void) return error.Unimplemented; | |
| 1947 | const a: *Allocating = @fieldParentPtr("interface", w); | |
| 1948 | const gpa = a.allocator; | |
| 1949 | var list = a.toArrayList(); | |
| 1950 | defer setArrayList(a, list); | |
| 1951 | const pos = file_reader.pos; | |
| 1952 | const additional = if (file_reader.getSize()) |size| size - pos else |_| std.atomic.cache_line; | |
| 1953 | list.ensureUnusedCapacity(gpa, limit.minInt(additional)) catch return error.WriteFailed; | |
| 1954 | const dest = limit.slice(list.unusedCapacitySlice()); | |
| 1955 | const n = file_reader.read(dest) catch |err| switch (err) { | |
| 1956 | error.ReadFailed => return error.ReadFailed, | |
| 1957 | error.EndOfStream => 0, | |
| 1958 | }; | |
| 1959 | list.items.len += n; | |
| 1960 | return n; | |
| 1961 | } | |
| 1962 | ||
| 1963 | fn setArrayList(a: *Allocating, list: std.ArrayListUnmanaged(u8)) void { | |
| 1964 | a.buffer = list.allocatedSlice(); | |
| 1965 | a.end = list.items.len; | |
| 1966 | } | |
| 1967 | ||
| 1968 | test Allocating { | |
| 1969 | var a: Allocating = .init(std.testing.allocator); | |
| 1970 | defer a.deinit(); | |
| 1971 | const w = &a.interface; | |
| 1972 | ||
| 1973 | const x: i32 = 42; | |
| 1974 | const y: i32 = 1234; | |
| 1975 | try w.print("x: {}\ny: {}\n", .{ x, y }); | |
| 1976 | ||
| 1977 | try testing.expectEqualSlices(u8, "x: 42\ny: 1234\n", a.getWritten()); | |
| 1978 | } | |
| 1979 | }; |
lib/std/io/tty.zig+2-2| ... | ... | @@ -73,7 +73,7 @@ pub const Config = union(enum) { |
| 73 | 73 | |
| 74 | 74 | pub const SetColorError = std.os.windows.SetConsoleTextAttributeError || std.io.Writer.Error; |
| 75 | 75 | |
| 76 | pub fn setColor(conf: Config, bw: *std.io.BufferedWriter, color: Color) SetColorError!void { | |
| 76 | pub fn setColor(conf: Config, w: *std.io.Writer, color: Color) SetColorError!void { | |
| 77 | 77 | nosuspend switch (conf) { |
| 78 | 78 | .no_color => return, |
| 79 | 79 | .escape_codes => { |
| ... | ... | @@ -98,7 +98,7 @@ pub const Config = union(enum) { |
| 98 | 98 | .dim => "\x1b[2m", |
| 99 | 99 | .reset => "\x1b[0m", |
| 100 | 100 | }; |
| 101 | try bw.writeAll(color_string); | |
| 101 | try w.writeAll(color_string); | |
| 102 | 102 | }, |
| 103 | 103 | .windows_api => |ctx| if (native_os == .windows) { |
| 104 | 104 | const attributes = switch (color) { |
lib/std/json.zig+2-2| ... | ... | @@ -127,9 +127,9 @@ pub fn Formatter(comptime T: type) type { |
| 127 | 127 | self: @This(), |
| 128 | 128 | comptime fmt_spec: []const u8, |
| 129 | 129 | options: std.fmt.FormatOptions, |
| 130 | writer: *std.io.BufferedWriter, | |
| 130 | writer: *std.io.Writer, | |
| 131 | 131 | ) !void { |
| 132 | _ = fmt_spec; | |
| 132 | comptime std.debug.assert(fmt_spec.len == 0); | |
| 133 | 133 | _ = options; |
| 134 | 134 | try Stringify.value(self.value, self.options, writer); |
| 135 | 135 | } |
lib/std/json/Stringify.zig+13-16| ... | ... | @@ -23,13 +23,14 @@ const Allocator = std.mem.Allocator; |
| 23 | 23 | const ArrayList = std.ArrayList; |
| 24 | 24 | const BitStack = std.BitStack; |
| 25 | 25 | const Stringify = @This(); |
| 26 | const Writer = std.io.Writer; | |
| 26 | 27 | |
| 27 | 28 | const IndentationMode = enum(u1) { |
| 28 | 29 | object = 0, |
| 29 | 30 | array = 1, |
| 30 | 31 | }; |
| 31 | 32 | |
| 32 | writer: *std.io.BufferedWriter, | |
| 33 | writer: *Writer, | |
| 33 | 34 | options: Options = .{}, |
| 34 | 35 | indent_level: usize = 0, |
| 35 | 36 | next_punctuation: enum { |
| ... | ... | @@ -77,7 +78,7 @@ const safety_checks: @TypeOf(safety_checks_hint) = if (build_mode_has_safety) |
| 77 | 78 | else |
| 78 | 79 | .assumed_correct; |
| 79 | 80 | |
| 80 | pub const Error = std.io.Writer.Error; | |
| 81 | pub const Error = Writer.Error; | |
| 81 | 82 | |
| 82 | 83 | pub fn beginArray(self: *Stringify) Error!void { |
| 83 | 84 | if (build_mode_has_safety) assert(self.raw_streaming_mode == .none); |
| ... | ... | @@ -224,8 +225,7 @@ pub fn print(self: *Stringify, comptime fmt: []const u8, args: anytype) Error!vo |
| 224 | 225 | |
| 225 | 226 | test print { |
| 226 | 227 | var out_buf: [1024]u8 = undefined; |
| 227 | var out: std.io.BufferedWriter = undefined; | |
| 228 | out.initFixed(&out_buf); | |
| 228 | var out: Writer = .fixed(&out_buf); | |
| 229 | 229 | |
| 230 | 230 | var w: Stringify = .{ .writer = &out, .options = .{ .whitespace = .indent_2 } }; |
| 231 | 231 | |
| ... | ... | @@ -567,10 +567,10 @@ pub const Options = struct { |
| 567 | 567 | emit_nonportable_numbers_as_strings: bool = false, |
| 568 | 568 | }; |
| 569 | 569 | |
| 570 | /// Writes the given value to the `std.io.Writer` writer. | |
| 570 | /// Writes the given value to the `Writer` writer. | |
| 571 | 571 | /// See `Stringify` for how the given value is serialized into JSON. |
| 572 | 572 | /// The maximum nesting depth of the output JSON document is 256. |
| 573 | pub fn value(v: anytype, options: Options, writer: *std.io.BufferedWriter) Error!void { | |
| 573 | pub fn value(v: anytype, options: Options, writer: *Writer) Error!void { | |
| 574 | 574 | var s: Stringify = .{ .writer = writer, .options = options }; |
| 575 | 575 | try s.write(v); |
| 576 | 576 | } |
| ... | ... | @@ -634,7 +634,7 @@ test valueAlloc { |
| 634 | 634 | try std.testing.expectEqualStrings(expected, actual); |
| 635 | 635 | } |
| 636 | 636 | |
| 637 | fn outputUnicodeEscape(codepoint: u21, bw: *std.io.BufferedWriter) Error!void { | |
| 637 | fn outputUnicodeEscape(codepoint: u21, bw: *Writer) Error!void { | |
| 638 | 638 | if (codepoint <= 0xFFFF) { |
| 639 | 639 | // If the character is in the Basic Multilingual Plane (U+0000 through U+FFFF), |
| 640 | 640 | // then it may be represented as a six-character sequence: a reverse solidus, followed |
| ... | ... | @@ -654,7 +654,7 @@ fn outputUnicodeEscape(codepoint: u21, bw: *std.io.BufferedWriter) Error!void { |
| 654 | 654 | } |
| 655 | 655 | } |
| 656 | 656 | |
| 657 | fn outputSpecialEscape(c: u8, writer: *std.io.BufferedWriter) Error!void { | |
| 657 | fn outputSpecialEscape(c: u8, writer: *Writer) Error!void { | |
| 658 | 658 | switch (c) { |
| 659 | 659 | '\\' => try writer.writeAll("\\\\"), |
| 660 | 660 | '\"' => try writer.writeAll("\\\""), |
| ... | ... | @@ -668,14 +668,14 @@ fn outputSpecialEscape(c: u8, writer: *std.io.BufferedWriter) Error!void { |
| 668 | 668 | } |
| 669 | 669 | |
| 670 | 670 | /// Write `string` to `writer` as a JSON encoded string. |
| 671 | pub fn encodeJsonString(string: []const u8, options: Options, writer: *std.io.BufferedWriter) Error!void { | |
| 671 | pub fn encodeJsonString(string: []const u8, options: Options, writer: *Writer) Error!void { | |
| 672 | 672 | try writer.writeByte('\"'); |
| 673 | 673 | try encodeJsonStringChars(string, options, writer); |
| 674 | 674 | try writer.writeByte('\"'); |
| 675 | 675 | } |
| 676 | 676 | |
| 677 | 677 | /// Write `chars` to `writer` as JSON encoded string characters. |
| 678 | pub fn encodeJsonStringChars(chars: []const u8, options: Options, writer: *std.io.BufferedWriter) Error!void { | |
| 678 | pub fn encodeJsonStringChars(chars: []const u8, options: Options, writer: *Writer) Error!void { | |
| 679 | 679 | var write_cursor: usize = 0; |
| 680 | 680 | var i: usize = 0; |
| 681 | 681 | if (options.escape_unicode) { |
| ... | ... | @@ -718,8 +718,7 @@ pub fn encodeJsonStringChars(chars: []const u8, options: Options, writer: *std.i |
| 718 | 718 | |
| 719 | 719 | test "json write stream" { |
| 720 | 720 | var out_buf: [1024]u8 = undefined; |
| 721 | var out: std.io.BufferedWriter = undefined; | |
| 722 | out.initFixed(&out_buf); | |
| 721 | var out: Writer = .fixed(&out_buf); | |
| 723 | 722 | var w: Stringify = .{ .writer = &out, .options = .{ .whitespace = .indent_2 } }; |
| 724 | 723 | try testBasicWriteStream(&w); |
| 725 | 724 | } |
| ... | ... | @@ -971,16 +970,14 @@ test "stringify struct with custom stringifier" { |
| 971 | 970 | |
| 972 | 971 | fn testStringify(expected: []const u8, v: anytype, options: Options) !void { |
| 973 | 972 | var buffer: [4096]u8 = undefined; |
| 974 | var bw: std.io.BufferedWriter = undefined; | |
| 975 | bw.initFixed(&buffer); | |
| 973 | var bw: Writer = .fixed(&buffer); | |
| 976 | 974 | try value(v, options, &bw); |
| 977 | 975 | try std.testing.expectEqualStrings(expected, bw.getWritten()); |
| 978 | 976 | } |
| 979 | 977 | |
| 980 | 978 | test "raw streaming" { |
| 981 | 979 | var out_buf: [1024]u8 = undefined; |
| 982 | var out: std.io.BufferedWriter = undefined; | |
| 983 | out.initFixed(&out_buf); | |
| 980 | var out: Writer = .fixed(&out_buf); | |
| 984 | 981 | |
| 985 | 982 | var w: Stringify = .{ .writer = &out, .options = .{ .whitespace = .indent_2 } }; |
| 986 | 983 | try w.beginObject(); |
lib/std/json/dynamic_test.zig+3-4| ... | ... | @@ -4,6 +4,7 @@ const mem = std.mem; |
| 4 | 4 | const testing = std.testing; |
| 5 | 5 | const ArenaAllocator = std.heap.ArenaAllocator; |
| 6 | 6 | const Allocator = std.mem.Allocator; |
| 7 | const Writer = std.io.Writer; | |
| 7 | 8 | |
| 8 | 9 | const ObjectMap = @import("dynamic.zig").ObjectMap; |
| 9 | 10 | const Array = @import("dynamic.zig").Array; |
| ... | ... | @@ -73,8 +74,7 @@ test "json.parser.dynamic" { |
| 73 | 74 | |
| 74 | 75 | test "write json then parse it" { |
| 75 | 76 | var out_buffer: [1000]u8 = undefined; |
| 76 | var fixed_writer: std.io.BufferedWriter = undefined; | |
| 77 | fixed_writer.initFixed(&out_buffer); | |
| 77 | var fixed_writer: Writer = .fixed(&out_buffer); | |
| 78 | 78 | var jw: json.Stringify = .{ .writer = &fixed_writer, .options = .{} }; |
| 79 | 79 | |
| 80 | 80 | try jw.beginObject(); |
| ... | ... | @@ -240,8 +240,7 @@ test "Value.jsonStringify" { |
| 240 | 240 | .{ .object = obj }, |
| 241 | 241 | }; |
| 242 | 242 | var buffer: [0x1000]u8 = undefined; |
| 243 | var fixed_writer: std.io.BufferedWriter = undefined; | |
| 244 | fixed_writer.initFixed(&buffer); | |
| 243 | var fixed_writer: Writer = .fixed(&buffer); | |
| 245 | 244 | |
| 246 | 245 | var jw: json.Stringify = .{ .writer = &fixed_writer, .options = .{ .whitespace = .indent_1 } }; |
| 247 | 246 | try jw.write(array); |
lib/std/leb128.zig+3-3| ... | ... | @@ -1,6 +1,7 @@ |
| 1 | 1 | const builtin = @import("builtin"); |
| 2 | 2 | const std = @import("std"); |
| 3 | 3 | const testing = std.testing; |
| 4 | const Writer = std.io.Writer; | |
| 4 | 5 | |
| 5 | 6 | /// This is an "advanced" function. It allows one to use a fixed amount of memory to store a |
| 6 | 7 | /// ULEB128. This defeats the entire purpose of using this data encoding; it will no longer use |
| ... | ... | @@ -241,7 +242,7 @@ fn test_write_leb128(value: anytype) !void { |
| 241 | 242 | const signedness = @typeInfo(T).int.signedness; |
| 242 | 243 | const t_signed = signedness == .signed; |
| 243 | 244 | |
| 244 | const writeStream = if (t_signed) std.io.BufferedWriter.writeIleb128 else std.io.BufferedWriter.writeUleb128; | |
| 245 | const writeStream = if (t_signed) Writer.writeIleb128 else Writer.writeUleb128; | |
| 245 | 246 | const readStream = if (t_signed) std.io.Reader.readIleb128 else std.io.Reader.readUleb128; |
| 246 | 247 | |
| 247 | 248 | // decode to a larger bit size too, to ensure sign extension |
| ... | ... | @@ -261,8 +262,7 @@ fn test_write_leb128(value: anytype) !void { |
| 261 | 262 | const max_groups = if (@typeInfo(T).int.bits == 0) 1 else (@typeInfo(T).int.bits + 6) / 7; |
| 262 | 263 | |
| 263 | 264 | var buf: [max_groups]u8 = undefined; |
| 264 | var bw: std.io.BufferedWriter = undefined; | |
| 265 | bw.initFixed(&buf); | |
| 265 | var bw: Writer = .fixed(&buf); | |
| 266 | 266 | |
| 267 | 267 | // stream write |
| 268 | 268 | try testing.expect((try writeStream(&bw, value)) == bytes_needed); |
lib/std/math/big/int.zig+1-1| ... | ... | @@ -2322,7 +2322,7 @@ pub const Const = struct { |
| 2322 | 2322 | /// this function will fail to print the string, printing "(BigInt)" instead of a number. |
| 2323 | 2323 | /// This is because the rendering algorithm requires reversing a string, which requires O(N) memory. |
| 2324 | 2324 | /// See `toString` and `toStringAlloc` for a way to print big integers without failure. |
| 2325 | pub fn format(self: Const, bw: *std.io.BufferedWriter, comptime fmt: []const u8) !void { | |
| 2325 | pub fn format(self: Const, bw: *std.io.Writer, comptime fmt: []const u8) !void { | |
| 2326 | 2326 | comptime var base = 10; |
| 2327 | 2327 | comptime var case: std.fmt.Case = .lower; |
| 2328 | 2328 |
lib/std/net.zig+1-1| ... | ... | @@ -1915,7 +1915,7 @@ pub const Stream = struct { |
| 1915 | 1915 | |
| 1916 | 1916 | fn read( |
| 1917 | 1917 | context: ?*anyopaque, |
| 1918 | bw: *std.io.BufferedWriter, | |
| 1918 | bw: *std.io.Writer, | |
| 1919 | 1919 | limit: std.io.Limit, |
| 1920 | 1920 | ) std.io.Reader.Error!usize { |
| 1921 | 1921 | const buf = limit.slice(try bw.writableSliceGreedy(1)); |
lib/std/tar.zig+11-19| ... | ... | @@ -358,7 +358,7 @@ pub const Iterator = struct { |
| 358 | 358 | }; |
| 359 | 359 | } |
| 360 | 360 | |
| 361 | fn read(context: ?*anyopaque, bw: *std.io.BufferedWriter, limit: std.io.Limit) std.io.Reader.StreamError!usize { | |
| 361 | fn read(context: ?*anyopaque, bw: *std.io.Writer, limit: std.io.Limit) std.io.Reader.StreamError!usize { | |
| 362 | 362 | const file: *File = @ptrCast(@alignCast(context)); |
| 363 | 363 | if (file.unread_bytes.* == 0) return error.EndOfStream; |
| 364 | 364 | const n = try file.parent_reader.read(bw, limit.min(.limited(file.unread_bytes.*))); |
| ... | ... | @@ -381,7 +381,7 @@ pub const Iterator = struct { |
| 381 | 381 | return n; |
| 382 | 382 | } |
| 383 | 383 | |
| 384 | pub fn readRemaining(file: *File, out: *std.io.BufferedWriter) std.io.Reader.StreamRemainingError!void { | |
| 384 | pub fn readRemaining(file: *File, out: *std.io.Writer) std.io.Reader.StreamRemainingError!void { | |
| 385 | 385 | return file.reader().readRemaining(out); |
| 386 | 386 | } |
| 387 | 387 | }; |
| ... | ... | @@ -818,8 +818,7 @@ test PaxIterator { |
| 818 | 818 | var buffer: [1024]u8 = undefined; |
| 819 | 819 | |
| 820 | 820 | outer: for (cases) |case| { |
| 821 | var br: std.io.Reader = undefined; | |
| 822 | br.initFixed(case.data); | |
| 821 | var br: std.io.Reader = .fixed(case.data); | |
| 823 | 822 | var iter: PaxIterator = .init(&br, case.data.len); |
| 824 | 823 | |
| 825 | 824 | var i: usize = 0; |
| ... | ... | @@ -955,8 +954,7 @@ test Iterator { |
| 955 | 954 | // example/empty/ |
| 956 | 955 | |
| 957 | 956 | const data = @embedFile("tar/testdata/example.tar"); |
| 958 | var br: std.io.Reader = undefined; | |
| 959 | br.initFixed(data); | |
| 957 | var br: std.io.Reader = .fixed(data); | |
| 960 | 958 | |
| 961 | 959 | // User provided buffers to the iterator |
| 962 | 960 | var file_name_buffer: [std.fs.max_path_bytes]u8 = undefined; |
| ... | ... | @@ -1015,8 +1013,7 @@ test pipeToFileSystem { |
| 1015 | 1013 | // example/empty/ |
| 1016 | 1014 | |
| 1017 | 1015 | const data = @embedFile("tar/testdata/example.tar"); |
| 1018 | var br: std.io.Reader = undefined; | |
| 1019 | br.initFixed(data); | |
| 1016 | var br: std.io.Reader = .fixed(data); | |
| 1020 | 1017 | |
| 1021 | 1018 | var tmp = testing.tmpDir(.{ .no_follow = true }); |
| 1022 | 1019 | defer tmp.cleanup(); |
| ... | ... | @@ -1047,8 +1044,7 @@ test pipeToFileSystem { |
| 1047 | 1044 | |
| 1048 | 1045 | test "pipeToFileSystem root_dir" { |
| 1049 | 1046 | const data = @embedFile("tar/testdata/example.tar"); |
| 1050 | var br: std.io.Reader = undefined; | |
| 1051 | br.initFixed(data); | |
| 1047 | var br: std.io.Reader = .fixed(data); | |
| 1052 | 1048 | |
| 1053 | 1049 | // with strip_components = 1 |
| 1054 | 1050 | { |
| ... | ... | @@ -1073,7 +1069,7 @@ test "pipeToFileSystem root_dir" { |
| 1073 | 1069 | |
| 1074 | 1070 | // with strip_components = 0 |
| 1075 | 1071 | { |
| 1076 | br.initFixed(data); | |
| 1072 | br = .fixed(data); | |
| 1077 | 1073 | var tmp = testing.tmpDir(.{ .no_follow = true }); |
| 1078 | 1074 | defer tmp.cleanup(); |
| 1079 | 1075 | var diagnostics: Diagnostics = .{ .allocator = testing.allocator }; |
| ... | ... | @@ -1096,8 +1092,7 @@ test "pipeToFileSystem root_dir" { |
| 1096 | 1092 | |
| 1097 | 1093 | test "findRoot with single file archive" { |
| 1098 | 1094 | const data = @embedFile("tar/testdata/22752.tar"); |
| 1099 | var br: std.io.Reader = undefined; | |
| 1100 | br.initFixed(data); | |
| 1095 | var br: std.io.Reader = .fixed(data); | |
| 1101 | 1096 | |
| 1102 | 1097 | var tmp = testing.tmpDir(.{}); |
| 1103 | 1098 | defer tmp.cleanup(); |
| ... | ... | @@ -1111,8 +1106,7 @@ test "findRoot with single file archive" { |
| 1111 | 1106 | |
| 1112 | 1107 | test "findRoot without explicit root dir" { |
| 1113 | 1108 | const data = @embedFile("tar/testdata/19820.tar"); |
| 1114 | var br: std.io.Reader = undefined; | |
| 1115 | br.initFixed(data); | |
| 1109 | var br: std.io.Reader = .fixed(data); | |
| 1116 | 1110 | |
| 1117 | 1111 | var tmp = testing.tmpDir(.{}); |
| 1118 | 1112 | defer tmp.cleanup(); |
| ... | ... | @@ -1126,8 +1120,7 @@ test "findRoot without explicit root dir" { |
| 1126 | 1120 | |
| 1127 | 1121 | test "pipeToFileSystem strip_components" { |
| 1128 | 1122 | const data = @embedFile("tar/testdata/example.tar"); |
| 1129 | var br: std.io.Reader = undefined; | |
| 1130 | br.initFixed(data); | |
| 1123 | var br: std.io.Reader = .fixed(data); | |
| 1131 | 1124 | |
| 1132 | 1125 | var tmp = testing.tmpDir(.{ .no_follow = true }); |
| 1133 | 1126 | defer tmp.cleanup(); |
| ... | ... | @@ -1188,8 +1181,7 @@ test "executable bit" { |
| 1188 | 1181 | const data = @embedFile("tar/testdata/example.tar"); |
| 1189 | 1182 | |
| 1190 | 1183 | for ([_]PipeOptions.ModeMode{ .ignore, .executable_bit_only }) |opt| { |
| 1191 | var br: std.io.Reader = undefined; | |
| 1192 | br.initFixed(data); | |
| 1184 | var br: std.io.Reader = .fixed(data); | |
| 1193 | 1185 | |
| 1194 | 1186 | var tmp = testing.tmpDir(.{ .no_follow = true }); |
| 1195 | 1187 | //defer tmp.cleanup(); |
lib/std/tar/Writer.zig+6-10| ... | ... | @@ -14,7 +14,7 @@ pub const Options = struct { |
| 14 | 14 | mtime: u64 = 0, |
| 15 | 15 | }; |
| 16 | 16 | |
| 17 | underlying_writer: *std.io.BufferedWriter, | |
| 17 | underlying_writer: *std.io.Writer, | |
| 18 | 18 | prefix: []const u8 = "", |
| 19 | 19 | mtime_now: u64 = 0, |
| 20 | 20 | |
| ... | ... | @@ -277,7 +277,7 @@ pub const Header = extern struct { |
| 277 | 277 | try octal(&w.checksum, checksum); |
| 278 | 278 | } |
| 279 | 279 | |
| 280 | pub fn write(h: *Header, bw: *std.io.BufferedWriter) error{ OctalOverflow, WriteFailed }!void { | |
| 280 | pub fn write(h: *Header, bw: *std.io.Writer) error{ OctalOverflow, WriteFailed }!void { | |
| 281 | 281 | try h.updateChecksum(); |
| 282 | 282 | try bw.writeAll(std.mem.asBytes(h)); |
| 283 | 283 | } |
| ... | ... | @@ -433,16 +433,14 @@ test "write files" { |
| 433 | 433 | { |
| 434 | 434 | const root = "root"; |
| 435 | 435 | |
| 436 | var output: std.io.AllocatingWriter = undefined; | |
| 437 | output.init(testing.allocator); | |
| 436 | var output: std.io.AllocatingWriter = .init(testing.allocator); | |
| 438 | 437 | var wrt: Writer = .{ .underlying_writer = &output.buffered_writer }; |
| 439 | 438 | defer output.deinit(); |
| 440 | 439 | try wrt.setRoot(root); |
| 441 | 440 | for (files) |file| |
| 442 | 441 | try wrt.writeFileBytes(file.path, file.content, .{}); |
| 443 | 442 | |
| 444 | var input: std.io.Reader = undefined; | |
| 445 | input.initFixed(output.getWritten()); | |
| 443 | var input: std.io.Reader = .fixed(output.getWritten()); | |
| 446 | 444 | var iter = std.tar.iterator(&input, .{ |
| 447 | 445 | .file_name_buffer = &file_name_buffer, |
| 448 | 446 | .link_name_buffer = &link_name_buffer, |
| ... | ... | @@ -476,13 +474,11 @@ test "write files" { |
| 476 | 474 | var wrt: Writer = .{ .underlying_writer = &output.buffered_writer }; |
| 477 | 475 | defer output.deinit(); |
| 478 | 476 | for (files) |file| { |
| 479 | var content: std.io.Reader = undefined; | |
| 480 | content.initFixed(file.content); | |
| 477 | var content: std.io.Reader = .fixed(file.content); | |
| 481 | 478 | try wrt.writeFileStream(file.path, file.content.len, &content, .{}); |
| 482 | 479 | } |
| 483 | 480 | |
| 484 | var input: std.io.Reader = undefined; | |
| 485 | input.initFixed(output.getWritten()); | |
| 481 | var input: std.io.Reader = .fixed(output.getWritten()); | |
| 486 | 482 | var iter = std.tar.iterator(&input, .{ |
| 487 | 483 | .file_name_buffer = &file_name_buffer, |
| 488 | 484 | .link_name_buffer = &link_name_buffer, |
lib/std/testing.zig+4-3| ... | ... | @@ -2,6 +2,7 @@ const std = @import("std.zig"); |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | 3 | const assert = std.debug.assert; |
| 4 | 4 | const math = std.math; |
| 5 | const Writer = std.io.Writer; | |
| 5 | 6 | |
| 6 | 7 | /// Provides deterministic randomness in unit tests. |
| 7 | 8 | /// Initialized on startup. Read-only after that. |
| ... | ... | @@ -459,7 +460,7 @@ fn SliceDiffer(comptime T: type) type { |
| 459 | 460 | |
| 460 | 461 | const Self = @This(); |
| 461 | 462 | |
| 462 | pub fn write(self: Self, bw: *std.io.BufferedWriter) !void { | |
| 463 | pub fn write(self: Self, bw: *Writer) !void { | |
| 463 | 464 | for (self.expected, 0..) |value, i| { |
| 464 | 465 | const full_index = self.start_index + i; |
| 465 | 466 | const diff = if (i < self.actual.len) !std.meta.eql(self.actual[i], value) else true; |
| ... | ... | @@ -480,7 +481,7 @@ const BytesDiffer = struct { |
| 480 | 481 | actual: []const u8, |
| 481 | 482 | ttyconf: std.io.tty.Config, |
| 482 | 483 | |
| 483 | pub fn write(self: BytesDiffer, bw: *std.io.BufferedWriter) !void { | |
| 484 | pub fn write(self: BytesDiffer, bw: *Writer) !void { | |
| 484 | 485 | var expected_iterator = std.mem.window(u8, self.expected, 16, 16); |
| 485 | 486 | var row: usize = 0; |
| 486 | 487 | while (expected_iterator.next()) |chunk| { |
| ... | ... | @@ -526,7 +527,7 @@ const BytesDiffer = struct { |
| 526 | 527 | } |
| 527 | 528 | } |
| 528 | 529 | |
| 529 | fn writeDiff(self: BytesDiffer, bw: *std.io.BufferedWriter, comptime fmt: []const u8, args: anytype, diff: bool) !void { | |
| 530 | fn writeDiff(self: BytesDiffer, bw: *Writer, comptime fmt: []const u8, args: anytype, diff: bool) !void { | |
| 530 | 531 | if (diff) try self.ttyconf.setColor(bw, .red); |
| 531 | 532 | try bw.print(fmt, args); |
| 532 | 533 | if (diff) try self.ttyconf.setColor(bw, .reset); |
lib/std/tz.zig+3-6| ... | ... | @@ -215,8 +215,7 @@ pub const Tz = struct { |
| 215 | 215 | |
| 216 | 216 | test "slim" { |
| 217 | 217 | const data = @embedFile("tz/asia_tokyo.tzif"); |
| 218 | var in_stream: std.io.Reader = undefined; | |
| 219 | in_stream.initFixed(data); | |
| 218 | var in_stream: std.io.Reader = .fixed(data); | |
| 220 | 219 | |
| 221 | 220 | var tz = try std.Tz.parse(std.testing.allocator, &in_stream); |
| 222 | 221 | defer tz.deinit(); |
| ... | ... | @@ -229,8 +228,7 @@ test "slim" { |
| 229 | 228 | |
| 230 | 229 | test "fat" { |
| 231 | 230 | const data = @embedFile("tz/antarctica_davis.tzif"); |
| 232 | var in_stream: std.io.Reader = undefined; | |
| 233 | in_stream.initFixed(data); | |
| 231 | var in_stream: std.io.Reader = .fixed(data); | |
| 234 | 232 | |
| 235 | 233 | var tz = try std.Tz.parse(std.testing.allocator, &in_stream); |
| 236 | 234 | defer tz.deinit(); |
| ... | ... | @@ -243,8 +241,7 @@ test "fat" { |
| 243 | 241 | test "legacy" { |
| 244 | 242 | // Taken from Slackware 8.0, from 2001 |
| 245 | 243 | const data = @embedFile("tz/europe_vatican.tzif"); |
| 246 | var in_stream: std.io.Reader = undefined; | |
| 247 | in_stream.initFixed(data); | |
| 244 | var in_stream: std.io.Reader = .fixed(data); | |
| 248 | 245 | |
| 249 | 246 | var tz = try std.Tz.parse(std.testing.allocator, &in_stream); |
| 250 | 247 | defer tz.deinit(); |
lib/std/zig.zig+8-15| ... | ... | @@ -2,6 +2,12 @@ |
| 2 | 2 | //! source lives here. These APIs are provided as-is and have absolutely no API |
| 3 | 3 | //! guarantees whatsoever. |
| 4 | 4 | |
| 5 | const std = @import("std.zig"); | |
| 6 | const tokenizer = @import("zig/tokenizer.zig"); | |
| 7 | const assert = std.debug.assert; | |
| 8 | const Allocator = std.mem.Allocator; | |
| 9 | const Writer = std.io.Writer; | |
| 10 | ||
| 5 | 11 | pub const ErrorBundle = @import("zig/ErrorBundle.zig"); |
| 6 | 12 | pub const Server = @import("zig/Server.zig"); |
| 7 | 13 | pub const Client = @import("zig/Client.zig"); |
| ... | ... | @@ -356,11 +362,6 @@ pub fn serializeCpuAlloc(ally: Allocator, cpu: std.Target.Cpu) Allocator.Error![ |
| 356 | 362 | return buffer.toOwnedSlice(); |
| 357 | 363 | } |
| 358 | 364 | |
| 359 | const std = @import("std.zig"); | |
| 360 | const tokenizer = @import("zig/tokenizer.zig"); | |
| 361 | const assert = std.debug.assert; | |
| 362 | const Allocator = std.mem.Allocator; | |
| 363 | ||
| 364 | 365 | /// Return a Formatter for a Zig identifier, escaping it with `@""` syntax if needed. |
| 365 | 366 | /// |
| 366 | 367 | /// - An empty `{}` format specifier escapes invalid identifiers, identifiers that shadow primitives |
| ... | ... | @@ -412,11 +413,7 @@ test fmtId { |
| 412 | 413 | } |
| 413 | 414 | |
| 414 | 415 | /// Print the string as a Zig identifier, escaping it with `@""` syntax if needed. |
| 415 | fn formatId( | |
| 416 | bytes: []const u8, | |
| 417 | bw: *std.io.BufferedWriter, | |
| 418 | comptime fmt: []const u8, | |
| 419 | ) !void { | |
| 416 | fn formatId(bytes: []const u8, bw: *Writer, comptime fmt: []const u8) !void { | |
| 420 | 417 | const allow_primitive, const allow_underscore = comptime parse_fmt: { |
| 421 | 418 | var allow_primitive = false; |
| 422 | 419 | var allow_underscore = false; |
| ... | ... | @@ -470,11 +467,7 @@ test fmtEscapes { |
| 470 | 467 | /// Print the string as escaped contents of a double quoted or single-quoted string. |
| 471 | 468 | /// Format `{}` treats contents as a double-quoted string. |
| 472 | 469 | /// Format `{'}` treats contents as a single-quoted string. |
| 473 | pub fn stringEscape( | |
| 474 | bytes: []const u8, | |
| 475 | bw: *std.io.BufferedWriter, | |
| 476 | comptime f: []const u8, | |
| 477 | ) !void { | |
| 470 | pub fn stringEscape(bytes: []const u8, bw: *Writer, comptime f: []const u8) !void { | |
| 478 | 471 | for (bytes) |byte| switch (byte) { |
| 479 | 472 | '\n' => try bw.writeAll("\\n"), |
| 480 | 473 | '\r' => try bw.writeAll("\\r"), |
lib/std/zig/Ast.zig+12-11| ... | ... | @@ -4,6 +4,16 @@ |
| 4 | 4 | //! For Zon syntax, the root node is at nodes[0] and contains lhs as the node |
| 5 | 5 | //! index of the main expression. |
| 6 | 6 | |
| 7 | const std = @import("../std.zig"); | |
| 8 | const assert = std.debug.assert; | |
| 9 | const testing = std.testing; | |
| 10 | const mem = std.mem; | |
| 11 | const Token = std.zig.Token; | |
| 12 | const Ast = @This(); | |
| 13 | const Allocator = std.mem.Allocator; | |
| 14 | const Parse = @import("Parse.zig"); | |
| 15 | const Writer = std.io.Writer; | |
| 16 | ||
| 7 | 17 | /// Reference to externally-owned data. |
| 8 | 18 | source: [:0]const u8, |
| 9 | 19 | |
| ... | ... | @@ -205,7 +215,7 @@ pub fn renderAlloc(tree: Ast, gpa: Allocator) error{OutOfMemory}![]u8 { |
| 205 | 215 | |
| 206 | 216 | pub const Render = @import("Ast/Render.zig"); |
| 207 | 217 | |
| 208 | pub fn render(tree: Ast, gpa: Allocator, bw: *std.io.BufferedWriter, fixups: Render.Fixups) Render.Error!void { | |
| 218 | pub fn render(tree: Ast, gpa: Allocator, bw: *Writer, fixups: Render.Fixups) Render.Error!void { | |
| 209 | 219 | return Render.tree(gpa, bw, tree, fixups); |
| 210 | 220 | } |
| 211 | 221 | |
| ... | ... | @@ -311,7 +321,7 @@ pub fn rootDecls(tree: Ast) []const Node.Index { |
| 311 | 321 | } |
| 312 | 322 | } |
| 313 | 323 | |
| 314 | pub fn renderError(tree: Ast, parse_error: Error, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 324 | pub fn renderError(tree: Ast, parse_error: Error, bw: *Writer) Writer.Error!void { | |
| 315 | 325 | switch (parse_error.tag) { |
| 316 | 326 | .asterisk_after_ptr_deref => { |
| 317 | 327 | // Note that the token will point at the `.*` but ideally the source |
| ... | ... | @@ -4118,15 +4128,6 @@ pub fn tokensToSpan(tree: *const Ast, start: Ast.TokenIndex, end: Ast.TokenIndex |
| 4118 | 4128 | return Span{ .start = start_off, .end = end_off, .main = tree.tokenStart(main) }; |
| 4119 | 4129 | } |
| 4120 | 4130 | |
| 4121 | const std = @import("../std.zig"); | |
| 4122 | const assert = std.debug.assert; | |
| 4123 | const testing = std.testing; | |
| 4124 | const mem = std.mem; | |
| 4125 | const Token = std.zig.Token; | |
| 4126 | const Ast = @This(); | |
| 4127 | const Allocator = std.mem.Allocator; | |
| 4128 | const Parse = @import("Parse.zig"); | |
| 4129 | ||
| 4130 | 4131 | test { |
| 4131 | 4132 | _ = Parse; |
| 4132 | 4133 | _ = Render; |
lib/std/zig/Ast/Render.zig+6-5| ... | ... | @@ -6,6 +6,7 @@ const meta = std.meta; |
| 6 | 6 | const Ast = std.zig.Ast; |
| 7 | 7 | const Token = std.zig.Token; |
| 8 | 8 | const primitives = std.zig.primitives; |
| 9 | const Writer = std.io.Writer; | |
| 9 | 10 | |
| 10 | 11 | const Render = @This(); |
| 11 | 12 | |
| ... | ... | @@ -82,7 +83,7 @@ pub const Fixups = struct { |
| 82 | 83 | } |
| 83 | 84 | }; |
| 84 | 85 | |
| 85 | pub fn renderTree(gpa: Allocator, bw: *std.io.BufferedWriter, tree: Ast, fixups: Fixups) Error!void { | |
| 86 | pub fn renderTree(gpa: Allocator, bw: *Writer, tree: Ast, fixups: Fixups) Error!void { | |
| 86 | 87 | assert(tree.errors.len == 0); // Cannot render an invalid tree. |
| 87 | 88 | var auto_indenting_stream: AutoIndentingStream = .init(gpa, bw, indent_delta); |
| 88 | 89 | defer auto_indenting_stream.deinit(); |
| ... | ... | @@ -3136,7 +3137,7 @@ fn anythingBetween(tree: Ast, start_token: Ast.TokenIndex, end_token: Ast.TokenI |
| 3136 | 3137 | return false; |
| 3137 | 3138 | } |
| 3138 | 3139 | |
| 3139 | fn writeFixingWhitespace(bw: *std.io.BufferedWriter, slice: []const u8) Error!void { | |
| 3140 | fn writeFixingWhitespace(bw: *Writer, slice: []const u8) Error!void { | |
| 3140 | 3141 | for (slice) |byte| switch (byte) { |
| 3141 | 3142 | '\t' => try bw.splatByteAll(' ', indent_delta), |
| 3142 | 3143 | '\r' => {}, |
| ... | ... | @@ -3266,7 +3267,7 @@ fn rowSize(tree: Ast, exprs: []const Ast.Node.Index, rtoken: Ast.TokenIndex) usi |
| 3266 | 3267 | /// This should be done whenever a scope that ends in a .semicolon or a |
| 3267 | 3268 | /// .comma is introduced. |
| 3268 | 3269 | const AutoIndentingStream = struct { |
| 3269 | underlying_writer: *std.io.BufferedWriter, | |
| 3270 | underlying_writer: *Writer, | |
| 3270 | 3271 | |
| 3271 | 3272 | /// Offset into the source at which formatting has been disabled with |
| 3272 | 3273 | /// a `zig fmt: off` comment. |
| ... | ... | @@ -3301,10 +3302,10 @@ const AutoIndentingStream = struct { |
| 3301 | 3302 | indent_count: usize, |
| 3302 | 3303 | }; |
| 3303 | 3304 | |
| 3304 | pub fn init(gpa: Allocator, bw: *std.io.BufferedWriter, indent_delta_: usize) AutoIndentingStream { | |
| 3305 | pub fn init(gpa: Allocator, bw: *Writer, starting_indent_delta: usize) AutoIndentingStream { | |
| 3305 | 3306 | return .{ |
| 3306 | 3307 | .underlying_writer = bw, |
| 3307 | .indent_delta = indent_delta_, | |
| 3308 | .indent_delta = starting_indent_delta, | |
| 3308 | 3309 | .indent_stack = .init(gpa), |
| 3309 | 3310 | .space_stack = .init(gpa), |
| 3310 | 3311 | }; |
lib/std/zig/ErrorBundle.zig+10-9| ... | ... | @@ -7,6 +7,12 @@ |
| 7 | 7 | //! empty, it means there are no errors. This special encoding exists so that |
| 8 | 8 | //! heap allocation is not needed in the common case of no errors. |
| 9 | 9 | |
| 10 | const std = @import("std"); | |
| 11 | const ErrorBundle = @This(); | |
| 12 | const Allocator = std.mem.Allocator; | |
| 13 | const assert = std.debug.assert; | |
| 14 | const Writer = std.io.Writer; | |
| 15 | ||
| 10 | 16 | string_bytes: []const u8, |
| 11 | 17 | /// The first thing in this array is an `ErrorMessageList`. |
| 12 | 18 | extra: []const u32, |
| ... | ... | @@ -163,7 +169,7 @@ pub fn renderToStdErr(eb: ErrorBundle, options: RenderOptions) void { |
| 163 | 169 | renderToWriter(eb, options, bw) catch return; |
| 164 | 170 | } |
| 165 | 171 | |
| 166 | pub fn renderToWriter(eb: ErrorBundle, options: RenderOptions, bw: *std.io.BufferedWriter) (std.io.Writer.Error || std.posix.UnexpectedError)!void { | |
| 172 | pub fn renderToWriter(eb: ErrorBundle, options: RenderOptions, bw: *Writer) (Writer.Error || std.posix.UnexpectedError)!void { | |
| 167 | 173 | if (eb.extra.len == 0) return; |
| 168 | 174 | for (eb.getMessages()) |err_msg| { |
| 169 | 175 | try renderErrorMessageToWriter(eb, options, err_msg, bw, "error", .red, 0); |
| ... | ... | @@ -182,11 +188,11 @@ fn renderErrorMessageToWriter( |
| 182 | 188 | eb: ErrorBundle, |
| 183 | 189 | options: RenderOptions, |
| 184 | 190 | err_msg_index: MessageIndex, |
| 185 | bw: *std.io.BufferedWriter, | |
| 191 | bw: *Writer, | |
| 186 | 192 | kind: []const u8, |
| 187 | 193 | color: std.io.tty.Color, |
| 188 | 194 | indent: usize, |
| 189 | ) (std.io.Writer.Error || std.posix.UnexpectedError)!void { | |
| 195 | ) (Writer.Error || std.posix.UnexpectedError)!void { | |
| 190 | 196 | const ttyconf = options.ttyconf; |
| 191 | 197 | const err_msg = eb.getErrorMessage(err_msg_index); |
| 192 | 198 | const prefix_start = bw.count; |
| ... | ... | @@ -294,7 +300,7 @@ fn renderErrorMessageToWriter( |
| 294 | 300 | /// to allow for long, good-looking error messages. |
| 295 | 301 | /// |
| 296 | 302 | /// This is used to split the message in `@compileError("hello\nworld")` for example. |
| 297 | fn writeMsg(eb: ErrorBundle, err_msg: ErrorMessage, bw: *std.io.BufferedWriter, indent: usize) !void { | |
| 303 | fn writeMsg(eb: ErrorBundle, err_msg: ErrorMessage, bw: *Writer, indent: usize) !void { | |
| 298 | 304 | var lines = std.mem.splitScalar(u8, eb.nullTerminatedString(err_msg.msg), '\n'); |
| 299 | 305 | while (lines.next()) |line| { |
| 300 | 306 | try bw.writeAll(line); |
| ... | ... | @@ -304,11 +310,6 @@ fn writeMsg(eb: ErrorBundle, err_msg: ErrorMessage, bw: *std.io.BufferedWriter, |
| 304 | 310 | } |
| 305 | 311 | } |
| 306 | 312 | |
| 307 | const std = @import("std"); | |
| 308 | const ErrorBundle = @This(); | |
| 309 | const Allocator = std.mem.Allocator; | |
| 310 | const assert = std.debug.assert; | |
| 311 | ||
| 312 | 313 | pub const Wip = struct { |
| 313 | 314 | gpa: Allocator, |
| 314 | 315 | string_bytes: std.ArrayListUnmanaged(u8), |
lib/std/zig/Server.zig+3-2| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | in: *std.io.Reader, |
| 2 | out: *std.io.BufferedWriter, | |
| 2 | out: *Writer, | |
| 3 | 3 | |
| 4 | 4 | pub const Message = struct { |
| 5 | 5 | pub const Header = extern struct { |
| ... | ... | @@ -94,7 +94,7 @@ pub const Message = struct { |
| 94 | 94 | |
| 95 | 95 | pub const Options = struct { |
| 96 | 96 | in: *std.io.Reader, |
| 97 | out: *std.io.BufferedWriter, | |
| 97 | out: *Writer, | |
| 98 | 98 | zig_version: []const u8, |
| 99 | 99 | }; |
| 100 | 100 | |
| ... | ... | @@ -215,3 +215,4 @@ const assert = std.debug.assert; |
| 215 | 215 | const native_endian = builtin.target.cpu.arch.endian(); |
| 216 | 216 | const need_bswap = native_endian != .little; |
| 217 | 217 | const Cache = std.Build.Cache; |
| 218 | const Writer = std.io.Writer; |
lib/std/zig/WindowsSdk.zig+6-6| ... | ... | @@ -1,11 +1,12 @@ |
| 1 | const WindowsSdk = @This(); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const std = @import("std"); | |
| 4 | const Writer = std.io.Writer; | |
| 5 | ||
| 1 | 6 | windows10sdk: ?Installation, |
| 2 | 7 | windows81sdk: ?Installation, |
| 3 | 8 | msvc_lib_dir: ?[]const u8, |
| 4 | 9 | |
| 5 | const WindowsSdk = @This(); | |
| 6 | const std = @import("std"); | |
| 7 | const builtin = @import("builtin"); | |
| 8 | ||
| 9 | 10 | const windows = std.os.windows; |
| 10 | 11 | const RRF = windows.advapi32.RRF; |
| 11 | 12 | |
| ... | ... | @@ -759,8 +760,7 @@ const MsvcLibDir = struct { |
| 759 | 760 | while (instances_dir_it.next() catch return error.PathNotFound) |entry| { |
| 760 | 761 | if (entry.kind != .directory) continue; |
| 761 | 762 | |
| 762 | var bw: std.io.BufferedWriter = undefined; | |
| 763 | bw.initFixed(&state_subpath_buf); | |
| 763 | var bw: Writer = .fixed(&state_subpath_buf); | |
| 764 | 764 | |
| 765 | 765 | bw.writeAll(entry.name) catch unreachable; |
| 766 | 766 | bw.writeByte(std.fs.path.sep) catch unreachable; |
lib/std/zig/ZonGen.zig+3-2| ... | ... | @@ -521,8 +521,8 @@ pub fn strLitSizeHint(tree: Ast, node: Ast.Node.Index) usize { |
| 521 | 521 | pub fn parseStrLit( |
| 522 | 522 | tree: Ast, |
| 523 | 523 | node: Ast.Node.Index, |
| 524 | writer: *std.io.BufferedWriter, | |
| 525 | ) std.io.Writer.Error!std.zig.string_literal.Result { | |
| 524 | writer: *Writer, | |
| 525 | ) Writer.Error!std.zig.string_literal.Result { | |
| 526 | 526 | switch (tree.nodeTag(node)) { |
| 527 | 527 | .string_literal => { |
| 528 | 528 | const token = tree.nodeMainToken(node); |
| ... | ... | @@ -933,3 +933,4 @@ const StringIndexContext = std.hash_map.StringIndexContext; |
| 933 | 933 | const ZonGen = @This(); |
| 934 | 934 | const Zoir = @import("Zoir.zig"); |
| 935 | 935 | const Ast = @import("Ast.zig"); |
| 936 | const Writer = std.io.Writer; |
lib/std/zig/llvm/Builder.zig+35-38| ... | ... | @@ -91,7 +91,7 @@ pub const String = enum(u32) { |
| 91 | 91 | string: String, |
| 92 | 92 | builder: *const Builder, |
| 93 | 93 | }; |
| 94 | fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime fmt_str: []const u8) std.io.Writer.Error!void { | |
| 94 | fn format(data: FormatData, bw: *Writer, comptime fmt_str: []const u8) Writer.Error!void { | |
| 95 | 95 | if (comptime std.mem.indexOfNone(u8, fmt_str, "\"r")) |_| |
| 96 | 96 | @compileError("invalid format string: '" ++ fmt_str ++ "'"); |
| 97 | 97 | assert(data.string != .none); |
| ... | ... | @@ -649,7 +649,7 @@ pub const Type = enum(u32) { |
| 649 | 649 | type: Type, |
| 650 | 650 | builder: *const Builder, |
| 651 | 651 | }; |
| 652 | fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime fmt_str: []const u8) std.io.Writer.Error!void { | |
| 652 | fn format(data: FormatData, bw: *Writer, comptime fmt_str: []const u8) Writer.Error!void { | |
| 653 | 653 | assert(data.type != .none); |
| 654 | 654 | if (comptime std.mem.eql(u8, fmt_str, "m")) { |
| 655 | 655 | const item = data.builder.type_items.items[@intFromEnum(data.type)]; |
| ... | ... | @@ -1129,7 +1129,7 @@ pub const Attribute = union(Kind) { |
| 1129 | 1129 | attribute_index: Index, |
| 1130 | 1130 | builder: *const Builder, |
| 1131 | 1131 | }; |
| 1132 | fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime fmt_str: []const u8) std.io.Writer.Error!void { | |
| 1132 | fn format(data: FormatData, bw: *Writer, comptime fmt_str: []const u8) Writer.Error!void { | |
| 1133 | 1133 | if (comptime std.mem.indexOfNone(u8, fmt_str, "\"#")) |_| |
| 1134 | 1134 | @compileError("invalid format string: '" ++ fmt_str ++ "'"); |
| 1135 | 1135 | const attribute = data.attribute_index.toAttribute(data.builder); |
| ... | ... | @@ -1568,7 +1568,7 @@ pub const Attributes = enum(u32) { |
| 1568 | 1568 | attributes: Attributes, |
| 1569 | 1569 | builder: *const Builder, |
| 1570 | 1570 | }; |
| 1571 | fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime fmt_str: []const u8) std.io.Writer.Error!void { | |
| 1571 | fn format(data: FormatData, bw: *Writer, comptime fmt_str: []const u8) Writer.Error!void { | |
| 1572 | 1572 | for (data.attributes.slice(data.builder)) |attribute_index| try Attribute.Index.format(.{ |
| 1573 | 1573 | .attribute_index = attribute_index, |
| 1574 | 1574 | .builder = data.builder, |
| ... | ... | @@ -1761,11 +1761,11 @@ pub const Linkage = enum(u4) { |
| 1761 | 1761 | extern_weak = 7, |
| 1762 | 1762 | external = 0, |
| 1763 | 1763 | |
| 1764 | pub fn format(self: Linkage, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void { | |
| 1764 | pub fn format(self: Linkage, bw: *Writer, comptime _: []const u8) Writer.Error!void { | |
| 1765 | 1765 | if (self != .external) try bw.print(" {s}", .{@tagName(self)}); |
| 1766 | 1766 | } |
| 1767 | 1767 | |
| 1768 | fn formatOptional(data: ?Linkage, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void { | |
| 1768 | fn formatOptional(data: ?Linkage, bw: *Writer, comptime _: []const u8) Writer.Error!void { | |
| 1769 | 1769 | if (data) |linkage| try bw.print(" {s}", .{@tagName(linkage)}); |
| 1770 | 1770 | } |
| 1771 | 1771 | pub fn fmtOptional(self: ?Linkage) std.fmt.Formatter(formatOptional) { |
| ... | ... | @@ -1778,7 +1778,7 @@ pub const Preemption = enum { |
| 1778 | 1778 | dso_local, |
| 1779 | 1779 | implicit_dso_local, |
| 1780 | 1780 | |
| 1781 | pub fn format(self: Preemption, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void { | |
| 1781 | pub fn format(self: Preemption, bw: *Writer, comptime _: []const u8) Writer.Error!void { | |
| 1782 | 1782 | if (self == .dso_local) try bw.print(" {s}", .{@tagName(self)}); |
| 1783 | 1783 | } |
| 1784 | 1784 | }; |
| ... | ... | @@ -1796,11 +1796,7 @@ pub const Visibility = enum(u2) { |
| 1796 | 1796 | }; |
| 1797 | 1797 | } |
| 1798 | 1798 | |
| 1799 | pub fn format( | |
| 1800 | self: Visibility, | |
| 1801 | comptime format_string: []const u8, | |
| 1802 | writer: *std.io.BufferedWriter, | |
| 1803 | ) std.io.Writer.Error!void { | |
| 1799 | pub fn format(self: Visibility, comptime format_string: []const u8, writer: *Writer) Writer.Error!void { | |
| 1804 | 1800 | comptime assert(format_string.len == 0); |
| 1805 | 1801 | if (self != .default) try writer.print(" {s}", .{@tagName(self)}); |
| 1806 | 1802 | } |
| ... | ... | @@ -1811,7 +1807,7 @@ pub const DllStorageClass = enum(u2) { |
| 1811 | 1807 | dllimport = 1, |
| 1812 | 1808 | dllexport = 2, |
| 1813 | 1809 | |
| 1814 | pub fn format(self: DllStorageClass, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void { | |
| 1810 | pub fn format(self: DllStorageClass, bw: *Writer, comptime _: []const u8) Writer.Error!void { | |
| 1815 | 1811 | if (self != .default) try bw.print(" {s}", .{@tagName(self)}); |
| 1816 | 1812 | } |
| 1817 | 1813 | }; |
| ... | ... | @@ -1823,7 +1819,7 @@ pub const ThreadLocal = enum(u3) { |
| 1823 | 1819 | initialexec = 3, |
| 1824 | 1820 | localexec = 4, |
| 1825 | 1821 | |
| 1826 | pub fn format(self: ThreadLocal, bw: *std.io.BufferedWriter, comptime prefix: []const u8) std.io.Writer.Error!void { | |
| 1822 | pub fn format(self: ThreadLocal, bw: *Writer, comptime prefix: []const u8) Writer.Error!void { | |
| 1827 | 1823 | if (self == .default) return; |
| 1828 | 1824 | try bw.print("{s}thread_local", .{prefix}); |
| 1829 | 1825 | if (self != .generaldynamic) try bw.print("({s})", .{@tagName(self)}); |
| ... | ... | @@ -1837,7 +1833,7 @@ pub const UnnamedAddr = enum(u2) { |
| 1837 | 1833 | unnamed_addr = 1, |
| 1838 | 1834 | local_unnamed_addr = 2, |
| 1839 | 1835 | |
| 1840 | pub fn format(self: UnnamedAddr, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void { | |
| 1836 | pub fn format(self: UnnamedAddr, bw: *Writer, comptime _: []const u8) Writer.Error!void { | |
| 1841 | 1837 | if (self != .default) try bw.print(" {s}", .{@tagName(self)}); |
| 1842 | 1838 | } |
| 1843 | 1839 | }; |
| ... | ... | @@ -1931,7 +1927,7 @@ pub const AddrSpace = enum(u24) { |
| 1931 | 1927 | pub const funcref: AddrSpace = @enumFromInt(20); |
| 1932 | 1928 | }; |
| 1933 | 1929 | |
| 1934 | pub fn format(self: AddrSpace, bw: *std.io.BufferedWriter, comptime prefix: []const u8) std.io.Writer.Error!void { | |
| 1930 | pub fn format(self: AddrSpace, bw: *Writer, comptime prefix: []const u8) Writer.Error!void { | |
| 1935 | 1931 | if (self != .default) try bw.print("{s}addrspace({d})", .{ prefix, @intFromEnum(self) }); |
| 1936 | 1932 | } |
| 1937 | 1933 | }; |
| ... | ... | @@ -1940,7 +1936,7 @@ pub const ExternallyInitialized = enum { |
| 1940 | 1936 | default, |
| 1941 | 1937 | externally_initialized, |
| 1942 | 1938 | |
| 1943 | pub fn format(self: ExternallyInitialized, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void { | |
| 1939 | pub fn format(self: ExternallyInitialized, bw: *Writer, comptime _: []const u8) Writer.Error!void { | |
| 1944 | 1940 | if (self != .default) try bw.print(" {s}", .{@tagName(self)}); |
| 1945 | 1941 | } |
| 1946 | 1942 | }; |
| ... | ... | @@ -1964,7 +1960,7 @@ pub const Alignment = enum(u6) { |
| 1964 | 1960 | return if (self == .default) 0 else (@intFromEnum(self) + 1); |
| 1965 | 1961 | } |
| 1966 | 1962 | |
| 1967 | pub fn format(self: Alignment, bw: *std.io.BufferedWriter, comptime prefix: []const u8) std.io.Writer.Error!void { | |
| 1963 | pub fn format(self: Alignment, bw: *Writer, comptime prefix: []const u8) Writer.Error!void { | |
| 1968 | 1964 | try bw.print("{s}align {d}", .{ prefix, self.toByteUnits() orelse return }); |
| 1969 | 1965 | } |
| 1970 | 1966 | }; |
| ... | ... | @@ -2038,7 +2034,7 @@ pub const CallConv = enum(u10) { |
| 2038 | 2034 | |
| 2039 | 2035 | pub const default = CallConv.ccc; |
| 2040 | 2036 | |
| 2041 | pub fn format(self: CallConv, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void { | |
| 2037 | pub fn format(self: CallConv, bw: *Writer, comptime _: []const u8) Writer.Error!void { | |
| 2042 | 2038 | switch (self) { |
| 2043 | 2039 | default => {}, |
| 2044 | 2040 | .fastcc, |
| ... | ... | @@ -2119,7 +2115,7 @@ pub const StrtabString = enum(u32) { |
| 2119 | 2115 | string: StrtabString, |
| 2120 | 2116 | builder: *const Builder, |
| 2121 | 2117 | }; |
| 2122 | fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime fmt_str: []const u8) std.io.Writer.Error!void { | |
| 2118 | fn format(data: FormatData, bw: *Writer, comptime fmt_str: []const u8) Writer.Error!void { | |
| 2123 | 2119 | if (comptime std.mem.indexOfNone(u8, fmt_str, "\"r")) |_| |
| 2124 | 2120 | @compileError("invalid format string: '" ++ fmt_str ++ "'"); |
| 2125 | 2121 | assert(data.string != .none); |
| ... | ... | @@ -2306,7 +2302,7 @@ pub const Global = struct { |
| 2306 | 2302 | global: Index, |
| 2307 | 2303 | builder: *const Builder, |
| 2308 | 2304 | }; |
| 2309 | fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void { | |
| 2305 | fn format(data: FormatData, bw: *Writer, comptime _: []const u8) Writer.Error!void { | |
| 2310 | 2306 | try bw.print("@{f}", .{ |
| 2311 | 2307 | data.global.unwrap(data.builder).name(data.builder).fmt(data.builder), |
| 2312 | 2308 | }); |
| ... | ... | @@ -4752,7 +4748,7 @@ pub const Function = struct { |
| 4752 | 4748 | function: Function.Index, |
| 4753 | 4749 | builder: *Builder, |
| 4754 | 4750 | }; |
| 4755 | fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime fmt_str: []const u8) std.io.Writer.Error!void { | |
| 4751 | fn format(data: FormatData, bw: *Writer, comptime fmt_str: []const u8) Writer.Error!void { | |
| 4756 | 4752 | if (comptime std.mem.indexOfNone(u8, fmt_str, ", %")) |_| |
| 4757 | 4753 | @compileError("invalid format string: '" ++ fmt_str ++ "'"); |
| 4758 | 4754 | if (comptime std.mem.indexOfScalar(u8, fmt_str, ',') != null) { |
| ... | ... | @@ -6944,7 +6940,7 @@ pub const MemoryAccessKind = enum(u1) { |
| 6944 | 6940 | normal, |
| 6945 | 6941 | @"volatile", |
| 6946 | 6942 | |
| 6947 | pub fn format(self: MemoryAccessKind, bw: *std.io.BufferedWriter, comptime prefix: []const u8) std.io.Writer.Error!void { | |
| 6943 | pub fn format(self: MemoryAccessKind, bw: *Writer, comptime prefix: []const u8) Writer.Error!void { | |
| 6948 | 6944 | if (self != .normal) try bw.print("{s}{s}", .{ prefix, @tagName(self) }); |
| 6949 | 6945 | } |
| 6950 | 6946 | }; |
| ... | ... | @@ -6953,7 +6949,7 @@ pub const SyncScope = enum(u1) { |
| 6953 | 6949 | singlethread, |
| 6954 | 6950 | system, |
| 6955 | 6951 | |
| 6956 | pub fn format(self: SyncScope, bw: *std.io.BufferedWriter, comptime prefix: []const u8) std.io.Writer.Error!void { | |
| 6952 | pub fn format(self: SyncScope, bw: *Writer, comptime prefix: []const u8) Writer.Error!void { | |
| 6957 | 6953 | if (self != .system) try bw.print( |
| 6958 | 6954 | \\{s}syncscope("{s}") |
| 6959 | 6955 | , .{ prefix, @tagName(self) }); |
| ... | ... | @@ -6969,7 +6965,7 @@ pub const AtomicOrdering = enum(u3) { |
| 6969 | 6965 | acq_rel = 5, |
| 6970 | 6966 | seq_cst = 6, |
| 6971 | 6967 | |
| 6972 | pub fn format(self: AtomicOrdering, bw: *std.io.BufferedWriter, comptime prefix: []const u8) std.io.Writer.Error!void { | |
| 6968 | pub fn format(self: AtomicOrdering, bw: *Writer, comptime prefix: []const u8) Writer.Error!void { | |
| 6973 | 6969 | if (self != .none) try bw.print("{s}{s}", .{ prefix, @tagName(self) }); |
| 6974 | 6970 | } |
| 6975 | 6971 | }; |
| ... | ... | @@ -7385,7 +7381,7 @@ pub const Constant = enum(u32) { |
| 7385 | 7381 | constant: Constant, |
| 7386 | 7382 | builder: *Builder, |
| 7387 | 7383 | }; |
| 7388 | fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime fmt_str: []const u8) std.io.Writer.Error!void { | |
| 7384 | fn format(data: FormatData, bw: *Writer, comptime fmt_str: []const u8) Writer.Error!void { | |
| 7389 | 7385 | if (comptime std.mem.indexOfNone(u8, fmt_str, ", %")) |_| |
| 7390 | 7386 | @compileError("invalid format string: '" ++ fmt_str ++ "'"); |
| 7391 | 7387 | if (comptime std.mem.indexOfScalar(u8, fmt_str, ',') != null) { |
| ... | ... | @@ -7712,7 +7708,7 @@ pub const Value = enum(u32) { |
| 7712 | 7708 | function: Function.Index, |
| 7713 | 7709 | builder: *Builder, |
| 7714 | 7710 | }; |
| 7715 | fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime fmt_str: []const u8) std.io.Writer.Error!void { | |
| 7711 | fn format(data: FormatData, bw: *Writer, comptime fmt_str: []const u8) Writer.Error!void { | |
| 7716 | 7712 | switch (data.value.unwrap()) { |
| 7717 | 7713 | .instruction => |instruction| try Function.Instruction.Index.format(.{ |
| 7718 | 7714 | .instruction = instruction, |
| ... | ... | @@ -7757,7 +7753,7 @@ pub const MetadataString = enum(u32) { |
| 7757 | 7753 | metadata_string: MetadataString, |
| 7758 | 7754 | builder: *const Builder, |
| 7759 | 7755 | }; |
| 7760 | fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void { | |
| 7756 | fn format(data: FormatData, bw: *Writer, comptime _: []const u8) Writer.Error!void { | |
| 7761 | 7757 | try printEscapedString(data.metadata_string.slice(data.builder), .always_quote, bw); |
| 7762 | 7758 | } |
| 7763 | 7759 | fn fmt(self: MetadataString, builder: *const Builder) std.fmt.Formatter(format) { |
| ... | ... | @@ -7922,7 +7918,7 @@ pub const Metadata = enum(u32) { |
| 7922 | 7918 | AllCallsDescribed: bool = false, |
| 7923 | 7919 | Unused: u2 = 0, |
| 7924 | 7920 | |
| 7925 | pub fn format(self: DIFlags, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void { | |
| 7921 | pub fn format(self: DIFlags, bw: *Writer, comptime _: []const u8) Writer.Error!void { | |
| 7926 | 7922 | var need_pipe = false; |
| 7927 | 7923 | inline for (@typeInfo(DIFlags).@"struct".fields) |field| { |
| 7928 | 7924 | switch (@typeInfo(field.type)) { |
| ... | ... | @@ -7979,7 +7975,7 @@ pub const Metadata = enum(u32) { |
| 7979 | 7975 | ObjCDirect: bool = false, |
| 7980 | 7976 | Unused: u20 = 0, |
| 7981 | 7977 | |
| 7982 | pub fn format(self: DISPFlags, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void { | |
| 7978 | pub fn format(self: DISPFlags, bw: *Writer, comptime _: []const u8) Writer.Error!void { | |
| 7983 | 7979 | var need_pipe = false; |
| 7984 | 7980 | inline for (@typeInfo(DISPFlags).@"struct".fields) |field| { |
| 7985 | 7981 | switch (@typeInfo(field.type)) { |
| ... | ... | @@ -8196,7 +8192,7 @@ pub const Metadata = enum(u32) { |
| 8196 | 8192 | }; |
| 8197 | 8193 | }; |
| 8198 | 8194 | }; |
| 8199 | fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime fmt_str: []const u8) std.io.Writer.Error!void { | |
| 8195 | fn format(data: FormatData, bw: *Writer, comptime fmt_str: []const u8) Writer.Error!void { | |
| 8200 | 8196 | if (data.node == .none) return; |
| 8201 | 8197 | |
| 8202 | 8198 | const is_specialized = fmt_str.len > 0 and fmt_str[0] == 'S'; |
| ... | ... | @@ -8370,7 +8366,7 @@ pub const Metadata = enum(u32) { |
| 8370 | 8366 | DIGlobalVariableExpression, |
| 8371 | 8367 | }, |
| 8372 | 8368 | nodes: anytype, |
| 8373 | bw: *std.io.BufferedWriter, | |
| 8369 | bw: *Writer, | |
| 8374 | 8370 | ) !void { |
| 8375 | 8371 | comptime var fmt_str: []const u8 = ""; |
| 8376 | 8372 | const names = comptime std.meta.fieldNames(@TypeOf(nodes)); |
| ... | ... | @@ -8623,12 +8619,12 @@ pub fn deinit(self: *Builder) void { |
| 8623 | 8619 | self.* = undefined; |
| 8624 | 8620 | } |
| 8625 | 8621 | |
| 8626 | pub fn setModuleAsm(self: *Builder, aw: *std.io.AllocatingWriter) *std.io.BufferedWriter { | |
| 8622 | pub fn setModuleAsm(self: *Builder, aw: *std.io.AllocatingWriter) *Writer { | |
| 8627 | 8623 | self.module_asm.clearRetainingCapacity(); |
| 8628 | 8624 | return self.appendModuleAsm(aw); |
| 8629 | 8625 | } |
| 8630 | 8626 | |
| 8631 | pub fn appendModuleAsm(self: *Builder, aw: *std.io.AllocatingWriter) *std.io.BufferedWriter { | |
| 8627 | pub fn appendModuleAsm(self: *Builder, aw: *std.io.AllocatingWriter) *Writer { | |
| 8632 | 8628 | return aw.fromArrayList(self.gpa, &self.module_asm); |
| 8633 | 8629 | } |
| 8634 | 8630 | |
| ... | ... | @@ -9379,14 +9375,14 @@ pub fn printToFile(self: *Builder, path: []const u8) bool { |
| 9379 | 9375 | return true; |
| 9380 | 9376 | } |
| 9381 | 9377 | |
| 9382 | pub fn printBuffered(self: *Builder, writer: std.io.Writer) std.io.Writer.Error!void { | |
| 9378 | pub fn printBuffered(self: *Builder, writer: Writer) Writer.Error!void { | |
| 9383 | 9379 | var buffer: [4096]u8 = undefined; |
| 9384 | 9380 | var bw = writer.buffered(&buffer); |
| 9385 | 9381 | try self.print(&bw); |
| 9386 | 9382 | try bw.flush(); |
| 9387 | 9383 | } |
| 9388 | 9384 | |
| 9389 | pub fn print(self: *Builder, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 9385 | pub fn print(self: *Builder, bw: *Writer) Writer.Error!void { | |
| 9390 | 9386 | var need_newline = false; |
| 9391 | 9387 | var metadata_formatter: Metadata.Formatter = .{ .builder = self, .need_comma = undefined }; |
| 9392 | 9388 | defer metadata_formatter.map.deinit(self.gpa); |
| ... | ... | @@ -10458,7 +10454,7 @@ fn isValidIdentifier(id: []const u8) bool { |
| 10458 | 10454 | } |
| 10459 | 10455 | |
| 10460 | 10456 | const QuoteBehavior = enum { always_quote, quote_unless_valid_identifier }; |
| 10461 | fn printEscapedString(slice: []const u8, quotes: QuoteBehavior, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 10457 | fn printEscapedString(slice: []const u8, quotes: QuoteBehavior, bw: *Writer) Writer.Error!void { | |
| 10462 | 10458 | const need_quotes = switch (quotes) { |
| 10463 | 10459 | .always_quote => true, |
| 10464 | 10460 | .quote_unless_valid_identifier => !isValidIdentifier(slice), |
| ... | ... | @@ -15097,6 +15093,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco |
| 15097 | 15093 | return bitcode.toOwnedSlice(); |
| 15098 | 15094 | } |
| 15099 | 15095 | |
| 15096 | const std = @import("../../std.zig"); | |
| 15100 | 15097 | const Allocator = std.mem.Allocator; |
| 15101 | 15098 | const assert = std.debug.assert; |
| 15102 | 15099 | const bitcode_writer = @import("bitcode_writer.zig"); |
| ... | ... | @@ -15105,4 +15102,4 @@ const builtin = @import("builtin"); |
| 15105 | 15102 | const DW = std.dwarf; |
| 15106 | 15103 | const ir = @import("ir.zig"); |
| 15107 | 15104 | const log = std.log.scoped(.llvm); |
| 15108 | const std = @import("../../std.zig"); | |
| 15105 | const Writer = std.io.Writer; |
lib/std/zig/string_literal.zig+4-3| ... | ... | @@ -1,6 +1,7 @@ |
| 1 | 1 | const std = @import("../std.zig"); |
| 2 | 2 | const assert = std.debug.assert; |
| 3 | 3 | const utf8Encode = std.unicode.utf8Encode; |
| 4 | const Writer = std.io.Writer; | |
| 4 | 5 | |
| 5 | 6 | pub const ParseError = error{ |
| 6 | 7 | OutOfMemory, |
| ... | ... | @@ -44,7 +45,7 @@ pub const Error = union(enum) { |
| 44 | 45 | raw_string: []const u8, |
| 45 | 46 | }; |
| 46 | 47 | |
| 47 | fn formatMessage(self: FormatMessage, bw: *std.io.BufferedWriter, comptime f: []const u8) !void { | |
| 48 | fn formatMessage(self: FormatMessage, bw: *Writer, comptime f: []const u8) !void { | |
| 48 | 49 | _ = f; |
| 49 | 50 | switch (self.err) { |
| 50 | 51 | .invalid_escape_character => |bad_index| try bw.print( |
| ... | ... | @@ -316,9 +317,9 @@ test parseCharLiteral { |
| 316 | 317 | ); |
| 317 | 318 | } |
| 318 | 319 | |
| 319 | /// Parses `bytes` as a Zig string literal and writes the result to the `std.io.Writer` type. | |
| 320 | /// Parses `bytes` as a Zig string literal and writes the result to the `Writer` type. | |
| 320 | 321 | /// Asserts `bytes` has '"' at beginning and end. |
| 321 | pub fn parseWrite(writer: *std.io.BufferedWriter, bytes: []const u8) std.io.Writer.Error!Result { | |
| 322 | pub fn parseWrite(writer: *Writer, bytes: []const u8) Writer.Error!Result { | |
| 322 | 323 | assert(bytes.len >= 2 and bytes[0] == '"' and bytes[bytes.len - 1] == '"'); |
| 323 | 324 | |
| 324 | 325 | var index: usize = 1; |
lib/std/zip.zig+3-2| ... | ... | @@ -7,6 +7,7 @@ const builtin = @import("builtin"); |
| 7 | 7 | const std = @import("std"); |
| 8 | 8 | const File = std.fs.File; |
| 9 | 9 | const is_le = builtin.target.cpu.arch.endian() == .little; |
| 10 | const Writer = std.io.Writer; | |
| 10 | 11 | |
| 11 | 12 | pub const CompressionMethod = enum(u16) { |
| 12 | 13 | store = 0, |
| ... | ... | @@ -200,7 +201,7 @@ pub const Decompress = union { |
| 200 | 201 | |
| 201 | 202 | fn readStore( |
| 202 | 203 | context: ?*anyopaque, |
| 203 | writer: *std.io.BufferedWriter, | |
| 204 | writer: *Writer, | |
| 204 | 205 | limit: std.io.Limit, |
| 205 | 206 | ) std.io.Reader.StreamError!usize { |
| 206 | 207 | const d: *Decompress = @ptrCast(@alignCast(context)); |
| ... | ... | @@ -209,7 +210,7 @@ pub const Decompress = union { |
| 209 | 210 | |
| 210 | 211 | fn readDeflate( |
| 211 | 212 | context: ?*anyopaque, |
| 212 | writer: *std.io.BufferedWriter, | |
| 213 | writer: *Writer, | |
| 213 | 214 | limit: std.io.Limit, |
| 214 | 215 | ) std.io.Reader.StreamError!usize { |
| 215 | 216 | const d: *Decompress = @ptrCast(@alignCast(context)); |
lib/std/zip/test.zig+5-5| ... | ... | @@ -3,6 +3,7 @@ const testing = std.testing; |
| 3 | 3 | const zip = @import("../zip.zig"); |
| 4 | 4 | const maxInt = std.math.maxInt; |
| 5 | 5 | const assert = std.debug.assert; |
| 6 | const Writer = std.io.Writer; | |
| 6 | 7 | |
| 7 | 8 | const File = struct { |
| 8 | 9 | name: []const u8, |
| ... | ... | @@ -103,7 +104,7 @@ const Zip64Options = struct { |
| 103 | 104 | }; |
| 104 | 105 | |
| 105 | 106 | fn writeZip( |
| 106 | writer: *std.io.BufferedWriter, | |
| 107 | writer: *Writer, | |
| 107 | 108 | files: []const File, |
| 108 | 109 | store: []FileStore, |
| 109 | 110 | options: WriteZipOptions, |
| ... | ... | @@ -129,13 +130,13 @@ fn writeZip( |
| 129 | 130 | /// Provides methods to format and write the contents of a zip archive |
| 130 | 131 | /// to the underlying Writer. |
| 131 | 132 | const Zipper = struct { |
| 132 | writer: *std.io.BufferedWriter, | |
| 133 | writer: *Writer, | |
| 133 | 134 | init_count: u64, |
| 134 | 135 | central_count: u64 = 0, |
| 135 | 136 | first_central_offset: ?u64 = null, |
| 136 | 137 | last_central_limit: ?u64 = null, |
| 137 | 138 | |
| 138 | fn init(writer: *std.io.BufferedWriter) Zipper { | |
| 139 | fn init(writer: *Writer) Zipper { | |
| 139 | 140 | return .{ .writer = writer, .init_count = writer.count }; |
| 140 | 141 | } |
| 141 | 142 | |
| ... | ... | @@ -198,8 +199,7 @@ const Zipper = struct { |
| 198 | 199 | }, |
| 199 | 200 | .deflate => { |
| 200 | 201 | const offset = writer.count; |
| 201 | var br: std.io.Reader = undefined; | |
| 202 | br.initFixed(@constCast(opt.content)); | |
| 202 | var br: std.io.Reader = .fixed(opt.content); | |
| 203 | 203 | var compress: std.compress.flate.Compress = .init(&br, .{}); |
| 204 | 204 | var compress_br = compress.readable(&.{}); |
| 205 | 205 | const n = try compress_br.readRemaining(writer); |
lib/std/zon/stringify.zig+7-7| ... | ... | @@ -22,7 +22,7 @@ |
| 22 | 22 | |
| 23 | 23 | const std = @import("std"); |
| 24 | 24 | const assert = std.debug.assert; |
| 25 | const BufferedWriter = std.io.BufferedWriter; | |
| 25 | const Writer = std.io.Writer; | |
| 26 | 26 | |
| 27 | 27 | /// Options for `serialize`. |
| 28 | 28 | pub const SerializeOptions = struct { |
| ... | ... | @@ -41,7 +41,7 @@ pub const SerializeOptions = struct { |
| 41 | 41 | /// Serialize the given value as ZON. |
| 42 | 42 | /// |
| 43 | 43 | /// It is asserted at comptime that `@TypeOf(val)` is not a recursive type. |
| 44 | pub fn serialize(val: anytype, options: SerializeOptions, writer: *BufferedWriter) std.io.Writer.Error!void { | |
| 44 | pub fn serialize(val: anytype, options: SerializeOptions, writer: *Writer) Writer.Error!void { | |
| 45 | 45 | var s: Serializer = .{ |
| 46 | 46 | .writer = writer, |
| 47 | 47 | .options = .{ .whitespace = options.whitespace }, |
| ... | ... | @@ -60,7 +60,7 @@ pub fn serialize(val: anytype, options: SerializeOptions, writer: *BufferedWrite |
| 60 | 60 | pub fn serializeMaxDepth( |
| 61 | 61 | val: anytype, |
| 62 | 62 | options: SerializeOptions, |
| 63 | writer: *BufferedWriter, | |
| 63 | writer: *Writer, | |
| 64 | 64 | depth: usize, |
| 65 | 65 | ) Serializer.DepthError!void { |
| 66 | 66 | var s: Serializer = .{ |
| ... | ... | @@ -80,7 +80,7 @@ pub fn serializeMaxDepth( |
| 80 | 80 | pub fn serializeArbitraryDepth( |
| 81 | 81 | val: anytype, |
| 82 | 82 | options: SerializeOptions, |
| 83 | writer: *BufferedWriter, | |
| 83 | writer: *Writer, | |
| 84 | 84 | ) Serializer.Error!void { |
| 85 | 85 | var s: Serializer = .{ |
| 86 | 86 | .writer = writer, |
| ... | ... | @@ -437,9 +437,9 @@ pub const SerializeContainerOptions = struct { |
| 437 | 437 | pub const Serializer = struct { |
| 438 | 438 | options: Options = .{}, |
| 439 | 439 | indent_level: u8 = 0, |
| 440 | writer: *BufferedWriter, | |
| 440 | writer: *Writer, | |
| 441 | 441 | |
| 442 | pub const Error = std.io.Writer.Error; | |
| 442 | pub const Error = Writer.Error; | |
| 443 | 443 | pub const DepthError = Error || error{ExceededMaxDepth}; |
| 444 | 444 | |
| 445 | 445 | pub const Options = struct { |
| ... | ... | @@ -1040,7 +1040,7 @@ pub const Serializer = struct { |
| 1040 | 1040 | }; |
| 1041 | 1041 | |
| 1042 | 1042 | test Serializer { |
| 1043 | var bw: std.io.BufferedWriter = .{ | |
| 1043 | var bw: Writer = .{ | |
| 1044 | 1044 | .unbuffered_writer = .discarding, |
| 1045 | 1045 | .buffer = &.{}, |
| 1046 | 1046 | }; |
lib/ubsan_rt.zig+1-1| ... | ... | @@ -119,7 +119,7 @@ const Value = extern struct { |
| 119 | 119 | } |
| 120 | 120 | } |
| 121 | 121 | |
| 122 | pub fn format(value: Value, bw: *std.io.BufferedWriter, comptime fmt: []const u8) !void { | |
| 122 | pub fn format(value: Value, bw: *std.io.Writer, comptime fmt: []const u8) !void { | |
| 123 | 123 | comptime assert(fmt.len == 0); |
| 124 | 124 | |
| 125 | 125 | // Work around x86_64 backend limitation. |
src/Air.zig+3-1| ... | ... | @@ -7,6 +7,7 @@ |
| 7 | 7 | const std = @import("std"); |
| 8 | 8 | const builtin = @import("builtin"); |
| 9 | 9 | const assert = std.debug.assert; |
| 10 | const Writer = std.io.Writer; | |
| 10 | 11 | |
| 11 | 12 | const Air = @This(); |
| 12 | 13 | const InternPool = @import("InternPool.zig"); |
| ... | ... | @@ -957,7 +958,8 @@ pub const Inst = struct { |
| 957 | 958 | return index.unwrap().target; |
| 958 | 959 | } |
| 959 | 960 | |
| 960 | pub fn format(index: Index, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void { | |
| 961 | pub fn format(index: Index, bw: *Writer, comptime fmt: []const u8) Writer.Error!void { | |
| 962 | comptime assert(fmt.len == 0); | |
| 961 | 963 | try bw.writeByte('%'); |
| 962 | 964 | switch (index.unwrap()) { |
| 963 | 965 | .ref => {}, |
src/Air/Liveness.zig+4-2| ... | ... | @@ -10,6 +10,7 @@ const log = std.log.scoped(.liveness); |
| 10 | 10 | const assert = std.debug.assert; |
| 11 | 11 | const Allocator = std.mem.Allocator; |
| 12 | 12 | const Log2Int = std.math.Log2Int; |
| 13 | const Writer = std.io.Writer; | |
| 13 | 14 | |
| 14 | 15 | const Liveness = @This(); |
| 15 | 16 | const trace = @import("../tracy.zig").trace; |
| ... | ... | @@ -2036,7 +2037,7 @@ fn fmtInstSet(set: *const std.AutoHashMapUnmanaged(Air.Inst.Index, void)) FmtIns |
| 2036 | 2037 | const FmtInstSet = struct { |
| 2037 | 2038 | set: *const std.AutoHashMapUnmanaged(Air.Inst.Index, void), |
| 2038 | 2039 | |
| 2039 | pub fn format(val: FmtInstSet, bw: *std.io.BufferedWriter, comptime _: []const u8) !void { | |
| 2040 | pub fn format(val: FmtInstSet, bw: *Writer, comptime _: []const u8) !void { | |
| 2040 | 2041 | if (val.set.count() == 0) { |
| 2041 | 2042 | try bw.writeAll("[no instructions]"); |
| 2042 | 2043 | return; |
| ... | ... | @@ -2056,7 +2057,8 @@ fn fmtInstList(list: []const Air.Inst.Index) FmtInstList { |
| 2056 | 2057 | const FmtInstList = struct { |
| 2057 | 2058 | list: []const Air.Inst.Index, |
| 2058 | 2059 | |
| 2059 | pub fn format(val: FmtInstList, bw: *std.io.BufferedWriter, comptime _: []const u8) !void { | |
| 2060 | pub fn format(val: FmtInstList, bw: *Writer, comptime fmt: []const u8) !void { | |
| 2061 | comptime assert(fmt.len == 0); | |
| 2060 | 2062 | if (val.list.len == 0) { |
| 2061 | 2063 | try bw.writeAll("[no instructions]"); |
| 2062 | 2064 | return; |
src/Air/print.zig+45-45| ... | ... | @@ -8,7 +8,7 @@ const Type = @import("../Type.zig"); |
| 8 | 8 | const Air = @import("../Air.zig"); |
| 9 | 9 | const InternPool = @import("../InternPool.zig"); |
| 10 | 10 | |
| 11 | pub fn write(air: Air, stream: *std.io.BufferedWriter, pt: Zcu.PerThread, liveness: ?Air.Liveness) void { | |
| 11 | pub fn write(air: Air, stream: *std.io.Writer, pt: Zcu.PerThread, liveness: ?Air.Liveness) void { | |
| 12 | 12 | comptime std.debug.assert(build_options.enable_debug_extensions); |
| 13 | 13 | const instruction_bytes = air.instructions.len * |
| 14 | 14 | // Here we don't use @sizeOf(Air.Inst.Data) because it would include |
| ... | ... | @@ -54,7 +54,7 @@ pub fn write(air: Air, stream: *std.io.BufferedWriter, pt: Zcu.PerThread, livene |
| 54 | 54 | |
| 55 | 55 | pub fn writeInst( |
| 56 | 56 | air: Air, |
| 57 | stream: *std.io.BufferedWriter, | |
| 57 | stream: *std.io.Writer, | |
| 58 | 58 | inst: Air.Inst.Index, |
| 59 | 59 | pt: Zcu.PerThread, |
| 60 | 60 | liveness: ?Air.Liveness, |
| ... | ... | @@ -93,14 +93,14 @@ const Writer = struct { |
| 93 | 93 | |
| 94 | 94 | const Error = std.io.Writer.Error; |
| 95 | 95 | |
| 96 | fn writeBody(w: *Writer, s: *std.io.BufferedWriter, body: []const Air.Inst.Index) Error!void { | |
| 96 | fn writeBody(w: *Writer, s: *std.io.Writer, body: []const Air.Inst.Index) Error!void { | |
| 97 | 97 | for (body) |inst| { |
| 98 | 98 | try w.writeInst(s, inst); |
| 99 | 99 | try s.writeByte('\n'); |
| 100 | 100 | } |
| 101 | 101 | } |
| 102 | 102 | |
| 103 | fn writeInst(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 103 | fn writeInst(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 104 | 104 | const tag = w.air.instructions.items(.tag)[@intFromEnum(inst)]; |
| 105 | 105 | try s.splatByteAll(' ', w.indent); |
| 106 | 106 | try s.print("{f}{c}= {s}(", .{ |
| ... | ... | @@ -340,48 +340,48 @@ const Writer = struct { |
| 340 | 340 | try s.writeByte(')'); |
| 341 | 341 | } |
| 342 | 342 | |
| 343 | fn writeBinOp(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 343 | fn writeBinOp(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 344 | 344 | const bin_op = w.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 345 | 345 | try w.writeOperand(s, inst, 0, bin_op.lhs); |
| 346 | 346 | try s.writeAll(", "); |
| 347 | 347 | try w.writeOperand(s, inst, 1, bin_op.rhs); |
| 348 | 348 | } |
| 349 | 349 | |
| 350 | fn writeUnOp(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 350 | fn writeUnOp(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 351 | 351 | const un_op = w.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 352 | 352 | try w.writeOperand(s, inst, 0, un_op); |
| 353 | 353 | } |
| 354 | 354 | |
| 355 | fn writeNoOp(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 355 | fn writeNoOp(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 356 | 356 | _ = w; |
| 357 | 357 | _ = s; |
| 358 | 358 | _ = inst; |
| 359 | 359 | // no-op, no argument to write |
| 360 | 360 | } |
| 361 | 361 | |
| 362 | fn writeType(w: *Writer, s: *std.io.BufferedWriter, ty: Type) !void { | |
| 362 | fn writeType(w: *Writer, s: *std.io.Writer, ty: Type) !void { | |
| 363 | 363 | return ty.print(s, w.pt); |
| 364 | 364 | } |
| 365 | 365 | |
| 366 | fn writeTy(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 366 | fn writeTy(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 367 | 367 | const ty = w.air.instructions.items(.data)[@intFromEnum(inst)].ty; |
| 368 | 368 | try w.writeType(s, ty); |
| 369 | 369 | } |
| 370 | 370 | |
| 371 | fn writeArg(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 371 | fn writeArg(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 372 | 372 | const arg = w.air.instructions.items(.data)[@intFromEnum(inst)].arg; |
| 373 | 373 | try w.writeType(s, arg.ty.toType()); |
| 374 | 374 | try s.print(", {d}", .{arg.zir_param_index}); |
| 375 | 375 | } |
| 376 | 376 | |
| 377 | fn writeTyOp(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 377 | fn writeTyOp(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 378 | 378 | const ty_op = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 379 | 379 | try w.writeType(s, ty_op.ty.toType()); |
| 380 | 380 | try s.writeAll(", "); |
| 381 | 381 | try w.writeOperand(s, inst, 0, ty_op.operand); |
| 382 | 382 | } |
| 383 | 383 | |
| 384 | fn writeBlock(w: *Writer, s: *std.io.BufferedWriter, tag: Air.Inst.Tag, inst: Air.Inst.Index) Error!void { | |
| 384 | fn writeBlock(w: *Writer, s: *std.io.Writer, tag: Air.Inst.Tag, inst: Air.Inst.Index) Error!void { | |
| 385 | 385 | const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 386 | 386 | try w.writeType(s, ty_pl.ty.toType()); |
| 387 | 387 | const body: []const Air.Inst.Index = @ptrCast(switch (tag) { |
| ... | ... | @@ -422,7 +422,7 @@ const Writer = struct { |
| 422 | 422 | } |
| 423 | 423 | } |
| 424 | 424 | |
| 425 | fn writeLoop(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 425 | fn writeLoop(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 426 | 426 | const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 427 | 427 | const extra = w.air.extraData(Air.Block, ty_pl.payload); |
| 428 | 428 | const body: []const Air.Inst.Index = @ptrCast(w.air.extra.items[extra.end..][0..extra.data.body_len]); |
| ... | ... | @@ -438,7 +438,7 @@ const Writer = struct { |
| 438 | 438 | try s.writeAll("}"); |
| 439 | 439 | } |
| 440 | 440 | |
| 441 | fn writeAggregateInit(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 441 | fn writeAggregateInit(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 442 | 442 | const zcu = w.pt.zcu; |
| 443 | 443 | const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 444 | 444 | const vector_ty = ty_pl.ty.toType(); |
| ... | ... | @@ -454,7 +454,7 @@ const Writer = struct { |
| 454 | 454 | try s.writeAll("]"); |
| 455 | 455 | } |
| 456 | 456 | |
| 457 | fn writeUnionInit(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 457 | fn writeUnionInit(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 458 | 458 | const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 459 | 459 | const extra = w.air.extraData(Air.UnionInit, ty_pl.payload).data; |
| 460 | 460 | |
| ... | ... | @@ -462,7 +462,7 @@ const Writer = struct { |
| 462 | 462 | try w.writeOperand(s, inst, 0, extra.init); |
| 463 | 463 | } |
| 464 | 464 | |
| 465 | fn writeStructField(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 465 | fn writeStructField(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 466 | 466 | const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 467 | 467 | const extra = w.air.extraData(Air.StructField, ty_pl.payload).data; |
| 468 | 468 | |
| ... | ... | @@ -470,7 +470,7 @@ const Writer = struct { |
| 470 | 470 | try s.print(", {d}", .{extra.field_index}); |
| 471 | 471 | } |
| 472 | 472 | |
| 473 | fn writeTyPlBin(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 473 | fn writeTyPlBin(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 474 | 474 | const data = w.air.instructions.items(.data); |
| 475 | 475 | const ty_pl = data[@intFromEnum(inst)].ty_pl; |
| 476 | 476 | const extra = w.air.extraData(Air.Bin, ty_pl.payload).data; |
| ... | ... | @@ -483,7 +483,7 @@ const Writer = struct { |
| 483 | 483 | try w.writeOperand(s, inst, 1, extra.rhs); |
| 484 | 484 | } |
| 485 | 485 | |
| 486 | fn writeCmpxchg(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 486 | fn writeCmpxchg(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 487 | 487 | const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 488 | 488 | const extra = w.air.extraData(Air.Cmpxchg, ty_pl.payload).data; |
| 489 | 489 | |
| ... | ... | @@ -497,7 +497,7 @@ const Writer = struct { |
| 497 | 497 | }); |
| 498 | 498 | } |
| 499 | 499 | |
| 500 | fn writeMulAdd(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 500 | fn writeMulAdd(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 501 | 501 | const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 502 | 502 | const extra = w.air.extraData(Air.Bin, pl_op.payload).data; |
| 503 | 503 | |
| ... | ... | @@ -508,7 +508,7 @@ const Writer = struct { |
| 508 | 508 | try w.writeOperand(s, inst, 2, pl_op.operand); |
| 509 | 509 | } |
| 510 | 510 | |
| 511 | fn writeShuffleOne(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 511 | fn writeShuffleOne(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 512 | 512 | const unwrapped = w.air.unwrapShuffleOne(w.pt.zcu, inst); |
| 513 | 513 | try w.writeType(s, unwrapped.result_ty); |
| 514 | 514 | try s.writeAll(", "); |
| ... | ... | @@ -543,7 +543,7 @@ const Writer = struct { |
| 543 | 543 | try s.writeByte(']'); |
| 544 | 544 | } |
| 545 | 545 | |
| 546 | fn writeSelect(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 546 | fn writeSelect(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 547 | 547 | const zcu = w.pt.zcu; |
| 548 | 548 | const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 549 | 549 | const extra = w.air.extraData(Air.Bin, pl_op.payload).data; |
| ... | ... | @@ -558,14 +558,14 @@ const Writer = struct { |
| 558 | 558 | try w.writeOperand(s, inst, 2, extra.rhs); |
| 559 | 559 | } |
| 560 | 560 | |
| 561 | fn writeReduce(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 561 | fn writeReduce(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 562 | 562 | const reduce = w.air.instructions.items(.data)[@intFromEnum(inst)].reduce; |
| 563 | 563 | |
| 564 | 564 | try w.writeOperand(s, inst, 0, reduce.operand); |
| 565 | 565 | try s.print(", {s}", .{@tagName(reduce.operation)}); |
| 566 | 566 | } |
| 567 | 567 | |
| 568 | fn writeCmpVector(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 568 | fn writeCmpVector(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 569 | 569 | const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 570 | 570 | const extra = w.air.extraData(Air.VectorCmp, ty_pl.payload).data; |
| 571 | 571 | |
| ... | ... | @@ -575,7 +575,7 @@ const Writer = struct { |
| 575 | 575 | try w.writeOperand(s, inst, 1, extra.rhs); |
| 576 | 576 | } |
| 577 | 577 | |
| 578 | fn writeVectorStoreElem(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 578 | fn writeVectorStoreElem(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 579 | 579 | const data = w.air.instructions.items(.data)[@intFromEnum(inst)].vector_store_elem; |
| 580 | 580 | const extra = w.air.extraData(Air.VectorCmp, data.payload).data; |
| 581 | 581 | |
| ... | ... | @@ -586,21 +586,21 @@ const Writer = struct { |
| 586 | 586 | try w.writeOperand(s, inst, 2, extra.rhs); |
| 587 | 587 | } |
| 588 | 588 | |
| 589 | fn writeRuntimeNavPtr(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 589 | fn writeRuntimeNavPtr(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 590 | 590 | const ip = &w.pt.zcu.intern_pool; |
| 591 | 591 | const ty_nav = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_nav; |
| 592 | 592 | try w.writeType(s, .fromInterned(ty_nav.ty)); |
| 593 | 593 | try s.print(", '{}'", .{ip.getNav(ty_nav.nav).fqn.fmt(ip)}); |
| 594 | 594 | } |
| 595 | 595 | |
| 596 | fn writeAtomicLoad(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 596 | fn writeAtomicLoad(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 597 | 597 | const atomic_load = w.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load; |
| 598 | 598 | |
| 599 | 599 | try w.writeOperand(s, inst, 0, atomic_load.ptr); |
| 600 | 600 | try s.print(", {s}", .{@tagName(atomic_load.order)}); |
| 601 | 601 | } |
| 602 | 602 | |
| 603 | fn writePrefetch(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 603 | fn writePrefetch(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 604 | 604 | const prefetch = w.air.instructions.items(.data)[@intFromEnum(inst)].prefetch; |
| 605 | 605 | |
| 606 | 606 | try w.writeOperand(s, inst, 0, prefetch.ptr); |
| ... | ... | @@ -611,7 +611,7 @@ const Writer = struct { |
| 611 | 611 | |
| 612 | 612 | fn writeAtomicStore( |
| 613 | 613 | w: *Writer, |
| 614 | s: *std.io.BufferedWriter, | |
| 614 | s: *std.io.Writer, | |
| 615 | 615 | inst: Air.Inst.Index, |
| 616 | 616 | order: std.builtin.AtomicOrder, |
| 617 | 617 | ) Error!void { |
| ... | ... | @@ -622,7 +622,7 @@ const Writer = struct { |
| 622 | 622 | try s.print(", {s}", .{@tagName(order)}); |
| 623 | 623 | } |
| 624 | 624 | |
| 625 | fn writeAtomicRmw(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 625 | fn writeAtomicRmw(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 626 | 626 | const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 627 | 627 | const extra = w.air.extraData(Air.AtomicRmw, pl_op.payload).data; |
| 628 | 628 | |
| ... | ... | @@ -632,7 +632,7 @@ const Writer = struct { |
| 632 | 632 | try s.print(", {s}, {s}", .{ @tagName(extra.op()), @tagName(extra.ordering()) }); |
| 633 | 633 | } |
| 634 | 634 | |
| 635 | fn writeFieldParentPtr(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 635 | fn writeFieldParentPtr(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 636 | 636 | const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 637 | 637 | const extra = w.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; |
| 638 | 638 | |
| ... | ... | @@ -640,7 +640,7 @@ const Writer = struct { |
| 640 | 640 | try s.print(", {d}", .{extra.field_index}); |
| 641 | 641 | } |
| 642 | 642 | |
| 643 | fn writeAssembly(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 643 | fn writeAssembly(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 644 | 644 | const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 645 | 645 | const extra = w.air.extraData(Air.Asm, ty_pl.payload); |
| 646 | 646 | const is_volatile = @as(u1, @truncate(extra.data.flags >> 31)) != 0; |
| ... | ... | @@ -713,19 +713,19 @@ const Writer = struct { |
| 713 | 713 | try s.print(", \"{f}\"", .{std.zig.fmtEscapes(asm_source)}); |
| 714 | 714 | } |
| 715 | 715 | |
| 716 | fn writeDbgStmt(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 716 | fn writeDbgStmt(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 717 | 717 | const dbg_stmt = w.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt; |
| 718 | 718 | try s.print("{d}:{d}", .{ dbg_stmt.line + 1, dbg_stmt.column + 1 }); |
| 719 | 719 | } |
| 720 | 720 | |
| 721 | fn writeDbgVar(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 721 | fn writeDbgVar(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 722 | 722 | const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 723 | 723 | try w.writeOperand(s, inst, 0, pl_op.operand); |
| 724 | 724 | const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload); |
| 725 | 725 | try s.print(", \"{f}\"", .{std.zig.fmtEscapes(name.toSlice(w.air))}); |
| 726 | 726 | } |
| 727 | 727 | |
| 728 | fn writeCall(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 728 | fn writeCall(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 729 | 729 | const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 730 | 730 | const extra = w.air.extraData(Air.Call, pl_op.payload); |
| 731 | 731 | const args = @as([]const Air.Inst.Ref, @ptrCast(w.air.extra.items[extra.end..][0..extra.data.args_len])); |
| ... | ... | @@ -738,19 +738,19 @@ const Writer = struct { |
| 738 | 738 | try s.writeAll("]"); |
| 739 | 739 | } |
| 740 | 740 | |
| 741 | fn writeBr(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 741 | fn writeBr(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 742 | 742 | const br = w.air.instructions.items(.data)[@intFromEnum(inst)].br; |
| 743 | 743 | try w.writeInstIndex(s, br.block_inst, false); |
| 744 | 744 | try s.writeAll(", "); |
| 745 | 745 | try w.writeOperand(s, inst, 0, br.operand); |
| 746 | 746 | } |
| 747 | 747 | |
| 748 | fn writeRepeat(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 748 | fn writeRepeat(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 749 | 749 | const repeat = w.air.instructions.items(.data)[@intFromEnum(inst)].repeat; |
| 750 | 750 | try w.writeInstIndex(s, repeat.loop_inst, false); |
| 751 | 751 | } |
| 752 | 752 | |
| 753 | fn writeTry(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 753 | fn writeTry(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 754 | 754 | const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 755 | 755 | const extra = w.air.extraData(Air.Try, pl_op.payload); |
| 756 | 756 | const body: []const Air.Inst.Index = @ptrCast(w.air.extra.items[extra.end..][0..extra.data.body_len]); |
| ... | ... | @@ -784,7 +784,7 @@ const Writer = struct { |
| 784 | 784 | } |
| 785 | 785 | } |
| 786 | 786 | |
| 787 | fn writeTryPtr(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 787 | fn writeTryPtr(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 788 | 788 | const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 789 | 789 | const extra = w.air.extraData(Air.TryPtr, ty_pl.payload); |
| 790 | 790 | const body: []const Air.Inst.Index = @ptrCast(w.air.extra.items[extra.end..][0..extra.data.body_len]); |
| ... | ... | @@ -821,7 +821,7 @@ const Writer = struct { |
| 821 | 821 | } |
| 822 | 822 | } |
| 823 | 823 | |
| 824 | fn writeCondBr(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 824 | fn writeCondBr(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 825 | 825 | const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 826 | 826 | const extra = w.air.extraData(Air.CondBr, pl_op.payload); |
| 827 | 827 | const then_body: []const Air.Inst.Index = @ptrCast(w.air.extra.items[extra.end..][0..extra.data.then_body_len]); |
| ... | ... | @@ -880,7 +880,7 @@ const Writer = struct { |
| 880 | 880 | try s.writeAll("}"); |
| 881 | 881 | } |
| 882 | 882 | |
| 883 | fn writeSwitchBr(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 883 | fn writeSwitchBr(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 884 | 884 | const switch_br = w.air.unwrapSwitch(inst); |
| 885 | 885 | |
| 886 | 886 | const liveness: Air.Liveness.SwitchBrTable = if (w.liveness) |liveness| |
| ... | ... | @@ -966,25 +966,25 @@ const Writer = struct { |
| 966 | 966 | try s.splatByteAll(' ', old_indent); |
| 967 | 967 | } |
| 968 | 968 | |
| 969 | fn writeWasmMemorySize(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 969 | fn writeWasmMemorySize(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 970 | 970 | const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 971 | 971 | try s.print("{d}", .{pl_op.payload}); |
| 972 | 972 | } |
| 973 | 973 | |
| 974 | fn writeWasmMemoryGrow(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 974 | fn writeWasmMemoryGrow(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 975 | 975 | const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 976 | 976 | try s.print("{d}, ", .{pl_op.payload}); |
| 977 | 977 | try w.writeOperand(s, inst, 0, pl_op.operand); |
| 978 | 978 | } |
| 979 | 979 | |
| 980 | fn writeWorkDimension(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void { | |
| 980 | fn writeWorkDimension(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { | |
| 981 | 981 | const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 982 | 982 | try s.print("{d}", .{pl_op.payload}); |
| 983 | 983 | } |
| 984 | 984 | |
| 985 | 985 | fn writeOperand( |
| 986 | 986 | w: *Writer, |
| 987 | s: *std.io.BufferedWriter, | |
| 987 | s: *std.io.Writer, | |
| 988 | 988 | inst: Air.Inst.Index, |
| 989 | 989 | op_index: usize, |
| 990 | 990 | operand: Air.Inst.Ref, |
| ... | ... | @@ -1030,7 +1030,7 @@ const Writer = struct { |
| 1030 | 1030 | |
| 1031 | 1031 | fn writeInstIndex( |
| 1032 | 1032 | w: *Writer, |
| 1033 | s: *std.io.BufferedWriter, | |
| 1033 | s: *std.io.Writer, | |
| 1034 | 1034 | inst: Air.Inst.Index, |
| 1035 | 1035 | dies: bool, |
| 1036 | 1036 | ) Error!void { |
src/Compilation.zig+7-9| ... | ... | @@ -12,6 +12,7 @@ const ThreadPool = std.Thread.Pool; |
| 12 | 12 | const WaitGroup = std.Thread.WaitGroup; |
| 13 | 13 | const ErrorBundle = std.zig.ErrorBundle; |
| 14 | 14 | const fatal = std.process.fatal; |
| 15 | const Writer = std.io.Writer; | |
| 15 | 16 | |
| 16 | 17 | const Value = @import("Value.zig"); |
| 17 | 18 | const Type = @import("Type.zig"); |
| ... | ... | @@ -1000,15 +1001,12 @@ pub const CObject = struct { |
| 1000 | 1001 | |
| 1001 | 1002 | const file = std.fs.cwd().openFile(file_name, .{}) catch break :source_line 0; |
| 1002 | 1003 | defer file.close(); |
| 1003 | file.seekTo(diag.src_loc.offset + 1 - diag.src_loc.column) catch break :source_line 0; | |
| 1004 | ||
| 1005 | 1004 | var buffer: [1 << 10]u8 = undefined; |
| 1006 | var fr = file.reader(); | |
| 1007 | var br = fr.interface().buffered(&buffer); | |
| 1008 | var bw: std.io.BufferedWriter = undefined; | |
| 1009 | bw.initFixed(&buffer); | |
| 1005 | var fr = file.reader(&buffer); | |
| 1006 | fr.seekTo(diag.src_loc.offset + 1 - diag.src_loc.column) catch break :source_line 0; | |
| 1007 | var bw: Writer = .fixed(&buffer); | |
| 1010 | 1008 | break :source_line try eb.addString( |
| 1011 | buffer[0 .. br.readDelimiterEnding(&bw, '\n') catch break :source_line 0], | |
| 1009 | buffer[0 .. fr.interface.readDelimiterEnding(&bw, '\n') catch break :source_line 0], | |
| 1012 | 1010 | ); |
| 1013 | 1011 | }; |
| 1014 | 1012 | |
| ... | ... | @@ -6026,8 +6024,8 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 |
| 6026 | 6024 | |
| 6027 | 6025 | // In .rc files, a " within a quoted string is escaped as "" |
| 6028 | 6026 | const fmtRcEscape = struct { |
| 6029 | fn formatRcEscape(bytes: []const u8, bw: *std.io.BufferedWriter, comptime fmt: []const u8) !void { | |
| 6030 | _ = fmt; | |
| 6027 | fn formatRcEscape(bytes: []const u8, bw: *Writer, comptime fmt: []const u8) !void { | |
| 6028 | comptime assert(fmt.len == 0); | |
| 6031 | 6029 | for (bytes) |byte| switch (byte) { |
| 6032 | 6030 | '"' => try bw.writeAll("\"\""), |
| 6033 | 6031 | '\\' => try bw.writeAll("\\\\"), |
src/InternPool.zig+1-1| ... | ... | @@ -1888,7 +1888,7 @@ pub const NullTerminatedString = enum(u32) { |
| 1888 | 1888 | string: NullTerminatedString, |
| 1889 | 1889 | ip: *const InternPool, |
| 1890 | 1890 | }; |
| 1891 | fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime specifier: []const u8) std.io.Writer.Error!void { | |
| 1891 | fn format(data: FormatData, bw: *std.io.Writer, comptime specifier: []const u8) std.io.Writer.Error!void { | |
| 1892 | 1892 | const slice = data.string.toSlice(data.ip); |
| 1893 | 1893 | if (comptime std.mem.eql(u8, specifier, "")) { |
| 1894 | 1894 | try bw.writeAll(slice); |
src/Package/Fetch.zig+7-7| ... | ... | @@ -1366,9 +1366,9 @@ fn unpackGitPack(f: *Fetch, out_dir: fs.Dir, resource: *Resource.Git) anyerror!U |
| 1366 | 1366 | const index_prog_node = f.prog_node.start("Index pack", 0); |
| 1367 | 1367 | defer index_prog_node.end(); |
| 1368 | 1368 | var buffer: [4096]u8 = undefined; |
| 1369 | var index_buffered_writer: std.io.BufferedWriter = index_file.writer().buffered(&buffer); | |
| 1370 | try git.indexPack(gpa, object_format, pack_file, &index_buffered_writer); | |
| 1371 | try index_buffered_writer.flush(); | |
| 1369 | var index_file_writer = index_file.writer(&buffer); | |
| 1370 | try git.indexPack(gpa, object_format, pack_file, &index_file_writer.interface); | |
| 1371 | try index_file_writer.flush(); | |
| 1372 | 1372 | try index_file.sync(); |
| 1373 | 1373 | } |
| 1374 | 1374 | |
| ... | ... | @@ -1639,14 +1639,14 @@ fn computeHash(f: *Fetch, pkg_path: Cache.Path, filter: Filter) RunError!Compute |
| 1639 | 1639 | |
| 1640 | 1640 | fn dumpHashInfo(all_files: []const *const HashedFile) !void { |
| 1641 | 1641 | var buffer: [4096]u8 = undefined; |
| 1642 | var bw: std.io.BufferedWriter = std.fs.File.stdout().writer().buffered(&buffer); | |
| 1642 | var file_writer = std.fs.File.stdout().writer(&buffer); | |
| 1643 | const w = &file_writer.interface; | |
| 1643 | 1644 | for (all_files) |hashed_file| { |
| 1644 | try bw.print("{s}: {x}: {s}\n", .{ | |
| 1645 | try w.print("{s}: {x}: {s}\n", .{ | |
| 1645 | 1646 | @tagName(hashed_file.kind), &hashed_file.hash, hashed_file.normalized_path, |
| 1646 | 1647 | }); |
| 1647 | 1648 | } |
| 1648 | ||
| 1649 | try bw.flush(); | |
| 1649 | try file_writer.flush(); | |
| 1650 | 1650 | } |
| 1651 | 1651 | |
| 1652 | 1652 | fn workerHashFile(dir: fs.Dir, hashed_file: *HashedFile) void { |
src/Package/Fetch/git.zig+8-8| ... | ... | @@ -12,6 +12,7 @@ const Sha1 = std.crypto.hash.Sha1; |
| 12 | 12 | const Sha256 = std.crypto.hash.sha2.Sha256; |
| 13 | 13 | const assert = std.debug.assert; |
| 14 | 14 | const zlib = std.compress.zlib; |
| 15 | const Writer = std.io.Writer; | |
| 15 | 16 | |
| 16 | 17 | /// The ID of a Git object. |
| 17 | 18 | pub const Oid = union(Format) { |
| ... | ... | @@ -65,7 +66,7 @@ pub const Oid = union(Format) { |
| 65 | 66 | }; |
| 66 | 67 | } |
| 67 | 68 | |
| 68 | pub fn writable(hasher: *Hasher, buffer: []u8) std.io.BufferedWriter { | |
| 69 | pub fn writer(hasher: *Hasher, buffer: []u8) Writer { | |
| 69 | 70 | return switch (hasher.*) { |
| 70 | 71 | inline else => |*inner| inner.writable(buffer), |
| 71 | 72 | }; |
| ... | ... | @@ -134,9 +135,9 @@ pub const Oid = union(Format) { |
| 134 | 135 | } else error.InvalidOid; |
| 135 | 136 | } |
| 136 | 137 | |
| 137 | pub fn format(oid: Oid, bw: *std.io.BufferedWriter, comptime fmt: []const u8) std.io.Writer.Error!void { | |
| 138 | _ = fmt; | |
| 139 | try bw.print("{x}", .{oid.slice()}); | |
| 138 | pub fn format(oid: Oid, w: *Writer, comptime fmt: []const u8) Writer.Error!void { | |
| 139 | comptime assert(fmt.len == 0); | |
| 140 | try w.print("{x}", .{oid.slice()}); | |
| 140 | 141 | } |
| 141 | 142 | |
| 142 | 143 | pub fn slice(oid: *const Oid) []const u8 { |
| ... | ... | @@ -608,7 +609,7 @@ const Packet = union(enum) { |
| 608 | 609 | } |
| 609 | 610 | |
| 610 | 611 | /// Writes a packet in pkt-line format. |
| 611 | fn write(packet: Packet, writer: *std.io.BufferedWriter) !void { | |
| 612 | fn write(packet: Packet, writer: *Writer) !void { | |
| 612 | 613 | switch (packet) { |
| 613 | 614 | .flush => try writer.writeAll("0000"), |
| 614 | 615 | .delimiter => try writer.writeAll("0001"), |
| ... | ... | @@ -1481,8 +1482,7 @@ fn resolveDeltaChain( |
| 1481 | 1482 | const expanded_alloc_size = std.math.cast(usize, expanded_size) orelse return error.ObjectTooLarge; |
| 1482 | 1483 | const expanded_data = try allocator.alloc(u8, expanded_alloc_size); |
| 1483 | 1484 | errdefer allocator.free(expanded_data); |
| 1484 | var expanded_delta_stream: std.io.BufferedWriter = undefined; | |
| 1485 | expanded_delta_stream.initFixed(expanded_data); | |
| 1485 | var expanded_delta_stream: Writer = .fixed(expanded_data); | |
| 1486 | 1486 | try expandDelta(base_data, &delta_reader, &expanded_delta_stream); |
| 1487 | 1487 | if (expanded_delta_stream.end != expanded_size) return error.InvalidObject; |
| 1488 | 1488 | |
| ... | ... | @@ -1505,7 +1505,7 @@ fn readObjectRaw(gpa: Allocator, reader: *std.io.Reader, size: u64) ![]u8 { |
| 1505 | 1505 | |
| 1506 | 1506 | /// The format of the delta data is documented in |
| 1507 | 1507 | /// [pack-format](https://git-scm.com/docs/pack-format). |
| 1508 | fn expandDelta(base_object: []const u8, delta_reader: *std.io.Reader, writer: *std.io.BufferedWriter) !void { | |
| 1508 | fn expandDelta(base_object: []const u8, delta_reader: *std.io.Reader, writer: *Writer) !void { | |
| 1509 | 1509 | var base_offset: u32 = 0; |
| 1510 | 1510 | while (true) { |
| 1511 | 1511 | const inst: packed struct { value: u7, copy: bool } = @bitCast(delta_reader.takeByte() catch |e| switch (e) { |
src/Sema.zig+4-4| ... | ... | @@ -9544,8 +9544,8 @@ fn callConvSupportsVarArgs(cc: std.builtin.CallingConvention.Tag) bool { |
| 9544 | 9544 | fn checkCallConvSupportsVarArgs(sema: *Sema, block: *Block, src: LazySrcLoc, cc: std.builtin.CallingConvention.Tag) CompileError!void { |
| 9545 | 9545 | const CallingConventionsSupportingVarArgsList = struct { |
| 9546 | 9546 | arch: std.Target.Cpu.Arch, |
| 9547 | pub fn format(ctx: @This(), bw: *std.io.BufferedWriter, comptime fmt: []const u8) !void { | |
| 9548 | _ = fmt; | |
| 9547 | pub fn format(ctx: @This(), bw: *std.io.Writer, comptime fmt: []const u8) !void { | |
| 9548 | comptime assert(fmt.len == 0); | |
| 9549 | 9549 | var first = true; |
| 9550 | 9550 | for (calling_conventions_supporting_var_args) |cc_inner| { |
| 9551 | 9551 | for (std.Target.Cpu.Arch.fromCallingConvention(cc_inner)) |supported_arch| { |
| ... | ... | @@ -9990,8 +9990,8 @@ fn finishFunc( |
| 9990 | 9990 | .bad_arch => |allowed_archs| { |
| 9991 | 9991 | const ArchListFormatter = struct { |
| 9992 | 9992 | archs: []const std.Target.Cpu.Arch, |
| 9993 | pub fn format(formatter: @This(), bw: *std.io.BufferedWriter, comptime fmt: []const u8) !void { | |
| 9994 | _ = fmt; | |
| 9993 | pub fn format(formatter: @This(), bw: *std.io.Writer, comptime fmt: []const u8) !void { | |
| 9994 | comptime assert(fmt.len == 0); | |
| 9995 | 9995 | for (formatter.archs, 0..) |arch, i| { |
| 9996 | 9996 | if (i != 0) |
| 9997 | 9997 | try bw.writeAll(", "); |
src/Type.zig+5-4| ... | ... | @@ -18,6 +18,7 @@ const Alignment = InternPool.Alignment; |
| 18 | 18 | const Zir = std.zig.Zir; |
| 19 | 19 | const Type = @This(); |
| 20 | 20 | const SemaError = Zcu.SemaError; |
| 21 | const Writer = std.io.Writer; | |
| 21 | 22 | |
| 22 | 23 | ip_index: InternPool.Index, |
| 23 | 24 | |
| ... | ... | @@ -121,7 +122,7 @@ pub fn eql(a: Type, b: Type, zcu: *const Zcu) bool { |
| 121 | 122 | return a.toIntern() == b.toIntern(); |
| 122 | 123 | } |
| 123 | 124 | |
| 124 | pub fn format(ty: Type, bw: *std.io.BufferedWriter, comptime f: []const u8) !usize { | |
| 125 | pub fn format(ty: Type, bw: *Writer, comptime f: []const u8) !usize { | |
| 125 | 126 | _ = ty; |
| 126 | 127 | _ = f; |
| 127 | 128 | _ = bw; |
| ... | ... | @@ -142,7 +143,7 @@ const FormatContext = struct { |
| 142 | 143 | pt: Zcu.PerThread, |
| 143 | 144 | }; |
| 144 | 145 | |
| 145 | fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime f: []const u8) !void { | |
| 146 | fn format2(ctx: FormatContext, bw: *Writer, comptime f: []const u8) !void { | |
| 146 | 147 | comptime assert(f.len == 0); |
| 147 | 148 | try print(ctx.ty, bw, ctx.pt); |
| 148 | 149 | } |
| ... | ... | @@ -153,14 +154,14 @@ pub fn fmtDebug(ty: Type) std.fmt.Formatter(dump) { |
| 153 | 154 | |
| 154 | 155 | /// This is a debug function. In order to print types in a meaningful way |
| 155 | 156 | /// we also need access to the module. |
| 156 | pub fn dump(start_type: Type, bw: *std.io.BufferedWriter, comptime unused_format_string: []const u8) !void { | |
| 157 | pub fn dump(start_type: Type, bw: *Writer, comptime unused_format_string: []const u8) !void { | |
| 157 | 158 | comptime assert(unused_format_string.len == 0); |
| 158 | 159 | return bw.print("{any}", .{start_type.ip_index}); |
| 159 | 160 | } |
| 160 | 161 | |
| 161 | 162 | /// Prints a name suitable for `@typeName`. |
| 162 | 163 | /// TODO: take an `opt_sema` to pass to `fmtValue` when printing sentinels. |
| 163 | pub fn print(ty: Type, bw: *std.io.BufferedWriter, pt: Zcu.PerThread) std.io.Writer.Error!void { | |
| 164 | pub fn print(ty: Type, bw: *Writer, pt: Zcu.PerThread) Writer.Error!void { | |
| 164 | 165 | const zcu = pt.zcu; |
| 165 | 166 | const ip = &zcu.intern_pool; |
| 166 | 167 | switch (ip.indexToKey(ty.toIntern())) { |
src/Zcu.zig+4-4| ... | ... | @@ -15,6 +15,7 @@ const BigIntConst = std.math.big.int.Const; |
| 15 | 15 | const BigIntMutable = std.math.big.int.Mutable; |
| 16 | 16 | const Target = std.Target; |
| 17 | 17 | const Ast = std.zig.Ast; |
| 18 | const Writer = std.io.Writer; | |
| 18 | 19 | |
| 19 | 20 | const Zcu = @This(); |
| 20 | 21 | const Compilation = @import("Compilation.zig"); |
| ... | ... | @@ -1101,8 +1102,7 @@ pub const File = struct { |
| 1101 | 1102 | const gpa = pt.zcu.gpa; |
| 1102 | 1103 | const ip = &pt.zcu.intern_pool; |
| 1103 | 1104 | const strings = ip.getLocal(pt.tid).getMutableStrings(gpa); |
| 1104 | var bw: std.io.BufferedWriter = undefined; | |
| 1105 | bw.initFixed((try strings.addManyAsSlice(file.fullyQualifiedNameLen()))[0]); | |
| 1105 | var bw: Writer = .fixed((try strings.addManyAsSlice(file.fullyQualifiedNameLen()))[0]); | |
| 1106 | 1106 | file.renderFullyQualifiedName(&bw) catch unreachable; |
| 1107 | 1107 | assert(bw.end == bw.buffer.len); |
| 1108 | 1108 | return ip.getOrPutTrailingString(gpa, pt.tid, @intCast(bw.end), .no_embedded_nulls); |
| ... | ... | @@ -4260,7 +4260,7 @@ pub fn fmtDependee(zcu: *Zcu, d: InternPool.Dependee) std.fmt.Formatter(formatDe |
| 4260 | 4260 | return .{ .data = .{ .dependee = d, .zcu = zcu } }; |
| 4261 | 4261 | } |
| 4262 | 4262 | |
| 4263 | fn formatAnalUnit(data: struct { unit: AnalUnit, zcu: *Zcu }, bw: *std.io.BufferedWriter, comptime fmt: []const u8) !void { | |
| 4263 | fn formatAnalUnit(data: struct { unit: AnalUnit, zcu: *Zcu }, bw: *Writer, comptime fmt: []const u8) !void { | |
| 4264 | 4264 | _ = fmt; |
| 4265 | 4265 | const zcu = data.zcu; |
| 4266 | 4266 | const ip = &zcu.intern_pool; |
| ... | ... | @@ -4284,7 +4284,7 @@ fn formatAnalUnit(data: struct { unit: AnalUnit, zcu: *Zcu }, bw: *std.io.Buffer |
| 4284 | 4284 | .memoized_state => return bw.writeAll("memoized_state"), |
| 4285 | 4285 | } |
| 4286 | 4286 | } |
| 4287 | fn formatDependee(data: struct { dependee: InternPool.Dependee, zcu: *Zcu }, bw: *std.io.BufferedWriter, comptime fmt: []const u8) !void { | |
| 4287 | fn formatDependee(data: struct { dependee: InternPool.Dependee, zcu: *Zcu }, bw: *Writer, comptime fmt: []const u8) !void { | |
| 4288 | 4288 | _ = fmt; |
| 4289 | 4289 | const zcu = data.zcu; |
| 4290 | 4290 | const ip = &zcu.intern_pool; |
src/arch/riscv64/CodeGen.zig+14-6| ... | ... | @@ -6,6 +6,7 @@ const mem = std.mem; |
| 6 | 6 | const math = std.math; |
| 7 | 7 | const assert = std.debug.assert; |
| 8 | 8 | const Allocator = mem.Allocator; |
| 9 | const Writer = std.io.Writer; | |
| 9 | 10 | |
| 10 | 11 | const Air = @import("../../Air.zig"); |
| 11 | 12 | const Mir = @import("Mir.zig"); |
| ... | ... | @@ -566,7 +567,8 @@ const InstTracking = struct { |
| 566 | 567 | } |
| 567 | 568 | } |
| 568 | 569 | |
| 569 | pub fn format(inst_tracking: InstTracking, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void { | |
| 570 | pub fn format(inst_tracking: InstTracking, bw: *Writer, comptime fmt: []const u8) Writer.Error!void { | |
| 571 | comptime assert(fmt.len == 0); | |
| 570 | 572 | if (!std.meta.eql(inst_tracking.long, inst_tracking.short)) try bw.print("|{}| ", .{inst_tracking.long}); |
| 571 | 573 | try bw.print("{}", .{inst_tracking.short}); |
| 572 | 574 | } |
| ... | ... | @@ -932,7 +934,7 @@ const FormatWipMirData = struct { |
| 932 | 934 | func: *Func, |
| 933 | 935 | inst: Mir.Inst.Index, |
| 934 | 936 | }; |
| 935 | fn formatWipMir(data: FormatWipMirData, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void { | |
| 937 | fn formatWipMir(data: FormatWipMirData, bw: *Writer, comptime _: []const u8) Writer.Error!void { | |
| 936 | 938 | const pt = data.func.pt; |
| 937 | 939 | const comp = pt.zcu.comp; |
| 938 | 940 | var lower: Lower = .{ |
| ... | ... | @@ -980,7 +982,7 @@ const FormatNavData = struct { |
| 980 | 982 | ip: *const InternPool, |
| 981 | 983 | nav_index: InternPool.Nav.Index, |
| 982 | 984 | }; |
| 983 | fn formatNav(data: FormatNavData, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void { | |
| 985 | fn formatNav(data: FormatNavData, bw: *Writer, comptime _: []const u8) Writer.Error!void { | |
| 984 | 986 | try bw.print("{f}", .{data.ip.getNav(data.nav_index).fqn.fmt(data.ip)}); |
| 985 | 987 | } |
| 986 | 988 | fn fmtNav(nav_index: InternPool.Nav.Index, ip: *const InternPool) std.fmt.Formatter(formatNav) { |
| ... | ... | @@ -994,8 +996,13 @@ const FormatAirData = struct { |
| 994 | 996 | func: *Func, |
| 995 | 997 | inst: Air.Inst.Index, |
| 996 | 998 | }; |
| 997 | fn formatAir(data: FormatAirData, _: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void { | |
| 998 | data.func.air.dumpInst(data.inst, data.func.pt, data.func.liveness); | |
| 999 | fn formatAir(data: FormatAirData, w: *std.io.Writer, comptime fmt: []const u8) std.io.Writer.Error!void { | |
| 1000 | comptime assert(fmt.len == 0); | |
| 1001 | // not acceptable implementation: | |
| 1002 | // data.func.air.dumpInst(data.inst, data.func.pt, data.func.liveness); | |
| 1003 | _ = data; | |
| 1004 | _ = w; | |
| 1005 | @panic("TODO: unimplemented"); | |
| 999 | 1006 | } |
| 1000 | 1007 | fn fmtAir(func: *Func, inst: Air.Inst.Index) std.fmt.Formatter(formatAir) { |
| 1001 | 1008 | return .{ .data = .{ .func = func, .inst = inst } }; |
| ... | ... | @@ -1004,7 +1011,8 @@ fn fmtAir(func: *Func, inst: Air.Inst.Index) std.fmt.Formatter(formatAir) { |
| 1004 | 1011 | const FormatTrackingData = struct { |
| 1005 | 1012 | func: *Func, |
| 1006 | 1013 | }; |
| 1007 | fn formatTracking(data: FormatTrackingData, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void { | |
| 1014 | fn formatTracking(data: FormatTrackingData, bw: *Writer, comptime fmt: []const u8) Writer.Error!void { | |
| 1015 | comptime assert(fmt.len == 0); | |
| 1008 | 1016 | var it = data.func.inst_tracking.iterator(); |
| 1009 | 1017 | while (it.next()) |entry| try bw.print("\n%{d} = {f}", .{ entry.key_ptr.*, entry.value_ptr.* }); |
| 1010 | 1018 | } |
src/arch/riscv64/Mir.zig+1-1| ... | ... | @@ -92,7 +92,7 @@ pub const Inst = struct { |
| 92 | 92 | }, |
| 93 | 93 | }; |
| 94 | 94 | |
| 95 | pub fn format(inst: Inst, bw: *std.io.BufferedWriter, comptime fmt: []const u8) !void { | |
| 95 | pub fn format(inst: Inst, bw: *std.io.Writer, comptime fmt: []const u8) !void { | |
| 96 | 96 | assert(fmt.len == 0); |
| 97 | 97 | try bw.print("Tag: {s}, Data: {s}", .{ @tagName(inst.tag), @tagName(inst.data) }); |
| 98 | 98 | } |
src/arch/riscv64/bits.zig+3-1| ... | ... | @@ -2,6 +2,7 @@ const std = @import("std"); |
| 2 | 2 | const assert = std.debug.assert; |
| 3 | 3 | const testing = std.testing; |
| 4 | 4 | const Target = std.Target; |
| 5 | const Writer = std.io.Writer; | |
| 5 | 6 | |
| 6 | 7 | const Zcu = @import("../../Zcu.zig"); |
| 7 | 8 | const Mir = @import("Mir.zig"); |
| ... | ... | @@ -256,7 +257,8 @@ pub const FrameIndex = enum(u32) { |
| 256 | 257 | return @intFromEnum(fi) < named_count; |
| 257 | 258 | } |
| 258 | 259 | |
| 259 | pub fn format(fi: FrameIndex, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void { | |
| 260 | pub fn format(fi: FrameIndex, bw: *Writer, comptime fmt: []const u8) Writer.Error!void { | |
| 261 | comptime assert(fmt.len == 0); | |
| 260 | 262 | try bw.writeAll("FrameIndex"); |
| 261 | 263 | if (fi.isNamed()) |
| 262 | 264 | try bw.print(".{s}", .{@tagName(fi)}) |
src/arch/wasm/CodeGen.zig+1| ... | ... | @@ -5,6 +5,7 @@ const assert = std.debug.assert; |
| 5 | 5 | const testing = std.testing; |
| 6 | 6 | const mem = std.mem; |
| 7 | 7 | const log = std.log.scoped(.codegen); |
| 8 | const Writer = std.io.Writer; | |
| 8 | 9 | |
| 9 | 10 | const CodeGen = @This(); |
| 10 | 11 | const codegen = @import("../../codegen.zig"); |
src/arch/wasm/Emit.zig+7-6| ... | ... | @@ -4,6 +4,7 @@ const std = @import("std"); |
| 4 | 4 | const assert = std.debug.assert; |
| 5 | 5 | const Allocator = std.mem.Allocator; |
| 6 | 6 | const leb = std.leb; |
| 7 | const Writer = std.io.Writer; | |
| 7 | 8 | |
| 8 | 9 | const Wasm = link.File.Wasm; |
| 9 | 10 | const Mir = @import("Mir.zig"); |
| ... | ... | @@ -15,7 +16,7 @@ const codegen = @import("../../codegen.zig"); |
| 15 | 16 | mir: Mir, |
| 16 | 17 | wasm: *Wasm, |
| 17 | 18 | /// The binary representation of this module is written here. |
| 18 | bw: *std.io.BufferedWriter, | |
| 19 | bw: *Writer, | |
| 19 | 20 | |
| 20 | 21 | pub const Error = error{ |
| 21 | 22 | OutOfMemory, |
| ... | ... | @@ -893,12 +894,12 @@ pub fn lowerToCode(emit: *Emit) Error!void { |
| 893 | 894 | } |
| 894 | 895 | |
| 895 | 896 | /// Asserts 20 unused capacity. |
| 896 | fn encodeMemArg(bw: *std.io.BufferedWriter, mem_arg: Mir.MemArg) std.io.Writer.Error!void { | |
| 897 | fn encodeMemArg(bw: *Writer, mem_arg: Mir.MemArg) Writer.Error!void { | |
| 897 | 898 | try bw.writeLeb128(Wasm.Alignment.fromNonzeroByteUnits(mem_arg.alignment).toLog2Units()); |
| 898 | 899 | try bw.writeLeb128(mem_arg.offset); |
| 899 | 900 | } |
| 900 | 901 | |
| 901 | fn uavRefObj(wasm: *Wasm, bw: *std.io.BufferedWriter, value: InternPool.Index, offset: i32, is_wasm32: bool) std.io.Writer.Error!void { | |
| 902 | fn uavRefObj(wasm: *Wasm, bw: *Writer, value: InternPool.Index, offset: i32, is_wasm32: bool) Writer.Error!void { | |
| 902 | 903 | const comp = wasm.base.comp; |
| 903 | 904 | const gpa = comp.gpa; |
| 904 | 905 | const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const; |
| ... | ... | @@ -914,7 +915,7 @@ fn uavRefObj(wasm: *Wasm, bw: *std.io.BufferedWriter, value: InternPool.Index, o |
| 914 | 915 | try bw.splatByteAll(0, if (is_wasm32) 5 else 10); |
| 915 | 916 | } |
| 916 | 917 | |
| 917 | fn uavRefExe(wasm: *Wasm, bw: *std.io.BufferedWriter, value: InternPool.Index, offset: i32, is_wasm32: bool) !void { | |
| 918 | fn uavRefExe(wasm: *Wasm, bw: *Writer, value: InternPool.Index, offset: i32, is_wasm32: bool) !void { | |
| 918 | 919 | const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const; |
| 919 | 920 | try bw.writeByte(@intFromEnum(opcode)); |
| 920 | 921 | |
| ... | ... | @@ -922,7 +923,7 @@ fn uavRefExe(wasm: *Wasm, bw: *std.io.BufferedWriter, value: InternPool.Index, o |
| 922 | 923 | try bw.writeLeb128(@as(u32, @intCast(@as(i64, addr) + offset))); |
| 923 | 924 | } |
| 924 | 925 | |
| 925 | fn navRefOff(wasm: *Wasm, bw: *std.io.BufferedWriter, data: Mir.NavRefOff, is_wasm32: bool) !void { | |
| 926 | fn navRefOff(wasm: *Wasm, bw: *Writer, data: Mir.NavRefOff, is_wasm32: bool) !void { | |
| 926 | 927 | const comp = wasm.base.comp; |
| 927 | 928 | const zcu = comp.zcu.?; |
| 928 | 929 | const ip = &zcu.intern_pool; |
| ... | ... | @@ -947,6 +948,6 @@ fn navRefOff(wasm: *Wasm, bw: *std.io.BufferedWriter, data: Mir.NavRefOff, is_wa |
| 947 | 948 | } |
| 948 | 949 | } |
| 949 | 950 | |
| 950 | fn appendOutputFunctionIndex(bw: *std.io.BufferedWriter, i: Wasm.OutputFunctionIndex) std.io.Writer.Error!void { | |
| 951 | fn appendOutputFunctionIndex(bw: *Writer, i: Wasm.OutputFunctionIndex) Writer.Error!void { | |
| 951 | 952 | return bw.writeLeb128(@intFromEnum(i)); |
| 952 | 953 | } |
src/arch/x86_64/CodeGen.zig+14-7| ... | ... | @@ -6,6 +6,7 @@ const log = std.log.scoped(.codegen); |
| 6 | 6 | const tracking_log = std.log.scoped(.tracking); |
| 7 | 7 | const verbose_tracking_log = std.log.scoped(.verbose_tracking); |
| 8 | 8 | const wip_mir_log = std.log.scoped(.wip_mir); |
| 9 | const Writer = std.io.Writer; | |
| 9 | 10 | |
| 10 | 11 | const Air = @import("../../Air.zig"); |
| 11 | 12 | const Allocator = std.mem.Allocator; |
| ... | ... | @@ -524,7 +525,7 @@ pub const MCValue = union(enum) { |
| 524 | 525 | }; |
| 525 | 526 | } |
| 526 | 527 | |
| 527 | pub fn format(mcv: MCValue, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void { | |
| 528 | pub fn format(mcv: MCValue, bw: *Writer, comptime _: []const u8) Writer.Error!void { | |
| 528 | 529 | switch (mcv) { |
| 529 | 530 | .none, .unreach, .dead, .undef => try bw.print("({s})", .{@tagName(mcv)}), |
| 530 | 531 | .immediate => |pl| try bw.print("0x{x}", .{pl}), |
| ... | ... | @@ -811,7 +812,7 @@ const InstTracking = struct { |
| 811 | 812 | } |
| 812 | 813 | } |
| 813 | 814 | |
| 814 | pub fn format(tracking: InstTracking, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void { | |
| 815 | pub fn format(tracking: InstTracking, bw: *Writer, comptime _: []const u8) Writer.Error!void { | |
| 815 | 816 | if (!std.meta.eql(tracking.long, tracking.short)) try bw.print("|{f}| ", .{tracking.long}); |
| 816 | 817 | try bw.print("{f}", .{tracking.short}); |
| 817 | 818 | } |
| ... | ... | @@ -1087,7 +1088,7 @@ const FormatNavData = struct { |
| 1087 | 1088 | ip: *const InternPool, |
| 1088 | 1089 | nav_index: InternPool.Nav.Index, |
| 1089 | 1090 | }; |
| 1090 | fn formatNav(data: FormatNavData, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void { | |
| 1091 | fn formatNav(data: FormatNavData, bw: *Writer, comptime _: []const u8) Writer.Error!void { | |
| 1091 | 1092 | try bw.print("{f}", .{data.ip.getNav(data.nav_index).fqn.fmt(data.ip)}); |
| 1092 | 1093 | } |
| 1093 | 1094 | fn fmtNav(nav_index: InternPool.Nav.Index, ip: *const InternPool) std.fmt.Formatter(formatNav) { |
| ... | ... | @@ -1101,8 +1102,13 @@ const FormatAirData = struct { |
| 1101 | 1102 | self: *CodeGen, |
| 1102 | 1103 | inst: Air.Inst.Index, |
| 1103 | 1104 | }; |
| 1104 | fn formatAir(data: FormatAirData, _: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void { | |
| 1105 | data.self.air.dumpInst(data.inst, data.self.pt, data.self.liveness); | |
| 1105 | fn formatAir(data: FormatAirData, w: *std.io.Writer, comptime fmt: []const u8) Writer.Error!void { | |
| 1106 | comptime assert(fmt.len == 0); | |
| 1107 | // not acceptable implementation: | |
| 1108 | //data.self.air.dumpInst(data.inst, data.self.pt, data.self.liveness); | |
| 1109 | _ = data; | |
| 1110 | _ = w; | |
| 1111 | @panic("TODO: unimplemented"); | |
| 1106 | 1112 | } |
| 1107 | 1113 | fn fmtAir(self: *CodeGen, inst: Air.Inst.Index) std.fmt.Formatter(formatAir) { |
| 1108 | 1114 | return .{ .data = .{ .self = self, .inst = inst } }; |
| ... | ... | @@ -1112,7 +1118,7 @@ const FormatWipMirData = struct { |
| 1112 | 1118 | self: *CodeGen, |
| 1113 | 1119 | inst: Mir.Inst.Index, |
| 1114 | 1120 | }; |
| 1115 | fn formatWipMir(data: FormatWipMirData, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void { | |
| 1121 | fn formatWipMir(data: FormatWipMirData, bw: *Writer, comptime _: []const u8) Writer.Error!void { | |
| 1116 | 1122 | var lower: Lower = .{ |
| 1117 | 1123 | .target = data.self.target, |
| 1118 | 1124 | .allocator = data.self.gpa, |
| ... | ... | @@ -1208,7 +1214,8 @@ fn fmtWipMir(self: *CodeGen, inst: Mir.Inst.Index) std.fmt.Formatter(formatWipMi |
| 1208 | 1214 | const FormatTrackingData = struct { |
| 1209 | 1215 | self: *CodeGen, |
| 1210 | 1216 | }; |
| 1211 | fn formatTracking(data: FormatTrackingData, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void { | |
| 1217 | fn formatTracking(data: FormatTrackingData, bw: *Writer, comptime fmt: []const u8) Writer.Error!void { | |
| 1218 | comptime assert(fmt.len == 0); | |
| 1212 | 1219 | var it = data.self.inst_tracking.iterator(); |
| 1213 | 1220 | while (it.next()) |entry| try bw.print("\n{f} = {f}", .{ entry.key_ptr.*, entry.value_ptr.* }); |
| 1214 | 1221 | } |
src/arch/x86_64/Disassembler.zig+2-4| ... | ... | @@ -372,8 +372,7 @@ fn parseGpRegister(low_enc: u3, is_extended: bool, rex: Rex, bit_size: u64) Regi |
| 372 | 372 | } |
| 373 | 373 | |
| 374 | 374 | fn parseImm(dis: *Disassembler, kind: Encoding.Op) !Immediate { |
| 375 | var br: std.io.Reader = undefined; | |
| 376 | br.initFixed(dis.code[dis.pos..]); | |
| 375 | var br: std.io.Reader = .fixed(dis.code[dis.pos..]); | |
| 377 | 376 | defer dis.pos += br.seek; |
| 378 | 377 | return switch (kind) { |
| 379 | 378 | .imm8s, .rel8 => .s(try br.takeInt(i8, .little)), |
| ... | ... | @@ -388,8 +387,7 @@ fn parseImm(dis: *Disassembler, kind: Encoding.Op) !Immediate { |
| 388 | 387 | } |
| 389 | 388 | |
| 390 | 389 | fn parseOffset(dis: *Disassembler) !u64 { |
| 391 | var br: std.io.Reader = undefined; | |
| 392 | br.initFixed(dis.code[dis.pos..]); | |
| 390 | var br: std.io.Reader = .fixed(dis.code[dis.pos..]); | |
| 393 | 391 | defer dis.pos += br.seek; |
| 394 | 392 | return br.takeInt(u64, .little); |
| 395 | 393 | } |
src/arch/x86_64/Encoding.zig+4-4| ... | ... | @@ -3,6 +3,7 @@ const Encoding = @This(); |
| 3 | 3 | const std = @import("std"); |
| 4 | 4 | const assert = std.debug.assert; |
| 5 | 5 | const math = std.math; |
| 6 | const Writer = std.io.Writer; | |
| 6 | 7 | |
| 7 | 8 | const bits = @import("bits.zig"); |
| 8 | 9 | const encoder = @import("encoder.zig"); |
| ... | ... | @@ -158,8 +159,8 @@ pub fn modRmExt(encoding: Encoding) u3 { |
| 158 | 159 | }; |
| 159 | 160 | } |
| 160 | 161 | |
| 161 | pub fn format(encoding: Encoding, bw: *std.io.BufferedWriter, comptime fmt: []const u8) !void { | |
| 162 | _ = fmt; | |
| 162 | pub fn format(encoding: Encoding, bw: *Writer, comptime fmt: []const u8) !void { | |
| 163 | comptime assert(fmt.len == 0); | |
| 163 | 164 | |
| 164 | 165 | var opc = encoding.opcode(); |
| 165 | 166 | if (encoding.data.mode.isVex()) { |
| ... | ... | @@ -1016,8 +1017,7 @@ fn estimateInstructionLength(prefix: Prefix, encoding: Encoding, ops: []const Op |
| 1016 | 1017 | @memcpy(inst.ops[0..ops.len], ops); |
| 1017 | 1018 | |
| 1018 | 1019 | var buf: [15]u8 = undefined; |
| 1019 | var bw: std.io.BufferedWriter = undefined; | |
| 1020 | bw.initFixed(&buf); | |
| 1020 | var bw: Writer = .fixed(&buf); | |
| 1021 | 1021 | inst.encode(&bw, .{ |
| 1022 | 1022 | .allow_frame_locs = true, |
| 1023 | 1023 | .allow_symbols = true, |
src/arch/x86_64/bits.zig+6-2| ... | ... | @@ -6,6 +6,8 @@ const Allocator = std.mem.Allocator; |
| 6 | 6 | const ArrayList = std.ArrayList; |
| 7 | 7 | const InternPool = @import("../../InternPool.zig"); |
| 8 | 8 | const link = @import("../../link.zig"); |
| 9 | const Writer = std.io.Writer; | |
| 10 | ||
| 9 | 11 | const Mir = @import("Mir.zig"); |
| 10 | 12 | |
| 11 | 13 | /// EFLAGS condition codes |
| ... | ... | @@ -728,7 +730,8 @@ pub const FrameIndex = enum(u32) { |
| 728 | 730 | return @intFromEnum(fi) < named_count; |
| 729 | 731 | } |
| 730 | 732 | |
| 731 | pub fn format(fi: FrameIndex, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void { | |
| 733 | pub fn format(fi: FrameIndex, bw: *Writer, comptime fmt: []const u8) Writer.Error!void { | |
| 734 | comptime assert(fmt.len == 0); | |
| 732 | 735 | try bw.writeAll("FrameIndex"); |
| 733 | 736 | if (fi.isNamed()) |
| 734 | 737 | try bw.print(".{s}", .{@tagName(fi)}) |
| ... | ... | @@ -835,7 +838,8 @@ pub const Memory = struct { |
| 835 | 838 | }; |
| 836 | 839 | } |
| 837 | 840 | |
| 838 | pub fn format(s: Size, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void { | |
| 841 | pub fn format(s: Size, bw: *Writer, comptime fmt: []const u8) Writer.Error!void { | |
| 842 | comptime assert(fmt.len == 0); | |
| 839 | 843 | if (s == .none) return; |
| 840 | 844 | try bw.writeAll(@tagName(s)); |
| 841 | 845 | switch (s) { |
src/arch/x86_64/encoder.zig+7-6| ... | ... | @@ -3,6 +3,7 @@ const assert = std.debug.assert; |
| 3 | 3 | const log = std.log.scoped(.x86_64_encoder); |
| 4 | 4 | const math = std.math; |
| 5 | 5 | const testing = std.testing; |
| 6 | const Writer = std.io.Writer; | |
| 6 | 7 | |
| 7 | 8 | const bits = @import("bits.zig"); |
| 8 | 9 | const Encoding = @import("Encoding.zig"); |
| ... | ... | @@ -226,7 +227,7 @@ pub const Instruction = struct { |
| 226 | 227 | }; |
| 227 | 228 | } |
| 228 | 229 | |
| 229 | fn format(op: Operand, bw: *std.io.BufferedWriter, comptime unused_format_string: []const u8) !void { | |
| 230 | fn format(op: Operand, bw: *Writer, comptime unused_format_string: []const u8) !void { | |
| 230 | 231 | _ = op; |
| 231 | 232 | _ = bw; |
| 232 | 233 | _ = unused_format_string; |
| ... | ... | @@ -238,7 +239,7 @@ pub const Instruction = struct { |
| 238 | 239 | enc_op: Encoding.Op, |
| 239 | 240 | }; |
| 240 | 241 | |
| 241 | fn fmtContext(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_format_string: []const u8) std.io.Writer.Error!void { | |
| 242 | fn fmtContext(ctx: FormatContext, bw: *Writer, comptime unused_format_string: []const u8) Writer.Error!void { | |
| 242 | 243 | _ = unused_format_string; |
| 243 | 244 | const op = ctx.op; |
| 244 | 245 | const enc_op = ctx.enc_op; |
| ... | ... | @@ -360,7 +361,7 @@ pub const Instruction = struct { |
| 360 | 361 | return inst; |
| 361 | 362 | } |
| 362 | 363 | |
| 363 | pub fn format(inst: Instruction, bw: *std.io.BufferedWriter, comptime unused_format_string: []const u8) std.io.Writer.Error!void { | |
| 364 | pub fn format(inst: Instruction, bw: *Writer, comptime unused_format_string: []const u8) Writer.Error!void { | |
| 364 | 365 | _ = unused_format_string; |
| 365 | 366 | switch (inst.prefix) { |
| 366 | 367 | .none, .directive => {}, |
| ... | ... | @@ -374,7 +375,7 @@ pub const Instruction = struct { |
| 374 | 375 | } |
| 375 | 376 | } |
| 376 | 377 | |
| 377 | pub fn encode(inst: Instruction, bw: *std.io.BufferedWriter, comptime opts: Options) !void { | |
| 378 | pub fn encode(inst: Instruction, bw: *Writer, comptime opts: Options) !void { | |
| 378 | 379 | assert(inst.prefix != .directive); |
| 379 | 380 | const encoder: Encoder(opts) = .{ .bw = bw }; |
| 380 | 381 | const enc = inst.encoding; |
| ... | ... | @@ -784,7 +785,7 @@ pub const Options = struct { allow_frame_locs: bool = false, allow_symbols: bool |
| 784 | 785 | |
| 785 | 786 | fn Encoder(comptime opts: Options) type { |
| 786 | 787 | return struct { |
| 787 | bw: *std.io.BufferedWriter, | |
| 788 | bw: *Writer, | |
| 788 | 789 | |
| 789 | 790 | const Self = @This(); |
| 790 | 791 | pub const options = opts; |
| ... | ... | @@ -2198,7 +2199,7 @@ const Assembler = struct { |
| 2198 | 2199 | }; |
| 2199 | 2200 | } |
| 2200 | 2201 | |
| 2201 | pub fn assemble(as: *Assembler, bw: *std.io.BufferedWriter) !void { | |
| 2202 | pub fn assemble(as: *Assembler, bw: *Writer) !void { | |
| 2202 | 2203 | while (try as.next()) |parsed_inst| { |
| 2203 | 2204 | const inst: Instruction = try .new(.none, parsed_inst.mnemonic, &parsed_inst.ops); |
| 2204 | 2205 | try inst.encode(bw, .{}); |
src/codegen.zig+5-4| ... | ... | @@ -8,6 +8,7 @@ const mem = std.mem; |
| 8 | 8 | const math = std.math; |
| 9 | 9 | const target_util = @import("target.zig"); |
| 10 | 10 | const trace = @import("tracy.zig").trace; |
| 11 | const Writer = std.io.Writer; | |
| 11 | 12 | |
| 12 | 13 | const Air = @import("Air.zig"); |
| 13 | 14 | const Allocator = mem.Allocator; |
| ... | ... | @@ -326,7 +327,7 @@ pub fn generateSymbolInner( |
| 326 | 327 | pt: Zcu.PerThread, |
| 327 | 328 | src_loc: Zcu.LazySrcLoc, |
| 328 | 329 | val: Value, |
| 329 | bw: *std.io.BufferedWriter, | |
| 330 | bw: *Writer, | |
| 330 | 331 | reloc_parent: link.File.RelocInfo.Parent, |
| 331 | 332 | ) GenerateSymbolError!void { |
| 332 | 333 | const zcu = pt.zcu; |
| ... | ... | @@ -707,7 +708,7 @@ fn lowerPtr( |
| 707 | 708 | pt: Zcu.PerThread, |
| 708 | 709 | src_loc: Zcu.LazySrcLoc, |
| 709 | 710 | ptr_val: InternPool.Index, |
| 710 | bw: *std.io.BufferedWriter, | |
| 711 | bw: *Writer, | |
| 711 | 712 | reloc_parent: link.File.RelocInfo.Parent, |
| 712 | 713 | prev_offset: u64, |
| 713 | 714 | ) GenerateSymbolError!void { |
| ... | ... | @@ -760,7 +761,7 @@ fn lowerUavRef( |
| 760 | 761 | pt: Zcu.PerThread, |
| 761 | 762 | src_loc: Zcu.LazySrcLoc, |
| 762 | 763 | uav: InternPool.Key.Ptr.BaseAddr.Uav, |
| 763 | bw: *std.io.BufferedWriter, | |
| 764 | bw: *Writer, | |
| 764 | 765 | reloc_parent: link.File.RelocInfo.Parent, |
| 765 | 766 | offset: u64, |
| 766 | 767 | ) GenerateSymbolError!void { |
| ... | ... | @@ -814,7 +815,7 @@ fn lowerNavRef( |
| 814 | 815 | lf: *link.File, |
| 815 | 816 | pt: Zcu.PerThread, |
| 816 | 817 | nav_index: InternPool.Nav.Index, |
| 817 | bw: *std.io.BufferedWriter, | |
| 818 | bw: *Writer, | |
| 818 | 819 | reloc_parent: link.File.RelocInfo.Parent, |
| 819 | 820 | offset: u64, |
| 820 | 821 | ) GenerateSymbolError!void { |
src/codegen/c.zig+68-67| ... | ... | @@ -4,6 +4,7 @@ const assert = std.debug.assert; |
| 4 | 4 | const mem = std.mem; |
| 5 | 5 | const log = std.log.scoped(.c); |
| 6 | 6 | const Allocator = mem.Allocator; |
| 7 | const Writer = std.io.Writer; | |
| 7 | 8 | |
| 8 | 9 | const dev = @import("../dev.zig"); |
| 9 | 10 | const link = @import("../link.zig"); |
| ... | ... | @@ -69,7 +70,7 @@ pub const Mir = struct { |
| 69 | 70 | } |
| 70 | 71 | }; |
| 71 | 72 | |
| 72 | pub const Error = std.io.Writer.Error || std.mem.Allocator.Error || error{AnalysisFail}; | |
| 73 | pub const Error = Writer.Error || std.mem.Allocator.Error || error{AnalysisFail}; | |
| 73 | 74 | |
| 74 | 75 | pub const CType = @import("c/Type.zig"); |
| 75 | 76 | |
| ... | ... | @@ -344,9 +345,9 @@ fn isReservedIdent(ident: []const u8) bool { |
| 344 | 345 | |
| 345 | 346 | fn formatIdent( |
| 346 | 347 | ident: []const u8, |
| 347 | bw: *std.io.BufferedWriter, | |
| 348 | bw: *Writer, | |
| 348 | 349 | comptime fmt_str: []const u8, |
| 349 | ) std.io.Writer.Error!void { | |
| 350 | ) Writer.Error!void { | |
| 350 | 351 | const solo = fmt_str.len != 0 and fmt_str[0] == ' '; // space means solo; not part of a bigger ident. |
| 351 | 352 | if (solo and isReservedIdent(ident)) { |
| 352 | 353 | try bw.writeAll("zig_e_"); |
| ... | ... | @@ -374,9 +375,9 @@ const CTypePoolStringFormatData = struct { |
| 374 | 375 | }; |
| 375 | 376 | fn formatCTypePoolString( |
| 376 | 377 | data: CTypePoolStringFormatData, |
| 377 | bw: *std.io.BufferedWriter, | |
| 378 | bw: *Writer, | |
| 378 | 379 | comptime fmt_str: []const u8, |
| 379 | ) std.io.Writer.Error!void { | |
| 380 | ) Writer.Error!void { | |
| 380 | 381 | if (data.ctype_pool_string.toSlice(data.ctype_pool)) |slice| |
| 381 | 382 | try formatIdent(slice, bw, fmt_str) |
| 382 | 383 | else |
| ... | ... | @@ -504,7 +505,7 @@ pub const Function = struct { |
| 504 | 505 | return result; |
| 505 | 506 | } |
| 506 | 507 | |
| 507 | fn writeCValue(f: *Function, bw: *std.io.BufferedWriter, c_value: CValue, location: ValueRenderLocation) !void { | |
| 508 | fn writeCValue(f: *Function, bw: *Writer, c_value: CValue, location: ValueRenderLocation) !void { | |
| 508 | 509 | switch (c_value) { |
| 509 | 510 | .none => unreachable, |
| 510 | 511 | .new_local, .local => |i| try bw.print("t{d}", .{i}), |
| ... | ... | @@ -517,7 +518,7 @@ pub const Function = struct { |
| 517 | 518 | } |
| 518 | 519 | } |
| 519 | 520 | |
| 520 | fn writeCValueDeref(f: *Function, bw: *std.io.BufferedWriter, c_value: CValue) !void { | |
| 521 | fn writeCValueDeref(f: *Function, bw: *Writer, c_value: CValue) !void { | |
| 521 | 522 | switch (c_value) { |
| 522 | 523 | .none => unreachable, |
| 523 | 524 | .new_local, .local, .constant => { |
| ... | ... | @@ -538,7 +539,7 @@ pub const Function = struct { |
| 538 | 539 | |
| 539 | 540 | fn writeCValueMember( |
| 540 | 541 | f: *Function, |
| 541 | bw: *std.io.BufferedWriter, | |
| 542 | bw: *Writer, | |
| 542 | 543 | c_value: CValue, |
| 543 | 544 | member: CValue, |
| 544 | 545 | ) Error!void { |
| ... | ... | @@ -552,7 +553,7 @@ pub const Function = struct { |
| 552 | 553 | } |
| 553 | 554 | } |
| 554 | 555 | |
| 555 | fn writeCValueDerefMember(f: *Function, bw: *std.io.BufferedWriter, c_value: CValue, member: CValue) !void { | |
| 556 | fn writeCValueDerefMember(f: *Function, bw: *Writer, c_value: CValue, member: CValue) !void { | |
| 556 | 557 | switch (c_value) { |
| 557 | 558 | .new_local, .local, .arg, .arg_array => { |
| 558 | 559 | try f.writeCValue(bw, c_value, .Other); |
| ... | ... | @@ -584,15 +585,15 @@ pub const Function = struct { |
| 584 | 585 | return f.object.dg.byteSize(ctype); |
| 585 | 586 | } |
| 586 | 587 | |
| 587 | fn renderType(f: *Function, bw: *std.io.BufferedWriter, ctype: Type) !void { | |
| 588 | fn renderType(f: *Function, bw: *Writer, ctype: Type) !void { | |
| 588 | 589 | return f.object.dg.renderType(bw, ctype); |
| 589 | 590 | } |
| 590 | 591 | |
| 591 | fn renderCType(f: *Function, bw: *std.io.BufferedWriter, ctype: CType) !void { | |
| 592 | fn renderCType(f: *Function, bw: *Writer, ctype: CType) !void { | |
| 592 | 593 | return f.object.dg.renderCType(bw, ctype); |
| 593 | 594 | } |
| 594 | 595 | |
| 595 | fn renderIntCast(f: *Function, bw: *std.io.BufferedWriter, dest_ty: Type, src: CValue, v: Vectorize, src_ty: Type, location: ValueRenderLocation) !void { | |
| 596 | fn renderIntCast(f: *Function, bw: *Writer, dest_ty: Type, src: CValue, v: Vectorize, src_ty: Type, location: ValueRenderLocation) !void { | |
| 596 | 597 | return f.object.dg.renderIntCast(bw, dest_ty, .{ .c_value = .{ .f = f, .value = src, .v = v } }, src_ty, location); |
| 597 | 598 | } |
| 598 | 599 | |
| ... | ... | @@ -757,7 +758,7 @@ pub const DeclGen = struct { |
| 757 | 758 | |
| 758 | 759 | fn renderUav( |
| 759 | 760 | dg: *DeclGen, |
| 760 | bw: *std.io.BufferedWriter, | |
| 761 | bw: *Writer, | |
| 761 | 762 | uav: InternPool.Key.Ptr.BaseAddr.Uav, |
| 762 | 763 | location: ValueRenderLocation, |
| 763 | 764 | ) Error!void { |
| ... | ... | @@ -819,7 +820,7 @@ pub const DeclGen = struct { |
| 819 | 820 | |
| 820 | 821 | fn renderNav( |
| 821 | 822 | dg: *DeclGen, |
| 822 | bw: *std.io.BufferedWriter, | |
| 823 | bw: *Writer, | |
| 823 | 824 | nav_index: InternPool.Nav.Index, |
| 824 | 825 | location: ValueRenderLocation, |
| 825 | 826 | ) Error!void { |
| ... | ... | @@ -868,7 +869,7 @@ pub const DeclGen = struct { |
| 868 | 869 | |
| 869 | 870 | fn renderPointer( |
| 870 | 871 | dg: *DeclGen, |
| 871 | bw: *std.io.BufferedWriter, | |
| 872 | bw: *Writer, | |
| 872 | 873 | derivation: Value.PointerDeriveStep, |
| 873 | 874 | location: ValueRenderLocation, |
| 874 | 875 | ) Error!void { |
| ... | ... | @@ -972,13 +973,13 @@ pub const DeclGen = struct { |
| 972 | 973 | } |
| 973 | 974 | } |
| 974 | 975 | |
| 975 | fn renderErrorName(dg: *DeclGen, bw: *std.io.BufferedWriter, err_name: InternPool.NullTerminatedString) !void { | |
| 976 | fn renderErrorName(dg: *DeclGen, bw: *Writer, err_name: InternPool.NullTerminatedString) !void { | |
| 976 | 977 | try bw.print("zig_error_{f}", .{fmtIdent(err_name.toSlice(&dg.pt.zcu.intern_pool))}); |
| 977 | 978 | } |
| 978 | 979 | |
| 979 | 980 | fn renderValue( |
| 980 | 981 | dg: *DeclGen, |
| 981 | writer: *std.io.BufferedWriter, | |
| 982 | writer: *Writer, | |
| 982 | 983 | val: Value, |
| 983 | 984 | location: ValueRenderLocation, |
| 984 | 985 | ) Error!void { |
| ... | ... | @@ -1587,7 +1588,7 @@ pub const DeclGen = struct { |
| 1587 | 1588 | |
| 1588 | 1589 | fn renderUndefValue( |
| 1589 | 1590 | dg: *DeclGen, |
| 1590 | bw: *std.io.BufferedWriter, | |
| 1591 | bw: *Writer, | |
| 1591 | 1592 | ty: Type, |
| 1592 | 1593 | location: ValueRenderLocation, |
| 1593 | 1594 | ) Error!void { |
| ... | ... | @@ -1890,7 +1891,7 @@ pub const DeclGen = struct { |
| 1890 | 1891 | |
| 1891 | 1892 | fn renderFunctionSignature( |
| 1892 | 1893 | dg: *DeclGen, |
| 1893 | bw: *std.io.BufferedWriter, | |
| 1894 | bw: *Writer, | |
| 1894 | 1895 | fn_val: Value, |
| 1895 | 1896 | fn_align: InternPool.Alignment, |
| 1896 | 1897 | kind: CType.Kind, |
| ... | ... | @@ -2011,11 +2012,11 @@ pub const DeclGen = struct { |
| 2011 | 2012 | /// | `renderTypeAndName` | "uint8_t *name" | "uint8_t *name[10]" | |
| 2012 | 2013 | /// | `renderType` | "uint8_t *" | "uint8_t *[10]" | |
| 2013 | 2014 | /// |
| 2014 | fn renderType(dg: *DeclGen, bw: *std.io.BufferedWriter, t: Type) Error!void { | |
| 2015 | fn renderType(dg: *DeclGen, bw: *Writer, t: Type) Error!void { | |
| 2015 | 2016 | try dg.renderCType(bw, try dg.ctypeFromType(t, .complete)); |
| 2016 | 2017 | } |
| 2017 | 2018 | |
| 2018 | fn renderCType(dg: *DeclGen, bw: *std.io.BufferedWriter, ctype: CType) Error!void { | |
| 2019 | fn renderCType(dg: *DeclGen, bw: *Writer, ctype: CType) Error!void { | |
| 2019 | 2020 | _ = try renderTypePrefix(dg.pass, &dg.ctype_pool, dg.pt.zcu, bw, ctype, .suffix, .{}); |
| 2020 | 2021 | try renderTypeSuffix(dg.pass, &dg.ctype_pool, dg.pt.zcu, bw, ctype, .suffix, .{}); |
| 2021 | 2022 | } |
| ... | ... | @@ -2030,7 +2031,7 @@ pub const DeclGen = struct { |
| 2030 | 2031 | value: Value, |
| 2031 | 2032 | }, |
| 2032 | 2033 | |
| 2033 | pub fn writeValue(self: *const IntCastContext, dg: *DeclGen, bw: *std.io.BufferedWriter, location: ValueRenderLocation) !void { | |
| 2034 | pub fn writeValue(self: *const IntCastContext, dg: *DeclGen, bw: *Writer, location: ValueRenderLocation) !void { | |
| 2034 | 2035 | switch (self.*) { |
| 2035 | 2036 | .c_value => |v| { |
| 2036 | 2037 | try v.f.writeCValue(bw, v.value, location); |
| ... | ... | @@ -2076,7 +2077,7 @@ pub const DeclGen = struct { |
| 2076 | 2077 | /// | > 64 bit integer | > 64 bit integer | zig_make_<dest_ty>(zig_hi_<src_ty>(src), zig_lo_<src_ty>(src)) |
| 2077 | 2078 | fn renderIntCast( |
| 2078 | 2079 | dg: *DeclGen, |
| 2079 | bw: *std.io.BufferedWriter, | |
| 2080 | bw: *Writer, | |
| 2080 | 2081 | dest_ty: Type, |
| 2081 | 2082 | context: IntCastContext, |
| 2082 | 2083 | src_ty: Type, |
| ... | ... | @@ -2160,7 +2161,7 @@ pub const DeclGen = struct { |
| 2160 | 2161 | /// |
| 2161 | 2162 | fn renderTypeAndName( |
| 2162 | 2163 | dg: *DeclGen, |
| 2163 | bw: *std.io.BufferedWriter, | |
| 2164 | bw: *Writer, | |
| 2164 | 2165 | ty: Type, |
| 2165 | 2166 | name: CValue, |
| 2166 | 2167 | qualifiers: CQualifiers, |
| ... | ... | @@ -2181,7 +2182,7 @@ pub const DeclGen = struct { |
| 2181 | 2182 | |
| 2182 | 2183 | fn renderCTypeAndName( |
| 2183 | 2184 | dg: *DeclGen, |
| 2184 | bw: *std.io.BufferedWriter, | |
| 2185 | bw: *Writer, | |
| 2185 | 2186 | ctype: CType, |
| 2186 | 2187 | name: CValue, |
| 2187 | 2188 | qualifiers: CQualifiers, |
| ... | ... | @@ -2201,7 +2202,7 @@ pub const DeclGen = struct { |
| 2201 | 2202 | try renderTypeSuffix(dg.pass, &dg.ctype_pool, zcu, bw, ctype, .suffix, .{}); |
| 2202 | 2203 | } |
| 2203 | 2204 | |
| 2204 | fn writeName(dg: *DeclGen, bw: *std.io.BufferedWriter, c_value: CValue) !void { | |
| 2205 | fn writeName(dg: *DeclGen, bw: *Writer, c_value: CValue) !void { | |
| 2205 | 2206 | switch (c_value) { |
| 2206 | 2207 | .new_local, .local => |i| try bw.print("t{d}", .{i}), |
| 2207 | 2208 | .constant => |uav| try renderUavName(bw, uav), |
| ... | ... | @@ -2211,7 +2212,7 @@ pub const DeclGen = struct { |
| 2211 | 2212 | } |
| 2212 | 2213 | } |
| 2213 | 2214 | |
| 2214 | fn writeCValue(dg: *DeclGen, bw: *std.io.BufferedWriter, c_value: CValue) Error!void { | |
| 2215 | fn writeCValue(dg: *DeclGen, bw: *Writer, c_value: CValue) Error!void { | |
| 2215 | 2216 | switch (c_value) { |
| 2216 | 2217 | .none, .new_local, .local, .local_ref => unreachable, |
| 2217 | 2218 | .constant => |uav| try renderUavName(bw, uav), |
| ... | ... | @@ -2234,7 +2235,7 @@ pub const DeclGen = struct { |
| 2234 | 2235 | } |
| 2235 | 2236 | } |
| 2236 | 2237 | |
| 2237 | fn writeCValueDeref(dg: *DeclGen, bw: *std.io.BufferedWriter, c_value: CValue) !void { | |
| 2238 | fn writeCValueDeref(dg: *DeclGen, bw: *Writer, c_value: CValue) !void { | |
| 2238 | 2239 | switch (c_value) { |
| 2239 | 2240 | .none, |
| 2240 | 2241 | .new_local, |
| ... | ... | @@ -2263,7 +2264,7 @@ pub const DeclGen = struct { |
| 2263 | 2264 | |
| 2264 | 2265 | fn writeCValueMember( |
| 2265 | 2266 | dg: *DeclGen, |
| 2266 | bw: *std.io.BufferedWriter, | |
| 2267 | bw: *Writer, | |
| 2267 | 2268 | c_value: CValue, |
| 2268 | 2269 | member: CValue, |
| 2269 | 2270 | ) Error!void { |
| ... | ... | @@ -2274,7 +2275,7 @@ pub const DeclGen = struct { |
| 2274 | 2275 | |
| 2275 | 2276 | fn writeCValueDerefMember( |
| 2276 | 2277 | dg: *DeclGen, |
| 2277 | bw: *std.io.BufferedWriter, | |
| 2278 | bw: *Writer, | |
| 2278 | 2279 | c_value: CValue, |
| 2279 | 2280 | member: CValue, |
| 2280 | 2281 | ) !void { |
| ... | ... | @@ -2341,7 +2342,7 @@ pub const DeclGen = struct { |
| 2341 | 2342 | try fwd.writeAll(";\n"); |
| 2342 | 2343 | } |
| 2343 | 2344 | |
| 2344 | fn renderNavName(dg: *DeclGen, bw: *std.io.BufferedWriter, nav_index: InternPool.Nav.Index) !void { | |
| 2345 | fn renderNavName(dg: *DeclGen, bw: *Writer, nav_index: InternPool.Nav.Index) !void { | |
| 2345 | 2346 | const zcu = dg.pt.zcu; |
| 2346 | 2347 | const ip = &zcu.intern_pool; |
| 2347 | 2348 | const nav = ip.getNav(nav_index); |
| ... | ... | @@ -2360,15 +2361,15 @@ pub const DeclGen = struct { |
| 2360 | 2361 | } |
| 2361 | 2362 | } |
| 2362 | 2363 | |
| 2363 | fn renderUavName(bw: *std.io.BufferedWriter, uav: Value) !void { | |
| 2364 | fn renderUavName(bw: *Writer, uav: Value) !void { | |
| 2364 | 2365 | try bw.print("__anon_{d}", .{@intFromEnum(uav.toIntern())}); |
| 2365 | 2366 | } |
| 2366 | 2367 | |
| 2367 | fn renderTypeForBuiltinFnName(dg: *DeclGen, bw: *std.io.BufferedWriter, ty: Type) !void { | |
| 2368 | fn renderTypeForBuiltinFnName(dg: *DeclGen, bw: *Writer, ty: Type) !void { | |
| 2368 | 2369 | try dg.renderCTypeForBuiltinFnName(bw, try dg.ctypeFromType(ty, .complete)); |
| 2369 | 2370 | } |
| 2370 | 2371 | |
| 2371 | fn renderCTypeForBuiltinFnName(dg: *DeclGen, bw: *std.io.BufferedWriter, ctype: CType) !void { | |
| 2372 | fn renderCTypeForBuiltinFnName(dg: *DeclGen, bw: *Writer, ctype: CType) !void { | |
| 2372 | 2373 | switch (ctype.info(&dg.ctype_pool)) { |
| 2373 | 2374 | else => |ctype_info| try bw.print("{c}{d}", .{ |
| 2374 | 2375 | if (ctype.isBool()) |
| ... | ... | @@ -2387,7 +2388,7 @@ pub const DeclGen = struct { |
| 2387 | 2388 | } |
| 2388 | 2389 | } |
| 2389 | 2390 | |
| 2390 | fn renderBuiltinInfo(dg: *DeclGen, bw: *std.io.BufferedWriter, ty: Type, info: BuiltinInfo) !void { | |
| 2391 | fn renderBuiltinInfo(dg: *DeclGen, bw: *Writer, ty: Type, info: BuiltinInfo) !void { | |
| 2391 | 2392 | const ctype = try dg.ctypeFromType(ty, .complete); |
| 2392 | 2393 | const is_big = ctype.info(&dg.ctype_pool) == .array; |
| 2393 | 2394 | switch (info) { |
| ... | ... | @@ -2436,9 +2437,9 @@ const RenderCTypeTrailing = enum { |
| 2436 | 2437 | |
| 2437 | 2438 | pub fn format( |
| 2438 | 2439 | self: @This(), |
| 2439 | bw: *std.io.BufferedWriter, | |
| 2440 | bw: *Writer, | |
| 2440 | 2441 | comptime fmt: []const u8, |
| 2441 | ) std.io.Writer.Error!void { | |
| 2442 | ) Writer.Error!void { | |
| 2442 | 2443 | if (fmt.len != 0) @compileError("invalid format string '" ++ |
| 2443 | 2444 | fmt ++ "' for type '" ++ @typeName(@This()) ++ "'"); |
| 2444 | 2445 | switch (self) { |
| ... | ... | @@ -2447,12 +2448,12 @@ const RenderCTypeTrailing = enum { |
| 2447 | 2448 | } |
| 2448 | 2449 | } |
| 2449 | 2450 | }; |
| 2450 | fn renderAlignedTypeName(bw: *std.io.BufferedWriter, ctype: CType) !void { | |
| 2451 | fn renderAlignedTypeName(bw: *Writer, ctype: CType) !void { | |
| 2451 | 2452 | try bw.print("anon__aligned_{d}", .{@intFromEnum(ctype.index)}); |
| 2452 | 2453 | } |
| 2453 | 2454 | fn renderFwdDeclTypeName( |
| 2454 | 2455 | zcu: *Zcu, |
| 2455 | bw: *std.io.BufferedWriter, | |
| 2456 | bw: *Writer, | |
| 2456 | 2457 | ctype: CType, |
| 2457 | 2458 | fwd_decl: CType.Info.FwdDecl, |
| 2458 | 2459 | attributes: []const u8, |
| ... | ... | @@ -2471,11 +2472,11 @@ fn renderTypePrefix( |
| 2471 | 2472 | pass: DeclGen.Pass, |
| 2472 | 2473 | ctype_pool: *const CType.Pool, |
| 2473 | 2474 | zcu: *Zcu, |
| 2474 | bw: *std.io.BufferedWriter, | |
| 2475 | bw: *Writer, | |
| 2475 | 2476 | ctype: CType, |
| 2476 | 2477 | parent_fix: CTypeFix, |
| 2477 | 2478 | qualifiers: CQualifiers, |
| 2478 | ) std.io.Writer.Error!RenderCTypeTrailing { | |
| 2479 | ) Writer.Error!RenderCTypeTrailing { | |
| 2479 | 2480 | var trailing = RenderCTypeTrailing.maybe_space; |
| 2480 | 2481 | switch (ctype.info(ctype_pool)) { |
| 2481 | 2482 | .basic => |basic_info| try bw.writeAll(@tagName(basic_info)), |
| ... | ... | @@ -2588,11 +2589,11 @@ fn renderTypeSuffix( |
| 2588 | 2589 | pass: DeclGen.Pass, |
| 2589 | 2590 | ctype_pool: *const CType.Pool, |
| 2590 | 2591 | zcu: *Zcu, |
| 2591 | bw: *std.io.BufferedWriter, | |
| 2592 | bw: *Writer, | |
| 2592 | 2593 | ctype: CType, |
| 2593 | 2594 | parent_fix: CTypeFix, |
| 2594 | 2595 | qualifiers: CQualifiers, |
| 2595 | ) std.io.Writer.Error!void { | |
| 2596 | ) Writer.Error!void { | |
| 2596 | 2597 | switch (ctype.info(ctype_pool)) { |
| 2597 | 2598 | .basic, .aligned, .fwd_decl, .aggregate => {}, |
| 2598 | 2599 | .pointer => |pointer_info| try renderTypeSuffix( |
| ... | ... | @@ -2644,7 +2645,7 @@ fn renderTypeSuffix( |
| 2644 | 2645 | } |
| 2645 | 2646 | fn renderFields( |
| 2646 | 2647 | zcu: *Zcu, |
| 2647 | bw: *std.io.BufferedWriter, | |
| 2648 | bw: *Writer, | |
| 2648 | 2649 | ctype_pool: *const CType.Pool, |
| 2649 | 2650 | aggregate_info: CType.Info.Aggregate, |
| 2650 | 2651 | indent: usize, |
| ... | ... | @@ -2686,7 +2687,7 @@ fn renderFields( |
| 2686 | 2687 | |
| 2687 | 2688 | pub fn genTypeDecl( |
| 2688 | 2689 | zcu: *Zcu, |
| 2689 | bw: *std.io.BufferedWriter, | |
| 2690 | bw: *Writer, | |
| 2690 | 2691 | global_ctype_pool: *const CType.Pool, |
| 2691 | 2692 | global_ctype: CType, |
| 2692 | 2693 | pass: DeclGen.Pass, |
| ... | ... | @@ -2766,7 +2767,7 @@ pub fn genTypeDecl( |
| 2766 | 2767 | } |
| 2767 | 2768 | } |
| 2768 | 2769 | |
| 2769 | pub fn genGlobalAsm(zcu: *Zcu, bw: *std.io.BufferedWriter) !void { | |
| 2770 | pub fn genGlobalAsm(zcu: *Zcu, bw: *Writer) !void { | |
| 2770 | 2771 | for (zcu.global_assembly.values()) |asm_source| { |
| 2771 | 2772 | try bw.print("__asm({fs});\n", .{fmtStringLiteral(asm_source, null)}); |
| 2772 | 2773 | } |
| ... | ... | @@ -5247,7 +5248,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal |
| 5247 | 5248 | return local; |
| 5248 | 5249 | } |
| 5249 | 5250 | |
| 5250 | fn airTrap(f: *Function, bw: *std.io.BufferedWriter) !void { | |
| 5251 | fn airTrap(f: *Function, bw: *Writer) !void { | |
| 5251 | 5252 | // Not even allowed to call trap in a naked function. |
| 5252 | 5253 | if (f.object.dg.is_naked_fn) return; |
| 5253 | 5254 | try bw.writeAll("zig_trap();\n"); |
| ... | ... | @@ -7052,7 +7053,7 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa |
| 7052 | 7053 | return .none; |
| 7053 | 7054 | } |
| 7054 | 7055 | |
| 7055 | fn writeSliceOrPtr(f: *Function, bw: *std.io.BufferedWriter, ptr: CValue, ptr_ty: Type) !void { | |
| 7056 | fn writeSliceOrPtr(f: *Function, bw: *Writer, ptr: CValue, ptr_ty: Type) !void { | |
| 7056 | 7057 | const pt = f.object.dg.pt; |
| 7057 | 7058 | const zcu = pt.zcu; |
| 7058 | 7059 | if (ptr_ty.isSlice(zcu)) { |
| ... | ... | @@ -7980,7 +7981,7 @@ fn toMemoryOrder(order: std.builtin.AtomicOrder) [:0]const u8 { |
| 7980 | 7981 | }; |
| 7981 | 7982 | } |
| 7982 | 7983 | |
| 7983 | fn writeMemoryOrder(bw: *std.io.BufferedWriter, order: std.builtin.AtomicOrder) !void { | |
| 7984 | fn writeMemoryOrder(bw: *Writer, order: std.builtin.AtomicOrder) !void { | |
| 7984 | 7985 | return bw.writeAll(toMemoryOrder(order)); |
| 7985 | 7986 | } |
| 7986 | 7987 | |
| ... | ... | @@ -8125,7 +8126,7 @@ const StringLiteral = struct { |
| 8125 | 8126 | len: usize, |
| 8126 | 8127 | cur_len: usize, |
| 8127 | 8128 | start_count: usize, |
| 8128 | bw: *std.io.BufferedWriter, | |
| 8129 | bw: *Writer, | |
| 8129 | 8130 | |
| 8130 | 8131 | // MSVC throws C2078 if an array of size 65536 or greater is initialized with a string literal, |
| 8131 | 8132 | // regardless of the length of the string literal initializing it. Array initializer syntax is |
| ... | ... | @@ -8138,7 +8139,7 @@ const StringLiteral = struct { |
| 8138 | 8139 | const max_char_len = 4; |
| 8139 | 8140 | const max_literal_len = @min(16380 - max_char_len, 4095); |
| 8140 | 8141 | |
| 8141 | fn init(bw: *std.io.BufferedWriter, len: usize) StringLiteral { | |
| 8142 | fn init(bw: *Writer, len: usize) StringLiteral { | |
| 8142 | 8143 | return .{ |
| 8143 | 8144 | .cur_len = 0, |
| 8144 | 8145 | .len = len, |
| ... | ... | @@ -8147,7 +8148,7 @@ const StringLiteral = struct { |
| 8147 | 8148 | }; |
| 8148 | 8149 | } |
| 8149 | 8150 | |
| 8150 | pub fn start(sl: *StringLiteral) std.io.Writer.Error!void { | |
| 8151 | pub fn start(sl: *StringLiteral) Writer.Error!void { | |
| 8151 | 8152 | if (sl.len <= max_string_initializer_len) { |
| 8152 | 8153 | try sl.bw.writeByte('\"'); |
| 8153 | 8154 | } else { |
| ... | ... | @@ -8155,7 +8156,7 @@ const StringLiteral = struct { |
| 8155 | 8156 | } |
| 8156 | 8157 | } |
| 8157 | 8158 | |
| 8158 | pub fn end(sl: *StringLiteral) std.io.Writer.Error!void { | |
| 8159 | pub fn end(sl: *StringLiteral) Writer.Error!void { | |
| 8159 | 8160 | if (sl.len <= max_string_initializer_len) { |
| 8160 | 8161 | try sl.bw.writeByte('\"'); |
| 8161 | 8162 | } else { |
| ... | ... | @@ -8163,7 +8164,7 @@ const StringLiteral = struct { |
| 8163 | 8164 | } |
| 8164 | 8165 | } |
| 8165 | 8166 | |
| 8166 | fn writeStringLiteralChar(sl: *StringLiteral, c: u8) std.io.Writer.Error!void { | |
| 8167 | fn writeStringLiteralChar(sl: *StringLiteral, c: u8) Writer.Error!void { | |
| 8167 | 8168 | switch (c) { |
| 8168 | 8169 | 7 => try sl.bw.writeAll("\\a"), |
| 8169 | 8170 | 8 => try sl.bw.writeAll("\\b"), |
| ... | ... | @@ -8180,7 +8181,7 @@ const StringLiteral = struct { |
| 8180 | 8181 | } |
| 8181 | 8182 | } |
| 8182 | 8183 | |
| 8183 | pub fn writeChar(sl: *StringLiteral, c: u8) std.io.Writer.Error!void { | |
| 8184 | pub fn writeChar(sl: *StringLiteral, c: u8) Writer.Error!void { | |
| 8184 | 8185 | if (sl.len <= max_string_initializer_len) { |
| 8185 | 8186 | if (sl.cur_len == 0 and sl.bw.count - sl.start_count > 1) |
| 8186 | 8187 | try sl.bw.writeAll("\"\""); |
| ... | ... | @@ -8202,9 +8203,9 @@ const StringLiteral = struct { |
| 8202 | 8203 | const FormatStringContext = struct { str: []const u8, sentinel: ?u8 }; |
| 8203 | 8204 | fn formatStringLiteral( |
| 8204 | 8205 | data: FormatStringContext, |
| 8205 | bw: *std.io.BufferedWriter, | |
| 8206 | bw: *Writer, | |
| 8206 | 8207 | comptime fmt: []const u8, |
| 8207 | ) std.io.Writer.Error!void { | |
| 8208 | ) Writer.Error!void { | |
| 8208 | 8209 | if (fmt.len != 1 or fmt[0] != 's') @compileError("Invalid fmt: " ++ fmt); |
| 8209 | 8210 | |
| 8210 | 8211 | var literal: StringLiteral = .init(bw, data.str.len + @intFromBool(data.sentinel != null)); |
| ... | ... | @@ -8233,9 +8234,9 @@ const FormatIntLiteralContext = struct { |
| 8233 | 8234 | }; |
| 8234 | 8235 | fn formatIntLiteral( |
| 8235 | 8236 | data: FormatIntLiteralContext, |
| 8236 | bw: *std.io.BufferedWriter, | |
| 8237 | bw: *Writer, | |
| 8237 | 8238 | comptime fmt: []const u8, |
| 8238 | ) std.io.Writer.Error!void { | |
| 8239 | ) Writer.Error!void { | |
| 8239 | 8240 | const pt = data.dg.pt; |
| 8240 | 8241 | const zcu = pt.zcu; |
| 8241 | 8242 | const target = &data.dg.mod.resolved_target.result; |
| ... | ... | @@ -8423,7 +8424,7 @@ const Materialize = struct { |
| 8423 | 8424 | } }; |
| 8424 | 8425 | } |
| 8425 | 8426 | |
| 8426 | pub fn mat(self: Materialize, f: *Function, bw: *std.io.BufferedWriter) !void { | |
| 8427 | pub fn mat(self: Materialize, f: *Function, bw: *Writer) !void { | |
| 8427 | 8428 | try f.writeCValue(bw, self.local, .Other); |
| 8428 | 8429 | } |
| 8429 | 8430 | |
| ... | ... | @@ -8435,27 +8436,27 @@ const Materialize = struct { |
| 8435 | 8436 | const Assignment = struct { |
| 8436 | 8437 | ctype: CType, |
| 8437 | 8438 | |
| 8438 | pub fn start(f: *Function, bw: *std.io.BufferedWriter, ctype: CType) !Assignment { | |
| 8439 | pub fn start(f: *Function, bw: *Writer, ctype: CType) !Assignment { | |
| 8439 | 8440 | const self: Assignment = .{ .ctype = ctype }; |
| 8440 | 8441 | try self.restart(f, bw); |
| 8441 | 8442 | return self; |
| 8442 | 8443 | } |
| 8443 | 8444 | |
| 8444 | pub fn restart(self: Assignment, f: *Function, bw: *std.io.BufferedWriter) !void { | |
| 8445 | pub fn restart(self: Assignment, f: *Function, bw: *Writer) !void { | |
| 8445 | 8446 | switch (self.strategy(f)) { |
| 8446 | 8447 | .assign => {}, |
| 8447 | 8448 | .memcpy => try bw.writeAll("memcpy("), |
| 8448 | 8449 | } |
| 8449 | 8450 | } |
| 8450 | 8451 | |
| 8451 | pub fn assign(self: Assignment, f: *Function, bw: *std.io.BufferedWriter) !void { | |
| 8452 | pub fn assign(self: Assignment, f: *Function, bw: *Writer) !void { | |
| 8452 | 8453 | switch (self.strategy(f)) { |
| 8453 | 8454 | .assign => try bw.writeAll(" = "), |
| 8454 | 8455 | .memcpy => try bw.writeAll(", "), |
| 8455 | 8456 | } |
| 8456 | 8457 | } |
| 8457 | 8458 | |
| 8458 | pub fn end(self: Assignment, f: *Function, bw: *std.io.BufferedWriter) !void { | |
| 8459 | pub fn end(self: Assignment, f: *Function, bw: *Writer) !void { | |
| 8459 | 8460 | switch (self.strategy(f)) { |
| 8460 | 8461 | .assign => {}, |
| 8461 | 8462 | .memcpy => { |
| ... | ... | @@ -8479,7 +8480,7 @@ const Assignment = struct { |
| 8479 | 8480 | const Vectorize = struct { |
| 8480 | 8481 | index: CValue = .none, |
| 8481 | 8482 | |
| 8482 | pub fn start(f: *Function, inst: Air.Inst.Index, writer: *std.io.BufferedWriter, ty: Type) !Vectorize { | |
| 8483 | pub fn start(f: *Function, inst: Air.Inst.Index, writer: *Writer, ty: Type) !Vectorize { | |
| 8483 | 8484 | const pt = f.object.dg.pt; |
| 8484 | 8485 | const zcu = pt.zcu; |
| 8485 | 8486 | return if (ty.zigTypeTag(zcu) == .vector) index: { |
| ... | ... | @@ -8499,7 +8500,7 @@ const Vectorize = struct { |
| 8499 | 8500 | } else .{}; |
| 8500 | 8501 | } |
| 8501 | 8502 | |
| 8502 | pub fn elem(self: Vectorize, f: *Function, bw: *std.io.BufferedWriter) !void { | |
| 8503 | pub fn elem(self: Vectorize, f: *Function, bw: *Writer) !void { | |
| 8503 | 8504 | if (self.index != .none) { |
| 8504 | 8505 | try bw.writeByte('['); |
| 8505 | 8506 | try f.writeCValue(bw, self.index, .Other); |
| ... | ... | @@ -8507,7 +8508,7 @@ const Vectorize = struct { |
| 8507 | 8508 | } |
| 8508 | 8509 | } |
| 8509 | 8510 | |
| 8510 | pub fn end(self: Vectorize, f: *Function, inst: Air.Inst.Index, bw: *std.io.BufferedWriter) !void { | |
| 8511 | pub fn end(self: Vectorize, f: *Function, inst: Air.Inst.Index, bw: *Writer) !void { | |
| 8511 | 8512 | if (self.index != .none) { |
| 8512 | 8513 | try f.object.outdent(); |
| 8513 | 8514 | try bw.writeByte('}'); |
src/codegen/c/Type.zig+8-6| ... | ... | @@ -209,7 +209,7 @@ pub fn getStandardDefineAbbrev(ctype: CType) ?[]const u8 { |
| 209 | 209 | }; |
| 210 | 210 | } |
| 211 | 211 | |
| 212 | pub fn renderLiteralPrefix(ctype: CType, bw: *std.io.BufferedWriter, kind: Kind, pool: *const Pool) std.io.Writer.Error!void { | |
| 212 | pub fn renderLiteralPrefix(ctype: CType, bw: *Writer, kind: Kind, pool: *const Pool) Writer.Error!void { | |
| 213 | 213 | switch (ctype.info(pool)) { |
| 214 | 214 | .basic => |basic_info| switch (basic_info) { |
| 215 | 215 | .void => unreachable, |
| ... | ... | @@ -270,7 +270,7 @@ pub fn renderLiteralPrefix(ctype: CType, bw: *std.io.BufferedWriter, kind: Kind, |
| 270 | 270 | } |
| 271 | 271 | } |
| 272 | 272 | |
| 273 | pub fn renderLiteralSuffix(ctype: CType, bw: *std.io.BufferedWriter, pool: *const Pool) std.io.Writer.Error!void { | |
| 273 | pub fn renderLiteralSuffix(ctype: CType, bw: *Writer, pool: *const Pool) Writer.Error!void { | |
| 274 | 274 | switch (ctype.info(pool)) { |
| 275 | 275 | .basic => |basic_info| switch (basic_info) { |
| 276 | 276 | .void => unreachable, |
| ... | ... | @@ -940,10 +940,10 @@ pub const Pool = struct { |
| 940 | 940 | const FormatData = struct { string: String, pool: *const Pool }; |
| 941 | 941 | fn format( |
| 942 | 942 | data: FormatData, |
| 943 | bw: *std.io.BufferedWriter, | |
| 943 | bw: *Writer, | |
| 944 | 944 | comptime fmt_str: []const u8, |
| 945 | ) std.io.Writer.Error!void { | |
| 946 | if (fmt_str.len > 0) @compileError("invalid format string '" ++ fmt_str ++ "'"); | |
| 945 | ) Writer.Error!void { | |
| 946 | comptime assert(fmt_str.len == 0); | |
| 947 | 947 | if (data.string.toSlice(data.pool)) |slice| |
| 948 | 948 | try bw.writeAll(slice) |
| 949 | 949 | else |
| ... | ... | @@ -3280,10 +3280,12 @@ pub const AlignAs = packed struct { |
| 3280 | 3280 | } |
| 3281 | 3281 | }; |
| 3282 | 3282 | |
| 3283 | const std = @import("std"); | |
| 3283 | 3284 | const assert = std.debug.assert; |
| 3285 | const Writer = std.io.Writer; | |
| 3286 | ||
| 3284 | 3287 | const CType = @This(); |
| 3285 | 3288 | const InternPool = @import("../../InternPool.zig"); |
| 3286 | 3289 | const Module = @import("../../Package/Module.zig"); |
| 3287 | const std = @import("std"); | |
| 3288 | 3290 | const Type = @import("../../Type.zig"); |
| 3289 | 3291 | const Zcu = @import("../../Zcu.zig"); |
src/codegen/spirv/spec.zig+2-1| ... | ... | @@ -18,7 +18,8 @@ pub const IdResult = enum(Word) { |
| 18 | 18 | none, |
| 19 | 19 | _, |
| 20 | 20 | |
| 21 | pub fn format(self: IdResult, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void { | |
| 21 | pub fn format(self: IdResult, bw: *std.io.Writer, comptime fmt: []const u8) std.io.Writer.Error!void { | |
| 22 | comptime std.debug.assert(fmt.len == 0); | |
| 22 | 23 | switch (self) { |
| 23 | 24 | .none => try bw.writeAll("(none)"), |
| 24 | 25 | else => try bw.print("%{}", .{@intFromEnum(self)}), |
src/fmt.zig+19-18| ... | ... | @@ -1,3 +1,12 @@ |
| 1 | const std = @import("std"); | |
| 2 | const mem = std.mem; | |
| 3 | const fs = std.fs; | |
| 4 | const process = std.process; | |
| 5 | const Allocator = std.mem.Allocator; | |
| 6 | const Color = std.zig.Color; | |
| 7 | const fatal = std.process.fatal; | |
| 8 | const File = std.fs.File; | |
| 9 | ||
| 1 | 10 | const usage_fmt = |
| 2 | 11 | \\Usage: zig fmt [file]... |
| 3 | 12 | \\ |
| ... | ... | @@ -27,7 +36,7 @@ const Fmt = struct { |
| 27 | 36 | gpa: Allocator, |
| 28 | 37 | arena: Allocator, |
| 29 | 38 | out_buffer: std.ArrayListUnmanaged(u8), |
| 30 | stdout: *std.io.BufferedWriter, | |
| 39 | stdout_writer: *File.Writer, | |
| 31 | 40 | |
| 32 | 41 | const SeenMap = std.AutoHashMap(fs.File.INode, void); |
| 33 | 42 | }; |
| ... | ... | @@ -49,7 +58,7 @@ pub fn run(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 49 | 58 | const arg = args[i]; |
| 50 | 59 | if (mem.startsWith(u8, arg, "-")) { |
| 51 | 60 | if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { |
| 52 | try std.fs.File.stdout().writeAll(usage_fmt); | |
| 61 | try File.stdout().writeAll(usage_fmt); | |
| 53 | 62 | return process.cleanExit(); |
| 54 | 63 | } else if (mem.eql(u8, arg, "--color")) { |
| 55 | 64 | if (i + 1 >= args.len) { |
| ... | ... | @@ -133,10 +142,9 @@ pub fn run(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 133 | 142 | try std.zig.printAstErrorsToStderr(gpa, tree, "<stdin>", color); |
| 134 | 143 | process.exit(2); |
| 135 | 144 | } |
| 136 | var aw: std.io.AllocatingWriter = undefined; | |
| 137 | aw.init(gpa); | |
| 145 | var aw: std.io.AllocatingWriter = .init(gpa); | |
| 138 | 146 | defer aw.deinit(); |
| 139 | try tree.render(gpa, &aw.buffered_writer, .{}); | |
| 147 | try tree.render(gpa, &aw.interface, .{}); | |
| 140 | 148 | const formatted = aw.getWritten(); |
| 141 | 149 | |
| 142 | 150 | if (check_flag) { |
| ... | ... | @@ -144,7 +152,7 @@ pub fn run(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 144 | 152 | process.exit(code); |
| 145 | 153 | } |
| 146 | 154 | |
| 147 | return std.fs.File.stdout().writeAll(formatted); | |
| 155 | return File.stdout().writeAll(formatted); | |
| 148 | 156 | } |
| 149 | 157 | |
| 150 | 158 | if (input_files.items.len == 0) { |
| ... | ... | @@ -152,7 +160,7 @@ pub fn run(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 152 | 160 | } |
| 153 | 161 | |
| 154 | 162 | var stdout_buffer: [4096]u8 = undefined; |
| 155 | var stdout: std.io.BufferedWriter = std.fs.File.stdout().writer().buffered(&stdout_buffer); | |
| 163 | var stdout_writer = File.stdout().writer(&stdout_buffer); | |
| 156 | 164 | |
| 157 | 165 | var fmt: Fmt = .{ |
| 158 | 166 | .gpa = gpa, |
| ... | ... | @@ -163,7 +171,7 @@ pub fn run(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 163 | 171 | .force_zon = force_zon, |
| 164 | 172 | .color = color, |
| 165 | 173 | .out_buffer = .empty, |
| 166 | .stdout = &stdout, | |
| 174 | .stdout_writer = &stdout_writer, | |
| 167 | 175 | }; |
| 168 | 176 | defer fmt.seen.deinit(); |
| 169 | 177 | defer fmt.out_buffer.deinit(gpa); |
| ... | ... | @@ -190,6 +198,7 @@ pub fn run(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 190 | 198 | if (fmt.any_error) { |
| 191 | 199 | process.exit(1); |
| 192 | 200 | } |
| 201 | try fmt.stdout_writer.flush(); | |
| 193 | 202 | } |
| 194 | 203 | |
| 195 | 204 | fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool, dir: fs.Dir, sub_path: []const u8) anyerror!void { |
| ... | ... | @@ -336,7 +345,7 @@ fn fmtPathFile( |
| 336 | 345 | return; |
| 337 | 346 | |
| 338 | 347 | if (check_mode) { |
| 339 | try fmt.stdout.print("{s}\n", .{file_path}); | |
| 348 | try fmt.stdout_writer.interface.print("{s}\n", .{file_path}); | |
| 340 | 349 | fmt.any_error = true; |
| 341 | 350 | } else { |
| 342 | 351 | var af = try dir.atomicFile(sub_path, .{ .mode = stat.mode }); |
| ... | ... | @@ -344,18 +353,10 @@ fn fmtPathFile( |
| 344 | 353 | |
| 345 | 354 | try af.file.writeAll(fmt.out_buffer.items); |
| 346 | 355 | try af.finish(); |
| 347 | try fmt.stdout.print("{s}\n", .{file_path}); | |
| 356 | try fmt.stdout_writer.interface.print("{s}\n", .{file_path}); | |
| 348 | 357 | } |
| 349 | 358 | } |
| 350 | 359 | |
| 351 | const std = @import("std"); | |
| 352 | const mem = std.mem; | |
| 353 | const fs = std.fs; | |
| 354 | const process = std.process; | |
| 355 | const Allocator = std.mem.Allocator; | |
| 356 | const Color = std.zig.Color; | |
| 357 | const fatal = std.process.fatal; | |
| 358 | ||
| 359 | 360 | /// Provided for debugging/testing purposes; unused by the compiler. |
| 360 | 361 | pub fn main() !void { |
| 361 | 362 | const gpa = std.heap.smp_allocator; |
src/link/Coff.zig+39-39| ... | ... | @@ -1,5 +1,41 @@ |
| 1 | 1 | //! The main driver of the self-hosted COFF linker. |
| 2 | 2 | |
| 3 | const Coff = @This(); | |
| 4 | ||
| 5 | const std = @import("std"); | |
| 6 | const build_options = @import("build_options"); | |
| 7 | const builtin = @import("builtin"); | |
| 8 | const assert = std.debug.assert; | |
| 9 | const coff_util = std.coff; | |
| 10 | const fmt = std.fmt; | |
| 11 | const fs = std.fs; | |
| 12 | const log = std.log.scoped(.link); | |
| 13 | const math = std.math; | |
| 14 | const mem = std.mem; | |
| 15 | ||
| 16 | const Allocator = std.mem.Allocator; | |
| 17 | const Path = std.Build.Cache.Path; | |
| 18 | const Directory = std.Build.Cache.Directory; | |
| 19 | const Cache = std.Build.Cache; | |
| 20 | const Writer = std.io.Writer; | |
| 21 | ||
| 22 | const aarch64_util = @import("../arch/aarch64/bits.zig"); | |
| 23 | const allocPrint = std.fmt.allocPrint; | |
| 24 | const codegen = @import("../codegen.zig"); | |
| 25 | const link = @import("../link.zig"); | |
| 26 | const target_util = @import("../target.zig"); | |
| 27 | const trace = @import("../tracy.zig").trace; | |
| 28 | ||
| 29 | const Compilation = @import("../Compilation.zig"); | |
| 30 | const Zcu = @import("../Zcu.zig"); | |
| 31 | const InternPool = @import("../InternPool.zig"); | |
| 32 | const TableSection = @import("table_section.zig").TableSection; | |
| 33 | const StringTable = @import("StringTable.zig"); | |
| 34 | const Type = @import("../Type.zig"); | |
| 35 | const Value = @import("../Value.zig"); | |
| 36 | const AnalUnit = InternPool.AnalUnit; | |
| 37 | const dev = @import("../dev.zig"); | |
| 38 | ||
| 3 | 39 | base: link.File, |
| 4 | 40 | image_base: u64, |
| 5 | 41 | /// TODO this and minor_subsystem_version should be combined into one property and left as |
| ... | ... | @@ -2175,8 +2211,7 @@ fn writeDataDirectoriesHeaders(coff: *Coff) !void { |
| 2175 | 2211 | fn writeHeader(coff: *Coff) !void { |
| 2176 | 2212 | const target = &coff.base.comp.root_mod.resolved_target.result; |
| 2177 | 2213 | const gpa = coff.base.comp.gpa; |
| 2178 | var bw: std.io.BufferedWriter = undefined; | |
| 2179 | bw.initFixed(try gpa.alloc(u8, coff.getSizeOfHeaders())); | |
| 2214 | var bw: Writer = .fixed(try gpa.alloc(u8, coff.getSizeOfHeaders())); | |
| 2180 | 2215 | defer gpa.free(bw.buffer); |
| 2181 | 2216 | |
| 2182 | 2217 | bw.writeAll(&msdos_stub) catch unreachable; |
| ... | ... | @@ -3066,14 +3101,14 @@ const ImportTable = struct { |
| 3066 | 3101 | ctx: Context, |
| 3067 | 3102 | }; |
| 3068 | 3103 | |
| 3069 | fn format(itab: ImportTable, bw: *std.io.BufferedWriter, comptime unused_format_string: []const u8) std.io.Writer.Error!void { | |
| 3104 | fn format(itab: ImportTable, bw: *Writer, comptime unused_format_string: []const u8) Writer.Error!void { | |
| 3070 | 3105 | _ = itab; |
| 3071 | 3106 | _ = bw; |
| 3072 | 3107 | _ = unused_format_string; |
| 3073 | 3108 | @compileError("do not format ImportTable directly; use itab.fmtDebug()"); |
| 3074 | 3109 | } |
| 3075 | 3110 | |
| 3076 | fn format2(fmt_ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_format_string: []const u8) std.io.Writer.Error!void { | |
| 3111 | fn format2(fmt_ctx: FormatContext, bw: *Writer, comptime unused_format_string: []const u8) Writer.Error!void { | |
| 3077 | 3112 | comptime assert(unused_format_string.len == 0); |
| 3078 | 3113 | const lib_name = fmt_ctx.ctx.coff.temp_strtab.getAssumeExists(fmt_ctx.ctx.name_off); |
| 3079 | 3114 | const base_vaddr = getBaseAddress(fmt_ctx.ctx); |
| ... | ... | @@ -3105,41 +3140,6 @@ fn pwriteAll(coff: *Coff, bytes: []const u8, offset: u64) error{LinkFailure}!voi |
| 3105 | 3140 | }; |
| 3106 | 3141 | } |
| 3107 | 3142 | |
| 3108 | const Coff = @This(); | |
| 3109 | ||
| 3110 | const std = @import("std"); | |
| 3111 | const build_options = @import("build_options"); | |
| 3112 | const builtin = @import("builtin"); | |
| 3113 | const assert = std.debug.assert; | |
| 3114 | const coff_util = std.coff; | |
| 3115 | const fmt = std.fmt; | |
| 3116 | const fs = std.fs; | |
| 3117 | const log = std.log.scoped(.link); | |
| 3118 | const math = std.math; | |
| 3119 | const mem = std.mem; | |
| 3120 | ||
| 3121 | const Allocator = std.mem.Allocator; | |
| 3122 | const Path = std.Build.Cache.Path; | |
| 3123 | const Directory = std.Build.Cache.Directory; | |
| 3124 | const Cache = std.Build.Cache; | |
| 3125 | ||
| 3126 | const aarch64_util = @import("../arch/aarch64/bits.zig"); | |
| 3127 | const allocPrint = std.fmt.allocPrint; | |
| 3128 | const codegen = @import("../codegen.zig"); | |
| 3129 | const link = @import("../link.zig"); | |
| 3130 | const target_util = @import("../target.zig"); | |
| 3131 | const trace = @import("../tracy.zig").trace; | |
| 3132 | ||
| 3133 | const Compilation = @import("../Compilation.zig"); | |
| 3134 | const Zcu = @import("../Zcu.zig"); | |
| 3135 | const InternPool = @import("../InternPool.zig"); | |
| 3136 | const TableSection = @import("table_section.zig").TableSection; | |
| 3137 | const StringTable = @import("StringTable.zig"); | |
| 3138 | const Type = @import("../Type.zig"); | |
| 3139 | const Value = @import("../Value.zig"); | |
| 3140 | const AnalUnit = InternPool.AnalUnit; | |
| 3141 | const dev = @import("../dev.zig"); | |
| 3142 | ||
| 3143 | 3143 | /// This is the start of a Portable Executable (PE) file. |
| 3144 | 3144 | /// It starts with a MS-DOS header followed by a MS-DOS stub program. |
| 3145 | 3145 | /// This data does not change so we include it as follows in all binaries. |
src/link/Dwarf.zig+21-25| ... | ... | @@ -648,8 +648,7 @@ const Unit = struct { |
| 648 | 648 | assert(len >= unit.trailer_len); |
| 649 | 649 | if (sec == &dwarf.debug_line.section) { |
| 650 | 650 | var buf: [1 + uleb128Bytes(std.math.maxInt(u32)) + 1]u8 = undefined; |
| 651 | var bw: std.io.BufferedWriter = undefined; | |
| 652 | bw.initFixed(&buf); | |
| 651 | var bw: Writer = .fixed(&buf); | |
| 653 | 652 | bw.writeByte(DW.LNS.extended_op) catch unreachable; |
| 654 | 653 | const extended_op_bytes = bw.end; |
| 655 | 654 | var op_len_bytes: u5 = 1; |
| ... | ... | @@ -668,8 +667,7 @@ const Unit = struct { |
| 668 | 667 | assert(bw.end >= unit.trailer_len and bw.end <= len); |
| 669 | 668 | return dwarf.getFile().?.pwriteAll(bw.getWritten(), sec.off(dwarf) + start); |
| 670 | 669 | } |
| 671 | var trailer_bw: std.io.BufferedWriter = undefined; | |
| 672 | trailer_bw.initFixed(try dwarf.gpa.alloc(u8, len)); | |
| 670 | var trailer_bw: Writer = .fixed(try dwarf.gpa.alloc(u8, len)); | |
| 673 | 671 | defer dwarf.gpa.free(trailer_bw.buffer); |
| 674 | 672 | const fill_byte: u8 = if (sec == &dwarf.debug_abbrev.section) fill: { |
| 675 | 673 | assert(uleb128Bytes(@intFromEnum(AbbrevCode.null)) == 1); |
| ... | ... | @@ -833,8 +831,7 @@ const Entry = struct { |
| 833 | 831 | 1 + uleb128Bytes(std.math.maxInt(u32)) + 1, |
| 834 | 832 | ) |
| 835 | 833 | ]u8 = undefined; |
| 836 | var bw: std.io.BufferedWriter = undefined; | |
| 837 | bw.initFixed(&buf); | |
| 834 | var bw: Writer = .fixed(&buf); | |
| 838 | 835 | if (sec == &dwarf.debug_info.section) switch (len) { |
| 839 | 836 | 0 => {}, |
| 840 | 837 | 1 => bw.writeLeb128(try dwarf.refAbbrevCode(.pad_1)) catch unreachable, |
| ... | ... | @@ -1134,7 +1131,7 @@ pub const Loc = union(enum) { |
| 1134 | 1131 | }; |
| 1135 | 1132 | } |
| 1136 | 1133 | |
| 1137 | fn writeReg(bw: *std.io.BufferedWriter, reg: u32, op0: u8, opx: u8) std.io.Writer.Error!void { | |
| 1134 | fn writeReg(bw: *Writer, reg: u32, op0: u8, opx: u8) Writer.Error!void { | |
| 1138 | 1135 | if (std.math.cast(u5, reg)) |small_reg| { |
| 1139 | 1136 | try bw.writeByte(op0 + small_reg); |
| 1140 | 1137 | } else { |
| ... | ... | @@ -1143,7 +1140,7 @@ pub const Loc = union(enum) { |
| 1143 | 1140 | } |
| 1144 | 1141 | } |
| 1145 | 1142 | |
| 1146 | fn write(loc: Loc, bw: *std.io.BufferedWriter, adapter: anytype) UpdateError!void { | |
| 1143 | fn write(loc: Loc, bw: *Writer, adapter: anytype) UpdateError!void { | |
| 1147 | 1144 | switch (loc) { |
| 1148 | 1145 | .empty => {}, |
| 1149 | 1146 | .addr_reloc => |sym_index| { |
| ... | ... | @@ -1795,10 +1792,10 @@ pub const WipNav = struct { |
| 1795 | 1792 | fn endian(_: ExprLocCounter) std.builtin.Endian { |
| 1796 | 1793 | return @import("builtin").cpu.arch.endian(); |
| 1797 | 1794 | } |
| 1798 | fn addrSym(counter: ExprLocCounter, bw: *std.io.BufferedWriter, _: u32) error{}!void { | |
| 1795 | fn addrSym(counter: ExprLocCounter, bw: *Writer, _: u32) error{}!void { | |
| 1799 | 1796 | bw.count += @intFromEnum(counter.address_size); |
| 1800 | 1797 | } |
| 1801 | fn infoEntry(counter: ExprLocCounter, bw: *std.io.BufferedWriter, _: Unit.Index, _: Entry.Index) error{}!void { | |
| 1798 | fn infoEntry(counter: ExprLocCounter, bw: *Writer, _: Unit.Index, _: Entry.Index) error{}!void { | |
| 1802 | 1799 | bw.count += counter.section_offset_bytes; |
| 1803 | 1800 | } |
| 1804 | 1801 | }; |
| ... | ... | @@ -1817,10 +1814,10 @@ pub const WipNav = struct { |
| 1817 | 1814 | fn endian(ctx: @This()) std.builtin.Endian { |
| 1818 | 1815 | return ctx.wip_nav.dwarf.endian; |
| 1819 | 1816 | } |
| 1820 | fn addrSym(ctx: @This(), _: *std.io.BufferedWriter, sym_index: u32) UpdateError!void { | |
| 1817 | fn addrSym(ctx: @This(), _: *Writer, sym_index: u32) UpdateError!void { | |
| 1821 | 1818 | try ctx.wip_nav.infoAddrSym(sym_index, 0); |
| 1822 | 1819 | } |
| 1823 | fn infoEntry(ctx: @This(), _: *std.io.BufferedWriter, unit: Unit.Index, entry: Entry.Index) UpdateError!void { | |
| 1820 | fn infoEntry(ctx: @This(), _: *Writer, unit: Unit.Index, entry: Entry.Index) UpdateError!void { | |
| 1824 | 1821 | try ctx.wip_nav.infoSectionOffset(.debug_info, unit, entry, 0); |
| 1825 | 1822 | } |
| 1826 | 1823 | } = .{ .wip_nav = wip_nav }; |
| ... | ... | @@ -1852,10 +1849,10 @@ pub const WipNav = struct { |
| 1852 | 1849 | fn endian(ctx: @This()) std.builtin.Endian { |
| 1853 | 1850 | return ctx.wip_nav.dwarf.endian; |
| 1854 | 1851 | } |
| 1855 | fn addrSym(ctx: @This(), _: *std.io.BufferedWriter, sym_index: u32) UpdateError!void { | |
| 1852 | fn addrSym(ctx: @This(), _: *Writer, sym_index: u32) UpdateError!void { | |
| 1856 | 1853 | try ctx.wip_nav.frameAddrSym(sym_index, 0); |
| 1857 | 1854 | } |
| 1858 | fn infoEntry(ctx: @This(), _: *std.io.BufferedWriter, unit: Unit.Index, entry: Entry.Index) UpdateError!void { | |
| 1855 | fn infoEntry(ctx: @This(), _: *Writer, unit: Unit.Index, entry: Entry.Index) UpdateError!void { | |
| 1859 | 1856 | try ctx.wip_nav.sectionOffset(.debug_frame, .debug_info, unit, entry, 0); |
| 1860 | 1857 | } |
| 1861 | 1858 | } = .{ .wip_nav = wip_nav }; |
| ... | ... | @@ -2756,8 +2753,7 @@ fn finishWipNavFuncInner( |
| 2756 | 2753 | try dibw.writeLeb128(@intFromEnum(AbbrevCode.null)); |
| 2757 | 2754 | } else { |
| 2758 | 2755 | const abbrev_code_buf = wip_nav.debug_info.getWritten()[0..AbbrevCode.decl_bytes]; |
| 2759 | var abbrev_code_br: std.io.Reader = undefined; | |
| 2760 | abbrev_code_br.initFixed(abbrev_code_buf); | |
| 2756 | var abbrev_code_br: std.io.Reader = .fixed(abbrev_code_buf); | |
| 2761 | 2757 | const abbrev_code: AbbrevCode = @enumFromInt(abbrev_code_br.takeLeb128(@typeInfo(AbbrevCode).@"enum".tag_type) catch unreachable); |
| 2762 | 2758 | std.leb.writeUnsignedFixed( |
| 2763 | 2759 | AbbrevCode.decl_bytes, |
| ... | ... | @@ -4565,14 +4561,14 @@ pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { |
| 4565 | 4561 | |
| 4566 | 4562 | var header: std.ArrayListUnmanaged(u8) = .empty; |
| 4567 | 4563 | defer header.deinit(gpa); |
| 4568 | var header_bw: std.io.BufferedWriter = undefined; | |
| 4564 | var header_bw: Writer = undefined; | |
| 4569 | 4565 | if (dwarf.debug_aranges.section.dirty) { |
| 4570 | 4566 | for (dwarf.debug_aranges.section.units.items, 0..) |*unit_ptr, unit_index| { |
| 4571 | 4567 | const unit: Unit.Index = @enumFromInt(unit_index); |
| 4572 | 4568 | unit_ptr.clear(); |
| 4573 | 4569 | try unit_ptr.cross_section_relocs.ensureTotalCapacity(gpa, 1); |
| 4574 | 4570 | try header.resize(gpa, unit_ptr.header_len); |
| 4575 | header_bw.initFixed(header.items); | |
| 4571 | header_bw = .fixed(header.items); | |
| 4576 | 4572 | const unit_len = (if (unit_ptr.next.unwrap()) |next_unit| |
| 4577 | 4573 | dwarf.debug_aranges.section.getUnit(next_unit).off |
| 4578 | 4574 | else |
| ... | ... | @@ -4610,7 +4606,7 @@ pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { |
| 4610 | 4606 | const Register = @import("../arch/x86_64/bits.zig").Register; |
| 4611 | 4607 | for (dwarf.debug_frame.section.units.items) |*unit| { |
| 4612 | 4608 | try header.resize(gpa, unit.header_len); |
| 4613 | header_bw.initFixed(header.items); | |
| 4609 | header_bw = .fixed(header.items); | |
| 4614 | 4610 | const unit_len = unit.header_len - dwarf.unitLengthBytes(); |
| 4615 | 4611 | switch (dwarf.format) { |
| 4616 | 4612 | .@"32" => header_bw.writeInt(u32, @intCast(unit_len), dwarf.endian) catch unreachable, |
| ... | ... | @@ -4651,7 +4647,7 @@ pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { |
| 4651 | 4647 | try unit_ptr.cross_unit_relocs.ensureTotalCapacity(gpa, 1); |
| 4652 | 4648 | try unit_ptr.cross_section_relocs.ensureTotalCapacity(gpa, 7); |
| 4653 | 4649 | try header.resize(gpa, unit_ptr.header_len); |
| 4654 | header_bw.initFixed(header.items); | |
| 4650 | header_bw = .fixed(header.items); | |
| 4655 | 4651 | const unit_len = (if (unit_ptr.next.unwrap()) |next_unit| |
| 4656 | 4652 | dwarf.debug_info.section.getUnit(next_unit).off |
| 4657 | 4653 | else |
| ... | ... | @@ -4751,7 +4747,7 @@ pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { |
| 4751 | 4747 | unit.clear(); |
| 4752 | 4748 | try unit.cross_section_relocs.ensureTotalCapacity(gpa, mod_info.dirs.count() + 2 * (mod_info.files.count())); |
| 4753 | 4749 | try header.resize(gpa, unit.header_len); |
| 4754 | header_bw.initFixed(header.items); | |
| 4750 | header_bw = .fixed(header.items); | |
| 4755 | 4751 | const unit_len = (if (unit.next.unwrap()) |next_unit| |
| 4756 | 4752 | dwarf.debug_line.section.getUnit(next_unit).off |
| 4757 | 4753 | else |
| ... | ... | @@ -4859,7 +4855,7 @@ pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { |
| 4859 | 4855 | if (dwarf.debug_rnglists.section.dirty) { |
| 4860 | 4856 | for (dwarf.debug_rnglists.section.units.items) |*unit| { |
| 4861 | 4857 | try header.resize(gpa, unit.header_len); |
| 4862 | header_bw.initFixed(header.items); | |
| 4858 | header_bw = .fixed(header.items); | |
| 4863 | 4859 | const unit_len = (if (unit.next.unwrap()) |next_unit| |
| 4864 | 4860 | dwarf.debug_rnglists.section.getUnit(next_unit).off |
| 4865 | 4861 | else |
| ... | ... | @@ -6078,7 +6074,7 @@ fn writeInt(dwarf: *Dwarf, buf: []u8, int: u64) void { |
| 6078 | 6074 | } |
| 6079 | 6075 | } |
| 6080 | 6076 | |
| 6081 | fn writeIntTo(dwarf: *Dwarf, bw: *std.io.BufferedWriter, len: usize, int: u64) !void { | |
| 6077 | fn writeIntTo(dwarf: *Dwarf, bw: *Writer, len: usize, int: u64) !void { | |
| 6082 | 6078 | dwarf.writeInt(try bw.writableSlice(len), int); |
| 6083 | 6079 | } |
| 6084 | 6080 | |
| ... | ... | @@ -6127,8 +6123,7 @@ fn leb128Bytes(value: anytype) u32 { |
| 6127 | 6123 | var buffer: [ |
| 6128 | 6124 | std.math.divCeil(u16, @intFromBool(value_info.signedness == .signed) + value_info.bits, 7) catch unreachable |
| 6129 | 6125 | ]u8 = undefined; |
| 6130 | var bw: std.io.BufferedWriter = undefined; | |
| 6131 | bw.initFixed(&buffer); | |
| 6126 | var bw: Writer = .fixed(&buffer); | |
| 6132 | 6127 | bw.writeLeb128(value) catch unreachable; |
| 6133 | 6128 | return @intCast(bw.end); |
| 6134 | 6129 | } |
| ... | ... | @@ -6155,3 +6150,4 @@ const log = std.log.scoped(.dwarf); |
| 6155 | 6150 | const std = @import("std"); |
| 6156 | 6151 | const target_info = @import("../target.zig"); |
| 6157 | 6152 | const Allocator = std.mem.Allocator; |
| 6153 | const Writer = std.io.Writer; |
src/link/Elf.zig+18-18| ... | ... | @@ -3029,8 +3029,7 @@ fn writeAtoms(self: *Elf) !void { |
| 3029 | 3029 | if (self.requiresThunks()) { |
| 3030 | 3030 | for (self.thunks.items) |th| { |
| 3031 | 3031 | try buffer.resize(th.size(self)); |
| 3032 | var bw: std.io.BufferedWriter = undefined; | |
| 3033 | bw.initFixed(buffer.items); | |
| 3032 | var bw: Writer = .fixed(buffer.items); | |
| 3034 | 3033 | const shdr = slice.items(.shdr)[th.output_section_index]; |
| 3035 | 3034 | const offset = @as(u64, @intCast(th.value)) + shdr.sh_offset; |
| 3036 | 3035 | try th.write(self, &bw); |
| ... | ... | @@ -3136,7 +3135,7 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 3136 | 3135 | |
| 3137 | 3136 | var buffer: std.ArrayListUnmanaged(u8) = .empty; |
| 3138 | 3137 | defer buffer.deinit(gpa); |
| 3139 | var bw: std.io.BufferedWriter = undefined; | |
| 3138 | var bw: Writer = undefined; | |
| 3140 | 3139 | |
| 3141 | 3140 | if (self.section_indexes.interp) |shndx| { |
| 3142 | 3141 | const shdr = slice.items(.shdr)[shndx]; |
| ... | ... | @@ -3156,7 +3155,7 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 3156 | 3155 | if (self.section_indexes.gnu_hash) |shndx| { |
| 3157 | 3156 | const shdr = slice.items(.shdr)[shndx]; |
| 3158 | 3157 | try buffer.resize(gpa, self.gnu_hash.size()); |
| 3159 | bw.initFixed(buffer.items); | |
| 3158 | bw = .fixed(buffer.items); | |
| 3160 | 3159 | try self.gnu_hash.write(self, &bw); |
| 3161 | 3160 | assert(bw.end == bw.buffer.len); |
| 3162 | 3161 | try self.pwriteAll(bw.buffer, shdr.sh_offset); |
| ... | ... | @@ -3170,7 +3169,7 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 3170 | 3169 | if (self.section_indexes.verneed) |shndx| { |
| 3171 | 3170 | const shdr = slice.items(.shdr)[shndx]; |
| 3172 | 3171 | try buffer.resize(gpa, self.verneed.size()); |
| 3173 | bw.initFixed(buffer.items); | |
| 3172 | bw = .fixed(buffer.items); | |
| 3174 | 3173 | try self.verneed.write(&bw); |
| 3175 | 3174 | assert(bw.end == bw.buffer.len); |
| 3176 | 3175 | try self.pwriteAll(bw.buffer, shdr.sh_offset); |
| ... | ... | @@ -3179,7 +3178,7 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 3179 | 3178 | if (self.section_indexes.dynamic) |shndx| { |
| 3180 | 3179 | const shdr = slice.items(.shdr)[shndx]; |
| 3181 | 3180 | try buffer.resize(gpa, self.dynamic.size(self)); |
| 3182 | bw.initFixed(buffer.items); | |
| 3181 | bw = .fixed(buffer.items); | |
| 3183 | 3182 | try self.dynamic.write(self, &bw); |
| 3184 | 3183 | assert(bw.end == bw.buffer.len); |
| 3185 | 3184 | try self.pwriteAll(bw.buffer, shdr.sh_offset); |
| ... | ... | @@ -3188,7 +3187,7 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 3188 | 3187 | if (self.section_indexes.dynsymtab) |shndx| { |
| 3189 | 3188 | const shdr = slice.items(.shdr)[shndx]; |
| 3190 | 3189 | try buffer.resize(gpa, self.dynsym.size()); |
| 3191 | bw.initFixed(buffer.items); | |
| 3190 | bw = .fixed(buffer.items); | |
| 3192 | 3191 | try self.dynsym.write(self, &bw); |
| 3193 | 3192 | assert(bw.end == bw.buffer.len); |
| 3194 | 3193 | try self.pwriteAll(bw.buffer, shdr.sh_offset); |
| ... | ... | @@ -3208,7 +3207,7 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 3208 | 3207 | const shdr = slice.items(.shdr)[shndx]; |
| 3209 | 3208 | const sh_size = try self.cast(usize, shdr.sh_size); |
| 3210 | 3209 | try buffer.resize(gpa, @intCast(sh_size - existing_size)); |
| 3211 | bw.initFixed(buffer.items); | |
| 3210 | bw = .fixed(buffer.items); | |
| 3212 | 3211 | try eh_frame.writeEhFrame(self, &bw); |
| 3213 | 3212 | assert(bw.end == bw.buffer.len); |
| 3214 | 3213 | try self.pwriteAll(bw.buffer, shdr.sh_offset + existing_size); |
| ... | ... | @@ -3218,7 +3217,7 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 3218 | 3217 | const shdr = slice.items(.shdr)[shndx]; |
| 3219 | 3218 | const sh_size = try self.cast(usize, shdr.sh_size); |
| 3220 | 3219 | try buffer.resize(gpa, sh_size); |
| 3221 | bw.initFixed(buffer.items); | |
| 3220 | bw = .fixed(buffer.items); | |
| 3222 | 3221 | try eh_frame.writeEhFrameHdr(self, &bw); |
| 3223 | 3222 | assert(bw.end == bw.buffer.len); |
| 3224 | 3223 | try self.pwriteAll(bw.buffer, shdr.sh_offset); |
| ... | ... | @@ -3227,7 +3226,7 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 3227 | 3226 | if (self.section_indexes.got) |index| { |
| 3228 | 3227 | const shdr = slice.items(.shdr)[index]; |
| 3229 | 3228 | try buffer.resize(gpa, self.got.size(self)); |
| 3230 | bw.initFixed(buffer.items); | |
| 3229 | bw = .fixed(buffer.items); | |
| 3231 | 3230 | try self.got.write(self, &bw); |
| 3232 | 3231 | assert(bw.end == bw.buffer.len); |
| 3233 | 3232 | try self.pwriteAll(bw.buffer, shdr.sh_offset); |
| ... | ... | @@ -3244,7 +3243,7 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 3244 | 3243 | if (self.section_indexes.plt) |shndx| { |
| 3245 | 3244 | const shdr = slice.items(.shdr)[shndx]; |
| 3246 | 3245 | try buffer.resize(gpa, self.plt.size(self)); |
| 3247 | bw.initFixed(buffer.items); | |
| 3246 | bw = .fixed(buffer.items); | |
| 3248 | 3247 | try self.plt.write(self, &bw); |
| 3249 | 3248 | assert(bw.end == bw.buffer.len); |
| 3250 | 3249 | try self.pwriteAll(bw.buffer, shdr.sh_offset); |
| ... | ... | @@ -3253,7 +3252,7 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 3253 | 3252 | if (self.section_indexes.got_plt) |shndx| { |
| 3254 | 3253 | const shdr = slice.items(.shdr)[shndx]; |
| 3255 | 3254 | try buffer.resize(gpa, self.got_plt.size(self)); |
| 3256 | bw.initFixed(buffer.items); | |
| 3255 | bw = .fixed(buffer.items); | |
| 3257 | 3256 | try self.got_plt.write(self, &bw); |
| 3258 | 3257 | assert(bw.end == bw.buffer.len); |
| 3259 | 3258 | try self.pwriteAll(bw.buffer, shdr.sh_offset); |
| ... | ... | @@ -3262,7 +3261,7 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 3262 | 3261 | if (self.section_indexes.plt_got) |shndx| { |
| 3263 | 3262 | const shdr = slice.items(.shdr)[shndx]; |
| 3264 | 3263 | try buffer.resize(gpa, self.plt_got.size(self)); |
| 3265 | bw.initFixed(buffer.items); | |
| 3264 | bw = .fixed(buffer.items); | |
| 3266 | 3265 | try self.plt_got.write(self, &bw); |
| 3267 | 3266 | assert(bw.end == bw.buffer.len); |
| 3268 | 3267 | try self.pwriteAll(bw.buffer, shdr.sh_offset); |
| ... | ... | @@ -3883,7 +3882,7 @@ fn fmtShdr(self: *Elf, shdr: elf.Elf64_Shdr) std.fmt.Formatter(formatShdr) { |
| 3883 | 3882 | } }; |
| 3884 | 3883 | } |
| 3885 | 3884 | |
| 3886 | fn formatShdr(ctx: FormatShdrCtx, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 3885 | fn formatShdr(ctx: FormatShdrCtx, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 3887 | 3886 | _ = unused_fmt_string; |
| 3888 | 3887 | const shdr = ctx.shdr; |
| 3889 | 3888 | try bw.print("{s} : @{x} ({x}) : align({x}) : size({x}) : entsize({x}) : flags({f})", .{ |
| ... | ... | @@ -3898,7 +3897,7 @@ pub fn fmtShdrFlags(sh_flags: u64) std.fmt.Formatter(formatShdrFlags) { |
| 3898 | 3897 | return .{ .data = sh_flags }; |
| 3899 | 3898 | } |
| 3900 | 3899 | |
| 3901 | fn formatShdrFlags(sh_flags: u64, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) !void { | |
| 3900 | fn formatShdrFlags(sh_flags: u64, bw: *Writer, comptime unused_fmt_string: []const u8) !void { | |
| 3902 | 3901 | _ = unused_fmt_string; |
| 3903 | 3902 | if (elf.SHF_WRITE & sh_flags != 0) { |
| 3904 | 3903 | try bw.writeByte('W'); |
| ... | ... | @@ -3958,7 +3957,7 @@ fn fmtPhdr(self: *Elf, phdr: elf.Elf64_Phdr) std.fmt.Formatter(formatPhdr) { |
| 3958 | 3957 | |
| 3959 | 3958 | fn formatPhdr( |
| 3960 | 3959 | ctx: FormatPhdrCtx, |
| 3961 | bw: *std.io.BufferedWriter, | |
| 3960 | bw: *Writer, | |
| 3962 | 3961 | comptime unused_fmt_string: []const u8, |
| 3963 | 3962 | ) !void { |
| 3964 | 3963 | _ = unused_fmt_string; |
| ... | ... | @@ -3994,7 +3993,7 @@ pub fn dumpState(self: *Elf) std.fmt.Formatter(fmtDumpState) { |
| 3994 | 3993 | |
| 3995 | 3994 | fn fmtDumpState( |
| 3996 | 3995 | self: *Elf, |
| 3997 | bw: *std.io.BufferedWriter, | |
| 3996 | bw: *Writer, | |
| 3998 | 3997 | comptime unused_fmt_string: []const u8, |
| 3999 | 3998 | ) !void { |
| 4000 | 3999 | _ = unused_fmt_string; |
| ... | ... | @@ -4216,7 +4215,7 @@ pub const Ref = struct { |
| 4216 | 4215 | return ref.index == other.index and ref.file == other.file; |
| 4217 | 4216 | } |
| 4218 | 4217 | |
| 4219 | pub fn format(ref: Ref, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 4218 | pub fn format(ref: Ref, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 4220 | 4219 | _ = unused_fmt_string; |
| 4221 | 4220 | try bw.print("ref({},{})", .{ ref.index, ref.file }); |
| 4222 | 4221 | } |
| ... | ... | @@ -4493,6 +4492,7 @@ const Allocator = std.mem.Allocator; |
| 4493 | 4492 | const Hash = std.hash.Wyhash; |
| 4494 | 4493 | const Path = std.Build.Cache.Path; |
| 4495 | 4494 | const Stat = std.Build.Cache.File.Stat; |
| 4495 | const Writer = std.io.Writer; | |
| 4496 | 4496 | |
| 4497 | 4497 | const codegen = @import("../codegen.zig"); |
| 4498 | 4498 | const dev = @import("../dev.zig"); |
src/link/Elf/Archive.zig+5-4| ... | ... | @@ -184,7 +184,7 @@ pub const ArSymtab = struct { |
| 184 | 184 | } |
| 185 | 185 | } |
| 186 | 186 | |
| 187 | pub fn format(ar: ArSymtab, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 187 | pub fn format(ar: ArSymtab, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 188 | 188 | _ = ar; |
| 189 | 189 | _ = bw; |
| 190 | 190 | _ = unused_fmt_string; |
| ... | ... | @@ -203,7 +203,7 @@ pub const ArSymtab = struct { |
| 203 | 203 | } }; |
| 204 | 204 | } |
| 205 | 205 | |
| 206 | fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 206 | fn format2(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 207 | 207 | _ = unused_fmt_string; |
| 208 | 208 | const ar = ctx.ar; |
| 209 | 209 | const elf_file = ctx.elf_file; |
| ... | ... | @@ -251,8 +251,8 @@ pub const ArStrtab = struct { |
| 251 | 251 | try writer.writeAll(ar.buffer.items); |
| 252 | 252 | } |
| 253 | 253 | |
| 254 | pub fn format(ar: ArStrtab, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 255 | _ = unused_fmt_string; | |
| 254 | pub fn format(ar: ArStrtab, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 255 | comptime assert(unused_fmt_string.len == 0); | |
| 256 | 256 | try bw.print("{f}", .{std.fmt.fmtSliceEscapeLower(ar.buffer.items)}); |
| 257 | 257 | } |
| 258 | 258 | }; |
| ... | ... | @@ -277,6 +277,7 @@ const log = std.log.scoped(.link); |
| 277 | 277 | const mem = std.mem; |
| 278 | 278 | const Path = std.Build.Cache.Path; |
| 279 | 279 | const Allocator = std.mem.Allocator; |
| 280 | const Writer = std.io.Writer; | |
| 280 | 281 | |
| 281 | 282 | const Diags = @import("../../link.zig").Diags; |
| 282 | 283 | const Archive = @This(); |
src/link/Elf/Atom.zig+23-25| ... | ... | @@ -622,8 +622,7 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) RelocError!voi |
| 622 | 622 | const cpu_arch = elf_file.getTarget().cpu.arch; |
| 623 | 623 | const file_ptr = self.file(elf_file).?; |
| 624 | 624 | |
| 625 | var bw: std.io.BufferedWriter = undefined; | |
| 626 | bw.initFixed(code); | |
| 625 | var bw: Writer = .fixed(code); | |
| 627 | 626 | |
| 628 | 627 | const rels = self.relocs(elf_file); |
| 629 | 628 | var it = RelocsIterator{ .relocs = rels }; |
| ... | ... | @@ -807,8 +806,7 @@ pub fn resolveRelocsNonAlloc(self: Atom, elf_file: *Elf, code: []u8, undefs: any |
| 807 | 806 | const cpu_arch = elf_file.getTarget().cpu.arch; |
| 808 | 807 | const file_ptr = self.file(elf_file).?; |
| 809 | 808 | |
| 810 | var bw: std.io.BufferedWriter = undefined; | |
| 811 | bw.initFixed(code); | |
| 809 | var bw: Writer = .fixed(code); | |
| 812 | 810 | |
| 813 | 811 | const rels = self.relocs(elf_file); |
| 814 | 812 | var has_reloc_errors = false; |
| ... | ... | @@ -908,7 +906,7 @@ pub fn setExtra(atom: Atom, extras: Extra, elf_file: *Elf) void { |
| 908 | 906 | atom.file(elf_file).?.setAtomExtra(atom.extra_index, extras); |
| 909 | 907 | } |
| 910 | 908 | |
| 911 | pub fn format(atom: Atom, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 909 | pub fn format(atom: Atom, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 912 | 910 | _ = atom; |
| 913 | 911 | _ = bw; |
| 914 | 912 | _ = unused_fmt_string; |
| ... | ... | @@ -927,7 +925,7 @@ const FormatContext = struct { |
| 927 | 925 | elf_file: *Elf, |
| 928 | 926 | }; |
| 929 | 927 | |
| 930 | fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 928 | fn format2(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 931 | 929 | _ = unused_fmt_string; |
| 932 | 930 | const atom = ctx.atom; |
| 933 | 931 | const elf_file = ctx.elf_file; |
| ... | ... | @@ -1079,8 +1077,8 @@ const x86_64 = struct { |
| 1079 | 1077 | target: *const Symbol, |
| 1080 | 1078 | args: ResolveArgs, |
| 1081 | 1079 | it: *RelocsIterator, |
| 1082 | bw: *std.io.BufferedWriter, | |
| 1083 | ) std.io.Writer.Error!void { | |
| 1080 | bw: *Writer, | |
| 1081 | ) Writer.Error!void { | |
| 1084 | 1082 | dev.check(.x86_64_backend); |
| 1085 | 1083 | const t = &elf_file.base.comp.root_mod.resolved_target.result; |
| 1086 | 1084 | const diags = &elf_file.base.comp.link_diags; |
| ... | ... | @@ -1211,8 +1209,8 @@ const x86_64 = struct { |
| 1211 | 1209 | rel: elf.Elf64_Rela, |
| 1212 | 1210 | target: *const Symbol, |
| 1213 | 1211 | args: ResolveArgs, |
| 1214 | bw: *std.io.BufferedWriter, | |
| 1215 | ) std.io.Writer.Error!void { | |
| 1212 | bw: *Writer, | |
| 1213 | ) Writer.Error!void { | |
| 1216 | 1214 | dev.check(.x86_64_backend); |
| 1217 | 1215 | |
| 1218 | 1216 | const r_type: elf.R_X86_64 = @enumFromInt(rel.r_type()); |
| ... | ... | @@ -1287,7 +1285,7 @@ const x86_64 = struct { |
| 1287 | 1285 | rels: []const elf.Elf64_Rela, |
| 1288 | 1286 | value: i32, |
| 1289 | 1287 | elf_file: *Elf, |
| 1290 | bw: *std.io.BufferedWriter, | |
| 1288 | bw: *Writer, | |
| 1291 | 1289 | ) !void { |
| 1292 | 1290 | dev.check(.x86_64_backend); |
| 1293 | 1291 | assert(rels.len == 2); |
| ... | ... | @@ -1327,7 +1325,7 @@ const x86_64 = struct { |
| 1327 | 1325 | rels: []const elf.Elf64_Rela, |
| 1328 | 1326 | value: i32, |
| 1329 | 1327 | elf_file: *Elf, |
| 1330 | bw: *std.io.BufferedWriter, | |
| 1328 | bw: *Writer, | |
| 1331 | 1329 | ) !void { |
| 1332 | 1330 | dev.check(.x86_64_backend); |
| 1333 | 1331 | assert(rels.len == 2); |
| ... | ... | @@ -1388,7 +1386,7 @@ const x86_64 = struct { |
| 1388 | 1386 | .{ .imm = .s(-129) }, |
| 1389 | 1387 | }, t) catch return false; |
| 1390 | 1388 | var buf: [std.atomic.cache_line]u8 = undefined; |
| 1391 | var bw = std.io.Writer.null.buffered(&buf); | |
| 1389 | var bw = Writer.null.buffered(&buf); | |
| 1392 | 1390 | inst.encode(&bw, .{}) catch return false; |
| 1393 | 1391 | return true; |
| 1394 | 1392 | }, |
| ... | ... | @@ -1435,7 +1433,7 @@ const x86_64 = struct { |
| 1435 | 1433 | rels: []const elf.Elf64_Rela, |
| 1436 | 1434 | value: i32, |
| 1437 | 1435 | elf_file: *Elf, |
| 1438 | bw: *std.io.BufferedWriter, | |
| 1436 | bw: *Writer, | |
| 1439 | 1437 | ) !void { |
| 1440 | 1438 | dev.check(.x86_64_backend); |
| 1441 | 1439 | assert(rels.len == 2); |
| ... | ... | @@ -1483,8 +1481,7 @@ const x86_64 = struct { |
| 1483 | 1481 | } |
| 1484 | 1482 | |
| 1485 | 1483 | fn encode(insts: []const Instruction, code: []u8) !void { |
| 1486 | var bw: std.io.BufferedWriter = undefined; | |
| 1487 | bw.initFixed(code); | |
| 1484 | var bw: Writer = .fixed(code); | |
| 1488 | 1485 | for (insts) |inst| try inst.encode(&bw, .{}); |
| 1489 | 1486 | } |
| 1490 | 1487 | |
| ... | ... | @@ -1589,8 +1586,8 @@ const aarch64 = struct { |
| 1589 | 1586 | target: *const Symbol, |
| 1590 | 1587 | args: ResolveArgs, |
| 1591 | 1588 | it: *RelocsIterator, |
| 1592 | bw: *std.io.BufferedWriter, | |
| 1593 | ) std.io.Writer.Error!void { | |
| 1589 | bw: *Writer, | |
| 1590 | ) Writer.Error!void { | |
| 1594 | 1591 | _ = it; |
| 1595 | 1592 | |
| 1596 | 1593 | const diags = &elf_file.base.comp.link_diags; |
| ... | ... | @@ -1792,7 +1789,7 @@ const aarch64 = struct { |
| 1792 | 1789 | rel: elf.Elf64_Rela, |
| 1793 | 1790 | target: *const Symbol, |
| 1794 | 1791 | args: ResolveArgs, |
| 1795 | bw: *std.io.BufferedWriter, | |
| 1792 | bw: *Writer, | |
| 1796 | 1793 | ) !void { |
| 1797 | 1794 | const r_type: elf.R_AARCH64 = @enumFromInt(rel.r_type()); |
| 1798 | 1795 | _, const A, const S, _, _, _, _ = args; |
| ... | ... | @@ -1865,7 +1862,7 @@ const riscv = struct { |
| 1865 | 1862 | target: *const Symbol, |
| 1866 | 1863 | args: ResolveArgs, |
| 1867 | 1864 | it: *RelocsIterator, |
| 1868 | bw: *std.io.BufferedWriter, | |
| 1865 | bw: *Writer, | |
| 1869 | 1866 | ) !void { |
| 1870 | 1867 | const diags = &elf_file.base.comp.link_diags; |
| 1871 | 1868 | const r_type: elf.R_RISCV = @enumFromInt(rel.r_type()); |
| ... | ... | @@ -2000,8 +1997,8 @@ const riscv = struct { |
| 2000 | 1997 | rel: elf.Elf64_Rela, |
| 2001 | 1998 | target: *const Symbol, |
| 2002 | 1999 | args: ResolveArgs, |
| 2003 | bw: *std.io.BufferedWriter, | |
| 2004 | ) std.io.Writer.Error!void { | |
| 2000 | bw: *Writer, | |
| 2001 | ) Writer.Error!void { | |
| 2005 | 2002 | const r_type: elf.R_RISCV = @enumFromInt(rel.r_type()); |
| 2006 | 2003 | |
| 2007 | 2004 | _, const A, const S, const GOT, _, _, const DTP = args; |
| ... | ... | @@ -2105,14 +2102,15 @@ pub const Extra = struct { |
| 2105 | 2102 | const std = @import("std"); |
| 2106 | 2103 | const assert = std.debug.assert; |
| 2107 | 2104 | const elf = std.elf; |
| 2108 | const eh_frame = @import("eh_frame.zig"); | |
| 2109 | 2105 | const log = std.log.scoped(.link); |
| 2110 | 2106 | const math = std.math; |
| 2111 | 2107 | const mem = std.mem; |
| 2112 | 2108 | const relocs_log = std.log.scoped(.link_relocs); |
| 2113 | const relocation = @import("relocation.zig"); | |
| 2114 | ||
| 2115 | 2109 | const Allocator = mem.Allocator; |
| 2110 | const Writer = std.io.Writer; | |
| 2111 | ||
| 2112 | const eh_frame = @import("eh_frame.zig"); | |
| 2113 | const relocation = @import("relocation.zig"); | |
| 2116 | 2114 | const Atom = @This(); |
| 2117 | 2115 | const Elf = @import("../Elf.zig"); |
| 2118 | 2116 | const Fde = eh_frame.Fde; |
src/link/Elf/AtomList.zig+6-5| ... | ... | @@ -167,7 +167,7 @@ pub fn lastAtom(list: AtomList, elf_file: *Elf) *Atom { |
| 167 | 167 | return elf_file.atom(list.atoms.keys()[list.atoms.keys().len - 1]).?; |
| 168 | 168 | } |
| 169 | 169 | |
| 170 | pub fn format(list: AtomList, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 170 | pub fn format(list: AtomList, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 171 | 171 | _ = list; |
| 172 | 172 | _ = bw; |
| 173 | 173 | _ = unused_fmt_string; |
| ... | ... | @@ -180,8 +180,8 @@ pub fn fmt(list: AtomList, elf_file: *Elf) std.fmt.Formatter(format2) { |
| 180 | 180 | return .{ .data = .{ list, elf_file } }; |
| 181 | 181 | } |
| 182 | 182 | |
| 183 | fn format2(ctx: FormatCtx, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 184 | _ = unused_fmt_string; | |
| 183 | fn format2(ctx: FormatCtx, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 184 | comptime assert(unused_fmt_string.len == 0); | |
| 185 | 185 | const list, const elf_file = ctx; |
| 186 | 186 | try bw.print("list : @{x} : shdr({d}) : align({x}) : size({x})", .{ |
| 187 | 187 | list.address(elf_file), list.output_section_index, |
| ... | ... | @@ -195,13 +195,14 @@ fn format2(ctx: FormatCtx, bw: *std.io.BufferedWriter, comptime unused_fmt_strin |
| 195 | 195 | try bw.writeAll(" }"); |
| 196 | 196 | } |
| 197 | 197 | |
| 198 | const std = @import("std"); | |
| 198 | 199 | const assert = std.debug.assert; |
| 199 | 200 | const elf = std.elf; |
| 200 | 201 | const log = std.log.scoped(.link); |
| 201 | 202 | const math = std.math; |
| 202 | const std = @import("std"); | |
| 203 | ||
| 204 | 203 | const Allocator = std.mem.Allocator; |
| 204 | const Writer = std.io.Writer; | |
| 205 | ||
| 205 | 206 | const Atom = @import("Atom.zig"); |
| 206 | 207 | const AtomList = @This(); |
| 207 | 208 | const Elf = @import("../Elf.zig"); |
src/link/Elf/LinkerDefined.zig+5-4| ... | ... | @@ -449,8 +449,8 @@ const FormatContext = struct { |
| 449 | 449 | elf_file: *Elf, |
| 450 | 450 | }; |
| 451 | 451 | |
| 452 | fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 453 | _ = unused_fmt_string; | |
| 452 | fn formatSymtab(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 453 | comptime assert(unused_fmt_string.len == 0); | |
| 454 | 454 | const self = ctx.self; |
| 455 | 455 | const elf_file = ctx.elf_file; |
| 456 | 456 | try bw.writeAll(" globals\n"); |
| ... | ... | @@ -464,12 +464,13 @@ fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_ |
| 464 | 464 | } |
| 465 | 465 | } |
| 466 | 466 | |
| 467 | const std = @import("std"); | |
| 468 | const Allocator = mem.Allocator; | |
| 467 | 469 | const assert = std.debug.assert; |
| 468 | 470 | const elf = std.elf; |
| 469 | 471 | const mem = std.mem; |
| 470 | const std = @import("std"); | |
| 472 | const Writer = std.io.Writer; | |
| 471 | 473 | |
| 472 | const Allocator = mem.Allocator; | |
| 473 | 474 | const Atom = @import("Atom.zig"); |
| 474 | 475 | const Elf = @import("../Elf.zig"); |
| 475 | 476 | const File = @import("file.zig").File; |
src/link/Elf/Merge.zig+7-6| ... | ... | @@ -157,7 +157,7 @@ pub const Section = struct { |
| 157 | 157 | } |
| 158 | 158 | }; |
| 159 | 159 | |
| 160 | pub fn format(msec: Section, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 160 | pub fn format(msec: Section, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 161 | 161 | _ = msec; |
| 162 | 162 | _ = bw; |
| 163 | 163 | _ = unused_fmt_string; |
| ... | ... | @@ -176,7 +176,7 @@ pub const Section = struct { |
| 176 | 176 | elf_file: *Elf, |
| 177 | 177 | }; |
| 178 | 178 | |
| 179 | pub fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 179 | pub fn format2(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 180 | 180 | _ = unused_fmt_string; |
| 181 | 181 | const msec = ctx.msec; |
| 182 | 182 | const elf_file = ctx.elf_file; |
| ... | ... | @@ -219,7 +219,7 @@ pub const Subsection = struct { |
| 219 | 219 | return msec.bytes.items[msub.string_index..][0..msub.size]; |
| 220 | 220 | } |
| 221 | 221 | |
| 222 | pub fn format(msub: Subsection, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 222 | pub fn format(msub: Subsection, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 223 | 223 | _ = msub; |
| 224 | 224 | _ = bw; |
| 225 | 225 | _ = unused_fmt_string; |
| ... | ... | @@ -238,7 +238,7 @@ pub const Subsection = struct { |
| 238 | 238 | elf_file: *Elf, |
| 239 | 239 | }; |
| 240 | 240 | |
| 241 | pub fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 241 | pub fn format2(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 242 | 242 | _ = unused_fmt_string; |
| 243 | 243 | const msub = ctx.msub; |
| 244 | 244 | const elf_file = ctx.elf_file; |
| ... | ... | @@ -307,11 +307,12 @@ pub const InputSection = struct { |
| 307 | 307 | |
| 308 | 308 | const String = struct { pos: u32, len: u32 }; |
| 309 | 309 | |
| 310 | const std = @import("std"); | |
| 310 | 311 | const assert = std.debug.assert; |
| 311 | 312 | const mem = std.mem; |
| 312 | const std = @import("std"); | |
| 313 | ||
| 314 | 313 | const Allocator = mem.Allocator; |
| 314 | const Writer = std.io.Writer; | |
| 315 | ||
| 315 | 316 | const Atom = @import("Atom.zig"); |
| 316 | 317 | const Elf = @import("../Elf.zig"); |
| 317 | 318 | const Merge = @This(); |
src/link/Elf/Object.zig+11-12| ... | ... | @@ -448,8 +448,7 @@ fn parseEhFrame( |
| 448 | 448 | const fdes_start = self.fdes.items.len; |
| 449 | 449 | const cies_start = self.cies.items.len; |
| 450 | 450 | |
| 451 | var it: eh_frame.Iterator = undefined; | |
| 452 | it.br.initFixed(raw); | |
| 451 | var it: eh_frame.Iterator = .{ .br = .fixed(raw) }; | |
| 453 | 452 | while (try it.next()) |rec| { |
| 454 | 453 | const rel_range = filterRelocs(self.relocs.items[rel_start..][0..relocs.len], rec.offset, rec.size + 4); |
| 455 | 454 | switch (rec.tag) { |
| ... | ... | @@ -1199,8 +1198,7 @@ pub fn codeDecompressAlloc(self: *Object, elf_file: *Elf, atom_index: Atom.Index |
| 1199 | 1198 | const chdr = (try r.takeStruct(elf.Elf64_Chdr)).*; |
| 1200 | 1199 | switch (chdr.ch_type) { |
| 1201 | 1200 | .ZLIB => { |
| 1202 | var bw: std.io.BufferedWriter = undefined; | |
| 1203 | bw.initFixed(try gpa.alloc(u8, std.math.cast(usize, chdr.ch_size) orelse return error.Overflow)); | |
| 1201 | var bw: Writer = .fixed(try gpa.alloc(u8, std.math.cast(usize, chdr.ch_size) orelse return error.Overflow)); | |
| 1204 | 1202 | errdefer gpa.free(bw.buffer); |
| 1205 | 1203 | try std.compress.zlib.decompress(&r, &bw); |
| 1206 | 1204 | if (bw.end != bw.buffer.len) return error.InputOutput; |
| ... | ... | @@ -1430,7 +1428,7 @@ pub fn group(self: *Object, index: Elf.Group.Index) *Elf.Group { |
| 1430 | 1428 | return &self.groups.items[index]; |
| 1431 | 1429 | } |
| 1432 | 1430 | |
| 1433 | pub fn format(self: *Object, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 1431 | pub fn format(self: *Object, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 1434 | 1432 | _ = self; |
| 1435 | 1433 | _ = bw; |
| 1436 | 1434 | _ = unused_fmt_string; |
| ... | ... | @@ -1449,7 +1447,7 @@ const FormatContext = struct { |
| 1449 | 1447 | elf_file: *Elf, |
| 1450 | 1448 | }; |
| 1451 | 1449 | |
| 1452 | fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 1450 | fn formatSymtab(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 1453 | 1451 | _ = unused_fmt_string; |
| 1454 | 1452 | const object = ctx.object; |
| 1455 | 1453 | const elf_file = ctx.elf_file; |
| ... | ... | @@ -1476,7 +1474,7 @@ pub fn fmtAtoms(self: *Object, elf_file: *Elf) std.fmt.Formatter(formatAtoms) { |
| 1476 | 1474 | } }; |
| 1477 | 1475 | } |
| 1478 | 1476 | |
| 1479 | fn formatAtoms(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 1477 | fn formatAtoms(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 1480 | 1478 | _ = unused_fmt_string; |
| 1481 | 1479 | const object = ctx.object; |
| 1482 | 1480 | try bw.writeAll(" atoms\n"); |
| ... | ... | @@ -1493,7 +1491,7 @@ pub fn fmtCies(self: *Object, elf_file: *Elf) std.fmt.Formatter(formatCies) { |
| 1493 | 1491 | } }; |
| 1494 | 1492 | } |
| 1495 | 1493 | |
| 1496 | fn formatCies(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 1494 | fn formatCies(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 1497 | 1495 | _ = unused_fmt_string; |
| 1498 | 1496 | const object = ctx.object; |
| 1499 | 1497 | try bw.writeAll(" cies\n"); |
| ... | ... | @@ -1509,7 +1507,7 @@ pub fn fmtFdes(self: *Object, elf_file: *Elf) std.fmt.Formatter(formatFdes) { |
| 1509 | 1507 | } }; |
| 1510 | 1508 | } |
| 1511 | 1509 | |
| 1512 | fn formatFdes(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 1510 | fn formatFdes(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 1513 | 1511 | _ = unused_fmt_string; |
| 1514 | 1512 | const object = ctx.object; |
| 1515 | 1513 | try bw.writeAll(" fdes\n"); |
| ... | ... | @@ -1525,7 +1523,7 @@ pub fn fmtGroups(self: *Object, elf_file: *Elf) std.fmt.Formatter(formatGroups) |
| 1525 | 1523 | } }; |
| 1526 | 1524 | } |
| 1527 | 1525 | |
| 1528 | fn formatGroups(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 1526 | fn formatGroups(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 1529 | 1527 | comptime assert(unused_fmt_string.len == 0); |
| 1530 | 1528 | const object = ctx.object; |
| 1531 | 1529 | const elf_file = ctx.elf_file; |
| ... | ... | @@ -1547,8 +1545,8 @@ pub fn fmtPath(self: Object) std.fmt.Formatter(formatPath) { |
| 1547 | 1545 | return .{ .data = self }; |
| 1548 | 1546 | } |
| 1549 | 1547 | |
| 1550 | fn formatPath(object: Object, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 1551 | _ = unused_fmt_string; | |
| 1548 | fn formatPath(object: Object, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 1549 | comptime assert(unused_fmt_string.len == 0); | |
| 1552 | 1550 | if (object.archive) |ar| { |
| 1553 | 1551 | try bw.print("{f}({f})", .{ ar.path, object.path }); |
| 1554 | 1552 | } else { |
| ... | ... | @@ -1574,6 +1572,7 @@ const math = std.math; |
| 1574 | 1572 | const mem = std.mem; |
| 1575 | 1573 | const Path = std.Build.Cache.Path; |
| 1576 | 1574 | const Allocator = std.mem.Allocator; |
| 1575 | const Writer = std.io.Writer; | |
| 1577 | 1576 | |
| 1578 | 1577 | const Diags = @import("../../link.zig").Diags; |
| 1579 | 1578 | const Archive = @import("Archive.zig"); |
src/link/Elf/SharedObject.zig+4-3| ... | ... | @@ -509,7 +509,7 @@ pub fn setSymbolExtra(self: *SharedObject, index: u32, extra: Symbol.Extra) void |
| 509 | 509 | } |
| 510 | 510 | } |
| 511 | 511 | |
| 512 | pub fn format(self: SharedObject, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 512 | pub fn format(self: SharedObject, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 513 | 513 | _ = self; |
| 514 | 514 | _ = bw; |
| 515 | 515 | _ = unused_fmt_string; |
| ... | ... | @@ -528,8 +528,8 @@ const FormatContext = struct { |
| 528 | 528 | elf_file: *Elf, |
| 529 | 529 | }; |
| 530 | 530 | |
| 531 | fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 532 | _ = unused_fmt_string; | |
| 531 | fn formatSymtab(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 532 | comptime assert(unused_fmt_string.len == 0); | |
| 533 | 533 | const shared = ctx.shared; |
| 534 | 534 | const elf_file = ctx.elf_file; |
| 535 | 535 | try bw.writeAll(" globals\n"); |
| ... | ... | @@ -553,6 +553,7 @@ const mem = std.mem; |
| 553 | 553 | const Path = std.Build.Cache.Path; |
| 554 | 554 | const Stat = std.Build.Cache.File.Stat; |
| 555 | 555 | const Allocator = mem.Allocator; |
| 556 | const Writer = std.io.Writer; | |
| 556 | 557 | |
| 557 | 558 | const Elf = @import("../Elf.zig"); |
| 558 | 559 | const File = @import("file.zig").File; |
src/link/Elf/Symbol.zig+7-6| ... | ... | @@ -316,7 +316,7 @@ pub fn setOutputSym(symbol: Symbol, elf_file: *Elf, out: *elf.Elf64_Sym) void { |
| 316 | 316 | out.st_size = esym.st_size; |
| 317 | 317 | } |
| 318 | 318 | |
| 319 | pub fn format(symbol: Symbol, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 319 | pub fn format(symbol: Symbol, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 320 | 320 | _ = symbol; |
| 321 | 321 | _ = bw; |
| 322 | 322 | _ = unused_fmt_string; |
| ... | ... | @@ -335,7 +335,7 @@ pub fn fmtName(symbol: Symbol, elf_file: *Elf) std.fmt.Formatter(formatName) { |
| 335 | 335 | } }; |
| 336 | 336 | } |
| 337 | 337 | |
| 338 | fn formatName(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 338 | fn formatName(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 339 | 339 | _ = unused_fmt_string; |
| 340 | 340 | const elf_file = ctx.elf_file; |
| 341 | 341 | const symbol = ctx.symbol; |
| ... | ... | @@ -358,8 +358,8 @@ pub fn fmt(symbol: Symbol, elf_file: *Elf) std.fmt.Formatter(format2) { |
| 358 | 358 | } }; |
| 359 | 359 | } |
| 360 | 360 | |
| 361 | fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 362 | _ = unused_fmt_string; | |
| 361 | fn format2(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 362 | comptime assert(unused_fmt_string.len == 0); | |
| 363 | 363 | const symbol = ctx.symbol; |
| 364 | 364 | const elf_file = ctx.elf_file; |
| 365 | 365 | try bw.print("%{d} : {f} : @{x}", .{ |
| ... | ... | @@ -461,12 +461,13 @@ pub const Extra = struct { |
| 461 | 461 | |
| 462 | 462 | pub const Index = u32; |
| 463 | 463 | |
| 464 | const std = @import("std"); | |
| 464 | 465 | const assert = std.debug.assert; |
| 465 | 466 | const elf = std.elf; |
| 466 | 467 | const mem = std.mem; |
| 467 | const std = @import("std"); | |
| 468 | const synthetic_sections = @import("synthetic_sections.zig"); | |
| 468 | const Writer = std.io.Writer; | |
| 469 | 469 | |
| 470 | const synthetic_sections = @import("synthetic_sections.zig"); | |
| 470 | 471 | const Atom = @import("Atom.zig"); |
| 471 | 472 | const Elf = @import("../Elf.zig"); |
| 472 | 473 | const File = @import("file.zig").File; |
src/link/Elf/Thunk.zig+6-5| ... | ... | @@ -65,7 +65,7 @@ fn trampolineSize(cpu_arch: std.Target.Cpu.Arch) usize { |
| 65 | 65 | }; |
| 66 | 66 | } |
| 67 | 67 | |
| 68 | pub fn format(thunk: Thunk, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 68 | pub fn format(thunk: Thunk, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 69 | 69 | _ = thunk; |
| 70 | 70 | _ = bw; |
| 71 | 71 | _ = unused_fmt_string; |
| ... | ... | @@ -84,8 +84,8 @@ const FormatContext = struct { |
| 84 | 84 | elf_file: *Elf, |
| 85 | 85 | }; |
| 86 | 86 | |
| 87 | fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 88 | _ = unused_fmt_string; | |
| 87 | fn format2(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 88 | comptime assert(unused_fmt_string.len == 0); | |
| 89 | 89 | const thunk = ctx.thunk; |
| 90 | 90 | const elf_file = ctx.elf_file; |
| 91 | 91 | try bw.print("@{x} : size({x})\n", .{ thunk.value, thunk.size(elf_file) }); |
| ... | ... | @@ -117,14 +117,15 @@ const aarch64 = struct { |
| 117 | 117 | const Instruction = util.Instruction; |
| 118 | 118 | }; |
| 119 | 119 | |
| 120 | const std = @import("std"); | |
| 120 | 121 | const assert = std.debug.assert; |
| 121 | 122 | const elf = std.elf; |
| 122 | 123 | const log = std.log.scoped(.link); |
| 123 | 124 | const math = std.math; |
| 124 | 125 | const mem = std.mem; |
| 125 | const std = @import("std"); | |
| 126 | ||
| 127 | 126 | const Allocator = mem.Allocator; |
| 127 | const Writer = std.io.Writer; | |
| 128 | ||
| 128 | 129 | const Atom = @import("Atom.zig"); |
| 129 | 130 | const Elf = @import("../Elf.zig"); |
| 130 | 131 | const Symbol = @import("Symbol.zig"); |
src/link/Elf/ZigObject.zig+4-3| ... | ... | @@ -2198,7 +2198,7 @@ const FormatContext = struct { |
| 2198 | 2198 | elf_file: *Elf, |
| 2199 | 2199 | }; |
| 2200 | 2200 | |
| 2201 | fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 2201 | fn formatSymtab(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 2202 | 2202 | _ = unused_fmt_string; |
| 2203 | 2203 | const self = ctx.self; |
| 2204 | 2204 | const elf_file = ctx.elf_file; |
| ... | ... | @@ -2221,8 +2221,8 @@ pub fn fmtAtoms(self: *ZigObject, elf_file: *Elf) std.fmt.Formatter(formatAtoms) |
| 2221 | 2221 | } }; |
| 2222 | 2222 | } |
| 2223 | 2223 | |
| 2224 | fn formatAtoms(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 2225 | _ = unused_fmt_string; | |
| 2224 | fn formatAtoms(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 2225 | comptime assert(unused_fmt_string.len == 0); | |
| 2226 | 2226 | try bw.writeAll(" atoms\n"); |
| 2227 | 2227 | for (ctx.self.atoms_indexes.items) |atom_index| { |
| 2228 | 2228 | const atom_ptr = ctx.self.atom(atom_index) orelse continue; |
| ... | ... | @@ -2326,6 +2326,7 @@ const target_util = @import("../../target.zig"); |
| 2326 | 2326 | const trace = @import("../../tracy.zig").trace; |
| 2327 | 2327 | const std = @import("std"); |
| 2328 | 2328 | const Allocator = std.mem.Allocator; |
| 2329 | const Writer = std.io.Writer; | |
| 2329 | 2330 | |
| 2330 | 2331 | const Archive = @import("Archive.zig"); |
| 2331 | 2332 | const Atom = @import("Atom.zig"); |
src/link/Elf/eh_frame.zig+10-9| ... | ... | @@ -49,7 +49,7 @@ pub const Fde = struct { |
| 49 | 49 | |
| 50 | 50 | pub fn format( |
| 51 | 51 | fde: Fde, |
| 52 | bw: *std.io.BufferedWriter, | |
| 52 | bw: *Writer, | |
| 53 | 53 | comptime unused_fmt_string: []const u8, |
| 54 | 54 | ) !void { |
| 55 | 55 | _ = fde; |
| ... | ... | @@ -72,7 +72,7 @@ pub const Fde = struct { |
| 72 | 72 | |
| 73 | 73 | fn format2( |
| 74 | 74 | ctx: FdeFormatContext, |
| 75 | bw: *std.io.BufferedWriter, | |
| 75 | bw: *Writer, | |
| 76 | 76 | comptime unused_fmt_string: []const u8, |
| 77 | 77 | ) !void { |
| 78 | 78 | _ = unused_fmt_string; |
| ... | ... | @@ -148,7 +148,7 @@ pub const Cie = struct { |
| 148 | 148 | |
| 149 | 149 | pub fn format( |
| 150 | 150 | cie: Cie, |
| 151 | bw: *std.io.BufferedWriter, | |
| 151 | bw: *Writer, | |
| 152 | 152 | comptime unused_fmt_string: []const u8, |
| 153 | 153 | ) !void { |
| 154 | 154 | _ = cie; |
| ... | ... | @@ -171,7 +171,7 @@ pub const Cie = struct { |
| 171 | 171 | |
| 172 | 172 | fn format2( |
| 173 | 173 | ctx: CieFormatContext, |
| 174 | bw: *std.io.BufferedWriter, | |
| 174 | bw: *Writer, | |
| 175 | 175 | comptime unused_fmt_string: []const u8, |
| 176 | 176 | ) !void { |
| 177 | 177 | _ = unused_fmt_string; |
| ... | ... | @@ -319,7 +319,7 @@ fn resolveReloc(rec: anytype, sym: *const Symbol, rel: elf.Elf64_Rela, elf_file: |
| 319 | 319 | } |
| 320 | 320 | } |
| 321 | 321 | |
| 322 | pub fn writeEhFrame(elf_file: *Elf, bw: *std.io.BufferedWriter) !void { | |
| 322 | pub fn writeEhFrame(elf_file: *Elf, bw: *Writer) !void { | |
| 323 | 323 | relocs_log.debug("{x}: .eh_frame", .{ |
| 324 | 324 | elf_file.sections.items(.shdr)[elf_file.section_indexes.eh_frame.?].sh_addr, |
| 325 | 325 | }); |
| ... | ... | @@ -380,7 +380,7 @@ pub fn writeEhFrame(elf_file: *Elf, bw: *std.io.BufferedWriter) !void { |
| 380 | 380 | if (has_reloc_errors) return error.RelocFailure; |
| 381 | 381 | } |
| 382 | 382 | |
| 383 | pub fn writeEhFrameRelocatable(elf_file: *Elf, bw: *std.io.BufferedWriter) !void { | |
| 383 | pub fn writeEhFrameRelocatable(elf_file: *Elf, bw: *Writer) !void { | |
| 384 | 384 | for (elf_file.objects.items) |index| { |
| 385 | 385 | const object = elf_file.file(index).?.object; |
| 386 | 386 | |
| ... | ... | @@ -482,7 +482,7 @@ pub fn writeEhFrameRelocs(elf_file: *Elf, relocs: *std.ArrayList(elf.Elf64_Rela) |
| 482 | 482 | } |
| 483 | 483 | } |
| 484 | 484 | |
| 485 | pub fn writeEhFrameHdr(elf_file: *Elf, bw: *std.io.BufferedWriter) !void { | |
| 485 | pub fn writeEhFrameHdr(elf_file: *Elf, bw: *Writer) !void { | |
| 486 | 486 | const comp = elf_file.base.comp; |
| 487 | 487 | const gpa = comp.gpa; |
| 488 | 488 | |
| ... | ... | @@ -607,9 +607,10 @@ const assert = std.debug.assert; |
| 607 | 607 | const elf = std.elf; |
| 608 | 608 | const math = std.math; |
| 609 | 609 | const relocs_log = std.log.scoped(.link_relocs); |
| 610 | const relocation = @import("relocation.zig"); | |
| 611 | ||
| 610 | const Writer = std.io.Writer; | |
| 612 | 611 | const Allocator = std.mem.Allocator; |
| 612 | ||
| 613 | const relocation = @import("relocation.zig"); | |
| 613 | 614 | const Atom = @import("Atom.zig"); |
| 614 | 615 | const DW_EH_PE = std.dwarf.EH.PE; |
| 615 | 616 | const Elf = @import("../Elf.zig"); |
src/link/Elf/file.zig+4-2| ... | ... | @@ -14,8 +14,8 @@ pub const File = union(enum) { |
| 14 | 14 | return .{ .data = file }; |
| 15 | 15 | } |
| 16 | 16 | |
| 17 | fn formatPath(file: File, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 18 | _ = unused_fmt_string; | |
| 17 | fn formatPath(file: File, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 18 | comptime assert(unused_fmt_string.len == 0); | |
| 19 | 19 | switch (file) { |
| 20 | 20 | .zig_object => |zo| try bw.writeAll(zo.basename), |
| 21 | 21 | .linker_defined => try bw.writeAll("(linker defined)"), |
| ... | ... | @@ -289,6 +289,8 @@ const elf = std.elf; |
| 289 | 289 | const log = std.log.scoped(.link); |
| 290 | 290 | const Path = std.Build.Cache.Path; |
| 291 | 291 | const Allocator = std.mem.Allocator; |
| 292 | const Writer = std.io.Writer; | |
| 293 | const assert = std.debug.assert; | |
| 292 | 294 | |
| 293 | 295 | const Archive = @import("Archive.zig"); |
| 294 | 296 | const Atom = @import("Atom.zig"); |
src/link/Elf/gc.zig+4-3| ... | ... | @@ -185,8 +185,8 @@ const Level = struct { |
| 185 | 185 | self.value += 1; |
| 186 | 186 | } |
| 187 | 187 | |
| 188 | pub fn format(self: *const @This(), bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 189 | _ = unused_fmt_string; | |
| 188 | pub fn format(self: *const @This(), bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 189 | comptime assert(unused_fmt_string.len == 0); | |
| 190 | 190 | try bw.splatByteAll(' ', self.value); |
| 191 | 191 | } |
| 192 | 192 | }; |
| ... | ... | @@ -198,8 +198,9 @@ const assert = std.debug.assert; |
| 198 | 198 | const elf = std.elf; |
| 199 | 199 | const gc_track_live_log = std.log.scoped(.gc_track_live); |
| 200 | 200 | const mem = std.mem; |
| 201 | ||
| 202 | 201 | const Allocator = mem.Allocator; |
| 202 | const Writer = std.io.Writer; | |
| 203 | ||
| 203 | 204 | const Atom = @import("Atom.zig"); |
| 204 | 205 | const Elf = @import("../Elf.zig"); |
| 205 | 206 | const File = @import("file.zig").File; |
src/link/Elf/relocatable.zig+7-8| ... | ... | @@ -100,8 +100,7 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) !void { |
| 100 | 100 | state_log.debug("ar_strtab\n{f}\n", .{ar_strtab}); |
| 101 | 101 | } |
| 102 | 102 | |
| 103 | var bw: std.io.BufferedWriter = undefined; | |
| 104 | bw.initFixed(try gpa.alloc(u8, total_size)); | |
| 103 | var bw: Writer = .fixed(try gpa.alloc(u8, total_size)); | |
| 105 | 104 | defer gpa.free(bw.buffer); |
| 106 | 105 | |
| 107 | 106 | // Write magic |
| ... | ... | @@ -406,8 +405,7 @@ fn writeSyntheticSections(elf_file: *Elf) !void { |
| 406 | 405 | }; |
| 407 | 406 | const shdr = slice.items(.shdr)[shndx]; |
| 408 | 407 | const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow; |
| 409 | var bw: std.io.BufferedWriter = undefined; | |
| 410 | bw.initFixed(try gpa.alloc(u8, sh_size - existing_size)); | |
| 408 | var bw: Writer = .fixed(try gpa.alloc(u8, sh_size - existing_size)); | |
| 411 | 409 | defer gpa.free(bw.buffer); |
| 412 | 410 | try eh_frame.writeEhFrameRelocatable(elf_file, &bw); |
| 413 | 411 | log.debug("writing .eh_frame from 0x{x} to 0x{x}", .{ |
| ... | ... | @@ -458,18 +456,19 @@ fn writeGroups(elf_file: *Elf) !void { |
| 458 | 456 | } |
| 459 | 457 | } |
| 460 | 458 | |
| 459 | const std = @import("std"); | |
| 461 | 460 | const assert = std.debug.assert; |
| 462 | const build_options = @import("build_options"); | |
| 463 | const eh_frame = @import("eh_frame.zig"); | |
| 464 | 461 | const elf = std.elf; |
| 465 | const link = @import("../../link.zig"); | |
| 466 | 462 | const log = std.log.scoped(.link); |
| 467 | 463 | const math = std.math; |
| 468 | 464 | const mem = std.mem; |
| 469 | 465 | const state_log = std.log.scoped(.link_state); |
| 470 | 466 | const Path = std.Build.Cache.Path; |
| 471 | const std = @import("std"); | |
| 467 | const Writer = std.io.Writer; | |
| 472 | 468 | |
| 469 | const link = @import("../../link.zig"); | |
| 470 | const build_options = @import("build_options"); | |
| 471 | const eh_frame = @import("eh_frame.zig"); | |
| 473 | 472 | const Archive = @import("Archive.zig"); |
| 474 | 473 | const Compilation = @import("../../Compilation.zig"); |
| 475 | 474 | const Elf = @import("../Elf.zig"); |
src/link/Elf/relocation.zig+4-3| ... | ... | @@ -148,8 +148,8 @@ pub fn fmtRelocType(r_type: u32, cpu_arch: std.Target.Cpu.Arch) std.fmt.Formatte |
| 148 | 148 | } }; |
| 149 | 149 | } |
| 150 | 150 | |
| 151 | fn formatRelocType(ctx: FormatRelocTypeCtx, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 152 | _ = unused_fmt_string; | |
| 151 | fn formatRelocType(ctx: FormatRelocTypeCtx, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 152 | comptime assert(unused_fmt_string.len == 0); | |
| 153 | 153 | const r_type = ctx.r_type; |
| 154 | 154 | switch (ctx.cpu_arch) { |
| 155 | 155 | .x86_64 => try bw.print("R_X86_64_{s}", .{@tagName(@as(elf.R_X86_64, @enumFromInt(r_type)))}), |
| ... | ... | @@ -159,9 +159,10 @@ fn formatRelocType(ctx: FormatRelocTypeCtx, bw: *std.io.BufferedWriter, comptime |
| 159 | 159 | } |
| 160 | 160 | } |
| 161 | 161 | |
| 162 | const std = @import("std"); | |
| 162 | 163 | const assert = std.debug.assert; |
| 163 | 164 | const elf = std.elf; |
| 164 | const std = @import("std"); | |
| 165 | const Writer = std.io.Writer; | |
| 165 | 166 | |
| 166 | 167 | const Dwarf = @import("../Dwarf.zig"); |
| 167 | 168 | const Elf = @import("../Elf.zig"); |
src/link/Elf/synthetic_sections.zig+22-20| ... | ... | @@ -94,7 +94,7 @@ pub const DynamicSection = struct { |
| 94 | 94 | return nentries * @sizeOf(elf.Elf64_Dyn); |
| 95 | 95 | } |
| 96 | 96 | |
| 97 | pub fn write(dt: DynamicSection, elf_file: *Elf, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 97 | pub fn write(dt: DynamicSection, elf_file: *Elf, bw: *Writer) Writer.Error!void { | |
| 98 | 98 | const shdrs = elf_file.sections.items(.shdr); |
| 99 | 99 | |
| 100 | 100 | // NEEDED |
| ... | ... | @@ -360,7 +360,7 @@ pub const GotSection = struct { |
| 360 | 360 | return s; |
| 361 | 361 | } |
| 362 | 362 | |
| 363 | pub fn write(got: GotSection, elf_file: *Elf, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 363 | pub fn write(got: GotSection, elf_file: *Elf, bw: *Writer) Writer.Error!void { | |
| 364 | 364 | const comp = elf_file.base.comp; |
| 365 | 365 | const is_dyn_lib = elf_file.isEffectivelyDynLib(); |
| 366 | 366 | const apply_relocs = true; // TODO add user option for this |
| ... | ... | @@ -615,7 +615,7 @@ pub const GotSection = struct { |
| 615 | 615 | return .{ .data = .{ .got = got, .elf_file = elf_file } }; |
| 616 | 616 | } |
| 617 | 617 | |
| 618 | pub fn format2(ctx: FormatCtx, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 618 | pub fn format2(ctx: FormatCtx, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 619 | 619 | _ = unused_fmt_string; |
| 620 | 620 | const got = ctx.got; |
| 621 | 621 | const elf_file = ctx.elf_file; |
| ... | ... | @@ -672,7 +672,7 @@ pub const PltSection = struct { |
| 672 | 672 | }; |
| 673 | 673 | } |
| 674 | 674 | |
| 675 | pub fn write(plt: PltSection, elf_file: *Elf, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 675 | pub fn write(plt: PltSection, elf_file: *Elf, bw: *Writer) Writer.Error!void { | |
| 676 | 676 | const cpu_arch = elf_file.getTarget().cpu.arch; |
| 677 | 677 | switch (cpu_arch) { |
| 678 | 678 | .x86_64 => try x86_64.write(plt, elf_file, bw), |
| ... | ... | @@ -752,7 +752,7 @@ pub const PltSection = struct { |
| 752 | 752 | return .{ .data = .{ .plt = plt, .elf_file = elf_file } }; |
| 753 | 753 | } |
| 754 | 754 | |
| 755 | pub fn format2(ctx: FormatCtx, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 755 | pub fn format2(ctx: FormatCtx, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 756 | 756 | _ = unused_fmt_string; |
| 757 | 757 | const plt = ctx.plt; |
| 758 | 758 | const elf_file = ctx.elf_file; |
| ... | ... | @@ -770,7 +770,7 @@ pub const PltSection = struct { |
| 770 | 770 | } |
| 771 | 771 | |
| 772 | 772 | const x86_64 = struct { |
| 773 | fn write(plt: PltSection, elf_file: *Elf, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 773 | fn write(plt: PltSection, elf_file: *Elf, bw: *Writer) Writer.Error!void { | |
| 774 | 774 | const shdrs = elf_file.sections.items(.shdr); |
| 775 | 775 | const plt_addr = shdrs[elf_file.section_indexes.plt.?].sh_addr; |
| 776 | 776 | const got_plt_addr = shdrs[elf_file.section_indexes.got_plt.?].sh_addr; |
| ... | ... | @@ -805,7 +805,7 @@ pub const PltSection = struct { |
| 805 | 805 | }; |
| 806 | 806 | |
| 807 | 807 | const aarch64 = struct { |
| 808 | fn write(plt: PltSection, elf_file: *Elf, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 808 | fn write(plt: PltSection, elf_file: *Elf, bw: *Writer) Writer.Error!void { | |
| 809 | 809 | { |
| 810 | 810 | const shdrs = elf_file.sections.items(.shdr); |
| 811 | 811 | const plt_addr: i64 = @intCast(shdrs[elf_file.section_indexes.plt.?].sh_addr); |
| ... | ... | @@ -871,7 +871,7 @@ pub const GotPltSection = struct { |
| 871 | 871 | return preamble_size + elf_file.plt.symbols.items.len * 8; |
| 872 | 872 | } |
| 873 | 873 | |
| 874 | pub fn write(got_plt: GotPltSection, elf_file: *Elf, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 874 | pub fn write(got_plt: GotPltSection, elf_file: *Elf, bw: *Writer) Writer.Error!void { | |
| 875 | 875 | _ = got_plt; |
| 876 | 876 | { |
| 877 | 877 | // [0]: _DYNAMIC |
| ... | ... | @@ -922,7 +922,7 @@ pub const PltGotSection = struct { |
| 922 | 922 | }; |
| 923 | 923 | } |
| 924 | 924 | |
| 925 | pub fn write(plt_got: PltGotSection, elf_file: *Elf, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 925 | pub fn write(plt_got: PltGotSection, elf_file: *Elf, bw: *Writer) Writer.Error!void { | |
| 926 | 926 | const cpu_arch = elf_file.getTarget().cpu.arch; |
| 927 | 927 | switch (cpu_arch) { |
| 928 | 928 | .x86_64 => try x86_64.write(plt_got, elf_file, bw), |
| ... | ... | @@ -958,7 +958,7 @@ pub const PltGotSection = struct { |
| 958 | 958 | } |
| 959 | 959 | |
| 960 | 960 | const x86_64 = struct { |
| 961 | pub fn write(plt_got: PltGotSection, elf_file: *Elf, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 961 | pub fn write(plt_got: PltGotSection, elf_file: *Elf, bw: *Writer) Writer.Error!void { | |
| 962 | 962 | for (plt_got.symbols.items) |ref| { |
| 963 | 963 | const sym = elf_file.symbol(ref).?; |
| 964 | 964 | const target_addr = sym.gotAddress(elf_file); |
| ... | ... | @@ -976,7 +976,7 @@ pub const PltGotSection = struct { |
| 976 | 976 | }; |
| 977 | 977 | |
| 978 | 978 | const aarch64 = struct { |
| 979 | fn write(plt_got: PltGotSection, elf_file: *Elf, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 979 | fn write(plt_got: PltGotSection, elf_file: *Elf, bw: *Writer) Writer.Error!void { | |
| 980 | 980 | for (plt_got.symbols.items) |ref| { |
| 981 | 981 | const sym = elf_file.symbol(ref).?; |
| 982 | 982 | const target_addr = sym.gotAddress(elf_file); |
| ... | ... | @@ -1155,7 +1155,7 @@ pub const DynsymSection = struct { |
| 1155 | 1155 | return @as(u32, @intCast(dynsym.entries.items.len + 1)); |
| 1156 | 1156 | } |
| 1157 | 1157 | |
| 1158 | pub fn write(dynsym: DynsymSection, elf_file: *Elf, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 1158 | pub fn write(dynsym: DynsymSection, elf_file: *Elf, bw: *Writer) Writer.Error!void { | |
| 1159 | 1159 | try bw.writeStruct(Elf.null_sym); |
| 1160 | 1160 | for (dynsym.entries.items) |entry| { |
| 1161 | 1161 | const sym = elf_file.symbol(entry.ref).?; |
| ... | ... | @@ -1249,7 +1249,7 @@ pub const GnuHashSection = struct { |
| 1249 | 1249 | return header_size + hash.num_bloom * 8 + hash.num_buckets * 4 + hash.num_exports * 4; |
| 1250 | 1250 | } |
| 1251 | 1251 | |
| 1252 | pub fn write(hash: GnuHashSection, elf_file: *Elf, br: *std.io.BufferedWriter) !void { | |
| 1252 | pub fn write(hash: GnuHashSection, elf_file: *Elf, br: *Writer) !void { | |
| 1253 | 1253 | const exports = getExports(elf_file); |
| 1254 | 1254 | const export_off = elf_file.dynsym.count() - hash.num_exports; |
| 1255 | 1255 | |
| ... | ... | @@ -1458,7 +1458,7 @@ pub const VerneedSection = struct { |
| 1458 | 1458 | return vern.verneed.items.len * @sizeOf(elf.Elf64_Verneed) + vern.vernaux.items.len * @sizeOf(elf.Vernaux); |
| 1459 | 1459 | } |
| 1460 | 1460 | |
| 1461 | pub fn write(vern: VerneedSection, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 1461 | pub fn write(vern: VerneedSection, bw: *Writer) Writer.Error!void { | |
| 1462 | 1462 | try bw.writeAll(mem.sliceAsBytes(vern.verneed.items)); |
| 1463 | 1463 | try bw.writeAll(mem.sliceAsBytes(vern.vernaux.items)); |
| 1464 | 1464 | } |
| ... | ... | @@ -1486,7 +1486,7 @@ pub const GroupSection = struct { |
| 1486 | 1486 | return (members.len + 1) * @sizeOf(u32); |
| 1487 | 1487 | } |
| 1488 | 1488 | |
| 1489 | pub fn write(cgs: GroupSection, elf_file: *Elf, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 1489 | pub fn write(cgs: GroupSection, elf_file: *Elf, bw: *Writer) Writer.Error!void { | |
| 1490 | 1490 | const cg = cgs.comdatGroup(elf_file); |
| 1491 | 1491 | const object = cg.file(elf_file).object; |
| 1492 | 1492 | const members = cg.members(elf_file); |
| ... | ... | @@ -1514,7 +1514,7 @@ pub const GroupSection = struct { |
| 1514 | 1514 | } |
| 1515 | 1515 | }; |
| 1516 | 1516 | |
| 1517 | fn writeInt(value: anytype, elf_file: *Elf, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 1517 | fn writeInt(value: anytype, elf_file: *Elf, bw: *Writer) Writer.Error!void { | |
| 1518 | 1518 | const entry_size = elf_file.archPtrWidthBytes(); |
| 1519 | 1519 | const target = elf_file.getTarget(); |
| 1520 | 1520 | const endian = target.cpu.arch.endian(); |
| ... | ... | @@ -1526,17 +1526,19 @@ fn writeInt(value: anytype, elf_file: *Elf, bw: *std.io.BufferedWriter) std.io.W |
| 1526 | 1526 | } |
| 1527 | 1527 | } |
| 1528 | 1528 | |
| 1529 | const assert = std.debug.assert; | |
| 1530 | 1529 | const builtin = @import("builtin"); |
| 1530 | ||
| 1531 | const std = @import("std"); | |
| 1532 | const assert = std.debug.assert; | |
| 1531 | 1533 | const elf = std.elf; |
| 1532 | 1534 | const math = std.math; |
| 1533 | 1535 | const mem = std.mem; |
| 1534 | 1536 | const log = std.log.scoped(.link); |
| 1535 | 1537 | const relocs_log = std.log.scoped(.link_relocs); |
| 1536 | const relocation = @import("relocation.zig"); | |
| 1537 | const std = @import("std"); | |
| 1538 | ||
| 1539 | 1538 | const Allocator = std.mem.Allocator; |
| 1539 | const Writer = std.io.Writer; | |
| 1540 | ||
| 1541 | const relocation = @import("relocation.zig"); | |
| 1540 | 1542 | const Elf = @import("../Elf.zig"); |
| 1541 | 1543 | const File = @import("file.zig").File; |
| 1542 | 1544 | const SharedObject = @import("SharedObject.zig"); |
src/link/MachO.zig+17-24| ... | ... | @@ -2527,8 +2527,7 @@ fn writeThunkWorker(self: *MachO, thunk: Thunk) void { |
| 2527 | 2527 | |
| 2528 | 2528 | const doWork = struct { |
| 2529 | 2529 | fn doWork(th: Thunk, buffer: []u8, macho_file: *MachO) !void { |
| 2530 | var bw: std.io.BufferedWriter = undefined; | |
| 2531 | bw.initFixed(buffer[try macho_file.cast(usize, th.value)..][0..th.size()]); | |
| 2530 | var bw: Writer = .fixed(buffer[try macho_file.cast(usize, th.value)..][0..th.size()]); | |
| 2532 | 2531 | try th.write(macho_file, &bw); |
| 2533 | 2532 | } |
| 2534 | 2533 | }.doWork; |
| ... | ... | @@ -2556,8 +2555,7 @@ fn writeSyntheticSectionWorker(self: *MachO, sect_id: u8, out: []u8) void { |
| 2556 | 2555 | |
| 2557 | 2556 | const doWork = struct { |
| 2558 | 2557 | fn doWork(macho_file: *MachO, tag: Tag, buffer: []u8) !void { |
| 2559 | var bw: std.io.BufferedWriter = undefined; | |
| 2560 | bw.initFixed(buffer); | |
| 2558 | var bw: Writer = .fixed(buffer); | |
| 2561 | 2559 | switch (tag) { |
| 2562 | 2560 | .eh_frame => eh_frame.write(macho_file, buffer), |
| 2563 | 2561 | .unwind_info => try macho_file.unwind_info.write(macho_file, &bw), |
| ... | ... | @@ -2606,8 +2604,7 @@ fn updateLazyBindSizeWorker(self: *MachO) void { |
| 2606 | 2604 | try macho_file.lazy_bind_section.updateSize(macho_file); |
| 2607 | 2605 | const sect_id = macho_file.stubs_helper_sect_index.?; |
| 2608 | 2606 | const out = &macho_file.sections.items(.out)[sect_id]; |
| 2609 | var bw: std.io.BufferedWriter = undefined; | |
| 2610 | bw.initFixed(out.items); | |
| 2607 | var bw: Writer = .fixed(out.items); | |
| 2611 | 2608 | try macho_file.stubs_helper.write(macho_file, &bw); |
| 2612 | 2609 | } |
| 2613 | 2610 | }.doWork; |
| ... | ... | @@ -2667,8 +2664,7 @@ fn writeDyldInfo(self: *MachO) !void { |
| 2667 | 2664 | needed_size += cmd.lazy_bind_size; |
| 2668 | 2665 | needed_size += cmd.export_size; |
| 2669 | 2666 | |
| 2670 | var bw: std.io.BufferedWriter = undefined; | |
| 2671 | bw.initFixed(try gpa.alloc(u8, needed_size)); | |
| 2667 | var bw: Writer = .fixed(try gpa.alloc(u8, needed_size)); | |
| 2672 | 2668 | defer gpa.free(bw.buffer); |
| 2673 | 2669 | @memset(bw.buffer, 0); |
| 2674 | 2670 | |
| ... | ... | @@ -2690,8 +2686,7 @@ pub fn writeDataInCode(self: *MachO) !void { |
| 2690 | 2686 | const gpa = self.base.comp.gpa; |
| 2691 | 2687 | const cmd = self.data_in_code_cmd; |
| 2692 | 2688 | |
| 2693 | var bw: std.io.BufferedWriter = undefined; | |
| 2694 | bw.initFixed(try gpa.alloc(u8, self.data_in_code.size())); | |
| 2689 | var bw: Writer = .fixed(try gpa.alloc(u8, self.data_in_code.size())); | |
| 2695 | 2690 | defer gpa.free(bw.buffer); |
| 2696 | 2691 | |
| 2697 | 2692 | try self.data_in_code.write(self, &bw); |
| ... | ... | @@ -2706,8 +2701,7 @@ fn writeIndsymtab(self: *MachO) !void { |
| 2706 | 2701 | const gpa = self.base.comp.gpa; |
| 2707 | 2702 | const cmd = self.dysymtab_cmd; |
| 2708 | 2703 | |
| 2709 | var bw: std.io.BufferedWriter = undefined; | |
| 2710 | bw.initFixed(try gpa.alloc(u8, @sizeOf(u32) * cmd.nindirectsyms)); | |
| 2704 | var bw: Writer = .fixed(try gpa.alloc(u8, @sizeOf(u32) * cmd.nindirectsyms)); | |
| 2711 | 2705 | defer gpa.free(bw.buffer); |
| 2712 | 2706 | |
| 2713 | 2707 | try self.indsymtab.write(self, &bw); |
| ... | ... | @@ -2822,12 +2816,11 @@ fn calcSymtabSize(self: *MachO) !void { |
| 2822 | 2816 | } |
| 2823 | 2817 | } |
| 2824 | 2818 | |
| 2825 | fn writeLoadCommands(self: *MachO) std.io.Writer.Error!struct { usize, usize, u64 } { | |
| 2819 | fn writeLoadCommands(self: *MachO) Writer.Error!struct { usize, usize, u64 } { | |
| 2826 | 2820 | const comp = self.base.comp; |
| 2827 | 2821 | const gpa = comp.gpa; |
| 2828 | 2822 | |
| 2829 | var bw: std.io.BufferedWriter = undefined; | |
| 2830 | bw.initFixed(try gpa.alloc(u8, try load_commands.calcLoadCommandsSize(self, false))); | |
| 2823 | var bw: Writer = .fixed(try gpa.alloc(u8, try load_commands.calcLoadCommandsSize(self, false))); | |
| 2831 | 2824 | defer gpa.free(bw.buffer); |
| 2832 | 2825 | |
| 2833 | 2826 | var ncmds: usize = 0; |
| ... | ... | @@ -3021,8 +3014,7 @@ pub fn writeCodeSignature(self: *MachO, code_sig: *CodeSignature) !void { |
| 3021 | 3014 | const seg = self.getTextSegment(); |
| 3022 | 3015 | const offset = self.codesig_cmd.dataoff; |
| 3023 | 3016 | |
| 3024 | var bw: std.io.BufferedWriter = undefined; | |
| 3025 | bw.initFixed(try gpa.alloc(u8, code_sig.size())); | |
| 3017 | var bw: Writer = .fixed(try gpa.alloc(u8, code_sig.size())); | |
| 3026 | 3018 | defer gpa.free(bw.buffer); |
| 3027 | 3019 | try code_sig.writeAdhocSignature(self, .{ |
| 3028 | 3020 | .file = self.base.file.?, |
| ... | ... | @@ -3910,7 +3902,7 @@ pub fn dumpState(self: *MachO) std.fmt.Formatter(fmtDumpState) { |
| 3910 | 3902 | return .{ .data = self }; |
| 3911 | 3903 | } |
| 3912 | 3904 | |
| 3913 | fn fmtDumpState(self: *MachO, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 3905 | fn fmtDumpState(self: *MachO, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 3914 | 3906 | _ = unused_fmt_string; |
| 3915 | 3907 | if (self.getZigObject()) |zo| { |
| 3916 | 3908 | try bw.print("zig_object({d}) : {s}\n", .{ zo.index, zo.basename }); |
| ... | ... | @@ -3969,7 +3961,7 @@ fn fmtSections(self: *MachO) std.fmt.Formatter(formatSections) { |
| 3969 | 3961 | return .{ .data = self }; |
| 3970 | 3962 | } |
| 3971 | 3963 | |
| 3972 | fn formatSections(self: *MachO, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 3964 | fn formatSections(self: *MachO, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 3973 | 3965 | _ = unused_fmt_string; |
| 3974 | 3966 | const slice = self.sections.slice(); |
| 3975 | 3967 | for (slice.items(.header), slice.items(.segment_id), 0..) |header, seg_id, i| { |
| ... | ... | @@ -3987,7 +3979,7 @@ fn fmtSegments(self: *MachO) std.fmt.Formatter(formatSegments) { |
| 3987 | 3979 | return .{ .data = self }; |
| 3988 | 3980 | } |
| 3989 | 3981 | |
| 3990 | fn formatSegments(self: *MachO, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 3982 | fn formatSegments(self: *MachO, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 3991 | 3983 | _ = unused_fmt_string; |
| 3992 | 3984 | for (self.segments.items, 0..) |seg, i| { |
| 3993 | 3985 | try bw.print("seg({d}) : {s} : @{x}-{x} ({x}-{x})\n", .{ |
| ... | ... | @@ -4001,7 +3993,7 @@ pub fn fmtSectType(tt: u8) std.fmt.Formatter(formatSectType) { |
| 4001 | 3993 | return .{ .data = tt }; |
| 4002 | 3994 | } |
| 4003 | 3995 | |
| 4004 | fn formatSectType(tt: u8, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 3996 | fn formatSectType(tt: u8, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 4005 | 3997 | _ = unused_fmt_string; |
| 4006 | 3998 | const name = switch (tt) { |
| 4007 | 3999 | macho.S_REGULAR => "REGULAR", |
| ... | ... | @@ -4270,7 +4262,7 @@ pub const Platform = struct { |
| 4270 | 4262 | cpu_arch: std.Target.Cpu.Arch, |
| 4271 | 4263 | }; |
| 4272 | 4264 | |
| 4273 | pub fn formatTarget(ctx: FmtCtx, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 4265 | pub fn formatTarget(ctx: FmtCtx, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 4274 | 4266 | _ = unused_fmt_string; |
| 4275 | 4267 | try bw.print("{s}-{s}", .{ @tagName(ctx.cpu_arch), @tagName(ctx.platform.os_tag) }); |
| 4276 | 4268 | if (ctx.platform.abi != .none) { |
| ... | ... | @@ -4483,8 +4475,8 @@ pub const Ref = struct { |
| 4483 | 4475 | }; |
| 4484 | 4476 | } |
| 4485 | 4477 | |
| 4486 | pub fn format(ref: Ref, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 4487 | _ = unused_fmt_string; | |
| 4478 | pub fn format(ref: Ref, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 4479 | comptime assert(unused_fmt_string.len == 0); | |
| 4488 | 4480 | try bw.print("%{d} in file({d})", .{ ref.index, ref.file }); |
| 4489 | 4481 | } |
| 4490 | 4482 | }; |
| ... | ... | @@ -5387,6 +5379,7 @@ const macho = std.macho; |
| 5387 | 5379 | const math = std.math; |
| 5388 | 5380 | const mem = std.mem; |
| 5389 | 5381 | const meta = std.meta; |
| 5382 | const Writer = std.io.Writer; | |
| 5390 | 5383 | |
| 5391 | 5384 | const aarch64 = @import("../arch/aarch64/bits.zig"); |
| 5392 | 5385 | const bind = @import("MachO/dyld_info/bind.zig"); |
src/link/MachO/Archive.zig+7-6| ... | ... | @@ -78,11 +78,11 @@ pub fn unpack(self: *Archive, macho_file: *MachO, path: Path, handle_index: File |
| 78 | 78 | } |
| 79 | 79 | |
| 80 | 80 | pub fn writeHeader( |
| 81 | bw: *std.io.BufferedWriter, | |
| 81 | bw: *Writer, | |
| 82 | 82 | object_name: []const u8, |
| 83 | 83 | object_size: usize, |
| 84 | 84 | format: Format, |
| 85 | ) std.io.Writer.Error!void { | |
| 85 | ) Writer.Error!void { | |
| 86 | 86 | var hdr: ar_hdr = undefined; |
| 87 | 87 | @memset(mem.asBytes(&hdr), ' '); |
| 88 | 88 | inline for (@typeInfo(ar_hdr).@"struct".fields) |field| @field(hdr, field.name)[0] = '0'; |
| ... | ... | @@ -177,7 +177,7 @@ pub const ArSymtab = struct { |
| 177 | 177 | return ptr_width + ar.entries.items.len * 2 * ptr_width + ptr_width + mem.alignForward(usize, ar.strtab.buffer.items.len, ptr_width); |
| 178 | 178 | } |
| 179 | 179 | |
| 180 | pub fn write(ar: ArSymtab, bw: *std.io.BufferedWriter, format: Format, macho_file: *MachO) std.io.Writer.Error!void { | |
| 180 | pub fn write(ar: ArSymtab, bw: *Writer, format: Format, macho_file: *MachO) Writer.Error!void { | |
| 181 | 181 | const ptr_width = ptrWidth(format); |
| 182 | 182 | // Header |
| 183 | 183 | try writeHeader(bw, SYMDEF, ar.size(format), format); |
| ... | ... | @@ -212,7 +212,7 @@ pub const ArSymtab = struct { |
| 212 | 212 | return .{ .data = .{ .ar = ar, .macho_file = macho_file } }; |
| 213 | 213 | } |
| 214 | 214 | |
| 215 | fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 215 | fn format2(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 216 | 216 | _ = unused_fmt_string; |
| 217 | 217 | const ar = ctx.ar; |
| 218 | 218 | const macho_file = ctx.macho_file; |
| ... | ... | @@ -249,7 +249,7 @@ pub fn ptrWidth(format: Format) usize { |
| 249 | 249 | }; |
| 250 | 250 | } |
| 251 | 251 | |
| 252 | pub fn writeInt(bw: *std.io.BufferedWriter, format: Format, value: u64) std.io.Writer.Error!void { | |
| 252 | pub fn writeInt(bw: *Writer, format: Format, value: u64) Writer.Error!void { | |
| 253 | 253 | switch (format) { |
| 254 | 254 | .p32 => try bw.writeInt(u32, std.math.cast(u32, value) orelse return error.Overflow, .little), |
| 255 | 255 | .p64 => try bw.writeInt(u64, value, .little), |
| ... | ... | @@ -271,8 +271,9 @@ const log = std.log.scoped(.link); |
| 271 | 271 | const macho = std.macho; |
| 272 | 272 | const mem = std.mem; |
| 273 | 273 | const std = @import("std"); |
| 274 | const Allocator = mem.Allocator; | |
| 274 | const Allocator = std.mem.Allocator; | |
| 275 | 275 | const Path = std.Build.Cache.Path; |
| 276 | const Writer = std.io.Writer; | |
| 276 | 277 | |
| 277 | 278 | const Archive = @This(); |
| 278 | 279 | const File = @import("file.zig").File; |
src/link/MachO/Atom.zig+12-13| ... | ... | @@ -580,8 +580,7 @@ pub fn resolveRelocs(self: Atom, macho_file: *MachO, buffer: []u8) !void { |
| 580 | 580 | |
| 581 | 581 | relocs_log.debug("{x}: {s}", .{ self.value, name }); |
| 582 | 582 | |
| 583 | var bw: std.io.BufferedWriter = undefined; | |
| 584 | bw.initFixed(buffer); | |
| 583 | var bw: Writer = .fixed(buffer); | |
| 585 | 584 | |
| 586 | 585 | var has_error = false; |
| 587 | 586 | var i: usize = 0; |
| ... | ... | @@ -638,8 +637,8 @@ fn resolveRelocInner( |
| 638 | 637 | subtractor: ?Relocation, |
| 639 | 638 | code: []u8, |
| 640 | 639 | macho_file: *MachO, |
| 641 | bw: *std.io.BufferedWriter, | |
| 642 | ) std.io.Writer.Error!void { | |
| 640 | bw: *Writer, | |
| 641 | ) Writer.Error!void { | |
| 643 | 642 | const t = &macho_file.base.comp.root_mod.resolved_target.result; |
| 644 | 643 | const cpu_arch = t.cpu.arch; |
| 645 | 644 | const rel_offset = math.cast(usize, rel.offset - self.off) orelse return error.Overflow; |
| ... | ... | @@ -938,8 +937,7 @@ const x86_64 = struct { |
| 938 | 937 | } |
| 939 | 938 | |
| 940 | 939 | fn encode(insts: []const Instruction, code: []u8) !void { |
| 941 | var bw: std.io.BufferedWriter = undefined; | |
| 942 | bw.initFixed(code); | |
| 940 | var bw: Writer = .fixed(code); | |
| 943 | 941 | for (insts) |inst| try inst.encode(&bw, .{}); |
| 944 | 942 | } |
| 945 | 943 | |
| ... | ... | @@ -1140,8 +1138,8 @@ const FormatContext = struct { |
| 1140 | 1138 | macho_file: *MachO, |
| 1141 | 1139 | }; |
| 1142 | 1140 | |
| 1143 | fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 1144 | _ = unused_fmt_string; | |
| 1141 | fn format2(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 1142 | comptime assert(unused_fmt_string.len == 0); | |
| 1145 | 1143 | const atom = ctx.atom; |
| 1146 | 1144 | const macho_file = ctx.macho_file; |
| 1147 | 1145 | const file = atom.getFile(macho_file); |
| ... | ... | @@ -1197,19 +1195,20 @@ pub const Extra = struct { |
| 1197 | 1195 | |
| 1198 | 1196 | pub const Alignment = @import("../../InternPool.zig").Alignment; |
| 1199 | 1197 | |
| 1200 | const aarch64 = @import("../aarch64.zig"); | |
| 1198 | const std = @import("std"); | |
| 1201 | 1199 | const assert = std.debug.assert; |
| 1202 | 1200 | const macho = std.macho; |
| 1203 | 1201 | const math = std.math; |
| 1204 | 1202 | const mem = std.mem; |
| 1205 | 1203 | const log = std.log.scoped(.link); |
| 1206 | 1204 | const relocs_log = std.log.scoped(.link_relocs); |
| 1207 | const std = @import("std"); | |
| 1208 | const trace = @import("../../tracy.zig").trace; | |
| 1209 | ||
| 1205 | const Writer = std.io.Writer; | |
| 1210 | 1206 | const Allocator = mem.Allocator; |
| 1211 | const Atom = @This(); | |
| 1212 | 1207 | const AtomicBool = std.atomic.Value(bool); |
| 1208 | ||
| 1209 | const aarch64 = @import("../aarch64.zig"); | |
| 1210 | const trace = @import("../../tracy.zig").trace; | |
| 1211 | const Atom = @This(); | |
| 1213 | 1212 | const File = @import("file.zig").File; |
| 1214 | 1213 | const MachO = @import("../MachO.zig"); |
| 1215 | 1214 | const Object = @import("Object.zig"); |
src/link/MachO/DebugSymbols.zig+2-2| ... | ... | @@ -269,8 +269,7 @@ fn finalizeDwarfSegment(self: *DebugSymbols, macho_file: *MachO) void { |
| 269 | 269 | |
| 270 | 270 | fn writeLoadCommands(self: *DebugSymbols, macho_file: *MachO) !struct { usize, usize } { |
| 271 | 271 | const gpa = self.allocator; |
| 272 | var bw: std.io.BufferedWriter = undefined; | |
| 273 | bw.initFixed(try gpa.alloc(u8, load_commands.calcLoadCommandsSizeDsym(macho_file, self))); | |
| 272 | var bw: Writer = .fixed(try gpa.alloc(u8, load_commands.calcLoadCommandsSizeDsym(macho_file, self))); | |
| 274 | 273 | defer gpa.free(bw.buffer); |
| 275 | 274 | |
| 276 | 275 | var ncmds: usize = 0; |
| ... | ... | @@ -456,6 +455,7 @@ const math = std.math; |
| 456 | 455 | const mem = std.mem; |
| 457 | 456 | const padToIdeal = MachO.padToIdeal; |
| 458 | 457 | const trace = @import("../../tracy.zig").trace; |
| 458 | const Writer = std.io.Writer; | |
| 459 | 459 | |
| 460 | 460 | const Allocator = mem.Allocator; |
| 461 | 461 | const MachO = @import("../MachO.zig"); |
src/link/MachO/Dylib.zig+6-5| ... | ... | @@ -675,7 +675,7 @@ const FormatContext = struct { |
| 675 | 675 | macho_file: *MachO, |
| 676 | 676 | }; |
| 677 | 677 | |
| 678 | fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 678 | fn formatSymtab(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 679 | 679 | _ = unused_fmt_string; |
| 680 | 680 | const dylib = ctx.dylib; |
| 681 | 681 | const macho_file = ctx.macho_file; |
| ... | ... | @@ -901,19 +901,17 @@ const Export = struct { |
| 901 | 901 | }; |
| 902 | 902 | }; |
| 903 | 903 | |
| 904 | const std = @import("std"); | |
| 904 | 905 | const assert = std.debug.assert; |
| 905 | const fat = @import("fat.zig"); | |
| 906 | 906 | const fs = std.fs; |
| 907 | 907 | const fmt = std.fmt; |
| 908 | 908 | const log = std.log.scoped(.link); |
| 909 | 909 | const macho = std.macho; |
| 910 | 910 | const math = std.math; |
| 911 | 911 | const mem = std.mem; |
| 912 | const tapi = @import("../tapi.zig"); | |
| 913 | const trace = @import("../../tracy.zig").trace; | |
| 914 | const std = @import("std"); | |
| 915 | 912 | const Allocator = mem.Allocator; |
| 916 | 913 | const Path = std.Build.Cache.Path; |
| 914 | const Writer = std.io.Writer; | |
| 917 | 915 | |
| 918 | 916 | const Dylib = @This(); |
| 919 | 917 | const File = @import("file.zig").File; |
| ... | ... | @@ -922,3 +920,6 @@ const LoadCommandIterator = macho.LoadCommandIterator; |
| 922 | 920 | const MachO = @import("../MachO.zig"); |
| 923 | 921 | const Symbol = @import("Symbol.zig"); |
| 924 | 922 | const Tbd = tapi.Tbd; |
| 923 | const fat = @import("fat.zig"); | |
| 924 | const tapi = @import("../tapi.zig"); | |
| 925 | const trace = @import("../../tracy.zig").trace; |
src/link/MachO/InternalObject.zig+4-3| ... | ... | @@ -848,7 +848,7 @@ pub fn fmtAtoms(self: *InternalObject, macho_file: *MachO) std.fmt.Formatter(for |
| 848 | 848 | } }; |
| 849 | 849 | } |
| 850 | 850 | |
| 851 | fn formatAtoms(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 851 | fn formatAtoms(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 852 | 852 | _ = unused_fmt_string; |
| 853 | 853 | try bw.writeAll(" atoms\n"); |
| 854 | 854 | for (ctx.self.getAtoms()) |atom_index| { |
| ... | ... | @@ -864,8 +864,8 @@ pub fn fmtSymtab(self: *InternalObject, macho_file: *MachO) std.fmt.Formatter(fo |
| 864 | 864 | } }; |
| 865 | 865 | } |
| 866 | 866 | |
| 867 | fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 868 | _ = unused_fmt_string; | |
| 867 | fn formatSymtab(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 868 | comptime assert(unused_fmt_string.len == 0); | |
| 869 | 869 | const macho_file = ctx.macho_file; |
| 870 | 870 | const self = ctx.self; |
| 871 | 871 | try bw.writeAll(" symbols\n"); |
| ... | ... | @@ -896,6 +896,7 @@ const macho = std.macho; |
| 896 | 896 | const mem = std.mem; |
| 897 | 897 | const std = @import("std"); |
| 898 | 898 | const trace = @import("../../tracy.zig").trace; |
| 899 | const Writer = std.io.Writer; | |
| 899 | 900 | |
| 900 | 901 | const Allocator = std.mem.Allocator; |
| 901 | 902 | const Atom = @import("Atom.zig"); |
src/link/MachO/Object.zig+16-16| ... | ... | @@ -1065,8 +1065,7 @@ fn initEhFrameRecords(self: *Object, allocator: Allocator, sect_id: u8, file: Fi |
| 1065 | 1065 | } |
| 1066 | 1066 | } |
| 1067 | 1067 | |
| 1068 | var it: eh_frame.Iterator = undefined; | |
| 1069 | it.br.initFixed(self.eh_frame_data.items); | |
| 1068 | var it: eh_frame.Iterator = .{ .br = .fixed(self.eh_frame_data.items) }; | |
| 1070 | 1069 | while (try it.next()) |rec| { |
| 1071 | 1070 | switch (rec.tag) { |
| 1072 | 1071 | .cie => try self.cies.append(allocator, .{ |
| ... | ... | @@ -1695,7 +1694,7 @@ pub fn updateArSize(self: *Object, macho_file: *MachO) !void { |
| 1695 | 1694 | }; |
| 1696 | 1695 | } |
| 1697 | 1696 | |
| 1698 | pub fn writeAr(self: Object, bw: *std.io.BufferedWriter, ar_format: Archive.Format, macho_file: *MachO) !void { | |
| 1697 | pub fn writeAr(self: Object, bw: *Writer, ar_format: Archive.Format, macho_file: *MachO) !void { | |
| 1699 | 1698 | // Header |
| 1700 | 1699 | const size = try macho_file.cast(usize, self.output_ar_state.size); |
| 1701 | 1700 | const basename = std.fs.path.basename(self.path.sub_path); |
| ... | ... | @@ -2513,7 +2512,7 @@ pub fn readSectionData(self: Object, allocator: Allocator, file: File.Handle, n_ |
| 2513 | 2512 | return data; |
| 2514 | 2513 | } |
| 2515 | 2514 | |
| 2516 | pub fn format(self: *Object, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 2515 | pub fn format(self: *Object, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 2517 | 2516 | _ = self; |
| 2518 | 2517 | _ = bw; |
| 2519 | 2518 | _ = unused_fmt_string; |
| ... | ... | @@ -2532,7 +2531,7 @@ pub fn fmtAtoms(self: *Object, macho_file: *MachO) std.fmt.Formatter(formatAtoms |
| 2532 | 2531 | } }; |
| 2533 | 2532 | } |
| 2534 | 2533 | |
| 2535 | fn formatAtoms(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 2534 | fn formatAtoms(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 2536 | 2535 | _ = unused_fmt_string; |
| 2537 | 2536 | const object = ctx.object; |
| 2538 | 2537 | const macho_file = ctx.macho_file; |
| ... | ... | @@ -2550,7 +2549,7 @@ pub fn fmtCies(self: *Object, macho_file: *MachO) std.fmt.Formatter(formatCies) |
| 2550 | 2549 | } }; |
| 2551 | 2550 | } |
| 2552 | 2551 | |
| 2553 | fn formatCies(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 2552 | fn formatCies(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 2554 | 2553 | _ = unused_fmt_string; |
| 2555 | 2554 | const object = ctx.object; |
| 2556 | 2555 | try bw.writeAll(" cies\n"); |
| ... | ... | @@ -2566,7 +2565,7 @@ pub fn fmtFdes(self: *Object, macho_file: *MachO) std.fmt.Formatter(formatFdes) |
| 2566 | 2565 | } }; |
| 2567 | 2566 | } |
| 2568 | 2567 | |
| 2569 | fn formatFdes(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 2568 | fn formatFdes(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 2570 | 2569 | _ = unused_fmt_string; |
| 2571 | 2570 | const object = ctx.object; |
| 2572 | 2571 | try bw.writeAll(" fdes\n"); |
| ... | ... | @@ -2582,7 +2581,7 @@ pub fn fmtUnwindRecords(self: *Object, macho_file: *MachO) std.fmt.Formatter(for |
| 2582 | 2581 | } }; |
| 2583 | 2582 | } |
| 2584 | 2583 | |
| 2585 | fn formatUnwindRecords(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 2584 | fn formatUnwindRecords(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 2586 | 2585 | _ = unused_fmt_string; |
| 2587 | 2586 | const object = ctx.object; |
| 2588 | 2587 | const macho_file = ctx.macho_file; |
| ... | ... | @@ -2599,7 +2598,7 @@ pub fn fmtSymtab(self: *Object, macho_file: *MachO) std.fmt.Formatter(formatSymt |
| 2599 | 2598 | } }; |
| 2600 | 2599 | } |
| 2601 | 2600 | |
| 2602 | fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 2601 | fn formatSymtab(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 2603 | 2602 | _ = unused_fmt_string; |
| 2604 | 2603 | const object = ctx.object; |
| 2605 | 2604 | const macho_file = ctx.macho_file; |
| ... | ... | @@ -2629,7 +2628,7 @@ pub fn fmtPath(self: Object) std.fmt.Formatter(formatPath) { |
| 2629 | 2628 | return .{ .data = self }; |
| 2630 | 2629 | } |
| 2631 | 2630 | |
| 2632 | fn formatPath(object: Object, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 2631 | fn formatPath(object: Object, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 2633 | 2632 | _ = unused_fmt_string; |
| 2634 | 2633 | if (object.in_archive) |ar| { |
| 2635 | 2634 | try bw.print("{f}({s})", .{ |
| ... | ... | @@ -2690,7 +2689,7 @@ const StabFile = struct { |
| 2690 | 2689 | return object.symbols.items[index]; |
| 2691 | 2690 | } |
| 2692 | 2691 | |
| 2693 | pub fn format(stab: Stab, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 2692 | pub fn format(stab: Stab, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 2694 | 2693 | _ = stab; |
| 2695 | 2694 | _ = bw; |
| 2696 | 2695 | _ = unused_fmt_string; |
| ... | ... | @@ -2703,7 +2702,7 @@ const StabFile = struct { |
| 2703 | 2702 | return .{ .data = .{ stab, object } }; |
| 2704 | 2703 | } |
| 2705 | 2704 | |
| 2706 | fn format2(ctx: StabFormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 2705 | fn format2(ctx: StabFormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 2707 | 2706 | _ = unused_fmt_string; |
| 2708 | 2707 | const stab, const object = ctx; |
| 2709 | 2708 | const sym = stab.getSymbol(object).?; |
| ... | ... | @@ -3104,17 +3103,18 @@ const aarch64 = struct { |
| 3104 | 3103 | } |
| 3105 | 3104 | }; |
| 3106 | 3105 | |
| 3106 | const std = @import("std"); | |
| 3107 | 3107 | const assert = std.debug.assert; |
| 3108 | const eh_frame = @import("eh_frame.zig"); | |
| 3109 | 3108 | const log = std.log.scoped(.link); |
| 3110 | 3109 | const macho = std.macho; |
| 3111 | 3110 | const math = std.math; |
| 3112 | 3111 | const mem = std.mem; |
| 3113 | const trace = @import("../../tracy.zig").trace; | |
| 3114 | const std = @import("std"); | |
| 3115 | 3112 | const Path = std.Build.Cache.Path; |
| 3113 | const Allocator = std.mem.Allocator; | |
| 3114 | const Writer = std.io.Writer; | |
| 3116 | 3115 | |
| 3117 | const Allocator = mem.Allocator; | |
| 3116 | const eh_frame = @import("eh_frame.zig"); | |
| 3117 | const trace = @import("../../tracy.zig").trace; | |
| 3118 | 3118 | const Archive = @import("Archive.zig"); |
| 3119 | 3119 | const Atom = @import("Atom.zig"); |
| 3120 | 3120 | const Cie = eh_frame.Cie; |
src/link/MachO/Relocation.zig+3-2| ... | ... | @@ -76,7 +76,7 @@ pub fn fmtPretty(rel: Relocation, cpu_arch: std.Target.Cpu.Arch) std.fmt.Formatt |
| 76 | 76 | return .{ .data = .{ rel, cpu_arch } }; |
| 77 | 77 | } |
| 78 | 78 | |
| 79 | fn formatPretty(ctx: FormatCtx, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 79 | fn formatPretty(ctx: FormatCtx, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 80 | 80 | _ = unused_fmt_string; |
| 81 | 81 | const rel, const cpu_arch = ctx; |
| 82 | 82 | try bw.writeAll(switch (rel.type) { |
| ... | ... | @@ -157,10 +157,11 @@ pub const Type = enum { |
| 157 | 157 | |
| 158 | 158 | const Tag = enum { local, @"extern" }; |
| 159 | 159 | |
| 160 | const std = @import("std"); | |
| 160 | 161 | const assert = std.debug.assert; |
| 161 | 162 | const macho = std.macho; |
| 162 | 163 | const math = std.math; |
| 163 | const std = @import("std"); | |
| 164 | const Writer = std.io.Writer; | |
| 164 | 165 | |
| 165 | 166 | const Atom = @import("Atom.zig"); |
| 166 | 167 | const MachO = @import("../MachO.zig"); |
src/link/MachO/Symbol.zig+4-3| ... | ... | @@ -286,7 +286,7 @@ pub fn setOutputSym(symbol: Symbol, macho_file: *MachO, out: *macho.nlist_64) vo |
| 286 | 286 | } |
| 287 | 287 | } |
| 288 | 288 | |
| 289 | pub fn format(symbol: Symbol, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 289 | pub fn format(symbol: Symbol, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 290 | 290 | _ = symbol; |
| 291 | 291 | _ = bw; |
| 292 | 292 | _ = unused_fmt_string; |
| ... | ... | @@ -305,8 +305,8 @@ pub fn fmt(symbol: Symbol, macho_file: *MachO) std.fmt.Formatter(format2) { |
| 305 | 305 | } }; |
| 306 | 306 | } |
| 307 | 307 | |
| 308 | fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 309 | _ = unused_fmt_string; | |
| 308 | fn format2(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 309 | comptime assert(unused_fmt_string.len == 0); | |
| 310 | 310 | const symbol = ctx.symbol; |
| 311 | 311 | try bw.print("%{d} : {s} : @{x}", .{ |
| 312 | 312 | symbol.nlist_idx, |
| ... | ... | @@ -425,6 +425,7 @@ pub const Index = u32; |
| 425 | 425 | const assert = std.debug.assert; |
| 426 | 426 | const macho = std.macho; |
| 427 | 427 | const std = @import("std"); |
| 428 | const Writer = std.io.Writer; | |
| 428 | 429 | |
| 429 | 430 | const Atom = @import("Atom.zig"); |
| 430 | 431 | const File = @import("file.zig").File; |
src/link/MachO/Thunk.zig+4-3| ... | ... | @@ -20,7 +20,7 @@ pub fn getTargetAddress(thunk: Thunk, ref: MachO.Ref, macho_file: *MachO) u64 { |
| 20 | 20 | return thunk.getAddress(macho_file) + thunk.symbols.getIndex(ref).? * trampoline_size; |
| 21 | 21 | } |
| 22 | 22 | |
| 23 | pub fn write(thunk: Thunk, macho_file: *MachO, bw: *std.io.BufferedWriter) !void { | |
| 23 | pub fn write(thunk: Thunk, macho_file: *MachO, bw: *Writer) !void { | |
| 24 | 24 | for (thunk.symbols.keys(), 0..) |ref, i| { |
| 25 | 25 | const sym = ref.getSymbol(macho_file).?; |
| 26 | 26 | const saddr = thunk.getAddress(macho_file) + i * trampoline_size; |
| ... | ... | @@ -61,7 +61,7 @@ pub fn writeSymtab(thunk: Thunk, macho_file: *MachO, ctx: anytype) void { |
| 61 | 61 | } |
| 62 | 62 | } |
| 63 | 63 | |
| 64 | pub fn format(thunk: Thunk, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 64 | pub fn format(thunk: Thunk, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 65 | 65 | _ = thunk; |
| 66 | 66 | _ = bw; |
| 67 | 67 | _ = unused_fmt_string; |
| ... | ... | @@ -80,7 +80,7 @@ const FormatContext = struct { |
| 80 | 80 | macho_file: *MachO, |
| 81 | 81 | }; |
| 82 | 82 | |
| 83 | fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 83 | fn format2(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 84 | 84 | _ = unused_fmt_string; |
| 85 | 85 | const thunk = ctx.thunk; |
| 86 | 86 | const macho_file = ctx.macho_file; |
| ... | ... | @@ -103,6 +103,7 @@ const math = std.math; |
| 103 | 103 | const mem = std.mem; |
| 104 | 104 | const std = @import("std"); |
| 105 | 105 | const trace = @import("../../tracy.zig").trace; |
| 106 | const Writer = std.io.Writer; | |
| 106 | 107 | |
| 107 | 108 | const Allocator = mem.Allocator; |
| 108 | 109 | const Atom = @import("Atom.zig"); |
src/link/MachO/UnwindInfo.zig+7-6| ... | ... | @@ -289,7 +289,7 @@ pub fn calcSize(info: UnwindInfo) usize { |
| 289 | 289 | return total_size; |
| 290 | 290 | } |
| 291 | 291 | |
| 292 | pub fn write(info: UnwindInfo, macho_file: *MachO, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 292 | pub fn write(info: UnwindInfo, macho_file: *MachO, bw: *Writer) Writer.Error!void { | |
| 293 | 293 | const seg = macho_file.getTextSegment(); |
| 294 | 294 | const header = macho_file.sections.items(.header)[macho_file.unwind_info_sect_index.?]; |
| 295 | 295 | |
| ... | ... | @@ -449,7 +449,7 @@ pub const Encoding = extern struct { |
| 449 | 449 | return enc.enc == other.enc; |
| 450 | 450 | } |
| 451 | 451 | |
| 452 | pub fn format(enc: Encoding, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 452 | pub fn format(enc: Encoding, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 453 | 453 | _ = unused_fmt_string; |
| 454 | 454 | try bw.print("0x{x:0>8}", .{enc.enc}); |
| 455 | 455 | } |
| ... | ... | @@ -505,7 +505,7 @@ pub const Record = struct { |
| 505 | 505 | return lsda.getAddress(macho_file) + rec.lsda_offset; |
| 506 | 506 | } |
| 507 | 507 | |
| 508 | pub fn format(rec: Record, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 508 | pub fn format(rec: Record, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 509 | 509 | _ = rec; |
| 510 | 510 | _ = bw; |
| 511 | 511 | _ = unused_fmt_string; |
| ... | ... | @@ -524,7 +524,7 @@ pub const Record = struct { |
| 524 | 524 | macho_file: *MachO, |
| 525 | 525 | }; |
| 526 | 526 | |
| 527 | fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 527 | fn format2(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 528 | 528 | _ = unused_fmt_string; |
| 529 | 529 | const rec = ctx.rec; |
| 530 | 530 | const macho_file = ctx.macho_file; |
| ... | ... | @@ -589,7 +589,7 @@ const Page = struct { |
| 589 | 589 | return null; |
| 590 | 590 | } |
| 591 | 591 | |
| 592 | fn format(page: *const Page, bw: *std.io.BufferedWriter, comptime unused_format_string: []const u8) std.io.Writer.Error!void { | |
| 592 | fn format(page: *const Page, bw: *Writer, comptime unused_format_string: []const u8) Writer.Error!void { | |
| 593 | 593 | _ = page; |
| 594 | 594 | _ = bw; |
| 595 | 595 | _ = unused_format_string; |
| ... | ... | @@ -601,7 +601,7 @@ const Page = struct { |
| 601 | 601 | info: UnwindInfo, |
| 602 | 602 | }; |
| 603 | 603 | |
| 604 | fn format2(ctx: FormatPageContext, bw: *std.io.BufferedWriter, comptime unused_format_string: []const u8) std.io.Writer.Error!void { | |
| 604 | fn format2(ctx: FormatPageContext, bw: *Writer, comptime unused_format_string: []const u8) Writer.Error!void { | |
| 605 | 605 | _ = unused_format_string; |
| 606 | 606 | try bw.writeAll("Page:\n"); |
| 607 | 607 | try bw.print(" kind: {s}\n", .{@tagName(ctx.page.kind)}); |
| ... | ... | @@ -684,6 +684,7 @@ const macho = std.macho; |
| 684 | 684 | const math = std.math; |
| 685 | 685 | const mem = std.mem; |
| 686 | 686 | const trace = @import("../../tracy.zig").trace; |
| 687 | const Writer = std.io.Writer; | |
| 687 | 688 | |
| 688 | 689 | const Allocator = mem.Allocator; |
| 689 | 690 | const Atom = @import("Atom.zig"); |
src/link/MachO/ZigObject.zig+4-3| ... | ... | @@ -317,7 +317,7 @@ pub fn updateArSize(self: *ZigObject) void { |
| 317 | 317 | self.output_ar_state.size = self.data.items.len; |
| 318 | 318 | } |
| 319 | 319 | |
| 320 | pub fn writeAr(self: ZigObject, bw: *std.io.BufferedWriter, ar_format: Archive.Format) std.io.Writer.Error!void { | |
| 320 | pub fn writeAr(self: ZigObject, bw: *Writer, ar_format: Archive.Format) Writer.Error!void { | |
| 321 | 321 | // Header |
| 322 | 322 | const size = std.math.cast(usize, self.output_ar_state.size) orelse return error.Overflow; |
| 323 | 323 | try Archive.writeHeader(bw, self.basename, size, ar_format); |
| ... | ... | @@ -1688,7 +1688,7 @@ const FormatContext = struct { |
| 1688 | 1688 | macho_file: *MachO, |
| 1689 | 1689 | }; |
| 1690 | 1690 | |
| 1691 | fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 1691 | fn formatSymtab(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 1692 | 1692 | _ = unused_fmt_string; |
| 1693 | 1693 | try bw.writeAll(" symbols\n"); |
| 1694 | 1694 | const self = ctx.self; |
| ... | ... | @@ -1711,7 +1711,7 @@ pub fn fmtAtoms(self: *ZigObject, macho_file: *MachO) std.fmt.Formatter(formatAt |
| 1711 | 1711 | } }; |
| 1712 | 1712 | } |
| 1713 | 1713 | |
| 1714 | fn formatAtoms(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 1714 | fn formatAtoms(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 1715 | 1715 | _ = unused_fmt_string; |
| 1716 | 1716 | const self = ctx.self; |
| 1717 | 1717 | const macho_file = ctx.macho_file; |
| ... | ... | @@ -1783,6 +1783,7 @@ const mem = std.mem; |
| 1783 | 1783 | const target_util = @import("../../target.zig"); |
| 1784 | 1784 | const trace = @import("../../tracy.zig").trace; |
| 1785 | 1785 | const std = @import("std"); |
| 1786 | const Writer = std.io.Writer; | |
| 1786 | 1787 | |
| 1787 | 1788 | const Allocator = std.mem.Allocator; |
| 1788 | 1789 | const Archive = @import("Archive.zig"); |
src/link/MachO/dead_strip.zig+2-1| ... | ... | @@ -196,7 +196,7 @@ const Level = struct { |
| 196 | 196 | self.value += 1; |
| 197 | 197 | } |
| 198 | 198 | |
| 199 | pub fn format(self: *const @This(), bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 199 | pub fn format(self: *const @This(), bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 200 | 200 | _ = unused_fmt_string; |
| 201 | 201 | try bw.splatByteAll(' ', self.value); |
| 202 | 202 | } |
| ... | ... | @@ -213,6 +213,7 @@ const mem = std.mem; |
| 213 | 213 | const trace = @import("../../tracy.zig").trace; |
| 214 | 214 | const track_live_log = std.log.scoped(.dead_strip_track_live); |
| 215 | 215 | const std = @import("std"); |
| 216 | const Writer = std.io.Writer; | |
| 216 | 217 | |
| 217 | 218 | const Allocator = mem.Allocator; |
| 218 | 219 | const Atom = @import("Atom.zig"); |
src/link/MachO/dyld_info/Rebase.zig+12-11| ... | ... | @@ -133,7 +133,7 @@ fn finalize(rebase: *Rebase, gpa: Allocator) !void { |
| 133 | 133 | try done(bw); |
| 134 | 134 | } |
| 135 | 135 | |
| 136 | fn finalizeSegment(entries: []const Entry, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 136 | fn finalizeSegment(entries: []const Entry, bw: *Writer) Writer.Error!void { | |
| 137 | 137 | if (entries.len == 0) return; |
| 138 | 138 | |
| 139 | 139 | const segment_id = entries[0].segment_id; |
| ... | ... | @@ -220,24 +220,24 @@ fn finalizeSegment(entries: []const Entry, bw: *std.io.BufferedWriter) std.io.Wr |
| 220 | 220 | } |
| 221 | 221 | } |
| 222 | 222 | |
| 223 | fn setTypePointer(bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 223 | fn setTypePointer(bw: *Writer) Writer.Error!void { | |
| 224 | 224 | log.debug(">>> set type: {d}", .{macho.REBASE_TYPE_POINTER}); |
| 225 | 225 | try bw.writeByte(macho.REBASE_OPCODE_SET_TYPE_IMM | @as(u4, @intCast(macho.REBASE_TYPE_POINTER))); |
| 226 | 226 | } |
| 227 | 227 | |
| 228 | fn setSegmentOffset(segment_id: u4, offset: u64, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 228 | fn setSegmentOffset(segment_id: u4, offset: u64, bw: *Writer) Writer.Error!void { | |
| 229 | 229 | log.debug(">>> set segment: {d} and offset: {x}", .{ segment_id, offset }); |
| 230 | 230 | try bw.writeByte(macho.REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB | @as(u4, @truncate(segment_id))); |
| 231 | 231 | try bw.writeLeb128(offset); |
| 232 | 232 | } |
| 233 | 233 | |
| 234 | fn rebaseAddAddr(addr: u64, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 234 | fn rebaseAddAddr(addr: u64, bw: *Writer) Writer.Error!void { | |
| 235 | 235 | log.debug(">>> rebase with add: {x}", .{addr}); |
| 236 | 236 | try bw.writeByte(macho.REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB); |
| 237 | 237 | try bw.writeLeb128(addr); |
| 238 | 238 | } |
| 239 | 239 | |
| 240 | fn rebaseTimes(count: usize, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 240 | fn rebaseTimes(count: usize, bw: *Writer) Writer.Error!void { | |
| 241 | 241 | log.debug(">>> rebase with count: {d}", .{count}); |
| 242 | 242 | if (count <= 0xf) { |
| 243 | 243 | try bw.writeByte(macho.REBASE_OPCODE_DO_REBASE_IMM_TIMES | @as(u4, @truncate(count))); |
| ... | ... | @@ -247,14 +247,14 @@ fn rebaseTimes(count: usize, bw: *std.io.BufferedWriter) std.io.Writer.Error!voi |
| 247 | 247 | } |
| 248 | 248 | } |
| 249 | 249 | |
| 250 | fn rebaseTimesSkip(count: usize, skip: u64, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 250 | fn rebaseTimesSkip(count: usize, skip: u64, bw: *Writer) Writer.Error!void { | |
| 251 | 251 | log.debug(">>> rebase with count: {d} and skip: {x}", .{ count, skip }); |
| 252 | 252 | try bw.writeByte(macho.REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB); |
| 253 | 253 | try bw.writeLeb128(count); |
| 254 | 254 | try bw.writeLeb128(skip); |
| 255 | 255 | } |
| 256 | 256 | |
| 257 | fn addAddr(addr: u64, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 257 | fn addAddr(addr: u64, bw: *Writer) Writer.Error!void { | |
| 258 | 258 | log.debug(">>> add: {x}", .{addr}); |
| 259 | 259 | if (std.math.divExact(u64, addr, @sizeOf(u64))) |scaled| { |
| 260 | 260 | if (std.math.cast(u4, scaled)) |imm_scaled| return bw.writeByte( |
| ... | ... | @@ -265,12 +265,12 @@ fn addAddr(addr: u64, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { |
| 265 | 265 | try bw.writeLeb128(addr); |
| 266 | 266 | } |
| 267 | 267 | |
| 268 | fn done(bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 268 | fn done(bw: *Writer) Writer.Error!void { | |
| 269 | 269 | log.debug(">>> done", .{}); |
| 270 | 270 | try bw.writeByte(macho.REBASE_OPCODE_DONE); |
| 271 | 271 | } |
| 272 | 272 | |
| 273 | pub fn write(rebase: Rebase, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 273 | pub fn write(rebase: Rebase, bw: *Writer) Writer.Error!void { | |
| 274 | 274 | try bw.writeAll(rebase.buffer.items); |
| 275 | 275 | } |
| 276 | 276 | |
| ... | ... | @@ -654,9 +654,10 @@ const log = std.log.scoped(.link_dyld_info); |
| 654 | 654 | const macho = std.macho; |
| 655 | 655 | const mem = std.mem; |
| 656 | 656 | const testing = std.testing; |
| 657 | const trace = @import("../../../tracy.zig").trace; | |
| 658 | ||
| 659 | 657 | const Allocator = mem.Allocator; |
| 658 | const Writer = std.io.Writer; | |
| 659 | ||
| 660 | const trace = @import("../../../tracy.zig").trace; | |
| 660 | 661 | const File = @import("../file.zig").File; |
| 661 | 662 | const MachO = @import("../../MachO.zig"); |
| 662 | 663 | const Rebase = @This(); |
src/link/MachO/dyld_info/Trie.zig+6-6| ... | ... | @@ -166,8 +166,7 @@ fn finalize(self: *Trie, allocator: Allocator) !void { |
| 166 | 166 | |
| 167 | 167 | assert(self.buffer.len == 0); |
| 168 | 168 | self.buffer = try allocator.alloc(u8, size); |
| 169 | var bw: std.io.BufferedWriter = undefined; | |
| 170 | bw.initFixed(self.buffer); | |
| 169 | var bw: Writer = .fixed(self.buffer); | |
| 171 | 170 | for (ordered_nodes.items) |node_index| { |
| 172 | 171 | try self.writeNode(node_index, &bw); |
| 173 | 172 | } |
| ... | ... | @@ -185,7 +184,7 @@ const FinalizeNodeResult = struct { |
| 185 | 184 | /// Updates offset of this node in the output byte stream. |
| 186 | 185 | fn finalizeNode(self: *Trie, node_index: Node.Index, offset_in_trie: u32) !FinalizeNodeResult { |
| 187 | 186 | var buf: [1024]u8 = undefined; |
| 188 | var bw = std.io.Writer.null.buffered(&buf); | |
| 187 | var bw = Writer.null.buffered(&buf); | |
| 189 | 188 | const slice = self.nodes.slice(); |
| 190 | 189 | |
| 191 | 190 | var node_size: u32 = 0; |
| ... | ... | @@ -229,7 +228,7 @@ pub fn deinit(self: *Trie, allocator: Allocator) void { |
| 229 | 228 | allocator.free(self.buffer); |
| 230 | 229 | } |
| 231 | 230 | |
| 232 | pub fn write(self: Trie, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 231 | pub fn write(self: Trie, bw: *Writer) Writer.Error!void { | |
| 233 | 232 | try bw.writeAll(self.buffer); |
| 234 | 233 | } |
| 235 | 234 | |
| ... | ... | @@ -239,7 +238,7 @@ pub fn write(self: Trie, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { |
| 239 | 238 | /// iterate over `Trie.ordered_nodes` and call this method on each node. |
| 240 | 239 | /// This is one of the requirements of the MachO. |
| 241 | 240 | /// Panics if `finalize` was not called before calling this method. |
| 242 | fn writeNode(self: *Trie, node_index: Node.Index, bw: *std.io.BufferedWriter) !void { | |
| 241 | fn writeNode(self: *Trie, node_index: Node.Index, bw: *Writer) !void { | |
| 243 | 242 | const slice = self.nodes.slice(); |
| 244 | 243 | const edges = slice.items(.edges)[node_index]; |
| 245 | 244 | const is_terminal = slice.items(.is_terminal)[node_index]; |
| ... | ... | @@ -408,9 +407,10 @@ const macho = std.macho; |
| 408 | 407 | const mem = std.mem; |
| 409 | 408 | const std = @import("std"); |
| 410 | 409 | const testing = std.testing; |
| 410 | const Writer = std.io.Writer; | |
| 411 | ||
| 411 | 412 | const trace = @import("../../../tracy.zig").trace; |
| 412 | 413 | const DeprecatedLinearFifo = @import("../../../deprecated.zig").LinearFifo; |
| 413 | ||
| 414 | 414 | const Allocator = mem.Allocator; |
| 415 | 415 | const MachO = @import("../../MachO.zig"); |
| 416 | 416 | const Trie = @This(); |
src/link/MachO/dyld_info/bind.zig+19-18| ... | ... | @@ -139,7 +139,7 @@ pub const Bind = struct { |
| 139 | 139 | try done(bw); |
| 140 | 140 | } |
| 141 | 141 | |
| 142 | fn finalizeSegment(entries: []const Entry, ctx: *MachO, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 142 | fn finalizeSegment(entries: []const Entry, ctx: *MachO, bw: *Writer) Writer.Error!void { | |
| 143 | 143 | if (entries.len == 0) return; |
| 144 | 144 | |
| 145 | 145 | const seg_id = entries[0].segment_id; |
| ... | ... | @@ -251,7 +251,7 @@ pub const Bind = struct { |
| 251 | 251 | } |
| 252 | 252 | } |
| 253 | 253 | |
| 254 | pub fn write(bind: Bind, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 254 | pub fn write(bind: Bind, bw: *Writer) Writer.Error!void { | |
| 255 | 255 | try bw.writeAll(bind.buffer.items); |
| 256 | 256 | } |
| 257 | 257 | }; |
| ... | ... | @@ -380,7 +380,7 @@ pub const WeakBind = struct { |
| 380 | 380 | try done(bw); |
| 381 | 381 | } |
| 382 | 382 | |
| 383 | fn finalizeSegment(entries: []const Entry, ctx: *MachO, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 383 | fn finalizeSegment(entries: []const Entry, ctx: *MachO, bw: *Writer) Writer.Error!void { | |
| 384 | 384 | if (entries.len == 0) return; |
| 385 | 385 | |
| 386 | 386 | const seg_id = entries[0].segment_id; |
| ... | ... | @@ -481,7 +481,7 @@ pub const WeakBind = struct { |
| 481 | 481 | } |
| 482 | 482 | } |
| 483 | 483 | |
| 484 | pub fn write(bind: WeakBind, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 484 | pub fn write(bind: WeakBind, bw: *Writer) Writer.Error!void { | |
| 485 | 485 | try bw.writeAll(bind.buffer.items); |
| 486 | 486 | } |
| 487 | 487 | }; |
| ... | ... | @@ -565,30 +565,30 @@ pub const LazyBind = struct { |
| 565 | 565 | } |
| 566 | 566 | } |
| 567 | 567 | |
| 568 | pub fn write(bind: LazyBind, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 568 | pub fn write(bind: LazyBind, bw: *Writer) Writer.Error!void { | |
| 569 | 569 | try bw.writeAll(bind.buffer.items); |
| 570 | 570 | } |
| 571 | 571 | }; |
| 572 | 572 | |
| 573 | fn setSegmentOffset(segment_id: u4, offset: u64, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 573 | fn setSegmentOffset(segment_id: u4, offset: u64, bw: *Writer) Writer.Error!void { | |
| 574 | 574 | log.debug(">>> set segment: {d} and offset: {x}", .{ segment_id, offset }); |
| 575 | 575 | try bw.writeByte(macho.BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB | segment_id); |
| 576 | 576 | try bw.writeLeb128(offset); |
| 577 | 577 | } |
| 578 | 578 | |
| 579 | fn setSymbol(name: []const u8, flags: u4, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 579 | fn setSymbol(name: []const u8, flags: u4, bw: *Writer) Writer.Error!void { | |
| 580 | 580 | log.debug(">>> set symbol: {s} with flags: {x}", .{ name, flags }); |
| 581 | 581 | try bw.writeByte(macho.BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM | flags); |
| 582 | 582 | try bw.writeAll(name); |
| 583 | 583 | try bw.writeByte(0); |
| 584 | 584 | } |
| 585 | 585 | |
| 586 | fn setTypePointer(bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 586 | fn setTypePointer(bw: *Writer) Writer.Error!void { | |
| 587 | 587 | log.debug(">>> set type: {d}", .{macho.BIND_TYPE_POINTER}); |
| 588 | 588 | try bw.writeByte(macho.BIND_OPCODE_SET_TYPE_IMM | @as(u4, @intCast(macho.BIND_TYPE_POINTER))); |
| 589 | 589 | } |
| 590 | 590 | |
| 591 | fn setDylibOrdinal(ordinal: i16, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 591 | fn setDylibOrdinal(ordinal: i16, bw: *Writer) Writer.Error!void { | |
| 592 | 592 | switch (ordinal) { |
| 593 | 593 | else => unreachable, // Invalid dylib special binding |
| 594 | 594 | macho.BIND_SPECIAL_DYLIB_SELF, |
| ... | ... | @@ -610,18 +610,18 @@ fn setDylibOrdinal(ordinal: i16, bw: *std.io.BufferedWriter) std.io.Writer.Error |
| 610 | 610 | } |
| 611 | 611 | } |
| 612 | 612 | |
| 613 | fn setAddend(addend: i64, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 613 | fn setAddend(addend: i64, bw: *Writer) Writer.Error!void { | |
| 614 | 614 | log.debug(">>> set addend: {x}", .{addend}); |
| 615 | 615 | try bw.writeByte(macho.BIND_OPCODE_SET_ADDEND_SLEB); |
| 616 | 616 | try bw.writeLeb128(addend); |
| 617 | 617 | } |
| 618 | 618 | |
| 619 | fn doBind(bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 619 | fn doBind(bw: *Writer) Writer.Error!void { | |
| 620 | 620 | log.debug(">>> bind", .{}); |
| 621 | 621 | try bw.writeByte(macho.BIND_OPCODE_DO_BIND); |
| 622 | 622 | } |
| 623 | 623 | |
| 624 | fn doBindAddAddr(addr: u64, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 624 | fn doBindAddAddr(addr: u64, bw: *Writer) Writer.Error!void { | |
| 625 | 625 | log.debug(">>> bind with add: {x}", .{addr}); |
| 626 | 626 | if (std.math.divExact(u64, addr, @sizeOf(u64))) |scaled| { |
| 627 | 627 | if (std.math.cast(u4, scaled)) |imm_scaled| return bw.writeByte( |
| ... | ... | @@ -632,34 +632,35 @@ fn doBindAddAddr(addr: u64, bw: *std.io.BufferedWriter) std.io.Writer.Error!void |
| 632 | 632 | try bw.writeLeb128(addr); |
| 633 | 633 | } |
| 634 | 634 | |
| 635 | fn doBindTimesSkip(count: usize, skip: u64, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 635 | fn doBindTimesSkip(count: usize, skip: u64, bw: *Writer) Writer.Error!void { | |
| 636 | 636 | log.debug(">>> bind with count: {d} and skip: {x}", .{ count, skip }); |
| 637 | 637 | try bw.writeByte(macho.BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB); |
| 638 | 638 | try bw.writeLeb128(count); |
| 639 | 639 | try bw.writeLeb128(skip); |
| 640 | 640 | } |
| 641 | 641 | |
| 642 | fn addAddr(addr: u64, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 642 | fn addAddr(addr: u64, bw: *Writer) Writer.Error!void { | |
| 643 | 643 | log.debug(">>> add: {x}", .{addr}); |
| 644 | 644 | try bw.writeByte(macho.BIND_OPCODE_ADD_ADDR_ULEB); |
| 645 | 645 | try bw.writeLeb128(addr); |
| 646 | 646 | } |
| 647 | 647 | |
| 648 | fn done(bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 648 | fn done(bw: *Writer) Writer.Error!void { | |
| 649 | 649 | log.debug(">>> done", .{}); |
| 650 | 650 | try bw.writeByte(macho.BIND_OPCODE_DONE); |
| 651 | 651 | } |
| 652 | 652 | |
| 653 | const std = @import("std"); | |
| 653 | 654 | const assert = std.debug.assert; |
| 654 | 655 | const leb = std.leb; |
| 655 | 656 | const log = std.log.scoped(.link_dyld_info); |
| 656 | 657 | const macho = std.macho; |
| 657 | 658 | const mem = std.mem; |
| 658 | 659 | const testing = std.testing; |
| 659 | const trace = @import("../../../tracy.zig").trace; | |
| 660 | const std = @import("std"); | |
| 660 | const Allocator = std.mem.Allocator; | |
| 661 | const Writer = std.io.Writer; | |
| 661 | 662 | |
| 662 | const Allocator = mem.Allocator; | |
| 663 | const trace = @import("../../../tracy.zig").trace; | |
| 663 | 664 | const File = @import("../file.zig").File; |
| 664 | 665 | const MachO = @import("../../MachO.zig"); |
| 665 | 666 | const Symbol = @import("../Symbol.zig"); |
src/link/MachO/eh_frame.zig+4-4| ... | ... | @@ -103,7 +103,7 @@ pub const Cie = struct { |
| 103 | 103 | macho_file: *MachO, |
| 104 | 104 | }; |
| 105 | 105 | |
| 106 | fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 106 | fn format2(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 107 | 107 | _ = unused_fmt_string; |
| 108 | 108 | const cie = ctx.cie; |
| 109 | 109 | try bw.print("@{x} : size({x})", .{ |
| ... | ... | @@ -142,8 +142,7 @@ pub const Fde = struct { |
| 142 | 142 | const object = fde.getObject(macho_file); |
| 143 | 143 | const sect = object.sections.items(.header)[object.eh_frame_sect_index.?]; |
| 144 | 144 | |
| 145 | var br: std.io.Reader = undefined; | |
| 146 | br.initFixed(fde.getData(macho_file)); | |
| 145 | var br: std.io.Reader = .fixed(fde.getData(macho_file)); | |
| 147 | 146 | |
| 148 | 147 | try br.discard(4); |
| 149 | 148 | const cie_ptr = try br.takeInt(u32, .little); |
| ... | ... | @@ -249,7 +248,7 @@ pub const Fde = struct { |
| 249 | 248 | macho_file: *MachO, |
| 250 | 249 | }; |
| 251 | 250 | |
| 252 | fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 251 | fn format2(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 253 | 252 | _ = unused_fmt_string; |
| 254 | 253 | const fde = ctx.fde; |
| 255 | 254 | const macho_file = ctx.macho_file; |
| ... | ... | @@ -528,6 +527,7 @@ const math = std.math; |
| 528 | 527 | const mem = std.mem; |
| 529 | 528 | const std = @import("std"); |
| 530 | 529 | const trace = @import("../../tracy.zig").trace; |
| 530 | const Writer = std.io.Writer; | |
| 531 | 531 | |
| 532 | 532 | const Allocator = std.mem.Allocator; |
| 533 | 533 | const Atom = @import("Atom.zig"); |
src/link/MachO/file.zig+3-2| ... | ... | @@ -14,7 +14,7 @@ pub const File = union(enum) { |
| 14 | 14 | return .{ .data = file }; |
| 15 | 15 | } |
| 16 | 16 | |
| 17 | fn formatPath(file: File, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void { | |
| 17 | fn formatPath(file: File, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { | |
| 18 | 18 | _ = unused_fmt_string; |
| 19 | 19 | switch (file) { |
| 20 | 20 | .zig_object => |zo| try bw.writeAll(zo.basename), |
| ... | ... | @@ -322,7 +322,7 @@ pub const File = union(enum) { |
| 322 | 322 | }; |
| 323 | 323 | } |
| 324 | 324 | |
| 325 | pub fn writeAr(file: File, bw: *std.io.BufferedWriter, ar_format: Archive.Format, macho_file: *MachO) std.io.Writer.Error!void { | |
| 325 | pub fn writeAr(file: File, bw: *Writer, ar_format: Archive.Format, macho_file: *MachO) Writer.Error!void { | |
| 326 | 326 | return switch (file) { |
| 327 | 327 | .dylib, .internal => unreachable, |
| 328 | 328 | .zig_object => |x| x.writeAr(bw, ar_format), |
| ... | ... | @@ -365,6 +365,7 @@ const log = std.log.scoped(.link); |
| 365 | 365 | const macho = std.macho; |
| 366 | 366 | const Allocator = std.mem.Allocator; |
| 367 | 367 | const Path = std.Build.Cache.Path; |
| 368 | const Writer = std.io.Writer; | |
| 368 | 369 | |
| 369 | 370 | const trace = @import("../../tracy.zig").trace; |
| 370 | 371 | const Archive = @import("Archive.zig"); |
src/link/MachO/load_commands.zig+6-5| ... | ... | @@ -3,6 +3,7 @@ const assert = std.debug.assert; |
| 3 | 3 | const log = std.log.scoped(.link); |
| 4 | 4 | const macho = std.macho; |
| 5 | 5 | const mem = std.mem; |
| 6 | const Writer = std.io.Writer; | |
| 6 | 7 | |
| 7 | 8 | const Allocator = mem.Allocator; |
| 8 | 9 | const DebugSymbols = @import("DebugSymbols.zig"); |
| ... | ... | @@ -180,7 +181,7 @@ pub fn calcMinHeaderPadSize(macho_file: *MachO) !u32 { |
| 180 | 181 | return offset; |
| 181 | 182 | } |
| 182 | 183 | |
| 183 | pub fn writeDylinkerLC(bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 184 | pub fn writeDylinkerLC(bw: *Writer) Writer.Error!void { | |
| 184 | 185 | const name_len = mem.sliceTo(default_dyld_path, 0).len; |
| 185 | 186 | const cmdsize = @as(u32, @intCast(mem.alignForward( |
| 186 | 187 | u64, |
| ... | ... | @@ -204,7 +205,7 @@ const WriteDylibLCCtx = struct { |
| 204 | 205 | compatibility_version: u32 = 0x10000, |
| 205 | 206 | }; |
| 206 | 207 | |
| 207 | pub fn writeDylibLC(ctx: WriteDylibLCCtx, bw: *std.io.BufferedWriter) !void { | |
| 208 | pub fn writeDylibLC(ctx: WriteDylibLCCtx, bw: *Writer) !void { | |
| 208 | 209 | const name_len = ctx.name.len + 1; |
| 209 | 210 | const cmdsize: u32 = @intCast(mem.alignForward( |
| 210 | 211 | u64, |
| ... | ... | @@ -252,7 +253,7 @@ pub fn writeDylibIdLC(macho_file: *MachO, writer: anytype) !void { |
| 252 | 253 | }, writer); |
| 253 | 254 | } |
| 254 | 255 | |
| 255 | pub fn writeRpathLC(bw: *std.io.BufferedWriter, rpath: []const u8) !void { | |
| 256 | pub fn writeRpathLC(bw: *Writer, rpath: []const u8) !void { | |
| 256 | 257 | const rpath_len = rpath.len + 1; |
| 257 | 258 | const cmdsize = @as(u32, @intCast(mem.alignForward( |
| 258 | 259 | u64, |
| ... | ... | @@ -268,7 +269,7 @@ pub fn writeRpathLC(bw: *std.io.BufferedWriter, rpath: []const u8) !void { |
| 268 | 269 | try bw.splatByteAll(0, cmdsize - @sizeOf(macho.rpath_command) - rpath_len); |
| 269 | 270 | } |
| 270 | 271 | |
| 271 | pub fn writeVersionMinLC(bw: *std.io.BufferedWriter, platform: MachO.Platform, sdk_version: ?std.SemanticVersion) std.io.Writer.Error!void { | |
| 272 | pub fn writeVersionMinLC(bw: *Writer, platform: MachO.Platform, sdk_version: ?std.SemanticVersion) Writer.Error!void { | |
| 272 | 273 | const cmd: macho.LC = switch (platform.os_tag) { |
| 273 | 274 | .macos => .VERSION_MIN_MACOSX, |
| 274 | 275 | .ios => .VERSION_MIN_IPHONEOS, |
| ... | ... | @@ -286,7 +287,7 @@ pub fn writeVersionMinLC(bw: *std.io.BufferedWriter, platform: MachO.Platform, s |
| 286 | 287 | })); |
| 287 | 288 | } |
| 288 | 289 | |
| 289 | pub fn writeBuildVersionLC(bw: *std.io.BufferedWriter, platform: MachO.Platform, sdk_version: ?std.SemanticVersion) std.io.Writer.Error!void { | |
| 290 | pub fn writeBuildVersionLC(bw: *Writer, platform: MachO.Platform, sdk_version: ?std.SemanticVersion) Writer.Error!void { | |
| 290 | 291 | const cmdsize = @sizeOf(macho.build_version_command) + @sizeOf(macho.build_tool_version); |
| 291 | 292 | try bw.writeStruct(macho.build_version_command{ |
| 292 | 293 | .cmdsize = cmdsize, |
src/link/MachO/relocatable.zig+3-4| ... | ... | @@ -205,8 +205,7 @@ pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ? |
| 205 | 205 | state_log.debug("ar_symtab\n{f}\n", .{ar_symtab.fmt(macho_file)}); |
| 206 | 206 | } |
| 207 | 207 | |
| 208 | var bw: std.io.BufferedWriter = undefined; | |
| 209 | bw.initFixed(try gpa.alloc(u8, total_size)); | |
| 208 | var bw: Writer = .fixed(try gpa.alloc(u8, total_size)); | |
| 210 | 209 | defer gpa.free(bw.buffer); |
| 211 | 210 | |
| 212 | 211 | // Write magic |
| ... | ... | @@ -683,8 +682,7 @@ fn writeSectionsToFile(macho_file: *MachO) !void { |
| 683 | 682 | |
| 684 | 683 | fn writeLoadCommands(macho_file: *MachO) error{ LinkFailure, OutOfMemory }!struct { usize, usize } { |
| 685 | 684 | const gpa = macho_file.base.comp.gpa; |
| 686 | var bw: std.io.BufferedWriter = undefined; | |
| 687 | bw.initFixed(try gpa.alloc(u8, load_commands.calcLoadCommandsSizeObject(macho_file))); | |
| 685 | var bw: Writer = .fixed(try gpa.alloc(u8, load_commands.calcLoadCommandsSizeObject(macho_file))); | |
| 688 | 686 | defer gpa.free(bw.buffer); |
| 689 | 687 | |
| 690 | 688 | var ncmds: usize = 0; |
| ... | ... | @@ -759,6 +757,7 @@ const macho = std.macho; |
| 759 | 757 | const math = std.math; |
| 760 | 758 | const mem = std.mem; |
| 761 | 759 | const state_log = std.log.scoped(.link_state); |
| 760 | const Writer = std.io.Writer; | |
| 762 | 761 | |
| 763 | 762 | const Archive = @import("Archive.zig"); |
| 764 | 763 | const Atom = @import("Atom.zig"); |
src/link/MachO/synthetic.zig+17-16| ... | ... | @@ -27,7 +27,7 @@ pub const GotSection = struct { |
| 27 | 27 | return got.symbols.items.len * @sizeOf(u64); |
| 28 | 28 | } |
| 29 | 29 | |
| 30 | pub fn write(got: GotSection, macho_file: *MachO, bw: *std.io.BufferedWriter) !void { | |
| 30 | pub fn write(got: GotSection, macho_file: *MachO, bw: *Writer) !void { | |
| 31 | 31 | const tracy = trace(@src()); |
| 32 | 32 | defer tracy.end(); |
| 33 | 33 | for (got.symbols.items) |ref| { |
| ... | ... | @@ -48,7 +48,7 @@ pub const GotSection = struct { |
| 48 | 48 | |
| 49 | 49 | pub fn format2( |
| 50 | 50 | ctx: FormatCtx, |
| 51 | bw: *std.io.BufferedWriter, | |
| 51 | bw: *Writer, | |
| 52 | 52 | comptime unused_fmt_string: []const u8, |
| 53 | 53 | ) !void { |
| 54 | 54 | _ = unused_fmt_string; |
| ... | ... | @@ -94,7 +94,7 @@ pub const StubsSection = struct { |
| 94 | 94 | return stubs.symbols.items.len * header.reserved2; |
| 95 | 95 | } |
| 96 | 96 | |
| 97 | pub fn write(stubs: StubsSection, macho_file: *MachO, bw: *std.io.BufferedWriter) !void { | |
| 97 | pub fn write(stubs: StubsSection, macho_file: *MachO, bw: *Writer) !void { | |
| 98 | 98 | const tracy = trace(@src()); |
| 99 | 99 | defer tracy.end(); |
| 100 | 100 | const cpu_arch = macho_file.getTarget().cpu.arch; |
| ... | ... | @@ -137,7 +137,7 @@ pub const StubsSection = struct { |
| 137 | 137 | |
| 138 | 138 | pub fn format2( |
| 139 | 139 | ctx: FormatCtx, |
| 140 | bw: *std.io.BufferedWriter, | |
| 140 | bw: *Writer, | |
| 141 | 141 | comptime unused_fmt_string: []const u8, |
| 142 | 142 | ) !void { |
| 143 | 143 | _ = unused_fmt_string; |
| ... | ... | @@ -185,7 +185,7 @@ pub const StubsHelperSection = struct { |
| 185 | 185 | return s; |
| 186 | 186 | } |
| 187 | 187 | |
| 188 | pub fn write(stubs_helper: StubsHelperSection, macho_file: *MachO, bw: *std.io.BufferedWriter) !void { | |
| 188 | pub fn write(stubs_helper: StubsHelperSection, macho_file: *MachO, bw: *Writer) !void { | |
| 189 | 189 | const tracy = trace(@src()); |
| 190 | 190 | defer tracy.end(); |
| 191 | 191 | |
| ... | ... | @@ -230,7 +230,7 @@ pub const StubsHelperSection = struct { |
| 230 | 230 | } |
| 231 | 231 | } |
| 232 | 232 | |
| 233 | fn writePreamble(stubs_helper: StubsHelperSection, macho_file: *MachO, bw: *std.io.BufferedWriter) !void { | |
| 233 | fn writePreamble(stubs_helper: StubsHelperSection, macho_file: *MachO, bw: *Writer) !void { | |
| 234 | 234 | _ = stubs_helper; |
| 235 | 235 | const obj = macho_file.getInternalObject().?; |
| 236 | 236 | const cpu_arch = macho_file.getTarget().cpu.arch; |
| ... | ... | @@ -289,7 +289,7 @@ pub const LaSymbolPtrSection = struct { |
| 289 | 289 | return macho_file.stubs.symbols.items.len * @sizeOf(u64); |
| 290 | 290 | } |
| 291 | 291 | |
| 292 | pub fn write(laptr: LaSymbolPtrSection, macho_file: *MachO, bw: *std.io.BufferedWriter) !void { | |
| 292 | pub fn write(laptr: LaSymbolPtrSection, macho_file: *MachO, bw: *Writer) !void { | |
| 293 | 293 | const tracy = trace(@src()); |
| 294 | 294 | defer tracy.end(); |
| 295 | 295 | _ = laptr; |
| ... | ... | @@ -339,7 +339,7 @@ pub const TlvPtrSection = struct { |
| 339 | 339 | return tlv.symbols.items.len * @sizeOf(u64); |
| 340 | 340 | } |
| 341 | 341 | |
| 342 | pub fn write(tlv: TlvPtrSection, macho_file: *MachO, bw: *std.io.BufferedWriter) !void { | |
| 342 | pub fn write(tlv: TlvPtrSection, macho_file: *MachO, bw: *Writer) !void { | |
| 343 | 343 | const tracy = trace(@src()); |
| 344 | 344 | defer tracy.end(); |
| 345 | 345 | |
| ... | ... | @@ -364,7 +364,7 @@ pub const TlvPtrSection = struct { |
| 364 | 364 | |
| 365 | 365 | pub fn format2( |
| 366 | 366 | ctx: FormatCtx, |
| 367 | bw: *std.io.BufferedWriter, | |
| 367 | bw: *Writer, | |
| 368 | 368 | comptime unused_fmt_string: []const u8, |
| 369 | 369 | ) !void { |
| 370 | 370 | _ = unused_fmt_string; |
| ... | ... | @@ -415,7 +415,7 @@ pub const ObjcStubsSection = struct { |
| 415 | 415 | return objc.symbols.items.len * entrySize(macho_file.getTarget().cpu.arch); |
| 416 | 416 | } |
| 417 | 417 | |
| 418 | pub fn write(objc: ObjcStubsSection, macho_file: *MachO, bw: *std.io.BufferedWriter) !void { | |
| 418 | pub fn write(objc: ObjcStubsSection, macho_file: *MachO, bw: *Writer) !void { | |
| 419 | 419 | const tracy = trace(@src()); |
| 420 | 420 | defer tracy.end(); |
| 421 | 421 | |
| ... | ... | @@ -487,7 +487,7 @@ pub const ObjcStubsSection = struct { |
| 487 | 487 | |
| 488 | 488 | pub fn format2( |
| 489 | 489 | ctx: FormatCtx, |
| 490 | bw: *std.io.BufferedWriter, | |
| 490 | bw: *Writer, | |
| 491 | 491 | comptime unused_fmt_string: []const u8, |
| 492 | 492 | ) !void { |
| 493 | 493 | _ = unused_fmt_string; |
| ... | ... | @@ -516,7 +516,7 @@ pub const Indsymtab = struct { |
| 516 | 516 | macho_file.dysymtab_cmd.nindirectsyms = ind.nsyms(macho_file); |
| 517 | 517 | } |
| 518 | 518 | |
| 519 | pub fn write(ind: Indsymtab, macho_file: *MachO, bw: *std.io.BufferedWriter) !void { | |
| 519 | pub fn write(ind: Indsymtab, macho_file: *MachO, bw: *Writer) !void { | |
| 520 | 520 | const tracy = trace(@src()); |
| 521 | 521 | defer tracy.end(); |
| 522 | 522 | |
| ... | ... | @@ -593,7 +593,7 @@ pub const DataInCode = struct { |
| 593 | 593 | macho_file.data_in_code_cmd.datasize = math.cast(u32, dice.size()) orelse return error.Overflow; |
| 594 | 594 | } |
| 595 | 595 | |
| 596 | pub fn write(dice: DataInCode, macho_file: *MachO, bw: *std.io.BufferedWriter) !void { | |
| 596 | pub fn write(dice: DataInCode, macho_file: *MachO, bw: *Writer) !void { | |
| 597 | 597 | const base_address = if (!macho_file.base.isRelocatable()) |
| 598 | 598 | macho_file.getTextSegment().vmaddr |
| 599 | 599 | else |
| ... | ... | @@ -617,13 +617,14 @@ pub const DataInCode = struct { |
| 617 | 617 | }; |
| 618 | 618 | }; |
| 619 | 619 | |
| 620 | const std = @import("std"); | |
| 620 | 621 | const aarch64 = @import("../aarch64.zig"); |
| 621 | 622 | const assert = std.debug.assert; |
| 622 | 623 | const macho = std.macho; |
| 623 | 624 | const math = std.math; |
| 624 | const std = @import("std"); | |
| 625 | const trace = @import("../../tracy.zig").trace; | |
| 626 | ||
| 627 | 625 | const Allocator = std.mem.Allocator; |
| 626 | const Writer = std.io.Writer; | |
| 627 | ||
| 628 | const trace = @import("../../tracy.zig").trace; | |
| 628 | 629 | const MachO = @import("../MachO.zig"); |
| 629 | 630 | const Symbol = @import("Symbol.zig"); |
src/link/Plan9.zig+27-27| ... | ... | @@ -23,6 +23,7 @@ const Allocator = std.mem.Allocator; |
| 23 | 23 | const log = std.log.scoped(.link); |
| 24 | 24 | const assert = std.debug.assert; |
| 25 | 25 | const Path = std.Build.Cache.Path; |
| 26 | const Writer = std.io.Writer; | |
| 26 | 27 | |
| 27 | 28 | base: link.File, |
| 28 | 29 | sixtyfour_bit: bool, |
| ... | ... | @@ -336,25 +337,24 @@ fn putFn(self: *Plan9, nav_index: InternPool.Nav.Index, out: FnNavOutput) !void |
| 336 | 337 | }; |
| 337 | 338 | try fn_map_res.value_ptr.functions.put(gpa, nav_index, out); |
| 338 | 339 | |
| 339 | var aw: std.io.AllocatingWriter = undefined; | |
| 340 | aw.init(arena); | |
| 340 | var aw: std.io.AllocatingWriter = .init(arena); | |
| 341 | 341 | defer aw.deinit(); |
| 342 | const bw = &aw.buffered_writer; | |
| 342 | const w = &aw.interface; | |
| 343 | 343 | |
| 344 | 344 | // every 'z' starts with 0 |
| 345 | try bw.writeByte(0); | |
| 345 | try w.writeByte(0); | |
| 346 | 346 | // path component value of '/' |
| 347 | try bw.writeInt(u16, 1, .big); | |
| 347 | try w.writeInt(u16, 1, .big); | |
| 348 | 348 | |
| 349 | 349 | // getting the full file path |
| 350 | 350 | { |
| 351 | 351 | const full_path = try file.path.toAbsolute(comp.dirs, gpa); |
| 352 | 352 | defer gpa.free(full_path); |
| 353 | try self.addPathComponents(full_path, bw); | |
| 353 | try self.addPathComponents(full_path, w); | |
| 354 | 354 | } |
| 355 | 355 | |
| 356 | 356 | // null terminate |
| 357 | try bw.writeByte(0); | |
| 357 | try w.writeByte(0); | |
| 358 | 358 | const final = try aw.toOwnedSlice(); |
| 359 | 359 | self.syms.items[fn_map_res.value_ptr.sym_index - 1] = .{ |
| 360 | 360 | .type = .z, |
| ... | ... | @@ -370,17 +370,17 @@ fn putFn(self: *Plan9, nav_index: InternPool.Nav.Index, out: FnNavOutput) !void |
| 370 | 370 | } |
| 371 | 371 | } |
| 372 | 372 | |
| 373 | fn addPathComponents(self: *Plan9, path: []const u8, bw: *std.io.BufferedWriter) !void { | |
| 373 | fn addPathComponents(self: *Plan9, path: []const u8, w: *Writer) !void { | |
| 374 | 374 | const gpa = self.base.comp.gpa; |
| 375 | 375 | const sep = std.fs.path.sep; |
| 376 | 376 | var it = std.mem.tokenizeScalar(u8, path, sep); |
| 377 | 377 | while (it.next()) |component| { |
| 378 | 378 | if (self.file_segments.get(component)) |num| { |
| 379 | try bw.writeInt(u16, num, .big); | |
| 379 | try w.writeInt(u16, num, .big); | |
| 380 | 380 | } else { |
| 381 | 381 | self.file_segments_i += 1; |
| 382 | 382 | try self.file_segments.put(gpa, component, self.file_segments_i); |
| 383 | try bw.writeInt(u16, self.file_segments_i, .big); | |
| 383 | try w.writeInt(u16, self.file_segments_i, .big); | |
| 384 | 384 | } |
| 385 | 385 | } |
| 386 | 386 | } |
| ... | ... | @@ -527,14 +527,14 @@ fn allocateGotIndex(self: *Plan9) usize { |
| 527 | 527 | } |
| 528 | 528 | } |
| 529 | 529 | |
| 530 | pub fn changeLine(bw: *std.io.Writer, delta_line: i32) !void { | |
| 530 | pub fn changeLine(w: *std.io.Writer, delta_line: i32) !void { | |
| 531 | 531 | if (delta_line > 0 and delta_line < 65) { |
| 532 | try bw.writeByte(@intCast(delta_line)); | |
| 532 | try w.writeByte(@intCast(delta_line)); | |
| 533 | 533 | } else if (delta_line < 0 and delta_line > -65) { |
| 534 | try bw.writeByte(@intCast(-delta_line + 64)); | |
| 534 | try w.writeByte(@intCast(-delta_line + 64)); | |
| 535 | 535 | } else if (delta_line != 0) { |
| 536 | try bw.writeByte(0); | |
| 537 | try bw.writeInt(i32, delta_line, .big); | |
| 536 | try w.writeByte(0); | |
| 537 | try w.writeInt(i32, delta_line, .big); | |
| 538 | 538 | } |
| 539 | 539 | } |
| 540 | 540 | |
| ... | ... | @@ -1205,16 +1205,16 @@ pub fn writeSym(self: *Plan9, w: anytype, sym: aout.Sym) !void { |
| 1205 | 1205 | try w.writeByte(0); |
| 1206 | 1206 | } |
| 1207 | 1207 | |
| 1208 | pub fn writeSyms(self: *Plan9, bw: *std.io.BufferedWriter) !void { | |
| 1208 | pub fn writeSyms(self: *Plan9, w: *Writer) !void { | |
| 1209 | 1209 | const zcu = self.base.comp.zcu.?; |
| 1210 | 1210 | const ip = &zcu.intern_pool; |
| 1211 | 1211 | // write __GOT |
| 1212 | try self.writeSym(bw, self.syms.items[0]); | |
| 1212 | try self.writeSym(w, self.syms.items[0]); | |
| 1213 | 1213 | // write the f symbols |
| 1214 | 1214 | { |
| 1215 | 1215 | var it = self.file_segments.iterator(); |
| 1216 | 1216 | while (it.next()) |entry| { |
| 1217 | try self.writeSym(bw, .{ | |
| 1217 | try self.writeSym(w, .{ | |
| 1218 | 1218 | .type = .f, |
| 1219 | 1219 | .value = entry.value_ptr.*, |
| 1220 | 1220 | .name = entry.key_ptr.*, |
| ... | ... | @@ -1230,12 +1230,12 @@ pub fn writeSyms(self: *Plan9, bw: *std.io.BufferedWriter) !void { |
| 1230 | 1230 | const nav_metadata = self.navs.get(nav_index).?; |
| 1231 | 1231 | const atom = self.getAtom(nav_metadata.index); |
| 1232 | 1232 | const sym = self.syms.items[atom.sym_index.?]; |
| 1233 | try self.writeSym(bw, sym); | |
| 1233 | try self.writeSym(w, sym); | |
| 1234 | 1234 | if (self.nav_exports.get(nav_index)) |export_indices| { |
| 1235 | 1235 | for (export_indices) |export_idx| { |
| 1236 | 1236 | const exp = export_idx.ptr(zcu); |
| 1237 | 1237 | if (nav_metadata.getExport(self, exp.opts.name.toSlice(ip))) |exp_i| { |
| 1238 | try self.writeSym(bw, self.syms.items[exp_i]); | |
| 1238 | try self.writeSym(w, self.syms.items[exp_i]); | |
| 1239 | 1239 | } |
| 1240 | 1240 | } |
| 1241 | 1241 | } |
| ... | ... | @@ -1248,7 +1248,7 @@ pub fn writeSyms(self: *Plan9, bw: *std.io.BufferedWriter) !void { |
| 1248 | 1248 | const meta = kv.value_ptr; |
| 1249 | 1249 | const data_atom = if (meta.rodata_state != .unused) self.getAtomPtr(meta.rodata_atom) else continue; |
| 1250 | 1250 | const sym = self.syms.items[data_atom.sym_index.?]; |
| 1251 | try self.writeSym(bw, sym); | |
| 1251 | try self.writeSym(w, sym); | |
| 1252 | 1252 | } |
| 1253 | 1253 | } |
| 1254 | 1254 | // text symbols are the hardest: |
| ... | ... | @@ -1259,8 +1259,8 @@ pub fn writeSyms(self: *Plan9, bw: *std.io.BufferedWriter) !void { |
| 1259 | 1259 | while (it_file.next()) |fentry| { |
| 1260 | 1260 | var symidx_and_submap = fentry.value_ptr; |
| 1261 | 1261 | // write the z symbols |
| 1262 | try self.writeSym(bw, self.syms.items[symidx_and_submap.sym_index - 1]); | |
| 1263 | try self.writeSym(bw, self.syms.items[symidx_and_submap.sym_index]); | |
| 1262 | try self.writeSym(w, self.syms.items[symidx_and_submap.sym_index - 1]); | |
| 1263 | try self.writeSym(w, self.syms.items[symidx_and_submap.sym_index]); | |
| 1264 | 1264 | |
| 1265 | 1265 | // write all the decls come from the file of the z symbol |
| 1266 | 1266 | var submap_it = symidx_and_submap.functions.iterator(); |
| ... | ... | @@ -1269,7 +1269,7 @@ pub fn writeSyms(self: *Plan9, bw: *std.io.BufferedWriter) !void { |
| 1269 | 1269 | const nav_metadata = self.navs.get(nav_index).?; |
| 1270 | 1270 | const atom = self.getAtom(nav_metadata.index); |
| 1271 | 1271 | const sym = self.syms.items[atom.sym_index.?]; |
| 1272 | try self.writeSym(bw, sym); | |
| 1272 | try self.writeSym(w, sym); | |
| 1273 | 1273 | if (self.nav_exports.get(nav_index)) |export_indices| { |
| 1274 | 1274 | for (export_indices) |export_idx| { |
| 1275 | 1275 | const exp = export_idx.ptr(zcu); |
| ... | ... | @@ -1277,7 +1277,7 @@ pub fn writeSyms(self: *Plan9, bw: *std.io.BufferedWriter) !void { |
| 1277 | 1277 | const s = self.syms.items[exp_i]; |
| 1278 | 1278 | if (mem.eql(u8, s.name, "_start")) |
| 1279 | 1279 | self.entry_val = s.value; |
| 1280 | try self.writeSym(bw, s); | |
| 1280 | try self.writeSym(w, s); | |
| 1281 | 1281 | } |
| 1282 | 1282 | } |
| 1283 | 1283 | } |
| ... | ... | @@ -1290,7 +1290,7 @@ pub fn writeSyms(self: *Plan9, bw: *std.io.BufferedWriter) !void { |
| 1290 | 1290 | const meta = kv.value_ptr; |
| 1291 | 1291 | const text_atom = if (meta.text_state != .unused) self.getAtomPtr(meta.text_atom) else continue; |
| 1292 | 1292 | const sym = self.syms.items[text_atom.sym_index.?]; |
| 1293 | try self.writeSym(bw, sym); | |
| 1293 | try self.writeSym(w, sym); | |
| 1294 | 1294 | } |
| 1295 | 1295 | } |
| 1296 | 1296 | } |
| ... | ... | @@ -1299,7 +1299,7 @@ pub fn writeSyms(self: *Plan9, bw: *std.io.BufferedWriter) !void { |
| 1299 | 1299 | if (idx) |atom_idx| { |
| 1300 | 1300 | const atom = self.getAtom(atom_idx); |
| 1301 | 1301 | const sym = self.syms.items[atom.sym_index.?]; |
| 1302 | try self.writeSym(bw, sym); | |
| 1302 | try self.writeSym(w, sym); | |
| 1303 | 1303 | } |
| 1304 | 1304 | } |
| 1305 | 1305 | } |
src/link/Wasm.zig+5-5| ... | ... | @@ -28,6 +28,7 @@ const fs = std.fs; |
| 28 | 28 | const leb = std.leb; |
| 29 | 29 | const log = std.log.scoped(.link); |
| 30 | 30 | const mem = std.mem; |
| 31 | const Writer = std.io.Writer; | |
| 31 | 32 | |
| 32 | 33 | const Mir = @import("../arch/wasm/Mir.zig"); |
| 33 | 34 | const CodeGen = @import("../arch/wasm/CodeGen.zig"); |
| ... | ... | @@ -2124,8 +2125,8 @@ pub const FunctionType = extern struct { |
| 2124 | 2125 | wasm: *const Wasm, |
| 2125 | 2126 | ft: FunctionType, |
| 2126 | 2127 | |
| 2127 | pub fn format(self: Formatter, bw: *std.io.BufferedWriter, comptime format_string: []const u8) std.io.Writer.Error!void { | |
| 2128 | if (format_string.len != 0) std.fmt.invalidFmtError(format_string, self); | |
| 2128 | pub fn format(self: Formatter, bw: *Writer, comptime format_string: []const u8) Writer.Error!void { | |
| 2129 | comptime assert(format_string.len == 0); | |
| 2129 | 2130 | const params = self.ft.params.slice(self.wasm); |
| 2130 | 2131 | const returns = self.ft.returns.slice(self.wasm); |
| 2131 | 2132 | |
| ... | ... | @@ -2904,7 +2905,7 @@ pub const Feature = packed struct(u8) { |
| 2904 | 2905 | @"=", |
| 2905 | 2906 | }; |
| 2906 | 2907 | |
| 2907 | pub fn format(feature: Feature, bw: *std.io.BufferedWriter, comptime fmt: []const u8) std.io.Writer.Error!void { | |
| 2908 | pub fn format(feature: Feature, bw: *Writer, comptime fmt: []const u8) Writer.Error!void { | |
| 2908 | 2909 | _ = fmt; |
| 2909 | 2910 | try bw.print("{s} {s}", .{ @tagName(feature.prefix), @tagName(feature.tag) }); |
| 2910 | 2911 | } |
| ... | ... | @@ -3037,8 +3038,7 @@ fn parseObject(wasm: *Wasm, obj: link.Input.Object) !void { |
| 3037 | 3038 | const stat = try obj.file.stat(); |
| 3038 | 3039 | const size = std.math.cast(usize, stat.size) orelse return error.FileTooBig; |
| 3039 | 3040 | |
| 3040 | var br: std.io.Reader = undefined; | |
| 3041 | br.initFixed(try gpa.alloc(u8, size)); | |
| 3041 | var br: std.io.Reader = .fixed(try gpa.alloc(u8, size)); | |
| 3042 | 3042 | defer gpa.free(br.storageBuffer()); |
| 3043 | 3043 | |
| 3044 | 3044 | const n = try obj.file.preadAll(br.storageBuffer(), 0); |
src/link/Wasm/Flush.zig+355-354| ... | ... | @@ -18,6 +18,7 @@ const Allocator = std.mem.Allocator; |
| 18 | 18 | const mem = std.mem; |
| 19 | 19 | const log = std.log.scoped(.link); |
| 20 | 20 | const assert = std.debug.assert; |
| 21 | const Writer = std.io.Writer; | |
| 21 | 22 | |
| 22 | 23 | /// Ordered list of data segments that will appear in the final binary. |
| 23 | 24 | /// When sorted, to-be-merged segments will be made adjacent. |
| ... | ... | @@ -557,11 +558,11 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 557 | 558 | var data_section_index: ?u32 = null; |
| 558 | 559 | |
| 559 | 560 | assert(f.binary_bytes.items.len == 0); |
| 560 | var aw: std.io.AllocatingWriter = undefined; | |
| 561 | const bw = aw.fromArrayList(gpa, &f.binary_bytes); | |
| 561 | var aw: std.io.AllocatingWriter = .fromArrayList(gpa, &f.binary_bytes); | |
| 562 | 562 | defer f.binary_bytes = aw.toArrayList(); |
| 563 | const w = &aw.interface; | |
| 563 | 564 | |
| 564 | try bw.writeAll(&std.wasm.magic ++ &std.wasm.version); | |
| 565 | try w.writeAll(&std.wasm.magic ++ &std.wasm.version); | |
| 565 | 566 | |
| 566 | 567 | // Type section. |
| 567 | 568 | for (f.function_imports.values()) |id| { |
| ... | ... | @@ -571,16 +572,16 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 571 | 572 | try f.func_types.put(gpa, function.typeIndex(wasm), {}); |
| 572 | 573 | } |
| 573 | 574 | if (f.func_types.entries.len != 0) { |
| 574 | const header_offset = try reserveVecSectionHeader(bw); | |
| 575 | const header_offset = try reserveVecSectionHeader(w); | |
| 575 | 576 | for (f.func_types.keys()) |func_type_index| { |
| 576 | 577 | const func_type = func_type_index.ptr(wasm); |
| 577 | try bw.writeLeb128(std.wasm.function_type); | |
| 578 | try w.writeLeb128(std.wasm.function_type); | |
| 578 | 579 | const params = func_type.params.slice(wasm); |
| 579 | try bw.writeLeb128(params.len); | |
| 580 | for (params) |param_ty| try bw.writeLeb128(@intFromEnum(param_ty)); | |
| 580 | try w.writeLeb128(params.len); | |
| 581 | for (params) |param_ty| try w.writeLeb128(@intFromEnum(param_ty)); | |
| 581 | 582 | const returns = func_type.returns.slice(wasm); |
| 582 | try bw.writeLeb128(returns.len); | |
| 583 | for (returns) |ret_ty| try bw.writeLeb128(@intFromEnum(ret_ty)); | |
| 583 | try w.writeLeb128(returns.len); | |
| 584 | for (returns) |ret_ty| try w.writeLeb128(@intFromEnum(ret_ty)); | |
| 584 | 585 | } |
| 585 | 586 | replaceVecSectionHeader(&aw, header_offset, .type, @intCast(f.func_types.entries.len)); |
| 586 | 587 | section_index += 1; |
| ... | ... | @@ -595,42 +596,42 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 595 | 596 | // Import section |
| 596 | 597 | { |
| 597 | 598 | var total_imports: usize = 0; |
| 598 | const header_offset = try reserveVecSectionHeader(bw); | |
| 599 | const header_offset = try reserveVecSectionHeader(w); | |
| 599 | 600 | |
| 600 | 601 | for (f.function_imports.values()) |id| { |
| 601 | 602 | const module_name = id.moduleName(wasm).slice(wasm).?; |
| 602 | try bw.writeLeb128(module_name.len); | |
| 603 | try bw.writeAll(module_name); | |
| 603 | try w.writeLeb128(module_name.len); | |
| 604 | try w.writeAll(module_name); | |
| 604 | 605 | |
| 605 | 606 | const name = id.importName(wasm).slice(wasm); |
| 606 | try bw.writeLeb128(name.len); | |
| 607 | try bw.writeAll(name); | |
| 607 | try w.writeLeb128(name.len); | |
| 608 | try w.writeAll(name); | |
| 608 | 609 | |
| 609 | try bw.writeByte(@intFromEnum(std.wasm.ExternalKind.function)); | |
| 610 | try w.writeByte(@intFromEnum(std.wasm.ExternalKind.function)); | |
| 610 | 611 | const type_index: FuncTypeIndex = .fromTypeIndex(id.functionType(wasm), f); |
| 611 | try bw.writeLeb128(@intFromEnum(type_index)); | |
| 612 | try w.writeLeb128(@intFromEnum(type_index)); | |
| 612 | 613 | } |
| 613 | 614 | total_imports += f.function_imports.entries.len; |
| 614 | 615 | |
| 615 | 616 | for (wasm.table_imports.values()) |id| { |
| 616 | 617 | const table_import = id.value(wasm); |
| 617 | 618 | const module_name = table_import.module_name.slice(wasm); |
| 618 | try bw.writeLeb128(module_name.len); | |
| 619 | try bw.writeAll(module_name); | |
| 619 | try w.writeLeb128(module_name.len); | |
| 620 | try w.writeAll(module_name); | |
| 620 | 621 | |
| 621 | 622 | const name = table_import.name.slice(wasm); |
| 622 | try bw.writeLeb128(name.len); | |
| 623 | try bw.writeAll(name); | |
| 623 | try w.writeLeb128(name.len); | |
| 624 | try w.writeAll(name); | |
| 624 | 625 | |
| 625 | try bw.writeByte(@intFromEnum(std.wasm.ExternalKind.table)); | |
| 626 | try bw.writeLeb128(@intFromEnum(@as(std.wasm.RefType, table_import.flags.ref_type.to()))); | |
| 627 | try emitLimits(bw, table_import.limits()); | |
| 626 | try w.writeByte(@intFromEnum(std.wasm.ExternalKind.table)); | |
| 627 | try w.writeLeb128(@intFromEnum(@as(std.wasm.RefType, table_import.flags.ref_type.to()))); | |
| 628 | try emitLimits(w, table_import.limits()); | |
| 628 | 629 | } |
| 629 | 630 | total_imports += wasm.table_imports.entries.len; |
| 630 | 631 | |
| 631 | 632 | if (import_memory) { |
| 632 | 633 | const name = if (is_obj) wasm.preloaded_strings.__linear_memory else wasm.preloaded_strings.memory; |
| 633 | try emitMemoryImport(wasm, bw, name, &.{ | |
| 634 | try emitMemoryImport(wasm, w, name, &.{ | |
| 634 | 635 | // TODO the import_memory option needs to specify from which module |
| 635 | 636 | .module_name = wasm.object_host_name.unwrap().?, |
| 636 | 637 | .limits_min = wasm.memories.limits.min, |
| ... | ... | @@ -644,17 +645,17 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 644 | 645 | |
| 645 | 646 | for (f.global_imports.values()) |id| { |
| 646 | 647 | const module_name = id.moduleName(wasm).slice(wasm).?; |
| 647 | try bw.writeLeb128(module_name.len); | |
| 648 | try bw.writeAll(module_name); | |
| 648 | try w.writeLeb128(module_name.len); | |
| 649 | try w.writeAll(module_name); | |
| 649 | 650 | |
| 650 | 651 | const name = id.importName(wasm).slice(wasm); |
| 651 | try bw.writeLeb128(name.len); | |
| 652 | try bw.writeAll(name); | |
| 652 | try w.writeLeb128(name.len); | |
| 653 | try w.writeAll(name); | |
| 653 | 654 | |
| 654 | try bw.writeByte(@intFromEnum(std.wasm.ExternalKind.global)); | |
| 655 | try w.writeByte(@intFromEnum(std.wasm.ExternalKind.global)); | |
| 655 | 656 | const global_type = id.globalType(wasm); |
| 656 | try bw.writeLeb128(@intFromEnum(global_type.valtype)); | |
| 657 | try bw.writeByte(@intFromBool(global_type.mutable)); | |
| 657 | try w.writeLeb128(@intFromEnum(global_type.valtype)); | |
| 658 | try w.writeByte(@intFromBool(global_type.mutable)); | |
| 658 | 659 | } |
| 659 | 660 | total_imports += f.global_imports.entries.len; |
| 660 | 661 | |
| ... | ... | @@ -668,10 +669,10 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 668 | 669 | |
| 669 | 670 | // Function section |
| 670 | 671 | if (wasm.functions.count() != 0) { |
| 671 | const header_offset = try reserveVecSectionHeader(bw); | |
| 672 | const header_offset = try reserveVecSectionHeader(w); | |
| 672 | 673 | for (wasm.functions.keys()) |function| { |
| 673 | 674 | const index: FuncTypeIndex = .fromTypeIndex(function.typeIndex(wasm), f); |
| 674 | try bw.writeLeb128(@intFromEnum(index)); | |
| 675 | try w.writeLeb128(@intFromEnum(index)); | |
| 675 | 676 | } |
| 676 | 677 | |
| 677 | 678 | replaceVecSectionHeader(&aw, header_offset, .function, @intCast(wasm.functions.count())); |
| ... | ... | @@ -680,11 +681,11 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 680 | 681 | |
| 681 | 682 | // Table section |
| 682 | 683 | if (wasm.tables.entries.len > 0) { |
| 683 | const header_offset = try reserveVecSectionHeader(bw); | |
| 684 | const header_offset = try reserveVecSectionHeader(w); | |
| 684 | 685 | |
| 685 | 686 | for (wasm.tables.keys()) |table| { |
| 686 | try bw.writeLeb128(@intFromEnum(table.refType(wasm))); | |
| 687 | try emitLimits(bw, table.limits(wasm)); | |
| 687 | try w.writeLeb128(@intFromEnum(table.refType(wasm))); | |
| 688 | try emitLimits(w, table.limits(wasm)); | |
| 688 | 689 | } |
| 689 | 690 | |
| 690 | 691 | replaceVecSectionHeader(&aw, header_offset, .table, @intCast(wasm.tables.entries.len)); |
| ... | ... | @@ -693,8 +694,8 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 693 | 694 | |
| 694 | 695 | // Memory section. wasm currently only supports 1 linear memory segment. |
| 695 | 696 | if (!import_memory) { |
| 696 | const header_offset = try reserveVecSectionHeader(bw); | |
| 697 | try emitLimits(bw, wasm.memories.limits); | |
| 697 | const header_offset = try reserveVecSectionHeader(w); | |
| 698 | try emitLimits(w, wasm.memories.limits); | |
| 698 | 699 | replaceVecSectionHeader(&aw, header_offset, .memory, 1); |
| 699 | 700 | section_index += 1; |
| 700 | 701 | } |
| ... | ... | @@ -702,24 +703,24 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 702 | 703 | // Global section. |
| 703 | 704 | const globals_len: u32 = @intCast(wasm.globals.entries.len); |
| 704 | 705 | if (globals_len > 0) { |
| 705 | const header_offset = try reserveVecSectionHeader(bw); | |
| 706 | const header_offset = try reserveVecSectionHeader(w); | |
| 706 | 707 | |
| 707 | 708 | for (wasm.globals.keys()) |global_resolution| { |
| 708 | 709 | switch (global_resolution.unpack(wasm)) { |
| 709 | 710 | .unresolved => unreachable, |
| 710 | .__heap_base => try appendGlobal(bw, false, virtual_addrs.heap_base), | |
| 711 | .__heap_end => try appendGlobal(bw, false, virtual_addrs.heap_end), | |
| 712 | .__stack_pointer => try appendGlobal(bw, true, virtual_addrs.stack_pointer), | |
| 713 | .__tls_align => try appendGlobal(bw, false, @intCast(virtual_addrs.tls_align.toByteUnits().?)), | |
| 714 | .__tls_base => try appendGlobal(bw, true, virtual_addrs.tls_base.?), | |
| 715 | .__tls_size => try appendGlobal(bw, false, virtual_addrs.tls_size.?), | |
| 711 | .__heap_base => try appendGlobal(w, false, virtual_addrs.heap_base), | |
| 712 | .__heap_end => try appendGlobal(w, false, virtual_addrs.heap_end), | |
| 713 | .__stack_pointer => try appendGlobal(w, true, virtual_addrs.stack_pointer), | |
| 714 | .__tls_align => try appendGlobal(w, false, @intCast(virtual_addrs.tls_align.toByteUnits().?)), | |
| 715 | .__tls_base => try appendGlobal(w, true, virtual_addrs.tls_base.?), | |
| 716 | .__tls_size => try appendGlobal(w, false, virtual_addrs.tls_size.?), | |
| 716 | 717 | .object_global => |i| { |
| 717 | 718 | const global = i.ptr(wasm); |
| 718 | try bw.writeAll(&.{ | |
| 719 | try w.writeAll(&.{ | |
| 719 | 720 | @intFromEnum(@as(std.wasm.Valtype, global.flags.global_type.valtype.to())), |
| 720 | 721 | @intFromBool(global.flags.global_type.mutable), |
| 721 | 722 | }); |
| 722 | try emitExpr(wasm, bw, global.expr); | |
| 723 | try emitExpr(wasm, w, global.expr); | |
| 723 | 724 | }, |
| 724 | 725 | .nav_exe => unreachable, // Zig source code currently cannot represent this. |
| 725 | 726 | .nav_obj => unreachable, // Zig source code currently cannot represent this. |
| ... | ... | @@ -732,44 +733,44 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 732 | 733 | |
| 733 | 734 | // Export section |
| 734 | 735 | { |
| 735 | const header_offset = try reserveVecSectionHeader(bw); | |
| 736 | const header_offset = try reserveVecSectionHeader(w); | |
| 736 | 737 | var exports_len: usize = 0; |
| 737 | 738 | |
| 738 | 739 | for (wasm.function_exports.keys(), wasm.function_exports.values()) |exp_name, function_index| { |
| 739 | 740 | const name = exp_name.slice(wasm); |
| 740 | try bw.writeLeb128(name.len); | |
| 741 | try bw.writeAll(name); | |
| 742 | try bw.writeByte(@intFromEnum(std.wasm.ExternalKind.function)); | |
| 741 | try w.writeLeb128(name.len); | |
| 742 | try w.writeAll(name); | |
| 743 | try w.writeByte(@intFromEnum(std.wasm.ExternalKind.function)); | |
| 743 | 744 | const func_index = Wasm.OutputFunctionIndex.fromFunctionIndex(wasm, function_index); |
| 744 | try bw.writeLeb128(@intFromEnum(func_index)); | |
| 745 | try w.writeLeb128(@intFromEnum(func_index)); | |
| 745 | 746 | } |
| 746 | 747 | exports_len += wasm.function_exports.entries.len; |
| 747 | 748 | |
| 748 | 749 | if (wasm.export_table and f.indirect_function_table.entries.len > 0) { |
| 749 | 750 | const name = "__indirect_function_table"; |
| 750 | 751 | const index: u32 = @intCast(wasm.tables.getIndex(.__indirect_function_table).?); |
| 751 | try bw.writeLeb128(name.len); | |
| 752 | try bw.writeAll(name); | |
| 753 | try bw.writeByte(@intFromEnum(std.wasm.ExternalKind.table)); | |
| 754 | try bw.writeLeb128(index); | |
| 752 | try w.writeLeb128(name.len); | |
| 753 | try w.writeAll(name); | |
| 754 | try w.writeByte(@intFromEnum(std.wasm.ExternalKind.table)); | |
| 755 | try w.writeLeb128(index); | |
| 755 | 756 | exports_len += 1; |
| 756 | 757 | } |
| 757 | 758 | |
| 758 | 759 | if (export_memory) { |
| 759 | 760 | const name = "memory"; |
| 760 | try bw.writeLeb128(name.len); | |
| 761 | try bw.writeAll(name); | |
| 762 | try bw.writeByte(@intFromEnum(std.wasm.ExternalKind.memory)); | |
| 763 | try bw.writeUleb128(0); | |
| 761 | try w.writeLeb128(name.len); | |
| 762 | try w.writeAll(name); | |
| 763 | try w.writeByte(@intFromEnum(std.wasm.ExternalKind.memory)); | |
| 764 | try w.writeUleb128(0); | |
| 764 | 765 | exports_len += 1; |
| 765 | 766 | } |
| 766 | 767 | |
| 767 | 768 | for (wasm.global_exports.items) |exp| { |
| 768 | 769 | const name = exp.name.slice(wasm); |
| 769 | try bw.writeLeb128(name.len); | |
| 770 | try bw.writeAll(name); | |
| 771 | try bw.writeByte(@intFromEnum(std.wasm.ExternalKind.global)); | |
| 772 | try bw.writeLeb128(@intFromEnum(exp.global_index)); | |
| 770 | try w.writeLeb128(name.len); | |
| 771 | try w.writeAll(name); | |
| 772 | try w.writeByte(@intFromEnum(std.wasm.ExternalKind.global)); | |
| 773 | try w.writeLeb128(@intFromEnum(exp.global_index)); | |
| 773 | 774 | } |
| 774 | 775 | exports_len += wasm.global_exports.items.len; |
| 775 | 776 | |
| ... | ... | @@ -790,19 +791,19 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 790 | 791 | |
| 791 | 792 | // element section |
| 792 | 793 | if (f.indirect_function_table.entries.len > 0) { |
| 793 | const header_offset = try reserveVecSectionHeader(bw); | |
| 794 | const header_offset = try reserveVecSectionHeader(w); | |
| 794 | 795 | |
| 795 | 796 | // indirect function table elements |
| 796 | 797 | const table_index: u32 = @intCast(wasm.tables.getIndex(.__indirect_function_table).?); |
| 797 | 798 | // passive with implicit 0-index table or set table index manually |
| 798 | 799 | const flags: u32 = if (table_index == 0) 0x0 else 0x02; |
| 799 | try bw.writeLeb128(flags); | |
| 800 | if (flags == 0x02) try bw.writeLeb128(table_index); | |
| 800 | try w.writeLeb128(flags); | |
| 801 | if (flags == 0x02) try w.writeLeb128(table_index); | |
| 801 | 802 | // We start at index 1, so unresolved function pointers are invalid |
| 802 | try emitInit(bw, .{ .i32_const = 1 }); | |
| 803 | if (flags == 0x02) try bw.writeUleb128(0); // represents funcref | |
| 804 | try bw.writeLeb128(f.indirect_function_table.entries.len); | |
| 805 | for (f.indirect_function_table.keys()) |func_index| try bw.writeLeb128(@intFromEnum(func_index)); | |
| 803 | try emitInit(w, .{ .i32_const = 1 }); | |
| 804 | if (flags == 0x02) try w.writeUleb128(0); // represents funcref | |
| 805 | try w.writeLeb128(f.indirect_function_table.entries.len); | |
| 806 | for (f.indirect_function_table.keys()) |func_index| try w.writeLeb128(@intFromEnum(func_index)); | |
| 806 | 807 | |
| 807 | 808 | replaceVecSectionHeader(&aw, header_offset, .element, 1); |
| 808 | 809 | section_index += 1; |
| ... | ... | @@ -810,42 +811,42 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 810 | 811 | |
| 811 | 812 | // When the shared-memory option is enabled, we *must* emit the 'data count' section. |
| 812 | 813 | if (f.data_segment_groups.items.len > 0) { |
| 813 | const header_offset = try reserveVecSectionHeader(bw); | |
| 814 | const header_offset = try reserveVecSectionHeader(w); | |
| 814 | 815 | replaceVecSectionHeader(&aw, header_offset, .data_count, @intCast(f.data_segment_groups.items.len)); |
| 815 | 816 | } |
| 816 | 817 | |
| 817 | 818 | // Code section. |
| 818 | 819 | if (wasm.functions.count() != 0) { |
| 819 | const header_offset = try reserveVecSectionHeader(bw); | |
| 820 | const header_offset = try reserveVecSectionHeader(w); | |
| 820 | 821 | |
| 821 | 822 | for (wasm.functions.keys()) |resolution| switch (resolution.unpack(wasm)) { |
| 822 | 823 | .unresolved => unreachable, |
| 823 | 824 | .__wasm_apply_global_tls_relocs => @panic("TODO lower __wasm_apply_global_tls_relocs"), |
| 824 | 825 | .__wasm_call_ctors => { |
| 825 | const code_start = try reserveSizeHeader(bw); | |
| 826 | const code_start = try reserveSizeHeader(w); | |
| 826 | 827 | defer replaceSizeHeader(&aw, code_start); |
| 827 | try emitCallCtorsFunction(wasm, bw); | |
| 828 | try emitCallCtorsFunction(wasm, w); | |
| 828 | 829 | }, |
| 829 | 830 | .__wasm_init_memory => { |
| 830 | const code_start = try reserveSizeHeader(bw); | |
| 831 | const code_start = try reserveSizeHeader(w); | |
| 831 | 832 | defer replaceSizeHeader(&aw, code_start); |
| 832 | try emitInitMemoryFunction(wasm, bw, &virtual_addrs); | |
| 833 | try emitInitMemoryFunction(wasm, w, &virtual_addrs); | |
| 833 | 834 | }, |
| 834 | 835 | .__wasm_init_tls => { |
| 835 | const code_start = try reserveSizeHeader(bw); | |
| 836 | const code_start = try reserveSizeHeader(w); | |
| 836 | 837 | defer replaceSizeHeader(&aw, code_start); |
| 837 | try emitInitTlsFunction(wasm, bw); | |
| 838 | try emitInitTlsFunction(wasm, w); | |
| 838 | 839 | }, |
| 839 | 840 | .object_function => |i| { |
| 840 | 841 | const ptr = i.ptr(wasm); |
| 841 | 842 | const code = ptr.code.slice(wasm); |
| 842 | try bw.writeLeb128(code.len); | |
| 843 | const code_start = bw.count; | |
| 844 | try bw.writeAll(code); | |
| 843 | try w.writeLeb128(code.len); | |
| 844 | const code_start = w.count; | |
| 845 | try w.writeAll(code); | |
| 845 | 846 | if (!is_obj) applyRelocs(aw.getWritten()[code_start..], ptr.offset, ptr.relocations(wasm), wasm); |
| 846 | 847 | }, |
| 847 | 848 | .zcu_func => |i| { |
| 848 | const code_start = try reserveSizeHeader(bw); | |
| 849 | const code_start = try reserveSizeHeader(w); | |
| 849 | 850 | defer replaceSizeHeader(&aw, code_start); |
| 850 | 851 | |
| 851 | 852 | log.debug("lowering function code for '{s}'", .{resolution.name(wasm).?}); |
| ... | ... | @@ -855,7 +856,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 855 | 856 | const ip_index = i.key(wasm).*; |
| 856 | 857 | switch (ip.indexToKey(ip_index)) { |
| 857 | 858 | .enum_type => { |
| 858 | try emitTagNameFunction(wasm, bw, f.data_segments.get(.__zig_tag_name_table).?, i.value(wasm).tag_name.table_index, ip_index); | |
| 859 | try emitTagNameFunction(wasm, w, f.data_segments.get(.__zig_tag_name_table).?, i.value(wasm).tag_name.table_index, ip_index); | |
| 859 | 860 | }, |
| 860 | 861 | else => { |
| 861 | 862 | const func = i.value(wasm).function; |
| ... | ... | @@ -870,7 +871,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 870 | 871 | .func_tys = undefined, |
| 871 | 872 | .error_name_table_ref_count = undefined, |
| 872 | 873 | }; |
| 873 | try mir.lower(wasm, bw); | |
| 874 | try mir.lower(wasm, w); | |
| 874 | 875 | }, |
| 875 | 876 | } |
| 876 | 877 | }, |
| ... | ... | @@ -912,7 +913,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 912 | 913 | |
| 913 | 914 | // Data section. |
| 914 | 915 | if (f.data_segment_groups.items.len != 0) { |
| 915 | const header_offset = try reserveVecSectionHeader(bw); | |
| 916 | const header_offset = try reserveVecSectionHeader(w); | |
| 916 | 917 | |
| 917 | 918 | var group_index: u32 = 0; |
| 918 | 919 | var segment_offset: u32 = 0; |
| ... | ... | @@ -920,7 +921,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 920 | 921 | var group_end_addr = f.data_segment_groups.items[group_index].end_addr; |
| 921 | 922 | for (segment_ids, segment_vaddrs) |segment_id, segment_vaddr| { |
| 922 | 923 | if (segment_vaddr >= group_end_addr) { |
| 923 | try bw.splatByteAll(0, group_end_addr - group_start_addr - segment_offset); | |
| 924 | try w.splatByteAll(0, group_end_addr - group_start_addr - segment_offset); | |
| 924 | 925 | group_index += 1; |
| 925 | 926 | if (group_index >= f.data_segment_groups.items.len) { |
| 926 | 927 | // All remaining segments are zero. |
| ... | ... | @@ -934,10 +935,10 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 934 | 935 | const group_size = group_end_addr - group_start_addr; |
| 935 | 936 | log.debug("emit data section group, {d} bytes", .{group_size}); |
| 936 | 937 | const flags: Object.DataSegmentFlags = if (segment_id.isPassive(wasm)) .passive else .active; |
| 937 | try bw.writeLeb128(@intFromEnum(flags)); | |
| 938 | try w.writeLeb128(@intFromEnum(flags)); | |
| 938 | 939 | // Passive segments are initialized at runtime. |
| 939 | if (flags != .passive) try emitInit(bw, .{ .i32_const = @as(i32, @bitCast(group_start_addr)) }); | |
| 940 | try bw.writeLeb128(group_size); | |
| 940 | if (flags != .passive) try emitInit(w, .{ .i32_const = @as(i32, @bitCast(group_start_addr)) }); | |
| 941 | try w.writeLeb128(group_size); | |
| 941 | 942 | } |
| 942 | 943 | if (segment_id.isEmpty(wasm)) { |
| 943 | 944 | // It counted for virtual memory but it does not go into the binary. |
| ... | ... | @@ -946,59 +947,59 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 946 | 947 | |
| 947 | 948 | // Padding for alignment. |
| 948 | 949 | const needed_offset = segment_vaddr - group_start_addr; |
| 949 | try bw.splatByteAll(0, needed_offset - segment_offset); | |
| 950 | try w.splatByteAll(0, needed_offset - segment_offset); | |
| 950 | 951 | segment_offset = needed_offset; |
| 951 | 952 | |
| 952 | const code_start = bw.count; | |
| 953 | const code_start = w.count; | |
| 953 | 954 | append: { |
| 954 | 955 | const code = switch (segment_id.unpack(wasm)) { |
| 955 | 956 | .__heap_base => { |
| 956 | try bw.writeInt(u32, virtual_addrs.heap_base, .little); | |
| 957 | try w.writeInt(u32, virtual_addrs.heap_base, .little); | |
| 957 | 958 | break :append; |
| 958 | 959 | }, |
| 959 | 960 | .__heap_end => { |
| 960 | try bw.writeInt(u32, virtual_addrs.heap_end, .little); | |
| 961 | try w.writeInt(u32, virtual_addrs.heap_end, .little); | |
| 961 | 962 | break :append; |
| 962 | 963 | }, |
| 963 | 964 | .__zig_error_names => { |
| 964 | try bw.writeAll(wasm.error_name_bytes.items); | |
| 965 | try w.writeAll(wasm.error_name_bytes.items); | |
| 965 | 966 | break :append; |
| 966 | 967 | }, |
| 967 | 968 | .__zig_error_name_table => { |
| 968 | 969 | if (is_obj) @panic("TODO error name table reloc"); |
| 969 | 970 | const base = f.data_segments.get(.__zig_error_names).?; |
| 970 | 971 | if (!is64) { |
| 971 | try emitTagNameTable(bw, wasm.error_name_offs.items, wasm.error_name_bytes.items, base, u32); | |
| 972 | try emitTagNameTable(w, wasm.error_name_offs.items, wasm.error_name_bytes.items, base, u32); | |
| 972 | 973 | } else { |
| 973 | try emitTagNameTable(bw, wasm.error_name_offs.items, wasm.error_name_bytes.items, base, u64); | |
| 974 | try emitTagNameTable(w, wasm.error_name_offs.items, wasm.error_name_bytes.items, base, u64); | |
| 974 | 975 | } |
| 975 | 976 | break :append; |
| 976 | 977 | }, |
| 977 | 978 | .__zig_tag_names => { |
| 978 | try bw.writeAll(wasm.tag_name_bytes.items); | |
| 979 | try w.writeAll(wasm.tag_name_bytes.items); | |
| 979 | 980 | break :append; |
| 980 | 981 | }, |
| 981 | 982 | .__zig_tag_name_table => { |
| 982 | 983 | if (is_obj) @panic("TODO tag name table reloc"); |
| 983 | 984 | const base = f.data_segments.get(.__zig_tag_names).?; |
| 984 | 985 | if (!is64) { |
| 985 | try emitTagNameTable(bw, wasm.tag_name_offs.items, wasm.tag_name_bytes.items, base, u32); | |
| 986 | try emitTagNameTable(w, wasm.tag_name_offs.items, wasm.tag_name_bytes.items, base, u32); | |
| 986 | 987 | } else { |
| 987 | try emitTagNameTable(bw, wasm.tag_name_offs.items, wasm.tag_name_bytes.items, base, u64); | |
| 988 | try emitTagNameTable(w, wasm.tag_name_offs.items, wasm.tag_name_bytes.items, base, u64); | |
| 988 | 989 | } |
| 989 | 990 | break :append; |
| 990 | 991 | }, |
| 991 | 992 | .object => |i| { |
| 992 | 993 | const ptr = i.ptr(wasm); |
| 993 | try bw.writeAll(ptr.payload.slice(wasm)); | |
| 994 | try w.writeAll(ptr.payload.slice(wasm)); | |
| 994 | 995 | if (!is_obj) applyRelocs(aw.getWritten()[code_start..], ptr.offset, ptr.relocations(wasm), wasm); |
| 995 | 996 | break :append; |
| 996 | 997 | }, |
| 997 | 998 | inline .uav_exe, .uav_obj, .nav_exe, .nav_obj => |i| i.value(wasm).code, |
| 998 | 999 | }; |
| 999 | try bw.writeAll(code.slice(wasm)); | |
| 1000 | try w.writeAll(code.slice(wasm)); | |
| 1000 | 1001 | } |
| 1001 | segment_offset += @intCast(bw.count - code_start); | |
| 1002 | segment_offset += @intCast(w.count - code_start); | |
| 1002 | 1003 | } |
| 1003 | 1004 | |
| 1004 | 1005 | replaceVecSectionHeader(&aw, header_offset, .data, @intCast(f.data_segment_groups.items.len)); |
| ... | ... | @@ -1019,7 +1020,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 1019 | 1020 | .none => {}, |
| 1020 | 1021 | .fast => { |
| 1021 | 1022 | var id: [16]u8 = undefined; |
| 1022 | std.crypto.hash.sha3.TurboShake128(null).hash(bw.getWritten(), &id, .{}); | |
| 1023 | std.crypto.hash.sha3.TurboShake128(null).hash(w.getWritten(), &id, .{}); | |
| 1023 | 1024 | var uuid: [36]u8 = undefined; |
| 1024 | 1025 | _ = try std.fmt.bufPrint(&uuid, "{x}-{x}-{x}-{x}-{x}", .{ |
| 1025 | 1026 | id[0..4], id[4..6], id[6..8], id[8..10], id[10..], |
| ... | ... | @@ -1067,62 +1068,62 @@ fn emitNameSection( |
| 1067 | 1068 | data_segment_groups: []const DataSegmentGroup, |
| 1068 | 1069 | ) !void { |
| 1069 | 1070 | const f = &wasm.flush_buffer; |
| 1070 | const bw = &aw.buffered_writer; | |
| 1071 | const header_offset = try reserveSectionHeader(bw); | |
| 1071 | const w = &aw.interface; | |
| 1072 | const header_offset = try reserveSectionHeader(w); | |
| 1072 | 1073 | defer replaceSectionHeader(aw, header_offset, @intFromEnum(std.wasm.Section.custom)); |
| 1073 | 1074 | |
| 1074 | 1075 | const section_name = "name"; |
| 1075 | try bw.writeLeb128(section_name.len); | |
| 1076 | try bw.writeAll(section_name); | |
| 1076 | try w.writeLeb128(section_name.len); | |
| 1077 | try w.writeAll(section_name); | |
| 1077 | 1078 | |
| 1078 | 1079 | { |
| 1079 | const sub_header_offset = try reserveSectionHeader(bw); | |
| 1080 | const sub_header_offset = try reserveSectionHeader(w); | |
| 1080 | 1081 | defer replaceSectionHeader(aw, sub_header_offset, @intFromEnum(std.wasm.NameSubsection.function)); |
| 1081 | 1082 | |
| 1082 | try bw.writeLeb128(f.function_imports.entries.len + wasm.functions.entries.len); | |
| 1083 | try w.writeLeb128(f.function_imports.entries.len + wasm.functions.entries.len); | |
| 1083 | 1084 | for (f.function_imports.keys(), 0..) |name_index, function_index| { |
| 1084 | 1085 | const name = name_index.slice(wasm); |
| 1085 | try bw.writeLeb128(function_index); | |
| 1086 | try bw.writeLeb128(name.len); | |
| 1087 | try bw.writeAll(name); | |
| 1086 | try w.writeLeb128(function_index); | |
| 1087 | try w.writeLeb128(name.len); | |
| 1088 | try w.writeAll(name); | |
| 1088 | 1089 | } |
| 1089 | 1090 | for (wasm.functions.keys(), f.function_imports.entries.len..) |resolution, function_index| { |
| 1090 | 1091 | const name = resolution.name(wasm).?; |
| 1091 | try bw.writeLeb128(function_index); | |
| 1092 | try bw.writeLeb128(name.len); | |
| 1093 | try bw.writeAll(name); | |
| 1092 | try w.writeLeb128(function_index); | |
| 1093 | try w.writeLeb128(name.len); | |
| 1094 | try w.writeAll(name); | |
| 1094 | 1095 | } |
| 1095 | 1096 | } |
| 1096 | 1097 | |
| 1097 | 1098 | { |
| 1098 | const sub_header_offset = try reserveSectionHeader(bw); | |
| 1099 | const sub_header_offset = try reserveSectionHeader(w); | |
| 1099 | 1100 | defer replaceSectionHeader(aw, sub_header_offset, @intFromEnum(std.wasm.NameSubsection.global)); |
| 1100 | 1101 | |
| 1101 | try bw.writeLeb128(f.global_imports.entries.len + wasm.globals.entries.len); | |
| 1102 | try w.writeLeb128(f.global_imports.entries.len + wasm.globals.entries.len); | |
| 1102 | 1103 | for (f.global_imports.keys(), 0..) |name_index, global_index| { |
| 1103 | 1104 | const name = name_index.slice(wasm); |
| 1104 | try bw.writeLeb128(global_index); | |
| 1105 | try bw.writeLeb128(name.len); | |
| 1106 | try bw.writeAll(name); | |
| 1105 | try w.writeLeb128(global_index); | |
| 1106 | try w.writeLeb128(name.len); | |
| 1107 | try w.writeAll(name); | |
| 1107 | 1108 | } |
| 1108 | 1109 | for (wasm.globals.keys(), f.global_imports.entries.len..) |resolution, global_index| { |
| 1109 | 1110 | const name = resolution.name(wasm).?; |
| 1110 | try bw.writeLeb128(global_index); | |
| 1111 | try bw.writeLeb128(name.len); | |
| 1112 | try bw.writeAll(name); | |
| 1111 | try w.writeLeb128(global_index); | |
| 1112 | try w.writeLeb128(name.len); | |
| 1113 | try w.writeAll(name); | |
| 1113 | 1114 | } |
| 1114 | 1115 | } |
| 1115 | 1116 | |
| 1116 | 1117 | { |
| 1117 | const sub_header_offset = try reserveSectionHeader(bw); | |
| 1118 | const sub_header_offset = try reserveSectionHeader(w); | |
| 1118 | 1119 | defer replaceSectionHeader(aw, sub_header_offset, @intFromEnum(std.wasm.NameSubsection.data_segment)); |
| 1119 | 1120 | |
| 1120 | try bw.writeLeb128(data_segment_groups.len); | |
| 1121 | try w.writeLeb128(data_segment_groups.len); | |
| 1121 | 1122 | for (data_segment_groups, 0..) |group, group_index| { |
| 1122 | 1123 | const name, _ = splitSegmentName(group.first_segment.name(wasm)); |
| 1123 | try bw.writeLeb128(group_index); | |
| 1124 | try bw.writeLeb128(name.len); | |
| 1125 | try bw.writeAll(name); | |
| 1124 | try w.writeLeb128(group_index); | |
| 1125 | try w.writeLeb128(name.len); | |
| 1126 | try w.writeAll(name); | |
| 1126 | 1127 | } |
| 1127 | 1128 | } |
| 1128 | 1129 | } |
| ... | ... | @@ -1131,87 +1132,87 @@ fn emitFeaturesSection(aw: *std.io.AllocatingWriter, target: *const std.Target) |
| 1131 | 1132 | const feature_count = target.cpu.features.count(); |
| 1132 | 1133 | if (feature_count == 0) return; |
| 1133 | 1134 | |
| 1134 | const bw = &aw.buffered_writer; | |
| 1135 | const header_offset = try reserveSectionHeader(bw); | |
| 1135 | const w = &aw.interface; | |
| 1136 | const header_offset = try reserveSectionHeader(w); | |
| 1136 | 1137 | defer replaceSectionHeader(aw, header_offset, @intFromEnum(std.wasm.Section.custom)); |
| 1137 | 1138 | |
| 1138 | 1139 | const section_name = "target_features"; |
| 1139 | try bw.writeLeb128(section_name.len); | |
| 1140 | try bw.writeAll(section_name); | |
| 1140 | try w.writeLeb128(section_name.len); | |
| 1141 | try w.writeAll(section_name); | |
| 1141 | 1142 | |
| 1142 | try bw.writeLeb128(feature_count); | |
| 1143 | try w.writeLeb128(feature_count); | |
| 1143 | 1144 | var safety_count = feature_count; |
| 1144 | 1145 | for (target.cpu.arch.allFeaturesList(), 0..) |*feature, i| { |
| 1145 | 1146 | if (!target.cpu.has(.wasm, @as(std.Target.wasm.Feature, @enumFromInt(i)))) continue; |
| 1146 | 1147 | safety_count -= 1; |
| 1147 | 1148 | |
| 1148 | try bw.writeUleb128('+'); | |
| 1149 | try w.writeUleb128('+'); | |
| 1149 | 1150 | // Depends on llvm_name for the hyphenated version that matches wasm tooling conventions. |
| 1150 | 1151 | const name = feature.llvm_name.?; |
| 1151 | try bw.writeLeb128(name.len); | |
| 1152 | try bw.writeAll(name); | |
| 1152 | try w.writeLeb128(name.len); | |
| 1153 | try w.writeAll(name); | |
| 1153 | 1154 | } |
| 1154 | 1155 | assert(safety_count == 0); |
| 1155 | 1156 | } |
| 1156 | 1157 | |
| 1157 | 1158 | fn emitBuildIdSection(aw: *std.io.AllocatingWriter, build_id: []const u8) !void { |
| 1158 | const bw = &aw.buffered_writer; | |
| 1159 | const header_offset = try reserveSectionHeader(bw); | |
| 1159 | const w = &aw.interface; | |
| 1160 | const header_offset = try reserveSectionHeader(w); | |
| 1160 | 1161 | defer replaceSectionHeader(aw, header_offset, @intFromEnum(std.wasm.Section.custom)); |
| 1161 | 1162 | |
| 1162 | 1163 | const section_name = "build_id"; |
| 1163 | try bw.writeLeb128(section_name.len); | |
| 1164 | try bw.writeAll(section_name); | |
| 1164 | try w.writeLeb128(section_name.len); | |
| 1165 | try w.writeAll(section_name); | |
| 1165 | 1166 | |
| 1166 | try bw.writeUleb128(1); | |
| 1167 | try bw.writeLeb128(build_id.len); | |
| 1168 | try bw.writeAll(build_id); | |
| 1167 | try w.writeUleb128(1); | |
| 1168 | try w.writeLeb128(build_id.len); | |
| 1169 | try w.writeAll(build_id); | |
| 1169 | 1170 | } |
| 1170 | 1171 | |
| 1171 | 1172 | fn emitProducerSection(aw: *std.io.AllocatingWriter) !void { |
| 1172 | const bw = &aw.buffered_writer; | |
| 1173 | const header_offset = try reserveSectionHeader(bw); | |
| 1173 | const w = &aw.interface; | |
| 1174 | const header_offset = try reserveSectionHeader(w); | |
| 1174 | 1175 | defer replaceSectionHeader(aw, header_offset, @intFromEnum(std.wasm.Section.custom)); |
| 1175 | 1176 | |
| 1176 | 1177 | const section_name = "producers"; |
| 1177 | try bw.writeLeb128(section_name.len); | |
| 1178 | try bw.writeAll(section_name); | |
| 1178 | try w.writeLeb128(section_name.len); | |
| 1179 | try w.writeAll(section_name); | |
| 1179 | 1180 | |
| 1180 | try bw.writeUleb128(2); // 2 fields: language + processed-by | |
| 1181 | try w.writeUleb128(2); // 2 fields: language + processed-by | |
| 1181 | 1182 | { |
| 1182 | 1183 | const field_name = "language"; |
| 1183 | try bw.writeLeb128(field_name.len); | |
| 1184 | try bw.writeAll(field_name); | |
| 1184 | try w.writeLeb128(field_name.len); | |
| 1185 | try w.writeAll(field_name); | |
| 1185 | 1186 | |
| 1186 | 1187 | // field_value_count (TODO: Parse object files for producer sections to detect their language) |
| 1187 | try bw.writeUleb128(1); | |
| 1188 | try w.writeUleb128(1); | |
| 1188 | 1189 | |
| 1189 | 1190 | // versioned name |
| 1190 | 1191 | { |
| 1191 | 1192 | const field_value = "Zig"; |
| 1192 | try bw.writeLeb128(field_value.len); | |
| 1193 | try bw.writeAll(field_value); | |
| 1193 | try w.writeLeb128(field_value.len); | |
| 1194 | try w.writeAll(field_value); | |
| 1194 | 1195 | |
| 1195 | try bw.writeLeb128(build_options.version.len); | |
| 1196 | try bw.writeAll(build_options.version); | |
| 1196 | try w.writeLeb128(build_options.version.len); | |
| 1197 | try w.writeAll(build_options.version); | |
| 1197 | 1198 | } |
| 1198 | 1199 | } |
| 1199 | 1200 | { |
| 1200 | 1201 | const field_name = "processed-by"; |
| 1201 | try bw.writeLeb128(field_name.len); | |
| 1202 | try bw.writeAll(field_name); | |
| 1202 | try w.writeLeb128(field_name.len); | |
| 1203 | try w.writeAll(field_name); | |
| 1203 | 1204 | |
| 1204 | 1205 | // field_value_count (TODO: Parse object files for producer sections to detect other used tools) |
| 1205 | try bw.writeUleb128(1); | |
| 1206 | try w.writeUleb128(1); | |
| 1206 | 1207 | |
| 1207 | 1208 | // versioned name |
| 1208 | 1209 | { |
| 1209 | 1210 | const field_value = "Zig"; |
| 1210 | try bw.writeLeb128(field_value.len); | |
| 1211 | try bw.writeAll(field_value); | |
| 1211 | try w.writeLeb128(field_value.len); | |
| 1212 | try w.writeAll(field_value); | |
| 1212 | 1213 | |
| 1213 | try bw.writeLeb128(build_options.version.len); | |
| 1214 | try bw.writeAll(build_options.version); | |
| 1214 | try w.writeLeb128(build_options.version.len); | |
| 1215 | try w.writeAll(build_options.version); | |
| 1215 | 1216 | } |
| 1216 | 1217 | } |
| 1217 | 1218 | } |
| ... | ... | @@ -1251,9 +1252,9 @@ fn wantSegmentMerge( |
| 1251 | 1252 | /// section id + fixed leb contents size + fixed leb vector length |
| 1252 | 1253 | const vec_section_header_size = section_header_size + size_header_size; |
| 1253 | 1254 | |
| 1254 | fn reserveVecSectionHeader(bw: *std.io.BufferedWriter) std.io.Writer.Error!u32 { | |
| 1255 | const offset = bw.count; | |
| 1256 | _ = try bw.writableSlice(vec_section_header_size); | |
| 1255 | fn reserveVecSectionHeader(w: *Writer) Writer.Error!u32 { | |
| 1256 | const offset = w.count; | |
| 1257 | _ = try w.writableSlice(vec_section_header_size); | |
| 1257 | 1258 | return @intCast(offset); |
| 1258 | 1259 | } |
| 1259 | 1260 | |
| ... | ... | @@ -1265,68 +1266,68 @@ fn replaceVecSectionHeader( |
| 1265 | 1266 | ) void { |
| 1266 | 1267 | const header = aw.getWritten()[offset..][0..vec_section_header_size]; |
| 1267 | 1268 | header[0] = @intFromEnum(section); |
| 1268 | std.leb.writeUnsignedFixed(5, header[1..6], @intCast(aw.buffered_writer.count - offset - section_header_size)); | |
| 1269 | std.leb.writeUnsignedFixed(5, header[1..6], @intCast(aw.interface.count - offset - section_header_size)); | |
| 1269 | 1270 | std.leb.writeUnsignedFixed(5, header[6..], n_items); |
| 1270 | 1271 | } |
| 1271 | 1272 | |
| 1272 | 1273 | const section_header_size = 1 + size_header_size; |
| 1273 | 1274 | |
| 1274 | fn reserveSectionHeader(bw: *std.io.BufferedWriter) std.io.Writer.Error!u32 { | |
| 1275 | const offset = bw.count; | |
| 1276 | _ = try bw.writableSlice(section_header_size); | |
| 1275 | fn reserveSectionHeader(w: *Writer) Writer.Error!u32 { | |
| 1276 | const offset = w.count; | |
| 1277 | _ = try w.writableSlice(section_header_size); | |
| 1277 | 1278 | return @intCast(offset); |
| 1278 | 1279 | } |
| 1279 | 1280 | |
| 1280 | 1281 | fn replaceSectionHeader(aw: *std.io.AllocatingWriter, offset: u32, section: u8) void { |
| 1281 | 1282 | const header = aw.getWritten()[offset..][0..section_header_size]; |
| 1282 | 1283 | header[0] = section; |
| 1283 | std.leb.writeUnsignedFixed(5, header[1..6], @intCast(aw.buffered_writer.count - offset - section_header_size)); | |
| 1284 | std.leb.writeUnsignedFixed(5, header[1..6], @intCast(aw.interface.count - offset - section_header_size)); | |
| 1284 | 1285 | } |
| 1285 | 1286 | |
| 1286 | 1287 | const size_header_size = 5; |
| 1287 | 1288 | |
| 1288 | fn reserveSizeHeader(bw: *std.io.BufferedWriter) std.io.Writer.Error!u32 { | |
| 1289 | const offset = bw.count; | |
| 1290 | _ = try bw.writableSlice(size_header_size); | |
| 1289 | fn reserveSizeHeader(w: *Writer) Writer.Error!u32 { | |
| 1290 | const offset = w.count; | |
| 1291 | _ = try w.writableSlice(size_header_size); | |
| 1291 | 1292 | return @intCast(offset); |
| 1292 | 1293 | } |
| 1293 | 1294 | |
| 1294 | 1295 | fn replaceSizeHeader(aw: *std.io.AllocatingWriter, offset: u32) void { |
| 1295 | 1296 | const header = aw.getWritten()[offset..][0..size_header_size]; |
| 1296 | std.leb.writeUnsignedFixed(5, header[0..5], @intCast(aw.buffered_writer.count - offset - size_header_size)); | |
| 1297 | std.leb.writeUnsignedFixed(5, header[0..5], @intCast(aw.interface.count - offset - size_header_size)); | |
| 1297 | 1298 | } |
| 1298 | 1299 | |
| 1299 | fn emitLimits(bw: *std.io.BufferedWriter, limits: std.wasm.Limits) std.io.Writer.Error!void { | |
| 1300 | try bw.writeByte(@bitCast(limits.flags)); | |
| 1301 | try bw.writeLeb128(limits.min); | |
| 1302 | if (limits.flags.has_max) try bw.writeLeb128(limits.max); | |
| 1300 | fn emitLimits(w: *Writer, limits: std.wasm.Limits) Writer.Error!void { | |
| 1301 | try w.writeByte(@bitCast(limits.flags)); | |
| 1302 | try w.writeLeb128(limits.min); | |
| 1303 | if (limits.flags.has_max) try w.writeLeb128(limits.max); | |
| 1303 | 1304 | } |
| 1304 | 1305 | |
| 1305 | 1306 | fn emitMemoryImport( |
| 1306 | 1307 | wasm: *Wasm, |
| 1307 | bw: *std.io.BufferedWriter, | |
| 1308 | w: *Writer, | |
| 1308 | 1309 | name_index: String, |
| 1309 | 1310 | memory_import: *const Wasm.MemoryImport, |
| 1310 | ) std.io.Writer.Error!void { | |
| 1311 | ) Writer.Error!void { | |
| 1311 | 1312 | const module_name = memory_import.module_name.slice(wasm); |
| 1312 | try bw.writeLeb128(module_name.len); | |
| 1313 | try bw.writeAll(module_name); | |
| 1313 | try w.writeLeb128(module_name.len); | |
| 1314 | try w.writeAll(module_name); | |
| 1314 | 1315 | |
| 1315 | 1316 | const name = name_index.slice(wasm); |
| 1316 | try bw.writeLeb128(name.len); | |
| 1317 | try bw.writeAll(name); | |
| 1317 | try w.writeLeb128(name.len); | |
| 1318 | try w.writeAll(name); | |
| 1318 | 1319 | |
| 1319 | try bw.writeByte(@intFromEnum(std.wasm.ExternalKind.memory)); | |
| 1320 | try emitLimits(bw, memory_import.limits()); | |
| 1320 | try w.writeByte(@intFromEnum(std.wasm.ExternalKind.memory)); | |
| 1321 | try emitLimits(w, memory_import.limits()); | |
| 1321 | 1322 | } |
| 1322 | 1323 | |
| 1323 | pub fn emitInit(bw: *std.io.BufferedWriter, init_expr: std.wasm.InitExpression) std.io.Writer.Error!void { | |
| 1324 | pub fn emitInit(w: *Writer, init_expr: std.wasm.InitExpression) Writer.Error!void { | |
| 1324 | 1325 | switch (init_expr) { |
| 1325 | 1326 | inline else => |val, tag| { |
| 1326 | try bw.writeByte(@intFromEnum(@field(std.wasm.Opcode, @tagName(tag)))); | |
| 1327 | try w.writeByte(@intFromEnum(@field(std.wasm.Opcode, @tagName(tag)))); | |
| 1327 | 1328 | switch (@typeInfo(@TypeOf(val))) { |
| 1328 | .int => try bw.writeLeb128(val), | |
| 1329 | .float => |float| try bw.writeInt( | |
| 1329 | .int => try w.writeLeb128(val), | |
| 1330 | .float => |float| try w.writeInt( | |
| 1330 | 1331 | @Type(.{ .int = .{ .signedness = .unsigned, .bits = float.bits } }), |
| 1331 | 1332 | @bitCast(val), |
| 1332 | 1333 | .little, |
| ... | ... | @@ -1335,44 +1336,44 @@ pub fn emitInit(bw: *std.io.BufferedWriter, init_expr: std.wasm.InitExpression) |
| 1335 | 1336 | } |
| 1336 | 1337 | }, |
| 1337 | 1338 | } |
| 1338 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.end)); | |
| 1339 | try w.writeByte(@intFromEnum(std.wasm.Opcode.end)); | |
| 1339 | 1340 | } |
| 1340 | 1341 | |
| 1341 | pub fn emitExpr(wasm: *const Wasm, bw: *std.io.BufferedWriter, expr: Wasm.Expr) std.io.Writer.Error!void { | |
| 1342 | pub fn emitExpr(wasm: *const Wasm, w: *Writer, expr: Wasm.Expr) Writer.Error!void { | |
| 1342 | 1343 | const slice = expr.slice(wasm); |
| 1343 | try bw.writeAll(slice[0 .. slice.len + 1]); // +1 to include end opcode | |
| 1344 | try w.writeAll(slice[0 .. slice.len + 1]); // +1 to include end opcode | |
| 1344 | 1345 | } |
| 1345 | 1346 | |
| 1346 | fn emitSegmentInfo(wasm: *Wasm, aw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 1347 | const bw = &aw.buffered_writer; | |
| 1348 | const header_offset = try reserveSectionHeader(bw); | |
| 1347 | fn emitSegmentInfo(wasm: *Wasm, aw: *Writer) Writer.Error!void { | |
| 1348 | const w = &aw.interface; | |
| 1349 | const header_offset = try reserveSectionHeader(w); | |
| 1349 | 1350 | defer replaceSectionHeader(aw, header_offset, @intFromEnum(Wasm.SubsectionType.segment_info)); |
| 1350 | 1351 | |
| 1351 | try bw.writeLeb128(wasm.segment_info.count()); | |
| 1352 | try w.writeLeb128(wasm.segment_info.count()); | |
| 1352 | 1353 | for (wasm.segment_info.values()) |segment_info| { |
| 1353 | 1354 | log.debug("Emit segment: {s} align({d}) flags({b})", .{ |
| 1354 | 1355 | segment_info.name, |
| 1355 | 1356 | segment_info.alignment, |
| 1356 | 1357 | segment_info.flags, |
| 1357 | 1358 | }); |
| 1358 | try bw.writeLeb128(segment_info.name.len); | |
| 1359 | try bw.writeAll(segment_info.name); | |
| 1360 | try bw.writeLeb128(segment_info.alignment.toLog2Units()); | |
| 1361 | try bw.writeLeb128(segment_info.flags); | |
| 1359 | try w.writeLeb128(segment_info.name.len); | |
| 1360 | try w.writeAll(segment_info.name); | |
| 1361 | try w.writeLeb128(segment_info.alignment.toLog2Units()); | |
| 1362 | try w.writeLeb128(segment_info.flags); | |
| 1362 | 1363 | } |
| 1363 | 1364 | } |
| 1364 | 1365 | |
| 1365 | 1366 | fn emitTagNameTable( |
| 1366 | bw: *std.io.BufferedWriter, | |
| 1367 | w: *Writer, | |
| 1367 | 1368 | tag_name_offs: []const u32, |
| 1368 | 1369 | tag_name_bytes: []const u8, |
| 1369 | 1370 | base: u32, |
| 1370 | 1371 | comptime Int: type, |
| 1371 | ) std.io.Writer.Error!void { | |
| 1372 | ) Writer.Error!void { | |
| 1372 | 1373 | for (tag_name_offs) |off| { |
| 1373 | 1374 | const name_len: u32 = @intCast(mem.indexOfScalar(u8, tag_name_bytes[off..], 0).?); |
| 1374 | try bw.writeInt(Int, base + off, .little); | |
| 1375 | try bw.writeInt(Int, name_len, .little); | |
| 1375 | try w.writeInt(Int, base + off, .little); | |
| 1376 | try w.writeInt(Int, name_len, .little); | |
| 1376 | 1377 | } |
| 1377 | 1378 | } |
| 1378 | 1379 | |
| ... | ... | @@ -1536,8 +1537,8 @@ fn reloc_leb_type(code: []u8, index: FuncTypeIndex) void { |
| 1536 | 1537 | std.leb.writeUnsignedFixed(5, code[0..5], @intFromEnum(index)); |
| 1537 | 1538 | } |
| 1538 | 1539 | |
| 1539 | fn emitCallCtorsFunction(wasm: *const Wasm, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 1540 | try bw.writeUleb128(0); // no locals | |
| 1540 | fn emitCallCtorsFunction(wasm: *const Wasm, w: *Writer) Writer.Error!void { | |
| 1541 | try w.writeUleb128(0); // no locals | |
| 1541 | 1542 | for (wasm.object_init_funcs.items) |init_func| { |
| 1542 | 1543 | const func = init_func.function_index.ptr(wasm); |
| 1543 | 1544 | if (!func.object_index.ptr(wasm).is_included) continue; |
| ... | ... | @@ -1546,16 +1547,16 @@ fn emitCallCtorsFunction(wasm: *const Wasm, bw: *std.io.BufferedWriter) std.io.W |
| 1546 | 1547 | |
| 1547 | 1548 | // Call function by its function index |
| 1548 | 1549 | const call_index: Wasm.OutputFunctionIndex = .fromObjectFunction(wasm, init_func.function_index); |
| 1549 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.call)); | |
| 1550 | try bw.writeLeb128(@intFromEnum(call_index)); | |
| 1550 | try w.writeByte(@intFromEnum(std.wasm.Opcode.call)); | |
| 1551 | try w.writeLeb128(@intFromEnum(call_index)); | |
| 1551 | 1552 | |
| 1552 | 1553 | // drop all returned values from the stack as __wasm_call_ctors has no return value |
| 1553 | try bw.splatByteAll(@intFromEnum(std.wasm.Opcode.drop), n_returns); | |
| 1554 | try w.splatByteAll(@intFromEnum(std.wasm.Opcode.drop), n_returns); | |
| 1554 | 1555 | } |
| 1555 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.end)); // end function body | |
| 1556 | try w.writeByte(@intFromEnum(std.wasm.Opcode.end)); // end function body | |
| 1556 | 1557 | } |
| 1557 | 1558 | |
| 1558 | fn emitInitMemoryFunction(wasm: *const Wasm, bw: *std.io.BufferedWriter, virtual_addrs: *const VirtualAddrs) std.io.Writer.Error!void { | |
| 1559 | fn emitInitMemoryFunction(wasm: *const Wasm, w: *Writer, virtual_addrs: *const VirtualAddrs) Writer.Error!void { | |
| 1559 | 1560 | const comp = wasm.base.comp; |
| 1560 | 1561 | const shared_memory = comp.config.shared_memory; |
| 1561 | 1562 | |
| ... | ... | @@ -1566,13 +1567,13 @@ fn emitInitMemoryFunction(wasm: *const Wasm, bw: *std.io.BufferedWriter, virtual |
| 1566 | 1567 | // function. |
| 1567 | 1568 | assert(wasm.any_passive_inits); |
| 1568 | 1569 | |
| 1569 | try bw.writeUleb128(0); // no locals | |
| 1570 | try w.writeUleb128(0); // no locals | |
| 1570 | 1571 | |
| 1571 | 1572 | if (virtual_addrs.init_memory_flag) |flag_address| { |
| 1572 | 1573 | assert(shared_memory); |
| 1573 | 1574 | // destination blocks |
| 1574 | 1575 | // based on values we jump to corresponding label |
| 1575 | try bw.writeAll(&.{ | |
| 1576 | try w.writeAll(&.{ | |
| 1576 | 1577 | @intFromEnum(std.wasm.Opcode.block), // $drop |
| 1577 | 1578 | @intFromEnum(std.wasm.BlockType.empty), |
| 1578 | 1579 | @intFromEnum(std.wasm.Opcode.block), // $wait |
| ... | ... | @@ -1582,24 +1583,24 @@ fn emitInitMemoryFunction(wasm: *const Wasm, bw: *std.io.BufferedWriter, virtual |
| 1582 | 1583 | }); |
| 1583 | 1584 | |
| 1584 | 1585 | // atomically check |
| 1585 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1586 | try bw.writeLeb128(@as(i32, @bitCast(flag_address))); | |
| 1587 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1588 | try bw.writeSleb128(0); | |
| 1589 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1590 | try bw.writeSleb128(1); | |
| 1591 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.atomics_prefix)); | |
| 1592 | try bw.writeLeb128(@intFromEnum(std.wasm.AtomicsOpcode.i32_atomic_rmw_cmpxchg)); | |
| 1593 | try bw.writeLeb128(comptime Alignment.@"4".toLog2Units()); | |
| 1594 | try bw.writeUleb128(0); // offset | |
| 1586 | try w.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1587 | try w.writeLeb128(@as(i32, @bitCast(flag_address))); | |
| 1588 | try w.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1589 | try w.writeSleb128(0); | |
| 1590 | try w.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1591 | try w.writeSleb128(1); | |
| 1592 | try w.writeByte(@intFromEnum(std.wasm.Opcode.atomics_prefix)); | |
| 1593 | try w.writeLeb128(@intFromEnum(std.wasm.AtomicsOpcode.i32_atomic_rmw_cmpxchg)); | |
| 1594 | try w.writeLeb128(comptime Alignment.@"4".toLog2Units()); | |
| 1595 | try w.writeUleb128(0); // offset | |
| 1595 | 1596 | |
| 1596 | 1597 | // based on the value from the atomic check, jump to the label. |
| 1597 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.br_table)); | |
| 1598 | try bw.writeUleb128(3 - 1); // length of the table (we have 3 blocks but because of the mandatory default the length is 2). | |
| 1599 | try bw.writeUleb128(0); // $init | |
| 1600 | try bw.writeUleb128(1); // $wait | |
| 1601 | try bw.writeUleb128(2); // $drop | |
| 1602 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.end)); | |
| 1598 | try w.writeByte(@intFromEnum(std.wasm.Opcode.br_table)); | |
| 1599 | try w.writeUleb128(3 - 1); // length of the table (we have 3 blocks but because of the mandatory default the length is 2). | |
| 1600 | try w.writeUleb128(0); // $init | |
| 1601 | try w.writeUleb128(1); // $wait | |
| 1602 | try w.writeUleb128(2); // $drop | |
| 1603 | try w.writeByte(@intFromEnum(std.wasm.Opcode.end)); | |
| 1603 | 1604 | } |
| 1604 | 1605 | |
| 1605 | 1606 | const segment_groups = wasm.flush_buffer.data_segment_groups.items; |
| ... | ... | @@ -1615,79 +1616,79 @@ fn emitInitMemoryFunction(wasm: *const Wasm, bw: *std.io.BufferedWriter, virtual |
| 1615 | 1616 | // For passive BSS segments we can simply issue a memory.fill(0). For |
| 1616 | 1617 | // non-BSS segments we do a memory.init. Both instructions take as |
| 1617 | 1618 | // their first argument the destination address. |
| 1618 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1619 | try bw.writeLeb128(@as(i32, @bitCast(start_addr))); | |
| 1619 | try w.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1620 | try w.writeLeb128(@as(i32, @bitCast(start_addr))); | |
| 1620 | 1621 | |
| 1621 | 1622 | if (shared_memory and segment.isTls(wasm)) { |
| 1622 | 1623 | // When we initialize the TLS segment we also set the `__tls_base` |
| 1623 | 1624 | // global. This allows the runtime to use this static copy of the |
| 1624 | 1625 | // TLS data for the first/main thread. |
| 1625 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1626 | try bw.writeLeb128(@as(i32, @bitCast(start_addr))); | |
| 1627 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.global_set)); | |
| 1628 | try bw.writeLeb128(virtual_addrs.tls_base.?); | |
| 1626 | try w.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1627 | try w.writeLeb128(@as(i32, @bitCast(start_addr))); | |
| 1628 | try w.writeByte(@intFromEnum(std.wasm.Opcode.global_set)); | |
| 1629 | try w.writeLeb128(virtual_addrs.tls_base.?); | |
| 1629 | 1630 | } |
| 1630 | 1631 | |
| 1631 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1632 | try bw.writeSleb128(0); | |
| 1633 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1634 | try bw.writeLeb128(@as(i32, @bitCast(segment_size))); | |
| 1635 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.misc_prefix)); | |
| 1632 | try w.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1633 | try w.writeSleb128(0); | |
| 1634 | try w.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1635 | try w.writeLeb128(@as(i32, @bitCast(segment_size))); | |
| 1636 | try w.writeByte(@intFromEnum(std.wasm.Opcode.misc_prefix)); | |
| 1636 | 1637 | if (segment.isBss(wasm)) { |
| 1637 | 1638 | // fill bss segment with zeroes |
| 1638 | try bw.writeLeb128(@intFromEnum(std.wasm.MiscOpcode.memory_fill)); | |
| 1639 | try w.writeLeb128(@intFromEnum(std.wasm.MiscOpcode.memory_fill)); | |
| 1639 | 1640 | } else { |
| 1640 | 1641 | // initialize the segment |
| 1641 | try bw.writeLeb128(@intFromEnum(std.wasm.MiscOpcode.memory_init)); | |
| 1642 | try bw.writeLeb128(segment_index); | |
| 1642 | try w.writeLeb128(@intFromEnum(std.wasm.MiscOpcode.memory_init)); | |
| 1643 | try w.writeLeb128(segment_index); | |
| 1643 | 1644 | } |
| 1644 | try bw.writeByte(0); // memory index immediate | |
| 1645 | try w.writeByte(0); // memory index immediate | |
| 1645 | 1646 | } |
| 1646 | 1647 | |
| 1647 | 1648 | if (virtual_addrs.init_memory_flag) |flag_address| { |
| 1648 | 1649 | assert(shared_memory); |
| 1649 | 1650 | |
| 1650 | 1651 | // we set the init memory flag to value '2' |
| 1651 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1652 | try bw.writeLeb128(@as(i32, @bitCast(flag_address))); | |
| 1653 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1654 | try bw.writeSleb128(2); | |
| 1655 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.atomics_prefix)); | |
| 1656 | try bw.writeLeb128(@intFromEnum(std.wasm.AtomicsOpcode.i32_atomic_store)); | |
| 1657 | try bw.writeLeb128(comptime Alignment.@"4".toLog2Units()); | |
| 1658 | try bw.writeUleb128(0); // offset | |
| 1652 | try w.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1653 | try w.writeLeb128(@as(i32, @bitCast(flag_address))); | |
| 1654 | try w.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1655 | try w.writeSleb128(2); | |
| 1656 | try w.writeByte(@intFromEnum(std.wasm.Opcode.atomics_prefix)); | |
| 1657 | try w.writeLeb128(@intFromEnum(std.wasm.AtomicsOpcode.i32_atomic_store)); | |
| 1658 | try w.writeLeb128(comptime Alignment.@"4".toLog2Units()); | |
| 1659 | try w.writeUleb128(0); // offset | |
| 1659 | 1660 | |
| 1660 | 1661 | // notify any waiters for segment initialization completion |
| 1661 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1662 | try bw.writeLeb128(@as(i32, @bitCast(flag_address))); | |
| 1663 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1664 | try bw.writeSleb128(-1); // number of waiters | |
| 1662 | try w.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1663 | try w.writeLeb128(@as(i32, @bitCast(flag_address))); | |
| 1664 | try w.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1665 | try w.writeSleb128(-1); // number of waiters | |
| 1665 | 1666 | |
| 1666 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.atomics_prefix)); | |
| 1667 | try bw.writeLeb128(@intFromEnum(std.wasm.AtomicsOpcode.memory_atomic_notify)); | |
| 1668 | try bw.writeLeb128(comptime Alignment.@"4".toLog2Units()); | |
| 1669 | try bw.writeUleb128(0); // offset | |
| 1670 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.drop)); | |
| 1667 | try w.writeByte(@intFromEnum(std.wasm.Opcode.atomics_prefix)); | |
| 1668 | try w.writeLeb128(@intFromEnum(std.wasm.AtomicsOpcode.memory_atomic_notify)); | |
| 1669 | try w.writeLeb128(comptime Alignment.@"4".toLog2Units()); | |
| 1670 | try w.writeUleb128(0); // offset | |
| 1671 | try w.writeByte(@intFromEnum(std.wasm.Opcode.drop)); | |
| 1671 | 1672 | |
| 1672 | 1673 | // branch and drop segments |
| 1673 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.br)); | |
| 1674 | try bw.writeUleb128(1); | |
| 1674 | try w.writeByte(@intFromEnum(std.wasm.Opcode.br)); | |
| 1675 | try w.writeUleb128(1); | |
| 1675 | 1676 | |
| 1676 | 1677 | // wait for thread to initialize memory segments |
| 1677 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.end)); // end $wait | |
| 1678 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1679 | try bw.writeLeb128(@as(i32, @bitCast(flag_address))); | |
| 1680 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1681 | try bw.writeSleb128(1); // expected flag value | |
| 1682 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.i64_const)); | |
| 1683 | try bw.writeSleb128(-1); // timeout | |
| 1684 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.atomics_prefix)); | |
| 1685 | try bw.writeByte(@intFromEnum(std.wasm.AtomicsOpcode.memory_atomic_wait32)); | |
| 1686 | try bw.writeLeb128(comptime Alignment.@"4".toLog2Units()); | |
| 1687 | try bw.writeUleb128(0); // offset | |
| 1688 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.drop)); | |
| 1689 | ||
| 1690 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.end)); // end $drop | |
| 1678 | try w.writeByte(@intFromEnum(std.wasm.Opcode.end)); // end $wait | |
| 1679 | try w.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1680 | try w.writeLeb128(@as(i32, @bitCast(flag_address))); | |
| 1681 | try w.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1682 | try w.writeSleb128(1); // expected flag value | |
| 1683 | try w.writeByte(@intFromEnum(std.wasm.Opcode.i64_const)); | |
| 1684 | try w.writeSleb128(-1); // timeout | |
| 1685 | try w.writeByte(@intFromEnum(std.wasm.Opcode.atomics_prefix)); | |
| 1686 | try w.writeByte(@intFromEnum(std.wasm.AtomicsOpcode.memory_atomic_wait32)); | |
| 1687 | try w.writeLeb128(comptime Alignment.@"4".toLog2Units()); | |
| 1688 | try w.writeUleb128(0); // offset | |
| 1689 | try w.writeByte(@intFromEnum(std.wasm.Opcode.drop)); | |
| 1690 | ||
| 1691 | try w.writeByte(@intFromEnum(std.wasm.Opcode.end)); // end $drop | |
| 1691 | 1692 | } |
| 1692 | 1693 | |
| 1693 | 1694 | for (segment_groups, 0..) |group, segment_index| { |
| ... | ... | @@ -1698,20 +1699,20 @@ fn emitInitMemoryFunction(wasm: *const Wasm, bw: *std.io.BufferedWriter, virtual |
| 1698 | 1699 | // during the initialization of each thread (__wasm_init_tls). |
| 1699 | 1700 | if (shared_memory and segment.isTls(wasm)) continue; |
| 1700 | 1701 | |
| 1701 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.misc_prefix)); | |
| 1702 | try bw.writeLeb128(@intFromEnum(std.wasm.MiscOpcode.data_drop)); | |
| 1703 | try bw.writeLeb128(segment_index); | |
| 1702 | try w.writeByte(@intFromEnum(std.wasm.Opcode.misc_prefix)); | |
| 1703 | try w.writeLeb128(@intFromEnum(std.wasm.MiscOpcode.data_drop)); | |
| 1704 | try w.writeLeb128(segment_index); | |
| 1704 | 1705 | } |
| 1705 | 1706 | |
| 1706 | 1707 | // End of the function body |
| 1707 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.end)); | |
| 1708 | try w.writeByte(@intFromEnum(std.wasm.Opcode.end)); | |
| 1708 | 1709 | } |
| 1709 | 1710 | |
| 1710 | fn emitInitTlsFunction(wasm: *const Wasm, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 1711 | fn emitInitTlsFunction(wasm: *const Wasm, w: *Writer) Writer.Error!void { | |
| 1711 | 1712 | const comp = wasm.base.comp; |
| 1712 | 1713 | assert(comp.config.shared_memory); |
| 1713 | 1714 | |
| 1714 | try bw.writeUleb128(0); // no locals | |
| 1715 | try w.writeUleb128(0); // no locals | |
| 1715 | 1716 | |
| 1716 | 1717 | // If there's a TLS segment, initialize it during runtime using the bulk-memory feature |
| 1717 | 1718 | // TLS segment is always the first one due to how we sort the data segments. |
| ... | ... | @@ -1724,31 +1725,31 @@ fn emitInitTlsFunction(wasm: *const Wasm, bw: *std.io.BufferedWriter) std.io.Wri |
| 1724 | 1725 | |
| 1725 | 1726 | const param_local: u32 = 0; |
| 1726 | 1727 | |
| 1727 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.local_get)); | |
| 1728 | try bw.writeLeb128(param_local); | |
| 1728 | try w.writeByte(@intFromEnum(std.wasm.Opcode.local_get)); | |
| 1729 | try w.writeLeb128(param_local); | |
| 1729 | 1730 | |
| 1730 | 1731 | const tls_base_global_index: Wasm.GlobalIndex = @enumFromInt(wasm.globals.getIndex(.__tls_base).?); |
| 1731 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.global_set)); | |
| 1732 | try bw.writeLeb128(@intFromEnum(tls_base_global_index)); | |
| 1732 | try w.writeByte(@intFromEnum(std.wasm.Opcode.global_set)); | |
| 1733 | try w.writeLeb128(@intFromEnum(tls_base_global_index)); | |
| 1733 | 1734 | |
| 1734 | 1735 | // load stack values for the bulk-memory operation |
| 1735 | 1736 | { |
| 1736 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.local_get)); | |
| 1737 | try bw.writeLeb128(param_local); | |
| 1737 | try w.writeByte(@intFromEnum(std.wasm.Opcode.local_get)); | |
| 1738 | try w.writeLeb128(param_local); | |
| 1738 | 1739 | |
| 1739 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1740 | try bw.writeSleb128(0); // segment offset | |
| 1740 | try w.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1741 | try w.writeSleb128(0); // segment offset | |
| 1741 | 1742 | |
| 1742 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1743 | try bw.writeLeb128(@as(i32, @bitCast(group_size))); // segment offset | |
| 1743 | try w.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1744 | try w.writeLeb128(@as(i32, @bitCast(group_size))); // segment offset | |
| 1744 | 1745 | } |
| 1745 | 1746 | |
| 1746 | 1747 | // perform the bulk-memory operation to initialize the data segment |
| 1747 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.misc_prefix)); | |
| 1748 | try bw.writeLeb128(@intFromEnum(std.wasm.MiscOpcode.memory_init)); | |
| 1748 | try w.writeByte(@intFromEnum(std.wasm.Opcode.misc_prefix)); | |
| 1749 | try w.writeLeb128(@intFromEnum(std.wasm.MiscOpcode.memory_init)); | |
| 1749 | 1750 | // segment immediate |
| 1750 | try bw.writeLeb128(data_segment_index); | |
| 1751 | try bw.writeByte(0); // memory index immediate | |
| 1751 | try w.writeLeb128(data_segment_index); | |
| 1752 | try w.writeByte(0); // memory index immediate | |
| 1752 | 1753 | } |
| 1753 | 1754 | |
| 1754 | 1755 | // If we have to perform any TLS relocations, call the corresponding function |
| ... | ... | @@ -1756,21 +1757,21 @@ fn emitInitTlsFunction(wasm: *const Wasm, bw: *std.io.BufferedWriter) std.io.Wri |
| 1756 | 1757 | // generated by the linker. |
| 1757 | 1758 | if (wasm.functions.getIndex(.__wasm_apply_global_tls_relocs)) |function_index| { |
| 1758 | 1759 | const output_function_index: Wasm.OutputFunctionIndex = .fromFunctionIndex(wasm, @enumFromInt(function_index)); |
| 1759 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.call)); | |
| 1760 | try bw.writeLeb128(@intFromEnum(output_function_index)); | |
| 1760 | try w.writeByte(@intFromEnum(std.wasm.Opcode.call)); | |
| 1761 | try w.writeLeb128(@intFromEnum(output_function_index)); | |
| 1761 | 1762 | } |
| 1762 | 1763 | |
| 1763 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.end)); | |
| 1764 | try w.writeByte(@intFromEnum(std.wasm.Opcode.end)); | |
| 1764 | 1765 | } |
| 1765 | 1766 | |
| 1766 | 1767 | fn emitStartSection(aw: *std.io.AllocatingWriter, i: Wasm.OutputFunctionIndex) !void { |
| 1767 | const header_offset = try reserveVecSectionHeader(&aw.buffered_writer); | |
| 1768 | const header_offset = try reserveVecSectionHeader(&aw.interface); | |
| 1768 | 1769 | defer replaceVecSectionHeader(aw, header_offset, .start, @intFromEnum(i)); |
| 1769 | 1770 | } |
| 1770 | 1771 | |
| 1771 | 1772 | fn emitTagNameFunction( |
| 1772 | 1773 | wasm: *Wasm, |
| 1773 | bw: *std.io.BufferedWriter, | |
| 1774 | w: *Writer, | |
| 1774 | 1775 | table_base_addr: u32, |
| 1775 | 1776 | table_index: u32, |
| 1776 | 1777 | enum_type_ip: InternPool.Index, |
| ... | ... | @@ -1782,33 +1783,33 @@ fn emitTagNameFunction( |
| 1782 | 1783 | const enum_type = ip.loadEnumType(enum_type_ip); |
| 1783 | 1784 | const tag_values = enum_type.values.get(ip); |
| 1784 | 1785 | |
| 1785 | try bw.writeUleb128(0); // no locals | |
| 1786 | try w.writeUleb128(0); // no locals | |
| 1786 | 1787 | |
| 1787 | 1788 | const slice_abi_size: u32 = 8; |
| 1788 | 1789 | if (tag_values.len == 0) { |
| 1789 | 1790 | // Then it's auto-numbered and therefore a direct table lookup. |
| 1790 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.local_get)); | |
| 1791 | try bw.writeUleb128(0); | |
| 1791 | try w.writeByte(@intFromEnum(std.wasm.Opcode.local_get)); | |
| 1792 | try w.writeUleb128(0); | |
| 1792 | 1793 | |
| 1793 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.local_get)); | |
| 1794 | try bw.writeUleb128(1); | |
| 1794 | try w.writeByte(@intFromEnum(std.wasm.Opcode.local_get)); | |
| 1795 | try w.writeUleb128(1); | |
| 1795 | 1796 | |
| 1796 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1797 | try w.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1797 | 1798 | if (std.math.isPowerOfTwo(slice_abi_size)) { |
| 1798 | try bw.writeLeb128(@as(i32, @bitCast(@as(u32, std.math.log2_int(u32, slice_abi_size))))); | |
| 1799 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_shl)); | |
| 1799 | try w.writeLeb128(@as(i32, @bitCast(@as(u32, std.math.log2_int(u32, slice_abi_size))))); | |
| 1800 | try w.writeByte(@intFromEnum(std.wasm.Opcode.i32_shl)); | |
| 1800 | 1801 | } else { |
| 1801 | try bw.writeLeb128(@as(i32, @bitCast(slice_abi_size))); | |
| 1802 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_mul)); | |
| 1802 | try w.writeLeb128(@as(i32, @bitCast(slice_abi_size))); | |
| 1803 | try w.writeByte(@intFromEnum(std.wasm.Opcode.i32_mul)); | |
| 1803 | 1804 | } |
| 1804 | 1805 | |
| 1805 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.i64_load)); | |
| 1806 | try bw.writeLeb128(comptime Alignment.@"4".toLog2Units()); | |
| 1807 | try bw.writeLeb128(table_base_addr + slice_abi_size * table_index); | |
| 1806 | try w.writeByte(@intFromEnum(std.wasm.Opcode.i64_load)); | |
| 1807 | try w.writeLeb128(comptime Alignment.@"4".toLog2Units()); | |
| 1808 | try w.writeLeb128(table_base_addr + slice_abi_size * table_index); | |
| 1808 | 1809 | |
| 1809 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.i64_store)); | |
| 1810 | try bw.writeLeb128(comptime Alignment.@"4".toLog2Units()); | |
| 1811 | try bw.writeUleb128(0); | |
| 1810 | try w.writeByte(@intFromEnum(std.wasm.Opcode.i64_store)); | |
| 1811 | try w.writeLeb128(comptime Alignment.@"4".toLog2Units()); | |
| 1812 | try w.writeUleb128(0); | |
| 1812 | 1813 | } else { |
| 1813 | 1814 | const int_info = Zcu.Type.intInfo(.fromInterned(enum_type.tag_ty), zcu); |
| 1814 | 1815 | const outer_block_type: std.wasm.BlockType = switch (int_info.bits) { |
| ... | ... | @@ -1817,80 +1818,80 @@ fn emitTagNameFunction( |
| 1817 | 1818 | else => return diags.fail("wasm linker does not yet implement @tagName for sparse enums with more than 64 bit integer tag types", .{}), |
| 1818 | 1819 | }; |
| 1819 | 1820 | |
| 1820 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.local_get)); | |
| 1821 | try bw.writeUleb128(0); | |
| 1821 | try w.writeByte(@intFromEnum(std.wasm.Opcode.local_get)); | |
| 1822 | try w.writeUleb128(0); | |
| 1822 | 1823 | |
| 1823 | 1824 | // Outer block that computes table offset. |
| 1824 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.block)); | |
| 1825 | try bw.writeByte(@intFromEnum(outer_block_type)); | |
| 1825 | try w.writeByte(@intFromEnum(std.wasm.Opcode.block)); | |
| 1826 | try w.writeByte(@intFromEnum(outer_block_type)); | |
| 1826 | 1827 | |
| 1827 | 1828 | for (tag_values, 0..) |tag_value, tag_index| { |
| 1828 | 1829 | // block for this if case |
| 1829 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.block)); | |
| 1830 | try bw.writeByte(@intFromEnum(std.wasm.BlockType.empty)); | |
| 1830 | try w.writeByte(@intFromEnum(std.wasm.Opcode.block)); | |
| 1831 | try w.writeByte(@intFromEnum(std.wasm.BlockType.empty)); | |
| 1831 | 1832 | |
| 1832 | 1833 | // Tag value whose name should be returned. |
| 1833 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.local_get)); | |
| 1834 | try bw.writeUleb128(1); | |
| 1834 | try w.writeByte(@intFromEnum(std.wasm.Opcode.local_get)); | |
| 1835 | try w.writeUleb128(1); | |
| 1835 | 1836 | |
| 1836 | 1837 | const val: Zcu.Value = .fromInterned(tag_value); |
| 1837 | 1838 | switch (outer_block_type) { |
| 1838 | 1839 | .i32 => { |
| 1839 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1840 | try bw.writeLeb128(@as(i32, switch (int_info.signedness) { | |
| 1840 | try w.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1841 | try w.writeLeb128(@as(i32, switch (int_info.signedness) { | |
| 1841 | 1842 | .signed => @intCast(val.toSignedInt(zcu)), |
| 1842 | 1843 | .unsigned => @bitCast(@as(u32, @intCast(val.toUnsignedInt(zcu)))), |
| 1843 | 1844 | })); |
| 1844 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_ne)); | |
| 1845 | try w.writeByte(@intFromEnum(std.wasm.Opcode.i32_ne)); | |
| 1845 | 1846 | }, |
| 1846 | 1847 | .i64 => { |
| 1847 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.i64_const)); | |
| 1848 | try bw.writeLeb128(@as(i64, switch (int_info.signedness) { | |
| 1848 | try w.writeByte(@intFromEnum(std.wasm.Opcode.i64_const)); | |
| 1849 | try w.writeLeb128(@as(i64, switch (int_info.signedness) { | |
| 1849 | 1850 | .signed => val.toSignedInt(zcu), |
| 1850 | 1851 | .unsigned => @bitCast(val.toUnsignedInt(zcu)), |
| 1851 | 1852 | })); |
| 1852 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.i64_ne)); | |
| 1853 | try w.writeByte(@intFromEnum(std.wasm.Opcode.i64_ne)); | |
| 1853 | 1854 | }, |
| 1854 | 1855 | else => unreachable, |
| 1855 | 1856 | } |
| 1856 | 1857 | |
| 1857 | 1858 | // if they're not equal, break out of current branch |
| 1858 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.br_if)); | |
| 1859 | try bw.writeUleb128(0); | |
| 1859 | try w.writeByte(@intFromEnum(std.wasm.Opcode.br_if)); | |
| 1860 | try w.writeUleb128(0); | |
| 1860 | 1861 | |
| 1861 | 1862 | // Put the table offset of the result on the stack. |
| 1862 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1863 | try bw.writeLeb128(@as(i32, @bitCast(@as(u32, @intCast(slice_abi_size * tag_index))))); | |
| 1863 | try w.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 1864 | try w.writeLeb128(@as(i32, @bitCast(@as(u32, @intCast(slice_abi_size * tag_index))))); | |
| 1864 | 1865 | |
| 1865 | 1866 | // break outside blocks |
| 1866 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.br)); | |
| 1867 | try bw.writeUleb128(1); | |
| 1867 | try w.writeByte(@intFromEnum(std.wasm.Opcode.br)); | |
| 1868 | try w.writeUleb128(1); | |
| 1868 | 1869 | |
| 1869 | 1870 | // end the block for this case |
| 1870 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.end)); | |
| 1871 | try w.writeByte(@intFromEnum(std.wasm.Opcode.end)); | |
| 1871 | 1872 | } |
| 1872 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.@"unreachable")); | |
| 1873 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.end)); | |
| 1873 | try w.writeByte(@intFromEnum(std.wasm.Opcode.@"unreachable")); | |
| 1874 | try w.writeByte(@intFromEnum(std.wasm.Opcode.end)); | |
| 1874 | 1875 | |
| 1875 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.i64_load)); | |
| 1876 | try bw.writeLeb128(comptime Alignment.@"4".toLog2Units()); | |
| 1877 | try bw.writeLeb128(table_base_addr + slice_abi_size * table_index); | |
| 1876 | try w.writeByte(@intFromEnum(std.wasm.Opcode.i64_load)); | |
| 1877 | try w.writeLeb128(comptime Alignment.@"4".toLog2Units()); | |
| 1878 | try w.writeLeb128(table_base_addr + slice_abi_size * table_index); | |
| 1878 | 1879 | |
| 1879 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.i64_store)); | |
| 1880 | try bw.writeLeb128(comptime Alignment.@"4".toLog2Units()); | |
| 1881 | try bw.writeUleb128(0); | |
| 1880 | try w.writeByte(@intFromEnum(std.wasm.Opcode.i64_store)); | |
| 1881 | try w.writeLeb128(comptime Alignment.@"4".toLog2Units()); | |
| 1882 | try w.writeUleb128(0); | |
| 1882 | 1883 | } |
| 1883 | 1884 | |
| 1884 | 1885 | // End of the function body |
| 1885 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.end)); | |
| 1886 | try w.writeByte(@intFromEnum(std.wasm.Opcode.end)); | |
| 1886 | 1887 | } |
| 1887 | 1888 | |
| 1888 | fn appendGlobal(bw: *std.io.BufferedWriter, mutable: bool, val: u32) std.io.Writer.Error!void { | |
| 1889 | try bw.writeAll(&.{ | |
| 1889 | fn appendGlobal(w: *Writer, mutable: bool, val: u32) Writer.Error!void { | |
| 1890 | try w.writeAll(&.{ | |
| 1890 | 1891 | @intFromEnum(std.wasm.Valtype.i32), |
| 1891 | 1892 | @intFromBool(mutable), |
| 1892 | 1893 | @intFromEnum(std.wasm.Opcode.i32_const), |
| 1893 | 1894 | }); |
| 1894 | try bw.writeLeb128(val); | |
| 1895 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.end)); | |
| 1895 | try w.writeLeb128(val); | |
| 1896 | try w.writeByte(@intFromEnum(std.wasm.Opcode.end)); | |
| 1896 | 1897 | } |
src/link/riscv.zig+7-6| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | pub fn writeSetSub6(comptime op: enum { set, sub }, addend: anytype, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 1 | pub fn writeSetSub6(comptime op: enum { set, sub }, addend: anytype, bw: *Writer) Writer.Error!void { | |
| 2 | 2 | const mask: u8 = 0b11_000000; |
| 3 | 3 | const actual: i8 = @truncate(addend); |
| 4 | 4 | const old_value = (try bw.writableArray(1))[0]; |
| ... | ... | @@ -9,7 +9,7 @@ pub fn writeSetSub6(comptime op: enum { set, sub }, addend: anytype, bw: *std.io |
| 9 | 9 | try bw.writeByte(new_value); |
| 10 | 10 | } |
| 11 | 11 | |
| 12 | pub fn writeSetSubUleb(comptime op: enum { set, sub }, addend: i64, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 12 | pub fn writeSetSubUleb(comptime op: enum { set, sub }, addend: i64, bw: *Writer) Writer.Error!void { | |
| 13 | 13 | switch (op) { |
| 14 | 14 | .set => try overwriteUleb(@intCast(addend), bw), |
| 15 | 15 | .sub => { |
| ... | ... | @@ -20,7 +20,7 @@ pub fn writeSetSubUleb(comptime op: enum { set, sub }, addend: i64, bw: *std.io. |
| 20 | 20 | } |
| 21 | 21 | } |
| 22 | 22 | |
| 23 | fn overwriteUleb(new_value: u64, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 23 | fn overwriteUleb(new_value: u64, bw: *Writer) Writer.Error!void { | |
| 24 | 24 | var value: u64 = new_value; |
| 25 | 25 | while (true) { |
| 26 | 26 | const byte = (try bw.writableArray(1))[0]; |
| ... | ... | @@ -34,8 +34,8 @@ pub fn writeAddend( |
| 34 | 34 | comptime Int: type, |
| 35 | 35 | comptime op: enum { add, sub }, |
| 36 | 36 | value: anytype, |
| 37 | bw: *std.io.BufferedWriter, | |
| 38 | ) std.io.Writer.Error!void { | |
| 37 | bw: *Writer, | |
| 38 | ) Writer.Error!void { | |
| 39 | 39 | const n = @divExact(@bitSizeOf(Int), 8); |
| 40 | 40 | var V: Int = mem.readInt(Int, (try bw.writableSliceGreedy(n))[0..n], .little); |
| 41 | 41 | const addend: Int = @truncate(value); |
| ... | ... | @@ -108,8 +108,9 @@ pub const Eflags = packed struct(u32) { |
| 108 | 108 | }; |
| 109 | 109 | }; |
| 110 | 110 | |
| 111 | const mem = std.mem; | |
| 112 | 111 | const std = @import("std"); |
| 112 | const mem = std.mem; | |
| 113 | const Writer = std.io.Writer; | |
| 113 | 114 | |
| 114 | 115 | const encoding = @import("../arch/riscv64/encoding.zig"); |
| 115 | 116 | const Instruction = encoding.Instruction; |
src/link/table_section.zig+2-1| ... | ... | @@ -39,7 +39,7 @@ pub fn TableSection(comptime Entry: type) type { |
| 39 | 39 | return self.entries.items.len; |
| 40 | 40 | } |
| 41 | 41 | |
| 42 | pub fn format(self: Self, bw: *std.io.BufferedWriter, comptime unused_format_string: []const u8) std.io.Writer.Error!void { | |
| 42 | pub fn format(self: Self, bw: *Writer, comptime unused_format_string: []const u8) Writer.Error!void { | |
| 43 | 43 | comptime assert(unused_format_string.len == 0); |
| 44 | 44 | try bw.writeAll("TableSection:\n"); |
| 45 | 45 | for (self.entries.items, 0..) |entry, i| { |
| ... | ... | @@ -57,3 +57,4 @@ const assert = std.debug.assert; |
| 57 | 57 | const log = std.log.scoped(.link); |
| 58 | 58 | |
| 59 | 59 | const Allocator = std.mem.Allocator; |
| 60 | const Writer = std.io.Writer; |
src/print_env.zig+5-4| ... | ... | @@ -22,8 +22,9 @@ pub fn cmdEnv(arena: Allocator, args: []const []const u8) !void { |
| 22 | 22 | const triple = try host.zigTriple(arena); |
| 23 | 23 | |
| 24 | 24 | var buffer: [1024]u8 = undefined; |
| 25 | var bw: std.io.BufferedWriter = std.fs.File.stdout().writer().buffered(&buffer); | |
| 26 | var jws: std.json.Stringify = .{ .writer = &bw, .options = .{ .whitespace = .indent_1 } }; | |
| 25 | var stdout_writer = std.fs.File.stdout().writer(&buffer); | |
| 26 | const w = &stdout_writer.interface(); | |
| 27 | var jws: std.json.Stringify = .{ .writer = w, .options = .{ .whitespace = .indent_1 } }; | |
| 27 | 28 | |
| 28 | 29 | try jws.beginObject(); |
| 29 | 30 | |
| ... | ... | @@ -54,7 +55,7 @@ pub fn cmdEnv(arena: Allocator, args: []const []const u8) !void { |
| 54 | 55 | try jws.endObject(); |
| 55 | 56 | |
| 56 | 57 | try jws.endObject(); |
| 57 | try bw.writeByte('\n'); | |
| 58 | try w.writeByte('\n'); | |
| 58 | 59 | |
| 59 | try bw.flush(); | |
| 60 | try w.flush(); | |
| 60 | 61 | } |
src/print_targets.zig+2-1| ... | ... | @@ -10,6 +10,7 @@ const target = @import("target.zig"); |
| 10 | 10 | const assert = std.debug.assert; |
| 11 | 11 | const glibc = @import("libs/glibc.zig"); |
| 12 | 12 | const introspect = @import("introspect.zig"); |
| 13 | const Writer = std.io.Writer; | |
| 13 | 14 | |
| 14 | 15 | pub fn cmdTargets(arena: Allocator, args: []const []const u8) !void { |
| 15 | 16 | _ = args; |
| ... | ... | @@ -20,7 +21,7 @@ pub fn cmdTargets(arena: Allocator, args: []const []const u8) !void { |
| 20 | 21 | try bw.flush(); |
| 21 | 22 | } |
| 22 | 23 | |
| 23 | fn print(arena: Allocator, output: *std.io.BufferedWriter, host: *const Target) std.io.Writer.Error!void { | |
| 24 | fn print(arena: Allocator, output: *Writer, host: *const Target) Writer.Error!void { | |
| 24 | 25 | var zig_lib_directory = introspect.findZigLibDir(arena) catch |err| { |
| 25 | 26 | fatal("unable to find zig installation directory: {s}\n", .{@errorName(err)}); |
| 26 | 27 | }; |
src/print_value.zig+7-6| ... | ... | @@ -9,6 +9,7 @@ const Sema = @import("Sema.zig"); |
| 9 | 9 | const InternPool = @import("InternPool.zig"); |
| 10 | 10 | const Allocator = std.mem.Allocator; |
| 11 | 11 | const Target = std.Target; |
| 12 | const Writer = std.io.Writer; | |
| 12 | 13 | |
| 13 | 14 | const max_aggregate_items = 100; |
| 14 | 15 | const max_string_len = 256; |
| ... | ... | @@ -20,7 +21,7 @@ pub const FormatContext = struct { |
| 20 | 21 | depth: u8, |
| 21 | 22 | }; |
| 22 | 23 | |
| 23 | pub fn formatSema(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime fmt: []const u8) std.io.Writer.Error!void { | |
| 24 | pub fn formatSema(ctx: FormatContext, bw: *Writer, comptime fmt: []const u8) std.io.Writer.Error!void { | |
| 24 | 25 | const sema = ctx.opt_sema.?; |
| 25 | 26 | comptime std.debug.assert(fmt.len == 0); |
| 26 | 27 | return print(ctx.val, bw, ctx.depth, ctx.pt, sema) catch |err| switch (err) { |
| ... | ... | @@ -31,7 +32,7 @@ pub fn formatSema(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime fmt: |
| 31 | 32 | }; |
| 32 | 33 | } |
| 33 | 34 | |
| 34 | pub fn format(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime fmt: []const u8) std.io.Writer.Error!void { | |
| 35 | pub fn format(ctx: FormatContext, bw: *Writer, comptime fmt: []const u8) std.io.Writer.Error!void { | |
| 35 | 36 | std.debug.assert(ctx.opt_sema == null); |
| 36 | 37 | comptime std.debug.assert(fmt.len == 0); |
| 37 | 38 | return print(ctx.val, bw, ctx.depth, ctx.pt, null) catch |err| switch (err) { |
| ... | ... | @@ -43,7 +44,7 @@ pub fn format(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime fmt: []co |
| 43 | 44 | |
| 44 | 45 | pub fn print( |
| 45 | 46 | val: Value, |
| 46 | bw: *std.io.BufferedWriter, | |
| 47 | bw: *Writer, | |
| 47 | 48 | level: u8, |
| 48 | 49 | pt: Zcu.PerThread, |
| 49 | 50 | opt_sema: ?*Sema, |
| ... | ... | @@ -186,7 +187,7 @@ fn printAggregate( |
| 186 | 187 | val: Value, |
| 187 | 188 | aggregate: InternPool.Key.Aggregate, |
| 188 | 189 | is_ref: bool, |
| 189 | bw: *std.io.BufferedWriter, | |
| 190 | bw: *Writer, | |
| 190 | 191 | level: u8, |
| 191 | 192 | pt: Zcu.PerThread, |
| 192 | 193 | opt_sema: ?*Sema, |
| ... | ... | @@ -272,7 +273,7 @@ fn printPtr( |
| 272 | 273 | ptr_val: Value, |
| 273 | 274 | /// Whether to print `derivation` as an lvalue or rvalue. If `null`, the more concise option is chosen. |
| 274 | 275 | want_kind: ?PrintPtrKind, |
| 275 | bw: *std.io.BufferedWriter, | |
| 276 | bw: *Writer, | |
| 276 | 277 | level: u8, |
| 277 | 278 | pt: Zcu.PerThread, |
| 278 | 279 | opt_sema: ?*Sema, |
| ... | ... | @@ -318,7 +319,7 @@ const PrintPtrKind = enum { lvalue, rvalue }; |
| 318 | 319 | /// Returns the root derivation, which may be ignored. |
| 319 | 320 | pub fn printPtrDerivation( |
| 320 | 321 | derivation: Value.PointerDeriveStep, |
| 321 | bw: *std.io.BufferedWriter, | |
| 322 | bw: *Writer, | |
| 322 | 323 | pt: Zcu.PerThread, |
| 323 | 324 | /// Whether to print `derivation` as an lvalue or rvalue. If `null`, the more concise option is chosen. |
| 324 | 325 | /// If this is `.rvalue`, the result may look like `&foo`, so it's not necessarily valid to treat it as |
src/print_zir.zig+107-107| ... | ... | @@ -10,7 +10,7 @@ const Zcu = @import("Zcu.zig"); |
| 10 | 10 | const LazySrcLoc = Zcu.LazySrcLoc; |
| 11 | 11 | |
| 12 | 12 | /// Write human-readable, debug formatted ZIR code. |
| 13 | pub fn renderAsText(gpa: Allocator, tree: ?Ast, zir: Zir, bw: *std.io.BufferedWriter) !void { | |
| 13 | pub fn renderAsText(gpa: Allocator, tree: ?Ast, zir: Zir, bw: *std.io.Writer) !void { | |
| 14 | 14 | var arena = std.heap.ArenaAllocator.init(gpa); |
| 15 | 15 | defer arena.deinit(); |
| 16 | 16 | |
| ... | ... | @@ -57,7 +57,7 @@ pub fn renderInstructionContext( |
| 57 | 57 | scope_file: *Zcu.File, |
| 58 | 58 | parent_decl_node: Ast.Node.Index, |
| 59 | 59 | indent: u32, |
| 60 | bw: *std.io.BufferedWriter, | |
| 60 | bw: *std.io.Writer, | |
| 61 | 61 | ) !void { |
| 62 | 62 | var arena = std.heap.ArenaAllocator.init(gpa); |
| 63 | 63 | defer arena.deinit(); |
| ... | ... | @@ -89,7 +89,7 @@ pub fn renderSingleInstruction( |
| 89 | 89 | scope_file: *Zcu.File, |
| 90 | 90 | parent_decl_node: Ast.Node.Index, |
| 91 | 91 | indent: u32, |
| 92 | bw: *std.io.BufferedWriter, | |
| 92 | bw: *std.io.Writer, | |
| 93 | 93 | ) !void { |
| 94 | 94 | var arena = std.heap.ArenaAllocator.init(gpa); |
| 95 | 95 | defer arena.deinit(); |
| ... | ... | @@ -176,11 +176,11 @@ const Writer = struct { |
| 176 | 176 | } |
| 177 | 177 | } = .{}, |
| 178 | 178 | |
| 179 | const Error = std.io.Writer.Error || std.mem.Allocator.Error; | |
| 179 | const Error = std.io.Writer.Error || Allocator.Error; | |
| 180 | 180 | |
| 181 | 181 | fn writeInstToStream( |
| 182 | 182 | self: *Writer, |
| 183 | stream: *std.io.BufferedWriter, | |
| 183 | stream: *std.io.Writer, | |
| 184 | 184 | inst: Zir.Inst.Index, |
| 185 | 185 | ) Error!void { |
| 186 | 186 | const tags = self.code.instructions.items(.tag); |
| ... | ... | @@ -510,7 +510,7 @@ const Writer = struct { |
| 510 | 510 | } |
| 511 | 511 | } |
| 512 | 512 | |
| 513 | fn writeExtended(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 513 | fn writeExtended(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 514 | 514 | const extended = self.code.instructions.items(.data)[@intFromEnum(inst)].extended; |
| 515 | 515 | try stream.print("{s}(", .{@tagName(extended.opcode)}); |
| 516 | 516 | switch (extended.opcode) { |
| ... | ... | @@ -619,13 +619,13 @@ const Writer = struct { |
| 619 | 619 | } |
| 620 | 620 | } |
| 621 | 621 | |
| 622 | fn writeExtNode(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void { | |
| 622 | fn writeExtNode(self: *Writer, stream: *std.io.Writer, extended: Zir.Inst.Extended.InstData) !void { | |
| 623 | 623 | try stream.writeAll(")) "); |
| 624 | 624 | const src_node: Ast.Node.Offset = @enumFromInt(@as(i32, @bitCast(extended.operand))); |
| 625 | 625 | try self.writeSrcNode(stream, src_node); |
| 626 | 626 | } |
| 627 | 627 | |
| 628 | fn writeArrayInitElemType(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 628 | fn writeArrayInitElemType(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 629 | 629 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].bin; |
| 630 | 630 | try self.writeInstRef(stream, inst_data.lhs); |
| 631 | 631 | try stream.print(", {d})", .{@intFromEnum(inst_data.rhs)}); |
| ... | ... | @@ -633,7 +633,7 @@ const Writer = struct { |
| 633 | 633 | |
| 634 | 634 | fn writeUnNode( |
| 635 | 635 | self: *Writer, |
| 636 | stream: *std.io.BufferedWriter, | |
| 636 | stream: *std.io.Writer, | |
| 637 | 637 | inst: Zir.Inst.Index, |
| 638 | 638 | ) Error!void { |
| 639 | 639 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| ... | ... | @@ -644,7 +644,7 @@ const Writer = struct { |
| 644 | 644 | |
| 645 | 645 | fn writeUnTok( |
| 646 | 646 | self: *Writer, |
| 647 | stream: *std.io.BufferedWriter, | |
| 647 | stream: *std.io.Writer, | |
| 648 | 648 | inst: Zir.Inst.Index, |
| 649 | 649 | ) Error!void { |
| 650 | 650 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].un_tok; |
| ... | ... | @@ -655,7 +655,7 @@ const Writer = struct { |
| 655 | 655 | |
| 656 | 656 | fn writeValidateDestructure( |
| 657 | 657 | self: *Writer, |
| 658 | stream: *std.io.BufferedWriter, | |
| 658 | stream: *std.io.Writer, | |
| 659 | 659 | inst: Zir.Inst.Index, |
| 660 | 660 | ) Error!void { |
| 661 | 661 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| ... | ... | @@ -669,7 +669,7 @@ const Writer = struct { |
| 669 | 669 | |
| 670 | 670 | fn writeValidateArrayInitTy( |
| 671 | 671 | self: *Writer, |
| 672 | stream: *std.io.BufferedWriter, | |
| 672 | stream: *std.io.Writer, | |
| 673 | 673 | inst: Zir.Inst.Index, |
| 674 | 674 | ) Error!void { |
| 675 | 675 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| ... | ... | @@ -681,7 +681,7 @@ const Writer = struct { |
| 681 | 681 | |
| 682 | 682 | fn writeArrayTypeSentinel( |
| 683 | 683 | self: *Writer, |
| 684 | stream: *std.io.BufferedWriter, | |
| 684 | stream: *std.io.Writer, | |
| 685 | 685 | inst: Zir.Inst.Index, |
| 686 | 686 | ) Error!void { |
| 687 | 687 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| ... | ... | @@ -697,7 +697,7 @@ const Writer = struct { |
| 697 | 697 | |
| 698 | 698 | fn writePtrType( |
| 699 | 699 | self: *Writer, |
| 700 | stream: *std.io.BufferedWriter, | |
| 700 | stream: *std.io.Writer, | |
| 701 | 701 | inst: Zir.Inst.Index, |
| 702 | 702 | ) Error!void { |
| 703 | 703 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].ptr_type; |
| ... | ... | @@ -740,12 +740,12 @@ const Writer = struct { |
| 740 | 740 | try self.writeSrcNode(stream, extra.data.src_node); |
| 741 | 741 | } |
| 742 | 742 | |
| 743 | fn writeInt(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 743 | fn writeInt(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 744 | 744 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].int; |
| 745 | 745 | try stream.print("{d})", .{inst_data}); |
| 746 | 746 | } |
| 747 | 747 | |
| 748 | fn writeIntBig(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 748 | fn writeIntBig(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 749 | 749 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].str; |
| 750 | 750 | const byte_count = inst_data.len * @sizeOf(std.math.big.Limb); |
| 751 | 751 | const limb_bytes = self.code.string_bytes[@intFromEnum(inst_data.start)..][0..byte_count]; |
| ... | ... | @@ -764,12 +764,12 @@ const Writer = struct { |
| 764 | 764 | try stream.print("{s})", .{as_string}); |
| 765 | 765 | } |
| 766 | 766 | |
| 767 | fn writeFloat(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 767 | fn writeFloat(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 768 | 768 | const number = self.code.instructions.items(.data)[@intFromEnum(inst)].float; |
| 769 | 769 | try stream.print("{d})", .{number}); |
| 770 | 770 | } |
| 771 | 771 | |
| 772 | fn writeFloat128(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 772 | fn writeFloat128(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 773 | 773 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 774 | 774 | const extra = self.code.extraData(Zir.Inst.Float128, inst_data.payload_index).data; |
| 775 | 775 | const number = extra.get(); |
| ... | ... | @@ -780,7 +780,7 @@ const Writer = struct { |
| 780 | 780 | |
| 781 | 781 | fn writeStr( |
| 782 | 782 | self: *Writer, |
| 783 | stream: *std.io.BufferedWriter, | |
| 783 | stream: *std.io.Writer, | |
| 784 | 784 | inst: Zir.Inst.Index, |
| 785 | 785 | ) Error!void { |
| 786 | 786 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].str; |
| ... | ... | @@ -788,7 +788,7 @@ const Writer = struct { |
| 788 | 788 | try stream.print("\"{f}\")", .{std.zig.fmtEscapes(str)}); |
| 789 | 789 | } |
| 790 | 790 | |
| 791 | fn writeSliceStart(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 791 | fn writeSliceStart(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 792 | 792 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 793 | 793 | const extra = self.code.extraData(Zir.Inst.SliceStart, inst_data.payload_index).data; |
| 794 | 794 | try self.writeInstRef(stream, extra.lhs); |
| ... | ... | @@ -798,7 +798,7 @@ const Writer = struct { |
| 798 | 798 | try self.writeSrcNode(stream, inst_data.src_node); |
| 799 | 799 | } |
| 800 | 800 | |
| 801 | fn writeSliceEnd(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 801 | fn writeSliceEnd(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 802 | 802 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 803 | 803 | const extra = self.code.extraData(Zir.Inst.SliceEnd, inst_data.payload_index).data; |
| 804 | 804 | try self.writeInstRef(stream, extra.lhs); |
| ... | ... | @@ -810,7 +810,7 @@ const Writer = struct { |
| 810 | 810 | try self.writeSrcNode(stream, inst_data.src_node); |
| 811 | 811 | } |
| 812 | 812 | |
| 813 | fn writeSliceSentinel(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 813 | fn writeSliceSentinel(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 814 | 814 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 815 | 815 | const extra = self.code.extraData(Zir.Inst.SliceSentinel, inst_data.payload_index).data; |
| 816 | 816 | try self.writeInstRef(stream, extra.lhs); |
| ... | ... | @@ -824,7 +824,7 @@ const Writer = struct { |
| 824 | 824 | try self.writeSrcNode(stream, inst_data.src_node); |
| 825 | 825 | } |
| 826 | 826 | |
| 827 | fn writeSliceLength(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 827 | fn writeSliceLength(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 828 | 828 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 829 | 829 | const extra = self.code.extraData(Zir.Inst.SliceLength, inst_data.payload_index).data; |
| 830 | 830 | try self.writeInstRef(stream, extra.lhs); |
| ... | ... | @@ -840,7 +840,7 @@ const Writer = struct { |
| 840 | 840 | try self.writeSrcNode(stream, inst_data.src_node); |
| 841 | 841 | } |
| 842 | 842 | |
| 843 | fn writeUnionInit(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 843 | fn writeUnionInit(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 844 | 844 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 845 | 845 | const extra = self.code.extraData(Zir.Inst.UnionInit, inst_data.payload_index).data; |
| 846 | 846 | try self.writeInstRef(stream, extra.union_type); |
| ... | ... | @@ -852,7 +852,7 @@ const Writer = struct { |
| 852 | 852 | try self.writeSrcNode(stream, inst_data.src_node); |
| 853 | 853 | } |
| 854 | 854 | |
| 855 | fn writeShuffle(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 855 | fn writeShuffle(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 856 | 856 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 857 | 857 | const extra = self.code.extraData(Zir.Inst.Shuffle, inst_data.payload_index).data; |
| 858 | 858 | try self.writeInstRef(stream, extra.elem_type); |
| ... | ... | @@ -866,7 +866,7 @@ const Writer = struct { |
| 866 | 866 | try self.writeSrcNode(stream, inst_data.src_node); |
| 867 | 867 | } |
| 868 | 868 | |
| 869 | fn writeSelect(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void { | |
| 869 | fn writeSelect(self: *Writer, stream: *std.io.Writer, extended: Zir.Inst.Extended.InstData) !void { | |
| 870 | 870 | const extra = self.code.extraData(Zir.Inst.Select, extended.operand).data; |
| 871 | 871 | try self.writeInstRef(stream, extra.elem_type); |
| 872 | 872 | try stream.writeAll(", "); |
| ... | ... | @@ -879,7 +879,7 @@ const Writer = struct { |
| 879 | 879 | try self.writeSrcNode(stream, extra.node); |
| 880 | 880 | } |
| 881 | 881 | |
| 882 | fn writeMulAdd(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 882 | fn writeMulAdd(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 883 | 883 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 884 | 884 | const extra = self.code.extraData(Zir.Inst.MulAdd, inst_data.payload_index).data; |
| 885 | 885 | try self.writeInstRef(stream, extra.mulend1); |
| ... | ... | @@ -891,7 +891,7 @@ const Writer = struct { |
| 891 | 891 | try self.writeSrcNode(stream, inst_data.src_node); |
| 892 | 892 | } |
| 893 | 893 | |
| 894 | fn writeBuiltinCall(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 894 | fn writeBuiltinCall(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 895 | 895 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 896 | 896 | const extra = self.code.extraData(Zir.Inst.BuiltinCall, inst_data.payload_index).data; |
| 897 | 897 | |
| ... | ... | @@ -907,7 +907,7 @@ const Writer = struct { |
| 907 | 907 | try self.writeSrcNode(stream, inst_data.src_node); |
| 908 | 908 | } |
| 909 | 909 | |
| 910 | fn writeFieldParentPtr(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void { | |
| 910 | fn writeFieldParentPtr(self: *Writer, stream: *std.io.Writer, extended: Zir.Inst.Extended.InstData) !void { | |
| 911 | 911 | const extra = self.code.extraData(Zir.Inst.FieldParentPtr, extended.operand).data; |
| 912 | 912 | const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).@"struct".backing_integer.?; |
| 913 | 913 | const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(FlagsInt, @truncate(extended.small))); |
| ... | ... | @@ -924,7 +924,7 @@ const Writer = struct { |
| 924 | 924 | try self.writeSrcNode(stream, extra.src_node); |
| 925 | 925 | } |
| 926 | 926 | |
| 927 | fn writeBuiltinAsyncCall(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void { | |
| 927 | fn writeBuiltinAsyncCall(self: *Writer, stream: *std.io.Writer, extended: Zir.Inst.Extended.InstData) !void { | |
| 928 | 928 | const extra = self.code.extraData(Zir.Inst.AsyncCall, extended.operand).data; |
| 929 | 929 | try self.writeInstRef(stream, extra.frame_buffer); |
| 930 | 930 | try stream.writeAll(", "); |
| ... | ... | @@ -937,7 +937,7 @@ const Writer = struct { |
| 937 | 937 | try self.writeSrcNode(stream, extra.node); |
| 938 | 938 | } |
| 939 | 939 | |
| 940 | fn writeParam(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 940 | fn writeParam(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 941 | 941 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_tok; |
| 942 | 942 | const extra = self.code.extraData(Zir.Inst.Param, inst_data.payload_index); |
| 943 | 943 | const body = self.code.bodySlice(extra.end, extra.data.type.body_len); |
| ... | ... | @@ -952,7 +952,7 @@ const Writer = struct { |
| 952 | 952 | try self.writeSrcTok(stream, inst_data.src_tok); |
| 953 | 953 | } |
| 954 | 954 | |
| 955 | fn writePlNodeBin(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 955 | fn writePlNodeBin(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 956 | 956 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 957 | 957 | const extra = self.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 958 | 958 | try self.writeInstRef(stream, extra.lhs); |
| ... | ... | @@ -962,7 +962,7 @@ const Writer = struct { |
| 962 | 962 | try self.writeSrcNode(stream, inst_data.src_node); |
| 963 | 963 | } |
| 964 | 964 | |
| 965 | fn writePlNodeMultiOp(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 965 | fn writePlNodeMultiOp(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 966 | 966 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 967 | 967 | const extra = self.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index); |
| 968 | 968 | const args = self.code.refSlice(extra.end, extra.data.operands_len); |
| ... | ... | @@ -975,7 +975,7 @@ const Writer = struct { |
| 975 | 975 | try self.writeSrcNode(stream, inst_data.src_node); |
| 976 | 976 | } |
| 977 | 977 | |
| 978 | fn writeArrayMul(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 978 | fn writeArrayMul(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 979 | 979 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 980 | 980 | const extra = self.code.extraData(Zir.Inst.ArrayMul, inst_data.payload_index).data; |
| 981 | 981 | try self.writeInstRef(stream, extra.res_ty); |
| ... | ... | @@ -987,13 +987,13 @@ const Writer = struct { |
| 987 | 987 | try self.writeSrcNode(stream, inst_data.src_node); |
| 988 | 988 | } |
| 989 | 989 | |
| 990 | fn writeElemValImm(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 990 | fn writeElemValImm(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 991 | 991 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].elem_val_imm; |
| 992 | 992 | try self.writeInstRef(stream, inst_data.operand); |
| 993 | 993 | try stream.print(", {d})", .{inst_data.idx}); |
| 994 | 994 | } |
| 995 | 995 | |
| 996 | fn writeArrayInitElemPtr(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 996 | fn writeArrayInitElemPtr(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 997 | 997 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 998 | 998 | const extra = self.code.extraData(Zir.Inst.ElemPtrImm, inst_data.payload_index).data; |
| 999 | 999 | |
| ... | ... | @@ -1002,7 +1002,7 @@ const Writer = struct { |
| 1002 | 1002 | try self.writeSrcNode(stream, inst_data.src_node); |
| 1003 | 1003 | } |
| 1004 | 1004 | |
| 1005 | fn writePlNodeExport(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 1005 | fn writePlNodeExport(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 1006 | 1006 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 1007 | 1007 | const extra = self.code.extraData(Zir.Inst.Export, inst_data.payload_index).data; |
| 1008 | 1008 | |
| ... | ... | @@ -1013,7 +1013,7 @@ const Writer = struct { |
| 1013 | 1013 | try self.writeSrcNode(stream, inst_data.src_node); |
| 1014 | 1014 | } |
| 1015 | 1015 | |
| 1016 | fn writeValidateArrayInitRefTy(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 1016 | fn writeValidateArrayInitRefTy(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 1017 | 1017 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 1018 | 1018 | const extra = self.code.extraData(Zir.Inst.ArrayInitRefTy, inst_data.payload_index).data; |
| 1019 | 1019 | |
| ... | ... | @@ -1023,7 +1023,7 @@ const Writer = struct { |
| 1023 | 1023 | try self.writeSrcNode(stream, inst_data.src_node); |
| 1024 | 1024 | } |
| 1025 | 1025 | |
| 1026 | fn writeStructInit(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 1026 | fn writeStructInit(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 1027 | 1027 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 1028 | 1028 | const extra = self.code.extraData(Zir.Inst.StructInit, inst_data.payload_index); |
| 1029 | 1029 | var field_i: u32 = 0; |
| ... | ... | @@ -1047,7 +1047,7 @@ const Writer = struct { |
| 1047 | 1047 | try self.writeSrcNode(stream, inst_data.src_node); |
| 1048 | 1048 | } |
| 1049 | 1049 | |
| 1050 | fn writeCmpxchg(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void { | |
| 1050 | fn writeCmpxchg(self: *Writer, stream: *std.io.Writer, extended: Zir.Inst.Extended.InstData) !void { | |
| 1051 | 1051 | const extra = self.code.extraData(Zir.Inst.Cmpxchg, extended.operand).data; |
| 1052 | 1052 | |
| 1053 | 1053 | try self.writeInstRef(stream, extra.ptr); |
| ... | ... | @@ -1063,7 +1063,7 @@ const Writer = struct { |
| 1063 | 1063 | try self.writeSrcNode(stream, extra.node); |
| 1064 | 1064 | } |
| 1065 | 1065 | |
| 1066 | fn writePtrCastFull(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void { | |
| 1066 | fn writePtrCastFull(self: *Writer, stream: *std.io.Writer, extended: Zir.Inst.Extended.InstData) !void { | |
| 1067 | 1067 | const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).@"struct".backing_integer.?; |
| 1068 | 1068 | const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(FlagsInt, @truncate(extended.small))); |
| 1069 | 1069 | const extra = self.code.extraData(Zir.Inst.BinNode, extended.operand).data; |
| ... | ... | @@ -1079,7 +1079,7 @@ const Writer = struct { |
| 1079 | 1079 | try self.writeSrcNode(stream, extra.node); |
| 1080 | 1080 | } |
| 1081 | 1081 | |
| 1082 | fn writePtrCastNoDest(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void { | |
| 1082 | fn writePtrCastNoDest(self: *Writer, stream: *std.io.Writer, extended: Zir.Inst.Extended.InstData) !void { | |
| 1083 | 1083 | const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).@"struct".backing_integer.?; |
| 1084 | 1084 | const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(FlagsInt, @truncate(extended.small))); |
| 1085 | 1085 | const extra = self.code.extraData(Zir.Inst.UnNode, extended.operand).data; |
| ... | ... | @@ -1090,7 +1090,7 @@ const Writer = struct { |
| 1090 | 1090 | try self.writeSrcNode(stream, extra.node); |
| 1091 | 1091 | } |
| 1092 | 1092 | |
| 1093 | fn writeAtomicLoad(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 1093 | fn writeAtomicLoad(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 1094 | 1094 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 1095 | 1095 | const extra = self.code.extraData(Zir.Inst.AtomicLoad, inst_data.payload_index).data; |
| 1096 | 1096 | |
| ... | ... | @@ -1103,7 +1103,7 @@ const Writer = struct { |
| 1103 | 1103 | try self.writeSrcNode(stream, inst_data.src_node); |
| 1104 | 1104 | } |
| 1105 | 1105 | |
| 1106 | fn writeAtomicStore(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 1106 | fn writeAtomicStore(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 1107 | 1107 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 1108 | 1108 | const extra = self.code.extraData(Zir.Inst.AtomicStore, inst_data.payload_index).data; |
| 1109 | 1109 | |
| ... | ... | @@ -1116,7 +1116,7 @@ const Writer = struct { |
| 1116 | 1116 | try self.writeSrcNode(stream, inst_data.src_node); |
| 1117 | 1117 | } |
| 1118 | 1118 | |
| 1119 | fn writeAtomicRmw(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 1119 | fn writeAtomicRmw(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 1120 | 1120 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 1121 | 1121 | const extra = self.code.extraData(Zir.Inst.AtomicRmw, inst_data.payload_index).data; |
| 1122 | 1122 | |
| ... | ... | @@ -1131,7 +1131,7 @@ const Writer = struct { |
| 1131 | 1131 | try self.writeSrcNode(stream, inst_data.src_node); |
| 1132 | 1132 | } |
| 1133 | 1133 | |
| 1134 | fn writeStructInitAnon(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 1134 | fn writeStructInitAnon(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 1135 | 1135 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 1136 | 1136 | const extra = self.code.extraData(Zir.Inst.StructInitAnon, inst_data.payload_index); |
| 1137 | 1137 | var field_i: u32 = 0; |
| ... | ... | @@ -1152,7 +1152,7 @@ const Writer = struct { |
| 1152 | 1152 | try self.writeSrcNode(stream, inst_data.src_node); |
| 1153 | 1153 | } |
| 1154 | 1154 | |
| 1155 | fn writeStructInitFieldType(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 1155 | fn writeStructInitFieldType(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 1156 | 1156 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 1157 | 1157 | const extra = self.code.extraData(Zir.Inst.FieldType, inst_data.payload_index).data; |
| 1158 | 1158 | try self.writeInstRef(stream, extra.container_type); |
| ... | ... | @@ -1161,7 +1161,7 @@ const Writer = struct { |
| 1161 | 1161 | try self.writeSrcNode(stream, inst_data.src_node); |
| 1162 | 1162 | } |
| 1163 | 1163 | |
| 1164 | fn writeFieldTypeRef(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 1164 | fn writeFieldTypeRef(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 1165 | 1165 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 1166 | 1166 | const extra = self.code.extraData(Zir.Inst.FieldTypeRef, inst_data.payload_index).data; |
| 1167 | 1167 | try self.writeInstRef(stream, extra.container_type); |
| ... | ... | @@ -1171,7 +1171,7 @@ const Writer = struct { |
| 1171 | 1171 | try self.writeSrcNode(stream, inst_data.src_node); |
| 1172 | 1172 | } |
| 1173 | 1173 | |
| 1174 | fn writeNodeMultiOp(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void { | |
| 1174 | fn writeNodeMultiOp(self: *Writer, stream: *std.io.Writer, extended: Zir.Inst.Extended.InstData) !void { | |
| 1175 | 1175 | const extra = self.code.extraData(Zir.Inst.NodeMultiOp, extended.operand); |
| 1176 | 1176 | const operands = self.code.refSlice(extra.end, extended.small); |
| 1177 | 1177 | |
| ... | ... | @@ -1185,7 +1185,7 @@ const Writer = struct { |
| 1185 | 1185 | |
| 1186 | 1186 | fn writeInstNode( |
| 1187 | 1187 | self: *Writer, |
| 1188 | stream: *std.io.BufferedWriter, | |
| 1188 | stream: *std.io.Writer, | |
| 1189 | 1189 | inst: Zir.Inst.Index, |
| 1190 | 1190 | ) Error!void { |
| 1191 | 1191 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].inst_node; |
| ... | ... | @@ -1196,7 +1196,7 @@ const Writer = struct { |
| 1196 | 1196 | |
| 1197 | 1197 | fn writeAsm( |
| 1198 | 1198 | self: *Writer, |
| 1199 | stream: *std.io.BufferedWriter, | |
| 1199 | stream: *std.io.Writer, | |
| 1200 | 1200 | extended: Zir.Inst.Extended.InstData, |
| 1201 | 1201 | tmpl_is_expr: bool, |
| 1202 | 1202 | ) !void { |
| ... | ... | @@ -1274,7 +1274,7 @@ const Writer = struct { |
| 1274 | 1274 | try self.writeSrcNode(stream, extra.data.src_node); |
| 1275 | 1275 | } |
| 1276 | 1276 | |
| 1277 | fn writeOverflowArithmetic(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void { | |
| 1277 | fn writeOverflowArithmetic(self: *Writer, stream: *std.io.Writer, extended: Zir.Inst.Extended.InstData) !void { | |
| 1278 | 1278 | const extra = self.code.extraData(Zir.Inst.BinNode, extended.operand).data; |
| 1279 | 1279 | |
| 1280 | 1280 | try self.writeInstRef(stream, extra.lhs); |
| ... | ... | @@ -1286,7 +1286,7 @@ const Writer = struct { |
| 1286 | 1286 | |
| 1287 | 1287 | fn writeCall( |
| 1288 | 1288 | self: *Writer, |
| 1289 | stream: *std.io.BufferedWriter, | |
| 1289 | stream: *std.io.Writer, | |
| 1290 | 1290 | inst: Zir.Inst.Index, |
| 1291 | 1291 | comptime kind: enum { direct, field }, |
| 1292 | 1292 | ) !void { |
| ... | ... | @@ -1337,7 +1337,7 @@ const Writer = struct { |
| 1337 | 1337 | try self.writeSrcNode(stream, inst_data.src_node); |
| 1338 | 1338 | } |
| 1339 | 1339 | |
| 1340 | fn writeBlock(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 1340 | fn writeBlock(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 1341 | 1341 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 1342 | 1342 | const extra = self.code.extraData(Zir.Inst.Block, inst_data.payload_index); |
| 1343 | 1343 | const body = self.code.bodySlice(extra.end, extra.data.body_len); |
| ... | ... | @@ -1346,7 +1346,7 @@ const Writer = struct { |
| 1346 | 1346 | try self.writeSrcNode(stream, inst_data.src_node); |
| 1347 | 1347 | } |
| 1348 | 1348 | |
| 1349 | fn writeBlockComptime(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 1349 | fn writeBlockComptime(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 1350 | 1350 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 1351 | 1351 | const extra = self.code.extraData(Zir.Inst.BlockComptime, inst_data.payload_index); |
| 1352 | 1352 | const body = self.code.bodySlice(extra.end, extra.data.body_len); |
| ... | ... | @@ -1356,7 +1356,7 @@ const Writer = struct { |
| 1356 | 1356 | try self.writeSrcNode(stream, inst_data.src_node); |
| 1357 | 1357 | } |
| 1358 | 1358 | |
| 1359 | fn writeCondBr(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 1359 | fn writeCondBr(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 1360 | 1360 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 1361 | 1361 | const extra = self.code.extraData(Zir.Inst.CondBr, inst_data.payload_index); |
| 1362 | 1362 | const then_body = self.code.bodySlice(extra.end, extra.data.then_body_len); |
| ... | ... | @@ -1370,7 +1370,7 @@ const Writer = struct { |
| 1370 | 1370 | try self.writeSrcNode(stream, inst_data.src_node); |
| 1371 | 1371 | } |
| 1372 | 1372 | |
| 1373 | fn writeTry(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 1373 | fn writeTry(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 1374 | 1374 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 1375 | 1375 | const extra = self.code.extraData(Zir.Inst.Try, inst_data.payload_index); |
| 1376 | 1376 | const body = self.code.bodySlice(extra.end, extra.data.body_len); |
| ... | ... | @@ -1381,7 +1381,7 @@ const Writer = struct { |
| 1381 | 1381 | try self.writeSrcNode(stream, inst_data.src_node); |
| 1382 | 1382 | } |
| 1383 | 1383 | |
| 1384 | fn writeStructDecl(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void { | |
| 1384 | fn writeStructDecl(self: *Writer, stream: *std.io.Writer, extended: Zir.Inst.Extended.InstData) !void { | |
| 1385 | 1385 | const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small); |
| 1386 | 1386 | |
| 1387 | 1387 | const extra = self.code.extraData(Zir.Inst.StructDecl, extended.operand); |
| ... | ... | @@ -1573,7 +1573,7 @@ const Writer = struct { |
| 1573 | 1573 | try self.writeSrcNode(stream, .zero); |
| 1574 | 1574 | } |
| 1575 | 1575 | |
| 1576 | fn writeUnionDecl(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void { | |
| 1576 | fn writeUnionDecl(self: *Writer, stream: *std.io.Writer, extended: Zir.Inst.Extended.InstData) !void { | |
| 1577 | 1577 | const small = @as(Zir.Inst.UnionDecl.Small, @bitCast(extended.small)); |
| 1578 | 1578 | |
| 1579 | 1579 | const extra = self.code.extraData(Zir.Inst.UnionDecl, extended.operand); |
| ... | ... | @@ -1724,7 +1724,7 @@ const Writer = struct { |
| 1724 | 1724 | try self.writeSrcNode(stream, .zero); |
| 1725 | 1725 | } |
| 1726 | 1726 | |
| 1727 | fn writeEnumDecl(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void { | |
| 1727 | fn writeEnumDecl(self: *Writer, stream: *std.io.Writer, extended: Zir.Inst.Extended.InstData) !void { | |
| 1728 | 1728 | const small = @as(Zir.Inst.EnumDecl.Small, @bitCast(extended.small)); |
| 1729 | 1729 | |
| 1730 | 1730 | const extra = self.code.extraData(Zir.Inst.EnumDecl, extended.operand); |
| ... | ... | @@ -1845,7 +1845,7 @@ const Writer = struct { |
| 1845 | 1845 | |
| 1846 | 1846 | fn writeOpaqueDecl( |
| 1847 | 1847 | self: *Writer, |
| 1848 | stream: *std.io.BufferedWriter, | |
| 1848 | stream: *std.io.Writer, | |
| 1849 | 1849 | extended: Zir.Inst.Extended.InstData, |
| 1850 | 1850 | ) !void { |
| 1851 | 1851 | const small = @as(Zir.Inst.OpaqueDecl.Small, @bitCast(extended.small)); |
| ... | ... | @@ -1887,7 +1887,7 @@ const Writer = struct { |
| 1887 | 1887 | try self.writeSrcNode(stream, .zero); |
| 1888 | 1888 | } |
| 1889 | 1889 | |
| 1890 | fn writeTupleDecl(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void { | |
| 1890 | fn writeTupleDecl(self: *Writer, stream: *std.io.Writer, extended: Zir.Inst.Extended.InstData) !void { | |
| 1891 | 1891 | const fields_len = extended.small; |
| 1892 | 1892 | assert(fields_len != 0); |
| 1893 | 1893 | const extra = self.code.extraData(Zir.Inst.TupleDecl, extended.operand); |
| ... | ... | @@ -1915,7 +1915,7 @@ const Writer = struct { |
| 1915 | 1915 | |
| 1916 | 1916 | fn writeErrorSetDecl( |
| 1917 | 1917 | self: *Writer, |
| 1918 | stream: *std.io.BufferedWriter, | |
| 1918 | stream: *std.io.Writer, | |
| 1919 | 1919 | inst: Zir.Inst.Index, |
| 1920 | 1920 | ) !void { |
| 1921 | 1921 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| ... | ... | @@ -1940,7 +1940,7 @@ const Writer = struct { |
| 1940 | 1940 | try self.writeSrcNode(stream, inst_data.src_node); |
| 1941 | 1941 | } |
| 1942 | 1942 | |
| 1943 | fn writeSwitchBlockErrUnion(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 1943 | fn writeSwitchBlockErrUnion(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 1944 | 1944 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 1945 | 1945 | const extra = self.code.extraData(Zir.Inst.SwitchBlockErrUnion, inst_data.payload_index); |
| 1946 | 1946 | |
| ... | ... | @@ -2077,7 +2077,7 @@ const Writer = struct { |
| 2077 | 2077 | try self.writeSrcNode(stream, inst_data.src_node); |
| 2078 | 2078 | } |
| 2079 | 2079 | |
| 2080 | fn writeSwitchBlock(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 2080 | fn writeSwitchBlock(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 2081 | 2081 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 2082 | 2082 | const extra = self.code.extraData(Zir.Inst.SwitchBlock, inst_data.payload_index); |
| 2083 | 2083 | |
| ... | ... | @@ -2207,7 +2207,7 @@ const Writer = struct { |
| 2207 | 2207 | try self.writeSrcNode(stream, inst_data.src_node); |
| 2208 | 2208 | } |
| 2209 | 2209 | |
| 2210 | fn writePlNodeField(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 2210 | fn writePlNodeField(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 2211 | 2211 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 2212 | 2212 | const extra = self.code.extraData(Zir.Inst.Field, inst_data.payload_index).data; |
| 2213 | 2213 | const name = self.code.nullTerminatedString(extra.field_name_start); |
| ... | ... | @@ -2216,7 +2216,7 @@ const Writer = struct { |
| 2216 | 2216 | try self.writeSrcNode(stream, inst_data.src_node); |
| 2217 | 2217 | } |
| 2218 | 2218 | |
| 2219 | fn writePlNodeFieldNamed(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 2219 | fn writePlNodeFieldNamed(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 2220 | 2220 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 2221 | 2221 | const extra = self.code.extraData(Zir.Inst.FieldNamed, inst_data.payload_index).data; |
| 2222 | 2222 | try self.writeInstRef(stream, extra.lhs); |
| ... | ... | @@ -2226,7 +2226,7 @@ const Writer = struct { |
| 2226 | 2226 | try self.writeSrcNode(stream, inst_data.src_node); |
| 2227 | 2227 | } |
| 2228 | 2228 | |
| 2229 | fn writeAs(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 2229 | fn writeAs(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 2230 | 2230 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 2231 | 2231 | const extra = self.code.extraData(Zir.Inst.As, inst_data.payload_index).data; |
| 2232 | 2232 | try self.writeInstRef(stream, extra.dest_type); |
| ... | ... | @@ -2238,7 +2238,7 @@ const Writer = struct { |
| 2238 | 2238 | |
| 2239 | 2239 | fn writeNode( |
| 2240 | 2240 | self: *Writer, |
| 2241 | stream: *std.io.BufferedWriter, | |
| 2241 | stream: *std.io.Writer, | |
| 2242 | 2242 | inst: Zir.Inst.Index, |
| 2243 | 2243 | ) Error!void { |
| 2244 | 2244 | const src_node = self.code.instructions.items(.data)[@intFromEnum(inst)].node; |
| ... | ... | @@ -2248,7 +2248,7 @@ const Writer = struct { |
| 2248 | 2248 | |
| 2249 | 2249 | fn writeStrTok( |
| 2250 | 2250 | self: *Writer, |
| 2251 | stream: *std.io.BufferedWriter, | |
| 2251 | stream: *std.io.Writer, | |
| 2252 | 2252 | inst: Zir.Inst.Index, |
| 2253 | 2253 | ) Error!void { |
| 2254 | 2254 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].str_tok; |
| ... | ... | @@ -2257,7 +2257,7 @@ const Writer = struct { |
| 2257 | 2257 | try self.writeSrcTok(stream, inst_data.src_tok); |
| 2258 | 2258 | } |
| 2259 | 2259 | |
| 2260 | fn writeStrOp(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 2260 | fn writeStrOp(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 2261 | 2261 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].str_op; |
| 2262 | 2262 | const str = inst_data.getStr(self.code); |
| 2263 | 2263 | try self.writeInstRef(stream, inst_data.operand); |
| ... | ... | @@ -2266,7 +2266,7 @@ const Writer = struct { |
| 2266 | 2266 | |
| 2267 | 2267 | fn writeFunc( |
| 2268 | 2268 | self: *Writer, |
| 2269 | stream: *std.io.BufferedWriter, | |
| 2269 | stream: *std.io.Writer, | |
| 2270 | 2270 | inst: Zir.Inst.Index, |
| 2271 | 2271 | inferred_error_set: bool, |
| 2272 | 2272 | ) !void { |
| ... | ... | @@ -2317,7 +2317,7 @@ const Writer = struct { |
| 2317 | 2317 | ); |
| 2318 | 2318 | } |
| 2319 | 2319 | |
| 2320 | fn writeFuncFancy(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 2320 | fn writeFuncFancy(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 2321 | 2321 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 2322 | 2322 | const extra = self.code.extraData(Zir.Inst.FuncFancy, inst_data.payload_index); |
| 2323 | 2323 | |
| ... | ... | @@ -2376,7 +2376,7 @@ const Writer = struct { |
| 2376 | 2376 | ); |
| 2377 | 2377 | } |
| 2378 | 2378 | |
| 2379 | fn writeAllocExtended(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void { | |
| 2379 | fn writeAllocExtended(self: *Writer, stream: *std.io.Writer, extended: Zir.Inst.Extended.InstData) !void { | |
| 2380 | 2380 | const extra = self.code.extraData(Zir.Inst.AllocExtended, extended.operand); |
| 2381 | 2381 | const small = @as(Zir.Inst.AllocExtended.Small, @bitCast(extended.small)); |
| 2382 | 2382 | |
| ... | ... | @@ -2399,7 +2399,7 @@ const Writer = struct { |
| 2399 | 2399 | try self.writeSrcNode(stream, extra.data.src_node); |
| 2400 | 2400 | } |
| 2401 | 2401 | |
| 2402 | fn writeTypeofPeer(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void { | |
| 2402 | fn writeTypeofPeer(self: *Writer, stream: *std.io.Writer, extended: Zir.Inst.Extended.InstData) !void { | |
| 2403 | 2403 | const extra = self.code.extraData(Zir.Inst.TypeOfPeer, extended.operand); |
| 2404 | 2404 | const body = self.code.bodySlice(extra.data.body_index, extra.data.body_len); |
| 2405 | 2405 | try self.writeBracedBody(stream, body); |
| ... | ... | @@ -2412,7 +2412,7 @@ const Writer = struct { |
| 2412 | 2412 | try stream.writeAll("])"); |
| 2413 | 2413 | } |
| 2414 | 2414 | |
| 2415 | fn writeBoolBr(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 2415 | fn writeBoolBr(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 2416 | 2416 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 2417 | 2417 | const extra = self.code.extraData(Zir.Inst.BoolBr, inst_data.payload_index); |
| 2418 | 2418 | const body = self.code.bodySlice(extra.end, extra.data.body_len); |
| ... | ... | @@ -2423,7 +2423,7 @@ const Writer = struct { |
| 2423 | 2423 | try self.writeSrcNode(stream, inst_data.src_node); |
| 2424 | 2424 | } |
| 2425 | 2425 | |
| 2426 | fn writeIntType(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 2426 | fn writeIntType(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 2427 | 2427 | const int_type = self.code.instructions.items(.data)[@intFromEnum(inst)].int_type; |
| 2428 | 2428 | const prefix: u8 = switch (int_type.signedness) { |
| 2429 | 2429 | .signed => 'i', |
| ... | ... | @@ -2433,7 +2433,7 @@ const Writer = struct { |
| 2433 | 2433 | try self.writeSrcNode(stream, int_type.src_node); |
| 2434 | 2434 | } |
| 2435 | 2435 | |
| 2436 | fn writeSaveErrRetIndex(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 2436 | fn writeSaveErrRetIndex(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 2437 | 2437 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].save_err_ret_index; |
| 2438 | 2438 | |
| 2439 | 2439 | try self.writeInstRef(stream, inst_data.operand); |
| ... | ... | @@ -2441,7 +2441,7 @@ const Writer = struct { |
| 2441 | 2441 | try stream.writeAll(")"); |
| 2442 | 2442 | } |
| 2443 | 2443 | |
| 2444 | fn writeRestoreErrRetIndex(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void { | |
| 2444 | fn writeRestoreErrRetIndex(self: *Writer, stream: *std.io.Writer, extended: Zir.Inst.Extended.InstData) !void { | |
| 2445 | 2445 | const extra = self.code.extraData(Zir.Inst.RestoreErrRetIndex, extended.operand).data; |
| 2446 | 2446 | |
| 2447 | 2447 | try self.writeInstRef(stream, extra.block); |
| ... | ... | @@ -2451,7 +2451,7 @@ const Writer = struct { |
| 2451 | 2451 | try self.writeSrcNode(stream, extra.src_node); |
| 2452 | 2452 | } |
| 2453 | 2453 | |
| 2454 | fn writeBreak(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 2454 | fn writeBreak(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 2455 | 2455 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].@"break"; |
| 2456 | 2456 | const extra = self.code.extraData(Zir.Inst.Break, inst_data.payload_index).data; |
| 2457 | 2457 | |
| ... | ... | @@ -2461,7 +2461,7 @@ const Writer = struct { |
| 2461 | 2461 | try stream.writeAll(")"); |
| 2462 | 2462 | } |
| 2463 | 2463 | |
| 2464 | fn writeArrayInit(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 2464 | fn writeArrayInit(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 2465 | 2465 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 2466 | 2466 | |
| 2467 | 2467 | const extra = self.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index); |
| ... | ... | @@ -2477,7 +2477,7 @@ const Writer = struct { |
| 2477 | 2477 | try self.writeSrcNode(stream, inst_data.src_node); |
| 2478 | 2478 | } |
| 2479 | 2479 | |
| 2480 | fn writeArrayInitAnon(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 2480 | fn writeArrayInitAnon(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 2481 | 2481 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 2482 | 2482 | |
| 2483 | 2483 | const extra = self.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index); |
| ... | ... | @@ -2492,7 +2492,7 @@ const Writer = struct { |
| 2492 | 2492 | try self.writeSrcNode(stream, inst_data.src_node); |
| 2493 | 2493 | } |
| 2494 | 2494 | |
| 2495 | fn writeArrayInitSent(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 2495 | fn writeArrayInitSent(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 2496 | 2496 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 2497 | 2497 | |
| 2498 | 2498 | const extra = self.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index); |
| ... | ... | @@ -2512,7 +2512,7 @@ const Writer = struct { |
| 2512 | 2512 | try self.writeSrcNode(stream, inst_data.src_node); |
| 2513 | 2513 | } |
| 2514 | 2514 | |
| 2515 | fn writeUnreachable(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 2515 | fn writeUnreachable(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 2516 | 2516 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].@"unreachable"; |
| 2517 | 2517 | try stream.writeAll(") "); |
| 2518 | 2518 | try self.writeSrcNode(stream, inst_data.src_node); |
| ... | ... | @@ -2520,7 +2520,7 @@ const Writer = struct { |
| 2520 | 2520 | |
| 2521 | 2521 | fn writeFuncCommon( |
| 2522 | 2522 | self: *Writer, |
| 2523 | stream: *std.io.BufferedWriter, | |
| 2523 | stream: *std.io.Writer, | |
| 2524 | 2524 | inferred_error_set: bool, |
| 2525 | 2525 | var_args: bool, |
| 2526 | 2526 | is_noinline: bool, |
| ... | ... | @@ -2557,19 +2557,19 @@ const Writer = struct { |
| 2557 | 2557 | try self.writeSrcNode(stream, src_node); |
| 2558 | 2558 | } |
| 2559 | 2559 | |
| 2560 | fn writeDbgStmt(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 2560 | fn writeDbgStmt(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 2561 | 2561 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt; |
| 2562 | 2562 | try stream.print("{d}, {d})", .{ inst_data.line + 1, inst_data.column + 1 }); |
| 2563 | 2563 | } |
| 2564 | 2564 | |
| 2565 | fn writeDefer(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 2565 | fn writeDefer(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 2566 | 2566 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].@"defer"; |
| 2567 | 2567 | const body = self.code.bodySlice(inst_data.index, inst_data.len); |
| 2568 | 2568 | try self.writeBracedBody(stream, body); |
| 2569 | 2569 | try stream.writeByte(')'); |
| 2570 | 2570 | } |
| 2571 | 2571 | |
| 2572 | fn writeDeferErrCode(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 2572 | fn writeDeferErrCode(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 2573 | 2573 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].defer_err_code; |
| 2574 | 2574 | const extra = self.code.extraData(Zir.Inst.DeferErrCode, inst_data.payload_index).data; |
| 2575 | 2575 | |
| ... | ... | @@ -2582,7 +2582,7 @@ const Writer = struct { |
| 2582 | 2582 | try stream.writeByte(')'); |
| 2583 | 2583 | } |
| 2584 | 2584 | |
| 2585 | fn writeDeclaration(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 2585 | fn writeDeclaration(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 2586 | 2586 | const decl = self.code.getDeclaration(inst); |
| 2587 | 2587 | |
| 2588 | 2588 | const prev_parent_decl_node = self.parent_decl_node; |
| ... | ... | @@ -2639,26 +2639,26 @@ const Writer = struct { |
| 2639 | 2639 | try self.writeSrcNode(stream, .zero); |
| 2640 | 2640 | } |
| 2641 | 2641 | |
| 2642 | fn writeClosureGet(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void { | |
| 2642 | fn writeClosureGet(self: *Writer, stream: *std.io.Writer, extended: Zir.Inst.Extended.InstData) !void { | |
| 2643 | 2643 | try stream.print("{d})) ", .{extended.small}); |
| 2644 | 2644 | const src_node: Ast.Node.Offset = @enumFromInt(@as(i32, @bitCast(extended.operand))); |
| 2645 | 2645 | try self.writeSrcNode(stream, src_node); |
| 2646 | 2646 | } |
| 2647 | 2647 | |
| 2648 | fn writeBuiltinValue(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void { | |
| 2648 | fn writeBuiltinValue(self: *Writer, stream: *std.io.Writer, extended: Zir.Inst.Extended.InstData) !void { | |
| 2649 | 2649 | const val: Zir.Inst.BuiltinValue = @enumFromInt(extended.small); |
| 2650 | 2650 | try stream.print("{s})) ", .{@tagName(val)}); |
| 2651 | 2651 | const src_node: Ast.Node.Offset = @enumFromInt(@as(i32, @bitCast(extended.operand))); |
| 2652 | 2652 | try self.writeSrcNode(stream, src_node); |
| 2653 | 2653 | } |
| 2654 | 2654 | |
| 2655 | fn writeInplaceArithResultTy(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void { | |
| 2655 | fn writeInplaceArithResultTy(self: *Writer, stream: *std.io.Writer, extended: Zir.Inst.Extended.InstData) !void { | |
| 2656 | 2656 | const op: Zir.Inst.InplaceOp = @enumFromInt(extended.small); |
| 2657 | 2657 | try self.writeInstRef(stream, @enumFromInt(extended.operand)); |
| 2658 | 2658 | try stream.print(", {s}))", .{@tagName(op)}); |
| 2659 | 2659 | } |
| 2660 | 2660 | |
| 2661 | fn writeInstRef(self: *Writer, stream: *std.io.BufferedWriter, ref: Zir.Inst.Ref) !void { | |
| 2661 | fn writeInstRef(self: *Writer, stream: *std.io.Writer, ref: Zir.Inst.Ref) !void { | |
| 2662 | 2662 | if (ref == .none) { |
| 2663 | 2663 | return stream.writeAll(".none"); |
| 2664 | 2664 | } else if (ref.toIndex()) |i| { |
| ... | ... | @@ -2669,12 +2669,12 @@ const Writer = struct { |
| 2669 | 2669 | } |
| 2670 | 2670 | } |
| 2671 | 2671 | |
| 2672 | fn writeInstIndex(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 2672 | fn writeInstIndex(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 2673 | 2673 | _ = self; |
| 2674 | 2674 | return stream.print("%{d}", .{@intFromEnum(inst)}); |
| 2675 | 2675 | } |
| 2676 | 2676 | |
| 2677 | fn writeCaptures(self: *Writer, stream: *std.io.BufferedWriter, extra_index: usize, captures_len: u32) !usize { | |
| 2677 | fn writeCaptures(self: *Writer, stream: *std.io.Writer, extra_index: usize, captures_len: u32) !usize { | |
| 2678 | 2678 | if (captures_len == 0) { |
| 2679 | 2679 | try stream.writeAll("{}"); |
| 2680 | 2680 | return extra_index; |
| ... | ... | @@ -2694,7 +2694,7 @@ const Writer = struct { |
| 2694 | 2694 | return extra_index + 2 * captures_len; |
| 2695 | 2695 | } |
| 2696 | 2696 | |
| 2697 | fn writeCapture(self: *Writer, stream: *std.io.BufferedWriter, capture: Zir.Inst.Capture) !void { | |
| 2697 | fn writeCapture(self: *Writer, stream: *std.io.Writer, capture: Zir.Inst.Capture) !void { | |
| 2698 | 2698 | switch (capture.unwrap()) { |
| 2699 | 2699 | .nested => |i| return stream.print("[{d}]", .{i}), |
| 2700 | 2700 | .instruction => |inst| return self.writeInstIndex(stream, inst), |
| ... | ... | @@ -2713,7 +2713,7 @@ const Writer = struct { |
| 2713 | 2713 | |
| 2714 | 2714 | fn writeOptionalInstRef( |
| 2715 | 2715 | self: *Writer, |
| 2716 | stream: *std.io.BufferedWriter, | |
| 2716 | stream: *std.io.Writer, | |
| 2717 | 2717 | prefix: []const u8, |
| 2718 | 2718 | inst: Zir.Inst.Ref, |
| 2719 | 2719 | ) !void { |
| ... | ... | @@ -2724,7 +2724,7 @@ const Writer = struct { |
| 2724 | 2724 | |
| 2725 | 2725 | fn writeOptionalInstRefOrBody( |
| 2726 | 2726 | self: *Writer, |
| 2727 | stream: *std.io.BufferedWriter, | |
| 2727 | stream: *std.io.Writer, | |
| 2728 | 2728 | prefix: []const u8, |
| 2729 | 2729 | ref: Zir.Inst.Ref, |
| 2730 | 2730 | body: []const Zir.Inst.Index, |
| ... | ... | @@ -2742,7 +2742,7 @@ const Writer = struct { |
| 2742 | 2742 | |
| 2743 | 2743 | fn writeFlag( |
| 2744 | 2744 | self: *Writer, |
| 2745 | stream: *std.io.BufferedWriter, | |
| 2745 | stream: *std.io.Writer, | |
| 2746 | 2746 | name: []const u8, |
| 2747 | 2747 | flag: bool, |
| 2748 | 2748 | ) !void { |
| ... | ... | @@ -2751,7 +2751,7 @@ const Writer = struct { |
| 2751 | 2751 | try stream.writeAll(name); |
| 2752 | 2752 | } |
| 2753 | 2753 | |
| 2754 | fn writeSrcNode(self: *Writer, stream: *std.io.BufferedWriter, src_node: Ast.Node.Offset) !void { | |
| 2754 | fn writeSrcNode(self: *Writer, stream: *std.io.Writer, src_node: Ast.Node.Offset) !void { | |
| 2755 | 2755 | const tree = self.tree orelse return; |
| 2756 | 2756 | const abs_node = src_node.toAbsolute(self.parent_decl_node); |
| 2757 | 2757 | const src_span = tree.nodeToSpan(abs_node); |
| ... | ... | @@ -2763,7 +2763,7 @@ const Writer = struct { |
| 2763 | 2763 | }); |
| 2764 | 2764 | } |
| 2765 | 2765 | |
| 2766 | fn writeSrcTok(self: *Writer, stream: *std.io.BufferedWriter, src_tok: Ast.TokenOffset) !void { | |
| 2766 | fn writeSrcTok(self: *Writer, stream: *std.io.Writer, src_tok: Ast.TokenOffset) !void { | |
| 2767 | 2767 | const tree = self.tree orelse return; |
| 2768 | 2768 | const abs_tok = src_tok.toAbsolute(tree.firstToken(self.parent_decl_node)); |
| 2769 | 2769 | const span_start = tree.tokenStart(abs_tok); |
| ... | ... | @@ -2776,7 +2776,7 @@ const Writer = struct { |
| 2776 | 2776 | }); |
| 2777 | 2777 | } |
| 2778 | 2778 | |
| 2779 | fn writeSrcTokAbs(self: *Writer, stream: *std.io.BufferedWriter, src_tok: Ast.TokenIndex) !void { | |
| 2779 | fn writeSrcTokAbs(self: *Writer, stream: *std.io.Writer, src_tok: Ast.TokenIndex) !void { | |
| 2780 | 2780 | const tree = self.tree orelse return; |
| 2781 | 2781 | const span_start = tree.tokenStart(src_tok); |
| 2782 | 2782 | const span_end = span_start + @as(u32, @intCast(tree.tokenSlice(src_tok).len)); |
| ... | ... | @@ -2788,15 +2788,15 @@ const Writer = struct { |
| 2788 | 2788 | }); |
| 2789 | 2789 | } |
| 2790 | 2790 | |
| 2791 | fn writeBracedDecl(self: *Writer, stream: *std.io.BufferedWriter, body: []const Zir.Inst.Index) !void { | |
| 2791 | fn writeBracedDecl(self: *Writer, stream: *std.io.Writer, body: []const Zir.Inst.Index) !void { | |
| 2792 | 2792 | try self.writeBracedBodyConditional(stream, body, self.recurse_decls); |
| 2793 | 2793 | } |
| 2794 | 2794 | |
| 2795 | fn writeBracedBody(self: *Writer, stream: *std.io.BufferedWriter, body: []const Zir.Inst.Index) !void { | |
| 2795 | fn writeBracedBody(self: *Writer, stream: *std.io.Writer, body: []const Zir.Inst.Index) !void { | |
| 2796 | 2796 | try self.writeBracedBodyConditional(stream, body, self.recurse_blocks); |
| 2797 | 2797 | } |
| 2798 | 2798 | |
| 2799 | fn writeBracedBodyConditional(self: *Writer, stream: *std.io.BufferedWriter, body: []const Zir.Inst.Index, enabled: bool) !void { | |
| 2799 | fn writeBracedBodyConditional(self: *Writer, stream: *std.io.Writer, body: []const Zir.Inst.Index, enabled: bool) !void { | |
| 2800 | 2800 | if (body.len == 0) { |
| 2801 | 2801 | try stream.writeAll("{}"); |
| 2802 | 2802 | } else if (enabled) { |
| ... | ... | @@ -2825,7 +2825,7 @@ const Writer = struct { |
| 2825 | 2825 | } |
| 2826 | 2826 | } |
| 2827 | 2827 | |
| 2828 | fn writeBody(self: *Writer, stream: *std.io.BufferedWriter, body: []const Zir.Inst.Index) !void { | |
| 2828 | fn writeBody(self: *Writer, stream: *std.io.Writer, body: []const Zir.Inst.Index) !void { | |
| 2829 | 2829 | for (body) |inst| { |
| 2830 | 2830 | try stream.splatByteAll(' ', self.indent); |
| 2831 | 2831 | try stream.print("%{d} ", .{@intFromEnum(inst)}); |
| ... | ... | @@ -2834,7 +2834,7 @@ const Writer = struct { |
| 2834 | 2834 | } |
| 2835 | 2835 | } |
| 2836 | 2836 | |
| 2837 | fn writeImport(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { | |
| 2837 | fn writeImport(self: *Writer, stream: *std.io.Writer, inst: Zir.Inst.Index) !void { | |
| 2838 | 2838 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_tok; |
| 2839 | 2839 | const extra = self.code.extraData(Zir.Inst.Import, inst_data.payload_index).data; |
| 2840 | 2840 | try self.writeInstRef(stream, extra.res_ty); |
src/print_zoir.zig+4-3| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | pub fn renderToWriter(zoir: Zoir, arena: Allocator, w: *std.io.BufferedWriter) error{ WriteFailed, OutOfMemory }!void { | |
| 1 | pub fn renderToWriter(zoir: Zoir, arena: Allocator, w: *Writer) error{ WriteFailed, OutOfMemory }!void { | |
| 2 | 2 | assert(!zoir.hasCompileErrors()); |
| 3 | 3 | |
| 4 | 4 | const bytes_per_node = comptime n: { |
| ... | ... | @@ -41,12 +41,12 @@ pub fn renderToWriter(zoir: Zoir, arena: Allocator, w: *std.io.BufferedWriter) e |
| 41 | 41 | } |
| 42 | 42 | |
| 43 | 43 | const PrintZon = struct { |
| 44 | w: *std.io.BufferedWriter, | |
| 44 | w: *Writer, | |
| 45 | 45 | arena: Allocator, |
| 46 | 46 | zoir: Zoir, |
| 47 | 47 | indent: u32, |
| 48 | 48 | |
| 49 | const Error = std.io.Writer.Error; | |
| 49 | const Error = Writer.Error; | |
| 50 | 50 | |
| 51 | 51 | fn renderRoot(pz: *PrintZon) Error!void { |
| 52 | 52 | try pz.renderNode(.root); |
| ... | ... | @@ -113,3 +113,4 @@ const std = @import("std"); |
| 113 | 113 | const assert = std.debug.assert; |
| 114 | 114 | const Allocator = std.mem.Allocator; |
| 115 | 115 | const Zoir = std.zig.Zoir; |
| 116 | const Writer = std.io.Writer; |