| author | |
| committer | |
| log | 8373788c4c5fecac940ce5b86e35d803f9f14a21 |
| tree | 4b7ffda8c011e93e3b04af1fd0d26ed56690738e |
| parent | 4780cc50cf7e42f6af3eb71ef3897f4b341215b4 |
| parent | c40fb96ca358e2ef28aecc2b7ebc5ffab43ccac8 |
| signature |
std.zig: finish updating to new I/O API23 files changed, 275 insertions(+), 595 deletions(-)
lib/compiler/objcopy.zig+9-9| ... | ... | @@ -10,6 +10,9 @@ const assert = std.debug.assert; |
| 10 | 10 | const fatal = std.process.fatal; |
| 11 | 11 | const Server = std.zig.Server; |
| 12 | 12 | |
| 13 | var stdin_buffer: [1024]u8 = undefined; | |
| 14 | var stdout_buffer: [1024]u8 = undefined; | |
| 15 | ||
| 13 | 16 | pub fn main() !void { |
| 14 | 17 | var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator); |
| 15 | 18 | defer arena_instance.deinit(); |
| ... | ... | @@ -22,11 +25,8 @@ pub fn main() !void { |
| 22 | 25 | return cmdObjCopy(gpa, arena, args[1..]); |
| 23 | 26 | } |
| 24 | 27 | |
| 25 | fn cmdObjCopy( | |
| 26 | gpa: Allocator, | |
| 27 | arena: Allocator, | |
| 28 | args: []const []const u8, | |
| 29 | ) !void { | |
| 28 | fn cmdObjCopy(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | |
| 29 | _ = gpa; | |
| 30 | 30 | var i: usize = 0; |
| 31 | 31 | var opt_out_fmt: ?std.Target.ObjectFormat = null; |
| 32 | 32 | var opt_input: ?[]const u8 = null; |
| ... | ... | @@ -225,13 +225,13 @@ fn cmdObjCopy( |
| 225 | 225 | } |
| 226 | 226 | |
| 227 | 227 | if (listen) { |
| 228 | var stdin_reader = fs.File.stdin().reader(&stdin_buffer); | |
| 229 | var stdout_writer = fs.File.stdout().writer(&stdout_buffer); | |
| 228 | 230 | var server = try Server.init(.{ |
| 229 | .gpa = gpa, | |
| 230 | .in = .stdin(), | |
| 231 | .out = .stdout(), | |
| 231 | .in = &stdin_reader.interface, | |
| 232 | .out = &stdout_writer.interface, | |
| 232 | 233 | .zig_version = builtin.zig_version_string, |
| 233 | 234 | }); |
| 234 | defer server.deinit(); | |
| 235 | 235 | |
| 236 | 236 | var seen_update = false; |
| 237 | 237 | while (true) { |
lib/compiler/resinator/main.zig+4-2| ... | ... | @@ -13,6 +13,8 @@ const hasDisjointCodePage = @import("disjoint_code_page.zig").hasDisjointCodePag |
| 13 | 13 | const fmtResourceType = @import("res.zig").NameOrOrdinal.fmtResourceType; |
| 14 | 14 | const aro = @import("aro"); |
| 15 | 15 | |
| 16 | var stdout_buffer: [1024]u8 = undefined; | |
| 17 | ||
| 16 | 18 | pub fn main() !void { |
| 17 | 19 | var gpa: std.heap.GeneralPurposeAllocator(.{}) = .init; |
| 18 | 20 | defer std.debug.assert(gpa.deinit() == .ok); |
| ... | ... | @@ -41,12 +43,12 @@ pub fn main() !void { |
| 41 | 43 | cli_args = args[3..]; |
| 42 | 44 | } |
| 43 | 45 | |
| 46 | var stdout_writer2 = std.fs.File.stdout().writer(&stdout_buffer); | |
| 44 | 47 | var error_handler: ErrorHandler = switch (zig_integration) { |
| 45 | 48 | true => .{ |
| 46 | 49 | .server = .{ |
| 47 | .out = std.fs.File.stdout(), | |
| 50 | .out = &stdout_writer2.interface, | |
| 48 | 51 | .in = undefined, // won't be receiving messages |
| 49 | .receive_fifo = undefined, // won't be receiving messages | |
| 50 | 52 | }, |
| 51 | 53 | }, |
| 52 | 54 | false => .{ |
lib/compiler/test_runner.zig+8-7| ... | ... | @@ -2,7 +2,6 @@ |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | 3 | |
| 4 | 4 | const std = @import("std"); |
| 5 | const io = std.io; | |
| 6 | 5 | const testing = std.testing; |
| 7 | 6 | const assert = std.debug.assert; |
| 8 | 7 | |
| ... | ... | @@ -11,8 +10,10 @@ pub const std_options: std.Options = .{ |
| 11 | 10 | }; |
| 12 | 11 | |
| 13 | 12 | var log_err_count: usize = 0; |
| 14 | var fba_buffer: [8192]u8 = undefined; | |
| 15 | 13 | var fba = std.heap.FixedBufferAllocator.init(&fba_buffer); |
| 14 | var fba_buffer: [8192]u8 = undefined; | |
| 15 | var stdin_buffer: [4096]u8 = undefined; | |
| 16 | var stdout_buffer: [4096]u8 = undefined; | |
| 16 | 17 | |
| 17 | 18 | const crippled = switch (builtin.zig_backend) { |
| 18 | 19 | .stage2_powerpc, |
| ... | ... | @@ -67,13 +68,13 @@ pub fn main() void { |
| 67 | 68 | |
| 68 | 69 | fn mainServer() !void { |
| 69 | 70 | @disableInstrumentation(); |
| 71 | var stdin_reader = std.fs.File.stdin().readerStreaming(&stdin_buffer); | |
| 72 | var stdout_writer = std.fs.File.stdout().writerStreaming(&stdout_buffer); | |
| 70 | 73 | var server = try std.zig.Server.init(.{ |
| 71 | .gpa = fba.allocator(), | |
| 72 | .in = .stdin(), | |
| 73 | .out = .stdout(), | |
| 74 | .in = &stdin_reader.interface, | |
| 75 | .out = &stdout_writer.interface, | |
| 74 | 76 | .zig_version = builtin.zig_version_string, |
| 75 | 77 | }); |
| 76 | defer server.deinit(); | |
| 77 | 78 | |
| 78 | 79 | if (builtin.fuzz) { |
| 79 | 80 | const coverage_id = fuzzer_coverage_id(); |
| ... | ... | @@ -103,7 +104,7 @@ fn mainServer() !void { |
| 103 | 104 | defer testing.allocator.free(expected_panic_msgs); |
| 104 | 105 | |
| 105 | 106 | for (test_fns, names, expected_panic_msgs) |test_fn, *name, *expected_panic_msg| { |
| 106 | name.* = @as(u32, @intCast(string_bytes.items.len)); | |
| 107 | name.* = @intCast(string_bytes.items.len); | |
| 107 | 108 | try string_bytes.ensureUnusedCapacity(testing.allocator, test_fn.name.len + 1); |
| 108 | 109 | string_bytes.appendSliceAssumeCapacity(test_fn.name); |
| 109 | 110 | string_bytes.appendAssumeCapacity(0); |
lib/std/Build/Step/Run.zig+1-1| ... | ... | @@ -1744,7 +1744,7 @@ fn sendMessage(file: std.fs.File, tag: std.zig.Client.Message.Tag) !void { |
| 1744 | 1744 | .tag = tag, |
| 1745 | 1745 | .bytes_len = 0, |
| 1746 | 1746 | }; |
| 1747 | try file.writeAll(std.mem.asBytes(&header)); | |
| 1747 | try file.writeAll(@ptrCast(&header)); | |
| 1748 | 1748 | } |
| 1749 | 1749 | |
| 1750 | 1750 | fn sendRunTestMessage(file: std.fs.File, tag: std.zig.Client.Message.Tag, index: u32) !void { |
lib/std/Io/Reader.zig+17-17| ... | ... | @@ -1108,9 +1108,9 @@ pub fn takeVarInt(r: *Reader, comptime Int: type, endian: std.builtin.Endian, n: |
| 1108 | 1108 | /// Asserts the buffer was initialized with a capacity at least `@sizeOf(T)`. |
| 1109 | 1109 | /// |
| 1110 | 1110 | /// See also: |
| 1111 | /// * `peekStructReference` | |
| 1111 | /// * `peekStructPointer` | |
| 1112 | 1112 | /// * `takeStruct` |
| 1113 | pub fn takeStructReference(r: *Reader, comptime T: type) Error!*align(1) T { | |
| 1113 | pub fn takeStructPointer(r: *Reader, comptime T: type) Error!*align(1) T { | |
| 1114 | 1114 | // Only extern and packed structs have defined in-memory layout. |
| 1115 | 1115 | comptime assert(@typeInfo(T).@"struct".layout != .auto); |
| 1116 | 1116 | return @ptrCast(try r.takeArray(@sizeOf(T))); |
| ... | ... | @@ -1122,9 +1122,9 @@ pub fn takeStructReference(r: *Reader, comptime T: type) Error!*align(1) T { |
| 1122 | 1122 | /// Asserts the buffer was initialized with a capacity at least `@sizeOf(T)`. |
| 1123 | 1123 | /// |
| 1124 | 1124 | /// See also: |
| 1125 | /// * `takeStructReference` | |
| 1125 | /// * `takeStructPointer` | |
| 1126 | 1126 | /// * `peekStruct` |
| 1127 | pub fn peekStructReference(r: *Reader, comptime T: type) Error!*align(1) T { | |
| 1127 | pub fn peekStructPointer(r: *Reader, comptime T: type) Error!*align(1) T { | |
| 1128 | 1128 | // Only extern and packed structs have defined in-memory layout. |
| 1129 | 1129 | comptime assert(@typeInfo(T).@"struct".layout != .auto); |
| 1130 | 1130 | return @ptrCast(try r.peekArray(@sizeOf(T))); |
| ... | ... | @@ -1136,14 +1136,14 @@ pub fn peekStructReference(r: *Reader, comptime T: type) Error!*align(1) T { |
| 1136 | 1136 | /// when `endian` is comptime-known and matches the host endianness. |
| 1137 | 1137 | /// |
| 1138 | 1138 | /// See also: |
| 1139 | /// * `takeStructReference` | |
| 1139 | /// * `takeStructPointer` | |
| 1140 | 1140 | /// * `peekStruct` |
| 1141 | 1141 | pub inline fn takeStruct(r: *Reader, comptime T: type, endian: std.builtin.Endian) Error!T { |
| 1142 | 1142 | switch (@typeInfo(T)) { |
| 1143 | 1143 | .@"struct" => |info| switch (info.layout) { |
| 1144 | 1144 | .auto => @compileError("ill-defined memory layout"), |
| 1145 | 1145 | .@"extern" => { |
| 1146 | var res = (try r.takeStructReference(T)).*; | |
| 1146 | var res = (try r.takeStructPointer(T)).*; | |
| 1147 | 1147 | if (native_endian != endian) std.mem.byteSwapAllFields(T, &res); |
| 1148 | 1148 | return res; |
| 1149 | 1149 | }, |
| ... | ... | @@ -1162,13 +1162,13 @@ pub inline fn takeStruct(r: *Reader, comptime T: type, endian: std.builtin.Endia |
| 1162 | 1162 | /// |
| 1163 | 1163 | /// See also: |
| 1164 | 1164 | /// * `takeStruct` |
| 1165 | /// * `peekStructReference` | |
| 1165 | /// * `peekStructPointer` | |
| 1166 | 1166 | pub inline fn peekStruct(r: *Reader, comptime T: type, endian: std.builtin.Endian) Error!T { |
| 1167 | 1167 | switch (@typeInfo(T)) { |
| 1168 | 1168 | .@"struct" => |info| switch (info.layout) { |
| 1169 | 1169 | .auto => @compileError("ill-defined memory layout"), |
| 1170 | 1170 | .@"extern" => { |
| 1171 | var res = (try r.peekStructReference(T)).*; | |
| 1171 | var res = (try r.peekStructPointer(T)).*; | |
| 1172 | 1172 | if (native_endian != endian) std.mem.byteSwapAllFields(T, &res); |
| 1173 | 1173 | return res; |
| 1174 | 1174 | }, |
| ... | ... | @@ -1557,27 +1557,27 @@ test takeVarInt { |
| 1557 | 1557 | try testing.expectError(error.EndOfStream, r.takeVarInt(u16, .little, 1)); |
| 1558 | 1558 | } |
| 1559 | 1559 | |
| 1560 | test takeStructReference { | |
| 1560 | test takeStructPointer { | |
| 1561 | 1561 | var r: Reader = .fixed(&.{ 0x12, 0x00, 0x34, 0x56 }); |
| 1562 | 1562 | const S = extern struct { a: u8, b: u16 }; |
| 1563 | 1563 | switch (native_endian) { |
| 1564 | .little => try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x5634 }), (try r.takeStructReference(S)).*), | |
| 1565 | .big => try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x3456 }), (try r.takeStructReference(S)).*), | |
| 1564 | .little => try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x5634 }), (try r.takeStructPointer(S)).*), | |
| 1565 | .big => try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x3456 }), (try r.takeStructPointer(S)).*), | |
| 1566 | 1566 | } |
| 1567 | try testing.expectError(error.EndOfStream, r.takeStructReference(S)); | |
| 1567 | try testing.expectError(error.EndOfStream, r.takeStructPointer(S)); | |
| 1568 | 1568 | } |
| 1569 | 1569 | |
| 1570 | test peekStructReference { | |
| 1570 | test peekStructPointer { | |
| 1571 | 1571 | var r: Reader = .fixed(&.{ 0x12, 0x00, 0x34, 0x56 }); |
| 1572 | 1572 | const S = extern struct { a: u8, b: u16 }; |
| 1573 | 1573 | switch (native_endian) { |
| 1574 | 1574 | .little => { |
| 1575 | try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x5634 }), (try r.peekStructReference(S)).*); | |
| 1576 | try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x5634 }), (try r.peekStructReference(S)).*); | |
| 1575 | try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x5634 }), (try r.peekStructPointer(S)).*); | |
| 1576 | try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x5634 }), (try r.peekStructPointer(S)).*); | |
| 1577 | 1577 | }, |
| 1578 | 1578 | .big => { |
| 1579 | try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x3456 }), (try r.peekStructReference(S)).*); | |
| 1580 | try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x3456 }), (try r.peekStructReference(S)).*); | |
| 1579 | try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x3456 }), (try r.peekStructPointer(S)).*); | |
| 1580 | try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x3456 }), (try r.peekStructPointer(S)).*); | |
| 1581 | 1581 | }, |
| 1582 | 1582 | } |
| 1583 | 1583 | } |
lib/std/Io/Writer.zig+18-1| ... | ... | @@ -860,7 +860,15 @@ pub inline fn writeSliceEndian( |
| 860 | 860 | if (native_endian == endian) { |
| 861 | 861 | return writeAll(w, @ptrCast(slice)); |
| 862 | 862 | } else { |
| 863 | return w.writeArraySwap(w, Elem, slice); | |
| 863 | return writeSliceSwap(w, Elem, slice); | |
| 864 | } | |
| 865 | } | |
| 866 | ||
| 867 | pub fn writeSliceSwap(w: *Writer, Elem: type, slice: []const Elem) Error!void { | |
| 868 | for (slice) |elem| { | |
| 869 | var tmp = elem; | |
| 870 | std.mem.byteSwapAllFields(Elem, &tmp); | |
| 871 | try w.writeAll(@ptrCast(&tmp)); | |
| 864 | 872 | } |
| 865 | 873 | } |
| 866 | 874 | |
| ... | ... | @@ -2638,3 +2646,12 @@ test writeStruct { |
| 2638 | 2646 | }, &buffer); |
| 2639 | 2647 | } |
| 2640 | 2648 | } |
| 2649 | ||
| 2650 | test writeSliceEndian { | |
| 2651 | var buffer: [5]u8 align(2) = undefined; | |
| 2652 | var w: Writer = .fixed(&buffer); | |
| 2653 | try w.writeByte('x'); | |
| 2654 | const array: [2]u16 = .{ 0x1234, 0x5678 }; | |
| 2655 | try writeSliceEndian(&w, u16, &array, .big); | |
| 2656 | try testing.expectEqualSlices(u8, &.{ 'x', 0x12, 0x34, 0x56, 0x78 }, &buffer); | |
| 2657 | } |
lib/std/debug.zig+7| ... | ... | @@ -566,6 +566,13 @@ pub fn assertReadable(slice: []const volatile u8) void { |
| 566 | 566 | for (slice) |*byte| _ = byte.*; |
| 567 | 567 | } |
| 568 | 568 | |
| 569 | /// Invokes detectable illegal behavior when the provided array is not aligned | |
| 570 | /// to the provided amount. | |
| 571 | pub fn assertAligned(ptr: anytype, comptime alignment: std.mem.Alignment) void { | |
| 572 | const aligned_ptr: *align(alignment.toByteUnits()) anyopaque = @alignCast(@ptrCast(ptr)); | |
| 573 | _ = aligned_ptr; | |
| 574 | } | |
| 575 | ||
| 569 | 576 | /// Equivalent to `@panic` but with a formatted message. |
| 570 | 577 | pub fn panic(comptime format: []const u8, args: anytype) noreturn { |
| 571 | 578 | @branchHint(.cold); |
lib/std/mem.zig+20-16| ... | ... | @@ -2179,22 +2179,8 @@ pub fn byteSwapAllFields(comptime S: type, ptr: *S) void { |
| 2179 | 2179 | const BackingInt = std.meta.Int(.unsigned, @bitSizeOf(S)); |
| 2180 | 2180 | ptr.* = @bitCast(@byteSwap(@as(BackingInt, @bitCast(ptr.*)))); |
| 2181 | 2181 | }, |
| 2182 | .array => { | |
| 2183 | for (ptr) |*item| { | |
| 2184 | switch (@typeInfo(@TypeOf(item.*))) { | |
| 2185 | .@"struct", .@"union", .array => byteSwapAllFields(@TypeOf(item.*), item), | |
| 2186 | .@"enum" => { | |
| 2187 | item.* = @enumFromInt(@byteSwap(@intFromEnum(item.*))); | |
| 2188 | }, | |
| 2189 | .bool => {}, | |
| 2190 | .float => |float_info| { | |
| 2191 | item.* = @bitCast(@byteSwap(@as(std.meta.Int(.unsigned, float_info.bits), @bitCast(item.*)))); | |
| 2192 | }, | |
| 2193 | else => { | |
| 2194 | item.* = @byteSwap(item.*); | |
| 2195 | }, | |
| 2196 | } | |
| 2197 | } | |
| 2182 | .array => |info| { | |
| 2183 | byteSwapAllElements(info.child, ptr); | |
| 2198 | 2184 | }, |
| 2199 | 2185 | else => { |
| 2200 | 2186 | ptr.* = @byteSwap(ptr.*); |
| ... | ... | @@ -2258,6 +2244,24 @@ test byteSwapAllFields { |
| 2258 | 2244 | }, k); |
| 2259 | 2245 | } |
| 2260 | 2246 | |
| 2247 | pub fn byteSwapAllElements(comptime Elem: type, slice: []Elem) void { | |
| 2248 | for (slice) |*elem| { | |
| 2249 | switch (@typeInfo(@TypeOf(elem.*))) { | |
| 2250 | .@"struct", .@"union", .array => byteSwapAllFields(@TypeOf(elem.*), elem), | |
| 2251 | .@"enum" => { | |
| 2252 | elem.* = @enumFromInt(@byteSwap(@intFromEnum(elem.*))); | |
| 2253 | }, | |
| 2254 | .bool => {}, | |
| 2255 | .float => |float_info| { | |
| 2256 | elem.* = @bitCast(@byteSwap(@as(std.meta.Int(.unsigned, float_info.bits), @bitCast(elem.*)))); | |
| 2257 | }, | |
| 2258 | else => { | |
| 2259 | elem.* = @byteSwap(elem.*); | |
| 2260 | }, | |
| 2261 | } | |
| 2262 | } | |
| 2263 | } | |
| 2264 | ||
| 2261 | 2265 | /// Returns an iterator that iterates over the slices of `buffer` that are not |
| 2262 | 2266 | /// any of the items in `delimiters`. |
| 2263 | 2267 | /// |
lib/std/zig.zig+1| ... | ... | @@ -908,4 +908,5 @@ test { |
| 908 | 908 | _ = system; |
| 909 | 909 | _ = target; |
| 910 | 910 | _ = c_translation; |
| 911 | _ = llvm; | |
| 911 | 912 | } |
lib/std/zig/LibCInstallation.zig+3-4| ... | ... | @@ -370,7 +370,7 @@ fn findNativeIncludeDirWindows( |
| 370 | 370 | |
| 371 | 371 | for (installs) |install| { |
| 372 | 372 | result_buf.shrinkAndFree(0); |
| 373 | try result_buf.writer().print("{s}\\Include\\{s}\\ucrt", .{ install.path, install.version }); | |
| 373 | try result_buf.print("{s}\\Include\\{s}\\ucrt", .{ install.path, install.version }); | |
| 374 | 374 | |
| 375 | 375 | var dir = fs.cwd().openDir(result_buf.items, .{}) catch |err| switch (err) { |
| 376 | 376 | error.FileNotFound, |
| ... | ... | @@ -417,7 +417,7 @@ fn findNativeCrtDirWindows( |
| 417 | 417 | |
| 418 | 418 | for (installs) |install| { |
| 419 | 419 | result_buf.shrinkAndFree(0); |
| 420 | try result_buf.writer().print("{s}\\Lib\\{s}\\ucrt\\{s}", .{ install.path, install.version, arch_sub_dir }); | |
| 420 | try result_buf.print("{s}\\Lib\\{s}\\ucrt\\{s}", .{ install.path, install.version, arch_sub_dir }); | |
| 421 | 421 | |
| 422 | 422 | var dir = fs.cwd().openDir(result_buf.items, .{}) catch |err| switch (err) { |
| 423 | 423 | error.FileNotFound, |
| ... | ... | @@ -484,8 +484,7 @@ fn findNativeKernel32LibDir( |
| 484 | 484 | |
| 485 | 485 | for (installs) |install| { |
| 486 | 486 | result_buf.shrinkAndFree(0); |
| 487 | const stream = result_buf.writer(); | |
| 488 | try stream.print("{s}\\Lib\\{s}\\um\\{s}", .{ install.path, install.version, arch_sub_dir }); | |
| 487 | try result_buf.print("{s}\\Lib\\{s}\\um\\{s}", .{ install.path, install.version, arch_sub_dir }); | |
| 489 | 488 | |
| 490 | 489 | var dir = fs.cwd().openDir(result_buf.items, .{}) catch |err| switch (err) { |
| 491 | 490 | error.FileNotFound, |
lib/std/zig/Server.zig+57-157| ... | ... | @@ -1,6 +1,20 @@ |
| 1 | in: std.fs.File, | |
| 2 | out: std.fs.File, | |
| 3 | receive_fifo: std.fifo.LinearFifo(u8, .Dynamic), | |
| 1 | const Server = @This(); | |
| 2 | ||
| 3 | const builtin = @import("builtin"); | |
| 4 | ||
| 5 | const std = @import("std"); | |
| 6 | const Allocator = std.mem.Allocator; | |
| 7 | const assert = std.debug.assert; | |
| 8 | const native_endian = builtin.target.cpu.arch.endian(); | |
| 9 | const need_bswap = native_endian != .little; | |
| 10 | const Cache = std.Build.Cache; | |
| 11 | const OutMessage = std.zig.Server.Message; | |
| 12 | const InMessage = std.zig.Client.Message; | |
| 13 | const Reader = std.Io.Reader; | |
| 14 | const Writer = std.Io.Writer; | |
| 15 | ||
| 16 | in: *Reader, | |
| 17 | out: *Writer, | |
| 4 | 18 | |
| 5 | 19 | pub const Message = struct { |
| 6 | 20 | pub const Header = extern struct { |
| ... | ... | @@ -94,9 +108,8 @@ pub const Message = struct { |
| 94 | 108 | }; |
| 95 | 109 | |
| 96 | 110 | pub const Options = struct { |
| 97 | gpa: Allocator, | |
| 98 | in: std.fs.File, | |
| 99 | out: std.fs.File, | |
| 111 | in: *Reader, | |
| 112 | out: *Writer, | |
| 100 | 113 | zig_version: []const u8, |
| 101 | 114 | }; |
| 102 | 115 | |
| ... | ... | @@ -104,96 +117,40 @@ pub fn init(options: Options) !Server { |
| 104 | 117 | var s: Server = .{ |
| 105 | 118 | .in = options.in, |
| 106 | 119 | .out = options.out, |
| 107 | .receive_fifo = std.fifo.LinearFifo(u8, .Dynamic).init(options.gpa), | |
| 108 | 120 | }; |
| 109 | 121 | try s.serveStringMessage(.zig_version, options.zig_version); |
| 110 | 122 | return s; |
| 111 | 123 | } |
| 112 | 124 | |
| 113 | pub fn deinit(s: *Server) void { | |
| 114 | s.receive_fifo.deinit(); | |
| 115 | s.* = undefined; | |
| 116 | } | |
| 117 | ||
| 118 | 125 | pub fn receiveMessage(s: *Server) !InMessage.Header { |
| 119 | const Header = InMessage.Header; | |
| 120 | const fifo = &s.receive_fifo; | |
| 121 | var last_amt_zero = false; | |
| 122 | ||
| 123 | while (true) { | |
| 124 | const buf = fifo.readableSlice(0); | |
| 125 | assert(fifo.readableLength() == buf.len); | |
| 126 | if (buf.len >= @sizeOf(Header)) { | |
| 127 | const header: *align(1) const Header = @ptrCast(buf[0..@sizeOf(Header)]); | |
| 128 | const bytes_len = bswap(header.bytes_len); | |
| 129 | const tag = bswap(header.tag); | |
| 130 | ||
| 131 | if (buf.len - @sizeOf(Header) >= bytes_len) { | |
| 132 | fifo.discard(@sizeOf(Header)); | |
| 133 | return .{ | |
| 134 | .tag = tag, | |
| 135 | .bytes_len = bytes_len, | |
| 136 | }; | |
| 137 | } else { | |
| 138 | const needed = bytes_len - (buf.len - @sizeOf(Header)); | |
| 139 | const write_buffer = try fifo.writableWithSize(needed); | |
| 140 | const amt = try s.in.read(write_buffer); | |
| 141 | fifo.update(amt); | |
| 142 | continue; | |
| 143 | } | |
| 144 | } | |
| 145 | ||
| 146 | const write_buffer = try fifo.writableWithSize(256); | |
| 147 | const amt = try s.in.read(write_buffer); | |
| 148 | fifo.update(amt); | |
| 149 | if (amt == 0) { | |
| 150 | if (last_amt_zero) return error.BrokenPipe; | |
| 151 | last_amt_zero = true; | |
| 152 | } | |
| 153 | } | |
| 126 | return s.in.takeStruct(InMessage.Header, .little); | |
| 154 | 127 | } |
| 155 | 128 | |
| 156 | 129 | pub fn receiveBody_u32(s: *Server) !u32 { |
| 157 | const fifo = &s.receive_fifo; | |
| 158 | const buf = fifo.readableSlice(0); | |
| 159 | const result = @as(*align(1) const u32, @ptrCast(buf[0..4])).*; | |
| 160 | fifo.discard(4); | |
| 161 | return bswap(result); | |
| 130 | return s.in.takeInt(u32, .little); | |
| 162 | 131 | } |
| 163 | 132 | |
| 164 | 133 | pub fn serveStringMessage(s: *Server, tag: OutMessage.Tag, msg: []const u8) !void { |
| 165 | return s.serveMessage(.{ | |
| 134 | try s.serveMessageHeader(.{ | |
| 166 | 135 | .tag = tag, |
| 167 | .bytes_len = @as(u32, @intCast(msg.len)), | |
| 168 | }, &.{msg}); | |
| 136 | .bytes_len = @intCast(msg.len), | |
| 137 | }); | |
| 138 | try s.out.writeAll(msg); | |
| 139 | try s.out.flush(); | |
| 169 | 140 | } |
| 170 | 141 | |
| 171 | pub fn serveMessage( | |
| 172 | s: *const Server, | |
| 173 | header: OutMessage.Header, | |
| 174 | bufs: []const []const u8, | |
| 175 | ) !void { | |
| 176 | var iovecs: [10]std.posix.iovec_const = undefined; | |
| 177 | const header_le = bswap(header); | |
| 178 | iovecs[0] = .{ | |
| 179 | .base = @as([*]const u8, @ptrCast(&header_le)), | |
| 180 | .len = @sizeOf(OutMessage.Header), | |
| 181 | }; | |
| 182 | for (bufs, iovecs[1 .. bufs.len + 1]) |buf, *iovec| { | |
| 183 | iovec.* = .{ | |
| 184 | .base = buf.ptr, | |
| 185 | .len = buf.len, | |
| 186 | }; | |
| 187 | } | |
| 188 | try s.out.writevAll(iovecs[0 .. bufs.len + 1]); | |
| 142 | /// Don't forget to flush! | |
| 143 | pub fn serveMessageHeader(s: *const Server, header: OutMessage.Header) !void { | |
| 144 | try s.out.writeStruct(header, .little); | |
| 189 | 145 | } |
| 190 | 146 | |
| 191 | pub fn serveU64Message(s: *Server, tag: OutMessage.Tag, int: u64) !void { | |
| 192 | const msg_le = bswap(int); | |
| 193 | return s.serveMessage(.{ | |
| 147 | pub fn serveU64Message(s: *const Server, tag: OutMessage.Tag, int: u64) !void { | |
| 148 | try serveMessageHeader(s, .{ | |
| 194 | 149 | .tag = tag, |
| 195 | 150 | .bytes_len = @sizeOf(u64), |
| 196 | }, &.{std.mem.asBytes(&msg_le)}); | |
| 151 | }); | |
| 152 | try s.out.writeInt(u64, int, .little); | |
| 153 | try s.out.flush(); | |
| 197 | 154 | } |
| 198 | 155 | |
| 199 | 156 | pub fn serveEmitDigest( |
| ... | ... | @@ -201,26 +158,22 @@ pub fn serveEmitDigest( |
| 201 | 158 | digest: *const [Cache.bin_digest_len]u8, |
| 202 | 159 | header: OutMessage.EmitDigest, |
| 203 | 160 | ) !void { |
| 204 | try s.serveMessage(.{ | |
| 161 | try s.serveMessageHeader(.{ | |
| 205 | 162 | .tag = .emit_digest, |
| 206 | 163 | .bytes_len = @intCast(digest.len + @sizeOf(OutMessage.EmitDigest)), |
| 207 | }, &.{ | |
| 208 | std.mem.asBytes(&header), | |
| 209 | digest, | |
| 210 | 164 | }); |
| 165 | try s.out.writeStruct(header, .little); | |
| 166 | try s.out.writeAll(digest); | |
| 167 | try s.out.flush(); | |
| 211 | 168 | } |
| 212 | 169 | |
| 213 | pub fn serveTestResults( | |
| 214 | s: *Server, | |
| 215 | msg: OutMessage.TestResults, | |
| 216 | ) !void { | |
| 217 | const msg_le = bswap(msg); | |
| 218 | try s.serveMessage(.{ | |
| 170 | pub fn serveTestResults(s: *Server, msg: OutMessage.TestResults) !void { | |
| 171 | try s.serveMessageHeader(.{ | |
| 219 | 172 | .tag = .test_results, |
| 220 | 173 | .bytes_len = @intCast(@sizeOf(OutMessage.TestResults)), |
| 221 | }, &.{ | |
| 222 | std.mem.asBytes(&msg_le), | |
| 223 | 174 | }); |
| 175 | try s.out.writeStruct(msg, .little); | |
| 176 | try s.out.flush(); | |
| 224 | 177 | } |
| 225 | 178 | |
| 226 | 179 | pub fn serveErrorBundle(s: *Server, error_bundle: std.zig.ErrorBundle) !void { |
| ... | ... | @@ -230,91 +183,38 @@ pub fn serveErrorBundle(s: *Server, error_bundle: std.zig.ErrorBundle) !void { |
| 230 | 183 | }; |
| 231 | 184 | const bytes_len = @sizeOf(OutMessage.ErrorBundle) + |
| 232 | 185 | 4 * error_bundle.extra.len + error_bundle.string_bytes.len; |
| 233 | try s.serveMessage(.{ | |
| 186 | try s.serveMessageHeader(.{ | |
| 234 | 187 | .tag = .error_bundle, |
| 235 | 188 | .bytes_len = @intCast(bytes_len), |
| 236 | }, &.{ | |
| 237 | std.mem.asBytes(&eb_hdr), | |
| 238 | // TODO: implement @ptrCast between slices changing the length | |
| 239 | std.mem.sliceAsBytes(error_bundle.extra), | |
| 240 | error_bundle.string_bytes, | |
| 241 | 189 | }); |
| 190 | try s.out.writeStruct(eb_hdr, .little); | |
| 191 | try s.out.writeSliceEndian(u32, error_bundle.extra, .little); | |
| 192 | try s.out.writeAll(error_bundle.string_bytes); | |
| 193 | try s.out.flush(); | |
| 242 | 194 | } |
| 243 | 195 | |
| 244 | 196 | pub const TestMetadata = struct { |
| 245 | names: []u32, | |
| 246 | expected_panic_msgs: []u32, | |
| 197 | names: []const u32, | |
| 198 | expected_panic_msgs: []const u32, | |
| 247 | 199 | string_bytes: []const u8, |
| 248 | 200 | }; |
| 249 | 201 | |
| 250 | 202 | pub fn serveTestMetadata(s: *Server, test_metadata: TestMetadata) !void { |
| 251 | 203 | const header: OutMessage.TestMetadata = .{ |
| 252 | .tests_len = bswap(@as(u32, @intCast(test_metadata.names.len))), | |
| 253 | .string_bytes_len = bswap(@as(u32, @intCast(test_metadata.string_bytes.len))), | |
| 204 | .tests_len = @intCast(test_metadata.names.len), | |
| 205 | .string_bytes_len = @intCast(test_metadata.string_bytes.len), | |
| 254 | 206 | }; |
| 255 | 207 | const trailing = 2; |
| 256 | 208 | const bytes_len = @sizeOf(OutMessage.TestMetadata) + |
| 257 | 209 | trailing * @sizeOf(u32) * test_metadata.names.len + test_metadata.string_bytes.len; |
| 258 | 210 | |
| 259 | if (need_bswap) { | |
| 260 | bswap_u32_array(test_metadata.names); | |
| 261 | bswap_u32_array(test_metadata.expected_panic_msgs); | |
| 262 | } | |
| 263 | defer if (need_bswap) { | |
| 264 | bswap_u32_array(test_metadata.names); | |
| 265 | bswap_u32_array(test_metadata.expected_panic_msgs); | |
| 266 | }; | |
| 267 | ||
| 268 | return s.serveMessage(.{ | |
| 211 | try s.serveMessageHeader(.{ | |
| 269 | 212 | .tag = .test_metadata, |
| 270 | 213 | .bytes_len = @intCast(bytes_len), |
| 271 | }, &.{ | |
| 272 | std.mem.asBytes(&header), | |
| 273 | // TODO: implement @ptrCast between slices changing the length | |
| 274 | std.mem.sliceAsBytes(test_metadata.names), | |
| 275 | std.mem.sliceAsBytes(test_metadata.expected_panic_msgs), | |
| 276 | test_metadata.string_bytes, | |
| 277 | 214 | }); |
| 215 | try s.out.writeStruct(header, .little); | |
| 216 | try s.out.writeSliceEndian(u32, test_metadata.names, .little); | |
| 217 | try s.out.writeSliceEndian(u32, test_metadata.expected_panic_msgs, .little); | |
| 218 | try s.out.writeAll(test_metadata.string_bytes); | |
| 219 | try s.out.flush(); | |
| 278 | 220 | } |
| 279 | ||
| 280 | fn bswap(x: anytype) @TypeOf(x) { | |
| 281 | if (!need_bswap) return x; | |
| 282 | ||
| 283 | const T = @TypeOf(x); | |
| 284 | switch (@typeInfo(T)) { | |
| 285 | .@"enum" => return @as(T, @enumFromInt(@byteSwap(@intFromEnum(x)))), | |
| 286 | .int => return @byteSwap(x), | |
| 287 | .@"struct" => |info| switch (info.layout) { | |
| 288 | .@"extern" => { | |
| 289 | var result: T = undefined; | |
| 290 | inline for (info.fields) |field| { | |
| 291 | @field(result, field.name) = bswap(@field(x, field.name)); | |
| 292 | } | |
| 293 | return result; | |
| 294 | }, | |
| 295 | .@"packed" => { | |
| 296 | const I = info.backing_integer.?; | |
| 297 | return @as(T, @bitCast(@byteSwap(@as(I, @bitCast(x))))); | |
| 298 | }, | |
| 299 | .auto => @compileError("auto layout struct"), | |
| 300 | }, | |
| 301 | else => @compileError("bswap on type " ++ @typeName(T)), | |
| 302 | } | |
| 303 | } | |
| 304 | ||
| 305 | fn bswap_u32_array(slice: []u32) void { | |
| 306 | comptime assert(need_bswap); | |
| 307 | for (slice) |*elem| elem.* = @byteSwap(elem.*); | |
| 308 | } | |
| 309 | ||
| 310 | const OutMessage = std.zig.Server.Message; | |
| 311 | const InMessage = std.zig.Client.Message; | |
| 312 | ||
| 313 | const Server = @This(); | |
| 314 | const builtin = @import("builtin"); | |
| 315 | const std = @import("std"); | |
| 316 | const Allocator = std.mem.Allocator; | |
| 317 | const assert = std.debug.assert; | |
| 318 | const native_endian = builtin.target.cpu.arch.endian(); | |
| 319 | const need_bswap = native_endian != .little; | |
| 320 | const Cache = std.Build.Cache; |
lib/std/zig/WindowsSdk.zig+7-7| ... | ... | @@ -1,11 +1,12 @@ |
| 1 | const WindowsSdk = @This(); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const std = @import("std"); | |
| 4 | const Writer = std.Io.Writer; | |
| 5 | ||
| 1 | 6 | windows10sdk: ?Installation, |
| 2 | 7 | windows81sdk: ?Installation, |
| 3 | 8 | msvc_lib_dir: ?[]const u8, |
| 4 | 9 | |
| 5 | const WindowsSdk = @This(); | |
| 6 | const std = @import("std"); | |
| 7 | const builtin = @import("builtin"); | |
| 8 | ||
| 9 | 10 | const windows = std.os.windows; |
| 10 | 11 | const RRF = windows.advapi32.RRF; |
| 11 | 12 | |
| ... | ... | @@ -759,14 +760,13 @@ const MsvcLibDir = struct { |
| 759 | 760 | while (instances_dir_it.next() catch return error.PathNotFound) |entry| { |
| 760 | 761 | if (entry.kind != .directory) continue; |
| 761 | 762 | |
| 762 | var fbs = std.io.fixedBufferStream(&state_subpath_buf); | |
| 763 | const writer = fbs.writer(); | |
| 763 | var writer: Writer = .fixed(&state_subpath_buf); | |
| 764 | 764 | |
| 765 | 765 | writer.writeAll(entry.name) catch unreachable; |
| 766 | 766 | writer.writeByte(std.fs.path.sep) catch unreachable; |
| 767 | 767 | writer.writeAll("state.json") catch unreachable; |
| 768 | 768 | |
| 769 | const json_contents = instances_dir.readFileAlloc(allocator, fbs.getWritten(), std.math.maxInt(usize)) catch continue; | |
| 769 | const json_contents = instances_dir.readFileAlloc(allocator, writer.buffered(), std.math.maxInt(usize)) catch continue; | |
| 770 | 770 | defer allocator.free(json_contents); |
| 771 | 771 | |
| 772 | 772 | var parsed = std.json.parseFromSlice(std.json.Value, allocator, json_contents, .{}) catch continue; |
lib/std/zig/llvm.zig+6| ... | ... | @@ -1,3 +1,9 @@ |
| 1 | 1 | pub const BitcodeReader = @import("llvm/BitcodeReader.zig"); |
| 2 | 2 | pub const bitcode_writer = @import("llvm/bitcode_writer.zig"); |
| 3 | 3 | pub const Builder = @import("llvm/Builder.zig"); |
| 4 | ||
| 5 | test { | |
| 6 | _ = BitcodeReader; | |
| 7 | _ = bitcode_writer; | |
| 8 | _ = Builder; | |
| 9 | } |
lib/std/zig/llvm/BitcodeReader.zig+16-12| ... | ... | @@ -1,6 +1,11 @@ |
| 1 | const BitcodeReader = @This(); | |
| 2 | ||
| 3 | const std = @import("../../std.zig"); | |
| 4 | const assert = std.debug.assert; | |
| 5 | ||
| 1 | 6 | allocator: std.mem.Allocator, |
| 2 | 7 | record_arena: std.heap.ArenaAllocator.State, |
| 3 | reader: std.io.AnyReader, | |
| 8 | reader: *std.Io.Reader, | |
| 4 | 9 | keep_names: bool, |
| 5 | 10 | bit_buffer: u32, |
| 6 | 11 | bit_offset: u5, |
| ... | ... | @@ -93,7 +98,7 @@ pub const Record = struct { |
| 93 | 98 | }; |
| 94 | 99 | |
| 95 | 100 | pub const InitOptions = struct { |
| 96 | reader: std.io.AnyReader, | |
| 101 | reader: *std.Io.Reader, | |
| 97 | 102 | keep_names: bool = false, |
| 98 | 103 | }; |
| 99 | 104 | pub fn init(allocator: std.mem.Allocator, options: InitOptions) BitcodeReader { |
| ... | ... | @@ -172,7 +177,7 @@ pub fn next(bc: *BitcodeReader) !?Item { |
| 172 | 177 | |
| 173 | 178 | pub fn skipBlock(bc: *BitcodeReader, block: Block) !void { |
| 174 | 179 | assert(bc.bit_offset == 0); |
| 175 | try bc.reader.skipBytes(@as(u34, block.len) * 4, .{}); | |
| 180 | try bc.reader.discardAll(4 * @as(usize, block.len)); | |
| 176 | 181 | try bc.endBlock(); |
| 177 | 182 | } |
| 178 | 183 | |
| ... | ... | @@ -371,19 +376,19 @@ fn align32Bits(bc: *BitcodeReader) void { |
| 371 | 376 | |
| 372 | 377 | fn read32Bits(bc: *BitcodeReader) !u32 { |
| 373 | 378 | assert(bc.bit_offset == 0); |
| 374 | return bc.reader.readInt(u32, .little); | |
| 379 | return bc.reader.takeInt(u32, .little); | |
| 375 | 380 | } |
| 376 | 381 | |
| 377 | 382 | fn readBytes(bc: *BitcodeReader, bytes: []u8) !void { |
| 378 | 383 | assert(bc.bit_offset == 0); |
| 379 | try bc.reader.readNoEof(bytes); | |
| 384 | try bc.reader.readSliceAll(bytes); | |
| 380 | 385 | |
| 381 | 386 | const trailing_bytes = bytes.len % 4; |
| 382 | 387 | if (trailing_bytes > 0) { |
| 383 | var bit_buffer = [1]u8{0} ** 4; | |
| 384 | try bc.reader.readNoEof(bit_buffer[trailing_bytes..]); | |
| 388 | var bit_buffer: [4]u8 = @splat(0); | |
| 389 | try bc.reader.readSliceAll(bit_buffer[trailing_bytes..]); | |
| 385 | 390 | bc.bit_buffer = std.mem.readInt(u32, &bit_buffer, .little); |
| 386 | bc.bit_offset = @intCast(trailing_bytes * 8); | |
| 391 | bc.bit_offset = @intCast(8 * trailing_bytes); | |
| 387 | 392 | } |
| 388 | 393 | } |
| 389 | 394 | |
| ... | ... | @@ -509,7 +514,6 @@ const Abbrev = struct { |
| 509 | 514 | }; |
| 510 | 515 | }; |
| 511 | 516 | |
| 512 | const assert = std.debug.assert; | |
| 513 | const std = @import("../../std.zig"); | |
| 514 | ||
| 515 | const BitcodeReader = @This(); | |
| 517 | test { | |
| 518 | _ = &skipBlock; | |
| 519 | } |
lib/std/zig/perf_test.zig+6-8| ... | ... | @@ -1,7 +1,6 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | 2 | const mem = std.mem; |
| 3 | 3 | const Tokenizer = std.zig.Tokenizer; |
| 4 | const io = std.io; | |
| 5 | 4 | const fmtIntSizeBin = std.fmt.fmtIntSizeBin; |
| 6 | 5 | |
| 7 | 6 | const source = @embedFile("../os.zig"); |
| ... | ... | @@ -22,16 +21,15 @@ pub fn main() !void { |
| 22 | 21 | const bytes_per_sec_float = @as(f64, @floatFromInt(source.len * iterations)) / elapsed_s; |
| 23 | 22 | const bytes_per_sec = @as(u64, @intFromFloat(@floor(bytes_per_sec_float))); |
| 24 | 23 | |
| 25 | var stdout_file: std.fs.File = .stdout(); | |
| 26 | const stdout = stdout_file.deprecatedWriter(); | |
| 27 | try stdout.print("parsing speed: {:.2}/s, {:.2} used \n", .{ | |
| 28 | fmtIntSizeBin(bytes_per_sec), | |
| 29 | fmtIntSizeBin(memory_used), | |
| 30 | }); | |
| 24 | var stdout_buffer: [1024]u8 = undefined; | |
| 25 | var stdout_writer = std.fs.File.stdout().writer(&stdout_buffer); | |
| 26 | const stdout = &stdout_writer.interface; | |
| 27 | try stdout.print("parsing speed: {Bi:.2}/s, {Bi:.2} used \n", .{ bytes_per_sec, memory_used }); | |
| 28 | try stdout.flush(); | |
| 31 | 29 | } |
| 32 | 30 | |
| 33 | 31 | fn testOnce() usize { |
| 34 | var fixed_buf_alloc = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]); | |
| 32 | var fixed_buf_alloc = std.heap.FixedBufferAllocator.init(&fixed_buffer_mem); | |
| 35 | 33 | const allocator = fixed_buf_alloc.allocator(); |
| 36 | 34 | _ = std.zig.Ast.parse(allocator, source, .zig) catch @panic("parse failure"); |
| 37 | 35 | return fixed_buf_alloc.end_index; |
lib/std/zig/system/linux.zig+17-18| ... | ... | @@ -1,7 +1,6 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | 3 | const mem = std.mem; |
| 4 | const io = std.io; | |
| 5 | 4 | const fs = std.fs; |
| 6 | 5 | const fmt = std.fmt; |
| 7 | 6 | const testing = std.testing; |
| ... | ... | @@ -344,8 +343,8 @@ fn testParser( |
| 344 | 343 | expected_model: *const Target.Cpu.Model, |
| 345 | 344 | input: []const u8, |
| 346 | 345 | ) !void { |
| 347 | var fbs = io.fixedBufferStream(input); | |
| 348 | const result = try parser.parse(arch, fbs.reader()); | |
| 346 | var r: std.Io.Reader = .fixed(input); | |
| 347 | const result = try parser.parse(arch, &r); | |
| 349 | 348 | try testing.expectEqual(expected_model, result.?.model); |
| 350 | 349 | try testing.expect(expected_model.features.eql(result.?.features)); |
| 351 | 350 | } |
| ... | ... | @@ -357,20 +356,17 @@ fn testParser( |
| 357 | 356 | // When all the lines have been analyzed the finalize method is called. |
| 358 | 357 | fn CpuinfoParser(comptime impl: anytype) type { |
| 359 | 358 | return struct { |
| 360 | fn parse(arch: Target.Cpu.Arch, reader: anytype) anyerror!?Target.Cpu { | |
| 361 | var line_buf: [1024]u8 = undefined; | |
| 359 | fn parse(arch: Target.Cpu.Arch, reader: *std.Io.Reader) !?Target.Cpu { | |
| 362 | 360 | var obj: impl = .{}; |
| 363 | ||
| 364 | while (true) { | |
| 365 | const line = (try reader.readUntilDelimiterOrEof(&line_buf, '\n')) orelse break; | |
| 361 | while (reader.takeDelimiterExclusive('\n')) |line| { | |
| 366 | 362 | const colon_pos = mem.indexOfScalar(u8, line, ':') orelse continue; |
| 367 | 363 | const key = mem.trimEnd(u8, line[0..colon_pos], " \t"); |
| 368 | 364 | const value = mem.trimStart(u8, line[colon_pos + 1 ..], " \t"); |
| 369 | ||
| 370 | if (!try obj.line_hook(key, value)) | |
| 371 | break; | |
| 365 | if (!try obj.line_hook(key, value)) break; | |
| 366 | } else |err| switch (err) { | |
| 367 | error.EndOfStream => {}, | |
| 368 | else => |e| return e, | |
| 372 | 369 | } |
| 373 | ||
| 374 | 370 | return obj.finalize(arch); |
| 375 | 371 | } |
| 376 | 372 | }; |
| ... | ... | @@ -383,15 +379,18 @@ inline fn getAArch64CpuFeature(comptime feat_reg: []const u8) u64 { |
| 383 | 379 | } |
| 384 | 380 | |
| 385 | 381 | pub fn detectNativeCpuAndFeatures() ?Target.Cpu { |
| 386 | var f = fs.openFileAbsolute("/proc/cpuinfo", .{}) catch |err| switch (err) { | |
| 382 | var file = fs.openFileAbsolute("/proc/cpuinfo", .{}) catch |err| switch (err) { | |
| 387 | 383 | else => return null, |
| 388 | 384 | }; |
| 389 | defer f.close(); | |
| 385 | defer file.close(); | |
| 386 | ||
| 387 | var buffer: [4096]u8 = undefined; // "flags" lines can get pretty long. | |
| 388 | var file_reader = file.reader(&buffer); | |
| 390 | 389 | |
| 391 | 390 | const current_arch = builtin.cpu.arch; |
| 392 | 391 | switch (current_arch) { |
| 393 | 392 | .arm, .armeb, .thumb, .thumbeb => { |
| 394 | return ArmCpuinfoParser.parse(current_arch, f.deprecatedReader()) catch null; | |
| 393 | return ArmCpuinfoParser.parse(current_arch, &file_reader.interface) catch null; | |
| 395 | 394 | }, |
| 396 | 395 | .aarch64, .aarch64_be => { |
| 397 | 396 | const registers = [12]u64{ |
| ... | ... | @@ -413,13 +412,13 @@ pub fn detectNativeCpuAndFeatures() ?Target.Cpu { |
| 413 | 412 | return core; |
| 414 | 413 | }, |
| 415 | 414 | .sparc64 => { |
| 416 | return SparcCpuinfoParser.parse(current_arch, f.deprecatedReader()) catch null; | |
| 415 | return SparcCpuinfoParser.parse(current_arch, &file_reader.interface) catch null; | |
| 417 | 416 | }, |
| 418 | 417 | .powerpc, .powerpcle, .powerpc64, .powerpc64le => { |
| 419 | return PowerpcCpuinfoParser.parse(current_arch, f.deprecatedReader()) catch null; | |
| 418 | return PowerpcCpuinfoParser.parse(current_arch, &file_reader.interface) catch null; | |
| 420 | 419 | }, |
| 421 | 420 | .riscv64, .riscv32 => { |
| 422 | return RiscvCpuinfoParser.parse(current_arch, f.deprecatedReader()) catch null; | |
| 421 | return RiscvCpuinfoParser.parse(current_arch, &file_reader.interface) catch null; | |
| 423 | 422 | }, |
| 424 | 423 | else => {}, |
| 425 | 424 | } |
src/Compilation.zig+41-40| ... | ... | @@ -12,6 +12,7 @@ const ThreadPool = std.Thread.Pool; |
| 12 | 12 | const WaitGroup = std.Thread.WaitGroup; |
| 13 | 13 | const ErrorBundle = std.zig.ErrorBundle; |
| 14 | 14 | const fatal = std.process.fatal; |
| 15 | const Writer = std.io.Writer; | |
| 15 | 16 | |
| 16 | 17 | const Value = @import("Value.zig"); |
| 17 | 18 | const Type = @import("Type.zig"); |
| ... | ... | @@ -44,6 +45,8 @@ const Builtin = @import("Builtin.zig"); |
| 44 | 45 | const LlvmObject = @import("codegen/llvm.zig").Object; |
| 45 | 46 | const dev = @import("dev.zig"); |
| 46 | 47 | |
| 48 | const DeprecatedLinearFifo = @import("deprecated.zig").LinearFifo; | |
| 49 | ||
| 47 | 50 | pub const Config = @import("Compilation/Config.zig"); |
| 48 | 51 | |
| 49 | 52 | /// General-purpose allocator. Used for both temporary and long-term storage. |
| ... | ... | @@ -121,15 +124,15 @@ work_queues: [ |
| 121 | 124 | } |
| 122 | 125 | break :len len; |
| 123 | 126 | } |
| 124 | ]std.fifo.LinearFifo(Job, .Dynamic), | |
| 127 | ]DeprecatedLinearFifo(Job), | |
| 125 | 128 | |
| 126 | 129 | /// These jobs are to invoke the Clang compiler to create an object file, which |
| 127 | 130 | /// gets linked with the Compilation. |
| 128 | c_object_work_queue: std.fifo.LinearFifo(*CObject, .Dynamic), | |
| 131 | c_object_work_queue: DeprecatedLinearFifo(*CObject), | |
| 129 | 132 | |
| 130 | 133 | /// These jobs are to invoke the RC compiler to create a compiled resource file (.res), which |
| 131 | 134 | /// gets linked with the Compilation. |
| 132 | win32_resource_work_queue: if (dev.env.supports(.win32_resource)) std.fifo.LinearFifo(*Win32Resource, .Dynamic) else struct { | |
| 135 | win32_resource_work_queue: if (dev.env.supports(.win32_resource)) DeprecatedLinearFifo(*Win32Resource) else struct { | |
| 133 | 136 | pub fn ensureUnusedCapacity(_: @This(), _: u0) error{}!void {} |
| 134 | 137 | pub fn readItem(_: @This()) ?noreturn { |
| 135 | 138 | return null; |
| ... | ... | @@ -995,13 +998,13 @@ pub const CObject = struct { |
| 995 | 998 | |
| 996 | 999 | const file = fs.cwd().openFile(file_name, .{}) catch break :source_line 0; |
| 997 | 1000 | defer file.close(); |
| 998 | file.seekTo(diag.src_loc.offset + 1 - diag.src_loc.column) catch break :source_line 0; | |
| 999 | ||
| 1000 | var line = std.ArrayList(u8).init(eb.gpa); | |
| 1001 | defer line.deinit(); | |
| 1002 | file.deprecatedReader().readUntilDelimiterArrayList(&line, '\n', 1 << 10) catch break :source_line 0; | |
| 1003 | ||
| 1004 | break :source_line try eb.addString(line.items); | |
| 1001 | var buffer: [1024]u8 = undefined; | |
| 1002 | var file_reader = file.reader(&buffer); | |
| 1003 | file_reader.seekTo(diag.src_loc.offset + 1 - diag.src_loc.column) catch break :source_line 0; | |
| 1004 | var aw: Writer.Allocating = .init(eb.gpa); | |
| 1005 | defer aw.deinit(); | |
| 1006 | _ = file_reader.interface.streamDelimiterEnding(&aw.writer, '\n') catch break :source_line 0; | |
| 1007 | break :source_line try eb.addString(aw.getWritten()); | |
| 1005 | 1008 | }; |
| 1006 | 1009 | |
| 1007 | 1010 | return .{ |
| ... | ... | @@ -1067,11 +1070,11 @@ pub const CObject = struct { |
| 1067 | 1070 | } |
| 1068 | 1071 | }; |
| 1069 | 1072 | |
| 1073 | var buffer: [1024]u8 = undefined; | |
| 1070 | 1074 | const file = try fs.cwd().openFile(path, .{}); |
| 1071 | 1075 | defer file.close(); |
| 1072 | var br = std.io.bufferedReader(file.deprecatedReader()); | |
| 1073 | const reader = br.reader(); | |
| 1074 | var bc = std.zig.llvm.BitcodeReader.init(gpa, .{ .reader = reader.any() }); | |
| 1076 | var file_reader = file.reader(&buffer); | |
| 1077 | var bc = std.zig.llvm.BitcodeReader.init(gpa, .{ .reader = &file_reader.interface }); | |
| 1075 | 1078 | defer bc.deinit(); |
| 1076 | 1079 | |
| 1077 | 1080 | var file_names: std.AutoArrayHashMapUnmanaged(u32, []const u8) = .empty; |
| ... | ... | @@ -1873,15 +1876,12 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1873 | 1876 | |
| 1874 | 1877 | if (options.verbose_llvm_cpu_features) { |
| 1875 | 1878 | if (options.root_mod.resolved_target.llvm_cpu_features) |cf| print: { |
| 1876 | std.debug.lockStdErr(); | |
| 1877 | defer std.debug.unlockStdErr(); | |
| 1878 | const stderr = fs.File.stderr().deprecatedWriter(); | |
| 1879 | nosuspend { | |
| 1880 | stderr.print("compilation: {s}\n", .{options.root_name}) catch break :print; | |
| 1881 | stderr.print(" target: {s}\n", .{try target.zigTriple(arena)}) catch break :print; | |
| 1882 | stderr.print(" cpu: {s}\n", .{target.cpu.model.name}) catch break :print; | |
| 1883 | stderr.print(" features: {s}\n", .{cf}) catch {}; | |
| 1884 | } | |
| 1879 | const stderr_w = std.debug.lockStderrWriter(&.{}); | |
| 1880 | defer std.debug.unlockStderrWriter(); | |
| 1881 | stderr_w.print("compilation: {s}\n", .{options.root_name}) catch break :print; | |
| 1882 | stderr_w.print(" target: {s}\n", .{try target.zigTriple(arena)}) catch break :print; | |
| 1883 | stderr_w.print(" cpu: {s}\n", .{target.cpu.model.name}) catch break :print; | |
| 1884 | stderr_w.print(" features: {s}\n", .{cf}) catch {}; | |
| 1885 | 1885 | } |
| 1886 | 1886 | } |
| 1887 | 1887 | |
| ... | ... | @@ -2483,7 +2483,7 @@ pub fn destroy(comp: *Compilation) void { |
| 2483 | 2483 | if (comp.zcu) |zcu| zcu.deinit(); |
| 2484 | 2484 | comp.cache_use.deinit(); |
| 2485 | 2485 | |
| 2486 | for (comp.work_queues) |work_queue| work_queue.deinit(); | |
| 2486 | for (&comp.work_queues) |*work_queue| work_queue.deinit(); | |
| 2487 | 2487 | comp.c_object_work_queue.deinit(); |
| 2488 | 2488 | comp.win32_resource_work_queue.deinit(); |
| 2489 | 2489 | |
| ... | ... | @@ -3931,11 +3931,12 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle { |
| 3931 | 3931 | // This AU is referenced and has a transitive compile error, meaning it referenced something with a compile error. |
| 3932 | 3932 | // However, we haven't reported any such error. |
| 3933 | 3933 | // This is a compiler bug. |
| 3934 | const stderr = fs.File.stderr().deprecatedWriter(); | |
| 3935 | try stderr.writeAll("referenced transitive analysis errors, but none actually emitted\n"); | |
| 3936 | try stderr.print("{f} [transitive failure]\n", .{zcu.fmtAnalUnit(failed_unit)}); | |
| 3934 | var stderr_w = std.debug.lockStderrWriter(&.{}); | |
| 3935 | defer std.debug.unlockStderrWriter(); | |
| 3936 | try stderr_w.writeAll("referenced transitive analysis errors, but none actually emitted\n"); | |
| 3937 | try stderr_w.print("{f} [transitive failure]\n", .{zcu.fmtAnalUnit(failed_unit)}); | |
| 3937 | 3938 | while (ref) |r| { |
| 3938 | try stderr.print("referenced by: {f}{s}\n", .{ | |
| 3939 | try stderr_w.print("referenced by: {f}{s}\n", .{ | |
| 3939 | 3940 | zcu.fmtAnalUnit(r.referencer), |
| 3940 | 3941 | if (zcu.transitive_failed_analysis.contains(r.referencer)) " [transitive failure]" else "", |
| 3941 | 3942 | }); |
| ... | ... | @@ -6213,13 +6214,10 @@ fn spawnZigRc( |
| 6213 | 6214 | const stdout = poller.fifo(.stdout); |
| 6214 | 6215 | |
| 6215 | 6216 | poll: while (true) { |
| 6216 | while (stdout.readableLength() < @sizeOf(std.zig.Server.Message.Header)) { | |
| 6217 | if (!(try poller.poll())) break :poll; | |
| 6218 | } | |
| 6219 | const header = stdout.reader().readStruct(std.zig.Server.Message.Header) catch unreachable; | |
| 6220 | while (stdout.readableLength() < header.bytes_len) { | |
| 6221 | if (!(try poller.poll())) break :poll; | |
| 6222 | } | |
| 6217 | while (stdout.readableLength() < @sizeOf(std.zig.Server.Message.Header)) if (!try poller.poll()) break :poll; | |
| 6218 | var header: std.zig.Server.Message.Header = undefined; | |
| 6219 | assert(stdout.read(std.mem.asBytes(&header)) == @sizeOf(std.zig.Server.Message.Header)); | |
| 6220 | while (stdout.readableLength() < header.bytes_len) if (!try poller.poll()) break :poll; | |
| 6223 | 6221 | const body = stdout.readableSliceOfLen(header.bytes_len); |
| 6224 | 6222 | |
| 6225 | 6223 | switch (header.tag) { |
| ... | ... | @@ -7209,13 +7207,16 @@ pub fn lockAndSetMiscFailure( |
| 7209 | 7207 | } |
| 7210 | 7208 | |
| 7211 | 7209 | pub fn dump_argv(argv: []const []const u8) void { |
| 7212 | std.debug.lockStdErr(); | |
| 7213 | defer std.debug.unlockStdErr(); | |
| 7214 | const stderr = fs.File.stderr().deprecatedWriter(); | |
| 7215 | for (argv[0 .. argv.len - 1]) |arg| { | |
| 7216 | nosuspend stderr.print("{s} ", .{arg}) catch return; | |
| 7210 | var buffer: [64]u8 = undefined; | |
| 7211 | const stderr = std.debug.lockStderrWriter(&buffer); | |
| 7212 | defer std.debug.unlockStderrWriter(); | |
| 7213 | nosuspend { | |
| 7214 | for (argv) |arg| { | |
| 7215 | stderr.writeAll(arg) catch return; | |
| 7216 | (stderr.writableArray(1) catch return)[0] = ' '; | |
| 7217 | } | |
| 7218 | stderr.buffer[stderr.end - 1] = '\n'; | |
| 7217 | 7219 | } |
| 7218 | nosuspend stderr.print("{s}\n", .{argv[argv.len - 1]}) catch {}; | |
| 7219 | 7220 | } |
| 7220 | 7221 | |
| 7221 | 7222 | pub fn getZigBackend(comp: Compilation) std.builtin.CompilerBackend { |
src/Zcu.zig+1-1| ... | ... | @@ -2821,7 +2821,7 @@ pub fn loadZirCache(gpa: Allocator, cache_file: std.fs.File) !Zir { |
| 2821 | 2821 | var buffer: [2000]u8 = undefined; |
| 2822 | 2822 | var file_reader = cache_file.reader(&buffer); |
| 2823 | 2823 | return result: { |
| 2824 | const header = file_reader.interface.takeStructReference(Zir.Header) catch |err| break :result err; | |
| 2824 | const header = file_reader.interface.takeStructPointer(Zir.Header) catch |err| break :result err; | |
| 2825 | 2825 | break :result loadZirCacheBody(gpa, header.*, &file_reader.interface); |
| 2826 | 2826 | } catch |err| switch (err) { |
| 2827 | 2827 | error.ReadFailed => return file_reader.err.?, |
src/Zcu/PerThread.zig+1-1| ... | ... | @@ -349,7 +349,7 @@ fn loadZirZoirCache( |
| 349 | 349 | const cache_br = &cache_fr.interface; |
| 350 | 350 | |
| 351 | 351 | // First we read the header to determine the lengths of arrays. |
| 352 | const header = (cache_br.takeStructReference(Header) catch |err| switch (err) { | |
| 352 | const header = (cache_br.takeStructPointer(Header) catch |err| switch (err) { | |
| 353 | 353 | error.ReadFailed => return cache_fr.err.?, |
| 354 | 354 | // This can happen if Zig bails out of this function between creating |
| 355 | 355 | // the cached file and writing it. |
src/deprecated.zig-262| ... | ... | @@ -52,15 +52,6 @@ pub fn LinearFifo(comptime T: type) type { |
| 52 | 52 | } |
| 53 | 53 | } |
| 54 | 54 | |
| 55 | /// Reduce allocated capacity to `size`. | |
| 56 | pub fn shrink(self: *Self, size: usize) void { | |
| 57 | assert(size >= self.count); | |
| 58 | self.realign(); | |
| 59 | self.buf = self.allocator.realloc(self.buf, size) catch |e| switch (e) { | |
| 60 | error.OutOfMemory => return, // no problem, capacity is still correct then. | |
| 61 | }; | |
| 62 | } | |
| 63 | ||
| 64 | 55 | /// Ensure that the buffer can fit at least `size` items |
| 65 | 56 | pub fn ensureTotalCapacity(self: *Self, size: usize) !void { |
| 66 | 57 | if (self.buf.len >= size) return; |
| ... | ... | @@ -76,11 +67,6 @@ pub fn LinearFifo(comptime T: type) type { |
| 76 | 67 | return try self.ensureTotalCapacity(math.add(usize, self.count, size) catch return error.OutOfMemory); |
| 77 | 68 | } |
| 78 | 69 | |
| 79 | /// Returns number of items currently in fifo | |
| 80 | pub fn readableLength(self: Self) usize { | |
| 81 | return self.count; | |
| 82 | } | |
| 83 | ||
| 84 | 70 | /// Returns a writable slice from the 'read' end of the fifo |
| 85 | 71 | fn readableSliceMut(self: Self, offset: usize) []T { |
| 86 | 72 | if (offset > self.count) return &[_]T{}; |
| ... | ... | @@ -95,22 +81,6 @@ pub fn LinearFifo(comptime T: type) type { |
| 95 | 81 | } |
| 96 | 82 | } |
| 97 | 83 | |
| 98 | /// Returns a readable slice from `offset` | |
| 99 | pub fn readableSlice(self: Self, offset: usize) []const T { | |
| 100 | return self.readableSliceMut(offset); | |
| 101 | } | |
| 102 | ||
| 103 | pub fn readableSliceOfLen(self: *Self, len: usize) []const T { | |
| 104 | assert(len <= self.count); | |
| 105 | const buf = self.readableSlice(0); | |
| 106 | if (buf.len >= len) { | |
| 107 | return buf[0..len]; | |
| 108 | } else { | |
| 109 | self.realign(); | |
| 110 | return self.readableSlice(0)[0..len]; | |
| 111 | } | |
| 112 | } | |
| 113 | ||
| 114 | 84 | /// Discard first `count` items in the fifo |
| 115 | 85 | pub fn discard(self: *Self, count: usize) void { |
| 116 | 86 | assert(count <= self.count); |
| ... | ... | @@ -143,28 +113,6 @@ pub fn LinearFifo(comptime T: type) type { |
| 143 | 113 | return c; |
| 144 | 114 | } |
| 145 | 115 | |
| 146 | /// Read data from the fifo into `dst`, returns number of items copied. | |
| 147 | pub fn read(self: *Self, dst: []T) usize { | |
| 148 | var dst_left = dst; | |
| 149 | ||
| 150 | while (dst_left.len > 0) { | |
| 151 | const slice = self.readableSlice(0); | |
| 152 | if (slice.len == 0) break; | |
| 153 | const n = @min(slice.len, dst_left.len); | |
| 154 | @memcpy(dst_left[0..n], slice[0..n]); | |
| 155 | self.discard(n); | |
| 156 | dst_left = dst_left[n..]; | |
| 157 | } | |
| 158 | ||
| 159 | return dst.len - dst_left.len; | |
| 160 | } | |
| 161 | ||
| 162 | /// Same as `read` except it returns an error union | |
| 163 | /// The purpose of this function existing is to match `std.io.Reader` API. | |
| 164 | fn readFn(self: *Self, dest: []u8) error{}!usize { | |
| 165 | return self.read(dest); | |
| 166 | } | |
| 167 | ||
| 168 | 116 | /// Returns number of items available in fifo |
| 169 | 117 | pub fn writableLength(self: Self) usize { |
| 170 | 118 | return self.buf.len - self.count; |
| ... | ... | @@ -183,20 +131,6 @@ pub fn LinearFifo(comptime T: type) type { |
| 183 | 131 | } |
| 184 | 132 | } |
| 185 | 133 | |
| 186 | /// Returns a writable buffer of at least `size` items, allocating memory as needed. | |
| 187 | /// Use `fifo.update` once you've written data to it. | |
| 188 | pub fn writableWithSize(self: *Self, size: usize) ![]T { | |
| 189 | try self.ensureUnusedCapacity(size); | |
| 190 | ||
| 191 | // try to avoid realigning buffer | |
| 192 | var slice = self.writableSlice(0); | |
| 193 | if (slice.len < size) { | |
| 194 | self.realign(); | |
| 195 | slice = self.writableSlice(0); | |
| 196 | } | |
| 197 | return slice; | |
| 198 | } | |
| 199 | ||
| 200 | 134 | /// Update the tail location of the buffer (usually follows use of writable/writableWithSize) |
| 201 | 135 | pub fn update(self: *Self, count: usize) void { |
| 202 | 136 | assert(self.count + count <= self.buf.len); |
| ... | ... | @@ -231,201 +165,5 @@ pub fn LinearFifo(comptime T: type) type { |
| 231 | 165 | self.buf[tail] = item; |
| 232 | 166 | self.update(1); |
| 233 | 167 | } |
| 234 | ||
| 235 | /// Appends the data in `src` to the fifo. | |
| 236 | /// Allocates more memory as necessary | |
| 237 | pub fn write(self: *Self, src: []const T) !void { | |
| 238 | try self.ensureUnusedCapacity(src.len); | |
| 239 | ||
| 240 | return self.writeAssumeCapacity(src); | |
| 241 | } | |
| 242 | ||
| 243 | /// Same as `write` except it returns the number of bytes written, which is always the same | |
| 244 | /// as `bytes.len`. The purpose of this function existing is to match `std.io.Writer` API. | |
| 245 | fn appendWrite(self: *Self, bytes: []const u8) error{OutOfMemory}!usize { | |
| 246 | try self.write(bytes); | |
| 247 | return bytes.len; | |
| 248 | } | |
| 249 | ||
| 250 | /// Make `count` items available before the current read location | |
| 251 | fn rewind(self: *Self, count: usize) void { | |
| 252 | assert(self.writableLength() >= count); | |
| 253 | ||
| 254 | var head = self.head + (self.buf.len - count); | |
| 255 | head &= self.buf.len - 1; | |
| 256 | self.head = head; | |
| 257 | self.count += count; | |
| 258 | } | |
| 259 | ||
| 260 | /// Place data back into the read stream | |
| 261 | pub fn unget(self: *Self, src: []const T) !void { | |
| 262 | try self.ensureUnusedCapacity(src.len); | |
| 263 | ||
| 264 | self.rewind(src.len); | |
| 265 | ||
| 266 | const slice = self.readableSliceMut(0); | |
| 267 | if (src.len < slice.len) { | |
| 268 | @memcpy(slice[0..src.len], src); | |
| 269 | } else { | |
| 270 | @memcpy(slice, src[0..slice.len]); | |
| 271 | const slice2 = self.readableSliceMut(slice.len); | |
| 272 | @memcpy(slice2[0 .. src.len - slice.len], src[slice.len..]); | |
| 273 | } | |
| 274 | } | |
| 275 | ||
| 276 | /// Returns the item at `offset`. | |
| 277 | /// Asserts offset is within bounds. | |
| 278 | pub fn peekItem(self: Self, offset: usize) T { | |
| 279 | assert(offset < self.count); | |
| 280 | ||
| 281 | var index = self.head + offset; | |
| 282 | index &= self.buf.len - 1; | |
| 283 | return self.buf[index]; | |
| 284 | } | |
| 285 | ||
| 286 | pub fn toOwnedSlice(self: *Self) Allocator.Error![]T { | |
| 287 | if (self.head != 0) self.realign(); | |
| 288 | assert(self.head == 0); | |
| 289 | assert(self.count <= self.buf.len); | |
| 290 | const allocator = self.allocator; | |
| 291 | if (allocator.resize(self.buf, self.count)) { | |
| 292 | const result = self.buf[0..self.count]; | |
| 293 | self.* = Self.init(allocator); | |
| 294 | return result; | |
| 295 | } | |
| 296 | const new_memory = try allocator.dupe(T, self.buf[0..self.count]); | |
| 297 | allocator.free(self.buf); | |
| 298 | self.* = Self.init(allocator); | |
| 299 | return new_memory; | |
| 300 | } | |
| 301 | 168 | }; |
| 302 | 169 | } |
| 303 | ||
| 304 | test "LinearFifo(u8, .Dynamic) discard(0) from empty buffer should not error on overflow" { | |
| 305 | var fifo = LinearFifo(u8, .Dynamic).init(testing.allocator); | |
| 306 | defer fifo.deinit(); | |
| 307 | ||
| 308 | // If overflow is not explicitly allowed this will crash in debug / safe mode | |
| 309 | fifo.discard(0); | |
| 310 | } | |
| 311 | ||
| 312 | test "LinearFifo(u8, .Dynamic)" { | |
| 313 | var fifo = LinearFifo(u8, .Dynamic).init(testing.allocator); | |
| 314 | defer fifo.deinit(); | |
| 315 | ||
| 316 | try fifo.write("HELLO"); | |
| 317 | try testing.expectEqual(@as(usize, 5), fifo.readableLength()); | |
| 318 | try testing.expectEqualSlices(u8, "HELLO", fifo.readableSlice(0)); | |
| 319 | ||
| 320 | { | |
| 321 | var i: usize = 0; | |
| 322 | while (i < 5) : (i += 1) { | |
| 323 | try fifo.write(&[_]u8{fifo.peekItem(i)}); | |
| 324 | } | |
| 325 | try testing.expectEqual(@as(usize, 10), fifo.readableLength()); | |
| 326 | try testing.expectEqualSlices(u8, "HELLOHELLO", fifo.readableSlice(0)); | |
| 327 | } | |
| 328 | ||
| 329 | { | |
| 330 | try testing.expectEqual(@as(u8, 'H'), fifo.readItem().?); | |
| 331 | try testing.expectEqual(@as(u8, 'E'), fifo.readItem().?); | |
| 332 | try testing.expectEqual(@as(u8, 'L'), fifo.readItem().?); | |
| 333 | try testing.expectEqual(@as(u8, 'L'), fifo.readItem().?); | |
| 334 | try testing.expectEqual(@as(u8, 'O'), fifo.readItem().?); | |
| 335 | } | |
| 336 | try testing.expectEqual(@as(usize, 5), fifo.readableLength()); | |
| 337 | ||
| 338 | { // Writes that wrap around | |
| 339 | try testing.expectEqual(@as(usize, 11), fifo.writableLength()); | |
| 340 | try testing.expectEqual(@as(usize, 6), fifo.writableSlice(0).len); | |
| 341 | fifo.writeAssumeCapacity("6<chars<11"); | |
| 342 | try testing.expectEqualSlices(u8, "HELLO6<char", fifo.readableSlice(0)); | |
| 343 | try testing.expectEqualSlices(u8, "s<11", fifo.readableSlice(11)); | |
| 344 | try testing.expectEqualSlices(u8, "11", fifo.readableSlice(13)); | |
| 345 | try testing.expectEqualSlices(u8, "", fifo.readableSlice(15)); | |
| 346 | fifo.discard(11); | |
| 347 | try testing.expectEqualSlices(u8, "s<11", fifo.readableSlice(0)); | |
| 348 | fifo.discard(4); | |
| 349 | try testing.expectEqual(@as(usize, 0), fifo.readableLength()); | |
| 350 | } | |
| 351 | ||
| 352 | { | |
| 353 | const buf = try fifo.writableWithSize(12); | |
| 354 | try testing.expectEqual(@as(usize, 12), buf.len); | |
| 355 | var i: u8 = 0; | |
| 356 | while (i < 10) : (i += 1) { | |
| 357 | buf[i] = i + 'a'; | |
| 358 | } | |
| 359 | fifo.update(10); | |
| 360 | try testing.expectEqualSlices(u8, "abcdefghij", fifo.readableSlice(0)); | |
| 361 | } | |
| 362 | ||
| 363 | { | |
| 364 | try fifo.unget("prependedstring"); | |
| 365 | var result: [30]u8 = undefined; | |
| 366 | try testing.expectEqualSlices(u8, "prependedstringabcdefghij", result[0..fifo.read(&result)]); | |
| 367 | try fifo.unget("b"); | |
| 368 | try fifo.unget("a"); | |
| 369 | try testing.expectEqualSlices(u8, "ab", result[0..fifo.read(&result)]); | |
| 370 | } | |
| 371 | ||
| 372 | fifo.shrink(0); | |
| 373 | ||
| 374 | { | |
| 375 | try fifo.writer().print("{s}, {s}!", .{ "Hello", "World" }); | |
| 376 | var result: [30]u8 = undefined; | |
| 377 | try testing.expectEqualSlices(u8, "Hello, World!", result[0..fifo.read(&result)]); | |
| 378 | try testing.expectEqual(@as(usize, 0), fifo.readableLength()); | |
| 379 | } | |
| 380 | ||
| 381 | { | |
| 382 | try fifo.writer().writeAll("This is a test"); | |
| 383 | var result: [30]u8 = undefined; | |
| 384 | try testing.expectEqualSlices(u8, "This", (try fifo.reader().readUntilDelimiterOrEof(&result, ' ')).?); | |
| 385 | try testing.expectEqualSlices(u8, "is", (try fifo.reader().readUntilDelimiterOrEof(&result, ' ')).?); | |
| 386 | try testing.expectEqualSlices(u8, "a", (try fifo.reader().readUntilDelimiterOrEof(&result, ' ')).?); | |
| 387 | try testing.expectEqualSlices(u8, "test", (try fifo.reader().readUntilDelimiterOrEof(&result, ' ')).?); | |
| 388 | } | |
| 389 | ||
| 390 | { | |
| 391 | try fifo.ensureTotalCapacity(1); | |
| 392 | var in_fbs = std.io.fixedBufferStream("pump test"); | |
| 393 | var out_buf: [50]u8 = undefined; | |
| 394 | var out_fbs = std.io.fixedBufferStream(&out_buf); | |
| 395 | try fifo.pump(in_fbs.reader(), out_fbs.writer()); | |
| 396 | try testing.expectEqualSlices(u8, in_fbs.buffer, out_fbs.getWritten()); | |
| 397 | } | |
| 398 | } | |
| 399 | ||
| 400 | test LinearFifo { | |
| 401 | inline for ([_]type{ u1, u8, u16, u64 }) |T| { | |
| 402 | const FifoType = LinearFifo(T); | |
| 403 | var fifo: FifoType = .init(testing.allocator); | |
| 404 | defer fifo.deinit(); | |
| 405 | ||
| 406 | try fifo.write(&[_]T{ 0, 1, 1, 0, 1 }); | |
| 407 | try testing.expectEqual(@as(usize, 5), fifo.readableLength()); | |
| 408 | ||
| 409 | { | |
| 410 | try testing.expectEqual(@as(T, 0), fifo.readItem().?); | |
| 411 | try testing.expectEqual(@as(T, 1), fifo.readItem().?); | |
| 412 | try testing.expectEqual(@as(T, 1), fifo.readItem().?); | |
| 413 | try testing.expectEqual(@as(T, 0), fifo.readItem().?); | |
| 414 | try testing.expectEqual(@as(T, 1), fifo.readItem().?); | |
| 415 | try testing.expectEqual(@as(usize, 0), fifo.readableLength()); | |
| 416 | } | |
| 417 | ||
| 418 | { | |
| 419 | try fifo.writeItem(1); | |
| 420 | try fifo.writeItem(1); | |
| 421 | try fifo.writeItem(1); | |
| 422 | try testing.expectEqual(@as(usize, 3), fifo.readableLength()); | |
| 423 | } | |
| 424 | ||
| 425 | { | |
| 426 | var readBuf: [3]T = undefined; | |
| 427 | const n = fifo.read(&readBuf); | |
| 428 | try testing.expectEqual(@as(usize, 3), n); // NOTE: It should be the number of items. | |
| 429 | } | |
| 430 | } | |
| 431 | } |
src/main.zig+25-21| ... | ... | @@ -65,8 +65,10 @@ pub fn wasi_cwd() std.os.wasi.fd_t { |
| 65 | 65 | |
| 66 | 66 | const fatal = std.process.fatal; |
| 67 | 67 | |
| 68 | /// This can be global since stdin is a singleton. | |
| 69 | var stdin_buffer: [4096]u8 align(std.heap.page_size_min) = undefined; | |
| 68 | 70 | /// This can be global since stdout is a singleton. |
| 69 | var stdio_buffer: [4096]u8 = undefined; | |
| 71 | var stdout_buffer: [4096]u8 align(std.heap.page_size_min) = undefined; | |
| 70 | 72 | |
| 71 | 73 | /// Shaming all the locations that inappropriately use an O(N) search algorithm. |
| 72 | 74 | /// Please delete this and fix the compilation errors! |
| ... | ... | @@ -3564,10 +3566,12 @@ fn buildOutputType( |
| 3564 | 3566 | switch (listen) { |
| 3565 | 3567 | .none => {}, |
| 3566 | 3568 | .stdio => { |
| 3569 | var stdin_reader = fs.File.stdin().reader(&stdin_buffer); | |
| 3570 | var stdout_writer = fs.File.stdout().writer(&stdout_buffer); | |
| 3567 | 3571 | try serve( |
| 3568 | 3572 | comp, |
| 3569 | .stdin(), | |
| 3570 | .stdout(), | |
| 3573 | &stdin_reader.interface, | |
| 3574 | &stdout_writer.interface, | |
| 3571 | 3575 | test_exec_args.items, |
| 3572 | 3576 | self_exe_path, |
| 3573 | 3577 | arg_mode, |
| ... | ... | @@ -3587,10 +3591,13 @@ fn buildOutputType( |
| 3587 | 3591 | const conn = try server.accept(); |
| 3588 | 3592 | defer conn.stream.close(); |
| 3589 | 3593 | |
| 3594 | var input = conn.stream.reader(&stdin_buffer); | |
| 3595 | var output = conn.stream.writer(&stdout_buffer); | |
| 3596 | ||
| 3590 | 3597 | try serve( |
| 3591 | 3598 | comp, |
| 3592 | .{ .handle = conn.stream.handle }, | |
| 3593 | .{ .handle = conn.stream.handle }, | |
| 3599 | input.interface(), | |
| 3600 | &output.interface, | |
| 3594 | 3601 | test_exec_args.items, |
| 3595 | 3602 | self_exe_path, |
| 3596 | 3603 | arg_mode, |
| ... | ... | @@ -4056,8 +4063,8 @@ fn saveState(comp: *Compilation, incremental: bool) void { |
| 4056 | 4063 | |
| 4057 | 4064 | fn serve( |
| 4058 | 4065 | comp: *Compilation, |
| 4059 | in: fs.File, | |
| 4060 | out: fs.File, | |
| 4066 | in: *std.Io.Reader, | |
| 4067 | out: *std.Io.Writer, | |
| 4061 | 4068 | test_exec_args: []const ?[]const u8, |
| 4062 | 4069 | self_exe_path: ?[]const u8, |
| 4063 | 4070 | arg_mode: ArgMode, |
| ... | ... | @@ -4067,12 +4074,10 @@ fn serve( |
| 4067 | 4074 | const gpa = comp.gpa; |
| 4068 | 4075 | |
| 4069 | 4076 | var server = try Server.init(.{ |
| 4070 | .gpa = gpa, | |
| 4071 | 4077 | .in = in, |
| 4072 | 4078 | .out = out, |
| 4073 | 4079 | .zig_version = build_options.version, |
| 4074 | 4080 | }); |
| 4075 | defer server.deinit(); | |
| 4076 | 4081 | |
| 4077 | 4082 | var child_pid: ?std.process.Child.Id = null; |
| 4078 | 4083 | |
| ... | ... | @@ -5494,10 +5499,10 @@ fn jitCmd( |
| 5494 | 5499 | defer comp.destroy(); |
| 5495 | 5500 | |
| 5496 | 5501 | if (options.server) { |
| 5502 | var stdout_writer = fs.File.stdout().writer(&stdout_buffer); | |
| 5497 | 5503 | var server: std.zig.Server = .{ |
| 5498 | .out = fs.File.stdout(), | |
| 5504 | .out = &stdout_writer.interface, | |
| 5499 | 5505 | .in = undefined, // won't be receiving messages |
| 5500 | .receive_fifo = undefined, // won't be receiving messages | |
| 5501 | 5506 | }; |
| 5502 | 5507 | |
| 5503 | 5508 | try comp.update(root_prog_node); |
| ... | ... | @@ -6061,7 +6066,7 @@ fn cmdAstCheck( |
| 6061 | 6066 | }; |
| 6062 | 6067 | } else fs.File.stdin(); |
| 6063 | 6068 | defer if (zig_source_path != null) f.close(); |
| 6064 | var file_reader: fs.File.Reader = f.reader(&stdio_buffer); | |
| 6069 | var file_reader: fs.File.Reader = f.reader(&stdin_buffer); | |
| 6065 | 6070 | break :s std.zig.readSourceFileToEndAlloc(arena, &file_reader) catch |err| { |
| 6066 | 6071 | fatal("unable to load file '{s}' for ast-check: {s}", .{ display_path, @errorName(err) }); |
| 6067 | 6072 | }; |
| ... | ... | @@ -6079,7 +6084,7 @@ fn cmdAstCheck( |
| 6079 | 6084 | |
| 6080 | 6085 | const tree = try Ast.parse(arena, source, mode); |
| 6081 | 6086 | |
| 6082 | var stdout_writer = fs.File.stdout().writerStreaming(&stdio_buffer); | |
| 6087 | var stdout_writer = fs.File.stdout().writerStreaming(&stdout_buffer); | |
| 6083 | 6088 | const stdout_bw = &stdout_writer.interface; |
| 6084 | 6089 | switch (mode) { |
| 6085 | 6090 | .zig => { |
| ... | ... | @@ -6294,7 +6299,7 @@ fn detectNativeCpuWithLLVM( |
| 6294 | 6299 | } |
| 6295 | 6300 | |
| 6296 | 6301 | fn printCpu(cpu: std.Target.Cpu) !void { |
| 6297 | var stdout_writer = fs.File.stdout().writerStreaming(&stdio_buffer); | |
| 6302 | var stdout_writer = fs.File.stdout().writerStreaming(&stdout_buffer); | |
| 6298 | 6303 | const stdout_bw = &stdout_writer.interface; |
| 6299 | 6304 | |
| 6300 | 6305 | if (cpu.model.llvm_name) |llvm_name| { |
| ... | ... | @@ -6343,7 +6348,7 @@ fn cmdDumpLlvmInts( |
| 6343 | 6348 | const dl = tm.createTargetDataLayout(); |
| 6344 | 6349 | const context = llvm.Context.create(); |
| 6345 | 6350 | |
| 6346 | var stdout_writer = fs.File.stdout().writerStreaming(&stdio_buffer); | |
| 6351 | var stdout_writer = fs.File.stdout().writerStreaming(&stdout_buffer); | |
| 6347 | 6352 | const stdout_bw = &stdout_writer.interface; |
| 6348 | 6353 | for ([_]u16{ 1, 8, 16, 32, 64, 128, 256 }) |bits| { |
| 6349 | 6354 | const int_type = context.intType(bits); |
| ... | ... | @@ -6372,9 +6377,8 @@ fn cmdDumpZir( |
| 6372 | 6377 | defer f.close(); |
| 6373 | 6378 | |
| 6374 | 6379 | const zir = try Zcu.loadZirCache(arena, f); |
| 6375 | var stdout_writer = fs.File.stdout().writerStreaming(&stdio_buffer); | |
| 6380 | var stdout_writer = fs.File.stdout().writerStreaming(&stdout_buffer); | |
| 6376 | 6381 | const stdout_bw = &stdout_writer.interface; |
| 6377 | ||
| 6378 | 6382 | { |
| 6379 | 6383 | const instruction_bytes = zir.instructions.len * |
| 6380 | 6384 | // Here we don't use @sizeOf(Zir.Inst.Data) because it would include |
| ... | ... | @@ -6420,7 +6424,7 @@ fn cmdChangelist( |
| 6420 | 6424 | var f = fs.cwd().openFile(old_source_path, .{}) catch |err| |
| 6421 | 6425 | fatal("unable to open old source file '{s}': {s}", .{ old_source_path, @errorName(err) }); |
| 6422 | 6426 | defer f.close(); |
| 6423 | var file_reader: fs.File.Reader = f.reader(&stdio_buffer); | |
| 6427 | var file_reader: fs.File.Reader = f.reader(&stdin_buffer); | |
| 6424 | 6428 | break :source std.zig.readSourceFileToEndAlloc(arena, &file_reader) catch |err| |
| 6425 | 6429 | fatal("unable to read old source file '{s}': {s}", .{ old_source_path, @errorName(err) }); |
| 6426 | 6430 | }; |
| ... | ... | @@ -6428,7 +6432,7 @@ fn cmdChangelist( |
| 6428 | 6432 | var f = fs.cwd().openFile(new_source_path, .{}) catch |err| |
| 6429 | 6433 | fatal("unable to open new source file '{s}': {s}", .{ new_source_path, @errorName(err) }); |
| 6430 | 6434 | defer f.close(); |
| 6431 | var file_reader: fs.File.Reader = f.reader(&stdio_buffer); | |
| 6435 | var file_reader: fs.File.Reader = f.reader(&stdin_buffer); | |
| 6432 | 6436 | break :source std.zig.readSourceFileToEndAlloc(arena, &file_reader) catch |err| |
| 6433 | 6437 | fatal("unable to read new source file '{s}': {s}", .{ new_source_path, @errorName(err) }); |
| 6434 | 6438 | }; |
| ... | ... | @@ -6460,7 +6464,7 @@ fn cmdChangelist( |
| 6460 | 6464 | var inst_map: std.AutoHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index) = .empty; |
| 6461 | 6465 | try Zcu.mapOldZirToNew(arena, old_zir, new_zir, &inst_map); |
| 6462 | 6466 | |
| 6463 | var stdout_writer = fs.File.stdout().writerStreaming(&stdio_buffer); | |
| 6467 | var stdout_writer = fs.File.stdout().writerStreaming(&stdout_buffer); | |
| 6464 | 6468 | const stdout_bw = &stdout_writer.interface; |
| 6465 | 6469 | { |
| 6466 | 6470 | try stdout_bw.print("Instruction mappings:\n", .{}); |
| ... | ... | @@ -6920,7 +6924,7 @@ fn cmdFetch( |
| 6920 | 6924 | |
| 6921 | 6925 | const name = switch (save) { |
| 6922 | 6926 | .no => { |
| 6923 | var stdout = fs.File.stdout().writerStreaming(&stdio_buffer); | |
| 6927 | var stdout = fs.File.stdout().writerStreaming(&stdout_buffer); | |
| 6924 | 6928 | try stdout.interface.print("{s}\n", .{package_hash_slice}); |
| 6925 | 6929 | try stdout.interface.flush(); |
| 6926 | 6930 | return cleanExit(); |
test/src/Cases.zig-2| ... | ... | @@ -800,8 +800,6 @@ const TestManifestConfigDefaults = struct { |
| 800 | 800 | } |
| 801 | 801 | // Windows |
| 802 | 802 | defaults = defaults ++ "x86_64-windows" ++ ","; |
| 803 | // Wasm | |
| 804 | defaults = defaults ++ "wasm32-wasi"; | |
| 805 | 803 | break :blk defaults; |
| 806 | 804 | }; |
| 807 | 805 | } else if (std.mem.eql(u8, key, "output_mode")) { |
test/tests.zig+10-9| ... | ... | @@ -1335,15 +1335,16 @@ const test_targets = blk: { |
| 1335 | 1335 | |
| 1336 | 1336 | // WASI Targets |
| 1337 | 1337 | |
| 1338 | .{ | |
| 1339 | .target = .{ | |
| 1340 | .cpu_arch = .wasm32, | |
| 1341 | .os_tag = .wasi, | |
| 1342 | .abi = .none, | |
| 1343 | }, | |
| 1344 | .use_llvm = false, | |
| 1345 | .use_lld = false, | |
| 1346 | }, | |
| 1338 | // TODO: lowerTry for pointers | |
| 1339 | //.{ | |
| 1340 | // .target = .{ | |
| 1341 | // .cpu_arch = .wasm32, | |
| 1342 | // .os_tag = .wasi, | |
| 1343 | // .abi = .none, | |
| 1344 | // }, | |
| 1345 | // .use_llvm = false, | |
| 1346 | // .use_lld = false, | |
| 1347 | //}, | |
| 1347 | 1348 | .{ |
| 1348 | 1349 | .target = .{ |
| 1349 | 1350 | .cpu_arch = .wasm32, |