zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 1ae7c7687f3180b167e4a2f676bddb892a99e28c (tree)
parent 2f6a80043ea1b9cfc2119c5a5e885ab145b218f6
Author: Motiejus Jakštys <motiejus@jakstys.lt>
Date:   Mon, 23 Feb 2026 20:11:21 +0000

sema_test: zero-copy PrecomputedFunc — point into binary data directly

PrecomputedFunc now stores raw [*]const u8 byte pointers instead of c.Air,
eliminating per-function heap allocations and memcpy in parsePrecomputedAir.
airCompareOne takes two PrecomputedFunc values; C-sema output is wrapped via
precomputedFromCAir.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Diffstat:
Mstage0/sema_test.zig | 298++++++++++++++++++++++++++++++++++++-------------------------------------------
Mstage0/stages_test.zig | 4++--
2 files changed, 138 insertions(+), 164 deletions(-)

diff --git a/stage0/sema_test.zig b/stage0/sema_test.zig @@ -227,12 +227,20 @@ test "sema: function decl smoke test" { const air_tag_names = @import("air_tag_names"); /// A parsed function from the pre-computed AIR binary data. +/// Fields are raw byte pointers into the binary data — no alignment +/// requirements, no copies. When inst_len == 0 or extra_len == 0 the +/// corresponding pointer is undefined and must not be dereferenced. pub const PrecomputedFunc = struct { name: []const u8, - air: c.Air, + inst_len: u32, + tags: [*]const u8, + datas: [*]const u8, + extra_len: u32, + extra: [*]const u8, }; /// Parse pre-computed AIR from binary data (generated by air_gen). +/// Zero-copy: pointers point directly into `data`. /// Binary format: /// func_count: u32 (little-endian) /// Per function: @@ -243,12 +251,12 @@ pub const PrecomputedFunc = struct { /// inst_datas: [inst_len * 8]u8 /// extra_len: u32 /// extra: [extra_len * 4]u8 -pub fn parsePrecomputedAir(gpa: std.mem.Allocator, data: []const u8) ![]PrecomputedFunc { +pub fn parsePrecomputedAir(data: []const u8) ![]PrecomputedFunc { var pos: usize = 0; const func_count = readU32(data, &pos) orelse return error.InvalidAirData; - const funcs = try gpa.alloc(PrecomputedFunc, func_count); - errdefer gpa.free(funcs); + const funcs = try std.testing.allocator.alloc(PrecomputedFunc, func_count); + errdefer std.testing.allocator.free(funcs); for (funcs) |*f| { // name @@ -257,48 +265,33 @@ pub fn parsePrecomputedAir(gpa: std.mem.Allocator, data: []const u8) ![]Precompu f.name = data[pos..][0..name_len]; pos += name_len; - // inst_tags + inst_datas (allocate copies with proper alignment) + // inst_tags + inst_datas — point directly into data const inst_len = readU32(data, &pos) orelse return error.InvalidAirData; - - const tags: [*c]u8 = if (inst_len > 0) blk: { + f.inst_len = inst_len; + if (inst_len > 0) { if (pos + inst_len > data.len) return error.InvalidAirData; - const alloc = try gpa.alloc(u8, inst_len); - @memcpy(alloc, data[pos..][0..inst_len]); - break :blk alloc.ptr; - } else null; - pos += inst_len; - - const datas: [*c]c.AirInstData = if (inst_len > 0) blk: { + f.tags = data[pos..].ptr; + pos += inst_len; const datas_byte_len = inst_len * 8; if (pos + datas_byte_len > data.len) return error.InvalidAirData; - const alloc = try gpa.alloc(c.AirInstData, inst_len); - const alloc_bytes: [*]u8 = @ptrCast(alloc.ptr); - @memcpy(alloc_bytes[0..datas_byte_len], data[pos..][0..datas_byte_len]); - break :blk alloc.ptr; - } else null; - pos += inst_len * 8; - - // extra (allocate copy with u32 alignment) + f.datas = data[pos..].ptr; + pos += datas_byte_len; + } else { + f.tags = undefined; + f.datas = undefined; + } + + // extra — point directly into data const extra_len = readU32(data, &pos) orelse return error.InvalidAirData; - const extra: [*c]u32 = if (extra_len > 0) blk: { + f.extra_len = extra_len; + if (extra_len > 0) { const extra_byte_len = extra_len * 4; if (pos + extra_byte_len > data.len) return error.InvalidAirData; - const alloc = try gpa.alloc(u32, extra_len); - const alloc_bytes: [*]u8 = @ptrCast(alloc.ptr); - @memcpy(alloc_bytes[0..extra_byte_len], data[pos..][0..extra_byte_len]); - break :blk alloc.ptr; - } else null; - pos += extra_len * 4; - - f.air = .{ - .inst_len = inst_len, - .inst_cap = inst_len, - .inst_tags = tags, - .inst_datas = datas, - .extra_len = extra_len, - .extra_cap = extra_len, - .extra = extra, - }; + f.extra = data[pos..].ptr; + pos += extra_byte_len; + } else { + f.extra = undefined; + } } return funcs; @@ -311,13 +304,8 @@ fn readU32(data: []const u8, pos: *usize) ?u32 { return val; } -pub fn freePrecomputedAir(gpa: std.mem.Allocator, funcs: []PrecomputedFunc) void { - for (funcs) |f| { - if (f.air.inst_tags) |t| gpa.free(t[0..f.air.inst_len]); - if (f.air.inst_datas) |d| gpa.free(d[0..f.air.inst_len]); - if (f.air.extra) |e| gpa.free(e[0..f.air.extra_len]); - } - gpa.free(funcs); +pub fn freePrecomputedAir(funcs: []PrecomputedFunc) void { + std.testing.allocator.free(funcs); } /// Compare C sema output against pre-computed AIR data. @@ -331,10 +319,22 @@ pub fn airComparePrecomputed(precomputed: []const PrecomputedFunc, c_func_air_li std.debug.print("C function '{s}' not found in pre-computed AIR\n", .{c_name}); return error.AirMismatch; }; - try airCompareOne(c_name, &pf.air, &cf.air); + const c_pf = precomputedFromCAir(cf); + try airCompareOne(c_name, pf.*, c_pf); } } +fn precomputedFromCAir(cf: *const c.SemaFuncAir) PrecomputedFunc { + return .{ + .name = if (cf.name) |n| std.mem.span(n) else "", + .inst_len = cf.air.inst_len, + .tags = if (cToOpt(u8, cf.air.inst_tags)) |t| t else undefined, + .datas = if (cToOpt(c.AirInstData, cf.air.inst_datas)) |d| @ptrCast(d) else undefined, + .extra_len = cf.air.extra_len, + .extra = if (cToOpt(u32, cf.air.extra)) |e| @ptrCast(e) else undefined, + }; +} + fn precomputedFindByName(funcs: []const PrecomputedFunc, name: []const u8) ?*const PrecomputedFunc { const bare_name = stripModulePrefix(name); for (funcs) |*f| { @@ -361,6 +361,10 @@ fn cToOpt(comptime T: type, ptr: [*c]T) ?[*]const T { return if (ptr == null) null else @ptrCast(ptr); } +fn readExtraWord(extra: [*]const u8, index: usize) u32 { + return std.mem.readInt(u32, extra[index * 4 ..][0..4], .little); +} + fn airTagNameSlice(tag_val: u8) []const u8 { return air_tag_names.names[tag_val]; } @@ -617,45 +621,37 @@ fn normalizeNtsPadding(extra: []u32, nts_index: u32) void { } } -fn airCompareOne(name: []const u8, zig_air: *const c.Air, c_air: *const c.Air) !void { - if (zig_air.inst_len != c_air.inst_len) { - std.debug.print("'{s}': inst_len mismatch: zig={d} c={d}\n", .{ name, zig_air.inst_len, c_air.inst_len }); - if (cToOpt(u8, zig_air.inst_tags)) |zt| { - std.debug.print(" zig tags:", .{}); - for (0..zig_air.inst_len) |j| std.debug.print(" {s}", .{airTagNameSlice(zt[j])}); +fn airCompareOne(name: []const u8, a: PrecomputedFunc, b: PrecomputedFunc) !void { + if (a.inst_len != b.inst_len) { + std.debug.print("'{s}': inst_len mismatch: a={d} b={d}\n", .{ name, a.inst_len, b.inst_len }); + if (a.inst_len > 0) { + std.debug.print(" a tags:", .{}); + for (0..a.inst_len) |j| std.debug.print(" {s}", .{airTagNameSlice(a.tags[j])}); std.debug.print("\n", .{}); } - if (cToOpt(u8, c_air.inst_tags)) |ct| { - std.debug.print(" c tags:", .{}); - for (0..c_air.inst_len) |j| std.debug.print(" {s}", .{airTagNameSlice(ct[j])}); + if (b.inst_len > 0) { + std.debug.print(" b tags:", .{}); + for (0..b.inst_len) |j| std.debug.print(" {s}", .{airTagNameSlice(b.tags[j])}); std.debug.print("\n", .{}); } return error.AirMismatch; } - const inst_len = zig_air.inst_len; + const inst_len = a.inst_len; // Canonical ref maps shared between datas and extra comparisons. - var zig_ref_map = std.AutoHashMap(u32, u32).init(std.testing.allocator); - defer zig_ref_map.deinit(); - var c_ref_map = std.AutoHashMap(u32, u32).init(std.testing.allocator); - defer c_ref_map.deinit(); - var next_zig_id: u32 = 0; - var next_c_id: u32 = 0; + var a_ref_map = std.AutoHashMap(u32, u32).init(std.testing.allocator); + defer a_ref_map.deinit(); + var b_ref_map = std.AutoHashMap(u32, u32).init(std.testing.allocator); + defer b_ref_map.deinit(); + var next_a_id: u32 = 0; + var next_b_id: u32 = 0; // Tags if (inst_len > 0) { - const zig_tags: [*]const u8 = cToOpt(u8, zig_air.inst_tags) orelse { - std.debug.print("'{s}': Zig inst_tags is null but inst_len={d}\n", .{ name, inst_len }); - return error.AirMismatch; - }; - const c_tags: [*]const u8 = cToOpt(u8, c_air.inst_tags) orelse { - std.debug.print("'{s}': C inst_tags is null but inst_len={d}\n", .{ name, inst_len }); - return error.AirMismatch; - }; - if (!std.mem.eql(u8, zig_tags[0..inst_len], c_tags[0..inst_len])) { + if (!std.mem.eql(u8, a.tags[0..inst_len], b.tags[0..inst_len])) { std.debug.print("'{s}': tags mismatch (inst_len={d}):", .{ name, inst_len }); for (0..inst_len) |j| { - std.debug.print(" zig[{d}]={d}({s}) c[{d}]={d}({s})", .{ j, zig_tags[j], airTagNameSlice(zig_tags[j]), j, c_tags[j], airTagNameSlice(c_tags[j]) }); + std.debug.print(" a[{d}]={d}({s}) b[{d}]={d}({s})", .{ j, a.tags[j], airTagNameSlice(a.tags[j]), j, b.tags[j], airTagNameSlice(b.tags[j]) }); } std.debug.print("\n", .{}); return error.AirMismatch; @@ -671,45 +667,35 @@ fn airCompareOne(name: []const u8, zig_air: *const c.Air, c_air: *const c.Air) ! // (un_op, no_op, ty, repeat) leave padding uninitialised — only // compare the meaningful slots per tag via airInstNumSlots. if (inst_len > 0) { - const zig_tags: [*]const u8 = cToOpt(u8, zig_air.inst_tags) orelse unreachable; - const zig_datas: [*]const u8 = @ptrCast(cToOpt(c.AirInstData, zig_air.inst_datas) orelse { - std.debug.print("'{s}': Zig inst_datas is null but inst_len={d}\n", .{ name, inst_len }); - return error.AirMismatch; - }); - const c_datas: [*]const u8 = @ptrCast(cToOpt(c.AirInstData, c_air.inst_datas) orelse { - std.debug.print("'{s}': C inst_datas is null but inst_len={d}\n", .{ name, inst_len }); - return error.AirMismatch; - }); - for (0..inst_len) |j| { const off = j * 8; - const tag_val = zig_tags[j]; + const tag_val = a.tags[j]; const ref_slots = airDataRefSlots(tag_val); const num_slots = airInstNumSlots(tag_val); for (0..num_slots) |slot| { const s = off + slot * 4; - const zig_word = std.mem.readInt(u32, zig_datas[s..][0..4], .little); - const c_word = std.mem.readInt(u32, c_datas[s..][0..4], .little); + const a_word = std.mem.readInt(u32, a.datas[s..][0..4], .little); + const b_word = std.mem.readInt(u32, b.datas[s..][0..4], .little); // Skip data comparison for dead BLOCKs (tag 51). // Dead BLOCKs have undefined data in Zig vs zeroed in C. - // Only check c_word to avoid reading uninitialized Zig data + // Only check b_word to avoid reading uninitialized Zig data // (which triggers valgrind "uninitialised value" errors). - if (tag_val == 51 and c_word == 0) continue; + if (tag_val == 51 and b_word == 0) continue; if (ref_slots[slot]) { // This slot is a Ref — canonicalize IP refs. - const zig_canon = canonicalizeRef(zig_word, &zig_ref_map, &next_zig_id); - const c_canon = canonicalizeRef(c_word, &c_ref_map, &next_c_id); - if (zig_canon != c_canon) { - std.debug.print("'{s}': datas ref mismatch at inst[{d}] slot {d}: zig=0x{x}[{s}] c=0x{x}[{s}] (canon: zig={d} c={d}) (tag={s})\n", .{ name, j, slot, zig_word, refKindStr(zig_word), c_word, refKindStr(c_word), zig_canon, c_canon, airTagNameSlice(tag_val) }); + const a_canon = canonicalizeRef(a_word, &a_ref_map, &next_a_id); + const b_canon = canonicalizeRef(b_word, &b_ref_map, &next_b_id); + if (a_canon != b_canon) { + std.debug.print("'{s}': datas ref mismatch at inst[{d}] slot {d}: a=0x{x}[{s}] b=0x{x}[{s}] (canon: a={d} b={d}) (tag={s})\n", .{ name, j, slot, a_word, refKindStr(a_word), b_word, refKindStr(b_word), a_canon, b_canon, airTagNameSlice(tag_val) }); return error.AirMismatch; } } else { // Non-ref field — compare directly. - if (zig_word != c_word) { - std.debug.print("'{s}': datas mismatch at inst[{d}] slot {d}: zig=0x{x} c=0x{x} (tag={s})\n", .{ name, j, slot, zig_word, c_word, airTagNameSlice(tag_val) }); + if (a_word != b_word) { + std.debug.print("'{s}': datas mismatch at inst[{d}] slot {d}: a=0x{x} b=0x{x} (tag={s})\n", .{ name, j, slot, a_word, b_word, airTagNameSlice(tag_val) }); return error.AirMismatch; } } @@ -718,24 +704,24 @@ fn airCompareOne(name: []const u8, zig_air: *const c.Air, c_air: *const c.Air) ! } // Extra - if (zig_air.extra_len != c_air.extra_len) { - std.debug.print("'{s}': extra_len mismatch: zig={d} c={d}\n", .{ name, zig_air.extra_len, c_air.extra_len }); + if (a.extra_len != b.extra_len) { + std.debug.print("'{s}': extra_len mismatch: a={d} b={d}\n", .{ name, a.extra_len, b.extra_len }); // Print first divergence point - const min_len = @min(zig_air.extra_len, c_air.extra_len); + const min_len = @min(a.extra_len, b.extra_len); if (min_len > 0) { - const zig_e: [*]const u32 = cToOpt(u32, zig_air.extra).?; - const c_e: [*]const u32 = cToOpt(u32, c_air.extra).?; var printed: u32 = 0; for (0..min_len) |ei| { - if (zig_e[ei] != c_e[ei] and printed < 40) { - std.debug.print(" extra[{d}]: zig={d} c={d}\n", .{ ei, zig_e[ei], c_e[ei] }); + const a_val = readExtraWord(a.extra, ei); + const b_val = readExtraWord(b.extra, ei); + if (a_val != b_val and printed < 40) { + std.debug.print(" extra[{d}]: a={d} b={d}\n", .{ ei, a_val, b_val }); printed += 1; } } // Also dump the raw extra arrays around the first divergence var first_diff: usize = min_len; for (0..min_len) |ei| { - if (zig_e[ei] != c_e[ei]) { + if (readExtraWord(a.extra, ei) != readExtraWord(b.extra, ei)) { first_diff = ei; break; } @@ -743,96 +729,85 @@ fn airCompareOne(name: []const u8, zig_air: *const c.Air, c_air: *const c.Air) ! if (first_diff < min_len) { const start = if (first_diff > 5) first_diff - 5 else 0; const end = @min(first_diff + 20, min_len); - std.debug.print(" zig extra[{d}..{d}]:", .{ start, end }); - for (start..end) |ei| std.debug.print(" {d}", .{zig_e[ei]}); - std.debug.print("\n c extra[{d}..{d}]:", .{ start, end }); - for (start..end) |ei| std.debug.print(" {d}", .{c_e[ei]}); + std.debug.print(" a extra[{d}..{d}]:", .{ start, end }); + for (start..end) |ei| std.debug.print(" {d}", .{readExtraWord(a.extra, ei)}); + std.debug.print("\n b extra[{d}..{d}]:", .{ start, end }); + for (start..end) |ei| std.debug.print(" {d}", .{readExtraWord(b.extra, ei)}); std.debug.print("\n", .{}); } } return error.AirMismatch; } - const extra_len = zig_air.extra_len; + const extra_len = a.extra_len; if (extra_len > 0) { - const zig_extra: [*]const u32 = cToOpt(u32, zig_air.extra) orelse { - std.debug.print("'{s}': Zig extra is null but extra_len={d}\n", .{ name, extra_len }); - return error.AirMismatch; - }; - const c_extra: [*]const u32 = cToOpt(u32, c_air.extra) orelse { - std.debug.print("'{s}': C extra is null but extra_len={d}\n", .{ name, extra_len }); - return error.AirMismatch; - }; // Make mutable copies and normalize NullTerminatedString padding. // Zig's appendAirString leaves trailing bytes uninitialised (0xaa // in debug); the C side zeroes them. Normalise both to zero. - const zig_extra_copy = try std.testing.allocator.alloc(u32, extra_len); - defer std.testing.allocator.free(zig_extra_copy); - @memcpy(zig_extra_copy, zig_extra[0..extra_len]); - const c_extra_copy = try std.testing.allocator.alloc(u32, extra_len); - defer std.testing.allocator.free(c_extra_copy); - @memcpy(c_extra_copy, c_extra[0..extra_len]); + const a_extra_copy = try std.testing.allocator.alloc(u32, extra_len); + defer std.testing.allocator.free(a_extra_copy); + @memcpy(std.mem.sliceAsBytes(a_extra_copy), a.extra[0 .. extra_len * 4]); + const b_extra_copy = try std.testing.allocator.alloc(u32, extra_len); + defer std.testing.allocator.free(b_extra_copy); + @memcpy(std.mem.sliceAsBytes(b_extra_copy), b.extra[0 .. extra_len * 4]); if (inst_len > 0) { - const tags: [*]const u8 = cToOpt(u8, zig_air.inst_tags).?; - const zig_datas_raw: [*]const u8 = @ptrCast(cToOpt(c.AirInstData, zig_air.inst_datas).?); - const c_datas_raw: [*]const u8 = @ptrCast(cToOpt(c.AirInstData, c_air.inst_datas).?); for (0..inst_len) |j| { - if (tags[j] == c.AIR_INST_DBG_VAR_VAL or - tags[j] == c.AIR_INST_DBG_VAR_PTR or - tags[j] == c.AIR_INST_DBG_ARG_INLINE) + if (a.tags[j] == c.AIR_INST_DBG_VAR_VAL or + a.tags[j] == c.AIR_INST_DBG_VAR_PTR or + a.tags[j] == c.AIR_INST_DBG_ARG_INLINE) { // pl_op: slot 0 = operand, slot 1 = payload (NullTerminatedString) - const zig_nts = std.mem.readInt(u32, zig_datas_raw[j * 8 + 4 ..][0..4], .little); - const c_nts = std.mem.readInt(u32, c_datas_raw[j * 8 + 4 ..][0..4], .little); - normalizeNtsPadding(zig_extra_copy, zig_nts); - normalizeNtsPadding(c_extra_copy, c_nts); + const a_nts = std.mem.readInt(u32, a.datas[j * 8 + 4 ..][0..4], .little); + const b_nts = std.mem.readInt(u32, b.datas[j * 8 + 4 ..][0..4], .little); + normalizeNtsPadding(a_extra_copy, a_nts); + normalizeNtsPadding(b_extra_copy, b_nts); } - if (tags[j] == c.AIR_INST_DBG_INLINE_BLOCK) { + if (a.tags[j] == c.AIR_INST_DBG_INLINE_BLOCK) { // ty_pl: slot 1 = payload (extra index). // Extra layout: {func(IP ref), body_len, body...} // Canonicalize the func IP ref. - const zig_payload = std.mem.readInt(u32, zig_datas_raw[j * 8 + 4 ..][0..4], .little); - const c_payload = std.mem.readInt(u32, c_datas_raw[j * 8 + 4 ..][0..4], .little); - if (zig_payload < extra_len and c_payload < extra_len) { - zig_extra_copy[zig_payload] = canonicalizeRef(zig_extra_copy[zig_payload], &zig_ref_map, &next_zig_id); - c_extra_copy[c_payload] = canonicalizeRef(c_extra_copy[c_payload], &c_ref_map, &next_c_id); + const a_payload = std.mem.readInt(u32, a.datas[j * 8 + 4 ..][0..4], .little); + const b_payload = std.mem.readInt(u32, b.datas[j * 8 + 4 ..][0..4], .little); + if (a_payload < extra_len and b_payload < extra_len) { + a_extra_copy[a_payload] = canonicalizeRef(a_extra_copy[a_payload], &a_ref_map, &next_a_id); + b_extra_copy[b_payload] = canonicalizeRef(b_extra_copy[b_payload], &b_ref_map, &next_b_id); } } - if (tags[j] == c.AIR_INST_CALL or - tags[j] == c.AIR_INST_CALL_ALWAYS_TAIL or - tags[j] == c.AIR_INST_CALL_NEVER_TAIL or - tags[j] == c.AIR_INST_CALL_NEVER_INLINE) + if (a.tags[j] == c.AIR_INST_CALL or + a.tags[j] == c.AIR_INST_CALL_ALWAYS_TAIL or + a.tags[j] == c.AIR_INST_CALL_NEVER_TAIL or + a.tags[j] == c.AIR_INST_CALL_NEVER_INLINE) { // pl_op: slot 1 = payload (extra index). // Extra layout: {args_len, arg_refs[0..args_len]} // Canonicalize arg refs (they may be IP refs). - const zig_payload = std.mem.readInt(u32, zig_datas_raw[j * 8 + 4 ..][0..4], .little); - const c_payload = std.mem.readInt(u32, c_datas_raw[j * 8 + 4 ..][0..4], .little); - if (zig_payload < extra_len and c_payload < extra_len) { - const zig_args_len = zig_extra_copy[zig_payload]; - const c_args_len = c_extra_copy[c_payload]; + const a_payload = std.mem.readInt(u32, a.datas[j * 8 + 4 ..][0..4], .little); + const b_payload = std.mem.readInt(u32, b.datas[j * 8 + 4 ..][0..4], .little); + if (a_payload < extra_len and b_payload < extra_len) { + const a_args_len = a_extra_copy[a_payload]; + const b_args_len = b_extra_copy[b_payload]; var ai: u32 = 0; - while (ai < zig_args_len and ai < c_args_len) : (ai += 1) { - const zi = zig_payload + 1 + ai; - const ci = c_payload + 1 + ai; - if (zi < extra_len and ci < extra_len) { - zig_extra_copy[zi] = canonicalizeRef(zig_extra_copy[zi], &zig_ref_map, &next_zig_id); - c_extra_copy[ci] = canonicalizeRef(c_extra_copy[ci], &c_ref_map, &next_c_id); + while (ai < a_args_len and ai < b_args_len) : (ai += 1) { + const a_idx = a_payload + 1 + ai; + const b_idx = b_payload + 1 + ai; + if (a_idx < extra_len and b_idx < extra_len) { + a_extra_copy[a_idx] = canonicalizeRef(a_extra_copy[a_idx], &a_ref_map, &next_a_id); + b_extra_copy[b_idx] = canonicalizeRef(b_extra_copy[b_idx], &b_ref_map, &next_b_id); } } } } } } - if (!std.mem.eql(u32, zig_extra_copy, c_extra_copy)) { + if (!std.mem.eql(u32, a_extra_copy, b_extra_copy)) { std.debug.print("'{s}': extra mismatch (extra_len={d})\n", .{ name, extra_len }); - std.debug.print(" zig extra:", .{}); - for (0..extra_len) |ei| std.debug.print(" {d}", .{zig_extra_copy[ei]}); - std.debug.print("\n c extra:", .{}); - for (0..extra_len) |ei| std.debug.print(" {d}", .{c_extra_copy[ei]}); + std.debug.print(" a extra:", .{}); + for (0..extra_len) |ei| std.debug.print(" {d}", .{a_extra_copy[ei]}); + std.debug.print("\n b extra:", .{}); + for (0..extra_len) |ei| std.debug.print(" {d}", .{b_extra_copy[ei]}); std.debug.print("\n", .{}); for (0..extra_len) |ei| { - if (zig_extra_copy[ei] != c_extra_copy[ei]) { - std.debug.print(" extra[{d}]: zig=0x{x} c=0x{x}\n", .{ ei, zig_extra_copy[ei], c_extra_copy[ei] }); + if (a_extra_copy[ei] != b_extra_copy[ei]) { + std.debug.print(" extra[{d}]: a=0x{x} b=0x{x}\n", .{ ei, a_extra_copy[ei], b_extra_copy[ei] }); } } return error.AirMismatch; @@ -843,7 +818,6 @@ fn airCompareOne(name: []const u8, zig_air: *const c.Air, c_air: *const c.Air) ! const corpus = @import("corpus.zig"); test "sema air: unit tests" { - const gpa = std.testing.allocator; @setEvalBranchQuota(corpus.sema_unit_tests.len * 2); inline for (corpus.sema_unit_tests) |path| { const source: [:0]const u8 = @embedFile("../" ++ path); @@ -851,8 +825,8 @@ test "sema air: unit tests" { defer result.deinit(); const air_data = @import("air_data").getData(path); - const precomputed = try parsePrecomputedAir(gpa, air_data); - defer freePrecomputedAir(gpa, precomputed); + const precomputed = try parsePrecomputedAir(air_data); + defer freePrecomputedAir(precomputed); airComparePrecomputed(precomputed, result.c_func_air_list) catch { std.debug.print("FAIL: {s}\n", .{path}); return error.TestFailed; diff --git a/stage0/stages_test.zig b/stage0/stages_test.zig @@ -91,8 +91,8 @@ fn stagesCheck(gpa: Allocator, comptime path: []const u8, source: [:0]const u8) defer sc.semaFuncAirListDeinit(&c_func_air_list); const air_data = @import("air_data").getData(path); - const precomputed = try sema_test.parsePrecomputedAir(gpa, air_data); - defer sema_test.freePrecomputedAir(gpa, precomputed); + const precomputed = try sema_test.parsePrecomputedAir(air_data); + defer sema_test.freePrecomputedAir(precomputed); try sema_test.airComparePrecomputed(precomputed, c_func_air_list); } }