authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-07 21:47:32-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-07 22:43:53-07:00
log043079d7655efefbec97d8338b7d7fa3f9fcbdb0
treef8854e91cd66e0366401f3cd9f2878efe1ce0a28
parenta983f5b90f21c09ccc9e3fca1565b1b84b540307

std.io.Writer.VectorWrapper: fix vtable not being a unique addr


2 files changed, 7 insertions(+), 4 deletions(-)

lib/std/io/Reader.zig+2-2
...@@ -323,7 +323,7 @@ pub fn readVecLimit(r: *Reader, data: []const []u8, limit: Limit) Error!usize {...@@ -323,7 +323,7 @@ pub fn readVecLimit(r: *Reader, data: []const []u8, limit: Limit) Error!usize {
323 },323 },
324 .writer = .{324 .writer = .{
325 .buffer = if (first.len >= r.buffer.len) first else r.buffer,325 .buffer = if (first.len >= r.buffer.len) first else r.buffer,
326 .vtable = &Writer.VectorWrapper.vtable,326 .vtable = Writer.VectorWrapper.vtable,
327 },327 },
328 };328 };
329 var n = r.vtable.stream(r, &wrapper.writer, .limited(remaining)) catch |err| switch (err) {329 var n = r.vtable.stream(r, &wrapper.writer, .limited(remaining)) catch |err| switch (err) {
...@@ -599,7 +599,7 @@ pub fn readSliceShort(r: *Reader, buffer: []u8) ShortError!usize {...@@ -599,7 +599,7 @@ pub fn readSliceShort(r: *Reader, buffer: []u8) ShortError!usize {
599 },599 },
600 .writer = .{600 .writer = .{
601 .buffer = if (remaining.len >= r.buffer.len) remaining else r.buffer,601 .buffer = if (remaining.len >= r.buffer.len) remaining else r.buffer,
602 .vtable = &Writer.VectorWrapper.vtable,602 .vtable = Writer.VectorWrapper.vtable,
603 },603 },
604 };604 };
605 const n = r.vtable.stream(r, &wrapper.writer, .unlimited) catch |err| switch (err) {605 const n = r.vtable.stream(r, &wrapper.writer, .unlimited) catch |err| switch (err) {
lib/std/io/Writer.zig+5-2
...@@ -392,11 +392,14 @@ pub const VectorWrapper = struct {...@@ -392,11 +392,14 @@ pub const VectorWrapper = struct {
392 it: WritableVectorIterator,392 it: WritableVectorIterator,
393 /// Tracks whether the "writable vector" API was used.393 /// Tracks whether the "writable vector" API was used.
394 used: bool = false,394 used: bool = false,
395 pub const vtable: VTable = .{ .drain = fixedDrain };395 pub const vtable: *const VTable = &unique_vtable_allocation;
396 /// This is intended to be constant but it must be a unique address for
397 /// `@fieldParentPtr` to work.
398 var unique_vtable_allocation: VTable = .{ .drain = fixedDrain };
396};399};
397400
398pub fn writableVectorIterator(w: *Writer) Error!WritableVectorIterator {401pub fn writableVectorIterator(w: *Writer) Error!WritableVectorIterator {
399 if (w.vtable == &VectorWrapper.vtable) {402 if (w.vtable == VectorWrapper.vtable) {
400 const wrapper: *VectorWrapper = @fieldParentPtr("writer", w);403 const wrapper: *VectorWrapper = @fieldParentPtr("writer", w);
401 wrapper.used = true;404 wrapper.used = true;
402 return wrapper.it;405 return wrapper.it;