fixes for this branch

I had to bring back some of the old API so that I could compile the new
compiler with an old compiler.
This commit is contained in:
Andrew Kelley 2024-09-25 13:22:47 -07:00
parent 4f8d244e7e
commit 9ccf8d3332
5 changed files with 152 additions and 75 deletions

View File

@ -761,18 +761,91 @@ pub const TestFn = struct {
func: *const fn () anyerror!void,
};
const old_version = std.SemanticVersion.parse("0.14.0-dev.1659+4ceefca14") catch unreachable;
const is_old = @import("builtin").zig_version.order(old_version) != .gt;
/// This function type is used by the Zig language code generation and
/// therefore must be kept in sync with the compiler implementation.
pub const PanicFn = fn (PanicCause, ?*StackTrace, ?usize) noreturn;
pub const PanicFn = if (is_old)
fn ([]const u8, ?*StackTrace, ?usize) noreturn
else
fn (PanicCause, ?*StackTrace, ?usize) noreturn;
/// The entry point for auto-generated calls by the compiler.
pub const panic: PanicFn = if (@hasDecl(root, "panic"))
pub const panic: PanicFn = if (is_old)
defaultPanicOld
else if (@hasDecl(root, "panic"))
root.panic
else if (@hasDecl(root, "os") and @hasDecl(root.os, "panic"))
root.os.panic
else
std.debug.defaultPanic;
pub fn defaultPanicOld(
msg: []const u8,
trace: ?*const std.builtin.StackTrace,
first_trace_addr: ?usize,
) noreturn {
@branchHint(.cold);
std.debug.print("old panic: {s}\n", .{msg});
_ = trace;
_ = first_trace_addr;
@trap();
}
pub fn panicSentinelMismatch(expected: anytype, actual: @TypeOf(expected)) noreturn {
@branchHint(.cold);
std.debug.panicExtra(null, @returnAddress(), "sentinel mismatch: expected {any}, found {any}", .{ expected, actual });
}
pub fn panicUnwrapError(st: ?*StackTrace, err: anyerror) noreturn {
@branchHint(.cold);
std.debug.panicExtra(st, @returnAddress(), "attempt to unwrap error: {s}", .{@errorName(err)});
}
pub fn panicOutOfBounds(index: usize, len: usize) noreturn {
@branchHint(.cold);
std.debug.panicExtra(null, @returnAddress(), "index out of bounds: index {d}, len {d}", .{ index, len });
}
pub fn panicStartGreaterThanEnd(start: usize, end: usize) noreturn {
@branchHint(.cold);
std.debug.panicExtra(null, @returnAddress(), "start index {d} is larger than end index {d}", .{ start, end });
}
pub fn panicInactiveUnionField(active: anytype, wanted: @TypeOf(active)) noreturn {
@branchHint(.cold);
std.debug.panicExtra(null, @returnAddress(), "access of union field '{s}' while field '{s}' is active", .{ @tagName(wanted), @tagName(active) });
}
pub const panic_messages = struct {
pub const unreach = "reached unreachable code";
pub const unwrap_null = "attempt to use null value";
pub const cast_to_null = "cast causes pointer to be null";
pub const incorrect_alignment = "incorrect alignment";
pub const invalid_error_code = "invalid error code";
pub const cast_truncated_data = "integer cast truncated bits";
pub const negative_to_unsigned = "attempt to cast negative value to unsigned integer";
pub const integer_overflow = "integer overflow";
pub const shl_overflow = "left shift overflowed bits";
pub const shr_overflow = "right shift overflowed bits";
pub const divide_by_zero = "division by zero";
pub const exact_division_remainder = "exact division produced remainder";
pub const inactive_union_field = "access of inactive union field";
pub const integer_part_out_of_bounds = "integer part of floating point value out of bounds";
pub const corrupt_switch = "switch on corrupt value";
pub const shift_rhs_too_big = "shift amount is greater than the type size";
pub const invalid_enum_value = "invalid enum value";
pub const sentinel_mismatch = "sentinel mismatch";
pub const unwrap_error = "attempt to unwrap error";
pub const index_out_of_bounds = "index out of bounds";
pub const start_index_greater_than_end = "start index is larger than end index";
pub const for_len_mismatch = "for loop over objects with non-equal lengths";
pub const memcpy_len_mismatch = "@memcpy arguments have non-equal lengths";
pub const memcpy_alias = "@memcpy arguments alias";
pub const noreturn_returned = "'noreturn' function returned";
};
/// This data structure is used by the Zig language code generation and
/// therefore must be kept in sync with the compiler implementation.
pub const PanicCause = union(enum) {

View File

@ -437,7 +437,7 @@ pub fn panicExtra(
break :blk &buf;
},
};
std.builtin.panic(msg, trace, ret_addr);
std.builtin.panic(.{ .explicit_call = msg }, trace, ret_addr);
}
/// Non-zero whenever the program triggered a panic.
@ -487,18 +487,6 @@ pub fn defaultPanic(
.freestanding => {
@trap();
},
.wasi => {
// TODO: before merging my branch, unify this logic with the main panic logic
var buffer: [1000]u8 = undefined;
var i: usize = 0;
i += fmtPanicCause(buffer[i..], cause);
buffer[i] = '\n';
i += 1;
const msg = buffer[0..i];
lockStdErr();
io.getStdErr().writeAll(msg) catch {};
@trap();
},
.uefi => {
const uefi = std.os.uefi;
@ -571,7 +559,7 @@ pub fn defaultPanic(
i += fmtInt10(buffer[i..], std.Thread.getCurrentId());
i += fmtBuf(buffer[i..], " panic: ");
}
i += fmtPanicCause(&buffer, cause);
i += fmtPanicCause(buffer[i..], cause);
buffer[i] = '\n';
i += 1;
const msg = buffer[0..i];
@ -672,7 +660,7 @@ fn fmtInt10(out_buf: []u8, integer_value: usize) usize {
while (true) {
i -= 1;
tmp_buf[i] = '0' + (a % 10);
tmp_buf[i] = '0' + @as(u8, @intCast(a % 10));
a /= 10;
if (a == 0) break;
}

View File

@ -2566,7 +2566,7 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Zcu.ErrorMsg
std.debug.print("compile error during Sema:\n", .{});
var error_bundle = wip_errors.toOwnedBundle("") catch @panic("out of memory");
error_bundle.renderToStdErr(.{ .ttyconf = .no_color });
crash_report.compilerPanic("unexpected compile error occurred", null, null);
crash_report.compilerPanic(.{ .explicit_call = "unexpected compile error occurred" }, null, null);
}
if (block) |start_block| {
@ -7334,17 +7334,21 @@ fn callPanic(
call_operation: CallOperation,
) !void {
const pt = sema.pt;
if (!pt.zcu.backendSupportsFeature(.panic_fn)) {
const zcu = pt.zcu;
if (!zcu.backendSupportsFeature(.panic_fn)) {
_ = try block.addNoOp(.trap);
return;
}
const panic_cause_ty = try pt.getBuiltinType("PanicCause");
const panic_cause = try block.addUnionInit(panic_cause_ty, @intFromEnum(tag), payload);
const panic_cause = if (payload == .void_value)
try initUnionFromEnumTag(pt, panic_cause_ty, panic_cause_ty.unionTagType(zcu).?, @intFromEnum(tag))
else
try block.addUnionInit(panic_cause_ty, @intFromEnum(tag), payload);
const panic_fn = try pt.getBuiltin("panic");
const err_return_trace = try sema.getErrorReturnTrace(block);
const opt_usize_ty = try pt.optionalType(.usize_type);
const null_usize = try pt.nullValue(opt_usize_ty);
const args: [3]Air.Inst.Ref = .{ panic_cause, err_return_trace, Air.internedToRef(null_usize) };
const args: [3]Air.Inst.Ref = .{ panic_cause, err_return_trace, Air.internedToRef(null_usize.toIntern()) };
try sema.callBuiltin(block, call_src, panic_fn, .auto, &args, call_operation);
}
@ -18326,11 +18330,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
.undefined,
.null,
.enum_literal,
=> |type_info_tag| return Air.internedToRef((try pt.internUnion(.{
.ty = type_info_ty.toIntern(),
.tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(type_info_tag))).toIntern(),
.val = .void_value,
}))),
=> |type_info_tag| return initUnionFromEnumTag(pt, type_info_ty, type_info_tag_ty, @intFromEnum(type_info_tag)),
.@"fn" => {
const fn_info_ty = try getInnerType(sema, block, src, type_info_ty, "Fn");
const param_info_ty = try getInnerType(sema, block, src, fn_info_ty, "Param");
@ -28009,7 +28009,7 @@ fn addSafetyCheckSentinelMismatch(
assert(std.mem.eql(u8, fields[1].name, "found"));
assert(fields.len == 2);
}
const panic_cause_payload = &fail_block.addAggregateInit(mm_ty, &.{ expected_sentinel, actual_sentinel });
const panic_cause_payload = try fail_block.addAggregateInit(mm_ty, &.{ expected_sentinel, actual_sentinel });
try callPanic(sema, &fail_block, src, .sentinel_mismatch_usize, panic_cause_payload, .@"safety check");
} else {
try callPanic(sema, &fail_block, src, .sentinel_mismatch_other, .void_value, .@"safety check");
@ -38997,3 +38997,11 @@ fn getInnerType(
try sema.ensureNavResolved(src, nav);
return Type.fromInterned(ip.getNav(nav).status.resolved.val);
}
fn initUnionFromEnumTag(pt: Zcu.PerThread, union_ty: Type, union_tag_ty: Type, field_index: u32) !Air.Inst.Ref {
return Air.internedToRef((try pt.internUnion(.{
.ty = union_ty.toIntern(),
.tag = (try pt.enumValueFieldIndex(union_tag_ty, field_index)).toIntern(),
.val = .void_value,
})));
}

View File

@ -3848,13 +3848,13 @@ pub const Object = struct {
.undef => unreachable, // handled above
.simple_value => |simple_value| switch (simple_value) {
.undefined,
.void,
.null,
.empty_struct,
.@"unreachable",
.generic_poison,
=> unreachable, // non-runtime values
.undefined => unreachable, // non-runtime value
.void => unreachable, // non-runtime value
.null => unreachable, // non-runtime value
.empty_struct => unreachable, // non-runtime value
.@"unreachable" => unreachable, // non-runtime value
.generic_poison => unreachable, // non-runtime value
.false => .false,
.true => .true,
},
@ -5675,43 +5675,48 @@ pub const FuncGen = struct {
}
}
fn buildSimplePanic(fg: *FuncGen, panic_id: Zcu.PanicId) !void {
const o = fg.ng.object;
const zcu = o.pt.zcu;
const ip = &zcu.intern_pool;
const msg_nav_index = zcu.panic_messages[@intFromEnum(panic_id)].unwrap().?;
const msg_nav = ip.getNav(msg_nav_index);
const msg_len = Type.fromInterned(msg_nav.typeOf(ip)).childType(zcu).arrayLen(zcu);
const msg_ptr = try o.lowerValue(msg_nav.status.resolved.val);
const null_opt_addr_global = try fg.resolveNullOptUsize();
const target = zcu.getTarget();
const llvm_usize = try o.lowerType(Type.usize);
// example:
// call fastcc void @test2.panic(
// ptr @builtin.panic_messages.integer_overflow__anon_987, ; msg.ptr
// i64 16, ; msg.len
// ptr null, ; stack trace
// ptr @2, ; addr (null ?usize)
// )
const panic_func = zcu.funcInfo(zcu.panic_func_index);
const panic_nav = ip.getNav(panic_func.owner_nav);
const fn_info = zcu.typeToFunc(Type.fromInterned(panic_nav.typeOf(ip))).?;
const panic_global = try o.resolveLlvmFunction(panic_func.owner_nav);
_ = try fg.wip.callIntrinsicAssumeCold();
_ = try fg.wip.call(
.normal,
toLlvmCallConv(fn_info.cc, target),
.none,
panic_global.typeOf(&o.builder),
panic_global.toValue(&o.builder),
&.{
msg_ptr.toValue(),
try o.builder.intValue(llvm_usize, msg_len),
try o.builder.nullValue(.ptr),
null_opt_addr_global.toValue(),
},
"",
);
const PanicCauseTag = @typeInfo(std.builtin.PanicCause).@"union".tag_type.?;
fn buildSimplePanic(fg: *FuncGen, panic_cause_tag: PanicCauseTag) !void {
// TODO update this before merging the branch
_ = panic_cause_tag;
//const o = fg.ng.object;
//const zcu = o.pt.zcu;
//const ip = &zcu.intern_pool;
//const msg_nav_index = zcu.panic_messages[@intFromEnum(panic_id)].unwrap().?;
//const msg_nav = ip.getNav(msg_nav_index);
//const msg_len = Type.fromInterned(msg_nav.typeOf(ip)).childType(zcu).arrayLen(zcu);
//const msg_ptr = try o.lowerValue(msg_nav.status.resolved.val);
//const null_opt_addr_global = try fg.resolveNullOptUsize();
//const target = zcu.getTarget();
//const llvm_usize = try o.lowerType(Type.usize);
//// example:
//// call fastcc void @test2.panic(
//// ptr @builtin.panic_messages.integer_overflow__anon_987, ; msg.ptr
//// i64 16, ; msg.len
//// ptr null, ; stack trace
//// ptr @2, ; addr (null ?usize)
//// )
//const panic_func = zcu.funcInfo(zcu.panic_func_index);
//const panic_nav = ip.getNav(panic_func.owner_nav);
//const fn_info = zcu.typeToFunc(Type.fromInterned(panic_nav.typeOf(ip))).?;
//const panic_global = try o.resolveLlvmFunction(panic_func.owner_nav);
//_ = try fg.wip.callIntrinsicAssumeCold();
//_ = try fg.wip.call(
// .normal,
// toLlvmCallConv(fn_info.cc, target),
// .none,
// panic_global.typeOf(&o.builder),
// panic_global.toValue(&o.builder),
// &.{
// msg_ptr.toValue(),
// try o.builder.intValue(llvm_usize, msg_len),
// try o.builder.nullValue(.ptr),
// null_opt_addr_global.toValue(),
// },
// "",
//);
_ = try fg.wip.callIntrinsic(.normal, .none, .trap, &.{}, &.{}, "");
_ = try fg.wip.@"unreachable"();
}

View File

@ -212,7 +212,7 @@ fn handleSegfaultPosix(sig: i32, info: *const posix.siginfo_t, ctx_ptr: ?*anyopa
else => .not_supported,
};
PanicSwitch.dispatch(null, stack_ctx, error_msg);
PanicSwitch.dispatch(null, stack_ctx, .{ .explicit_call = error_msg });
}
const WindowsSegfaultMessage = union(enum) {
@ -338,7 +338,7 @@ const PanicSwitch = struct {
// it's happening and print a message.
var panic_state: *volatile PanicState = &panic_state_raw;
if (panic_state.awaiting_dispatch) {
dispatch(null, .{ .current = .{ .ret_addr = null } }, "Panic while preparing callstack");
dispatch(null, .{ .current = .{ .ret_addr = null } }, .{ .explicit_call = "Panic while preparing callstack" });
}
panic_state.awaiting_dispatch = true;
}
@ -518,6 +518,7 @@ const PanicSwitch = struct {
stack: StackContext,
panic_cause: std.builtin.PanicCause,
) void {
var buffer: [1000]u8 = undefined;
switch (state.recover_verbosity) {
.message_and_stack => {
// lower the verbosity, and restore it at the end if we don't panic.
@ -525,7 +526,8 @@ const PanicSwitch = struct {
const stderr = io.getStdErr().writer();
stderr.writeAll("\nPanicked during a panic: ") catch {};
stderr.writeAll(panic_cause) catch {};
const msg = buffer[0..std.debug.fmtPanicCause(&buffer, panic_cause)];
stderr.writeAll(msg) catch {};
stderr.writeAll("\nInner panic stack:\n") catch {};
if (trace) |t| {
debug.dumpStackTrace(t.*);
@ -539,7 +541,8 @@ const PanicSwitch = struct {
const stderr = io.getStdErr().writer();
stderr.writeAll("\nPanicked while dumping inner panic stack: ") catch {};
stderr.writeAll(panic_cause) catch {};
const msg = buffer[0..std.debug.fmtPanicCause(&buffer, panic_cause)];
stderr.writeAll(msg) catch {};
stderr.writeAll("\n") catch {};
// If we succeed, restore all the way to dumping the stack.