diff --git a/lib/std/array_list.zig b/lib/std/array_list.zig index e8675fde61ce..727f5308b1d5 100644 --- a/lib/std/array_list.zig +++ b/lib/std/array_list.zig @@ -270,11 +270,11 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { @compileError("The Writer interface is only defined for ArrayList(u8) " ++ "but the given type is ArrayList(" ++ @typeName(T) ++ ")") else - std.io.Writer(*Self, error{OutOfMemory}, appendWrite); + std.io.Writer(error{OutOfMemory}); /// Initializes a Writer which will append to the list. pub fn writer(self: *Self) Writer { - return .{ .context = self }; + return Writer.init(self, appendWrite); } /// Same as `append` except it returns the number of bytes written, which is always the same @@ -688,25 +688,6 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ allocator: Allocator, }; - pub const Writer = if (T != u8) - @compileError("The Writer interface is only defined for ArrayList(u8) " ++ - "but the given type is ArrayList(" ++ @typeName(T) ++ ")") - else - std.io.Writer(WriterContext, error{OutOfMemory}, appendWrite); - - /// Initializes a Writer which will append to the list. - pub fn writer(self: *Self, allocator: Allocator) Writer { - return .{ .context = .{ .self = self, .allocator = allocator } }; - } - - /// Same as `append` except it returns the number of bytes written, which is always the same - /// as `m.len`. The purpose of this function existing is to match `std.io.Writer` API. - /// Invalidates pointers if additional memory is needed. - fn appendWrite(context: WriterContext, m: []const u8) Allocator.Error!usize { - try context.self.appendSlice(context.allocator, m); - return m.len; - } - /// Append a value to the list `n` times. /// Allocates more memory as necessary. /// Invalidates pointers if additional memory is needed. diff --git a/lib/std/fs/file.zig b/lib/std/fs/file.zig index a1e81c9b9418..124af7e54e76 100644 --- a/lib/std/fs/file.zig +++ b/lib/std/fs/file.zig @@ -1372,16 +1372,34 @@ pub const File = struct { } } - pub const Reader = io.Reader(File, ReadError, read); + pub const Reader = io.Reader(ReadError); + + pub fn reader(file: *const File) Reader { + // HACK: The Reader interface expects a mutable pointer to context, but there is no need + // to have that here, as `readFn` never modifies the memory of the `File` struct. + // We want the `Reader` interface to handle these kinds of situations, but sadly + // there is no way to discard const and compile time, so that would mean that + // `FixedBufferStream` could not be used in that context. + return Reader.init(@intToPtr(*File, @ptrToInt(file)), readFn); + } - pub fn reader(file: File) Reader { - return .{ .context = file }; + fn readFn(self: *File, buffer: []u8) ReadError!usize { + return self.read(buffer); } - pub const Writer = io.Writer(File, WriteError, write); + pub const Writer = io.Writer(WriteError); - pub fn writer(file: File) Writer { - return .{ .context = file }; + pub fn writer(file: *const File) Writer { + // HACK: The Writer interface expects a mutable pointer to context, but there is no need + // to have that here, as `writeFn` never modifies the memory of the `File` struct. + // We want the `Writer` interface to handle these kinds of situations, but sadly + // there is no way to discard const and compile time, so that would mean that + // `FixedBufferStream` could not be used in that context. + return Writer.init(@intToPtr(*File, @ptrToInt(file)), writeFn); + } + + fn writeFn(self: *File, bytes: []const u8) WriteError!usize { + return self.write(bytes); } pub const SeekableStream = io.SeekableStream( diff --git a/lib/std/io.zig b/lib/std/io.zig index b12ca80142ab..15147e70b921 100644 --- a/lib/std/io.zig +++ b/lib/std/io.zig @@ -162,10 +162,13 @@ pub const BufferedAtomicFile = @import("io/buffered_atomic_file.zig").BufferedAt pub const StreamSource = @import("io/stream_source.zig").StreamSource; /// A Writer that doesn't write to anything. -pub const null_writer = @as(NullWriter, .{ .context = {} }); +pub const null_writer = NullWriter{ + .context = undefined, + .writeFn = dummyWrite, +}; -const NullWriter = Writer(void, error{}, dummyWrite); -fn dummyWrite(context: void, data: []const u8) error{}!usize { +const NullWriter = Writer(error{}); +fn dummyWrite(context: *anyopaque, data: []const u8) error{}!usize { _ = context; return data.len; } diff --git a/lib/std/io/buffered_writer.zig b/lib/std/io/buffered_writer.zig index 497a1810a7e1..b84d909a78c9 100644 --- a/lib/std/io/buffered_writer.zig +++ b/lib/std/io/buffered_writer.zig @@ -10,7 +10,7 @@ pub fn BufferedWriter(comptime buffer_size: usize, comptime WriterType: type) ty end: usize = 0, pub const Error = WriterType.Error; - pub const Writer = io.Writer(*Self, Error, write); + pub const Writer = io.Writer(Error); const Self = @This(); @@ -20,7 +20,7 @@ pub fn BufferedWriter(comptime buffer_size: usize, comptime WriterType: type) ty } pub fn writer(self: *Self) Writer { - return .{ .context = self }; + return Writer.init(self, write); } pub fn write(self: *Self, bytes: []const u8) Error!usize { diff --git a/lib/std/io/counting_reader.zig b/lib/std/io/counting_reader.zig index 54e8e6f531a3..c49da91b62bf 100644 --- a/lib/std/io/counting_reader.zig +++ b/lib/std/io/counting_reader.zig @@ -9,7 +9,7 @@ pub fn CountingReader(comptime ReaderType: anytype) type { bytes_read: u64 = 0, pub const Error = ReaderType.Error; - pub const Reader = io.Reader(*@This(), Error, read); + pub const Reader = io.Reader(Error); pub fn read(self: *@This(), buf: []u8) Error!usize { const amt = try self.child_reader.read(buf); @@ -18,7 +18,7 @@ pub fn CountingReader(comptime ReaderType: anytype) type { } pub fn reader(self: *@This()) Reader { - return .{ .context = self }; + return Reader.init(self, read); } }; } diff --git a/lib/std/io/counting_writer.zig b/lib/std/io/counting_writer.zig index ee86c2a9b1e0..6d6bbfe638c9 100644 --- a/lib/std/io/counting_writer.zig +++ b/lib/std/io/counting_writer.zig @@ -9,7 +9,7 @@ pub fn CountingWriter(comptime WriterType: type) type { child_stream: WriterType, pub const Error = WriterType.Error; - pub const Writer = io.Writer(*Self, Error, write); + pub const Writer = io.Writer(Error); const Self = @This(); @@ -20,7 +20,7 @@ pub fn CountingWriter(comptime WriterType: type) type { } pub fn writer(self: *Self) Writer { - return .{ .context = self }; + return Writer.init(self, write); } }; } diff --git a/lib/std/io/fixed_buffer_stream.zig b/lib/std/io/fixed_buffer_stream.zig index b002bb47b83a..6c3597e15684 100644 --- a/lib/std/io/fixed_buffer_stream.zig +++ b/lib/std/io/fixed_buffer_stream.zig @@ -17,8 +17,8 @@ pub fn FixedBufferStream(comptime Buffer: type) type { pub const SeekError = error{}; pub const GetSeekPosError = error{}; - pub const Reader = io.Reader(*Self, ReadError, read); - pub const Writer = io.Writer(*Self, WriteError, write); + pub const Reader = io.Reader(ReadError); + pub const Writer = io.Writer(WriteError); pub const SeekableStream = io.SeekableStream( *Self, @@ -33,11 +33,11 @@ pub fn FixedBufferStream(comptime Buffer: type) type { const Self = @This(); pub fn reader(self: *Self) Reader { - return .{ .context = self }; + return Reader.init(self, read); } pub fn writer(self: *Self) Writer { - return .{ .context = self }; + return Writer.init(self, write); } pub fn seekableStream(self: *Self) SeekableStream { diff --git a/lib/std/io/limited_reader.zig b/lib/std/io/limited_reader.zig index aa00af0d0925..14095552acdc 100644 --- a/lib/std/io/limited_reader.zig +++ b/lib/std/io/limited_reader.zig @@ -9,7 +9,7 @@ pub fn LimitedReader(comptime ReaderType: type) type { bytes_left: u64, pub const Error = ReaderType.Error; - pub const Reader = io.Reader(*Self, Error, read); + pub const Reader = io.Reader(Error); const Self = @This(); @@ -21,7 +21,7 @@ pub fn LimitedReader(comptime ReaderType: type) type { } pub fn reader(self: *Self) Reader { - return .{ .context = self }; + return Reader.init(self, read); } }; } diff --git a/lib/std/io/reader.zig b/lib/std/io/reader.zig index b86aca6cbd40..2e0886c8fb5c 100644 --- a/lib/std/io/reader.zig +++ b/lib/std/io/reader.zig @@ -4,26 +4,33 @@ const assert = std.debug.assert; const mem = std.mem; const testing = std.testing; -pub fn Reader( - comptime Context: type, - comptime ReadError: type, - /// Returns the number of bytes read. It may be less than buffer.len. - /// If the number of bytes read is 0, it means end of stream. - /// End of stream is not an error condition. - comptime readFn: fn (context: Context, buffer: []u8) ReadError!usize, -) type { +pub fn Reader(comptime ReadError: type) type { return struct { pub const Error = ReadError; - context: Context, + context: *anyopaque, + readFn: *const fn (context: *anyopaque, buffer: []u8) Error!usize, const Self = @This(); + pub fn init( + context: anytype, + /// Returns the number of bytes read. It may be less than buffer.len. + /// If the number of bytes read is 0, it means end of stream. + /// End of stream is not an error condition. + comptime readFn: *const fn (ctx: @TypeOf(context), buffer: []u8) Error!usize, + ) Self { + return Self{ + .context = context, + .readFn = makeWrapper(context, Error, readFn), + }; + } + /// Returns the number of bytes read. It may be less than buffer.len. /// If the number of bytes read is 0, it means end of stream. /// End of stream is not an error condition. pub fn read(self: Self, buffer: []u8) Error!usize { - return readFn(self.context, buffer); + return self.readFn(self.context, buffer); } /// Returns the number of bytes read. If the number read is smaller than `buffer.len`, it @@ -363,6 +370,22 @@ pub fn Reader( }; } +fn makeWrapper( + context: anytype, + comptime Error: type, + comptime readFn: *const fn (ctx: @TypeOf(context), buffer: []u8) Error!usize, +) *const fn (ctx: *anyopaque, buffer: []u8) Error!usize { + const Context = @TypeOf(context.*); + const ContextPtr = @TypeOf(context); + return struct { + fn wrapper(ctx: *anyopaque, buffer: []u8) Error!usize { + const aligned = @alignCast(@alignOf(Context), ctx); + const casted = @ptrCast(ContextPtr, aligned); + return readFn(casted, buffer); + } + }.wrapper; +} + test "Reader" { var buf = "a\x02".*; var fis = std.io.fixedBufferStream(&buf); diff --git a/lib/std/io/writer.zig b/lib/std/io/writer.zig index 3160c37ff201..0f5060380f5f 100644 --- a/lib/std/io/writer.zig +++ b/lib/std/io/writer.zig @@ -2,19 +2,26 @@ const std = @import("../std.zig"); const assert = std.debug.assert; const mem = std.mem; -pub fn Writer( - comptime Context: type, - comptime WriteError: type, - comptime writeFn: fn (context: Context, bytes: []const u8) WriteError!usize, -) type { +pub fn Writer(comptime WriteError: type) type { return struct { - context: Context, + context: *anyopaque, + writeFn: *const fn (ctx: *anyopaque, bytes: []const u8) Error!usize, const Self = @This(); pub const Error = WriteError; + pub fn init( + context: anytype, + comptime writeFn: *const fn (ctx: @TypeOf(context), bytes: []const u8) Error!usize, + ) Self { + return Self{ + .context = context, + .writeFn = makeWrapper(context, Error, writeFn), + }; + } + pub fn write(self: Self, bytes: []const u8) Error!usize { - return writeFn(self.context, bytes); + return self.writeFn(self.context, bytes); } pub fn writeAll(self: Self, bytes: []const u8) Error!void { @@ -89,3 +96,19 @@ pub fn Writer( } }; } + +fn makeWrapper( + context: anytype, + comptime Error: type, + comptime writeFn: *const fn (ctx: @TypeOf(context), bytes: []const u8) Error!usize, +) *const fn (ctx: *anyopaque, bytes: []const u8) Error!usize { + const Context = @TypeOf(context.*); + const ContextPtr = @TypeOf(context); + return struct { + fn wrapper(ctx: *anyopaque, bytes: []const u8) Error!usize { + const aligned = @alignCast(@alignOf(Context), ctx); + const casted = @ptrCast(ContextPtr, aligned); + return writeFn(casted, bytes); + } + }.wrapper; +} diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig index 0c54b3c75136..1fa76908701c 100644 --- a/lib/std/zig/render.zig +++ b/lib/std/zig/render.zig @@ -2932,7 +2932,7 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type { return struct { const Self = @This(); pub const WriteError = UnderlyingWriter.Error; - pub const Writer = std.io.Writer(*Self, WriteError, write); + pub const Writer = std.io.Writer(WriteError); underlying_writer: UnderlyingWriter, @@ -2955,7 +2955,7 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type { indent_next_line: usize = 0, pub fn writer(self: *Self) Writer { - return .{ .context = self }; + return Writer.init(self, write); } pub fn write(self: *Self, bytes: []const u8) WriteError!usize { diff --git a/src/AstGen.zig b/src/AstGen.zig index 4e571ffda9cf..c7a8eaffb40c 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -10174,9 +10174,7 @@ fn appendErrorNodeNotes( notes: []const u32, ) Allocator.Error!void { @setCold(true); - const string_bytes = &astgen.string_bytes; - const msg = @intCast(u32, string_bytes.items.len); - try string_bytes.writer(astgen.gpa).print(format ++ "\x00", args); + const msg = try astgen.printStringBytes(format, args); const notes_index: u32 = if (notes.len != 0) blk: { const notes_start = astgen.extra.items.len; try astgen.extra.ensureTotalCapacity(astgen.gpa, notes_start + 1 + notes.len); @@ -10241,9 +10239,7 @@ fn appendErrorTokNotes( notes: []const u32, ) !void { @setCold(true); - const string_bytes = &astgen.string_bytes; - const msg = @intCast(u32, string_bytes.items.len); - try string_bytes.writer(astgen.gpa).print(format ++ "\x00", args); + const msg = try astgen.printStringBytes(format, args); const notes_index: u32 = if (notes.len != 0) blk: { const notes_start = astgen.extra.items.len; try astgen.extra.ensureTotalCapacity(astgen.gpa, notes_start + 1 + notes.len); @@ -10280,9 +10276,7 @@ fn appendErrorOff( args: anytype, ) Allocator.Error!void { @setCold(true); - const string_bytes = &astgen.string_bytes; - const msg = @intCast(u32, string_bytes.items.len); - try string_bytes.writer(astgen.gpa).print(format ++ "\x00", args); + const msg = try astgen.printStringBytes(format, args); try astgen.compile_errors.append(astgen.gpa, .{ .msg = msg, .node = 0, @@ -10299,11 +10293,8 @@ fn errNoteTok( args: anytype, ) Allocator.Error!u32 { @setCold(true); - const string_bytes = &astgen.string_bytes; - const msg = @intCast(u32, string_bytes.items.len); - try string_bytes.writer(astgen.gpa).print(format ++ "\x00", args); return astgen.addExtra(Zir.Inst.CompileErrors.Item{ - .msg = msg, + .msg = try astgen.printStringBytes(format, args), .node = 0, .token = token, .byte_offset = 0, @@ -10318,11 +10309,8 @@ fn errNoteNode( args: anytype, ) Allocator.Error!u32 { @setCold(true); - const string_bytes = &astgen.string_bytes; - const msg = @intCast(u32, string_bytes.items.len); - try string_bytes.writer(astgen.gpa).print(format ++ "\x00", args); return astgen.addExtra(Zir.Inst.CompileErrors.Item{ - .msg = msg, + .msg = try astgen.printStringBytes(format, args), .node = node, .token = 0, .byte_offset = 0, @@ -10330,6 +10318,17 @@ fn errNoteNode( }); } +fn printStringBytes(astgen: *AstGen, comptime format: []const u8, args: anytype) !u32 { + const string_bytes = &astgen.string_bytes; + const msg = @intCast(u32, string_bytes.items.len); + + var managed = string_bytes.toManaged(astgen.gpa); + defer string_bytes.* = managed.moveToUnmanaged(); + try managed.writer().print(format ++ "\x00", args); + + return msg; +} + fn identAsString(astgen: *AstGen, ident_token: Ast.TokenIndex) !u32 { const gpa = astgen.gpa; const string_bytes = &astgen.string_bytes; diff --git a/src/Compilation.zig b/src/Compilation.zig index 7f6314bbb04c..7d615cd2d7a8 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -439,7 +439,7 @@ pub const AllErrors = struct { try counting_stderr.writeAll(": "); // This is the length of the part before the error message: // e.g. "file.zig:4:5: error: " - const prefix_len = @intCast(usize, counting_stderr.context.bytes_written); + const prefix_len = @intCast(usize, counting_writer.bytes_written); ttyconf.setColor(stderr, .Reset); ttyconf.setColor(stderr, .Bold); if (src.count == 1) { diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 1fd953973071..de038edac593 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -6695,7 +6695,7 @@ fn IndentWriter(comptime UnderlyingWriter: type) type { return struct { const Self = @This(); pub const Error = UnderlyingWriter.Error; - pub const Writer = std.io.Writer(*Self, Error, write); + pub const Writer = std.io.Writer(Error); pub const indent_delta = 1; @@ -6704,7 +6704,7 @@ fn IndentWriter(comptime UnderlyingWriter: type) type { current_line_empty: bool = true, pub fn writer(self: *Self) Writer { - return .{ .context = self }; + return Writer.init(self, write); } pub fn write(self: *Self, bytes: []const u8) Error!usize { diff --git a/src/link/MachO/Archive.zig b/src/link/MachO/Archive.zig index d222394ad5a1..3dcd8f864b6c 100644 --- a/src/link/MachO/Archive.zig +++ b/src/link/MachO/Archive.zig @@ -189,7 +189,7 @@ pub fn parseObject( offset: u32, ) !Object { const reader = self.file.reader(); - try reader.context.seekTo(self.fat_offset + offset); + try self.file.seekTo(self.fat_offset + offset); const object_header = try reader.readStruct(ar_hdr); diff --git a/src/link/MachO/zld.zig b/src/link/MachO/zld.zig index 9baecd326a3c..726db83b32ae 100644 --- a/src/link/MachO/zld.zig +++ b/src/link/MachO/zld.zig @@ -122,7 +122,7 @@ pub const Zld = struct { const cpu_arch = self.options.target.cpu.arch; const reader = file.reader(); const fat_offset = try fat.getLibraryOffset(reader, cpu_arch); - try reader.context.seekTo(fat_offset); + try file.seekTo(fat_offset); var archive = Archive{ .name = name, diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 4a9db75c9806..c7ffa39ec6b5 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -2098,7 +2098,12 @@ fn populateErrorNameTable(wasm: *Wasm) !void { const offset = @intCast(u32, atom.code.items.len); // first we create the data for the slice of the name try atom.code.appendNTimes(wasm.base.allocator, 0, 4); // ptr to name, will be relocated - try atom.code.writer(wasm.base.allocator).writeIntLittle(u32, len - 1); + { + var managed = atom.code.toManaged(wasm.base.allocator); + defer atom.code = managed.moveToUnmanaged(); + try managed.writer().writeIntLittle(u32, len - 1); + } + // create relocation to the error name try atom.relocs.append(wasm.base.allocator, .{ .index = names_symbol_index, diff --git a/src/link/Wasm/Object.zig b/src/link/Wasm/Object.zig index e5947228a527..2a690c19816a 100644 --- a/src/link/Wasm/Object.zig +++ b/src/link/Wasm/Object.zig @@ -374,13 +374,13 @@ fn Parser(comptime ReaderType: type) type { if (std.mem.eql(u8, name, "linking")) { is_object_file.* = true; parser.object.relocatable_data = relocatable_data.items; // at this point no new relocatable sections will appear so we're free to store them. - try parser.parseMetadata(gpa, @intCast(usize, reader.context.bytes_left)); + try parser.parseMetadata(gpa, @intCast(usize, limited_reader.bytes_left)); } else if (std.mem.startsWith(u8, name, "reloc")) { try parser.parseRelocations(gpa); } else if (std.mem.eql(u8, name, "target_features")) { try parser.parseFeatures(gpa); } else if (std.mem.startsWith(u8, name, ".debug")) { - const debug_size = @intCast(u32, reader.context.bytes_left); + const debug_size = @intCast(u32, limited_reader.bytes_left); const debug_content = try gpa.alloc(u8, debug_size); errdefer gpa.free(debug_content); try reader.readNoEof(debug_content); @@ -394,7 +394,7 @@ fn Parser(comptime ReaderType: type) type { .section_index = section_index, }); } else { - try reader.skipBytes(reader.context.bytes_left, .{}); + try reader.skipBytes(limited_reader.bytes_left, .{}); } }, .type => { @@ -409,7 +409,7 @@ fn Parser(comptime ReaderType: type) type { result.* = try readEnum(std.wasm.Valtype, reader); } } - try assertEnd(reader); + try assertEnd(&limited_reader); }, .import => { for (try readVec(&parser.object.imports, reader, gpa)) |*import| { @@ -443,13 +443,13 @@ fn Parser(comptime ReaderType: type) type { .kind = kind_value, }; } - try assertEnd(reader); + try assertEnd(&limited_reader); }, .function => { for (try readVec(&parser.object.functions, reader, gpa)) |*func| { func.* = .{ .type_index = try readLeb(u32, reader) }; } - try assertEnd(reader); + try assertEnd(&limited_reader); }, .table => { for (try readVec(&parser.object.tables, reader, gpa)) |*table| { @@ -458,13 +458,13 @@ fn Parser(comptime ReaderType: type) type { .limits = try readLimits(reader), }; } - try assertEnd(reader); + try assertEnd(&limited_reader); }, .memory => { for (try readVec(&parser.object.memories, reader, gpa)) |*memory| { memory.* = .{ .limits = try readLimits(reader) }; } - try assertEnd(reader); + try assertEnd(&limited_reader); }, .global => { for (try readVec(&parser.object.globals, reader, gpa)) |*global| { @@ -476,7 +476,7 @@ fn Parser(comptime ReaderType: type) type { .init = try readInit(reader), }; } - try assertEnd(reader); + try assertEnd(&limited_reader); }, .@"export" => { for (try readVec(&parser.object.exports, reader, gpa)) |*exp| { @@ -490,11 +490,11 @@ fn Parser(comptime ReaderType: type) type { .index = try readLeb(u32, reader), }; } - try assertEnd(reader); + try assertEnd(&limited_reader); }, .start => { parser.object.start = try readLeb(u32, reader); - try assertEnd(reader); + try assertEnd(&limited_reader); }, .element => { for (try readVec(&parser.object.elements, reader, gpa)) |*elem| { @@ -505,15 +505,15 @@ fn Parser(comptime ReaderType: type) type { idx.* = try readLeb(u32, reader); } } - try assertEnd(reader); + try assertEnd(&limited_reader); }, .code => { - var start = reader.context.bytes_left; + var start = limited_reader.bytes_left; var index: u32 = 0; const count = try readLeb(u32, reader); while (index < count) : (index += 1) { const code_len = try readLeb(u32, reader); - const offset = @intCast(u32, start - reader.context.bytes_left); + const offset = @intCast(u32, start - limited_reader.bytes_left); const data = try gpa.alloc(u8, code_len); errdefer gpa.free(data); try reader.readNoEof(data); @@ -528,7 +528,7 @@ fn Parser(comptime ReaderType: type) type { } }, .data => { - var start = reader.context.bytes_left; + var start = limited_reader.bytes_left; var index: u32 = 0; const count = try readLeb(u32, reader); while (index < count) : (index += 1) { @@ -537,7 +537,7 @@ fn Parser(comptime ReaderType: type) type { _ = flags; // TODO: Do we need to check flags to detect passive/active memory? _ = data_offset; const data_len = try readLeb(u32, reader); - const offset = @intCast(u32, start - reader.context.bytes_left); + const offset = @intCast(u32, start - limited_reader.bytes_left); const data = try gpa.alloc(u8, data_len); errdefer gpa.free(data); try reader.readNoEof(data); @@ -864,11 +864,12 @@ fn readInit(reader: anytype) !std.wasm.InitExpression { return init_expr; } -fn assertEnd(reader: anytype) !void { +fn assertEnd(limited_reader: anytype) !void { var buf: [1]u8 = undefined; + const reader = limited_reader.reader(); const len = try reader.read(&buf); if (len != 0) return error.MalformedSection; - if (reader.context.bytes_left != 0) return error.MalformedSection; + if (limited_reader.bytes_left != 0) return error.MalformedSection; } /// Parses an object file into atoms, for code and data sections