authorgravatar for topolarity@tapscott.meCody Tapscott <topolarity@tapscott.me> 2022-07-30 06:34:49-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-30 12:36:11-07:00
logc0a1b4fa46dfd00d0cc4d1b6954bc07ae762e31e
tree0a1c5d0951abca83fc9610d6c99093b63563c23a
parent8632e4fc7b6cad33b951f71298ee6ac478e133cb

stage2: Fix AIR printing

Packed structs never have comptime fields, and a slice might actually be backed by a variable, which we need to catch before iterating its elements.

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

src/TypedValue.zig+10-4
......@@ -73,6 +73,9 @@ pub fn print(
7373 const target = mod.getTarget();
7474 var val = tv.val;
7575 var ty = tv.ty;
76 if (val.isVariable(mod))
77 return writer.writeAll("(variable)");
78
7679 while (true) switch (val.tag()) {
7780 .u1_type => return writer.writeAll("u1"),
7881 .u8_type => return writer.writeAll("u8"),
......@@ -155,9 +158,12 @@ pub fn print(
155158 }
156159 try print(.{
157160 .ty = ty.structFieldType(i),
158 .val = ty.structFieldValueComptime(i) orelse b: {
159 const vals = val.castTag(.aggregate).?.data;
160 break :b vals[i];
161 .val = switch (ty.containerLayout()) {
162 .Packed => val.castTag(.aggregate).?.data[i],
163 else => ty.structFieldValueComptime(i) orelse b: {
164 const vals = val.castTag(.aggregate).?.data;
165 break :b vals[i];
166 },
161167 },
162168 }, writer, level - 1, mod);
163169 }
......@@ -241,7 +247,7 @@ pub fn print(
241247 mod.declPtr(val.castTag(.function).?.data.owner_decl).name,
242248 }),
243249 .extern_fn => return writer.writeAll("(extern function)"),
244 .variable => return writer.writeAll("(variable)"),
250 .variable => unreachable,
245251 .decl_ref_mut => {
246252 const decl_index = val.castTag(.decl_ref_mut).?.data.decl_index;
247253 const decl = mod.declPtr(decl_index);
src/value.zig+20
......@@ -2664,6 +2664,26 @@ pub const Value = extern union {
26642664 }
26652665 }
26662666
2667 /// Returns true if a Value is backed by a variable
2668 pub fn isVariable(
2669 val: Value,
2670 mod: *Module,
2671 ) bool {
2672 return switch (val.tag()) {
2673 .slice => val.castTag(.slice).?.data.ptr.isVariable(mod),
2674 .comptime_field_ptr => val.castTag(.comptime_field_ptr).?.data.field_val.isVariable(mod),
2675 .elem_ptr => val.castTag(.elem_ptr).?.data.array_ptr.isVariable(mod),
2676 .field_ptr => val.castTag(.field_ptr).?.data.container_ptr.isVariable(mod),
2677 .eu_payload_ptr => val.castTag(.eu_payload_ptr).?.data.container_ptr.isVariable(mod),
2678 .opt_payload_ptr => val.castTag(.opt_payload_ptr).?.data.container_ptr.isVariable(mod),
2679 .decl_ref => mod.declPtr(val.castTag(.decl_ref).?.data).val.isVariable(mod),
2680 .decl_ref_mut => mod.declPtr(val.castTag(.decl_ref_mut).?.data.decl_index).val.isVariable(mod),
2681
2682 .variable => true,
2683 else => false,
2684 };
2685 }
2686
26672687 // Asserts that the provided start/end are in-bounds.
26682688 pub fn sliceArray(
26692689 val: Value,