Update Zig to use the new Writergate version (#1664)

For reference: https://github.com/ziglang/zig/pull/24329

some commits have been extracted from #1583, but the x86_64 backend has
been disabled due to its horrible performance.

Remaining work:
- [x] Wait for official builds on ziglang.org and upload them to our
repository
- [x] Add workaround for https://github.com/ziglang/zig/pull/24466
- [x] Fix TODO comment about ANSI support in stdout
- [x] Check for compile-time performance changes → it went from 13.1 to
11.9 seconds 🎉
This commit is contained in:
IntegratedQuantum 2025-07-15 23:00:29 +02:00 committed by GitHub
parent 6811f21682
commit aae66ea77f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
29 changed files with 135 additions and 120 deletions

View File

@ -14,11 +14,12 @@ jobs:
name: Compilation Check name: Compilation Check
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: mlugg/setup-zig@v1 - uses: mlugg/setup-zig@v2
with: with:
version: 0.14.0 version: 0.15.0-dev.1034+bd97b6618
- run: sudo apt install libgl-dev libasound2-dev libx11-dev glslang-tools - run: sudo apt install libgl-dev libasound2-dev libx11-dev glslang-tools
- run: wget -O /opt/hostedtoolcache/zig/0.14.0/x64/lib/std/zig/render.zig https://github.com/PixelGuys/Cubyz-std-lib/releases/download/0.14.0/render.zig - run: echo "zigPath=$(command -v zig | sed 's/.\{3\}$//')" >> $GITHUB_ENV
- run: wget -O $zigPath/lib/std/zig/render.zig https://github.com/PixelGuys/Cubyz-std-lib/releases/download/0.15.0-dev.1034+bd97b6618/render.zig
- run: zig build - run: zig build
- run: zig build -Dtarget=x86_64-windows-gnu - run: zig build -Dtarget=x86_64-windows-gnu
- run: zig build test - run: zig build test

View File

@ -1 +1 @@
0.14.0 0.15.0-dev.1034+bd97b6618

View File

@ -52,6 +52,7 @@ fn linkLibraries(b: *std.Build, exe: *std.Build.Step.Compile, useLocalDeps: bool
exe.addObjectFile(subPath.path(b, libName(b, "SPIRV-Tools-opt", t))); exe.addObjectFile(subPath.path(b, libName(b, "SPIRV-Tools-opt", t)));
if(t.os.tag == .windows) { if(t.os.tag == .windows) {
exe.linkSystemLibrary("crypt32");
exe.linkSystemLibrary("gdi32"); exe.linkSystemLibrary("gdi32");
exe.linkSystemLibrary("opengl32"); exe.linkSystemLibrary("opengl32");
exe.linkSystemLibrary("ws2_32"); exe.linkSystemLibrary("ws2_32");
@ -168,15 +169,19 @@ pub fn build(b: *std.Build) !void {
.install_dir = .{.custom = ".."}, .install_dir = .{.custom = ".."},
}); });
const exe = b.addExecutable(.{ const mainModule = b.addModule("main", .{
.name = "Cubyzig",
.root_source_file = b.path("src/main.zig"), .root_source_file = b.path("src/main.zig"),
.target = target, .target = target,
.optimize = optimize, .optimize = optimize,
//.sanitize_thread = true,
//.use_llvm = false,
}); });
exe.root_module.addImport("main", exe.root_module);
const exe = b.addExecutable(.{
.name = "Cubyzig",
.root_module = mainModule,
//.sanitize_thread = true,
.use_llvm = true,
});
exe.root_module.addImport("main", mainModule);
try addModFeatures(b, exe); try addModFeatures(b, exe);
linkLibraries(b, exe, useLocalDeps); linkLibraries(b, exe, useLocalDeps);
@ -193,13 +198,11 @@ pub fn build(b: *std.Build) !void {
run_step.dependOn(&run_cmd.step); run_step.dependOn(&run_cmd.step);
const exe_tests = b.addTest(.{ const exe_tests = b.addTest(.{
.root_source_file = b.path("src/main.zig"), .root_module = mainModule,
.test_runner = .{.path = b.path("test/runner.zig"), .mode = .simple}, .test_runner = .{.path = b.path("test/runner.zig"), .mode = .simple},
.target = target,
.optimize = optimize,
}); });
linkLibraries(b, exe_tests, useLocalDeps); linkLibraries(b, exe_tests, useLocalDeps);
exe_tests.root_module.addImport("main", exe_tests.root_module); exe_tests.root_module.addImport("main", mainModule);
try addModFeatures(b, exe_tests); try addModFeatures(b, exe_tests);
const run_exe_tests = b.addRunArtifact(exe_tests); const run_exe_tests = b.addRunArtifact(exe_tests);
@ -210,16 +213,14 @@ pub fn build(b: *std.Build) !void {
const formatter = b.addExecutable(.{ const formatter = b.addExecutable(.{
.name = "CubyzigFormatter", .name = "CubyzigFormatter",
.root_source_file = b.path("src/formatter/format.zig"), .root_module = b.addModule("format", .{
.target = target, .root_source_file = b.path("src/formatter/format.zig"),
.optimize = optimize, .target = target,
.optimize = optimize,
}),
}); });
// ZLS is stupid and cannot detect which executable is the main one, so we add the import everywhere... // ZLS is stupid and cannot detect which executable is the main one, so we add the import everywhere...
formatter.root_module.addAnonymousImport("main", .{ formatter.root_module.addImport("main", mainModule);
.target = target,
.optimize = optimize,
.root_source_file = b.path("src/main.zig"),
});
const formatter_install = b.addInstallArtifact(formatter, .{}); const formatter_install = b.addInstallArtifact(formatter, .{});
@ -234,16 +235,14 @@ pub fn build(b: *std.Build) !void {
const zig_fmt = b.addExecutable(.{ const zig_fmt = b.addExecutable(.{
.name = "zig_fmt", .name = "zig_fmt",
.root_source_file = b.path("src/formatter/fmt.zig"), .root_module = b.addModule("fmt", .{
.target = target, .root_source_file = b.path("src/formatter/fmt.zig"),
.optimize = optimize, .target = target,
.optimize = optimize,
}),
}); });
// ZLS is stupid and cannot detect which executable is the main one, so we add the import everywhere... // ZLS is stupid and cannot detect which executable is the main one, so we add the import everywhere...
zig_fmt.root_module.addAnonymousImport("main", .{ zig_fmt.root_module.addImport("main", mainModule);
.target = target,
.optimize = optimize,
.root_source_file = b.path("src/main.zig"),
});
const zig_fmt_install = b.addInstallArtifact(zig_fmt, .{}); const zig_fmt_install = b.addInstallArtifact(zig_fmt, .{});

View File

@ -33,7 +33,7 @@ then
esac esac
fi fi
VERSION=zig-$OS-$ARCH-$BASE_VERSION VERSION=zig-$ARCH-$OS-$BASE_VERSION
mkdir -p compiler/zig mkdir -p compiler/zig
touch compiler/version.txt touch compiler/version.txt

View File

@ -14,7 +14,7 @@ IF "%arch%"=="" (
set arch=x86_64 set arch=x86_64
) )
set version=zig-windows-%arch%-%baseVersion% set version=zig-%arch%-windows-%baseVersion%
if not exist compiler mkdir compiler if not exist compiler mkdir compiler
if not exist compiler\version.txt copy NUL compiler\version.txt >NUL if not exist compiler\version.txt copy NUL compiler\version.txt >NUL

View File

@ -309,7 +309,7 @@ pub const Sync = struct { // MARK: Sync
const typ = try reader.readEnum(Command.PayloadType); const typ = try reader.readEnum(Command.PayloadType);
@setEvalBranchQuota(100000); @setEvalBranchQuota(100000);
const payload: Command.Payload = switch(typ) { const payload: Command.Payload = switch(typ) {
inline else => |_typ| @unionInit(Command.Payload, @tagName(_typ), try std.meta.FieldType(Command.Payload, _typ).deserialize(reader, .server, source)), inline else => |_typ| @unionInit(Command.Payload, @tagName(_typ), try @FieldType(Command.Payload, @tagName(_typ)).deserialize(reader, .server, source)),
}; };
executeCommand(payload, source); executeCommand(payload, source);
} }
@ -2001,7 +2001,7 @@ pub fn save(self: Inventory, allocator: NeverFailingAllocator) ZonElement {
for(self._items, 0..) |stack, i| { for(self._items, 0..) |stack, i| {
if(!stack.empty()) { if(!stack.empty()) {
var buf: [1024]u8 = undefined; var buf: [1024]u8 = undefined;
zonObject.put(buf[0..std.fmt.formatIntBuf(&buf, i, 10, .lower, .{})], stack.store(allocator)); zonObject.put(buf[0..std.fmt.printInt(&buf, i, 10, .lower, .{})], stack.store(allocator));
} }
} }
return zonObject; return zonObject;
@ -2011,7 +2011,7 @@ pub fn loadFromZon(self: Inventory, zon: ZonElement) void {
for(self._items, 0..) |*stack, i| { for(self._items, 0..) |*stack, i| {
stack.clear(); stack.clear();
var buf: [1024]u8 = undefined; var buf: [1024]u8 = undefined;
const stackZon = zon.getChild(buf[0..std.fmt.formatIntBuf(&buf, i, 10, .lower, .{})]); const stackZon = zon.getChild(buf[0..std.fmt.printInt(&buf, i, 10, .lower, .{})]);
if(stackZon == .object) { if(stackZon == .object) {
stack.item = Item.init(stackZon) catch |err| { stack.item = Item.init(stackZon) catch |err| {
const msg = stackZon.toStringEfficient(main.stackAllocator, ""); const msg = stackZon.toStringEfficient(main.stackAllocator, "");

View File

@ -644,7 +644,7 @@ pub fn loadWorldAssets(assetFolder: []const u8, blockPalette: *Palette, itemPale
break :blk null; break :blk null;
}) |addon| { }) |addon| {
if(addon.kind == .directory) { if(addon.kind == .directory) {
const path = std.fmt.allocPrintZ(main.stackAllocator.allocator, "assets/{s}/blocks/textures", .{addon.name}) catch unreachable; const path = std.fmt.allocPrintSentinel(main.stackAllocator.allocator, "assets/{s}/blocks/textures", .{addon.name}, 0) catch unreachable;
defer main.stackAllocator.free(path); defer main.stackAllocator.free(path);
std.fs.cwd().access(path, .{}) catch continue; std.fs.cwd().access(path, .{}) catch continue;
main.utils.file_monitor.listenToPath(path, main.blocks.meshes.reloadTextures, 0); main.utils.file_monitor.listenToPath(path, main.blocks.meshes.reloadTextures, 0);
@ -680,7 +680,7 @@ pub fn unloadAssets() void { // MARK: unloadAssets()
break :blk null; break :blk null;
}) |addon| { }) |addon| {
if(addon.kind == .directory) { if(addon.kind == .directory) {
const path = std.fmt.allocPrintZ(main.stackAllocator.allocator, "assets/{s}/blocks/textures", .{addon.name}) catch unreachable; const path = std.fmt.allocPrintSentinel(main.stackAllocator.allocator, "assets/{s}/blocks/textures", .{addon.name}, 0) catch unreachable;
defer main.stackAllocator.free(path); defer main.stackAllocator.free(path);
std.fs.cwd().access(path, .{}) catch continue; std.fs.cwd().access(path, .{}) catch continue;
main.utils.file_monitor.removePath(path); main.utils.file_monitor.removePath(path);

View File

@ -27,11 +27,11 @@ const AudioData = struct {
}; };
const addon = id[0..colonIndex]; const addon = id[0..colonIndex];
const fileName = id[colonIndex + 1 ..]; const fileName = id[colonIndex + 1 ..];
const path1 = std.fmt.allocPrintZ(main.stackAllocator.allocator, "assets/{s}/music/{s}.ogg", .{addon, fileName}) catch unreachable; const path1 = std.fmt.allocPrintSentinel(main.stackAllocator.allocator, "assets/{s}/music/{s}.ogg", .{addon, fileName}, 0) catch unreachable;
defer main.stackAllocator.free(path1); defer main.stackAllocator.free(path1);
var err: c_int = 0; var err: c_int = 0;
if(c.stb_vorbis_open_filename(path1.ptr, &err, null)) |ogg_stream| return ogg_stream; if(c.stb_vorbis_open_filename(path1.ptr, &err, null)) |ogg_stream| return ogg_stream;
const path2 = std.fmt.allocPrintZ(main.stackAllocator.allocator, "serverAssets/{s}/music/{s}.ogg", .{addon, fileName}) catch unreachable; const path2 = std.fmt.allocPrintSentinel(main.stackAllocator.allocator, "serverAssets/{s}/music/{s}.ogg", .{addon, fileName}, 0) catch unreachable;
defer main.stackAllocator.free(path2); defer main.stackAllocator.free(path2);
if(c.stb_vorbis_open_filename(path2.ptr, &err, null)) |ogg_stream| return ogg_stream; if(c.stb_vorbis_open_filename(path2.ptr, &err, null)) |ogg_stream| return ogg_stream;
std.log.err("Couldn't find music with id \"{s}\". Searched path \"{s}\" and \"{s}\"", .{id, path1, path2}); std.log.err("Couldn't find music with id \"{s}\". Searched path \"{s}\" and \"{s}\"", .{id, path1, path2});
@ -309,7 +309,7 @@ fn miniaudioCallback(
output: ?*anyopaque, output: ?*anyopaque,
input: ?*const anyopaque, input: ?*const anyopaque,
frameCount: u32, frameCount: u32,
) callconv(.C) void { ) callconv(.c) void {
_ = input; _ = input;
_ = maDevice; _ = maDevice;
const valuesPerBuffer = 2*frameCount; // Stereo const valuesPerBuffer = 2*frameCount; // Stereo

View File

@ -7,7 +7,15 @@ pub fn main() !void {
} }
// zig fmt: off // zig fmt: off
/// Everything below is a direct copy of fmt.zig from the zig compiler /// Everything below is a direct copy of src/fmt.zig from the zig compiler
const std = @import("std");
const mem = std.mem;
const fs = std.fs;
const process = std.process;
const Allocator = std.mem.Allocator;
const Color = std.zig.Color;
const fatal = std.process.fatal;
const usage_fmt = const usage_fmt =
\\Usage: zig fmt [file]... \\Usage: zig fmt [file]...
@ -63,7 +71,7 @@ pub fn run(
const arg = args[i]; const arg = args[i];
if (mem.startsWith(u8, arg, "-")) { if (mem.startsWith(u8, arg, "-")) {
if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) {
const stdout = std.io.getStdOut().writer(); const stdout = std.fs.File.stdout().deprecatedWriter();
try stdout.writeAll(usage_fmt); try stdout.writeAll(usage_fmt);
return process.cleanExit(); return process.cleanExit();
} else if (mem.eql(u8, arg, "--color")) { } else if (mem.eql(u8, arg, "--color")) {
@ -104,7 +112,7 @@ pub fn run(
fatal("cannot use --stdin with positional arguments", .{}); fatal("cannot use --stdin with positional arguments", .{});
} }
const stdin = std.io.getStdIn(); const stdin: fs.File = .stdin();
const source_code = std.zig.readSourceFileToEndAlloc(gpa, stdin, null) catch |err| { const source_code = std.zig.readSourceFileToEndAlloc(gpa, stdin, null) catch |err| {
fatal("unable to read stdin: {}", .{err}); fatal("unable to read stdin: {}", .{err});
}; };
@ -157,7 +165,7 @@ pub fn run(
process.exit(code); process.exit(code);
} }
return std.io.getStdOut().writeAll(formatted); return std.fs.File.stdout().writeAll(formatted);
} }
if (input_files.items.len == 0) { if (input_files.items.len == 0) {
@ -213,6 +221,7 @@ const FmtError = error{
DestinationAddressRequired, DestinationAddressRequired,
DiskQuota, DiskQuota,
FileTooBig, FileTooBig,
MessageTooBig,
InputOutput, InputOutput,
NoSpaceLeft, NoSpaceLeft,
AccessDenied, AccessDenied,
@ -373,7 +382,7 @@ fn fmtPathFile(
return; return;
if (check_mode) { if (check_mode) {
const stdout = std.io.getStdOut().writer(); const stdout = std.fs.File.stdout().deprecatedWriter();
try stdout.print("{s}\n", .{file_path}); try stdout.print("{s}\n", .{file_path});
fmt.any_error = true; fmt.any_error = true;
} else { } else {
@ -382,15 +391,7 @@ fn fmtPathFile(
try af.file.writeAll(fmt.out_buffer.items); try af.file.writeAll(fmt.out_buffer.items);
try af.finish(); try af.finish();
const stdout = std.io.getStdOut().writer(); const stdout = std.fs.File.stdout().deprecatedWriter();
try stdout.print("{s}\n", .{file_path}); try stdout.print("{s}\n", .{file_path});
} }
} }
const std = @import("std");
const mem = std.mem;
const fs = std.fs;
const process = std.process;
const Allocator = std.mem.Allocator;
const Color = std.zig.Color;
const fatal = std.process.fatal;

View File

@ -1900,6 +1900,7 @@ pub fn LargeBuffer(comptime Entry: type) type { // MARK: LargerBuffer
} }
pub fn init(self: *Self, allocator: NeverFailingAllocator, size: u31, binding: c_uint) void { pub fn init(self: *Self, allocator: NeverFailingAllocator, size: u31, binding: c_uint) void {
self.used = 0;
self.binding = binding; self.binding = binding;
self.createBuffer(size); self.createBuffer(size);
self.activeFence = 0; self.activeFence = 0;
@ -2512,7 +2513,7 @@ pub const Image = struct { // MARK: Image
pub fn readFromFile(allocator: NeverFailingAllocator, path: []const u8) !Image { pub fn readFromFile(allocator: NeverFailingAllocator, path: []const u8) !Image {
var result: Image = undefined; var result: Image = undefined;
var channel: c_int = undefined; var channel: c_int = undefined;
const nullTerminatedPath = std.fmt.allocPrintZ(main.stackAllocator.allocator, "{s}", .{path}) catch unreachable; // TODO: Find a more zig-friendly image loading library. const nullTerminatedPath = main.stackAllocator.dupeZ(u8, path); // TODO: Find a more zig-friendly image loading library.
errdefer main.stackAllocator.free(nullTerminatedPath); errdefer main.stackAllocator.free(nullTerminatedPath);
stb_image.stbi_set_flip_vertically_on_load(1); stb_image.stbi_set_flip_vertically_on_load(1);
const data = stb_image.stbi_load(nullTerminatedPath.ptr, @ptrCast(&result.width), @ptrCast(&result.height), &channel, 4) orelse { const data = stb_image.stbi_load(nullTerminatedPath.ptr, @ptrCast(&result.width), @ptrCast(&result.height), &channel, 4) orelse {
@ -2526,7 +2527,7 @@ pub const Image = struct { // MARK: Image
pub fn readUnflippedFromFile(allocator: NeverFailingAllocator, path: []const u8) !Image { pub fn readUnflippedFromFile(allocator: NeverFailingAllocator, path: []const u8) !Image {
var result: Image = undefined; var result: Image = undefined;
var channel: c_int = undefined; var channel: c_int = undefined;
const nullTerminatedPath = std.fmt.allocPrintZ(main.stackAllocator.allocator, "{s}", .{path}) catch unreachable; // TODO: Find a more zig-friendly image loading library. const nullTerminatedPath = main.stackAllocator.dupeZ(u8, path); // TODO: Find a more zig-friendly image loading library.
errdefer main.stackAllocator.free(nullTerminatedPath); errdefer main.stackAllocator.free(nullTerminatedPath);
const data = stb_image.stbi_load(nullTerminatedPath.ptr, @ptrCast(&result.width), @ptrCast(&result.height), &channel, 4) orelse { const data = stb_image.stbi_load(nullTerminatedPath.ptr, @ptrCast(&result.width), @ptrCast(&result.height), &channel, 4) orelse {
return error.FileNotFound; return error.FileNotFound;

View File

@ -434,10 +434,10 @@ pub const Key = struct { // MARK: Key
}; };
pub const GLFWCallbacks = struct { // MARK: GLFWCallbacks pub const GLFWCallbacks = struct { // MARK: GLFWCallbacks
fn errorCallback(errorCode: c_int, description: [*c]const u8) callconv(.C) void { fn errorCallback(errorCode: c_int, description: [*c]const u8) callconv(.c) void {
std.log.err("GLFW Error({}): {s}", .{errorCode, description}); std.log.err("GLFW Error({}): {s}", .{errorCode, description});
} }
fn keyCallback(_: ?*c.GLFWwindow, glfw_key: c_int, scancode: c_int, action: c_int, _mods: c_int) callconv(.C) void { fn keyCallback(_: ?*c.GLFWwindow, glfw_key: c_int, scancode: c_int, action: c_int, _mods: c_int) callconv(.c) void {
const mods: Key.Modifiers = @bitCast(@as(u6, @intCast(_mods))); const mods: Key.Modifiers = @bitCast(@as(u6, @intCast(_mods)));
if(!mods.control and main.gui.selectedTextInput != null and c.glfwGetKeyName(glfw_key, scancode) != null) return; // Don't send events for keys that are used in writing letters. if(!mods.control and main.gui.selectedTextInput != null and c.glfwGetKeyName(glfw_key, scancode) != null) return; // Don't send events for keys that are used in writing letters.
const isGrabbed = grabbed; const isGrabbed = grabbed;
@ -465,13 +465,13 @@ pub const GLFWCallbacks = struct { // MARK: GLFWCallbacks
} }
} }
} }
fn charCallback(_: ?*c.GLFWwindow, codepoint: c_uint) callconv(.C) void { fn charCallback(_: ?*c.GLFWwindow, codepoint: c_uint) callconv(.c) void {
if(!grabbed) { if(!grabbed) {
main.gui.textCallbacks.char(@intCast(codepoint)); main.gui.textCallbacks.char(@intCast(codepoint));
} }
} }
pub fn framebufferSize(_: ?*c.GLFWwindow, newWidth: c_int, newHeight: c_int) callconv(.C) void { pub fn framebufferSize(_: ?*c.GLFWwindow, newWidth: c_int, newHeight: c_int) callconv(.c) void {
std.log.info("Framebuffer: {}, {}", .{newWidth, newHeight}); std.log.info("Framebuffer: {}, {}", .{newWidth, newHeight});
width = @intCast(newWidth); width = @intCast(newWidth);
height = @intCast(newHeight); height = @intCast(newHeight);
@ -485,7 +485,7 @@ pub const GLFWCallbacks = struct { // MARK: GLFWCallbacks
var deltaBufferPosition: u2 = 0; var deltaBufferPosition: u2 = 0;
var currentPos: Vec2f = Vec2f{0, 0}; var currentPos: Vec2f = Vec2f{0, 0};
var ignoreDataAfterRecentGrab: bool = true; var ignoreDataAfterRecentGrab: bool = true;
fn cursorPosition(_: ?*c.GLFWwindow, x: f64, y: f64) callconv(.C) void { fn cursorPosition(_: ?*c.GLFWwindow, x: f64, y: f64) callconv(.c) void {
const newPos = Vec2f{ const newPos = Vec2f{
@floatCast(x), @floatCast(x),
@floatCast(y), @floatCast(y),
@ -509,7 +509,7 @@ pub const GLFWCallbacks = struct { // MARK: GLFWCallbacks
currentPos = newPos; currentPos = newPos;
lastUsedMouse = true; lastUsedMouse = true;
} }
fn mouseButton(_: ?*c.GLFWwindow, button: c_int, action: c_int, _mods: c_int) callconv(.C) void { fn mouseButton(_: ?*c.GLFWwindow, button: c_int, action: c_int, _mods: c_int) callconv(.c) void {
const mods: Key.Modifiers = @bitCast(@as(u6, @intCast(_mods))); const mods: Key.Modifiers = @bitCast(@as(u6, @intCast(_mods)));
const isGrabbed = grabbed; const isGrabbed = grabbed;
if(action == c.GLFW_PRESS or action == c.GLFW_RELEASE) { if(action == c.GLFW_PRESS or action == c.GLFW_RELEASE) {
@ -526,11 +526,11 @@ pub const GLFWCallbacks = struct { // MARK: GLFWCallbacks
} }
} }
} }
fn scroll(_: ?*c.GLFWwindow, xOffset: f64, yOffset: f64) callconv(.C) void { fn scroll(_: ?*c.GLFWwindow, xOffset: f64, yOffset: f64) callconv(.c) void {
_ = xOffset; _ = xOffset;
scrollOffset += @floatCast(yOffset); scrollOffset += @floatCast(yOffset);
} }
fn glDebugOutput(source: c_uint, typ: c_uint, _: c_uint, severity: c_uint, length: c_int, message: [*c]const u8, _: ?*const anyopaque) callconv(.C) void { fn glDebugOutput(source: c_uint, typ: c_uint, _: c_uint, severity: c_uint, length: c_int, message: [*c]const u8, _: ?*const anyopaque) callconv(.c) void {
const sourceString: []const u8 = switch(source) { const sourceString: []const u8 = switch(source) {
c.GL_DEBUG_SOURCE_API => "API", c.GL_DEBUG_SOURCE_API => "API",
c.GL_DEBUG_SOURCE_APPLICATION => "Application", c.GL_DEBUG_SOURCE_APPLICATION => "Application",

View File

@ -168,12 +168,12 @@ fn moveCursorLeft(self: *TextInput, mods: main.Window.Key.Modifiers) void {
if(self.cursor.? == 0) return; if(self.cursor.? == 0) return;
self.cursor.? -= 1; self.cursor.? -= 1;
// Find end of previous "word": // Find end of previous "word":
while(!std.ascii.isAlphabetic(text[self.cursor.?]) and std.ascii.isASCII(text[self.cursor.?])) { while(!std.ascii.isAlphabetic(text[self.cursor.?]) and std.ascii.isAscii(text[self.cursor.?])) {
if(self.cursor.? == 0) return; if(self.cursor.? == 0) return;
self.cursor.? -= 1; self.cursor.? -= 1;
} }
// Find the start of the previous "word": // Find the start of the previous "word":
while(std.ascii.isAlphabetic(text[self.cursor.?]) or !std.ascii.isASCII(text[self.cursor.?])) { while(std.ascii.isAlphabetic(text[self.cursor.?]) or !std.ascii.isAscii(text[self.cursor.?])) {
if(self.cursor.? == 0) return; if(self.cursor.? == 0) return;
self.cursor.? -= 1; self.cursor.? -= 1;
} }
@ -213,12 +213,12 @@ fn moveCursorRight(self: *TextInput, mods: main.Window.Key.Modifiers) void {
if(mods.control) { if(mods.control) {
const text = self.currentString.items; const text = self.currentString.items;
// Find start of next "word": // Find start of next "word":
while(!std.ascii.isAlphabetic(text[self.cursor.?]) and std.ascii.isASCII(text[self.cursor.?])) { while(!std.ascii.isAlphabetic(text[self.cursor.?]) and std.ascii.isAscii(text[self.cursor.?])) {
self.cursor.? += 1; self.cursor.? += 1;
if(self.cursor.? >= self.currentString.items.len) return; if(self.cursor.? >= self.currentString.items.len) return;
} }
// Find the end of the next "word": // Find the end of the next "word":
while(std.ascii.isAlphabetic(text[self.cursor.?]) or !std.ascii.isASCII(text[self.cursor.?])) { while(std.ascii.isAlphabetic(text[self.cursor.?]) or !std.ascii.isAscii(text[self.cursor.?])) {
self.cursor.? += 1; self.cursor.? += 1;
if(self.cursor.? >= self.currentString.items.len) return; if(self.cursor.? >= self.currentString.items.len) return;
} }

View File

@ -30,7 +30,7 @@ const width: f32 = 420;
fn discoverIpAddress() void { fn discoverIpAddress() void {
main.server.connectionManager.makeOnline(); main.server.connectionManager.makeOnline();
ipAddress = std.fmt.allocPrint(main.globalAllocator.allocator, "{}", .{main.server.connectionManager.externalAddress}) catch unreachable; ipAddress = std.fmt.allocPrint(main.globalAllocator.allocator, "{f}", .{main.server.connectionManager.externalAddress}) catch unreachable;
gotIpAddress.store(true, .release); gotIpAddress.store(true, .release);
} }

View File

@ -41,7 +41,7 @@ pub fn onOpen() void {
row.add(Label.init(.{0, 0}, 200, connection.user.?.name, .left)); row.add(Label.init(.{0, 0}, 200, connection.user.?.name, .left));
row.add(Button.initText(.{0, 0}, 100, "Kick", .{.callback = @ptrCast(&kick), .arg = @intFromPtr(connection)})); row.add(Button.initText(.{0, 0}, 100, "Kick", .{.callback = @ptrCast(&kick), .arg = @intFromPtr(connection)}));
} else { } else {
const ip = std.fmt.allocPrint(main.stackAllocator.allocator, "{}", .{connection.remoteAddress}) catch unreachable; const ip = std.fmt.allocPrint(main.stackAllocator.allocator, "{f}", .{connection.remoteAddress}) catch unreachable;
defer main.stackAllocator.free(ip); defer main.stackAllocator.free(ip);
row.add(Label.init(.{0, 0}, 200, ip, .left)); row.add(Label.init(.{0, 0}, 200, ip, .left));
row.add(Button.initText(.{0, 0}, 100, "Cancel", .{.callback = @ptrCast(&kick), .arg = @intFromPtr(connection)})); row.add(Button.initText(.{0, 0}, 100, "Cancel", .{.callback = @ptrCast(&kick), .arg = @intFromPtr(connection)}));

View File

@ -34,7 +34,7 @@ fn discoverIpAddress() void {
ipAddress = main.globalAllocator.dupe(u8, @errorName(err)); ipAddress = main.globalAllocator.dupe(u8, @errorName(err));
return; return;
}; };
ipAddress = std.fmt.allocPrint(main.globalAllocator.allocator, "{}", .{connection.?.externalAddress}) catch unreachable; ipAddress = std.fmt.allocPrint(main.globalAllocator.allocator, "{f}", .{connection.?.externalAddress}) catch unreachable;
gotIpAddress.store(true, .release); gotIpAddress.store(true, .release);
} }

View File

@ -62,7 +62,7 @@ pub fn openWorld(name: []const u8) void {
}; };
while(!main.server.running.load(.acquire)) { while(!main.server.running.load(.acquire)) {
std.time.sleep(1_000_000); std.Thread.sleep(1_000_000);
} }
clientConnection.world = &main.game.testWorld; clientConnection.world = &main.game.testWorld;
const ipPort = std.fmt.allocPrint(main.stackAllocator.allocator, "127.0.0.1:{}", .{main.server.connectionManager.localPort}) catch unreachable; const ipPort = std.fmt.allocPrint(main.stackAllocator.allocator, "127.0.0.1:{}", .{main.server.connectionManager.localPort}) catch unreachable;

View File

@ -265,11 +265,10 @@ pub const JsonElement = union(JsonType) { // MARK: JsonElement
fn recurseToString(json: JsonElement, list: *List(u8), tabs: u32, comptime visualCharacters: bool) void { fn recurseToString(json: JsonElement, list: *List(u8), tabs: u32, comptime visualCharacters: bool) void {
switch(json) { switch(json) {
.JsonInt => |value| { .JsonInt => |value| {
std.fmt.formatInt(value, 10, .lower, .{}, list.writer()) catch unreachable; list.writer().print("{d}", .{value}) catch unreachable;
}, },
.JsonFloat => |value| { .JsonFloat => |value| {
var buf: [std.fmt.format_float.bufferSize(.scientific, @TypeOf(value))]u8 = undefined; list.writer().print("{e}", .{value}) catch unreachable;
list.appendSlice(std.fmt.format_float.formatFloat(&buf, value, .{.mode = .scientific}) catch unreachable);
}, },
.JsonBool => |value| { .JsonBool => |value| {
if(value) { if(value) {

View File

@ -231,7 +231,7 @@ fn initLogging() void {
return; return;
}; };
supportsANSIColors = std.io.getStdOut().supportsAnsiEscapeCodes(); supportsANSIColors = std.fs.File.stdout().supportsAnsiEscapeCodes();
} }
fn deinitLogging() void { fn deinitLogging() void {
@ -264,7 +264,9 @@ fn logToStdErr(comptime format: []const u8, args: anytype) void {
const string = std.fmt.allocPrint(allocator, format, args) catch format; const string = std.fmt.allocPrint(allocator, format, args) catch format;
defer allocator.free(string); defer allocator.free(string);
nosuspend std.io.getStdErr().writeAll(string) catch {}; const writer = std.debug.lockStderrWriter(&.{});
defer std.debug.unlockStderrWriter();
nosuspend writer.writeAll(string) catch {};
} }
// MARK: Callbacks // MARK: Callbacks
@ -682,7 +684,7 @@ pub fn main() void { // MARK: main()
c.glClear(c.GL_DEPTH_BUFFER_BIT | c.GL_STENCIL_BUFFER_BIT | c.GL_COLOR_BUFFER_BIT); c.glClear(c.GL_DEPTH_BUFFER_BIT | c.GL_STENCIL_BUFFER_BIT | c.GL_COLOR_BUFFER_BIT);
gui.windowlist.gpu_performance_measuring.stopQuery(); gui.windowlist.gpu_performance_measuring.stopQuery();
} else { } else {
std.time.sleep(16_000_000); std.Thread.sleep(16_000_000);
} }
const endRendering = std.time.nanoTimestamp(); const endRendering = std.time.nanoTimestamp();
@ -696,7 +698,7 @@ pub fn main() void { // MARK: main()
if(settings.fpsCap) |fpsCap| { if(settings.fpsCap) |fpsCap| {
const minFrameTime = @divFloor(1000*1000*1000, fpsCap); const minFrameTime = @divFloor(1000*1000*1000, fpsCap);
const sleep = @min(minFrameTime, @max(0, minFrameTime - (endRendering -% lastBeginRendering))); const sleep = @min(minFrameTime, @max(0, minFrameTime - (endRendering -% lastBeginRendering)));
std.time.sleep(sleep); std.Thread.sleep(sleep);
} }
const begin = std.time.nanoTimestamp(); const begin = std.time.nanoTimestamp();
const deltaTime = @as(f64, @floatFromInt(begin -% lastBeginRendering))/1e9; const deltaTime = @as(f64, @floatFromInt(begin -% lastBeginRendering))/1e9;

View File

@ -64,10 +64,19 @@ const Socket = struct {
.port = @byteSwap(destination.port), .port = @byteSwap(destination.port),
.addr = destination.ip, .addr = destination.ip,
}; };
std.debug.assert(data.len == posix.sendto(self.socketID, data, 0, @ptrCast(&addr), @sizeOf(posix.sockaddr.in)) catch |err| { if(builtin.os.tag == .windows) { // TODO: Upstream error, fix after next Zig update after #24466 is merged
std.log.info("Got error while sending to {}: {s}", .{destination, @errorName(err)}); const result = posix.system.sendto(self.socketID, data.ptr, data.len, 0, @ptrCast(&addr), @sizeOf(posix.sockaddr.in));
return; if(result < 0) {
}); std.log.info("Got error while sending to {f}: {s}", .{destination, @tagName(std.os.windows.ws2_32.WSAGetLastError())});
} else {
std.debug.assert(@as(usize, @intCast(result)) == data.len);
}
} else {
std.debug.assert(data.len == posix.sendto(self.socketID, data, 0, @ptrCast(&addr), @sizeOf(posix.sockaddr.in)) catch |err| {
std.log.info("Got error while sending to {f}: {s}", .{destination, @errorName(err)});
return;
});
}
} }
fn receive(self: Socket, buffer: []u8, timeout: i32, resultAddress: *Address) ![]u8 { fn receive(self: Socket, buffer: []u8, timeout: i32, resultAddress: *Address) ![]u8 {
@ -85,7 +94,7 @@ const Socket = struct {
else => |err| return std.os.windows.unexpectedWSAError(err), else => |err| return std.os.windows.unexpectedWSAError(err),
} }
} else if(length == 0) { } else if(length == 0) {
std.time.sleep(1000000); // Manually sleep, since WSAPoll is blocking. std.Thread.sleep(1000000); // Manually sleep, since WSAPoll is blocking.
return error.Timeout; return error.Timeout;
} }
} else { } else {
@ -139,7 +148,7 @@ pub const Address = struct {
pub const localHost = 0x0100007f; pub const localHost = 0x0100007f;
pub fn format(self: Address, _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void { pub fn format(self: Address, writer: anytype) !void {
if(self.isSymmetricNAT) { if(self.isSymmetricNAT) {
try writer.print("{}.{}.{}.{}:?{}", .{self.ip & 255, self.ip >> 8 & 255, self.ip >> 16 & 255, self.ip >> 24, self.port}); try writer.print("{}.{}.{}.{}:?{}", .{self.ip & 255, self.ip >> 8 & 255, self.ip >> 16 & 255, self.ip >> 24, self.port});
} else { } else {
@ -295,7 +304,7 @@ const STUN = struct { // MARK: STUN
continue; continue;
}; };
if(oldAddress) |other| { if(oldAddress) |other| {
std.log.info("{}", .{result}); std.log.info("{f}", .{result});
if(other.ip == result.ip and other.port == result.port) { if(other.ip == result.ip and other.port == result.port) {
return result; return result;
} else { } else {
@ -556,17 +565,17 @@ pub const ConnectionManager = struct { // MARK: ConnectionManager
} }
if(self.allowNewConnections.load(.monotonic) or source.ip == Address.localHost) { if(self.allowNewConnections.load(.monotonic) or source.ip == Address.localHost) {
if(data.len != 0 and data[0] == @intFromEnum(Connection.ChannelId.init)) { if(data.len != 0 and data[0] == @intFromEnum(Connection.ChannelId.init)) {
const ip = std.fmt.allocPrint(main.stackAllocator.allocator, "{}", .{source}) catch unreachable; const ip = std.fmt.allocPrint(main.stackAllocator.allocator, "{f}", .{source}) catch unreachable;
defer main.stackAllocator.free(ip); defer main.stackAllocator.free(ip);
const user = main.server.User.initAndIncreaseRefCount(main.server.connectionManager, ip) catch |err| { const user = main.server.User.initAndIncreaseRefCount(main.server.connectionManager, ip) catch |err| {
std.log.err("Cannot connect user from external IP {}: {s}", .{source, @errorName(err)}); std.log.err("Cannot connect user from external IP {f}: {s}", .{source, @errorName(err)});
return; return;
}; };
user.decreaseRefCount(); user.decreaseRefCount();
} }
} else { } else {
// TODO: Reduce the number of false alarms in the short period after a disconnect. // TODO: Reduce the number of false alarms in the short period after a disconnect.
std.log.warn("Unknown connection from address: {}", .{source}); std.log.warn("Unknown connection from address: {f}", .{source});
std.log.debug("Message: {any}", .{data}); std.log.debug("Message: {any}", .{data});
} }
} }
@ -2025,7 +2034,7 @@ pub const Connection = struct { // MARK: Connection
self.tryReceive(data) catch |err| { self.tryReceive(data) catch |err| {
std.log.err("Got error while processing received network data: {s}", .{@errorName(err)}); std.log.err("Got error while processing received network data: {s}", .{@errorName(err)});
if(@errorReturnTrace()) |trace| { if(@errorReturnTrace()) |trace| {
std.log.info("{}", .{trace}); std.log.info("{f}", .{trace});
} }
self.disconnect(); self.disconnect();
}; };
@ -2218,7 +2227,7 @@ pub const Connection = struct { // MARK: Connection
self.manager.send(&.{@intFromEnum(ChannelId.disconnect)}, self.remoteAddress, null); self.manager.send(&.{@intFromEnum(ChannelId.disconnect)}, self.remoteAddress, null);
self.connectionState.store(.disconnectDesired, .unordered); self.connectionState.store(.disconnectDesired, .unordered);
if(builtin.os.tag == .windows and !self.isServerSide() and main.server.world != null) { if(builtin.os.tag == .windows and !self.isServerSide() and main.server.world != null) {
std.time.sleep(10000000); // Windows is too eager to close the socket, without waiting here we get a ConnectionResetByPeer on the other side. std.Thread.sleep(10000000); // Windows is too eager to close the socket, without waiting here we get a ConnectionResetByPeer on the other side.
} }
self.manager.removeConnection(self); self.manager.removeConnection(self);
if(self.user) |user| { if(self.user) |user| {

View File

@ -1717,7 +1717,7 @@ pub const ChunkMesh = struct { // MARK: ChunkMesh
} }
self.culledSortingCount += @intCast(self.blockBreakingFaces.items.len); self.culledSortingCount += @intCast(self.blockBreakingFaces.items.len);
// Upload: // Upload:
faceBuffers[std.math.log2_int(u32, self.pos.voxelSize)].uploadData(self.sortingOutputBuffer[0..self.culledSortingCount], &self.transparentMesh.bufferAllocation); faceBuffers[self.transparentMesh.lod].uploadData(self.sortingOutputBuffer[0..self.culledSortingCount], &self.transparentMesh.bufferAllocation);
self.uploadChunkPosition(); self.uploadChunkPosition();
} }

View File

@ -444,7 +444,7 @@ pub fn start(name: []const u8, port: ?u16) void {
while(running.load(.monotonic)) { while(running.load(.monotonic)) {
const newTime = std.time.nanoTimestamp(); const newTime = std.time.nanoTimestamp();
if(newTime -% lastTime < updateNanoTime) { if(newTime -% lastTime < updateNanoTime) {
std.time.sleep(@intCast(lastTime +% updateNanoTime -% newTime)); std.Thread.sleep(@intCast(lastTime +% updateNanoTime -% newTime));
lastTime +%= updateNanoTime; lastTime +%= updateNanoTime;
} else { } else {
std.log.warn("The server is lagging behind by {d:.1} ms", .{@as(f32, @floatFromInt(newTime -% lastTime -% updateNanoTime))/1000000.0}); std.log.warn("The server is lagging behind by {d:.1} ms", .{@as(f32, @floatFromInt(newTime -% lastTime -% updateNanoTime))/1000000.0});

View File

@ -48,7 +48,7 @@ pub const RegionFile = struct { // MARK: RegionFile
defer main.stackAllocator.free(data); defer main.stackAllocator.free(data);
self.load(path, data) catch { self.load(path, data) catch {
std.log.err("Corrupted region file: {s}", .{path}); std.log.err("Corrupted region file: {s}", .{path});
if(@errorReturnTrace()) |trace| std.log.info("{}", .{trace}); if(@errorReturnTrace()) |trace| std.log.info("{f}", .{trace});
}; };
return self; return self;
} }

View File

@ -751,7 +751,7 @@ pub const ServerWorld = struct { // MARK: ServerWorld
updateRequest.region.decreaseRefCount(); updateRequest.region.decreaseRefCount();
} }
self.mutex.unlock(); self.mutex.unlock();
std.time.sleep(1_000_000); std.Thread.sleep(1_000_000);
self.mutex.lock(); self.mutex.lock();
if(main.threadPool.queueSize() == 0 and self.chunkUpdateQueue.peek() == null and self.regionUpdateQueue.peek() == null) break; if(main.threadPool.queueSize() == 0 and self.chunkUpdateQueue.peek() == null and self.regionUpdateQueue.peek() == null) break;
} }

View File

@ -655,7 +655,7 @@ pub fn BlockingMaxHeap(comptime T: type) type { // MARK: BlockingMaxHeap
self.waitingThreads.broadcast(); self.waitingThreads.broadcast();
while(self.waitingThreadCount != 0) { while(self.waitingThreadCount != 0) {
self.mutex.unlock(); self.mutex.unlock();
std.time.sleep(1000000); std.Thread.sleep(1000000);
self.mutex.lock(); self.mutex.lock();
} }
self.mutex.unlock(); self.mutex.unlock();
@ -899,7 +899,7 @@ pub const ThreadPool = struct { // MARK: ThreadPool
// Wait for active tasks: // Wait for active tasks:
for(self.currentTasks) |*task| { for(self.currentTasks) |*task| {
while(task.load(.monotonic) == vtable) { while(task.load(.monotonic) == vtable) {
std.time.sleep(1e6); std.Thread.sleep(1e6);
} }
} }
} }
@ -966,7 +966,7 @@ pub const ThreadPool = struct { // MARK: ThreadPool
break; break;
} }
} }
std.time.sleep(1000000); std.Thread.sleep(1000000);
} }
} }
@ -998,7 +998,7 @@ pub fn DynamicPackedIntArray(size: comptime_int) type { // MARK: DynamicPackedIn
pub fn initCapacity(bitSize: u5) Self { pub fn initCapacity(bitSize: u5) Self {
std.debug.assert(bitSize == 0 or bitSize & bitSize - 1 == 0); // Must be a power of 2 std.debug.assert(bitSize == 0 or bitSize & bitSize - 1 == 0); // Must be a power of 2
return .{ return .{
.data = dynamicIntArrayAllocator.allocator().alignedAlloc(u32, 64, @as(usize, @divExact(size, @bitSizeOf(u32)))*bitSize), .data = dynamicIntArrayAllocator.allocator().alignedAlloc(u32, .@"64", @as(usize, @divExact(size, @bitSizeOf(u32)))*bitSize),
.bitSize = bitSize, .bitSize = bitSize,
}; };
} }

View File

@ -98,7 +98,7 @@ const LinuxImpl = struct { // MARK: LinuxImpl
return; return;
}) |entry| { }) |entry| {
if(entry.kind == .directory) { if(entry.kind == .directory) {
const subPath = std.fmt.allocPrintZ(main.stackAllocator.allocator, "{s}/{s}", .{path, entry.name}) catch unreachable; const subPath = std.fmt.allocPrintSentinel(main.stackAllocator.allocator, "{s}/{s}", .{path, entry.name}, 0) catch unreachable;
defer main.stackAllocator.free(subPath); defer main.stackAllocator.free(subPath);
addWatchDescriptor(info, subPath); addWatchDescriptor(info, subPath);
addWatchDescriptorsRecursive(info, subPath); addWatchDescriptorsRecursive(info, subPath);

View File

@ -17,7 +17,7 @@ pub const StackAllocator = struct { // MARK: StackAllocator
pub fn init(backingAllocator: NeverFailingAllocator, size: u31) StackAllocator { pub fn init(backingAllocator: NeverFailingAllocator, size: u31) StackAllocator {
return .{ return .{
.backingAllocator = backingAllocator, .backingAllocator = backingAllocator,
.buffer = backingAllocator.alignedAlloc(u8, 4096, size), .buffer = backingAllocator.alignedAlloc(u8, .fromByteUnits(4096), size),
.index = 0, .index = 0,
}; };
} }
@ -341,9 +341,9 @@ pub const NeverFailingAllocator = struct { // MARK: NeverFailingAllocator
self: NeverFailingAllocator, self: NeverFailingAllocator,
comptime T: type, comptime T: type,
/// null means naturally aligned /// null means naturally aligned
comptime alignment: ?u29, comptime alignment: ?Alignment,
n: usize, n: usize,
) []align(alignment orelse @alignOf(T)) T { ) []align(if(alignment) |a| a.toByteUnits() else @alignOf(T)) T {
return self.allocator.alignedAlloc(T, alignment, n) catch unreachable; return self.allocator.alignedAlloc(T, alignment, n) catch unreachable;
} }
@ -351,10 +351,10 @@ pub const NeverFailingAllocator = struct { // MARK: NeverFailingAllocator
self: NeverFailingAllocator, self: NeverFailingAllocator,
comptime T: type, comptime T: type,
/// null means naturally aligned /// null means naturally aligned
comptime alignment: ?u29, comptime alignment: ?Alignment,
n: usize, n: usize,
return_address: usize, return_address: usize,
) []align(alignment orelse @alignOf(T)) T { ) []align(if(alignment) |a| a.toByteUnits() else @alignOf(T)) T {
return self.allocator.allocAdvancedWithRetAddr(T, alignment, n, return_address) catch unreachable; return self.allocator.allocAdvancedWithRetAddr(T, alignment, n, return_address) catch unreachable;
} }
@ -483,6 +483,7 @@ pub const NeverFailingArenaAllocator = struct { // MARK: NeverFailingArena
} }
pub fn shrinkAndFree(self: *NeverFailingArenaAllocator) void { pub fn shrinkAndFree(self: *NeverFailingArenaAllocator) void {
if(true) return;
const node = self.arena.state.buffer_list.first orelse return; const node = self.arena.state.buffer_list.first orelse return;
const allocBuf = @as([*]u8, @ptrCast(node))[0..node.data]; const allocBuf = @as([*]u8, @ptrCast(node))[0..node.data];
const dataSize = std.mem.alignForward(usize, @sizeOf(std.SinglyLinkedList(usize).Node) + self.arena.state.end_index, @alignOf(std.SinglyLinkedList(usize).Node)); const dataSize = std.mem.alignForward(usize, @sizeOf(std.SinglyLinkedList(usize).Node) + self.arena.state.end_index, @alignOf(std.SinglyLinkedList(usize).Node));
@ -570,7 +571,7 @@ pub fn MemoryPool(Item: type) type { // MARK: MemoryPool
main.utils.assertLocked(&pool.mutex); main.utils.assertLocked(&pool.mutex);
pool.totalAllocations += 1; pool.totalAllocations += 1;
pool.freeAllocations += 1; pool.freeAllocations += 1;
const mem = pool.arena.allocator().alignedAlloc(u8, item_alignment, item_size); const mem = pool.arena.allocator().alignedAlloc(u8, .fromByteUnits(item_alignment), item_size);
return mem[0..item_size]; // coerce slice to array pointer return mem[0..item_size]; // coerce slice to array pointer
} }
}; };
@ -634,7 +635,7 @@ pub fn PowerOfTwoPoolAllocator(minSize: comptime_int, maxSize: comptime_int, max
fn allocNew(self: *Bucket, arena: NeverFailingAllocator, size: usize) [*]align(alignment) u8 { fn allocNew(self: *Bucket, arena: NeverFailingAllocator, size: usize) [*]align(alignment) u8 {
self.totalAllocations += 1; self.totalAllocations += 1;
self.freeAllocations += 1; self.freeAllocations += 1;
return arena.alignedAlloc(u8, alignment, size).ptr; return arena.alignedAlloc(u8, .fromByteUnits(alignment), size).ptr;
} }
}; };

View File

@ -213,7 +213,7 @@ pub fn List(comptime T: type) type {
@compileError("The Writer interface is only defined for ArrayList(u8) " ++ @compileError("The Writer interface is only defined for ArrayList(u8) " ++
"but the given type is ArrayList(" ++ @typeName(T) ++ ")") "but the given type is ArrayList(" ++ @typeName(T) ++ ")")
else else
std.io.Writer(*@This(), error{}, appendWrite); std.io.GenericWriter(*@This(), error{}, appendWrite);
pub fn writer(self: *@This()) Writer { pub fn writer(self: *@This()) Writer {
return .{.context = self}; return .{.context = self};

View File

@ -351,11 +351,10 @@ pub const ZonElement = union(enum) { // MARK: Zon
fn recurseToString(zon: ZonElement, list: *List(u8), tabs: u32, comptime visualCharacters: bool) void { fn recurseToString(zon: ZonElement, list: *List(u8), tabs: u32, comptime visualCharacters: bool) void {
switch(zon) { switch(zon) {
.int => |value| { .int => |value| {
std.fmt.formatInt(value, 10, .lower, .{}, list.writer()) catch unreachable; list.writer().print("{d}", .{value}) catch unreachable;
}, },
.float => |value| { .float => |value| {
var buf: [std.fmt.format_float.bufferSize(.scientific, @TypeOf(value))]u8 = undefined; list.writer().print("{e}", .{value}) catch unreachable;
list.appendSlice(std.fmt.format_float.formatFloat(&buf, value, .{.mode = .scientific}) catch unreachable);
}, },
.bool => |value| { .bool => |value| {
if(value) { if(value) {

View File

@ -1,5 +1,5 @@
//! Default test runner for unit tests.
// Source: https://github.com/ziglang/zig/blob/0.14.0/lib/compiler/test_runner.zig // Source: https://github.com/ziglang/zig/blob/0.14.0/lib/compiler/test_runner.zig
//! Default test runner for unit tests.
const builtin = @import("builtin"); const builtin = @import("builtin");
const std = @import("std"); const std = @import("std");
@ -16,7 +16,9 @@ var fba_buffer: [8192]u8 = undefined;
var fba = std.heap.FixedBufferAllocator.init(&fba_buffer); var fba = std.heap.FixedBufferAllocator.init(&fba_buffer);
const crippled = switch(builtin.zig_backend) { const crippled = switch(builtin.zig_backend) {
.stage2_riscv64 => true, .stage2_powerpc,
.stage2_riscv64,
=> true,
else => false, else => false,
}; };
@ -68,8 +70,8 @@ fn mainServer() !void {
@disableInstrumentation(); @disableInstrumentation();
var server = try std.zig.Server.init(.{ var server = try std.zig.Server.init(.{
.gpa = fba.allocator(), .gpa = fba.allocator(),
.in = std.io.getStdIn(), .in = .stdin(),
.out = std.io.getStdOut(), .out = .stdout(),
.zig_version = builtin.zig_version_string, .zig_version = builtin.zig_version_string,
}); });
defer server.deinit(); defer server.deinit();
@ -189,7 +191,7 @@ fn mainTerminal() void {
.root_name = "Test", .root_name = "Test",
.estimated_total_items = test_fn_list.len, .estimated_total_items = test_fn_list.len,
}); });
const doColors = std.io.getStdErr().supportsAnsiEscapeCodes(); const doColors = std.fs.File.stderr().supportsAnsiEscapeCodes();
const reset = if(doColors) "\x1b[0m" else ""; const reset = if(doColors) "\x1b[0m" else "";
const red = if(doColors) "\x1b[31m" else ""; const red = if(doColors) "\x1b[31m" else "";
const yellow = if(doColors) "\x1b[33m" else ""; const yellow = if(doColors) "\x1b[33m" else "";
@ -283,6 +285,7 @@ pub fn mainSimple() anyerror!void {
}; };
// is the backend capable of using std.fmt.format to print a summary at the end? // is the backend capable of using std.fmt.format to print a summary at the end?
const print_summary = switch(builtin.zig_backend) { const print_summary = switch(builtin.zig_backend) {
.stage2_riscv64 => true,
else => false, else => false,
}; };
@ -291,7 +294,7 @@ pub fn mainSimple() anyerror!void {
var failed: u64 = 0; var failed: u64 = 0;
// we don't want to bring in File and Writer if the backend doesn't support it // we don't want to bring in File and Writer if the backend doesn't support it
const stderr = if(comptime enable_print) std.io.getStdErr() else {}; const stderr = if(comptime enable_print) std.fs.File.stderr() else {};
for(builtin.test_functions) |test_fn| { for(builtin.test_functions) |test_fn| {
if(test_fn.func()) |_| { if(test_fn.func()) |_| {
@ -300,7 +303,7 @@ pub fn mainSimple() anyerror!void {
stderr.writeAll("... ") catch {}; stderr.writeAll("... ") catch {};
stderr.writeAll("PASS\n") catch {}; stderr.writeAll("PASS\n") catch {};
} }
} else |err| if(enable_print) { } else |err| {
if(enable_print) { if(enable_print) {
stderr.writeAll(test_fn.name) catch {}; stderr.writeAll(test_fn.name) catch {};
stderr.writeAll("... ") catch {}; stderr.writeAll("... ") catch {};
@ -318,7 +321,7 @@ pub fn mainSimple() anyerror!void {
passed += 1; passed += 1;
} }
if(enable_print and print_summary) { if(enable_print and print_summary) {
stderr.writer().print("{} passed, {} skipped, {} failed\n", .{passed, skipped, failed}) catch {}; stderr.deprecatedWriter().print("{} passed, {} skipped, {} failed\n", .{passed, skipped, failed}) catch {};
} }
if(failed != 0) std.process.exit(1); if(failed != 0) std.process.exit(1);
} }
@ -343,7 +346,7 @@ var is_fuzz_test: bool = undefined;
extern fn fuzzer_set_name(name_ptr: [*]const u8, name_len: usize) void; extern fn fuzzer_set_name(name_ptr: [*]const u8, name_len: usize) void;
extern fn fuzzer_init(cache_dir: FuzzerSlice) void; extern fn fuzzer_init(cache_dir: FuzzerSlice) void;
extern fn fuzzer_init_corpus_elem(input_ptr: [*]const u8, input_len: usize) void; extern fn fuzzer_init_corpus_elem(input_ptr: [*]const u8, input_len: usize) void;
extern fn fuzzer_start(testOne: *const fn([*]const u8, usize) callconv(.C) void) void; extern fn fuzzer_start(testOne: *const fn([*]const u8, usize) callconv(.c) void) void;
extern fn fuzzer_coverage_id() u64; extern fn fuzzer_coverage_id() u64;
pub fn fuzz( pub fn fuzz(
@ -375,7 +378,7 @@ pub fn fuzz(
const global = struct { const global = struct {
var ctx: @TypeOf(context) = undefined; var ctx: @TypeOf(context) = undefined;
fn fuzzer_one(input_ptr: [*]const u8, input_len: usize) callconv(.C) void { fn fuzzer_one(input_ptr: [*]const u8, input_len: usize) callconv(.c) void {
@disableInstrumentation(); @disableInstrumentation();
testing.allocator_instance = .{}; testing.allocator_instance = .{};
defer if(testing.allocator_instance.deinit() == .leak) std.process.exit(1); defer if(testing.allocator_instance.deinit() == .leak) std.process.exit(1);