mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 14:25:16 +00:00
Merge pull request #25726 from mlugg/std-log-colors
Cache stderr ttyconf, colorize `std.log`, and fix `--webui`
This commit is contained in:
commit
4174ab9c2c
@ -442,8 +442,7 @@ pub fn main() !void {
|
||||
if (builtin.single_threaded) fatal("'--webui' is not yet supported on single-threaded hosts", .{});
|
||||
}
|
||||
|
||||
const stderr: std.fs.File = .stderr();
|
||||
const ttyconf = get_tty_conf(color, stderr);
|
||||
const ttyconf = color.detectTtyConf();
|
||||
switch (ttyconf) {
|
||||
.no_color => try graph.env_map.put("NO_COLOR", "1"),
|
||||
.escape_codes => try graph.env_map.put("CLICOLOR_FORCE", "1"),
|
||||
@ -522,9 +521,9 @@ pub fn main() !void {
|
||||
.error_style = error_style,
|
||||
.multiline_errors = multiline_errors,
|
||||
.summary = summary orelse if (watch or webui_listen != null) .line else .failures,
|
||||
.ttyconf = ttyconf,
|
||||
.stderr = stderr,
|
||||
.thread_pool = undefined,
|
||||
|
||||
.ttyconf = ttyconf,
|
||||
};
|
||||
defer {
|
||||
run.memory_blocked_steps.deinit(gpa);
|
||||
@ -563,9 +562,9 @@ pub fn main() !void {
|
||||
break :ws .init(.{
|
||||
.gpa = gpa,
|
||||
.thread_pool = &run.thread_pool,
|
||||
.ttyconf = ttyconf,
|
||||
.graph = &graph,
|
||||
.all_steps = run.step_stack.keys(),
|
||||
.ttyconf = run.ttyconf,
|
||||
.root_prog_node = main_progress_node,
|
||||
.watch = watch,
|
||||
.listen_address = listen_address,
|
||||
@ -578,7 +577,7 @@ pub fn main() !void {
|
||||
}
|
||||
|
||||
rebuild: while (true) : (if (run.error_style.clearOnUpdate()) {
|
||||
const bw = std.debug.lockStderrWriter(&stdio_buffer_allocation);
|
||||
const bw, _ = std.debug.lockStderrWriter(&stdio_buffer_allocation);
|
||||
defer std.debug.unlockStderrWriter();
|
||||
try bw.writeAll("\x1B[2J\x1B[3J\x1B[H");
|
||||
}) {
|
||||
@ -682,13 +681,14 @@ const Run = struct {
|
||||
/// Allocated into `gpa`.
|
||||
step_stack: std.AutoArrayHashMapUnmanaged(*Step, void),
|
||||
thread_pool: std.Thread.Pool,
|
||||
/// Similar to the `tty.Config` returned by `std.debug.lockStderrWriter`,
|
||||
/// but also respects the '--color' flag.
|
||||
ttyconf: tty.Config,
|
||||
|
||||
claimed_rss: usize,
|
||||
error_style: ErrorStyle,
|
||||
multiline_errors: MultilineErrors,
|
||||
summary: Summary,
|
||||
ttyconf: tty.Config,
|
||||
stderr: File,
|
||||
};
|
||||
|
||||
fn prepare(
|
||||
@ -834,8 +834,6 @@ fn runStepNames(
|
||||
}
|
||||
}
|
||||
|
||||
const ttyconf = run.ttyconf;
|
||||
|
||||
if (fuzz) |mode| blk: {
|
||||
switch (builtin.os.tag) {
|
||||
// Current implementation depends on two things that need to be ported to Windows:
|
||||
@ -863,9 +861,9 @@ fn runStepNames(
|
||||
gpa,
|
||||
io,
|
||||
thread_pool,
|
||||
run.ttyconf,
|
||||
step_stack.keys(),
|
||||
parent_prog_node,
|
||||
ttyconf,
|
||||
mode,
|
||||
) catch |err| fatal("failed to start fuzzer: {s}", .{@errorName(err)});
|
||||
defer f.deinit();
|
||||
@ -890,8 +888,9 @@ fn runStepNames(
|
||||
.none => break :summary,
|
||||
}
|
||||
|
||||
const w = std.debug.lockStderrWriter(&stdio_buffer_allocation);
|
||||
const w, _ = std.debug.lockStderrWriter(&stdio_buffer_allocation);
|
||||
defer std.debug.unlockStderrWriter();
|
||||
const ttyconf = run.ttyconf;
|
||||
|
||||
const total_count = success_count + failure_count + pending_count + skipped_count;
|
||||
ttyconf.setColor(w, .cyan) catch {};
|
||||
@ -1399,9 +1398,10 @@ fn workerMakeOneStep(
|
||||
const show_error_msgs = s.result_error_msgs.items.len > 0;
|
||||
const show_stderr = s.result_stderr.len > 0;
|
||||
if (show_error_msgs or show_compile_errors or show_stderr) {
|
||||
const bw = std.debug.lockStderrWriter(&stdio_buffer_allocation);
|
||||
const bw, _ = std.debug.lockStderrWriter(&stdio_buffer_allocation);
|
||||
defer std.debug.unlockStderrWriter();
|
||||
printErrorMessages(run.gpa, s, .{ .ttyconf = run.ttyconf }, bw, run.error_style, run.multiline_errors) catch {};
|
||||
const ttyconf = run.ttyconf;
|
||||
printErrorMessages(run.gpa, s, .{}, bw, ttyconf, run.error_style, run.multiline_errors) catch {};
|
||||
}
|
||||
|
||||
handle_result: {
|
||||
@ -1465,11 +1465,10 @@ pub fn printErrorMessages(
|
||||
failing_step: *Step,
|
||||
options: std.zig.ErrorBundle.RenderOptions,
|
||||
stderr: *Writer,
|
||||
ttyconf: tty.Config,
|
||||
error_style: ErrorStyle,
|
||||
multiline_errors: MultilineErrors,
|
||||
) !void {
|
||||
const ttyconf = options.ttyconf;
|
||||
|
||||
if (error_style.verboseContext()) {
|
||||
// Provide context for where these error messages are coming from by
|
||||
// printing the corresponding Step subtree.
|
||||
@ -1513,7 +1512,7 @@ pub fn printErrorMessages(
|
||||
}
|
||||
}
|
||||
|
||||
try failing_step.result_error_bundle.renderToWriter(options, stderr);
|
||||
try failing_step.result_error_bundle.renderToWriter(options, stderr, ttyconf);
|
||||
|
||||
for (failing_step.result_error_msgs.items) |msg| {
|
||||
try ttyconf.setColor(stderr, .red);
|
||||
@ -1759,14 +1758,6 @@ const ErrorStyle = enum {
|
||||
const MultilineErrors = enum { indent, newline, none };
|
||||
const Summary = enum { all, new, failures, line, none };
|
||||
|
||||
fn get_tty_conf(color: Color, stderr: File) tty.Config {
|
||||
return switch (color) {
|
||||
.auto => tty.detectConfig(stderr),
|
||||
.on => .escape_codes,
|
||||
.off => .no_color,
|
||||
};
|
||||
}
|
||||
|
||||
fn fatalWithHint(comptime f: []const u8, args: anytype) noreturn {
|
||||
std.debug.print(f ++ "\n access the help menu with 'zig build -h'\n", args);
|
||||
process.exit(1);
|
||||
|
||||
@ -124,10 +124,10 @@ pub const Diagnostics = struct {
|
||||
try self.errors.append(self.allocator, error_details);
|
||||
}
|
||||
|
||||
pub fn renderToStdErr(self: *Diagnostics, args: []const []const u8, config: std.Io.tty.Config) void {
|
||||
const stderr = std.debug.lockStderrWriter(&.{});
|
||||
pub fn renderToStdErr(self: *Diagnostics, args: []const []const u8) void {
|
||||
const stderr, const ttyconf = std.debug.lockStderrWriter(&.{});
|
||||
defer std.debug.unlockStderrWriter();
|
||||
self.renderToWriter(args, stderr, config) catch return;
|
||||
self.renderToWriter(args, stderr, ttyconf) catch return;
|
||||
}
|
||||
|
||||
pub fn renderToWriter(self: *Diagnostics, args: []const []const u8, writer: *std.Io.Writer, config: std.Io.tty.Config) !void {
|
||||
|
||||
@ -67,20 +67,15 @@ pub const Diagnostics = struct {
|
||||
return @intCast(index);
|
||||
}
|
||||
|
||||
pub fn renderToStdErr(self: *Diagnostics, cwd: std.fs.Dir, source: []const u8, tty_config: std.Io.tty.Config, source_mappings: ?SourceMappings) void {
|
||||
pub fn renderToStdErr(self: *Diagnostics, cwd: std.fs.Dir, source: []const u8, source_mappings: ?SourceMappings) void {
|
||||
const io = self.io;
|
||||
const stderr = std.debug.lockStderrWriter(&.{});
|
||||
const stderr, const ttyconf = std.debug.lockStderrWriter(&.{});
|
||||
defer std.debug.unlockStderrWriter();
|
||||
for (self.errors.items) |err_details| {
|
||||
renderErrorMessage(io, stderr, tty_config, cwd, err_details, source, self.strings.items, source_mappings) catch return;
|
||||
renderErrorMessage(io, stderr, ttyconf, cwd, err_details, source, self.strings.items, source_mappings) catch return;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn renderToStdErrDetectTTY(self: *Diagnostics, cwd: std.fs.Dir, source: []const u8, source_mappings: ?SourceMappings) void {
|
||||
const tty_config = std.Io.tty.detectConfig(std.fs.File.stderr());
|
||||
return self.renderToStdErr(cwd, source, tty_config, source_mappings);
|
||||
}
|
||||
|
||||
pub fn contains(self: *const Diagnostics, err: ErrorDetails.Error) bool {
|
||||
for (self.errors.items) |details| {
|
||||
if (details.err == err) return true;
|
||||
|
||||
@ -28,13 +28,11 @@ pub fn main() !void {
|
||||
defer arena_state.deinit();
|
||||
const arena = arena_state.allocator();
|
||||
|
||||
const stderr = std.fs.File.stderr();
|
||||
const stderr_config = std.Io.tty.detectConfig(stderr);
|
||||
|
||||
const args = try std.process.argsAlloc(arena);
|
||||
|
||||
if (args.len < 2) {
|
||||
try renderErrorMessage(std.debug.lockStderrWriter(&.{}), stderr_config, .err, "expected zig lib dir as first argument", .{});
|
||||
const w, const ttyconf = std.debug.lockStderrWriter(&.{});
|
||||
try renderErrorMessage(w, ttyconf, .err, "expected zig lib dir as first argument", .{});
|
||||
std.process.exit(1);
|
||||
}
|
||||
const zig_lib_dir = args[1];
|
||||
@ -56,9 +54,7 @@ pub fn main() !void {
|
||||
.in = undefined, // won't be receiving messages
|
||||
},
|
||||
},
|
||||
false => .{
|
||||
.tty = stderr_config,
|
||||
},
|
||||
false => .stderr,
|
||||
};
|
||||
|
||||
var options = options: {
|
||||
@ -75,12 +71,14 @@ pub fn main() !void {
|
||||
|
||||
if (!zig_integration) {
|
||||
// print any warnings/notes
|
||||
cli_diagnostics.renderToStdErr(cli_args, stderr_config);
|
||||
cli_diagnostics.renderToStdErr(cli_args);
|
||||
// If there was something printed, then add an extra newline separator
|
||||
// so that there is a clear separation between the cli diagnostics and whatever
|
||||
// gets printed after
|
||||
if (cli_diagnostics.errors.items.len > 0) {
|
||||
try stderr.writeAll("\n");
|
||||
const stderr, _ = std.debug.lockStderrWriter(&.{});
|
||||
defer std.debug.unlockStderrWriter();
|
||||
try stderr.writeByte('\n');
|
||||
}
|
||||
}
|
||||
break :options options;
|
||||
@ -130,17 +128,18 @@ pub fn main() !void {
|
||||
const aro_arena = aro_arena_state.allocator();
|
||||
|
||||
var stderr_buf: [512]u8 = undefined;
|
||||
var stderr_writer = stderr.writer(&stderr_buf);
|
||||
var diagnostics: aro.Diagnostics = switch (zig_integration) {
|
||||
false => .{ .output = .{ .to_writer = .{
|
||||
.writer = &stderr_writer.interface,
|
||||
.color = stderr_config,
|
||||
} } },
|
||||
true => .{ .output = .{ .to_list = .{
|
||||
.arena = .init(gpa),
|
||||
} } },
|
||||
};
|
||||
defer diagnostics.deinit();
|
||||
var diagnostics: aro.Diagnostics = .{ .output = output: {
|
||||
if (zig_integration) break :output .{ .to_list = .{ .arena = .init(gpa) } };
|
||||
const w, const ttyconf = std.debug.lockStderrWriter(&stderr_buf);
|
||||
break :output .{ .to_writer = .{
|
||||
.writer = w,
|
||||
.color = ttyconf,
|
||||
} };
|
||||
} };
|
||||
defer {
|
||||
diagnostics.deinit();
|
||||
if (!zig_integration) std.debug.unlockStderrWriter();
|
||||
}
|
||||
|
||||
var comp = aro.Compilation.init(aro_arena, aro_arena, io, &diagnostics, std.fs.cwd());
|
||||
defer comp.deinit();
|
||||
@ -307,7 +306,7 @@ pub fn main() !void {
|
||||
|
||||
// print any warnings/notes
|
||||
if (!zig_integration) {
|
||||
diagnostics.renderToStdErr(std.fs.cwd(), final_input, stderr_config, mapping_results.mappings);
|
||||
diagnostics.renderToStdErr(std.fs.cwd(), final_input, mapping_results.mappings);
|
||||
}
|
||||
|
||||
// write the depfile
|
||||
@ -660,7 +659,7 @@ const SourceMappings = @import("source_mapping.zig").SourceMappings;
|
||||
|
||||
const ErrorHandler = union(enum) {
|
||||
server: std.zig.Server,
|
||||
tty: std.Io.tty.Config,
|
||||
stderr,
|
||||
|
||||
pub fn emitCliDiagnostics(
|
||||
self: *ErrorHandler,
|
||||
@ -675,9 +674,7 @@ const ErrorHandler = union(enum) {
|
||||
|
||||
try server.serveErrorBundle(error_bundle);
|
||||
},
|
||||
.tty => {
|
||||
diagnostics.renderToStdErr(args, self.tty);
|
||||
},
|
||||
.stderr => diagnostics.renderToStdErr(args),
|
||||
}
|
||||
}
|
||||
|
||||
@ -698,11 +695,11 @@ const ErrorHandler = union(enum) {
|
||||
|
||||
try server.serveErrorBundle(error_bundle);
|
||||
},
|
||||
.tty => {
|
||||
.stderr => {
|
||||
// aro errors have already been emitted
|
||||
const stderr = std.debug.lockStderrWriter(&.{});
|
||||
const stderr, const ttyconf = std.debug.lockStderrWriter(&.{});
|
||||
defer std.debug.unlockStderrWriter();
|
||||
try renderErrorMessage(stderr, self.tty, .err, "{s}", .{fail_msg});
|
||||
try renderErrorMessage(stderr, ttyconf, .err, "{s}", .{fail_msg});
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -722,9 +719,7 @@ const ErrorHandler = union(enum) {
|
||||
|
||||
try server.serveErrorBundle(error_bundle);
|
||||
},
|
||||
.tty => {
|
||||
diagnostics.renderToStdErr(cwd, source, self.tty, mappings);
|
||||
},
|
||||
.stderr => diagnostics.renderToStdErr(cwd, source, mappings),
|
||||
}
|
||||
}
|
||||
|
||||
@ -745,10 +740,10 @@ const ErrorHandler = union(enum) {
|
||||
|
||||
try server.serveErrorBundle(error_bundle);
|
||||
},
|
||||
.tty => {
|
||||
const stderr = std.debug.lockStderrWriter(&.{});
|
||||
.stderr => {
|
||||
const stderr, const ttyconf = std.debug.lockStderrWriter(&.{});
|
||||
defer std.debug.unlockStderrWriter();
|
||||
try renderErrorMessage(stderr, self.tty, msg_type, format, args);
|
||||
try renderErrorMessage(stderr, ttyconf, msg_type, format, args);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -394,8 +394,7 @@ fn buildWasmBinary(
|
||||
}
|
||||
|
||||
if (result_error_bundle.errorMessageCount() > 0) {
|
||||
const color = std.zig.Color.auto;
|
||||
result_error_bundle.renderToStdErr(color.renderOptions());
|
||||
result_error_bundle.renderToStdErr(.{}, true);
|
||||
std.log.err("the following command failed with {d} compilation errors:\n{s}", .{
|
||||
result_error_bundle.errorMessageCount(),
|
||||
try std.Build.Step.allocPrintCmd(arena, null, argv.items),
|
||||
|
||||
@ -2257,8 +2257,8 @@ pub const GeneratedFile = struct {
|
||||
|
||||
pub fn getPath2(gen: GeneratedFile, src_builder: *Build, asking_step: ?*Step) []const u8 {
|
||||
return gen.path orelse {
|
||||
const w = debug.lockStderrWriter(&.{});
|
||||
dumpBadGetPathHelp(gen.step, w, .detect(.stderr()), src_builder, asking_step) catch {};
|
||||
const w, const ttyconf = debug.lockStderrWriter(&.{});
|
||||
dumpBadGetPathHelp(gen.step, w, ttyconf, src_builder, asking_step) catch {};
|
||||
debug.unlockStderrWriter();
|
||||
@panic("misconfigured build script");
|
||||
};
|
||||
@ -2466,8 +2466,8 @@ pub const LazyPath = union(enum) {
|
||||
var file_path: Cache.Path = .{
|
||||
.root_dir = Cache.Directory.cwd(),
|
||||
.sub_path = gen.file.path orelse {
|
||||
const w = debug.lockStderrWriter(&.{});
|
||||
dumpBadGetPathHelp(gen.file.step, w, .detect(.stderr()), src_builder, asking_step) catch {};
|
||||
const w, const ttyconf = debug.lockStderrWriter(&.{});
|
||||
dumpBadGetPathHelp(gen.file.step, w, ttyconf, src_builder, asking_step) catch {};
|
||||
debug.unlockStderrWriter();
|
||||
@panic("misconfigured build script");
|
||||
},
|
||||
@ -2558,13 +2558,11 @@ fn dumpBadDirnameHelp(
|
||||
comptime msg: []const u8,
|
||||
args: anytype,
|
||||
) anyerror!void {
|
||||
const w = debug.lockStderrWriter(&.{});
|
||||
const w, const tty_config = debug.lockStderrWriter(&.{});
|
||||
defer debug.unlockStderrWriter();
|
||||
|
||||
try w.print(msg, args);
|
||||
|
||||
const tty_config = std.Io.tty.detectConfig(.stderr());
|
||||
|
||||
if (fail_step) |s| {
|
||||
tty_config.setColor(w, .red) catch {};
|
||||
try w.writeAll(" The step was created by this stack trace:\n");
|
||||
|
||||
@ -16,6 +16,7 @@ const build_runner = @import("root");
|
||||
|
||||
gpa: Allocator,
|
||||
io: Io,
|
||||
ttyconf: tty.Config,
|
||||
mode: Mode,
|
||||
|
||||
/// Allocated into `gpa`.
|
||||
@ -25,7 +26,6 @@ wait_group: std.Thread.WaitGroup,
|
||||
root_prog_node: std.Progress.Node,
|
||||
prog_node: std.Progress.Node,
|
||||
thread_pool: *std.Thread.Pool,
|
||||
ttyconf: tty.Config,
|
||||
|
||||
/// Protects `coverage_files`.
|
||||
coverage_mutex: std.Thread.Mutex,
|
||||
@ -79,9 +79,9 @@ pub fn init(
|
||||
gpa: Allocator,
|
||||
io: Io,
|
||||
thread_pool: *std.Thread.Pool,
|
||||
ttyconf: tty.Config,
|
||||
all_steps: []const *Build.Step,
|
||||
root_prog_node: std.Progress.Node,
|
||||
ttyconf: tty.Config,
|
||||
mode: Mode,
|
||||
) Allocator.Error!Fuzz {
|
||||
const run_steps: []const *Step.Run = steps: {
|
||||
@ -115,11 +115,11 @@ pub fn init(
|
||||
return .{
|
||||
.gpa = gpa,
|
||||
.io = io,
|
||||
.ttyconf = ttyconf,
|
||||
.mode = mode,
|
||||
.run_steps = run_steps,
|
||||
.wait_group = .{},
|
||||
.thread_pool = thread_pool,
|
||||
.ttyconf = ttyconf,
|
||||
.root_prog_node = root_prog_node,
|
||||
.prog_node = .none,
|
||||
.coverage_files = .empty,
|
||||
@ -158,7 +158,7 @@ pub fn deinit(fuzz: *Fuzz) void {
|
||||
fuzz.gpa.free(fuzz.run_steps);
|
||||
}
|
||||
|
||||
fn rebuildTestsWorkerRun(run: *Step.Run, gpa: Allocator, ttyconf: std.Io.tty.Config, parent_prog_node: std.Progress.Node) void {
|
||||
fn rebuildTestsWorkerRun(run: *Step.Run, gpa: Allocator, ttyconf: tty.Config, parent_prog_node: std.Progress.Node) void {
|
||||
rebuildTestsWorkerRunFallible(run, gpa, ttyconf, parent_prog_node) catch |err| {
|
||||
const compile = run.producer.?;
|
||||
log.err("step '{s}': failed to rebuild in fuzz mode: {s}", .{
|
||||
@ -167,7 +167,7 @@ fn rebuildTestsWorkerRun(run: *Step.Run, gpa: Allocator, ttyconf: std.Io.tty.Con
|
||||
};
|
||||
}
|
||||
|
||||
fn rebuildTestsWorkerRunFallible(run: *Step.Run, gpa: Allocator, ttyconf: std.Io.tty.Config, parent_prog_node: std.Progress.Node) !void {
|
||||
fn rebuildTestsWorkerRunFallible(run: *Step.Run, gpa: Allocator, ttyconf: tty.Config, parent_prog_node: std.Progress.Node) !void {
|
||||
const compile = run.producer.?;
|
||||
const prog_node = parent_prog_node.start(compile.step.name, 0);
|
||||
defer prog_node.end();
|
||||
@ -180,9 +180,9 @@ fn rebuildTestsWorkerRunFallible(run: *Step.Run, gpa: Allocator, ttyconf: std.Io
|
||||
|
||||
if (show_error_msgs or show_compile_errors or show_stderr) {
|
||||
var buf: [256]u8 = undefined;
|
||||
const w = std.debug.lockStderrWriter(&buf);
|
||||
const w, _ = std.debug.lockStderrWriter(&buf);
|
||||
defer std.debug.unlockStderrWriter();
|
||||
build_runner.printErrorMessages(gpa, &compile.step, .{ .ttyconf = ttyconf }, w, .verbose, .indent) catch {};
|
||||
build_runner.printErrorMessages(gpa, &compile.step, .{}, w, ttyconf, .verbose, .indent) catch {};
|
||||
}
|
||||
|
||||
const rebuilt_bin_path = result catch |err| switch (err) {
|
||||
@ -206,9 +206,9 @@ fn fuzzWorkerRun(
|
||||
run.rerunInFuzzMode(fuzz, unit_test_index, prog_node) catch |err| switch (err) {
|
||||
error.MakeFailed => {
|
||||
var buf: [256]u8 = undefined;
|
||||
const w = std.debug.lockStderrWriter(&buf);
|
||||
const w, _ = std.debug.lockStderrWriter(&buf);
|
||||
defer std.debug.unlockStderrWriter();
|
||||
build_runner.printErrorMessages(gpa, &run.step, .{ .ttyconf = fuzz.ttyconf }, w, .verbose, .indent) catch {};
|
||||
build_runner.printErrorMessages(gpa, &run.step, .{}, w, fuzz.ttyconf, .verbose, .indent) catch {};
|
||||
return;
|
||||
},
|
||||
else => {
|
||||
|
||||
@ -1056,15 +1056,15 @@ fn getGeneratedFilePath(compile: *Compile, comptime tag_name: []const u8, asking
|
||||
const maybe_path: ?*GeneratedFile = @field(compile, tag_name);
|
||||
|
||||
const generated_file = maybe_path orelse {
|
||||
const w = std.debug.lockStderrWriter(&.{});
|
||||
std.Build.dumpBadGetPathHelp(&compile.step, w, .detect(.stderr()), compile.step.owner, asking_step) catch {};
|
||||
const w, const ttyconf = std.debug.lockStderrWriter(&.{});
|
||||
std.Build.dumpBadGetPathHelp(&compile.step, w, ttyconf, compile.step.owner, asking_step) catch {};
|
||||
std.debug.unlockStderrWriter();
|
||||
@panic("missing emit option for " ++ tag_name);
|
||||
};
|
||||
|
||||
const path = generated_file.path orelse {
|
||||
const w = std.debug.lockStderrWriter(&.{});
|
||||
std.Build.dumpBadGetPathHelp(&compile.step, w, .detect(.stderr()), compile.step.owner, asking_step) catch {};
|
||||
const w, const ttyconf = std.debug.lockStderrWriter(&.{});
|
||||
std.Build.dumpBadGetPathHelp(&compile.step, w, ttyconf, compile.step.owner, asking_step) catch {};
|
||||
std.debug.unlockStderrWriter();
|
||||
@panic(tag_name ++ " is null. Is there a missing step dependency?");
|
||||
};
|
||||
@ -2027,10 +2027,9 @@ fn checkCompileErrors(compile: *Compile) !void {
|
||||
var aw: std.Io.Writer.Allocating = .init(arena);
|
||||
defer aw.deinit();
|
||||
try actual_eb.renderToWriter(.{
|
||||
.ttyconf = .no_color,
|
||||
.include_reference_trace = false,
|
||||
.include_source_line = false,
|
||||
}, &aw.writer);
|
||||
}, &aw.writer, .no_color);
|
||||
break :ae try aw.toOwnedSlice();
|
||||
};
|
||||
|
||||
|
||||
@ -1587,11 +1587,15 @@ fn spawnChildAndCollect(
|
||||
run.step.test_results = res.test_results;
|
||||
if (res.test_metadata) |tm| {
|
||||
run.cached_test_metadata = tm.toCachedTestMetadata();
|
||||
if (options.web_server) |ws| ws.updateTimeReportRunTest(
|
||||
run,
|
||||
&run.cached_test_metadata.?,
|
||||
tm.ns_per_test,
|
||||
);
|
||||
if (options.web_server) |ws| {
|
||||
if (b.graph.time_report) {
|
||||
ws.updateTimeReportRunTest(
|
||||
run,
|
||||
&run.cached_test_metadata.?,
|
||||
tm.ns_per_test,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
} else {
|
||||
|
||||
@ -54,9 +54,9 @@ pub fn notifyUpdate(ws: *WebServer) void {
|
||||
pub const Options = struct {
|
||||
gpa: Allocator,
|
||||
thread_pool: *std.Thread.Pool,
|
||||
ttyconf: Io.tty.Config,
|
||||
graph: *const std.Build.Graph,
|
||||
all_steps: []const *Build.Step,
|
||||
ttyconf: Io.tty.Config,
|
||||
root_prog_node: std.Progress.Node,
|
||||
watch: bool,
|
||||
listen_address: net.IpAddress,
|
||||
@ -101,10 +101,10 @@ pub fn init(opts: Options) WebServer {
|
||||
return .{
|
||||
.gpa = opts.gpa,
|
||||
.thread_pool = opts.thread_pool,
|
||||
.ttyconf = opts.ttyconf,
|
||||
.graph = opts.graph,
|
||||
.all_steps = all_steps,
|
||||
.listen_address = opts.listen_address,
|
||||
.ttyconf = opts.ttyconf,
|
||||
.root_prog_node = opts.root_prog_node,
|
||||
.watch = opts.watch,
|
||||
|
||||
@ -236,9 +236,9 @@ pub fn finishBuild(ws: *WebServer, opts: struct {
|
||||
ws.gpa,
|
||||
ws.graph.io,
|
||||
ws.thread_pool,
|
||||
ws.ttyconf,
|
||||
ws.all_steps,
|
||||
ws.root_prog_node,
|
||||
ws.ttyconf,
|
||||
.{ .forever = .{ .ws = ws } },
|
||||
) catch |err| std.process.fatal("failed to start fuzzer: {s}", .{@errorName(err)});
|
||||
ws.fuzz.?.start();
|
||||
@ -655,8 +655,7 @@ fn buildClientWasm(ws: *WebServer, arena: Allocator, optimize: std.builtin.Optim
|
||||
}
|
||||
|
||||
if (result_error_bundle.errorMessageCount() > 0) {
|
||||
const color = std.zig.Color.auto;
|
||||
result_error_bundle.renderToStdErr(color.renderOptions());
|
||||
result_error_bundle.renderToStdErr(.{}, .auto);
|
||||
log.err("the following command failed with {d} compilation errors:\n{s}", .{
|
||||
result_error_bundle.errorMessageCount(),
|
||||
try Build.Step.allocPrintCmd(arena, null, argv.items),
|
||||
|
||||
@ -272,7 +272,7 @@ pub fn unlockStdErr() void {
|
||||
std.Progress.unlockStdErr();
|
||||
}
|
||||
|
||||
/// Allows the caller to freely write to stderr until `unlockStdErr` is called.
|
||||
/// Allows the caller to freely write to stderr until `unlockStderrWriter` is called.
|
||||
///
|
||||
/// During the lock, any `std.Progress` information is cleared from the terminal.
|
||||
///
|
||||
@ -282,8 +282,16 @@ pub fn unlockStdErr() void {
|
||||
///
|
||||
/// The returned `Writer` does not need to be manually flushed: flushing is performed automatically
|
||||
/// when the matching `unlockStderrWriter` call occurs.
|
||||
pub fn lockStderrWriter(buffer: []u8) *Writer {
|
||||
return std.Progress.lockStderrWriter(buffer);
|
||||
pub fn lockStderrWriter(buffer: []u8) struct { *Writer, tty.Config } {
|
||||
const global = struct {
|
||||
var conf: ?tty.Config = null;
|
||||
};
|
||||
const w = std.Progress.lockStderrWriter(buffer);
|
||||
// The stderr lock also locks access to `global.conf`.
|
||||
if (global.conf == null) {
|
||||
global.conf = .detect(.stderr());
|
||||
}
|
||||
return .{ w, global.conf.? };
|
||||
}
|
||||
|
||||
pub fn unlockStderrWriter() void {
|
||||
@ -297,7 +305,7 @@ pub fn unlockStderrWriter() void {
|
||||
/// function returns.
|
||||
pub fn print(comptime fmt: []const u8, args: anytype) void {
|
||||
var buffer: [64]u8 = undefined;
|
||||
const bw = lockStderrWriter(&buffer);
|
||||
const bw, _ = lockStderrWriter(&buffer);
|
||||
defer unlockStderrWriter();
|
||||
nosuspend bw.print(fmt, args) catch return;
|
||||
}
|
||||
@ -314,9 +322,8 @@ pub inline fn getSelfDebugInfo() !*SelfInfo {
|
||||
/// Tries to print a hexadecimal view of the bytes, unbuffered, and ignores any error returned.
|
||||
/// Obtains the stderr mutex while dumping.
|
||||
pub fn dumpHex(bytes: []const u8) void {
|
||||
const bw = lockStderrWriter(&.{});
|
||||
const bw, const ttyconf = lockStderrWriter(&.{});
|
||||
defer unlockStderrWriter();
|
||||
const ttyconf = tty.detectConfig(.stderr());
|
||||
dumpHexFallible(bw, ttyconf, bytes) catch {};
|
||||
}
|
||||
|
||||
@ -538,9 +545,7 @@ pub fn defaultPanic(
|
||||
_ = panicking.fetchAdd(1, .seq_cst);
|
||||
|
||||
trace: {
|
||||
const tty_config = tty.detectConfig(.stderr());
|
||||
|
||||
const stderr = lockStderrWriter(&.{});
|
||||
const stderr, const tty_config = lockStderrWriter(&.{});
|
||||
defer unlockStderrWriter();
|
||||
|
||||
if (builtin.single_threaded) {
|
||||
@ -743,8 +748,7 @@ pub noinline fn writeCurrentStackTrace(options: StackUnwindOptions, writer: *Wri
|
||||
}
|
||||
/// A thin wrapper around `writeCurrentStackTrace` which writes to stderr and ignores write errors.
|
||||
pub fn dumpCurrentStackTrace(options: StackUnwindOptions) void {
|
||||
const tty_config = tty.detectConfig(.stderr());
|
||||
const stderr = lockStderrWriter(&.{});
|
||||
const stderr, const tty_config = lockStderrWriter(&.{});
|
||||
defer unlockStderrWriter();
|
||||
writeCurrentStackTrace(.{
|
||||
.first_address = a: {
|
||||
@ -809,8 +813,7 @@ pub fn writeStackTrace(st: *const StackTrace, writer: *Writer, tty_config: tty.C
|
||||
}
|
||||
/// A thin wrapper around `writeStackTrace` which writes to stderr and ignores write errors.
|
||||
pub fn dumpStackTrace(st: *const StackTrace) void {
|
||||
const tty_config = tty.detectConfig(.stderr());
|
||||
const stderr = lockStderrWriter(&.{});
|
||||
const stderr, const tty_config = lockStderrWriter(&.{});
|
||||
defer unlockStderrWriter();
|
||||
writeStackTrace(st, stderr, tty_config) catch |err| switch (err) {
|
||||
error.WriteFailed => {},
|
||||
@ -1552,9 +1555,7 @@ pub fn defaultHandleSegfault(addr: ?usize, name: []const u8, opt_ctx: ?CpuContex
|
||||
_ = panicking.fetchAdd(1, .seq_cst);
|
||||
|
||||
trace: {
|
||||
const tty_config = tty.detectConfig(.stderr());
|
||||
|
||||
const stderr = lockStderrWriter(&.{});
|
||||
const stderr, const tty_config = lockStderrWriter(&.{});
|
||||
defer unlockStderrWriter();
|
||||
|
||||
if (addr) |a| {
|
||||
@ -1612,7 +1613,7 @@ test "manage resources correctly" {
|
||||
&di,
|
||||
&discarding.writer,
|
||||
S.showMyTrace(),
|
||||
tty.detectConfig(.stderr()),
|
||||
.no_color,
|
||||
);
|
||||
}
|
||||
|
||||
@ -1674,8 +1675,7 @@ pub fn ConfigurableTrace(comptime size: usize, comptime stack_frame_count: usize
|
||||
pub fn dump(t: @This()) void {
|
||||
if (!enabled) return;
|
||||
|
||||
const tty_config = tty.detectConfig(.stderr());
|
||||
const stderr = lockStderrWriter(&.{});
|
||||
const stderr, const tty_config = lockStderrWriter(&.{});
|
||||
defer unlockStderrWriter();
|
||||
const end = @min(t.index, size);
|
||||
for (t.addrs[0..end], 0..) |frames_array, i| {
|
||||
|
||||
@ -47,7 +47,7 @@ pub const Value = union(enum) {
|
||||
}
|
||||
|
||||
pub fn dump(v: Value) void {
|
||||
const w = std.debug.lockStderrWriter(&.{});
|
||||
const w, _ = std.debug.lockStderrWriter(&.{});
|
||||
defer std.debug.unlockStderrWriter();
|
||||
|
||||
json.Stringify.value(v, .{}, w) catch return;
|
||||
|
||||
111
lib/std/log.zig
111
lib/std/log.zig
@ -13,63 +13,15 @@
|
||||
//! `const log = std.log.scoped(.libfoo);` to use .libfoo as the scope of its
|
||||
//! log messages.
|
||||
//!
|
||||
//! An example `logFn` might look something like this:
|
||||
//!
|
||||
//! For an example implementation of the `logFn` function, see `defaultLog`,
|
||||
//! which is the default implementation. It outputs to stderr, using color if
|
||||
//! the detected `std.Io.tty.Config` supports it. Its output looks like this:
|
||||
//! ```
|
||||
//! const std = @import("std");
|
||||
//!
|
||||
//! pub const std_options: std.Options = .{
|
||||
//! // Set the log level to info
|
||||
//! .log_level = .info,
|
||||
//!
|
||||
//! // Define logFn to override the std implementation
|
||||
//! .logFn = myLogFn,
|
||||
//! };
|
||||
//!
|
||||
//! pub fn myLogFn(
|
||||
//! comptime level: std.log.Level,
|
||||
//! comptime scope: @Type(.enum_literal),
|
||||
//! comptime format: []const u8,
|
||||
//! args: anytype,
|
||||
//! ) void {
|
||||
//! // Ignore all non-error logging from sources other than
|
||||
//! // .my_project, .nice_library and the default
|
||||
//! const scope_prefix = "(" ++ switch (scope) {
|
||||
//! .my_project, .nice_library, std.log.default_log_scope => @tagName(scope),
|
||||
//! else => if (@intFromEnum(level) <= @intFromEnum(std.log.Level.err))
|
||||
//! @tagName(scope)
|
||||
//! else
|
||||
//! return,
|
||||
//! } ++ "): ";
|
||||
//!
|
||||
//! const prefix = "[" ++ comptime level.asText() ++ "] " ++ scope_prefix;
|
||||
//!
|
||||
//! // Print the message to stderr, silently ignoring any errors
|
||||
//! std.debug.lockStdErr();
|
||||
//! defer std.debug.unlockStdErr();
|
||||
//! var stderr = std.fs.File.stderr().writer(&.{});
|
||||
//! nosuspend stderr.interface.print(prefix ++ format ++ "\n", args) catch return;
|
||||
//! }
|
||||
//!
|
||||
//! pub fn main() void {
|
||||
//! // Using the default scope:
|
||||
//! std.log.debug("A borderline useless debug log message", .{}); // Won't be printed as log_level is .info
|
||||
//! std.log.info("Flux capacitor is starting to overheat", .{});
|
||||
//!
|
||||
//! // Using scoped logging:
|
||||
//! const my_project_log = std.log.scoped(.my_project);
|
||||
//! const nice_library_log = std.log.scoped(.nice_library);
|
||||
//! const verbose_lib_log = std.log.scoped(.verbose_lib);
|
||||
//!
|
||||
//! my_project_log.debug("Starting up", .{}); // Won't be printed as log_level is .info
|
||||
//! nice_library_log.warn("Something went very wrong, sorry", .{});
|
||||
//! verbose_lib_log.warn("Added 1 + 1: {}", .{1 + 1}); // Won't be printed as it gets filtered out by our log function
|
||||
//! }
|
||||
//! ```
|
||||
//! Which produces the following output:
|
||||
//! ```
|
||||
//! [info] (default): Flux capacitor is starting to overheat
|
||||
//! [warning] (nice_library): Something went very wrong, sorry
|
||||
//! error: this is an error
|
||||
//! error(scope): this is an error with a non-default scope
|
||||
//! warning: this is a warning
|
||||
//! info: this is an informative message
|
||||
//! debug: this is a debugging message
|
||||
//! ```
|
||||
|
||||
const std = @import("std.zig");
|
||||
@ -104,37 +56,28 @@ pub const default_level: Level = switch (builtin.mode) {
|
||||
.ReleaseSafe, .ReleaseFast, .ReleaseSmall => .info,
|
||||
};
|
||||
|
||||
const level = std.options.log_level;
|
||||
|
||||
pub const ScopeLevel = struct {
|
||||
scope: @Type(.enum_literal),
|
||||
level: Level,
|
||||
};
|
||||
|
||||
const scope_levels = std.options.log_scope_levels;
|
||||
|
||||
fn log(
|
||||
comptime message_level: Level,
|
||||
comptime level: Level,
|
||||
comptime scope: @Type(.enum_literal),
|
||||
comptime format: []const u8,
|
||||
args: anytype,
|
||||
) void {
|
||||
if (comptime !logEnabled(message_level, scope)) return;
|
||||
if (comptime !logEnabled(level, scope)) return;
|
||||
|
||||
std.options.logFn(message_level, scope, format, args);
|
||||
std.options.logFn(level, scope, format, args);
|
||||
}
|
||||
|
||||
/// Determine if a specific log message level and scope combination are enabled for logging.
|
||||
pub fn logEnabled(comptime message_level: Level, comptime scope: @Type(.enum_literal)) bool {
|
||||
inline for (scope_levels) |scope_level| {
|
||||
if (scope_level.scope == scope) return @intFromEnum(message_level) <= @intFromEnum(scope_level.level);
|
||||
pub fn logEnabled(comptime level: Level, comptime scope: @Type(.enum_literal)) bool {
|
||||
inline for (std.options.log_scope_levels) |scope_level| {
|
||||
if (scope_level.scope == scope) return @intFromEnum(level) <= @intFromEnum(scope_level.level);
|
||||
}
|
||||
return @intFromEnum(message_level) <= @intFromEnum(level);
|
||||
}
|
||||
|
||||
/// Determine if a specific log message level using the default log scope is enabled for logging.
|
||||
pub fn defaultLogEnabled(comptime message_level: Level) bool {
|
||||
return comptime logEnabled(message_level, default_log_scope);
|
||||
return @intFromEnum(level) <= @intFromEnum(std.options.log_level);
|
||||
}
|
||||
|
||||
/// The default implementation for the log function. Custom log functions may
|
||||
@ -143,17 +86,31 @@ pub fn defaultLogEnabled(comptime message_level: Level) bool {
|
||||
/// Uses a 64-byte buffer for formatted printing which is flushed before this
|
||||
/// function returns.
|
||||
pub fn defaultLog(
|
||||
comptime message_level: Level,
|
||||
comptime level: Level,
|
||||
comptime scope: @Type(.enum_literal),
|
||||
comptime format: []const u8,
|
||||
args: anytype,
|
||||
) void {
|
||||
const level_txt = comptime message_level.asText();
|
||||
const prefix2 = if (scope == .default) ": " else "(" ++ @tagName(scope) ++ "): ";
|
||||
var buffer: [64]u8 = undefined;
|
||||
const stderr = std.debug.lockStderrWriter(&buffer);
|
||||
const stderr, const ttyconf = std.debug.lockStderrWriter(&buffer);
|
||||
defer std.debug.unlockStderrWriter();
|
||||
nosuspend stderr.print(level_txt ++ prefix2 ++ format ++ "\n", args) catch return;
|
||||
ttyconf.setColor(stderr, switch (level) {
|
||||
.err => .red,
|
||||
.warn => .yellow,
|
||||
.info => .green,
|
||||
.debug => .magenta,
|
||||
}) catch {};
|
||||
ttyconf.setColor(stderr, .bold) catch {};
|
||||
stderr.writeAll(level.asText()) catch return;
|
||||
ttyconf.setColor(stderr, .reset) catch {};
|
||||
ttyconf.setColor(stderr, .dim) catch {};
|
||||
ttyconf.setColor(stderr, .bold) catch {};
|
||||
if (scope != .default) {
|
||||
stderr.print("({s})", .{@tagName(scope)}) catch return;
|
||||
}
|
||||
stderr.writeAll(": ") catch return;
|
||||
ttyconf.setColor(stderr, .reset) catch {};
|
||||
stderr.print(format ++ "\n", args) catch return;
|
||||
}
|
||||
|
||||
/// Returns a scoped logging namespace that logs all messages using the scope
|
||||
|
||||
@ -355,7 +355,7 @@ test expectApproxEqRel {
|
||||
/// This function is intended to be used only in tests. When the two slices are not
|
||||
/// equal, prints diagnostics to stderr to show exactly how they are not equal (with
|
||||
/// the differences highlighted in red), then returns a test failure error.
|
||||
/// The colorized output is optional and controlled by the return of `std.Io.tty.detectConfig()`.
|
||||
/// The colorized output is optional and controlled by the return of `std.Io.tty.Config.detect`.
|
||||
/// If your inputs are UTF-8 encoded strings, consider calling `expectEqualStrings` instead.
|
||||
pub fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const T) !void {
|
||||
const diff_index: usize = diff_index: {
|
||||
@ -367,9 +367,9 @@ pub fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const
|
||||
break :diff_index if (expected.len == actual.len) return else shortest;
|
||||
};
|
||||
if (!backend_can_print) return error.TestExpectedEqual;
|
||||
const stderr_w = std.debug.lockStderrWriter(&.{});
|
||||
const stderr_w, const ttyconf = std.debug.lockStderrWriter(&.{});
|
||||
defer std.debug.unlockStderrWriter();
|
||||
failEqualSlices(T, expected, actual, diff_index, stderr_w) catch {};
|
||||
failEqualSlices(T, expected, actual, diff_index, stderr_w, ttyconf) catch {};
|
||||
return error.TestExpectedEqual;
|
||||
}
|
||||
|
||||
@ -379,6 +379,7 @@ fn failEqualSlices(
|
||||
actual: []const T,
|
||||
diff_index: usize,
|
||||
w: *std.Io.Writer,
|
||||
ttyconf: std.Io.tty.Config,
|
||||
) !void {
|
||||
try w.print("slices differ. first difference occurs at index {d} (0x{X})\n", .{ diff_index, diff_index });
|
||||
|
||||
@ -398,7 +399,6 @@ fn failEqualSlices(
|
||||
const actual_window = actual[window_start..@min(actual.len, window_start + max_window_size)];
|
||||
const actual_truncated = window_start + actual_window.len < actual.len;
|
||||
|
||||
const ttyconf = std.Io.tty.detectConfig(.stderr());
|
||||
var differ = if (T == u8) BytesDiffer{
|
||||
.expected = expected_window,
|
||||
.actual = actual_window,
|
||||
|
||||
@ -53,17 +53,18 @@ pub const Color = enum {
|
||||
/// Assume stderr is a terminal.
|
||||
on,
|
||||
|
||||
pub fn get_tty_conf(color: Color) Io.tty.Config {
|
||||
pub fn getTtyConf(color: Color, detected: Io.tty.Config) Io.tty.Config {
|
||||
return switch (color) {
|
||||
.auto => Io.tty.detectConfig(std.fs.File.stderr()),
|
||||
.auto => detected,
|
||||
.on => .escape_codes,
|
||||
.off => .no_color,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn renderOptions(color: Color) std.zig.ErrorBundle.RenderOptions {
|
||||
return .{
|
||||
.ttyconf = get_tty_conf(color),
|
||||
pub fn detectTtyConf(color: Color) Io.tty.Config {
|
||||
return switch (color) {
|
||||
.auto => .detect(.stderr()),
|
||||
.on => .escape_codes,
|
||||
.off => .no_color,
|
||||
};
|
||||
}
|
||||
};
|
||||
@ -606,7 +607,7 @@ pub fn printAstErrorsToStderr(gpa: Allocator, tree: Ast, path: []const u8, color
|
||||
|
||||
var error_bundle = try wip_errors.toOwnedBundle("");
|
||||
defer error_bundle.deinit(gpa);
|
||||
error_bundle.renderToStdErr(color.renderOptions());
|
||||
error_bundle.renderToStdErr(.{}, color);
|
||||
}
|
||||
|
||||
pub fn putAstErrorsIntoBundle(
|
||||
|
||||
@ -157,23 +157,22 @@ pub fn nullTerminatedString(eb: ErrorBundle, index: String) [:0]const u8 {
|
||||
}
|
||||
|
||||
pub const RenderOptions = struct {
|
||||
ttyconf: Io.tty.Config,
|
||||
include_reference_trace: bool = true,
|
||||
include_source_line: bool = true,
|
||||
include_log_text: bool = true,
|
||||
};
|
||||
|
||||
pub fn renderToStdErr(eb: ErrorBundle, options: RenderOptions) void {
|
||||
pub fn renderToStdErr(eb: ErrorBundle, options: RenderOptions, color: std.zig.Color) void {
|
||||
var buffer: [256]u8 = undefined;
|
||||
const w = std.debug.lockStderrWriter(&buffer);
|
||||
const w, const ttyconf = std.debug.lockStderrWriter(&buffer);
|
||||
defer std.debug.unlockStderrWriter();
|
||||
renderToWriter(eb, options, w) catch return;
|
||||
renderToWriter(eb, options, w, color.getTtyConf(ttyconf)) catch return;
|
||||
}
|
||||
|
||||
pub fn renderToWriter(eb: ErrorBundle, options: RenderOptions, w: *Writer) (Writer.Error || std.posix.UnexpectedError)!void {
|
||||
pub fn renderToWriter(eb: ErrorBundle, options: RenderOptions, w: *Writer, ttyconf: Io.tty.Config) (Writer.Error || std.posix.UnexpectedError)!void {
|
||||
if (eb.extra.len == 0) return;
|
||||
for (eb.getMessages()) |err_msg| {
|
||||
try renderErrorMessageToWriter(eb, options, err_msg, w, "error", .red, 0);
|
||||
try renderErrorMessageToWriter(eb, options, err_msg, w, ttyconf, "error", .red, 0);
|
||||
}
|
||||
|
||||
if (options.include_log_text) {
|
||||
@ -190,11 +189,11 @@ fn renderErrorMessageToWriter(
|
||||
options: RenderOptions,
|
||||
err_msg_index: MessageIndex,
|
||||
w: *Writer,
|
||||
ttyconf: Io.tty.Config,
|
||||
kind: []const u8,
|
||||
color: Io.tty.Color,
|
||||
indent: usize,
|
||||
) (Writer.Error || std.posix.UnexpectedError)!void {
|
||||
const ttyconf = options.ttyconf;
|
||||
const err_msg = eb.getErrorMessage(err_msg_index);
|
||||
if (err_msg.src_loc != .none) {
|
||||
const src = eb.extraData(SourceLocation, @intFromEnum(err_msg.src_loc));
|
||||
@ -251,7 +250,7 @@ fn renderErrorMessageToWriter(
|
||||
try ttyconf.setColor(w, .reset);
|
||||
}
|
||||
for (eb.getNotes(err_msg_index)) |note| {
|
||||
try renderErrorMessageToWriter(eb, options, note, w, "note", .cyan, indent);
|
||||
try renderErrorMessageToWriter(eb, options, note, w, ttyconf, "note", .cyan, indent);
|
||||
}
|
||||
if (src.data.reference_trace_len > 0 and options.include_reference_trace) {
|
||||
try ttyconf.setColor(w, .reset);
|
||||
@ -300,7 +299,7 @@ fn renderErrorMessageToWriter(
|
||||
}
|
||||
try ttyconf.setColor(w, .reset);
|
||||
for (eb.getNotes(err_msg_index)) |note| {
|
||||
try renderErrorMessageToWriter(eb, options, note, w, "note", .cyan, indent + 4);
|
||||
try renderErrorMessageToWriter(eb, options, note, w, ttyconf, "note", .cyan, indent + 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -6386,7 +6386,7 @@ var fixed_buffer_mem: [100 * 1024]u8 = undefined;
|
||||
|
||||
fn testParse(source: [:0]const u8, allocator: mem.Allocator, anything_changed: *bool) ![]u8 {
|
||||
var buffer: [64]u8 = undefined;
|
||||
const stderr = std.debug.lockStderrWriter(&buffer);
|
||||
const stderr, _ = std.debug.lockStderrWriter(&buffer);
|
||||
defer std.debug.unlockStderrWriter();
|
||||
|
||||
var tree = try std.zig.Ast.parse(allocator, source, .zig);
|
||||
|
||||
@ -73,13 +73,13 @@ pub fn writeInst(
|
||||
}
|
||||
|
||||
pub fn dump(air: Air, pt: Zcu.PerThread, liveness: ?Air.Liveness) void {
|
||||
const stderr_bw = std.debug.lockStderrWriter(&.{});
|
||||
const stderr_bw, _ = std.debug.lockStderrWriter(&.{});
|
||||
defer std.debug.unlockStderrWriter();
|
||||
air.write(stderr_bw, pt, liveness);
|
||||
}
|
||||
|
||||
pub fn dumpInst(air: Air, inst: Air.Inst.Index, pt: Zcu.PerThread, liveness: ?Air.Liveness) void {
|
||||
const stderr_bw = std.debug.lockStderrWriter(&.{});
|
||||
const stderr_bw, _ = std.debug.lockStderrWriter(&.{});
|
||||
defer std.debug.unlockStderrWriter();
|
||||
air.writeInst(stderr_bw, inst, pt, liveness);
|
||||
}
|
||||
|
||||
@ -2093,7 +2093,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,
|
||||
|
||||
if (options.verbose_llvm_cpu_features) {
|
||||
if (options.root_mod.resolved_target.llvm_cpu_features) |cf| print: {
|
||||
const stderr_w = std.debug.lockStderrWriter(&.{});
|
||||
const stderr_w, _ = std.debug.lockStderrWriter(&.{});
|
||||
defer std.debug.unlockStderrWriter();
|
||||
stderr_w.print("compilation: {s}\n", .{options.root_name}) catch break :print;
|
||||
stderr_w.print(" target: {s}\n", .{try target.zigTriple(arena)}) catch break :print;
|
||||
@ -4270,7 +4270,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle {
|
||||
// However, we haven't reported any such error.
|
||||
// This is a compiler bug.
|
||||
print_ctx: {
|
||||
var stderr_w = std.debug.lockStderrWriter(&.{});
|
||||
var stderr_w, _ = std.debug.lockStderrWriter(&.{});
|
||||
defer std.debug.unlockStderrWriter();
|
||||
stderr_w.writeAll("referenced transitive analysis errors, but none actually emitted\n") catch break :print_ctx;
|
||||
stderr_w.print("{f} [transitive failure]\n", .{zcu.fmtAnalUnit(failed_unit)}) catch break :print_ctx;
|
||||
@ -7752,7 +7752,7 @@ pub fn lockAndSetMiscFailure(
|
||||
|
||||
pub fn dump_argv(argv: []const []const u8) void {
|
||||
var buffer: [64]u8 = undefined;
|
||||
const stderr = std.debug.lockStderrWriter(&buffer);
|
||||
const stderr, _ = std.debug.lockStderrWriter(&buffer);
|
||||
defer std.debug.unlockStderrWriter();
|
||||
nosuspend {
|
||||
for (argv, 0..) |arg, i| {
|
||||
|
||||
@ -11330,7 +11330,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
|
||||
|
||||
fn dumpAllFallible(ip: *const InternPool) anyerror!void {
|
||||
var buffer: [4096]u8 = undefined;
|
||||
const stderr_bw = std.debug.lockStderrWriter(&buffer);
|
||||
const stderr_bw, _ = std.debug.lockStderrWriter(&buffer);
|
||||
defer std.debug.unlockStderrWriter();
|
||||
for (ip.locals, 0..) |*local, tid| {
|
||||
const items = local.shared.items.view();
|
||||
@ -11462,7 +11462,7 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)
|
||||
}
|
||||
|
||||
var buffer: [4096]u8 = undefined;
|
||||
const stderr_bw = std.debug.lockStderrWriter(&buffer);
|
||||
const stderr_bw, _ = std.debug.lockStderrWriter(&buffer);
|
||||
defer std.debug.unlockStderrWriter();
|
||||
|
||||
const SortContext = struct {
|
||||
|
||||
@ -2043,7 +2043,7 @@ const UnpackResult = struct {
|
||||
defer errors.deinit(gpa);
|
||||
var aw: Io.Writer.Allocating = .init(gpa);
|
||||
defer aw.deinit();
|
||||
try errors.renderToWriter(.{ .ttyconf = .no_color }, &aw.writer);
|
||||
try errors.renderToWriter(.{}, &aw.writer, .no_color);
|
||||
try std.testing.expectEqualStrings(
|
||||
\\error: unable to unpack
|
||||
\\ note: unable to create symlink from 'dir2/file2' to 'filename': SymlinkError
|
||||
@ -2360,7 +2360,7 @@ const TestFetchBuilder = struct {
|
||||
}
|
||||
var aw: Io.Writer.Allocating = .init(std.testing.allocator);
|
||||
defer aw.deinit();
|
||||
try errors.renderToWriter(.{ .ttyconf = .no_color }, &aw.writer);
|
||||
try errors.renderToWriter(.{}, &aw.writer, .no_color);
|
||||
try std.testing.expectEqualStrings(msg, aw.written());
|
||||
}
|
||||
};
|
||||
|
||||
@ -2631,7 +2631,7 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Zcu.ErrorMsg
|
||||
Compilation.addModuleErrorMsg(zcu, &wip_errors, err_msg.*, false) catch @panic("out of memory");
|
||||
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 });
|
||||
error_bundle.renderToStdErr(.{}, .auto);
|
||||
std.debug.panicExtra(@returnAddress(), "unexpected compile error occurred", .{});
|
||||
}
|
||||
|
||||
|
||||
@ -4473,7 +4473,7 @@ fn runCodegenInner(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) e
|
||||
defer if (liveness) |*l| l.deinit(gpa);
|
||||
|
||||
if (build_options.enable_debug_extensions and comp.verbose_air) {
|
||||
const stderr = std.debug.lockStderrWriter(&.{});
|
||||
const stderr, _ = std.debug.lockStderrWriter(&.{});
|
||||
defer std.debug.unlockStderrWriter();
|
||||
stderr.print("# Begin Function AIR: {f}:\n", .{fqn.fmt(ip)}) catch {};
|
||||
air.write(stderr, pt, liveness);
|
||||
|
||||
@ -74,10 +74,10 @@ pub fn printInstruction(dis: Disassemble, inst: aarch64.encoding.Instruction, wr
|
||||
dis.operands_separator,
|
||||
imm12,
|
||||
});
|
||||
return if (!elide_shift) writer.print("{s}{f} #{s}", .{
|
||||
return if (!elide_shift) writer.print("{s}{f} #{t}", .{
|
||||
dis.operands_separator,
|
||||
fmtCase(.lsl, dis.case),
|
||||
@tagName(sh),
|
||||
sh,
|
||||
});
|
||||
},
|
||||
.add_subtract_immediate_with_tags => |add_subtract_immediate_with_tags| {
|
||||
@ -176,10 +176,10 @@ pub fn printInstruction(dis: Disassemble, inst: aarch64.encoding.Instruction, wr
|
||||
dis.operands_separator,
|
||||
imm16,
|
||||
});
|
||||
return if (!elide_shift) writer.print("{s}{f} #{s}", .{
|
||||
return if (!elide_shift) writer.print("{s}{f} #{t}", .{
|
||||
dis.operands_separator,
|
||||
fmtCase(.lsl, dis.case),
|
||||
@tagName(hw),
|
||||
hw,
|
||||
});
|
||||
},
|
||||
.bitfield => |bitfield| {
|
||||
@ -833,8 +833,36 @@ pub fn printInstruction(dis: Disassemble, inst: aarch64.encoding.Instruction, wr
|
||||
},
|
||||
.rotate_right_into_flags => {},
|
||||
.evaluate_into_flags => {},
|
||||
.conditional_compare_register => {},
|
||||
.conditional_compare_immediate => {},
|
||||
.conditional_compare_register => |conditional_compare_register| {
|
||||
const group = conditional_compare_register.group;
|
||||
const sf = group.sf;
|
||||
return writer.print("{f}{s}{f}{s}{f}{s}#0x{x}{s}{f}", .{
|
||||
fmtCase(group.op, dis.case),
|
||||
dis.mnemonic_operands_separator,
|
||||
group.Rn.decode(.{}).general(sf).fmtCase(dis.case),
|
||||
dis.operands_separator,
|
||||
group.Rm.decode(.{}).general(sf).fmtCase(dis.case),
|
||||
dis.operands_separator,
|
||||
@as(u4, @bitCast(group.nzcv)),
|
||||
dis.operands_separator,
|
||||
fmtCase(group.cond, dis.case),
|
||||
});
|
||||
},
|
||||
.conditional_compare_immediate => |conditional_compare_immediate| {
|
||||
const group = conditional_compare_immediate.group;
|
||||
const sf = group.sf;
|
||||
return writer.print("{f}{s}{f}{s}#0x{x}{s}#0x{x}{s}{f}", .{
|
||||
fmtCase(group.op, dis.case),
|
||||
dis.mnemonic_operands_separator,
|
||||
group.Rn.decode(.{}).general(sf).fmtCase(dis.case),
|
||||
dis.operands_separator,
|
||||
group.imm5,
|
||||
dis.operands_separator,
|
||||
@as(u4, @bitCast(group.nzcv)),
|
||||
dis.operands_separator,
|
||||
fmtCase(group.cond, dis.case),
|
||||
});
|
||||
},
|
||||
.conditional_select => |conditional_select| {
|
||||
const decoded = conditional_select.decode();
|
||||
if (decoded == .unallocated) break :unallocated;
|
||||
|
||||
@ -107,6 +107,7 @@ pub fn emit(
|
||||
mir.body[nav_reloc.reloc.label],
|
||||
body_end - Instruction.size * (1 + nav_reloc.reloc.label),
|
||||
nav_reloc.reloc.addend,
|
||||
if (ip.getNav(nav_reloc.nav).getExtern(ip)) |_| .got_load else .direct,
|
||||
);
|
||||
for (mir.uav_relocs) |uav_reloc| try emitReloc(
|
||||
lf,
|
||||
@ -124,6 +125,7 @@ pub fn emit(
|
||||
mir.body[uav_reloc.reloc.label],
|
||||
body_end - Instruction.size * (1 + uav_reloc.reloc.label),
|
||||
uav_reloc.reloc.addend,
|
||||
.direct,
|
||||
);
|
||||
for (mir.lazy_relocs) |lazy_reloc| try emitReloc(
|
||||
lf,
|
||||
@ -136,10 +138,11 @@ pub fn emit(
|
||||
mf.getZigObject().?.getOrCreateMetadataForLazySymbol(mf, pt, lazy_reloc.symbol) catch |err|
|
||||
return zcu.codegenFail(func.owner_nav, "{s} creating lazy symbol", .{@errorName(err)})
|
||||
else
|
||||
return zcu.codegenFail(func.owner_nav, "external symbols unimplemented for {s}", .{@tagName(lf.tag)}),
|
||||
return zcu.codegenFail(func.owner_nav, "external symbols unimplemented for {t}", .{lf.tag}),
|
||||
mir.body[lazy_reloc.reloc.label],
|
||||
body_end - Instruction.size * (1 + lazy_reloc.reloc.label),
|
||||
lazy_reloc.reloc.addend,
|
||||
.direct,
|
||||
);
|
||||
for (mir.global_relocs) |global_reloc| try emitReloc(
|
||||
lf,
|
||||
@ -150,10 +153,11 @@ pub fn emit(
|
||||
else if (lf.cast(.macho)) |mf|
|
||||
try mf.getGlobalSymbol(std.mem.span(global_reloc.name), null)
|
||||
else
|
||||
return zcu.codegenFail(func.owner_nav, "external symbols unimplemented for {s}", .{@tagName(lf.tag)}),
|
||||
return zcu.codegenFail(func.owner_nav, "external symbols unimplemented for {t}", .{lf.tag}),
|
||||
mir.body[global_reloc.reloc.label],
|
||||
body_end - Instruction.size * (1 + global_reloc.reloc.label),
|
||||
global_reloc.reloc.addend,
|
||||
.direct,
|
||||
);
|
||||
const literal_reloc_offset: i19 = @intCast(mir.epilogue.len + literals_align_gap);
|
||||
for (mir.literal_relocs) |literal_reloc| {
|
||||
@ -188,6 +192,7 @@ fn emitReloc(
|
||||
instruction: Instruction,
|
||||
offset: u32,
|
||||
addend: u64,
|
||||
kind: enum { direct, got_load },
|
||||
) !void {
|
||||
const gpa = zcu.gpa;
|
||||
switch (instruction.decode()) {
|
||||
@ -198,11 +203,20 @@ fn emitReloc(
|
||||
const r_type: std.elf.R_AARCH64 = switch (decoded.decode()) {
|
||||
else => unreachable,
|
||||
.pc_relative_addressing => |pc_relative_addressing| switch (pc_relative_addressing.group.op) {
|
||||
.adr => .ADR_PREL_LO21,
|
||||
.adrp => .ADR_PREL_PG_HI21,
|
||||
.adr => switch (kind) {
|
||||
.direct => .ADR_PREL_LO21,
|
||||
.got_load => unreachable,
|
||||
},
|
||||
.adrp => switch (kind) {
|
||||
.direct => .ADR_PREL_PG_HI21,
|
||||
.got_load => .ADR_GOT_PAGE,
|
||||
},
|
||||
},
|
||||
.add_subtract_immediate => |add_subtract_immediate| switch (add_subtract_immediate.group.op) {
|
||||
.add => .ADD_ABS_LO12_NC,
|
||||
.add => switch (kind) {
|
||||
.direct => .ADD_ABS_LO12_NC,
|
||||
.got_load => unreachable,
|
||||
},
|
||||
.sub => unreachable,
|
||||
},
|
||||
};
|
||||
@ -223,7 +237,10 @@ fn emitReloc(
|
||||
.offset = offset,
|
||||
.target = sym_index,
|
||||
.addend = @bitCast(addend),
|
||||
.type = .page,
|
||||
.type = switch (kind) {
|
||||
.direct => .page,
|
||||
.got_load => .got_load_page,
|
||||
},
|
||||
.meta = .{
|
||||
.pcrel = true,
|
||||
.has_subtractor = false,
|
||||
@ -238,7 +255,10 @@ fn emitReloc(
|
||||
.offset = offset,
|
||||
.target = sym_index,
|
||||
.addend = @bitCast(addend),
|
||||
.type = .pageoff,
|
||||
.type = switch (kind) {
|
||||
.direct => .pageoff,
|
||||
.got_load => .got_load_pageoff,
|
||||
},
|
||||
.meta = .{
|
||||
.pcrel = false,
|
||||
.has_subtractor = false,
|
||||
@ -285,20 +305,39 @@ fn emitReloc(
|
||||
const r_type: std.elf.R_AARCH64 = switch (decoded.decode().register_unsigned_immediate.decode()) {
|
||||
.integer => |integer| switch (integer.decode()) {
|
||||
.unallocated, .prfm => unreachable,
|
||||
.strb, .ldrb, .ldrsb => .LDST8_ABS_LO12_NC,
|
||||
.strh, .ldrh, .ldrsh => .LDST16_ABS_LO12_NC,
|
||||
.ldrsw => .LDST32_ABS_LO12_NC,
|
||||
inline .str, .ldr => |encoded| switch (encoded.sf) {
|
||||
.strb, .ldrb, .ldrsb => switch (kind) {
|
||||
.direct => .LDST8_ABS_LO12_NC,
|
||||
.got_load => unreachable,
|
||||
},
|
||||
.strh, .ldrh, .ldrsh => switch (kind) {
|
||||
.direct => .LDST16_ABS_LO12_NC,
|
||||
.got_load => unreachable,
|
||||
},
|
||||
.ldrsw => switch (kind) {
|
||||
.direct => .LDST32_ABS_LO12_NC,
|
||||
.got_load => unreachable,
|
||||
},
|
||||
inline .str, .ldr => |encoded, mnemonic| switch (encoded.sf) {
|
||||
.word => .LDST32_ABS_LO12_NC,
|
||||
.doubleword => .LDST64_ABS_LO12_NC,
|
||||
.doubleword => switch (kind) {
|
||||
.direct => .LDST64_ABS_LO12_NC,
|
||||
.got_load => switch (mnemonic) {
|
||||
else => comptime unreachable,
|
||||
.str => unreachable,
|
||||
.ldr => .LD64_GOT_LO12_NC,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
.vector => |vector| switch (vector.group.opc1.decode(vector.group.size)) {
|
||||
.byte => .LDST8_ABS_LO12_NC,
|
||||
.half => .LDST16_ABS_LO12_NC,
|
||||
.single => .LDST32_ABS_LO12_NC,
|
||||
.double => .LDST64_ABS_LO12_NC,
|
||||
.quad => .LDST128_ABS_LO12_NC,
|
||||
.vector => |vector| switch (kind) {
|
||||
.direct => switch (vector.group.opc1.decode(vector.group.size)) {
|
||||
.byte => .LDST8_ABS_LO12_NC,
|
||||
.half => .LDST16_ABS_LO12_NC,
|
||||
.single => .LDST32_ABS_LO12_NC,
|
||||
.double => .LDST64_ABS_LO12_NC,
|
||||
.quad => .LDST128_ABS_LO12_NC,
|
||||
},
|
||||
.got_load => unreachable,
|
||||
},
|
||||
};
|
||||
try atom.addReloc(gpa, .{
|
||||
@ -314,7 +353,10 @@ fn emitReloc(
|
||||
.offset = offset,
|
||||
.target = sym_index,
|
||||
.addend = @bitCast(addend),
|
||||
.type = .pageoff,
|
||||
.type = switch (kind) {
|
||||
.direct => .pageoff,
|
||||
.got_load => .got_load_pageoff,
|
||||
},
|
||||
.meta = .{
|
||||
.pcrel = false,
|
||||
.has_subtractor = false,
|
||||
|
||||
@ -961,7 +961,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
.inst_index = undefined,
|
||||
};
|
||||
air_tag: switch (air.next().?) {
|
||||
else => |air_tag| return isel.fail("unimplemented {s}", .{@tagName(air_tag)}),
|
||||
else => |air_tag| return isel.fail("unimplemented {t}", .{air_tag}),
|
||||
.arg => {
|
||||
const arg_vi = isel.live_values.fetchRemove(air.inst_index).?.value;
|
||||
defer arg_vi.deref(isel);
|
||||
@ -1117,12 +1117,12 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
|
||||
const bin_op = air.data(air.inst_index).bin_op;
|
||||
const ty = isel.air.typeOf(bin_op.lhs, ip);
|
||||
if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });
|
||||
if (!ty.isAbiInt(zcu)) return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) });
|
||||
const int_info = ty.intInfo(zcu);
|
||||
switch (int_info.bits) {
|
||||
0 => unreachable,
|
||||
32, 64 => |bits| switch (int_info.signedness) {
|
||||
.signed => return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) }),
|
||||
.signed => return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) }),
|
||||
.unsigned => {
|
||||
const res_ra = try res_vi.value.defReg(isel) orelse break :unused;
|
||||
const lhs_vi = try isel.use(bin_op.lhs);
|
||||
@ -1160,7 +1160,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
try lhs_mat.finish(isel);
|
||||
},
|
||||
},
|
||||
else => return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) }),
|
||||
else => return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) }),
|
||||
}
|
||||
}
|
||||
if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
|
||||
@ -1172,7 +1172,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
const bin_op = air.data(air.inst_index).bin_op;
|
||||
const ty = isel.air.typeOf(bin_op.lhs, ip);
|
||||
if (!ty.isRuntimeFloat()) {
|
||||
if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });
|
||||
if (!ty.isAbiInt(zcu)) return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) });
|
||||
const int_info = ty.intInfo(zcu);
|
||||
switch (int_info.bits) {
|
||||
0 => unreachable,
|
||||
@ -1318,7 +1318,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
try rhs_lo64_mat.finish(isel);
|
||||
try lhs_lo64_mat.finish(isel);
|
||||
},
|
||||
else => return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) }),
|
||||
else => return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) }),
|
||||
}
|
||||
} else switch (ty.floatBits(isel.target)) {
|
||||
else => unreachable,
|
||||
@ -1421,7 +1421,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
|
||||
const bin_op = air.data(air.inst_index).bin_op;
|
||||
const ty = isel.air.typeOf(bin_op.lhs, ip);
|
||||
if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });
|
||||
if (!ty.isAbiInt(zcu)) return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) });
|
||||
const int_info = ty.intInfo(zcu);
|
||||
switch (int_info.signedness) {
|
||||
.signed => switch (int_info.bits) {
|
||||
@ -1443,7 +1443,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
try rhs_mat.finish(isel);
|
||||
try lhs_mat.finish(isel);
|
||||
},
|
||||
else => return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) }),
|
||||
else => return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) }),
|
||||
},
|
||||
.unsigned => switch (int_info.bits) {
|
||||
0 => unreachable,
|
||||
@ -1545,8 +1545,8 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
try rhs_mat.finish(isel);
|
||||
try lhs_mat.finish(isel);
|
||||
},
|
||||
65...128 => return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) }),
|
||||
else => return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) }),
|
||||
65...128 => return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) }),
|
||||
else => return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) }),
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -1558,7 +1558,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
|
||||
const bin_op = air.data(air.inst_index).bin_op;
|
||||
const ty = isel.air.typeOf(bin_op.lhs, ip);
|
||||
if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });
|
||||
if (!ty.isAbiInt(zcu)) return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) });
|
||||
const int_info = ty.intInfo(zcu);
|
||||
switch (int_info.bits) {
|
||||
0 => unreachable,
|
||||
@ -1784,7 +1784,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
try rhs_mat.finish(isel);
|
||||
try lhs_mat.finish(isel);
|
||||
},
|
||||
else => return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) }),
|
||||
else => return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) }),
|
||||
}
|
||||
}
|
||||
if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
|
||||
@ -1897,7 +1897,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
const bin_op = air.data(air.inst_index).bin_op;
|
||||
const ty = isel.air.typeOf(bin_op.lhs, ip);
|
||||
if (!ty.isRuntimeFloat()) {
|
||||
if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });
|
||||
if (!ty.isAbiInt(zcu)) return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) });
|
||||
const int_info = ty.intInfo(zcu);
|
||||
switch (int_info.bits) {
|
||||
0 => unreachable,
|
||||
@ -1970,7 +1970,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
else => unreachable,
|
||||
.div_trunc, .div_exact => {},
|
||||
.div_floor => switch (int_info.signedness) {
|
||||
.signed => return isel.fail("unimplemented {s}", .{@tagName(air_tag)}),
|
||||
.signed => return isel.fail("unimplemented {t}", .{air_tag}),
|
||||
.unsigned => {},
|
||||
},
|
||||
}
|
||||
@ -2012,7 +2012,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
try call.paramLiveOut(isel, lhs_lo64_vi.?, .r0);
|
||||
try call.finishParams(isel);
|
||||
},
|
||||
else => return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) }),
|
||||
else => return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) }),
|
||||
}
|
||||
} else switch (ty.floatBits(isel.target)) {
|
||||
else => unreachable,
|
||||
@ -2169,9 +2169,9 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
const bin_op = air.data(air.inst_index).bin_op;
|
||||
const ty = isel.air.typeOf(bin_op.lhs, ip);
|
||||
if (!ty.isRuntimeFloat()) {
|
||||
if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });
|
||||
if (!ty.isAbiInt(zcu)) return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) });
|
||||
const int_info = ty.intInfo(zcu);
|
||||
if (int_info.bits > 64) return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });
|
||||
if (int_info.bits > 64) return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) });
|
||||
|
||||
const res_ra = try res_vi.value.defReg(isel) orelse break :unused;
|
||||
const lhs_vi = try isel.use(bin_op.lhs);
|
||||
@ -2494,9 +2494,9 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
const bin_op = air.data(air.inst_index).bin_op;
|
||||
const ty = isel.air.typeOf(bin_op.lhs, ip);
|
||||
if (!ty.isRuntimeFloat()) {
|
||||
if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });
|
||||
if (!ty.isAbiInt(zcu)) return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) });
|
||||
const int_info = ty.intInfo(zcu);
|
||||
if (int_info.bits > 64) return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });
|
||||
if (int_info.bits > 64) return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) });
|
||||
|
||||
const res_ra = try res_vi.value.defReg(isel) orelse break :unused;
|
||||
const lhs_vi = try isel.use(bin_op.lhs);
|
||||
@ -2920,8 +2920,8 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
else if (ty.isAbiInt(zcu))
|
||||
ty.intInfo(zcu)
|
||||
else
|
||||
return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });
|
||||
if (int_info.bits > 128) return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });
|
||||
return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) });
|
||||
if (int_info.bits > 128) return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) });
|
||||
|
||||
const lhs_vi = try isel.use(bin_op.lhs);
|
||||
const rhs_vi = try isel.use(bin_op.rhs);
|
||||
@ -2968,7 +2968,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
|
||||
const bin_op = air.data(air.inst_index).bin_op;
|
||||
const ty = isel.air.typeOf(bin_op.lhs, ip);
|
||||
if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });
|
||||
if (!ty.isAbiInt(zcu)) return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) });
|
||||
const int_info = ty.intInfo(zcu);
|
||||
switch (int_info.bits) {
|
||||
0 => unreachable,
|
||||
@ -3161,7 +3161,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
try lhs_hi64_mat.finish(isel);
|
||||
break :unused;
|
||||
},
|
||||
else => return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) }),
|
||||
else => return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) }),
|
||||
}
|
||||
}
|
||||
if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
|
||||
@ -3174,10 +3174,10 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
const ty = ty_op.ty.toType();
|
||||
const int_info: std.builtin.Type.Int = int_info: {
|
||||
if (ty_op.ty == .bool_type) break :int_info .{ .signedness = .unsigned, .bits = 1 };
|
||||
if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });
|
||||
if (!ty.isAbiInt(zcu)) return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) });
|
||||
break :int_info ty.intInfo(zcu);
|
||||
};
|
||||
if (int_info.bits > 128) return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });
|
||||
if (int_info.bits > 128) return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) });
|
||||
|
||||
const src_vi = try isel.use(ty_op.operand);
|
||||
var offset = res_vi.value.size(isel);
|
||||
@ -3302,7 +3302,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
}
|
||||
},
|
||||
128 => try dst_vi.value.move(isel, ty_op.operand),
|
||||
else => return isel.fail("bad {s} {f} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty), isel.fmtType(src_ty) }),
|
||||
else => return isel.fail("bad {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) }),
|
||||
}
|
||||
} else if ((dst_ty.isPtrAtRuntime(zcu) or dst_ty.isAbiInt(zcu)) and (src_ty.isPtrAtRuntime(zcu) or src_ty.isAbiInt(zcu))) {
|
||||
try dst_vi.value.move(isel, ty_op.operand);
|
||||
@ -3313,7 +3313,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
src_ty.errorUnionSet(zcu).hasRuntimeBitsIgnoreComptime(zcu));
|
||||
if (dst_ty.errorUnionPayload(zcu).toIntern() == src_ty.errorUnionPayload(zcu).toIntern()) {
|
||||
try dst_vi.value.move(isel, ty_op.operand);
|
||||
} else return isel.fail("bad {s} {f} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty), isel.fmtType(src_ty) });
|
||||
} else return isel.fail("bad {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) });
|
||||
} else if (dst_tag == .float and src_tag == .float) {
|
||||
assert(dst_ty.floatBits(isel.target) == src_ty.floatBits(isel.target));
|
||||
try dst_vi.value.move(isel, ty_op.operand);
|
||||
@ -3483,7 +3483,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
try call.paramAddress(isel, src_vi, .r1);
|
||||
try call.paramAddress(isel, dst_vi.value, .r0);
|
||||
try call.finishParams(isel);
|
||||
} else return isel.fail("bad {s} {f} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty), isel.fmtType(src_ty) });
|
||||
} else return isel.fail("bad {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) });
|
||||
} else if (dst_tag == .array and dst_ty.childType(zcu).isAbiInt(zcu) and src_ty.isAbiInt(zcu)) {
|
||||
const dst_child_int_info = dst_ty.childType(zcu).intInfo(zcu);
|
||||
const src_int_info = src_ty.intInfo(zcu);
|
||||
@ -3510,8 +3510,8 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
try call.paramAddress(isel, src_vi, .r1);
|
||||
try call.paramAddress(isel, dst_vi.value, .r0);
|
||||
try call.finishParams(isel);
|
||||
} else return isel.fail("bad {s} {f} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty), isel.fmtType(src_ty) });
|
||||
} else return isel.fail("bad {s} {f} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty), isel.fmtType(src_ty) });
|
||||
} else return isel.fail("bad {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) });
|
||||
} else return isel.fail("bad {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) });
|
||||
}
|
||||
if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
|
||||
},
|
||||
@ -3737,7 +3737,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
|
||||
const ty_op = air.data(air.inst_index).ty_op;
|
||||
const ty = isel.air.typeOf(ty_op.operand, ip);
|
||||
if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });
|
||||
if (!ty.isAbiInt(zcu)) return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) });
|
||||
const int_info = ty.intInfo(zcu);
|
||||
switch (int_info.bits) {
|
||||
0 => unreachable,
|
||||
@ -3769,7 +3769,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
try src_hi64_mat.finish(isel);
|
||||
try src_lo64_mat.finish(isel);
|
||||
},
|
||||
else => return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) }),
|
||||
else => return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) }),
|
||||
}
|
||||
}
|
||||
if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
|
||||
@ -3780,7 +3780,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
|
||||
const ty_op = air.data(air.inst_index).ty_op;
|
||||
const ty = isel.air.typeOf(ty_op.operand, ip);
|
||||
if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });
|
||||
if (!ty.isAbiInt(zcu)) return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) });
|
||||
const int_info = ty.intInfo(zcu);
|
||||
switch (int_info.bits) {
|
||||
0 => unreachable,
|
||||
@ -3812,7 +3812,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
try src_hi64_mat.finish(isel);
|
||||
try src_lo64_mat.finish(isel);
|
||||
},
|
||||
else => return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) }),
|
||||
else => return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) }),
|
||||
}
|
||||
}
|
||||
if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
|
||||
@ -3823,9 +3823,9 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
|
||||
const ty_op = air.data(air.inst_index).ty_op;
|
||||
const ty = isel.air.typeOf(ty_op.operand, ip);
|
||||
if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });
|
||||
if (!ty.isAbiInt(zcu)) return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) });
|
||||
const int_info = ty.intInfo(zcu);
|
||||
if (int_info.bits > 64) return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });
|
||||
if (int_info.bits > 64) return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) });
|
||||
|
||||
const res_ra = try res_vi.value.defReg(isel) orelse break :unused;
|
||||
const src_vi = try isel.use(ty_op.operand);
|
||||
@ -3877,9 +3877,9 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
|
||||
const ty_op = air.data(air.inst_index).ty_op;
|
||||
const ty = ty_op.ty.toType();
|
||||
if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });
|
||||
if (!ty.isAbiInt(zcu)) return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) });
|
||||
const int_info = ty.intInfo(zcu);
|
||||
if (int_info.bits > 64) return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });
|
||||
if (int_info.bits > 64) return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) });
|
||||
|
||||
if (int_info.bits == 8) break :unused try res_vi.value.move(isel, ty_op.operand);
|
||||
const res_ra = try res_vi.value.defReg(isel) orelse break :unused;
|
||||
@ -3941,9 +3941,9 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
|
||||
const ty_op = air.data(air.inst_index).ty_op;
|
||||
const ty = ty_op.ty.toType();
|
||||
if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });
|
||||
if (!ty.isAbiInt(zcu)) return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) });
|
||||
const int_info = ty.intInfo(zcu);
|
||||
if (int_info.bits > 64) return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });
|
||||
if (int_info.bits > 64) return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) });
|
||||
|
||||
const res_ra = try res_vi.value.defReg(isel) orelse break :unused;
|
||||
const src_vi = try isel.use(ty_op.operand);
|
||||
@ -4244,7 +4244,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
const ty_op = air.data(air.inst_index).ty_op;
|
||||
const ty = ty_op.ty.toType();
|
||||
if (!ty.isRuntimeFloat()) {
|
||||
if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });
|
||||
if (!ty.isAbiInt(zcu)) return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) });
|
||||
switch (ty.intInfo(zcu).bits) {
|
||||
0 => unreachable,
|
||||
1...32 => {
|
||||
@ -4306,7 +4306,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
try src_lo64_mat.finish(isel);
|
||||
try src_hi64_mat.finish(isel);
|
||||
},
|
||||
else => return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) }),
|
||||
else => return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) }),
|
||||
}
|
||||
} else switch (ty.floatBits(isel.target)) {
|
||||
else => unreachable,
|
||||
@ -4465,216 +4465,61 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
if (isel.live_values.fetchRemove(air.inst_index)) |res_vi| unused: {
|
||||
defer res_vi.value.deref(isel);
|
||||
|
||||
var bin_op = air.data(air.inst_index).bin_op;
|
||||
const bin_op = air.data(air.inst_index).bin_op;
|
||||
const ty = isel.air.typeOf(bin_op.lhs, ip);
|
||||
if (!ty.isRuntimeFloat()) {
|
||||
const int_info: std.builtin.Type.Int = if (ty.toIntern() == .bool_type)
|
||||
.{ .signedness = .unsigned, .bits = 1 }
|
||||
else if (ty.isAbiInt(zcu))
|
||||
ty.intInfo(zcu)
|
||||
else if (ty.isPtrAtRuntime(zcu))
|
||||
.{ .signedness = .unsigned, .bits = 64 }
|
||||
else
|
||||
return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });
|
||||
if (int_info.bits > 256) return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });
|
||||
|
||||
const res_ra = try res_vi.value.defReg(isel) orelse break :unused;
|
||||
try isel.emit(.csinc(res_ra.w(), .wzr, .wzr, .invert(cond: switch (air_tag) {
|
||||
switch (ip.indexToKey(ty.toIntern())) {
|
||||
else => {},
|
||||
.opt_type => |payload_ty| switch (air_tag) {
|
||||
else => unreachable,
|
||||
.cmp_lt => switch (int_info.signedness) {
|
||||
.signed => .lt,
|
||||
.unsigned => .lo,
|
||||
.cmp_eq, .cmp_neq => if (!ty.optionalReprIsPayload(zcu)) {
|
||||
const lhs_vi = try isel.use(bin_op.lhs);
|
||||
const rhs_vi = try isel.use(bin_op.rhs);
|
||||
const payload_size = ZigType.abiSize(.fromInterned(payload_ty), zcu);
|
||||
var lhs_payload_part_it = lhs_vi.field(ty, 0, payload_size);
|
||||
const lhs_payload_part_vi = try lhs_payload_part_it.only(isel);
|
||||
var rhs_payload_part_it = rhs_vi.field(ty, 0, payload_size);
|
||||
const rhs_payload_part_vi = try rhs_payload_part_it.only(isel);
|
||||
const cmp_info = try isel.cmp(
|
||||
try res_vi.value.defReg(isel) orelse break :unused,
|
||||
.fromInterned(payload_ty),
|
||||
lhs_payload_part_vi.?,
|
||||
air_tag.toCmpOp().?,
|
||||
rhs_payload_part_vi.?,
|
||||
);
|
||||
try isel.emit(.@"b."(
|
||||
.vc,
|
||||
@intCast((isel.instructions.items.len + 1 - cmp_info.cset_label) << 2),
|
||||
));
|
||||
var lhs_has_value_part_it = lhs_vi.field(ty, payload_size, 1);
|
||||
const lhs_has_value_part_vi = try lhs_has_value_part_it.only(isel);
|
||||
const lhs_has_value_part_mat = try lhs_has_value_part_vi.?.matReg(isel);
|
||||
var rhs_has_value_part_it = rhs_vi.field(ty, payload_size, 1);
|
||||
const rhs_has_value_part_vi = try rhs_has_value_part_it.only(isel);
|
||||
const rhs_has_value_part_mat = try rhs_has_value_part_vi.?.matReg(isel);
|
||||
try isel.emit(.ccmp(
|
||||
lhs_has_value_part_mat.ra.w(),
|
||||
.{ .register = rhs_has_value_part_mat.ra.w() },
|
||||
.{ .n = false, .z = false, .c = false, .v = true },
|
||||
.eq,
|
||||
));
|
||||
try isel.emit(.ands(
|
||||
.wzr,
|
||||
lhs_has_value_part_mat.ra.w(),
|
||||
.{ .register = rhs_has_value_part_mat.ra.w() },
|
||||
));
|
||||
try rhs_has_value_part_mat.finish(isel);
|
||||
try lhs_has_value_part_mat.finish(isel);
|
||||
break :unused;
|
||||
},
|
||||
.cmp_lte => switch (int_info.bits) {
|
||||
else => unreachable,
|
||||
1...64 => switch (int_info.signedness) {
|
||||
.signed => .le,
|
||||
.unsigned => .ls,
|
||||
},
|
||||
65...128 => {
|
||||
std.mem.swap(Air.Inst.Ref, &bin_op.lhs, &bin_op.rhs);
|
||||
continue :cond .cmp_gte;
|
||||
},
|
||||
},
|
||||
.cmp_eq => .eq,
|
||||
.cmp_gte => switch (int_info.signedness) {
|
||||
.signed => .ge,
|
||||
.unsigned => .hs,
|
||||
},
|
||||
.cmp_gt => switch (int_info.bits) {
|
||||
else => unreachable,
|
||||
1...64 => switch (int_info.signedness) {
|
||||
.signed => .gt,
|
||||
.unsigned => .hi,
|
||||
},
|
||||
65...128 => {
|
||||
std.mem.swap(Air.Inst.Ref, &bin_op.lhs, &bin_op.rhs);
|
||||
continue :cond .cmp_lt;
|
||||
},
|
||||
},
|
||||
.cmp_neq => .ne,
|
||||
})));
|
||||
|
||||
const lhs_vi = try isel.use(bin_op.lhs);
|
||||
const rhs_vi = try isel.use(bin_op.rhs);
|
||||
var part_offset = lhs_vi.size(isel);
|
||||
while (part_offset > 0) {
|
||||
const part_size = @min(part_offset, 8);
|
||||
part_offset -= part_size;
|
||||
var lhs_part_it = lhs_vi.field(ty, part_offset, part_size);
|
||||
const lhs_part_vi = try lhs_part_it.only(isel);
|
||||
const lhs_part_mat = try lhs_part_vi.?.matReg(isel);
|
||||
var rhs_part_it = rhs_vi.field(ty, part_offset, part_size);
|
||||
const rhs_part_vi = try rhs_part_it.only(isel);
|
||||
const rhs_part_mat = try rhs_part_vi.?.matReg(isel);
|
||||
try isel.emit(switch (part_size) {
|
||||
else => unreachable,
|
||||
1...4 => switch (part_offset) {
|
||||
0 => .subs(.wzr, lhs_part_mat.ra.w(), .{ .register = rhs_part_mat.ra.w() }),
|
||||
else => switch (air_tag) {
|
||||
else => unreachable,
|
||||
.cmp_lt, .cmp_lte, .cmp_gte, .cmp_gt => .sbcs(
|
||||
.wzr,
|
||||
lhs_part_mat.ra.w(),
|
||||
rhs_part_mat.ra.w(),
|
||||
),
|
||||
.cmp_eq, .cmp_neq => .ccmp(
|
||||
lhs_part_mat.ra.w(),
|
||||
.{ .register = rhs_part_mat.ra.w() },
|
||||
.{ .n = false, .z = false, .c = false, .v = false },
|
||||
.eq,
|
||||
),
|
||||
},
|
||||
},
|
||||
5...8 => switch (part_offset) {
|
||||
0 => .subs(.xzr, lhs_part_mat.ra.x(), .{ .register = rhs_part_mat.ra.x() }),
|
||||
else => switch (air_tag) {
|
||||
else => unreachable,
|
||||
.cmp_lt, .cmp_lte, .cmp_gte, .cmp_gt => .sbcs(
|
||||
.xzr,
|
||||
lhs_part_mat.ra.x(),
|
||||
rhs_part_mat.ra.x(),
|
||||
),
|
||||
.cmp_eq, .cmp_neq => .ccmp(
|
||||
lhs_part_mat.ra.x(),
|
||||
.{ .register = rhs_part_mat.ra.x() },
|
||||
.{ .n = false, .z = false, .c = false, .v = false },
|
||||
.eq,
|
||||
),
|
||||
},
|
||||
},
|
||||
});
|
||||
try rhs_part_mat.finish(isel);
|
||||
try lhs_part_mat.finish(isel);
|
||||
}
|
||||
} else switch (ty.floatBits(isel.target)) {
|
||||
else => unreachable,
|
||||
16, 32, 64 => |bits| {
|
||||
const res_ra = try res_vi.value.defReg(isel) orelse break :unused;
|
||||
const need_fcvt = switch (bits) {
|
||||
else => unreachable,
|
||||
16 => !isel.target.cpu.has(.aarch64, .fullfp16),
|
||||
32, 64 => false,
|
||||
};
|
||||
try isel.emit(.csinc(res_ra.w(), .wzr, .wzr, .invert(switch (air_tag) {
|
||||
else => unreachable,
|
||||
.cmp_lt => .lo,
|
||||
.cmp_lte => .ls,
|
||||
.cmp_eq => .eq,
|
||||
.cmp_gte => .ge,
|
||||
.cmp_gt => .gt,
|
||||
.cmp_neq => .ne,
|
||||
})));
|
||||
|
||||
const lhs_vi = try isel.use(bin_op.lhs);
|
||||
const rhs_vi = try isel.use(bin_op.rhs);
|
||||
const lhs_mat = try lhs_vi.matReg(isel);
|
||||
const rhs_mat = try rhs_vi.matReg(isel);
|
||||
const lhs_ra = if (need_fcvt) try isel.allocVecReg() else lhs_mat.ra;
|
||||
defer if (need_fcvt) isel.freeReg(lhs_ra);
|
||||
const rhs_ra = if (need_fcvt) try isel.allocVecReg() else rhs_mat.ra;
|
||||
defer if (need_fcvt) isel.freeReg(rhs_ra);
|
||||
try isel.emit(bits: switch (bits) {
|
||||
else => unreachable,
|
||||
16 => if (need_fcvt)
|
||||
continue :bits 32
|
||||
else
|
||||
.fcmp(lhs_ra.h(), .{ .register = rhs_ra.h() }),
|
||||
32 => .fcmp(lhs_ra.s(), .{ .register = rhs_ra.s() }),
|
||||
64 => .fcmp(lhs_ra.d(), .{ .register = rhs_ra.d() }),
|
||||
});
|
||||
if (need_fcvt) {
|
||||
try isel.emit(.fcvt(rhs_ra.s(), rhs_mat.ra.h()));
|
||||
try isel.emit(.fcvt(lhs_ra.s(), lhs_mat.ra.h()));
|
||||
}
|
||||
try rhs_mat.finish(isel);
|
||||
try lhs_mat.finish(isel);
|
||||
},
|
||||
80, 128 => |bits| {
|
||||
const res_ra = try res_vi.value.defReg(isel) orelse break :unused;
|
||||
|
||||
try call.prepareReturn(isel);
|
||||
try call.returnFill(isel, .r0);
|
||||
try isel.emit(.csinc(res_ra.w(), .wzr, .wzr, .invert(cond: switch (air_tag) {
|
||||
else => unreachable,
|
||||
.cmp_lt => .lt,
|
||||
.cmp_lte => .le,
|
||||
.cmp_eq => .eq,
|
||||
.cmp_gte => {
|
||||
std.mem.swap(Air.Inst.Ref, &bin_op.lhs, &bin_op.rhs);
|
||||
continue :cond .cmp_lte;
|
||||
},
|
||||
.cmp_gt => {
|
||||
std.mem.swap(Air.Inst.Ref, &bin_op.lhs, &bin_op.rhs);
|
||||
continue :cond .cmp_lt;
|
||||
},
|
||||
.cmp_neq => .ne,
|
||||
})));
|
||||
try isel.emit(.subs(.wzr, .w0, .{ .immediate = 0 }));
|
||||
try call.finishReturn(isel);
|
||||
|
||||
try call.prepareCallee(isel);
|
||||
try isel.global_relocs.append(gpa, .{
|
||||
.name = switch (bits) {
|
||||
else => unreachable,
|
||||
16 => "__cmphf2",
|
||||
32 => "__cmpsf2",
|
||||
64 => "__cmpdf2",
|
||||
80 => "__cmpxf2",
|
||||
128 => "__cmptf2",
|
||||
},
|
||||
.reloc = .{ .label = @intCast(isel.instructions.items.len) },
|
||||
});
|
||||
try isel.emit(.bl(0));
|
||||
try call.finishCallee(isel);
|
||||
|
||||
try call.prepareParams(isel);
|
||||
const lhs_vi = try isel.use(bin_op.lhs);
|
||||
const rhs_vi = try isel.use(bin_op.rhs);
|
||||
switch (bits) {
|
||||
else => unreachable,
|
||||
16, 32, 64, 128 => {
|
||||
try call.paramLiveOut(isel, rhs_vi, .v1);
|
||||
try call.paramLiveOut(isel, lhs_vi, .v0);
|
||||
},
|
||||
80 => {
|
||||
var rhs_hi16_it = rhs_vi.field(ty, 8, 8);
|
||||
const rhs_hi16_vi = try rhs_hi16_it.only(isel);
|
||||
try call.paramLiveOut(isel, rhs_hi16_vi.?, .r3);
|
||||
var rhs_lo64_it = rhs_vi.field(ty, 0, 8);
|
||||
const rhs_lo64_vi = try rhs_lo64_it.only(isel);
|
||||
try call.paramLiveOut(isel, rhs_lo64_vi.?, .r2);
|
||||
var lhs_hi16_it = lhs_vi.field(ty, 8, 8);
|
||||
const lhs_hi16_vi = try lhs_hi16_it.only(isel);
|
||||
try call.paramLiveOut(isel, lhs_hi16_vi.?, .r1);
|
||||
var lhs_lo64_it = lhs_vi.field(ty, 0, 8);
|
||||
const lhs_lo64_vi = try lhs_lo64_it.only(isel);
|
||||
try call.paramLiveOut(isel, lhs_lo64_vi.?, .r0);
|
||||
},
|
||||
}
|
||||
try call.finishParams(isel);
|
||||
},
|
||||
}
|
||||
_ = try isel.cmp(
|
||||
try res_vi.value.defReg(isel) orelse break :unused,
|
||||
ty,
|
||||
try isel.use(bin_op.lhs),
|
||||
air_tag.toCmpOp().?,
|
||||
try isel.use(bin_op.rhs),
|
||||
);
|
||||
}
|
||||
if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
|
||||
},
|
||||
@ -5497,7 +5342,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
try src_mat.finish(isel);
|
||||
},
|
||||
};
|
||||
} else return isel.fail("too big {s} {f} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty), isel.fmtType(src_ty) });
|
||||
} else return isel.fail("too big {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) });
|
||||
}
|
||||
if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
|
||||
},
|
||||
@ -5517,7 +5362,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
.int => .integer_out_of_bounds,
|
||||
.@"enum" => {
|
||||
if (!dst_ty.isNonexhaustiveEnum(zcu)) {
|
||||
return isel.fail("bad {s} {f} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty), isel.fmtType(src_ty) });
|
||||
return isel.fail("bad {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) });
|
||||
}
|
||||
break :panic_id .invalid_enum_value;
|
||||
},
|
||||
@ -5599,7 +5444,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
try src_mat.finish(isel);
|
||||
}
|
||||
}
|
||||
} else return isel.fail("too big {s} {f} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty), isel.fmtType(src_ty) });
|
||||
} else return isel.fail("too big {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) });
|
||||
}
|
||||
if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
|
||||
},
|
||||
@ -5610,7 +5455,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
const ty_op = air.data(air.inst_index).ty_op;
|
||||
const dst_ty = ty_op.ty.toType();
|
||||
const src_ty = isel.air.typeOf(ty_op.operand, ip);
|
||||
if (!dst_ty.isAbiInt(zcu) or !src_ty.isAbiInt(zcu)) return isel.fail("bad {s} {f} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty), isel.fmtType(src_ty) });
|
||||
if (!dst_ty.isAbiInt(zcu) or !src_ty.isAbiInt(zcu)) return isel.fail("bad {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) });
|
||||
const dst_int_info = dst_ty.intInfo(zcu);
|
||||
switch (dst_int_info.bits) {
|
||||
0 => unreachable,
|
||||
@ -5683,9 +5528,9 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
try src_lo64_vi.?.liveOut(isel, dst_lo64_ra);
|
||||
}
|
||||
},
|
||||
else => return isel.fail("too big {s} {f} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty), isel.fmtType(src_ty) }),
|
||||
else => return isel.fail("too big {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) }),
|
||||
},
|
||||
else => return isel.fail("too big {s} {f} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty), isel.fmtType(src_ty) }),
|
||||
else => return isel.fail("too big {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) }),
|
||||
}
|
||||
}
|
||||
if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
|
||||
@ -6487,7 +6332,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
const ty_op = air.data(air.inst_index).ty_op;
|
||||
const dst_ty = ty_op.ty.toType();
|
||||
const src_ty = isel.air.typeOf(ty_op.operand, ip);
|
||||
if (!dst_ty.isAbiInt(zcu)) return isel.fail("bad {s} {f} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty), isel.fmtType(src_ty) });
|
||||
if (!dst_ty.isAbiInt(zcu)) return isel.fail("bad {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) });
|
||||
const dst_int_info = dst_ty.intInfo(zcu);
|
||||
const src_bits = src_ty.floatBits(isel.target);
|
||||
switch (@max(dst_int_info.bits, src_bits)) {
|
||||
@ -6617,7 +6462,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
}
|
||||
try call.finishParams(isel);
|
||||
},
|
||||
else => return isel.fail("too big {s} {f} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty), isel.fmtType(src_ty) }),
|
||||
else => return isel.fail("too big {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) }),
|
||||
}
|
||||
}
|
||||
if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
|
||||
@ -6630,7 +6475,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
const dst_ty = ty_op.ty.toType();
|
||||
const src_ty = isel.air.typeOf(ty_op.operand, ip);
|
||||
const dst_bits = dst_ty.floatBits(isel.target);
|
||||
if (!src_ty.isAbiInt(zcu)) return isel.fail("bad {s} {f} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty), isel.fmtType(src_ty) });
|
||||
if (!src_ty.isAbiInt(zcu)) return isel.fail("bad {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) });
|
||||
const src_int_info = src_ty.intInfo(zcu);
|
||||
switch (@max(dst_bits, src_int_info.bits)) {
|
||||
0 => unreachable,
|
||||
@ -6757,7 +6602,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
}
|
||||
try call.finishParams(isel);
|
||||
},
|
||||
else => return isel.fail("too big {s} {f} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty), isel.fmtType(src_ty) }),
|
||||
else => return isel.fail("too big {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) }),
|
||||
}
|
||||
}
|
||||
if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
|
||||
@ -6836,7 +6681,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
|
||||
break :air_tag if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
|
||||
},
|
||||
else => return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty) }),
|
||||
else => return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(dst_ty) }),
|
||||
}
|
||||
};
|
||||
|
||||
@ -7157,7 +7002,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
else => unreachable,
|
||||
},
|
||||
}),
|
||||
else => return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(union_ty) }),
|
||||
else => return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(union_ty) }),
|
||||
}
|
||||
}
|
||||
var payload_it = union_vi.value.field(union_ty, union_layout.payloadOffset(), union_layout.payload_size);
|
||||
@ -7412,7 +7257,10 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
||||
.nav = ty_nav.nav,
|
||||
.reloc = .{ .label = @intCast(isel.instructions.items.len) },
|
||||
});
|
||||
try isel.emit(.add(ptr_ra.x(), ptr_ra.x(), .{ .immediate = 0 }));
|
||||
if (ip.getNav(ty_nav.nav).getExtern(ip)) |_|
|
||||
try isel.emit(.ldr(ptr_ra.x(), .{ .unsigned_offset = .{ .base = ptr_ra.x(), .offset = 0 } }))
|
||||
else
|
||||
try isel.emit(.add(ptr_ra.x(), ptr_ra.x(), .{ .immediate = 0 }));
|
||||
try isel.nav_relocs.append(gpa, .{
|
||||
.nav = ty_nav.nav,
|
||||
.reloc = .{ .label = @intCast(isel.instructions.items.len) },
|
||||
@ -8499,6 +8347,217 @@ fn ctzLimb(
|
||||
}
|
||||
}
|
||||
|
||||
fn cmp(
|
||||
isel: *Select,
|
||||
res_ra: Register.Alias,
|
||||
ty: ZigType,
|
||||
orig_lhs_vi: Value.Index,
|
||||
op: std.math.CompareOperator,
|
||||
orig_rhs_vi: Value.Index,
|
||||
) !struct { cset_label: usize } {
|
||||
var lhs_vi = orig_lhs_vi;
|
||||
var rhs_vi = orig_rhs_vi;
|
||||
if (!ty.isRuntimeFloat()) {
|
||||
const int_info: std.builtin.Type.Int = if (ty.toIntern() == .bool_type)
|
||||
.{ .signedness = .unsigned, .bits = 1 }
|
||||
else if (ty.isAbiInt(isel.pt.zcu))
|
||||
ty.intInfo(isel.pt.zcu)
|
||||
else if (ty.isPtrAtRuntime(isel.pt.zcu))
|
||||
.{ .signedness = .unsigned, .bits = 64 }
|
||||
else
|
||||
return isel.fail("bad cmp_{t} {f}", .{ op, isel.fmtType(ty) });
|
||||
if (int_info.bits > 256) return isel.fail("too big cmp_{t} {f}", .{ op, isel.fmtType(ty) });
|
||||
try isel.emit(.csinc(res_ra.w(), .wzr, .wzr, .invert(cond: switch (op) {
|
||||
.lt => switch (int_info.signedness) {
|
||||
.signed => .lt,
|
||||
.unsigned => .lo,
|
||||
},
|
||||
.lte => switch (int_info.bits) {
|
||||
else => unreachable,
|
||||
1...64 => switch (int_info.signedness) {
|
||||
.signed => .le,
|
||||
.unsigned => .ls,
|
||||
},
|
||||
65...128 => {
|
||||
std.mem.swap(Value.Index, &lhs_vi, &rhs_vi);
|
||||
continue :cond .gte;
|
||||
},
|
||||
},
|
||||
.eq => .eq,
|
||||
.gte => switch (int_info.signedness) {
|
||||
.signed => .ge,
|
||||
.unsigned => .hs,
|
||||
},
|
||||
.gt => switch (int_info.bits) {
|
||||
else => unreachable,
|
||||
1...64 => switch (int_info.signedness) {
|
||||
.signed => .gt,
|
||||
.unsigned => .hi,
|
||||
},
|
||||
65...128 => {
|
||||
std.mem.swap(Value.Index, &lhs_vi, &rhs_vi);
|
||||
continue :cond .lt;
|
||||
},
|
||||
},
|
||||
.neq => .ne,
|
||||
})));
|
||||
const cset_label = isel.instructions.items.len;
|
||||
|
||||
var part_offset = lhs_vi.size(isel);
|
||||
while (part_offset > 0) {
|
||||
const part_size = @min(part_offset, 8);
|
||||
part_offset -= part_size;
|
||||
var lhs_part_it = lhs_vi.field(ty, part_offset, part_size);
|
||||
const lhs_part_vi = try lhs_part_it.only(isel);
|
||||
const lhs_part_mat = try lhs_part_vi.?.matReg(isel);
|
||||
var rhs_part_it = rhs_vi.field(ty, part_offset, part_size);
|
||||
const rhs_part_vi = try rhs_part_it.only(isel);
|
||||
const rhs_part_mat = try rhs_part_vi.?.matReg(isel);
|
||||
try isel.emit(switch (part_size) {
|
||||
else => unreachable,
|
||||
1...4 => switch (part_offset) {
|
||||
0 => .subs(.wzr, lhs_part_mat.ra.w(), .{ .register = rhs_part_mat.ra.w() }),
|
||||
else => switch (op) {
|
||||
.lt, .lte, .gte, .gt => .sbcs(
|
||||
.wzr,
|
||||
lhs_part_mat.ra.w(),
|
||||
rhs_part_mat.ra.w(),
|
||||
),
|
||||
.eq, .neq => .ccmp(
|
||||
lhs_part_mat.ra.w(),
|
||||
.{ .register = rhs_part_mat.ra.w() },
|
||||
.{ .n = false, .z = false, .c = false, .v = false },
|
||||
.eq,
|
||||
),
|
||||
},
|
||||
},
|
||||
5...8 => switch (part_offset) {
|
||||
0 => .subs(.xzr, lhs_part_mat.ra.x(), .{ .register = rhs_part_mat.ra.x() }),
|
||||
else => switch (op) {
|
||||
.lt, .lte, .gte, .gt => .sbcs(
|
||||
.xzr,
|
||||
lhs_part_mat.ra.x(),
|
||||
rhs_part_mat.ra.x(),
|
||||
),
|
||||
.eq, .neq => .ccmp(
|
||||
lhs_part_mat.ra.x(),
|
||||
.{ .register = rhs_part_mat.ra.x() },
|
||||
.{ .n = false, .z = false, .c = false, .v = false },
|
||||
.eq,
|
||||
),
|
||||
},
|
||||
},
|
||||
});
|
||||
try rhs_part_mat.finish(isel);
|
||||
try lhs_part_mat.finish(isel);
|
||||
}
|
||||
return .{ .cset_label = cset_label };
|
||||
}
|
||||
switch (ty.floatBits(isel.target)) {
|
||||
else => unreachable,
|
||||
16, 32, 64 => |bits| {
|
||||
const need_fcvt = switch (bits) {
|
||||
else => unreachable,
|
||||
16 => !isel.target.cpu.has(.aarch64, .fullfp16),
|
||||
32, 64 => false,
|
||||
};
|
||||
try isel.emit(.csinc(res_ra.w(), .wzr, .wzr, .invert(switch (op) {
|
||||
.lt => .lo,
|
||||
.lte => .ls,
|
||||
.eq => .eq,
|
||||
.gte => .ge,
|
||||
.gt => .gt,
|
||||
.neq => .ne,
|
||||
})));
|
||||
const cset_label = isel.instructions.items.len;
|
||||
|
||||
const lhs_mat = try lhs_vi.matReg(isel);
|
||||
const rhs_mat = try rhs_vi.matReg(isel);
|
||||
const lhs_ra = if (need_fcvt) try isel.allocVecReg() else lhs_mat.ra;
|
||||
defer if (need_fcvt) isel.freeReg(lhs_ra);
|
||||
const rhs_ra = if (need_fcvt) try isel.allocVecReg() else rhs_mat.ra;
|
||||
defer if (need_fcvt) isel.freeReg(rhs_ra);
|
||||
try isel.emit(bits: switch (bits) {
|
||||
else => unreachable,
|
||||
16 => if (need_fcvt)
|
||||
continue :bits 32
|
||||
else
|
||||
.fcmp(lhs_ra.h(), .{ .register = rhs_ra.h() }),
|
||||
32 => .fcmp(lhs_ra.s(), .{ .register = rhs_ra.s() }),
|
||||
64 => .fcmp(lhs_ra.d(), .{ .register = rhs_ra.d() }),
|
||||
});
|
||||
if (need_fcvt) {
|
||||
try isel.emit(.fcvt(rhs_ra.s(), rhs_mat.ra.h()));
|
||||
try isel.emit(.fcvt(lhs_ra.s(), lhs_mat.ra.h()));
|
||||
}
|
||||
try rhs_mat.finish(isel);
|
||||
try lhs_mat.finish(isel);
|
||||
return .{ .cset_label = cset_label };
|
||||
},
|
||||
80, 128 => |bits| {
|
||||
try call.prepareReturn(isel);
|
||||
try call.returnFill(isel, .r0);
|
||||
try isel.emit(.csinc(res_ra.w(), .wzr, .wzr, .invert(cond: switch (op) {
|
||||
.lt => .lt,
|
||||
.lte => .le,
|
||||
.eq => .eq,
|
||||
.gte => {
|
||||
std.mem.swap(Value.Index, &lhs_vi, &rhs_vi);
|
||||
continue :cond .lte;
|
||||
},
|
||||
.gt => {
|
||||
std.mem.swap(Value.Index, &lhs_vi, &rhs_vi);
|
||||
continue :cond .lt;
|
||||
},
|
||||
.neq => .ne,
|
||||
})));
|
||||
const cset_label = isel.instructions.items.len;
|
||||
try isel.emit(.subs(.wzr, .w0, .{ .immediate = 0 }));
|
||||
try call.finishReturn(isel);
|
||||
|
||||
try call.prepareCallee(isel);
|
||||
try isel.global_relocs.append(isel.pt.zcu.gpa, .{
|
||||
.name = switch (bits) {
|
||||
else => unreachable,
|
||||
16 => "__cmphf2",
|
||||
32 => "__cmpsf2",
|
||||
64 => "__cmpdf2",
|
||||
80 => "__cmpxf2",
|
||||
128 => "__cmptf2",
|
||||
},
|
||||
.reloc = .{ .label = @intCast(isel.instructions.items.len) },
|
||||
});
|
||||
try isel.emit(.bl(0));
|
||||
try call.finishCallee(isel);
|
||||
|
||||
try call.prepareParams(isel);
|
||||
switch (bits) {
|
||||
else => unreachable,
|
||||
16, 32, 64, 128 => {
|
||||
try call.paramLiveOut(isel, rhs_vi, .v1);
|
||||
try call.paramLiveOut(isel, lhs_vi, .v0);
|
||||
},
|
||||
80 => {
|
||||
var rhs_hi16_it = rhs_vi.field(ty, 8, 8);
|
||||
const rhs_hi16_vi = try rhs_hi16_it.only(isel);
|
||||
try call.paramLiveOut(isel, rhs_hi16_vi.?, .r3);
|
||||
var rhs_lo64_it = rhs_vi.field(ty, 0, 8);
|
||||
const rhs_lo64_vi = try rhs_lo64_it.only(isel);
|
||||
try call.paramLiveOut(isel, rhs_lo64_vi.?, .r2);
|
||||
var lhs_hi16_it = lhs_vi.field(ty, 8, 8);
|
||||
const lhs_hi16_vi = try lhs_hi16_it.only(isel);
|
||||
try call.paramLiveOut(isel, lhs_hi16_vi.?, .r1);
|
||||
var lhs_lo64_it = lhs_vi.field(ty, 0, 8);
|
||||
const lhs_lo64_vi = try lhs_lo64_it.only(isel);
|
||||
try call.paramLiveOut(isel, lhs_lo64_vi.?, .r0);
|
||||
},
|
||||
}
|
||||
try call.finishParams(isel);
|
||||
return .{ .cset_label = cset_label };
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn loadReg(
|
||||
isel: *Select,
|
||||
ra: Register.Alias,
|
||||
@ -9272,9 +9331,9 @@ pub const Value = struct {
|
||||
opts: AddOrSubtractOptions,
|
||||
) !void {
|
||||
const zcu = isel.pt.zcu;
|
||||
if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(op), isel.fmtType(ty) });
|
||||
if (!ty.isAbiInt(zcu)) return isel.fail("bad {t} {f}", .{ op, isel.fmtType(ty) });
|
||||
const int_info = ty.intInfo(zcu);
|
||||
if (int_info.bits > 128) return isel.fail("too big {s} {f}", .{ @tagName(op), isel.fmtType(ty) });
|
||||
if (int_info.bits > 128) return isel.fail("too big {t} {f}", .{ op, isel.fmtType(ty) });
|
||||
var part_offset = res_vi.size(isel);
|
||||
var need_wrap = switch (opts.overflow) {
|
||||
.@"unreachable" => false,
|
||||
@ -10783,7 +10842,7 @@ pub const Value = struct {
|
||||
.err_name => continue :constant_key .{ .undef = error_union_type.payload_type },
|
||||
.payload => |payload| {
|
||||
constant = payload;
|
||||
constant_key = ip.indexToKey(payload);
|
||||
constant_key = ip.indexToKey(constant);
|
||||
continue :constant_key constant_key;
|
||||
},
|
||||
}
|
||||
@ -10915,7 +10974,10 @@ pub const Value = struct {
|
||||
.addend = ptr.byte_offset,
|
||||
},
|
||||
});
|
||||
try isel.emit(.add(mat.ra.x(), mat.ra.x(), .{ .immediate = 0 }));
|
||||
if (ip.getNav(nav).getExtern(ip)) |_|
|
||||
try isel.emit(.ldr(mat.ra.x(), .{ .unsigned_offset = .{ .base = mat.ra.x(), .offset = 0 } }))
|
||||
else
|
||||
try isel.emit(.add(mat.ra.x(), mat.ra.x(), .{ .immediate = 0 }));
|
||||
try isel.nav_relocs.append(zcu.gpa, .{
|
||||
.nav = nav,
|
||||
.reloc = .{
|
||||
@ -11017,7 +11079,7 @@ pub const Value = struct {
|
||||
} } else .{ .undef = child_ty },
|
||||
else => |child| {
|
||||
constant = child;
|
||||
constant_key = ip.indexToKey(child);
|
||||
constant_key = ip.indexToKey(constant);
|
||||
continue :constant_key constant_key;
|
||||
},
|
||||
};
|
||||
@ -11040,7 +11102,7 @@ pub const Value = struct {
|
||||
},
|
||||
.repeated_elem => |repeated_elem| {
|
||||
constant = repeated_elem;
|
||||
constant_key = ip.indexToKey(repeated_elem);
|
||||
constant_key = ip.indexToKey(constant);
|
||||
continue :constant_key constant_key;
|
||||
},
|
||||
};
|
||||
@ -11099,6 +11161,28 @@ pub const Value = struct {
|
||||
}
|
||||
},
|
||||
},
|
||||
.un => |un| {
|
||||
const loaded_union = ip.loadUnionType(un.ty);
|
||||
const union_layout = ZigType.getUnionLayout(loaded_union, zcu);
|
||||
if (loaded_union.hasTag(ip)) {
|
||||
const tag_offset = union_layout.tagOffset();
|
||||
if (offset >= tag_offset and offset + size <= tag_offset + union_layout.tag_size) {
|
||||
offset -= tag_offset;
|
||||
continue :constant_key switch (ip.indexToKey(un.tag)) {
|
||||
else => unreachable,
|
||||
.int => |int| .{ .int = int },
|
||||
.enum_tag => |enum_tag| .{ .enum_tag = enum_tag },
|
||||
};
|
||||
}
|
||||
}
|
||||
const payload_offset = union_layout.payloadOffset();
|
||||
if (offset >= payload_offset and offset + size <= payload_offset + union_layout.payload_size) {
|
||||
offset -= payload_offset;
|
||||
constant = un.val;
|
||||
constant_key = ip.indexToKey(constant);
|
||||
continue :constant_key constant_key;
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
var buffer: [16]u8 = @splat(0);
|
||||
@ -11188,7 +11272,7 @@ fn initValueAdvanced(
|
||||
}
|
||||
pub fn dumpValues(isel: *Select, which: enum { only_referenced, all }) void {
|
||||
errdefer |err| @panic(@errorName(err));
|
||||
const stderr = std.debug.lockStderrWriter(&.{});
|
||||
const stderr, _ = std.debug.lockStderrWriter(&.{});
|
||||
defer std.debug.unlockStderrWriter();
|
||||
|
||||
const zcu = isel.pt.zcu;
|
||||
@ -11259,7 +11343,7 @@ pub fn dumpValues(isel: *Select, which: enum { only_referenced, all }) void {
|
||||
first = false;
|
||||
};
|
||||
if (reverse_live_registers.get(vi)) |ra| {
|
||||
try stderr.print("{s}{s}", .{ if (first) " <- " else ", ", @tagName(ra) });
|
||||
try stderr.print("{s}{t}", .{ if (first) " <- " else ", ", ra });
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
@ -11267,8 +11351,8 @@ pub fn dumpValues(isel: *Select, which: enum { only_referenced, all }) void {
|
||||
switch (value.flags.parent_tag) {
|
||||
.unallocated => if (value.offset_from_parent != 0) try stderr.print(" +0x{x}", .{value.offset_from_parent}),
|
||||
.stack_slot => {
|
||||
try stderr.print(" [{s}, #{s}0x{x}", .{
|
||||
@tagName(value.parent_payload.stack_slot.base),
|
||||
try stderr.print(" [{t}, #{s}0x{x}", .{
|
||||
value.parent_payload.stack_slot.base,
|
||||
if (value.parent_payload.stack_slot.offset < 0) "-" else "",
|
||||
@abs(value.parent_payload.stack_slot.offset),
|
||||
});
|
||||
@ -11282,7 +11366,7 @@ pub fn dumpValues(isel: *Select, which: enum { only_referenced, all }) void {
|
||||
isel.fmtConstant(value.parent_payload.constant),
|
||||
}),
|
||||
}
|
||||
try stderr.print(" align({s})", .{@tagName(value.flags.alignment)});
|
||||
try stderr.print(" align({t})", .{value.flags.alignment});
|
||||
switch (value.flags.location_tag) {
|
||||
.large => try stderr.print(" size=0x{x} large", .{value.location_payload.large.size}),
|
||||
.small => {
|
||||
@ -11292,8 +11376,8 @@ pub fn dumpValues(isel: *Select, which: enum { only_referenced, all }) void {
|
||||
.unsigned => {},
|
||||
.signed => try stderr.writeAll(" signed"),
|
||||
}
|
||||
if (loc.hint != .zr) try stderr.print(" hint={s}", .{@tagName(loc.hint)});
|
||||
if (loc.register != .zr) try stderr.print(" loc={s}", .{@tagName(loc.register)});
|
||||
if (loc.hint != .zr) try stderr.print(" hint={t}", .{loc.hint});
|
||||
if (loc.register != .zr) try stderr.print(" loc={t}", .{loc.register});
|
||||
},
|
||||
}
|
||||
try stderr.print(" refs={d}\n", .{value.refs});
|
||||
|
||||
@ -95,7 +95,7 @@ fn dumpCrashContext() Io.Writer.Error!void {
|
||||
|
||||
// TODO: this does mean that a different thread could grab the stderr mutex between the context
|
||||
// and the actual panic printing, which would be quite confusing.
|
||||
const stderr = std.debug.lockStderrWriter(&.{});
|
||||
const stderr, _ = std.debug.lockStderrWriter(&.{});
|
||||
defer std.debug.unlockStderrWriter();
|
||||
|
||||
try stderr.writeAll("Compiler crash context:\n");
|
||||
|
||||
@ -124,7 +124,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) !
|
||||
try wip_errors.addZirErrorMessages(zir, tree, source_code, "<stdin>");
|
||||
var error_bundle = try wip_errors.toOwnedBundle("");
|
||||
defer error_bundle.deinit(gpa);
|
||||
error_bundle.renderToStdErr(color.renderOptions());
|
||||
error_bundle.renderToStdErr(.{}, color);
|
||||
process.exit(2);
|
||||
}
|
||||
} else {
|
||||
@ -138,7 +138,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) !
|
||||
try wip_errors.addZoirErrorMessages(zoir, tree, source_code, "<stdin>");
|
||||
var error_bundle = try wip_errors.toOwnedBundle("");
|
||||
defer error_bundle.deinit(gpa);
|
||||
error_bundle.renderToStdErr(color.renderOptions());
|
||||
error_bundle.renderToStdErr(.{}, color);
|
||||
process.exit(2);
|
||||
}
|
||||
}
|
||||
@ -317,7 +317,7 @@ fn fmtPathFile(
|
||||
try wip_errors.addZirErrorMessages(zir, tree, source_code, file_path);
|
||||
var error_bundle = try wip_errors.toOwnedBundle("");
|
||||
defer error_bundle.deinit(gpa);
|
||||
error_bundle.renderToStdErr(fmt.color.renderOptions());
|
||||
error_bundle.renderToStdErr(.{}, fmt.color);
|
||||
fmt.any_error = true;
|
||||
}
|
||||
},
|
||||
@ -332,7 +332,7 @@ fn fmtPathFile(
|
||||
try wip_errors.addZoirErrorMessages(zoir, tree, source_code, file_path);
|
||||
var error_bundle = try wip_errors.toOwnedBundle("");
|
||||
defer error_bundle.deinit(gpa);
|
||||
error_bundle.renderToStdErr(fmt.color.renderOptions());
|
||||
error_bundle.renderToStdErr(.{}, fmt.color);
|
||||
fmt.any_error = true;
|
||||
}
|
||||
},
|
||||
|
||||
@ -312,7 +312,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;
|
||||
@ -332,11 +332,11 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
|
||||
|
||||
if (aro_comp.diagnostics.output.to_list.messages.items.len != 0) {
|
||||
var buffer: [64]u8 = undefined;
|
||||
const w = std.debug.lockStderrWriter(&buffer);
|
||||
const w, const ttyconf = std.debug.lockStderrWriter(&buffer);
|
||||
defer std.debug.unlockStderrWriter();
|
||||
for (aro_comp.diagnostics.output.to_list.messages.items) |msg| {
|
||||
if (msg.kind == .@"fatal error" or msg.kind == .@"error") {
|
||||
msg.write(w, .detect(std.fs.File.stderr()), true) catch {};
|
||||
msg.write(w, ttyconf, true) catch {};
|
||||
return error.AroPreprocessorFailed;
|
||||
}
|
||||
}
|
||||
@ -356,7 +356,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
|
||||
error.OutOfMemory => |e| return e,
|
||||
error.ParseError => {
|
||||
var buffer: [64]u8 = undefined;
|
||||
const w = std.debug.lockStderrWriter(&buffer);
|
||||
const w, _ = std.debug.lockStderrWriter(&buffer);
|
||||
defer std.debug.unlockStderrWriter();
|
||||
try w.writeAll("error: ");
|
||||
try def_diagnostics.writeMsg(w, input);
|
||||
|
||||
@ -1028,7 +1028,7 @@ fn testParse(machine_type: std.coff.IMAGE.FILE.MACHINE, source: [:0]const u8, ex
|
||||
const module = parse(std.testing.allocator, source, machine_type, .mingw, &diagnostics) catch |err| switch (err) {
|
||||
error.OutOfMemory => |e| return e,
|
||||
error.ParseError => {
|
||||
const stderr = std.debug.lockStderrWriter(&.{});
|
||||
const stderr, _ = std.debug.lockStderrWriter(&.{});
|
||||
defer std.debug.unlockStderrWriter();
|
||||
try diagnostics.writeMsg(stderr, source);
|
||||
try stderr.writeByte('\n');
|
||||
|
||||
@ -2215,7 +2215,7 @@ fn resolvePathInputLib(
|
||||
var error_bundle = try wip_errors.toOwnedBundle("");
|
||||
defer error_bundle.deinit(gpa);
|
||||
|
||||
error_bundle.renderToStdErr(color.renderOptions());
|
||||
error_bundle.renderToStdErr(.{}, color);
|
||||
|
||||
std.process.exit(1);
|
||||
}
|
||||
|
||||
@ -2335,7 +2335,7 @@ pub fn deleteExport(coff: *Coff, exported: Zcu.Exported, name: InternPool.NullTe
|
||||
}
|
||||
|
||||
pub fn dump(coff: *Coff, tid: Zcu.PerThread.Id) void {
|
||||
const w = std.debug.lockStderrWriter(&.{});
|
||||
const w, _ = std.debug.lockStderrWriter(&.{});
|
||||
defer std.debug.unlockStderrWriter();
|
||||
coff.printNode(tid, w, .root, 0) catch {};
|
||||
}
|
||||
|
||||
@ -1965,7 +1965,7 @@ pub fn deleteExport(elf: *Elf, exported: Zcu.Exported, name: InternPool.NullTerm
|
||||
}
|
||||
|
||||
pub fn dump(elf: *Elf, tid: Zcu.PerThread.Id) void {
|
||||
const w = std.debug.lockStderrWriter(&.{});
|
||||
const w, _ = std.debug.lockStderrWriter(&.{});
|
||||
defer std.debug.unlockStderrWriter();
|
||||
elf.printNode(tid, w, .root, 0) catch {};
|
||||
}
|
||||
|
||||
18
src/main.zig
18
src/main.zig
@ -4520,7 +4520,7 @@ fn updateModule(comp: *Compilation, color: Color, prog_node: std.Progress.Node)
|
||||
defer errors.deinit(comp.gpa);
|
||||
|
||||
if (errors.errorMessageCount() > 0) {
|
||||
errors.renderToStdErr(color.renderOptions());
|
||||
errors.renderToStdErr(.{}, color);
|
||||
return error.CompileErrorsReported;
|
||||
}
|
||||
}
|
||||
@ -4573,7 +4573,7 @@ fn cmdTranslateC(
|
||||
return;
|
||||
} else {
|
||||
const color: Color = .auto;
|
||||
result.errors.renderToStdErr(color.renderOptions());
|
||||
result.errors.renderToStdErr(.{}, color);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
@ -5199,7 +5199,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8)
|
||||
|
||||
if (fetch.error_bundle.root_list.items.len > 0) {
|
||||
var errors = try fetch.error_bundle.toOwnedBundle("");
|
||||
errors.renderToStdErr(color.renderOptions());
|
||||
errors.renderToStdErr(.{}, color);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
@ -6135,7 +6135,7 @@ fn cmdAstCheck(arena: Allocator, io: Io, args: []const []const u8) !void {
|
||||
try wip_errors.init(arena);
|
||||
try wip_errors.addZirErrorMessages(zir, tree, source, display_path);
|
||||
var error_bundle = try wip_errors.toOwnedBundle("");
|
||||
error_bundle.renderToStdErr(color.renderOptions());
|
||||
error_bundle.renderToStdErr(.{}, color);
|
||||
if (zir.loweringFailed()) {
|
||||
process.exit(1);
|
||||
}
|
||||
@ -6206,7 +6206,7 @@ fn cmdAstCheck(arena: Allocator, io: Io, args: []const []const u8) !void {
|
||||
try wip_errors.init(arena);
|
||||
try wip_errors.addZoirErrorMessages(zoir, tree, source, display_path);
|
||||
var error_bundle = try wip_errors.toOwnedBundle("");
|
||||
error_bundle.renderToStdErr(color.renderOptions());
|
||||
error_bundle.renderToStdErr(.{}, color);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
@ -6479,7 +6479,7 @@ fn cmdChangelist(arena: Allocator, io: Io, args: []const []const u8) !void {
|
||||
try wip_errors.init(arena);
|
||||
try wip_errors.addZirErrorMessages(old_zir, old_tree, old_source, old_source_path);
|
||||
var error_bundle = try wip_errors.toOwnedBundle("");
|
||||
error_bundle.renderToStdErr(color.renderOptions());
|
||||
error_bundle.renderToStdErr(.{}, color);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
@ -6491,7 +6491,7 @@ fn cmdChangelist(arena: Allocator, io: Io, args: []const []const u8) !void {
|
||||
try wip_errors.init(arena);
|
||||
try wip_errors.addZirErrorMessages(new_zir, new_tree, new_source, new_source_path);
|
||||
var error_bundle = try wip_errors.toOwnedBundle("");
|
||||
error_bundle.renderToStdErr(color.renderOptions());
|
||||
error_bundle.renderToStdErr(.{}, color);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
@ -6948,7 +6948,7 @@ fn cmdFetch(
|
||||
|
||||
if (fetch.error_bundle.root_list.items.len > 0) {
|
||||
var errors = try fetch.error_bundle.toOwnedBundle("");
|
||||
errors.renderToStdErr(color.renderOptions());
|
||||
errors.renderToStdErr(.{}, color);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
@ -7304,7 +7304,7 @@ fn loadManifest(
|
||||
|
||||
var error_bundle = try wip_errors.toOwnedBundle("");
|
||||
defer error_bundle.deinit(gpa);
|
||||
error_bundle.renderToStdErr(options.color.renderOptions());
|
||||
error_bundle.renderToStdErr(.{}, options.color);
|
||||
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
@ -899,7 +899,6 @@ test "enum value allocation" {
|
||||
}
|
||||
|
||||
test "enum literal casting to tagged union" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
@ -935,7 +934,6 @@ test "enum literal casting to error union with payload enum" {
|
||||
}
|
||||
|
||||
test "constant enum initialization with differing sizes" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
||||
|
||||
@ -149,7 +149,6 @@ test "nested optional field in struct" {
|
||||
}
|
||||
|
||||
test "equality compare optionals and non-optionals" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
||||
@ -209,7 +208,6 @@ test "equality compare optionals and non-optionals" {
|
||||
}
|
||||
|
||||
test "compare optionals with modified payloads" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
||||
|
||||
var lhs: ?bool = false;
|
||||
|
||||
@ -576,7 +576,6 @@ test "switch with null and T peer types and inferred result location type" {
|
||||
}
|
||||
|
||||
test "switch prongs with cases with identical payload types" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
@ -824,7 +823,6 @@ test "comptime inline switch" {
|
||||
}
|
||||
|
||||
test "switch capture peer type resolution" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
|
||||
|
||||
const U = union(enum) {
|
||||
|
||||
@ -496,7 +496,6 @@ test "anon tuple field referencing comptime var isn't comptime" {
|
||||
}
|
||||
|
||||
test "tuple with runtime value coerced into a slice with a sentinel" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
||||
|
||||
@ -208,7 +208,6 @@ const Payload = union(Letter) {
|
||||
};
|
||||
|
||||
test "union with specified enum tag" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
||||
@ -219,7 +218,6 @@ test "union with specified enum tag" {
|
||||
}
|
||||
|
||||
test "packed union generates correctly aligned type" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
|
||||
@ -605,7 +603,6 @@ fn returnAnInt(x: i32) TaggedFoo {
|
||||
}
|
||||
|
||||
test "tagged union with all void fields but a meaningful tag" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
@ -1032,7 +1029,6 @@ test "containers with single-field enums" {
|
||||
}
|
||||
|
||||
test "@unionInit on union with tag but no fields" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
@ -1446,8 +1442,6 @@ test "access the tag of a global tagged union" {
|
||||
}
|
||||
|
||||
test "coerce enum literal to union in result loc" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
|
||||
const U = union(enum) {
|
||||
a,
|
||||
b: u8,
|
||||
|
||||
@ -89,10 +89,9 @@ pub fn main() !void {
|
||||
const output = allocating.written()[0 .. allocating.written().len - 1 :0];
|
||||
|
||||
var tree = try std.zig.Ast.parse(allocator, output, .zig);
|
||||
var color: std.zig.Color = .on;
|
||||
|
||||
if (tree.errors.len != 0) {
|
||||
try std.zig.printAstErrorsToStderr(allocator, tree, "", color);
|
||||
try std.zig.printAstErrorsToStderr(allocator, tree, "", .auto);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -104,7 +103,7 @@ pub fn main() !void {
|
||||
try wip_errors.addZirErrorMessages(zir, tree, output, "");
|
||||
var error_bundle = try wip_errors.toOwnedBundle("");
|
||||
defer error_bundle.deinit(allocator);
|
||||
error_bundle.renderToStdErr(color.renderOptions());
|
||||
error_bundle.renderToStdErr(.{}, .auto);
|
||||
}
|
||||
|
||||
const formatted_output = try tree.renderAlloc(allocator);
|
||||
@ -931,7 +930,7 @@ fn parseHexInt(text: []const u8) !u31 {
|
||||
}
|
||||
|
||||
fn usageAndExit(arg0: []const u8, code: u8) noreturn {
|
||||
const stderr = std.debug.lockStderrWriter(&.{});
|
||||
const stderr, _ = std.debug.lockStderrWriter(&.{});
|
||||
stderr.print(
|
||||
\\Usage: {s} <SPIRV-Headers repository path> <path/to/zig/src/codegen/spirv/extinst.zig.grammar.json>
|
||||
\\
|
||||
|
||||
@ -177,7 +177,9 @@ pub fn main() !void {
|
||||
|
||||
const args = try std.process.argsAlloc(gpa);
|
||||
if (args.len < 2 or mem.eql(u8, args[1], "--help")) {
|
||||
usage(std.debug.lockStderrWriter(&.{}), args[0]) catch std.process.exit(2);
|
||||
const w, _ = std.debug.lockStderrWriter(&.{});
|
||||
defer std.debug.unlockStderrWriter();
|
||||
usage(w, args[0]) catch std.process.exit(2);
|
||||
std.process.exit(1);
|
||||
}
|
||||
const linux_path = args[1];
|
||||
|
||||
@ -340,8 +340,7 @@ const Eval = struct {
|
||||
.unknown => return,
|
||||
.compile_errors => |ce| ce,
|
||||
.stdout, .exit_code => {
|
||||
const color: std.zig.Color = .auto;
|
||||
error_bundle.renderToStdErr(color.renderOptions());
|
||||
error_bundle.renderToStdErr(.{}, .auto);
|
||||
eval.fatal("update '{s}': unexpected compile errors", .{update.name});
|
||||
},
|
||||
};
|
||||
@ -350,8 +349,7 @@ const Eval = struct {
|
||||
|
||||
for (error_bundle.getMessages()) |err_idx| {
|
||||
if (expected_idx == expected.errors.len) {
|
||||
const color: std.zig.Color = .auto;
|
||||
error_bundle.renderToStdErr(color.renderOptions());
|
||||
error_bundle.renderToStdErr(.{}, .auto);
|
||||
eval.fatal("update '{s}': more errors than expected", .{update.name});
|
||||
}
|
||||
try eval.checkOneError(update, error_bundle, expected.errors[expected_idx], false, err_idx);
|
||||
@ -359,8 +357,7 @@ const Eval = struct {
|
||||
|
||||
for (error_bundle.getNotes(err_idx)) |note_idx| {
|
||||
if (expected_idx == expected.errors.len) {
|
||||
const color: std.zig.Color = .auto;
|
||||
error_bundle.renderToStdErr(color.renderOptions());
|
||||
error_bundle.renderToStdErr(.{}, .auto);
|
||||
eval.fatal("update '{s}': more error notes than expected", .{update.name});
|
||||
}
|
||||
try eval.checkOneError(update, error_bundle, expected.errors[expected_idx], true, note_idx);
|
||||
@ -369,8 +366,7 @@ const Eval = struct {
|
||||
}
|
||||
|
||||
if (!std.mem.eql(u8, error_bundle.getCompileLogOutput(), expected.compile_log_output)) {
|
||||
const color: std.zig.Color = .auto;
|
||||
error_bundle.renderToStdErr(color.renderOptions());
|
||||
error_bundle.renderToStdErr(.{}, .auto);
|
||||
eval.fatal("update '{s}': unexpected compile log output", .{update.name});
|
||||
}
|
||||
}
|
||||
@ -404,8 +400,7 @@ const Eval = struct {
|
||||
expected.column != src.column + 1 or
|
||||
!std.mem.eql(u8, expected.msg, msg))
|
||||
{
|
||||
const color: std.zig.Color = .auto;
|
||||
eb.renderToStdErr(color.renderOptions());
|
||||
eb.renderToStdErr(.{}, .auto);
|
||||
eval.fatal("update '{s}': compile error did not match expected error", .{update.name});
|
||||
}
|
||||
}
|
||||
|
||||
@ -961,7 +961,9 @@ fn objectLessThan(context: void, a: *json.ObjectMap, b: *json.ObjectMap) bool {
|
||||
}
|
||||
|
||||
fn printUsageAndExit(arg0: []const u8) noreturn {
|
||||
printUsage(std.debug.lockStderrWriter(&.{}), arg0) catch std.process.exit(2);
|
||||
const w, _ = std.debug.lockStderrWriter(&.{});
|
||||
defer std.debug.unlockStderrWriter();
|
||||
printUsage(w, arg0) catch std.process.exit(2);
|
||||
std.process.exit(1);
|
||||
}
|
||||
|
||||
|
||||
@ -2167,7 +2167,7 @@ fn processOneTarget(job: Job) void {
|
||||
}
|
||||
|
||||
fn usageAndExit(arg0: []const u8, code: u8) noreturn {
|
||||
const stderr = std.debug.lockStderrWriter(&.{});
|
||||
const stderr, _ = std.debug.lockStderrWriter(&.{});
|
||||
stderr.print(
|
||||
\\Usage: {s} /path/to/llvm-tblgen /path/git/llvm-project /path/git/zig [zig_name filter]
|
||||
\\
|
||||
|
||||
@ -190,7 +190,9 @@ pub fn main() anyerror!void {
|
||||
}
|
||||
|
||||
fn printUsageAndExit(arg0: []const u8) noreturn {
|
||||
printUsage(std.debug.lockStderrWriter(&.{}), arg0) catch std.process.exit(2);
|
||||
const w, _ = std.debug.lockStderrWriter(&.{});
|
||||
defer std.debug.unlockStderrWriter();
|
||||
printUsage(w, arg0) catch std.process.exit(2);
|
||||
std.process.exit(1);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user