authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-08-26 23:30:16-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-08-28 18:30:57-07:00
log9860dd475ab754f85f2f8c96039255bda8721002
treef1f309035fe51e724bbc6e28b28f986cfda55d4d
parent8f4cb4614fa7fe275dff360e9f281cb43b99261a

std: delete most remaining uses of GenericWriter


9 files changed, 116 insertions(+), 666 deletions(-)

lib/std/Io.zig-42
......@@ -144,48 +144,6 @@ pub fn GenericReader(
144144 return @errorCast(self.any().readAllAlloc(allocator, max_size));
145145 }
146146
147 pub inline fn readUntilDelimiterAlloc(
148 self: Self,
149 allocator: Allocator,
150 delimiter: u8,
151 max_size: usize,
152 ) (NoEofError || Allocator.Error || error{StreamTooLong})![]u8 {
153 return @errorCast(self.any().readUntilDelimiterAlloc(
154 allocator,
155 delimiter,
156 max_size,
157 ));
158 }
159
160 pub inline fn readUntilDelimiter(
161 self: Self,
162 buf: []u8,
163 delimiter: u8,
164 ) (NoEofError || error{StreamTooLong})![]u8 {
165 return @errorCast(self.any().readUntilDelimiter(buf, delimiter));
166 }
167
168 pub inline fn readUntilDelimiterOrEofAlloc(
169 self: Self,
170 allocator: Allocator,
171 delimiter: u8,
172 max_size: usize,
173 ) (Error || Allocator.Error || error{StreamTooLong})!?[]u8 {
174 return @errorCast(self.any().readUntilDelimiterOrEofAlloc(
175 allocator,
176 delimiter,
177 max_size,
178 ));
179 }
180
181 pub inline fn readUntilDelimiterOrEof(
182 self: Self,
183 buf: []u8,
184 delimiter: u8,
185 ) (Error || error{StreamTooLong})!?[]u8 {
186 return @errorCast(self.any().readUntilDelimiterOrEof(buf, delimiter));
187 }
188
189147 pub inline fn streamUntilDelimiter(
190148 self: Self,
191149 writer: anytype,
lib/std/Io/DeprecatedReader.zig-4
......@@ -290,7 +290,3 @@ const mem = std.mem;
290290const testing = std.testing;
291291const native_endian = @import("builtin").target.cpu.arch.endian();
292292const Alignment = std.mem.Alignment;
293
294test {
295 _ = @import("Reader/test.zig");
296}
lib/std/Io/Reader/test.zig deleted-351
......@@ -1,351 +0,0 @@
1const builtin = @import("builtin");
2const std = @import("../../std.zig");
3const testing = std.testing;
4
5test "Reader" {
6 var buf = "a\x02".*;
7 var fis = std.io.fixedBufferStream(&buf);
8 const reader = fis.reader();
9 try testing.expect((try reader.readByte()) == 'a');
10 try testing.expect((try reader.readEnum(enum(u8) {
11 a = 0,
12 b = 99,
13 c = 2,
14 d = 3,
15 }, builtin.cpu.arch.endian())) == .c);
16 try testing.expectError(error.EndOfStream, reader.readByte());
17}
18
19test "isBytes" {
20 var fis = std.io.fixedBufferStream("foobar");
21 const reader = fis.reader();
22 try testing.expectEqual(true, try reader.isBytes("foo"));
23 try testing.expectEqual(false, try reader.isBytes("qux"));
24}
25
26test "skipBytes" {
27 var fis = std.io.fixedBufferStream("foobar");
28 const reader = fis.reader();
29 try reader.skipBytes(3, .{});
30 try testing.expect(try reader.isBytes("bar"));
31 try reader.skipBytes(0, .{});
32 try testing.expectError(error.EndOfStream, reader.skipBytes(1, .{}));
33}
34
35test "readUntilDelimiterArrayList returns ArrayLists with bytes read until the delimiter, then EndOfStream" {
36 const a = std.testing.allocator;
37 var list = std.array_list.Managed(u8).init(a);
38 defer list.deinit();
39
40 var fis = std.io.fixedBufferStream("0000\n1234\n");
41 const reader = fis.reader();
42
43 try reader.readUntilDelimiterArrayList(&list, '\n', 5);
44 try std.testing.expectEqualStrings("0000", list.items);
45 try reader.readUntilDelimiterArrayList(&list, '\n', 5);
46 try std.testing.expectEqualStrings("1234", list.items);
47 try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiterArrayList(&list, '\n', 5));
48}
49
50test "readUntilDelimiterArrayList returns an empty ArrayList" {
51 const a = std.testing.allocator;
52 var list = std.array_list.Managed(u8).init(a);
53 defer list.deinit();
54
55 var fis = std.io.fixedBufferStream("\n");
56 const reader = fis.reader();
57
58 try reader.readUntilDelimiterArrayList(&list, '\n', 5);
59 try std.testing.expectEqualStrings("", list.items);
60}
61
62test "readUntilDelimiterArrayList returns StreamTooLong, then an ArrayList with bytes read until the delimiter" {
63 const a = std.testing.allocator;
64 var list = std.array_list.Managed(u8).init(a);
65 defer list.deinit();
66
67 var fis = std.io.fixedBufferStream("1234567\n");
68 const reader = fis.reader();
69
70 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiterArrayList(&list, '\n', 5));
71 try std.testing.expectEqualStrings("12345", list.items);
72 try reader.readUntilDelimiterArrayList(&list, '\n', 5);
73 try std.testing.expectEqualStrings("67", list.items);
74}
75
76test "readUntilDelimiterArrayList returns EndOfStream" {
77 const a = std.testing.allocator;
78 var list = std.array_list.Managed(u8).init(a);
79 defer list.deinit();
80
81 var fis = std.io.fixedBufferStream("1234");
82 const reader = fis.reader();
83
84 try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiterArrayList(&list, '\n', 5));
85 try std.testing.expectEqualStrings("1234", list.items);
86}
87
88test "readUntilDelimiterAlloc returns ArrayLists with bytes read until the delimiter, then EndOfStream" {
89 const a = std.testing.allocator;
90
91 var fis = std.io.fixedBufferStream("0000\n1234\n");
92 const reader = fis.reader();
93
94 {
95 const result = try reader.readUntilDelimiterAlloc(a, '\n', 5);
96 defer a.free(result);
97 try std.testing.expectEqualStrings("0000", result);
98 }
99
100 {
101 const result = try reader.readUntilDelimiterAlloc(a, '\n', 5);
102 defer a.free(result);
103 try std.testing.expectEqualStrings("1234", result);
104 }
105
106 try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiterAlloc(a, '\n', 5));
107}
108
109test "readUntilDelimiterAlloc returns an empty ArrayList" {
110 const a = std.testing.allocator;
111
112 var fis = std.io.fixedBufferStream("\n");
113 const reader = fis.reader();
114
115 {
116 const result = try reader.readUntilDelimiterAlloc(a, '\n', 5);
117 defer a.free(result);
118 try std.testing.expectEqualStrings("", result);
119 }
120}
121
122test "readUntilDelimiterAlloc returns StreamTooLong, then an ArrayList with bytes read until the delimiter" {
123 const a = std.testing.allocator;
124
125 var fis = std.io.fixedBufferStream("1234567\n");
126 const reader = fis.reader();
127
128 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiterAlloc(a, '\n', 5));
129
130 const result = try reader.readUntilDelimiterAlloc(a, '\n', 5);
131 defer a.free(result);
132 try std.testing.expectEqualStrings("67", result);
133}
134
135test "readUntilDelimiterAlloc returns EndOfStream" {
136 const a = std.testing.allocator;
137
138 var fis = std.io.fixedBufferStream("1234");
139 const reader = fis.reader();
140
141 try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiterAlloc(a, '\n', 5));
142}
143
144test "readUntilDelimiter returns bytes read until the delimiter" {
145 var buf: [5]u8 = undefined;
146 var fis = std.io.fixedBufferStream("0000\n1234\n");
147 const reader = fis.reader();
148 try std.testing.expectEqualStrings("0000", try reader.readUntilDelimiter(&buf, '\n'));
149 try std.testing.expectEqualStrings("1234", try reader.readUntilDelimiter(&buf, '\n'));
150}
151
152test "readUntilDelimiter returns an empty string" {
153 var buf: [5]u8 = undefined;
154 var fis = std.io.fixedBufferStream("\n");
155 const reader = fis.reader();
156 try std.testing.expectEqualStrings("", try reader.readUntilDelimiter(&buf, '\n'));
157}
158
159test "readUntilDelimiter returns StreamTooLong, then an empty string" {
160 var buf: [5]u8 = undefined;
161 var fis = std.io.fixedBufferStream("12345\n");
162 const reader = fis.reader();
163 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiter(&buf, '\n'));
164 try std.testing.expectEqualStrings("", try reader.readUntilDelimiter(&buf, '\n'));
165}
166
167test "readUntilDelimiter returns StreamTooLong, then bytes read until the delimiter" {
168 var buf: [5]u8 = undefined;
169 var fis = std.io.fixedBufferStream("1234567\n");
170 const reader = fis.reader();
171 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiter(&buf, '\n'));
172 try std.testing.expectEqualStrings("67", try reader.readUntilDelimiter(&buf, '\n'));
173}
174
175test "readUntilDelimiter returns EndOfStream" {
176 {
177 var buf: [5]u8 = undefined;
178 var fis = std.io.fixedBufferStream("");
179 const reader = fis.reader();
180 try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiter(&buf, '\n'));
181 }
182 {
183 var buf: [5]u8 = undefined;
184 var fis = std.io.fixedBufferStream("1234");
185 const reader = fis.reader();
186 try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiter(&buf, '\n'));
187 }
188}
189
190test "readUntilDelimiter returns bytes read until delimiter, then EndOfStream" {
191 var buf: [5]u8 = undefined;
192 var fis = std.io.fixedBufferStream("1234\n");
193 const reader = fis.reader();
194 try std.testing.expectEqualStrings("1234", try reader.readUntilDelimiter(&buf, '\n'));
195 try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiter(&buf, '\n'));
196}
197
198test "readUntilDelimiter returns StreamTooLong, then EndOfStream" {
199 var buf: [5]u8 = undefined;
200 var fis = std.io.fixedBufferStream("12345");
201 const reader = fis.reader();
202 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiter(&buf, '\n'));
203 try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiter(&buf, '\n'));
204}
205
206test "readUntilDelimiter writes all bytes read to the output buffer" {
207 var buf: [5]u8 = undefined;
208 var fis = std.io.fixedBufferStream("0000\n12345");
209 const reader = fis.reader();
210 _ = try reader.readUntilDelimiter(&buf, '\n');
211 try std.testing.expectEqualStrings("0000\n", &buf);
212 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiter(&buf, '\n'));
213 try std.testing.expectEqualStrings("12345", &buf);
214}
215
216test "readUntilDelimiterOrEofAlloc returns ArrayLists with bytes read until the delimiter, then EndOfStream" {
217 const a = std.testing.allocator;
218
219 var fis = std.io.fixedBufferStream("0000\n1234\n");
220 const reader = fis.reader();
221
222 {
223 const result = (try reader.readUntilDelimiterOrEofAlloc(a, '\n', 5)).?;
224 defer a.free(result);
225 try std.testing.expectEqualStrings("0000", result);
226 }
227
228 {
229 const result = (try reader.readUntilDelimiterOrEofAlloc(a, '\n', 5)).?;
230 defer a.free(result);
231 try std.testing.expectEqualStrings("1234", result);
232 }
233
234 try std.testing.expect((try reader.readUntilDelimiterOrEofAlloc(a, '\n', 5)) == null);
235}
236
237test "readUntilDelimiterOrEofAlloc returns an empty ArrayList" {
238 const a = std.testing.allocator;
239
240 var fis = std.io.fixedBufferStream("\n");
241 const reader = fis.reader();
242
243 {
244 const result = (try reader.readUntilDelimiterOrEofAlloc(a, '\n', 5)).?;
245 defer a.free(result);
246 try std.testing.expectEqualStrings("", result);
247 }
248}
249
250test "readUntilDelimiterOrEofAlloc returns StreamTooLong, then an ArrayList with bytes read until the delimiter" {
251 const a = std.testing.allocator;
252
253 var fis = std.io.fixedBufferStream("1234567\n");
254 const reader = fis.reader();
255
256 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiterOrEofAlloc(a, '\n', 5));
257
258 const result = (try reader.readUntilDelimiterOrEofAlloc(a, '\n', 5)).?;
259 defer a.free(result);
260 try std.testing.expectEqualStrings("67", result);
261}
262
263test "readUntilDelimiterOrEof returns bytes read until the delimiter" {
264 var buf: [5]u8 = undefined;
265 var fis = std.io.fixedBufferStream("0000\n1234\n");
266 const reader = fis.reader();
267 try std.testing.expectEqualStrings("0000", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);
268 try std.testing.expectEqualStrings("1234", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);
269}
270
271test "readUntilDelimiterOrEof returns an empty string" {
272 var buf: [5]u8 = undefined;
273 var fis = std.io.fixedBufferStream("\n");
274 const reader = fis.reader();
275 try std.testing.expectEqualStrings("", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);
276}
277
278test "readUntilDelimiterOrEof returns StreamTooLong, then an empty string" {
279 var buf: [5]u8 = undefined;
280 var fis = std.io.fixedBufferStream("12345\n");
281 const reader = fis.reader();
282 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiterOrEof(&buf, '\n'));
283 try std.testing.expectEqualStrings("", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);
284}
285
286test "readUntilDelimiterOrEof returns StreamTooLong, then bytes read until the delimiter" {
287 var buf: [5]u8 = undefined;
288 var fis = std.io.fixedBufferStream("1234567\n");
289 const reader = fis.reader();
290 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiterOrEof(&buf, '\n'));
291 try std.testing.expectEqualStrings("67", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);
292}
293
294test "readUntilDelimiterOrEof returns null" {
295 var buf: [5]u8 = undefined;
296 var fis = std.io.fixedBufferStream("");
297 const reader = fis.reader();
298 try std.testing.expect((try reader.readUntilDelimiterOrEof(&buf, '\n')) == null);
299}
300
301test "readUntilDelimiterOrEof returns bytes read until delimiter, then null" {
302 var buf: [5]u8 = undefined;
303 var fis = std.io.fixedBufferStream("1234\n");
304 const reader = fis.reader();
305 try std.testing.expectEqualStrings("1234", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);
306 try std.testing.expect((try reader.readUntilDelimiterOrEof(&buf, '\n')) == null);
307}
308
309test "readUntilDelimiterOrEof returns bytes read until end-of-stream" {
310 var buf: [5]u8 = undefined;
311 var fis = std.io.fixedBufferStream("1234");
312 const reader = fis.reader();
313 try std.testing.expectEqualStrings("1234", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);
314}
315
316test "readUntilDelimiterOrEof returns StreamTooLong, then bytes read until end-of-stream" {
317 var buf: [5]u8 = undefined;
318 var fis = std.io.fixedBufferStream("1234567");
319 const reader = fis.reader();
320 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiterOrEof(&buf, '\n'));
321 try std.testing.expectEqualStrings("67", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);
322}
323
324test "readUntilDelimiterOrEof writes all bytes read to the output buffer" {
325 var buf: [5]u8 = undefined;
326 var fis = std.io.fixedBufferStream("0000\n12345");
327 const reader = fis.reader();
328 _ = try reader.readUntilDelimiterOrEof(&buf, '\n');
329 try std.testing.expectEqualStrings("0000\n", &buf);
330 try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiterOrEof(&buf, '\n'));
331 try std.testing.expectEqualStrings("12345", &buf);
332}
333
334test "streamUntilDelimiter writes all bytes without delimiter to the output" {
335 const input_string = "some_string_with_delimiter!";
336 var input_fbs = std.io.fixedBufferStream(input_string);
337 const reader = input_fbs.reader();
338
339 var output: [input_string.len]u8 = undefined;
340 var output_fbs = std.io.fixedBufferStream(&output);
341 const writer = output_fbs.writer();
342
343 try reader.streamUntilDelimiter(writer, '!', input_fbs.buffer.len);
344 try std.testing.expectEqualStrings("some_string_with_delimiter", output_fbs.getWritten());
345 try std.testing.expectError(error.EndOfStream, reader.streamUntilDelimiter(writer, '!', input_fbs.buffer.len));
346
347 input_fbs.reset();
348 output_fbs.reset();
349
350 try std.testing.expectError(error.StreamTooLong, reader.streamUntilDelimiter(writer, '!', 5));
351}
lib/std/Thread.zig+1-1
......@@ -167,7 +167,7 @@ pub fn setName(self: Thread, name: []const u8) SetNameError!void {
167167 const file = try std.fs.cwd().openFile(path, .{ .mode = .write_only });
168168 defer file.close();
169169
170 try file.deprecatedWriter().writeAll(name);
170 try file.writeAll(name);
171171 return;
172172 },
173173 .windows => {
lib/std/array_list.zig-54
......@@ -2041,60 +2041,6 @@ test "Managed(T) of struct T" {
20412041 }
20422042}
20432043
2044test "Managed(u8) implements writer" {
2045 const a = testing.allocator;
2046
2047 {
2048 var buffer = Managed(u8).init(a);
2049 defer buffer.deinit();
2050
2051 const x: i32 = 42;
2052 const y: i32 = 1234;
2053 try buffer.writer().print("x: {}\ny: {}\n", .{ x, y });
2054
2055 try testing.expectEqualSlices(u8, "x: 42\ny: 1234\n", buffer.items);
2056 }
2057 {
2058 var list = AlignedManaged(u8, .@"2").init(a);
2059 defer list.deinit();
2060
2061 const writer = list.writer();
2062 try writer.writeAll("a");
2063 try writer.writeAll("bc");
2064 try writer.writeAll("d");
2065 try writer.writeAll("efg");
2066
2067 try testing.expectEqualSlices(u8, list.items, "abcdefg");
2068 }
2069}
2070
2071test "ArrayList(u8) implements writer" {
2072 const a = testing.allocator;
2073
2074 {
2075 var buffer: ArrayList(u8) = .empty;
2076 defer buffer.deinit(a);
2077
2078 const x: i32 = 42;
2079 const y: i32 = 1234;
2080 try buffer.writer(a).print("x: {}\ny: {}\n", .{ x, y });
2081
2082 try testing.expectEqualSlices(u8, "x: 42\ny: 1234\n", buffer.items);
2083 }
2084 {
2085 var list: Aligned(u8, .@"2") = .empty;
2086 defer list.deinit(a);
2087
2088 const writer = list.writer(a);
2089 try writer.writeAll("a");
2090 try writer.writeAll("bc");
2091 try writer.writeAll("d");
2092 try writer.writeAll("efg");
2093
2094 try testing.expectEqualSlices(u8, list.items, "abcdefg");
2095 }
2096}
2097
20982044test "shrink still sets length when resizing is disabled" {
20992045 var failing_allocator = testing.FailingAllocator.init(testing.allocator, .{ .resize_fail_index = 0 });
21002046 const a = failing_allocator.allocator();
lib/std/crypto/scrypt.zig+12-9
......@@ -304,31 +304,34 @@ const crypt_format = struct {
304304
305305 /// Serialize parameters into a string in modular crypt format.
306306 pub fn serialize(params: anytype, str: []u8) EncodingError![]const u8 {
307 var buf = io.fixedBufferStream(str);
308 try serializeTo(params, buf.writer());
309 return buf.getWritten();
307 var w: std.Io.Writer = .fixed(str);
308 serializeTo(params, &w) catch |err| switch (err) {
309 error.WriteFailed => return error.NoSpaceLeft,
310 else => |e| return e,
311 };
312 return w.buffered();
310313 }
311314
312315 /// Compute the number of bytes required to serialize `params`
313316 pub fn calcSize(params: anytype) usize {
314317 var trash: [128]u8 = undefined;
315318 var d: std.Io.Writer.Discarding = .init(&trash);
316 serializeTo(params, &d) catch unreachable;
319 serializeTo(params, &d.writer) catch unreachable;
317320 return @intCast(d.fullCount());
318321 }
319322
320 fn serializeTo(params: anytype, out: anytype) !void {
323 fn serializeTo(params: anytype, w: *std.Io.Writer) !void {
321324 var header: [14]u8 = undefined;
322325 header[0..3].* = prefix.*;
323326 Codec.intEncode(header[3..4], params.ln);
324327 Codec.intEncode(header[4..9], params.r);
325328 Codec.intEncode(header[9..14], params.p);
326 try out.writeAll(&header);
327 try out.writeAll(params.salt);
328 try out.writeAll("$");
329 try w.writeAll(&header);
330 try w.writeAll(params.salt);
331 try w.writeAll("$");
329332 var buf: [@TypeOf(params.hash).max_encoded_length]u8 = undefined;
330333 const hash_str = try params.hash.toB64(&buf);
331 try out.writeAll(hash_str);
334 try w.writeAll(hash_str);
332335 }
333336
334337 /// Custom codec that maps 6 bits into 8 like regular Base64, but uses its own alphabet,
lib/std/debug/Dwarf/expression.zig+101-100
......@@ -8,6 +8,8 @@ const OP = std.dwarf.OP;
88const abi = std.debug.Dwarf.abi;
99const mem = std.mem;
1010const assert = std.debug.assert;
11const testing = std.testing;
12const Writer = std.Io.Writer;
1113
1214/// Expressions can be evaluated in different contexts, each requiring its own set of inputs.
1315/// Callers should specify all the fields relevant to their context. If a field is required
......@@ -782,7 +784,7 @@ pub fn Builder(comptime options: Options) type {
782784
783785 return struct {
784786 /// Zero-operand instructions
785 pub fn writeOpcode(writer: anytype, comptime opcode: u8) !void {
787 pub fn writeOpcode(writer: *Writer, comptime opcode: u8) !void {
786788 if (options.call_frame_context and !comptime isOpcodeValidInCFA(opcode)) return error.InvalidCFAOpcode;
787789 switch (opcode) {
788790 OP.dup,
......@@ -823,14 +825,14 @@ pub fn Builder(comptime options: Options) type {
823825 }
824826
825827 // 2.5.1.1: Literal Encodings
826 pub fn writeLiteral(writer: anytype, literal: u8) !void {
828 pub fn writeLiteral(writer: *Writer, literal: u8) !void {
827829 switch (literal) {
828830 0...31 => |n| try writer.writeByte(n + OP.lit0),
829831 else => return error.InvalidLiteral,
830832 }
831833 }
832834
833 pub fn writeConst(writer: anytype, comptime T: type, value: T) !void {
835 pub fn writeConst(writer: *Writer, comptime T: type, value: T) !void {
834836 if (@typeInfo(T) != .int) @compileError("Constants must be integers");
835837
836838 switch (T) {
......@@ -852,7 +854,7 @@ pub fn Builder(comptime options: Options) type {
852854 else => switch (@typeInfo(T).int.signedness) {
853855 .unsigned => {
854856 try writer.writeByte(OP.constu);
855 try leb.writeUleb128(writer, value);
857 try writer.writeUleb128(value);
856858 },
857859 .signed => {
858860 try writer.writeByte(OP.consts);
......@@ -862,105 +864,105 @@ pub fn Builder(comptime options: Options) type {
862864 }
863865 }
864866
865 pub fn writeConstx(writer: anytype, debug_addr_offset: anytype) !void {
867 pub fn writeConstx(writer: *Writer, debug_addr_offset: anytype) !void {
866868 try writer.writeByte(OP.constx);
867 try leb.writeUleb128(writer, debug_addr_offset);
869 try writer.writeUleb128(debug_addr_offset);
868870 }
869871
870 pub fn writeConstType(writer: anytype, die_offset: anytype, value_bytes: []const u8) !void {
872 pub fn writeConstType(writer: *Writer, die_offset: anytype, value_bytes: []const u8) !void {
871873 if (options.call_frame_context) return error.InvalidCFAOpcode;
872874 if (value_bytes.len > 0xff) return error.InvalidTypeLength;
873875 try writer.writeByte(OP.const_type);
874 try leb.writeUleb128(writer, die_offset);
876 try writer.writeUleb128(die_offset);
875877 try writer.writeByte(@intCast(value_bytes.len));
876878 try writer.writeAll(value_bytes);
877879 }
878880
879 pub fn writeAddr(writer: anytype, value: addr_type) !void {
881 pub fn writeAddr(writer: *Writer, value: addr_type) !void {
880882 try writer.writeByte(OP.addr);
881883 try writer.writeInt(addr_type, value, options.endian);
882884 }
883885
884 pub fn writeAddrx(writer: anytype, debug_addr_offset: anytype) !void {
886 pub fn writeAddrx(writer: *Writer, debug_addr_offset: anytype) !void {
885887 if (options.call_frame_context) return error.InvalidCFAOpcode;
886888 try writer.writeByte(OP.addrx);
887 try leb.writeUleb128(writer, debug_addr_offset);
889 try writer.writeUleb128(debug_addr_offset);
888890 }
889891
890892 // 2.5.1.2: Register Values
891 pub fn writeFbreg(writer: anytype, offset: anytype) !void {
893 pub fn writeFbreg(writer: *Writer, offset: anytype) !void {
892894 try writer.writeByte(OP.fbreg);
893895 try leb.writeIleb128(writer, offset);
894896 }
895897
896 pub fn writeBreg(writer: anytype, register: u8, offset: anytype) !void {
898 pub fn writeBreg(writer: *Writer, register: u8, offset: anytype) !void {
897899 if (register > 31) return error.InvalidRegister;
898900 try writer.writeByte(OP.breg0 + register);
899901 try leb.writeIleb128(writer, offset);
900902 }
901903
902 pub fn writeBregx(writer: anytype, register: anytype, offset: anytype) !void {
904 pub fn writeBregx(writer: *Writer, register: anytype, offset: anytype) !void {
903905 try writer.writeByte(OP.bregx);
904 try leb.writeUleb128(writer, register);
906 try writer.writeUleb128(register);
905907 try leb.writeIleb128(writer, offset);
906908 }
907909
908 pub fn writeRegvalType(writer: anytype, register: anytype, offset: anytype) !void {
910 pub fn writeRegvalType(writer: *Writer, register: anytype, offset: anytype) !void {
909911 if (options.call_frame_context) return error.InvalidCFAOpcode;
910912 try writer.writeByte(OP.regval_type);
911 try leb.writeUleb128(writer, register);
912 try leb.writeUleb128(writer, offset);
913 try writer.writeUleb128(register);
914 try writer.writeUleb128(offset);
913915 }
914916
915917 // 2.5.1.3: Stack Operations
916 pub fn writePick(writer: anytype, index: u8) !void {
918 pub fn writePick(writer: *Writer, index: u8) !void {
917919 try writer.writeByte(OP.pick);
918920 try writer.writeByte(index);
919921 }
920922
921 pub fn writeDerefSize(writer: anytype, size: u8) !void {
923 pub fn writeDerefSize(writer: *Writer, size: u8) !void {
922924 try writer.writeByte(OP.deref_size);
923925 try writer.writeByte(size);
924926 }
925927
926 pub fn writeXDerefSize(writer: anytype, size: u8) !void {
928 pub fn writeXDerefSize(writer: *Writer, size: u8) !void {
927929 try writer.writeByte(OP.xderef_size);
928930 try writer.writeByte(size);
929931 }
930932
931 pub fn writeDerefType(writer: anytype, size: u8, die_offset: anytype) !void {
933 pub fn writeDerefType(writer: *Writer, size: u8, die_offset: anytype) !void {
932934 if (options.call_frame_context) return error.InvalidCFAOpcode;
933935 try writer.writeByte(OP.deref_type);
934936 try writer.writeByte(size);
935 try leb.writeUleb128(writer, die_offset);
937 try writer.writeUleb128(die_offset);
936938 }
937939
938 pub fn writeXDerefType(writer: anytype, size: u8, die_offset: anytype) !void {
940 pub fn writeXDerefType(writer: *Writer, size: u8, die_offset: anytype) !void {
939941 try writer.writeByte(OP.xderef_type);
940942 try writer.writeByte(size);
941 try leb.writeUleb128(writer, die_offset);
943 try writer.writeUleb128(die_offset);
942944 }
943945
944946 // 2.5.1.4: Arithmetic and Logical Operations
945947
946 pub fn writePlusUconst(writer: anytype, uint_value: anytype) !void {
948 pub fn writePlusUconst(writer: *Writer, uint_value: anytype) !void {
947949 try writer.writeByte(OP.plus_uconst);
948 try leb.writeUleb128(writer, uint_value);
950 try writer.writeUleb128(uint_value);
949951 }
950952
951953 // 2.5.1.5: Control Flow Operations
952954
953 pub fn writeSkip(writer: anytype, offset: i16) !void {
955 pub fn writeSkip(writer: *Writer, offset: i16) !void {
954956 try writer.writeByte(OP.skip);
955957 try writer.writeInt(i16, offset, options.endian);
956958 }
957959
958 pub fn writeBra(writer: anytype, offset: i16) !void {
960 pub fn writeBra(writer: *Writer, offset: i16) !void {
959961 try writer.writeByte(OP.bra);
960962 try writer.writeInt(i16, offset, options.endian);
961963 }
962964
963 pub fn writeCall(writer: anytype, comptime T: type, offset: T) !void {
965 pub fn writeCall(writer: *Writer, comptime T: type, offset: T) !void {
964966 if (options.call_frame_context) return error.InvalidCFAOpcode;
965967 switch (T) {
966968 u16 => try writer.writeByte(OP.call2),
......@@ -971,45 +973,45 @@ pub fn Builder(comptime options: Options) type {
971973 try writer.writeInt(T, offset, options.endian);
972974 }
973975
974 pub fn writeCallRef(writer: anytype, comptime is_64: bool, value: if (is_64) u64 else u32) !void {
976 pub fn writeCallRef(writer: *Writer, comptime is_64: bool, value: if (is_64) u64 else u32) !void {
975977 if (options.call_frame_context) return error.InvalidCFAOpcode;
976978 try writer.writeByte(OP.call_ref);
977979 try writer.writeInt(if (is_64) u64 else u32, value, options.endian);
978980 }
979981
980 pub fn writeConvert(writer: anytype, die_offset: anytype) !void {
982 pub fn writeConvert(writer: *Writer, die_offset: anytype) !void {
981983 if (options.call_frame_context) return error.InvalidCFAOpcode;
982984 try writer.writeByte(OP.convert);
983 try leb.writeUleb128(writer, die_offset);
985 try writer.writeUleb128(die_offset);
984986 }
985987
986 pub fn writeReinterpret(writer: anytype, die_offset: anytype) !void {
988 pub fn writeReinterpret(writer: *Writer, die_offset: anytype) !void {
987989 if (options.call_frame_context) return error.InvalidCFAOpcode;
988990 try writer.writeByte(OP.reinterpret);
989 try leb.writeUleb128(writer, die_offset);
991 try writer.writeUleb128(die_offset);
990992 }
991993
992994 // 2.5.1.7: Special Operations
993995
994 pub fn writeEntryValue(writer: anytype, expression: []const u8) !void {
996 pub fn writeEntryValue(writer: *Writer, expression: []const u8) !void {
995997 try writer.writeByte(OP.entry_value);
996 try leb.writeUleb128(writer, expression.len);
998 try writer.writeUleb128(expression.len);
997999 try writer.writeAll(expression);
9981000 }
9991001
10001002 // 2.6: Location Descriptions
1001 pub fn writeReg(writer: anytype, register: u8) !void {
1003 pub fn writeReg(writer: *Writer, register: u8) !void {
10021004 try writer.writeByte(OP.reg0 + register);
10031005 }
10041006
1005 pub fn writeRegx(writer: anytype, register: anytype) !void {
1007 pub fn writeRegx(writer: *Writer, register: anytype) !void {
10061008 try writer.writeByte(OP.regx);
1007 try leb.writeUleb128(writer, register);
1009 try writer.writeUleb128(register);
10081010 }
10091011
1010 pub fn writeImplicitValue(writer: anytype, value_bytes: []const u8) !void {
1012 pub fn writeImplicitValue(writer: *Writer, value_bytes: []const u8) !void {
10111013 try writer.writeByte(OP.implicit_value);
1012 try leb.writeUleb128(writer, value_bytes.len);
1014 try writer.writeUleb128(value_bytes.len);
10131015 try writer.writeAll(value_bytes);
10141016 }
10151017 };
......@@ -1042,8 +1044,7 @@ fn isOpcodeRegisterLocation(opcode: u8) bool {
10421044 };
10431045}
10441046
1045const testing = std.testing;
1046test "DWARF expressions" {
1047test "basics" {
10471048 const allocator = std.testing.allocator;
10481049
10491050 const options = Options{};
......@@ -1052,10 +1053,10 @@ test "DWARF expressions" {
10521053
10531054 const b = Builder(options);
10541055
1055 var program = std.array_list.Managed(u8).init(allocator);
1056 var program: std.Io.Writer.Allocating = .init(allocator);
10561057 defer program.deinit();
10571058
1058 const writer = program.writer();
1059 const writer = &program.writer;
10591060
10601061 // Literals
10611062 {
......@@ -1064,7 +1065,7 @@ test "DWARF expressions" {
10641065 try b.writeLiteral(writer, @intCast(i));
10651066 }
10661067
1067 _ = try stack_machine.run(program.items, allocator, context, 0);
1068 _ = try stack_machine.run(program.written(), allocator, context, 0);
10681069
10691070 for (0..32) |i| {
10701071 const expected = 31 - i;
......@@ -1108,16 +1109,16 @@ test "DWARF expressions" {
11081109 var mock_compile_unit: std.debug.Dwarf.CompileUnit = undefined;
11091110 mock_compile_unit.addr_base = 1;
11101111
1111 var mock_debug_addr = std.array_list.Managed(u8).init(allocator);
1112 var mock_debug_addr: std.Io.Writer.Allocating = .init(allocator);
11121113 defer mock_debug_addr.deinit();
11131114
1114 try mock_debug_addr.writer().writeInt(u16, 0, native_endian);
1115 try mock_debug_addr.writer().writeInt(usize, input[11], native_endian);
1116 try mock_debug_addr.writer().writeInt(usize, input[12], native_endian);
1115 try mock_debug_addr.writer.writeInt(u16, 0, native_endian);
1116 try mock_debug_addr.writer.writeInt(usize, input[11], native_endian);
1117 try mock_debug_addr.writer.writeInt(usize, input[12], native_endian);
11171118
1118 const context = Context{
1119 const context: Context = .{
11191120 .compile_unit = &mock_compile_unit,
1120 .debug_addr = mock_debug_addr.items,
1121 .debug_addr = mock_debug_addr.written(),
11211122 };
11221123
11231124 try b.writeConstx(writer, @as(usize, 1));
......@@ -1127,7 +1128,7 @@ test "DWARF expressions" {
11271128 const type_bytes: []const u8 = &.{ 1, 2, 3, 4 };
11281129 try b.writeConstType(writer, die_offset, type_bytes);
11291130
1130 _ = try stack_machine.run(program.items, allocator, context, 0);
1131 _ = try stack_machine.run(program.written(), allocator, context, 0);
11311132
11321133 const const_type = stack_machine.stack.pop().?.const_type;
11331134 try testing.expectEqual(die_offset, const_type.type_offset);
......@@ -1185,7 +1186,7 @@ test "DWARF expressions" {
11851186 try b.writeBregx(writer, abi.ipRegNum(native_arch).?, @as(usize, 300));
11861187 try b.writeRegvalType(writer, @as(u8, 0), @as(usize, 400));
11871188
1188 _ = try stack_machine.run(program.items, allocator, context, 0);
1189 _ = try stack_machine.run(program.written(), allocator, context, 0);
11891190
11901191 const regval_type = stack_machine.stack.pop().?.regval_type;
11911192 try testing.expectEqual(@as(usize, 400), regval_type.type_offset);
......@@ -1214,7 +1215,7 @@ test "DWARF expressions" {
12141215 program.clearRetainingCapacity();
12151216 try b.writeConst(writer, u8, 1);
12161217 try b.writeOpcode(writer, OP.dup);
1217 _ = try stack_machine.run(program.items, allocator, context, null);
1218 _ = try stack_machine.run(program.written(), allocator, context, null);
12181219 try testing.expectEqual(@as(usize, 1), stack_machine.stack.pop().?.generic);
12191220 try testing.expectEqual(@as(usize, 1), stack_machine.stack.pop().?.generic);
12201221
......@@ -1222,7 +1223,7 @@ test "DWARF expressions" {
12221223 program.clearRetainingCapacity();
12231224 try b.writeConst(writer, u8, 1);
12241225 try b.writeOpcode(writer, OP.drop);
1225 _ = try stack_machine.run(program.items, allocator, context, null);
1226 _ = try stack_machine.run(program.written(), allocator, context, null);
12261227 try testing.expect(stack_machine.stack.pop() == null);
12271228
12281229 stack_machine.reset();
......@@ -1231,7 +1232,7 @@ test "DWARF expressions" {
12311232 try b.writeConst(writer, u8, 5);
12321233 try b.writeConst(writer, u8, 6);
12331234 try b.writePick(writer, 2);
1234 _ = try stack_machine.run(program.items, allocator, context, null);
1235 _ = try stack_machine.run(program.written(), allocator, context, null);
12351236 try testing.expectEqual(@as(usize, 4), stack_machine.stack.pop().?.generic);
12361237
12371238 stack_machine.reset();
......@@ -1240,7 +1241,7 @@ test "DWARF expressions" {
12401241 try b.writeConst(writer, u8, 5);
12411242 try b.writeConst(writer, u8, 6);
12421243 try b.writeOpcode(writer, OP.over);
1243 _ = try stack_machine.run(program.items, allocator, context, null);
1244 _ = try stack_machine.run(program.written(), allocator, context, null);
12441245 try testing.expectEqual(@as(usize, 5), stack_machine.stack.pop().?.generic);
12451246
12461247 stack_machine.reset();
......@@ -1248,7 +1249,7 @@ test "DWARF expressions" {
12481249 try b.writeConst(writer, u8, 5);
12491250 try b.writeConst(writer, u8, 6);
12501251 try b.writeOpcode(writer, OP.swap);
1251 _ = try stack_machine.run(program.items, allocator, context, null);
1252 _ = try stack_machine.run(program.written(), allocator, context, null);
12521253 try testing.expectEqual(@as(usize, 5), stack_machine.stack.pop().?.generic);
12531254 try testing.expectEqual(@as(usize, 6), stack_machine.stack.pop().?.generic);
12541255
......@@ -1258,7 +1259,7 @@ test "DWARF expressions" {
12581259 try b.writeConst(writer, u8, 5);
12591260 try b.writeConst(writer, u8, 6);
12601261 try b.writeOpcode(writer, OP.rot);
1261 _ = try stack_machine.run(program.items, allocator, context, null);
1262 _ = try stack_machine.run(program.written(), allocator, context, null);
12621263 try testing.expectEqual(@as(usize, 5), stack_machine.stack.pop().?.generic);
12631264 try testing.expectEqual(@as(usize, 4), stack_machine.stack.pop().?.generic);
12641265 try testing.expectEqual(@as(usize, 6), stack_machine.stack.pop().?.generic);
......@@ -1269,7 +1270,7 @@ test "DWARF expressions" {
12691270 program.clearRetainingCapacity();
12701271 try b.writeAddr(writer, @intFromPtr(&deref_target));
12711272 try b.writeOpcode(writer, OP.deref);
1272 _ = try stack_machine.run(program.items, allocator, context, null);
1273 _ = try stack_machine.run(program.written(), allocator, context, null);
12731274 try testing.expectEqual(deref_target, stack_machine.stack.pop().?.generic);
12741275
12751276 stack_machine.reset();
......@@ -1277,14 +1278,14 @@ test "DWARF expressions" {
12771278 try b.writeLiteral(writer, 0);
12781279 try b.writeAddr(writer, @intFromPtr(&deref_target));
12791280 try b.writeOpcode(writer, OP.xderef);
1280 _ = try stack_machine.run(program.items, allocator, context, null);
1281 _ = try stack_machine.run(program.written(), allocator, context, null);
12811282 try testing.expectEqual(deref_target, stack_machine.stack.pop().?.generic);
12821283
12831284 stack_machine.reset();
12841285 program.clearRetainingCapacity();
12851286 try b.writeAddr(writer, @intFromPtr(&deref_target));
12861287 try b.writeDerefSize(writer, 1);
1287 _ = try stack_machine.run(program.items, allocator, context, null);
1288 _ = try stack_machine.run(program.written(), allocator, context, null);
12881289 try testing.expectEqual(@as(usize, @as(*const u8, @ptrCast(&deref_target)).*), stack_machine.stack.pop().?.generic);
12891290
12901291 stack_machine.reset();
......@@ -1292,7 +1293,7 @@ test "DWARF expressions" {
12921293 try b.writeLiteral(writer, 0);
12931294 try b.writeAddr(writer, @intFromPtr(&deref_target));
12941295 try b.writeXDerefSize(writer, 1);
1295 _ = try stack_machine.run(program.items, allocator, context, null);
1296 _ = try stack_machine.run(program.written(), allocator, context, null);
12961297 try testing.expectEqual(@as(usize, @as(*const u8, @ptrCast(&deref_target)).*), stack_machine.stack.pop().?.generic);
12971298
12981299 const type_offset: usize = @truncate(0xaabbaabb_aabbaabb);
......@@ -1301,7 +1302,7 @@ test "DWARF expressions" {
13011302 program.clearRetainingCapacity();
13021303 try b.writeAddr(writer, @intFromPtr(&deref_target));
13031304 try b.writeDerefType(writer, 1, type_offset);
1304 _ = try stack_machine.run(program.items, allocator, context, null);
1305 _ = try stack_machine.run(program.written(), allocator, context, null);
13051306 const deref_type = stack_machine.stack.pop().?.regval_type;
13061307 try testing.expectEqual(type_offset, deref_type.type_offset);
13071308 try testing.expectEqual(@as(u8, 1), deref_type.type_size);
......@@ -1312,7 +1313,7 @@ test "DWARF expressions" {
13121313 try b.writeLiteral(writer, 0);
13131314 try b.writeAddr(writer, @intFromPtr(&deref_target));
13141315 try b.writeXDerefType(writer, 1, type_offset);
1315 _ = try stack_machine.run(program.items, allocator, context, null);
1316 _ = try stack_machine.run(program.written(), allocator, context, null);
13161317 const xderef_type = stack_machine.stack.pop().?.regval_type;
13171318 try testing.expectEqual(type_offset, xderef_type.type_offset);
13181319 try testing.expectEqual(@as(u8, 1), xderef_type.type_size);
......@@ -1323,7 +1324,7 @@ test "DWARF expressions" {
13231324 stack_machine.reset();
13241325 program.clearRetainingCapacity();
13251326 try b.writeOpcode(writer, OP.push_object_address);
1326 _ = try stack_machine.run(program.items, allocator, context, null);
1327 _ = try stack_machine.run(program.written(), allocator, context, null);
13271328 try testing.expectEqual(@as(usize, @intFromPtr(context.object_address.?)), stack_machine.stack.pop().?.generic);
13281329
13291330 // TODO: Test OP.form_tls_address
......@@ -1333,7 +1334,7 @@ test "DWARF expressions" {
13331334 stack_machine.reset();
13341335 program.clearRetainingCapacity();
13351336 try b.writeOpcode(writer, OP.call_frame_cfa);
1336 _ = try stack_machine.run(program.items, allocator, context, null);
1337 _ = try stack_machine.run(program.written(), allocator, context, null);
13371338 try testing.expectEqual(context.cfa.?, stack_machine.stack.pop().?.generic);
13381339 }
13391340
......@@ -1345,7 +1346,7 @@ test "DWARF expressions" {
13451346 program.clearRetainingCapacity();
13461347 try b.writeConst(writer, i16, -4096);
13471348 try b.writeOpcode(writer, OP.abs);
1348 _ = try stack_machine.run(program.items, allocator, context, null);
1349 _ = try stack_machine.run(program.written(), allocator, context, null);
13491350 try testing.expectEqual(@as(usize, 4096), stack_machine.stack.pop().?.generic);
13501351
13511352 stack_machine.reset();
......@@ -1353,7 +1354,7 @@ test "DWARF expressions" {
13531354 try b.writeConst(writer, u16, 0xff0f);
13541355 try b.writeConst(writer, u16, 0xf0ff);
13551356 try b.writeOpcode(writer, OP.@"and");
1356 _ = try stack_machine.run(program.items, allocator, context, null);
1357 _ = try stack_machine.run(program.written(), allocator, context, null);
13571358 try testing.expectEqual(@as(usize, 0xf00f), stack_machine.stack.pop().?.generic);
13581359
13591360 stack_machine.reset();
......@@ -1361,7 +1362,7 @@ test "DWARF expressions" {
13611362 try b.writeConst(writer, i16, -404);
13621363 try b.writeConst(writer, i16, 100);
13631364 try b.writeOpcode(writer, OP.div);
1364 _ = try stack_machine.run(program.items, allocator, context, null);
1365 _ = try stack_machine.run(program.written(), allocator, context, null);
13651366 try testing.expectEqual(@as(isize, -404 / 100), @as(isize, @bitCast(stack_machine.stack.pop().?.generic)));
13661367
13671368 stack_machine.reset();
......@@ -1369,7 +1370,7 @@ test "DWARF expressions" {
13691370 try b.writeConst(writer, u16, 200);
13701371 try b.writeConst(writer, u16, 50);
13711372 try b.writeOpcode(writer, OP.minus);
1372 _ = try stack_machine.run(program.items, allocator, context, null);
1373 _ = try stack_machine.run(program.written(), allocator, context, null);
13731374 try testing.expectEqual(@as(usize, 150), stack_machine.stack.pop().?.generic);
13741375
13751376 stack_machine.reset();
......@@ -1377,7 +1378,7 @@ test "DWARF expressions" {
13771378 try b.writeConst(writer, u16, 123);
13781379 try b.writeConst(writer, u16, 100);
13791380 try b.writeOpcode(writer, OP.mod);
1380 _ = try stack_machine.run(program.items, allocator, context, null);
1381 _ = try stack_machine.run(program.written(), allocator, context, null);
13811382 try testing.expectEqual(@as(usize, 23), stack_machine.stack.pop().?.generic);
13821383
13831384 stack_machine.reset();
......@@ -1385,7 +1386,7 @@ test "DWARF expressions" {
13851386 try b.writeConst(writer, u16, 0xff);
13861387 try b.writeConst(writer, u16, 0xee);
13871388 try b.writeOpcode(writer, OP.mul);
1388 _ = try stack_machine.run(program.items, allocator, context, null);
1389 _ = try stack_machine.run(program.written(), allocator, context, null);
13891390 try testing.expectEqual(@as(usize, 0xed12), stack_machine.stack.pop().?.generic);
13901391
13911392 stack_machine.reset();
......@@ -1394,7 +1395,7 @@ test "DWARF expressions" {
13941395 try b.writeOpcode(writer, OP.neg);
13951396 try b.writeConst(writer, i16, -6);
13961397 try b.writeOpcode(writer, OP.neg);
1397 _ = try stack_machine.run(program.items, allocator, context, null);
1398 _ = try stack_machine.run(program.written(), allocator, context, null);
13981399 try testing.expectEqual(@as(usize, 6), stack_machine.stack.pop().?.generic);
13991400 try testing.expectEqual(@as(isize, -5), @as(isize, @bitCast(stack_machine.stack.pop().?.generic)));
14001401
......@@ -1402,7 +1403,7 @@ test "DWARF expressions" {
14021403 program.clearRetainingCapacity();
14031404 try b.writeConst(writer, u16, 0xff0f);
14041405 try b.writeOpcode(writer, OP.not);
1405 _ = try stack_machine.run(program.items, allocator, context, null);
1406 _ = try stack_machine.run(program.written(), allocator, context, null);
14061407 try testing.expectEqual(~@as(usize, 0xff0f), stack_machine.stack.pop().?.generic);
14071408
14081409 stack_machine.reset();
......@@ -1410,7 +1411,7 @@ test "DWARF expressions" {
14101411 try b.writeConst(writer, u16, 0xff0f);
14111412 try b.writeConst(writer, u16, 0xf0ff);
14121413 try b.writeOpcode(writer, OP.@"or");
1413 _ = try stack_machine.run(program.items, allocator, context, null);
1414 _ = try stack_machine.run(program.written(), allocator, context, null);
14141415 try testing.expectEqual(@as(usize, 0xffff), stack_machine.stack.pop().?.generic);
14151416
14161417 stack_machine.reset();
......@@ -1418,14 +1419,14 @@ test "DWARF expressions" {
14181419 try b.writeConst(writer, i16, 402);
14191420 try b.writeConst(writer, i16, 100);
14201421 try b.writeOpcode(writer, OP.plus);
1421 _ = try stack_machine.run(program.items, allocator, context, null);
1422 _ = try stack_machine.run(program.written(), allocator, context, null);
14221423 try testing.expectEqual(@as(usize, 502), stack_machine.stack.pop().?.generic);
14231424
14241425 stack_machine.reset();
14251426 program.clearRetainingCapacity();
14261427 try b.writeConst(writer, u16, 4096);
14271428 try b.writePlusUconst(writer, @as(usize, 8192));
1428 _ = try stack_machine.run(program.items, allocator, context, null);
1429 _ = try stack_machine.run(program.written(), allocator, context, null);
14291430 try testing.expectEqual(@as(usize, 4096 + 8192), stack_machine.stack.pop().?.generic);
14301431
14311432 stack_machine.reset();
......@@ -1433,7 +1434,7 @@ test "DWARF expressions" {
14331434 try b.writeConst(writer, u16, 0xfff);
14341435 try b.writeConst(writer, u16, 1);
14351436 try b.writeOpcode(writer, OP.shl);
1436 _ = try stack_machine.run(program.items, allocator, context, null);
1437 _ = try stack_machine.run(program.written(), allocator, context, null);
14371438 try testing.expectEqual(@as(usize, 0xfff << 1), stack_machine.stack.pop().?.generic);
14381439
14391440 stack_machine.reset();
......@@ -1441,7 +1442,7 @@ test "DWARF expressions" {
14411442 try b.writeConst(writer, u16, 0xfff);
14421443 try b.writeConst(writer, u16, 1);
14431444 try b.writeOpcode(writer, OP.shr);
1444 _ = try stack_machine.run(program.items, allocator, context, null);
1445 _ = try stack_machine.run(program.written(), allocator, context, null);
14451446 try testing.expectEqual(@as(usize, 0xfff >> 1), stack_machine.stack.pop().?.generic);
14461447
14471448 stack_machine.reset();
......@@ -1449,7 +1450,7 @@ test "DWARF expressions" {
14491450 try b.writeConst(writer, u16, 0xfff);
14501451 try b.writeConst(writer, u16, 1);
14511452 try b.writeOpcode(writer, OP.shr);
1452 _ = try stack_machine.run(program.items, allocator, context, null);
1453 _ = try stack_machine.run(program.written(), allocator, context, null);
14531454 try testing.expectEqual(@as(usize, @bitCast(@as(isize, 0xfff) >> 1)), stack_machine.stack.pop().?.generic);
14541455
14551456 stack_machine.reset();
......@@ -1457,7 +1458,7 @@ test "DWARF expressions" {
14571458 try b.writeConst(writer, u16, 0xf0ff);
14581459 try b.writeConst(writer, u16, 0xff0f);
14591460 try b.writeOpcode(writer, OP.xor);
1460 _ = try stack_machine.run(program.items, allocator, context, null);
1461 _ = try stack_machine.run(program.written(), allocator, context, null);
14611462 try testing.expectEqual(@as(usize, 0x0ff0), stack_machine.stack.pop().?.generic);
14621463 }
14631464
......@@ -1486,7 +1487,7 @@ test "DWARF expressions" {
14861487 try b.writeConst(writer, u16, 1);
14871488 try b.writeConst(writer, u16, 0);
14881489 try b.writeOpcode(writer, e[0]);
1489 _ = try stack_machine.run(program.items, allocator, context, null);
1490 _ = try stack_machine.run(program.written(), allocator, context, null);
14901491 try testing.expectEqual(@as(usize, e[3]), stack_machine.stack.pop().?.generic);
14911492 try testing.expectEqual(@as(usize, e[2]), stack_machine.stack.pop().?.generic);
14921493 try testing.expectEqual(@as(usize, e[1]), stack_machine.stack.pop().?.generic);
......@@ -1497,7 +1498,7 @@ test "DWARF expressions" {
14971498 try b.writeLiteral(writer, 2);
14981499 try b.writeSkip(writer, 1);
14991500 try b.writeLiteral(writer, 3);
1500 _ = try stack_machine.run(program.items, allocator, context, null);
1501 _ = try stack_machine.run(program.written(), allocator, context, null);
15011502 try testing.expectEqual(@as(usize, 2), stack_machine.stack.pop().?.generic);
15021503
15031504 stack_machine.reset();
......@@ -1509,7 +1510,7 @@ test "DWARF expressions" {
15091510 try b.writeBra(writer, 1);
15101511 try b.writeLiteral(writer, 4);
15111512 try b.writeLiteral(writer, 5);
1512 _ = try stack_machine.run(program.items, allocator, context, null);
1513 _ = try stack_machine.run(program.written(), allocator, context, null);
15131514 try testing.expectEqual(@as(usize, 5), stack_machine.stack.pop().?.generic);
15141515 try testing.expectEqual(@as(usize, 4), stack_machine.stack.pop().?.generic);
15151516 try testing.expect(stack_machine.stack.pop() == null);
......@@ -1535,7 +1536,7 @@ test "DWARF expressions" {
15351536 program.clearRetainingCapacity();
15361537 try b.writeConstType(writer, @as(usize, 0), &value_bytes);
15371538 try b.writeConvert(writer, @as(usize, 0));
1538 _ = try stack_machine.run(program.items, allocator, context, null);
1539 _ = try stack_machine.run(program.written(), allocator, context, null);
15391540 try testing.expectEqual(value, stack_machine.stack.pop().?.generic);
15401541
15411542 // Reinterpret to generic type
......@@ -1543,7 +1544,7 @@ test "DWARF expressions" {
15431544 program.clearRetainingCapacity();
15441545 try b.writeConstType(writer, @as(usize, 0), &value_bytes);
15451546 try b.writeReinterpret(writer, @as(usize, 0));
1546 _ = try stack_machine.run(program.items, allocator, context, null);
1547 _ = try stack_machine.run(program.written(), allocator, context, null);
15471548 try testing.expectEqual(value, stack_machine.stack.pop().?.generic);
15481549
15491550 // Reinterpret to new type
......@@ -1553,7 +1554,7 @@ test "DWARF expressions" {
15531554 program.clearRetainingCapacity();
15541555 try b.writeConstType(writer, @as(usize, 0), &value_bytes);
15551556 try b.writeReinterpret(writer, die_offset);
1556 _ = try stack_machine.run(program.items, allocator, context, null);
1557 _ = try stack_machine.run(program.written(), allocator, context, null);
15571558 const const_type = stack_machine.stack.pop().?.const_type;
15581559 try testing.expectEqual(die_offset, const_type.type_offset);
15591560
......@@ -1561,7 +1562,7 @@ test "DWARF expressions" {
15611562 program.clearRetainingCapacity();
15621563 try b.writeLiteral(writer, 0);
15631564 try b.writeReinterpret(writer, die_offset);
1564 _ = try stack_machine.run(program.items, allocator, context, null);
1565 _ = try stack_machine.run(program.written(), allocator, context, null);
15651566 const regval_type = stack_machine.stack.pop().?.regval_type;
15661567 try testing.expectEqual(die_offset, regval_type.type_offset);
15671568 }
......@@ -1573,20 +1574,20 @@ test "DWARF expressions" {
15731574 stack_machine.reset();
15741575 program.clearRetainingCapacity();
15751576 try b.writeOpcode(writer, OP.nop);
1576 _ = try stack_machine.run(program.items, allocator, context, null);
1577 _ = try stack_machine.run(program.written(), allocator, context, null);
15771578 try testing.expect(stack_machine.stack.pop() == null);
15781579
15791580 // Sub-expression
15801581 {
1581 var sub_program = std.array_list.Managed(u8).init(allocator);
1582 var sub_program: std.Io.Writer.Allocating = .init(allocator);
15821583 defer sub_program.deinit();
1583 const sub_writer = sub_program.writer();
1584 const sub_writer = &sub_program.writer;
15841585 try b.writeLiteral(sub_writer, 3);
15851586
15861587 stack_machine.reset();
15871588 program.clearRetainingCapacity();
1588 try b.writeEntryValue(writer, sub_program.items);
1589 _ = try stack_machine.run(program.items, allocator, context, null);
1589 try b.writeEntryValue(writer, sub_program.written());
1590 _ = try stack_machine.run(program.written(), allocator, context, null);
15901591 try testing.expectEqual(@as(usize, 3), stack_machine.stack.pop().?.generic);
15911592 }
15921593
......@@ -1605,15 +1606,15 @@ test "DWARF expressions" {
16051606 if (abi.regBytes(&thread_context, 0, reg_context)) |reg_bytes| {
16061607 mem.writeInt(usize, reg_bytes[0..@sizeOf(usize)], 0xee, native_endian);
16071608
1608 var sub_program = std.array_list.Managed(u8).init(allocator);
1609 var sub_program: std.Io.Writer.Allocating = .init(allocator);
16091610 defer sub_program.deinit();
1610 const sub_writer = sub_program.writer();
1611 const sub_writer = &sub_program.writer;
16111612 try b.writeReg(sub_writer, 0);
16121613
16131614 stack_machine.reset();
16141615 program.clearRetainingCapacity();
1615 try b.writeEntryValue(writer, sub_program.items);
1616 _ = try stack_machine.run(program.items, allocator, context, null);
1616 try b.writeEntryValue(writer, sub_program.written());
1617 _ = try stack_machine.run(program.written(), allocator, context, null);
16171618 try testing.expectEqual(@as(usize, 0xee), stack_machine.stack.pop().?.generic);
16181619 } else |err| {
16191620 switch (err) {
lib/std/leb128.zig-103
......@@ -33,28 +33,6 @@ pub fn readUleb128(comptime T: type, reader: anytype) !T {
3333 return @as(T, @truncate(value));
3434}
3535
36/// Write a single unsigned integer as unsigned LEB128 to the given writer.
37pub fn writeUleb128(writer: anytype, arg: anytype) !void {
38 const Arg = @TypeOf(arg);
39 const Int = switch (Arg) {
40 comptime_int => std.math.IntFittingRange(arg, arg),
41 else => Arg,
42 };
43 const Value = if (@typeInfo(Int).int.bits < 8) u8 else Int;
44 var value: Value = arg;
45
46 while (true) {
47 const byte: u8 = @truncate(value & 0x7f);
48 value >>= 7;
49 if (value == 0) {
50 try writer.writeByte(byte);
51 break;
52 } else {
53 try writer.writeByte(byte | 0x80);
54 }
55 }
56}
57
5836/// Read a single signed LEB128 value from the given reader as type T,
5937/// or error.Overflow if the value cannot fit.
6038pub fn readIleb128(comptime T: type, reader: anytype) !T {
......@@ -374,84 +352,3 @@ test "deserialize unsigned LEB128" {
374352 // Decode sequence of ULEB128 values
375353 try test_read_uleb128_seq(u64, 4, "\x81\x01\x3f\x80\x7f\x80\x80\x80\x00");
376354}
377
378fn test_write_leb128(value: anytype) !void {
379 const T = @TypeOf(value);
380 const signedness = @typeInfo(T).int.signedness;
381 const t_signed = signedness == .signed;
382
383 const writeStream = if (t_signed) writeIleb128 else writeUleb128;
384 const readStream = if (t_signed) readIleb128 else readUleb128;
385
386 // decode to a larger bit size too, to ensure sign extension
387 // is working as expected
388 const larger_type_bits = ((@typeInfo(T).int.bits + 8) / 8) * 8;
389 const B = std.meta.Int(signedness, larger_type_bits);
390
391 const bytes_needed = bn: {
392 if (@typeInfo(T).int.bits <= 7) break :bn @as(u16, 1);
393
394 const unused_bits = if (value < 0) @clz(~value) else @clz(value);
395 const used_bits: u16 = (@typeInfo(T).int.bits - unused_bits) + @intFromBool(t_signed);
396 if (used_bits <= 7) break :bn @as(u16, 1);
397 break :bn ((used_bits + 6) / 7);
398 };
399
400 const max_groups = if (@typeInfo(T).int.bits == 0) 1 else (@typeInfo(T).int.bits + 6) / 7;
401
402 var buf: [max_groups]u8 = undefined;
403 var fbs = std.io.fixedBufferStream(&buf);
404
405 // stream write
406 try writeStream(fbs.writer(), value);
407 const w1_pos = fbs.pos;
408 try testing.expect(w1_pos == bytes_needed);
409
410 // stream read
411 fbs.pos = 0;
412 const sr = try readStream(T, fbs.reader());
413 try testing.expect(fbs.pos == w1_pos);
414 try testing.expect(sr == value);
415
416 // bigger type stream read
417 fbs.pos = 0;
418 const bsr = try readStream(B, fbs.reader());
419 try testing.expect(fbs.pos == w1_pos);
420 try testing.expect(bsr == value);
421}
422
423test "serialize unsigned LEB128" {
424 if (builtin.cpu.arch == .x86 and builtin.abi == .musl and builtin.link_mode == .dynamic) return error.SkipZigTest;
425
426 const max_bits = 18;
427
428 comptime var t = 0;
429 inline while (t <= max_bits) : (t += 1) {
430 const T = std.meta.Int(.unsigned, t);
431 const min = std.math.minInt(T);
432 const max = std.math.maxInt(T);
433 var i = @as(std.meta.Int(.unsigned, @typeInfo(T).int.bits + 1), min);
434
435 while (i <= max) : (i += 1) try test_write_leb128(@as(T, @intCast(i)));
436 }
437}
438
439test "serialize signed LEB128" {
440 if (builtin.cpu.arch == .x86 and builtin.abi == .musl and builtin.link_mode == .dynamic) return error.SkipZigTest;
441
442 // explicitly test i0 because starting `t` at 0
443 // will break the while loop
444 try test_write_leb128(@as(i0, 0));
445
446 const max_bits = 18;
447
448 comptime var t = 1;
449 inline while (t <= max_bits) : (t += 1) {
450 const T = std.meta.Int(.signed, t);
451 const min = std.math.minInt(T);
452 const max = std.math.maxInt(T);
453 var i = @as(std.meta.Int(.signed, @typeInfo(T).int.bits + 1), min);
454
455 while (i <= max) : (i += 1) try test_write_leb128(@as(T, @intCast(i)));
456 }
457}
lib/std/posix/test.zig+2-2
......@@ -683,11 +683,11 @@ test "mmap" {
683683 const file = try tmp.dir.createFile(test_out_file, .{});
684684 defer file.close();
685685
686 const stream = file.deprecatedWriter();
686 var stream = file.writer(&.{});
687687
688688 var i: u32 = 0;
689689 while (i < alloc_size / @sizeOf(u32)) : (i += 1) {
690 try stream.writeInt(u32, i, .little);
690 try stream.interface.writeInt(u32, i, .little);
691691 }
692692 }
693693