authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-06-02 21:52:38-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-01 16:35:29-07:00
log1e2aab2f97843572138076b21e2efb568e060a33
treed80cc061081c998926b4707035df03b6495cc854
parent3c98e2c826e1a8650090a889cf3a1560335b2968

std: combine BufferedWriter into Writer


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 {
535535}
536536
537537const MsgWriter = struct {
538 w: std.io.BufferedWriter(4096, std.fs.File.Writer),
538 w: *std.fs.File.Writer,
539539 config: std.io.tty.Config,
540540
541 fn init(config: std.io.tty.Config) MsgWriter {
541 fn init(config: std.io.tty.Config, buffer: []u8) MsgWriter {
542542 std.debug.lockStdErr();
543543 return .{
544 .w = std.io.bufferedWriter(std.io.getStdErr().writer()),
544 .w = std.fs.stderr().writer(buffer),
545545 .config = config,
546546 };
547547 }
lib/compiler/build_runner.zig+9-8
......@@ -12,6 +12,7 @@ const Watch = std.Build.Watch;
1212const Fuzz = std.Build.Fuzz;
1313const Allocator = std.mem.Allocator;
1414const fatal = std.process.fatal;
15const Writer = std.io.Writer;
1516const runner = @This();
1617
1718pub const root = @import("@build");
......@@ -773,7 +774,7 @@ const PrintNode = struct {
773774 last: bool = false,
774775};
775776
776fn printPrefix(node: *PrintNode, stderr: *std.io.BufferedWriter, ttyconf: std.io.tty.Config) !void {
777fn printPrefix(node: *PrintNode, stderr: *Writer, ttyconf: std.io.tty.Config) !void {
777778 const parent = node.parent orelse return;
778779 if (parent.parent == null) return;
779780 try printPrefix(parent, stderr, ttyconf);
......@@ -787,7 +788,7 @@ fn printPrefix(node: *PrintNode, stderr: *std.io.BufferedWriter, ttyconf: std.io
787788 }
788789}
789790
790fn printChildNodePrefix(stderr: *std.io.BufferedWriter, ttyconf: std.io.tty.Config) !void {
791fn printChildNodePrefix(stderr: *Writer, ttyconf: std.io.tty.Config) !void {
791792 try stderr.writeAll(switch (ttyconf) {
792793 .no_color, .windows_api => "+- ",
793794 .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
796797
797798fn printStepStatus(
798799 s: *Step,
799 stderr: *std.io.BufferedWriter,
800 stderr: *Writer,
800801 ttyconf: std.io.tty.Config,
801802 run: *const Run,
802803) !void {
......@@ -876,7 +877,7 @@ fn printStepStatus(
876877
877878fn printStepFailure(
878879 s: *Step,
879 stderr: *std.io.BufferedWriter,
880 stderr: *Writer,
880881 ttyconf: std.io.tty.Config,
881882) !void {
882883 if (s.result_error_bundle.errorMessageCount() > 0) {
......@@ -930,7 +931,7 @@ fn printTreeStep(
930931 b: *std.Build,
931932 s: *Step,
932933 run: *const Run,
933 stderr: *std.io.BufferedWriter,
934 stderr: *Writer,
934935 ttyconf: std.io.tty.Config,
935936 parent_node: *PrintNode,
936937 step_stack: *std.AutoArrayHashMapUnmanaged(*Step, void),
......@@ -1188,7 +1189,7 @@ pub fn printErrorMessages(
11881189 gpa: Allocator,
11891190 failing_step: *Step,
11901191 options: std.zig.ErrorBundle.RenderOptions,
1191 stderr: *std.io.BufferedWriter,
1192 stderr: *Writer,
11921193 prominent_compile_errors: bool,
11931194) !void {
11941195 // Provide context for where these error messages are coming from by
......@@ -1241,7 +1242,7 @@ pub fn printErrorMessages(
12411242 }
12421243}
12431244
1244fn steps(builder: *std.Build, bw: *std.io.BufferedWriter) !void {
1245fn steps(builder: *std.Build, bw: *Writer) !void {
12451246 const allocator = builder.allocator;
12461247 for (builder.top_level_steps.values()) |top_level_step| {
12471248 const name = if (&top_level_step.step == builder.default_step)
......@@ -1254,7 +1255,7 @@ fn steps(builder: *std.Build, bw: *std.io.BufferedWriter) !void {
12541255
12551256var stdio_buffer: [256]u8 = undefined;
12561257
1257fn usage(b: *std.Build, bw: *std.io.BufferedWriter) !void {
1258fn usage(b: *std.Build, bw: *Writer) !void {
12581259 try bw.print(
12591260 \\Usage: {s} build [steps] [options]
12601261 \\
lib/docs/wasm/main.zig+2-1
......@@ -5,6 +5,7 @@ const Ast = std.zig.Ast;
55const Walk = @import("Walk");
66const markdown = @import("markdown.zig");
77const Decl = Walk.Decl;
8const Writer = std.io.Writer;
89
910const fileSourceHtml = @import("html_render.zig").fileSourceHtml;
1011const appendEscaped = @import("html_render.zig").appendEscaped;
......@@ -702,7 +703,7 @@ fn render_docs(
702703 r: markdown.Render,
703704 doc: markdown.Document,
704705 node: markdown.Document.Node.Index,
705 writer: *std.io.BufferedWriter,
706 writer: *Writer,
706707 ) !void {
707708 const decl_index_ptr: *const Decl.Index = @alignCast(@ptrCast(r.context));
708709 const data = doc.nodes.items(.data)[@intFromEnum(node)];
lib/docs/wasm/markdown/Document.zig+2-1
......@@ -5,6 +5,7 @@ const builtin = @import("builtin");
55const assert = std.debug.assert;
66const Allocator = std.mem.Allocator;
77const Render = @import("Render.zig");
8const Writer = std.io.Writer;
89
910nodes: Node.List.Slice,
1011extra: []u32,
......@@ -160,7 +161,7 @@ pub fn deinit(doc: *Document, allocator: Allocator) void {
160161}
161162
162163/// Renders a document directly to a writer using the default renderer.
163pub fn render(doc: Document, writer: *std.io.BufferedWriter) @TypeOf(writer).Error!void {
164pub fn render(doc: Document, writer: *Writer) Writer.Error!void {
164165 const renderer: Render(@TypeOf(writer), void) = .{ .context = {} };
165166 try renderer.render(doc, writer);
166167}
lib/docs/wasm/markdown/Render.zig+10-8
......@@ -5,6 +5,8 @@
55//! for node types for which they require no special rendering.
66
77const std = @import("std");
8const Writer = std.io.Writer;
9
810const Document = @import("Document.zig");
911const Node = Document.Node;
1012const Render = @This();
......@@ -14,10 +16,10 @@ renderFn: *const fn (
1416 r: Render,
1517 doc: Document,
1618 node: Node.Index,
17 writer: *std.io.BufferedWriter,
18) std.io.Writer.Error!void = renderDefault,
19 writer: *Writer,
20) Writer.Error!void = renderDefault,
1921
20pub fn render(r: Render, doc: Document, writer: *std.io.BufferedWriter) std.io.Writer.Error!void {
22pub fn render(r: Render, doc: Document, writer: *Writer) Writer.Error!void {
2123 try r.renderFn(r, doc, .root, writer);
2224}
2325
......@@ -25,8 +27,8 @@ pub fn renderDefault(
2527 r: Render,
2628 doc: Document,
2729 node: Node.Index,
28 writer: *std.io.BufferedWriter,
29) std.io.Writer.Error!void {
30 writer: *Writer,
31) Writer.Error!void {
3032 const data = doc.nodes.items(.data)[@intFromEnum(node)];
3133 switch (doc.nodes.items(.tag)[@intFromEnum(node)]) {
3234 .root => {
......@@ -183,8 +185,8 @@ pub fn renderDefault(
183185pub fn renderInlineNodeText(
184186 doc: Document,
185187 node: Node.Index,
186 writer: *std.io.BufferedWriter,
187) std.io.Writer.Error!void {
188 writer: *Writer,
189) Writer.Error!void {
188190 const data = doc.nodes.items(.data)[@intFromEnum(node)];
189191 switch (doc.nodes.items(.tag)[@intFromEnum(node)]) {
190192 .root,
......@@ -229,7 +231,7 @@ pub fn fmtHtml(bytes: []const u8) std.fmt.Formatter(formatHtml) {
229231 return .{ .data = bytes };
230232}
231233
232fn formatHtml(bytes: []const u8, writer: *std.io.BufferedWriter, comptime fmt: []const u8) !void {
234fn formatHtml(bytes: []const u8, writer: *Writer, comptime fmt: []const u8) !void {
233235 _ = fmt;
234236 for (bytes) |b| {
235237 switch (b) {
lib/std/Build/Cache.zig+2-3
......@@ -286,9 +286,8 @@ pub const HashHelper = struct {
286286
287287pub fn binToHex(bin_digest: BinDigest) HexDigest {
288288 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;
292291 return out_digest;
293292}
294293
lib/std/Build/Cache/Directory.zig+3-7
......@@ -55,15 +55,11 @@ pub fn closeAndFree(self: *Directory, gpa: Allocator) void {
5555 self.* = undefined;
5656}
5757
58pub fn format(
59 self: Directory,
60 bw: *std.io.BufferedWriter,
61 comptime fmt_string: []const u8,
62) !void {
58pub fn format(self: Directory, w: *std.io.Writer, comptime fmt_string: []const u8) !void {
6359 if (fmt_string.len != 0) fmt.invalidFmtError(fmt_string, self);
6460 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);
6763 }
6864}
6965
lib/std/Build/Cache/Path.zig+10-14
......@@ -140,11 +140,7 @@ pub fn toStringZ(p: Path, allocator: Allocator) Allocator.Error![:0]u8 {
140140 return std.fmt.allocPrintZ(allocator, "{f}", .{p});
141141}
142142
143pub fn format(
144 self: Path,
145 bw: *std.io.BufferedWriter,
146 comptime fmt_string: []const u8,
147) !void {
143pub fn format(self: Path, w: *std.io.Writer, comptime fmt_string: []const u8) !void {
148144 if (fmt_string.len == 1) {
149145 // Quote-escape the string.
150146 const stringEscape = std.zig.stringEscape;
......@@ -154,33 +150,33 @@ pub fn format(
154150 else => @compileError("unsupported format string: " ++ fmt_string),
155151 };
156152 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);
159155 }
160156 if (self.sub_path.len > 0) {
161 try stringEscape(self.sub_path, bw, f);
157 try stringEscape(self.sub_path, w, f);
162158 }
163159 return;
164160 }
165161 if (fmt_string.len > 0)
166162 std.fmt.invalidFmtError(fmt_string, self);
167163 if (std.fs.path.isAbsolute(self.sub_path)) {
168 try bw.writeAll(self.sub_path);
164 try w.writeAll(self.sub_path);
169165 return;
170166 }
171167 if (self.root_dir.path) |p| {
172 try bw.writeAll(p);
168 try w.writeAll(p);
173169 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);
176172 }
177173 return;
178174 }
179175 if (self.sub_path.len > 0) {
180 try bw.writeAll(self.sub_path);
176 try w.writeAll(self.sub_path);
181177 return;
182178 }
183 try bw.writeByte('.');
179 try w.writeByte('.');
184180}
185181
186182pub fn eql(self: Path, other: Path) bool {
lib/std/Build/Step/CheckObject.zig+39-44
......@@ -6,6 +6,7 @@ const macho = std.macho;
66const math = std.math;
77const mem = std.mem;
88const testing = std.testing;
9const Writer = std.io.Writer;
910
1011const CheckObject = @This();
1112
......@@ -231,7 +232,7 @@ const ComputeCompareExpected = struct {
231232
232233 pub fn format(
233234 value: ComputeCompareExpected,
234 bw: *std.io.BufferedWriter,
235 bw: *Writer,
235236 comptime fmt: []const u8,
236237 ) !void {
237238 if (fmt.len != 0) std.fmt.invalidFmtError(fmt, value);
......@@ -619,7 +620,7 @@ fn make(step: *Step, make_options: Step.MakeOptions) !void {
619620
620621 fn formatMessageString(
621622 ctx: Ctx,
622 bw: *std.io.BufferedWriter,
623 bw: *Writer,
623624 comptime unused_fmt_string: []const u8,
624625 ) !void {
625626 _ = unused_fmt_string;
......@@ -813,7 +814,7 @@ const MachODumper = struct {
813814 return null;
814815 }
815816
816 fn dumpHeader(hdr: macho.mach_header_64, bw: *std.io.BufferedWriter) !void {
817 fn dumpHeader(hdr: macho.mach_header_64, bw: *Writer) !void {
817818 const cputype = switch (hdr.cputype) {
818819 macho.CPU_TYPE_ARM64 => "ARM64",
819820 macho.CPU_TYPE_X86_64 => "X86_64",
......@@ -881,7 +882,7 @@ const MachODumper = struct {
881882 try bw.writeByte('\n');
882883 }
883884
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 {
885886 // print header first
886887 try bw.print(
887888 \\LC {d}
......@@ -1107,7 +1108,7 @@ const MachODumper = struct {
11071108 }
11081109 }
11091110
1110 fn dumpSymtab(ctx: ObjectContext, bw: *std.io.BufferedWriter) !void {
1111 fn dumpSymtab(ctx: ObjectContext, bw: *Writer) !void {
11111112 try bw.writeAll(symtab_label ++ "\n");
11121113
11131114 for (ctx.symtab.items) |sym| {
......@@ -1178,7 +1179,7 @@ const MachODumper = struct {
11781179 }
11791180 }
11801181
1181 fn dumpIndirectSymtab(ctx: ObjectContext, bw: *std.io.BufferedWriter) !void {
1182 fn dumpIndirectSymtab(ctx: ObjectContext, bw: *Writer) !void {
11821183 try bw.writeAll(indirect_symtab_label ++ "\n");
11831184
11841185 var sects_buffer: [3]macho.section_64 = undefined;
......@@ -1227,7 +1228,7 @@ const MachODumper = struct {
12271228 }
12281229 }
12291230
1230 fn dumpRebaseInfo(ctx: ObjectContext, data: []const u8, bw: *std.io.BufferedWriter) !void {
1231 fn dumpRebaseInfo(ctx: ObjectContext, data: []const u8, bw: *Writer) !void {
12311232 var rebases: std.ArrayList(u64) = .init(ctx.gpa);
12321233 defer rebases.deinit();
12331234 try ctx.parseRebaseInfo(data, &rebases);
......@@ -1324,7 +1325,7 @@ const MachODumper = struct {
13241325 };
13251326 };
13261327
1327 fn dumpBindInfo(ctx: ObjectContext, data: []const u8, bw: *std.io.BufferedWriter) !void {
1328 fn dumpBindInfo(ctx: ObjectContext, data: []const u8, bw: *Writer) !void {
13281329 var bindings: std.ArrayList(Binding) = .init(ctx.gpa);
13291330 defer {
13301331 for (bindings.items) |*b| {
......@@ -1348,8 +1349,7 @@ const MachODumper = struct {
13481349 }
13491350
13501351 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);
13531353
13541354 var seg_id: ?u8 = null;
13551355 var tag: Binding.Tag = .self;
......@@ -1439,15 +1439,14 @@ const MachODumper = struct {
14391439 } else |_| {}
14401440 }
14411441
1442 fn dumpExportsTrie(ctx: ObjectContext, data: []const u8, bw: *std.io.BufferedWriter) !void {
1442 fn dumpExportsTrie(ctx: ObjectContext, data: []const u8, bw: *Writer) !void {
14431443 const seg = ctx.getSegmentByName("__TEXT") orelse return;
14441444
14451445 var arena = std.heap.ArenaAllocator.init(ctx.gpa);
14461446 defer arena.deinit();
14471447
14481448 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);
14511450 try parseTrieNode(arena.allocator(), &br, "", &exports);
14521451
14531452 mem.sort(Export, exports.items, {}, Export.lessThan);
......@@ -1577,7 +1576,7 @@ const MachODumper = struct {
15771576 }
15781577 }
15791578
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 {
15811580 const data = ctx.data[sect.offset..][0..sect.size];
15821581 try bw.print("{s}", .{data});
15831582 }
......@@ -1704,8 +1703,7 @@ const ElfDumper = struct {
17041703
17051704 fn parseAndDumpArchive(step: *Step, check: Check, bytes: []const u8) ![]const u8 {
17061705 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);
17091707
17101708 if (!mem.eql(u8, try br.takeArray(elf.ARMAG.len), elf.ARMAG)) return error.InvalidArchiveMagicNumber;
17111709
......@@ -1779,8 +1777,7 @@ const ElfDumper = struct {
17791777 }
17801778
17811779 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);
17841781 const num = switch (ptr_width) {
17851782 .p32 => try br.takeInt(u32, .big),
17861783 .p64 => try br.takeInt(u64, .big),
......@@ -1807,7 +1804,7 @@ const ElfDumper = struct {
18071804 }
18081805 }
18091806
1810 fn dumpSymtab(ctx: ArchiveContext, bw: *std.io.BufferedWriter) !void {
1807 fn dumpSymtab(ctx: ArchiveContext, bw: *Writer) !void {
18111808 var symbols: std.AutoArrayHashMap(usize, std.ArrayList([]const u8)) = .init(ctx.gpa);
18121809 defer {
18131810 for (symbols.values()) |*value| value.deinit();
......@@ -1827,7 +1824,7 @@ const ElfDumper = struct {
18271824 }
18281825 }
18291826
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 {
18311828 for (ctx.objects.values()) |object| {
18321829 try bw.print("object {s}\n", .{object.name});
18331830 const output = try parseAndDumpObject(step, check, object.data);
......@@ -1850,8 +1847,7 @@ const ElfDumper = struct {
18501847
18511848 fn parseAndDumpObject(step: *Step, check: Check, bytes: []const u8) ![]const u8 {
18521849 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);
18551851
18561852 const hdr = try br.takeStruct(elf.Elf64_Ehdr);
18571853 if (!mem.eql(u8, hdr.e_ident[0..4], "\x7fELF")) return error.InvalidMagicNumber;
......@@ -1944,13 +1940,13 @@ const ElfDumper = struct {
19441940 symtab: Symtab,
19451941 dysymtab: Symtab,
19461942
1947 fn dumpHeader(ctx: ObjectContext, bw: *std.io.BufferedWriter) !void {
1943 fn dumpHeader(ctx: ObjectContext, bw: *Writer) !void {
19481944 try bw.writeAll("header\n");
19491945 try bw.print("type {s}\n", .{@tagName(ctx.hdr.e_type)});
19501946 try bw.print("entry {x}\n", .{ctx.hdr.e_entry});
19511947 }
19521948
1953 fn dumpPhdrs(ctx: ObjectContext, bw: *std.io.BufferedWriter) !void {
1949 fn dumpPhdrs(ctx: ObjectContext, bw: *Writer) !void {
19541950 if (ctx.phdrs.len == 0) return;
19551951
19561952 try bw.writeAll("program headers\n");
......@@ -1989,7 +1985,7 @@ const ElfDumper = struct {
19891985 }
19901986 }
19911987
1992 fn dumpShdrs(ctx: ObjectContext, bw: *std.io.BufferedWriter) !void {
1988 fn dumpShdrs(ctx: ObjectContext, bw: *Writer) !void {
19931989 if (ctx.shdrs.len == 0) return;
19941990
19951991 try bw.writeAll("section headers\n");
......@@ -2006,7 +2002,7 @@ const ElfDumper = struct {
20062002 }
20072003 }
20082004
2009 fn dumpDynamicSection(ctx: ObjectContext, shndx: usize, bw: *std.io.BufferedWriter) !void {
2005 fn dumpDynamicSection(ctx: ObjectContext, shndx: usize, bw: *Writer) !void {
20102006 const shdr = ctx.shdrs[shndx];
20112007 const strtab = ctx.getSectionContents(shdr.sh_link);
20122008 const data = ctx.getSectionContents(shndx);
......@@ -2144,7 +2140,7 @@ const ElfDumper = struct {
21442140 }
21452141 }
21462142
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 {
21482144 const symtab = switch (@"type") {
21492145 .symtab => ctx.symtab,
21502146 .dysymtab => ctx.dysymtab,
......@@ -2226,7 +2222,7 @@ const ElfDumper = struct {
22262222 }
22272223 }
22282224
2229 fn dumpSection(ctx: ObjectContext, shndx: usize, bw: *std.io.BufferedWriter) !void {
2225 fn dumpSection(ctx: ObjectContext, shndx: usize, bw: *Writer) !void {
22302226 const data = ctx.getSectionContents(shndx);
22312227 try bw.print("{s}", .{data});
22322228 }
......@@ -2276,7 +2272,7 @@ const ElfDumper = struct {
22762272
22772273 fn formatShType(
22782274 sh_type: u32,
2279 bw: *std.io.BufferedWriter,
2275 bw: *Writer,
22802276 comptime unused_fmt_string: []const u8,
22812277 ) !void {
22822278 _ = unused_fmt_string;
......@@ -2321,7 +2317,7 @@ const ElfDumper = struct {
23212317
23222318 fn formatPhType(
23232319 ph_type: u32,
2324 bw: *std.io.BufferedWriter,
2320 bw: *Writer,
23252321 comptime unused_fmt_string: []const u8,
23262322 ) !void {
23272323 _ = unused_fmt_string;
......@@ -2353,8 +2349,7 @@ const WasmDumper = struct {
23532349
23542350 fn parseAndDump(step: *Step, check: Check, bytes: []const u8) ![]const u8 {
23552351 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);
23582353
23592354 const buf = try br.takeArray(8);
23602355 if (!mem.eql(u8, buf[0..4], &std.wasm.magic)) return error.InvalidMagicByte;
......@@ -2376,12 +2371,12 @@ const WasmDumper = struct {
23762371 step: *Step,
23772372 check: Check,
23782373 br: *std.io.Reader,
2379 bw: *std.io.BufferedWriter,
2374 bw: *Writer,
23802375 ) !void {
23812376 var section_br: std.io.Reader = undefined;
23822377 switch (check.kind) {
23832378 .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)));
23852380 try parseAndDumpSection(step, section, &section_br, bw);
23862381 } else |err| switch (err) {
23872382 error.InvalidEnumTag => return step.fail("invalid section id", .{}),
......@@ -2396,7 +2391,7 @@ const WasmDumper = struct {
23962391 step: *Step,
23972392 section: std.wasm.Section,
23982393 br: *std.io.Reader,
2399 bw: *std.io.BufferedWriter,
2394 bw: *Writer,
24002395 ) !void {
24012396 try bw.print(
24022397 \\Section {s}
......@@ -2444,7 +2439,7 @@ const WasmDumper = struct {
24442439 }
24452440 }
24462441
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 {
24482443 switch (section) {
24492444 .type => {
24502445 var i: u32 = 0;
......@@ -2575,7 +2570,7 @@ const WasmDumper = struct {
25752570 }
25762571 }
25772572
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 {
25792574 const tag = br.takeEnum(E, .little) catch |err| switch (err) {
25802575 error.InvalidEnumTag => return step.fail("invalid wasm type value", .{}),
25812576 else => |e| return e,
......@@ -2584,7 +2579,7 @@ const WasmDumper = struct {
25842579 return tag;
25852580 }
25862581
2587 fn parseDumpLimits(br: *std.io.Reader, bw: *std.io.BufferedWriter) !void {
2582 fn parseDumpLimits(br: *std.io.Reader, bw: *Writer) !void {
25882583 const flags = try br.takeLeb128(u8);
25892584 const min = try br.takeLeb128(u32);
25902585
......@@ -2592,7 +2587,7 @@ const WasmDumper = struct {
25922587 if (flags != 0) try bw.print("max {x}\n", .{try br.takeLeb128(u32)});
25932588 }
25942589
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 {
25962591 const opcode = br.takeEnum(std.wasm.Opcode, .little) catch |err| switch (err) {
25972592 error.InvalidEnumTag => return step.fail("invalid wasm opcode", .{}),
25982593 else => |e| return e,
......@@ -2612,14 +2607,14 @@ const WasmDumper = struct {
26122607 }
26132608
26142609 /// 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 {
26162611 var subsection_br: std.io.Reader = undefined;
26172612 while (br.seek < br.buffer.len) {
26182613 switch (try parseDumpType(step, std.wasm.NameSubsection, br, bw)) {
26192614 // The module name subsection ... consists of a single name
26202615 // that is assigned to the module itself.
26212616 .module => {
2622 subsection_br.initFixed(try br.take(try br.takeLeb128(u32)));
2617 subsection_br = .fixed(try br.take(try br.takeLeb128(u32)));
26232618 const name = try subsection_br.take(try subsection_br.takeLeb128(u32));
26242619 try bw.print(
26252620 \\name {s}
......@@ -2631,7 +2626,7 @@ const WasmDumper = struct {
26312626 // The function name subsection ... consists of a name map
26322627 // assigning function names to function indices.
26332628 .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)));
26352630 const entries = try br.takeLeb128(u32);
26362631 try bw.print(
26372632 \\names {d}
......@@ -2661,7 +2656,7 @@ const WasmDumper = struct {
26612656 }
26622657 }
26632658
2664 fn parseDumpProducers(br: *std.io.Reader, bw: *std.io.BufferedWriter) !void {
2659 fn parseDumpProducers(br: *std.io.Reader, bw: *Writer) !void {
26652660 const field_count = try br.takeLeb128(u32);
26662661 try bw.print(
26672662 \\fields {d}
......@@ -2689,7 +2684,7 @@ const WasmDumper = struct {
26892684 }
26902685 }
26912686
2692 fn parseDumpFeatures(br: *std.io.Reader, bw: *std.io.BufferedWriter) !void {
2687 fn parseDumpFeatures(br: *std.io.Reader, bw: *Writer) !void {
26932688 const feature_count = try br.takeLeb128(u32);
26942689 try bw.print(
26952690 \\features {d}
lib/std/Build/Step/ConfigHeader.zig+8-7
......@@ -2,6 +2,7 @@ const std = @import("std");
22const ConfigHeader = @This();
33const Step = std.Build.Step;
44const Allocator = std.mem.Allocator;
5const Writer = std.io.Writer;
56
67pub const Style = union(enum) {
78 /// A configure format supported by autotools that uses `#undef foo` to
......@@ -277,7 +278,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
277278fn render_autoconf_undef(
278279 step: *Step,
279280 contents: []const u8,
280 bw: *std.io.BufferedWriter,
281 bw: *Writer,
281282 values: std.StringArrayHashMap(Value),
282283 src_path: []const u8,
283284) !void {
......@@ -382,7 +383,7 @@ fn render_autoconf_at(
382383fn render_cmake(
383384 step: *Step,
384385 contents: []const u8,
385 bw: *std.io.BufferedWriter,
386 bw: *Writer,
386387 values: std.StringArrayHashMap(Value),
387388 src_path: []const u8,
388389) !void {
......@@ -508,7 +509,7 @@ fn render_cmake(
508509
509510fn render_blank(
510511 gpa: std.mem.Allocator,
511 bw: *std.io.BufferedWriter,
512 bw: *Writer,
512513 defines: std.StringArrayHashMap(Value),
513514 include_path: []const u8,
514515 include_guard_override: ?[]const u8,
......@@ -541,11 +542,11 @@ fn render_blank(
541542 , .{include_guard_name});
542543}
543544
544fn render_nasm(bw: *std.io.BufferedWriter, defines: std.StringArrayHashMap(Value)) !void {
545fn render_nasm(bw: *Writer, defines: std.StringArrayHashMap(Value)) !void {
545546 for (defines.keys(), defines.values()) |name, value| try renderValueNasm(bw, name, value);
546547}
547548
548fn renderValueC(bw: *std.io.BufferedWriter, name: []const u8, value: Value) !void {
549fn renderValueC(bw: *Writer, name: []const u8, value: Value) !void {
549550 switch (value) {
550551 .undef => try bw.print("/* #undef {s} */\n", .{name}),
551552 .defined => try bw.print("#define {s}\n", .{name}),
......@@ -557,7 +558,7 @@ fn renderValueC(bw: *std.io.BufferedWriter, name: []const u8, value: Value) !voi
557558 }
558559}
559560
560fn renderValueNasm(bw: *std.io.BufferedWriter, name: []const u8, value: Value) !void {
561fn renderValueNasm(bw: *Writer, name: []const u8, value: Value) !void {
561562 switch (value) {
562563 .undef => try bw.print("; %undef {s}\n", .{name}),
563564 .defined => try bw.print("%define {s}\n", .{name}),
......@@ -570,7 +571,7 @@ fn renderValueNasm(bw: *std.io.BufferedWriter, name: []const u8, value: Value) !
570571}
571572
572573fn expand_variables_autoconf_at(
573 bw: *std.io.BufferedWriter,
574 bw: *Writer,
574575 contents: []const u8,
575576 values: std.StringArrayHashMap(Value),
576577 used: []bool,
lib/std/Build/Step/Run.zig+7-11
......@@ -1015,18 +1015,14 @@ fn populateGeneratedPaths(
10151015 }
10161016}
10171017
1018fn formatTerm(
1019 term: ?std.process.Child.Term,
1020 bw: *std.io.BufferedWriter,
1021 comptime fmt: []const u8,
1022) !void {
1023 _ = fmt;
1018fn formatTerm(term: ?std.process.Child.Term, w: *std.io.Writer, comptime fmt: []const u8) !void {
1019 comptime assert(fmt.len == 0);
10241020 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");
10301026}
10311027fn fmtTerm(term: ?std.process.Child.Term) std.fmt.Formatter(formatTerm) {
10321028 return .{ .data = term };
lib/std/Progress.zig+4-3
......@@ -9,6 +9,7 @@ const Progress = @This();
99const posix = std.posix;
1010const is_big_endian = builtin.cpu.arch.endian() == .big;
1111const is_windows = builtin.os.tag == .windows;
12const Writer = std.io.Writer;
1213
1314/// `null` if the current node (and its children) should
1415/// not print on update()
......@@ -607,7 +608,7 @@ pub fn unlockStdErr() void {
607608}
608609
609610/// Protected by `stderr_mutex`.
610var stderr_buffered_writer: std.io.BufferedWriter = .{
611var stderr_buffered_writer: Writer = .{
611612 .unbuffered_writer = stderr_file_writer.interface(),
612613 .buffer = &.{},
613614};
......@@ -617,13 +618,13 @@ var stderr_file_writer: std.fs.File.Writer = .{
617618 .mode = .streaming,
618619};
619620
620/// Allows the caller to freely write to the returned `std.io.BufferedWriter`,
621/// Allows the caller to freely write to the returned `Writer`,
621622/// initialized with `buffer`, until `unlockStderrWriter` is called.
622623///
623624/// During the lock, any `std.Progress` information is cleared from the terminal.
624625///
625626/// The lock is recursive; the same thread may hold the lock multiple times.
626pub fn lockStderrWriter(buffer: []u8) *std.io.BufferedWriter {
627pub fn lockStderrWriter(buffer: []u8) *Writer {
627628 stderr_mutex.lock();
628629 clearWrittenWithEscapeCodes() catch {};
629630 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 {
152152
153153pub fn format(
154154 self: Version,
155 bw: *std.io.BufferedWriter,
155 bw: *std.io.Writer,
156156 comptime fmt: []const u8,
157157) !void {
158158 if (fmt.len != 0) std.fmt.invalidFmtError(fmt, self);
lib/std/Target.zig+1-1
......@@ -301,7 +301,7 @@ pub const Os = struct {
301301
302302 /// This function is defined to serialize a Zig source code representation of this
303303 /// 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 {
305305 const maybe_name = std.enums.tagName(WindowsVersion, ver);
306306 if (comptime std.mem.eql(u8, fmt_str, "s")) {
307307 if (maybe_name) |name|
lib/std/Uri.zig+7-7
......@@ -5,6 +5,7 @@ const std = @import("std.zig");
55const testing = std.testing;
66const Allocator = std.mem.Allocator;
77const assert = std.debug.assert;
8const Writer = std.io.Writer;
89
910const Uri = @This();
1011
......@@ -84,7 +85,7 @@ pub const Component = union(enum) {
8485 };
8586 }
8687
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 {
8889 if (fmt.len == 0) {
8990 try bw.print("std.Uri.Component{{ .{s} = \"{}\" }}", .{
9091 @tagName(component),
......@@ -136,10 +137,10 @@ pub const Component = union(enum) {
136137 }
137138
138139 pub fn percentEncode(
139 bw: *std.io.BufferedWriter,
140 bw: *Writer,
140141 raw: []const u8,
141142 comptime isValidChar: fn (u8) bool,
142 ) std.io.Writer.Error!void {
143 ) Writer.Error!void {
143144 var start: usize = 0;
144145 for (raw, 0..) |char, index| {
145146 if (isValidChar(char)) continue;
......@@ -280,7 +281,7 @@ pub const WriteToStreamOptions = struct {
280281 port: bool = true,
281282};
282283
283pub fn writeToStream(uri: Uri, options: WriteToStreamOptions, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
284pub fn writeToStream(uri: Uri, options: WriteToStreamOptions, bw: *Writer) Writer.Error!void {
284285 if (options.scheme) {
285286 try bw.print("{s}:", .{uri.scheme});
286287 if (options.authority and uri.host != null) {
......@@ -317,7 +318,7 @@ pub fn writeToStream(uri: Uri, options: WriteToStreamOptions, bw: *std.io.Buffer
317318 }
318319}
319320
320pub fn format(uri: Uri, bw: *std.io.BufferedWriter, comptime fmt: []const u8) std.io.Writer.Error!void {
321pub fn format(uri: Uri, bw: *Writer, comptime fmt: []const u8) Writer.Error!void {
321322 const scheme = comptime std.mem.indexOfScalar(u8, fmt, ';') != null or fmt.len == 0;
322323 const authentication = comptime std.mem.indexOfScalar(u8, fmt, '@') != null or fmt.len == 0;
323324 const authority = comptime std.mem.indexOfScalar(u8, fmt, '+') != null or fmt.len == 0;
......@@ -461,8 +462,7 @@ test remove_dot_segments {
461462
462463/// 5.2.3. Merge Paths
463464fn 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.*);
466466 if (!base.isEmpty()) {
467467 aux.print("{fpath}", .{base}) catch return error.NoSpaceLeft;
468468 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
905905 pub fn print(self: *Self, gpa: Allocator, comptime fmt: []const u8, args: anytype) error{OutOfMemory}!void {
906906 comptime assert(T == u8);
907907 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);
910909 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) {
912911 error.WriteFailed => return error.OutOfMemory,
913912 };
914913 }
915914
916915 pub fn printAssumeCapacity(self: *Self, comptime fmt: []const u8, args: anytype) void {
917916 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;
922920 }
923921
924922 /// Append a value to the list `n` times.
lib/std/builtin.zig+1-1
......@@ -34,7 +34,7 @@ pub const StackTrace = struct {
3434 index: usize,
3535 instruction_addresses: []usize,
3636
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 {
3838 comptime if (fmt.len != 0) unreachable;
3939
4040 // TODO: re-evaluate whether to use format() methods at all.
lib/std/compress/flate.zig+22-41
......@@ -1,6 +1,7 @@
11const builtin = @import("builtin");
22const std = @import("../std.zig");
33const testing = std.testing;
4const Writer = std.io.Writer;
45
56/// Container of the deflate bit stream body. Container adds header before
67/// deflate bit stream and footer after. It can bi gzip, zlib or raw (no header,
......@@ -106,7 +107,7 @@ pub const Container = enum {
106107 }
107108 }
108109
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 {
110111 var bits: [4]u8 = undefined;
111112 switch (hasher.*) {
112113 .gzip => |*gzip| {
......@@ -230,8 +231,7 @@ test "compress/decompress" {
230231 // compress original stream to compressed stream
231232 {
232233 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);
235235 var compress: Compress = .init(&original, .raw);
236236 var compress_br = compress.readable(&.{});
237237 const n = try compress_br.readRemaining(&compressed, .{ .level = level });
......@@ -246,16 +246,14 @@ test "compress/decompress" {
246246 // decompress compressed stream to decompressed stream
247247 {
248248 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);
251250 try Decompress.pump(container, &compressed, &decompressed);
252251 try testing.expectEqualSlices(u8, data, decompressed.getWritten());
253252 }
254253
255254 // compressor writer interface
256255 {
257 var compressed: std.io.BufferedWriter = undefined;
258 compressed.initFixed(&cmp_buf);
256 var compressed: Writer = .fixed(&cmp_buf);
259257 var cmp = try Compress.init(container, &compressed, .{ .level = level });
260258 var cmp_wrt = cmp.writer();
261259 try cmp_wrt.writeAll(data);
......@@ -285,8 +283,7 @@ test "compress/decompress" {
285283 // compress original stream to compressed stream
286284 {
287285 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);
290287 var cmp = try Compress.Huffman.init(container, &compressed);
291288 try cmp.compress(original.reader());
292289 try cmp.finish();
......@@ -300,8 +297,7 @@ test "compress/decompress" {
300297 // decompress compressed stream to decompressed stream
301298 {
302299 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);
305301 try Decompress.pump(container, &compressed, &decompressed);
306302 try testing.expectEqualSlices(u8, data, decompressed.getWritten());
307303 }
......@@ -319,8 +315,7 @@ test "compress/decompress" {
319315 // compress original stream to compressed stream
320316 {
321317 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);
324319 var cmp = try Compress.SimpleCompressor(.store, container).init(&compressed);
325320 try cmp.compress(original.reader());
326321 try cmp.finish();
......@@ -335,8 +330,7 @@ test "compress/decompress" {
335330 // decompress compressed stream to decompressed stream
336331 {
337332 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);
340334 try Decompress.pump(container, &compressed, &decompressed);
341335 try testing.expectEqualSlices(u8, data, decompressed.getWritten());
342336 }
......@@ -491,8 +485,7 @@ fn testInterface(comptime pkg: type, gzip_data: []const u8, plain_data: []const
491485
492486 // decompress
493487 {
494 var plain: std.io.BufferedWriter = undefined;
495 plain.initFixed(&buffer2);
488 var plain: Writer = .fixed(&buffer2);
496489
497490 var in: std.io.Reader = .fixed(gzip_data);
498491 try pkg.decompress(&in, &plain);
......@@ -501,10 +494,8 @@ fn testInterface(comptime pkg: type, gzip_data: []const u8, plain_data: []const
501494
502495 // compress/decompress
503496 {
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);
508499
509500 var in: std.io.Reader = .fixed(plain_data);
510501 try pkg.compress(&in, &compressed, .{});
......@@ -516,10 +507,8 @@ fn testInterface(comptime pkg: type, gzip_data: []const u8, plain_data: []const
516507
517508 // compressor/decompressor
518509 {
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);
523512
524513 var in: std.io.Reader = .fixed(plain_data);
525514 var cmp = try pkg.compressor(&compressed, .{});
......@@ -536,10 +525,8 @@ fn testInterface(comptime pkg: type, gzip_data: []const u8, plain_data: []const
536525 {
537526 // huffman compress/decompress
538527 {
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);
543530
544531 var in: std.io.Reader = .fixed(plain_data);
545532 try pkg.huffman.compress(&in, &compressed);
......@@ -551,10 +538,8 @@ fn testInterface(comptime pkg: type, gzip_data: []const u8, plain_data: []const
551538
552539 // huffman compressor/decompressor
553540 {
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);
558543
559544 var in: std.io.Reader = .fixed(plain_data);
560545 var cmp = try pkg.huffman.compressor(&compressed);
......@@ -571,10 +556,8 @@ fn testInterface(comptime pkg: type, gzip_data: []const u8, plain_data: []const
571556 {
572557 // store compress/decompress
573558 {
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);
578561
579562 var in: std.io.Reader = .fixed(plain_data);
580563 try pkg.store.compress(&in, &compressed);
......@@ -586,10 +569,8 @@ fn testInterface(comptime pkg: type, gzip_data: []const u8, plain_data: []const
586569
587570 // store compressor/decompressor
588571 {
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);
593574
594575 var in: std.io.Reader = .fixed(plain_data);
595576 var cmp = try pkg.store.compressor(&compressed);
lib/std/compress/flate/BlockWriter.zig+14-13
......@@ -3,6 +3,7 @@
33const std = @import("std");
44const io = std.io;
55const assert = std.debug.assert;
6const Writer = std.io.Writer;
67
78const BlockWriter = @This();
89const flate = @import("../flate.zig");
......@@ -13,7 +14,7 @@ const Token = @import("Token.zig");
1314const codegen_order = huffman.codegen_order;
1415const end_code_mark = 255;
1516
16output: *std.io.BufferedWriter,
17output: *Writer,
1718
1819codegen_freq: [huffman.codegen_code_count]u16 = undefined,
1920literal_freq: [huffman.max_num_lit]u16 = undefined,
......@@ -26,7 +27,7 @@ fixed_literal_encoding: Compress.LiteralEncoder,
2627fixed_distance_encoding: Compress.DistanceEncoder,
2728huff_distance: Compress.DistanceEncoder,
2829
29pub fn init(output: *std.io.BufferedWriter) BlockWriter {
30pub fn init(output: *Writer) BlockWriter {
3031 return .{
3132 .output = output,
3233 .fixed_literal_encoding = Compress.fixedLiteralEncoder(),
......@@ -41,15 +42,15 @@ pub fn init(output: *std.io.BufferedWriter) BlockWriter {
4142/// That is after final block; when last byte could be incomplete or
4243/// after stored block; which is aligned to the byte boundary (it has x
4344/// padding bits after first 3 bits).
44pub fn flush(self: *BlockWriter) std.io.Writer.Error!void {
45pub fn flush(self: *BlockWriter) Writer.Error!void {
4546 try self.bit_writer.flush();
4647}
4748
48pub fn setWriter(self: *BlockWriter, new_writer: *std.io.BufferedWriter) void {
49pub fn setWriter(self: *BlockWriter, new_writer: *Writer) void {
4950 self.bit_writer.setWriter(new_writer);
5051}
5152
52fn writeCode(self: *BlockWriter, c: Compress.HuffCode) std.io.Writer.Error!void {
53fn writeCode(self: *BlockWriter, c: Compress.HuffCode) Writer.Error!void {
5354 try self.bit_writer.writeBits(c.code, c.len);
5455}
5556
......@@ -231,7 +232,7 @@ fn dynamicHeader(
231232 num_distances: u32,
232233 num_codegens: u32,
233234 eof: bool,
234) std.io.Writer.Error!void {
235) Writer.Error!void {
235236 const first_bits: u32 = if (eof) 5 else 4;
236237 try self.bit_writer.writeBits(first_bits, 3);
237238 try self.bit_writer.writeBits(num_literals - 257, 5);
......@@ -271,7 +272,7 @@ fn dynamicHeader(
271272 }
272273}
273274
274fn storedHeader(self: *BlockWriter, length: usize, eof: bool) std.io.Writer.Error!void {
275fn storedHeader(self: *BlockWriter, length: usize, eof: bool) Writer.Error!void {
275276 assert(length <= 65535);
276277 const flag: u32 = if (eof) 1 else 0;
277278 try self.bit_writer.writeBits(flag, 3);
......@@ -281,7 +282,7 @@ fn storedHeader(self: *BlockWriter, length: usize, eof: bool) std.io.Writer.Erro
281282 try self.bit_writer.writeBits(~l, 16);
282283}
283284
284fn fixedHeader(self: *BlockWriter, eof: bool) std.io.Writer.Error!void {
285fn fixedHeader(self: *BlockWriter, eof: bool) Writer.Error!void {
285286 // Indicate that we are a fixed Huffman block
286287 var value: u32 = 2;
287288 if (eof) {
......@@ -295,7 +296,7 @@ fn fixedHeader(self: *BlockWriter, eof: bool) std.io.Writer.Error!void {
295296// is larger than the original bytes, the data will be written as a
296297// stored block.
297298// If the input is null, the tokens will always be Huffman encoded.
298pub fn write(self: *BlockWriter, tokens: []const Token, eof: bool, input: ?[]const u8) std.io.Writer.Error!void {
299pub fn write(self: *BlockWriter, tokens: []const Token, eof: bool, input: ?[]const u8) Writer.Error!void {
299300 const lit_and_dist = self.indexTokens(tokens);
300301 const num_literals = lit_and_dist.num_literals;
301302 const num_distances = lit_and_dist.num_distances;
......@@ -373,7 +374,7 @@ pub fn write(self: *BlockWriter, tokens: []const Token, eof: bool, input: ?[]con
373374 try self.writeTokens(tokens, &literal_encoding.codes, &distance_encoding.codes);
374375}
375376
376pub fn storedBlock(self: *BlockWriter, input: []const u8, eof: bool) std.io.Writer.Error!void {
377pub fn storedBlock(self: *BlockWriter, input: []const u8, eof: bool) Writer.Error!void {
377378 try self.storedHeader(input.len, eof);
378379 try self.bit_writer.writeBytes(input);
379380}
......@@ -388,7 +389,7 @@ fn dynamicBlock(
388389 tokens: []const Token,
389390 eof: bool,
390391 input: ?[]const u8,
391) std.io.Writer.Error!void {
392) Writer.Error!void {
392393 const total_tokens = self.indexTokens(tokens);
393394 const num_literals = total_tokens.num_literals;
394395 const num_distances = total_tokens.num_distances;
......@@ -485,7 +486,7 @@ fn writeTokens(
485486 tokens: []const Token,
486487 le_codes: []Compress.HuffCode,
487488 oe_codes: []Compress.HuffCode,
488) std.io.Writer.Error!void {
489) Writer.Error!void {
489490 for (tokens) |t| {
490491 if (t.kind == Token.Kind.literal) {
491492 try self.writeCode(le_codes[t.literal()]);
......@@ -512,7 +513,7 @@ fn writeTokens(
512513
513514// Encodes a block of bytes as either Huffman encoded literals or uncompressed bytes
514515// if the results only gains very little from compression.
515pub fn huffmanBlock(self: *BlockWriter, input: []const u8, eof: bool) std.io.Writer.Error!void {
516pub fn huffmanBlock(self: *BlockWriter, input: []const u8, eof: bool) Writer.Error!void {
516517 // Add everything as literals
517518 histogram(input, &self.literal_freq);
518519
lib/std/compress/flate/Compress.zig+15-16
......@@ -47,6 +47,7 @@ const testing = std.testing;
4747const expect = testing.expect;
4848const mem = std.mem;
4949const math = std.math;
50const Writer = std.io.Writer;
5051
5152const Compress = @This();
5253const Token = @import("Token.zig");
......@@ -142,7 +143,7 @@ const FlushOption = enum { none, flush, final };
142143/// flush tokens to the token writer.
143144///
144145/// Returns number of bytes consumed from `lh`.
145fn tokenizeSlice(c: *Compress, bw: *std.io.BufferedWriter, limit: std.io.Limit, lh: []const u8) !usize {
146fn tokenizeSlice(c: *Compress, bw: *Writer, limit: std.io.Limit, lh: []const u8) !usize {
146147 _ = bw;
147148 _ = limit;
148149 if (true) @panic("TODO");
......@@ -299,7 +300,7 @@ pub fn finish(c: *Compress) !void {
299300
300301/// Use another writer while preserving history. Most probably flush
301302/// should be called on old writer before setting new.
302pub fn setWriter(self: *Compress, new_writer: *std.io.BufferedWriter) void {
303pub fn setWriter(self: *Compress, new_writer: *Writer) void {
303304 self.block_writer.setWriter(new_writer);
304305 self.output = new_writer;
305306}
......@@ -767,7 +768,7 @@ fn byFreq(context: void, a: LiteralNode, b: LiteralNode) bool {
767768
768769fn read(
769770 context: ?*anyopaque,
770 bw: *std.io.BufferedWriter,
771 bw: *Writer,
771772 limit: std.io.Limit,
772773) std.io.Reader.StreamError!usize {
773774 const c: *Compress = @ptrCast(@alignCast(context));
......@@ -1147,8 +1148,7 @@ test "file tokenization" {
11471148 const data = case.data;
11481149
11491150 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);
11521152
11531153 // buffer for decompressed data
11541154 var al = std.ArrayList(u8).init(testing.allocator);
......@@ -1181,10 +1181,10 @@ test "file tokenization" {
11811181}
11821182
11831183const TokenDecoder = struct {
1184 output: *std.io.BufferedWriter,
1184 output: *Writer,
11851185 tokens_count: usize,
11861186
1187 pub fn init(output: *std.io.BufferedWriter) TokenDecoder {
1187 pub fn init(output: *Writer) TokenDecoder {
11881188 return .{
11891189 .output = output,
11901190 .tokens_count = 0,
......@@ -1222,8 +1222,7 @@ test "store simple compressor" {
12221222 //0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21,
12231223 };
12241224
1225 var fbs: std.io.Reader = undefined;
1226 fbs.initFixed(data);
1225 var fbs: std.io.Reader = .fixed(data);
12271226 var al = std.ArrayList(u8).init(testing.allocator);
12281227 defer al.deinit();
12291228
......@@ -1232,7 +1231,7 @@ test "store simple compressor" {
12321231 try cmp.finish();
12331232 try testing.expectEqualSlices(u8, &expected, al.items);
12341233
1235 fbs.initFixed(data);
1234 fbs = .fixed(data);
12361235 try al.resize(0);
12371236
12381237 // huffman only compresoor will also emit store block for this small sample
......@@ -1244,7 +1243,7 @@ test "store simple compressor" {
12441243
12451244test "sliding window match" {
12461245 const data = "Blah blah blah blah blah!";
1247 var win: std.io.BufferedWriter = .{};
1246 var win: Writer = .{};
12481247 try expect(win.write(data) == data.len);
12491248 try expect(win.wp == data.len);
12501249 try expect(win.rp == 0);
......@@ -1263,9 +1262,9 @@ test "sliding window match" {
12631262}
12641263
12651264test "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;
12691268 win.buffer[win.rp] = 0xab;
12701269 try expect(win.lookahead().len == 100);
12711270 try expect(win.tokensBuffer().?.len == win.rp);
......@@ -1273,8 +1272,8 @@ test "sliding window slide" {
12731272 const n = win.slide();
12741273 try expect(n == 32757);
12751274 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);
12781277 try expect(win.lookahead().len == 100);
12791278 try expect(win.tokensBuffer() == null);
12801279}
lib/std/compress/flate/Decompress.zig+10-15
......@@ -23,6 +23,7 @@ const Container = flate.Container;
2323const Token = @import("Token.zig");
2424const testing = std.testing;
2525const Decompress = @This();
26const Writer = std.io.Writer;
2627
2728input: *std.io.Reader,
2829// Hashes, produces checksum, of uncompressed data for gzip/zlib footer.
......@@ -141,7 +142,7 @@ fn decodeSymbol(self: *Decompress, decoder: anytype) !Symbol {
141142
142143pub fn read(
143144 context: ?*anyopaque,
144 bw: *std.io.BufferedWriter,
145 bw: *Writer,
145146 limit: std.io.Limit,
146147) std.io.Reader.StreamError!usize {
147148 const d: *Decompress = @alignCast(@ptrCast(context));
......@@ -159,7 +160,7 @@ pub fn read(
159160
160161fn readInner(
161162 d: *Decompress,
162 bw: *std.io.BufferedWriter,
163 bw: *Writer,
163164 limit: std.io.Limit,
164165) (Error || error{ WriteFailed, EndOfStream })!usize {
165166 const in = d.input;
......@@ -347,7 +348,7 @@ fn readInner(
347348
348349/// Write match (back-reference to the same data slice) starting at `distance`
349350/// back from current write position, and `length` of bytes.
350fn writeMatch(bw: *std.io.BufferedWriter, length: u16, distance: u16) !void {
351fn writeMatch(bw: *Writer, length: u16, distance: u16) !void {
351352 _ = bw;
352353 _ = length;
353354 _ = distance;
......@@ -727,8 +728,7 @@ test "decompress" {
727728 },
728729 };
729730 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);
732732 var aw: std.io.AllocatingWriter = undefined;
733733 aw.init(testing.allocator);
734734 defer aw.deinit();
......@@ -788,8 +788,7 @@ test "gzip decompress" {
788788 },
789789 };
790790 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);
793792 var aw: std.io.AllocatingWriter = undefined;
794793 aw.init(testing.allocator);
795794 defer aw.deinit();
......@@ -818,8 +817,7 @@ test "zlib decompress" {
818817 },
819818 };
820819 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);
823821 var aw: std.io.AllocatingWriter = undefined;
824822 aw.init(testing.allocator);
825823 defer aw.deinit();
......@@ -880,8 +878,7 @@ test "fuzzing tests" {
880878 };
881879
882880 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"));
885882 var aw: std.io.AllocatingWriter = undefined;
886883 aw.init(testing.allocator);
887884 defer aw.deinit();
......@@ -903,8 +900,7 @@ test "bug 18966" {
903900 const input = @embedFile("testdata/fuzz/bug_18966.input");
904901 const expect = @embedFile("testdata/fuzz/bug_18966.expect");
905902
906 var in: std.io.Reader = undefined;
907 in.initFixed(@constCast(input));
903 var in: std.io.Reader = .fixed(input);
908904 var aw: std.io.AllocatingWriter = undefined;
909905 aw.init(testing.allocator);
910906 defer aw.deinit();
......@@ -921,8 +917,7 @@ test "reading into empty buffer" {
921917 0b0000_0001, 0b0000_1100, 0x00, 0b1111_0011, 0xff, // deflate fixed buffer header len, nlen
922918 'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', 0x0a, // non compressed data
923919 };
924 var in: std.io.Reader = undefined;
925 in.initFixed(@constCast(input));
920 var in: std.io.Reader = .fixed(input);
926921 var decomp: Decompress = .init(&in, .raw);
927922 var decompress_br = decomp.readable(&.{});
928923 var buf: [0]u8 = undefined;
lib/std/compress/lzma.zig+11-12
......@@ -6,6 +6,7 @@ const Allocator = std.mem.Allocator;
66const testing = std.testing;
77const expectEqualSlices = std.testing.expectEqualSlices;
88const expectError = std.testing.expectError;
9const Writer = std.io.Writer;
910
1011pub const RangeDecoder = struct {
1112 range: u32,
......@@ -320,7 +321,7 @@ pub const Decode = struct {
320321 self: *Decode,
321322 allocator: Allocator,
322323 br: *std.io.Reader,
323 bw: *std.io.BufferedWriter,
324 bw: *Writer,
324325 buffer: anytype,
325326 decoder: *RangeDecoder,
326327 bytes_read: *usize,
......@@ -417,7 +418,7 @@ pub const Decode = struct {
417418 self: *Decode,
418419 allocator: Allocator,
419420 br: *std.io.Reader,
420 bw: *std.io.BufferedWriter,
421 bw: *Writer,
421422 buffer: anytype,
422423 decoder: *RangeDecoder,
423424 bytes_read: *usize,
......@@ -429,7 +430,7 @@ pub const Decode = struct {
429430 self: *Decode,
430431 allocator: Allocator,
431432 br: *std.io.Reader,
432 bw: *std.io.BufferedWriter,
433 bw: *Writer,
433434 buffer: anytype,
434435 decoder: *RangeDecoder,
435436 bytes_read: *usize,
......@@ -667,8 +668,8 @@ const LzCircularBuffer = struct {
667668 self: *Self,
668669 allocator: Allocator,
669670 lit: u8,
670 bw: *std.io.BufferedWriter,
671 ) std.io.Writer.Error!void {
671 bw: *Writer,
672 ) Writer.Error!void {
672673 try self.set(allocator, self.cursor, lit);
673674 self.cursor += 1;
674675 self.len += 1;
......@@ -686,8 +687,8 @@ const LzCircularBuffer = struct {
686687 allocator: Allocator,
687688 len: usize,
688689 dist: usize,
689 bw: *std.io.BufferedWriter,
690 ) std.io.Writer.Error!void {
690 bw: *Writer,
691 ) Writer.Error!void {
691692 if (dist > self.dict_size or dist > self.len) {
692693 return error.CorruptInput;
693694 }
......@@ -704,7 +705,7 @@ const LzCircularBuffer = struct {
704705 }
705706 }
706707
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 {
708709 if (self.cursor > 0) {
709710 try bw.writeAll(self.buf.items[0..self.cursor]);
710711 self.cursor = 0;
......@@ -839,8 +840,7 @@ test "Vec2D get addition overflow" {
839840
840841fn testDecompress(compressed: []const u8) ![]u8 {
841842 const allocator = std.testing.allocator;
842 var br: std.io.Reader = undefined;
843 br.initFixed(compressed);
843 var br: std.io.Reader = .fixed(compressed);
844844 var decompressor = try Decompress.initOptions(allocator, &br, .{});
845845 defer decompressor.deinit();
846846 const reader = decompressor.reader();
......@@ -927,8 +927,7 @@ test "too small uncompressed size in header" {
927927
928928test "reading one byte" {
929929 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);
932931 var decompressor = try Decompress.initOptions(std.testing.allocator, &br, .{});
933932 defer decompressor.deinit();
934933 var buffer = [1]u8{0};
lib/std/compress/lzma2.zig+6-6
......@@ -1,8 +1,9 @@
11const std = @import("../std.zig");
22const Allocator = std.mem.Allocator;
33const lzma = std.compress.lzma;
4const Writer = std.io.Writer;
45
5pub fn decompress(gpa: Allocator, reader: *std.io.Reader, writer: *std.io.BufferedWriter) std.io.Reader.StreamError!void {
6pub fn decompress(gpa: Allocator, reader: *std.io.Reader, writer: *Writer) std.io.Reader.StreamError!void {
67 var decoder = try Decode.init(gpa);
78 defer decoder.deinit(gpa);
89 return decoder.decompress(gpa, reader, writer);
......@@ -34,7 +35,7 @@ pub const Decode = struct {
3435 self: *Decode,
3536 allocator: Allocator,
3637 reader: *std.io.Reader,
37 writer: *std.io.BufferedWriter,
38 writer: *Writer,
3839 ) !void {
3940 var accum = LzAccumBuffer.init(std.math.maxInt(usize));
4041 defer accum.deinit(allocator);
......@@ -57,7 +58,7 @@ pub const Decode = struct {
5758 self: *Decode,
5859 allocator: Allocator,
5960 br: *std.io.Reader,
60 writer: *std.io.BufferedWriter,
61 writer: *Writer,
6162 accum: *LzAccumBuffer,
6263 status: u8,
6364 ) !void {
......@@ -150,7 +151,7 @@ pub const Decode = struct {
150151 fn parseUncompressed(
151152 allocator: Allocator,
152153 reader: *std.io.Reader,
153 writer: *std.io.BufferedWriter,
154 writer: *Writer,
154155 accum: *LzAccumBuffer,
155156 reset_dict: bool,
156157 ) !void {
......@@ -276,8 +277,7 @@ test decompress {
276277 0x01, 0x00, 0x05, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x02,
277278 0x00, 0x06, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00,
278279 };
279 var stream: std.io.Reader = undefined;
280 stream.initFixed(&compressed);
280 var stream: std.io.Reader = .fixed(&compressed);
281281 var decomp: std.io.AllocatingWriter = undefined;
282282 const decomp_bw = decomp.init(std.testing.allocator);
283283 defer decomp.deinit();
lib/std/compress/zstd/Decompress.zig+5-6
......@@ -3,8 +3,8 @@ const std = @import("std");
33const assert = std.debug.assert;
44const Reader = std.io.Reader;
55const Limit = std.io.Limit;
6const BufferedWriter = std.io.BufferedWriter;
76const zstd = @import("../zstd.zig");
7const Writer = std.io.Writer;
88
99input: *Reader,
1010state: State,
......@@ -77,7 +77,7 @@ pub fn reader(self: *Decompress) Reader {
7777 };
7878}
7979
80fn read(context: ?*anyopaque, bw: *BufferedWriter, limit: Limit) Reader.StreamError!usize {
80fn read(context: ?*anyopaque, bw: *Writer, limit: Limit) Reader.StreamError!usize {
8181 const d: *Decompress = @ptrCast(@alignCast(context));
8282 const in = d.input;
8383
......@@ -139,7 +139,7 @@ fn initFrame(d: *Decompress, window_size_max: usize, magic: Frame.Magic) !void {
139139 }
140140}
141141
142fn readInFrame(d: *Decompress, bw: *BufferedWriter, limit: Limit, state: *State.InFrame) !usize {
142fn readInFrame(d: *Decompress, bw: *Writer, limit: Limit, state: *State.InFrame) !usize {
143143 const in = d.input;
144144
145145 const header_bytes = try in.takeArray(3);
......@@ -649,8 +649,7 @@ pub const Frame = struct {
649649
650650 if (decode.literal_written_count + literal_length > decode.literal_header.regenerated_size)
651651 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..]);
654653 try decodeLiterals(decode, &sub_bw, literal_length);
655654 decode.literal_written_count += literal_length;
656655 // This is not a @memmove; it intentionally repeats patterns
......@@ -698,7 +697,7 @@ pub const Frame = struct {
698697 }
699698
700699 /// 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 {
702701 switch (self.literal_header.block_type) {
703702 .raw => {
704703 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");
77const mem = std.mem;
88const math = std.math;
99const assert = std.debug.assert;
10const Writer = std.io.Writer;
1011
1112pub const block_length = 64;
1213pub const digest_length = 20;
......@@ -252,21 +253,18 @@ pub fn round(d_s: *[5]u32, b: *const [64]u8) void {
252253 d_s[4] +%= v[4];
253254}
254255
255pub fn writable(sha1: *Sha1, buffer: []u8) std.io.BufferedWriter {
256pub fn writer(sha1: *Sha1, buffer: []u8) Writer {
256257 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 },
264260 .buffer = buffer,
265261 };
266262}
267263
268fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) std.io.Writer.Error!usize {
269 const sha1: *Sha1 = @ptrCast(@alignCast(context));
264fn 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;
270268 const start_total = sha1.total_len;
271269 if (sha1.buf_end == 0) {
272270 try writeSplatAligned(sha1, data, splat);
......@@ -299,7 +297,7 @@ fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) std.
299297 return @intCast(sha1.total_len - start_total);
300298}
301299
302fn writeSplatAligned(sha1: *Sha1, data: []const []const u8, splat: usize) std.io.Writer.Error!void {
300fn writeSplatAligned(sha1: *Sha1, data: []const []const u8, splat: usize) Writer.Error!void {
303301 assert(sha1.buf_end == 0);
304302 for (data[0 .. data.len - 1]) |slice| {
305303 var off: usize = 0;
lib/std/crypto/codecs/asn1.zig+4-1
......@@ -1,5 +1,8 @@
11//! ASN.1 types for public consumption.
2
23const std = @import("std");
4const Writer = std.io.Writer;
5
36pub const der = @import("./asn1/der.zig");
47pub const Oid = @import("./asn1/Oid.zig");
58
......@@ -90,7 +93,7 @@ pub const Tag = struct {
9093 };
9194 }
9295
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 {
9497 var tag1: FirstTag = .{
9598 .number = undefined,
9699 .constructed = self.constructed,
lib/std/crypto/codecs/asn1/Oid.zig+5-6
......@@ -9,7 +9,7 @@ pub const EncodeError = error{
99 MissingPrefix,
1010};
1111
12pub fn encode(dot_notation: []const u8, out: *std.io.BufferedWriter) EncodeError!void {
12pub fn encode(dot_notation: []const u8, out: *Writer) EncodeError!void {
1313 var split = std.mem.splitScalar(u8, dot_notation, '.');
1414 const first_str = split.next() orelse return error.MissingPrefix;
1515 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
4141pub const InitError = std.fmt.ParseIntError || error{ MissingPrefix, BufferTooSmall };
4242
4343pub 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);
4645 encode(dot_notation, &bw) catch |err| switch (err) {
4746 error.WriteFailed => return error.BufferTooSmall,
4847 else => |e| return e,
......@@ -58,7 +57,7 @@ test fromDot {
5857 }
5958}
6059
61pub fn toDot(self: Oid, writer: *std.io.BufferedWriter) std.io.Writer.Error!void {
60pub fn toDot(self: Oid, writer: *Writer) Writer.Error!void {
6261 const encoded = self.encoded;
6362 const first = @divTrunc(encoded[0], 40);
6463 const second = encoded[0] - first * 40;
......@@ -90,8 +89,7 @@ test toDot {
9089 var buf: [256]u8 = undefined;
9190
9291 for (test_cases) |t| {
93 var bw: std.io.BufferedWriter = undefined;
94 bw.initFixed(&buf);
92 var bw: Writer = .fixed(&buf);
9593 try toDot(Oid{ .encoded = t.encoded }, &bw);
9694 try std.testing.expectEqualStrings(t.dot_notation, bw.getWritten());
9795 }
......@@ -219,3 +217,4 @@ const encoding_base = 128;
219217const Allocator = std.mem.Allocator;
220218const der = @import("der.zig");
221219const asn1 = @import("../asn1.zig");
220const Writer = std.io.Writer;
lib/std/crypto/ecdsa.zig+2-2
......@@ -6,6 +6,7 @@ const io = std.io;
66const mem = std.mem;
77const sha3 = crypto.hash.sha3;
88const testing = std.testing;
9const Writer = std.io.Writer;
910
1011const EncodingError = crypto.errors.EncodingError;
1112const IdentityElementError = crypto.errors.IdentityElementError;
......@@ -135,8 +136,7 @@ pub fn Ecdsa(comptime Curve: type, comptime Hash: type) type {
135136 /// The maximum length of the DER encoding is der_encoded_length_max.
136137 /// The function returns a slice, that can be shorter than der_encoded_length_max.
137138 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);
140140 const r_len = @as(u8, @intCast(sig.r.len + (sig.r[0] >> 7)));
141141 const s_len = @as(u8, @intCast(sig.s.len + (sig.s[0] >> 7)));
142142 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;
55const io = std.io;
66const mem = std.mem;
77const meta = std.meta;
8const Writer = std.io.Writer;
89
910const fields_delimiter = "$";
1011const fields_delimiter_scalar = '$';
......@@ -188,16 +189,15 @@ pub fn deserialize(comptime HashResult: type, str: []const u8) Error!HashResult
188189///
189190/// `params` can also include any additional parameters.
190191pub 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();
195195}
196196
197197/// Compute the number of bytes required to serialize `params`
198198pub fn calcSize(params: anytype) usize {
199199 var trash: [128]u8 = undefined;
200 var bw: std.io.BufferedWriter = .{
200 var bw: Writer = .{
201201 .unbuffered_writer = .discarding,
202202 .buffer = &trash,
203203 };
......@@ -205,7 +205,7 @@ pub fn calcSize(params: anytype) usize {
205205 return bw.count;
206206}
207207
208fn serializeTo(params: anytype, out: *std.io.BufferedWriter) !void {
208fn serializeTo(params: anytype, out: *Writer) !void {
209209 const HashResult = @TypeOf(params);
210210
211211 if (@hasField(HashResult, version_param_name)) {
lib/std/crypto/scrypt.zig+8-11
......@@ -10,6 +10,7 @@ const math = std.math;
1010const mem = std.mem;
1111const meta = std.meta;
1212const pwhash = crypto.pwhash;
13const Writer = std.io.Writer;
1314
1415const phc_format = @import("phc_encoding.zig");
1516
......@@ -304,26 +305,22 @@ const crypt_format = struct {
304305
305306 /// Serialize parameters into a string in modular crypt format.
306307 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();
311311 }
312312
313313 /// Compute the number of bytes required to serialize `params`
314314 pub fn calcSize(params: anytype) usize {
315315 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) {
321318 error.WriteFailed => unreachable,
322319 };
323 return bw.count;
320 return w.count;
324321 }
325322
326 fn serializeTo(params: anytype, out: *std.io.BufferedWriter) !void {
323 fn serializeTo(params: anytype, out: *Writer) !void {
327324 var header: [14]u8 = undefined;
328325 header[0..3].* = prefix.*;
329326 Codec.intEncode(header[3..4], params.ln);
lib/std/crypto/sha2.zig+4-3
......@@ -18,6 +18,7 @@ const builtin = @import("builtin");
1818const mem = std.mem;
1919const math = std.math;
2020const htest = @import("test.zig");
21const Writer = std.io.Writer;
2122
2223pub const Sha224 = Sha2x32(iv224, 224);
2324pub const Sha256 = Sha2x32(iv256, 256);
......@@ -382,20 +383,20 @@ fn Sha2x32(comptime iv: Iv32, digest_bits: comptime_int) type {
382383 for (&d.s, v) |*dv, vv| dv.* +%= vv;
383384 }
384385
385 pub fn writable(this: *@This(), buffer: []u8) std.io.BufferedWriter {
386 pub fn writable(this: *@This(), buffer: []u8) Writer {
386387 return .{
387388 .unbuffered_writer = .{
388389 .context = this,
389390 .vtable = &.{
390391 .writeSplat = writeSplat,
391 .writeFile = std.io.Writer.unimplementedWriteFile,
392 .writeFile = Writer.unimplementedWriteFile,
392393 },
393394 },
394395 .buffer = buffer,
395396 };
396397 }
397398
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 {
399400 const this: *@This() = @ptrCast(@alignCast(context));
400401 const start_total = this.total_len;
401402 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,
2525
2626/// The encrypted stream from the client to the server. Bytes are pushed here
2727/// via `writer`.
28output: *std.io.BufferedWriter,
28output: *Writer,
2929
3030/// Populated when `error.TlsAlert` is returned.
3131alert: ?tls.Alert = null,
......@@ -72,7 +72,7 @@ pub const SslKeyLog = struct {
7272 client_key_seq: u64,
7373 server_key_seq: u64,
7474 client_random: [32]u8,
75 writer: *std.io.BufferedWriter,
75 writer: *Writer,
7676
7777 fn clientCounter(key_log: *@This()) u64 {
7878 defer key_log.client_key_seq += 1;
......@@ -176,7 +176,7 @@ const InitError = error{
176176pub fn init(
177177 client: *Client,
178178 input: *std.io.Reader,
179 output: *std.io.BufferedWriter,
179 output: *Writer,
180180 options: Options,
181181) InitError!void {
182182 assert(input.buffer.len >= min_buffer_len);
......@@ -1043,7 +1043,7 @@ pub fn eof(c: Client) bool {
10431043 return c.received_close_notify;
10441044}
10451045
1046fn read(context: ?*anyopaque, bw: *std.io.BufferedWriter, limit: std.io.Limit) Reader.StreamError!usize {
1046fn read(context: ?*anyopaque, bw: *Writer, limit: std.io.Limit) Reader.StreamError!usize {
10471047 const c: *Client = @ptrCast(@alignCast(context));
10481048 if (c.eof()) return error.EndOfStream;
10491049 const input = c.input;
......@@ -1226,7 +1226,7 @@ fn failRead(c: *Client, err: ReadError) error{ReadFailed} {
12261226 return error.ReadFailed;
12271227}
12281228
1229fn logSecrets(bw: *std.io.BufferedWriter, context: anytype, secrets: anytype) void {
1229fn logSecrets(bw: *Writer, context: anytype, secrets: anytype) void {
12301230 inline for (@typeInfo(@TypeOf(secrets)).@"struct".fields) |field| bw.print("{s}" ++
12311231 (if (@hasField(@TypeOf(context), "counter")) "_{d}" else "") ++ " {x} {x}\n", .{field.name} ++
12321232 (if (@hasField(@TypeOf(context), "counter")) .{context.counter} else .{}) ++ .{
lib/std/debug.zig+18-18
......@@ -12,6 +12,7 @@ const windows = std.os.windows;
1212const native_arch = builtin.cpu.arch;
1313const native_os = builtin.os.tag;
1414const native_endian = native_arch.endian();
15const Writer = std.io.Writer;
1516
1617pub const MemoryAccessor = @import("debug/MemoryAccessor.zig");
1718pub const FixedBufferReader = @import("debug/FixedBufferReader.zig");
......@@ -208,9 +209,9 @@ pub fn unlockStdErr() void {
208209///
209210/// During the lock, any `std.Progress` information is cleared from the terminal.
210211///
211/// Returns a `std.io.BufferedWriter` with empty buffer, meaning that it is
212/// Returns a `Writer` with empty buffer, meaning that it is
212213/// in fact unbuffered and does not need to be flushed.
213pub fn lockStderrWriter(buffer: []u8) *std.io.BufferedWriter {
214pub fn lockStderrWriter(buffer: []u8) *Writer {
214215 return std.Progress.lockStderrWriter(buffer);
215216}
216217
......@@ -252,7 +253,7 @@ pub fn dumpHex(bytes: []const u8) void {
252253}
253254
254255/// Prints a hexadecimal view of the bytes, returning any error that occurs.
255pub fn dumpHexFallible(bw: *std.io.BufferedWriter, ttyconf: std.io.tty.Config, bytes: []const u8) !void {
256pub fn dumpHexFallible(bw: *Writer, ttyconf: std.io.tty.Config, bytes: []const u8) !void {
256257 var chunks = mem.window(u8, bytes, 16, 16);
257258 while (chunks.next()) |window| {
258259 // 1. Print the address.
......@@ -329,7 +330,7 @@ pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
329330}
330331
331332/// Prints the current stack trace to the provided writer.
332pub fn dumpCurrentStackTraceToWriter(start_addr: ?usize, writer: *std.io.BufferedWriter) !void {
333pub fn dumpCurrentStackTraceToWriter(start_addr: ?usize, writer: *Writer) !void {
333334 if (builtin.target.cpu.arch.isWasm()) {
334335 if (native_os == .wasi) {
335336 try writer.writeAll("Unable to dump stack trace: not implemented for Wasm\n");
......@@ -413,7 +414,7 @@ pub inline fn getContext(context: *ThreadContext) bool {
413414/// Tries to print the stack trace starting from the supplied base pointer to stderr,
414415/// unbuffered, and ignores any error returned.
415416/// TODO multithreaded awareness
416pub fn dumpStackTraceFromBase(context: *ThreadContext, stderr: *std.io.BufferedWriter) void {
417pub fn dumpStackTraceFromBase(context: *ThreadContext, stderr: *Writer) void {
417418 nosuspend {
418419 if (builtin.target.cpu.arch.isWasm()) {
419420 if (native_os == .wasi) {
......@@ -584,8 +585,7 @@ pub fn panicExtra(
584585 const size = 0x1000;
585586 const trunc_msg = "(msg truncated)";
586587 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]);
589589 // a minor annoyance with this is that it will result in the NoSpaceLeft
590590 // error being part of the @panic stack trace (but that error should
591591 // only happen rarely)
......@@ -733,7 +733,7 @@ fn waitForOtherThreadToFinishPanicking() void {
733733
734734pub fn writeStackTrace(
735735 stack_trace: std.builtin.StackTrace,
736 writer: *std.io.BufferedWriter,
736 writer: *Writer,
737737 debug_info: *SelfInfo,
738738 tty_config: io.tty.Config,
739739) !void {
......@@ -964,7 +964,7 @@ pub const StackIterator = struct {
964964};
965965
966966pub fn writeCurrentStackTrace(
967 writer: *std.io.BufferedWriter,
967 writer: *Writer,
968968 debug_info: *SelfInfo,
969969 tty_config: io.tty.Config,
970970 start_addr: ?usize,
......@@ -1052,7 +1052,7 @@ pub noinline fn walkStackWindows(addresses: []usize, existing_context: ?*const w
10521052}
10531053
10541054pub fn writeStackTraceWindows(
1055 writer: *std.io.BufferedWriter,
1055 writer: *Writer,
10561056 debug_info: *SelfInfo,
10571057 tty_config: io.tty.Config,
10581058 context: *const windows.CONTEXT,
......@@ -1072,7 +1072,7 @@ pub fn writeStackTraceWindows(
10721072 }
10731073}
10741074
1075fn printUnknownSource(debug_info: *SelfInfo, writer: *std.io.BufferedWriter, address: usize, tty_config: io.tty.Config) !void {
1075fn printUnknownSource(debug_info: *SelfInfo, writer: *Writer, address: usize, tty_config: io.tty.Config) !void {
10761076 const module_name = debug_info.getModuleNameForAddress(address);
10771077 return printLineInfo(
10781078 writer,
......@@ -1085,14 +1085,14 @@ fn printUnknownSource(debug_info: *SelfInfo, writer: *std.io.BufferedWriter, add
10851085 );
10861086}
10871087
1088fn printLastUnwindError(it: *StackIterator, debug_info: *SelfInfo, writer: *std.io.BufferedWriter, tty_config: io.tty.Config) void {
1088fn printLastUnwindError(it: *StackIterator, debug_info: *SelfInfo, writer: *Writer, tty_config: io.tty.Config) void {
10891089 if (!have_ucontext) return;
10901090 if (it.getLastError()) |unwind_error| {
10911091 printUnwindError(debug_info, writer, unwind_error.address, unwind_error.err, tty_config) catch {};
10921092 }
10931093}
10941094
1095fn printUnwindError(debug_info: *SelfInfo, writer: *std.io.BufferedWriter, address: usize, err: UnwindError, tty_config: io.tty.Config) !void {
1095fn printUnwindError(debug_info: *SelfInfo, writer: *Writer, address: usize, err: UnwindError, tty_config: io.tty.Config) !void {
10961096 const module_name = debug_info.getModuleNameForAddress(address) orelse "???";
10971097 try tty_config.setColor(writer, .dim);
10981098 if (err == error.MissingDebugInfo) {
......@@ -1103,7 +1103,7 @@ fn printUnwindError(debug_info: *SelfInfo, writer: *std.io.BufferedWriter, addre
11031103 try tty_config.setColor(writer, .reset);
11041104}
11051105
1106pub fn printSourceAtAddress(debug_info: *SelfInfo, writer: *std.io.BufferedWriter, address: usize, tty_config: io.tty.Config) !void {
1106pub fn printSourceAtAddress(debug_info: *SelfInfo, writer: *Writer, address: usize, tty_config: io.tty.Config) !void {
11071107 const module = debug_info.getModuleForAddress(address) catch |err| switch (err) {
11081108 error.MissingDebugInfo, error.InvalidDebugInfo => return printUnknownSource(debug_info, writer, address, tty_config),
11091109 else => return err,
......@@ -1127,7 +1127,7 @@ pub fn printSourceAtAddress(debug_info: *SelfInfo, writer: *std.io.BufferedWrite
11271127}
11281128
11291129fn printLineInfo(
1130 writer: *std.io.BufferedWriter,
1130 writer: *Writer,
11311131 source_location: ?SourceLocation,
11321132 address: usize,
11331133 symbol_name: []const u8,
......@@ -1174,7 +1174,7 @@ fn printLineInfo(
11741174 }
11751175}
11761176
1177fn printLineFromFileAnyOs(writer: *std.io.BufferedWriter, source_location: SourceLocation) !void {
1177fn printLineFromFileAnyOs(writer: *Writer, source_location: SourceLocation) !void {
11781178 // Need this to always block even in async I/O mode, because this could potentially
11791179 // be called from e.g. the event loop code crashing.
11801180 var f = try fs.cwd().openFile(source_location.file_name, .{});
......@@ -1567,7 +1567,7 @@ fn handleSegfaultWindowsExtra(info: *windows.EXCEPTION_POINTERS, msg: u8, label:
15671567 posix.abort();
15681568}
15691569
1570fn dumpSegfaultInfoWindows(info: *windows.EXCEPTION_POINTERS, msg: u8, label: ?[]const u8, stderr: *std.io.BufferedWriter) void {
1570fn dumpSegfaultInfoWindows(info: *windows.EXCEPTION_POINTERS, msg: u8, label: ?[]const u8, stderr: *Writer) void {
15711571 _ = switch (msg) {
15721572 0 => stderr.print("{s}\n", .{label.?}),
15731573 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
16991699 t: @This(),
17001700 comptime fmt: []const u8,
17011701 options: std.fmt.FormatOptions,
1702 writer: *std.io.BufferedWriter,
1702 writer: *Writer,
17031703 ) !void {
17041704 if (fmt.len != 0) std.fmt.invalidFmtError(fmt, t);
17051705 _ = options;
lib/std/debug/Dwarf/expression.zig+28-27
......@@ -9,6 +9,7 @@ const abi = std.debug.Dwarf.abi;
99const mem = std.mem;
1010const assert = std.debug.assert;
1111const Allocator = std.mem.Allocator;
12const Writer = std.io.Writer;
1213
1314/// Expressions can be evaluated in different contexts, each requiring its own set of inputs.
1415/// 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 {
826827
827828 return struct {
828829 /// 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 {
830831 if (options.call_frame_context and !comptime isOpcodeValidInCFA(opcode)) return error.InvalidCFAOpcode;
831832 switch (opcode) {
832833 OP.dup,
......@@ -867,14 +868,14 @@ pub fn Builder(comptime options: Options) type {
867868 }
868869
869870 // 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 {
871872 switch (literal) {
872873 0...31 => |n| try writer.writeByte(n + OP.lit0),
873874 else => return error.InvalidLiteral,
874875 }
875876 }
876877
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 {
878879 if (@typeInfo(T) != .int) @compileError("Constants must be integers");
879880
880881 switch (T) {
......@@ -906,12 +907,12 @@ pub fn Builder(comptime options: Options) type {
906907 }
907908 }
908909
909 pub fn writeConstx(writer: *std.io.BufferedWriter, debug_addr_offset: anytype) !void {
910 pub fn writeConstx(writer: *Writer, debug_addr_offset: anytype) !void {
910911 try writer.writeByte(OP.constx);
911912 try leb.writeUleb128(writer, debug_addr_offset);
912913 }
913914
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 {
915916 if (options.call_frame_context) return error.InvalidCFAOpcode;
916917 if (value_bytes.len > 0xff) return error.InvalidTypeLength;
917918 try writer.writeByte(OP.const_type);
......@@ -920,36 +921,36 @@ pub fn Builder(comptime options: Options) type {
920921 try writer.writeAll(value_bytes);
921922 }
922923
923 pub fn writeAddr(writer: *std.io.BufferedWriter, value: Address) !void {
924 pub fn writeAddr(writer: *Writer, value: Address) !void {
924925 try writer.writeByte(OP.addr);
925926 try writer.writeInt(Address, value, options.endian);
926927 }
927928
928 pub fn writeAddrx(writer: *std.io.BufferedWriter, debug_addr_offset: anytype) !void {
929 pub fn writeAddrx(writer: *Writer, debug_addr_offset: anytype) !void {
929930 if (options.call_frame_context) return error.InvalidCFAOpcode;
930931 try writer.writeByte(OP.addrx);
931932 try leb.writeUleb128(writer, debug_addr_offset);
932933 }
933934
934935 // 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 {
936937 try writer.writeByte(OP.fbreg);
937938 try leb.writeIleb128(writer, offset);
938939 }
939940
940 pub fn writeBreg(writer: *std.io.BufferedWriter, register: u8, offset: anytype) !void {
941 pub fn writeBreg(writer: *Writer, register: u8, offset: anytype) !void {
941942 if (register > 31) return error.InvalidRegister;
942943 try writer.writeByte(OP.breg0 + register);
943944 try leb.writeIleb128(writer, offset);
944945 }
945946
946 pub fn writeBregx(writer: *std.io.BufferedWriter, register: anytype, offset: anytype) !void {
947 pub fn writeBregx(writer: *Writer, register: anytype, offset: anytype) !void {
947948 try writer.writeByte(OP.bregx);
948949 try leb.writeUleb128(writer, register);
949950 try leb.writeIleb128(writer, offset);
950951 }
951952
952 pub fn writeRegvalType(writer: *std.io.BufferedWriter, register: anytype, offset: anytype) !void {
953 pub fn writeRegvalType(writer: *Writer, register: anytype, offset: anytype) !void {
953954 if (options.call_frame_context) return error.InvalidCFAOpcode;
954955 try writer.writeByte(OP.regval_type);
955956 try leb.writeUleb128(writer, register);
......@@ -957,29 +958,29 @@ pub fn Builder(comptime options: Options) type {
957958 }
958959
959960 // 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 {
961962 try writer.writeByte(OP.pick);
962963 try writer.writeByte(index);
963964 }
964965
965 pub fn writeDerefSize(writer: *std.io.BufferedWriter, size: u8) !void {
966 pub fn writeDerefSize(writer: *Writer, size: u8) !void {
966967 try writer.writeByte(OP.deref_size);
967968 try writer.writeByte(size);
968969 }
969970
970 pub fn writeXDerefSize(writer: *std.io.BufferedWriter, size: u8) !void {
971 pub fn writeXDerefSize(writer: *Writer, size: u8) !void {
971972 try writer.writeByte(OP.xderef_size);
972973 try writer.writeByte(size);
973974 }
974975
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 {
976977 if (options.call_frame_context) return error.InvalidCFAOpcode;
977978 try writer.writeByte(OP.deref_type);
978979 try writer.writeByte(size);
979980 try leb.writeUleb128(writer, die_offset);
980981 }
981982
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 {
983984 try writer.writeByte(OP.xderef_type);
984985 try writer.writeByte(size);
985986 try leb.writeUleb128(writer, die_offset);
......@@ -987,24 +988,24 @@ pub fn Builder(comptime options: Options) type {
987988
988989 // 2.5.1.4: Arithmetic and Logical Operations
989990
990 pub fn writePlusUconst(writer: *std.io.BufferedWriter, uint_value: anytype) !void {
991 pub fn writePlusUconst(writer: *Writer, uint_value: anytype) !void {
991992 try writer.writeByte(OP.plus_uconst);
992993 try leb.writeUleb128(writer, uint_value);
993994 }
994995
995996 // 2.5.1.5: Control Flow Operations
996997
997 pub fn writeSkip(writer: *std.io.BufferedWriter, offset: i16) !void {
998 pub fn writeSkip(writer: *Writer, offset: i16) !void {
998999 try writer.writeByte(OP.skip);
9991000 try writer.writeInt(i16, offset, options.endian);
10001001 }
10011002
1002 pub fn writeBra(writer: *std.io.BufferedWriter, offset: i16) !void {
1003 pub fn writeBra(writer: *Writer, offset: i16) !void {
10031004 try writer.writeByte(OP.bra);
10041005 try writer.writeInt(i16, offset, options.endian);
10051006 }
10061007
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 {
10081009 if (options.call_frame_context) return error.InvalidCFAOpcode;
10091010 switch (T) {
10101011 u16 => try writer.writeByte(OP.call2),
......@@ -1015,19 +1016,19 @@ pub fn Builder(comptime options: Options) type {
10151016 try writer.writeInt(T, offset, options.endian);
10161017 }
10171018
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 {
10191020 if (options.call_frame_context) return error.InvalidCFAOpcode;
10201021 try writer.writeByte(OP.call_ref);
10211022 try writer.writeInt(if (is_64) u64 else u32, value, options.endian);
10221023 }
10231024
1024 pub fn writeConvert(writer: *std.io.BufferedWriter, die_offset: anytype) !void {
1025 pub fn writeConvert(writer: *Writer, die_offset: anytype) !void {
10251026 if (options.call_frame_context) return error.InvalidCFAOpcode;
10261027 try writer.writeByte(OP.convert);
10271028 try leb.writeUleb128(writer, die_offset);
10281029 }
10291030
1030 pub fn writeReinterpret(writer: *std.io.BufferedWriter, die_offset: anytype) !void {
1031 pub fn writeReinterpret(writer: *Writer, die_offset: anytype) !void {
10311032 if (options.call_frame_context) return error.InvalidCFAOpcode;
10321033 try writer.writeByte(OP.reinterpret);
10331034 try leb.writeUleb128(writer, die_offset);
......@@ -1035,23 +1036,23 @@ pub fn Builder(comptime options: Options) type {
10351036
10361037 // 2.5.1.7: Special Operations
10371038
1038 pub fn writeEntryValue(writer: *std.io.BufferedWriter, expression: []const u8) !void {
1039 pub fn writeEntryValue(writer: *Writer, expression: []const u8) !void {
10391040 try writer.writeByte(OP.entry_value);
10401041 try leb.writeUleb128(writer, expression.len);
10411042 try writer.writeAll(expression);
10421043 }
10431044
10441045 // 2.6: Location Descriptions
1045 pub fn writeReg(writer: *std.io.BufferedWriter, register: u8) !void {
1046 pub fn writeReg(writer: *Writer, register: u8) !void {
10461047 try writer.writeByte(OP.reg0 + register);
10471048 }
10481049
1049 pub fn writeRegx(writer: *std.io.BufferedWriter, register: anytype) !void {
1050 pub fn writeRegx(writer: *Writer, register: anytype) !void {
10501051 try writer.writeByte(OP.regx);
10511052 try leb.writeUleb128(writer, register);
10521053 }
10531054
1054 pub fn writeImplicitValue(writer: *std.io.BufferedWriter, value_bytes: []const u8) !void {
1055 pub fn writeImplicitValue(writer: *Writer, value_bytes: []const u8) !void {
10551056 try writer.writeByte(OP.implicit_value);
10561057 try leb.writeUleb128(writer, value_bytes.len);
10571058 try writer.writeAll(value_bytes);
lib/std/debug/FixedBufferReader.zig+1-2
......@@ -52,8 +52,7 @@ pub fn readIntChecked(
5252}
5353
5454pub 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);
5756 br.seek = fbr.pos;
5857 const result = br.takeLeb128(T);
5958 fbr.pos = br.seek;
lib/std/fmt.zig+10-12
......@@ -13,6 +13,7 @@ const lossyCast = math.lossyCast;
1313const expectFmt = std.testing.expectFmt;
1414const testing = std.testing;
1515const Allocator = std.mem.Allocator;
16const Writer = std.io.Writer;
1617
1718pub const float = @import("fmt/float.zig");
1819
......@@ -92,7 +93,7 @@ pub const Options = struct {
9293/// A user type may be a `struct`, `vector`, `union` or `enum` type.
9394///
9495/// To print literal curly braces, escape them by writing them twice, e.g. `{{` or `}}`.
95pub fn format(bw: *std.io.BufferedWriter, comptime fmt: []const u8, args: anytype) std.io.Writer.Error!void {
96pub fn format(bw: *Writer, comptime fmt: []const u8, args: anytype) Writer.Error!void {
9697 const ArgsType = @TypeOf(args);
9798 const args_type_info = @typeInfo(ArgsType);
9899 if (args_type_info != .@"struct") {
......@@ -452,7 +453,7 @@ fn SliceEscape(comptime case: Case) type {
452453 return struct {
453454 pub fn format(
454455 bytes: []const u8,
455 bw: *std.io.BufferedWriter,
456 bw: *Writer,
456457 comptime fmt: []const u8,
457458 ) !void {
458459 _ = fmt;
......@@ -494,8 +495,7 @@ pub fn fmtSliceEscapeUpper(bytes: []const u8) std.fmt.Formatter(formatSliceEscap
494495/// Asserts the rendered integer value fits in `buffer`.
495496/// Returns the end index within `buffer`.
496497pub 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);
499499 bw.printIntOptions(value, base, case, options) catch unreachable;
500500 return bw.end;
501501}
......@@ -532,7 +532,7 @@ pub fn Formatter(comptime formatFn: anytype) type {
532532 const Data = @typeInfo(@TypeOf(formatFn)).@"fn".params[0].type.?;
533533 return struct {
534534 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 {
536536 try formatFn(self.data, writer, fmt);
537537 }
538538 };
......@@ -830,8 +830,7 @@ pub const BufPrintError = error{
830830
831831/// Print a Formatter string into `buf`. Returns a slice of the bytes printed.
832832pub 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);
835834 bw.print(fmt, args) catch |err| switch (err) {
836835 error.WriteFailed => return error.NoSpaceLeft,
837836 };
......@@ -846,7 +845,7 @@ pub fn bufPrintZ(buf: []u8, comptime fmt: []const u8, args: anytype) BufPrintErr
846845/// Count the characters needed for format.
847846pub fn count(comptime fmt: []const u8, args: anytype) usize {
848847 var trash_buffer: [64]u8 = undefined;
849 var bw: std.io.BufferedWriter = .{
848 var bw: Writer = .{
850849 .unbuffered_writer = .discarding,
851850 .buffer = &trash_buffer,
852851 };
......@@ -1018,16 +1017,15 @@ test "int.padded" {
10181017test "buffer" {
10191018 {
10201019 var buf1: [32]u8 = undefined;
1021 var bw: std.io.BufferedWriter = undefined;
1022 bw.initFixed(&buf1);
1020 var bw: Writer = .fixed(&buf1);
10231021 try bw.printValue("", .{}, 1234, std.options.fmt_max_depth);
10241022 try std.testing.expectEqualStrings("1234", bw.getWritten());
10251023
1026 bw.initFixed(&buf1);
1024 bw = .fixed(&buf1);
10271025 try bw.printValue("c", .{}, 'a', std.options.fmt_max_depth);
10281026 try std.testing.expectEqualStrings("a", bw.getWritten());
10291027
1030 bw.initFixed(&buf1);
1028 bw = .fixed(&buf1);
10311029 try bw.printValue("b", .{}, 0b1100, std.options.fmt_max_depth);
10321030 try std.testing.expectEqualStrings("1100", bw.getWritten());
10331031 }
lib/std/fs/File.zig+26-27
......@@ -844,7 +844,7 @@ pub fn write(self: File, bytes: []const u8) WriteError!usize {
844844 return posix.write(self.handle, bytes);
845845}
846846
847/// One-shot alternative to `std.io.BufferedWriter.writeAll` via `writer`.
847/// One-shot alternative to `std.io.Writer.writeAll` via `writer`.
848848pub fn writeAll(self: File, bytes: []const u8) WriteError!void {
849849 var index: usize = 0;
850850 while (index < bytes.len) {
......@@ -1029,7 +1029,7 @@ pub const Reader = struct {
10291029
10301030 fn stream(
10311031 io_reader: *std.io.Reader,
1032 bw: *BufferedWriter,
1032 bw: *std.io.Writer,
10331033 limit: std.io.Limit,
10341034 ) std.io.Reader.StreamError!usize {
10351035 const r: *Reader = @fieldParentPtr("interface", io_reader);
......@@ -1180,6 +1180,12 @@ pub const Reader = struct {
11801180 .failure => return error.ReadFailed,
11811181 }
11821182 }
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 }
11831189};
11841190
11851191pub const Writer = struct {
......@@ -1189,6 +1195,7 @@ pub const Writer = struct {
11891195 pos: u64 = 0,
11901196 sendfile_err: ?SendfileError = null,
11911197 seek_err: ?SeekError = null,
1198 interface: std.io.Writer,
11921199
11931200 pub const Mode = Reader.Mode;
11941201
......@@ -1205,20 +1212,20 @@ pub const Writer = struct {
12051212 /// vectors through the underlying write calls as possible.
12061213 const max_buffers_len = 16;
12071214
1208 pub fn interface(w: *Writer) std.io.Writer {
1215 pub fn init(file: File, buffer: []u8) std.io.Writer {
12091216 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,
12141225 },
12151226 };
12161227 }
12171228
1218 pub fn writable(w: *Writer, buffer: []u8) std.io.BufferedWriter {
1219 return interface(w).buffered(buffer);
1220 }
1221
12221229 pub fn moveToReader(w: *Writer) Reader {
12231230 defer w.* = undefined;
12241231 return .{
......@@ -1229,9 +1236,10 @@ pub const Writer = struct {
12291236 };
12301237 }
12311238
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);
12341241 const handle = w.file.handle;
1242 if (true) @panic("update to check for buffered data");
12351243 var splat_buffer: [256]u8 = undefined;
12361244 if (is_windows) {
12371245 if (data.len == 1 and splat == 0) return 0;
......@@ -1282,14 +1290,8 @@ pub const Writer = struct {
12821290 };
12831291 }
12841292
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);
12931295 const out_fd = w.file.handle;
12941296 const in_fd = file_reader.file.handle;
12951297 // TODO try using copy_file_range on Linux
......@@ -1299,9 +1301,8 @@ pub const Writer = struct {
12991301 if (native_os == .linux and w.mode == .streaming) sf: {
13001302 // Try using sendfile on Linux.
13011303 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);
13051306 const max_count = 0x7ffff000; // Avoid EINVAL.
13061307 var off: std.os.linux.off_t = undefined;
13071308 const off_ptr: ?*std.os.linux.off_t, const count: usize = switch (file_reader.mode) {
......@@ -1315,8 +1316,7 @@ pub const Writer = struct {
13151316 }
13161317 return 0;
13171318 };
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;
13201320 break :o .{ &off, @min(@intFromEnum(limit), size - file_reader.pos, max_count) };
13211321 },
13221322 .streaming => .{ null, limit.minInt(max_count) },
......@@ -1576,4 +1576,3 @@ const linux = std.os.linux;
15761576const windows = std.os.windows;
15771577const maxInt = std.math.maxInt;
15781578const Alignment = std.mem.Alignment;
1579const 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) {
150150 return .{ .data = paths };
151151}
152152
153fn formatJoin(paths: []const []const u8, bw: *std.io.BufferedWriter, comptime fmt: []const u8) !void {
154 _ = fmt;
153fn formatJoin(paths: []const []const u8, bw: *std.io.Writer, comptime fmt: []const u8) !void {
154 comptime assert(fmt.len == 0);
155155
156156 const first_path_idx = for (paths, 0..) |p, idx| {
157157 if (p.len != 0) break idx;
lib/std/hash/crc.zig+8-10
......@@ -1,4 +1,5 @@
11const std = @import("../std.zig");
2const Writer = std.io.Writer;
23
34pub fn Generic(comptime W: type, comptime algorithm: Algorithm(W)) type {
45 return struct {
......@@ -79,21 +80,18 @@ pub fn Generic(comptime W: type, comptime algorithm: Algorithm(W)) type {
7980 return c.final();
8081 }
8182
82 pub fn writable(self: *Self, buffer: []u8) std.io.BufferedWriter {
83 pub fn writer(self: *Self, buffer: []u8) Writer {
8384 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 },
9187 .buffer = buffer,
9288 };
9389 }
9490
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;
9795 var n: usize = 0;
9896 for (data[0 .. data.len - 1]) |slice| {
9997 self.update(slice);
lib/std/http.zig+70-129
......@@ -1,6 +1,8 @@
11const builtin = @import("builtin");
22const std = @import("std.zig");
33const assert = std.debug.assert;
4const Writer = std.io.Writer;
5const File = std.fs.File;
46
57pub const Client = @import("http/Client.zig");
68pub const Server = @import("http/Server.zig");
......@@ -504,7 +506,7 @@ pub const Reader = struct {
504506
505507 fn contentLengthRead(
506508 ctx: ?*anyopaque,
507 bw: *std.io.BufferedWriter,
509 bw: *Writer,
508510 limit: std.io.Limit,
509511 ) std.io.Reader.StreamError!usize {
510512 const reader: *Reader = @alignCast(@ptrCast(ctx));
......@@ -534,7 +536,7 @@ pub const Reader = struct {
534536
535537 fn chunkedRead(
536538 ctx: ?*anyopaque,
537 bw: *std.io.BufferedWriter,
539 bw: *Writer,
538540 limit: std.io.Limit,
539541 ) std.io.Reader.StreamError!usize {
540542 const reader: *Reader = @alignCast(@ptrCast(ctx));
......@@ -559,7 +561,7 @@ pub const Reader = struct {
559561
560562 fn chunkedReadEndless(
561563 reader: *Reader,
562 bw: *std.io.BufferedWriter,
564 bw: *Writer,
563565 limit: std.io.Limit,
564566 chunk_len_ptr: *RemainingChunkLen,
565567 ) (BodyError || std.io.Reader.StreamError)!usize {
......@@ -747,11 +749,12 @@ pub const Decompressor = struct {
747749pub const BodyWriter = struct {
748750 /// Until the lifetime of `BodyWriter` ends, it is illegal to modify the
749751 /// state of this other than via methods of `BodyWriter`.
750 http_protocol_output: *std.io.BufferedWriter,
752 http_protocol_output: *Writer,
751753 state: State,
752754 elide: bool,
755 interface: Writer,
753756
754 pub const WriteError = std.io.Writer.Error;
757 pub const Error = Writer.Error;
755758
756759 /// How many zeroes to reserve for hex-encoded chunk length.
757760 const chunk_len_digits = 8;
......@@ -787,7 +790,7 @@ pub const BodyWriter = struct {
787790 };
788791
789792 /// 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 {
791794 const out = w.http_protocol_output;
792795 switch (w.state) {
793796 .end, .none, .content_length => return out.flush(),
......@@ -820,7 +823,7 @@ pub const BodyWriter = struct {
820823 /// See also:
821824 /// * `endUnflushed`
822825 /// * `endChunked`
823 pub fn end(w: *BodyWriter) WriteError!void {
826 pub fn end(w: *BodyWriter) Error!void {
824827 try endUnflushed(w);
825828 try w.http_protocol_output.flush();
826829 }
......@@ -836,7 +839,7 @@ pub const BodyWriter = struct {
836839 /// See also:
837840 /// * `end`
838841 /// * `endChunked`
839 pub fn endUnflushed(w: *BodyWriter) WriteError!void {
842 pub fn endUnflushed(w: *BodyWriter) Error!void {
840843 switch (w.state) {
841844 .end => unreachable,
842845 .content_length => |len| {
......@@ -862,7 +865,7 @@ pub const BodyWriter = struct {
862865 /// See also:
863866 /// * `endChunkedUnflushed`
864867 /// * `end`
865 pub fn endChunked(w: *BodyWriter, options: EndChunkedOptions) WriteError!void {
868 pub fn endChunked(w: *BodyWriter, options: EndChunkedOptions) Error!void {
866869 try endChunkedUnflushed(w, options);
867870 try w.http_protocol_output.flush();
868871 }
......@@ -879,7 +882,7 @@ pub const BodyWriter = struct {
879882 /// * `endChunked`
880883 /// * `endUnflushed`
881884 /// * `end`
882 pub fn endChunkedUnflushed(w: *BodyWriter, options: EndChunkedOptions) WriteError!void {
885 pub fn endChunkedUnflushed(w: *BodyWriter, options: EndChunkedOptions) Error!void {
883886 const chunked = &w.state.chunked;
884887 if (w.elide) {
885888 w.state = .end;
......@@ -910,138 +913,78 @@ pub const BodyWriter = struct {
910913 w.state = .end;
911914 }
912915
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);
916921 w.state.content_length -= n;
917922 return n;
918923 }
919924
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);
958930 }
959931
960932 /// 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);
981937 }
982938
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;
994944 return n;
995945 }
996946
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 {
1008951 // If the file size is unknown, we cannot lower to a `writeFile` since we would
1009952 // have to flush the chunk header before knowing the chunk length.
1010953 return error.Unimplemented;
1011954 };
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;
1014957 state: switch (chunked.*) {
1015958 .offset => |off| {
1016959 // 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;
1018961 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);
1021964 chunked.* = .{ .chunk_len = data_len + 2 - n };
1022965 return n;
1023966 },
1024967 .chunk_len => |chunk_len| l: switch (chunk_len) {
1025968 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);
1028971 @memcpy(header_buf, chunk_header_template);
1029972 chunked.* = .{ .offset = off };
1030973 continue :state .{ .offset = off };
1031974 },
1032975 1 => {
1033 try bw.writeByte('\n');
976 try out.writeByte('\n');
1034977 chunked.chunk_len = 0;
1035978 continue :l 0;
1036979 },
1037980 2 => {
1038 try bw.writeByte('\r');
981 try out.writeByte('\r');
1039982 chunked.chunk_len = 1;
1040983 continue :l 1;
1041984 },
1042985 else => {
1043986 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);
1045988 chunked.chunk_len = chunk_len - n;
1046989 return n;
1047990 },
......@@ -1049,47 +992,45 @@ pub const BodyWriter = struct {
1049992 }
1050993 }
1051994
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;
10601001 state: switch (chunked.*) {
10611002 .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));
10641005 return data_len;
10651006 }
1066 const buffered_len = bw.end - offset - chunk_header_template.len;
1007 const buffered_len = out.end - offset - chunk_header_template.len;
10671008 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);
10701011 chunked.* = .{ .chunk_len = data_len + 2 - n };
10711012 return n;
10721013 },
10731014 .chunk_len => |chunk_len| l: switch (chunk_len) {
10741015 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);
10771018 @memcpy(header_buf, chunk_header_template);
10781019 chunked.* = .{ .offset = offset };
10791020 continue :state .{ .offset = offset };
10801021 },
10811022 1 => {
1082 try bw.writeByte('\n');
1023 try out.writeByte('\n');
10831024 chunked.chunk_len = 0;
10841025 continue :l 0;
10851026 },
10861027 2 => {
1087 try bw.writeByte('\r');
1028 try out.writeByte('\r');
10881029 chunked.chunk_len = 1;
10891030 continue :l 1;
10901031 },
10911032 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));
10931034 chunked.chunk_len = chunk_len - n;
10941035 return n;
10951036 },
......@@ -1112,21 +1053,21 @@ pub const BodyWriter = struct {
11121053 }
11131054 }
11141055
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 .{
11171058 .context = w,
11181059 .vtable = switch (w.state) {
11191060 .none => &.{
1120 .writeSplat = noneWriteSplat,
1121 .writeFile = noneWriteFile,
1061 .drain = noneDrain,
1062 .sendFile = noneSendFile,
11221063 },
11231064 .content_length => &.{
1124 .writeSplat = contentLengthWriteSplat,
1125 .writeFile = contentLengthWriteFile,
1065 .drain = contentLengthDrain,
1066 .sendFile = contentLengthSendFile,
11261067 },
11271068 .chunked => &.{
1128 .writeSplat = chunkedWriteSplat,
1129 .writeFile = chunkedWriteFile,
1069 .drain = chunkedDrain,
1070 .sendFile = chunkedSendFile,
11301071 },
11311072 .end => unreachable,
11321073 },
lib/std/http/Client.zig+14-15
......@@ -13,6 +13,7 @@ const net = std.net;
1313const Uri = std.Uri;
1414const Allocator = mem.Allocator;
1515const assert = std.debug.assert;
16const Writer = std.io.Writer;
1617
1718const Client = @This();
1819
......@@ -229,7 +230,7 @@ pub const Connection = struct {
229230 stream_reader: net.Stream.Reader,
230231 /// HTTP protocol from client to server.
231232 /// This either goes directly to `stream_writer`, or to a TLS client.
232 writer: std.io.BufferedWriter,
233 writer: Writer,
233234 /// HTTP protocol from server to client.
234235 /// This either comes directly from `stream_reader`, or from a TLS client.
235236 reader: std.io.Reader,
......@@ -297,7 +298,7 @@ pub const Connection = struct {
297298
298299 const Tls = struct {
299300 /// Data from `client` to `Connection.stream`.
300 writer: std.io.BufferedWriter,
301 writer: Writer,
301302 /// Data from `Connection.stream` to `client`.
302303 reader: std.io.Reader,
303304 client: std.crypto.tls.Client,
......@@ -403,7 +404,7 @@ pub const Connection = struct {
403404 }
404405 }
405406
406 pub fn flush(c: *Connection) std.io.Writer.Error!void {
407 pub fn flush(c: *Connection) Writer.Error!void {
407408 try c.writer.flush();
408409 if (c.protocol == .tls) {
409410 if (disable_tls) unreachable;
......@@ -415,7 +416,7 @@ pub const Connection = struct {
415416 /// If the connection is a TLS connection, sends the close_notify alert.
416417 ///
417418 /// Flushes all buffers.
418 pub fn end(c: *Connection) std.io.Writer.Error!void {
419 pub fn end(c: *Connection) Writer.Error!void {
419420 try c.writer.flush();
420421 if (c.protocol == .tls) {
421422 if (disable_tls) unreachable;
......@@ -818,13 +819,13 @@ pub const Request = struct {
818819 }
819820
820821 /// 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 {
822823 try sendBodilessUnflushed(r);
823824 try r.connection.?.flush();
824825 }
825826
826827 /// 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 {
828829 assert(r.transfer_encoding == .none);
829830 assert(!r.method.requestHasBody());
830831 try sendHead(r);
......@@ -834,7 +835,7 @@ pub const Request = struct {
834835 ///
835836 /// See also:
836837 /// * `sendBodyUnflushed`
837 pub fn sendBody(r: *Request) std.io.Writer.Error!http.BodyWriter {
838 pub fn sendBody(r: *Request) Writer.Error!http.BodyWriter {
838839 const result = try sendBodyUnflushed(r);
839840 try r.connection.?.flush();
840841 return result;
......@@ -845,7 +846,7 @@ pub const Request = struct {
845846 ///
846847 /// See also:
847848 /// * `sendBody`
848 pub fn sendBodyUnflushed(r: *Request) std.io.Writer.Error!http.BodyWriter {
849 pub fn sendBodyUnflushed(r: *Request) Writer.Error!http.BodyWriter {
849850 assert(r.method.requestHasBody());
850851 try sendHead(r);
851852 return .{
......@@ -860,7 +861,7 @@ pub const Request = struct {
860861 }
861862
862863 /// Sends HTTP headers without flushing.
863 fn sendHead(r: *Request) std.io.Writer.Error!void {
864 fn sendHead(r: *Request) Writer.Error!void {
864865 const uri = r.uri;
865866 const connection = r.connection.?;
866867 const w = &connection.writer;
......@@ -1134,7 +1135,7 @@ pub const Request = struct {
11341135
11351136 /// Returns true if the default behavior is required, otherwise handles
11361137 /// 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 {
11381139 switch (v) {
11391140 .default => return true,
11401141 .omit => return false,
......@@ -1242,16 +1243,14 @@ pub const basic_authorization = struct {
12421243 }
12431244
12441245 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);
12471247 write(uri, &bw) catch unreachable;
12481248 return bw.getWritten();
12491249 }
12501250
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 {
12521252 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);
12551254 bw.print("{fuser}:{fpassword}", .{
12561255 uri.user orelse Uri.Component.empty,
12571256 uri.password orelse Uri.Component.empty,
lib/std/http/Server.zig+11-10
......@@ -6,11 +6,12 @@ const mem = std.mem;
66const Uri = std.Uri;
77const assert = std.debug.assert;
88const testing = std.testing;
9const Writer = std.io.Writer;
910
1011const Server = @This();
1112
1213/// Data from the HTTP server to the HTTP client.
13out: *std.io.BufferedWriter,
14out: *Writer,
1415reader: http.Reader,
1516
1617/// Initialize an HTTP server that can respond to multiple requests on the same
......@@ -20,7 +21,7 @@ reader: http.Reader,
2021/// header, otherwise `receiveHead` returns `error.HttpHeadersOversize`.
2122///
2223/// The returned `Server` is ready for `receiveHead` to be called.
23pub fn init(in: *std.io.Reader, out: *std.io.BufferedWriter) Server {
24pub fn init(in: *std.io.Reader, out: *Writer) Server {
2425 return .{
2526 .reader = .{
2627 .in = in,
......@@ -397,7 +398,7 @@ pub const Request = struct {
397398 /// be done to satisfy the request.
398399 ///
399400 /// 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 {
401402 try writeExpectContinue(request);
402403 const o = options.respond_options;
403404 assert(o.status != .@"continue");
......@@ -485,7 +486,7 @@ pub const Request = struct {
485486
486487 /// The header is not guaranteed to be sent until `WebSocket.flush` is
487488 /// 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 {
489490 if (request.head.expect != null) return error.HttpExpectationFailed;
490491
491492 const out = request.server.out;
......@@ -611,7 +612,7 @@ pub const Request = struct {
611612pub const WebSocket = struct {
612613 key: []const u8,
613614 input: *std.io.Reader,
614 output: *std.io.BufferedWriter,
615 output: *Writer,
615616
616617 pub const Header0 = packed struct(u8) {
617618 opcode: Opcode,
......@@ -701,21 +702,21 @@ pub const WebSocket = struct {
701702 }
702703 }
703704
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 {
705706 try writeMessageVecUnflushed(ws, &.{data}, op);
706707 try ws.output.flush();
707708 }
708709
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 {
710711 try writeMessageVecUnflushed(ws, &.{data}, op);
711712 }
712713
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 {
714715 try writeMessageVecUnflushed(ws, data, op);
715716 try ws.output.flush();
716717 }
717718
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 {
719720 const total_len = l: {
720721 var total_len: u64 = 0;
721722 for (data) |iovec| total_len += iovec.len;
......@@ -749,7 +750,7 @@ pub const WebSocket = struct {
749750 try out.writeVecAll(data);
750751 }
751752
752 pub fn flush(ws: *WebSocket) std.io.Writer.Error!void {
753 pub fn flush(ws: *WebSocket) Writer.Error!void {
753754 try ws.output.flush();
754755 }
755756};
lib/std/io.zig-3
......@@ -72,8 +72,6 @@ pub const Limit = enum(usize) {
7272pub const Reader = @import("io/Reader.zig");
7373pub const Writer = @import("io/Writer.zig");
7474
75pub const AllocatingWriter = @import("io/AllocatingWriter.zig");
76
7775pub const ChangeDetectionStream = @import("io/change_detection_stream.zig").ChangeDetectionStream;
7876pub const changeDetectionStream = @import("io/change_detection_stream.zig").changeDetectionStream;
7977
......@@ -485,7 +483,6 @@ pub fn PollFiles(comptime StreamEnum: type) type {
485483}
486484
487485test {
488 _ = AllocatingWriter;
489486 _ = Reader;
490487 _ = Writer;
491488 _ = @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
12const std = @import("../std.zig");
13const AllocatingWriter = @This();
14const 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.
18written: []u8,
19allocator: std.mem.Allocator,
20/// When using this API, it is not necessary to call
21/// `std.io.BufferedWriter.flush`.
22buffered_writer: std.io.BufferedWriter,
23
24const vtable: std.io.Writer.VTable = .{
25 .writeSplat = writeSplat,
26 .writeFile = writeFile,
27};
28
29/// Sets the `AllocatingWriter` to an empty state.
30pub fn init(aw: *AllocatingWriter, allocator: std.mem.Allocator) void {
31 aw.initOwnedSlice(allocator, &.{});
32}
33
34pub 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
39pub 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
53pub 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.
60pub 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.
82pub 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
95pub fn toOwnedSlice(aw: *AllocatingWriter) error{OutOfMemory}![]u8 {
96 var list = aw.toArrayList();
97 return list.toOwnedSlice(aw.allocator);
98}
99
100pub 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
106fn setArrayList(aw: *AllocatingWriter, list: std.ArrayListUnmanaged(u8)) void {
107 aw.written = list.items;
108 aw.buffered_writer.buffer = list.unusedCapacitySlice();
109}
110
111pub 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
121pub 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
128pub fn clearRetainingCapacity(aw: *AllocatingWriter) void {
129 aw.shrinkRetainingCapacity(0);
130}
131
132fn 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
161fn 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
204test 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 @@
1const std = @import("../std.zig");
2const BufferedWriter = @This();
3const assert = std.debug.assert;
4const native_endian = @import("builtin").target.cpu.arch.endian();
5const Writer = std.io.Writer;
6const Allocator = std.mem.Allocator;
7const testing = std.testing;
8const Limit = std.io.Limit;
9const 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.
19unbuffered_writer: Writer,
20/// If this has length zero, the writer is unbuffered, and `flush` is a no-op.
21buffer: []u8,
22/// In `buffer` before this are buffered bytes, after this is `undefined`.
23end: 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`.
26count: 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.
30pub 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.
35pub fn writer(bw: *BufferedWriter) Writer {
36 return .{
37 .context = bw,
38 .vtable = &.{
39 .writeSplat = passthruWriteSplat,
40 .writeFile = passthruWriteFile,
41 },
42 };
43}
44
45const 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.
53pub 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
63pub 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`.
68pub 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`.
74pub fn reset(bw: *BufferedWriter) void {
75 assert(bw.unbuffered_writer.vtable == &fixed_vtable);
76 bw.end = 0;
77 bw.count = 0;
78}
79
80pub 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
87pub 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
96pub 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`.
103pub 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`.
112pub 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`.
123pub 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
145pub fn ensureUnusedCapacity(bw: *BufferedWriter, n: usize) Writer.Error!void {
146 _ = try writableSliceGreedy(bw, n);
147}
148
149pub 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`.
158pub 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`.
167pub 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`.
186pub 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.
217pub 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`.
224pub 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.
229pub 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
242fn 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
354fn 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.
362fn 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
384pub 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.
408pub 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
413pub fn print(bw: *BufferedWriter, comptime format: []const u8, args: anytype) Writer.Error!void {
414 try std.fmt.format(bw, format, args);
415}
416
417pub 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.
456pub 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`.
464pub 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.
470pub 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`.
483pub 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.
488pub 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
494pub 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
503pub 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
513pub 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)`
527pub 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.
545pub 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.
558pub 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
572fn 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
652pub 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
665pub 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.
719pub 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
732pub 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
763pub 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
767pub 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
791pub 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
1056fn 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
1061pub 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
1110pub 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
1114pub fn printAscii(bw: *BufferedWriter, bytes: []const u8, options: std.fmt.Options) Writer.Error!void {
1115 return bw.alignBufferOptions(bytes, options);
1116}
1117
1118pub 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
1124pub 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
1192pub 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
1224pub 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
1323pub 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
1333pub 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
1387const ANY = "any";
1388
1389fn 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
1396pub fn invalidFmtError(comptime fmt: []const u8, value: anytype) noreturn {
1397 @compileError("invalid format string '" ++ fmt ++ "' for type '" ++ @typeName(@TypeOf(value)) ++ "'");
1398}
1399
1400pub fn printDurationSigned(bw: *BufferedWriter, ns: i64) Writer.Error!void {
1401 if (ns < 0) try bw.writeByte('-');
1402 return bw.printDurationUnsigned(@abs(ns));
1403}
1404
1405pub 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`.
1455pub 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
1467pub 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
1478pub 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.
1487pub 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.
1499pub 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.
1511pub 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
1519fn 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
1550test "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
1626test 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
1663test 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
1731fn 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
1739fn 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
1747test 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
1765test "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
1773test "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
1782fn 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
1790test 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
1805test "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
1815test 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
1833test "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
1857test 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 {
11491149}
11501150
11511151test fixed {
1152 var r: Reader = undefined;
1153 r.initFixed("a\x02");
1152 var r: Reader = .fixed("a\x02");
11541153 try testing.expect((try r.takeByte()) == 'a');
11551154 try testing.expect((try r.takeEnum(enum(u8) {
11561155 a = 0,
......@@ -1186,8 +1185,7 @@ test peekArray {
11861185}
11871186
11881187test discardAll {
1189 var r: Reader = undefined;
1190 r.initFixed("foobar");
1188 var r: Reader = .fixed("foobar");
11911189 try r.discard(3);
11921190 try testing.expectEqualStrings("bar", try r.take(3));
11931191 try r.discard(0);
......@@ -1300,8 +1298,7 @@ test readVec {
13001298
13011299test "expected error.EndOfStream" {
13021300 // 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("");
13051302 try std.testing.expectError(error.EndOfStream, r.readEnum(enum(u8) { a, b }, .little));
13061303 try std.testing.expectError(error.EndOfStream, r.isBytes("foo"));
13071304}
lib/std/io/Reader/Limited.zig+3-3
......@@ -2,7 +2,7 @@ const Limited = @This();
22
33const std = @import("../../std.zig");
44const Reader = std.io.Reader;
5const BufferedWriter = std.io.BufferedWriter;
5const Writer = std.io.Writer;
66const Limit = std.io.Limit;
77
88unlimited: *Reader,
......@@ -25,10 +25,10 @@ pub fn init(reader: *Reader, limit: Limit, buffer: []u8) Limited {
2525 };
2626}
2727
28fn stream(context: ?*anyopaque, bw: *BufferedWriter, limit: Limit) Reader.StreamError!usize {
28fn stream(context: ?*anyopaque, w: *Writer, limit: Limit) Reader.StreamError!usize {
2929 const l: *Limited = @alignCast(@ptrCast(context));
3030 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);
3232 l.remaining = l.remaining.subtract(n).?;
3333 return n;
3434}
lib/std/io/Writer.zig+1836-130
......@@ -1,51 +1,71 @@
1const builtin = @import("builtin");
2const native_endian = builtin.target.cpu.arch.endian();
3
4const Writer = @This();
15const std = @import("../std.zig");
26const assert = std.debug.assert;
3const Writer = @This();
47const Limit = std.io.Limit;
58const File = std.fs.File;
9const testing = std.testing;
10const Allocator = std.mem.Allocator;
611
712context: ?*anyopaque,
813vtable: *const VTable,
14/// If this has length zero, the writer is unbuffered, and `flush` is a no-op.
15buffer: []u8,
16/// In `buffer` before this are buffered bytes, after this is `undefined`.
17end: 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.
23count: usize = 0,
924
1025pub 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.
1234 ///
1335 /// `data.len` must be greater than zero, and the last element of `data` is
1436 /// special. It is repeated as necessary so that it is written `splat`
15 /// number of times.
37 /// number of times, which may be zero.
1638 ///
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`.
1841 ///
1942 /// 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,
2346
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`.
2649 ///
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`.
2952 ///
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.
3358 ///
3459 /// `error.Unimplemented` indicates the callee cannot offer a more
3560 /// efficient implementation than the caller performing its own reads.
36 writeFile: *const fn (
37 ctx: ?*anyopaque,
61 sendFile: *const fn (
62 w: *Writer,
3863 file_reader: *File.Reader,
3964 /// 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.
4367 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,
4969};
5070
5171pub const Error = error{
......@@ -70,97 +90,1602 @@ pub const FileError = error{
7090 Unimplemented,
7191};
7292
73pub 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`.
95pub fn fixed(buffer: []u8) Writer {
96 return .{
97 .context = undefined,
98 .vtable = &.{ .drain = fixedDrain },
99 .buffer = buffer,
100 };
101}
102
103pub fn hashed(w: *Writer, hasher: anytype) Hashed(@TypeOf(hasher)) {
104 return .{ .out = w, .hasher = hasher };
105}
106
107pub const failing: Writer = .{
108 .context = undefined,
109 .vtable = &.{
110 .drain = failingDrain,
111 .sendFile = failingSendFile,
112 },
113};
114
115pub 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.
127pub fn buffered(w: *const Writer) []u8 {
128 return w.buffer[0..w.end];
129}
130
131pub fn countSplat(n: usize, data: []const []const u8, splat: usize) usize {
74132 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;
76137}
77138
78pub fn writeSplat(w: Writer, data: []const []const u8, splat: usize) Error!usize {
139pub 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`.
147pub 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.
154pub fn writeSplat(w: *Writer, data: []const []const u8, splat: usize) Error!usize {
79155 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;
81190}
82191
83pub fn writeFile(
84 w: Writer,
85 file_reader: *File.Reader,
192/// Equivalent to `writeSplat` but writes at most `limit` bytes.
193pub fn writeSplatLimit(
194 w: *Writer,
195 data: []const []const u8,
196 splat: usize,
86197 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");
91204}
92205
93pub fn buffered(w: Writer, buffer: []u8) std.io.BufferedWriter {
94 return .{
95 .buffer = buffer,
96 .unbuffered_writer = w,
206/// Drains all remaining buffered data.
207pub 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
215pub fn unusedCapacitySlice(w: *const Writer) []u8 {
216 return w.buffer[w.end..];
217}
218
219pub 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`.
226pub 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`.
235pub 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`.
246pub 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
268pub fn ensureUnusedCapacity(w: *Writer, n: usize) Error!void {
269 _ = try writableSliceGreedy(w, n);
270}
271
272pub 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`.
281pub 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`.
290pub 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`.
309pub 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
337pub 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.
351pub 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
356pub fn print(w: *Writer, comptime format: []const u8, args: anytype) Error!void {
357 try std.fmt.format(w, format, args);
358}
359
360pub 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.
399pub 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`.
407pub 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.
413pub 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`.
426pub 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.
431pub 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
437pub 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
446pub 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
456pub 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)`
470pub 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.
487pub 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.
494pub 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,
97499 };
500 w.advance(n);
501 return n;
502}
503
504pub 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.
528pub 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
537pub 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
568pub 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
572pub 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
596pub 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 }
98859}
99860
100pub fn unbuffered(w: Writer) std.io.BufferedWriter {
101 return w.buffered(&.{});
861fn printErrorSet(w: *Writer, error_set: anyerror) Error!void {
862 var vecs: [2][]const u8 = .{ "error.", @errorName(error_set) };
863 try w.writeVecAll(&vecs);
102864}
103865
104pub fn failingWriteSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) Error!usize {
105 _ = context;
866pub 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
915pub fn printAsciiChar(w: *Writer, c: u8, options: std.fmt.Options) Error!void {
916 return w.alignBufferOptions(@as(*const [1]u8, &c), options);
917}
918
919pub fn printAscii(w: *Writer, bytes: []const u8, options: std.fmt.Options) Error!void {
920 return w.alignBufferOptions(bytes, options);
921}
922
923pub 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
929pub 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
997pub 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
1028pub 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
1127pub 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
1137pub 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
1191const ANY = "any";
1192
1193fn 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
1200pub fn invalidFmtError(comptime fmt: []const u8, value: anytype) noreturn {
1201 @compileError("invalid format string '" ++ fmt ++ "' for type '" ++ @typeName(@TypeOf(value)) ++ "'");
1202}
1203
1204pub fn printDurationSigned(w: *Writer, ns: i64) Error!void {
1205 if (ns < 0) try w.writeByte('-');
1206 return w.printDurationUnsigned(@abs(ns));
1207}
1208
1209pub 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`.
1258pub 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
1269pub 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
1280pub 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.
1289pub 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.
1301pub 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.
1313pub 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
1321fn 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
1352test "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
1427test 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
1464test 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
1532fn 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
1539fn 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
1546test 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
1564test "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
1571test "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
1579fn 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
1586test 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
1601test "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
1611test 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
1627test "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
1650pub fn failingDrain(w: *Writer, data: []const []const u8, splat: usize) Error!usize {
1651 _ = w;
1061652 _ = data;
1071653 _ = splat;
1081654 return error.WriteFailed;
1091655}
1101656
111pub 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;
1657pub fn failingSendFile(w: *Writer, file_reader: *File.Reader, limit: Limit) FileError!usize {
1658 _ = w;
1191659 _ = file_reader;
1201660 _ = limit;
121 _ = headers_and_trailers;
122 _ = headers_len;
1231661 return error.WriteFailed;
1241662}
1251663
126pub const failing: Writer = .{
127 .context = undefined,
128 .vtable = &.{
129 .writeSplat = failingWriteSplat,
130 .writeFile = failingWriteFile,
131 },
132};
133
134pub 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..];
1664pub 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..];
1381667 var written: usize = pattern.len * splat;
139 for (headers) |bytes| written += bytes.len;
1668 for (slice) |bytes| written += bytes.len;
1669 w.end = 0;
1401670 return written;
1411671}
1421672
143pub 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;
1673pub 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;
1631682 }
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;
1641689 return n;
1651690 } else |_| {
1661691 // Error is observable on `file_reader` instance, and it is better to
......@@ -169,33 +1694,52 @@ pub fn discardingWriteFile(
1691694 }
1701695}
1711696
172pub const discarding: Writer = .{
173 .context = undefined,
174 .vtable = &.{
175 .writeSplat = discardingWriteSplat,
176 .writeFile = discardingWriteFile,
177 },
178};
179
1801697/// For use when the `Writer` implementation can cannot offer a more efficient
1811698/// implementation than a basic read/write loop on the file.
182pub 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;
1699pub fn unimplementedSendFile(w: *Writer, file_reader: *File.Reader, limit: Limit) FileError!usize {
1700 _ = w;
1901701 _ = file_reader;
1911702 _ = limit;
192 _ = headers_and_trailers;
193 _ = headers_len;
1941703 return error.Unimplemented;
1951704}
1961705
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.
1710fn 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
1971741/// 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`.
1991743///
2001744/// When using this, the underlying writer is best unbuffered because all
2011745/// writes are passed on directly to it.
......@@ -206,27 +1750,35 @@ pub fn unimplementedWriteFile(
2061750/// details.
2071751pub fn Hashed(comptime Hasher: type) type {
2081752 return struct {
209 out: *std.io.BufferedWriter,
1753 out: *Writer,
2101754 hasher: Hasher,
1755 interface: Writer,
2111756
212 pub fn writable(this: *@This(), buffer: []u8) std.io.BufferedWriter {
1757 pub fn init(out: *Writer) @This() {
2131758 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},
2201764 },
221 .buffer = buffer,
2221765 };
2231766 }
2241767
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;
2291780 var remaining: usize = n;
1781 const short_data = data[0 .. data.len - @intFromBool(splat == 0)];
2301782 for (short_data) |slice| {
2311783 if (remaining < slice.len) {
2321784 this.hasher.update(slice[0..remaining]);
......@@ -243,31 +1795,185 @@ pub fn Hashed(comptime Hasher: type) type {
2431795 },
2441796 else => splat - 1,
2451797 };
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) {
2491801 0 => {
2501802 assert(remaining == 0);
251 return n;
2521803 },
2531804 1 => {
2541805 var buffer: [64]u8 = undefined;
255 @memset(&buffer, last[0]);
1806 @memset(&buffer, pattern[0]);
2561807 while (remaining > 0) {
2571808 const update_len = @min(remaining, buffer.len);
2581809 this.hasher.update(buffer[0..update_len]);
2591810 remaining -= update_len;
2601811 }
261 return n;
2621812 },
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 },
2691820 }
2701821 return n;
2711822 }
2721823 };
2731824}
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`.
1833pub 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) {
7373
7474 pub const SetColorError = std.os.windows.SetConsoleTextAttributeError || std.io.Writer.Error;
7575
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 {
7777 nosuspend switch (conf) {
7878 .no_color => return,
7979 .escape_codes => {
......@@ -98,7 +98,7 @@ pub const Config = union(enum) {
9898 .dim => "\x1b[2m",
9999 .reset => "\x1b[0m",
100100 };
101 try bw.writeAll(color_string);
101 try w.writeAll(color_string);
102102 },
103103 .windows_api => |ctx| if (native_os == .windows) {
104104 const attributes = switch (color) {
lib/std/json.zig+2-2
......@@ -127,9 +127,9 @@ pub fn Formatter(comptime T: type) type {
127127 self: @This(),
128128 comptime fmt_spec: []const u8,
129129 options: std.fmt.FormatOptions,
130 writer: *std.io.BufferedWriter,
130 writer: *std.io.Writer,
131131 ) !void {
132 _ = fmt_spec;
132 comptime std.debug.assert(fmt_spec.len == 0);
133133 _ = options;
134134 try Stringify.value(self.value, self.options, writer);
135135 }
lib/std/json/Stringify.zig+13-16
......@@ -23,13 +23,14 @@ const Allocator = std.mem.Allocator;
2323const ArrayList = std.ArrayList;
2424const BitStack = std.BitStack;
2525const Stringify = @This();
26const Writer = std.io.Writer;
2627
2728const IndentationMode = enum(u1) {
2829 object = 0,
2930 array = 1,
3031};
3132
32writer: *std.io.BufferedWriter,
33writer: *Writer,
3334options: Options = .{},
3435indent_level: usize = 0,
3536next_punctuation: enum {
......@@ -77,7 +78,7 @@ const safety_checks: @TypeOf(safety_checks_hint) = if (build_mode_has_safety)
7778else
7879 .assumed_correct;
7980
80pub const Error = std.io.Writer.Error;
81pub const Error = Writer.Error;
8182
8283pub fn beginArray(self: *Stringify) Error!void {
8384 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
224225
225226test print {
226227 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);
229229
230230 var w: Stringify = .{ .writer = &out, .options = .{ .whitespace = .indent_2 } };
231231
......@@ -567,10 +567,10 @@ pub const Options = struct {
567567 emit_nonportable_numbers_as_strings: bool = false,
568568};
569569
570/// Writes the given value to the `std.io.Writer` writer.
570/// Writes the given value to the `Writer` writer.
571571/// See `Stringify` for how the given value is serialized into JSON.
572572/// The maximum nesting depth of the output JSON document is 256.
573pub fn value(v: anytype, options: Options, writer: *std.io.BufferedWriter) Error!void {
573pub fn value(v: anytype, options: Options, writer: *Writer) Error!void {
574574 var s: Stringify = .{ .writer = writer, .options = options };
575575 try s.write(v);
576576}
......@@ -634,7 +634,7 @@ test valueAlloc {
634634 try std.testing.expectEqualStrings(expected, actual);
635635}
636636
637fn outputUnicodeEscape(codepoint: u21, bw: *std.io.BufferedWriter) Error!void {
637fn outputUnicodeEscape(codepoint: u21, bw: *Writer) Error!void {
638638 if (codepoint <= 0xFFFF) {
639639 // If the character is in the Basic Multilingual Plane (U+0000 through U+FFFF),
640640 // 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 {
654654 }
655655}
656656
657fn outputSpecialEscape(c: u8, writer: *std.io.BufferedWriter) Error!void {
657fn outputSpecialEscape(c: u8, writer: *Writer) Error!void {
658658 switch (c) {
659659 '\\' => try writer.writeAll("\\\\"),
660660 '\"' => try writer.writeAll("\\\""),
......@@ -668,14 +668,14 @@ fn outputSpecialEscape(c: u8, writer: *std.io.BufferedWriter) Error!void {
668668}
669669
670670/// Write `string` to `writer` as a JSON encoded string.
671pub fn encodeJsonString(string: []const u8, options: Options, writer: *std.io.BufferedWriter) Error!void {
671pub fn encodeJsonString(string: []const u8, options: Options, writer: *Writer) Error!void {
672672 try writer.writeByte('\"');
673673 try encodeJsonStringChars(string, options, writer);
674674 try writer.writeByte('\"');
675675}
676676
677677/// Write `chars` to `writer` as JSON encoded string characters.
678pub fn encodeJsonStringChars(chars: []const u8, options: Options, writer: *std.io.BufferedWriter) Error!void {
678pub fn encodeJsonStringChars(chars: []const u8, options: Options, writer: *Writer) Error!void {
679679 var write_cursor: usize = 0;
680680 var i: usize = 0;
681681 if (options.escape_unicode) {
......@@ -718,8 +718,7 @@ pub fn encodeJsonStringChars(chars: []const u8, options: Options, writer: *std.i
718718
719719test "json write stream" {
720720 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);
723722 var w: Stringify = .{ .writer = &out, .options = .{ .whitespace = .indent_2 } };
724723 try testBasicWriteStream(&w);
725724}
......@@ -971,16 +970,14 @@ test "stringify struct with custom stringifier" {
971970
972971fn testStringify(expected: []const u8, v: anytype, options: Options) !void {
973972 var buffer: [4096]u8 = undefined;
974 var bw: std.io.BufferedWriter = undefined;
975 bw.initFixed(&buffer);
973 var bw: Writer = .fixed(&buffer);
976974 try value(v, options, &bw);
977975 try std.testing.expectEqualStrings(expected, bw.getWritten());
978976}
979977
980978test "raw streaming" {
981979 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);
984981
985982 var w: Stringify = .{ .writer = &out, .options = .{ .whitespace = .indent_2 } };
986983 try w.beginObject();
lib/std/json/dynamic_test.zig+3-4
......@@ -4,6 +4,7 @@ const mem = std.mem;
44const testing = std.testing;
55const ArenaAllocator = std.heap.ArenaAllocator;
66const Allocator = std.mem.Allocator;
7const Writer = std.io.Writer;
78
89const ObjectMap = @import("dynamic.zig").ObjectMap;
910const Array = @import("dynamic.zig").Array;
......@@ -73,8 +74,7 @@ test "json.parser.dynamic" {
7374
7475test "write json then parse it" {
7576 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);
7878 var jw: json.Stringify = .{ .writer = &fixed_writer, .options = .{} };
7979
8080 try jw.beginObject();
......@@ -240,8 +240,7 @@ test "Value.jsonStringify" {
240240 .{ .object = obj },
241241 };
242242 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);
245244
246245 var jw: json.Stringify = .{ .writer = &fixed_writer, .options = .{ .whitespace = .indent_1 } };
247246 try jw.write(array);
lib/std/leb128.zig+3-3
......@@ -1,6 +1,7 @@
11const builtin = @import("builtin");
22const std = @import("std");
33const testing = std.testing;
4const Writer = std.io.Writer;
45
56/// This is an "advanced" function. It allows one to use a fixed amount of memory to store a
67/// 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 {
241242 const signedness = @typeInfo(T).int.signedness;
242243 const t_signed = signedness == .signed;
243244
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;
245246 const readStream = if (t_signed) std.io.Reader.readIleb128 else std.io.Reader.readUleb128;
246247
247248 // decode to a larger bit size too, to ensure sign extension
......@@ -261,8 +262,7 @@ fn test_write_leb128(value: anytype) !void {
261262 const max_groups = if (@typeInfo(T).int.bits == 0) 1 else (@typeInfo(T).int.bits + 6) / 7;
262263
263264 var buf: [max_groups]u8 = undefined;
264 var bw: std.io.BufferedWriter = undefined;
265 bw.initFixed(&buf);
265 var bw: Writer = .fixed(&buf);
266266
267267 // stream write
268268 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 {
23222322 /// this function will fail to print the string, printing "(BigInt)" instead of a number.
23232323 /// This is because the rendering algorithm requires reversing a string, which requires O(N) memory.
23242324 /// 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 {
23262326 comptime var base = 10;
23272327 comptime var case: std.fmt.Case = .lower;
23282328
lib/std/net.zig+1-1
......@@ -1915,7 +1915,7 @@ pub const Stream = struct {
19151915
19161916 fn read(
19171917 context: ?*anyopaque,
1918 bw: *std.io.BufferedWriter,
1918 bw: *std.io.Writer,
19191919 limit: std.io.Limit,
19201920 ) std.io.Reader.Error!usize {
19211921 const buf = limit.slice(try bw.writableSliceGreedy(1));
lib/std/tar.zig+11-19
......@@ -358,7 +358,7 @@ pub const Iterator = struct {
358358 };
359359 }
360360
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 {
362362 const file: *File = @ptrCast(@alignCast(context));
363363 if (file.unread_bytes.* == 0) return error.EndOfStream;
364364 const n = try file.parent_reader.read(bw, limit.min(.limited(file.unread_bytes.*)));
......@@ -381,7 +381,7 @@ pub const Iterator = struct {
381381 return n;
382382 }
383383
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 {
385385 return file.reader().readRemaining(out);
386386 }
387387 };
......@@ -818,8 +818,7 @@ test PaxIterator {
818818 var buffer: [1024]u8 = undefined;
819819
820820 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);
823822 var iter: PaxIterator = .init(&br, case.data.len);
824823
825824 var i: usize = 0;
......@@ -955,8 +954,7 @@ test Iterator {
955954 // example/empty/
956955
957956 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);
960958
961959 // User provided buffers to the iterator
962960 var file_name_buffer: [std.fs.max_path_bytes]u8 = undefined;
......@@ -1015,8 +1013,7 @@ test pipeToFileSystem {
10151013 // example/empty/
10161014
10171015 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);
10201017
10211018 var tmp = testing.tmpDir(.{ .no_follow = true });
10221019 defer tmp.cleanup();
......@@ -1047,8 +1044,7 @@ test pipeToFileSystem {
10471044
10481045test "pipeToFileSystem root_dir" {
10491046 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);
10521048
10531049 // with strip_components = 1
10541050 {
......@@ -1073,7 +1069,7 @@ test "pipeToFileSystem root_dir" {
10731069
10741070 // with strip_components = 0
10751071 {
1076 br.initFixed(data);
1072 br = .fixed(data);
10771073 var tmp = testing.tmpDir(.{ .no_follow = true });
10781074 defer tmp.cleanup();
10791075 var diagnostics: Diagnostics = .{ .allocator = testing.allocator };
......@@ -1096,8 +1092,7 @@ test "pipeToFileSystem root_dir" {
10961092
10971093test "findRoot with single file archive" {
10981094 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);
11011096
11021097 var tmp = testing.tmpDir(.{});
11031098 defer tmp.cleanup();
......@@ -1111,8 +1106,7 @@ test "findRoot with single file archive" {
11111106
11121107test "findRoot without explicit root dir" {
11131108 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);
11161110
11171111 var tmp = testing.tmpDir(.{});
11181112 defer tmp.cleanup();
......@@ -1126,8 +1120,7 @@ test "findRoot without explicit root dir" {
11261120
11271121test "pipeToFileSystem strip_components" {
11281122 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);
11311124
11321125 var tmp = testing.tmpDir(.{ .no_follow = true });
11331126 defer tmp.cleanup();
......@@ -1188,8 +1181,7 @@ test "executable bit" {
11881181 const data = @embedFile("tar/testdata/example.tar");
11891182
11901183 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);
11931185
11941186 var tmp = testing.tmpDir(.{ .no_follow = true });
11951187 //defer tmp.cleanup();
lib/std/tar/Writer.zig+6-10
......@@ -14,7 +14,7 @@ pub const Options = struct {
1414 mtime: u64 = 0,
1515};
1616
17underlying_writer: *std.io.BufferedWriter,
17underlying_writer: *std.io.Writer,
1818prefix: []const u8 = "",
1919mtime_now: u64 = 0,
2020
......@@ -277,7 +277,7 @@ pub const Header = extern struct {
277277 try octal(&w.checksum, checksum);
278278 }
279279
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 {
281281 try h.updateChecksum();
282282 try bw.writeAll(std.mem.asBytes(h));
283283 }
......@@ -433,16 +433,14 @@ test "write files" {
433433 {
434434 const root = "root";
435435
436 var output: std.io.AllocatingWriter = undefined;
437 output.init(testing.allocator);
436 var output: std.io.AllocatingWriter = .init(testing.allocator);
438437 var wrt: Writer = .{ .underlying_writer = &output.buffered_writer };
439438 defer output.deinit();
440439 try wrt.setRoot(root);
441440 for (files) |file|
442441 try wrt.writeFileBytes(file.path, file.content, .{});
443442
444 var input: std.io.Reader = undefined;
445 input.initFixed(output.getWritten());
443 var input: std.io.Reader = .fixed(output.getWritten());
446444 var iter = std.tar.iterator(&input, .{
447445 .file_name_buffer = &file_name_buffer,
448446 .link_name_buffer = &link_name_buffer,
......@@ -476,13 +474,11 @@ test "write files" {
476474 var wrt: Writer = .{ .underlying_writer = &output.buffered_writer };
477475 defer output.deinit();
478476 for (files) |file| {
479 var content: std.io.Reader = undefined;
480 content.initFixed(file.content);
477 var content: std.io.Reader = .fixed(file.content);
481478 try wrt.writeFileStream(file.path, file.content.len, &content, .{});
482479 }
483480
484 var input: std.io.Reader = undefined;
485 input.initFixed(output.getWritten());
481 var input: std.io.Reader = .fixed(output.getWritten());
486482 var iter = std.tar.iterator(&input, .{
487483 .file_name_buffer = &file_name_buffer,
488484 .link_name_buffer = &link_name_buffer,
lib/std/testing.zig+4-3
......@@ -2,6 +2,7 @@ const std = @import("std.zig");
22const builtin = @import("builtin");
33const assert = std.debug.assert;
44const math = std.math;
5const Writer = std.io.Writer;
56
67/// Provides deterministic randomness in unit tests.
78/// Initialized on startup. Read-only after that.
......@@ -459,7 +460,7 @@ fn SliceDiffer(comptime T: type) type {
459460
460461 const Self = @This();
461462
462 pub fn write(self: Self, bw: *std.io.BufferedWriter) !void {
463 pub fn write(self: Self, bw: *Writer) !void {
463464 for (self.expected, 0..) |value, i| {
464465 const full_index = self.start_index + i;
465466 const diff = if (i < self.actual.len) !std.meta.eql(self.actual[i], value) else true;
......@@ -480,7 +481,7 @@ const BytesDiffer = struct {
480481 actual: []const u8,
481482 ttyconf: std.io.tty.Config,
482483
483 pub fn write(self: BytesDiffer, bw: *std.io.BufferedWriter) !void {
484 pub fn write(self: BytesDiffer, bw: *Writer) !void {
484485 var expected_iterator = std.mem.window(u8, self.expected, 16, 16);
485486 var row: usize = 0;
486487 while (expected_iterator.next()) |chunk| {
......@@ -526,7 +527,7 @@ const BytesDiffer = struct {
526527 }
527528 }
528529
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 {
530531 if (diff) try self.ttyconf.setColor(bw, .red);
531532 try bw.print(fmt, args);
532533 if (diff) try self.ttyconf.setColor(bw, .reset);
lib/std/tz.zig+3-6
......@@ -215,8 +215,7 @@ pub const Tz = struct {
215215
216216test "slim" {
217217 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);
220219
221220 var tz = try std.Tz.parse(std.testing.allocator, &in_stream);
222221 defer tz.deinit();
......@@ -229,8 +228,7 @@ test "slim" {
229228
230229test "fat" {
231230 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);
234232
235233 var tz = try std.Tz.parse(std.testing.allocator, &in_stream);
236234 defer tz.deinit();
......@@ -243,8 +241,7 @@ test "fat" {
243241test "legacy" {
244242 // Taken from Slackware 8.0, from 2001
245243 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);
248245
249246 var tz = try std.Tz.parse(std.testing.allocator, &in_stream);
250247 defer tz.deinit();
lib/std/zig.zig+8-15
......@@ -2,6 +2,12 @@
22//! source lives here. These APIs are provided as-is and have absolutely no API
33//! guarantees whatsoever.
44
5const std = @import("std.zig");
6const tokenizer = @import("zig/tokenizer.zig");
7const assert = std.debug.assert;
8const Allocator = std.mem.Allocator;
9const Writer = std.io.Writer;
10
511pub const ErrorBundle = @import("zig/ErrorBundle.zig");
612pub const Server = @import("zig/Server.zig");
713pub const Client = @import("zig/Client.zig");
......@@ -356,11 +362,6 @@ pub fn serializeCpuAlloc(ally: Allocator, cpu: std.Target.Cpu) Allocator.Error![
356362 return buffer.toOwnedSlice();
357363}
358364
359const std = @import("std.zig");
360const tokenizer = @import("zig/tokenizer.zig");
361const assert = std.debug.assert;
362const Allocator = std.mem.Allocator;
363
364365/// Return a Formatter for a Zig identifier, escaping it with `@""` syntax if needed.
365366///
366367/// - An empty `{}` format specifier escapes invalid identifiers, identifiers that shadow primitives
......@@ -412,11 +413,7 @@ test fmtId {
412413}
413414
414415/// Print the string as a Zig identifier, escaping it with `@""` syntax if needed.
415fn formatId(
416 bytes: []const u8,
417 bw: *std.io.BufferedWriter,
418 comptime fmt: []const u8,
419) !void {
416fn formatId(bytes: []const u8, bw: *Writer, comptime fmt: []const u8) !void {
420417 const allow_primitive, const allow_underscore = comptime parse_fmt: {
421418 var allow_primitive = false;
422419 var allow_underscore = false;
......@@ -470,11 +467,7 @@ test fmtEscapes {
470467/// Print the string as escaped contents of a double quoted or single-quoted string.
471468/// Format `{}` treats contents as a double-quoted string.
472469/// Format `{'}` treats contents as a single-quoted string.
473pub fn stringEscape(
474 bytes: []const u8,
475 bw: *std.io.BufferedWriter,
476 comptime f: []const u8,
477) !void {
470pub fn stringEscape(bytes: []const u8, bw: *Writer, comptime f: []const u8) !void {
478471 for (bytes) |byte| switch (byte) {
479472 '\n' => try bw.writeAll("\\n"),
480473 '\r' => try bw.writeAll("\\r"),
lib/std/zig/Ast.zig+12-11
......@@ -4,6 +4,16 @@
44//! For Zon syntax, the root node is at nodes[0] and contains lhs as the node
55//! index of the main expression.
66
7const std = @import("../std.zig");
8const assert = std.debug.assert;
9const testing = std.testing;
10const mem = std.mem;
11const Token = std.zig.Token;
12const Ast = @This();
13const Allocator = std.mem.Allocator;
14const Parse = @import("Parse.zig");
15const Writer = std.io.Writer;
16
717/// Reference to externally-owned data.
818source: [:0]const u8,
919
......@@ -205,7 +215,7 @@ pub fn renderAlloc(tree: Ast, gpa: Allocator) error{OutOfMemory}![]u8 {
205215
206216pub const Render = @import("Ast/Render.zig");
207217
208pub fn render(tree: Ast, gpa: Allocator, bw: *std.io.BufferedWriter, fixups: Render.Fixups) Render.Error!void {
218pub fn render(tree: Ast, gpa: Allocator, bw: *Writer, fixups: Render.Fixups) Render.Error!void {
209219 return Render.tree(gpa, bw, tree, fixups);
210220}
211221
......@@ -311,7 +321,7 @@ pub fn rootDecls(tree: Ast) []const Node.Index {
311321 }
312322}
313323
314pub fn renderError(tree: Ast, parse_error: Error, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
324pub fn renderError(tree: Ast, parse_error: Error, bw: *Writer) Writer.Error!void {
315325 switch (parse_error.tag) {
316326 .asterisk_after_ptr_deref => {
317327 // 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
41184128 return Span{ .start = start_off, .end = end_off, .main = tree.tokenStart(main) };
41194129}
41204130
4121const std = @import("../std.zig");
4122const assert = std.debug.assert;
4123const testing = std.testing;
4124const mem = std.mem;
4125const Token = std.zig.Token;
4126const Ast = @This();
4127const Allocator = std.mem.Allocator;
4128const Parse = @import("Parse.zig");
4129
41304131test {
41314132 _ = Parse;
41324133 _ = Render;
lib/std/zig/Ast/Render.zig+6-5
......@@ -6,6 +6,7 @@ const meta = std.meta;
66const Ast = std.zig.Ast;
77const Token = std.zig.Token;
88const primitives = std.zig.primitives;
9const Writer = std.io.Writer;
910
1011const Render = @This();
1112
......@@ -82,7 +83,7 @@ pub const Fixups = struct {
8283 }
8384};
8485
85pub fn renderTree(gpa: Allocator, bw: *std.io.BufferedWriter, tree: Ast, fixups: Fixups) Error!void {
86pub fn renderTree(gpa: Allocator, bw: *Writer, tree: Ast, fixups: Fixups) Error!void {
8687 assert(tree.errors.len == 0); // Cannot render an invalid tree.
8788 var auto_indenting_stream: AutoIndentingStream = .init(gpa, bw, indent_delta);
8889 defer auto_indenting_stream.deinit();
......@@ -3136,7 +3137,7 @@ fn anythingBetween(tree: Ast, start_token: Ast.TokenIndex, end_token: Ast.TokenI
31363137 return false;
31373138}
31383139
3139fn writeFixingWhitespace(bw: *std.io.BufferedWriter, slice: []const u8) Error!void {
3140fn writeFixingWhitespace(bw: *Writer, slice: []const u8) Error!void {
31403141 for (slice) |byte| switch (byte) {
31413142 '\t' => try bw.splatByteAll(' ', indent_delta),
31423143 '\r' => {},
......@@ -3266,7 +3267,7 @@ fn rowSize(tree: Ast, exprs: []const Ast.Node.Index, rtoken: Ast.TokenIndex) usi
32663267/// This should be done whenever a scope that ends in a .semicolon or a
32673268/// .comma is introduced.
32683269const AutoIndentingStream = struct {
3269 underlying_writer: *std.io.BufferedWriter,
3270 underlying_writer: *Writer,
32703271
32713272 /// Offset into the source at which formatting has been disabled with
32723273 /// a `zig fmt: off` comment.
......@@ -3301,10 +3302,10 @@ const AutoIndentingStream = struct {
33013302 indent_count: usize,
33023303 };
33033304
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 {
33053306 return .{
33063307 .underlying_writer = bw,
3307 .indent_delta = indent_delta_,
3308 .indent_delta = starting_indent_delta,
33083309 .indent_stack = .init(gpa),
33093310 .space_stack = .init(gpa),
33103311 };
lib/std/zig/ErrorBundle.zig+10-9
......@@ -7,6 +7,12 @@
77//! empty, it means there are no errors. This special encoding exists so that
88//! heap allocation is not needed in the common case of no errors.
99
10const std = @import("std");
11const ErrorBundle = @This();
12const Allocator = std.mem.Allocator;
13const assert = std.debug.assert;
14const Writer = std.io.Writer;
15
1016string_bytes: []const u8,
1117/// The first thing in this array is an `ErrorMessageList`.
1218extra: []const u32,
......@@ -163,7 +169,7 @@ pub fn renderToStdErr(eb: ErrorBundle, options: RenderOptions) void {
163169 renderToWriter(eb, options, bw) catch return;
164170}
165171
166pub fn renderToWriter(eb: ErrorBundle, options: RenderOptions, bw: *std.io.BufferedWriter) (std.io.Writer.Error || std.posix.UnexpectedError)!void {
172pub fn renderToWriter(eb: ErrorBundle, options: RenderOptions, bw: *Writer) (Writer.Error || std.posix.UnexpectedError)!void {
167173 if (eb.extra.len == 0) return;
168174 for (eb.getMessages()) |err_msg| {
169175 try renderErrorMessageToWriter(eb, options, err_msg, bw, "error", .red, 0);
......@@ -182,11 +188,11 @@ fn renderErrorMessageToWriter(
182188 eb: ErrorBundle,
183189 options: RenderOptions,
184190 err_msg_index: MessageIndex,
185 bw: *std.io.BufferedWriter,
191 bw: *Writer,
186192 kind: []const u8,
187193 color: std.io.tty.Color,
188194 indent: usize,
189) (std.io.Writer.Error || std.posix.UnexpectedError)!void {
195) (Writer.Error || std.posix.UnexpectedError)!void {
190196 const ttyconf = options.ttyconf;
191197 const err_msg = eb.getErrorMessage(err_msg_index);
192198 const prefix_start = bw.count;
......@@ -294,7 +300,7 @@ fn renderErrorMessageToWriter(
294300/// to allow for long, good-looking error messages.
295301///
296302/// This is used to split the message in `@compileError("hello\nworld")` for example.
297fn writeMsg(eb: ErrorBundle, err_msg: ErrorMessage, bw: *std.io.BufferedWriter, indent: usize) !void {
303fn writeMsg(eb: ErrorBundle, err_msg: ErrorMessage, bw: *Writer, indent: usize) !void {
298304 var lines = std.mem.splitScalar(u8, eb.nullTerminatedString(err_msg.msg), '\n');
299305 while (lines.next()) |line| {
300306 try bw.writeAll(line);
......@@ -304,11 +310,6 @@ fn writeMsg(eb: ErrorBundle, err_msg: ErrorMessage, bw: *std.io.BufferedWriter,
304310 }
305311}
306312
307const std = @import("std");
308const ErrorBundle = @This();
309const Allocator = std.mem.Allocator;
310const assert = std.debug.assert;
311
312313pub const Wip = struct {
313314 gpa: Allocator,
314315 string_bytes: std.ArrayListUnmanaged(u8),
lib/std/zig/Server.zig+3-2
......@@ -1,5 +1,5 @@
11in: *std.io.Reader,
2out: *std.io.BufferedWriter,
2out: *Writer,
33
44pub const Message = struct {
55 pub const Header = extern struct {
......@@ -94,7 +94,7 @@ pub const Message = struct {
9494
9595pub const Options = struct {
9696 in: *std.io.Reader,
97 out: *std.io.BufferedWriter,
97 out: *Writer,
9898 zig_version: []const u8,
9999};
100100
......@@ -215,3 +215,4 @@ const assert = std.debug.assert;
215215const native_endian = builtin.target.cpu.arch.endian();
216216const need_bswap = native_endian != .little;
217217const Cache = std.Build.Cache;
218const Writer = std.io.Writer;
lib/std/zig/WindowsSdk.zig+6-6
......@@ -1,11 +1,12 @@
1const WindowsSdk = @This();
2const builtin = @import("builtin");
3const std = @import("std");
4const Writer = std.io.Writer;
5
16windows10sdk: ?Installation,
27windows81sdk: ?Installation,
38msvc_lib_dir: ?[]const u8,
49
5const WindowsSdk = @This();
6const std = @import("std");
7const builtin = @import("builtin");
8
910const windows = std.os.windows;
1011const RRF = windows.advapi32.RRF;
1112
......@@ -759,8 +760,7 @@ const MsvcLibDir = struct {
759760 while (instances_dir_it.next() catch return error.PathNotFound) |entry| {
760761 if (entry.kind != .directory) continue;
761762
762 var bw: std.io.BufferedWriter = undefined;
763 bw.initFixed(&state_subpath_buf);
763 var bw: Writer = .fixed(&state_subpath_buf);
764764
765765 bw.writeAll(entry.name) catch unreachable;
766766 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 {
521521pub fn parseStrLit(
522522 tree: Ast,
523523 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 {
526526 switch (tree.nodeTag(node)) {
527527 .string_literal => {
528528 const token = tree.nodeMainToken(node);
......@@ -933,3 +933,4 @@ const StringIndexContext = std.hash_map.StringIndexContext;
933933const ZonGen = @This();
934934const Zoir = @import("Zoir.zig");
935935const Ast = @import("Ast.zig");
936const Writer = std.io.Writer;
lib/std/zig/llvm/Builder.zig+35-38
......@@ -91,7 +91,7 @@ pub const String = enum(u32) {
9191 string: String,
9292 builder: *const Builder,
9393 };
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 {
9595 if (comptime std.mem.indexOfNone(u8, fmt_str, "\"r")) |_|
9696 @compileError("invalid format string: '" ++ fmt_str ++ "'");
9797 assert(data.string != .none);
......@@ -649,7 +649,7 @@ pub const Type = enum(u32) {
649649 type: Type,
650650 builder: *const Builder,
651651 };
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 {
653653 assert(data.type != .none);
654654 if (comptime std.mem.eql(u8, fmt_str, "m")) {
655655 const item = data.builder.type_items.items[@intFromEnum(data.type)];
......@@ -1129,7 +1129,7 @@ pub const Attribute = union(Kind) {
11291129 attribute_index: Index,
11301130 builder: *const Builder,
11311131 };
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 {
11331133 if (comptime std.mem.indexOfNone(u8, fmt_str, "\"#")) |_|
11341134 @compileError("invalid format string: '" ++ fmt_str ++ "'");
11351135 const attribute = data.attribute_index.toAttribute(data.builder);
......@@ -1568,7 +1568,7 @@ pub const Attributes = enum(u32) {
15681568 attributes: Attributes,
15691569 builder: *const Builder,
15701570 };
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 {
15721572 for (data.attributes.slice(data.builder)) |attribute_index| try Attribute.Index.format(.{
15731573 .attribute_index = attribute_index,
15741574 .builder = data.builder,
......@@ -1761,11 +1761,11 @@ pub const Linkage = enum(u4) {
17611761 extern_weak = 7,
17621762 external = 0,
17631763
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 {
17651765 if (self != .external) try bw.print(" {s}", .{@tagName(self)});
17661766 }
17671767
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 {
17691769 if (data) |linkage| try bw.print(" {s}", .{@tagName(linkage)});
17701770 }
17711771 pub fn fmtOptional(self: ?Linkage) std.fmt.Formatter(formatOptional) {
......@@ -1778,7 +1778,7 @@ pub const Preemption = enum {
17781778 dso_local,
17791779 implicit_dso_local,
17801780
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 {
17821782 if (self == .dso_local) try bw.print(" {s}", .{@tagName(self)});
17831783 }
17841784};
......@@ -1796,11 +1796,7 @@ pub const Visibility = enum(u2) {
17961796 };
17971797 }
17981798
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 {
18041800 comptime assert(format_string.len == 0);
18051801 if (self != .default) try writer.print(" {s}", .{@tagName(self)});
18061802 }
......@@ -1811,7 +1807,7 @@ pub const DllStorageClass = enum(u2) {
18111807 dllimport = 1,
18121808 dllexport = 2,
18131809
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 {
18151811 if (self != .default) try bw.print(" {s}", .{@tagName(self)});
18161812 }
18171813};
......@@ -1823,7 +1819,7 @@ pub const ThreadLocal = enum(u3) {
18231819 initialexec = 3,
18241820 localexec = 4,
18251821
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 {
18271823 if (self == .default) return;
18281824 try bw.print("{s}thread_local", .{prefix});
18291825 if (self != .generaldynamic) try bw.print("({s})", .{@tagName(self)});
......@@ -1837,7 +1833,7 @@ pub const UnnamedAddr = enum(u2) {
18371833 unnamed_addr = 1,
18381834 local_unnamed_addr = 2,
18391835
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 {
18411837 if (self != .default) try bw.print(" {s}", .{@tagName(self)});
18421838 }
18431839};
......@@ -1931,7 +1927,7 @@ pub const AddrSpace = enum(u24) {
19311927 pub const funcref: AddrSpace = @enumFromInt(20);
19321928 };
19331929
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 {
19351931 if (self != .default) try bw.print("{s}addrspace({d})", .{ prefix, @intFromEnum(self) });
19361932 }
19371933};
......@@ -1940,7 +1936,7 @@ pub const ExternallyInitialized = enum {
19401936 default,
19411937 externally_initialized,
19421938
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 {
19441940 if (self != .default) try bw.print(" {s}", .{@tagName(self)});
19451941 }
19461942};
......@@ -1964,7 +1960,7 @@ pub const Alignment = enum(u6) {
19641960 return if (self == .default) 0 else (@intFromEnum(self) + 1);
19651961 }
19661962
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 {
19681964 try bw.print("{s}align {d}", .{ prefix, self.toByteUnits() orelse return });
19691965 }
19701966};
......@@ -2038,7 +2034,7 @@ pub const CallConv = enum(u10) {
20382034
20392035 pub const default = CallConv.ccc;
20402036
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 {
20422038 switch (self) {
20432039 default => {},
20442040 .fastcc,
......@@ -2119,7 +2115,7 @@ pub const StrtabString = enum(u32) {
21192115 string: StrtabString,
21202116 builder: *const Builder,
21212117 };
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 {
21232119 if (comptime std.mem.indexOfNone(u8, fmt_str, "\"r")) |_|
21242120 @compileError("invalid format string: '" ++ fmt_str ++ "'");
21252121 assert(data.string != .none);
......@@ -2306,7 +2302,7 @@ pub const Global = struct {
23062302 global: Index,
23072303 builder: *const Builder,
23082304 };
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 {
23102306 try bw.print("@{f}", .{
23112307 data.global.unwrap(data.builder).name(data.builder).fmt(data.builder),
23122308 });
......@@ -4752,7 +4748,7 @@ pub const Function = struct {
47524748 function: Function.Index,
47534749 builder: *Builder,
47544750 };
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 {
47564752 if (comptime std.mem.indexOfNone(u8, fmt_str, ", %")) |_|
47574753 @compileError("invalid format string: '" ++ fmt_str ++ "'");
47584754 if (comptime std.mem.indexOfScalar(u8, fmt_str, ',') != null) {
......@@ -6944,7 +6940,7 @@ pub const MemoryAccessKind = enum(u1) {
69446940 normal,
69456941 @"volatile",
69466942
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 {
69486944 if (self != .normal) try bw.print("{s}{s}", .{ prefix, @tagName(self) });
69496945 }
69506946};
......@@ -6953,7 +6949,7 @@ pub const SyncScope = enum(u1) {
69536949 singlethread,
69546950 system,
69556951
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 {
69576953 if (self != .system) try bw.print(
69586954 \\{s}syncscope("{s}")
69596955 , .{ prefix, @tagName(self) });
......@@ -6969,7 +6965,7 @@ pub const AtomicOrdering = enum(u3) {
69696965 acq_rel = 5,
69706966 seq_cst = 6,
69716967
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 {
69736969 if (self != .none) try bw.print("{s}{s}", .{ prefix, @tagName(self) });
69746970 }
69756971};
......@@ -7385,7 +7381,7 @@ pub const Constant = enum(u32) {
73857381 constant: Constant,
73867382 builder: *Builder,
73877383 };
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 {
73897385 if (comptime std.mem.indexOfNone(u8, fmt_str, ", %")) |_|
73907386 @compileError("invalid format string: '" ++ fmt_str ++ "'");
73917387 if (comptime std.mem.indexOfScalar(u8, fmt_str, ',') != null) {
......@@ -7712,7 +7708,7 @@ pub const Value = enum(u32) {
77127708 function: Function.Index,
77137709 builder: *Builder,
77147710 };
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 {
77167712 switch (data.value.unwrap()) {
77177713 .instruction => |instruction| try Function.Instruction.Index.format(.{
77187714 .instruction = instruction,
......@@ -7757,7 +7753,7 @@ pub const MetadataString = enum(u32) {
77577753 metadata_string: MetadataString,
77587754 builder: *const Builder,
77597755 };
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 {
77617757 try printEscapedString(data.metadata_string.slice(data.builder), .always_quote, bw);
77627758 }
77637759 fn fmt(self: MetadataString, builder: *const Builder) std.fmt.Formatter(format) {
......@@ -7922,7 +7918,7 @@ pub const Metadata = enum(u32) {
79227918 AllCallsDescribed: bool = false,
79237919 Unused: u2 = 0,
79247920
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 {
79267922 var need_pipe = false;
79277923 inline for (@typeInfo(DIFlags).@"struct".fields) |field| {
79287924 switch (@typeInfo(field.type)) {
......@@ -7979,7 +7975,7 @@ pub const Metadata = enum(u32) {
79797975 ObjCDirect: bool = false,
79807976 Unused: u20 = 0,
79817977
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 {
79837979 var need_pipe = false;
79847980 inline for (@typeInfo(DISPFlags).@"struct".fields) |field| {
79857981 switch (@typeInfo(field.type)) {
......@@ -8196,7 +8192,7 @@ pub const Metadata = enum(u32) {
81968192 };
81978193 };
81988194 };
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 {
82008196 if (data.node == .none) return;
82018197
82028198 const is_specialized = fmt_str.len > 0 and fmt_str[0] == 'S';
......@@ -8370,7 +8366,7 @@ pub const Metadata = enum(u32) {
83708366 DIGlobalVariableExpression,
83718367 },
83728368 nodes: anytype,
8373 bw: *std.io.BufferedWriter,
8369 bw: *Writer,
83748370 ) !void {
83758371 comptime var fmt_str: []const u8 = "";
83768372 const names = comptime std.meta.fieldNames(@TypeOf(nodes));
......@@ -8623,12 +8619,12 @@ pub fn deinit(self: *Builder) void {
86238619 self.* = undefined;
86248620}
86258621
8626pub fn setModuleAsm(self: *Builder, aw: *std.io.AllocatingWriter) *std.io.BufferedWriter {
8622pub fn setModuleAsm(self: *Builder, aw: *std.io.AllocatingWriter) *Writer {
86278623 self.module_asm.clearRetainingCapacity();
86288624 return self.appendModuleAsm(aw);
86298625}
86308626
8631pub fn appendModuleAsm(self: *Builder, aw: *std.io.AllocatingWriter) *std.io.BufferedWriter {
8627pub fn appendModuleAsm(self: *Builder, aw: *std.io.AllocatingWriter) *Writer {
86328628 return aw.fromArrayList(self.gpa, &self.module_asm);
86338629}
86348630
......@@ -9379,14 +9375,14 @@ pub fn printToFile(self: *Builder, path: []const u8) bool {
93799375 return true;
93809376}
93819377
9382pub fn printBuffered(self: *Builder, writer: std.io.Writer) std.io.Writer.Error!void {
9378pub fn printBuffered(self: *Builder, writer: Writer) Writer.Error!void {
93839379 var buffer: [4096]u8 = undefined;
93849380 var bw = writer.buffered(&buffer);
93859381 try self.print(&bw);
93869382 try bw.flush();
93879383}
93889384
9389pub fn print(self: *Builder, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
9385pub fn print(self: *Builder, bw: *Writer) Writer.Error!void {
93909386 var need_newline = false;
93919387 var metadata_formatter: Metadata.Formatter = .{ .builder = self, .need_comma = undefined };
93929388 defer metadata_formatter.map.deinit(self.gpa);
......@@ -10458,7 +10454,7 @@ fn isValidIdentifier(id: []const u8) bool {
1045810454}
1045910455
1046010456const QuoteBehavior = enum { always_quote, quote_unless_valid_identifier };
10461fn printEscapedString(slice: []const u8, quotes: QuoteBehavior, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
10457fn printEscapedString(slice: []const u8, quotes: QuoteBehavior, bw: *Writer) Writer.Error!void {
1046210458 const need_quotes = switch (quotes) {
1046310459 .always_quote => true,
1046410460 .quote_unless_valid_identifier => !isValidIdentifier(slice),
......@@ -15097,6 +15093,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco
1509715093 return bitcode.toOwnedSlice();
1509815094}
1509915095
15096const std = @import("../../std.zig");
1510015097const Allocator = std.mem.Allocator;
1510115098const assert = std.debug.assert;
1510215099const bitcode_writer = @import("bitcode_writer.zig");
......@@ -15105,4 +15102,4 @@ const builtin = @import("builtin");
1510515102const DW = std.dwarf;
1510615103const ir = @import("ir.zig");
1510715104const log = std.log.scoped(.llvm);
15108const std = @import("../../std.zig");
15105const Writer = std.io.Writer;
lib/std/zig/string_literal.zig+4-3
......@@ -1,6 +1,7 @@
11const std = @import("../std.zig");
22const assert = std.debug.assert;
33const utf8Encode = std.unicode.utf8Encode;
4const Writer = std.io.Writer;
45
56pub const ParseError = error{
67 OutOfMemory,
......@@ -44,7 +45,7 @@ pub const Error = union(enum) {
4445 raw_string: []const u8,
4546 };
4647
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 {
4849 _ = f;
4950 switch (self.err) {
5051 .invalid_escape_character => |bad_index| try bw.print(
......@@ -316,9 +317,9 @@ test parseCharLiteral {
316317 );
317318}
318319
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.
320321/// Asserts `bytes` has '"' at beginning and end.
321pub fn parseWrite(writer: *std.io.BufferedWriter, bytes: []const u8) std.io.Writer.Error!Result {
322pub fn parseWrite(writer: *Writer, bytes: []const u8) Writer.Error!Result {
322323 assert(bytes.len >= 2 and bytes[0] == '"' and bytes[bytes.len - 1] == '"');
323324
324325 var index: usize = 1;
lib/std/zip.zig+3-2
......@@ -7,6 +7,7 @@ const builtin = @import("builtin");
77const std = @import("std");
88const File = std.fs.File;
99const is_le = builtin.target.cpu.arch.endian() == .little;
10const Writer = std.io.Writer;
1011
1112pub const CompressionMethod = enum(u16) {
1213 store = 0,
......@@ -200,7 +201,7 @@ pub const Decompress = union {
200201
201202 fn readStore(
202203 context: ?*anyopaque,
203 writer: *std.io.BufferedWriter,
204 writer: *Writer,
204205 limit: std.io.Limit,
205206 ) std.io.Reader.StreamError!usize {
206207 const d: *Decompress = @ptrCast(@alignCast(context));
......@@ -209,7 +210,7 @@ pub const Decompress = union {
209210
210211 fn readDeflate(
211212 context: ?*anyopaque,
212 writer: *std.io.BufferedWriter,
213 writer: *Writer,
213214 limit: std.io.Limit,
214215 ) std.io.Reader.StreamError!usize {
215216 const d: *Decompress = @ptrCast(@alignCast(context));
lib/std/zip/test.zig+5-5
......@@ -3,6 +3,7 @@ const testing = std.testing;
33const zip = @import("../zip.zig");
44const maxInt = std.math.maxInt;
55const assert = std.debug.assert;
6const Writer = std.io.Writer;
67
78const File = struct {
89 name: []const u8,
......@@ -103,7 +104,7 @@ const Zip64Options = struct {
103104};
104105
105106fn writeZip(
106 writer: *std.io.BufferedWriter,
107 writer: *Writer,
107108 files: []const File,
108109 store: []FileStore,
109110 options: WriteZipOptions,
......@@ -129,13 +130,13 @@ fn writeZip(
129130/// Provides methods to format and write the contents of a zip archive
130131/// to the underlying Writer.
131132const Zipper = struct {
132 writer: *std.io.BufferedWriter,
133 writer: *Writer,
133134 init_count: u64,
134135 central_count: u64 = 0,
135136 first_central_offset: ?u64 = null,
136137 last_central_limit: ?u64 = null,
137138
138 fn init(writer: *std.io.BufferedWriter) Zipper {
139 fn init(writer: *Writer) Zipper {
139140 return .{ .writer = writer, .init_count = writer.count };
140141 }
141142
......@@ -198,8 +199,7 @@ const Zipper = struct {
198199 },
199200 .deflate => {
200201 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);
203203 var compress: std.compress.flate.Compress = .init(&br, .{});
204204 var compress_br = compress.readable(&.{});
205205 const n = try compress_br.readRemaining(writer);
lib/std/zon/stringify.zig+7-7
......@@ -22,7 +22,7 @@
2222
2323const std = @import("std");
2424const assert = std.debug.assert;
25const BufferedWriter = std.io.BufferedWriter;
25const Writer = std.io.Writer;
2626
2727/// Options for `serialize`.
2828pub const SerializeOptions = struct {
......@@ -41,7 +41,7 @@ pub const SerializeOptions = struct {
4141/// Serialize the given value as ZON.
4242///
4343/// It is asserted at comptime that `@TypeOf(val)` is not a recursive type.
44pub fn serialize(val: anytype, options: SerializeOptions, writer: *BufferedWriter) std.io.Writer.Error!void {
44pub fn serialize(val: anytype, options: SerializeOptions, writer: *Writer) Writer.Error!void {
4545 var s: Serializer = .{
4646 .writer = writer,
4747 .options = .{ .whitespace = options.whitespace },
......@@ -60,7 +60,7 @@ pub fn serialize(val: anytype, options: SerializeOptions, writer: *BufferedWrite
6060pub fn serializeMaxDepth(
6161 val: anytype,
6262 options: SerializeOptions,
63 writer: *BufferedWriter,
63 writer: *Writer,
6464 depth: usize,
6565) Serializer.DepthError!void {
6666 var s: Serializer = .{
......@@ -80,7 +80,7 @@ pub fn serializeMaxDepth(
8080pub fn serializeArbitraryDepth(
8181 val: anytype,
8282 options: SerializeOptions,
83 writer: *BufferedWriter,
83 writer: *Writer,
8484) Serializer.Error!void {
8585 var s: Serializer = .{
8686 .writer = writer,
......@@ -437,9 +437,9 @@ pub const SerializeContainerOptions = struct {
437437pub const Serializer = struct {
438438 options: Options = .{},
439439 indent_level: u8 = 0,
440 writer: *BufferedWriter,
440 writer: *Writer,
441441
442 pub const Error = std.io.Writer.Error;
442 pub const Error = Writer.Error;
443443 pub const DepthError = Error || error{ExceededMaxDepth};
444444
445445 pub const Options = struct {
......@@ -1040,7 +1040,7 @@ pub const Serializer = struct {
10401040};
10411041
10421042test Serializer {
1043 var bw: std.io.BufferedWriter = .{
1043 var bw: Writer = .{
10441044 .unbuffered_writer = .discarding,
10451045 .buffer = &.{},
10461046 };
lib/ubsan_rt.zig+1-1
......@@ -119,7 +119,7 @@ const Value = extern struct {
119119 }
120120 }
121121
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 {
123123 comptime assert(fmt.len == 0);
124124
125125 // Work around x86_64 backend limitation.
src/Air.zig+3-1
......@@ -7,6 +7,7 @@
77const std = @import("std");
88const builtin = @import("builtin");
99const assert = std.debug.assert;
10const Writer = std.io.Writer;
1011
1112const Air = @This();
1213const InternPool = @import("InternPool.zig");
......@@ -957,7 +958,8 @@ pub const Inst = struct {
957958 return index.unwrap().target;
958959 }
959960
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);
961963 try bw.writeByte('%');
962964 switch (index.unwrap()) {
963965 .ref => {},
src/Air/Liveness.zig+4-2
......@@ -10,6 +10,7 @@ const log = std.log.scoped(.liveness);
1010const assert = std.debug.assert;
1111const Allocator = std.mem.Allocator;
1212const Log2Int = std.math.Log2Int;
13const Writer = std.io.Writer;
1314
1415const Liveness = @This();
1516const trace = @import("../tracy.zig").trace;
......@@ -2036,7 +2037,7 @@ fn fmtInstSet(set: *const std.AutoHashMapUnmanaged(Air.Inst.Index, void)) FmtIns
20362037const FmtInstSet = struct {
20372038 set: *const std.AutoHashMapUnmanaged(Air.Inst.Index, void),
20382039
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 {
20402041 if (val.set.count() == 0) {
20412042 try bw.writeAll("[no instructions]");
20422043 return;
......@@ -2056,7 +2057,8 @@ fn fmtInstList(list: []const Air.Inst.Index) FmtInstList {
20562057const FmtInstList = struct {
20572058 list: []const Air.Inst.Index,
20582059
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);
20602062 if (val.list.len == 0) {
20612063 try bw.writeAll("[no instructions]");
20622064 return;
src/Air/print.zig+45-45
......@@ -8,7 +8,7 @@ const Type = @import("../Type.zig");
88const Air = @import("../Air.zig");
99const InternPool = @import("../InternPool.zig");
1010
11pub fn write(air: Air, stream: *std.io.BufferedWriter, pt: Zcu.PerThread, liveness: ?Air.Liveness) void {
11pub fn write(air: Air, stream: *std.io.Writer, pt: Zcu.PerThread, liveness: ?Air.Liveness) void {
1212 comptime std.debug.assert(build_options.enable_debug_extensions);
1313 const instruction_bytes = air.instructions.len *
1414 // 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
5454
5555pub fn writeInst(
5656 air: Air,
57 stream: *std.io.BufferedWriter,
57 stream: *std.io.Writer,
5858 inst: Air.Inst.Index,
5959 pt: Zcu.PerThread,
6060 liveness: ?Air.Liveness,
......@@ -93,14 +93,14 @@ const Writer = struct {
9393
9494 const Error = std.io.Writer.Error;
9595
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 {
9797 for (body) |inst| {
9898 try w.writeInst(s, inst);
9999 try s.writeByte('\n');
100100 }
101101 }
102102
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 {
104104 const tag = w.air.instructions.items(.tag)[@intFromEnum(inst)];
105105 try s.splatByteAll(' ', w.indent);
106106 try s.print("{f}{c}= {s}(", .{
......@@ -340,48 +340,48 @@ const Writer = struct {
340340 try s.writeByte(')');
341341 }
342342
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 {
344344 const bin_op = w.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
345345 try w.writeOperand(s, inst, 0, bin_op.lhs);
346346 try s.writeAll(", ");
347347 try w.writeOperand(s, inst, 1, bin_op.rhs);
348348 }
349349
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 {
351351 const un_op = w.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
352352 try w.writeOperand(s, inst, 0, un_op);
353353 }
354354
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 {
356356 _ = w;
357357 _ = s;
358358 _ = inst;
359359 // no-op, no argument to write
360360 }
361361
362 fn writeType(w: *Writer, s: *std.io.BufferedWriter, ty: Type) !void {
362 fn writeType(w: *Writer, s: *std.io.Writer, ty: Type) !void {
363363 return ty.print(s, w.pt);
364364 }
365365
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 {
367367 const ty = w.air.instructions.items(.data)[@intFromEnum(inst)].ty;
368368 try w.writeType(s, ty);
369369 }
370370
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 {
372372 const arg = w.air.instructions.items(.data)[@intFromEnum(inst)].arg;
373373 try w.writeType(s, arg.ty.toType());
374374 try s.print(", {d}", .{arg.zir_param_index});
375375 }
376376
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 {
378378 const ty_op = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
379379 try w.writeType(s, ty_op.ty.toType());
380380 try s.writeAll(", ");
381381 try w.writeOperand(s, inst, 0, ty_op.operand);
382382 }
383383
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 {
385385 const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
386386 try w.writeType(s, ty_pl.ty.toType());
387387 const body: []const Air.Inst.Index = @ptrCast(switch (tag) {
......@@ -422,7 +422,7 @@ const Writer = struct {
422422 }
423423 }
424424
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 {
426426 const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
427427 const extra = w.air.extraData(Air.Block, ty_pl.payload);
428428 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 {
438438 try s.writeAll("}");
439439 }
440440
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 {
442442 const zcu = w.pt.zcu;
443443 const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
444444 const vector_ty = ty_pl.ty.toType();
......@@ -454,7 +454,7 @@ const Writer = struct {
454454 try s.writeAll("]");
455455 }
456456
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 {
458458 const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
459459 const extra = w.air.extraData(Air.UnionInit, ty_pl.payload).data;
460460
......@@ -462,7 +462,7 @@ const Writer = struct {
462462 try w.writeOperand(s, inst, 0, extra.init);
463463 }
464464
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 {
466466 const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
467467 const extra = w.air.extraData(Air.StructField, ty_pl.payload).data;
468468
......@@ -470,7 +470,7 @@ const Writer = struct {
470470 try s.print(", {d}", .{extra.field_index});
471471 }
472472
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 {
474474 const data = w.air.instructions.items(.data);
475475 const ty_pl = data[@intFromEnum(inst)].ty_pl;
476476 const extra = w.air.extraData(Air.Bin, ty_pl.payload).data;
......@@ -483,7 +483,7 @@ const Writer = struct {
483483 try w.writeOperand(s, inst, 1, extra.rhs);
484484 }
485485
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 {
487487 const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
488488 const extra = w.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
489489
......@@ -497,7 +497,7 @@ const Writer = struct {
497497 });
498498 }
499499
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 {
501501 const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
502502 const extra = w.air.extraData(Air.Bin, pl_op.payload).data;
503503
......@@ -508,7 +508,7 @@ const Writer = struct {
508508 try w.writeOperand(s, inst, 2, pl_op.operand);
509509 }
510510
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 {
512512 const unwrapped = w.air.unwrapShuffleOne(w.pt.zcu, inst);
513513 try w.writeType(s, unwrapped.result_ty);
514514 try s.writeAll(", ");
......@@ -543,7 +543,7 @@ const Writer = struct {
543543 try s.writeByte(']');
544544 }
545545
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 {
547547 const zcu = w.pt.zcu;
548548 const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
549549 const extra = w.air.extraData(Air.Bin, pl_op.payload).data;
......@@ -558,14 +558,14 @@ const Writer = struct {
558558 try w.writeOperand(s, inst, 2, extra.rhs);
559559 }
560560
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 {
562562 const reduce = w.air.instructions.items(.data)[@intFromEnum(inst)].reduce;
563563
564564 try w.writeOperand(s, inst, 0, reduce.operand);
565565 try s.print(", {s}", .{@tagName(reduce.operation)});
566566 }
567567
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 {
569569 const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
570570 const extra = w.air.extraData(Air.VectorCmp, ty_pl.payload).data;
571571
......@@ -575,7 +575,7 @@ const Writer = struct {
575575 try w.writeOperand(s, inst, 1, extra.rhs);
576576 }
577577
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 {
579579 const data = w.air.instructions.items(.data)[@intFromEnum(inst)].vector_store_elem;
580580 const extra = w.air.extraData(Air.VectorCmp, data.payload).data;
581581
......@@ -586,21 +586,21 @@ const Writer = struct {
586586 try w.writeOperand(s, inst, 2, extra.rhs);
587587 }
588588
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 {
590590 const ip = &w.pt.zcu.intern_pool;
591591 const ty_nav = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_nav;
592592 try w.writeType(s, .fromInterned(ty_nav.ty));
593593 try s.print(", '{}'", .{ip.getNav(ty_nav.nav).fqn.fmt(ip)});
594594 }
595595
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 {
597597 const atomic_load = w.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load;
598598
599599 try w.writeOperand(s, inst, 0, atomic_load.ptr);
600600 try s.print(", {s}", .{@tagName(atomic_load.order)});
601601 }
602602
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 {
604604 const prefetch = w.air.instructions.items(.data)[@intFromEnum(inst)].prefetch;
605605
606606 try w.writeOperand(s, inst, 0, prefetch.ptr);
......@@ -611,7 +611,7 @@ const Writer = struct {
611611
612612 fn writeAtomicStore(
613613 w: *Writer,
614 s: *std.io.BufferedWriter,
614 s: *std.io.Writer,
615615 inst: Air.Inst.Index,
616616 order: std.builtin.AtomicOrder,
617617 ) Error!void {
......@@ -622,7 +622,7 @@ const Writer = struct {
622622 try s.print(", {s}", .{@tagName(order)});
623623 }
624624
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 {
626626 const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
627627 const extra = w.air.extraData(Air.AtomicRmw, pl_op.payload).data;
628628
......@@ -632,7 +632,7 @@ const Writer = struct {
632632 try s.print(", {s}, {s}", .{ @tagName(extra.op()), @tagName(extra.ordering()) });
633633 }
634634
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 {
636636 const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
637637 const extra = w.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
638638
......@@ -640,7 +640,7 @@ const Writer = struct {
640640 try s.print(", {d}", .{extra.field_index});
641641 }
642642
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 {
644644 const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
645645 const extra = w.air.extraData(Air.Asm, ty_pl.payload);
646646 const is_volatile = @as(u1, @truncate(extra.data.flags >> 31)) != 0;
......@@ -713,19 +713,19 @@ const Writer = struct {
713713 try s.print(", \"{f}\"", .{std.zig.fmtEscapes(asm_source)});
714714 }
715715
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 {
717717 const dbg_stmt = w.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;
718718 try s.print("{d}:{d}", .{ dbg_stmt.line + 1, dbg_stmt.column + 1 });
719719 }
720720
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 {
722722 const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
723723 try w.writeOperand(s, inst, 0, pl_op.operand);
724724 const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload);
725725 try s.print(", \"{f}\"", .{std.zig.fmtEscapes(name.toSlice(w.air))});
726726 }
727727
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 {
729729 const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
730730 const extra = w.air.extraData(Air.Call, pl_op.payload);
731731 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 {
738738 try s.writeAll("]");
739739 }
740740
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 {
742742 const br = w.air.instructions.items(.data)[@intFromEnum(inst)].br;
743743 try w.writeInstIndex(s, br.block_inst, false);
744744 try s.writeAll(", ");
745745 try w.writeOperand(s, inst, 0, br.operand);
746746 }
747747
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 {
749749 const repeat = w.air.instructions.items(.data)[@intFromEnum(inst)].repeat;
750750 try w.writeInstIndex(s, repeat.loop_inst, false);
751751 }
752752
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 {
754754 const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
755755 const extra = w.air.extraData(Air.Try, pl_op.payload);
756756 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 {
784784 }
785785 }
786786
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 {
788788 const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
789789 const extra = w.air.extraData(Air.TryPtr, ty_pl.payload);
790790 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 {
821821 }
822822 }
823823
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 {
825825 const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
826826 const extra = w.air.extraData(Air.CondBr, pl_op.payload);
827827 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 {
880880 try s.writeAll("}");
881881 }
882882
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 {
884884 const switch_br = w.air.unwrapSwitch(inst);
885885
886886 const liveness: Air.Liveness.SwitchBrTable = if (w.liveness) |liveness|
......@@ -966,25 +966,25 @@ const Writer = struct {
966966 try s.splatByteAll(' ', old_indent);
967967 }
968968
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 {
970970 const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
971971 try s.print("{d}", .{pl_op.payload});
972972 }
973973
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 {
975975 const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
976976 try s.print("{d}, ", .{pl_op.payload});
977977 try w.writeOperand(s, inst, 0, pl_op.operand);
978978 }
979979
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 {
981981 const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
982982 try s.print("{d}", .{pl_op.payload});
983983 }
984984
985985 fn writeOperand(
986986 w: *Writer,
987 s: *std.io.BufferedWriter,
987 s: *std.io.Writer,
988988 inst: Air.Inst.Index,
989989 op_index: usize,
990990 operand: Air.Inst.Ref,
......@@ -1030,7 +1030,7 @@ const Writer = struct {
10301030
10311031 fn writeInstIndex(
10321032 w: *Writer,
1033 s: *std.io.BufferedWriter,
1033 s: *std.io.Writer,
10341034 inst: Air.Inst.Index,
10351035 dies: bool,
10361036 ) Error!void {
src/Compilation.zig+7-9
......@@ -12,6 +12,7 @@ const ThreadPool = std.Thread.Pool;
1212const WaitGroup = std.Thread.WaitGroup;
1313const ErrorBundle = std.zig.ErrorBundle;
1414const fatal = std.process.fatal;
15const Writer = std.io.Writer;
1516
1617const Value = @import("Value.zig");
1718const Type = @import("Type.zig");
......@@ -1000,15 +1001,12 @@ pub const CObject = struct {
10001001
10011002 const file = std.fs.cwd().openFile(file_name, .{}) catch break :source_line 0;
10021003 defer file.close();
1003 file.seekTo(diag.src_loc.offset + 1 - diag.src_loc.column) catch break :source_line 0;
1004
10051004 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);
10101008 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],
10121010 );
10131011 };
10141012
......@@ -6026,8 +6024,8 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32
60266024
60276025 // In .rc files, a " within a quoted string is escaped as ""
60286026 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);
60316029 for (bytes) |byte| switch (byte) {
60326030 '"' => try bw.writeAll("\"\""),
60336031 '\\' => try bw.writeAll("\\\\"),
src/InternPool.zig+1-1
......@@ -1888,7 +1888,7 @@ pub const NullTerminatedString = enum(u32) {
18881888 string: NullTerminatedString,
18891889 ip: *const InternPool,
18901890 };
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 {
18921892 const slice = data.string.toSlice(data.ip);
18931893 if (comptime std.mem.eql(u8, specifier, "")) {
18941894 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
13661366 const index_prog_node = f.prog_node.start("Index pack", 0);
13671367 defer index_prog_node.end();
13681368 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();
13721372 try index_file.sync();
13731373 }
13741374
......@@ -1639,14 +1639,14 @@ fn computeHash(f: *Fetch, pkg_path: Cache.Path, filter: Filter) RunError!Compute
16391639
16401640fn dumpHashInfo(all_files: []const *const HashedFile) !void {
16411641 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;
16431644 for (all_files) |hashed_file| {
1644 try bw.print("{s}: {x}: {s}\n", .{
1645 try w.print("{s}: {x}: {s}\n", .{
16451646 @tagName(hashed_file.kind), &hashed_file.hash, hashed_file.normalized_path,
16461647 });
16471648 }
1648
1649 try bw.flush();
1649 try file_writer.flush();
16501650}
16511651
16521652fn 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;
1212const Sha256 = std.crypto.hash.sha2.Sha256;
1313const assert = std.debug.assert;
1414const zlib = std.compress.zlib;
15const Writer = std.io.Writer;
1516
1617/// The ID of a Git object.
1718pub const Oid = union(Format) {
......@@ -65,7 +66,7 @@ pub const Oid = union(Format) {
6566 };
6667 }
6768
68 pub fn writable(hasher: *Hasher, buffer: []u8) std.io.BufferedWriter {
69 pub fn writer(hasher: *Hasher, buffer: []u8) Writer {
6970 return switch (hasher.*) {
7071 inline else => |*inner| inner.writable(buffer),
7172 };
......@@ -134,9 +135,9 @@ pub const Oid = union(Format) {
134135 } else error.InvalidOid;
135136 }
136137
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()});
140141 }
141142
142143 pub fn slice(oid: *const Oid) []const u8 {
......@@ -608,7 +609,7 @@ const Packet = union(enum) {
608609 }
609610
610611 /// 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 {
612613 switch (packet) {
613614 .flush => try writer.writeAll("0000"),
614615 .delimiter => try writer.writeAll("0001"),
......@@ -1481,8 +1482,7 @@ fn resolveDeltaChain(
14811482 const expanded_alloc_size = std.math.cast(usize, expanded_size) orelse return error.ObjectTooLarge;
14821483 const expanded_data = try allocator.alloc(u8, expanded_alloc_size);
14831484 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);
14861486 try expandDelta(base_data, &delta_reader, &expanded_delta_stream);
14871487 if (expanded_delta_stream.end != expanded_size) return error.InvalidObject;
14881488
......@@ -1505,7 +1505,7 @@ fn readObjectRaw(gpa: Allocator, reader: *std.io.Reader, size: u64) ![]u8 {
15051505
15061506/// The format of the delta data is documented in
15071507/// [pack-format](https://git-scm.com/docs/pack-format).
1508fn expandDelta(base_object: []const u8, delta_reader: *std.io.Reader, writer: *std.io.BufferedWriter) !void {
1508fn expandDelta(base_object: []const u8, delta_reader: *std.io.Reader, writer: *Writer) !void {
15091509 var base_offset: u32 = 0;
15101510 while (true) {
15111511 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 {
95449544fn checkCallConvSupportsVarArgs(sema: *Sema, block: *Block, src: LazySrcLoc, cc: std.builtin.CallingConvention.Tag) CompileError!void {
95459545 const CallingConventionsSupportingVarArgsList = struct {
95469546 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);
95499549 var first = true;
95509550 for (calling_conventions_supporting_var_args) |cc_inner| {
95519551 for (std.Target.Cpu.Arch.fromCallingConvention(cc_inner)) |supported_arch| {
......@@ -9990,8 +9990,8 @@ fn finishFunc(
99909990 .bad_arch => |allowed_archs| {
99919991 const ArchListFormatter = struct {
99929992 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);
99959995 for (formatter.archs, 0..) |arch, i| {
99969996 if (i != 0)
99979997 try bw.writeAll(", ");
src/Type.zig+5-4
......@@ -18,6 +18,7 @@ const Alignment = InternPool.Alignment;
1818const Zir = std.zig.Zir;
1919const Type = @This();
2020const SemaError = Zcu.SemaError;
21const Writer = std.io.Writer;
2122
2223ip_index: InternPool.Index,
2324
......@@ -121,7 +122,7 @@ pub fn eql(a: Type, b: Type, zcu: *const Zcu) bool {
121122 return a.toIntern() == b.toIntern();
122123}
123124
124pub fn format(ty: Type, bw: *std.io.BufferedWriter, comptime f: []const u8) !usize {
125pub fn format(ty: Type, bw: *Writer, comptime f: []const u8) !usize {
125126 _ = ty;
126127 _ = f;
127128 _ = bw;
......@@ -142,7 +143,7 @@ const FormatContext = struct {
142143 pt: Zcu.PerThread,
143144};
144145
145fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime f: []const u8) !void {
146fn format2(ctx: FormatContext, bw: *Writer, comptime f: []const u8) !void {
146147 comptime assert(f.len == 0);
147148 try print(ctx.ty, bw, ctx.pt);
148149}
......@@ -153,14 +154,14 @@ pub fn fmtDebug(ty: Type) std.fmt.Formatter(dump) {
153154
154155/// This is a debug function. In order to print types in a meaningful way
155156/// we also need access to the module.
156pub fn dump(start_type: Type, bw: *std.io.BufferedWriter, comptime unused_format_string: []const u8) !void {
157pub fn dump(start_type: Type, bw: *Writer, comptime unused_format_string: []const u8) !void {
157158 comptime assert(unused_format_string.len == 0);
158159 return bw.print("{any}", .{start_type.ip_index});
159160}
160161
161162/// Prints a name suitable for `@typeName`.
162163/// TODO: take an `opt_sema` to pass to `fmtValue` when printing sentinels.
163pub fn print(ty: Type, bw: *std.io.BufferedWriter, pt: Zcu.PerThread) std.io.Writer.Error!void {
164pub fn print(ty: Type, bw: *Writer, pt: Zcu.PerThread) Writer.Error!void {
164165 const zcu = pt.zcu;
165166 const ip = &zcu.intern_pool;
166167 switch (ip.indexToKey(ty.toIntern())) {
src/Zcu.zig+4-4
......@@ -15,6 +15,7 @@ const BigIntConst = std.math.big.int.Const;
1515const BigIntMutable = std.math.big.int.Mutable;
1616const Target = std.Target;
1717const Ast = std.zig.Ast;
18const Writer = std.io.Writer;
1819
1920const Zcu = @This();
2021const Compilation = @import("Compilation.zig");
......@@ -1101,8 +1102,7 @@ pub const File = struct {
11011102 const gpa = pt.zcu.gpa;
11021103 const ip = &pt.zcu.intern_pool;
11031104 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]);
11061106 file.renderFullyQualifiedName(&bw) catch unreachable;
11071107 assert(bw.end == bw.buffer.len);
11081108 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
42604260 return .{ .data = .{ .dependee = d, .zcu = zcu } };
42614261}
42624262
4263fn formatAnalUnit(data: struct { unit: AnalUnit, zcu: *Zcu }, bw: *std.io.BufferedWriter, comptime fmt: []const u8) !void {
4263fn formatAnalUnit(data: struct { unit: AnalUnit, zcu: *Zcu }, bw: *Writer, comptime fmt: []const u8) !void {
42644264 _ = fmt;
42654265 const zcu = data.zcu;
42664266 const ip = &zcu.intern_pool;
......@@ -4284,7 +4284,7 @@ fn formatAnalUnit(data: struct { unit: AnalUnit, zcu: *Zcu }, bw: *std.io.Buffer
42844284 .memoized_state => return bw.writeAll("memoized_state"),
42854285 }
42864286}
4287fn formatDependee(data: struct { dependee: InternPool.Dependee, zcu: *Zcu }, bw: *std.io.BufferedWriter, comptime fmt: []const u8) !void {
4287fn formatDependee(data: struct { dependee: InternPool.Dependee, zcu: *Zcu }, bw: *Writer, comptime fmt: []const u8) !void {
42884288 _ = fmt;
42894289 const zcu = data.zcu;
42904290 const ip = &zcu.intern_pool;
src/arch/riscv64/CodeGen.zig+14-6
......@@ -6,6 +6,7 @@ const mem = std.mem;
66const math = std.math;
77const assert = std.debug.assert;
88const Allocator = mem.Allocator;
9const Writer = std.io.Writer;
910
1011const Air = @import("../../Air.zig");
1112const Mir = @import("Mir.zig");
......@@ -566,7 +567,8 @@ const InstTracking = struct {
566567 }
567568 }
568569
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);
570572 if (!std.meta.eql(inst_tracking.long, inst_tracking.short)) try bw.print("|{}| ", .{inst_tracking.long});
571573 try bw.print("{}", .{inst_tracking.short});
572574 }
......@@ -932,7 +934,7 @@ const FormatWipMirData = struct {
932934 func: *Func,
933935 inst: Mir.Inst.Index,
934936};
935fn formatWipMir(data: FormatWipMirData, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void {
937fn formatWipMir(data: FormatWipMirData, bw: *Writer, comptime _: []const u8) Writer.Error!void {
936938 const pt = data.func.pt;
937939 const comp = pt.zcu.comp;
938940 var lower: Lower = .{
......@@ -980,7 +982,7 @@ const FormatNavData = struct {
980982 ip: *const InternPool,
981983 nav_index: InternPool.Nav.Index,
982984};
983fn formatNav(data: FormatNavData, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void {
985fn formatNav(data: FormatNavData, bw: *Writer, comptime _: []const u8) Writer.Error!void {
984986 try bw.print("{f}", .{data.ip.getNav(data.nav_index).fqn.fmt(data.ip)});
985987}
986988fn fmtNav(nav_index: InternPool.Nav.Index, ip: *const InternPool) std.fmt.Formatter(formatNav) {
......@@ -994,8 +996,13 @@ const FormatAirData = struct {
994996 func: *Func,
995997 inst: Air.Inst.Index,
996998};
997fn 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);
999fn 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");
9991006}
10001007fn fmtAir(func: *Func, inst: Air.Inst.Index) std.fmt.Formatter(formatAir) {
10011008 return .{ .data = .{ .func = func, .inst = inst } };
......@@ -1004,7 +1011,8 @@ fn fmtAir(func: *Func, inst: Air.Inst.Index) std.fmt.Formatter(formatAir) {
10041011const FormatTrackingData = struct {
10051012 func: *Func,
10061013};
1007fn formatTracking(data: FormatTrackingData, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void {
1014fn formatTracking(data: FormatTrackingData, bw: *Writer, comptime fmt: []const u8) Writer.Error!void {
1015 comptime assert(fmt.len == 0);
10081016 var it = data.func.inst_tracking.iterator();
10091017 while (it.next()) |entry| try bw.print("\n%{d} = {f}", .{ entry.key_ptr.*, entry.value_ptr.* });
10101018}
src/arch/riscv64/Mir.zig+1-1
......@@ -92,7 +92,7 @@ pub const Inst = struct {
9292 },
9393 };
9494
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 {
9696 assert(fmt.len == 0);
9797 try bw.print("Tag: {s}, Data: {s}", .{ @tagName(inst.tag), @tagName(inst.data) });
9898 }
src/arch/riscv64/bits.zig+3-1
......@@ -2,6 +2,7 @@ const std = @import("std");
22const assert = std.debug.assert;
33const testing = std.testing;
44const Target = std.Target;
5const Writer = std.io.Writer;
56
67const Zcu = @import("../../Zcu.zig");
78const Mir = @import("Mir.zig");
......@@ -256,7 +257,8 @@ pub const FrameIndex = enum(u32) {
256257 return @intFromEnum(fi) < named_count;
257258 }
258259
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);
260262 try bw.writeAll("FrameIndex");
261263 if (fi.isNamed())
262264 try bw.print(".{s}", .{@tagName(fi)})
src/arch/wasm/CodeGen.zig+1
......@@ -5,6 +5,7 @@ const assert = std.debug.assert;
55const testing = std.testing;
66const mem = std.mem;
77const log = std.log.scoped(.codegen);
8const Writer = std.io.Writer;
89
910const CodeGen = @This();
1011const codegen = @import("../../codegen.zig");
src/arch/wasm/Emit.zig+7-6
......@@ -4,6 +4,7 @@ const std = @import("std");
44const assert = std.debug.assert;
55const Allocator = std.mem.Allocator;
66const leb = std.leb;
7const Writer = std.io.Writer;
78
89const Wasm = link.File.Wasm;
910const Mir = @import("Mir.zig");
......@@ -15,7 +16,7 @@ const codegen = @import("../../codegen.zig");
1516mir: Mir,
1617wasm: *Wasm,
1718/// The binary representation of this module is written here.
18bw: *std.io.BufferedWriter,
19bw: *Writer,
1920
2021pub const Error = error{
2122 OutOfMemory,
......@@ -893,12 +894,12 @@ pub fn lowerToCode(emit: *Emit) Error!void {
893894}
894895
895896/// Asserts 20 unused capacity.
896fn encodeMemArg(bw: *std.io.BufferedWriter, mem_arg: Mir.MemArg) std.io.Writer.Error!void {
897fn encodeMemArg(bw: *Writer, mem_arg: Mir.MemArg) Writer.Error!void {
897898 try bw.writeLeb128(Wasm.Alignment.fromNonzeroByteUnits(mem_arg.alignment).toLog2Units());
898899 try bw.writeLeb128(mem_arg.offset);
899900}
900901
901fn uavRefObj(wasm: *Wasm, bw: *std.io.BufferedWriter, value: InternPool.Index, offset: i32, is_wasm32: bool) std.io.Writer.Error!void {
902fn uavRefObj(wasm: *Wasm, bw: *Writer, value: InternPool.Index, offset: i32, is_wasm32: bool) Writer.Error!void {
902903 const comp = wasm.base.comp;
903904 const gpa = comp.gpa;
904905 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
914915 try bw.splatByteAll(0, if (is_wasm32) 5 else 10);
915916}
916917
917fn uavRefExe(wasm: *Wasm, bw: *std.io.BufferedWriter, value: InternPool.Index, offset: i32, is_wasm32: bool) !void {
918fn uavRefExe(wasm: *Wasm, bw: *Writer, value: InternPool.Index, offset: i32, is_wasm32: bool) !void {
918919 const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const;
919920 try bw.writeByte(@intFromEnum(opcode));
920921
......@@ -922,7 +923,7 @@ fn uavRefExe(wasm: *Wasm, bw: *std.io.BufferedWriter, value: InternPool.Index, o
922923 try bw.writeLeb128(@as(u32, @intCast(@as(i64, addr) + offset)));
923924}
924925
925fn navRefOff(wasm: *Wasm, bw: *std.io.BufferedWriter, data: Mir.NavRefOff, is_wasm32: bool) !void {
926fn navRefOff(wasm: *Wasm, bw: *Writer, data: Mir.NavRefOff, is_wasm32: bool) !void {
926927 const comp = wasm.base.comp;
927928 const zcu = comp.zcu.?;
928929 const ip = &zcu.intern_pool;
......@@ -947,6 +948,6 @@ fn navRefOff(wasm: *Wasm, bw: *std.io.BufferedWriter, data: Mir.NavRefOff, is_wa
947948 }
948949}
949950
950fn appendOutputFunctionIndex(bw: *std.io.BufferedWriter, i: Wasm.OutputFunctionIndex) std.io.Writer.Error!void {
951fn appendOutputFunctionIndex(bw: *Writer, i: Wasm.OutputFunctionIndex) Writer.Error!void {
951952 return bw.writeLeb128(@intFromEnum(i));
952953}
src/arch/x86_64/CodeGen.zig+14-7
......@@ -6,6 +6,7 @@ const log = std.log.scoped(.codegen);
66const tracking_log = std.log.scoped(.tracking);
77const verbose_tracking_log = std.log.scoped(.verbose_tracking);
88const wip_mir_log = std.log.scoped(.wip_mir);
9const Writer = std.io.Writer;
910
1011const Air = @import("../../Air.zig");
1112const Allocator = std.mem.Allocator;
......@@ -524,7 +525,7 @@ pub const MCValue = union(enum) {
524525 };
525526 }
526527
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 {
528529 switch (mcv) {
529530 .none, .unreach, .dead, .undef => try bw.print("({s})", .{@tagName(mcv)}),
530531 .immediate => |pl| try bw.print("0x{x}", .{pl}),
......@@ -811,7 +812,7 @@ const InstTracking = struct {
811812 }
812813 }
813814
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 {
815816 if (!std.meta.eql(tracking.long, tracking.short)) try bw.print("|{f}| ", .{tracking.long});
816817 try bw.print("{f}", .{tracking.short});
817818 }
......@@ -1087,7 +1088,7 @@ const FormatNavData = struct {
10871088 ip: *const InternPool,
10881089 nav_index: InternPool.Nav.Index,
10891090};
1090fn formatNav(data: FormatNavData, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void {
1091fn formatNav(data: FormatNavData, bw: *Writer, comptime _: []const u8) Writer.Error!void {
10911092 try bw.print("{f}", .{data.ip.getNav(data.nav_index).fqn.fmt(data.ip)});
10921093}
10931094fn fmtNav(nav_index: InternPool.Nav.Index, ip: *const InternPool) std.fmt.Formatter(formatNav) {
......@@ -1101,8 +1102,13 @@ const FormatAirData = struct {
11011102 self: *CodeGen,
11021103 inst: Air.Inst.Index,
11031104};
1104fn 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);
1105fn 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");
11061112}
11071113fn fmtAir(self: *CodeGen, inst: Air.Inst.Index) std.fmt.Formatter(formatAir) {
11081114 return .{ .data = .{ .self = self, .inst = inst } };
......@@ -1112,7 +1118,7 @@ const FormatWipMirData = struct {
11121118 self: *CodeGen,
11131119 inst: Mir.Inst.Index,
11141120};
1115fn formatWipMir(data: FormatWipMirData, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void {
1121fn formatWipMir(data: FormatWipMirData, bw: *Writer, comptime _: []const u8) Writer.Error!void {
11161122 var lower: Lower = .{
11171123 .target = data.self.target,
11181124 .allocator = data.self.gpa,
......@@ -1208,7 +1214,8 @@ fn fmtWipMir(self: *CodeGen, inst: Mir.Inst.Index) std.fmt.Formatter(formatWipMi
12081214const FormatTrackingData = struct {
12091215 self: *CodeGen,
12101216};
1211fn formatTracking(data: FormatTrackingData, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void {
1217fn formatTracking(data: FormatTrackingData, bw: *Writer, comptime fmt: []const u8) Writer.Error!void {
1218 comptime assert(fmt.len == 0);
12121219 var it = data.self.inst_tracking.iterator();
12131220 while (it.next()) |entry| try bw.print("\n{f} = {f}", .{ entry.key_ptr.*, entry.value_ptr.* });
12141221}
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
372372}
373373
374374fn 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..]);
377376 defer dis.pos += br.seek;
378377 return switch (kind) {
379378 .imm8s, .rel8 => .s(try br.takeInt(i8, .little)),
......@@ -388,8 +387,7 @@ fn parseImm(dis: *Disassembler, kind: Encoding.Op) !Immediate {
388387}
389388
390389fn 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..]);
393391 defer dis.pos += br.seek;
394392 return br.takeInt(u64, .little);
395393}
src/arch/x86_64/Encoding.zig+4-4
......@@ -3,6 +3,7 @@ const Encoding = @This();
33const std = @import("std");
44const assert = std.debug.assert;
55const math = std.math;
6const Writer = std.io.Writer;
67
78const bits = @import("bits.zig");
89const encoder = @import("encoder.zig");
......@@ -158,8 +159,8 @@ pub fn modRmExt(encoding: Encoding) u3 {
158159 };
159160}
160161
161pub fn format(encoding: Encoding, bw: *std.io.BufferedWriter, comptime fmt: []const u8) !void {
162 _ = fmt;
162pub fn format(encoding: Encoding, bw: *Writer, comptime fmt: []const u8) !void {
163 comptime assert(fmt.len == 0);
163164
164165 var opc = encoding.opcode();
165166 if (encoding.data.mode.isVex()) {
......@@ -1016,8 +1017,7 @@ fn estimateInstructionLength(prefix: Prefix, encoding: Encoding, ops: []const Op
10161017 @memcpy(inst.ops[0..ops.len], ops);
10171018
10181019 var buf: [15]u8 = undefined;
1019 var bw: std.io.BufferedWriter = undefined;
1020 bw.initFixed(&buf);
1020 var bw: Writer = .fixed(&buf);
10211021 inst.encode(&bw, .{
10221022 .allow_frame_locs = true,
10231023 .allow_symbols = true,
src/arch/x86_64/bits.zig+6-2
......@@ -6,6 +6,8 @@ const Allocator = std.mem.Allocator;
66const ArrayList = std.ArrayList;
77const InternPool = @import("../../InternPool.zig");
88const link = @import("../../link.zig");
9const Writer = std.io.Writer;
10
911const Mir = @import("Mir.zig");
1012
1113/// EFLAGS condition codes
......@@ -728,7 +730,8 @@ pub const FrameIndex = enum(u32) {
728730 return @intFromEnum(fi) < named_count;
729731 }
730732
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);
732735 try bw.writeAll("FrameIndex");
733736 if (fi.isNamed())
734737 try bw.print(".{s}", .{@tagName(fi)})
......@@ -835,7 +838,8 @@ pub const Memory = struct {
835838 };
836839 }
837840
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);
839843 if (s == .none) return;
840844 try bw.writeAll(@tagName(s));
841845 switch (s) {
src/arch/x86_64/encoder.zig+7-6
......@@ -3,6 +3,7 @@ const assert = std.debug.assert;
33const log = std.log.scoped(.x86_64_encoder);
44const math = std.math;
55const testing = std.testing;
6const Writer = std.io.Writer;
67
78const bits = @import("bits.zig");
89const Encoding = @import("Encoding.zig");
......@@ -226,7 +227,7 @@ pub const Instruction = struct {
226227 };
227228 }
228229
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 {
230231 _ = op;
231232 _ = bw;
232233 _ = unused_format_string;
......@@ -238,7 +239,7 @@ pub const Instruction = struct {
238239 enc_op: Encoding.Op,
239240 };
240241
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 {
242243 _ = unused_format_string;
243244 const op = ctx.op;
244245 const enc_op = ctx.enc_op;
......@@ -360,7 +361,7 @@ pub const Instruction = struct {
360361 return inst;
361362 }
362363
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 {
364365 _ = unused_format_string;
365366 switch (inst.prefix) {
366367 .none, .directive => {},
......@@ -374,7 +375,7 @@ pub const Instruction = struct {
374375 }
375376 }
376377
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 {
378379 assert(inst.prefix != .directive);
379380 const encoder: Encoder(opts) = .{ .bw = bw };
380381 const enc = inst.encoding;
......@@ -784,7 +785,7 @@ pub const Options = struct { allow_frame_locs: bool = false, allow_symbols: bool
784785
785786fn Encoder(comptime opts: Options) type {
786787 return struct {
787 bw: *std.io.BufferedWriter,
788 bw: *Writer,
788789
789790 const Self = @This();
790791 pub const options = opts;
......@@ -2198,7 +2199,7 @@ const Assembler = struct {
21982199 };
21992200 }
22002201
2201 pub fn assemble(as: *Assembler, bw: *std.io.BufferedWriter) !void {
2202 pub fn assemble(as: *Assembler, bw: *Writer) !void {
22022203 while (try as.next()) |parsed_inst| {
22032204 const inst: Instruction = try .new(.none, parsed_inst.mnemonic, &parsed_inst.ops);
22042205 try inst.encode(bw, .{});
src/codegen.zig+5-4
......@@ -8,6 +8,7 @@ const mem = std.mem;
88const math = std.math;
99const target_util = @import("target.zig");
1010const trace = @import("tracy.zig").trace;
11const Writer = std.io.Writer;
1112
1213const Air = @import("Air.zig");
1314const Allocator = mem.Allocator;
......@@ -326,7 +327,7 @@ pub fn generateSymbolInner(
326327 pt: Zcu.PerThread,
327328 src_loc: Zcu.LazySrcLoc,
328329 val: Value,
329 bw: *std.io.BufferedWriter,
330 bw: *Writer,
330331 reloc_parent: link.File.RelocInfo.Parent,
331332) GenerateSymbolError!void {
332333 const zcu = pt.zcu;
......@@ -707,7 +708,7 @@ fn lowerPtr(
707708 pt: Zcu.PerThread,
708709 src_loc: Zcu.LazySrcLoc,
709710 ptr_val: InternPool.Index,
710 bw: *std.io.BufferedWriter,
711 bw: *Writer,
711712 reloc_parent: link.File.RelocInfo.Parent,
712713 prev_offset: u64,
713714) GenerateSymbolError!void {
......@@ -760,7 +761,7 @@ fn lowerUavRef(
760761 pt: Zcu.PerThread,
761762 src_loc: Zcu.LazySrcLoc,
762763 uav: InternPool.Key.Ptr.BaseAddr.Uav,
763 bw: *std.io.BufferedWriter,
764 bw: *Writer,
764765 reloc_parent: link.File.RelocInfo.Parent,
765766 offset: u64,
766767) GenerateSymbolError!void {
......@@ -814,7 +815,7 @@ fn lowerNavRef(
814815 lf: *link.File,
815816 pt: Zcu.PerThread,
816817 nav_index: InternPool.Nav.Index,
817 bw: *std.io.BufferedWriter,
818 bw: *Writer,
818819 reloc_parent: link.File.RelocInfo.Parent,
819820 offset: u64,
820821) GenerateSymbolError!void {
src/codegen/c.zig+68-67
......@@ -4,6 +4,7 @@ const assert = std.debug.assert;
44const mem = std.mem;
55const log = std.log.scoped(.c);
66const Allocator = mem.Allocator;
7const Writer = std.io.Writer;
78
89const dev = @import("../dev.zig");
910const link = @import("../link.zig");
......@@ -69,7 +70,7 @@ pub const Mir = struct {
6970 }
7071};
7172
72pub const Error = std.io.Writer.Error || std.mem.Allocator.Error || error{AnalysisFail};
73pub const Error = Writer.Error || std.mem.Allocator.Error || error{AnalysisFail};
7374
7475pub const CType = @import("c/Type.zig");
7576
......@@ -344,9 +345,9 @@ fn isReservedIdent(ident: []const u8) bool {
344345
345346fn formatIdent(
346347 ident: []const u8,
347 bw: *std.io.BufferedWriter,
348 bw: *Writer,
348349 comptime fmt_str: []const u8,
349) std.io.Writer.Error!void {
350) Writer.Error!void {
350351 const solo = fmt_str.len != 0 and fmt_str[0] == ' '; // space means solo; not part of a bigger ident.
351352 if (solo and isReservedIdent(ident)) {
352353 try bw.writeAll("zig_e_");
......@@ -374,9 +375,9 @@ const CTypePoolStringFormatData = struct {
374375};
375376fn formatCTypePoolString(
376377 data: CTypePoolStringFormatData,
377 bw: *std.io.BufferedWriter,
378 bw: *Writer,
378379 comptime fmt_str: []const u8,
379) std.io.Writer.Error!void {
380) Writer.Error!void {
380381 if (data.ctype_pool_string.toSlice(data.ctype_pool)) |slice|
381382 try formatIdent(slice, bw, fmt_str)
382383 else
......@@ -504,7 +505,7 @@ pub const Function = struct {
504505 return result;
505506 }
506507
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 {
508509 switch (c_value) {
509510 .none => unreachable,
510511 .new_local, .local => |i| try bw.print("t{d}", .{i}),
......@@ -517,7 +518,7 @@ pub const Function = struct {
517518 }
518519 }
519520
520 fn writeCValueDeref(f: *Function, bw: *std.io.BufferedWriter, c_value: CValue) !void {
521 fn writeCValueDeref(f: *Function, bw: *Writer, c_value: CValue) !void {
521522 switch (c_value) {
522523 .none => unreachable,
523524 .new_local, .local, .constant => {
......@@ -538,7 +539,7 @@ pub const Function = struct {
538539
539540 fn writeCValueMember(
540541 f: *Function,
541 bw: *std.io.BufferedWriter,
542 bw: *Writer,
542543 c_value: CValue,
543544 member: CValue,
544545 ) Error!void {
......@@ -552,7 +553,7 @@ pub const Function = struct {
552553 }
553554 }
554555
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 {
556557 switch (c_value) {
557558 .new_local, .local, .arg, .arg_array => {
558559 try f.writeCValue(bw, c_value, .Other);
......@@ -584,15 +585,15 @@ pub const Function = struct {
584585 return f.object.dg.byteSize(ctype);
585586 }
586587
587 fn renderType(f: *Function, bw: *std.io.BufferedWriter, ctype: Type) !void {
588 fn renderType(f: *Function, bw: *Writer, ctype: Type) !void {
588589 return f.object.dg.renderType(bw, ctype);
589590 }
590591
591 fn renderCType(f: *Function, bw: *std.io.BufferedWriter, ctype: CType) !void {
592 fn renderCType(f: *Function, bw: *Writer, ctype: CType) !void {
592593 return f.object.dg.renderCType(bw, ctype);
593594 }
594595
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 {
596597 return f.object.dg.renderIntCast(bw, dest_ty, .{ .c_value = .{ .f = f, .value = src, .v = v } }, src_ty, location);
597598 }
598599
......@@ -757,7 +758,7 @@ pub const DeclGen = struct {
757758
758759 fn renderUav(
759760 dg: *DeclGen,
760 bw: *std.io.BufferedWriter,
761 bw: *Writer,
761762 uav: InternPool.Key.Ptr.BaseAddr.Uav,
762763 location: ValueRenderLocation,
763764 ) Error!void {
......@@ -819,7 +820,7 @@ pub const DeclGen = struct {
819820
820821 fn renderNav(
821822 dg: *DeclGen,
822 bw: *std.io.BufferedWriter,
823 bw: *Writer,
823824 nav_index: InternPool.Nav.Index,
824825 location: ValueRenderLocation,
825826 ) Error!void {
......@@ -868,7 +869,7 @@ pub const DeclGen = struct {
868869
869870 fn renderPointer(
870871 dg: *DeclGen,
871 bw: *std.io.BufferedWriter,
872 bw: *Writer,
872873 derivation: Value.PointerDeriveStep,
873874 location: ValueRenderLocation,
874875 ) Error!void {
......@@ -972,13 +973,13 @@ pub const DeclGen = struct {
972973 }
973974 }
974975
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 {
976977 try bw.print("zig_error_{f}", .{fmtIdent(err_name.toSlice(&dg.pt.zcu.intern_pool))});
977978 }
978979
979980 fn renderValue(
980981 dg: *DeclGen,
981 writer: *std.io.BufferedWriter,
982 writer: *Writer,
982983 val: Value,
983984 location: ValueRenderLocation,
984985 ) Error!void {
......@@ -1587,7 +1588,7 @@ pub const DeclGen = struct {
15871588
15881589 fn renderUndefValue(
15891590 dg: *DeclGen,
1590 bw: *std.io.BufferedWriter,
1591 bw: *Writer,
15911592 ty: Type,
15921593 location: ValueRenderLocation,
15931594 ) Error!void {
......@@ -1890,7 +1891,7 @@ pub const DeclGen = struct {
18901891
18911892 fn renderFunctionSignature(
18921893 dg: *DeclGen,
1893 bw: *std.io.BufferedWriter,
1894 bw: *Writer,
18941895 fn_val: Value,
18951896 fn_align: InternPool.Alignment,
18961897 kind: CType.Kind,
......@@ -2011,11 +2012,11 @@ pub const DeclGen = struct {
20112012 /// | `renderTypeAndName` | "uint8_t *name" | "uint8_t *name[10]" |
20122013 /// | `renderType` | "uint8_t *" | "uint8_t *[10]" |
20132014 ///
2014 fn renderType(dg: *DeclGen, bw: *std.io.BufferedWriter, t: Type) Error!void {
2015 fn renderType(dg: *DeclGen, bw: *Writer, t: Type) Error!void {
20152016 try dg.renderCType(bw, try dg.ctypeFromType(t, .complete));
20162017 }
20172018
2018 fn renderCType(dg: *DeclGen, bw: *std.io.BufferedWriter, ctype: CType) Error!void {
2019 fn renderCType(dg: *DeclGen, bw: *Writer, ctype: CType) Error!void {
20192020 _ = try renderTypePrefix(dg.pass, &dg.ctype_pool, dg.pt.zcu, bw, ctype, .suffix, .{});
20202021 try renderTypeSuffix(dg.pass, &dg.ctype_pool, dg.pt.zcu, bw, ctype, .suffix, .{});
20212022 }
......@@ -2030,7 +2031,7 @@ pub const DeclGen = struct {
20302031 value: Value,
20312032 },
20322033
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 {
20342035 switch (self.*) {
20352036 .c_value => |v| {
20362037 try v.f.writeCValue(bw, v.value, location);
......@@ -2076,7 +2077,7 @@ pub const DeclGen = struct {
20762077 /// | > 64 bit integer | > 64 bit integer | zig_make_<dest_ty>(zig_hi_<src_ty>(src), zig_lo_<src_ty>(src))
20772078 fn renderIntCast(
20782079 dg: *DeclGen,
2079 bw: *std.io.BufferedWriter,
2080 bw: *Writer,
20802081 dest_ty: Type,
20812082 context: IntCastContext,
20822083 src_ty: Type,
......@@ -2160,7 +2161,7 @@ pub const DeclGen = struct {
21602161 ///
21612162 fn renderTypeAndName(
21622163 dg: *DeclGen,
2163 bw: *std.io.BufferedWriter,
2164 bw: *Writer,
21642165 ty: Type,
21652166 name: CValue,
21662167 qualifiers: CQualifiers,
......@@ -2181,7 +2182,7 @@ pub const DeclGen = struct {
21812182
21822183 fn renderCTypeAndName(
21832184 dg: *DeclGen,
2184 bw: *std.io.BufferedWriter,
2185 bw: *Writer,
21852186 ctype: CType,
21862187 name: CValue,
21872188 qualifiers: CQualifiers,
......@@ -2201,7 +2202,7 @@ pub const DeclGen = struct {
22012202 try renderTypeSuffix(dg.pass, &dg.ctype_pool, zcu, bw, ctype, .suffix, .{});
22022203 }
22032204
2204 fn writeName(dg: *DeclGen, bw: *std.io.BufferedWriter, c_value: CValue) !void {
2205 fn writeName(dg: *DeclGen, bw: *Writer, c_value: CValue) !void {
22052206 switch (c_value) {
22062207 .new_local, .local => |i| try bw.print("t{d}", .{i}),
22072208 .constant => |uav| try renderUavName(bw, uav),
......@@ -2211,7 +2212,7 @@ pub const DeclGen = struct {
22112212 }
22122213 }
22132214
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 {
22152216 switch (c_value) {
22162217 .none, .new_local, .local, .local_ref => unreachable,
22172218 .constant => |uav| try renderUavName(bw, uav),
......@@ -2234,7 +2235,7 @@ pub const DeclGen = struct {
22342235 }
22352236 }
22362237
2237 fn writeCValueDeref(dg: *DeclGen, bw: *std.io.BufferedWriter, c_value: CValue) !void {
2238 fn writeCValueDeref(dg: *DeclGen, bw: *Writer, c_value: CValue) !void {
22382239 switch (c_value) {
22392240 .none,
22402241 .new_local,
......@@ -2263,7 +2264,7 @@ pub const DeclGen = struct {
22632264
22642265 fn writeCValueMember(
22652266 dg: *DeclGen,
2266 bw: *std.io.BufferedWriter,
2267 bw: *Writer,
22672268 c_value: CValue,
22682269 member: CValue,
22692270 ) Error!void {
......@@ -2274,7 +2275,7 @@ pub const DeclGen = struct {
22742275
22752276 fn writeCValueDerefMember(
22762277 dg: *DeclGen,
2277 bw: *std.io.BufferedWriter,
2278 bw: *Writer,
22782279 c_value: CValue,
22792280 member: CValue,
22802281 ) !void {
......@@ -2341,7 +2342,7 @@ pub const DeclGen = struct {
23412342 try fwd.writeAll(";\n");
23422343 }
23432344
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 {
23452346 const zcu = dg.pt.zcu;
23462347 const ip = &zcu.intern_pool;
23472348 const nav = ip.getNav(nav_index);
......@@ -2360,15 +2361,15 @@ pub const DeclGen = struct {
23602361 }
23612362 }
23622363
2363 fn renderUavName(bw: *std.io.BufferedWriter, uav: Value) !void {
2364 fn renderUavName(bw: *Writer, uav: Value) !void {
23642365 try bw.print("__anon_{d}", .{@intFromEnum(uav.toIntern())});
23652366 }
23662367
2367 fn renderTypeForBuiltinFnName(dg: *DeclGen, bw: *std.io.BufferedWriter, ty: Type) !void {
2368 fn renderTypeForBuiltinFnName(dg: *DeclGen, bw: *Writer, ty: Type) !void {
23682369 try dg.renderCTypeForBuiltinFnName(bw, try dg.ctypeFromType(ty, .complete));
23692370 }
23702371
2371 fn renderCTypeForBuiltinFnName(dg: *DeclGen, bw: *std.io.BufferedWriter, ctype: CType) !void {
2372 fn renderCTypeForBuiltinFnName(dg: *DeclGen, bw: *Writer, ctype: CType) !void {
23722373 switch (ctype.info(&dg.ctype_pool)) {
23732374 else => |ctype_info| try bw.print("{c}{d}", .{
23742375 if (ctype.isBool())
......@@ -2387,7 +2388,7 @@ pub const DeclGen = struct {
23872388 }
23882389 }
23892390
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 {
23912392 const ctype = try dg.ctypeFromType(ty, .complete);
23922393 const is_big = ctype.info(&dg.ctype_pool) == .array;
23932394 switch (info) {
......@@ -2436,9 +2437,9 @@ const RenderCTypeTrailing = enum {
24362437
24372438 pub fn format(
24382439 self: @This(),
2439 bw: *std.io.BufferedWriter,
2440 bw: *Writer,
24402441 comptime fmt: []const u8,
2441 ) std.io.Writer.Error!void {
2442 ) Writer.Error!void {
24422443 if (fmt.len != 0) @compileError("invalid format string '" ++
24432444 fmt ++ "' for type '" ++ @typeName(@This()) ++ "'");
24442445 switch (self) {
......@@ -2447,12 +2448,12 @@ const RenderCTypeTrailing = enum {
24472448 }
24482449 }
24492450};
2450fn renderAlignedTypeName(bw: *std.io.BufferedWriter, ctype: CType) !void {
2451fn renderAlignedTypeName(bw: *Writer, ctype: CType) !void {
24512452 try bw.print("anon__aligned_{d}", .{@intFromEnum(ctype.index)});
24522453}
24532454fn renderFwdDeclTypeName(
24542455 zcu: *Zcu,
2455 bw: *std.io.BufferedWriter,
2456 bw: *Writer,
24562457 ctype: CType,
24572458 fwd_decl: CType.Info.FwdDecl,
24582459 attributes: []const u8,
......@@ -2471,11 +2472,11 @@ fn renderTypePrefix(
24712472 pass: DeclGen.Pass,
24722473 ctype_pool: *const CType.Pool,
24732474 zcu: *Zcu,
2474 bw: *std.io.BufferedWriter,
2475 bw: *Writer,
24752476 ctype: CType,
24762477 parent_fix: CTypeFix,
24772478 qualifiers: CQualifiers,
2478) std.io.Writer.Error!RenderCTypeTrailing {
2479) Writer.Error!RenderCTypeTrailing {
24792480 var trailing = RenderCTypeTrailing.maybe_space;
24802481 switch (ctype.info(ctype_pool)) {
24812482 .basic => |basic_info| try bw.writeAll(@tagName(basic_info)),
......@@ -2588,11 +2589,11 @@ fn renderTypeSuffix(
25882589 pass: DeclGen.Pass,
25892590 ctype_pool: *const CType.Pool,
25902591 zcu: *Zcu,
2591 bw: *std.io.BufferedWriter,
2592 bw: *Writer,
25922593 ctype: CType,
25932594 parent_fix: CTypeFix,
25942595 qualifiers: CQualifiers,
2595) std.io.Writer.Error!void {
2596) Writer.Error!void {
25962597 switch (ctype.info(ctype_pool)) {
25972598 .basic, .aligned, .fwd_decl, .aggregate => {},
25982599 .pointer => |pointer_info| try renderTypeSuffix(
......@@ -2644,7 +2645,7 @@ fn renderTypeSuffix(
26442645}
26452646fn renderFields(
26462647 zcu: *Zcu,
2647 bw: *std.io.BufferedWriter,
2648 bw: *Writer,
26482649 ctype_pool: *const CType.Pool,
26492650 aggregate_info: CType.Info.Aggregate,
26502651 indent: usize,
......@@ -2686,7 +2687,7 @@ fn renderFields(
26862687
26872688pub fn genTypeDecl(
26882689 zcu: *Zcu,
2689 bw: *std.io.BufferedWriter,
2690 bw: *Writer,
26902691 global_ctype_pool: *const CType.Pool,
26912692 global_ctype: CType,
26922693 pass: DeclGen.Pass,
......@@ -2766,7 +2767,7 @@ pub fn genTypeDecl(
27662767 }
27672768}
27682769
2769pub fn genGlobalAsm(zcu: *Zcu, bw: *std.io.BufferedWriter) !void {
2770pub fn genGlobalAsm(zcu: *Zcu, bw: *Writer) !void {
27702771 for (zcu.global_assembly.values()) |asm_source| {
27712772 try bw.print("__asm({fs});\n", .{fmtStringLiteral(asm_source, null)});
27722773 }
......@@ -5247,7 +5248,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal
52475248 return local;
52485249}
52495250
5250fn airTrap(f: *Function, bw: *std.io.BufferedWriter) !void {
5251fn airTrap(f: *Function, bw: *Writer) !void {
52515252 // Not even allowed to call trap in a naked function.
52525253 if (f.object.dg.is_naked_fn) return;
52535254 try bw.writeAll("zig_trap();\n");
......@@ -7052,7 +7053,7 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa
70527053 return .none;
70537054}
70547055
7055fn writeSliceOrPtr(f: *Function, bw: *std.io.BufferedWriter, ptr: CValue, ptr_ty: Type) !void {
7056fn writeSliceOrPtr(f: *Function, bw: *Writer, ptr: CValue, ptr_ty: Type) !void {
70567057 const pt = f.object.dg.pt;
70577058 const zcu = pt.zcu;
70587059 if (ptr_ty.isSlice(zcu)) {
......@@ -7980,7 +7981,7 @@ fn toMemoryOrder(order: std.builtin.AtomicOrder) [:0]const u8 {
79807981 };
79817982}
79827983
7983fn writeMemoryOrder(bw: *std.io.BufferedWriter, order: std.builtin.AtomicOrder) !void {
7984fn writeMemoryOrder(bw: *Writer, order: std.builtin.AtomicOrder) !void {
79847985 return bw.writeAll(toMemoryOrder(order));
79857986}
79867987
......@@ -8125,7 +8126,7 @@ const StringLiteral = struct {
81258126 len: usize,
81268127 cur_len: usize,
81278128 start_count: usize,
8128 bw: *std.io.BufferedWriter,
8129 bw: *Writer,
81298130
81308131 // MSVC throws C2078 if an array of size 65536 or greater is initialized with a string literal,
81318132 // regardless of the length of the string literal initializing it. Array initializer syntax is
......@@ -8138,7 +8139,7 @@ const StringLiteral = struct {
81388139 const max_char_len = 4;
81398140 const max_literal_len = @min(16380 - max_char_len, 4095);
81408141
8141 fn init(bw: *std.io.BufferedWriter, len: usize) StringLiteral {
8142 fn init(bw: *Writer, len: usize) StringLiteral {
81428143 return .{
81438144 .cur_len = 0,
81448145 .len = len,
......@@ -8147,7 +8148,7 @@ const StringLiteral = struct {
81478148 };
81488149 }
81498150
8150 pub fn start(sl: *StringLiteral) std.io.Writer.Error!void {
8151 pub fn start(sl: *StringLiteral) Writer.Error!void {
81518152 if (sl.len <= max_string_initializer_len) {
81528153 try sl.bw.writeByte('\"');
81538154 } else {
......@@ -8155,7 +8156,7 @@ const StringLiteral = struct {
81558156 }
81568157 }
81578158
8158 pub fn end(sl: *StringLiteral) std.io.Writer.Error!void {
8159 pub fn end(sl: *StringLiteral) Writer.Error!void {
81598160 if (sl.len <= max_string_initializer_len) {
81608161 try sl.bw.writeByte('\"');
81618162 } else {
......@@ -8163,7 +8164,7 @@ const StringLiteral = struct {
81638164 }
81648165 }
81658166
8166 fn writeStringLiteralChar(sl: *StringLiteral, c: u8) std.io.Writer.Error!void {
8167 fn writeStringLiteralChar(sl: *StringLiteral, c: u8) Writer.Error!void {
81678168 switch (c) {
81688169 7 => try sl.bw.writeAll("\\a"),
81698170 8 => try sl.bw.writeAll("\\b"),
......@@ -8180,7 +8181,7 @@ const StringLiteral = struct {
81808181 }
81818182 }
81828183
8183 pub fn writeChar(sl: *StringLiteral, c: u8) std.io.Writer.Error!void {
8184 pub fn writeChar(sl: *StringLiteral, c: u8) Writer.Error!void {
81848185 if (sl.len <= max_string_initializer_len) {
81858186 if (sl.cur_len == 0 and sl.bw.count - sl.start_count > 1)
81868187 try sl.bw.writeAll("\"\"");
......@@ -8202,9 +8203,9 @@ const StringLiteral = struct {
82028203const FormatStringContext = struct { str: []const u8, sentinel: ?u8 };
82038204fn formatStringLiteral(
82048205 data: FormatStringContext,
8205 bw: *std.io.BufferedWriter,
8206 bw: *Writer,
82068207 comptime fmt: []const u8,
8207) std.io.Writer.Error!void {
8208) Writer.Error!void {
82088209 if (fmt.len != 1 or fmt[0] != 's') @compileError("Invalid fmt: " ++ fmt);
82098210
82108211 var literal: StringLiteral = .init(bw, data.str.len + @intFromBool(data.sentinel != null));
......@@ -8233,9 +8234,9 @@ const FormatIntLiteralContext = struct {
82338234};
82348235fn formatIntLiteral(
82358236 data: FormatIntLiteralContext,
8236 bw: *std.io.BufferedWriter,
8237 bw: *Writer,
82378238 comptime fmt: []const u8,
8238) std.io.Writer.Error!void {
8239) Writer.Error!void {
82398240 const pt = data.dg.pt;
82408241 const zcu = pt.zcu;
82418242 const target = &data.dg.mod.resolved_target.result;
......@@ -8423,7 +8424,7 @@ const Materialize = struct {
84238424 } };
84248425 }
84258426
8426 pub fn mat(self: Materialize, f: *Function, bw: *std.io.BufferedWriter) !void {
8427 pub fn mat(self: Materialize, f: *Function, bw: *Writer) !void {
84278428 try f.writeCValue(bw, self.local, .Other);
84288429 }
84298430
......@@ -8435,27 +8436,27 @@ const Materialize = struct {
84358436const Assignment = struct {
84368437 ctype: CType,
84378438
8438 pub fn start(f: *Function, bw: *std.io.BufferedWriter, ctype: CType) !Assignment {
8439 pub fn start(f: *Function, bw: *Writer, ctype: CType) !Assignment {
84398440 const self: Assignment = .{ .ctype = ctype };
84408441 try self.restart(f, bw);
84418442 return self;
84428443 }
84438444
8444 pub fn restart(self: Assignment, f: *Function, bw: *std.io.BufferedWriter) !void {
8445 pub fn restart(self: Assignment, f: *Function, bw: *Writer) !void {
84458446 switch (self.strategy(f)) {
84468447 .assign => {},
84478448 .memcpy => try bw.writeAll("memcpy("),
84488449 }
84498450 }
84508451
8451 pub fn assign(self: Assignment, f: *Function, bw: *std.io.BufferedWriter) !void {
8452 pub fn assign(self: Assignment, f: *Function, bw: *Writer) !void {
84528453 switch (self.strategy(f)) {
84538454 .assign => try bw.writeAll(" = "),
84548455 .memcpy => try bw.writeAll(", "),
84558456 }
84568457 }
84578458
8458 pub fn end(self: Assignment, f: *Function, bw: *std.io.BufferedWriter) !void {
8459 pub fn end(self: Assignment, f: *Function, bw: *Writer) !void {
84598460 switch (self.strategy(f)) {
84608461 .assign => {},
84618462 .memcpy => {
......@@ -8479,7 +8480,7 @@ const Assignment = struct {
84798480const Vectorize = struct {
84808481 index: CValue = .none,
84818482
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 {
84838484 const pt = f.object.dg.pt;
84848485 const zcu = pt.zcu;
84858486 return if (ty.zigTypeTag(zcu) == .vector) index: {
......@@ -8499,7 +8500,7 @@ const Vectorize = struct {
84998500 } else .{};
85008501 }
85018502
8502 pub fn elem(self: Vectorize, f: *Function, bw: *std.io.BufferedWriter) !void {
8503 pub fn elem(self: Vectorize, f: *Function, bw: *Writer) !void {
85038504 if (self.index != .none) {
85048505 try bw.writeByte('[');
85058506 try f.writeCValue(bw, self.index, .Other);
......@@ -8507,7 +8508,7 @@ const Vectorize = struct {
85078508 }
85088509 }
85098510
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 {
85118512 if (self.index != .none) {
85128513 try f.object.outdent();
85138514 try bw.writeByte('}');
src/codegen/c/Type.zig+8-6
......@@ -209,7 +209,7 @@ pub fn getStandardDefineAbbrev(ctype: CType) ?[]const u8 {
209209 };
210210}
211211
212pub fn renderLiteralPrefix(ctype: CType, bw: *std.io.BufferedWriter, kind: Kind, pool: *const Pool) std.io.Writer.Error!void {
212pub fn renderLiteralPrefix(ctype: CType, bw: *Writer, kind: Kind, pool: *const Pool) Writer.Error!void {
213213 switch (ctype.info(pool)) {
214214 .basic => |basic_info| switch (basic_info) {
215215 .void => unreachable,
......@@ -270,7 +270,7 @@ pub fn renderLiteralPrefix(ctype: CType, bw: *std.io.BufferedWriter, kind: Kind,
270270 }
271271}
272272
273pub fn renderLiteralSuffix(ctype: CType, bw: *std.io.BufferedWriter, pool: *const Pool) std.io.Writer.Error!void {
273pub fn renderLiteralSuffix(ctype: CType, bw: *Writer, pool: *const Pool) Writer.Error!void {
274274 switch (ctype.info(pool)) {
275275 .basic => |basic_info| switch (basic_info) {
276276 .void => unreachable,
......@@ -940,10 +940,10 @@ pub const Pool = struct {
940940 const FormatData = struct { string: String, pool: *const Pool };
941941 fn format(
942942 data: FormatData,
943 bw: *std.io.BufferedWriter,
943 bw: *Writer,
944944 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);
947947 if (data.string.toSlice(data.pool)) |slice|
948948 try bw.writeAll(slice)
949949 else
......@@ -3280,10 +3280,12 @@ pub const AlignAs = packed struct {
32803280 }
32813281};
32823282
3283const std = @import("std");
32833284const assert = std.debug.assert;
3285const Writer = std.io.Writer;
3286
32843287const CType = @This();
32853288const InternPool = @import("../../InternPool.zig");
32863289const Module = @import("../../Package/Module.zig");
3287const std = @import("std");
32883290const Type = @import("../../Type.zig");
32893291const Zcu = @import("../../Zcu.zig");
src/codegen/spirv/spec.zig+2-1
......@@ -18,7 +18,8 @@ pub const IdResult = enum(Word) {
1818 none,
1919 _,
2020
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);
2223 switch (self) {
2324 .none => try bw.writeAll("(none)"),
2425 else => try bw.print("%{}", .{@intFromEnum(self)}),
src/fmt.zig+19-18
......@@ -1,3 +1,12 @@
1const std = @import("std");
2const mem = std.mem;
3const fs = std.fs;
4const process = std.process;
5const Allocator = std.mem.Allocator;
6const Color = std.zig.Color;
7const fatal = std.process.fatal;
8const File = std.fs.File;
9
110const usage_fmt =
211 \\Usage: zig fmt [file]...
312 \\
......@@ -27,7 +36,7 @@ const Fmt = struct {
2736 gpa: Allocator,
2837 arena: Allocator,
2938 out_buffer: std.ArrayListUnmanaged(u8),
30 stdout: *std.io.BufferedWriter,
39 stdout_writer: *File.Writer,
3140
3241 const SeenMap = std.AutoHashMap(fs.File.INode, void);
3342};
......@@ -49,7 +58,7 @@ pub fn run(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
4958 const arg = args[i];
5059 if (mem.startsWith(u8, arg, "-")) {
5160 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);
5362 return process.cleanExit();
5463 } else if (mem.eql(u8, arg, "--color")) {
5564 if (i + 1 >= args.len) {
......@@ -133,10 +142,9 @@ pub fn run(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
133142 try std.zig.printAstErrorsToStderr(gpa, tree, "<stdin>", color);
134143 process.exit(2);
135144 }
136 var aw: std.io.AllocatingWriter = undefined;
137 aw.init(gpa);
145 var aw: std.io.AllocatingWriter = .init(gpa);
138146 defer aw.deinit();
139 try tree.render(gpa, &aw.buffered_writer, .{});
147 try tree.render(gpa, &aw.interface, .{});
140148 const formatted = aw.getWritten();
141149
142150 if (check_flag) {
......@@ -144,7 +152,7 @@ pub fn run(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
144152 process.exit(code);
145153 }
146154
147 return std.fs.File.stdout().writeAll(formatted);
155 return File.stdout().writeAll(formatted);
148156 }
149157
150158 if (input_files.items.len == 0) {
......@@ -152,7 +160,7 @@ pub fn run(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
152160 }
153161
154162 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);
156164
157165 var fmt: Fmt = .{
158166 .gpa = gpa,
......@@ -163,7 +171,7 @@ pub fn run(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
163171 .force_zon = force_zon,
164172 .color = color,
165173 .out_buffer = .empty,
166 .stdout = &stdout,
174 .stdout_writer = &stdout_writer,
167175 };
168176 defer fmt.seen.deinit();
169177 defer fmt.out_buffer.deinit(gpa);
......@@ -190,6 +198,7 @@ pub fn run(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
190198 if (fmt.any_error) {
191199 process.exit(1);
192200 }
201 try fmt.stdout_writer.flush();
193202}
194203
195204fn 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(
336345 return;
337346
338347 if (check_mode) {
339 try fmt.stdout.print("{s}\n", .{file_path});
348 try fmt.stdout_writer.interface.print("{s}\n", .{file_path});
340349 fmt.any_error = true;
341350 } else {
342351 var af = try dir.atomicFile(sub_path, .{ .mode = stat.mode });
......@@ -344,18 +353,10 @@ fn fmtPathFile(
344353
345354 try af.file.writeAll(fmt.out_buffer.items);
346355 try af.finish();
347 try fmt.stdout.print("{s}\n", .{file_path});
356 try fmt.stdout_writer.interface.print("{s}\n", .{file_path});
348357 }
349358}
350359
351const std = @import("std");
352const mem = std.mem;
353const fs = std.fs;
354const process = std.process;
355const Allocator = std.mem.Allocator;
356const Color = std.zig.Color;
357const fatal = std.process.fatal;
358
359360/// Provided for debugging/testing purposes; unused by the compiler.
360361pub fn main() !void {
361362 const gpa = std.heap.smp_allocator;
src/link/Coff.zig+39-39
......@@ -1,5 +1,41 @@
11//! The main driver of the self-hosted COFF linker.
22
3const Coff = @This();
4
5const std = @import("std");
6const build_options = @import("build_options");
7const builtin = @import("builtin");
8const assert = std.debug.assert;
9const coff_util = std.coff;
10const fmt = std.fmt;
11const fs = std.fs;
12const log = std.log.scoped(.link);
13const math = std.math;
14const mem = std.mem;
15
16const Allocator = std.mem.Allocator;
17const Path = std.Build.Cache.Path;
18const Directory = std.Build.Cache.Directory;
19const Cache = std.Build.Cache;
20const Writer = std.io.Writer;
21
22const aarch64_util = @import("../arch/aarch64/bits.zig");
23const allocPrint = std.fmt.allocPrint;
24const codegen = @import("../codegen.zig");
25const link = @import("../link.zig");
26const target_util = @import("../target.zig");
27const trace = @import("../tracy.zig").trace;
28
29const Compilation = @import("../Compilation.zig");
30const Zcu = @import("../Zcu.zig");
31const InternPool = @import("../InternPool.zig");
32const TableSection = @import("table_section.zig").TableSection;
33const StringTable = @import("StringTable.zig");
34const Type = @import("../Type.zig");
35const Value = @import("../Value.zig");
36const AnalUnit = InternPool.AnalUnit;
37const dev = @import("../dev.zig");
38
339base: link.File,
440image_base: u64,
541/// TODO this and minor_subsystem_version should be combined into one property and left as
......@@ -2175,8 +2211,7 @@ fn writeDataDirectoriesHeaders(coff: *Coff) !void {
21752211fn writeHeader(coff: *Coff) !void {
21762212 const target = &coff.base.comp.root_mod.resolved_target.result;
21772213 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()));
21802215 defer gpa.free(bw.buffer);
21812216
21822217 bw.writeAll(&msdos_stub) catch unreachable;
......@@ -3066,14 +3101,14 @@ const ImportTable = struct {
30663101 ctx: Context,
30673102 };
30683103
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 {
30703105 _ = itab;
30713106 _ = bw;
30723107 _ = unused_format_string;
30733108 @compileError("do not format ImportTable directly; use itab.fmtDebug()");
30743109 }
30753110
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 {
30773112 comptime assert(unused_format_string.len == 0);
30783113 const lib_name = fmt_ctx.ctx.coff.temp_strtab.getAssumeExists(fmt_ctx.ctx.name_off);
30793114 const base_vaddr = getBaseAddress(fmt_ctx.ctx);
......@@ -3105,41 +3140,6 @@ fn pwriteAll(coff: *Coff, bytes: []const u8, offset: u64) error{LinkFailure}!voi
31053140 };
31063141}
31073142
3108const Coff = @This();
3109
3110const std = @import("std");
3111const build_options = @import("build_options");
3112const builtin = @import("builtin");
3113const assert = std.debug.assert;
3114const coff_util = std.coff;
3115const fmt = std.fmt;
3116const fs = std.fs;
3117const log = std.log.scoped(.link);
3118const math = std.math;
3119const mem = std.mem;
3120
3121const Allocator = std.mem.Allocator;
3122const Path = std.Build.Cache.Path;
3123const Directory = std.Build.Cache.Directory;
3124const Cache = std.Build.Cache;
3125
3126const aarch64_util = @import("../arch/aarch64/bits.zig");
3127const allocPrint = std.fmt.allocPrint;
3128const codegen = @import("../codegen.zig");
3129const link = @import("../link.zig");
3130const target_util = @import("../target.zig");
3131const trace = @import("../tracy.zig").trace;
3132
3133const Compilation = @import("../Compilation.zig");
3134const Zcu = @import("../Zcu.zig");
3135const InternPool = @import("../InternPool.zig");
3136const TableSection = @import("table_section.zig").TableSection;
3137const StringTable = @import("StringTable.zig");
3138const Type = @import("../Type.zig");
3139const Value = @import("../Value.zig");
3140const AnalUnit = InternPool.AnalUnit;
3141const dev = @import("../dev.zig");
3142
31433143/// This is the start of a Portable Executable (PE) file.
31443144/// It starts with a MS-DOS header followed by a MS-DOS stub program.
31453145/// 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 {
648648 assert(len >= unit.trailer_len);
649649 if (sec == &dwarf.debug_line.section) {
650650 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);
653652 bw.writeByte(DW.LNS.extended_op) catch unreachable;
654653 const extended_op_bytes = bw.end;
655654 var op_len_bytes: u5 = 1;
......@@ -668,8 +667,7 @@ const Unit = struct {
668667 assert(bw.end >= unit.trailer_len and bw.end <= len);
669668 return dwarf.getFile().?.pwriteAll(bw.getWritten(), sec.off(dwarf) + start);
670669 }
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));
673671 defer dwarf.gpa.free(trailer_bw.buffer);
674672 const fill_byte: u8 = if (sec == &dwarf.debug_abbrev.section) fill: {
675673 assert(uleb128Bytes(@intFromEnum(AbbrevCode.null)) == 1);
......@@ -833,8 +831,7 @@ const Entry = struct {
833831 1 + uleb128Bytes(std.math.maxInt(u32)) + 1,
834832 )
835833 ]u8 = undefined;
836 var bw: std.io.BufferedWriter = undefined;
837 bw.initFixed(&buf);
834 var bw: Writer = .fixed(&buf);
838835 if (sec == &dwarf.debug_info.section) switch (len) {
839836 0 => {},
840837 1 => bw.writeLeb128(try dwarf.refAbbrevCode(.pad_1)) catch unreachable,
......@@ -1134,7 +1131,7 @@ pub const Loc = union(enum) {
11341131 };
11351132 }
11361133
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 {
11381135 if (std.math.cast(u5, reg)) |small_reg| {
11391136 try bw.writeByte(op0 + small_reg);
11401137 } else {
......@@ -1143,7 +1140,7 @@ pub const Loc = union(enum) {
11431140 }
11441141 }
11451142
1146 fn write(loc: Loc, bw: *std.io.BufferedWriter, adapter: anytype) UpdateError!void {
1143 fn write(loc: Loc, bw: *Writer, adapter: anytype) UpdateError!void {
11471144 switch (loc) {
11481145 .empty => {},
11491146 .addr_reloc => |sym_index| {
......@@ -1795,10 +1792,10 @@ pub const WipNav = struct {
17951792 fn endian(_: ExprLocCounter) std.builtin.Endian {
17961793 return @import("builtin").cpu.arch.endian();
17971794 }
1798 fn addrSym(counter: ExprLocCounter, bw: *std.io.BufferedWriter, _: u32) error{}!void {
1795 fn addrSym(counter: ExprLocCounter, bw: *Writer, _: u32) error{}!void {
17991796 bw.count += @intFromEnum(counter.address_size);
18001797 }
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 {
18021799 bw.count += counter.section_offset_bytes;
18031800 }
18041801 };
......@@ -1817,10 +1814,10 @@ pub const WipNav = struct {
18171814 fn endian(ctx: @This()) std.builtin.Endian {
18181815 return ctx.wip_nav.dwarf.endian;
18191816 }
1820 fn addrSym(ctx: @This(), _: *std.io.BufferedWriter, sym_index: u32) UpdateError!void {
1817 fn addrSym(ctx: @This(), _: *Writer, sym_index: u32) UpdateError!void {
18211818 try ctx.wip_nav.infoAddrSym(sym_index, 0);
18221819 }
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 {
18241821 try ctx.wip_nav.infoSectionOffset(.debug_info, unit, entry, 0);
18251822 }
18261823 } = .{ .wip_nav = wip_nav };
......@@ -1852,10 +1849,10 @@ pub const WipNav = struct {
18521849 fn endian(ctx: @This()) std.builtin.Endian {
18531850 return ctx.wip_nav.dwarf.endian;
18541851 }
1855 fn addrSym(ctx: @This(), _: *std.io.BufferedWriter, sym_index: u32) UpdateError!void {
1852 fn addrSym(ctx: @This(), _: *Writer, sym_index: u32) UpdateError!void {
18561853 try ctx.wip_nav.frameAddrSym(sym_index, 0);
18571854 }
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 {
18591856 try ctx.wip_nav.sectionOffset(.debug_frame, .debug_info, unit, entry, 0);
18601857 }
18611858 } = .{ .wip_nav = wip_nav };
......@@ -2756,8 +2753,7 @@ fn finishWipNavFuncInner(
27562753 try dibw.writeLeb128(@intFromEnum(AbbrevCode.null));
27572754 } else {
27582755 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);
27612757 const abbrev_code: AbbrevCode = @enumFromInt(abbrev_code_br.takeLeb128(@typeInfo(AbbrevCode).@"enum".tag_type) catch unreachable);
27622758 std.leb.writeUnsignedFixed(
27632759 AbbrevCode.decl_bytes,
......@@ -4565,14 +4561,14 @@ pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
45654561
45664562 var header: std.ArrayListUnmanaged(u8) = .empty;
45674563 defer header.deinit(gpa);
4568 var header_bw: std.io.BufferedWriter = undefined;
4564 var header_bw: Writer = undefined;
45694565 if (dwarf.debug_aranges.section.dirty) {
45704566 for (dwarf.debug_aranges.section.units.items, 0..) |*unit_ptr, unit_index| {
45714567 const unit: Unit.Index = @enumFromInt(unit_index);
45724568 unit_ptr.clear();
45734569 try unit_ptr.cross_section_relocs.ensureTotalCapacity(gpa, 1);
45744570 try header.resize(gpa, unit_ptr.header_len);
4575 header_bw.initFixed(header.items);
4571 header_bw = .fixed(header.items);
45764572 const unit_len = (if (unit_ptr.next.unwrap()) |next_unit|
45774573 dwarf.debug_aranges.section.getUnit(next_unit).off
45784574 else
......@@ -4610,7 +4606,7 @@ pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
46104606 const Register = @import("../arch/x86_64/bits.zig").Register;
46114607 for (dwarf.debug_frame.section.units.items) |*unit| {
46124608 try header.resize(gpa, unit.header_len);
4613 header_bw.initFixed(header.items);
4609 header_bw = .fixed(header.items);
46144610 const unit_len = unit.header_len - dwarf.unitLengthBytes();
46154611 switch (dwarf.format) {
46164612 .@"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 {
46514647 try unit_ptr.cross_unit_relocs.ensureTotalCapacity(gpa, 1);
46524648 try unit_ptr.cross_section_relocs.ensureTotalCapacity(gpa, 7);
46534649 try header.resize(gpa, unit_ptr.header_len);
4654 header_bw.initFixed(header.items);
4650 header_bw = .fixed(header.items);
46554651 const unit_len = (if (unit_ptr.next.unwrap()) |next_unit|
46564652 dwarf.debug_info.section.getUnit(next_unit).off
46574653 else
......@@ -4751,7 +4747,7 @@ pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
47514747 unit.clear();
47524748 try unit.cross_section_relocs.ensureTotalCapacity(gpa, mod_info.dirs.count() + 2 * (mod_info.files.count()));
47534749 try header.resize(gpa, unit.header_len);
4754 header_bw.initFixed(header.items);
4750 header_bw = .fixed(header.items);
47554751 const unit_len = (if (unit.next.unwrap()) |next_unit|
47564752 dwarf.debug_line.section.getUnit(next_unit).off
47574753 else
......@@ -4859,7 +4855,7 @@ pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
48594855 if (dwarf.debug_rnglists.section.dirty) {
48604856 for (dwarf.debug_rnglists.section.units.items) |*unit| {
48614857 try header.resize(gpa, unit.header_len);
4862 header_bw.initFixed(header.items);
4858 header_bw = .fixed(header.items);
48634859 const unit_len = (if (unit.next.unwrap()) |next_unit|
48644860 dwarf.debug_rnglists.section.getUnit(next_unit).off
48654861 else
......@@ -6078,7 +6074,7 @@ fn writeInt(dwarf: *Dwarf, buf: []u8, int: u64) void {
60786074 }
60796075}
60806076
6081fn writeIntTo(dwarf: *Dwarf, bw: *std.io.BufferedWriter, len: usize, int: u64) !void {
6077fn writeIntTo(dwarf: *Dwarf, bw: *Writer, len: usize, int: u64) !void {
60826078 dwarf.writeInt(try bw.writableSlice(len), int);
60836079}
60846080
......@@ -6127,8 +6123,7 @@ fn leb128Bytes(value: anytype) u32 {
61276123 var buffer: [
61286124 std.math.divCeil(u16, @intFromBool(value_info.signedness == .signed) + value_info.bits, 7) catch unreachable
61296125 ]u8 = undefined;
6130 var bw: std.io.BufferedWriter = undefined;
6131 bw.initFixed(&buffer);
6126 var bw: Writer = .fixed(&buffer);
61326127 bw.writeLeb128(value) catch unreachable;
61336128 return @intCast(bw.end);
61346129}
......@@ -6155,3 +6150,4 @@ const log = std.log.scoped(.dwarf);
61556150const std = @import("std");
61566151const target_info = @import("../target.zig");
61576152const Allocator = std.mem.Allocator;
6153const Writer = std.io.Writer;
src/link/Elf.zig+18-18
......@@ -3029,8 +3029,7 @@ fn writeAtoms(self: *Elf) !void {
30293029 if (self.requiresThunks()) {
30303030 for (self.thunks.items) |th| {
30313031 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);
30343033 const shdr = slice.items(.shdr)[th.output_section_index];
30353034 const offset = @as(u64, @intCast(th.value)) + shdr.sh_offset;
30363035 try th.write(self, &bw);
......@@ -3136,7 +3135,7 @@ fn writeSyntheticSections(self: *Elf) !void {
31363135
31373136 var buffer: std.ArrayListUnmanaged(u8) = .empty;
31383137 defer buffer.deinit(gpa);
3139 var bw: std.io.BufferedWriter = undefined;
3138 var bw: Writer = undefined;
31403139
31413140 if (self.section_indexes.interp) |shndx| {
31423141 const shdr = slice.items(.shdr)[shndx];
......@@ -3156,7 +3155,7 @@ fn writeSyntheticSections(self: *Elf) !void {
31563155 if (self.section_indexes.gnu_hash) |shndx| {
31573156 const shdr = slice.items(.shdr)[shndx];
31583157 try buffer.resize(gpa, self.gnu_hash.size());
3159 bw.initFixed(buffer.items);
3158 bw = .fixed(buffer.items);
31603159 try self.gnu_hash.write(self, &bw);
31613160 assert(bw.end == bw.buffer.len);
31623161 try self.pwriteAll(bw.buffer, shdr.sh_offset);
......@@ -3170,7 +3169,7 @@ fn writeSyntheticSections(self: *Elf) !void {
31703169 if (self.section_indexes.verneed) |shndx| {
31713170 const shdr = slice.items(.shdr)[shndx];
31723171 try buffer.resize(gpa, self.verneed.size());
3173 bw.initFixed(buffer.items);
3172 bw = .fixed(buffer.items);
31743173 try self.verneed.write(&bw);
31753174 assert(bw.end == bw.buffer.len);
31763175 try self.pwriteAll(bw.buffer, shdr.sh_offset);
......@@ -3179,7 +3178,7 @@ fn writeSyntheticSections(self: *Elf) !void {
31793178 if (self.section_indexes.dynamic) |shndx| {
31803179 const shdr = slice.items(.shdr)[shndx];
31813180 try buffer.resize(gpa, self.dynamic.size(self));
3182 bw.initFixed(buffer.items);
3181 bw = .fixed(buffer.items);
31833182 try self.dynamic.write(self, &bw);
31843183 assert(bw.end == bw.buffer.len);
31853184 try self.pwriteAll(bw.buffer, shdr.sh_offset);
......@@ -3188,7 +3187,7 @@ fn writeSyntheticSections(self: *Elf) !void {
31883187 if (self.section_indexes.dynsymtab) |shndx| {
31893188 const shdr = slice.items(.shdr)[shndx];
31903189 try buffer.resize(gpa, self.dynsym.size());
3191 bw.initFixed(buffer.items);
3190 bw = .fixed(buffer.items);
31923191 try self.dynsym.write(self, &bw);
31933192 assert(bw.end == bw.buffer.len);
31943193 try self.pwriteAll(bw.buffer, shdr.sh_offset);
......@@ -3208,7 +3207,7 @@ fn writeSyntheticSections(self: *Elf) !void {
32083207 const shdr = slice.items(.shdr)[shndx];
32093208 const sh_size = try self.cast(usize, shdr.sh_size);
32103209 try buffer.resize(gpa, @intCast(sh_size - existing_size));
3211 bw.initFixed(buffer.items);
3210 bw = .fixed(buffer.items);
32123211 try eh_frame.writeEhFrame(self, &bw);
32133212 assert(bw.end == bw.buffer.len);
32143213 try self.pwriteAll(bw.buffer, shdr.sh_offset + existing_size);
......@@ -3218,7 +3217,7 @@ fn writeSyntheticSections(self: *Elf) !void {
32183217 const shdr = slice.items(.shdr)[shndx];
32193218 const sh_size = try self.cast(usize, shdr.sh_size);
32203219 try buffer.resize(gpa, sh_size);
3221 bw.initFixed(buffer.items);
3220 bw = .fixed(buffer.items);
32223221 try eh_frame.writeEhFrameHdr(self, &bw);
32233222 assert(bw.end == bw.buffer.len);
32243223 try self.pwriteAll(bw.buffer, shdr.sh_offset);
......@@ -3227,7 +3226,7 @@ fn writeSyntheticSections(self: *Elf) !void {
32273226 if (self.section_indexes.got) |index| {
32283227 const shdr = slice.items(.shdr)[index];
32293228 try buffer.resize(gpa, self.got.size(self));
3230 bw.initFixed(buffer.items);
3229 bw = .fixed(buffer.items);
32313230 try self.got.write(self, &bw);
32323231 assert(bw.end == bw.buffer.len);
32333232 try self.pwriteAll(bw.buffer, shdr.sh_offset);
......@@ -3244,7 +3243,7 @@ fn writeSyntheticSections(self: *Elf) !void {
32443243 if (self.section_indexes.plt) |shndx| {
32453244 const shdr = slice.items(.shdr)[shndx];
32463245 try buffer.resize(gpa, self.plt.size(self));
3247 bw.initFixed(buffer.items);
3246 bw = .fixed(buffer.items);
32483247 try self.plt.write(self, &bw);
32493248 assert(bw.end == bw.buffer.len);
32503249 try self.pwriteAll(bw.buffer, shdr.sh_offset);
......@@ -3253,7 +3252,7 @@ fn writeSyntheticSections(self: *Elf) !void {
32533252 if (self.section_indexes.got_plt) |shndx| {
32543253 const shdr = slice.items(.shdr)[shndx];
32553254 try buffer.resize(gpa, self.got_plt.size(self));
3256 bw.initFixed(buffer.items);
3255 bw = .fixed(buffer.items);
32573256 try self.got_plt.write(self, &bw);
32583257 assert(bw.end == bw.buffer.len);
32593258 try self.pwriteAll(bw.buffer, shdr.sh_offset);
......@@ -3262,7 +3261,7 @@ fn writeSyntheticSections(self: *Elf) !void {
32623261 if (self.section_indexes.plt_got) |shndx| {
32633262 const shdr = slice.items(.shdr)[shndx];
32643263 try buffer.resize(gpa, self.plt_got.size(self));
3265 bw.initFixed(buffer.items);
3264 bw = .fixed(buffer.items);
32663265 try self.plt_got.write(self, &bw);
32673266 assert(bw.end == bw.buffer.len);
32683267 try self.pwriteAll(bw.buffer, shdr.sh_offset);
......@@ -3883,7 +3882,7 @@ fn fmtShdr(self: *Elf, shdr: elf.Elf64_Shdr) std.fmt.Formatter(formatShdr) {
38833882 } };
38843883}
38853884
3886fn formatShdr(ctx: FormatShdrCtx, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
3885fn formatShdr(ctx: FormatShdrCtx, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
38873886 _ = unused_fmt_string;
38883887 const shdr = ctx.shdr;
38893888 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) {
38983897 return .{ .data = sh_flags };
38993898}
39003899
3901fn formatShdrFlags(sh_flags: u64, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) !void {
3900fn formatShdrFlags(sh_flags: u64, bw: *Writer, comptime unused_fmt_string: []const u8) !void {
39023901 _ = unused_fmt_string;
39033902 if (elf.SHF_WRITE & sh_flags != 0) {
39043903 try bw.writeByte('W');
......@@ -3958,7 +3957,7 @@ fn fmtPhdr(self: *Elf, phdr: elf.Elf64_Phdr) std.fmt.Formatter(formatPhdr) {
39583957
39593958fn formatPhdr(
39603959 ctx: FormatPhdrCtx,
3961 bw: *std.io.BufferedWriter,
3960 bw: *Writer,
39623961 comptime unused_fmt_string: []const u8,
39633962) !void {
39643963 _ = unused_fmt_string;
......@@ -3994,7 +3993,7 @@ pub fn dumpState(self: *Elf) std.fmt.Formatter(fmtDumpState) {
39943993
39953994fn fmtDumpState(
39963995 self: *Elf,
3997 bw: *std.io.BufferedWriter,
3996 bw: *Writer,
39983997 comptime unused_fmt_string: []const u8,
39993998) !void {
40003999 _ = unused_fmt_string;
......@@ -4216,7 +4215,7 @@ pub const Ref = struct {
42164215 return ref.index == other.index and ref.file == other.file;
42174216 }
42184217
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 {
42204219 _ = unused_fmt_string;
42214220 try bw.print("ref({},{})", .{ ref.index, ref.file });
42224221 }
......@@ -4493,6 +4492,7 @@ const Allocator = std.mem.Allocator;
44934492const Hash = std.hash.Wyhash;
44944493const Path = std.Build.Cache.Path;
44954494const Stat = std.Build.Cache.File.Stat;
4495const Writer = std.io.Writer;
44964496
44974497const codegen = @import("../codegen.zig");
44984498const dev = @import("../dev.zig");
src/link/Elf/Archive.zig+5-4
......@@ -184,7 +184,7 @@ pub const ArSymtab = struct {
184184 }
185185 }
186186
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 {
188188 _ = ar;
189189 _ = bw;
190190 _ = unused_fmt_string;
......@@ -203,7 +203,7 @@ pub const ArSymtab = struct {
203203 } };
204204 }
205205
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 {
207207 _ = unused_fmt_string;
208208 const ar = ctx.ar;
209209 const elf_file = ctx.elf_file;
......@@ -251,8 +251,8 @@ pub const ArStrtab = struct {
251251 try writer.writeAll(ar.buffer.items);
252252 }
253253
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);
256256 try bw.print("{f}", .{std.fmt.fmtSliceEscapeLower(ar.buffer.items)});
257257 }
258258};
......@@ -277,6 +277,7 @@ const log = std.log.scoped(.link);
277277const mem = std.mem;
278278const Path = std.Build.Cache.Path;
279279const Allocator = std.mem.Allocator;
280const Writer = std.io.Writer;
280281
281282const Diags = @import("../../link.zig").Diags;
282283const 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
622622 const cpu_arch = elf_file.getTarget().cpu.arch;
623623 const file_ptr = self.file(elf_file).?;
624624
625 var bw: std.io.BufferedWriter = undefined;
626 bw.initFixed(code);
625 var bw: Writer = .fixed(code);
627626
628627 const rels = self.relocs(elf_file);
629628 var it = RelocsIterator{ .relocs = rels };
......@@ -807,8 +806,7 @@ pub fn resolveRelocsNonAlloc(self: Atom, elf_file: *Elf, code: []u8, undefs: any
807806 const cpu_arch = elf_file.getTarget().cpu.arch;
808807 const file_ptr = self.file(elf_file).?;
809808
810 var bw: std.io.BufferedWriter = undefined;
811 bw.initFixed(code);
809 var bw: Writer = .fixed(code);
812810
813811 const rels = self.relocs(elf_file);
814812 var has_reloc_errors = false;
......@@ -908,7 +906,7 @@ pub fn setExtra(atom: Atom, extras: Extra, elf_file: *Elf) void {
908906 atom.file(elf_file).?.setAtomExtra(atom.extra_index, extras);
909907}
910908
911pub fn format(atom: Atom, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
909pub fn format(atom: Atom, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
912910 _ = atom;
913911 _ = bw;
914912 _ = unused_fmt_string;
......@@ -927,7 +925,7 @@ const FormatContext = struct {
927925 elf_file: *Elf,
928926};
929927
930fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
928fn format2(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
931929 _ = unused_fmt_string;
932930 const atom = ctx.atom;
933931 const elf_file = ctx.elf_file;
......@@ -1079,8 +1077,8 @@ const x86_64 = struct {
10791077 target: *const Symbol,
10801078 args: ResolveArgs,
10811079 it: *RelocsIterator,
1082 bw: *std.io.BufferedWriter,
1083 ) std.io.Writer.Error!void {
1080 bw: *Writer,
1081 ) Writer.Error!void {
10841082 dev.check(.x86_64_backend);
10851083 const t = &elf_file.base.comp.root_mod.resolved_target.result;
10861084 const diags = &elf_file.base.comp.link_diags;
......@@ -1211,8 +1209,8 @@ const x86_64 = struct {
12111209 rel: elf.Elf64_Rela,
12121210 target: *const Symbol,
12131211 args: ResolveArgs,
1214 bw: *std.io.BufferedWriter,
1215 ) std.io.Writer.Error!void {
1212 bw: *Writer,
1213 ) Writer.Error!void {
12161214 dev.check(.x86_64_backend);
12171215
12181216 const r_type: elf.R_X86_64 = @enumFromInt(rel.r_type());
......@@ -1287,7 +1285,7 @@ const x86_64 = struct {
12871285 rels: []const elf.Elf64_Rela,
12881286 value: i32,
12891287 elf_file: *Elf,
1290 bw: *std.io.BufferedWriter,
1288 bw: *Writer,
12911289 ) !void {
12921290 dev.check(.x86_64_backend);
12931291 assert(rels.len == 2);
......@@ -1327,7 +1325,7 @@ const x86_64 = struct {
13271325 rels: []const elf.Elf64_Rela,
13281326 value: i32,
13291327 elf_file: *Elf,
1330 bw: *std.io.BufferedWriter,
1328 bw: *Writer,
13311329 ) !void {
13321330 dev.check(.x86_64_backend);
13331331 assert(rels.len == 2);
......@@ -1388,7 +1386,7 @@ const x86_64 = struct {
13881386 .{ .imm = .s(-129) },
13891387 }, t) catch return false;
13901388 var buf: [std.atomic.cache_line]u8 = undefined;
1391 var bw = std.io.Writer.null.buffered(&buf);
1389 var bw = Writer.null.buffered(&buf);
13921390 inst.encode(&bw, .{}) catch return false;
13931391 return true;
13941392 },
......@@ -1435,7 +1433,7 @@ const x86_64 = struct {
14351433 rels: []const elf.Elf64_Rela,
14361434 value: i32,
14371435 elf_file: *Elf,
1438 bw: *std.io.BufferedWriter,
1436 bw: *Writer,
14391437 ) !void {
14401438 dev.check(.x86_64_backend);
14411439 assert(rels.len == 2);
......@@ -1483,8 +1481,7 @@ const x86_64 = struct {
14831481 }
14841482
14851483 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);
14881485 for (insts) |inst| try inst.encode(&bw, .{});
14891486 }
14901487
......@@ -1589,8 +1586,8 @@ const aarch64 = struct {
15891586 target: *const Symbol,
15901587 args: ResolveArgs,
15911588 it: *RelocsIterator,
1592 bw: *std.io.BufferedWriter,
1593 ) std.io.Writer.Error!void {
1589 bw: *Writer,
1590 ) Writer.Error!void {
15941591 _ = it;
15951592
15961593 const diags = &elf_file.base.comp.link_diags;
......@@ -1792,7 +1789,7 @@ const aarch64 = struct {
17921789 rel: elf.Elf64_Rela,
17931790 target: *const Symbol,
17941791 args: ResolveArgs,
1795 bw: *std.io.BufferedWriter,
1792 bw: *Writer,
17961793 ) !void {
17971794 const r_type: elf.R_AARCH64 = @enumFromInt(rel.r_type());
17981795 _, const A, const S, _, _, _, _ = args;
......@@ -1865,7 +1862,7 @@ const riscv = struct {
18651862 target: *const Symbol,
18661863 args: ResolveArgs,
18671864 it: *RelocsIterator,
1868 bw: *std.io.BufferedWriter,
1865 bw: *Writer,
18691866 ) !void {
18701867 const diags = &elf_file.base.comp.link_diags;
18711868 const r_type: elf.R_RISCV = @enumFromInt(rel.r_type());
......@@ -2000,8 +1997,8 @@ const riscv = struct {
20001997 rel: elf.Elf64_Rela,
20011998 target: *const Symbol,
20021999 args: ResolveArgs,
2003 bw: *std.io.BufferedWriter,
2004 ) std.io.Writer.Error!void {
2000 bw: *Writer,
2001 ) Writer.Error!void {
20052002 const r_type: elf.R_RISCV = @enumFromInt(rel.r_type());
20062003
20072004 _, const A, const S, const GOT, _, _, const DTP = args;
......@@ -2105,14 +2102,15 @@ pub const Extra = struct {
21052102const std = @import("std");
21062103const assert = std.debug.assert;
21072104const elf = std.elf;
2108const eh_frame = @import("eh_frame.zig");
21092105const log = std.log.scoped(.link);
21102106const math = std.math;
21112107const mem = std.mem;
21122108const relocs_log = std.log.scoped(.link_relocs);
2113const relocation = @import("relocation.zig");
2114
21152109const Allocator = mem.Allocator;
2110const Writer = std.io.Writer;
2111
2112const eh_frame = @import("eh_frame.zig");
2113const relocation = @import("relocation.zig");
21162114const Atom = @This();
21172115const Elf = @import("../Elf.zig");
21182116const Fde = eh_frame.Fde;
src/link/Elf/AtomList.zig+6-5
......@@ -167,7 +167,7 @@ pub fn lastAtom(list: AtomList, elf_file: *Elf) *Atom {
167167 return elf_file.atom(list.atoms.keys()[list.atoms.keys().len - 1]).?;
168168}
169169
170pub fn format(list: AtomList, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
170pub fn format(list: AtomList, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
171171 _ = list;
172172 _ = bw;
173173 _ = unused_fmt_string;
......@@ -180,8 +180,8 @@ pub fn fmt(list: AtomList, elf_file: *Elf) std.fmt.Formatter(format2) {
180180 return .{ .data = .{ list, elf_file } };
181181}
182182
183fn format2(ctx: FormatCtx, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
184 _ = unused_fmt_string;
183fn format2(ctx: FormatCtx, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
184 comptime assert(unused_fmt_string.len == 0);
185185 const list, const elf_file = ctx;
186186 try bw.print("list : @{x} : shdr({d}) : align({x}) : size({x})", .{
187187 list.address(elf_file), list.output_section_index,
......@@ -195,13 +195,14 @@ fn format2(ctx: FormatCtx, bw: *std.io.BufferedWriter, comptime unused_fmt_strin
195195 try bw.writeAll(" }");
196196}
197197
198const std = @import("std");
198199const assert = std.debug.assert;
199200const elf = std.elf;
200201const log = std.log.scoped(.link);
201202const math = std.math;
202const std = @import("std");
203
204203const Allocator = std.mem.Allocator;
204const Writer = std.io.Writer;
205
205206const Atom = @import("Atom.zig");
206207const AtomList = @This();
207208const Elf = @import("../Elf.zig");
src/link/Elf/LinkerDefined.zig+5-4
......@@ -449,8 +449,8 @@ const FormatContext = struct {
449449 elf_file: *Elf,
450450};
451451
452fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
453 _ = unused_fmt_string;
452fn formatSymtab(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
453 comptime assert(unused_fmt_string.len == 0);
454454 const self = ctx.self;
455455 const elf_file = ctx.elf_file;
456456 try bw.writeAll(" globals\n");
......@@ -464,12 +464,13 @@ fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_
464464 }
465465}
466466
467const std = @import("std");
468const Allocator = mem.Allocator;
467469const assert = std.debug.assert;
468470const elf = std.elf;
469471const mem = std.mem;
470const std = @import("std");
472const Writer = std.io.Writer;
471473
472const Allocator = mem.Allocator;
473474const Atom = @import("Atom.zig");
474475const Elf = @import("../Elf.zig");
475476const File = @import("file.zig").File;
src/link/Elf/Merge.zig+7-6
......@@ -157,7 +157,7 @@ pub const Section = struct {
157157 }
158158 };
159159
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 {
161161 _ = msec;
162162 _ = bw;
163163 _ = unused_fmt_string;
......@@ -176,7 +176,7 @@ pub const Section = struct {
176176 elf_file: *Elf,
177177 };
178178
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 {
180180 _ = unused_fmt_string;
181181 const msec = ctx.msec;
182182 const elf_file = ctx.elf_file;
......@@ -219,7 +219,7 @@ pub const Subsection = struct {
219219 return msec.bytes.items[msub.string_index..][0..msub.size];
220220 }
221221
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 {
223223 _ = msub;
224224 _ = bw;
225225 _ = unused_fmt_string;
......@@ -238,7 +238,7 @@ pub const Subsection = struct {
238238 elf_file: *Elf,
239239 };
240240
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 {
242242 _ = unused_fmt_string;
243243 const msub = ctx.msub;
244244 const elf_file = ctx.elf_file;
......@@ -307,11 +307,12 @@ pub const InputSection = struct {
307307
308308const String = struct { pos: u32, len: u32 };
309309
310const std = @import("std");
310311const assert = std.debug.assert;
311312const mem = std.mem;
312const std = @import("std");
313
314313const Allocator = mem.Allocator;
314const Writer = std.io.Writer;
315
315316const Atom = @import("Atom.zig");
316317const Elf = @import("../Elf.zig");
317318const Merge = @This();
src/link/Elf/Object.zig+11-12
......@@ -448,8 +448,7 @@ fn parseEhFrame(
448448 const fdes_start = self.fdes.items.len;
449449 const cies_start = self.cies.items.len;
450450
451 var it: eh_frame.Iterator = undefined;
452 it.br.initFixed(raw);
451 var it: eh_frame.Iterator = .{ .br = .fixed(raw) };
453452 while (try it.next()) |rec| {
454453 const rel_range = filterRelocs(self.relocs.items[rel_start..][0..relocs.len], rec.offset, rec.size + 4);
455454 switch (rec.tag) {
......@@ -1199,8 +1198,7 @@ pub fn codeDecompressAlloc(self: *Object, elf_file: *Elf, atom_index: Atom.Index
11991198 const chdr = (try r.takeStruct(elf.Elf64_Chdr)).*;
12001199 switch (chdr.ch_type) {
12011200 .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));
12041202 errdefer gpa.free(bw.buffer);
12051203 try std.compress.zlib.decompress(&r, &bw);
12061204 if (bw.end != bw.buffer.len) return error.InputOutput;
......@@ -1430,7 +1428,7 @@ pub fn group(self: *Object, index: Elf.Group.Index) *Elf.Group {
14301428 return &self.groups.items[index];
14311429}
14321430
1433pub fn format(self: *Object, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
1431pub fn format(self: *Object, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
14341432 _ = self;
14351433 _ = bw;
14361434 _ = unused_fmt_string;
......@@ -1449,7 +1447,7 @@ const FormatContext = struct {
14491447 elf_file: *Elf,
14501448};
14511449
1452fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
1450fn formatSymtab(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
14531451 _ = unused_fmt_string;
14541452 const object = ctx.object;
14551453 const elf_file = ctx.elf_file;
......@@ -1476,7 +1474,7 @@ pub fn fmtAtoms(self: *Object, elf_file: *Elf) std.fmt.Formatter(formatAtoms) {
14761474 } };
14771475}
14781476
1479fn formatAtoms(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
1477fn formatAtoms(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
14801478 _ = unused_fmt_string;
14811479 const object = ctx.object;
14821480 try bw.writeAll(" atoms\n");
......@@ -1493,7 +1491,7 @@ pub fn fmtCies(self: *Object, elf_file: *Elf) std.fmt.Formatter(formatCies) {
14931491 } };
14941492}
14951493
1496fn formatCies(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
1494fn formatCies(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
14971495 _ = unused_fmt_string;
14981496 const object = ctx.object;
14991497 try bw.writeAll(" cies\n");
......@@ -1509,7 +1507,7 @@ pub fn fmtFdes(self: *Object, elf_file: *Elf) std.fmt.Formatter(formatFdes) {
15091507 } };
15101508}
15111509
1512fn formatFdes(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
1510fn formatFdes(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
15131511 _ = unused_fmt_string;
15141512 const object = ctx.object;
15151513 try bw.writeAll(" fdes\n");
......@@ -1525,7 +1523,7 @@ pub fn fmtGroups(self: *Object, elf_file: *Elf) std.fmt.Formatter(formatGroups)
15251523 } };
15261524}
15271525
1528fn formatGroups(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
1526fn formatGroups(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
15291527 comptime assert(unused_fmt_string.len == 0);
15301528 const object = ctx.object;
15311529 const elf_file = ctx.elf_file;
......@@ -1547,8 +1545,8 @@ pub fn fmtPath(self: Object) std.fmt.Formatter(formatPath) {
15471545 return .{ .data = self };
15481546}
15491547
1550fn formatPath(object: Object, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
1551 _ = unused_fmt_string;
1548fn formatPath(object: Object, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
1549 comptime assert(unused_fmt_string.len == 0);
15521550 if (object.archive) |ar| {
15531551 try bw.print("{f}({f})", .{ ar.path, object.path });
15541552 } else {
......@@ -1574,6 +1572,7 @@ const math = std.math;
15741572const mem = std.mem;
15751573const Path = std.Build.Cache.Path;
15761574const Allocator = std.mem.Allocator;
1575const Writer = std.io.Writer;
15771576
15781577const Diags = @import("../../link.zig").Diags;
15791578const 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
509509 }
510510}
511511
512pub fn format(self: SharedObject, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
512pub fn format(self: SharedObject, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
513513 _ = self;
514514 _ = bw;
515515 _ = unused_fmt_string;
......@@ -528,8 +528,8 @@ const FormatContext = struct {
528528 elf_file: *Elf,
529529};
530530
531fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
532 _ = unused_fmt_string;
531fn formatSymtab(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
532 comptime assert(unused_fmt_string.len == 0);
533533 const shared = ctx.shared;
534534 const elf_file = ctx.elf_file;
535535 try bw.writeAll(" globals\n");
......@@ -553,6 +553,7 @@ const mem = std.mem;
553553const Path = std.Build.Cache.Path;
554554const Stat = std.Build.Cache.File.Stat;
555555const Allocator = mem.Allocator;
556const Writer = std.io.Writer;
556557
557558const Elf = @import("../Elf.zig");
558559const 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 {
316316 out.st_size = esym.st_size;
317317}
318318
319pub fn format(symbol: Symbol, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
319pub fn format(symbol: Symbol, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
320320 _ = symbol;
321321 _ = bw;
322322 _ = unused_fmt_string;
......@@ -335,7 +335,7 @@ pub fn fmtName(symbol: Symbol, elf_file: *Elf) std.fmt.Formatter(formatName) {
335335 } };
336336}
337337
338fn formatName(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
338fn formatName(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
339339 _ = unused_fmt_string;
340340 const elf_file = ctx.elf_file;
341341 const symbol = ctx.symbol;
......@@ -358,8 +358,8 @@ pub fn fmt(symbol: Symbol, elf_file: *Elf) std.fmt.Formatter(format2) {
358358 } };
359359}
360360
361fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
362 _ = unused_fmt_string;
361fn format2(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
362 comptime assert(unused_fmt_string.len == 0);
363363 const symbol = ctx.symbol;
364364 const elf_file = ctx.elf_file;
365365 try bw.print("%{d} : {f} : @{x}", .{
......@@ -461,12 +461,13 @@ pub const Extra = struct {
461461
462462pub const Index = u32;
463463
464const std = @import("std");
464465const assert = std.debug.assert;
465466const elf = std.elf;
466467const mem = std.mem;
467const std = @import("std");
468const synthetic_sections = @import("synthetic_sections.zig");
468const Writer = std.io.Writer;
469469
470const synthetic_sections = @import("synthetic_sections.zig");
470471const Atom = @import("Atom.zig");
471472const Elf = @import("../Elf.zig");
472473const 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 {
6565 };
6666}
6767
68pub fn format(thunk: Thunk, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
68pub fn format(thunk: Thunk, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
6969 _ = thunk;
7070 _ = bw;
7171 _ = unused_fmt_string;
......@@ -84,8 +84,8 @@ const FormatContext = struct {
8484 elf_file: *Elf,
8585};
8686
87fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
88 _ = unused_fmt_string;
87fn format2(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
88 comptime assert(unused_fmt_string.len == 0);
8989 const thunk = ctx.thunk;
9090 const elf_file = ctx.elf_file;
9191 try bw.print("@{x} : size({x})\n", .{ thunk.value, thunk.size(elf_file) });
......@@ -117,14 +117,15 @@ const aarch64 = struct {
117117 const Instruction = util.Instruction;
118118};
119119
120const std = @import("std");
120121const assert = std.debug.assert;
121122const elf = std.elf;
122123const log = std.log.scoped(.link);
123124const math = std.math;
124125const mem = std.mem;
125const std = @import("std");
126
127126const Allocator = mem.Allocator;
127const Writer = std.io.Writer;
128
128129const Atom = @import("Atom.zig");
129130const Elf = @import("../Elf.zig");
130131const Symbol = @import("Symbol.zig");
src/link/Elf/ZigObject.zig+4-3
......@@ -2198,7 +2198,7 @@ const FormatContext = struct {
21982198 elf_file: *Elf,
21992199};
22002200
2201fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
2201fn formatSymtab(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
22022202 _ = unused_fmt_string;
22032203 const self = ctx.self;
22042204 const elf_file = ctx.elf_file;
......@@ -2221,8 +2221,8 @@ pub fn fmtAtoms(self: *ZigObject, elf_file: *Elf) std.fmt.Formatter(formatAtoms)
22212221 } };
22222222}
22232223
2224fn formatAtoms(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
2225 _ = unused_fmt_string;
2224fn formatAtoms(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
2225 comptime assert(unused_fmt_string.len == 0);
22262226 try bw.writeAll(" atoms\n");
22272227 for (ctx.self.atoms_indexes.items) |atom_index| {
22282228 const atom_ptr = ctx.self.atom(atom_index) orelse continue;
......@@ -2326,6 +2326,7 @@ const target_util = @import("../../target.zig");
23262326const trace = @import("../../tracy.zig").trace;
23272327const std = @import("std");
23282328const Allocator = std.mem.Allocator;
2329const Writer = std.io.Writer;
23292330
23302331const Archive = @import("Archive.zig");
23312332const Atom = @import("Atom.zig");
src/link/Elf/eh_frame.zig+10-9
......@@ -49,7 +49,7 @@ pub const Fde = struct {
4949
5050 pub fn format(
5151 fde: Fde,
52 bw: *std.io.BufferedWriter,
52 bw: *Writer,
5353 comptime unused_fmt_string: []const u8,
5454 ) !void {
5555 _ = fde;
......@@ -72,7 +72,7 @@ pub const Fde = struct {
7272
7373 fn format2(
7474 ctx: FdeFormatContext,
75 bw: *std.io.BufferedWriter,
75 bw: *Writer,
7676 comptime unused_fmt_string: []const u8,
7777 ) !void {
7878 _ = unused_fmt_string;
......@@ -148,7 +148,7 @@ pub const Cie = struct {
148148
149149 pub fn format(
150150 cie: Cie,
151 bw: *std.io.BufferedWriter,
151 bw: *Writer,
152152 comptime unused_fmt_string: []const u8,
153153 ) !void {
154154 _ = cie;
......@@ -171,7 +171,7 @@ pub const Cie = struct {
171171
172172 fn format2(
173173 ctx: CieFormatContext,
174 bw: *std.io.BufferedWriter,
174 bw: *Writer,
175175 comptime unused_fmt_string: []const u8,
176176 ) !void {
177177 _ = unused_fmt_string;
......@@ -319,7 +319,7 @@ fn resolveReloc(rec: anytype, sym: *const Symbol, rel: elf.Elf64_Rela, elf_file:
319319 }
320320}
321321
322pub fn writeEhFrame(elf_file: *Elf, bw: *std.io.BufferedWriter) !void {
322pub fn writeEhFrame(elf_file: *Elf, bw: *Writer) !void {
323323 relocs_log.debug("{x}: .eh_frame", .{
324324 elf_file.sections.items(.shdr)[elf_file.section_indexes.eh_frame.?].sh_addr,
325325 });
......@@ -380,7 +380,7 @@ pub fn writeEhFrame(elf_file: *Elf, bw: *std.io.BufferedWriter) !void {
380380 if (has_reloc_errors) return error.RelocFailure;
381381}
382382
383pub fn writeEhFrameRelocatable(elf_file: *Elf, bw: *std.io.BufferedWriter) !void {
383pub fn writeEhFrameRelocatable(elf_file: *Elf, bw: *Writer) !void {
384384 for (elf_file.objects.items) |index| {
385385 const object = elf_file.file(index).?.object;
386386
......@@ -482,7 +482,7 @@ pub fn writeEhFrameRelocs(elf_file: *Elf, relocs: *std.ArrayList(elf.Elf64_Rela)
482482 }
483483}
484484
485pub fn writeEhFrameHdr(elf_file: *Elf, bw: *std.io.BufferedWriter) !void {
485pub fn writeEhFrameHdr(elf_file: *Elf, bw: *Writer) !void {
486486 const comp = elf_file.base.comp;
487487 const gpa = comp.gpa;
488488
......@@ -607,9 +607,10 @@ const assert = std.debug.assert;
607607const elf = std.elf;
608608const math = std.math;
609609const relocs_log = std.log.scoped(.link_relocs);
610const relocation = @import("relocation.zig");
611
610const Writer = std.io.Writer;
612611const Allocator = std.mem.Allocator;
612
613const relocation = @import("relocation.zig");
613614const Atom = @import("Atom.zig");
614615const DW_EH_PE = std.dwarf.EH.PE;
615616const Elf = @import("../Elf.zig");
src/link/Elf/file.zig+4-2
......@@ -14,8 +14,8 @@ pub const File = union(enum) {
1414 return .{ .data = file };
1515 }
1616
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);
1919 switch (file) {
2020 .zig_object => |zo| try bw.writeAll(zo.basename),
2121 .linker_defined => try bw.writeAll("(linker defined)"),
......@@ -289,6 +289,8 @@ const elf = std.elf;
289289const log = std.log.scoped(.link);
290290const Path = std.Build.Cache.Path;
291291const Allocator = std.mem.Allocator;
292const Writer = std.io.Writer;
293const assert = std.debug.assert;
292294
293295const Archive = @import("Archive.zig");
294296const Atom = @import("Atom.zig");
src/link/Elf/gc.zig+4-3
......@@ -185,8 +185,8 @@ const Level = struct {
185185 self.value += 1;
186186 }
187187
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);
190190 try bw.splatByteAll(' ', self.value);
191191 }
192192};
......@@ -198,8 +198,9 @@ const assert = std.debug.assert;
198198const elf = std.elf;
199199const gc_track_live_log = std.log.scoped(.gc_track_live);
200200const mem = std.mem;
201
202201const Allocator = mem.Allocator;
202const Writer = std.io.Writer;
203
203204const Atom = @import("Atom.zig");
204205const Elf = @import("../Elf.zig");
205206const 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 {
100100 state_log.debug("ar_strtab\n{f}\n", .{ar_strtab});
101101 }
102102
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));
105104 defer gpa.free(bw.buffer);
106105
107106 // Write magic
......@@ -406,8 +405,7 @@ fn writeSyntheticSections(elf_file: *Elf) !void {
406405 };
407406 const shdr = slice.items(.shdr)[shndx];
408407 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));
411409 defer gpa.free(bw.buffer);
412410 try eh_frame.writeEhFrameRelocatable(elf_file, &bw);
413411 log.debug("writing .eh_frame from 0x{x} to 0x{x}", .{
......@@ -458,18 +456,19 @@ fn writeGroups(elf_file: *Elf) !void {
458456 }
459457}
460458
459const std = @import("std");
461460const assert = std.debug.assert;
462const build_options = @import("build_options");
463const eh_frame = @import("eh_frame.zig");
464461const elf = std.elf;
465const link = @import("../../link.zig");
466462const log = std.log.scoped(.link);
467463const math = std.math;
468464const mem = std.mem;
469465const state_log = std.log.scoped(.link_state);
470466const Path = std.Build.Cache.Path;
471const std = @import("std");
467const Writer = std.io.Writer;
472468
469const link = @import("../../link.zig");
470const build_options = @import("build_options");
471const eh_frame = @import("eh_frame.zig");
473472const Archive = @import("Archive.zig");
474473const Compilation = @import("../../Compilation.zig");
475474const 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
148148 } };
149149}
150150
151fn formatRelocType(ctx: FormatRelocTypeCtx, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
152 _ = unused_fmt_string;
151fn formatRelocType(ctx: FormatRelocTypeCtx, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
152 comptime assert(unused_fmt_string.len == 0);
153153 const r_type = ctx.r_type;
154154 switch (ctx.cpu_arch) {
155155 .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
159159 }
160160}
161161
162const std = @import("std");
162163const assert = std.debug.assert;
163164const elf = std.elf;
164const std = @import("std");
165const Writer = std.io.Writer;
165166
166167const Dwarf = @import("../Dwarf.zig");
167168const Elf = @import("../Elf.zig");
src/link/Elf/synthetic_sections.zig+22-20
......@@ -94,7 +94,7 @@ pub const DynamicSection = struct {
9494 return nentries * @sizeOf(elf.Elf64_Dyn);
9595 }
9696
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 {
9898 const shdrs = elf_file.sections.items(.shdr);
9999
100100 // NEEDED
......@@ -360,7 +360,7 @@ pub const GotSection = struct {
360360 return s;
361361 }
362362
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 {
364364 const comp = elf_file.base.comp;
365365 const is_dyn_lib = elf_file.isEffectivelyDynLib();
366366 const apply_relocs = true; // TODO add user option for this
......@@ -615,7 +615,7 @@ pub const GotSection = struct {
615615 return .{ .data = .{ .got = got, .elf_file = elf_file } };
616616 }
617617
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 {
619619 _ = unused_fmt_string;
620620 const got = ctx.got;
621621 const elf_file = ctx.elf_file;
......@@ -672,7 +672,7 @@ pub const PltSection = struct {
672672 };
673673 }
674674
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 {
676676 const cpu_arch = elf_file.getTarget().cpu.arch;
677677 switch (cpu_arch) {
678678 .x86_64 => try x86_64.write(plt, elf_file, bw),
......@@ -752,7 +752,7 @@ pub const PltSection = struct {
752752 return .{ .data = .{ .plt = plt, .elf_file = elf_file } };
753753 }
754754
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 {
756756 _ = unused_fmt_string;
757757 const plt = ctx.plt;
758758 const elf_file = ctx.elf_file;
......@@ -770,7 +770,7 @@ pub const PltSection = struct {
770770 }
771771
772772 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 {
774774 const shdrs = elf_file.sections.items(.shdr);
775775 const plt_addr = shdrs[elf_file.section_indexes.plt.?].sh_addr;
776776 const got_plt_addr = shdrs[elf_file.section_indexes.got_plt.?].sh_addr;
......@@ -805,7 +805,7 @@ pub const PltSection = struct {
805805 };
806806
807807 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 {
809809 {
810810 const shdrs = elf_file.sections.items(.shdr);
811811 const plt_addr: i64 = @intCast(shdrs[elf_file.section_indexes.plt.?].sh_addr);
......@@ -871,7 +871,7 @@ pub const GotPltSection = struct {
871871 return preamble_size + elf_file.plt.symbols.items.len * 8;
872872 }
873873
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 {
875875 _ = got_plt;
876876 {
877877 // [0]: _DYNAMIC
......@@ -922,7 +922,7 @@ pub const PltGotSection = struct {
922922 };
923923 }
924924
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 {
926926 const cpu_arch = elf_file.getTarget().cpu.arch;
927927 switch (cpu_arch) {
928928 .x86_64 => try x86_64.write(plt_got, elf_file, bw),
......@@ -958,7 +958,7 @@ pub const PltGotSection = struct {
958958 }
959959
960960 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 {
962962 for (plt_got.symbols.items) |ref| {
963963 const sym = elf_file.symbol(ref).?;
964964 const target_addr = sym.gotAddress(elf_file);
......@@ -976,7 +976,7 @@ pub const PltGotSection = struct {
976976 };
977977
978978 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 {
980980 for (plt_got.symbols.items) |ref| {
981981 const sym = elf_file.symbol(ref).?;
982982 const target_addr = sym.gotAddress(elf_file);
......@@ -1155,7 +1155,7 @@ pub const DynsymSection = struct {
11551155 return @as(u32, @intCast(dynsym.entries.items.len + 1));
11561156 }
11571157
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 {
11591159 try bw.writeStruct(Elf.null_sym);
11601160 for (dynsym.entries.items) |entry| {
11611161 const sym = elf_file.symbol(entry.ref).?;
......@@ -1249,7 +1249,7 @@ pub const GnuHashSection = struct {
12491249 return header_size + hash.num_bloom * 8 + hash.num_buckets * 4 + hash.num_exports * 4;
12501250 }
12511251
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 {
12531253 const exports = getExports(elf_file);
12541254 const export_off = elf_file.dynsym.count() - hash.num_exports;
12551255
......@@ -1458,7 +1458,7 @@ pub const VerneedSection = struct {
14581458 return vern.verneed.items.len * @sizeOf(elf.Elf64_Verneed) + vern.vernaux.items.len * @sizeOf(elf.Vernaux);
14591459 }
14601460
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 {
14621462 try bw.writeAll(mem.sliceAsBytes(vern.verneed.items));
14631463 try bw.writeAll(mem.sliceAsBytes(vern.vernaux.items));
14641464 }
......@@ -1486,7 +1486,7 @@ pub const GroupSection = struct {
14861486 return (members.len + 1) * @sizeOf(u32);
14871487 }
14881488
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 {
14901490 const cg = cgs.comdatGroup(elf_file);
14911491 const object = cg.file(elf_file).object;
14921492 const members = cg.members(elf_file);
......@@ -1514,7 +1514,7 @@ pub const GroupSection = struct {
15141514 }
15151515};
15161516
1517fn writeInt(value: anytype, elf_file: *Elf, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
1517fn writeInt(value: anytype, elf_file: *Elf, bw: *Writer) Writer.Error!void {
15181518 const entry_size = elf_file.archPtrWidthBytes();
15191519 const target = elf_file.getTarget();
15201520 const endian = target.cpu.arch.endian();
......@@ -1526,17 +1526,19 @@ fn writeInt(value: anytype, elf_file: *Elf, bw: *std.io.BufferedWriter) std.io.W
15261526 }
15271527}
15281528
1529const assert = std.debug.assert;
15301529const builtin = @import("builtin");
1530
1531const std = @import("std");
1532const assert = std.debug.assert;
15311533const elf = std.elf;
15321534const math = std.math;
15331535const mem = std.mem;
15341536const log = std.log.scoped(.link);
15351537const relocs_log = std.log.scoped(.link_relocs);
1536const relocation = @import("relocation.zig");
1537const std = @import("std");
1538
15391538const Allocator = std.mem.Allocator;
1539const Writer = std.io.Writer;
1540
1541const relocation = @import("relocation.zig");
15401542const Elf = @import("../Elf.zig");
15411543const File = @import("file.zig").File;
15421544const SharedObject = @import("SharedObject.zig");
src/link/MachO.zig+17-24
......@@ -2527,8 +2527,7 @@ fn writeThunkWorker(self: *MachO, thunk: Thunk) void {
25272527
25282528 const doWork = struct {
25292529 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()]);
25322531 try th.write(macho_file, &bw);
25332532 }
25342533 }.doWork;
......@@ -2556,8 +2555,7 @@ fn writeSyntheticSectionWorker(self: *MachO, sect_id: u8, out: []u8) void {
25562555
25572556 const doWork = struct {
25582557 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);
25612559 switch (tag) {
25622560 .eh_frame => eh_frame.write(macho_file, buffer),
25632561 .unwind_info => try macho_file.unwind_info.write(macho_file, &bw),
......@@ -2606,8 +2604,7 @@ fn updateLazyBindSizeWorker(self: *MachO) void {
26062604 try macho_file.lazy_bind_section.updateSize(macho_file);
26072605 const sect_id = macho_file.stubs_helper_sect_index.?;
26082606 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);
26112608 try macho_file.stubs_helper.write(macho_file, &bw);
26122609 }
26132610 }.doWork;
......@@ -2667,8 +2664,7 @@ fn writeDyldInfo(self: *MachO) !void {
26672664 needed_size += cmd.lazy_bind_size;
26682665 needed_size += cmd.export_size;
26692666
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));
26722668 defer gpa.free(bw.buffer);
26732669 @memset(bw.buffer, 0);
26742670
......@@ -2690,8 +2686,7 @@ pub fn writeDataInCode(self: *MachO) !void {
26902686 const gpa = self.base.comp.gpa;
26912687 const cmd = self.data_in_code_cmd;
26922688
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()));
26952690 defer gpa.free(bw.buffer);
26962691
26972692 try self.data_in_code.write(self, &bw);
......@@ -2706,8 +2701,7 @@ fn writeIndsymtab(self: *MachO) !void {
27062701 const gpa = self.base.comp.gpa;
27072702 const cmd = self.dysymtab_cmd;
27082703
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));
27112705 defer gpa.free(bw.buffer);
27122706
27132707 try self.indsymtab.write(self, &bw);
......@@ -2822,12 +2816,11 @@ fn calcSymtabSize(self: *MachO) !void {
28222816 }
28232817}
28242818
2825fn writeLoadCommands(self: *MachO) std.io.Writer.Error!struct { usize, usize, u64 } {
2819fn writeLoadCommands(self: *MachO) Writer.Error!struct { usize, usize, u64 } {
28262820 const comp = self.base.comp;
28272821 const gpa = comp.gpa;
28282822
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)));
28312824 defer gpa.free(bw.buffer);
28322825
28332826 var ncmds: usize = 0;
......@@ -3021,8 +3014,7 @@ pub fn writeCodeSignature(self: *MachO, code_sig: *CodeSignature) !void {
30213014 const seg = self.getTextSegment();
30223015 const offset = self.codesig_cmd.dataoff;
30233016
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()));
30263018 defer gpa.free(bw.buffer);
30273019 try code_sig.writeAdhocSignature(self, .{
30283020 .file = self.base.file.?,
......@@ -3910,7 +3902,7 @@ pub fn dumpState(self: *MachO) std.fmt.Formatter(fmtDumpState) {
39103902 return .{ .data = self };
39113903}
39123904
3913fn fmtDumpState(self: *MachO, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
3905fn fmtDumpState(self: *MachO, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
39143906 _ = unused_fmt_string;
39153907 if (self.getZigObject()) |zo| {
39163908 try bw.print("zig_object({d}) : {s}\n", .{ zo.index, zo.basename });
......@@ -3969,7 +3961,7 @@ fn fmtSections(self: *MachO) std.fmt.Formatter(formatSections) {
39693961 return .{ .data = self };
39703962}
39713963
3972fn formatSections(self: *MachO, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
3964fn formatSections(self: *MachO, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
39733965 _ = unused_fmt_string;
39743966 const slice = self.sections.slice();
39753967 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) {
39873979 return .{ .data = self };
39883980}
39893981
3990fn formatSegments(self: *MachO, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
3982fn formatSegments(self: *MachO, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
39913983 _ = unused_fmt_string;
39923984 for (self.segments.items, 0..) |seg, i| {
39933985 try bw.print("seg({d}) : {s} : @{x}-{x} ({x}-{x})\n", .{
......@@ -4001,7 +3993,7 @@ pub fn fmtSectType(tt: u8) std.fmt.Formatter(formatSectType) {
40013993 return .{ .data = tt };
40023994}
40033995
4004fn formatSectType(tt: u8, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
3996fn formatSectType(tt: u8, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
40053997 _ = unused_fmt_string;
40063998 const name = switch (tt) {
40073999 macho.S_REGULAR => "REGULAR",
......@@ -4270,7 +4262,7 @@ pub const Platform = struct {
42704262 cpu_arch: std.Target.Cpu.Arch,
42714263 };
42724264
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 {
42744266 _ = unused_fmt_string;
42754267 try bw.print("{s}-{s}", .{ @tagName(ctx.cpu_arch), @tagName(ctx.platform.os_tag) });
42764268 if (ctx.platform.abi != .none) {
......@@ -4483,8 +4475,8 @@ pub const Ref = struct {
44834475 };
44844476 }
44854477
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);
44884480 try bw.print("%{d} in file({d})", .{ ref.index, ref.file });
44894481 }
44904482};
......@@ -5387,6 +5379,7 @@ const macho = std.macho;
53875379const math = std.math;
53885380const mem = std.mem;
53895381const meta = std.meta;
5382const Writer = std.io.Writer;
53905383
53915384const aarch64 = @import("../arch/aarch64/bits.zig");
53925385const 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
7878}
7979
8080pub fn writeHeader(
81 bw: *std.io.BufferedWriter,
81 bw: *Writer,
8282 object_name: []const u8,
8383 object_size: usize,
8484 format: Format,
85) std.io.Writer.Error!void {
85) Writer.Error!void {
8686 var hdr: ar_hdr = undefined;
8787 @memset(mem.asBytes(&hdr), ' ');
8888 inline for (@typeInfo(ar_hdr).@"struct".fields) |field| @field(hdr, field.name)[0] = '0';
......@@ -177,7 +177,7 @@ pub const ArSymtab = struct {
177177 return ptr_width + ar.entries.items.len * 2 * ptr_width + ptr_width + mem.alignForward(usize, ar.strtab.buffer.items.len, ptr_width);
178178 }
179179
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 {
181181 const ptr_width = ptrWidth(format);
182182 // Header
183183 try writeHeader(bw, SYMDEF, ar.size(format), format);
......@@ -212,7 +212,7 @@ pub const ArSymtab = struct {
212212 return .{ .data = .{ .ar = ar, .macho_file = macho_file } };
213213 }
214214
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 {
216216 _ = unused_fmt_string;
217217 const ar = ctx.ar;
218218 const macho_file = ctx.macho_file;
......@@ -249,7 +249,7 @@ pub fn ptrWidth(format: Format) usize {
249249 };
250250}
251251
252pub fn writeInt(bw: *std.io.BufferedWriter, format: Format, value: u64) std.io.Writer.Error!void {
252pub fn writeInt(bw: *Writer, format: Format, value: u64) Writer.Error!void {
253253 switch (format) {
254254 .p32 => try bw.writeInt(u32, std.math.cast(u32, value) orelse return error.Overflow, .little),
255255 .p64 => try bw.writeInt(u64, value, .little),
......@@ -271,8 +271,9 @@ const log = std.log.scoped(.link);
271271const macho = std.macho;
272272const mem = std.mem;
273273const std = @import("std");
274const Allocator = mem.Allocator;
274const Allocator = std.mem.Allocator;
275275const Path = std.Build.Cache.Path;
276const Writer = std.io.Writer;
276277
277278const Archive = @This();
278279const 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 {
580580
581581 relocs_log.debug("{x}: {s}", .{ self.value, name });
582582
583 var bw: std.io.BufferedWriter = undefined;
584 bw.initFixed(buffer);
583 var bw: Writer = .fixed(buffer);
585584
586585 var has_error = false;
587586 var i: usize = 0;
......@@ -638,8 +637,8 @@ fn resolveRelocInner(
638637 subtractor: ?Relocation,
639638 code: []u8,
640639 macho_file: *MachO,
641 bw: *std.io.BufferedWriter,
642) std.io.Writer.Error!void {
640 bw: *Writer,
641) Writer.Error!void {
643642 const t = &macho_file.base.comp.root_mod.resolved_target.result;
644643 const cpu_arch = t.cpu.arch;
645644 const rel_offset = math.cast(usize, rel.offset - self.off) orelse return error.Overflow;
......@@ -938,8 +937,7 @@ const x86_64 = struct {
938937 }
939938
940939 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);
943941 for (insts) |inst| try inst.encode(&bw, .{});
944942 }
945943
......@@ -1140,8 +1138,8 @@ const FormatContext = struct {
11401138 macho_file: *MachO,
11411139};
11421140
1143fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
1144 _ = unused_fmt_string;
1141fn format2(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
1142 comptime assert(unused_fmt_string.len == 0);
11451143 const atom = ctx.atom;
11461144 const macho_file = ctx.macho_file;
11471145 const file = atom.getFile(macho_file);
......@@ -1197,19 +1195,20 @@ pub const Extra = struct {
11971195
11981196pub const Alignment = @import("../../InternPool.zig").Alignment;
11991197
1200const aarch64 = @import("../aarch64.zig");
1198const std = @import("std");
12011199const assert = std.debug.assert;
12021200const macho = std.macho;
12031201const math = std.math;
12041202const mem = std.mem;
12051203const log = std.log.scoped(.link);
12061204const relocs_log = std.log.scoped(.link_relocs);
1207const std = @import("std");
1208const trace = @import("../../tracy.zig").trace;
1209
1205const Writer = std.io.Writer;
12101206const Allocator = mem.Allocator;
1211const Atom = @This();
12121207const AtomicBool = std.atomic.Value(bool);
1208
1209const aarch64 = @import("../aarch64.zig");
1210const trace = @import("../../tracy.zig").trace;
1211const Atom = @This();
12131212const File = @import("file.zig").File;
12141213const MachO = @import("../MachO.zig");
12151214const Object = @import("Object.zig");
src/link/MachO/DebugSymbols.zig+2-2
......@@ -269,8 +269,7 @@ fn finalizeDwarfSegment(self: *DebugSymbols, macho_file: *MachO) void {
269269
270270fn writeLoadCommands(self: *DebugSymbols, macho_file: *MachO) !struct { usize, usize } {
271271 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)));
274273 defer gpa.free(bw.buffer);
275274
276275 var ncmds: usize = 0;
......@@ -456,6 +455,7 @@ const math = std.math;
456455const mem = std.mem;
457456const padToIdeal = MachO.padToIdeal;
458457const trace = @import("../../tracy.zig").trace;
458const Writer = std.io.Writer;
459459
460460const Allocator = mem.Allocator;
461461const MachO = @import("../MachO.zig");
src/link/MachO/Dylib.zig+6-5
......@@ -675,7 +675,7 @@ const FormatContext = struct {
675675 macho_file: *MachO,
676676};
677677
678fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
678fn formatSymtab(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
679679 _ = unused_fmt_string;
680680 const dylib = ctx.dylib;
681681 const macho_file = ctx.macho_file;
......@@ -901,19 +901,17 @@ const Export = struct {
901901 };
902902};
903903
904const std = @import("std");
904905const assert = std.debug.assert;
905const fat = @import("fat.zig");
906906const fs = std.fs;
907907const fmt = std.fmt;
908908const log = std.log.scoped(.link);
909909const macho = std.macho;
910910const math = std.math;
911911const mem = std.mem;
912const tapi = @import("../tapi.zig");
913const trace = @import("../../tracy.zig").trace;
914const std = @import("std");
915912const Allocator = mem.Allocator;
916913const Path = std.Build.Cache.Path;
914const Writer = std.io.Writer;
917915
918916const Dylib = @This();
919917const File = @import("file.zig").File;
......@@ -922,3 +920,6 @@ const LoadCommandIterator = macho.LoadCommandIterator;
922920const MachO = @import("../MachO.zig");
923921const Symbol = @import("Symbol.zig");
924922const Tbd = tapi.Tbd;
923const fat = @import("fat.zig");
924const tapi = @import("../tapi.zig");
925const 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
848848 } };
849849}
850850
851fn formatAtoms(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
851fn formatAtoms(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
852852 _ = unused_fmt_string;
853853 try bw.writeAll(" atoms\n");
854854 for (ctx.self.getAtoms()) |atom_index| {
......@@ -864,8 +864,8 @@ pub fn fmtSymtab(self: *InternalObject, macho_file: *MachO) std.fmt.Formatter(fo
864864 } };
865865}
866866
867fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
868 _ = unused_fmt_string;
867fn formatSymtab(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
868 comptime assert(unused_fmt_string.len == 0);
869869 const macho_file = ctx.macho_file;
870870 const self = ctx.self;
871871 try bw.writeAll(" symbols\n");
......@@ -896,6 +896,7 @@ const macho = std.macho;
896896const mem = std.mem;
897897const std = @import("std");
898898const trace = @import("../../tracy.zig").trace;
899const Writer = std.io.Writer;
899900
900901const Allocator = std.mem.Allocator;
901902const 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
10651065 }
10661066 }
10671067
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) };
10701069 while (try it.next()) |rec| {
10711070 switch (rec.tag) {
10721071 .cie => try self.cies.append(allocator, .{
......@@ -1695,7 +1694,7 @@ pub fn updateArSize(self: *Object, macho_file: *MachO) !void {
16951694 };
16961695}
16971696
1698pub fn writeAr(self: Object, bw: *std.io.BufferedWriter, ar_format: Archive.Format, macho_file: *MachO) !void {
1697pub fn writeAr(self: Object, bw: *Writer, ar_format: Archive.Format, macho_file: *MachO) !void {
16991698 // Header
17001699 const size = try macho_file.cast(usize, self.output_ar_state.size);
17011700 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_
25132512 return data;
25142513}
25152514
2516pub fn format(self: *Object, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
2515pub fn format(self: *Object, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
25172516 _ = self;
25182517 _ = bw;
25192518 _ = unused_fmt_string;
......@@ -2532,7 +2531,7 @@ pub fn fmtAtoms(self: *Object, macho_file: *MachO) std.fmt.Formatter(formatAtoms
25322531 } };
25332532}
25342533
2535fn formatAtoms(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
2534fn formatAtoms(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
25362535 _ = unused_fmt_string;
25372536 const object = ctx.object;
25382537 const macho_file = ctx.macho_file;
......@@ -2550,7 +2549,7 @@ pub fn fmtCies(self: *Object, macho_file: *MachO) std.fmt.Formatter(formatCies)
25502549 } };
25512550}
25522551
2553fn formatCies(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
2552fn formatCies(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
25542553 _ = unused_fmt_string;
25552554 const object = ctx.object;
25562555 try bw.writeAll(" cies\n");
......@@ -2566,7 +2565,7 @@ pub fn fmtFdes(self: *Object, macho_file: *MachO) std.fmt.Formatter(formatFdes)
25662565 } };
25672566}
25682567
2569fn formatFdes(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
2568fn formatFdes(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
25702569 _ = unused_fmt_string;
25712570 const object = ctx.object;
25722571 try bw.writeAll(" fdes\n");
......@@ -2582,7 +2581,7 @@ pub fn fmtUnwindRecords(self: *Object, macho_file: *MachO) std.fmt.Formatter(for
25822581 } };
25832582}
25842583
2585fn formatUnwindRecords(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
2584fn formatUnwindRecords(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
25862585 _ = unused_fmt_string;
25872586 const object = ctx.object;
25882587 const macho_file = ctx.macho_file;
......@@ -2599,7 +2598,7 @@ pub fn fmtSymtab(self: *Object, macho_file: *MachO) std.fmt.Formatter(formatSymt
25992598 } };
26002599}
26012600
2602fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
2601fn formatSymtab(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
26032602 _ = unused_fmt_string;
26042603 const object = ctx.object;
26052604 const macho_file = ctx.macho_file;
......@@ -2629,7 +2628,7 @@ pub fn fmtPath(self: Object) std.fmt.Formatter(formatPath) {
26292628 return .{ .data = self };
26302629}
26312630
2632fn formatPath(object: Object, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
2631fn formatPath(object: Object, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
26332632 _ = unused_fmt_string;
26342633 if (object.in_archive) |ar| {
26352634 try bw.print("{f}({s})", .{
......@@ -2690,7 +2689,7 @@ const StabFile = struct {
26902689 return object.symbols.items[index];
26912690 }
26922691
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 {
26942693 _ = stab;
26952694 _ = bw;
26962695 _ = unused_fmt_string;
......@@ -2703,7 +2702,7 @@ const StabFile = struct {
27032702 return .{ .data = .{ stab, object } };
27042703 }
27052704
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 {
27072706 _ = unused_fmt_string;
27082707 const stab, const object = ctx;
27092708 const sym = stab.getSymbol(object).?;
......@@ -3104,17 +3103,18 @@ const aarch64 = struct {
31043103 }
31053104};
31063105
3106const std = @import("std");
31073107const assert = std.debug.assert;
3108const eh_frame = @import("eh_frame.zig");
31093108const log = std.log.scoped(.link);
31103109const macho = std.macho;
31113110const math = std.math;
31123111const mem = std.mem;
3113const trace = @import("../../tracy.zig").trace;
3114const std = @import("std");
31153112const Path = std.Build.Cache.Path;
3113const Allocator = std.mem.Allocator;
3114const Writer = std.io.Writer;
31163115
3117const Allocator = mem.Allocator;
3116const eh_frame = @import("eh_frame.zig");
3117const trace = @import("../../tracy.zig").trace;
31183118const Archive = @import("Archive.zig");
31193119const Atom = @import("Atom.zig");
31203120const 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
7676 return .{ .data = .{ rel, cpu_arch } };
7777}
7878
79fn formatPretty(ctx: FormatCtx, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
79fn formatPretty(ctx: FormatCtx, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
8080 _ = unused_fmt_string;
8181 const rel, const cpu_arch = ctx;
8282 try bw.writeAll(switch (rel.type) {
......@@ -157,10 +157,11 @@ pub const Type = enum {
157157
158158const Tag = enum { local, @"extern" };
159159
160const std = @import("std");
160161const assert = std.debug.assert;
161162const macho = std.macho;
162163const math = std.math;
163const std = @import("std");
164const Writer = std.io.Writer;
164165
165166const Atom = @import("Atom.zig");
166167const 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
286286 }
287287}
288288
289pub fn format(symbol: Symbol, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
289pub fn format(symbol: Symbol, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
290290 _ = symbol;
291291 _ = bw;
292292 _ = unused_fmt_string;
......@@ -305,8 +305,8 @@ pub fn fmt(symbol: Symbol, macho_file: *MachO) std.fmt.Formatter(format2) {
305305 } };
306306}
307307
308fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
309 _ = unused_fmt_string;
308fn format2(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
309 comptime assert(unused_fmt_string.len == 0);
310310 const symbol = ctx.symbol;
311311 try bw.print("%{d} : {s} : @{x}", .{
312312 symbol.nlist_idx,
......@@ -425,6 +425,7 @@ pub const Index = u32;
425425const assert = std.debug.assert;
426426const macho = std.macho;
427427const std = @import("std");
428const Writer = std.io.Writer;
428429
429430const Atom = @import("Atom.zig");
430431const 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 {
2020 return thunk.getAddress(macho_file) + thunk.symbols.getIndex(ref).? * trampoline_size;
2121}
2222
23pub fn write(thunk: Thunk, macho_file: *MachO, bw: *std.io.BufferedWriter) !void {
23pub fn write(thunk: Thunk, macho_file: *MachO, bw: *Writer) !void {
2424 for (thunk.symbols.keys(), 0..) |ref, i| {
2525 const sym = ref.getSymbol(macho_file).?;
2626 const saddr = thunk.getAddress(macho_file) + i * trampoline_size;
......@@ -61,7 +61,7 @@ pub fn writeSymtab(thunk: Thunk, macho_file: *MachO, ctx: anytype) void {
6161 }
6262}
6363
64pub fn format(thunk: Thunk, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
64pub fn format(thunk: Thunk, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
6565 _ = thunk;
6666 _ = bw;
6767 _ = unused_fmt_string;
......@@ -80,7 +80,7 @@ const FormatContext = struct {
8080 macho_file: *MachO,
8181};
8282
83fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
83fn format2(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
8484 _ = unused_fmt_string;
8585 const thunk = ctx.thunk;
8686 const macho_file = ctx.macho_file;
......@@ -103,6 +103,7 @@ const math = std.math;
103103const mem = std.mem;
104104const std = @import("std");
105105const trace = @import("../../tracy.zig").trace;
106const Writer = std.io.Writer;
106107
107108const Allocator = mem.Allocator;
108109const Atom = @import("Atom.zig");
src/link/MachO/UnwindInfo.zig+7-6
......@@ -289,7 +289,7 @@ pub fn calcSize(info: UnwindInfo) usize {
289289 return total_size;
290290}
291291
292pub fn write(info: UnwindInfo, macho_file: *MachO, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
292pub fn write(info: UnwindInfo, macho_file: *MachO, bw: *Writer) Writer.Error!void {
293293 const seg = macho_file.getTextSegment();
294294 const header = macho_file.sections.items(.header)[macho_file.unwind_info_sect_index.?];
295295
......@@ -449,7 +449,7 @@ pub const Encoding = extern struct {
449449 return enc.enc == other.enc;
450450 }
451451
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 {
453453 _ = unused_fmt_string;
454454 try bw.print("0x{x:0>8}", .{enc.enc});
455455 }
......@@ -505,7 +505,7 @@ pub const Record = struct {
505505 return lsda.getAddress(macho_file) + rec.lsda_offset;
506506 }
507507
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 {
509509 _ = rec;
510510 _ = bw;
511511 _ = unused_fmt_string;
......@@ -524,7 +524,7 @@ pub const Record = struct {
524524 macho_file: *MachO,
525525 };
526526
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 {
528528 _ = unused_fmt_string;
529529 const rec = ctx.rec;
530530 const macho_file = ctx.macho_file;
......@@ -589,7 +589,7 @@ const Page = struct {
589589 return null;
590590 }
591591
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 {
593593 _ = page;
594594 _ = bw;
595595 _ = unused_format_string;
......@@ -601,7 +601,7 @@ const Page = struct {
601601 info: UnwindInfo,
602602 };
603603
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 {
605605 _ = unused_format_string;
606606 try bw.writeAll("Page:\n");
607607 try bw.print(" kind: {s}\n", .{@tagName(ctx.page.kind)});
......@@ -684,6 +684,7 @@ const macho = std.macho;
684684const math = std.math;
685685const mem = std.mem;
686686const trace = @import("../../tracy.zig").trace;
687const Writer = std.io.Writer;
687688
688689const Allocator = mem.Allocator;
689690const Atom = @import("Atom.zig");
src/link/MachO/ZigObject.zig+4-3
......@@ -317,7 +317,7 @@ pub fn updateArSize(self: *ZigObject) void {
317317 self.output_ar_state.size = self.data.items.len;
318318}
319319
320pub fn writeAr(self: ZigObject, bw: *std.io.BufferedWriter, ar_format: Archive.Format) std.io.Writer.Error!void {
320pub fn writeAr(self: ZigObject, bw: *Writer, ar_format: Archive.Format) Writer.Error!void {
321321 // Header
322322 const size = std.math.cast(usize, self.output_ar_state.size) orelse return error.Overflow;
323323 try Archive.writeHeader(bw, self.basename, size, ar_format);
......@@ -1688,7 +1688,7 @@ const FormatContext = struct {
16881688 macho_file: *MachO,
16891689};
16901690
1691fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
1691fn formatSymtab(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
16921692 _ = unused_fmt_string;
16931693 try bw.writeAll(" symbols\n");
16941694 const self = ctx.self;
......@@ -1711,7 +1711,7 @@ pub fn fmtAtoms(self: *ZigObject, macho_file: *MachO) std.fmt.Formatter(formatAt
17111711 } };
17121712}
17131713
1714fn formatAtoms(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
1714fn formatAtoms(ctx: FormatContext, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
17151715 _ = unused_fmt_string;
17161716 const self = ctx.self;
17171717 const macho_file = ctx.macho_file;
......@@ -1783,6 +1783,7 @@ const mem = std.mem;
17831783const target_util = @import("../../target.zig");
17841784const trace = @import("../../tracy.zig").trace;
17851785const std = @import("std");
1786const Writer = std.io.Writer;
17861787
17871788const Allocator = std.mem.Allocator;
17881789const Archive = @import("Archive.zig");
src/link/MachO/dead_strip.zig+2-1
......@@ -196,7 +196,7 @@ const Level = struct {
196196 self.value += 1;
197197 }
198198
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 {
200200 _ = unused_fmt_string;
201201 try bw.splatByteAll(' ', self.value);
202202 }
......@@ -213,6 +213,7 @@ const mem = std.mem;
213213const trace = @import("../../tracy.zig").trace;
214214const track_live_log = std.log.scoped(.dead_strip_track_live);
215215const std = @import("std");
216const Writer = std.io.Writer;
216217
217218const Allocator = mem.Allocator;
218219const Atom = @import("Atom.zig");
src/link/MachO/dyld_info/Rebase.zig+12-11
......@@ -133,7 +133,7 @@ fn finalize(rebase: *Rebase, gpa: Allocator) !void {
133133 try done(bw);
134134}
135135
136fn finalizeSegment(entries: []const Entry, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
136fn finalizeSegment(entries: []const Entry, bw: *Writer) Writer.Error!void {
137137 if (entries.len == 0) return;
138138
139139 const segment_id = entries[0].segment_id;
......@@ -220,24 +220,24 @@ fn finalizeSegment(entries: []const Entry, bw: *std.io.BufferedWriter) std.io.Wr
220220 }
221221}
222222
223fn setTypePointer(bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
223fn setTypePointer(bw: *Writer) Writer.Error!void {
224224 log.debug(">>> set type: {d}", .{macho.REBASE_TYPE_POINTER});
225225 try bw.writeByte(macho.REBASE_OPCODE_SET_TYPE_IMM | @as(u4, @intCast(macho.REBASE_TYPE_POINTER)));
226226}
227227
228fn setSegmentOffset(segment_id: u4, offset: u64, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
228fn setSegmentOffset(segment_id: u4, offset: u64, bw: *Writer) Writer.Error!void {
229229 log.debug(">>> set segment: {d} and offset: {x}", .{ segment_id, offset });
230230 try bw.writeByte(macho.REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB | @as(u4, @truncate(segment_id)));
231231 try bw.writeLeb128(offset);
232232}
233233
234fn rebaseAddAddr(addr: u64, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
234fn rebaseAddAddr(addr: u64, bw: *Writer) Writer.Error!void {
235235 log.debug(">>> rebase with add: {x}", .{addr});
236236 try bw.writeByte(macho.REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB);
237237 try bw.writeLeb128(addr);
238238}
239239
240fn rebaseTimes(count: usize, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
240fn rebaseTimes(count: usize, bw: *Writer) Writer.Error!void {
241241 log.debug(">>> rebase with count: {d}", .{count});
242242 if (count <= 0xf) {
243243 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
247247 }
248248}
249249
250fn rebaseTimesSkip(count: usize, skip: u64, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
250fn rebaseTimesSkip(count: usize, skip: u64, bw: *Writer) Writer.Error!void {
251251 log.debug(">>> rebase with count: {d} and skip: {x}", .{ count, skip });
252252 try bw.writeByte(macho.REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB);
253253 try bw.writeLeb128(count);
254254 try bw.writeLeb128(skip);
255255}
256256
257fn addAddr(addr: u64, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
257fn addAddr(addr: u64, bw: *Writer) Writer.Error!void {
258258 log.debug(">>> add: {x}", .{addr});
259259 if (std.math.divExact(u64, addr, @sizeOf(u64))) |scaled| {
260260 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 {
265265 try bw.writeLeb128(addr);
266266}
267267
268fn done(bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
268fn done(bw: *Writer) Writer.Error!void {
269269 log.debug(">>> done", .{});
270270 try bw.writeByte(macho.REBASE_OPCODE_DONE);
271271}
272272
273pub fn write(rebase: Rebase, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
273pub fn write(rebase: Rebase, bw: *Writer) Writer.Error!void {
274274 try bw.writeAll(rebase.buffer.items);
275275}
276276
......@@ -654,9 +654,10 @@ const log = std.log.scoped(.link_dyld_info);
654654const macho = std.macho;
655655const mem = std.mem;
656656const testing = std.testing;
657const trace = @import("../../../tracy.zig").trace;
658
659657const Allocator = mem.Allocator;
658const Writer = std.io.Writer;
659
660const trace = @import("../../../tracy.zig").trace;
660661const File = @import("../file.zig").File;
661662const MachO = @import("../../MachO.zig");
662663const Rebase = @This();
src/link/MachO/dyld_info/Trie.zig+6-6
......@@ -166,8 +166,7 @@ fn finalize(self: *Trie, allocator: Allocator) !void {
166166
167167 assert(self.buffer.len == 0);
168168 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);
171170 for (ordered_nodes.items) |node_index| {
172171 try self.writeNode(node_index, &bw);
173172 }
......@@ -185,7 +184,7 @@ const FinalizeNodeResult = struct {
185184/// Updates offset of this node in the output byte stream.
186185fn finalizeNode(self: *Trie, node_index: Node.Index, offset_in_trie: u32) !FinalizeNodeResult {
187186 var buf: [1024]u8 = undefined;
188 var bw = std.io.Writer.null.buffered(&buf);
187 var bw = Writer.null.buffered(&buf);
189188 const slice = self.nodes.slice();
190189
191190 var node_size: u32 = 0;
......@@ -229,7 +228,7 @@ pub fn deinit(self: *Trie, allocator: Allocator) void {
229228 allocator.free(self.buffer);
230229}
231230
232pub fn write(self: Trie, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
231pub fn write(self: Trie, bw: *Writer) Writer.Error!void {
233232 try bw.writeAll(self.buffer);
234233}
235234
......@@ -239,7 +238,7 @@ pub fn write(self: Trie, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
239238/// iterate over `Trie.ordered_nodes` and call this method on each node.
240239/// This is one of the requirements of the MachO.
241240/// Panics if `finalize` was not called before calling this method.
242fn writeNode(self: *Trie, node_index: Node.Index, bw: *std.io.BufferedWriter) !void {
241fn writeNode(self: *Trie, node_index: Node.Index, bw: *Writer) !void {
243242 const slice = self.nodes.slice();
244243 const edges = slice.items(.edges)[node_index];
245244 const is_terminal = slice.items(.is_terminal)[node_index];
......@@ -408,9 +407,10 @@ const macho = std.macho;
408407const mem = std.mem;
409408const std = @import("std");
410409const testing = std.testing;
410const Writer = std.io.Writer;
411
411412const trace = @import("../../../tracy.zig").trace;
412413const DeprecatedLinearFifo = @import("../../../deprecated.zig").LinearFifo;
413
414414const Allocator = mem.Allocator;
415415const MachO = @import("../../MachO.zig");
416416const Trie = @This();
src/link/MachO/dyld_info/bind.zig+19-18
......@@ -139,7 +139,7 @@ pub const Bind = struct {
139139 try done(bw);
140140 }
141141
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 {
143143 if (entries.len == 0) return;
144144
145145 const seg_id = entries[0].segment_id;
......@@ -251,7 +251,7 @@ pub const Bind = struct {
251251 }
252252 }
253253
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 {
255255 try bw.writeAll(bind.buffer.items);
256256 }
257257};
......@@ -380,7 +380,7 @@ pub const WeakBind = struct {
380380 try done(bw);
381381 }
382382
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 {
384384 if (entries.len == 0) return;
385385
386386 const seg_id = entries[0].segment_id;
......@@ -481,7 +481,7 @@ pub const WeakBind = struct {
481481 }
482482 }
483483
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 {
485485 try bw.writeAll(bind.buffer.items);
486486 }
487487};
......@@ -565,30 +565,30 @@ pub const LazyBind = struct {
565565 }
566566 }
567567
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 {
569569 try bw.writeAll(bind.buffer.items);
570570 }
571571};
572572
573fn setSegmentOffset(segment_id: u4, offset: u64, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
573fn setSegmentOffset(segment_id: u4, offset: u64, bw: *Writer) Writer.Error!void {
574574 log.debug(">>> set segment: {d} and offset: {x}", .{ segment_id, offset });
575575 try bw.writeByte(macho.BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB | segment_id);
576576 try bw.writeLeb128(offset);
577577}
578578
579fn setSymbol(name: []const u8, flags: u4, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
579fn setSymbol(name: []const u8, flags: u4, bw: *Writer) Writer.Error!void {
580580 log.debug(">>> set symbol: {s} with flags: {x}", .{ name, flags });
581581 try bw.writeByte(macho.BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM | flags);
582582 try bw.writeAll(name);
583583 try bw.writeByte(0);
584584}
585585
586fn setTypePointer(bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
586fn setTypePointer(bw: *Writer) Writer.Error!void {
587587 log.debug(">>> set type: {d}", .{macho.BIND_TYPE_POINTER});
588588 try bw.writeByte(macho.BIND_OPCODE_SET_TYPE_IMM | @as(u4, @intCast(macho.BIND_TYPE_POINTER)));
589589}
590590
591fn setDylibOrdinal(ordinal: i16, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
591fn setDylibOrdinal(ordinal: i16, bw: *Writer) Writer.Error!void {
592592 switch (ordinal) {
593593 else => unreachable, // Invalid dylib special binding
594594 macho.BIND_SPECIAL_DYLIB_SELF,
......@@ -610,18 +610,18 @@ fn setDylibOrdinal(ordinal: i16, bw: *std.io.BufferedWriter) std.io.Writer.Error
610610 }
611611}
612612
613fn setAddend(addend: i64, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
613fn setAddend(addend: i64, bw: *Writer) Writer.Error!void {
614614 log.debug(">>> set addend: {x}", .{addend});
615615 try bw.writeByte(macho.BIND_OPCODE_SET_ADDEND_SLEB);
616616 try bw.writeLeb128(addend);
617617}
618618
619fn doBind(bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
619fn doBind(bw: *Writer) Writer.Error!void {
620620 log.debug(">>> bind", .{});
621621 try bw.writeByte(macho.BIND_OPCODE_DO_BIND);
622622}
623623
624fn doBindAddAddr(addr: u64, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
624fn doBindAddAddr(addr: u64, bw: *Writer) Writer.Error!void {
625625 log.debug(">>> bind with add: {x}", .{addr});
626626 if (std.math.divExact(u64, addr, @sizeOf(u64))) |scaled| {
627627 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
632632 try bw.writeLeb128(addr);
633633}
634634
635fn doBindTimesSkip(count: usize, skip: u64, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
635fn doBindTimesSkip(count: usize, skip: u64, bw: *Writer) Writer.Error!void {
636636 log.debug(">>> bind with count: {d} and skip: {x}", .{ count, skip });
637637 try bw.writeByte(macho.BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB);
638638 try bw.writeLeb128(count);
639639 try bw.writeLeb128(skip);
640640}
641641
642fn addAddr(addr: u64, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
642fn addAddr(addr: u64, bw: *Writer) Writer.Error!void {
643643 log.debug(">>> add: {x}", .{addr});
644644 try bw.writeByte(macho.BIND_OPCODE_ADD_ADDR_ULEB);
645645 try bw.writeLeb128(addr);
646646}
647647
648fn done(bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
648fn done(bw: *Writer) Writer.Error!void {
649649 log.debug(">>> done", .{});
650650 try bw.writeByte(macho.BIND_OPCODE_DONE);
651651}
652652
653const std = @import("std");
653654const assert = std.debug.assert;
654655const leb = std.leb;
655656const log = std.log.scoped(.link_dyld_info);
656657const macho = std.macho;
657658const mem = std.mem;
658659const testing = std.testing;
659const trace = @import("../../../tracy.zig").trace;
660const std = @import("std");
660const Allocator = std.mem.Allocator;
661const Writer = std.io.Writer;
661662
662const Allocator = mem.Allocator;
663const trace = @import("../../../tracy.zig").trace;
663664const File = @import("../file.zig").File;
664665const MachO = @import("../../MachO.zig");
665666const Symbol = @import("../Symbol.zig");
src/link/MachO/eh_frame.zig+4-4
......@@ -103,7 +103,7 @@ pub const Cie = struct {
103103 macho_file: *MachO,
104104 };
105105
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 {
107107 _ = unused_fmt_string;
108108 const cie = ctx.cie;
109109 try bw.print("@{x} : size({x})", .{
......@@ -142,8 +142,7 @@ pub const Fde = struct {
142142 const object = fde.getObject(macho_file);
143143 const sect = object.sections.items(.header)[object.eh_frame_sect_index.?];
144144
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));
147146
148147 try br.discard(4);
149148 const cie_ptr = try br.takeInt(u32, .little);
......@@ -249,7 +248,7 @@ pub const Fde = struct {
249248 macho_file: *MachO,
250249 };
251250
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 {
253252 _ = unused_fmt_string;
254253 const fde = ctx.fde;
255254 const macho_file = ctx.macho_file;
......@@ -528,6 +527,7 @@ const math = std.math;
528527const mem = std.mem;
529528const std = @import("std");
530529const trace = @import("../../tracy.zig").trace;
530const Writer = std.io.Writer;
531531
532532const Allocator = std.mem.Allocator;
533533const Atom = @import("Atom.zig");
src/link/MachO/file.zig+3-2
......@@ -14,7 +14,7 @@ pub const File = union(enum) {
1414 return .{ .data = file };
1515 }
1616
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 {
1818 _ = unused_fmt_string;
1919 switch (file) {
2020 .zig_object => |zo| try bw.writeAll(zo.basename),
......@@ -322,7 +322,7 @@ pub const File = union(enum) {
322322 };
323323 }
324324
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 {
326326 return switch (file) {
327327 .dylib, .internal => unreachable,
328328 .zig_object => |x| x.writeAr(bw, ar_format),
......@@ -365,6 +365,7 @@ const log = std.log.scoped(.link);
365365const macho = std.macho;
366366const Allocator = std.mem.Allocator;
367367const Path = std.Build.Cache.Path;
368const Writer = std.io.Writer;
368369
369370const trace = @import("../../tracy.zig").trace;
370371const Archive = @import("Archive.zig");
src/link/MachO/load_commands.zig+6-5
......@@ -3,6 +3,7 @@ const assert = std.debug.assert;
33const log = std.log.scoped(.link);
44const macho = std.macho;
55const mem = std.mem;
6const Writer = std.io.Writer;
67
78const Allocator = mem.Allocator;
89const DebugSymbols = @import("DebugSymbols.zig");
......@@ -180,7 +181,7 @@ pub fn calcMinHeaderPadSize(macho_file: *MachO) !u32 {
180181 return offset;
181182}
182183
183pub fn writeDylinkerLC(bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
184pub fn writeDylinkerLC(bw: *Writer) Writer.Error!void {
184185 const name_len = mem.sliceTo(default_dyld_path, 0).len;
185186 const cmdsize = @as(u32, @intCast(mem.alignForward(
186187 u64,
......@@ -204,7 +205,7 @@ const WriteDylibLCCtx = struct {
204205 compatibility_version: u32 = 0x10000,
205206};
206207
207pub fn writeDylibLC(ctx: WriteDylibLCCtx, bw: *std.io.BufferedWriter) !void {
208pub fn writeDylibLC(ctx: WriteDylibLCCtx, bw: *Writer) !void {
208209 const name_len = ctx.name.len + 1;
209210 const cmdsize: u32 = @intCast(mem.alignForward(
210211 u64,
......@@ -252,7 +253,7 @@ pub fn writeDylibIdLC(macho_file: *MachO, writer: anytype) !void {
252253 }, writer);
253254}
254255
255pub fn writeRpathLC(bw: *std.io.BufferedWriter, rpath: []const u8) !void {
256pub fn writeRpathLC(bw: *Writer, rpath: []const u8) !void {
256257 const rpath_len = rpath.len + 1;
257258 const cmdsize = @as(u32, @intCast(mem.alignForward(
258259 u64,
......@@ -268,7 +269,7 @@ pub fn writeRpathLC(bw: *std.io.BufferedWriter, rpath: []const u8) !void {
268269 try bw.splatByteAll(0, cmdsize - @sizeOf(macho.rpath_command) - rpath_len);
269270}
270271
271pub fn writeVersionMinLC(bw: *std.io.BufferedWriter, platform: MachO.Platform, sdk_version: ?std.SemanticVersion) std.io.Writer.Error!void {
272pub fn writeVersionMinLC(bw: *Writer, platform: MachO.Platform, sdk_version: ?std.SemanticVersion) Writer.Error!void {
272273 const cmd: macho.LC = switch (platform.os_tag) {
273274 .macos => .VERSION_MIN_MACOSX,
274275 .ios => .VERSION_MIN_IPHONEOS,
......@@ -286,7 +287,7 @@ pub fn writeVersionMinLC(bw: *std.io.BufferedWriter, platform: MachO.Platform, s
286287 }));
287288}
288289
289pub fn writeBuildVersionLC(bw: *std.io.BufferedWriter, platform: MachO.Platform, sdk_version: ?std.SemanticVersion) std.io.Writer.Error!void {
290pub fn writeBuildVersionLC(bw: *Writer, platform: MachO.Platform, sdk_version: ?std.SemanticVersion) Writer.Error!void {
290291 const cmdsize = @sizeOf(macho.build_version_command) + @sizeOf(macho.build_tool_version);
291292 try bw.writeStruct(macho.build_version_command{
292293 .cmdsize = cmdsize,
src/link/MachO/relocatable.zig+3-4
......@@ -205,8 +205,7 @@ pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ?
205205 state_log.debug("ar_symtab\n{f}\n", .{ar_symtab.fmt(macho_file)});
206206 }
207207
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));
210209 defer gpa.free(bw.buffer);
211210
212211 // Write magic
......@@ -683,8 +682,7 @@ fn writeSectionsToFile(macho_file: *MachO) !void {
683682
684683fn writeLoadCommands(macho_file: *MachO) error{ LinkFailure, OutOfMemory }!struct { usize, usize } {
685684 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)));
688686 defer gpa.free(bw.buffer);
689687
690688 var ncmds: usize = 0;
......@@ -759,6 +757,7 @@ const macho = std.macho;
759757const math = std.math;
760758const mem = std.mem;
761759const state_log = std.log.scoped(.link_state);
760const Writer = std.io.Writer;
762761
763762const Archive = @import("Archive.zig");
764763const Atom = @import("Atom.zig");
src/link/MachO/synthetic.zig+17-16
......@@ -27,7 +27,7 @@ pub const GotSection = struct {
2727 return got.symbols.items.len * @sizeOf(u64);
2828 }
2929
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 {
3131 const tracy = trace(@src());
3232 defer tracy.end();
3333 for (got.symbols.items) |ref| {
......@@ -48,7 +48,7 @@ pub const GotSection = struct {
4848
4949 pub fn format2(
5050 ctx: FormatCtx,
51 bw: *std.io.BufferedWriter,
51 bw: *Writer,
5252 comptime unused_fmt_string: []const u8,
5353 ) !void {
5454 _ = unused_fmt_string;
......@@ -94,7 +94,7 @@ pub const StubsSection = struct {
9494 return stubs.symbols.items.len * header.reserved2;
9595 }
9696
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 {
9898 const tracy = trace(@src());
9999 defer tracy.end();
100100 const cpu_arch = macho_file.getTarget().cpu.arch;
......@@ -137,7 +137,7 @@ pub const StubsSection = struct {
137137
138138 pub fn format2(
139139 ctx: FormatCtx,
140 bw: *std.io.BufferedWriter,
140 bw: *Writer,
141141 comptime unused_fmt_string: []const u8,
142142 ) !void {
143143 _ = unused_fmt_string;
......@@ -185,7 +185,7 @@ pub const StubsHelperSection = struct {
185185 return s;
186186 }
187187
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 {
189189 const tracy = trace(@src());
190190 defer tracy.end();
191191
......@@ -230,7 +230,7 @@ pub const StubsHelperSection = struct {
230230 }
231231 }
232232
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 {
234234 _ = stubs_helper;
235235 const obj = macho_file.getInternalObject().?;
236236 const cpu_arch = macho_file.getTarget().cpu.arch;
......@@ -289,7 +289,7 @@ pub const LaSymbolPtrSection = struct {
289289 return macho_file.stubs.symbols.items.len * @sizeOf(u64);
290290 }
291291
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 {
293293 const tracy = trace(@src());
294294 defer tracy.end();
295295 _ = laptr;
......@@ -339,7 +339,7 @@ pub const TlvPtrSection = struct {
339339 return tlv.symbols.items.len * @sizeOf(u64);
340340 }
341341
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 {
343343 const tracy = trace(@src());
344344 defer tracy.end();
345345
......@@ -364,7 +364,7 @@ pub const TlvPtrSection = struct {
364364
365365 pub fn format2(
366366 ctx: FormatCtx,
367 bw: *std.io.BufferedWriter,
367 bw: *Writer,
368368 comptime unused_fmt_string: []const u8,
369369 ) !void {
370370 _ = unused_fmt_string;
......@@ -415,7 +415,7 @@ pub const ObjcStubsSection = struct {
415415 return objc.symbols.items.len * entrySize(macho_file.getTarget().cpu.arch);
416416 }
417417
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 {
419419 const tracy = trace(@src());
420420 defer tracy.end();
421421
......@@ -487,7 +487,7 @@ pub const ObjcStubsSection = struct {
487487
488488 pub fn format2(
489489 ctx: FormatCtx,
490 bw: *std.io.BufferedWriter,
490 bw: *Writer,
491491 comptime unused_fmt_string: []const u8,
492492 ) !void {
493493 _ = unused_fmt_string;
......@@ -516,7 +516,7 @@ pub const Indsymtab = struct {
516516 macho_file.dysymtab_cmd.nindirectsyms = ind.nsyms(macho_file);
517517 }
518518
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 {
520520 const tracy = trace(@src());
521521 defer tracy.end();
522522
......@@ -593,7 +593,7 @@ pub const DataInCode = struct {
593593 macho_file.data_in_code_cmd.datasize = math.cast(u32, dice.size()) orelse return error.Overflow;
594594 }
595595
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 {
597597 const base_address = if (!macho_file.base.isRelocatable())
598598 macho_file.getTextSegment().vmaddr
599599 else
......@@ -617,13 +617,14 @@ pub const DataInCode = struct {
617617 };
618618};
619619
620const std = @import("std");
620621const aarch64 = @import("../aarch64.zig");
621622const assert = std.debug.assert;
622623const macho = std.macho;
623624const math = std.math;
624const std = @import("std");
625const trace = @import("../../tracy.zig").trace;
626
627625const Allocator = std.mem.Allocator;
626const Writer = std.io.Writer;
627
628const trace = @import("../../tracy.zig").trace;
628629const MachO = @import("../MachO.zig");
629630const Symbol = @import("Symbol.zig");
src/link/Plan9.zig+27-27
......@@ -23,6 +23,7 @@ const Allocator = std.mem.Allocator;
2323const log = std.log.scoped(.link);
2424const assert = std.debug.assert;
2525const Path = std.Build.Cache.Path;
26const Writer = std.io.Writer;
2627
2728base: link.File,
2829sixtyfour_bit: bool,
......@@ -336,25 +337,24 @@ fn putFn(self: *Plan9, nav_index: InternPool.Nav.Index, out: FnNavOutput) !void
336337 };
337338 try fn_map_res.value_ptr.functions.put(gpa, nav_index, out);
338339
339 var aw: std.io.AllocatingWriter = undefined;
340 aw.init(arena);
340 var aw: std.io.AllocatingWriter = .init(arena);
341341 defer aw.deinit();
342 const bw = &aw.buffered_writer;
342 const w = &aw.interface;
343343
344344 // every 'z' starts with 0
345 try bw.writeByte(0);
345 try w.writeByte(0);
346346 // path component value of '/'
347 try bw.writeInt(u16, 1, .big);
347 try w.writeInt(u16, 1, .big);
348348
349349 // getting the full file path
350350 {
351351 const full_path = try file.path.toAbsolute(comp.dirs, gpa);
352352 defer gpa.free(full_path);
353 try self.addPathComponents(full_path, bw);
353 try self.addPathComponents(full_path, w);
354354 }
355355
356356 // null terminate
357 try bw.writeByte(0);
357 try w.writeByte(0);
358358 const final = try aw.toOwnedSlice();
359359 self.syms.items[fn_map_res.value_ptr.sym_index - 1] = .{
360360 .type = .z,
......@@ -370,17 +370,17 @@ fn putFn(self: *Plan9, nav_index: InternPool.Nav.Index, out: FnNavOutput) !void
370370 }
371371}
372372
373fn addPathComponents(self: *Plan9, path: []const u8, bw: *std.io.BufferedWriter) !void {
373fn addPathComponents(self: *Plan9, path: []const u8, w: *Writer) !void {
374374 const gpa = self.base.comp.gpa;
375375 const sep = std.fs.path.sep;
376376 var it = std.mem.tokenizeScalar(u8, path, sep);
377377 while (it.next()) |component| {
378378 if (self.file_segments.get(component)) |num| {
379 try bw.writeInt(u16, num, .big);
379 try w.writeInt(u16, num, .big);
380380 } else {
381381 self.file_segments_i += 1;
382382 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);
384384 }
385385 }
386386}
......@@ -527,14 +527,14 @@ fn allocateGotIndex(self: *Plan9) usize {
527527 }
528528}
529529
530pub fn changeLine(bw: *std.io.Writer, delta_line: i32) !void {
530pub fn changeLine(w: *std.io.Writer, delta_line: i32) !void {
531531 if (delta_line > 0 and delta_line < 65) {
532 try bw.writeByte(@intCast(delta_line));
532 try w.writeByte(@intCast(delta_line));
533533 } 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));
535535 } 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);
538538 }
539539}
540540
......@@ -1205,16 +1205,16 @@ pub fn writeSym(self: *Plan9, w: anytype, sym: aout.Sym) !void {
12051205 try w.writeByte(0);
12061206}
12071207
1208pub fn writeSyms(self: *Plan9, bw: *std.io.BufferedWriter) !void {
1208pub fn writeSyms(self: *Plan9, w: *Writer) !void {
12091209 const zcu = self.base.comp.zcu.?;
12101210 const ip = &zcu.intern_pool;
12111211 // write __GOT
1212 try self.writeSym(bw, self.syms.items[0]);
1212 try self.writeSym(w, self.syms.items[0]);
12131213 // write the f symbols
12141214 {
12151215 var it = self.file_segments.iterator();
12161216 while (it.next()) |entry| {
1217 try self.writeSym(bw, .{
1217 try self.writeSym(w, .{
12181218 .type = .f,
12191219 .value = entry.value_ptr.*,
12201220 .name = entry.key_ptr.*,
......@@ -1230,12 +1230,12 @@ pub fn writeSyms(self: *Plan9, bw: *std.io.BufferedWriter) !void {
12301230 const nav_metadata = self.navs.get(nav_index).?;
12311231 const atom = self.getAtom(nav_metadata.index);
12321232 const sym = self.syms.items[atom.sym_index.?];
1233 try self.writeSym(bw, sym);
1233 try self.writeSym(w, sym);
12341234 if (self.nav_exports.get(nav_index)) |export_indices| {
12351235 for (export_indices) |export_idx| {
12361236 const exp = export_idx.ptr(zcu);
12371237 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]);
12391239 }
12401240 }
12411241 }
......@@ -1248,7 +1248,7 @@ pub fn writeSyms(self: *Plan9, bw: *std.io.BufferedWriter) !void {
12481248 const meta = kv.value_ptr;
12491249 const data_atom = if (meta.rodata_state != .unused) self.getAtomPtr(meta.rodata_atom) else continue;
12501250 const sym = self.syms.items[data_atom.sym_index.?];
1251 try self.writeSym(bw, sym);
1251 try self.writeSym(w, sym);
12521252 }
12531253 }
12541254 // text symbols are the hardest:
......@@ -1259,8 +1259,8 @@ pub fn writeSyms(self: *Plan9, bw: *std.io.BufferedWriter) !void {
12591259 while (it_file.next()) |fentry| {
12601260 var symidx_and_submap = fentry.value_ptr;
12611261 // 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]);
12641264
12651265 // write all the decls come from the file of the z symbol
12661266 var submap_it = symidx_and_submap.functions.iterator();
......@@ -1269,7 +1269,7 @@ pub fn writeSyms(self: *Plan9, bw: *std.io.BufferedWriter) !void {
12691269 const nav_metadata = self.navs.get(nav_index).?;
12701270 const atom = self.getAtom(nav_metadata.index);
12711271 const sym = self.syms.items[atom.sym_index.?];
1272 try self.writeSym(bw, sym);
1272 try self.writeSym(w, sym);
12731273 if (self.nav_exports.get(nav_index)) |export_indices| {
12741274 for (export_indices) |export_idx| {
12751275 const exp = export_idx.ptr(zcu);
......@@ -1277,7 +1277,7 @@ pub fn writeSyms(self: *Plan9, bw: *std.io.BufferedWriter) !void {
12771277 const s = self.syms.items[exp_i];
12781278 if (mem.eql(u8, s.name, "_start"))
12791279 self.entry_val = s.value;
1280 try self.writeSym(bw, s);
1280 try self.writeSym(w, s);
12811281 }
12821282 }
12831283 }
......@@ -1290,7 +1290,7 @@ pub fn writeSyms(self: *Plan9, bw: *std.io.BufferedWriter) !void {
12901290 const meta = kv.value_ptr;
12911291 const text_atom = if (meta.text_state != .unused) self.getAtomPtr(meta.text_atom) else continue;
12921292 const sym = self.syms.items[text_atom.sym_index.?];
1293 try self.writeSym(bw, sym);
1293 try self.writeSym(w, sym);
12941294 }
12951295 }
12961296 }
......@@ -1299,7 +1299,7 @@ pub fn writeSyms(self: *Plan9, bw: *std.io.BufferedWriter) !void {
12991299 if (idx) |atom_idx| {
13001300 const atom = self.getAtom(atom_idx);
13011301 const sym = self.syms.items[atom.sym_index.?];
1302 try self.writeSym(bw, sym);
1302 try self.writeSym(w, sym);
13031303 }
13041304 }
13051305}
src/link/Wasm.zig+5-5
......@@ -28,6 +28,7 @@ const fs = std.fs;
2828const leb = std.leb;
2929const log = std.log.scoped(.link);
3030const mem = std.mem;
31const Writer = std.io.Writer;
3132
3233const Mir = @import("../arch/wasm/Mir.zig");
3334const CodeGen = @import("../arch/wasm/CodeGen.zig");
......@@ -2124,8 +2125,8 @@ pub const FunctionType = extern struct {
21242125 wasm: *const Wasm,
21252126 ft: FunctionType,
21262127
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);
21292130 const params = self.ft.params.slice(self.wasm);
21302131 const returns = self.ft.returns.slice(self.wasm);
21312132
......@@ -2904,7 +2905,7 @@ pub const Feature = packed struct(u8) {
29042905 @"=",
29052906 };
29062907
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 {
29082909 _ = fmt;
29092910 try bw.print("{s} {s}", .{ @tagName(feature.prefix), @tagName(feature.tag) });
29102911 }
......@@ -3037,8 +3038,7 @@ fn parseObject(wasm: *Wasm, obj: link.Input.Object) !void {
30373038 const stat = try obj.file.stat();
30383039 const size = std.math.cast(usize, stat.size) orelse return error.FileTooBig;
30393040
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));
30423042 defer gpa.free(br.storageBuffer());
30433043
30443044 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;
1818const mem = std.mem;
1919const log = std.log.scoped(.link);
2020const assert = std.debug.assert;
21const Writer = std.io.Writer;
2122
2223/// Ordered list of data segments that will appear in the final binary.
2324/// When sorted, to-be-merged segments will be made adjacent.
......@@ -557,11 +558,11 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
557558 var data_section_index: ?u32 = null;
558559
559560 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);
562562 defer f.binary_bytes = aw.toArrayList();
563 const w = &aw.interface;
563564
564 try bw.writeAll(&std.wasm.magic ++ &std.wasm.version);
565 try w.writeAll(&std.wasm.magic ++ &std.wasm.version);
565566
566567 // Type section.
567568 for (f.function_imports.values()) |id| {
......@@ -571,16 +572,16 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
571572 try f.func_types.put(gpa, function.typeIndex(wasm), {});
572573 }
573574 if (f.func_types.entries.len != 0) {
574 const header_offset = try reserveVecSectionHeader(bw);
575 const header_offset = try reserveVecSectionHeader(w);
575576 for (f.func_types.keys()) |func_type_index| {
576577 const func_type = func_type_index.ptr(wasm);
577 try bw.writeLeb128(std.wasm.function_type);
578 try w.writeLeb128(std.wasm.function_type);
578579 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));
581582 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));
584585 }
585586 replaceVecSectionHeader(&aw, header_offset, .type, @intCast(f.func_types.entries.len));
586587 section_index += 1;
......@@ -595,42 +596,42 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
595596 // Import section
596597 {
597598 var total_imports: usize = 0;
598 const header_offset = try reserveVecSectionHeader(bw);
599 const header_offset = try reserveVecSectionHeader(w);
599600
600601 for (f.function_imports.values()) |id| {
601602 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);
604605
605606 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);
608609
609 try bw.writeByte(@intFromEnum(std.wasm.ExternalKind.function));
610 try w.writeByte(@intFromEnum(std.wasm.ExternalKind.function));
610611 const type_index: FuncTypeIndex = .fromTypeIndex(id.functionType(wasm), f);
611 try bw.writeLeb128(@intFromEnum(type_index));
612 try w.writeLeb128(@intFromEnum(type_index));
612613 }
613614 total_imports += f.function_imports.entries.len;
614615
615616 for (wasm.table_imports.values()) |id| {
616617 const table_import = id.value(wasm);
617618 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);
620621
621622 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);
624625
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());
628629 }
629630 total_imports += wasm.table_imports.entries.len;
630631
631632 if (import_memory) {
632633 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, &.{
634635 // TODO the import_memory option needs to specify from which module
635636 .module_name = wasm.object_host_name.unwrap().?,
636637 .limits_min = wasm.memories.limits.min,
......@@ -644,17 +645,17 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
644645
645646 for (f.global_imports.values()) |id| {
646647 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);
649650
650651 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);
653654
654 try bw.writeByte(@intFromEnum(std.wasm.ExternalKind.global));
655 try w.writeByte(@intFromEnum(std.wasm.ExternalKind.global));
655656 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));
658659 }
659660 total_imports += f.global_imports.entries.len;
660661
......@@ -668,10 +669,10 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
668669
669670 // Function section
670671 if (wasm.functions.count() != 0) {
671 const header_offset = try reserveVecSectionHeader(bw);
672 const header_offset = try reserveVecSectionHeader(w);
672673 for (wasm.functions.keys()) |function| {
673674 const index: FuncTypeIndex = .fromTypeIndex(function.typeIndex(wasm), f);
674 try bw.writeLeb128(@intFromEnum(index));
675 try w.writeLeb128(@intFromEnum(index));
675676 }
676677
677678 replaceVecSectionHeader(&aw, header_offset, .function, @intCast(wasm.functions.count()));
......@@ -680,11 +681,11 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
680681
681682 // Table section
682683 if (wasm.tables.entries.len > 0) {
683 const header_offset = try reserveVecSectionHeader(bw);
684 const header_offset = try reserveVecSectionHeader(w);
684685
685686 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));
688689 }
689690
690691 replaceVecSectionHeader(&aw, header_offset, .table, @intCast(wasm.tables.entries.len));
......@@ -693,8 +694,8 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
693694
694695 // Memory section. wasm currently only supports 1 linear memory segment.
695696 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);
698699 replaceVecSectionHeader(&aw, header_offset, .memory, 1);
699700 section_index += 1;
700701 }
......@@ -702,24 +703,24 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
702703 // Global section.
703704 const globals_len: u32 = @intCast(wasm.globals.entries.len);
704705 if (globals_len > 0) {
705 const header_offset = try reserveVecSectionHeader(bw);
706 const header_offset = try reserveVecSectionHeader(w);
706707
707708 for (wasm.globals.keys()) |global_resolution| {
708709 switch (global_resolution.unpack(wasm)) {
709710 .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.?),
716717 .object_global => |i| {
717718 const global = i.ptr(wasm);
718 try bw.writeAll(&.{
719 try w.writeAll(&.{
719720 @intFromEnum(@as(std.wasm.Valtype, global.flags.global_type.valtype.to())),
720721 @intFromBool(global.flags.global_type.mutable),
721722 });
722 try emitExpr(wasm, bw, global.expr);
723 try emitExpr(wasm, w, global.expr);
723724 },
724725 .nav_exe => unreachable, // Zig source code currently cannot represent this.
725726 .nav_obj => unreachable, // Zig source code currently cannot represent this.
......@@ -732,44 +733,44 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
732733
733734 // Export section
734735 {
735 const header_offset = try reserveVecSectionHeader(bw);
736 const header_offset = try reserveVecSectionHeader(w);
736737 var exports_len: usize = 0;
737738
738739 for (wasm.function_exports.keys(), wasm.function_exports.values()) |exp_name, function_index| {
739740 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));
743744 const func_index = Wasm.OutputFunctionIndex.fromFunctionIndex(wasm, function_index);
744 try bw.writeLeb128(@intFromEnum(func_index));
745 try w.writeLeb128(@intFromEnum(func_index));
745746 }
746747 exports_len += wasm.function_exports.entries.len;
747748
748749 if (wasm.export_table and f.indirect_function_table.entries.len > 0) {
749750 const name = "__indirect_function_table";
750751 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);
755756 exports_len += 1;
756757 }
757758
758759 if (export_memory) {
759760 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);
764765 exports_len += 1;
765766 }
766767
767768 for (wasm.global_exports.items) |exp| {
768769 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));
773774 }
774775 exports_len += wasm.global_exports.items.len;
775776
......@@ -790,19 +791,19 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
790791
791792 // element section
792793 if (f.indirect_function_table.entries.len > 0) {
793 const header_offset = try reserveVecSectionHeader(bw);
794 const header_offset = try reserveVecSectionHeader(w);
794795
795796 // indirect function table elements
796797 const table_index: u32 = @intCast(wasm.tables.getIndex(.__indirect_function_table).?);
797798 // passive with implicit 0-index table or set table index manually
798799 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);
801802 // 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));
806807
807808 replaceVecSectionHeader(&aw, header_offset, .element, 1);
808809 section_index += 1;
......@@ -810,42 +811,42 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
810811
811812 // When the shared-memory option is enabled, we *must* emit the 'data count' section.
812813 if (f.data_segment_groups.items.len > 0) {
813 const header_offset = try reserveVecSectionHeader(bw);
814 const header_offset = try reserveVecSectionHeader(w);
814815 replaceVecSectionHeader(&aw, header_offset, .data_count, @intCast(f.data_segment_groups.items.len));
815816 }
816817
817818 // Code section.
818819 if (wasm.functions.count() != 0) {
819 const header_offset = try reserveVecSectionHeader(bw);
820 const header_offset = try reserveVecSectionHeader(w);
820821
821822 for (wasm.functions.keys()) |resolution| switch (resolution.unpack(wasm)) {
822823 .unresolved => unreachable,
823824 .__wasm_apply_global_tls_relocs => @panic("TODO lower __wasm_apply_global_tls_relocs"),
824825 .__wasm_call_ctors => {
825 const code_start = try reserveSizeHeader(bw);
826 const code_start = try reserveSizeHeader(w);
826827 defer replaceSizeHeader(&aw, code_start);
827 try emitCallCtorsFunction(wasm, bw);
828 try emitCallCtorsFunction(wasm, w);
828829 },
829830 .__wasm_init_memory => {
830 const code_start = try reserveSizeHeader(bw);
831 const code_start = try reserveSizeHeader(w);
831832 defer replaceSizeHeader(&aw, code_start);
832 try emitInitMemoryFunction(wasm, bw, &virtual_addrs);
833 try emitInitMemoryFunction(wasm, w, &virtual_addrs);
833834 },
834835 .__wasm_init_tls => {
835 const code_start = try reserveSizeHeader(bw);
836 const code_start = try reserveSizeHeader(w);
836837 defer replaceSizeHeader(&aw, code_start);
837 try emitInitTlsFunction(wasm, bw);
838 try emitInitTlsFunction(wasm, w);
838839 },
839840 .object_function => |i| {
840841 const ptr = i.ptr(wasm);
841842 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);
845846 if (!is_obj) applyRelocs(aw.getWritten()[code_start..], ptr.offset, ptr.relocations(wasm), wasm);
846847 },
847848 .zcu_func => |i| {
848 const code_start = try reserveSizeHeader(bw);
849 const code_start = try reserveSizeHeader(w);
849850 defer replaceSizeHeader(&aw, code_start);
850851
851852 log.debug("lowering function code for '{s}'", .{resolution.name(wasm).?});
......@@ -855,7 +856,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
855856 const ip_index = i.key(wasm).*;
856857 switch (ip.indexToKey(ip_index)) {
857858 .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);
859860 },
860861 else => {
861862 const func = i.value(wasm).function;
......@@ -870,7 +871,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
870871 .func_tys = undefined,
871872 .error_name_table_ref_count = undefined,
872873 };
873 try mir.lower(wasm, bw);
874 try mir.lower(wasm, w);
874875 },
875876 }
876877 },
......@@ -912,7 +913,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
912913
913914 // Data section.
914915 if (f.data_segment_groups.items.len != 0) {
915 const header_offset = try reserveVecSectionHeader(bw);
916 const header_offset = try reserveVecSectionHeader(w);
916917
917918 var group_index: u32 = 0;
918919 var segment_offset: u32 = 0;
......@@ -920,7 +921,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
920921 var group_end_addr = f.data_segment_groups.items[group_index].end_addr;
921922 for (segment_ids, segment_vaddrs) |segment_id, segment_vaddr| {
922923 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);
924925 group_index += 1;
925926 if (group_index >= f.data_segment_groups.items.len) {
926927 // All remaining segments are zero.
......@@ -934,10 +935,10 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
934935 const group_size = group_end_addr - group_start_addr;
935936 log.debug("emit data section group, {d} bytes", .{group_size});
936937 const flags: Object.DataSegmentFlags = if (segment_id.isPassive(wasm)) .passive else .active;
937 try bw.writeLeb128(@intFromEnum(flags));
938 try w.writeLeb128(@intFromEnum(flags));
938939 // 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);
941942 }
942943 if (segment_id.isEmpty(wasm)) {
943944 // 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 {
946947
947948 // Padding for alignment.
948949 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);
950951 segment_offset = needed_offset;
951952
952 const code_start = bw.count;
953 const code_start = w.count;
953954 append: {
954955 const code = switch (segment_id.unpack(wasm)) {
955956 .__heap_base => {
956 try bw.writeInt(u32, virtual_addrs.heap_base, .little);
957 try w.writeInt(u32, virtual_addrs.heap_base, .little);
957958 break :append;
958959 },
959960 .__heap_end => {
960 try bw.writeInt(u32, virtual_addrs.heap_end, .little);
961 try w.writeInt(u32, virtual_addrs.heap_end, .little);
961962 break :append;
962963 },
963964 .__zig_error_names => {
964 try bw.writeAll(wasm.error_name_bytes.items);
965 try w.writeAll(wasm.error_name_bytes.items);
965966 break :append;
966967 },
967968 .__zig_error_name_table => {
968969 if (is_obj) @panic("TODO error name table reloc");
969970 const base = f.data_segments.get(.__zig_error_names).?;
970971 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);
972973 } 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);
974975 }
975976 break :append;
976977 },
977978 .__zig_tag_names => {
978 try bw.writeAll(wasm.tag_name_bytes.items);
979 try w.writeAll(wasm.tag_name_bytes.items);
979980 break :append;
980981 },
981982 .__zig_tag_name_table => {
982983 if (is_obj) @panic("TODO tag name table reloc");
983984 const base = f.data_segments.get(.__zig_tag_names).?;
984985 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);
986987 } 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);
988989 }
989990 break :append;
990991 },
991992 .object => |i| {
992993 const ptr = i.ptr(wasm);
993 try bw.writeAll(ptr.payload.slice(wasm));
994 try w.writeAll(ptr.payload.slice(wasm));
994995 if (!is_obj) applyRelocs(aw.getWritten()[code_start..], ptr.offset, ptr.relocations(wasm), wasm);
995996 break :append;
996997 },
997998 inline .uav_exe, .uav_obj, .nav_exe, .nav_obj => |i| i.value(wasm).code,
998999 };
999 try bw.writeAll(code.slice(wasm));
1000 try w.writeAll(code.slice(wasm));
10001001 }
1001 segment_offset += @intCast(bw.count - code_start);
1002 segment_offset += @intCast(w.count - code_start);
10021003 }
10031004
10041005 replaceVecSectionHeader(&aw, header_offset, .data, @intCast(f.data_segment_groups.items.len));
......@@ -1019,7 +1020,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
10191020 .none => {},
10201021 .fast => {
10211022 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, .{});
10231024 var uuid: [36]u8 = undefined;
10241025 _ = try std.fmt.bufPrint(&uuid, "{x}-{x}-{x}-{x}-{x}", .{
10251026 id[0..4], id[4..6], id[6..8], id[8..10], id[10..],
......@@ -1067,62 +1068,62 @@ fn emitNameSection(
10671068 data_segment_groups: []const DataSegmentGroup,
10681069) !void {
10691070 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);
10721073 defer replaceSectionHeader(aw, header_offset, @intFromEnum(std.wasm.Section.custom));
10731074
10741075 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);
10771078
10781079 {
1079 const sub_header_offset = try reserveSectionHeader(bw);
1080 const sub_header_offset = try reserveSectionHeader(w);
10801081 defer replaceSectionHeader(aw, sub_header_offset, @intFromEnum(std.wasm.NameSubsection.function));
10811082
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);
10831084 for (f.function_imports.keys(), 0..) |name_index, function_index| {
10841085 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);
10881089 }
10891090 for (wasm.functions.keys(), f.function_imports.entries.len..) |resolution, function_index| {
10901091 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);
10941095 }
10951096 }
10961097
10971098 {
1098 const sub_header_offset = try reserveSectionHeader(bw);
1099 const sub_header_offset = try reserveSectionHeader(w);
10991100 defer replaceSectionHeader(aw, sub_header_offset, @intFromEnum(std.wasm.NameSubsection.global));
11001101
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);
11021103 for (f.global_imports.keys(), 0..) |name_index, global_index| {
11031104 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);
11071108 }
11081109 for (wasm.globals.keys(), f.global_imports.entries.len..) |resolution, global_index| {
11091110 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);
11131114 }
11141115 }
11151116
11161117 {
1117 const sub_header_offset = try reserveSectionHeader(bw);
1118 const sub_header_offset = try reserveSectionHeader(w);
11181119 defer replaceSectionHeader(aw, sub_header_offset, @intFromEnum(std.wasm.NameSubsection.data_segment));
11191120
1120 try bw.writeLeb128(data_segment_groups.len);
1121 try w.writeLeb128(data_segment_groups.len);
11211122 for (data_segment_groups, 0..) |group, group_index| {
11221123 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);
11261127 }
11271128 }
11281129}
......@@ -1131,87 +1132,87 @@ fn emitFeaturesSection(aw: *std.io.AllocatingWriter, target: *const std.Target)
11311132 const feature_count = target.cpu.features.count();
11321133 if (feature_count == 0) return;
11331134
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);
11361137 defer replaceSectionHeader(aw, header_offset, @intFromEnum(std.wasm.Section.custom));
11371138
11381139 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);
11411142
1142 try bw.writeLeb128(feature_count);
1143 try w.writeLeb128(feature_count);
11431144 var safety_count = feature_count;
11441145 for (target.cpu.arch.allFeaturesList(), 0..) |*feature, i| {
11451146 if (!target.cpu.has(.wasm, @as(std.Target.wasm.Feature, @enumFromInt(i)))) continue;
11461147 safety_count -= 1;
11471148
1148 try bw.writeUleb128('+');
1149 try w.writeUleb128('+');
11491150 // Depends on llvm_name for the hyphenated version that matches wasm tooling conventions.
11501151 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);
11531154 }
11541155 assert(safety_count == 0);
11551156}
11561157
11571158fn 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);
11601161 defer replaceSectionHeader(aw, header_offset, @intFromEnum(std.wasm.Section.custom));
11611162
11621163 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);
11651166
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);
11691170}
11701171
11711172fn 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);
11741175 defer replaceSectionHeader(aw, header_offset, @intFromEnum(std.wasm.Section.custom));
11751176
11761177 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);
11791180
1180 try bw.writeUleb128(2); // 2 fields: language + processed-by
1181 try w.writeUleb128(2); // 2 fields: language + processed-by
11811182 {
11821183 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);
11851186
11861187 // field_value_count (TODO: Parse object files for producer sections to detect their language)
1187 try bw.writeUleb128(1);
1188 try w.writeUleb128(1);
11881189
11891190 // versioned name
11901191 {
11911192 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);
11941195
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);
11971198 }
11981199 }
11991200 {
12001201 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);
12031204
12041205 // 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);
12061207
12071208 // versioned name
12081209 {
12091210 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);
12121213
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);
12151216 }
12161217 }
12171218}
......@@ -1251,9 +1252,9 @@ fn wantSegmentMerge(
12511252/// section id + fixed leb contents size + fixed leb vector length
12521253const vec_section_header_size = section_header_size + size_header_size;
12531254
1254fn reserveVecSectionHeader(bw: *std.io.BufferedWriter) std.io.Writer.Error!u32 {
1255 const offset = bw.count;
1256 _ = try bw.writableSlice(vec_section_header_size);
1255fn reserveVecSectionHeader(w: *Writer) Writer.Error!u32 {
1256 const offset = w.count;
1257 _ = try w.writableSlice(vec_section_header_size);
12571258 return @intCast(offset);
12581259}
12591260
......@@ -1265,68 +1266,68 @@ fn replaceVecSectionHeader(
12651266) void {
12661267 const header = aw.getWritten()[offset..][0..vec_section_header_size];
12671268 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));
12691270 std.leb.writeUnsignedFixed(5, header[6..], n_items);
12701271}
12711272
12721273const section_header_size = 1 + size_header_size;
12731274
1274fn reserveSectionHeader(bw: *std.io.BufferedWriter) std.io.Writer.Error!u32 {
1275 const offset = bw.count;
1276 _ = try bw.writableSlice(section_header_size);
1275fn reserveSectionHeader(w: *Writer) Writer.Error!u32 {
1276 const offset = w.count;
1277 _ = try w.writableSlice(section_header_size);
12771278 return @intCast(offset);
12781279}
12791280
12801281fn replaceSectionHeader(aw: *std.io.AllocatingWriter, offset: u32, section: u8) void {
12811282 const header = aw.getWritten()[offset..][0..section_header_size];
12821283 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));
12841285}
12851286
12861287const size_header_size = 5;
12871288
1288fn reserveSizeHeader(bw: *std.io.BufferedWriter) std.io.Writer.Error!u32 {
1289 const offset = bw.count;
1290 _ = try bw.writableSlice(size_header_size);
1289fn reserveSizeHeader(w: *Writer) Writer.Error!u32 {
1290 const offset = w.count;
1291 _ = try w.writableSlice(size_header_size);
12911292 return @intCast(offset);
12921293}
12931294
12941295fn replaceSizeHeader(aw: *std.io.AllocatingWriter, offset: u32) void {
12951296 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));
12971298}
12981299
1299fn 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);
1300fn 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);
13031304}
13041305
13051306fn emitMemoryImport(
13061307 wasm: *Wasm,
1307 bw: *std.io.BufferedWriter,
1308 w: *Writer,
13081309 name_index: String,
13091310 memory_import: *const Wasm.MemoryImport,
1310) std.io.Writer.Error!void {
1311) Writer.Error!void {
13111312 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);
13141315
13151316 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);
13181319
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());
13211322}
13221323
1323pub fn emitInit(bw: *std.io.BufferedWriter, init_expr: std.wasm.InitExpression) std.io.Writer.Error!void {
1324pub fn emitInit(w: *Writer, init_expr: std.wasm.InitExpression) Writer.Error!void {
13241325 switch (init_expr) {
13251326 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))));
13271328 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(
13301331 @Type(.{ .int = .{ .signedness = .unsigned, .bits = float.bits } }),
13311332 @bitCast(val),
13321333 .little,
......@@ -1335,44 +1336,44 @@ pub fn emitInit(bw: *std.io.BufferedWriter, init_expr: std.wasm.InitExpression)
13351336 }
13361337 },
13371338 }
1338 try bw.writeByte(@intFromEnum(std.wasm.Opcode.end));
1339 try w.writeByte(@intFromEnum(std.wasm.Opcode.end));
13391340}
13401341
1341pub fn emitExpr(wasm: *const Wasm, bw: *std.io.BufferedWriter, expr: Wasm.Expr) std.io.Writer.Error!void {
1342pub fn emitExpr(wasm: *const Wasm, w: *Writer, expr: Wasm.Expr) Writer.Error!void {
13421343 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
13441345}
13451346
1346fn 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);
1347fn emitSegmentInfo(wasm: *Wasm, aw: *Writer) Writer.Error!void {
1348 const w = &aw.interface;
1349 const header_offset = try reserveSectionHeader(w);
13491350 defer replaceSectionHeader(aw, header_offset, @intFromEnum(Wasm.SubsectionType.segment_info));
13501351
1351 try bw.writeLeb128(wasm.segment_info.count());
1352 try w.writeLeb128(wasm.segment_info.count());
13521353 for (wasm.segment_info.values()) |segment_info| {
13531354 log.debug("Emit segment: {s} align({d}) flags({b})", .{
13541355 segment_info.name,
13551356 segment_info.alignment,
13561357 segment_info.flags,
13571358 });
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);
13621363 }
13631364}
13641365
13651366fn emitTagNameTable(
1366 bw: *std.io.BufferedWriter,
1367 w: *Writer,
13671368 tag_name_offs: []const u32,
13681369 tag_name_bytes: []const u8,
13691370 base: u32,
13701371 comptime Int: type,
1371) std.io.Writer.Error!void {
1372) Writer.Error!void {
13721373 for (tag_name_offs) |off| {
13731374 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);
13761377 }
13771378}
13781379
......@@ -1536,8 +1537,8 @@ fn reloc_leb_type(code: []u8, index: FuncTypeIndex) void {
15361537 std.leb.writeUnsignedFixed(5, code[0..5], @intFromEnum(index));
15371538}
15381539
1539fn emitCallCtorsFunction(wasm: *const Wasm, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
1540 try bw.writeUleb128(0); // no locals
1540fn emitCallCtorsFunction(wasm: *const Wasm, w: *Writer) Writer.Error!void {
1541 try w.writeUleb128(0); // no locals
15411542 for (wasm.object_init_funcs.items) |init_func| {
15421543 const func = init_func.function_index.ptr(wasm);
15431544 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
15461547
15471548 // Call function by its function index
15481549 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));
15511552
15521553 // 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);
15541555 }
1555 try bw.writeByte(@intFromEnum(std.wasm.Opcode.end)); // end function body
1556 try w.writeByte(@intFromEnum(std.wasm.Opcode.end)); // end function body
15561557}
15571558
1558fn emitInitMemoryFunction(wasm: *const Wasm, bw: *std.io.BufferedWriter, virtual_addrs: *const VirtualAddrs) std.io.Writer.Error!void {
1559fn emitInitMemoryFunction(wasm: *const Wasm, w: *Writer, virtual_addrs: *const VirtualAddrs) Writer.Error!void {
15591560 const comp = wasm.base.comp;
15601561 const shared_memory = comp.config.shared_memory;
15611562
......@@ -1566,13 +1567,13 @@ fn emitInitMemoryFunction(wasm: *const Wasm, bw: *std.io.BufferedWriter, virtual
15661567 // function.
15671568 assert(wasm.any_passive_inits);
15681569
1569 try bw.writeUleb128(0); // no locals
1570 try w.writeUleb128(0); // no locals
15701571
15711572 if (virtual_addrs.init_memory_flag) |flag_address| {
15721573 assert(shared_memory);
15731574 // destination blocks
15741575 // based on values we jump to corresponding label
1575 try bw.writeAll(&.{
1576 try w.writeAll(&.{
15761577 @intFromEnum(std.wasm.Opcode.block), // $drop
15771578 @intFromEnum(std.wasm.BlockType.empty),
15781579 @intFromEnum(std.wasm.Opcode.block), // $wait
......@@ -1582,24 +1583,24 @@ fn emitInitMemoryFunction(wasm: *const Wasm, bw: *std.io.BufferedWriter, virtual
15821583 });
15831584
15841585 // 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
15951596
15961597 // 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));
16031604 }
16041605
16051606 const segment_groups = wasm.flush_buffer.data_segment_groups.items;
......@@ -1615,79 +1616,79 @@ fn emitInitMemoryFunction(wasm: *const Wasm, bw: *std.io.BufferedWriter, virtual
16151616 // For passive BSS segments we can simply issue a memory.fill(0). For
16161617 // non-BSS segments we do a memory.init. Both instructions take as
16171618 // 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)));
16201621
16211622 if (shared_memory and segment.isTls(wasm)) {
16221623 // When we initialize the TLS segment we also set the `__tls_base`
16231624 // global. This allows the runtime to use this static copy of the
16241625 // 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.?);
16291630 }
16301631
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));
16361637 if (segment.isBss(wasm)) {
16371638 // 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));
16391640 } else {
16401641 // 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);
16431644 }
1644 try bw.writeByte(0); // memory index immediate
1645 try w.writeByte(0); // memory index immediate
16451646 }
16461647
16471648 if (virtual_addrs.init_memory_flag) |flag_address| {
16481649 assert(shared_memory);
16491650
16501651 // 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
16591660
16601661 // 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
16651666
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));
16711672
16721673 // 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);
16751676
16761677 // 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
16911692 }
16921693
16931694 for (segment_groups, 0..) |group, segment_index| {
......@@ -1698,20 +1699,20 @@ fn emitInitMemoryFunction(wasm: *const Wasm, bw: *std.io.BufferedWriter, virtual
16981699 // during the initialization of each thread (__wasm_init_tls).
16991700 if (shared_memory and segment.isTls(wasm)) continue;
17001701
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);
17041705 }
17051706
17061707 // End of the function body
1707 try bw.writeByte(@intFromEnum(std.wasm.Opcode.end));
1708 try w.writeByte(@intFromEnum(std.wasm.Opcode.end));
17081709}
17091710
1710fn emitInitTlsFunction(wasm: *const Wasm, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
1711fn emitInitTlsFunction(wasm: *const Wasm, w: *Writer) Writer.Error!void {
17111712 const comp = wasm.base.comp;
17121713 assert(comp.config.shared_memory);
17131714
1714 try bw.writeUleb128(0); // no locals
1715 try w.writeUleb128(0); // no locals
17151716
17161717 // If there's a TLS segment, initialize it during runtime using the bulk-memory feature
17171718 // 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
17241725
17251726 const param_local: u32 = 0;
17261727
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);
17291730
17301731 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));
17331734
17341735 // load stack values for the bulk-memory operation
17351736 {
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);
17381739
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
17411742
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
17441745 }
17451746
17461747 // 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));
17491750 // 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
17521753 }
17531754
17541755 // 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
17561757 // generated by the linker.
17571758 if (wasm.functions.getIndex(.__wasm_apply_global_tls_relocs)) |function_index| {
17581759 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));
17611762 }
17621763
1763 try bw.writeByte(@intFromEnum(std.wasm.Opcode.end));
1764 try w.writeByte(@intFromEnum(std.wasm.Opcode.end));
17641765}
17651766
17661767fn 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);
17681769 defer replaceVecSectionHeader(aw, header_offset, .start, @intFromEnum(i));
17691770}
17701771
17711772fn emitTagNameFunction(
17721773 wasm: *Wasm,
1773 bw: *std.io.BufferedWriter,
1774 w: *Writer,
17741775 table_base_addr: u32,
17751776 table_index: u32,
17761777 enum_type_ip: InternPool.Index,
......@@ -1782,33 +1783,33 @@ fn emitTagNameFunction(
17821783 const enum_type = ip.loadEnumType(enum_type_ip);
17831784 const tag_values = enum_type.values.get(ip);
17841785
1785 try bw.writeUleb128(0); // no locals
1786 try w.writeUleb128(0); // no locals
17861787
17871788 const slice_abi_size: u32 = 8;
17881789 if (tag_values.len == 0) {
17891790 // 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);
17921793
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);
17951796
1796 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const));
1797 try w.writeByte(@intFromEnum(std.wasm.Opcode.i32_const));
17971798 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));
18001801 } 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));
18031804 }
18041805
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);
18081809
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);
18121813 } else {
18131814 const int_info = Zcu.Type.intInfo(.fromInterned(enum_type.tag_ty), zcu);
18141815 const outer_block_type: std.wasm.BlockType = switch (int_info.bits) {
......@@ -1817,80 +1818,80 @@ fn emitTagNameFunction(
18171818 else => return diags.fail("wasm linker does not yet implement @tagName for sparse enums with more than 64 bit integer tag types", .{}),
18181819 };
18191820
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);
18221823
18231824 // 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));
18261827
18271828 for (tag_values, 0..) |tag_value, tag_index| {
18281829 // 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));
18311832
18321833 // 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);
18351836
18361837 const val: Zcu.Value = .fromInterned(tag_value);
18371838 switch (outer_block_type) {
18381839 .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) {
18411842 .signed => @intCast(val.toSignedInt(zcu)),
18421843 .unsigned => @bitCast(@as(u32, @intCast(val.toUnsignedInt(zcu)))),
18431844 }));
1844 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_ne));
1845 try w.writeByte(@intFromEnum(std.wasm.Opcode.i32_ne));
18451846 },
18461847 .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) {
18491850 .signed => val.toSignedInt(zcu),
18501851 .unsigned => @bitCast(val.toUnsignedInt(zcu)),
18511852 }));
1852 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i64_ne));
1853 try w.writeByte(@intFromEnum(std.wasm.Opcode.i64_ne));
18531854 },
18541855 else => unreachable,
18551856 }
18561857
18571858 // 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);
18601861
18611862 // 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)))));
18641865
18651866 // 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);
18681869
18691870 // end the block for this case
1870 try bw.writeByte(@intFromEnum(std.wasm.Opcode.end));
1871 try w.writeByte(@intFromEnum(std.wasm.Opcode.end));
18711872 }
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));
18741875
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);
18781879
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);
18821883 }
18831884
18841885 // End of the function body
1885 try bw.writeByte(@intFromEnum(std.wasm.Opcode.end));
1886 try w.writeByte(@intFromEnum(std.wasm.Opcode.end));
18861887}
18871888
1888fn appendGlobal(bw: *std.io.BufferedWriter, mutable: bool, val: u32) std.io.Writer.Error!void {
1889 try bw.writeAll(&.{
1889fn appendGlobal(w: *Writer, mutable: bool, val: u32) Writer.Error!void {
1890 try w.writeAll(&.{
18901891 @intFromEnum(std.wasm.Valtype.i32),
18911892 @intFromBool(mutable),
18921893 @intFromEnum(std.wasm.Opcode.i32_const),
18931894 });
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));
18961897}
src/link/riscv.zig+7-6
......@@ -1,4 +1,4 @@
1pub fn writeSetSub6(comptime op: enum { set, sub }, addend: anytype, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
1pub fn writeSetSub6(comptime op: enum { set, sub }, addend: anytype, bw: *Writer) Writer.Error!void {
22 const mask: u8 = 0b11_000000;
33 const actual: i8 = @truncate(addend);
44 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
99 try bw.writeByte(new_value);
1010}
1111
12pub fn writeSetSubUleb(comptime op: enum { set, sub }, addend: i64, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
12pub fn writeSetSubUleb(comptime op: enum { set, sub }, addend: i64, bw: *Writer) Writer.Error!void {
1313 switch (op) {
1414 .set => try overwriteUleb(@intCast(addend), bw),
1515 .sub => {
......@@ -20,7 +20,7 @@ pub fn writeSetSubUleb(comptime op: enum { set, sub }, addend: i64, bw: *std.io.
2020 }
2121}
2222
23fn overwriteUleb(new_value: u64, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
23fn overwriteUleb(new_value: u64, bw: *Writer) Writer.Error!void {
2424 var value: u64 = new_value;
2525 while (true) {
2626 const byte = (try bw.writableArray(1))[0];
......@@ -34,8 +34,8 @@ pub fn writeAddend(
3434 comptime Int: type,
3535 comptime op: enum { add, sub },
3636 value: anytype,
37 bw: *std.io.BufferedWriter,
38) std.io.Writer.Error!void {
37 bw: *Writer,
38) Writer.Error!void {
3939 const n = @divExact(@bitSizeOf(Int), 8);
4040 var V: Int = mem.readInt(Int, (try bw.writableSliceGreedy(n))[0..n], .little);
4141 const addend: Int = @truncate(value);
......@@ -108,8 +108,9 @@ pub const Eflags = packed struct(u32) {
108108 };
109109};
110110
111const mem = std.mem;
112111const std = @import("std");
112const mem = std.mem;
113const Writer = std.io.Writer;
113114
114115const encoding = @import("../arch/riscv64/encoding.zig");
115116const Instruction = encoding.Instruction;
src/link/table_section.zig+2-1
......@@ -39,7 +39,7 @@ pub fn TableSection(comptime Entry: type) type {
3939 return self.entries.items.len;
4040 }
4141
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 {
4343 comptime assert(unused_format_string.len == 0);
4444 try bw.writeAll("TableSection:\n");
4545 for (self.entries.items, 0..) |entry, i| {
......@@ -57,3 +57,4 @@ const assert = std.debug.assert;
5757const log = std.log.scoped(.link);
5858
5959const Allocator = std.mem.Allocator;
60const Writer = std.io.Writer;
src/print_env.zig+5-4
......@@ -22,8 +22,9 @@ pub fn cmdEnv(arena: Allocator, args: []const []const u8) !void {
2222 const triple = try host.zigTriple(arena);
2323
2424 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 } };
2728
2829 try jws.beginObject();
2930
......@@ -54,7 +55,7 @@ pub fn cmdEnv(arena: Allocator, args: []const []const u8) !void {
5455 try jws.endObject();
5556
5657 try jws.endObject();
57 try bw.writeByte('\n');
58 try w.writeByte('\n');
5859
59 try bw.flush();
60 try w.flush();
6061}
src/print_targets.zig+2-1
......@@ -10,6 +10,7 @@ const target = @import("target.zig");
1010const assert = std.debug.assert;
1111const glibc = @import("libs/glibc.zig");
1212const introspect = @import("introspect.zig");
13const Writer = std.io.Writer;
1314
1415pub fn cmdTargets(arena: Allocator, args: []const []const u8) !void {
1516 _ = args;
......@@ -20,7 +21,7 @@ pub fn cmdTargets(arena: Allocator, args: []const []const u8) !void {
2021 try bw.flush();
2122}
2223
23fn print(arena: Allocator, output: *std.io.BufferedWriter, host: *const Target) std.io.Writer.Error!void {
24fn print(arena: Allocator, output: *Writer, host: *const Target) Writer.Error!void {
2425 var zig_lib_directory = introspect.findZigLibDir(arena) catch |err| {
2526 fatal("unable to find zig installation directory: {s}\n", .{@errorName(err)});
2627 };
src/print_value.zig+7-6
......@@ -9,6 +9,7 @@ const Sema = @import("Sema.zig");
99const InternPool = @import("InternPool.zig");
1010const Allocator = std.mem.Allocator;
1111const Target = std.Target;
12const Writer = std.io.Writer;
1213
1314const max_aggregate_items = 100;
1415const max_string_len = 256;
......@@ -20,7 +21,7 @@ pub const FormatContext = struct {
2021 depth: u8,
2122};
2223
23pub fn formatSema(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime fmt: []const u8) std.io.Writer.Error!void {
24pub fn formatSema(ctx: FormatContext, bw: *Writer, comptime fmt: []const u8) std.io.Writer.Error!void {
2425 const sema = ctx.opt_sema.?;
2526 comptime std.debug.assert(fmt.len == 0);
2627 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:
3132 };
3233}
3334
34pub fn format(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime fmt: []const u8) std.io.Writer.Error!void {
35pub fn format(ctx: FormatContext, bw: *Writer, comptime fmt: []const u8) std.io.Writer.Error!void {
3536 std.debug.assert(ctx.opt_sema == null);
3637 comptime std.debug.assert(fmt.len == 0);
3738 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
4344
4445pub fn print(
4546 val: Value,
46 bw: *std.io.BufferedWriter,
47 bw: *Writer,
4748 level: u8,
4849 pt: Zcu.PerThread,
4950 opt_sema: ?*Sema,
......@@ -186,7 +187,7 @@ fn printAggregate(
186187 val: Value,
187188 aggregate: InternPool.Key.Aggregate,
188189 is_ref: bool,
189 bw: *std.io.BufferedWriter,
190 bw: *Writer,
190191 level: u8,
191192 pt: Zcu.PerThread,
192193 opt_sema: ?*Sema,
......@@ -272,7 +273,7 @@ fn printPtr(
272273 ptr_val: Value,
273274 /// Whether to print `derivation` as an lvalue or rvalue. If `null`, the more concise option is chosen.
274275 want_kind: ?PrintPtrKind,
275 bw: *std.io.BufferedWriter,
276 bw: *Writer,
276277 level: u8,
277278 pt: Zcu.PerThread,
278279 opt_sema: ?*Sema,
......@@ -318,7 +319,7 @@ const PrintPtrKind = enum { lvalue, rvalue };
318319/// Returns the root derivation, which may be ignored.
319320pub fn printPtrDerivation(
320321 derivation: Value.PointerDeriveStep,
321 bw: *std.io.BufferedWriter,
322 bw: *Writer,
322323 pt: Zcu.PerThread,
323324 /// Whether to print `derivation` as an lvalue or rvalue. If `null`, the more concise option is chosen.
324325 /// 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");
1010const LazySrcLoc = Zcu.LazySrcLoc;
1111
1212/// Write human-readable, debug formatted ZIR code.
13pub fn renderAsText(gpa: Allocator, tree: ?Ast, zir: Zir, bw: *std.io.BufferedWriter) !void {
13pub fn renderAsText(gpa: Allocator, tree: ?Ast, zir: Zir, bw: *std.io.Writer) !void {
1414 var arena = std.heap.ArenaAllocator.init(gpa);
1515 defer arena.deinit();
1616
......@@ -57,7 +57,7 @@ pub fn renderInstructionContext(
5757 scope_file: *Zcu.File,
5858 parent_decl_node: Ast.Node.Index,
5959 indent: u32,
60 bw: *std.io.BufferedWriter,
60 bw: *std.io.Writer,
6161) !void {
6262 var arena = std.heap.ArenaAllocator.init(gpa);
6363 defer arena.deinit();
......@@ -89,7 +89,7 @@ pub fn renderSingleInstruction(
8989 scope_file: *Zcu.File,
9090 parent_decl_node: Ast.Node.Index,
9191 indent: u32,
92 bw: *std.io.BufferedWriter,
92 bw: *std.io.Writer,
9393) !void {
9494 var arena = std.heap.ArenaAllocator.init(gpa);
9595 defer arena.deinit();
......@@ -176,11 +176,11 @@ const Writer = struct {
176176 }
177177 } = .{},
178178
179 const Error = std.io.Writer.Error || std.mem.Allocator.Error;
179 const Error = std.io.Writer.Error || Allocator.Error;
180180
181181 fn writeInstToStream(
182182 self: *Writer,
183 stream: *std.io.BufferedWriter,
183 stream: *std.io.Writer,
184184 inst: Zir.Inst.Index,
185185 ) Error!void {
186186 const tags = self.code.instructions.items(.tag);
......@@ -510,7 +510,7 @@ const Writer = struct {
510510 }
511511 }
512512
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 {
514514 const extended = self.code.instructions.items(.data)[@intFromEnum(inst)].extended;
515515 try stream.print("{s}(", .{@tagName(extended.opcode)});
516516 switch (extended.opcode) {
......@@ -619,13 +619,13 @@ const Writer = struct {
619619 }
620620 }
621621
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 {
623623 try stream.writeAll(")) ");
624624 const src_node: Ast.Node.Offset = @enumFromInt(@as(i32, @bitCast(extended.operand)));
625625 try self.writeSrcNode(stream, src_node);
626626 }
627627
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 {
629629 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].bin;
630630 try self.writeInstRef(stream, inst_data.lhs);
631631 try stream.print(", {d})", .{@intFromEnum(inst_data.rhs)});
......@@ -633,7 +633,7 @@ const Writer = struct {
633633
634634 fn writeUnNode(
635635 self: *Writer,
636 stream: *std.io.BufferedWriter,
636 stream: *std.io.Writer,
637637 inst: Zir.Inst.Index,
638638 ) Error!void {
639639 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
......@@ -644,7 +644,7 @@ const Writer = struct {
644644
645645 fn writeUnTok(
646646 self: *Writer,
647 stream: *std.io.BufferedWriter,
647 stream: *std.io.Writer,
648648 inst: Zir.Inst.Index,
649649 ) Error!void {
650650 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].un_tok;
......@@ -655,7 +655,7 @@ const Writer = struct {
655655
656656 fn writeValidateDestructure(
657657 self: *Writer,
658 stream: *std.io.BufferedWriter,
658 stream: *std.io.Writer,
659659 inst: Zir.Inst.Index,
660660 ) Error!void {
661661 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
......@@ -669,7 +669,7 @@ const Writer = struct {
669669
670670 fn writeValidateArrayInitTy(
671671 self: *Writer,
672 stream: *std.io.BufferedWriter,
672 stream: *std.io.Writer,
673673 inst: Zir.Inst.Index,
674674 ) Error!void {
675675 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
......@@ -681,7 +681,7 @@ const Writer = struct {
681681
682682 fn writeArrayTypeSentinel(
683683 self: *Writer,
684 stream: *std.io.BufferedWriter,
684 stream: *std.io.Writer,
685685 inst: Zir.Inst.Index,
686686 ) Error!void {
687687 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
......@@ -697,7 +697,7 @@ const Writer = struct {
697697
698698 fn writePtrType(
699699 self: *Writer,
700 stream: *std.io.BufferedWriter,
700 stream: *std.io.Writer,
701701 inst: Zir.Inst.Index,
702702 ) Error!void {
703703 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].ptr_type;
......@@ -740,12 +740,12 @@ const Writer = struct {
740740 try self.writeSrcNode(stream, extra.data.src_node);
741741 }
742742
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 {
744744 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].int;
745745 try stream.print("{d})", .{inst_data});
746746 }
747747
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 {
749749 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].str;
750750 const byte_count = inst_data.len * @sizeOf(std.math.big.Limb);
751751 const limb_bytes = self.code.string_bytes[@intFromEnum(inst_data.start)..][0..byte_count];
......@@ -764,12 +764,12 @@ const Writer = struct {
764764 try stream.print("{s})", .{as_string});
765765 }
766766
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 {
768768 const number = self.code.instructions.items(.data)[@intFromEnum(inst)].float;
769769 try stream.print("{d})", .{number});
770770 }
771771
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 {
773773 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
774774 const extra = self.code.extraData(Zir.Inst.Float128, inst_data.payload_index).data;
775775 const number = extra.get();
......@@ -780,7 +780,7 @@ const Writer = struct {
780780
781781 fn writeStr(
782782 self: *Writer,
783 stream: *std.io.BufferedWriter,
783 stream: *std.io.Writer,
784784 inst: Zir.Inst.Index,
785785 ) Error!void {
786786 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].str;
......@@ -788,7 +788,7 @@ const Writer = struct {
788788 try stream.print("\"{f}\")", .{std.zig.fmtEscapes(str)});
789789 }
790790
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 {
792792 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
793793 const extra = self.code.extraData(Zir.Inst.SliceStart, inst_data.payload_index).data;
794794 try self.writeInstRef(stream, extra.lhs);
......@@ -798,7 +798,7 @@ const Writer = struct {
798798 try self.writeSrcNode(stream, inst_data.src_node);
799799 }
800800
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 {
802802 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
803803 const extra = self.code.extraData(Zir.Inst.SliceEnd, inst_data.payload_index).data;
804804 try self.writeInstRef(stream, extra.lhs);
......@@ -810,7 +810,7 @@ const Writer = struct {
810810 try self.writeSrcNode(stream, inst_data.src_node);
811811 }
812812
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 {
814814 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
815815 const extra = self.code.extraData(Zir.Inst.SliceSentinel, inst_data.payload_index).data;
816816 try self.writeInstRef(stream, extra.lhs);
......@@ -824,7 +824,7 @@ const Writer = struct {
824824 try self.writeSrcNode(stream, inst_data.src_node);
825825 }
826826
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 {
828828 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
829829 const extra = self.code.extraData(Zir.Inst.SliceLength, inst_data.payload_index).data;
830830 try self.writeInstRef(stream, extra.lhs);
......@@ -840,7 +840,7 @@ const Writer = struct {
840840 try self.writeSrcNode(stream, inst_data.src_node);
841841 }
842842
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 {
844844 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
845845 const extra = self.code.extraData(Zir.Inst.UnionInit, inst_data.payload_index).data;
846846 try self.writeInstRef(stream, extra.union_type);
......@@ -852,7 +852,7 @@ const Writer = struct {
852852 try self.writeSrcNode(stream, inst_data.src_node);
853853 }
854854
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 {
856856 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
857857 const extra = self.code.extraData(Zir.Inst.Shuffle, inst_data.payload_index).data;
858858 try self.writeInstRef(stream, extra.elem_type);
......@@ -866,7 +866,7 @@ const Writer = struct {
866866 try self.writeSrcNode(stream, inst_data.src_node);
867867 }
868868
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 {
870870 const extra = self.code.extraData(Zir.Inst.Select, extended.operand).data;
871871 try self.writeInstRef(stream, extra.elem_type);
872872 try stream.writeAll(", ");
......@@ -879,7 +879,7 @@ const Writer = struct {
879879 try self.writeSrcNode(stream, extra.node);
880880 }
881881
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 {
883883 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
884884 const extra = self.code.extraData(Zir.Inst.MulAdd, inst_data.payload_index).data;
885885 try self.writeInstRef(stream, extra.mulend1);
......@@ -891,7 +891,7 @@ const Writer = struct {
891891 try self.writeSrcNode(stream, inst_data.src_node);
892892 }
893893
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 {
895895 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
896896 const extra = self.code.extraData(Zir.Inst.BuiltinCall, inst_data.payload_index).data;
897897
......@@ -907,7 +907,7 @@ const Writer = struct {
907907 try self.writeSrcNode(stream, inst_data.src_node);
908908 }
909909
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 {
911911 const extra = self.code.extraData(Zir.Inst.FieldParentPtr, extended.operand).data;
912912 const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).@"struct".backing_integer.?;
913913 const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(FlagsInt, @truncate(extended.small)));
......@@ -924,7 +924,7 @@ const Writer = struct {
924924 try self.writeSrcNode(stream, extra.src_node);
925925 }
926926
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 {
928928 const extra = self.code.extraData(Zir.Inst.AsyncCall, extended.operand).data;
929929 try self.writeInstRef(stream, extra.frame_buffer);
930930 try stream.writeAll(", ");
......@@ -937,7 +937,7 @@ const Writer = struct {
937937 try self.writeSrcNode(stream, extra.node);
938938 }
939939
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 {
941941 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_tok;
942942 const extra = self.code.extraData(Zir.Inst.Param, inst_data.payload_index);
943943 const body = self.code.bodySlice(extra.end, extra.data.type.body_len);
......@@ -952,7 +952,7 @@ const Writer = struct {
952952 try self.writeSrcTok(stream, inst_data.src_tok);
953953 }
954954
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 {
956956 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
957957 const extra = self.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
958958 try self.writeInstRef(stream, extra.lhs);
......@@ -962,7 +962,7 @@ const Writer = struct {
962962 try self.writeSrcNode(stream, inst_data.src_node);
963963 }
964964
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 {
966966 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
967967 const extra = self.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index);
968968 const args = self.code.refSlice(extra.end, extra.data.operands_len);
......@@ -975,7 +975,7 @@ const Writer = struct {
975975 try self.writeSrcNode(stream, inst_data.src_node);
976976 }
977977
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 {
979979 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
980980 const extra = self.code.extraData(Zir.Inst.ArrayMul, inst_data.payload_index).data;
981981 try self.writeInstRef(stream, extra.res_ty);
......@@ -987,13 +987,13 @@ const Writer = struct {
987987 try self.writeSrcNode(stream, inst_data.src_node);
988988 }
989989
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 {
991991 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].elem_val_imm;
992992 try self.writeInstRef(stream, inst_data.operand);
993993 try stream.print(", {d})", .{inst_data.idx});
994994 }
995995
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 {
997997 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
998998 const extra = self.code.extraData(Zir.Inst.ElemPtrImm, inst_data.payload_index).data;
999999
......@@ -1002,7 +1002,7 @@ const Writer = struct {
10021002 try self.writeSrcNode(stream, inst_data.src_node);
10031003 }
10041004
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 {
10061006 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
10071007 const extra = self.code.extraData(Zir.Inst.Export, inst_data.payload_index).data;
10081008
......@@ -1013,7 +1013,7 @@ const Writer = struct {
10131013 try self.writeSrcNode(stream, inst_data.src_node);
10141014 }
10151015
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 {
10171017 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
10181018 const extra = self.code.extraData(Zir.Inst.ArrayInitRefTy, inst_data.payload_index).data;
10191019
......@@ -1023,7 +1023,7 @@ const Writer = struct {
10231023 try self.writeSrcNode(stream, inst_data.src_node);
10241024 }
10251025
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 {
10271027 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
10281028 const extra = self.code.extraData(Zir.Inst.StructInit, inst_data.payload_index);
10291029 var field_i: u32 = 0;
......@@ -1047,7 +1047,7 @@ const Writer = struct {
10471047 try self.writeSrcNode(stream, inst_data.src_node);
10481048 }
10491049
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 {
10511051 const extra = self.code.extraData(Zir.Inst.Cmpxchg, extended.operand).data;
10521052
10531053 try self.writeInstRef(stream, extra.ptr);
......@@ -1063,7 +1063,7 @@ const Writer = struct {
10631063 try self.writeSrcNode(stream, extra.node);
10641064 }
10651065
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 {
10671067 const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).@"struct".backing_integer.?;
10681068 const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(FlagsInt, @truncate(extended.small)));
10691069 const extra = self.code.extraData(Zir.Inst.BinNode, extended.operand).data;
......@@ -1079,7 +1079,7 @@ const Writer = struct {
10791079 try self.writeSrcNode(stream, extra.node);
10801080 }
10811081
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 {
10831083 const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).@"struct".backing_integer.?;
10841084 const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(FlagsInt, @truncate(extended.small)));
10851085 const extra = self.code.extraData(Zir.Inst.UnNode, extended.operand).data;
......@@ -1090,7 +1090,7 @@ const Writer = struct {
10901090 try self.writeSrcNode(stream, extra.node);
10911091 }
10921092
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 {
10941094 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
10951095 const extra = self.code.extraData(Zir.Inst.AtomicLoad, inst_data.payload_index).data;
10961096
......@@ -1103,7 +1103,7 @@ const Writer = struct {
11031103 try self.writeSrcNode(stream, inst_data.src_node);
11041104 }
11051105
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 {
11071107 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
11081108 const extra = self.code.extraData(Zir.Inst.AtomicStore, inst_data.payload_index).data;
11091109
......@@ -1116,7 +1116,7 @@ const Writer = struct {
11161116 try self.writeSrcNode(stream, inst_data.src_node);
11171117 }
11181118
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 {
11201120 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
11211121 const extra = self.code.extraData(Zir.Inst.AtomicRmw, inst_data.payload_index).data;
11221122
......@@ -1131,7 +1131,7 @@ const Writer = struct {
11311131 try self.writeSrcNode(stream, inst_data.src_node);
11321132 }
11331133
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 {
11351135 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
11361136 const extra = self.code.extraData(Zir.Inst.StructInitAnon, inst_data.payload_index);
11371137 var field_i: u32 = 0;
......@@ -1152,7 +1152,7 @@ const Writer = struct {
11521152 try self.writeSrcNode(stream, inst_data.src_node);
11531153 }
11541154
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 {
11561156 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
11571157 const extra = self.code.extraData(Zir.Inst.FieldType, inst_data.payload_index).data;
11581158 try self.writeInstRef(stream, extra.container_type);
......@@ -1161,7 +1161,7 @@ const Writer = struct {
11611161 try self.writeSrcNode(stream, inst_data.src_node);
11621162 }
11631163
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 {
11651165 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
11661166 const extra = self.code.extraData(Zir.Inst.FieldTypeRef, inst_data.payload_index).data;
11671167 try self.writeInstRef(stream, extra.container_type);
......@@ -1171,7 +1171,7 @@ const Writer = struct {
11711171 try self.writeSrcNode(stream, inst_data.src_node);
11721172 }
11731173
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 {
11751175 const extra = self.code.extraData(Zir.Inst.NodeMultiOp, extended.operand);
11761176 const operands = self.code.refSlice(extra.end, extended.small);
11771177
......@@ -1185,7 +1185,7 @@ const Writer = struct {
11851185
11861186 fn writeInstNode(
11871187 self: *Writer,
1188 stream: *std.io.BufferedWriter,
1188 stream: *std.io.Writer,
11891189 inst: Zir.Inst.Index,
11901190 ) Error!void {
11911191 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].inst_node;
......@@ -1196,7 +1196,7 @@ const Writer = struct {
11961196
11971197 fn writeAsm(
11981198 self: *Writer,
1199 stream: *std.io.BufferedWriter,
1199 stream: *std.io.Writer,
12001200 extended: Zir.Inst.Extended.InstData,
12011201 tmpl_is_expr: bool,
12021202 ) !void {
......@@ -1274,7 +1274,7 @@ const Writer = struct {
12741274 try self.writeSrcNode(stream, extra.data.src_node);
12751275 }
12761276
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 {
12781278 const extra = self.code.extraData(Zir.Inst.BinNode, extended.operand).data;
12791279
12801280 try self.writeInstRef(stream, extra.lhs);
......@@ -1286,7 +1286,7 @@ const Writer = struct {
12861286
12871287 fn writeCall(
12881288 self: *Writer,
1289 stream: *std.io.BufferedWriter,
1289 stream: *std.io.Writer,
12901290 inst: Zir.Inst.Index,
12911291 comptime kind: enum { direct, field },
12921292 ) !void {
......@@ -1337,7 +1337,7 @@ const Writer = struct {
13371337 try self.writeSrcNode(stream, inst_data.src_node);
13381338 }
13391339
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 {
13411341 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
13421342 const extra = self.code.extraData(Zir.Inst.Block, inst_data.payload_index);
13431343 const body = self.code.bodySlice(extra.end, extra.data.body_len);
......@@ -1346,7 +1346,7 @@ const Writer = struct {
13461346 try self.writeSrcNode(stream, inst_data.src_node);
13471347 }
13481348
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 {
13501350 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
13511351 const extra = self.code.extraData(Zir.Inst.BlockComptime, inst_data.payload_index);
13521352 const body = self.code.bodySlice(extra.end, extra.data.body_len);
......@@ -1356,7 +1356,7 @@ const Writer = struct {
13561356 try self.writeSrcNode(stream, inst_data.src_node);
13571357 }
13581358
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 {
13601360 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
13611361 const extra = self.code.extraData(Zir.Inst.CondBr, inst_data.payload_index);
13621362 const then_body = self.code.bodySlice(extra.end, extra.data.then_body_len);
......@@ -1370,7 +1370,7 @@ const Writer = struct {
13701370 try self.writeSrcNode(stream, inst_data.src_node);
13711371 }
13721372
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 {
13741374 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
13751375 const extra = self.code.extraData(Zir.Inst.Try, inst_data.payload_index);
13761376 const body = self.code.bodySlice(extra.end, extra.data.body_len);
......@@ -1381,7 +1381,7 @@ const Writer = struct {
13811381 try self.writeSrcNode(stream, inst_data.src_node);
13821382 }
13831383
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 {
13851385 const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
13861386
13871387 const extra = self.code.extraData(Zir.Inst.StructDecl, extended.operand);
......@@ -1573,7 +1573,7 @@ const Writer = struct {
15731573 try self.writeSrcNode(stream, .zero);
15741574 }
15751575
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 {
15771577 const small = @as(Zir.Inst.UnionDecl.Small, @bitCast(extended.small));
15781578
15791579 const extra = self.code.extraData(Zir.Inst.UnionDecl, extended.operand);
......@@ -1724,7 +1724,7 @@ const Writer = struct {
17241724 try self.writeSrcNode(stream, .zero);
17251725 }
17261726
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 {
17281728 const small = @as(Zir.Inst.EnumDecl.Small, @bitCast(extended.small));
17291729
17301730 const extra = self.code.extraData(Zir.Inst.EnumDecl, extended.operand);
......@@ -1845,7 +1845,7 @@ const Writer = struct {
18451845
18461846 fn writeOpaqueDecl(
18471847 self: *Writer,
1848 stream: *std.io.BufferedWriter,
1848 stream: *std.io.Writer,
18491849 extended: Zir.Inst.Extended.InstData,
18501850 ) !void {
18511851 const small = @as(Zir.Inst.OpaqueDecl.Small, @bitCast(extended.small));
......@@ -1887,7 +1887,7 @@ const Writer = struct {
18871887 try self.writeSrcNode(stream, .zero);
18881888 }
18891889
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 {
18911891 const fields_len = extended.small;
18921892 assert(fields_len != 0);
18931893 const extra = self.code.extraData(Zir.Inst.TupleDecl, extended.operand);
......@@ -1915,7 +1915,7 @@ const Writer = struct {
19151915
19161916 fn writeErrorSetDecl(
19171917 self: *Writer,
1918 stream: *std.io.BufferedWriter,
1918 stream: *std.io.Writer,
19191919 inst: Zir.Inst.Index,
19201920 ) !void {
19211921 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
......@@ -1940,7 +1940,7 @@ const Writer = struct {
19401940 try self.writeSrcNode(stream, inst_data.src_node);
19411941 }
19421942
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 {
19441944 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
19451945 const extra = self.code.extraData(Zir.Inst.SwitchBlockErrUnion, inst_data.payload_index);
19461946
......@@ -2077,7 +2077,7 @@ const Writer = struct {
20772077 try self.writeSrcNode(stream, inst_data.src_node);
20782078 }
20792079
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 {
20812081 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
20822082 const extra = self.code.extraData(Zir.Inst.SwitchBlock, inst_data.payload_index);
20832083
......@@ -2207,7 +2207,7 @@ const Writer = struct {
22072207 try self.writeSrcNode(stream, inst_data.src_node);
22082208 }
22092209
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 {
22112211 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
22122212 const extra = self.code.extraData(Zir.Inst.Field, inst_data.payload_index).data;
22132213 const name = self.code.nullTerminatedString(extra.field_name_start);
......@@ -2216,7 +2216,7 @@ const Writer = struct {
22162216 try self.writeSrcNode(stream, inst_data.src_node);
22172217 }
22182218
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 {
22202220 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
22212221 const extra = self.code.extraData(Zir.Inst.FieldNamed, inst_data.payload_index).data;
22222222 try self.writeInstRef(stream, extra.lhs);
......@@ -2226,7 +2226,7 @@ const Writer = struct {
22262226 try self.writeSrcNode(stream, inst_data.src_node);
22272227 }
22282228
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 {
22302230 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
22312231 const extra = self.code.extraData(Zir.Inst.As, inst_data.payload_index).data;
22322232 try self.writeInstRef(stream, extra.dest_type);
......@@ -2238,7 +2238,7 @@ const Writer = struct {
22382238
22392239 fn writeNode(
22402240 self: *Writer,
2241 stream: *std.io.BufferedWriter,
2241 stream: *std.io.Writer,
22422242 inst: Zir.Inst.Index,
22432243 ) Error!void {
22442244 const src_node = self.code.instructions.items(.data)[@intFromEnum(inst)].node;
......@@ -2248,7 +2248,7 @@ const Writer = struct {
22482248
22492249 fn writeStrTok(
22502250 self: *Writer,
2251 stream: *std.io.BufferedWriter,
2251 stream: *std.io.Writer,
22522252 inst: Zir.Inst.Index,
22532253 ) Error!void {
22542254 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;
......@@ -2257,7 +2257,7 @@ const Writer = struct {
22572257 try self.writeSrcTok(stream, inst_data.src_tok);
22582258 }
22592259
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 {
22612261 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].str_op;
22622262 const str = inst_data.getStr(self.code);
22632263 try self.writeInstRef(stream, inst_data.operand);
......@@ -2266,7 +2266,7 @@ const Writer = struct {
22662266
22672267 fn writeFunc(
22682268 self: *Writer,
2269 stream: *std.io.BufferedWriter,
2269 stream: *std.io.Writer,
22702270 inst: Zir.Inst.Index,
22712271 inferred_error_set: bool,
22722272 ) !void {
......@@ -2317,7 +2317,7 @@ const Writer = struct {
23172317 );
23182318 }
23192319
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 {
23212321 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
23222322 const extra = self.code.extraData(Zir.Inst.FuncFancy, inst_data.payload_index);
23232323
......@@ -2376,7 +2376,7 @@ const Writer = struct {
23762376 );
23772377 }
23782378
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 {
23802380 const extra = self.code.extraData(Zir.Inst.AllocExtended, extended.operand);
23812381 const small = @as(Zir.Inst.AllocExtended.Small, @bitCast(extended.small));
23822382
......@@ -2399,7 +2399,7 @@ const Writer = struct {
23992399 try self.writeSrcNode(stream, extra.data.src_node);
24002400 }
24012401
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 {
24032403 const extra = self.code.extraData(Zir.Inst.TypeOfPeer, extended.operand);
24042404 const body = self.code.bodySlice(extra.data.body_index, extra.data.body_len);
24052405 try self.writeBracedBody(stream, body);
......@@ -2412,7 +2412,7 @@ const Writer = struct {
24122412 try stream.writeAll("])");
24132413 }
24142414
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 {
24162416 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
24172417 const extra = self.code.extraData(Zir.Inst.BoolBr, inst_data.payload_index);
24182418 const body = self.code.bodySlice(extra.end, extra.data.body_len);
......@@ -2423,7 +2423,7 @@ const Writer = struct {
24232423 try self.writeSrcNode(stream, inst_data.src_node);
24242424 }
24252425
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 {
24272427 const int_type = self.code.instructions.items(.data)[@intFromEnum(inst)].int_type;
24282428 const prefix: u8 = switch (int_type.signedness) {
24292429 .signed => 'i',
......@@ -2433,7 +2433,7 @@ const Writer = struct {
24332433 try self.writeSrcNode(stream, int_type.src_node);
24342434 }
24352435
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 {
24372437 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].save_err_ret_index;
24382438
24392439 try self.writeInstRef(stream, inst_data.operand);
......@@ -2441,7 +2441,7 @@ const Writer = struct {
24412441 try stream.writeAll(")");
24422442 }
24432443
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 {
24452445 const extra = self.code.extraData(Zir.Inst.RestoreErrRetIndex, extended.operand).data;
24462446
24472447 try self.writeInstRef(stream, extra.block);
......@@ -2451,7 +2451,7 @@ const Writer = struct {
24512451 try self.writeSrcNode(stream, extra.src_node);
24522452 }
24532453
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 {
24552455 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].@"break";
24562456 const extra = self.code.extraData(Zir.Inst.Break, inst_data.payload_index).data;
24572457
......@@ -2461,7 +2461,7 @@ const Writer = struct {
24612461 try stream.writeAll(")");
24622462 }
24632463
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 {
24652465 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
24662466
24672467 const extra = self.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index);
......@@ -2477,7 +2477,7 @@ const Writer = struct {
24772477 try self.writeSrcNode(stream, inst_data.src_node);
24782478 }
24792479
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 {
24812481 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
24822482
24832483 const extra = self.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index);
......@@ -2492,7 +2492,7 @@ const Writer = struct {
24922492 try self.writeSrcNode(stream, inst_data.src_node);
24932493 }
24942494
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 {
24962496 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
24972497
24982498 const extra = self.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index);
......@@ -2512,7 +2512,7 @@ const Writer = struct {
25122512 try self.writeSrcNode(stream, inst_data.src_node);
25132513 }
25142514
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 {
25162516 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].@"unreachable";
25172517 try stream.writeAll(") ");
25182518 try self.writeSrcNode(stream, inst_data.src_node);
......@@ -2520,7 +2520,7 @@ const Writer = struct {
25202520
25212521 fn writeFuncCommon(
25222522 self: *Writer,
2523 stream: *std.io.BufferedWriter,
2523 stream: *std.io.Writer,
25242524 inferred_error_set: bool,
25252525 var_args: bool,
25262526 is_noinline: bool,
......@@ -2557,19 +2557,19 @@ const Writer = struct {
25572557 try self.writeSrcNode(stream, src_node);
25582558 }
25592559
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 {
25612561 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;
25622562 try stream.print("{d}, {d})", .{ inst_data.line + 1, inst_data.column + 1 });
25632563 }
25642564
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 {
25662566 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].@"defer";
25672567 const body = self.code.bodySlice(inst_data.index, inst_data.len);
25682568 try self.writeBracedBody(stream, body);
25692569 try stream.writeByte(')');
25702570 }
25712571
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 {
25732573 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].defer_err_code;
25742574 const extra = self.code.extraData(Zir.Inst.DeferErrCode, inst_data.payload_index).data;
25752575
......@@ -2582,7 +2582,7 @@ const Writer = struct {
25822582 try stream.writeByte(')');
25832583 }
25842584
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 {
25862586 const decl = self.code.getDeclaration(inst);
25872587
25882588 const prev_parent_decl_node = self.parent_decl_node;
......@@ -2639,26 +2639,26 @@ const Writer = struct {
26392639 try self.writeSrcNode(stream, .zero);
26402640 }
26412641
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 {
26432643 try stream.print("{d})) ", .{extended.small});
26442644 const src_node: Ast.Node.Offset = @enumFromInt(@as(i32, @bitCast(extended.operand)));
26452645 try self.writeSrcNode(stream, src_node);
26462646 }
26472647
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 {
26492649 const val: Zir.Inst.BuiltinValue = @enumFromInt(extended.small);
26502650 try stream.print("{s})) ", .{@tagName(val)});
26512651 const src_node: Ast.Node.Offset = @enumFromInt(@as(i32, @bitCast(extended.operand)));
26522652 try self.writeSrcNode(stream, src_node);
26532653 }
26542654
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 {
26562656 const op: Zir.Inst.InplaceOp = @enumFromInt(extended.small);
26572657 try self.writeInstRef(stream, @enumFromInt(extended.operand));
26582658 try stream.print(", {s}))", .{@tagName(op)});
26592659 }
26602660
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 {
26622662 if (ref == .none) {
26632663 return stream.writeAll(".none");
26642664 } else if (ref.toIndex()) |i| {
......@@ -2669,12 +2669,12 @@ const Writer = struct {
26692669 }
26702670 }
26712671
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 {
26732673 _ = self;
26742674 return stream.print("%{d}", .{@intFromEnum(inst)});
26752675 }
26762676
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 {
26782678 if (captures_len == 0) {
26792679 try stream.writeAll("{}");
26802680 return extra_index;
......@@ -2694,7 +2694,7 @@ const Writer = struct {
26942694 return extra_index + 2 * captures_len;
26952695 }
26962696
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 {
26982698 switch (capture.unwrap()) {
26992699 .nested => |i| return stream.print("[{d}]", .{i}),
27002700 .instruction => |inst| return self.writeInstIndex(stream, inst),
......@@ -2713,7 +2713,7 @@ const Writer = struct {
27132713
27142714 fn writeOptionalInstRef(
27152715 self: *Writer,
2716 stream: *std.io.BufferedWriter,
2716 stream: *std.io.Writer,
27172717 prefix: []const u8,
27182718 inst: Zir.Inst.Ref,
27192719 ) !void {
......@@ -2724,7 +2724,7 @@ const Writer = struct {
27242724
27252725 fn writeOptionalInstRefOrBody(
27262726 self: *Writer,
2727 stream: *std.io.BufferedWriter,
2727 stream: *std.io.Writer,
27282728 prefix: []const u8,
27292729 ref: Zir.Inst.Ref,
27302730 body: []const Zir.Inst.Index,
......@@ -2742,7 +2742,7 @@ const Writer = struct {
27422742
27432743 fn writeFlag(
27442744 self: *Writer,
2745 stream: *std.io.BufferedWriter,
2745 stream: *std.io.Writer,
27462746 name: []const u8,
27472747 flag: bool,
27482748 ) !void {
......@@ -2751,7 +2751,7 @@ const Writer = struct {
27512751 try stream.writeAll(name);
27522752 }
27532753
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 {
27552755 const tree = self.tree orelse return;
27562756 const abs_node = src_node.toAbsolute(self.parent_decl_node);
27572757 const src_span = tree.nodeToSpan(abs_node);
......@@ -2763,7 +2763,7 @@ const Writer = struct {
27632763 });
27642764 }
27652765
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 {
27672767 const tree = self.tree orelse return;
27682768 const abs_tok = src_tok.toAbsolute(tree.firstToken(self.parent_decl_node));
27692769 const span_start = tree.tokenStart(abs_tok);
......@@ -2776,7 +2776,7 @@ const Writer = struct {
27762776 });
27772777 }
27782778
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 {
27802780 const tree = self.tree orelse return;
27812781 const span_start = tree.tokenStart(src_tok);
27822782 const span_end = span_start + @as(u32, @intCast(tree.tokenSlice(src_tok).len));
......@@ -2788,15 +2788,15 @@ const Writer = struct {
27882788 });
27892789 }
27902790
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 {
27922792 try self.writeBracedBodyConditional(stream, body, self.recurse_decls);
27932793 }
27942794
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 {
27962796 try self.writeBracedBodyConditional(stream, body, self.recurse_blocks);
27972797 }
27982798
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 {
28002800 if (body.len == 0) {
28012801 try stream.writeAll("{}");
28022802 } else if (enabled) {
......@@ -2825,7 +2825,7 @@ const Writer = struct {
28252825 }
28262826 }
28272827
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 {
28292829 for (body) |inst| {
28302830 try stream.splatByteAll(' ', self.indent);
28312831 try stream.print("%{d} ", .{@intFromEnum(inst)});
......@@ -2834,7 +2834,7 @@ const Writer = struct {
28342834 }
28352835 }
28362836
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 {
28382838 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_tok;
28392839 const extra = self.code.extraData(Zir.Inst.Import, inst_data.payload_index).data;
28402840 try self.writeInstRef(stream, extra.res_ty);
src/print_zoir.zig+4-3
......@@ -1,4 +1,4 @@
1pub fn renderToWriter(zoir: Zoir, arena: Allocator, w: *std.io.BufferedWriter) error{ WriteFailed, OutOfMemory }!void {
1pub fn renderToWriter(zoir: Zoir, arena: Allocator, w: *Writer) error{ WriteFailed, OutOfMemory }!void {
22 assert(!zoir.hasCompileErrors());
33
44 const bytes_per_node = comptime n: {
......@@ -41,12 +41,12 @@ pub fn renderToWriter(zoir: Zoir, arena: Allocator, w: *std.io.BufferedWriter) e
4141}
4242
4343const PrintZon = struct {
44 w: *std.io.BufferedWriter,
44 w: *Writer,
4545 arena: Allocator,
4646 zoir: Zoir,
4747 indent: u32,
4848
49 const Error = std.io.Writer.Error;
49 const Error = Writer.Error;
5050
5151 fn renderRoot(pz: *PrintZon) Error!void {
5252 try pz.renderNode(.root);
......@@ -113,3 +113,4 @@ const std = @import("std");
113113const assert = std.debug.assert;
114114const Allocator = std.mem.Allocator;
115115const Zoir = std.zig.Zoir;
116const Writer = std.io.Writer;