more updates to not use GenericWriter

This commit is contained in:
Andrew Kelley 2025-08-21 16:50:55 -07:00
parent 379d7bc9f6
commit 2151b10a41
5 changed files with 65 additions and 52 deletions

View File

@ -546,7 +546,7 @@ pub fn generateBuiltinMacros(comp: *Compilation, system_defines_mode: SystemDefi
}
try buf.appendSlice("#define __STDC__ 1\n");
try buf.writer().print("#define __STDC_HOSTED__ {d}\n", .{@intFromBool(comp.target.os.tag != .freestanding)});
try buf.print("#define __STDC_HOSTED__ {d}\n", .{@intFromBool(comp.target.os.tag != .freestanding)});
// standard macros
try buf.appendSlice(

View File

@ -3,7 +3,7 @@ const Emit = @This();
const std = @import("std");
const assert = std.debug.assert;
const Allocator = std.mem.Allocator;
const leb = std.leb;
const ArrayList = std.ArrayList;
const Wasm = link.File.Wasm;
const Mir = @import("Mir.zig");
@ -15,7 +15,7 @@ const codegen = @import("../../codegen.zig");
mir: Mir,
wasm: *Wasm,
/// The binary representation that will be emitted by this module.
code: *std.ArrayListUnmanaged(u8),
code: *ArrayList(u8),
pub const Error = error{
OutOfMemory,
@ -85,7 +85,7 @@ pub fn lowerToCode(emit: *Emit) Error!void {
if (is_obj) {
@panic("TODO");
} else {
leb.writeUleb128(code.fixedWriter(), 1 + @intFromEnum(indirect_func_idx)) catch unreachable;
writeUleb128(code, 1 + @intFromEnum(indirect_func_idx));
}
inst += 1;
continue :loop tags[inst];
@ -99,7 +99,7 @@ pub fn lowerToCode(emit: *Emit) Error!void {
code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i32_const));
// MIR is lowered during flush, so there is indeed only one thread at this time.
const errors_len = 1 + comp.zcu.?.intern_pool.global_error_set.getNamesFromMainThread().len;
leb.writeIleb128(code.fixedWriter(), errors_len) catch unreachable;
writeSleb128(code, errors_len);
inst += 1;
continue :loop tags[inst];
@ -122,7 +122,7 @@ pub fn lowerToCode(emit: *Emit) Error!void {
continue :loop tags[inst];
} else {
const addr: u32 = wasm.errorNameTableAddr();
leb.writeIleb128(code.fixedWriter(), addr) catch unreachable;
writeSleb128(code, addr);
inst += 1;
continue :loop tags[inst];
@ -131,7 +131,7 @@ pub fn lowerToCode(emit: *Emit) Error!void {
.br_if, .br, .memory_grow, .memory_size => {
try code.ensureUnusedCapacity(gpa, 11);
code.appendAssumeCapacity(@intFromEnum(tags[inst]));
leb.writeUleb128(code.fixedWriter(), datas[inst].label) catch unreachable;
writeUleb128(code, datas[inst].label);
inst += 1;
continue :loop tags[inst];
@ -140,7 +140,7 @@ pub fn lowerToCode(emit: *Emit) Error!void {
.local_get, .local_set, .local_tee => {
try code.ensureUnusedCapacity(gpa, 11);
code.appendAssumeCapacity(@intFromEnum(tags[inst]));
leb.writeUleb128(code.fixedWriter(), datas[inst].local) catch unreachable;
writeUleb128(code, datas[inst].local);
inst += 1;
continue :loop tags[inst];
@ -153,8 +153,8 @@ pub fn lowerToCode(emit: *Emit) Error!void {
try code.ensureUnusedCapacity(gpa, 11 + 10 * labels.len);
code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.br_table));
// -1 because default label is not part of length/depth.
leb.writeUleb128(code.fixedWriter(), extra.data.length - 1) catch unreachable;
for (labels) |label| leb.writeUleb128(code.fixedWriter(), label) catch unreachable;
writeUleb128(code, extra.data.length - 1);
for (labels) |label| writeUleb128(code, label);
inst += 1;
continue :loop tags[inst];
@ -199,9 +199,9 @@ pub fn lowerToCode(emit: *Emit) Error!void {
code.appendNTimesAssumeCapacity(0, 5);
} else {
const index: Wasm.Flush.FuncTypeIndex = .fromTypeIndex(func_ty_index, &wasm.flush_buffer);
leb.writeUleb128(code.fixedWriter(), @intFromEnum(index)) catch unreachable;
writeUleb128(code, @intFromEnum(index));
}
leb.writeUleb128(code.fixedWriter(), @as(u32, 0)) catch unreachable; // table index
writeUleb128(code, @as(u32, 0)); // table index
inst += 1;
continue :loop tags[inst];
@ -263,7 +263,7 @@ pub fn lowerToCode(emit: *Emit) Error!void {
code.appendNTimesAssumeCapacity(0, 5);
} else {
const sp_global: Wasm.GlobalIndex = .stack_pointer;
std.leb.writeUleb128(code.fixedWriter(), @intFromEnum(sp_global)) catch unreachable;
writeUleb128(code, @intFromEnum(sp_global));
}
inst += 1;
@ -291,7 +291,7 @@ pub fn lowerToCode(emit: *Emit) Error!void {
.i32_const => {
try code.ensureUnusedCapacity(gpa, 6);
code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i32_const));
leb.writeIleb128(code.fixedWriter(), datas[inst].imm32) catch unreachable;
writeSleb128(code, datas[inst].imm32);
inst += 1;
continue :loop tags[inst];
@ -300,7 +300,7 @@ pub fn lowerToCode(emit: *Emit) Error!void {
try code.ensureUnusedCapacity(gpa, 11);
code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i64_const));
const int64: i64 = @bitCast(mir.extraData(Mir.Imm64, datas[inst].payload).data.toInt());
leb.writeIleb128(code.fixedWriter(), int64) catch unreachable;
writeSleb128(code, int64);
inst += 1;
continue :loop tags[inst];
@ -476,33 +476,33 @@ pub fn lowerToCode(emit: *Emit) Error!void {
const extra_index = datas[inst].payload;
const opcode = mir.extra[extra_index];
code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.misc_prefix));
leb.writeUleb128(code.fixedWriter(), opcode) catch unreachable;
writeUleb128(code, opcode);
switch (@as(std.wasm.MiscOpcode, @enumFromInt(opcode))) {
// bulk-memory opcodes
.data_drop => {
const segment = mir.extra[extra_index + 1];
leb.writeUleb128(code.fixedWriter(), segment) catch unreachable;
writeUleb128(code, segment);
inst += 1;
continue :loop tags[inst];
},
.memory_init => {
const segment = mir.extra[extra_index + 1];
leb.writeUleb128(code.fixedWriter(), segment) catch unreachable;
leb.writeUleb128(code.fixedWriter(), @as(u32, 0)) catch unreachable; // memory index
writeUleb128(code, segment);
writeUleb128(code, @as(u32, 0)); // memory index
inst += 1;
continue :loop tags[inst];
},
.memory_fill => {
leb.writeUleb128(code.fixedWriter(), @as(u32, 0)) catch unreachable; // memory index
writeUleb128(code, @as(u32, 0)); // memory index
inst += 1;
continue :loop tags[inst];
},
.memory_copy => {
leb.writeUleb128(code.fixedWriter(), @as(u32, 0)) catch unreachable; // dst memory index
leb.writeUleb128(code.fixedWriter(), @as(u32, 0)) catch unreachable; // src memory index
writeUleb128(code, @as(u32, 0)); // dst memory index
writeUleb128(code, @as(u32, 0)); // src memory index
inst += 1;
continue :loop tags[inst];
@ -538,7 +538,7 @@ pub fn lowerToCode(emit: *Emit) Error!void {
const extra_index = datas[inst].payload;
const opcode = mir.extra[extra_index];
code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.simd_prefix));
leb.writeUleb128(code.fixedWriter(), opcode) catch unreachable;
writeUleb128(code, opcode);
switch (@as(std.wasm.SimdOpcode, @enumFromInt(opcode))) {
.v128_store,
.v128_load,
@ -824,7 +824,7 @@ pub fn lowerToCode(emit: *Emit) Error!void {
const extra_index = datas[inst].payload;
const opcode = mir.extra[extra_index];
code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.atomics_prefix));
leb.writeUleb128(code.fixedWriter(), opcode) catch unreachable;
writeUleb128(code, opcode);
switch (@as(std.wasm.AtomicsOpcode, @enumFromInt(opcode))) {
.i32_atomic_load,
.i64_atomic_load,
@ -900,7 +900,7 @@ pub fn lowerToCode(emit: *Emit) Error!void {
// Hard-codes memory index 0 since multi-memory proposal is
// not yet accepted nor implemented.
const memory_index: u32 = 0;
leb.writeUleb128(code.fixedWriter(), memory_index) catch unreachable;
writeUleb128(code, memory_index);
inst += 1;
continue :loop tags[inst];
},
@ -915,15 +915,15 @@ pub fn lowerToCode(emit: *Emit) Error!void {
}
/// Asserts 20 unused capacity.
fn encodeMemArg(code: *std.ArrayListUnmanaged(u8), mem_arg: Mir.MemArg) void {
fn encodeMemArg(code: *ArrayList(u8), mem_arg: Mir.MemArg) void {
assert(code.unusedCapacitySlice().len >= 20);
// Wasm encodes alignment as power of 2, rather than natural alignment.
const encoded_alignment = @ctz(mem_arg.alignment);
leb.writeUleb128(code.fixedWriter(), encoded_alignment) catch unreachable;
leb.writeUleb128(code.fixedWriter(), mem_arg.offset) catch unreachable;
writeUleb128(code, encoded_alignment);
writeUleb128(code, mem_arg.offset);
}
fn uavRefObj(wasm: *Wasm, code: *std.ArrayListUnmanaged(u8), value: InternPool.Index, offset: i32, is_wasm32: bool) !void {
fn uavRefObj(wasm: *Wasm, code: *ArrayList(u8), value: InternPool.Index, offset: i32, is_wasm32: bool) !void {
const comp = wasm.base.comp;
const gpa = comp.gpa;
const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const;
@ -940,7 +940,7 @@ fn uavRefObj(wasm: *Wasm, code: *std.ArrayListUnmanaged(u8), value: InternPool.I
code.appendNTimesAssumeCapacity(0, if (is_wasm32) 5 else 10);
}
fn uavRefExe(wasm: *Wasm, code: *std.ArrayListUnmanaged(u8), value: InternPool.Index, offset: i32, is_wasm32: bool) !void {
fn uavRefExe(wasm: *Wasm, code: *ArrayList(u8), value: InternPool.Index, offset: i32, is_wasm32: bool) !void {
const comp = wasm.base.comp;
const gpa = comp.gpa;
const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const;
@ -949,10 +949,10 @@ fn uavRefExe(wasm: *Wasm, code: *std.ArrayListUnmanaged(u8), value: InternPool.I
code.appendAssumeCapacity(@intFromEnum(opcode));
const addr = wasm.uavAddr(value);
leb.writeUleb128(code.fixedWriter(), @as(u32, @intCast(@as(i64, addr) + offset))) catch unreachable;
writeUleb128(code, @as(u32, @intCast(@as(i64, addr) + offset)));
}
fn navRefOff(wasm: *Wasm, code: *std.ArrayListUnmanaged(u8), data: Mir.NavRefOff, is_wasm32: bool) !void {
fn navRefOff(wasm: *Wasm, code: *ArrayList(u8), data: Mir.NavRefOff, is_wasm32: bool) !void {
const comp = wasm.base.comp;
const zcu = comp.zcu.?;
const ip = &zcu.intern_pool;
@ -975,10 +975,22 @@ fn navRefOff(wasm: *Wasm, code: *std.ArrayListUnmanaged(u8), data: Mir.NavRefOff
code.appendNTimesAssumeCapacity(0, if (is_wasm32) 5 else 10);
} else {
const addr = wasm.navAddr(data.nav_index);
leb.writeUleb128(code.fixedWriter(), @as(u32, @intCast(@as(i64, addr) + data.offset))) catch unreachable;
writeUleb128(code, @as(u32, @intCast(@as(i64, addr) + data.offset)));
}
}
fn appendOutputFunctionIndex(code: *std.ArrayListUnmanaged(u8), i: Wasm.OutputFunctionIndex) void {
leb.writeUleb128(code.fixedWriter(), @intFromEnum(i)) catch unreachable;
fn appendOutputFunctionIndex(code: *ArrayList(u8), i: Wasm.OutputFunctionIndex) void {
writeUleb128(code, @intFromEnum(i));
}
fn writeUleb128(code: *ArrayList(u8), arg: anytype) void {
var w: std.Io.Writer = .fixed(code.unusedCapacitySlice());
w.writeUleb128(arg) catch unreachable;
code.items.len += w.end;
}
fn writeSleb128(code: *ArrayList(u8), arg: anytype) void {
var w: std.Io.Writer = .fixed(code.unusedCapacitySlice());
w.writeSleb128(arg) catch unreachable;
code.items.len += w.end;
}

View File

@ -6,6 +6,7 @@ const link = @import("link.zig");
const log = std.log.scoped(.codegen);
const mem = std.mem;
const math = std.math;
const ArrayList = std.ArrayList;
const target_util = @import("target.zig");
const trace = @import("tracy.zig").trace;
@ -179,7 +180,7 @@ pub fn emitFunction(
src_loc: Zcu.LazySrcLoc,
func_index: InternPool.Index,
any_mir: *const AnyMir,
code: *std.ArrayListUnmanaged(u8),
code: *ArrayList(u8),
debug_output: link.File.DebugInfoOutput,
) CodeGenError!void {
const zcu = pt.zcu;
@ -204,7 +205,7 @@ pub fn generateLazyFunction(
pt: Zcu.PerThread,
src_loc: Zcu.LazySrcLoc,
lazy_sym: link.File.LazySymbol,
code: *std.ArrayListUnmanaged(u8),
code: *ArrayList(u8),
debug_output: link.File.DebugInfoOutput,
) CodeGenError!void {
const zcu = pt.zcu;
@ -236,7 +237,7 @@ pub fn generateLazySymbol(
lazy_sym: link.File.LazySymbol,
// TODO don't use an "out" parameter like this; put it in the result instead
alignment: *Alignment,
code: *std.ArrayListUnmanaged(u8),
code: *ArrayList(u8),
debug_output: link.File.DebugInfoOutput,
reloc_parent: link.File.RelocInfo.Parent,
) CodeGenError!void {
@ -311,7 +312,7 @@ pub fn generateSymbol(
pt: Zcu.PerThread,
src_loc: Zcu.LazySrcLoc,
val: Value,
code: *std.ArrayListUnmanaged(u8),
code: *ArrayList(u8),
reloc_parent: link.File.RelocInfo.Parent,
) GenerateSymbolError!void {
const tracy = trace(@src());
@ -379,7 +380,7 @@ pub fn generateSymbol(
},
.err => |err| {
const int = try pt.getErrorValue(err.name);
try code.writer(gpa).writeInt(u16, @intCast(int), endian);
mem.writeInt(u16, try code.addManyAsArray(gpa, 2), @intCast(int), endian);
},
.error_union => |error_union| {
const payload_ty = ty.errorUnionPayload(zcu);
@ -389,7 +390,7 @@ pub fn generateSymbol(
};
if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
try code.writer(gpa).writeInt(u16, err_val, endian);
mem.writeInt(u16, try code.addManyAsArray(gpa, 2), err_val, endian);
return;
}
@ -399,7 +400,7 @@ pub fn generateSymbol(
// error value first when its type is larger than the error union's payload
if (error_align.order(payload_align) == .gt) {
try code.writer(gpa).writeInt(u16, err_val, endian);
mem.writeInt(u16, try code.addManyAsArray(gpa, 2), err_val, endian);
}
// emit payload part of the error union
@ -421,7 +422,7 @@ pub fn generateSymbol(
// Payload size is larger than error set, so emit our error set last
if (error_align.compare(.lte, payload_align)) {
const begin = code.items.len;
try code.writer(gpa).writeInt(u16, err_val, endian);
mem.writeInt(u16, try code.addManyAsArray(gpa, 2), err_val, endian);
const unpadded_end = code.items.len - begin;
const padded_end = abi_align.forward(unpadded_end);
const padding = math.cast(usize, padded_end - unpadded_end) orelse return error.Overflow;
@ -476,7 +477,7 @@ pub fn generateSymbol(
}));
try generateSymbol(bin_file, pt, src_loc, value, code, reloc_parent);
}
try code.writer(gpa).writeByte(@intFromBool(payload_val != null));
try code.append(gpa, @intFromBool(payload_val != null));
try code.appendNTimes(gpa, 0, padding);
}
},
@ -721,7 +722,7 @@ fn lowerPtr(
pt: Zcu.PerThread,
src_loc: Zcu.LazySrcLoc,
ptr_val: InternPool.Index,
code: *std.ArrayListUnmanaged(u8),
code: *ArrayList(u8),
reloc_parent: link.File.RelocInfo.Parent,
prev_offset: u64,
) GenerateSymbolError!void {
@ -774,7 +775,7 @@ fn lowerUavRef(
pt: Zcu.PerThread,
src_loc: Zcu.LazySrcLoc,
uav: InternPool.Key.Ptr.BaseAddr.Uav,
code: *std.ArrayListUnmanaged(u8),
code: *ArrayList(u8),
reloc_parent: link.File.RelocInfo.Parent,
offset: u64,
) GenerateSymbolError!void {
@ -834,7 +835,7 @@ fn lowerNavRef(
lf: *link.File,
pt: Zcu.PerThread,
nav_index: InternPool.Nav.Index,
code: *std.ArrayListUnmanaged(u8),
code: *ArrayList(u8),
reloc_parent: link.File.RelocInfo.Parent,
offset: u64,
) GenerateSymbolError!void {

View File

@ -304,7 +304,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
const include_dir = try comp.dirs.zig_lib.join(arena, &.{ "libc", "mingw", "def-include" });
if (comp.verbose_cc) print: {
var stderr = std.debug.lockStderrWriter();
var stderr = std.debug.lockStderrWriter(&.{});
defer std.debug.unlockStderrWriter();
nosuspend stderr.print("def file: {s}\n", .{def_file_path}) catch break :print;
nosuspend stderr.print("include dir: {s}\n", .{include_dir}) catch break :print;

View File

@ -2179,13 +2179,13 @@ fn writeDataDirectoriesHeaders(coff: *Coff) !void {
fn writeHeader(coff: *Coff) !void {
const target = &coff.base.comp.root_mod.resolved_target.result;
const gpa = coff.base.comp.gpa;
var buffer = std.array_list.Managed(u8).init(gpa);
var buffer: std.Io.Writer.Allocating = .init(gpa);
defer buffer.deinit();
const writer = buffer.writer();
const writer = &buffer.writer;
try buffer.ensureTotalCapacity(coff.getSizeOfHeaders());
writer.writeAll(&msdos_stub) catch unreachable;
mem.writeInt(u32, buffer.items[0x3c..][0..4], msdos_stub.len, .little);
mem.writeInt(u32, buffer.writer.buffer[0x3c..][0..4], msdos_stub.len, .little);
writer.writeAll("PE\x00\x00") catch unreachable;
var flags = coff_util.CoffHeaderFlags{
@ -2313,7 +2313,7 @@ fn writeHeader(coff: *Coff) !void {
},
}
try coff.pwriteAll(buffer.items, 0);
try coff.pwriteAll(buffer.written(), 0);
}
pub fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) {