| author | |
| committer | |
| log | 2f05b1482a6f62658cc70c252d48a24a40404aa8 |
| tree | 17384a9a13b9cb993918ded8c83b8d7a123e6b47 |
| parent | ac07ddadeb36019c262b4f28a4fa3884f6f50b32 |
* Add some assertions to make sure instructions are not none. I tested
all these with master branch as well and made sure the behavior tests
still passed with the assertions intact (along with a handful of
callsite updates).
* Fix Sema.resolveMaybeUndefValAllowVariablesMaybeRuntime not noticing
that interned values are comptime-known. This was causing all kinds
of chaos.
* Fix print_air writeType calling tag() without checking for ip_index6 files changed, 47 insertions(+), 28 deletions(-)
src/Air.zig+11-5| ... | ... | @@ -925,7 +925,7 @@ pub const Inst = struct { |
| 925 | 925 | |
| 926 | 926 | /// This Ref does not correspond to any AIR instruction or constant |
| 927 | 927 | /// value and may instead be used as a sentinel to indicate null. |
| 928 | none = std.math.maxInt(u32), | |
| 928 | none = @enumToInt(InternPool.Index.none), | |
| 929 | 929 | _, |
| 930 | 930 | }; |
| 931 | 931 | |
| ... | ... | @@ -1461,11 +1461,12 @@ pub fn deinit(air: *Air, gpa: std.mem.Allocator) void { |
| 1461 | 1461 | |
| 1462 | 1462 | pub const ref_start_index: u32 = InternPool.static_len; |
| 1463 | 1463 | |
| 1464 | pub fn indexToRef(inst: Air.Inst.Index) Air.Inst.Ref { | |
| 1465 | return @intToEnum(Air.Inst.Ref, ref_start_index + inst); | |
| 1464 | pub fn indexToRef(inst: Inst.Index) Inst.Ref { | |
| 1465 | return @intToEnum(Inst.Ref, ref_start_index + inst); | |
| 1466 | 1466 | } |
| 1467 | 1467 | |
| 1468 | pub fn refToIndex(inst: Air.Inst.Ref) ?Air.Inst.Index { | |
| 1468 | pub fn refToIndex(inst: Inst.Ref) ?Inst.Index { | |
| 1469 | assert(inst != .none); | |
| 1469 | 1470 | const ref_int = @enumToInt(inst); |
| 1470 | 1471 | if (ref_int >= ref_start_index) { |
| 1471 | 1472 | return ref_int - ref_start_index; |
| ... | ... | @@ -1474,8 +1475,13 @@ pub fn refToIndex(inst: Air.Inst.Ref) ?Air.Inst.Index { |
| 1474 | 1475 | } |
| 1475 | 1476 | } |
| 1476 | 1477 | |
| 1478 | pub fn refToIndexAllowNone(inst: Inst.Ref) ?Inst.Index { | |
| 1479 | if (inst == .none) return null; | |
| 1480 | return refToIndex(inst); | |
| 1481 | } | |
| 1482 | ||
| 1477 | 1483 | /// Returns `null` if runtime-known. |
| 1478 | pub fn value(air: Air, inst: Air.Inst.Ref, mod: *const Module) ?Value { | |
| 1484 | pub fn value(air: Air, inst: Inst.Ref, mod: *const Module) ?Value { | |
| 1479 | 1485 | const ref_int = @enumToInt(inst); |
| 1480 | 1486 | if (ref_int < ref_start_index) { |
| 1481 | 1487 | const ip_index = @intToEnum(InternPool.Index, ref_int); |
src/Liveness.zig+2-2| ... | ... | @@ -1268,7 +1268,7 @@ fn analyzeOperands( |
| 1268 | 1268 | _ = data.live_set.remove(inst); |
| 1269 | 1269 | |
| 1270 | 1270 | for (operands) |op_ref| { |
| 1271 | const operand = Air.refToIndex(op_ref) orelse continue; | |
| 1271 | const operand = Air.refToIndexAllowNone(op_ref) orelse continue; | |
| 1272 | 1272 | |
| 1273 | 1273 | // Don't compute any liveness for constants |
| 1274 | 1274 | switch (inst_tags[operand]) { |
| ... | ... | @@ -1304,7 +1304,7 @@ fn analyzeOperands( |
| 1304 | 1304 | while (i > 0) { |
| 1305 | 1305 | i -= 1; |
| 1306 | 1306 | const op_ref = operands[i]; |
| 1307 | const operand = Air.refToIndex(op_ref) orelse continue; | |
| 1307 | const operand = Air.refToIndexAllowNone(op_ref) orelse continue; | |
| 1308 | 1308 | |
| 1309 | 1309 | // Don't compute any liveness for constants |
| 1310 | 1310 | switch (inst_tags[operand]) { |
src/Liveness/Verify.zig+1-1| ... | ... | @@ -555,7 +555,7 @@ fn verifyDeath(self: *Verify, inst: Air.Inst.Index, operand: Air.Inst.Index) Err |
| 555 | 555 | } |
| 556 | 556 | |
| 557 | 557 | fn verifyOperand(self: *Verify, inst: Air.Inst.Index, op_ref: Air.Inst.Ref, dies: bool) Error!void { |
| 558 | const operand = Air.refToIndex(op_ref) orelse return; | |
| 558 | const operand = Air.refToIndexAllowNone(op_ref) orelse return; | |
| 559 | 559 | switch (self.air.instructions.items(.tag)[operand]) { |
| 560 | 560 | .constant, .const_ty, .interned => {}, |
| 561 | 561 | else => { |
src/Sema.zig+19-14| ... | ... | @@ -968,7 +968,7 @@ fn analyzeBodyInner( |
| 968 | 968 | .int_big => try sema.zirIntBig(block, inst), |
| 969 | 969 | .float => try sema.zirFloat(block, inst), |
| 970 | 970 | .float128 => try sema.zirFloat128(block, inst), |
| 971 | .int_type => try sema.zirIntType(block, inst), | |
| 971 | .int_type => try sema.zirIntType(inst), | |
| 972 | 972 | .is_non_err => try sema.zirIsNonErr(block, inst), |
| 973 | 973 | .is_non_err_ptr => try sema.zirIsNonErrPtr(block, inst), |
| 974 | 974 | .ret_is_non_err => try sema.zirRetIsNonErr(block, inst), |
| ... | ... | @@ -1694,7 +1694,7 @@ fn analyzeBodyInner( |
| 1694 | 1694 | const extra = sema.code.extraData(Zir.Inst.DeferErrCode, inst_data.payload_index).data; |
| 1695 | 1695 | const defer_body = sema.code.extra[extra.index..][0..extra.len]; |
| 1696 | 1696 | const err_code = try sema.resolveInst(inst_data.err_code); |
| 1697 | sema.inst_map.putAssumeCapacity(extra.remapped_err_code, err_code); | |
| 1697 | map.putAssumeCapacity(extra.remapped_err_code, err_code); | |
| 1698 | 1698 | const break_inst = sema.analyzeBodyInner(block, defer_body) catch |err| switch (err) { |
| 1699 | 1699 | error.ComptimeBreak => sema.comptime_break_inst, |
| 1700 | 1700 | else => |e| return e, |
| ... | ... | @@ -1730,7 +1730,16 @@ fn analyzeBodyInner( |
| 1730 | 1730 | return result; |
| 1731 | 1731 | } |
| 1732 | 1732 | |
| 1733 | pub fn resolveInstAllowNone(sema: *Sema, zir_ref: Zir.Inst.Ref) !Air.Inst.Ref { | |
| 1734 | if (zir_ref == .none) { | |
| 1735 | return .none; | |
| 1736 | } else { | |
| 1737 | return resolveInst(sema, zir_ref); | |
| 1738 | } | |
| 1739 | } | |
| 1740 | ||
| 1733 | 1741 | pub fn resolveInst(sema: *Sema, zir_ref: Zir.Inst.Ref) !Air.Inst.Ref { |
| 1742 | assert(zir_ref != .none); | |
| 1734 | 1743 | const i = @enumToInt(zir_ref); |
| 1735 | 1744 | // First section of indexes correspond to a set number of constant values. |
| 1736 | 1745 | // We intentionally map the same indexes to the same values between ZIR and AIR. |
| ... | ... | @@ -1969,6 +1978,7 @@ fn resolveMaybeUndefValAllowVariablesMaybeRuntime( |
| 1969 | 1978 | inst: Air.Inst.Ref, |
| 1970 | 1979 | make_runtime: *bool, |
| 1971 | 1980 | ) CompileError!?Value { |
| 1981 | assert(inst != .none); | |
| 1972 | 1982 | // First section of indexes correspond to a set number of constant values. |
| 1973 | 1983 | const int = @enumToInt(inst); |
| 1974 | 1984 | if (int < InternPool.static_len) { |
| ... | ... | @@ -1985,17 +1995,17 @@ fn resolveMaybeUndefValAllowVariablesMaybeRuntime( |
| 1985 | 1995 | } |
| 1986 | 1996 | return opv; |
| 1987 | 1997 | } |
| 1998 | const air_datas = sema.air_instructions.items(.data); | |
| 1988 | 1999 | switch (air_tags[i]) { |
| 1989 | 2000 | .constant => { |
| 1990 | const ty_pl = sema.air_instructions.items(.data)[i].ty_pl; | |
| 2001 | const ty_pl = air_datas[i].ty_pl; | |
| 1991 | 2002 | const val = sema.air_values.items[ty_pl.payload]; |
| 1992 | 2003 | if (val.tag() == .runtime_value) make_runtime.* = true; |
| 1993 | 2004 | if (val.isPtrToThreadLocal(sema.mod)) make_runtime.* = true; |
| 1994 | 2005 | return val; |
| 1995 | 2006 | }, |
| 1996 | .const_ty => { | |
| 1997 | return try sema.air_instructions.items(.data)[i].ty.toValue(sema.arena); | |
| 1998 | }, | |
| 2007 | .const_ty => return try air_datas[i].ty.toValue(sema.arena), | |
| 2008 | .interned => return air_datas[i].interned.toValue(), | |
| 1999 | 2009 | else => return null, |
| 2000 | 2010 | } |
| 2001 | 2011 | } |
| ... | ... | @@ -7913,15 +7923,10 @@ fn emitDbgInline( |
| 7913 | 7923 | }); |
| 7914 | 7924 | } |
| 7915 | 7925 | |
| 7916 | fn zirIntType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | |
| 7917 | _ = block; | |
| 7918 | const tracy = trace(@src()); | |
| 7919 | defer tracy.end(); | |
| 7920 | ||
| 7926 | fn zirIntType(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | |
| 7921 | 7927 | const mod = sema.mod; |
| 7922 | 7928 | const int_type = sema.code.instructions.items(.data)[inst].int_type; |
| 7923 | 7929 | const ty = try mod.intType(int_type.signedness, int_type.bit_count); |
| 7924 | ||
| 7925 | 7930 | return sema.addType(ty); |
| 7926 | 7931 | } |
| 7927 | 7932 | |
| ... | ... | @@ -17509,7 +17514,7 @@ fn zirRestoreErrRetIndex(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) |
| 17509 | 17514 | const tracy = trace(@src()); |
| 17510 | 17515 | defer tracy.end(); |
| 17511 | 17516 | |
| 17512 | const saved_index = if (Zir.refToIndex(inst_data.block)) |zir_block| b: { | |
| 17517 | const saved_index = if (Zir.refToIndexAllowNone(inst_data.block)) |zir_block| b: { | |
| 17513 | 17518 | var block = start_block; |
| 17514 | 17519 | while (true) { |
| 17515 | 17520 | if (block.label) |label| { |
| ... | ... | @@ -17535,7 +17540,7 @@ fn zirRestoreErrRetIndex(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) |
| 17535 | 17540 | |
| 17536 | 17541 | assert(saved_index != .none); // The .error_return_trace_index field was dropped somewhere |
| 17537 | 17542 | |
| 17538 | const operand = try sema.resolveInst(inst_data.operand); | |
| 17543 | const operand = try sema.resolveInstAllowNone(inst_data.operand); | |
| 17539 | 17544 | return sema.popErrorReturnTrace(start_block, src, operand, saved_index); |
| 17540 | 17545 | } |
| 17541 | 17546 |
src/Zir.zig+8-2| ... | ... | @@ -2132,7 +2132,7 @@ pub const Inst = struct { |
| 2132 | 2132 | |
| 2133 | 2133 | /// This Ref does not correspond to any ZIR instruction or constant |
| 2134 | 2134 | /// value and may instead be used as a sentinel to indicate null. |
| 2135 | none = std.math.maxInt(u32), | |
| 2135 | none = @enumToInt(InternPool.Index.none), | |
| 2136 | 2136 | _, |
| 2137 | 2137 | }; |
| 2138 | 2138 | |
| ... | ... | @@ -3814,13 +3814,14 @@ pub fn getFnInfo(zir: Zir, fn_inst: Inst.Index) FnInfo { |
| 3814 | 3814 | }; |
| 3815 | 3815 | } |
| 3816 | 3816 | |
| 3817 | const ref_start_index: u32 = InternPool.static_len; | |
| 3817 | pub const ref_start_index: u32 = InternPool.static_len; | |
| 3818 | 3818 | |
| 3819 | 3819 | pub fn indexToRef(inst: Inst.Index) Inst.Ref { |
| 3820 | 3820 | return @intToEnum(Inst.Ref, ref_start_index + inst); |
| 3821 | 3821 | } |
| 3822 | 3822 | |
| 3823 | 3823 | pub fn refToIndex(inst: Inst.Ref) ?Inst.Index { |
| 3824 | assert(inst != .none); | |
| 3824 | 3825 | const ref_int = @enumToInt(inst); |
| 3825 | 3826 | if (ref_int >= ref_start_index) { |
| 3826 | 3827 | return ref_int - ref_start_index; |
| ... | ... | @@ -3828,3 +3829,8 @@ pub fn refToIndex(inst: Inst.Ref) ?Inst.Index { |
| 3828 | 3829 | return null; |
| 3829 | 3830 | } |
| 3830 | 3831 | } |
| 3832 | ||
| 3833 | pub fn refToIndexAllowNone(inst: Inst.Ref) ?Inst.Index { | |
| 3834 | if (inst == .none) return null; | |
| 3835 | return refToIndex(inst); | |
| 3836 | } |
src/print_air.zig+6-4| ... | ... | @@ -366,10 +366,12 @@ const Writer = struct { |
| 366 | 366 | } |
| 367 | 367 | |
| 368 | 368 | fn writeType(w: *Writer, s: anytype, ty: Type) !void { |
| 369 | const t = ty.tag(); | |
| 370 | switch (t) { | |
| 371 | .inferred_alloc_const => try s.writeAll("(inferred_alloc_const)"), | |
| 372 | .inferred_alloc_mut => try s.writeAll("(inferred_alloc_mut)"), | |
| 369 | switch (ty.ip_index) { | |
| 370 | .none => switch (ty.tag()) { | |
| 371 | .inferred_alloc_const => try s.writeAll("(inferred_alloc_const)"), | |
| 372 | .inferred_alloc_mut => try s.writeAll("(inferred_alloc_mut)"), | |
| 373 | else => try ty.print(s, w.module), | |
| 374 | }, | |
| 373 | 375 | else => try ty.print(s, w.module), |
| 374 | 376 | } |
| 375 | 377 | } |