@zigc/lib 0.16.0 → 0.17.0-dev.131
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/c/fcntl.zig +6 -1
- package/c/inttypes.zig +0 -10
- package/c/math.zig +46 -122
- package/c/pthread.zig +57 -0
- package/c/search.zig +1 -27
- package/c/stdlib/drand48.zig +0 -57
- package/c/stdlib.zig +0 -100
- package/c/string.zig +20 -7
- package/c/strings.zig +0 -38
- package/c/unistd.zig +27 -26
- package/c/wchar.zig +10 -0
- package/c.zig +2 -2
- package/compiler/aro/aro/CodeGen.zig +5 -6
- package/compiler/aro/aro/Compilation.zig +17 -14
- package/compiler/aro/aro/Driver.zig +14 -13
- package/compiler/aro/aro/Parser.zig +20 -15
- package/compiler/aro/aro/Pragma.zig +3 -2
- package/compiler/aro/aro/Preprocessor.zig +9 -6
- package/compiler/aro/aro/pragmas/message.zig +3 -2
- package/compiler/aro/aro/text_literal.zig +3 -2
- package/compiler/aro/assembly_backend/x86_64.zig +4 -4
- package/compiler/build_runner.zig +0 -2
- package/compiler/reduce/Walk.zig +7 -7
- package/compiler/test_runner.zig +2 -2
- package/compiler/translate-c/Translator.zig +6 -2
- package/compiler/translate-c/main.zig +1 -1
- package/compiler_rt/cos.zig +0 -2
- package/compiler_rt/divmodei4.zig +40 -17
- package/compiler_rt/exp.zig +1 -6
- package/compiler_rt/exp2.zig +1 -6
- package/compiler_rt/exp_f128.zig +377 -0
- package/compiler_rt/fabs.zig +0 -2
- package/compiler_rt/fma.zig +0 -2
- package/compiler_rt/fmax.zig +0 -2
- package/compiler_rt/fmin.zig +0 -2
- package/compiler_rt/fmod.zig +0 -2
- package/compiler_rt/limb64.zig +876 -15
- package/compiler_rt/log.zig +0 -2
- package/compiler_rt/log10.zig +0 -2
- package/compiler_rt/log2.zig +0 -2
- package/compiler_rt/mulXi3.zig +1 -1
- package/compiler_rt/round.zig +0 -2
- package/compiler_rt/sin.zig +0 -2
- package/compiler_rt/sincos.zig +0 -2
- package/compiler_rt/sqrt.zig +0 -2
- package/compiler_rt/ssp.zig +1 -1
- package/compiler_rt/tan.zig +0 -2
- package/compiler_rt/trunc.zig +0 -2
- package/compiler_rt/udivmodei4.zig +28 -0
- package/fuzzer.zig +2 -0
- package/libc/musl/arch/mipsn32/syscall_arch.h +35 -32
- package/package.json +1 -1
- package/std/Build/Cache.zig +6 -6
- package/std/Build/Step/Compile.zig +0 -1
- package/std/Build/Step/Run.zig +2 -2
- package/std/Build/Step.zig +2 -4
- package/std/Build/WebServer.zig +2 -2
- package/std/Build.zig +0 -3
- package/std/Io/Dir.zig +7 -2
- package/std/Io/Dispatch.zig +3 -13
- package/std/Io/File/Writer.zig +8 -6
- package/std/Io/Reader.zig +8 -9
- package/std/Io/Semaphore.zig +112 -17
- package/std/Io/Terminal.zig +1 -1
- package/std/Io/Threaded.zig +171 -37
- package/std/Io/Uring.zig +13 -15
- package/std/Io/Writer.zig +46 -42
- package/std/Io/net.zig +11 -11
- package/std/Io.zig +90 -26
- package/std/SemanticVersion.zig +1 -1
- package/std/Target/Query.zig +2 -2
- package/std/Target.zig +50 -5
- package/std/array_hash_map.zig +9 -18
- package/std/builtin.zig +4 -0
- package/std/c/haiku.zig +3 -0
- package/std/c/serenity.zig +1 -6
- package/std/c.zig +89 -7
- package/std/compress/flate/Decompress.zig +2 -3
- package/std/compress/zstd/Decompress.zig +2 -4
- package/std/crypto/Certificate.zig +13 -1
- package/std/crypto/ascon.zig +75 -33
- package/std/crypto/codecs/asn1/Oid.zig +12 -1
- package/std/crypto/codecs/base64_hex_ct.zig +2 -4
- package/std/crypto/ml_kem.zig +2 -9
- package/std/crypto/tls/Client.zig +79 -4
- package/std/crypto/tls.zig +1 -1
- package/std/crypto.zig +1 -0
- package/std/debug/Pdb.zig +1 -1
- package/std/debug.zig +4 -3
- package/std/fmt.zig +8 -3
- package/std/fs/path.zig +6 -4
- package/std/heap/BufferFirstAllocator.zig +165 -0
- package/std/heap.zig +2 -126
- package/std/http/Client.zig +21 -24
- package/std/http.zig +3 -4
- package/std/json/Scanner.zig +2 -2
- package/std/os/emscripten.zig +1 -1
- package/std/os/linux/IoUring.zig +2 -0
- package/std/os/linux/aarch64.zig +41 -12
- package/std/os/linux/arc.zig +173 -0
- package/std/os/linux/arm.zig +41 -12
- package/std/os/linux/hexagon.zig +33 -11
- package/std/os/linux/loongarch32.zig +41 -13
- package/std/os/linux/loongarch64.zig +41 -12
- package/std/os/linux/m68k.zig +41 -13
- package/std/os/linux/mips.zig +67 -36
- package/std/os/linux/mips64.zig +60 -29
- package/std/os/linux/mipsn32.zig +60 -29
- package/std/os/linux/or1k.zig +41 -12
- package/std/os/linux/powerpc.zig +41 -12
- package/std/os/linux/powerpc64.zig +41 -12
- package/std/os/linux/riscv32.zig +41 -12
- package/std/os/linux/riscv64.zig +41 -12
- package/std/os/linux/s390x.zig +44 -7
- package/std/os/linux/sparc64.zig +83 -52
- package/std/os/linux/thumb.zig +52 -36
- package/std/os/linux/x32.zig +41 -12
- package/std/os/linux/x86.zig +42 -13
- package/std/os/linux/x86_64.zig +41 -12
- package/std/os/linux.zig +412 -436
- package/std/os/uefi/tables/boot_services.zig +9 -8
- package/std/os.zig +41 -0
- package/std/process.zig +1 -1
- package/std/sort.zig +3 -3
- package/std/zig/Ast/Render.zig +3 -3
- package/std/zig/AstGen.zig +44 -98
- package/std/zig/AstRlAnnotate.zig +0 -11
- package/std/zig/BuiltinFn.zig +0 -32
- package/std/zig/LibCInstallation.zig +4 -3
- package/std/zig/Parse.zig +7 -7
- package/std/zig/WindowsSdk.zig +13 -13
- package/std/zig/Zir.zig +50 -63
- package/std/zig/ZonGen.zig +6 -5
- package/std/zig/llvm/Builder.zig +12 -12
- package/std/zig.zig +1 -10
- package/std/zip.zig +5 -5
- package/zig.h +340 -1
- package/libc/mingw/math/fdiml.c +0 -24
- package/libc/mingw/winpthreads/spinlock.c +0 -82
- package/libc/musl/src/linux/tee.c +0 -8
- package/libc/musl/src/math/fdimf.c +0 -10
- package/libc/musl/src/math/fdiml.c +0 -18
- package/libc/musl/src/string/strdup.c +0 -10
- package/libc/musl/src/string/strndup.c +0 -12
- package/libc/musl/src/string/wcsdup.c +0 -10
- package/libc/musl/src/thread/pthread_spin_destroy.c +0 -6
- package/libc/musl/src/thread/pthread_spin_init.c +0 -6
- package/libc/musl/src/thread/pthread_spin_lock.c +0 -8
- package/libc/musl/src/thread/pthread_spin_trylock.c +0 -7
- package/libc/musl/src/thread/pthread_spin_unlock.c +0 -7
- package/libc/musl/src/unistd/dup2.c +0 -20
- package/libc/musl/src/unistd/dup3.c +0 -26
- package/libc/wasi/thread-stub/pthread_spin_lock.c +0 -8
- package/libc/wasi/thread-stub/pthread_spin_trylock.c +0 -8
- package/libc/wasi/thread-stub/pthread_spin_unlock.c +0 -7
|
@@ -353,7 +353,7 @@ pub fn init(input: *Reader, output: *Writer, options: Options) InitError!Client
|
|
|
353
353
|
if (record_len > tls.max_ciphertext_len) return error.TlsRecordOverflow;
|
|
354
354
|
const record_buffer = input.take(record_len) catch |err| switch (err) {
|
|
355
355
|
error.EndOfStream => return error.TlsConnectionTruncated,
|
|
356
|
-
error.ReadFailed => return
|
|
356
|
+
error.ReadFailed => |e| return e,
|
|
357
357
|
};
|
|
358
358
|
var record_decoder: tls.Decoder = .fromTheirSlice(record_buffer);
|
|
359
359
|
var ctd, const ct = content: switch (cipher_state) {
|
|
@@ -382,7 +382,9 @@ pub fn init(input: *Reader, output: *Writer, options: Options) InitError!Client
|
|
|
382
382
|
P.AEAD.decrypt(cleartext, ciphertext, auth_tag, record_header, nonce, pv.server_handshake_key) catch
|
|
383
383
|
return error.TlsBadRecordMac;
|
|
384
384
|
// TODO use scalar, non-slice version
|
|
385
|
-
|
|
385
|
+
const trimmed_len = mem.trimEnd(u8, cleartext, "\x00").len;
|
|
386
|
+
if (trimmed_len == 0) return error.TlsDecodeError;
|
|
387
|
+
cleartext_fragment_end += trimmed_len;
|
|
386
388
|
},
|
|
387
389
|
}
|
|
388
390
|
read_seq += 1;
|
|
@@ -1155,7 +1157,7 @@ fn readIndirect(c: *Client) Reader.Error!usize {
|
|
|
1155
1157
|
return failRead(c, error.TlsConnectionTruncated);
|
|
1156
1158
|
}
|
|
1157
1159
|
},
|
|
1158
|
-
error.ReadFailed => return
|
|
1160
|
+
error.ReadFailed => |e| return e,
|
|
1159
1161
|
};
|
|
1160
1162
|
const ct: tls.ContentType = @enumFromInt(record_header[0]);
|
|
1161
1163
|
const legacy_version = mem.readInt(u16, record_header[1..][0..2], .big);
|
|
@@ -1166,7 +1168,7 @@ fn readIndirect(c: *Client) Reader.Error!usize {
|
|
|
1166
1168
|
if (record_end > input.buffered().len) {
|
|
1167
1169
|
input.fillMore() catch |err| switch (err) {
|
|
1168
1170
|
error.EndOfStream => return failRead(c, error.TlsConnectionTruncated),
|
|
1169
|
-
error.ReadFailed => return
|
|
1171
|
+
error.ReadFailed => |e| return e,
|
|
1170
1172
|
};
|
|
1171
1173
|
if (record_end > input.buffered().len) return 0;
|
|
1172
1174
|
}
|
|
@@ -1176,6 +1178,7 @@ fn readIndirect(c: *Client) Reader.Error!usize {
|
|
|
1176
1178
|
.tls_1_3 => {
|
|
1177
1179
|
const pv = &p.tls_1_3;
|
|
1178
1180
|
const P = @TypeOf(p.*);
|
|
1181
|
+
if (record_len < P.AEAD.tag_length) return failRead(c, error.TlsRecordOverflow);
|
|
1179
1182
|
const ad = input.take(tls.record_header_len) catch unreachable; // already peeked
|
|
1180
1183
|
const ciphertext_len = record_len - P.AEAD.tag_length;
|
|
1181
1184
|
const ciphertext = input.take(ciphertext_len) catch unreachable; // already peeked
|
|
@@ -1192,6 +1195,7 @@ fn readIndirect(c: *Client) Reader.Error!usize {
|
|
|
1192
1195
|
return failRead(c, error.TlsBadRecordMac);
|
|
1193
1196
|
// TODO use scalar, non-slice version
|
|
1194
1197
|
const msg = mem.trimEnd(u8, cleartext, "\x00");
|
|
1198
|
+
if (msg.len == 0) return failRead(c, error.TlsDecodeError);
|
|
1195
1199
|
break :cleartext .{ msg.len - 1, @enumFromInt(msg[msg.len - 1]) };
|
|
1196
1200
|
},
|
|
1197
1201
|
.tls_1_2 => {
|
|
@@ -1668,3 +1672,74 @@ else
|
|
|
1668
1672
|
.AES_256_GCM_SHA384,
|
|
1669
1673
|
.ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
|
1670
1674
|
});
|
|
1675
|
+
|
|
1676
|
+
fn testReadError(input_buf: []const u8, cipher: tls.ApplicationCipher) ReadError {
|
|
1677
|
+
var input_reader: Reader = .fixed(input_buf);
|
|
1678
|
+
var read_buf: [tls.max_ciphertext_record_len]u8 = undefined;
|
|
1679
|
+
var c: Client = .{
|
|
1680
|
+
.input = &input_reader,
|
|
1681
|
+
.reader = .{
|
|
1682
|
+
.buffer = &read_buf,
|
|
1683
|
+
.vtable = &.{ .stream = stream, .readVec = readVec },
|
|
1684
|
+
.seek = 0,
|
|
1685
|
+
.end = 0,
|
|
1686
|
+
},
|
|
1687
|
+
.output = undefined,
|
|
1688
|
+
.writer = undefined,
|
|
1689
|
+
.tls_version = .tls_1_3,
|
|
1690
|
+
.read_seq = 0,
|
|
1691
|
+
.write_seq = 0,
|
|
1692
|
+
.received_close_notify = false,
|
|
1693
|
+
.allow_truncation_attacks = false,
|
|
1694
|
+
.application_cipher = cipher,
|
|
1695
|
+
.ssl_key_log = null,
|
|
1696
|
+
};
|
|
1697
|
+
var w: Writer = .failing;
|
|
1698
|
+
std.testing.expectError(error.ReadFailed, c.reader.stream(&w, .unlimited)) catch
|
|
1699
|
+
@panic("expected ReadFailed");
|
|
1700
|
+
return c.read_err.?;
|
|
1701
|
+
}
|
|
1702
|
+
|
|
1703
|
+
test "empty inner plaintext" {
|
|
1704
|
+
const AEAD = crypto.aead.chacha_poly.ChaCha20Poly1305;
|
|
1705
|
+
const key: [AEAD.key_length]u8 = @splat(0);
|
|
1706
|
+
const iv: [AEAD.nonce_length]u8 = @splat(0);
|
|
1707
|
+
|
|
1708
|
+
const plaintext = [1]u8{0x00};
|
|
1709
|
+
var ciphertext: [plaintext.len]u8 = undefined;
|
|
1710
|
+
var tag: [AEAD.tag_length]u8 = undefined;
|
|
1711
|
+
const content_len: u16 = plaintext.len + AEAD.tag_length;
|
|
1712
|
+
const record_header = [_]u8{ 0x17, 0x03, 0x03 } ++ mem.toBytes(big(content_len));
|
|
1713
|
+
AEAD.encrypt(&ciphertext, &tag, &plaintext, &record_header, iv, key);
|
|
1714
|
+
|
|
1715
|
+
try std.testing.expectEqual(error.TlsDecodeError, testReadError(
|
|
1716
|
+
&record_header ++ ciphertext ++ tag,
|
|
1717
|
+
.{ .CHACHA20_POLY1305_SHA256 = .{ .tls_1_3 = .{
|
|
1718
|
+
.server_key = key,
|
|
1719
|
+
.server_iv = iv,
|
|
1720
|
+
.client_secret = undefined,
|
|
1721
|
+
.server_secret = undefined,
|
|
1722
|
+
.client_key = undefined,
|
|
1723
|
+
.client_iv = undefined,
|
|
1724
|
+
} } },
|
|
1725
|
+
));
|
|
1726
|
+
}
|
|
1727
|
+
|
|
1728
|
+
test "record shorter than tag" {
|
|
1729
|
+
const AEAD = crypto.aead.chacha_poly.ChaCha20Poly1305;
|
|
1730
|
+
const record_len: u16 = AEAD.tag_length - 1;
|
|
1731
|
+
const header = [_]u8{ 0x17, 0x03, 0x03 } ++ mem.toBytes(big(record_len));
|
|
1732
|
+
const wire = header ++ @as([record_len]u8, @splat(0));
|
|
1733
|
+
|
|
1734
|
+
try std.testing.expectEqual(error.TlsRecordOverflow, testReadError(
|
|
1735
|
+
&wire,
|
|
1736
|
+
.{ .CHACHA20_POLY1305_SHA256 = .{ .tls_1_3 = .{
|
|
1737
|
+
.server_key = undefined,
|
|
1738
|
+
.server_iv = undefined,
|
|
1739
|
+
.client_secret = undefined,
|
|
1740
|
+
.server_secret = undefined,
|
|
1741
|
+
.client_key = undefined,
|
|
1742
|
+
.client_iv = undefined,
|
|
1743
|
+
} } },
|
|
1744
|
+
));
|
|
1745
|
+
}
|
package/std/crypto/tls.zig
CHANGED
|
@@ -666,7 +666,7 @@ pub const Decoder = struct {
|
|
|
666
666
|
if (request_amt > dest.len) return error.TlsRecordOverflow;
|
|
667
667
|
stream.readSlice(dest[0..request_amt]) catch |err| switch (err) {
|
|
668
668
|
error.EndOfStream => return error.TlsConnectionTruncated,
|
|
669
|
-
error.ReadFailed => return
|
|
669
|
+
error.ReadFailed => |e| return e,
|
|
670
670
|
};
|
|
671
671
|
d.cap += request_amt;
|
|
672
672
|
}
|
package/std/crypto.zig
CHANGED
package/std/debug/Pdb.zig
CHANGED
|
@@ -138,7 +138,7 @@ pub fn parseDbiStream(self: *Pdb) !void {
|
|
|
138
138
|
if (section_contrib_size != 0) {
|
|
139
139
|
const version = reader.takeEnum(pdb.SectionContrSubstreamVersion, .little) catch |err| switch (err) {
|
|
140
140
|
error.InvalidEnumTag, error.EndOfStream => return error.InvalidDebugInfo,
|
|
141
|
-
error.ReadFailed => return
|
|
141
|
+
error.ReadFailed => |e| return e,
|
|
142
142
|
};
|
|
143
143
|
_ = version;
|
|
144
144
|
sect_cont_offset += @sizeOf(u32);
|
package/std/debug.zig
CHANGED
|
@@ -1197,8 +1197,9 @@ fn printSourceAtAddress(
|
|
|
1197
1197
|
|
|
1198
1198
|
// Initialize the symbol array with space for at least one element, allocating this on the stack
|
|
1199
1199
|
// in the common case where only one element is needed
|
|
1200
|
-
var
|
|
1201
|
-
|
|
1200
|
+
var buf: [1]Symbol = undefined;
|
|
1201
|
+
var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&buf), getDebugInfoAllocator());
|
|
1202
|
+
const symbol_allocator = bfa.allocator();
|
|
1202
1203
|
var symbols = std.ArrayList(Symbol).initCapacity(symbol_allocator, 1) catch unreachable;
|
|
1203
1204
|
defer symbols.deinit(symbol_allocator);
|
|
1204
1205
|
|
|
@@ -1576,12 +1577,12 @@ fn handleSegfaultPosix(sig: posix.SIG, info: *const posix.siginfo_t, ctx_ptr: ?*
|
|
|
1576
1577
|
.tvos,
|
|
1577
1578
|
.visionos,
|
|
1578
1579
|
.watchos,
|
|
1580
|
+
.haiku,
|
|
1579
1581
|
=> @intFromPtr(info.addr),
|
|
1580
1582
|
.linux,
|
|
1581
1583
|
=> @intFromPtr(info.fields.sigfault.addr),
|
|
1582
1584
|
.netbsd,
|
|
1583
1585
|
=> @intFromPtr(info.info.reason.fault.addr),
|
|
1584
|
-
.haiku,
|
|
1585
1586
|
.openbsd,
|
|
1586
1587
|
=> @intFromPtr(info.data.fault.addr),
|
|
1587
1588
|
.illumos,
|
package/std/fmt.zig
CHANGED
|
@@ -542,7 +542,7 @@ pub fn parseIntSizeSuffix(buf: []const u8, digit_base: u8) ParseIntError!usize {
|
|
|
542
542
|
}
|
|
543
543
|
const multiplier = math.powi(usize, magnitude_base, orders_of_magnitude) catch |err| switch (err) {
|
|
544
544
|
error.Underflow => unreachable,
|
|
545
|
-
error.Overflow => return
|
|
545
|
+
error.Overflow => |e| return e,
|
|
546
546
|
};
|
|
547
547
|
const number = try std.fmt.parseInt(usize, without_suffix, digit_base);
|
|
548
548
|
return math.mul(usize, number, multiplier);
|
|
@@ -1342,9 +1342,9 @@ pub const hex_charset = "0123456789abcdef";
|
|
|
1342
1342
|
|
|
1343
1343
|
/// Converts an unsigned integer of any multiple of u8 to an array of lowercase
|
|
1344
1344
|
/// hex bytes, little endian.
|
|
1345
|
-
pub fn hex(x: anytype) [@
|
|
1345
|
+
pub fn hex(x: anytype) [@typeInfo(@TypeOf(x)).int.bits / 4]u8 {
|
|
1346
1346
|
comptime assert(@typeInfo(@TypeOf(x)).int.signedness == .unsigned);
|
|
1347
|
-
var result: [@
|
|
1347
|
+
var result: [@typeInfo(@TypeOf(x)).int.bits / 4]u8 = undefined;
|
|
1348
1348
|
var i: usize = 0;
|
|
1349
1349
|
while (i < result.len / 2) : (i += 1) {
|
|
1350
1350
|
const byte: u8 = @truncate(x >> @intCast(8 * i));
|
|
@@ -1360,6 +1360,11 @@ test hex {
|
|
|
1360
1360
|
try std.testing.expect(x.len == 8);
|
|
1361
1361
|
try std.testing.expectEqualStrings("efbeadde", &x);
|
|
1362
1362
|
}
|
|
1363
|
+
{
|
|
1364
|
+
const s = "[" ++ hex(@as(u48, 0x12345678_abcd)) ++ "]";
|
|
1365
|
+
try std.testing.expect(s.len == 14);
|
|
1366
|
+
try std.testing.expectEqualStrings("[cdab78563412]", s);
|
|
1367
|
+
}
|
|
1363
1368
|
{
|
|
1364
1369
|
const s = "[" ++ hex(@as(u64, 0x12345678_abcdef00)) ++ "]";
|
|
1365
1370
|
try std.testing.expect(s.len == 18);
|
package/std/fs/path.zig
CHANGED
|
@@ -894,8 +894,9 @@ pub fn resolve(allocator: Allocator, paths: []const []const u8) Allocator.Error!
|
|
|
894
894
|
pub fn resolveWindows(allocator: Allocator, paths: []const []const u8) Allocator.Error![]u8 {
|
|
895
895
|
// Avoid heap allocation when paths.len is <= @bitSizeOf(usize) * 2
|
|
896
896
|
// (we use `* 3` because stackFallback uses 1 usize as a length)
|
|
897
|
-
var
|
|
898
|
-
|
|
897
|
+
var buf: [3]usize = undefined;
|
|
898
|
+
var bit_set_allocator_state: std.heap.BufferFirstAllocator = .init(@ptrCast(&buf), allocator);
|
|
899
|
+
const bit_set_allocator = bit_set_allocator_state.allocator();
|
|
899
900
|
var relevant_paths = try std.bit_set.DynamicBitSetUnmanaged.initEmpty(bit_set_allocator, paths.len);
|
|
900
901
|
defer relevant_paths.deinit(bit_set_allocator);
|
|
901
902
|
|
|
@@ -1642,7 +1643,8 @@ fn windowsResolveAgainstCwd(
|
|
|
1642
1643
|
parsed: WindowsPath2(u8),
|
|
1643
1644
|
) ![]u8 {
|
|
1644
1645
|
// Space for 256 WTF-16 code units; potentially 3 WTF-8 bytes per WTF-16 code unit
|
|
1645
|
-
var
|
|
1646
|
+
var buf: [256 * 3]u8 = undefined;
|
|
1647
|
+
var temp_allocator_state: std.heap.BufferFirstAllocator = .init(&buf, gpa);
|
|
1646
1648
|
return switch (parsed.kind) {
|
|
1647
1649
|
.drive_absolute,
|
|
1648
1650
|
.unc_absolute,
|
|
@@ -1668,7 +1670,7 @@ fn windowsResolveAgainstCwd(
|
|
|
1668
1670
|
}
|
|
1669
1671
|
},
|
|
1670
1672
|
.drive_relative => blk: {
|
|
1671
|
-
const temp_allocator = temp_allocator_state.
|
|
1673
|
+
const temp_allocator = temp_allocator_state.allocator();
|
|
1672
1674
|
const drive_cwd = drive_cwd: {
|
|
1673
1675
|
const parsed_cwd = parsePathWindows(u8, cwd);
|
|
1674
1676
|
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
//! An allocator that attempts to allocate from the given buffer, falling back to
|
|
2
|
+
//! `fallback_allocator` if this fails.
|
|
3
|
+
|
|
4
|
+
const std = @import("../std.zig");
|
|
5
|
+
const heap = std.heap;
|
|
6
|
+
const testing = std.testing;
|
|
7
|
+
|
|
8
|
+
const Alignment = std.mem.Alignment;
|
|
9
|
+
const Allocator = std.mem.Allocator;
|
|
10
|
+
const FixedBufferAllocator = std.heap.FixedBufferAllocator;
|
|
11
|
+
|
|
12
|
+
const BufferFirstAllocator = @This();
|
|
13
|
+
|
|
14
|
+
fallback_allocator: Allocator,
|
|
15
|
+
fixed_buffer_allocator: FixedBufferAllocator,
|
|
16
|
+
|
|
17
|
+
pub fn init(buffer: []u8, fallback_allocator: Allocator) BufferFirstAllocator {
|
|
18
|
+
return .{
|
|
19
|
+
.fallback_allocator = fallback_allocator,
|
|
20
|
+
.fixed_buffer_allocator = .init(buffer),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
pub fn allocator(self: *BufferFirstAllocator) Allocator {
|
|
25
|
+
return .{
|
|
26
|
+
.ptr = self,
|
|
27
|
+
.vtable = &.{
|
|
28
|
+
.alloc = alloc,
|
|
29
|
+
.resize = resize,
|
|
30
|
+
.remap = remap,
|
|
31
|
+
.free = free,
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
fn alloc(
|
|
37
|
+
ctx: *anyopaque,
|
|
38
|
+
len: usize,
|
|
39
|
+
alignment: Alignment,
|
|
40
|
+
ra: usize,
|
|
41
|
+
) ?[*]u8 {
|
|
42
|
+
const self: *BufferFirstAllocator = @ptrCast(@alignCast(ctx));
|
|
43
|
+
return FixedBufferAllocator.alloc(&self.fixed_buffer_allocator, len, alignment, ra) orelse
|
|
44
|
+
return self.fallback_allocator.rawAlloc(len, alignment, ra);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
fn resize(
|
|
48
|
+
ctx: *anyopaque,
|
|
49
|
+
buf: []u8,
|
|
50
|
+
alignment: Alignment,
|
|
51
|
+
new_len: usize,
|
|
52
|
+
ra: usize,
|
|
53
|
+
) bool {
|
|
54
|
+
const self: *BufferFirstAllocator = @ptrCast(@alignCast(ctx));
|
|
55
|
+
if (self.fixed_buffer_allocator.ownsPtr(buf.ptr)) {
|
|
56
|
+
return FixedBufferAllocator.resize(&self.fixed_buffer_allocator, buf, alignment, new_len, ra);
|
|
57
|
+
} else {
|
|
58
|
+
return self.fallback_allocator.rawResize(buf, alignment, new_len, ra);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
fn remap(
|
|
63
|
+
context: *anyopaque,
|
|
64
|
+
memory: []u8,
|
|
65
|
+
alignment: Alignment,
|
|
66
|
+
new_len: usize,
|
|
67
|
+
return_address: usize,
|
|
68
|
+
) ?[*]u8 {
|
|
69
|
+
const self: *BufferFirstAllocator = @ptrCast(@alignCast(context));
|
|
70
|
+
if (self.fixed_buffer_allocator.ownsPtr(memory.ptr)) {
|
|
71
|
+
return FixedBufferAllocator.remap(&self.fixed_buffer_allocator, memory, alignment, new_len, return_address);
|
|
72
|
+
} else {
|
|
73
|
+
return self.fallback_allocator.rawRemap(memory, alignment, new_len, return_address);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
fn free(
|
|
78
|
+
ctx: *anyopaque,
|
|
79
|
+
buf: []u8,
|
|
80
|
+
alignment: Alignment,
|
|
81
|
+
ra: usize,
|
|
82
|
+
) void {
|
|
83
|
+
const self: *BufferFirstAllocator = @ptrCast(@alignCast(ctx));
|
|
84
|
+
if (self.fixed_buffer_allocator.ownsPtr(buf.ptr)) {
|
|
85
|
+
return FixedBufferAllocator.free(&self.fixed_buffer_allocator, buf, alignment, ra);
|
|
86
|
+
} else {
|
|
87
|
+
return self.fallback_allocator.rawFree(buf, alignment, ra);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
test "BufferFirstAllocator" {
|
|
92
|
+
// Buffer first specific tests
|
|
93
|
+
{
|
|
94
|
+
var buffer: [10]u8 = undefined;
|
|
95
|
+
var bfa_state: BufferFirstAllocator = .init(&buffer, std.testing.allocator);
|
|
96
|
+
const bfa = bfa_state.allocator();
|
|
97
|
+
|
|
98
|
+
// We're under the limit, so we should be allocated in the buffer
|
|
99
|
+
const txt0 = "hellowrld";
|
|
100
|
+
const buf0 = try bfa.create(@TypeOf(txt0.*));
|
|
101
|
+
buf0.* = txt0.*;
|
|
102
|
+
try testing.expect(bfa_state.fixed_buffer_allocator.ownsPtr(buf0.ptr));
|
|
103
|
+
|
|
104
|
+
// We're now over the limit, so we should be allocated from the fallback
|
|
105
|
+
const txt1 = "test!";
|
|
106
|
+
const buf1 = try bfa.create(@TypeOf(txt1.*));
|
|
107
|
+
buf1.* = txt1.*;
|
|
108
|
+
try testing.expect(!bfa_state.fixed_buffer_allocator.ownsPtr(buf1.ptr));
|
|
109
|
+
|
|
110
|
+
// Free the allocation that took up space in the buffer
|
|
111
|
+
try testing.expectEqualStrings(txt0, buf0);
|
|
112
|
+
bfa.destroy(buf0);
|
|
113
|
+
|
|
114
|
+
// The next allocation would go in the buffer, but it's too big so it doesn't
|
|
115
|
+
const txt2 = "qwertyqwerty";
|
|
116
|
+
const buf2 = try bfa.create(@TypeOf(txt2.*));
|
|
117
|
+
buf2.* = txt2.*;
|
|
118
|
+
try testing.expect(!bfa_state.fixed_buffer_allocator.ownsPtr(buf2.ptr));
|
|
119
|
+
|
|
120
|
+
// The next allocation is smaller and fits in the buffer
|
|
121
|
+
const txt3 = "dvorak";
|
|
122
|
+
const buf3 = try bfa.create(@TypeOf(txt3.*));
|
|
123
|
+
buf3.* = txt3.*;
|
|
124
|
+
try testing.expect(bfa_state.fixed_buffer_allocator.ownsPtr(buf3.ptr));
|
|
125
|
+
|
|
126
|
+
// The remainder in the buffer is too small for the following allocation so it falls back
|
|
127
|
+
const txt4 = "moretext";
|
|
128
|
+
const buf4 = try bfa.create(@TypeOf(txt4.*));
|
|
129
|
+
buf4.* = txt4.*;
|
|
130
|
+
try testing.expect(!bfa_state.fixed_buffer_allocator.ownsPtr(buf4.ptr));
|
|
131
|
+
|
|
132
|
+
// Check equality on the remaining buffers and free them
|
|
133
|
+
try testing.expectEqualStrings(txt1, buf1);
|
|
134
|
+
bfa.destroy(buf1);
|
|
135
|
+
try testing.expectEqualStrings(txt2, buf2);
|
|
136
|
+
bfa.destroy(buf2);
|
|
137
|
+
try testing.expectEqualStrings(txt3, buf3);
|
|
138
|
+
bfa.destroy(buf3);
|
|
139
|
+
try testing.expectEqualStrings(txt4, buf4);
|
|
140
|
+
bfa.destroy(buf4);
|
|
141
|
+
|
|
142
|
+
try testing.expectEqual(0, bfa_state.fixed_buffer_allocator.end_index);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Standard allocator tests
|
|
146
|
+
{
|
|
147
|
+
var buf: [4096]u8 = undefined;
|
|
148
|
+
{
|
|
149
|
+
var bfa: BufferFirstAllocator = .init(&buf, std.testing.allocator);
|
|
150
|
+
try heap.testAllocator(bfa.allocator());
|
|
151
|
+
}
|
|
152
|
+
{
|
|
153
|
+
var bfa: BufferFirstAllocator = .init(&buf, std.testing.allocator);
|
|
154
|
+
try heap.testAllocatorAligned(bfa.allocator());
|
|
155
|
+
}
|
|
156
|
+
{
|
|
157
|
+
var bfa: BufferFirstAllocator = .init(&buf, std.testing.allocator);
|
|
158
|
+
try heap.testAllocatorLargeAlignment(bfa.allocator());
|
|
159
|
+
}
|
|
160
|
+
{
|
|
161
|
+
var bfa: BufferFirstAllocator = .init(&buf, std.testing.allocator);
|
|
162
|
+
try heap.testAllocatorAlignedShrink(bfa.allocator());
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
package/std/heap.zig
CHANGED
|
@@ -12,6 +12,7 @@ const Alignment = std.mem.Alignment;
|
|
|
12
12
|
pub const ArenaAllocator = @import("heap/ArenaAllocator.zig");
|
|
13
13
|
pub const SmpAllocator = @import("heap/SmpAllocator.zig");
|
|
14
14
|
pub const FixedBufferAllocator = @import("heap/FixedBufferAllocator.zig");
|
|
15
|
+
pub const BufferFirstAllocator = @import("heap/BufferFirstAllocator.zig");
|
|
15
16
|
pub const PageAllocator = @import("heap/PageAllocator.zig");
|
|
16
17
|
pub const WasmAllocator = if (builtin.single_threaded) BrkAllocator else @compileError("unimplemented");
|
|
17
18
|
pub const BrkAllocator = @import("heap/BrkAllocator.zig");
|
|
@@ -367,113 +368,6 @@ pub const brk_allocator: Allocator = .{
|
|
|
367
368
|
.vtable = &BrkAllocator.vtable,
|
|
368
369
|
};
|
|
369
370
|
|
|
370
|
-
/// Returns a `StackFallbackAllocator` allocating using either a
|
|
371
|
-
/// `FixedBufferAllocator` on an array of size `size` and falling back to
|
|
372
|
-
/// `fallback_allocator` if that fails.
|
|
373
|
-
pub fn stackFallback(comptime size: usize, fallback_allocator: Allocator) StackFallbackAllocator(size) {
|
|
374
|
-
return StackFallbackAllocator(size){
|
|
375
|
-
.buffer = undefined,
|
|
376
|
-
.fallback_allocator = fallback_allocator,
|
|
377
|
-
.fixed_buffer_allocator = undefined,
|
|
378
|
-
};
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
/// An allocator that attempts to allocate using a
|
|
382
|
-
/// `FixedBufferAllocator` using an array of size `size`. If the
|
|
383
|
-
/// allocation fails, it will fall back to using
|
|
384
|
-
/// `fallback_allocator`. Easily created with `stackFallback`.
|
|
385
|
-
pub fn StackFallbackAllocator(comptime size: usize) type {
|
|
386
|
-
return struct {
|
|
387
|
-
const Self = @This();
|
|
388
|
-
|
|
389
|
-
buffer: [size]u8,
|
|
390
|
-
fallback_allocator: Allocator,
|
|
391
|
-
fixed_buffer_allocator: FixedBufferAllocator,
|
|
392
|
-
get_called: if (std.debug.runtime_safety) bool else void =
|
|
393
|
-
if (std.debug.runtime_safety) false else {},
|
|
394
|
-
|
|
395
|
-
/// This function both fetches a `Allocator` interface to this
|
|
396
|
-
/// allocator *and* resets the internal buffer allocator.
|
|
397
|
-
pub fn get(self: *Self) Allocator {
|
|
398
|
-
if (std.debug.runtime_safety) {
|
|
399
|
-
assert(!self.get_called); // `get` called multiple times; instead use `const allocator = stackFallback(N).get();`
|
|
400
|
-
self.get_called = true;
|
|
401
|
-
}
|
|
402
|
-
self.fixed_buffer_allocator = FixedBufferAllocator.init(self.buffer[0..]);
|
|
403
|
-
return .{
|
|
404
|
-
.ptr = self,
|
|
405
|
-
.vtable = &.{
|
|
406
|
-
.alloc = alloc,
|
|
407
|
-
.resize = resize,
|
|
408
|
-
.remap = remap,
|
|
409
|
-
.free = free,
|
|
410
|
-
},
|
|
411
|
-
};
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
/// Unlike most std allocators `StackFallbackAllocator` modifies
|
|
415
|
-
/// its internal state before returning an implementation of
|
|
416
|
-
/// the`Allocator` interface and therefore also doesn't use
|
|
417
|
-
/// the usual `.allocator()` method.
|
|
418
|
-
pub const allocator = @compileError("use 'const allocator = stackFallback(N).get();' instead");
|
|
419
|
-
|
|
420
|
-
fn alloc(
|
|
421
|
-
ctx: *anyopaque,
|
|
422
|
-
len: usize,
|
|
423
|
-
alignment: Alignment,
|
|
424
|
-
ra: usize,
|
|
425
|
-
) ?[*]u8 {
|
|
426
|
-
const self: *Self = @ptrCast(@alignCast(ctx));
|
|
427
|
-
return FixedBufferAllocator.alloc(&self.fixed_buffer_allocator, len, alignment, ra) orelse
|
|
428
|
-
return self.fallback_allocator.rawAlloc(len, alignment, ra);
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
fn resize(
|
|
432
|
-
ctx: *anyopaque,
|
|
433
|
-
buf: []u8,
|
|
434
|
-
alignment: Alignment,
|
|
435
|
-
new_len: usize,
|
|
436
|
-
ra: usize,
|
|
437
|
-
) bool {
|
|
438
|
-
const self: *Self = @ptrCast(@alignCast(ctx));
|
|
439
|
-
if (self.fixed_buffer_allocator.ownsPtr(buf.ptr)) {
|
|
440
|
-
return FixedBufferAllocator.resize(&self.fixed_buffer_allocator, buf, alignment, new_len, ra);
|
|
441
|
-
} else {
|
|
442
|
-
return self.fallback_allocator.rawResize(buf, alignment, new_len, ra);
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
fn remap(
|
|
447
|
-
context: *anyopaque,
|
|
448
|
-
memory: []u8,
|
|
449
|
-
alignment: Alignment,
|
|
450
|
-
new_len: usize,
|
|
451
|
-
return_address: usize,
|
|
452
|
-
) ?[*]u8 {
|
|
453
|
-
const self: *Self = @ptrCast(@alignCast(context));
|
|
454
|
-
if (self.fixed_buffer_allocator.ownsPtr(memory.ptr)) {
|
|
455
|
-
return FixedBufferAllocator.remap(&self.fixed_buffer_allocator, memory, alignment, new_len, return_address);
|
|
456
|
-
} else {
|
|
457
|
-
return self.fallback_allocator.rawRemap(memory, alignment, new_len, return_address);
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
fn free(
|
|
462
|
-
ctx: *anyopaque,
|
|
463
|
-
buf: []u8,
|
|
464
|
-
alignment: Alignment,
|
|
465
|
-
ra: usize,
|
|
466
|
-
) void {
|
|
467
|
-
const self: *Self = @ptrCast(@alignCast(ctx));
|
|
468
|
-
if (self.fixed_buffer_allocator.ownsPtr(buf.ptr)) {
|
|
469
|
-
return FixedBufferAllocator.free(&self.fixed_buffer_allocator, buf, alignment, ra);
|
|
470
|
-
} else {
|
|
471
|
-
return self.fallback_allocator.rawFree(buf, alignment, ra);
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
};
|
|
475
|
-
}
|
|
476
|
-
|
|
477
371
|
test c_allocator {
|
|
478
372
|
if (builtin.link_libc) {
|
|
479
373
|
try testAllocator(c_allocator);
|
|
@@ -524,25 +418,6 @@ test ArenaAllocator {
|
|
|
524
418
|
try testAllocatorAlignedShrink(allocator);
|
|
525
419
|
}
|
|
526
420
|
|
|
527
|
-
test "StackFallbackAllocator" {
|
|
528
|
-
{
|
|
529
|
-
var stack_allocator = stackFallback(4096, std.testing.allocator);
|
|
530
|
-
try testAllocator(stack_allocator.get());
|
|
531
|
-
}
|
|
532
|
-
{
|
|
533
|
-
var stack_allocator = stackFallback(4096, std.testing.allocator);
|
|
534
|
-
try testAllocatorAligned(stack_allocator.get());
|
|
535
|
-
}
|
|
536
|
-
{
|
|
537
|
-
var stack_allocator = stackFallback(4096, std.testing.allocator);
|
|
538
|
-
try testAllocatorLargeAlignment(stack_allocator.get());
|
|
539
|
-
}
|
|
540
|
-
{
|
|
541
|
-
var stack_allocator = stackFallback(4096, std.testing.allocator);
|
|
542
|
-
try testAllocatorAlignedShrink(stack_allocator.get());
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
|
|
546
421
|
/// This one should not try alignments that exceed what C malloc can handle.
|
|
547
422
|
pub fn testAllocator(base_allocator: mem.Allocator) !void {
|
|
548
423
|
var validationAllocator = mem.validationWrap(base_allocator);
|
|
@@ -1011,6 +886,7 @@ test {
|
|
|
1011
886
|
_ = ArenaAllocator;
|
|
1012
887
|
_ = DebugAllocator(.{});
|
|
1013
888
|
_ = FixedBufferAllocator;
|
|
889
|
+
_ = BufferFirstAllocator;
|
|
1014
890
|
if (builtin.single_threaded) {
|
|
1015
891
|
if (builtin.cpu.arch.isWasm() or (builtin.os.tag == .linux and !builtin.link_libc)) {
|
|
1016
892
|
_ = brk_allocator;
|