authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-11-30 18:48:31-08:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2021-11-30 18:48:31-08:00
log7355a201336c8e3892427e5932fe5cdd46cf96df
tree4ccec922634586847d02f2324d0db75f25200188
parentdd62a6d2e8de522187fd096354e7156cca1821c5
parent066eaa5e9cbfde172449f6d95bb884c7d86ac10c
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #10055 from leecannon/allocator_refactor

Allocgate

166 files changed, 1867 insertions(+), 1611 deletions(-)

ci/srht/update-download-page.zig+2-2
...@@ -6,7 +6,7 @@ pub fn main() !void {...@@ -6,7 +6,7 @@ pub fn main() !void {
6 var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);6 var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
7 defer arena.deinit();7 defer arena.deinit();
88
9 const allocator = &arena.allocator;9 const allocator = arena.allocator();
1010
11 const out_dir = "out";11 const out_dir = "out";
12 try std.fs.cwd().makePath(out_dir);12 try std.fs.cwd().makePath(out_dir);
...@@ -18,7 +18,7 @@ pub fn main() !void {...@@ -18,7 +18,7 @@ pub fn main() !void {
18}18}
1919
20fn render(20fn render(
21 allocator: *mem.Allocator,21 allocator: mem.Allocator,
22 in_file: []const u8,22 in_file: []const u8,
23 out_file: []const u8,23 out_file: []const u8,
24 fmt: enum {24 fmt: enum {
doc/docgen.zig+11-11
...@@ -21,7 +21,7 @@ pub fn main() !void {...@@ -21,7 +21,7 @@ pub fn main() !void {
21 var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);21 var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
22 defer arena.deinit();22 defer arena.deinit();
2323
24 const allocator = &arena.allocator;24 const allocator = arena.allocator();
2525
26 var args_it = process.args();26 var args_it = process.args();
2727
...@@ -342,7 +342,7 @@ const Action = enum {...@@ -342,7 +342,7 @@ const Action = enum {
342 Close,342 Close,
343};343};
344344
345fn genToc(allocator: *Allocator, tokenizer: *Tokenizer) !Toc {345fn genToc(allocator: Allocator, tokenizer: *Tokenizer) !Toc {
346 var urls = std.StringHashMap(Token).init(allocator);346 var urls = std.StringHashMap(Token).init(allocator);
347 errdefer urls.deinit();347 errdefer urls.deinit();
348348
...@@ -708,7 +708,7 @@ fn genToc(allocator: *Allocator, tokenizer: *Tokenizer) !Toc {...@@ -708,7 +708,7 @@ fn genToc(allocator: *Allocator, tokenizer: *Tokenizer) !Toc {
708 };708 };
709}709}
710710
711fn urlize(allocator: *Allocator, input: []const u8) ![]u8 {711fn urlize(allocator: Allocator, input: []const u8) ![]u8 {
712 var buf = std.ArrayList(u8).init(allocator);712 var buf = std.ArrayList(u8).init(allocator);
713 defer buf.deinit();713 defer buf.deinit();
714714
...@@ -727,7 +727,7 @@ fn urlize(allocator: *Allocator, input: []const u8) ![]u8 {...@@ -727,7 +727,7 @@ fn urlize(allocator: *Allocator, input: []const u8) ![]u8 {
727 return buf.toOwnedSlice();727 return buf.toOwnedSlice();
728}728}
729729
730fn escapeHtml(allocator: *Allocator, input: []const u8) ![]u8 {730fn escapeHtml(allocator: Allocator, input: []const u8) ![]u8 {
731 var buf = std.ArrayList(u8).init(allocator);731 var buf = std.ArrayList(u8).init(allocator);
732 defer buf.deinit();732 defer buf.deinit();
733733
...@@ -773,7 +773,7 @@ test "term color" {...@@ -773,7 +773,7 @@ test "term color" {
773 try testing.expectEqualSlices(u8, "A<span class=\"t32_1\">green</span>B", result);773 try testing.expectEqualSlices(u8, "A<span class=\"t32_1\">green</span>B", result);
774}774}
775775
776fn termColor(allocator: *Allocator, input: []const u8) ![]u8 {776fn termColor(allocator: Allocator, input: []const u8) ![]u8 {
777 var buf = std.ArrayList(u8).init(allocator);777 var buf = std.ArrayList(u8).init(allocator);
778 defer buf.deinit();778 defer buf.deinit();
779779
...@@ -883,7 +883,7 @@ fn writeEscapedLines(out: anytype, text: []const u8) !void {...@@ -883,7 +883,7 @@ fn writeEscapedLines(out: anytype, text: []const u8) !void {
883}883}
884884
885fn tokenizeAndPrintRaw(885fn tokenizeAndPrintRaw(
886 allocator: *Allocator,886 allocator: Allocator,
887 docgen_tokenizer: *Tokenizer,887 docgen_tokenizer: *Tokenizer,
888 out: anytype,888 out: anytype,
889 source_token: Token,889 source_token: Token,
...@@ -1137,7 +1137,7 @@ fn tokenizeAndPrintRaw(...@@ -1137,7 +1137,7 @@ fn tokenizeAndPrintRaw(
1137}1137}
11381138
1139fn tokenizeAndPrint(1139fn tokenizeAndPrint(
1140 allocator: *Allocator,1140 allocator: Allocator,
1141 docgen_tokenizer: *Tokenizer,1141 docgen_tokenizer: *Tokenizer,
1142 out: anytype,1142 out: anytype,
1143 source_token: Token,1143 source_token: Token,
...@@ -1146,7 +1146,7 @@ fn tokenizeAndPrint(...@@ -1146,7 +1146,7 @@ fn tokenizeAndPrint(
1146 return tokenizeAndPrintRaw(allocator, docgen_tokenizer, out, source_token, raw_src);1146 return tokenizeAndPrintRaw(allocator, docgen_tokenizer, out, source_token, raw_src);
1147}1147}
11481148
1149fn printSourceBlock(allocator: *Allocator, docgen_tokenizer: *Tokenizer, out: anytype, syntax_block: SyntaxBlock) !void {1149fn printSourceBlock(allocator: Allocator, docgen_tokenizer: *Tokenizer, out: anytype, syntax_block: SyntaxBlock) !void {
1150 const source_type = @tagName(syntax_block.source_type);1150 const source_type = @tagName(syntax_block.source_type);
11511151
1152 try out.print("<figure><figcaption class=\"{s}-cap\"><cite class=\"file\">{s}</cite></figcaption><pre>", .{ source_type, syntax_block.name });1152 try out.print("<figure><figcaption class=\"{s}-cap\"><cite class=\"file\">{s}</cite></figcaption><pre>", .{ source_type, syntax_block.name });
...@@ -1188,7 +1188,7 @@ fn printShell(out: anytype, shell_content: []const u8) !void {...@@ -1188,7 +1188,7 @@ fn printShell(out: anytype, shell_content: []const u8) !void {
1188}1188}
11891189
1190fn genHtml(1190fn genHtml(
1191 allocator: *Allocator,1191 allocator: Allocator,
1192 tokenizer: *Tokenizer,1192 tokenizer: *Tokenizer,
1193 toc: *Toc,1193 toc: *Toc,
1194 out: anytype,1194 out: anytype,
...@@ -1687,7 +1687,7 @@ fn genHtml(...@@ -1687,7 +1687,7 @@ fn genHtml(
1687 }1687 }
1688}1688}
16891689
1690fn exec(allocator: *Allocator, env_map: *std.BufMap, args: []const []const u8) !ChildProcess.ExecResult {1690fn exec(allocator: Allocator, env_map: *std.BufMap, args: []const []const u8) !ChildProcess.ExecResult {
1691 const result = try ChildProcess.exec(.{1691 const result = try ChildProcess.exec(.{
1692 .allocator = allocator,1692 .allocator = allocator,
1693 .argv = args,1693 .argv = args,
...@@ -1711,7 +1711,7 @@ fn exec(allocator: *Allocator, env_map: *std.BufMap, args: []const []const u8) !...@@ -1711,7 +1711,7 @@ fn exec(allocator: *Allocator, env_map: *std.BufMap, args: []const []const u8) !
1711 return result;1711 return result;
1712}1712}
17131713
1714fn getBuiltinCode(allocator: *Allocator, env_map: *std.BufMap, zig_exe: []const u8) ![]const u8 {1714fn getBuiltinCode(allocator: Allocator, env_map: *std.BufMap, zig_exe: []const u8) ![]const u8 {
1715 const result = try exec(allocator, env_map, &[_][]const u8{ zig_exe, "build-obj", "--show-builtin" });1715 const result = try exec(allocator, env_map, &[_][]const u8{ zig_exe, "build-obj", "--show-builtin" });
1716 return result.stdout;1716 return result.stdout;
1717}1717}
doc/langref.html.in+14-14
...@@ -7362,7 +7362,7 @@ fn amain() !void {...@@ -7362,7 +7362,7 @@ fn amain() !void {
7362}7362}
73637363
7364var global_download_frame: anyframe = undefined;7364var global_download_frame: anyframe = undefined;
7365fn fetchUrl(allocator: *Allocator, url: []const u8) ![]u8 {7365fn fetchUrl(allocator: Allocator, url: []const u8) ![]u8 {
7366 _ = url; // this is just an example, we don't actually do it!7366 _ = url; // this is just an example, we don't actually do it!
7367 const result = try allocator.dupe(u8, "this is the downloaded url contents");7367 const result = try allocator.dupe(u8, "this is the downloaded url contents");
7368 errdefer allocator.free(result);7368 errdefer allocator.free(result);
...@@ -7374,7 +7374,7 @@ fn fetchUrl(allocator: *Allocator, url: []const u8) ![]u8 {...@@ -7374,7 +7374,7 @@ fn fetchUrl(allocator: *Allocator, url: []const u8) ![]u8 {
7374}7374}
73757375
7376var global_file_frame: anyframe = undefined;7376var global_file_frame: anyframe = undefined;
7377fn readFile(allocator: *Allocator, filename: []const u8) ![]u8 {7377fn readFile(allocator: Allocator, filename: []const u8) ![]u8 {
7378 _ = filename; // this is just an example, we don't actually do it!7378 _ = filename; // this is just an example, we don't actually do it!
7379 const result = try allocator.dupe(u8, "this is the file contents");7379 const result = try allocator.dupe(u8, "this is the file contents");
7380 errdefer allocator.free(result);7380 errdefer allocator.free(result);
...@@ -7433,7 +7433,7 @@ fn amain() !void {...@@ -7433,7 +7433,7 @@ fn amain() !void {
7433 std.debug.print("file_text: {s}\n", .{file_text});7433 std.debug.print("file_text: {s}\n", .{file_text});
7434}7434}
74357435
7436fn fetchUrl(allocator: *Allocator, url: []const u8) ![]u8 {7436fn fetchUrl(allocator: Allocator, url: []const u8) ![]u8 {
7437 _ = url; // this is just an example, we don't actually do it!7437 _ = url; // this is just an example, we don't actually do it!
7438 const result = try allocator.dupe(u8, "this is the downloaded url contents");7438 const result = try allocator.dupe(u8, "this is the downloaded url contents");
7439 errdefer allocator.free(result);7439 errdefer allocator.free(result);
...@@ -7441,7 +7441,7 @@ fn fetchUrl(allocator: *Allocator, url: []const u8) ![]u8 {...@@ -7441,7 +7441,7 @@ fn fetchUrl(allocator: *Allocator, url: []const u8) ![]u8 {
7441 return result;7441 return result;
7442}7442}
74437443
7444fn readFile(allocator: *Allocator, filename: []const u8) ![]u8 {7444fn readFile(allocator: Allocator, filename: []const u8) ![]u8 {
7445 _ = filename; // this is just an example, we don't actually do it!7445 _ = filename; // this is just an example, we don't actually do it!
7446 const result = try allocator.dupe(u8, "this is the file contents");7446 const result = try allocator.dupe(u8, "this is the file contents");
7447 errdefer allocator.free(result);7447 errdefer allocator.free(result);
...@@ -10050,8 +10050,8 @@ pub fn main() void {...@@ -10050,8 +10050,8 @@ pub fn main() void {
10050 C has a default allocator - <code>malloc</code>, <code>realloc</code>, and <code>free</code>.10050 C has a default allocator - <code>malloc</code>, <code>realloc</code>, and <code>free</code>.
10051 When linking against libc, Zig exposes this allocator with {#syntax#}std.heap.c_allocator{#endsyntax#}.10051 When linking against libc, Zig exposes this allocator with {#syntax#}std.heap.c_allocator{#endsyntax#}.
10052 However, by convention, there is no default allocator in Zig. Instead, functions which need to10052 However, by convention, there is no default allocator in Zig. Instead, functions which need to
10053 allocate accept an {#syntax#}*Allocator{#endsyntax#} parameter. Likewise, data structures such as10053 allocate accept an {#syntax#}Allocator{#endsyntax#} parameter. Likewise, data structures such as
10054 {#syntax#}std.ArrayList{#endsyntax#} accept an {#syntax#}*Allocator{#endsyntax#} parameter in10054 {#syntax#}std.ArrayList{#endsyntax#} accept an {#syntax#}Allocator{#endsyntax#} parameter in
10055 their initialization functions:10055 their initialization functions:
10056 </p>10056 </p>
10057 {#code_begin|test|allocator#}10057 {#code_begin|test|allocator#}
...@@ -10061,12 +10061,12 @@ const expect = std.testing.expect;...@@ -10061,12 +10061,12 @@ const expect = std.testing.expect;
1006110061
10062test "using an allocator" {10062test "using an allocator" {
10063 var buffer: [100]u8 = undefined;10063 var buffer: [100]u8 = undefined;
10064 const allocator = &std.heap.FixedBufferAllocator.init(&buffer).allocator;10064 const allocator = std.heap.FixedBufferAllocator.init(&buffer).allocator();
10065 const result = try concat(allocator, "foo", "bar");10065 const result = try concat(allocator, "foo", "bar");
10066 try expect(std.mem.eql(u8, "foobar", result));10066 try expect(std.mem.eql(u8, "foobar", result));
10067}10067}
1006810068
10069fn concat(allocator: *Allocator, a: []const u8, b: []const u8) ![]u8 {10069fn concat(allocator: Allocator, a: []const u8, b: []const u8) ![]u8 {
10070 const result = try allocator.alloc(u8, a.len + b.len);10070 const result = try allocator.alloc(u8, a.len + b.len);
10071 std.mem.copy(u8, result, a);10071 std.mem.copy(u8, result, a);
10072 std.mem.copy(u8, result[a.len..], b);10072 std.mem.copy(u8, result[a.len..], b);
...@@ -10091,7 +10091,7 @@ fn concat(allocator: *Allocator, a: []const u8, b: []const u8) ![]u8 {...@@ -10091,7 +10091,7 @@ fn concat(allocator: *Allocator, a: []const u8, b: []const u8) ![]u8 {
10091 </p>10091 </p>
10092 <ol>10092 <ol>
10093 <li>10093 <li>
10094 Are you making a library? In this case, best to accept an {#syntax#}*Allocator{#endsyntax#}10094 Are you making a library? In this case, best to accept an {#syntax#}Allocator{#endsyntax#}
10095 as a parameter and allow your library's users to decide what allocator to use.10095 as a parameter and allow your library's users to decide what allocator to use.
10096 </li>10096 </li>
10097 <li>Are you linking libc? In this case, {#syntax#}std.heap.c_allocator{#endsyntax#} is likely10097 <li>Are you linking libc? In this case, {#syntax#}std.heap.c_allocator{#endsyntax#} is likely
...@@ -10114,7 +10114,7 @@ pub fn main() !void {...@@ -10114,7 +10114,7 @@ pub fn main() !void {
10114 var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);10114 var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
10115 defer arena.deinit();10115 defer arena.deinit();
1011610116
10117 const allocator = &arena.allocator;10117 const allocator = arena.allocator();
1011810118
10119 const ptr = try allocator.create(i32);10119 const ptr = try allocator.create(i32);
10120 std.debug.print("ptr={*}\n", .{ptr});10120 std.debug.print("ptr={*}\n", .{ptr});
...@@ -10200,7 +10200,7 @@ test "string literal to constant slice" {...@@ -10200,7 +10200,7 @@ test "string literal to constant slice" {
10200 {#header_open|Implementing an Allocator#}10200 {#header_open|Implementing an Allocator#}
10201 <p>Zig programmers can implement their own allocators by fulfilling the Allocator interface.10201 <p>Zig programmers can implement their own allocators by fulfilling the Allocator interface.
10202 In order to do this one must read carefully the documentation comments in std/mem.zig and10202 In order to do this one must read carefully the documentation comments in std/mem.zig and
10203 then supply a {#syntax#}reallocFn{#endsyntax#} and a {#syntax#}shrinkFn{#endsyntax#}.10203 then supply a {#syntax#}allocFn{#endsyntax#} and a {#syntax#}resizeFn{#endsyntax#}.
10204 </p>10204 </p>
10205 <p>10205 <p>
10206 There are many example allocators to look at for inspiration. Look at std/heap.zig and10206 There are many example allocators to look at for inspiration. Look at std/heap.zig and
...@@ -10281,7 +10281,7 @@ test "string literal to constant slice" {...@@ -10281,7 +10281,7 @@ test "string literal to constant slice" {
10281 <p>10281 <p>
10282 For example, the function's documentation may say "caller owns the returned memory", in which case10282 For example, the function's documentation may say "caller owns the returned memory", in which case
10283 the code that calls the function must have a plan for when to free that memory. Probably in this situation,10283 the code that calls the function must have a plan for when to free that memory. Probably in this situation,
10284 the function will accept an {#syntax#}*Allocator{#endsyntax#} parameter.10284 the function will accept an {#syntax#}Allocator{#endsyntax#} parameter.
10285 </p>10285 </p>
10286 <p>10286 <p>
10287 Sometimes the lifetime of a pointer may be more complicated. For example, the10287 Sometimes the lifetime of a pointer may be more complicated. For example, the
...@@ -10820,7 +10820,7 @@ const std = @import("std");...@@ -10820,7 +10820,7 @@ const std = @import("std");
1082010820
10821pub fn main() !void {10821pub fn main() !void {
10822 var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){};10822 var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){};
10823 const gpa = &general_purpose_allocator.allocator;10823 const gpa = general_purpose_allocator.allocator();
10824 const args = try std.process.argsAlloc(gpa);10824 const args = try std.process.argsAlloc(gpa);
10825 defer std.process.argsFree(gpa, args);10825 defer std.process.argsFree(gpa, args);
1082610826
...@@ -10842,7 +10842,7 @@ const PreopenList = std.fs.wasi.PreopenList;...@@ -10842,7 +10842,7 @@ const PreopenList = std.fs.wasi.PreopenList;
1084210842
10843pub fn main() !void {10843pub fn main() !void {
10844 var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){};10844 var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){};
10845 const gpa = &general_purpose_allocator.allocator;10845 const gpa = general_purpose_allocator.allocator();
1084610846
10847 var preopens = PreopenList.init(gpa);10847 var preopens = PreopenList.init(gpa);
10848 defer preopens.deinit();10848 defer preopens.deinit();
lib/std/Thread.zig+1-1
...@@ -460,7 +460,7 @@ const WindowsThreadImpl = struct {...@@ -460,7 +460,7 @@ const WindowsThreadImpl = struct {
460 errdefer assert(windows.kernel32.HeapFree(heap_handle, 0, alloc_ptr) != 0);460 errdefer assert(windows.kernel32.HeapFree(heap_handle, 0, alloc_ptr) != 0);
461461
462 const instance_bytes = @ptrCast([*]u8, alloc_ptr)[0..alloc_bytes];462 const instance_bytes = @ptrCast([*]u8, alloc_ptr)[0..alloc_bytes];
463 const instance = std.heap.FixedBufferAllocator.init(instance_bytes).allocator.create(Instance) catch unreachable;463 const instance = std.heap.FixedBufferAllocator.init(instance_bytes).allocator().create(Instance) catch unreachable;
464 instance.* = .{464 instance.* = .{
465 .fn_args = args,465 .fn_args = args,
466 .thread = .{466 .thread = .{
lib/std/array_hash_map.zig+33-33
...@@ -79,7 +79,7 @@ pub fn ArrayHashMap(...@@ -79,7 +79,7 @@ pub fn ArrayHashMap(
79 comptime std.hash_map.verifyContext(Context, K, K, u32);79 comptime std.hash_map.verifyContext(Context, K, K, u32);
80 return struct {80 return struct {
81 unmanaged: Unmanaged,81 unmanaged: Unmanaged,
82 allocator: *Allocator,82 allocator: Allocator,
83 ctx: Context,83 ctx: Context,
8484
85 /// The ArrayHashMapUnmanaged type using the same settings as this managed map.85 /// The ArrayHashMapUnmanaged type using the same settings as this managed map.
...@@ -118,12 +118,12 @@ pub fn ArrayHashMap(...@@ -118,12 +118,12 @@ pub fn ArrayHashMap(
118 const Self = @This();118 const Self = @This();
119119
120 /// Create an ArrayHashMap instance which will use a specified allocator.120 /// Create an ArrayHashMap instance which will use a specified allocator.
121 pub fn init(allocator: *Allocator) Self {121 pub fn init(allocator: Allocator) Self {
122 if (@sizeOf(Context) != 0)122 if (@sizeOf(Context) != 0)
123 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call initContext instead.");123 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call initContext instead.");
124 return initContext(allocator, undefined);124 return initContext(allocator, undefined);
125 }125 }
126 pub fn initContext(allocator: *Allocator, ctx: Context) Self {126 pub fn initContext(allocator: Allocator, ctx: Context) Self {
127 return .{127 return .{
128 .unmanaged = .{},128 .unmanaged = .{},
129 .allocator = allocator,129 .allocator = allocator,
...@@ -383,7 +383,7 @@ pub fn ArrayHashMap(...@@ -383,7 +383,7 @@ pub fn ArrayHashMap(
383 /// Create a copy of the hash map which can be modified separately.383 /// Create a copy of the hash map which can be modified separately.
384 /// The copy uses the same context as this instance, but the specified384 /// The copy uses the same context as this instance, but the specified
385 /// allocator.385 /// allocator.
386 pub fn cloneWithAllocator(self: Self, allocator: *Allocator) !Self {386 pub fn cloneWithAllocator(self: Self, allocator: Allocator) !Self {
387 var other = try self.unmanaged.cloneContext(allocator, self.ctx);387 var other = try self.unmanaged.cloneContext(allocator, self.ctx);
388 return other.promoteContext(allocator, self.ctx);388 return other.promoteContext(allocator, self.ctx);
389 }389 }
...@@ -396,7 +396,7 @@ pub fn ArrayHashMap(...@@ -396,7 +396,7 @@ pub fn ArrayHashMap(
396 }396 }
397 /// Create a copy of the hash map which can be modified separately.397 /// Create a copy of the hash map which can be modified separately.
398 /// The copy uses the specified allocator and context.398 /// The copy uses the specified allocator and context.
399 pub fn cloneWithAllocatorAndContext(self: Self, allocator: *Allocator, ctx: anytype) !ArrayHashMap(K, V, @TypeOf(ctx), store_hash) {399 pub fn cloneWithAllocatorAndContext(self: Self, allocator: Allocator, ctx: anytype) !ArrayHashMap(K, V, @TypeOf(ctx), store_hash) {
400 var other = try self.unmanaged.cloneContext(allocator, ctx);400 var other = try self.unmanaged.cloneContext(allocator, ctx);
401 return other.promoteContext(allocator, ctx);401 return other.promoteContext(allocator, ctx);
402 }402 }
...@@ -533,12 +533,12 @@ pub fn ArrayHashMapUnmanaged(...@@ -533,12 +533,12 @@ pub fn ArrayHashMapUnmanaged(
533533
534 /// Convert from an unmanaged map to a managed map. After calling this,534 /// Convert from an unmanaged map to a managed map. After calling this,
535 /// the promoted map should no longer be used.535 /// the promoted map should no longer be used.
536 pub fn promote(self: Self, allocator: *Allocator) Managed {536 pub fn promote(self: Self, allocator: Allocator) Managed {
537 if (@sizeOf(Context) != 0)537 if (@sizeOf(Context) != 0)
538 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call promoteContext instead.");538 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call promoteContext instead.");
539 return self.promoteContext(allocator, undefined);539 return self.promoteContext(allocator, undefined);
540 }540 }
541 pub fn promoteContext(self: Self, allocator: *Allocator, ctx: Context) Managed {541 pub fn promoteContext(self: Self, allocator: Allocator, ctx: Context) Managed {
542 return .{542 return .{
543 .unmanaged = self,543 .unmanaged = self,
544 .allocator = allocator,544 .allocator = allocator,
...@@ -549,7 +549,7 @@ pub fn ArrayHashMapUnmanaged(...@@ -549,7 +549,7 @@ pub fn ArrayHashMapUnmanaged(
549 /// Frees the backing allocation and leaves the map in an undefined state.549 /// Frees the backing allocation and leaves the map in an undefined state.
550 /// Note that this does not free keys or values. You must take care of that550 /// Note that this does not free keys or values. You must take care of that
551 /// before calling this function, if it is needed.551 /// before calling this function, if it is needed.
552 pub fn deinit(self: *Self, allocator: *Allocator) void {552 pub fn deinit(self: *Self, allocator: Allocator) void {
553 self.entries.deinit(allocator);553 self.entries.deinit(allocator);
554 if (self.index_header) |header| {554 if (self.index_header) |header| {
555 header.free(allocator);555 header.free(allocator);
...@@ -570,7 +570,7 @@ pub fn ArrayHashMapUnmanaged(...@@ -570,7 +570,7 @@ pub fn ArrayHashMapUnmanaged(
570 }570 }
571571
572 /// Clears the map and releases the backing allocation572 /// Clears the map and releases the backing allocation
573 pub fn clearAndFree(self: *Self, allocator: *Allocator) void {573 pub fn clearAndFree(self: *Self, allocator: Allocator) void {
574 self.entries.shrinkAndFree(allocator, 0);574 self.entries.shrinkAndFree(allocator, 0);
575 if (self.index_header) |header| {575 if (self.index_header) |header| {
576 header.free(allocator);576 header.free(allocator);
...@@ -633,24 +633,24 @@ pub fn ArrayHashMapUnmanaged(...@@ -633,24 +633,24 @@ pub fn ArrayHashMapUnmanaged(
633 /// Otherwise, puts a new item with undefined value, and633 /// Otherwise, puts a new item with undefined value, and
634 /// the `Entry` pointer points to it. Caller should then initialize634 /// the `Entry` pointer points to it. Caller should then initialize
635 /// the value (but not the key).635 /// the value (but not the key).
636 pub fn getOrPut(self: *Self, allocator: *Allocator, key: K) !GetOrPutResult {636 pub fn getOrPut(self: *Self, allocator: Allocator, key: K) !GetOrPutResult {
637 if (@sizeOf(Context) != 0)637 if (@sizeOf(Context) != 0)
638 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getOrPutContext instead.");638 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getOrPutContext instead.");
639 return self.getOrPutContext(allocator, key, undefined);639 return self.getOrPutContext(allocator, key, undefined);
640 }640 }
641 pub fn getOrPutContext(self: *Self, allocator: *Allocator, key: K, ctx: Context) !GetOrPutResult {641 pub fn getOrPutContext(self: *Self, allocator: Allocator, key: K, ctx: Context) !GetOrPutResult {
642 const gop = try self.getOrPutContextAdapted(allocator, key, ctx, ctx);642 const gop = try self.getOrPutContextAdapted(allocator, key, ctx, ctx);
643 if (!gop.found_existing) {643 if (!gop.found_existing) {
644 gop.key_ptr.* = key;644 gop.key_ptr.* = key;
645 }645 }
646 return gop;646 return gop;
647 }647 }
648 pub fn getOrPutAdapted(self: *Self, allocator: *Allocator, key: anytype, key_ctx: anytype) !GetOrPutResult {648 pub fn getOrPutAdapted(self: *Self, allocator: Allocator, key: anytype, key_ctx: anytype) !GetOrPutResult {
649 if (@sizeOf(Context) != 0)649 if (@sizeOf(Context) != 0)
650 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getOrPutContextAdapted instead.");650 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getOrPutContextAdapted instead.");
651 return self.getOrPutContextAdapted(allocator, key, key_ctx, undefined);651 return self.getOrPutContextAdapted(allocator, key, key_ctx, undefined);
652 }652 }
653 pub fn getOrPutContextAdapted(self: *Self, allocator: *Allocator, key: anytype, key_ctx: anytype, ctx: Context) !GetOrPutResult {653 pub fn getOrPutContextAdapted(self: *Self, allocator: Allocator, key: anytype, key_ctx: anytype, ctx: Context) !GetOrPutResult {
654 self.ensureTotalCapacityContext(allocator, self.entries.len + 1, ctx) catch |err| {654 self.ensureTotalCapacityContext(allocator, self.entries.len + 1, ctx) catch |err| {
655 // "If key exists this function cannot fail."655 // "If key exists this function cannot fail."
656 const index = self.getIndexAdapted(key, key_ctx) orelse return err;656 const index = self.getIndexAdapted(key, key_ctx) orelse return err;
...@@ -731,12 +731,12 @@ pub fn ArrayHashMapUnmanaged(...@@ -731,12 +731,12 @@ pub fn ArrayHashMapUnmanaged(
731 }731 }
732 }732 }
733733
734 pub fn getOrPutValue(self: *Self, allocator: *Allocator, key: K, value: V) !GetOrPutResult {734 pub fn getOrPutValue(self: *Self, allocator: Allocator, key: K, value: V) !GetOrPutResult {
735 if (@sizeOf(Context) != 0)735 if (@sizeOf(Context) != 0)
736 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getOrPutValueContext instead.");736 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getOrPutValueContext instead.");
737 return self.getOrPutValueContext(allocator, key, value, undefined);737 return self.getOrPutValueContext(allocator, key, value, undefined);
738 }738 }
739 pub fn getOrPutValueContext(self: *Self, allocator: *Allocator, key: K, value: V, ctx: Context) !GetOrPutResult {739 pub fn getOrPutValueContext(self: *Self, allocator: Allocator, key: K, value: V, ctx: Context) !GetOrPutResult {
740 const res = try self.getOrPutContextAdapted(allocator, key, ctx, ctx);740 const res = try self.getOrPutContextAdapted(allocator, key, ctx, ctx);
741 if (!res.found_existing) {741 if (!res.found_existing) {
742 res.key_ptr.* = key;742 res.key_ptr.* = key;
...@@ -749,12 +749,12 @@ pub fn ArrayHashMapUnmanaged(...@@ -749,12 +749,12 @@ pub fn ArrayHashMapUnmanaged(
749749
750 /// Increases capacity, guaranteeing that insertions up until the750 /// Increases capacity, guaranteeing that insertions up until the
751 /// `expected_count` will not cause an allocation, and therefore cannot fail.751 /// `expected_count` will not cause an allocation, and therefore cannot fail.
752 pub fn ensureTotalCapacity(self: *Self, allocator: *Allocator, new_capacity: usize) !void {752 pub fn ensureTotalCapacity(self: *Self, allocator: Allocator, new_capacity: usize) !void {
753 if (@sizeOf(ByIndexContext) != 0)753 if (@sizeOf(ByIndexContext) != 0)
754 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call ensureTotalCapacityContext instead.");754 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call ensureTotalCapacityContext instead.");
755 return self.ensureTotalCapacityContext(allocator, new_capacity, undefined);755 return self.ensureTotalCapacityContext(allocator, new_capacity, undefined);
756 }756 }
757 pub fn ensureTotalCapacityContext(self: *Self, allocator: *Allocator, new_capacity: usize, ctx: Context) !void {757 pub fn ensureTotalCapacityContext(self: *Self, allocator: Allocator, new_capacity: usize, ctx: Context) !void {
758 if (new_capacity <= linear_scan_max) {758 if (new_capacity <= linear_scan_max) {
759 try self.entries.ensureTotalCapacity(allocator, new_capacity);759 try self.entries.ensureTotalCapacity(allocator, new_capacity);
760 return;760 return;
...@@ -781,7 +781,7 @@ pub fn ArrayHashMapUnmanaged(...@@ -781,7 +781,7 @@ pub fn ArrayHashMapUnmanaged(
781 /// therefore cannot fail.781 /// therefore cannot fail.
782 pub fn ensureUnusedCapacity(782 pub fn ensureUnusedCapacity(
783 self: *Self,783 self: *Self,
784 allocator: *Allocator,784 allocator: Allocator,
785 additional_capacity: usize,785 additional_capacity: usize,
786 ) !void {786 ) !void {
787 if (@sizeOf(ByIndexContext) != 0)787 if (@sizeOf(ByIndexContext) != 0)
...@@ -790,7 +790,7 @@ pub fn ArrayHashMapUnmanaged(...@@ -790,7 +790,7 @@ pub fn ArrayHashMapUnmanaged(
790 }790 }
791 pub fn ensureUnusedCapacityContext(791 pub fn ensureUnusedCapacityContext(
792 self: *Self,792 self: *Self,
793 allocator: *Allocator,793 allocator: Allocator,
794 additional_capacity: usize,794 additional_capacity: usize,
795 ctx: Context,795 ctx: Context,
796 ) !void {796 ) !void {
...@@ -808,24 +808,24 @@ pub fn ArrayHashMapUnmanaged(...@@ -808,24 +808,24 @@ pub fn ArrayHashMapUnmanaged(
808808
809 /// Clobbers any existing data. To detect if a put would clobber809 /// Clobbers any existing data. To detect if a put would clobber
810 /// existing data, see `getOrPut`.810 /// existing data, see `getOrPut`.
811 pub fn put(self: *Self, allocator: *Allocator, key: K, value: V) !void {811 pub fn put(self: *Self, allocator: Allocator, key: K, value: V) !void {
812 if (@sizeOf(Context) != 0)812 if (@sizeOf(Context) != 0)
813 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call putContext instead.");813 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call putContext instead.");
814 return self.putContext(allocator, key, value, undefined);814 return self.putContext(allocator, key, value, undefined);
815 }815 }
816 pub fn putContext(self: *Self, allocator: *Allocator, key: K, value: V, ctx: Context) !void {816 pub fn putContext(self: *Self, allocator: Allocator, key: K, value: V, ctx: Context) !void {
817 const result = try self.getOrPutContext(allocator, key, ctx);817 const result = try self.getOrPutContext(allocator, key, ctx);
818 result.value_ptr.* = value;818 result.value_ptr.* = value;
819 }819 }
820820
821 /// Inserts a key-value pair into the hash map, asserting that no previous821 /// Inserts a key-value pair into the hash map, asserting that no previous
822 /// entry with the same key is already present822 /// entry with the same key is already present
823 pub fn putNoClobber(self: *Self, allocator: *Allocator, key: K, value: V) !void {823 pub fn putNoClobber(self: *Self, allocator: Allocator, key: K, value: V) !void {
824 if (@sizeOf(Context) != 0)824 if (@sizeOf(Context) != 0)
825 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call putNoClobberContext instead.");825 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call putNoClobberContext instead.");
826 return self.putNoClobberContext(allocator, key, value, undefined);826 return self.putNoClobberContext(allocator, key, value, undefined);
827 }827 }
828 pub fn putNoClobberContext(self: *Self, allocator: *Allocator, key: K, value: V, ctx: Context) !void {828 pub fn putNoClobberContext(self: *Self, allocator: Allocator, key: K, value: V, ctx: Context) !void {
829 const result = try self.getOrPutContext(allocator, key, ctx);829 const result = try self.getOrPutContext(allocator, key, ctx);
830 assert(!result.found_existing);830 assert(!result.found_existing);
831 result.value_ptr.* = value;831 result.value_ptr.* = value;
...@@ -859,12 +859,12 @@ pub fn ArrayHashMapUnmanaged(...@@ -859,12 +859,12 @@ pub fn ArrayHashMapUnmanaged(
859 }859 }
860860
861 /// Inserts a new `Entry` into the hash map, returning the previous one, if any.861 /// Inserts a new `Entry` into the hash map, returning the previous one, if any.
862 pub fn fetchPut(self: *Self, allocator: *Allocator, key: K, value: V) !?KV {862 pub fn fetchPut(self: *Self, allocator: Allocator, key: K, value: V) !?KV {
863 if (@sizeOf(Context) != 0)863 if (@sizeOf(Context) != 0)
864 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call fetchPutContext instead.");864 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call fetchPutContext instead.");
865 return self.fetchPutContext(allocator, key, value, undefined);865 return self.fetchPutContext(allocator, key, value, undefined);
866 }866 }
867 pub fn fetchPutContext(self: *Self, allocator: *Allocator, key: K, value: V, ctx: Context) !?KV {867 pub fn fetchPutContext(self: *Self, allocator: Allocator, key: K, value: V, ctx: Context) !?KV {
868 const gop = try self.getOrPutContext(allocator, key, ctx);868 const gop = try self.getOrPutContext(allocator, key, ctx);
869 var result: ?KV = null;869 var result: ?KV = null;
870 if (gop.found_existing) {870 if (gop.found_existing) {
...@@ -1132,12 +1132,12 @@ pub fn ArrayHashMapUnmanaged(...@@ -1132,12 +1132,12 @@ pub fn ArrayHashMapUnmanaged(
11321132
1133 /// Create a copy of the hash map which can be modified separately.1133 /// Create a copy of the hash map which can be modified separately.
1134 /// The copy uses the same context and allocator as this instance.1134 /// The copy uses the same context and allocator as this instance.
1135 pub fn clone(self: Self, allocator: *Allocator) !Self {1135 pub fn clone(self: Self, allocator: Allocator) !Self {
1136 if (@sizeOf(ByIndexContext) != 0)1136 if (@sizeOf(ByIndexContext) != 0)
1137 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call cloneContext instead.");1137 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call cloneContext instead.");
1138 return self.cloneContext(allocator, undefined);1138 return self.cloneContext(allocator, undefined);
1139 }1139 }
1140 pub fn cloneContext(self: Self, allocator: *Allocator, ctx: Context) !Self {1140 pub fn cloneContext(self: Self, allocator: Allocator, ctx: Context) !Self {
1141 var other: Self = .{};1141 var other: Self = .{};
1142 other.entries = try self.entries.clone(allocator);1142 other.entries = try self.entries.clone(allocator);
1143 errdefer other.entries.deinit(allocator);1143 errdefer other.entries.deinit(allocator);
...@@ -1152,12 +1152,12 @@ pub fn ArrayHashMapUnmanaged(...@@ -1152,12 +1152,12 @@ pub fn ArrayHashMapUnmanaged(
11521152
1153 /// Rebuilds the key indexes. If the underlying entries has been modified directly, users1153 /// Rebuilds the key indexes. If the underlying entries has been modified directly, users
1154 /// can call `reIndex` to update the indexes to account for these new entries.1154 /// can call `reIndex` to update the indexes to account for these new entries.
1155 pub fn reIndex(self: *Self, allocator: *Allocator) !void {1155 pub fn reIndex(self: *Self, allocator: Allocator) !void {
1156 if (@sizeOf(ByIndexContext) != 0)1156 if (@sizeOf(ByIndexContext) != 0)
1157 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call reIndexContext instead.");1157 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call reIndexContext instead.");
1158 return self.reIndexContext(allocator, undefined);1158 return self.reIndexContext(allocator, undefined);
1159 }1159 }
1160 pub fn reIndexContext(self: *Self, allocator: *Allocator, ctx: Context) !void {1160 pub fn reIndexContext(self: *Self, allocator: Allocator, ctx: Context) !void {
1161 if (self.entries.capacity <= linear_scan_max) return;1161 if (self.entries.capacity <= linear_scan_max) return;
1162 // We're going to rebuild the index header and replace the existing one (if any). The1162 // We're going to rebuild the index header and replace the existing one (if any). The
1163 // indexes should sized such that they will be at most 60% full.1163 // indexes should sized such that they will be at most 60% full.
...@@ -1189,12 +1189,12 @@ pub fn ArrayHashMapUnmanaged(...@@ -1189,12 +1189,12 @@ pub fn ArrayHashMapUnmanaged(
11891189
1190 /// Shrinks the underlying `Entry` array to `new_len` elements and discards any associated1190 /// Shrinks the underlying `Entry` array to `new_len` elements and discards any associated
1191 /// index entries. Reduces allocated capacity.1191 /// index entries. Reduces allocated capacity.
1192 pub fn shrinkAndFree(self: *Self, allocator: *Allocator, new_len: usize) void {1192 pub fn shrinkAndFree(self: *Self, allocator: Allocator, new_len: usize) void {
1193 if (@sizeOf(ByIndexContext) != 0)1193 if (@sizeOf(ByIndexContext) != 0)
1194 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call shrinkAndFreeContext instead.");1194 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call shrinkAndFreeContext instead.");
1195 return self.shrinkAndFreeContext(allocator, new_len, undefined);1195 return self.shrinkAndFreeContext(allocator, new_len, undefined);
1196 }1196 }
1197 pub fn shrinkAndFreeContext(self: *Self, allocator: *Allocator, new_len: usize, ctx: Context) void {1197 pub fn shrinkAndFreeContext(self: *Self, allocator: Allocator, new_len: usize, ctx: Context) void {
1198 // Remove index entries from the new length onwards.1198 // Remove index entries from the new length onwards.
1199 // Explicitly choose to ONLY remove index entries and not the underlying array list1199 // Explicitly choose to ONLY remove index entries and not the underlying array list
1200 // entries as we're going to remove them in the subsequent shrink call.1200 // entries as we're going to remove them in the subsequent shrink call.
...@@ -1844,7 +1844,7 @@ const IndexHeader = struct {...@@ -1844,7 +1844,7 @@ const IndexHeader = struct {
18441844
1845 /// Allocates an index header, and fills the entryIndexes array with empty.1845 /// Allocates an index header, and fills the entryIndexes array with empty.
1846 /// The distance array contents are undefined.1846 /// The distance array contents are undefined.
1847 fn alloc(allocator: *Allocator, new_bit_index: u8) !*IndexHeader {1847 fn alloc(allocator: Allocator, new_bit_index: u8) !*IndexHeader {
1848 const len = @as(usize, 1) << @intCast(math.Log2Int(usize), new_bit_index);1848 const len = @as(usize, 1) << @intCast(math.Log2Int(usize), new_bit_index);
1849 const index_size = hash_map.capacityIndexSize(new_bit_index);1849 const index_size = hash_map.capacityIndexSize(new_bit_index);
1850 const nbytes = @sizeOf(IndexHeader) + index_size * len;1850 const nbytes = @sizeOf(IndexHeader) + index_size * len;
...@@ -1858,7 +1858,7 @@ const IndexHeader = struct {...@@ -1858,7 +1858,7 @@ const IndexHeader = struct {
1858 }1858 }
18591859
1860 /// Releases the memory for a header and its associated arrays.1860 /// Releases the memory for a header and its associated arrays.
1861 fn free(header: *IndexHeader, allocator: *Allocator) void {1861 fn free(header: *IndexHeader, allocator: Allocator) void {
1862 const index_size = hash_map.capacityIndexSize(header.bit_index);1862 const index_size = hash_map.capacityIndexSize(header.bit_index);
1863 const ptr = @ptrCast([*]align(@alignOf(IndexHeader)) u8, header);1863 const ptr = @ptrCast([*]align(@alignOf(IndexHeader)) u8, header);
1864 const slice = ptr[0 .. @sizeOf(IndexHeader) + header.length() * index_size];1864 const slice = ptr[0 .. @sizeOf(IndexHeader) + header.length() * index_size];
lib/std/array_list.zig+28-28
...@@ -42,12 +42,12 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {...@@ -42,12 +42,12 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
42 /// How many T values this list can hold without allocating42 /// How many T values this list can hold without allocating
43 /// additional memory.43 /// additional memory.
44 capacity: usize,44 capacity: usize,
45 allocator: *Allocator,45 allocator: Allocator,
4646
47 pub const Slice = if (alignment) |a| ([]align(a) T) else []T;47 pub const Slice = if (alignment) |a| ([]align(a) T) else []T;
4848
49 /// Deinitialize with `deinit` or use `toOwnedSlice`.49 /// Deinitialize with `deinit` or use `toOwnedSlice`.
50 pub fn init(allocator: *Allocator) Self {50 pub fn init(allocator: Allocator) Self {
51 return Self{51 return Self{
52 .items = &[_]T{},52 .items = &[_]T{},
53 .capacity = 0,53 .capacity = 0,
...@@ -58,7 +58,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {...@@ -58,7 +58,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
58 /// Initialize with capacity to hold at least `num` elements.58 /// Initialize with capacity to hold at least `num` elements.
59 /// The resulting capacity is likely to be equal to `num`.59 /// The resulting capacity is likely to be equal to `num`.
60 /// Deinitialize with `deinit` or use `toOwnedSlice`.60 /// Deinitialize with `deinit` or use `toOwnedSlice`.
61 pub fn initCapacity(allocator: *Allocator, num: usize) !Self {61 pub fn initCapacity(allocator: Allocator, num: usize) !Self {
62 var self = Self.init(allocator);62 var self = Self.init(allocator);
63 try self.ensureTotalCapacityPrecise(num);63 try self.ensureTotalCapacityPrecise(num);
64 return self;64 return self;
...@@ -74,7 +74,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {...@@ -74,7 +74,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
74 /// ArrayList takes ownership of the passed in slice. The slice must have been74 /// ArrayList takes ownership of the passed in slice. The slice must have been
75 /// allocated with `allocator`.75 /// allocated with `allocator`.
76 /// Deinitialize with `deinit` or use `toOwnedSlice`.76 /// Deinitialize with `deinit` or use `toOwnedSlice`.
77 pub fn fromOwnedSlice(allocator: *Allocator, slice: Slice) Self {77 pub fn fromOwnedSlice(allocator: Allocator, slice: Slice) Self {
78 return Self{78 return Self{
79 .items = slice,79 .items = slice,
80 .capacity = slice.len,80 .capacity = slice.len,
...@@ -457,33 +457,33 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ...@@ -457,33 +457,33 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
457 /// Initialize with capacity to hold at least num elements.457 /// Initialize with capacity to hold at least num elements.
458 /// The resulting capacity is likely to be equal to `num`.458 /// The resulting capacity is likely to be equal to `num`.
459 /// Deinitialize with `deinit` or use `toOwnedSlice`.459 /// Deinitialize with `deinit` or use `toOwnedSlice`.
460 pub fn initCapacity(allocator: *Allocator, num: usize) !Self {460 pub fn initCapacity(allocator: Allocator, num: usize) !Self {
461 var self = Self{};461 var self = Self{};
462 try self.ensureTotalCapacityPrecise(allocator, num);462 try self.ensureTotalCapacityPrecise(allocator, num);
463 return self;463 return self;
464 }464 }
465465
466 /// Release all allocated memory.466 /// Release all allocated memory.
467 pub fn deinit(self: *Self, allocator: *Allocator) void {467 pub fn deinit(self: *Self, allocator: Allocator) void {
468 allocator.free(self.allocatedSlice());468 allocator.free(self.allocatedSlice());
469 self.* = undefined;469 self.* = undefined;
470 }470 }
471471
472 /// Convert this list into an analogous memory-managed one.472 /// Convert this list into an analogous memory-managed one.
473 /// The returned list has ownership of the underlying memory.473 /// The returned list has ownership of the underlying memory.
474 pub fn toManaged(self: *Self, allocator: *Allocator) ArrayListAligned(T, alignment) {474 pub fn toManaged(self: *Self, allocator: Allocator) ArrayListAligned(T, alignment) {
475 return .{ .items = self.items, .capacity = self.capacity, .allocator = allocator };475 return .{ .items = self.items, .capacity = self.capacity, .allocator = allocator };
476 }476 }
477477
478 /// The caller owns the returned memory. ArrayList becomes empty.478 /// The caller owns the returned memory. ArrayList becomes empty.
479 pub fn toOwnedSlice(self: *Self, allocator: *Allocator) Slice {479 pub fn toOwnedSlice(self: *Self, allocator: Allocator) Slice {
480 const result = allocator.shrink(self.allocatedSlice(), self.items.len);480 const result = allocator.shrink(self.allocatedSlice(), self.items.len);
481 self.* = Self{};481 self.* = Self{};
482 return result;482 return result;
483 }483 }
484484
485 /// The caller owns the returned memory. ArrayList becomes empty.485 /// The caller owns the returned memory. ArrayList becomes empty.
486 pub fn toOwnedSliceSentinel(self: *Self, allocator: *Allocator, comptime sentinel: T) ![:sentinel]T {486 pub fn toOwnedSliceSentinel(self: *Self, allocator: Allocator, comptime sentinel: T) ![:sentinel]T {
487 try self.append(allocator, sentinel);487 try self.append(allocator, sentinel);
488 const result = self.toOwnedSlice(allocator);488 const result = self.toOwnedSlice(allocator);
489 return result[0 .. result.len - 1 :sentinel];489 return result[0 .. result.len - 1 :sentinel];
...@@ -492,7 +492,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ...@@ -492,7 +492,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
492 /// Insert `item` at index `n`. Moves `list[n .. list.len]`492 /// Insert `item` at index `n`. Moves `list[n .. list.len]`
493 /// to higher indices to make room.493 /// to higher indices to make room.
494 /// This operation is O(N).494 /// This operation is O(N).
495 pub fn insert(self: *Self, allocator: *Allocator, n: usize, item: T) !void {495 pub fn insert(self: *Self, allocator: Allocator, n: usize, item: T) !void {
496 try self.ensureUnusedCapacity(allocator, 1);496 try self.ensureUnusedCapacity(allocator, 1);
497 self.items.len += 1;497 self.items.len += 1;
498498
...@@ -503,7 +503,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ...@@ -503,7 +503,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
503 /// Insert slice `items` at index `i`. Moves `list[i .. list.len]` to503 /// Insert slice `items` at index `i`. Moves `list[i .. list.len]` to
504 /// higher indicices make room.504 /// higher indicices make room.
505 /// This operation is O(N).505 /// This operation is O(N).
506 pub fn insertSlice(self: *Self, allocator: *Allocator, i: usize, items: []const T) !void {506 pub fn insertSlice(self: *Self, allocator: Allocator, i: usize, items: []const T) !void {
507 try self.ensureUnusedCapacity(allocator, items.len);507 try self.ensureUnusedCapacity(allocator, items.len);
508 self.items.len += items.len;508 self.items.len += items.len;
509509
...@@ -515,14 +515,14 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ...@@ -515,14 +515,14 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
515 /// Grows list if `len < new_items.len`.515 /// Grows list if `len < new_items.len`.
516 /// Shrinks list if `len > new_items.len`516 /// Shrinks list if `len > new_items.len`
517 /// Invalidates pointers if this ArrayList is resized.517 /// Invalidates pointers if this ArrayList is resized.
518 pub fn replaceRange(self: *Self, allocator: *Allocator, start: usize, len: usize, new_items: []const T) !void {518 pub fn replaceRange(self: *Self, allocator: Allocator, start: usize, len: usize, new_items: []const T) !void {
519 var managed = self.toManaged(allocator);519 var managed = self.toManaged(allocator);
520 try managed.replaceRange(start, len, new_items);520 try managed.replaceRange(start, len, new_items);
521 self.* = managed.moveToUnmanaged();521 self.* = managed.moveToUnmanaged();
522 }522 }
523523
524 /// Extend the list by 1 element. Allocates more memory as necessary.524 /// Extend the list by 1 element. Allocates more memory as necessary.
525 pub fn append(self: *Self, allocator: *Allocator, item: T) !void {525 pub fn append(self: *Self, allocator: Allocator, item: T) !void {
526 const new_item_ptr = try self.addOne(allocator);526 const new_item_ptr = try self.addOne(allocator);
527 new_item_ptr.* = item;527 new_item_ptr.* = item;
528 }528 }
...@@ -563,7 +563,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ...@@ -563,7 +563,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
563563
564 /// Append the slice of items to the list. Allocates more564 /// Append the slice of items to the list. Allocates more
565 /// memory as necessary.565 /// memory as necessary.
566 pub fn appendSlice(self: *Self, allocator: *Allocator, items: []const T) !void {566 pub fn appendSlice(self: *Self, allocator: Allocator, items: []const T) !void {
567 try self.ensureUnusedCapacity(allocator, items.len);567 try self.ensureUnusedCapacity(allocator, items.len);
568 self.appendSliceAssumeCapacity(items);568 self.appendSliceAssumeCapacity(items);
569 }569 }
...@@ -580,7 +580,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ...@@ -580,7 +580,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
580580
581 pub const WriterContext = struct {581 pub const WriterContext = struct {
582 self: *Self,582 self: *Self,
583 allocator: *Allocator,583 allocator: Allocator,
584 };584 };
585585
586 pub const Writer = if (T != u8)586 pub const Writer = if (T != u8)
...@@ -590,7 +590,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ...@@ -590,7 +590,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
590 std.io.Writer(WriterContext, error{OutOfMemory}, appendWrite);590 std.io.Writer(WriterContext, error{OutOfMemory}, appendWrite);
591591
592 /// Initializes a Writer which will append to the list.592 /// Initializes a Writer which will append to the list.
593 pub fn writer(self: *Self, allocator: *Allocator) Writer {593 pub fn writer(self: *Self, allocator: Allocator) Writer {
594 return .{ .context = .{ .self = self, .allocator = allocator } };594 return .{ .context = .{ .self = self, .allocator = allocator } };
595 }595 }
596596
...@@ -603,7 +603,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ...@@ -603,7 +603,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
603603
604 /// Append a value to the list `n` times.604 /// Append a value to the list `n` times.
605 /// Allocates more memory as necessary.605 /// Allocates more memory as necessary.
606 pub fn appendNTimes(self: *Self, allocator: *Allocator, value: T, n: usize) !void {606 pub fn appendNTimes(self: *Self, allocator: Allocator, value: T, n: usize) !void {
607 const old_len = self.items.len;607 const old_len = self.items.len;
608 try self.resize(allocator, self.items.len + n);608 try self.resize(allocator, self.items.len + n);
609 mem.set(T, self.items[old_len..self.items.len], value);609 mem.set(T, self.items[old_len..self.items.len], value);
...@@ -621,13 +621,13 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ...@@ -621,13 +621,13 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
621621
622 /// Adjust the list's length to `new_len`.622 /// Adjust the list's length to `new_len`.
623 /// Does not initialize added items, if any.623 /// Does not initialize added items, if any.
624 pub fn resize(self: *Self, allocator: *Allocator, new_len: usize) !void {624 pub fn resize(self: *Self, allocator: Allocator, new_len: usize) !void {
625 try self.ensureTotalCapacity(allocator, new_len);625 try self.ensureTotalCapacity(allocator, new_len);
626 self.items.len = new_len;626 self.items.len = new_len;
627 }627 }
628628
629 /// Reduce allocated capacity to `new_len`.629 /// Reduce allocated capacity to `new_len`.
630 pub fn shrinkAndFree(self: *Self, allocator: *Allocator, new_len: usize) void {630 pub fn shrinkAndFree(self: *Self, allocator: Allocator, new_len: usize) void {
631 assert(new_len <= self.items.len);631 assert(new_len <= self.items.len);
632632
633 self.items = allocator.realloc(self.allocatedSlice(), new_len) catch |e| switch (e) {633 self.items = allocator.realloc(self.allocatedSlice(), new_len) catch |e| switch (e) {
...@@ -653,7 +653,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ...@@ -653,7 +653,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
653 }653 }
654654
655 /// Invalidates all element pointers.655 /// Invalidates all element pointers.
656 pub fn clearAndFree(self: *Self, allocator: *Allocator) void {656 pub fn clearAndFree(self: *Self, allocator: Allocator) void {
657 allocator.free(self.allocatedSlice());657 allocator.free(self.allocatedSlice());
658 self.items.len = 0;658 self.items.len = 0;
659 self.capacity = 0;659 self.capacity = 0;
...@@ -663,7 +663,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ...@@ -663,7 +663,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
663663
664 /// Modify the array so that it can hold at least `new_capacity` items.664 /// Modify the array so that it can hold at least `new_capacity` items.
665 /// Invalidates pointers if additional memory is needed.665 /// Invalidates pointers if additional memory is needed.
666 pub fn ensureTotalCapacity(self: *Self, allocator: *Allocator, new_capacity: usize) !void {666 pub fn ensureTotalCapacity(self: *Self, allocator: Allocator, new_capacity: usize) !void {
667 var better_capacity = self.capacity;667 var better_capacity = self.capacity;
668 if (better_capacity >= new_capacity) return;668 if (better_capacity >= new_capacity) return;
669669
...@@ -679,7 +679,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ...@@ -679,7 +679,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
679 /// Like `ensureTotalCapacity`, but the resulting capacity is much more likely679 /// Like `ensureTotalCapacity`, but the resulting capacity is much more likely
680 /// (but not guaranteed) to be equal to `new_capacity`.680 /// (but not guaranteed) to be equal to `new_capacity`.
681 /// Invalidates pointers if additional memory is needed.681 /// Invalidates pointers if additional memory is needed.
682 pub fn ensureTotalCapacityPrecise(self: *Self, allocator: *Allocator, new_capacity: usize) !void {682 pub fn ensureTotalCapacityPrecise(self: *Self, allocator: Allocator, new_capacity: usize) !void {
683 if (self.capacity >= new_capacity) return;683 if (self.capacity >= new_capacity) return;
684684
685 const new_memory = try allocator.reallocAtLeast(self.allocatedSlice(), new_capacity);685 const new_memory = try allocator.reallocAtLeast(self.allocatedSlice(), new_capacity);
...@@ -691,7 +691,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ...@@ -691,7 +691,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
691 /// Invalidates pointers if additional memory is needed.691 /// Invalidates pointers if additional memory is needed.
692 pub fn ensureUnusedCapacity(692 pub fn ensureUnusedCapacity(
693 self: *Self,693 self: *Self,
694 allocator: *Allocator,694 allocator: Allocator,
695 additional_count: usize,695 additional_count: usize,
696 ) !void {696 ) !void {
697 return self.ensureTotalCapacity(allocator, self.items.len + additional_count);697 return self.ensureTotalCapacity(allocator, self.items.len + additional_count);
...@@ -706,7 +706,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ...@@ -706,7 +706,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
706706
707 /// Increase length by 1, returning pointer to the new item.707 /// Increase length by 1, returning pointer to the new item.
708 /// The returned pointer becomes invalid when the list resized.708 /// The returned pointer becomes invalid when the list resized.
709 pub fn addOne(self: *Self, allocator: *Allocator) !*T {709 pub fn addOne(self: *Self, allocator: Allocator) !*T {
710 const newlen = self.items.len + 1;710 const newlen = self.items.len + 1;
711 try self.ensureTotalCapacity(allocator, newlen);711 try self.ensureTotalCapacity(allocator, newlen);
712 return self.addOneAssumeCapacity();712 return self.addOneAssumeCapacity();
...@@ -726,7 +726,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ...@@ -726,7 +726,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
726 /// Resize the array, adding `n` new elements, which have `undefined` values.726 /// Resize the array, adding `n` new elements, which have `undefined` values.
727 /// The return value is an array pointing to the newly allocated elements.727 /// The return value is an array pointing to the newly allocated elements.
728 /// The returned pointer becomes invalid when the list is resized.728 /// The returned pointer becomes invalid when the list is resized.
729 pub fn addManyAsArray(self: *Self, allocator: *Allocator, comptime n: usize) !*[n]T {729 pub fn addManyAsArray(self: *Self, allocator: Allocator, comptime n: usize) !*[n]T {
730 const prev_len = self.items.len;730 const prev_len = self.items.len;
731 try self.resize(allocator, self.items.len + n);731 try self.resize(allocator, self.items.len + n);
732 return self.items[prev_len..][0..n];732 return self.items[prev_len..][0..n];
...@@ -1119,7 +1119,7 @@ test "std.ArrayList/ArrayListUnmanaged.insertSlice" {...@@ -1119,7 +1119,7 @@ test "std.ArrayList/ArrayListUnmanaged.insertSlice" {
1119test "std.ArrayList/ArrayListUnmanaged.replaceRange" {1119test "std.ArrayList/ArrayListUnmanaged.replaceRange" {
1120 var arena = std.heap.ArenaAllocator.init(testing.allocator);1120 var arena = std.heap.ArenaAllocator.init(testing.allocator);
1121 defer arena.deinit();1121 defer arena.deinit();
1122 const a = &arena.allocator;1122 const a = arena.allocator();
11231123
1124 const init = [_]i32{ 1, 2, 3, 4, 5 };1124 const init = [_]i32{ 1, 2, 3, 4, 5 };
1125 const new = [_]i32{ 0, 0, 0 };1125 const new = [_]i32{ 0, 0, 0 };
...@@ -1263,7 +1263,7 @@ test "std.ArrayList/ArrayListUnmanaged.shrink still sets length on error.OutOfMe...@@ -1263,7 +1263,7 @@ test "std.ArrayList/ArrayListUnmanaged.shrink still sets length on error.OutOfMe
1263 // use an arena allocator to make sure realloc returns error.OutOfMemory1263 // use an arena allocator to make sure realloc returns error.OutOfMemory
1264 var arena = std.heap.ArenaAllocator.init(testing.allocator);1264 var arena = std.heap.ArenaAllocator.init(testing.allocator);
1265 defer arena.deinit();1265 defer arena.deinit();
1266 const a = &arena.allocator;1266 const a = arena.allocator();
12671267
1268 {1268 {
1269 var list = ArrayList(i32).init(a);1269 var list = ArrayList(i32).init(a);
...@@ -1361,7 +1361,7 @@ test "ArrayListAligned/ArrayListAlignedUnmanaged accepts unaligned slices" {...@@ -1361,7 +1361,7 @@ test "ArrayListAligned/ArrayListAlignedUnmanaged accepts unaligned slices" {
13611361
1362test "std.ArrayList(u0)" {1362test "std.ArrayList(u0)" {
1363 // An ArrayList on zero-sized types should not need to allocate1363 // An ArrayList on zero-sized types should not need to allocate
1364 const a = &testing.FailingAllocator.init(testing.allocator, 0).allocator;1364 const a = testing.FailingAllocator.init(testing.allocator, 0).allocator();
13651365
1366 var list = ArrayList(u0).init(a);1366 var list = ArrayList(u0).init(a);
1367 defer list.deinit();1367 defer list.deinit();
lib/std/ascii.zig+2-2
...@@ -301,7 +301,7 @@ test "lowerString" {...@@ -301,7 +301,7 @@ test "lowerString" {
301301
302/// Allocates a lower case copy of `ascii_string`.302/// Allocates a lower case copy of `ascii_string`.
303/// Caller owns returned string and must free with `allocator`.303/// Caller owns returned string and must free with `allocator`.
304pub fn allocLowerString(allocator: *std.mem.Allocator, ascii_string: []const u8) ![]u8 {304pub fn allocLowerString(allocator: std.mem.Allocator, ascii_string: []const u8) ![]u8 {
305 const result = try allocator.alloc(u8, ascii_string.len);305 const result = try allocator.alloc(u8, ascii_string.len);
306 return lowerString(result, ascii_string);306 return lowerString(result, ascii_string);
307}307}
...@@ -330,7 +330,7 @@ test "upperString" {...@@ -330,7 +330,7 @@ test "upperString" {
330330
331/// Allocates an upper case copy of `ascii_string`.331/// Allocates an upper case copy of `ascii_string`.
332/// Caller owns returned string and must free with `allocator`.332/// Caller owns returned string and must free with `allocator`.
333pub fn allocUpperString(allocator: *std.mem.Allocator, ascii_string: []const u8) ![]u8 {333pub fn allocUpperString(allocator: std.mem.Allocator, ascii_string: []const u8) ![]u8 {
334 const result = try allocator.alloc(u8, ascii_string.len);334 const result = try allocator.alloc(u8, ascii_string.len);
335 return upperString(result, ascii_string);335 return upperString(result, ascii_string);
336}336}
lib/std/atomic/queue.zig+3-3
...@@ -156,7 +156,7 @@ pub fn Queue(comptime T: type) type {...@@ -156,7 +156,7 @@ pub fn Queue(comptime T: type) type {
156}156}
157157
158const Context = struct {158const Context = struct {
159 allocator: *std.mem.Allocator,159 allocator: std.mem.Allocator,
160 queue: *Queue(i32),160 queue: *Queue(i32),
161 put_sum: isize,161 put_sum: isize,
162 get_sum: isize,162 get_sum: isize,
...@@ -176,8 +176,8 @@ test "std.atomic.Queue" {...@@ -176,8 +176,8 @@ test "std.atomic.Queue" {
176 var plenty_of_memory = try std.heap.page_allocator.alloc(u8, 300 * 1024);176 var plenty_of_memory = try std.heap.page_allocator.alloc(u8, 300 * 1024);
177 defer std.heap.page_allocator.free(plenty_of_memory);177 defer std.heap.page_allocator.free(plenty_of_memory);
178178
179 var fixed_buffer_allocator = std.heap.ThreadSafeFixedBufferAllocator.init(plenty_of_memory);179 var fixed_buffer_allocator = std.heap.FixedBufferAllocator.init(plenty_of_memory);
180 var a = &fixed_buffer_allocator.allocator;180 var a = fixed_buffer_allocator.threadSafeAllocator();
181181
182 var queue = Queue(i32).init();182 var queue = Queue(i32).init();
183 var context = Context{183 var context = Context{
lib/std/atomic/stack.zig+3-3
...@@ -69,7 +69,7 @@ pub fn Stack(comptime T: type) type {...@@ -69,7 +69,7 @@ pub fn Stack(comptime T: type) type {
69}69}
7070
71const Context = struct {71const Context = struct {
72 allocator: *std.mem.Allocator,72 allocator: std.mem.Allocator,
73 stack: *Stack(i32),73 stack: *Stack(i32),
74 put_sum: isize,74 put_sum: isize,
75 get_sum: isize,75 get_sum: isize,
...@@ -88,8 +88,8 @@ test "std.atomic.stack" {...@@ -88,8 +88,8 @@ test "std.atomic.stack" {
88 var plenty_of_memory = try std.heap.page_allocator.alloc(u8, 300 * 1024);88 var plenty_of_memory = try std.heap.page_allocator.alloc(u8, 300 * 1024);
89 defer std.heap.page_allocator.free(plenty_of_memory);89 defer std.heap.page_allocator.free(plenty_of_memory);
9090
91 var fixed_buffer_allocator = std.heap.ThreadSafeFixedBufferAllocator.init(plenty_of_memory);91 var fixed_buffer_allocator = std.heap.FixedBufferAllocator.init(plenty_of_memory);
92 var a = &fixed_buffer_allocator.allocator;92 var a = fixed_buffer_allocator.threadSafeAllocator();
9393
94 var stack = Stack(i32).init();94 var stack = Stack(i32).init();
95 var context = Context{95 var context = Context{
lib/std/bit_set.zig+9-9
...@@ -476,7 +476,7 @@ pub const DynamicBitSetUnmanaged = struct {...@@ -476,7 +476,7 @@ pub const DynamicBitSetUnmanaged = struct {
476476
477 /// Creates a bit set with no elements present.477 /// Creates a bit set with no elements present.
478 /// If bit_length is not zero, deinit must eventually be called.478 /// If bit_length is not zero, deinit must eventually be called.
479 pub fn initEmpty(bit_length: usize, allocator: *Allocator) !Self {479 pub fn initEmpty(bit_length: usize, allocator: Allocator) !Self {
480 var self = Self{};480 var self = Self{};
481 try self.resize(bit_length, false, allocator);481 try self.resize(bit_length, false, allocator);
482 return self;482 return self;
...@@ -484,7 +484,7 @@ pub const DynamicBitSetUnmanaged = struct {...@@ -484,7 +484,7 @@ pub const DynamicBitSetUnmanaged = struct {
484484
485 /// Creates a bit set with all elements present.485 /// Creates a bit set with all elements present.
486 /// If bit_length is not zero, deinit must eventually be called.486 /// If bit_length is not zero, deinit must eventually be called.
487 pub fn initFull(bit_length: usize, allocator: *Allocator) !Self {487 pub fn initFull(bit_length: usize, allocator: Allocator) !Self {
488 var self = Self{};488 var self = Self{};
489 try self.resize(bit_length, true, allocator);489 try self.resize(bit_length, true, allocator);
490 return self;490 return self;
...@@ -493,7 +493,7 @@ pub const DynamicBitSetUnmanaged = struct {...@@ -493,7 +493,7 @@ pub const DynamicBitSetUnmanaged = struct {
493 /// Resizes to a new bit_length. If the new length is larger493 /// Resizes to a new bit_length. If the new length is larger
494 /// than the old length, fills any added bits with `fill`.494 /// than the old length, fills any added bits with `fill`.
495 /// If new_len is not zero, deinit must eventually be called.495 /// If new_len is not zero, deinit must eventually be called.
496 pub fn resize(self: *@This(), new_len: usize, fill: bool, allocator: *Allocator) !void {496 pub fn resize(self: *@This(), new_len: usize, fill: bool, allocator: Allocator) !void {
497 const old_len = self.bit_length;497 const old_len = self.bit_length;
498498
499 const old_masks = numMasks(old_len);499 const old_masks = numMasks(old_len);
...@@ -556,12 +556,12 @@ pub const DynamicBitSetUnmanaged = struct {...@@ -556,12 +556,12 @@ pub const DynamicBitSetUnmanaged = struct {
556 /// deinitializes the array and releases its memory.556 /// deinitializes the array and releases its memory.
557 /// The passed allocator must be the same one used for557 /// The passed allocator must be the same one used for
558 /// init* or resize in the past.558 /// init* or resize in the past.
559 pub fn deinit(self: *Self, allocator: *Allocator) void {559 pub fn deinit(self: *Self, allocator: Allocator) void {
560 self.resize(0, false, allocator) catch unreachable;560 self.resize(0, false, allocator) catch unreachable;
561 }561 }
562562
563 /// Creates a duplicate of this bit set, using the new allocator.563 /// Creates a duplicate of this bit set, using the new allocator.
564 pub fn clone(self: *const Self, new_allocator: *Allocator) !Self {564 pub fn clone(self: *const Self, new_allocator: Allocator) !Self {
565 const num_masks = numMasks(self.bit_length);565 const num_masks = numMasks(self.bit_length);
566 var copy = Self{};566 var copy = Self{};
567 try copy.resize(self.bit_length, false, new_allocator);567 try copy.resize(self.bit_length, false, new_allocator);
...@@ -742,13 +742,13 @@ pub const DynamicBitSet = struct {...@@ -742,13 +742,13 @@ pub const DynamicBitSet = struct {
742 pub const ShiftInt = std.math.Log2Int(MaskInt);742 pub const ShiftInt = std.math.Log2Int(MaskInt);
743743
744 /// The allocator used by this bit set744 /// The allocator used by this bit set
745 allocator: *Allocator,745 allocator: Allocator,
746746
747 /// The number of valid items in this bit set747 /// The number of valid items in this bit set
748 unmanaged: DynamicBitSetUnmanaged = .{},748 unmanaged: DynamicBitSetUnmanaged = .{},
749749
750 /// Creates a bit set with no elements present.750 /// Creates a bit set with no elements present.
751 pub fn initEmpty(bit_length: usize, allocator: *Allocator) !Self {751 pub fn initEmpty(bit_length: usize, allocator: Allocator) !Self {
752 return Self{752 return Self{
753 .unmanaged = try DynamicBitSetUnmanaged.initEmpty(bit_length, allocator),753 .unmanaged = try DynamicBitSetUnmanaged.initEmpty(bit_length, allocator),
754 .allocator = allocator,754 .allocator = allocator,
...@@ -756,7 +756,7 @@ pub const DynamicBitSet = struct {...@@ -756,7 +756,7 @@ pub const DynamicBitSet = struct {
756 }756 }
757757
758 /// Creates a bit set with all elements present.758 /// Creates a bit set with all elements present.
759 pub fn initFull(bit_length: usize, allocator: *Allocator) !Self {759 pub fn initFull(bit_length: usize, allocator: Allocator) !Self {
760 return Self{760 return Self{
761 .unmanaged = try DynamicBitSetUnmanaged.initFull(bit_length, allocator),761 .unmanaged = try DynamicBitSetUnmanaged.initFull(bit_length, allocator),
762 .allocator = allocator,762 .allocator = allocator,
...@@ -777,7 +777,7 @@ pub const DynamicBitSet = struct {...@@ -777,7 +777,7 @@ pub const DynamicBitSet = struct {
777 }777 }
778778
779 /// Creates a duplicate of this bit set, using the new allocator.779 /// Creates a duplicate of this bit set, using the new allocator.
780 pub fn clone(self: *const Self, new_allocator: *Allocator) !Self {780 pub fn clone(self: *const Self, new_allocator: Allocator) !Self {
781 return Self{781 return Self{
782 .unmanaged = try self.unmanaged.clone(new_allocator),782 .unmanaged = try self.unmanaged.clone(new_allocator),
783 .allocator = new_allocator,783 .allocator = new_allocator,
lib/std/buf_map.zig+1-1
...@@ -14,7 +14,7 @@ pub const BufMap = struct {...@@ -14,7 +14,7 @@ pub const BufMap = struct {
14 /// Create a BufMap backed by a specific allocator.14 /// Create a BufMap backed by a specific allocator.
15 /// That allocator will be used for both backing allocations15 /// That allocator will be used for both backing allocations
16 /// and string deduplication.16 /// and string deduplication.
17 pub fn init(allocator: *Allocator) BufMap {17 pub fn init(allocator: Allocator) BufMap {
18 var self = BufMap{ .hash_map = BufMapHashMap.init(allocator) };18 var self = BufMap{ .hash_map = BufMapHashMap.init(allocator) };
19 return self;19 return self;
20 }20 }
lib/std/buf_set.zig+2-2
...@@ -16,7 +16,7 @@ pub const BufSet = struct {...@@ -16,7 +16,7 @@ pub const BufSet = struct {
16 /// Create a BufSet using an allocator. The allocator will16 /// Create a BufSet using an allocator. The allocator will
17 /// be used internally for both backing allocations and17 /// be used internally for both backing allocations and
18 /// string duplication.18 /// string duplication.
19 pub fn init(a: *Allocator) BufSet {19 pub fn init(a: Allocator) BufSet {
20 var self = BufSet{ .hash_map = BufSetHashMap.init(a) };20 var self = BufSet{ .hash_map = BufSetHashMap.init(a) };
21 return self;21 return self;
22 }22 }
...@@ -67,7 +67,7 @@ pub const BufSet = struct {...@@ -67,7 +67,7 @@ pub const BufSet = struct {
67 }67 }
6868
69 /// Get the allocator used by this set69 /// Get the allocator used by this set
70 pub fn allocator(self: *const BufSet) *Allocator {70 pub fn allocator(self: *const BufSet) Allocator {
71 return self.hash_map.allocator;71 return self.hash_map.allocator;
72 }72 }
7373
lib/std/build.zig+9-9
...@@ -28,7 +28,7 @@ pub const OptionsStep = @import("build/OptionsStep.zig");...@@ -28,7 +28,7 @@ pub const OptionsStep = @import("build/OptionsStep.zig");
28pub const Builder = struct {28pub const Builder = struct {
29 install_tls: TopLevelStep,29 install_tls: TopLevelStep,
30 uninstall_tls: TopLevelStep,30 uninstall_tls: TopLevelStep,
31 allocator: *Allocator,31 allocator: Allocator,
32 user_input_options: UserInputOptionsMap,32 user_input_options: UserInputOptionsMap,
33 available_options_map: AvailableOptionsMap,33 available_options_map: AvailableOptionsMap,
34 available_options_list: ArrayList(AvailableOption),34 available_options_list: ArrayList(AvailableOption),
...@@ -134,7 +134,7 @@ pub const Builder = struct {...@@ -134,7 +134,7 @@ pub const Builder = struct {
134 };134 };
135135
136 pub fn create(136 pub fn create(
137 allocator: *Allocator,137 allocator: Allocator,
138 zig_exe: []const u8,138 zig_exe: []const u8,
139 build_root: []const u8,139 build_root: []const u8,
140 cache_root: []const u8,140 cache_root: []const u8,
...@@ -1285,7 +1285,7 @@ test "builder.findProgram compiles" {...@@ -1285,7 +1285,7 @@ test "builder.findProgram compiles" {
1285 defer arena.deinit();1285 defer arena.deinit();
12861286
1287 const builder = try Builder.create(1287 const builder = try Builder.create(
1288 &arena.allocator,1288 arena.allocator(),
1289 "zig",1289 "zig",
1290 "zig-cache",1290 "zig-cache",
1291 "zig-cache",1291 "zig-cache",
...@@ -3080,7 +3080,7 @@ pub const Step = struct {...@@ -3080,7 +3080,7 @@ pub const Step = struct {
3080 custom,3080 custom,
3081 };3081 };
30823082
3083 pub fn init(id: Id, name: []const u8, allocator: *Allocator, makeFn: fn (*Step) anyerror!void) Step {3083 pub fn init(id: Id, name: []const u8, allocator: Allocator, makeFn: fn (*Step) anyerror!void) Step {
3084 return Step{3084 return Step{
3085 .id = id,3085 .id = id,
3086 .name = allocator.dupe(u8, name) catch unreachable,3086 .name = allocator.dupe(u8, name) catch unreachable,
...@@ -3090,7 +3090,7 @@ pub const Step = struct {...@@ -3090,7 +3090,7 @@ pub const Step = struct {
3090 .done_flag = false,3090 .done_flag = false,
3091 };3091 };
3092 }3092 }
3093 pub fn initNoOp(id: Id, name: []const u8, allocator: *Allocator) Step {3093 pub fn initNoOp(id: Id, name: []const u8, allocator: Allocator) Step {
3094 return init(id, name, allocator, makeNoOp);3094 return init(id, name, allocator, makeNoOp);
3095 }3095 }
30963096
...@@ -3117,7 +3117,7 @@ pub const Step = struct {...@@ -3117,7 +3117,7 @@ pub const Step = struct {
3117 }3117 }
3118};3118};
31193119
3120fn doAtomicSymLinks(allocator: *Allocator, output_path: []const u8, filename_major_only: []const u8, filename_name_only: []const u8) !void {3120fn doAtomicSymLinks(allocator: Allocator, output_path: []const u8, filename_major_only: []const u8, filename_name_only: []const u8) !void {
3121 const out_dir = fs.path.dirname(output_path) orelse ".";3121 const out_dir = fs.path.dirname(output_path) orelse ".";
3122 const out_basename = fs.path.basename(output_path);3122 const out_basename = fs.path.basename(output_path);
3123 // sym link for libfoo.so.1 to libfoo.so.1.2.33123 // sym link for libfoo.so.1 to libfoo.so.1.2.3
...@@ -3141,7 +3141,7 @@ fn doAtomicSymLinks(allocator: *Allocator, output_path: []const u8, filename_maj...@@ -3141,7 +3141,7 @@ fn doAtomicSymLinks(allocator: *Allocator, output_path: []const u8, filename_maj
3141}3141}
31423142
3143/// Returned slice must be freed by the caller.3143/// Returned slice must be freed by the caller.
3144fn findVcpkgRoot(allocator: *Allocator) !?[]const u8 {3144fn findVcpkgRoot(allocator: Allocator) !?[]const u8 {
3145 const appdata_path = try fs.getAppDataDir(allocator, "vcpkg");3145 const appdata_path = try fs.getAppDataDir(allocator, "vcpkg");
3146 defer allocator.free(appdata_path);3146 defer allocator.free(appdata_path);
31473147
...@@ -3210,7 +3210,7 @@ test "Builder.dupePkg()" {...@@ -3210,7 +3210,7 @@ test "Builder.dupePkg()" {
3210 var arena = std.heap.ArenaAllocator.init(std.testing.allocator);3210 var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
3211 defer arena.deinit();3211 defer arena.deinit();
3212 var builder = try Builder.create(3212 var builder = try Builder.create(
3213 &arena.allocator,3213 arena.allocator(),
3214 "test",3214 "test",
3215 "test",3215 "test",
3216 "test",3216 "test",
...@@ -3255,7 +3255,7 @@ test "LibExeObjStep.addPackage" {...@@ -3255,7 +3255,7 @@ test "LibExeObjStep.addPackage" {
3255 defer arena.deinit();3255 defer arena.deinit();
32563256
3257 var builder = try Builder.create(3257 var builder = try Builder.create(
3258 &arena.allocator,3258 arena.allocator(),
3259 "test",3259 "test",
3260 "test",3260 "test",
3261 "test",3261 "test",
lib/std/build/InstallRawStep.zig+2-2
...@@ -40,7 +40,7 @@ const BinaryElfOutput = struct {...@@ -40,7 +40,7 @@ const BinaryElfOutput = struct {
40 self.segments.deinit();40 self.segments.deinit();
41 }41 }
4242
43 pub fn parse(allocator: *Allocator, elf_file: File) !Self {43 pub fn parse(allocator: Allocator, elf_file: File) !Self {
44 var self: Self = .{44 var self: Self = .{
45 .segments = ArrayList(*BinaryElfSegment).init(allocator),45 .segments = ArrayList(*BinaryElfSegment).init(allocator),
46 .sections = ArrayList(*BinaryElfSection).init(allocator),46 .sections = ArrayList(*BinaryElfSection).init(allocator),
...@@ -298,7 +298,7 @@ fn containsValidAddressRange(segments: []*BinaryElfSegment) bool {...@@ -298,7 +298,7 @@ fn containsValidAddressRange(segments: []*BinaryElfSegment) bool {
298 return true;298 return true;
299}299}
300300
301fn emitRaw(allocator: *Allocator, elf_path: []const u8, raw_path: []const u8, format: RawFormat) !void {301fn emitRaw(allocator: Allocator, elf_path: []const u8, raw_path: []const u8, format: RawFormat) !void {
302 var elf_file = try fs.cwd().openFile(elf_path, .{});302 var elf_file = try fs.cwd().openFile(elf_path, .{});
303 defer elf_file.close();303 defer elf_file.close();
304304
lib/std/build/OptionsStep.zig+2-2
...@@ -274,7 +274,7 @@ test "OptionsStep" {...@@ -274,7 +274,7 @@ test "OptionsStep" {
274 var arena = std.heap.ArenaAllocator.init(std.testing.allocator);274 var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
275 defer arena.deinit();275 defer arena.deinit();
276 var builder = try Builder.create(276 var builder = try Builder.create(
277 &arena.allocator,277 arena.allocator(),
278 "test",278 "test",
279 "test",279 "test",
280 "test",280 "test",
...@@ -350,5 +350,5 @@ test "OptionsStep" {...@@ -350,5 +350,5 @@ test "OptionsStep" {
350 \\350 \\
351 , options.contents.items);351 , options.contents.items);
352352
353 _ = try std.zig.parse(&arena.allocator, try options.contents.toOwnedSliceSentinel(0));353 _ = try std.zig.parse(arena.allocator(), try options.contents.toOwnedSliceSentinel(0));
354}354}
lib/std/builtin.zig+1-1
...@@ -75,7 +75,7 @@ pub const StackTrace = struct {...@@ -75,7 +75,7 @@ pub const StackTrace = struct {
75 };75 };
76 const tty_config = std.debug.detectTTYConfig();76 const tty_config = std.debug.detectTTYConfig();
77 try writer.writeAll("\n");77 try writer.writeAll("\n");
78 std.debug.writeStackTrace(self, writer, &arena.allocator, debug_info, tty_config) catch |err| {78 std.debug.writeStackTrace(self, writer, arena.allocator(), debug_info, tty_config) catch |err| {
79 try writer.print("Unable to print stack trace: {s}\n", .{@errorName(err)});79 try writer.print("Unable to print stack trace: {s}\n", .{@errorName(err)});
80 };80 };
81 try writer.writeAll("\n");81 try writer.writeAll("\n");
lib/std/child_process.zig+8-8
...@@ -23,7 +23,7 @@ pub const ChildProcess = struct {...@@ -23,7 +23,7 @@ pub const ChildProcess = struct {
23 handle: if (builtin.os.tag == .windows) windows.HANDLE else void,23 handle: if (builtin.os.tag == .windows) windows.HANDLE else void,
24 thread_handle: if (builtin.os.tag == .windows) windows.HANDLE else void,24 thread_handle: if (builtin.os.tag == .windows) windows.HANDLE else void,
2525
26 allocator: *mem.Allocator,26 allocator: mem.Allocator,
2727
28 stdin: ?File,28 stdin: ?File,
29 stdout: ?File,29 stdout: ?File,
...@@ -90,7 +90,7 @@ pub const ChildProcess = struct {...@@ -90,7 +90,7 @@ pub const ChildProcess = struct {
9090
91 /// First argument in argv is the executable.91 /// First argument in argv is the executable.
92 /// On success must call deinit.92 /// On success must call deinit.
93 pub fn init(argv: []const []const u8, allocator: *mem.Allocator) !*ChildProcess {93 pub fn init(argv: []const []const u8, allocator: mem.Allocator) !*ChildProcess {
94 const child = try allocator.create(ChildProcess);94 const child = try allocator.create(ChildProcess);
95 child.* = ChildProcess{95 child.* = ChildProcess{
96 .allocator = allocator,96 .allocator = allocator,
...@@ -329,7 +329,7 @@ pub const ChildProcess = struct {...@@ -329,7 +329,7 @@ pub const ChildProcess = struct {
329 /// Spawns a child process, waits for it, collecting stdout and stderr, and then returns.329 /// Spawns a child process, waits for it, collecting stdout and stderr, and then returns.
330 /// If it succeeds, the caller owns result.stdout and result.stderr memory.330 /// If it succeeds, the caller owns result.stdout and result.stderr memory.
331 pub fn exec(args: struct {331 pub fn exec(args: struct {
332 allocator: *mem.Allocator,332 allocator: mem.Allocator,
333 argv: []const []const u8,333 argv: []const []const u8,
334 cwd: ?[]const u8 = null,334 cwd: ?[]const u8 = null,
335 cwd_dir: ?fs.Dir = null,335 cwd_dir: ?fs.Dir = null,
...@@ -541,7 +541,7 @@ pub const ChildProcess = struct {...@@ -541,7 +541,7 @@ pub const ChildProcess = struct {
541541
542 var arena_allocator = std.heap.ArenaAllocator.init(self.allocator);542 var arena_allocator = std.heap.ArenaAllocator.init(self.allocator);
543 defer arena_allocator.deinit();543 defer arena_allocator.deinit();
544 const arena = &arena_allocator.allocator;544 const arena = arena_allocator.allocator();
545545
546 // The POSIX standard does not allow malloc() between fork() and execve(),546 // The POSIX standard does not allow malloc() between fork() and execve(),
547 // and `self.allocator` may be a libc allocator.547 // and `self.allocator` may be a libc allocator.
...@@ -931,7 +931,7 @@ fn windowsCreateProcess(app_name: [*:0]u16, cmd_line: [*:0]u16, envp_ptr: ?[*]u1...@@ -931,7 +931,7 @@ fn windowsCreateProcess(app_name: [*:0]u16, cmd_line: [*:0]u16, envp_ptr: ?[*]u1
931}931}
932932
933/// Caller must dealloc.933/// Caller must dealloc.
934fn windowsCreateCommandLine(allocator: *mem.Allocator, argv: []const []const u8) ![:0]u8 {934fn windowsCreateCommandLine(allocator: mem.Allocator, argv: []const []const u8) ![:0]u8 {
935 var buf = std.ArrayList(u8).init(allocator);935 var buf = std.ArrayList(u8).init(allocator);
936 defer buf.deinit();936 defer buf.deinit();
937937
...@@ -1081,7 +1081,7 @@ fn readIntFd(fd: i32) !ErrInt {...@@ -1081,7 +1081,7 @@ fn readIntFd(fd: i32) !ErrInt {
1081}1081}
10821082
1083/// Caller must free result.1083/// Caller must free result.
1084pub fn createWindowsEnvBlock(allocator: *mem.Allocator, env_map: *const BufMap) ![]u16 {1084pub fn createWindowsEnvBlock(allocator: mem.Allocator, env_map: *const BufMap) ![]u16 {
1085 // count bytes needed1085 // count bytes needed
1086 const max_chars_needed = x: {1086 const max_chars_needed = x: {
1087 var max_chars_needed: usize = 4; // 4 for the final 4 null bytes1087 var max_chars_needed: usize = 4; // 4 for the final 4 null bytes
...@@ -1117,7 +1117,7 @@ pub fn createWindowsEnvBlock(allocator: *mem.Allocator, env_map: *const BufMap)...@@ -1117,7 +1117,7 @@ pub fn createWindowsEnvBlock(allocator: *mem.Allocator, env_map: *const BufMap)
1117 return allocator.shrink(result, i);1117 return allocator.shrink(result, i);
1118}1118}
11191119
1120pub fn createNullDelimitedEnvMap(arena: *mem.Allocator, env_map: *const std.BufMap) ![:null]?[*:0]u8 {1120pub fn createNullDelimitedEnvMap(arena: mem.Allocator, env_map: *const std.BufMap) ![:null]?[*:0]u8 {
1121 const envp_count = env_map.count();1121 const envp_count = env_map.count();
1122 const envp_buf = try arena.allocSentinel(?[*:0]u8, envp_count, null);1122 const envp_buf = try arena.allocSentinel(?[*:0]u8, envp_count, null);
1123 {1123 {
...@@ -1149,7 +1149,7 @@ test "createNullDelimitedEnvMap" {...@@ -1149,7 +1149,7 @@ test "createNullDelimitedEnvMap" {
11491149
1150 var arena = std.heap.ArenaAllocator.init(allocator);1150 var arena = std.heap.ArenaAllocator.init(allocator);
1151 defer arena.deinit();1151 defer arena.deinit();
1152 const environ = try createNullDelimitedEnvMap(&arena.allocator, &envmap);1152 const environ = try createNullDelimitedEnvMap(arena.allocator(), &envmap);
11531153
1154 try testing.expectEqual(@as(usize, 5), environ.len);1154 try testing.expectEqual(@as(usize, 5), environ.len);
11551155
lib/std/coff.zig+3-3
...@@ -98,7 +98,7 @@ pub const CoffError = error{...@@ -98,7 +98,7 @@ pub const CoffError = error{
98// Official documentation of the format: https://docs.microsoft.com/en-us/windows/win32/debug/pe-format98// Official documentation of the format: https://docs.microsoft.com/en-us/windows/win32/debug/pe-format
99pub const Coff = struct {99pub const Coff = struct {
100 in_file: File,100 in_file: File,
101 allocator: *mem.Allocator,101 allocator: mem.Allocator,
102102
103 coff_header: CoffHeader,103 coff_header: CoffHeader,
104 pe_header: OptionalHeader,104 pe_header: OptionalHeader,
...@@ -107,7 +107,7 @@ pub const Coff = struct {...@@ -107,7 +107,7 @@ pub const Coff = struct {
107 guid: [16]u8,107 guid: [16]u8,
108 age: u32,108 age: u32,
109109
110 pub fn init(allocator: *mem.Allocator, in_file: File) Coff {110 pub fn init(allocator: mem.Allocator, in_file: File) Coff {
111 return Coff{111 return Coff{
112 .in_file = in_file,112 .in_file = in_file,
113 .allocator = allocator,113 .allocator = allocator,
...@@ -324,7 +324,7 @@ pub const Coff = struct {...@@ -324,7 +324,7 @@ pub const Coff = struct {
324 }324 }
325325
326 // Return an owned slice full of the section data326 // Return an owned slice full of the section data
327 pub fn getSectionData(self: *Coff, comptime name: []const u8, allocator: *mem.Allocator) ![]u8 {327 pub fn getSectionData(self: *Coff, comptime name: []const u8, allocator: mem.Allocator) ![]u8 {
328 const sec = for (self.sections.items) |*sec| {328 const sec = for (self.sections.items) |*sec| {
329 if (mem.eql(u8, sec.header.name[0..name.len], name)) {329 if (mem.eql(u8, sec.header.name[0..name.len], name)) {
330 break sec;330 break sec;
lib/std/compress/gzip.zig+3-3
...@@ -24,7 +24,7 @@ pub fn GzipStream(comptime ReaderType: type) type {...@@ -24,7 +24,7 @@ pub fn GzipStream(comptime ReaderType: type) type {
24 error{ CorruptedData, WrongChecksum };24 error{ CorruptedData, WrongChecksum };
25 pub const Reader = io.Reader(*Self, Error, read);25 pub const Reader = io.Reader(*Self, Error, read);
2626
27 allocator: *mem.Allocator,27 allocator: mem.Allocator,
28 inflater: deflate.InflateStream(ReaderType),28 inflater: deflate.InflateStream(ReaderType),
29 in_reader: ReaderType,29 in_reader: ReaderType,
30 hasher: std.hash.Crc32,30 hasher: std.hash.Crc32,
...@@ -37,7 +37,7 @@ pub fn GzipStream(comptime ReaderType: type) type {...@@ -37,7 +37,7 @@ pub fn GzipStream(comptime ReaderType: type) type {
37 modification_time: u32,37 modification_time: u32,
38 },38 },
3939
40 fn init(allocator: *mem.Allocator, source: ReaderType) !Self {40 fn init(allocator: mem.Allocator, source: ReaderType) !Self {
41 // gzip header format is specified in RFC195241 // gzip header format is specified in RFC1952
42 const header = try source.readBytesNoEof(10);42 const header = try source.readBytesNoEof(10);
4343
...@@ -152,7 +152,7 @@ pub fn GzipStream(comptime ReaderType: type) type {...@@ -152,7 +152,7 @@ pub fn GzipStream(comptime ReaderType: type) type {
152 };152 };
153}153}
154154
155pub fn gzipStream(allocator: *mem.Allocator, reader: anytype) !GzipStream(@TypeOf(reader)) {155pub fn gzipStream(allocator: mem.Allocator, reader: anytype) !GzipStream(@TypeOf(reader)) {
156 return GzipStream(@TypeOf(reader)).init(allocator, reader);156 return GzipStream(@TypeOf(reader)).init(allocator, reader);
157}157}
158158
lib/std/compress/zlib.zig+3-3
...@@ -17,13 +17,13 @@ pub fn ZlibStream(comptime ReaderType: type) type {...@@ -17,13 +17,13 @@ pub fn ZlibStream(comptime ReaderType: type) type {
17 error{ WrongChecksum, Unsupported };17 error{ WrongChecksum, Unsupported };
18 pub const Reader = io.Reader(*Self, Error, read);18 pub const Reader = io.Reader(*Self, Error, read);
1919
20 allocator: *mem.Allocator,20 allocator: mem.Allocator,
21 inflater: deflate.InflateStream(ReaderType),21 inflater: deflate.InflateStream(ReaderType),
22 in_reader: ReaderType,22 in_reader: ReaderType,
23 hasher: std.hash.Adler32,23 hasher: std.hash.Adler32,
24 window_slice: []u8,24 window_slice: []u8,
2525
26 fn init(allocator: *mem.Allocator, source: ReaderType) !Self {26 fn init(allocator: mem.Allocator, source: ReaderType) !Self {
27 // Zlib header format is specified in RFC195027 // Zlib header format is specified in RFC1950
28 const header = try source.readBytesNoEof(2);28 const header = try source.readBytesNoEof(2);
2929
...@@ -88,7 +88,7 @@ pub fn ZlibStream(comptime ReaderType: type) type {...@@ -88,7 +88,7 @@ pub fn ZlibStream(comptime ReaderType: type) type {
88 };88 };
89}89}
9090
91pub fn zlibStream(allocator: *mem.Allocator, reader: anytype) !ZlibStream(@TypeOf(reader)) {91pub fn zlibStream(allocator: mem.Allocator, reader: anytype) !ZlibStream(@TypeOf(reader)) {
92 return ZlibStream(@TypeOf(reader)).init(allocator, reader);92 return ZlibStream(@TypeOf(reader)).init(allocator, reader);
93}93}
9494
lib/std/crypto/argon2.zig+7-7
...@@ -201,7 +201,7 @@ fn initBlocks(...@@ -201,7 +201,7 @@ fn initBlocks(
201}201}
202202
203fn processBlocks(203fn processBlocks(
204 allocator: *mem.Allocator,204 allocator: mem.Allocator,
205 blocks: *Blocks,205 blocks: *Blocks,
206 time: u32,206 time: u32,
207 memory: u32,207 memory: u32,
...@@ -240,7 +240,7 @@ fn processBlocksSt(...@@ -240,7 +240,7 @@ fn processBlocksSt(
240}240}
241241
242fn processBlocksMt(242fn processBlocksMt(
243 allocator: *mem.Allocator,243 allocator: mem.Allocator,
244 blocks: *Blocks,244 blocks: *Blocks,
245 time: u32,245 time: u32,
246 memory: u32,246 memory: u32,
...@@ -480,7 +480,7 @@ fn indexAlpha(...@@ -480,7 +480,7 @@ fn indexAlpha(
480///480///
481/// Salt has to be at least 8 bytes length.481/// Salt has to be at least 8 bytes length.
482pub fn kdf(482pub fn kdf(
483 allocator: *mem.Allocator,483 allocator: mem.Allocator,
484 derived_key: []u8,484 derived_key: []u8,
485 password: []const u8,485 password: []const u8,
486 salt: []const u8,486 salt: []const u8,
...@@ -524,7 +524,7 @@ const PhcFormatHasher = struct {...@@ -524,7 +524,7 @@ const PhcFormatHasher = struct {
524 };524 };
525525
526 pub fn create(526 pub fn create(
527 allocator: *mem.Allocator,527 allocator: mem.Allocator,
528 password: []const u8,528 password: []const u8,
529 params: Params,529 params: Params,
530 mode: Mode,530 mode: Mode,
...@@ -550,7 +550,7 @@ const PhcFormatHasher = struct {...@@ -550,7 +550,7 @@ const PhcFormatHasher = struct {
550 }550 }
551551
552 pub fn verify(552 pub fn verify(
553 allocator: *mem.Allocator,553 allocator: mem.Allocator,
554 str: []const u8,554 str: []const u8,
555 password: []const u8,555 password: []const u8,
556 ) HasherError!void {556 ) HasherError!void {
...@@ -579,7 +579,7 @@ const PhcFormatHasher = struct {...@@ -579,7 +579,7 @@ const PhcFormatHasher = struct {
579///579///
580/// Only phc encoding is supported.580/// Only phc encoding is supported.
581pub const HashOptions = struct {581pub const HashOptions = struct {
582 allocator: ?*mem.Allocator,582 allocator: ?mem.Allocator,
583 params: Params,583 params: Params,
584 mode: Mode = .argon2id,584 mode: Mode = .argon2id,
585 encoding: pwhash.Encoding = .phc,585 encoding: pwhash.Encoding = .phc,
...@@ -609,7 +609,7 @@ pub fn strHash(...@@ -609,7 +609,7 @@ pub fn strHash(
609///609///
610/// Allocator is required for argon2.610/// Allocator is required for argon2.
611pub const VerifyOptions = struct {611pub const VerifyOptions = struct {
612 allocator: ?*mem.Allocator,612 allocator: ?mem.Allocator,
613};613};
614614
615/// Verify that a previously computed hash is valid for a given password.615/// Verify that a previously computed hash is valid for a given password.
lib/std/crypto/bcrypt.zig+2-2
...@@ -368,7 +368,7 @@ const CryptFormatHasher = struct {...@@ -368,7 +368,7 @@ const CryptFormatHasher = struct {
368368
369/// Options for hashing a password.369/// Options for hashing a password.
370pub const HashOptions = struct {370pub const HashOptions = struct {
371 allocator: ?*mem.Allocator = null,371 allocator: ?mem.Allocator = null,
372 params: Params,372 params: Params,
373 encoding: pwhash.Encoding,373 encoding: pwhash.Encoding,
374};374};
...@@ -394,7 +394,7 @@ pub fn strHash(...@@ -394,7 +394,7 @@ pub fn strHash(
394394
395/// Options for hash verification.395/// Options for hash verification.
396pub const VerifyOptions = struct {396pub const VerifyOptions = struct {
397 allocator: ?*mem.Allocator = null,397 allocator: ?mem.Allocator = null,
398};398};
399399
400/// Verify that a previously computed hash is valid for a given password.400/// Verify that a previously computed hash is valid for a given password.
lib/std/crypto/benchmark.zig+1-1
...@@ -363,7 +363,7 @@ pub fn main() !void {...@@ -363,7 +363,7 @@ pub fn main() !void {
363363
364 var buffer: [1024]u8 = undefined;364 var buffer: [1024]u8 = undefined;
365 var fixed = std.heap.FixedBufferAllocator.init(buffer[0..]);365 var fixed = std.heap.FixedBufferAllocator.init(buffer[0..]);
366 const args = try std.process.argsAlloc(&fixed.allocator);366 const args = try std.process.argsAlloc(fixed.allocator());
367367
368 var filter: ?[]u8 = "";368 var filter: ?[]u8 = "";
369369
lib/std/crypto/scrypt.zig+8-8
...@@ -161,7 +161,7 @@ pub const Params = struct {...@@ -161,7 +161,7 @@ pub const Params = struct {
161///161///
162/// scrypt is defined in RFC 7914.162/// scrypt is defined in RFC 7914.
163///163///
164/// allocator: *mem.Allocator.164/// allocator: mem.Allocator.
165///165///
166/// derived_key: Slice of appropriate size for generated key. Generally 16 or 32 bytes in length.166/// derived_key: Slice of appropriate size for generated key. Generally 16 or 32 bytes in length.
167/// May be uninitialized. All bytes will be overwritten.167/// May be uninitialized. All bytes will be overwritten.
...@@ -173,7 +173,7 @@ pub const Params = struct {...@@ -173,7 +173,7 @@ pub const Params = struct {
173///173///
174/// params: Params.174/// params: Params.
175pub fn kdf(175pub fn kdf(
176 allocator: *mem.Allocator,176 allocator: mem.Allocator,
177 derived_key: []u8,177 derived_key: []u8,
178 password: []const u8,178 password: []const u8,
179 salt: []const u8,179 salt: []const u8,
...@@ -406,7 +406,7 @@ const PhcFormatHasher = struct {...@@ -406,7 +406,7 @@ const PhcFormatHasher = struct {
406406
407 /// Return a non-deterministic hash of the password encoded as a PHC-format string407 /// Return a non-deterministic hash of the password encoded as a PHC-format string
408 pub fn create(408 pub fn create(
409 allocator: *mem.Allocator,409 allocator: mem.Allocator,
410 password: []const u8,410 password: []const u8,
411 params: Params,411 params: Params,
412 buf: []u8,412 buf: []u8,
...@@ -429,7 +429,7 @@ const PhcFormatHasher = struct {...@@ -429,7 +429,7 @@ const PhcFormatHasher = struct {
429429
430 /// Verify a password against a PHC-format encoded string430 /// Verify a password against a PHC-format encoded string
431 pub fn verify(431 pub fn verify(
432 allocator: *mem.Allocator,432 allocator: mem.Allocator,
433 str: []const u8,433 str: []const u8,
434 password: []const u8,434 password: []const u8,
435 ) HasherError!void {435 ) HasherError!void {
...@@ -455,7 +455,7 @@ const CryptFormatHasher = struct {...@@ -455,7 +455,7 @@ const CryptFormatHasher = struct {
455455
456 /// Return a non-deterministic hash of the password encoded into the modular crypt format456 /// Return a non-deterministic hash of the password encoded into the modular crypt format
457 pub fn create(457 pub fn create(
458 allocator: *mem.Allocator,458 allocator: mem.Allocator,
459 password: []const u8,459 password: []const u8,
460 params: Params,460 params: Params,
461 buf: []u8,461 buf: []u8,
...@@ -478,7 +478,7 @@ const CryptFormatHasher = struct {...@@ -478,7 +478,7 @@ const CryptFormatHasher = struct {
478478
479 /// Verify a password against a string in modular crypt format479 /// Verify a password against a string in modular crypt format
480 pub fn verify(480 pub fn verify(
481 allocator: *mem.Allocator,481 allocator: mem.Allocator,
482 str: []const u8,482 str: []const u8,
483 password: []const u8,483 password: []const u8,
484 ) HasherError!void {484 ) HasherError!void {
...@@ -497,7 +497,7 @@ const CryptFormatHasher = struct {...@@ -497,7 +497,7 @@ const CryptFormatHasher = struct {
497///497///
498/// Allocator is required for scrypt.498/// Allocator is required for scrypt.
499pub const HashOptions = struct {499pub const HashOptions = struct {
500 allocator: ?*mem.Allocator,500 allocator: ?mem.Allocator,
501 params: Params,501 params: Params,
502 encoding: pwhash.Encoding,502 encoding: pwhash.Encoding,
503};503};
...@@ -520,7 +520,7 @@ pub fn strHash(...@@ -520,7 +520,7 @@ pub fn strHash(
520///520///
521/// Allocator is required for scrypt.521/// Allocator is required for scrypt.
522pub const VerifyOptions = struct {522pub const VerifyOptions = struct {
523 allocator: ?*mem.Allocator,523 allocator: ?mem.Allocator,
524};524};
525525
526/// Verify that a previously computed hash is valid for a given password.526/// Verify that a previously computed hash is valid for a given password.
lib/std/cstr.zig+3-3
...@@ -33,7 +33,7 @@ fn testCStrFnsImpl() !void {...@@ -33,7 +33,7 @@ fn testCStrFnsImpl() !void {
3333
34/// Returns a mutable, null-terminated slice with the same length as `slice`.34/// Returns a mutable, null-terminated slice with the same length as `slice`.
35/// Caller owns the returned memory.35/// Caller owns the returned memory.
36pub fn addNullByte(allocator: *mem.Allocator, slice: []const u8) ![:0]u8 {36pub fn addNullByte(allocator: mem.Allocator, slice: []const u8) ![:0]u8 {
37 const result = try allocator.alloc(u8, slice.len + 1);37 const result = try allocator.alloc(u8, slice.len + 1);
38 mem.copy(u8, result, slice);38 mem.copy(u8, result, slice);
39 result[slice.len] = 0;39 result[slice.len] = 0;
...@@ -48,13 +48,13 @@ test "addNullByte" {...@@ -48,13 +48,13 @@ test "addNullByte" {
48}48}
4949
50pub const NullTerminated2DArray = struct {50pub const NullTerminated2DArray = struct {
51 allocator: *mem.Allocator,51 allocator: mem.Allocator,
52 byte_count: usize,52 byte_count: usize,
53 ptr: ?[*:null]?[*:0]u8,53 ptr: ?[*:null]?[*:0]u8,
5454
55 /// Takes N lists of strings, concatenates the lists together, and adds a null terminator55 /// Takes N lists of strings, concatenates the lists together, and adds a null terminator
56 /// Caller must deinit result56 /// Caller must deinit result
57 pub fn fromSlices(allocator: *mem.Allocator, slices: []const []const []const u8) !NullTerminated2DArray {57 pub fn fromSlices(allocator: mem.Allocator, slices: []const []const []const u8) !NullTerminated2DArray {
58 var new_len: usize = 1; // 1 for the list null58 var new_len: usize = 1; // 1 for the list null
59 var byte_count: usize = 0;59 var byte_count: usize = 0;
60 for (slices) |slice| {60 for (slices) |slice| {
lib/std/debug.zig+15-14
...@@ -29,7 +29,7 @@ pub const LineInfo = struct {...@@ -29,7 +29,7 @@ pub const LineInfo = struct {
29 line: u64,29 line: u64,
30 column: u64,30 column: u64,
31 file_name: []const u8,31 file_name: []const u8,
32 allocator: ?*mem.Allocator,32 allocator: ?mem.Allocator,
3333
34 pub fn deinit(self: LineInfo) void {34 pub fn deinit(self: LineInfo) void {
35 const allocator = self.allocator orelse return;35 const allocator = self.allocator orelse return;
...@@ -339,7 +339,7 @@ const RESET = "\x1b[0m";...@@ -339,7 +339,7 @@ const RESET = "\x1b[0m";
339pub fn writeStackTrace(339pub fn writeStackTrace(
340 stack_trace: std.builtin.StackTrace,340 stack_trace: std.builtin.StackTrace,
341 out_stream: anytype,341 out_stream: anytype,
342 allocator: *mem.Allocator,342 allocator: mem.Allocator,
343 debug_info: *DebugInfo,343 debug_info: *DebugInfo,
344 tty_config: TTY.Config,344 tty_config: TTY.Config,
345) !void {345) !void {
...@@ -662,7 +662,7 @@ pub const OpenSelfDebugInfoError = error{...@@ -662,7 +662,7 @@ pub const OpenSelfDebugInfoError = error{
662};662};
663663
664/// TODO resources https://github.com/ziglang/zig/issues/4353664/// TODO resources https://github.com/ziglang/zig/issues/4353
665pub fn openSelfDebugInfo(allocator: *mem.Allocator) anyerror!DebugInfo {665pub fn openSelfDebugInfo(allocator: mem.Allocator) anyerror!DebugInfo {
666 nosuspend {666 nosuspend {
667 if (builtin.strip_debug_info)667 if (builtin.strip_debug_info)
668 return error.MissingDebugInfo;668 return error.MissingDebugInfo;
...@@ -688,7 +688,7 @@ pub fn openSelfDebugInfo(allocator: *mem.Allocator) anyerror!DebugInfo {...@@ -688,7 +688,7 @@ pub fn openSelfDebugInfo(allocator: *mem.Allocator) anyerror!DebugInfo {
688/// it themselves, even on error.688/// it themselves, even on error.
689/// TODO resources https://github.com/ziglang/zig/issues/4353689/// TODO resources https://github.com/ziglang/zig/issues/4353
690/// TODO it's weird to take ownership even on error, rework this code.690/// TODO it's weird to take ownership even on error, rework this code.
691fn readCoffDebugInfo(allocator: *mem.Allocator, coff_file: File) !ModuleDebugInfo {691fn readCoffDebugInfo(allocator: mem.Allocator, coff_file: File) !ModuleDebugInfo {
692 nosuspend {692 nosuspend {
693 errdefer coff_file.close();693 errdefer coff_file.close();
694694
...@@ -755,7 +755,7 @@ fn chopSlice(ptr: []const u8, offset: u64, size: u64) ![]const u8 {...@@ -755,7 +755,7 @@ fn chopSlice(ptr: []const u8, offset: u64, size: u64) ![]const u8 {
755/// it themselves, even on error.755/// it themselves, even on error.
756/// TODO resources https://github.com/ziglang/zig/issues/4353756/// TODO resources https://github.com/ziglang/zig/issues/4353
757/// TODO it's weird to take ownership even on error, rework this code.757/// TODO it's weird to take ownership even on error, rework this code.
758pub fn readElfDebugInfo(allocator: *mem.Allocator, elf_file: File) !ModuleDebugInfo {758pub fn readElfDebugInfo(allocator: mem.Allocator, elf_file: File) !ModuleDebugInfo {
759 nosuspend {759 nosuspend {
760 const mapped_mem = try mapWholeFile(elf_file);760 const mapped_mem = try mapWholeFile(elf_file);
761 const hdr = @ptrCast(*const elf.Ehdr, &mapped_mem[0]);761 const hdr = @ptrCast(*const elf.Ehdr, &mapped_mem[0]);
...@@ -827,7 +827,7 @@ pub fn readElfDebugInfo(allocator: *mem.Allocator, elf_file: File) !ModuleDebugI...@@ -827,7 +827,7 @@ pub fn readElfDebugInfo(allocator: *mem.Allocator, elf_file: File) !ModuleDebugI
827/// This takes ownership of macho_file: users of this function should not close827/// This takes ownership of macho_file: users of this function should not close
828/// it themselves, even on error.828/// it themselves, even on error.
829/// TODO it's weird to take ownership even on error, rework this code.829/// TODO it's weird to take ownership even on error, rework this code.
830fn readMachODebugInfo(allocator: *mem.Allocator, macho_file: File) !ModuleDebugInfo {830fn readMachODebugInfo(allocator: mem.Allocator, macho_file: File) !ModuleDebugInfo {
831 const mapped_mem = try mapWholeFile(macho_file);831 const mapped_mem = try mapWholeFile(macho_file);
832832
833 const hdr = @ptrCast(833 const hdr = @ptrCast(
...@@ -1025,10 +1025,10 @@ fn mapWholeFile(file: File) ![]align(mem.page_size) const u8 {...@@ -1025,10 +1025,10 @@ fn mapWholeFile(file: File) ![]align(mem.page_size) const u8 {
1025}1025}
10261026
1027pub const DebugInfo = struct {1027pub const DebugInfo = struct {
1028 allocator: *mem.Allocator,1028 allocator: mem.Allocator,
1029 address_map: std.AutoHashMap(usize, *ModuleDebugInfo),1029 address_map: std.AutoHashMap(usize, *ModuleDebugInfo),
10301030
1031 pub fn init(allocator: *mem.Allocator) DebugInfo {1031 pub fn init(allocator: mem.Allocator) DebugInfo {
1032 return DebugInfo{1032 return DebugInfo{
1033 .allocator = allocator,1033 .allocator = allocator,
1034 .address_map = std.AutoHashMap(usize, *ModuleDebugInfo).init(allocator),1034 .address_map = std.AutoHashMap(usize, *ModuleDebugInfo).init(allocator),
...@@ -1278,7 +1278,7 @@ pub const ModuleDebugInfo = switch (native_os) {...@@ -1278,7 +1278,7 @@ pub const ModuleDebugInfo = switch (native_os) {
1278 addr_table: std.StringHashMap(u64),1278 addr_table: std.StringHashMap(u64),
1279 };1279 };
12801280
1281 pub fn allocator(self: @This()) *mem.Allocator {1281 pub fn allocator(self: @This()) mem.Allocator {
1282 return self.ofiles.allocator;1282 return self.ofiles.allocator;
1283 }1283 }
12841284
...@@ -1470,7 +1470,7 @@ pub const ModuleDebugInfo = switch (native_os) {...@@ -1470,7 +1470,7 @@ pub const ModuleDebugInfo = switch (native_os) {
1470 debug_data: PdbOrDwarf,1470 debug_data: PdbOrDwarf,
1471 coff: *coff.Coff,1471 coff: *coff.Coff,
14721472
1473 pub fn allocator(self: @This()) *mem.Allocator {1473 pub fn allocator(self: @This()) mem.Allocator {
1474 return self.coff.allocator;1474 return self.coff.allocator;
1475 }1475 }
14761476
...@@ -1560,14 +1560,15 @@ fn getSymbolFromDwarf(address: u64, di: *DW.DwarfInfo) !SymbolInfo {...@@ -1560,14 +1560,15 @@ fn getSymbolFromDwarf(address: u64, di: *DW.DwarfInfo) !SymbolInfo {
1560}1560}
15611561
1562/// TODO multithreaded awareness1562/// TODO multithreaded awareness
1563var debug_info_allocator: ?*mem.Allocator = null;1563var debug_info_allocator: ?mem.Allocator = null;
1564var debug_info_arena_allocator: std.heap.ArenaAllocator = undefined;1564var debug_info_arena_allocator: std.heap.ArenaAllocator = undefined;
1565fn getDebugInfoAllocator() *mem.Allocator {1565fn getDebugInfoAllocator() mem.Allocator {
1566 if (debug_info_allocator) |a| return a;1566 if (debug_info_allocator) |a| return a;
15671567
1568 debug_info_arena_allocator = std.heap.ArenaAllocator.init(std.heap.page_allocator);1568 debug_info_arena_allocator = std.heap.ArenaAllocator.init(std.heap.page_allocator);
1569 debug_info_allocator = &debug_info_arena_allocator.allocator;1569 const allocator = debug_info_arena_allocator.allocator();
1570 return &debug_info_arena_allocator.allocator;1570 debug_info_allocator = allocator;
1571 return allocator;
1571}1572}
15721573
1573/// Whether or not the current target can print useful debug information when a segfault occurs.1574/// Whether or not the current target can print useful debug information when a segfault occurs.
lib/std/dwarf.zig+8-8
...@@ -466,7 +466,7 @@ fn readUnitLength(in_stream: anytype, endian: std.builtin.Endian, is_64: *bool)...@@ -466,7 +466,7 @@ fn readUnitLength(in_stream: anytype, endian: std.builtin.Endian, is_64: *bool)
466}466}
467467
468// TODO the nosuspends here are workarounds468// TODO the nosuspends here are workarounds
469fn readAllocBytes(allocator: *mem.Allocator, in_stream: anytype, size: usize) ![]u8 {469fn readAllocBytes(allocator: mem.Allocator, in_stream: anytype, size: usize) ![]u8 {
470 const buf = try allocator.alloc(u8, size);470 const buf = try allocator.alloc(u8, size);
471 errdefer allocator.free(buf);471 errdefer allocator.free(buf);
472 if ((try nosuspend in_stream.read(buf)) < size) return error.EndOfFile;472 if ((try nosuspend in_stream.read(buf)) < size) return error.EndOfFile;
...@@ -481,18 +481,18 @@ fn readAddress(in_stream: anytype, endian: std.builtin.Endian, is_64: bool) !u64...@@ -481,18 +481,18 @@ fn readAddress(in_stream: anytype, endian: std.builtin.Endian, is_64: bool) !u64
481 @as(u64, try in_stream.readInt(u32, endian));481 @as(u64, try in_stream.readInt(u32, endian));
482}482}
483483
484fn parseFormValueBlockLen(allocator: *mem.Allocator, in_stream: anytype, size: usize) !FormValue {484fn parseFormValueBlockLen(allocator: mem.Allocator, in_stream: anytype, size: usize) !FormValue {
485 const buf = try readAllocBytes(allocator, in_stream, size);485 const buf = try readAllocBytes(allocator, in_stream, size);
486 return FormValue{ .Block = buf };486 return FormValue{ .Block = buf };
487}487}
488488
489// TODO the nosuspends here are workarounds489// TODO the nosuspends here are workarounds
490fn parseFormValueBlock(allocator: *mem.Allocator, in_stream: anytype, endian: std.builtin.Endian, size: usize) !FormValue {490fn parseFormValueBlock(allocator: mem.Allocator, in_stream: anytype, endian: std.builtin.Endian, size: usize) !FormValue {
491 const block_len = try nosuspend in_stream.readVarInt(usize, endian, size);491 const block_len = try nosuspend in_stream.readVarInt(usize, endian, size);
492 return parseFormValueBlockLen(allocator, in_stream, block_len);492 return parseFormValueBlockLen(allocator, in_stream, block_len);
493}493}
494494
495fn parseFormValueConstant(allocator: *mem.Allocator, in_stream: anytype, signed: bool, endian: std.builtin.Endian, comptime size: i32) !FormValue {495fn parseFormValueConstant(allocator: mem.Allocator, in_stream: anytype, signed: bool, endian: std.builtin.Endian, comptime size: i32) !FormValue {
496 _ = allocator;496 _ = allocator;
497 // TODO: Please forgive me, I've worked around zig not properly spilling some intermediate values here.497 // TODO: Please forgive me, I've worked around zig not properly spilling some intermediate values here.
498 // `nosuspend` should be removed from all the function calls once it is fixed.498 // `nosuspend` should be removed from all the function calls once it is fixed.
...@@ -520,7 +520,7 @@ fn parseFormValueConstant(allocator: *mem.Allocator, in_stream: anytype, signed:...@@ -520,7 +520,7 @@ fn parseFormValueConstant(allocator: *mem.Allocator, in_stream: anytype, signed:
520}520}
521521
522// TODO the nosuspends here are workarounds522// TODO the nosuspends here are workarounds
523fn parseFormValueRef(allocator: *mem.Allocator, in_stream: anytype, endian: std.builtin.Endian, size: i32) !FormValue {523fn parseFormValueRef(allocator: mem.Allocator, in_stream: anytype, endian: std.builtin.Endian, size: i32) !FormValue {
524 _ = allocator;524 _ = allocator;
525 return FormValue{525 return FormValue{
526 .Ref = switch (size) {526 .Ref = switch (size) {
...@@ -535,7 +535,7 @@ fn parseFormValueRef(allocator: *mem.Allocator, in_stream: anytype, endian: std....@@ -535,7 +535,7 @@ fn parseFormValueRef(allocator: *mem.Allocator, in_stream: anytype, endian: std.
535}535}
536536
537// TODO the nosuspends here are workarounds537// TODO the nosuspends here are workarounds
538fn parseFormValue(allocator: *mem.Allocator, in_stream: anytype, form_id: u64, endian: std.builtin.Endian, is_64: bool) anyerror!FormValue {538fn parseFormValue(allocator: mem.Allocator, in_stream: anytype, form_id: u64, endian: std.builtin.Endian, is_64: bool) anyerror!FormValue {
539 return switch (form_id) {539 return switch (form_id) {
540 FORM.addr => FormValue{ .Address = try readAddress(in_stream, endian, @sizeOf(usize) == 8) },540 FORM.addr => FormValue{ .Address = try readAddress(in_stream, endian, @sizeOf(usize) == 8) },
541 FORM.block1 => parseFormValueBlock(allocator, in_stream, endian, 1),541 FORM.block1 => parseFormValueBlock(allocator, in_stream, endian, 1),
...@@ -604,7 +604,7 @@ pub const DwarfInfo = struct {...@@ -604,7 +604,7 @@ pub const DwarfInfo = struct {
604 compile_unit_list: ArrayList(CompileUnit) = undefined,604 compile_unit_list: ArrayList(CompileUnit) = undefined,
605 func_list: ArrayList(Func) = undefined,605 func_list: ArrayList(Func) = undefined,
606606
607 pub fn allocator(self: DwarfInfo) *mem.Allocator {607 pub fn allocator(self: DwarfInfo) mem.Allocator {
608 return self.abbrev_table_list.allocator;608 return self.abbrev_table_list.allocator;
609 }609 }
610610
...@@ -1092,7 +1092,7 @@ pub const DwarfInfo = struct {...@@ -1092,7 +1092,7 @@ pub const DwarfInfo = struct {
1092/// the DwarfInfo fields before calling. These fields can be left undefined:1092/// the DwarfInfo fields before calling. These fields can be left undefined:
1093/// * abbrev_table_list1093/// * abbrev_table_list
1094/// * compile_unit_list1094/// * compile_unit_list
1095pub fn openDwarfDebugInfo(di: *DwarfInfo, allocator: *mem.Allocator) !void {1095pub fn openDwarfDebugInfo(di: *DwarfInfo, allocator: mem.Allocator) !void {
1096 di.abbrev_table_list = ArrayList(AbbrevTableHeader).init(allocator);1096 di.abbrev_table_list = ArrayList(AbbrevTableHeader).init(allocator);
1097 di.compile_unit_list = ArrayList(CompileUnit).init(allocator);1097 di.compile_unit_list = ArrayList(CompileUnit).init(allocator);
1098 di.func_list = ArrayList(Func).init(allocator);1098 di.func_list = ArrayList(Func).init(allocator);
lib/std/event/group.zig+3-3
...@@ -15,7 +15,7 @@ pub fn Group(comptime ReturnType: type) type {...@@ -15,7 +15,7 @@ pub fn Group(comptime ReturnType: type) type {
15 frame_stack: Stack,15 frame_stack: Stack,
16 alloc_stack: AllocStack,16 alloc_stack: AllocStack,
17 lock: Lock,17 lock: Lock,
18 allocator: *Allocator,18 allocator: Allocator,
1919
20 const Self = @This();20 const Self = @This();
2121
...@@ -31,7 +31,7 @@ pub fn Group(comptime ReturnType: type) type {...@@ -31,7 +31,7 @@ pub fn Group(comptime ReturnType: type) type {
31 handle: anyframe->ReturnType,31 handle: anyframe->ReturnType,
32 };32 };
3333
34 pub fn init(allocator: *Allocator) Self {34 pub fn init(allocator: Allocator) Self {
35 return Self{35 return Self{
36 .frame_stack = Stack.init(),36 .frame_stack = Stack.init(),
37 .alloc_stack = AllocStack.init(),37 .alloc_stack = AllocStack.init(),
...@@ -127,7 +127,7 @@ test "std.event.Group" {...@@ -127,7 +127,7 @@ test "std.event.Group" {
127127
128 _ = async testGroup(std.heap.page_allocator);128 _ = async testGroup(std.heap.page_allocator);
129}129}
130fn testGroup(allocator: *Allocator) callconv(.Async) void {130fn testGroup(allocator: Allocator) callconv(.Async) void {
131 var count: usize = 0;131 var count: usize = 0;
132 var group = Group(void).init(allocator);132 var group = Group(void).init(allocator);
133 var sleep_a_little_frame = async sleepALittle(&count);133 var sleep_a_little_frame = async sleepALittle(&count);
lib/std/event/loop.zig+4-4
...@@ -173,12 +173,12 @@ pub const Loop = struct {...@@ -173,12 +173,12 @@ pub const Loop = struct {
173 // We need at least one of these in case the fs thread wants to use onNextTick173 // We need at least one of these in case the fs thread wants to use onNextTick
174 const extra_thread_count = thread_count - 1;174 const extra_thread_count = thread_count - 1;
175 const resume_node_count = std.math.max(extra_thread_count, 1);175 const resume_node_count = std.math.max(extra_thread_count, 1);
176 self.eventfd_resume_nodes = try self.arena.allocator.alloc(176 self.eventfd_resume_nodes = try self.arena.allocator().alloc(
177 std.atomic.Stack(ResumeNode.EventFd).Node,177 std.atomic.Stack(ResumeNode.EventFd).Node,
178 resume_node_count,178 resume_node_count,
179 );179 );
180180
181 self.extra_threads = try self.arena.allocator.alloc(Thread, extra_thread_count);181 self.extra_threads = try self.arena.allocator().alloc(Thread, extra_thread_count);
182182
183 try self.initOsData(extra_thread_count);183 try self.initOsData(extra_thread_count);
184 errdefer self.deinitOsData();184 errdefer self.deinitOsData();
...@@ -727,7 +727,7 @@ pub const Loop = struct {...@@ -727,7 +727,7 @@ pub const Loop = struct {
727 /// with `allocator` and freed when the function returns.727 /// with `allocator` and freed when the function returns.
728 /// `func` must return void and it can be an async function.728 /// `func` must return void and it can be an async function.
729 /// Yields to the event loop, running the function on the next tick.729 /// Yields to the event loop, running the function on the next tick.
730 pub fn runDetached(self: *Loop, alloc: *mem.Allocator, comptime func: anytype, args: anytype) error{OutOfMemory}!void {730 pub fn runDetached(self: *Loop, alloc: mem.Allocator, comptime func: anytype, args: anytype) error{OutOfMemory}!void {
731 if (!std.io.is_async) @compileError("Can't use runDetached in non-async mode!");731 if (!std.io.is_async) @compileError("Can't use runDetached in non-async mode!");
732 if (@TypeOf(@call(.{}, func, args)) != void) {732 if (@TypeOf(@call(.{}, func, args)) != void) {
733 @compileError("`func` must not have a return value");733 @compileError("`func` must not have a return value");
...@@ -735,7 +735,7 @@ pub const Loop = struct {...@@ -735,7 +735,7 @@ pub const Loop = struct {
735735
736 const Wrapper = struct {736 const Wrapper = struct {
737 const Args = @TypeOf(args);737 const Args = @TypeOf(args);
738 fn run(func_args: Args, loop: *Loop, allocator: *mem.Allocator) void {738 fn run(func_args: Args, loop: *Loop, allocator: mem.Allocator) void {
739 loop.beginOneEvent();739 loop.beginOneEvent();
740 loop.yield();740 loop.yield();
741 @call(.{}, func, func_args); // compile error when called with non-void ret type741 @call(.{}, func, func_args); // compile error when called with non-void ret type
lib/std/event/rwlock.zig+1-1
...@@ -226,7 +226,7 @@ test "std.event.RwLock" {...@@ -226,7 +226,7 @@ test "std.event.RwLock" {
226 const expected_result = [1]i32{shared_it_count * @intCast(i32, shared_test_data.len)} ** shared_test_data.len;226 const expected_result = [1]i32{shared_it_count * @intCast(i32, shared_test_data.len)} ** shared_test_data.len;
227 try testing.expectEqualSlices(i32, expected_result, shared_test_data);227 try testing.expectEqualSlices(i32, expected_result, shared_test_data);
228}228}
229fn testLock(allocator: *Allocator, lock: *RwLock) callconv(.Async) void {229fn testLock(allocator: Allocator, lock: *RwLock) callconv(.Async) void {
230 var read_nodes: [100]Loop.NextTickNode = undefined;230 var read_nodes: [100]Loop.NextTickNode = undefined;
231 for (read_nodes) |*read_node| {231 for (read_nodes) |*read_node| {
232 const frame = allocator.create(@Frame(readRunner)) catch @panic("memory");232 const frame = allocator.create(@Frame(readRunner)) catch @panic("memory");
lib/std/fifo.zig+2-2
...@@ -33,7 +33,7 @@ pub fn LinearFifo(...@@ -33,7 +33,7 @@ pub fn LinearFifo(
33 };33 };
3434
35 return struct {35 return struct {
36 allocator: if (buffer_type == .Dynamic) *Allocator else void,36 allocator: if (buffer_type == .Dynamic) Allocator else void,
37 buf: if (buffer_type == .Static) [buffer_type.Static]T else []T,37 buf: if (buffer_type == .Static) [buffer_type.Static]T else []T,
38 head: usize,38 head: usize,
39 count: usize,39 count: usize,
...@@ -69,7 +69,7 @@ pub fn LinearFifo(...@@ -69,7 +69,7 @@ pub fn LinearFifo(
69 }69 }
70 },70 },
71 .Dynamic => struct {71 .Dynamic => struct {
72 pub fn init(allocator: *Allocator) Self {72 pub fn init(allocator: Allocator) Self {
73 return .{73 return .{
74 .allocator = allocator,74 .allocator = allocator,
75 .buf = &[_]T{},75 .buf = &[_]T{},
lib/std/fmt.zig+2-2
...@@ -1803,7 +1803,7 @@ pub fn count(comptime fmt: []const u8, args: anytype) u64 {...@@ -1803,7 +1803,7 @@ pub fn count(comptime fmt: []const u8, args: anytype) u64 {
18031803
1804pub const AllocPrintError = error{OutOfMemory};1804pub const AllocPrintError = error{OutOfMemory};
18051805
1806pub fn allocPrint(allocator: *mem.Allocator, comptime fmt: []const u8, args: anytype) AllocPrintError![]u8 {1806pub fn allocPrint(allocator: mem.Allocator, comptime fmt: []const u8, args: anytype) AllocPrintError![]u8 {
1807 const size = math.cast(usize, count(fmt, args)) catch |err| switch (err) {1807 const size = math.cast(usize, count(fmt, args)) catch |err| switch (err) {
1808 // Output too long. Can't possibly allocate enough memory to display it.1808 // Output too long. Can't possibly allocate enough memory to display it.
1809 error.Overflow => return error.OutOfMemory,1809 error.Overflow => return error.OutOfMemory,
...@@ -1816,7 +1816,7 @@ pub fn allocPrint(allocator: *mem.Allocator, comptime fmt: []const u8, args: any...@@ -1816,7 +1816,7 @@ pub fn allocPrint(allocator: *mem.Allocator, comptime fmt: []const u8, args: any
18161816
1817pub const allocPrint0 = @compileError("deprecated; use allocPrintZ");1817pub const allocPrint0 = @compileError("deprecated; use allocPrintZ");
18181818
1819pub fn allocPrintZ(allocator: *mem.Allocator, comptime fmt: []const u8, args: anytype) AllocPrintError![:0]u8 {1819pub fn allocPrintZ(allocator: mem.Allocator, comptime fmt: []const u8, args: anytype) AllocPrintError![:0]u8 {
1820 const result = try allocPrint(allocator, fmt ++ "\x00", args);1820 const result = try allocPrint(allocator, fmt ++ "\x00", args);
1821 return result[0 .. result.len - 1 :0];1821 return result[0 .. result.len - 1 :0];
1822}1822}
lib/std/fs.zig+8-8
...@@ -64,7 +64,7 @@ pub const need_async_thread = std.io.is_async and switch (builtin.os.tag) {...@@ -64,7 +64,7 @@ pub const need_async_thread = std.io.is_async and switch (builtin.os.tag) {
64};64};
6565
66/// TODO remove the allocator requirement from this API66/// TODO remove the allocator requirement from this API
67pub fn atomicSymLink(allocator: *Allocator, existing_path: []const u8, new_path: []const u8) !void {67pub fn atomicSymLink(allocator: Allocator, existing_path: []const u8, new_path: []const u8) !void {
68 if (cwd().symLink(existing_path, new_path, .{})) {68 if (cwd().symLink(existing_path, new_path, .{})) {
69 return;69 return;
70 } else |err| switch (err) {70 } else |err| switch (err) {
...@@ -875,7 +875,7 @@ pub const Dir = struct {...@@ -875,7 +875,7 @@ pub const Dir = struct {
875 /// Must call `Walker.deinit` when done.875 /// Must call `Walker.deinit` when done.
876 /// The order of returned file system entries is undefined.876 /// The order of returned file system entries is undefined.
877 /// `self` will not be closed after walking it.877 /// `self` will not be closed after walking it.
878 pub fn walk(self: Dir, allocator: *Allocator) !Walker {878 pub fn walk(self: Dir, allocator: Allocator) !Walker {
879 var name_buffer = std.ArrayList(u8).init(allocator);879 var name_buffer = std.ArrayList(u8).init(allocator);
880 errdefer name_buffer.deinit();880 errdefer name_buffer.deinit();
881881
...@@ -1393,7 +1393,7 @@ pub const Dir = struct {...@@ -1393,7 +1393,7 @@ pub const Dir = struct {
13931393
1394 /// Same as `Dir.realpath` except caller must free the returned memory.1394 /// Same as `Dir.realpath` except caller must free the returned memory.
1395 /// See also `Dir.realpath`.1395 /// See also `Dir.realpath`.
1396 pub fn realpathAlloc(self: Dir, allocator: *Allocator, pathname: []const u8) ![]u8 {1396 pub fn realpathAlloc(self: Dir, allocator: Allocator, pathname: []const u8) ![]u8 {
1397 // Use of MAX_PATH_BYTES here is valid as the realpath function does not1397 // Use of MAX_PATH_BYTES here is valid as the realpath function does not
1398 // have a variant that takes an arbitrary-size buffer.1398 // have a variant that takes an arbitrary-size buffer.
1399 // TODO(#4812): Consider reimplementing realpath or using the POSIX.1-20081399 // TODO(#4812): Consider reimplementing realpath or using the POSIX.1-2008
...@@ -1804,7 +1804,7 @@ pub const Dir = struct {...@@ -1804,7 +1804,7 @@ pub const Dir = struct {
18041804
1805 /// On success, caller owns returned buffer.1805 /// On success, caller owns returned buffer.
1806 /// If the file is larger than `max_bytes`, returns `error.FileTooBig`.1806 /// If the file is larger than `max_bytes`, returns `error.FileTooBig`.
1807 pub fn readFileAlloc(self: Dir, allocator: *mem.Allocator, file_path: []const u8, max_bytes: usize) ![]u8 {1807 pub fn readFileAlloc(self: Dir, allocator: mem.Allocator, file_path: []const u8, max_bytes: usize) ![]u8 {
1808 return self.readFileAllocOptions(allocator, file_path, max_bytes, null, @alignOf(u8), null);1808 return self.readFileAllocOptions(allocator, file_path, max_bytes, null, @alignOf(u8), null);
1809 }1809 }
18101810
...@@ -1815,7 +1815,7 @@ pub const Dir = struct {...@@ -1815,7 +1815,7 @@ pub const Dir = struct {
1815 /// Allows specifying alignment and a sentinel value.1815 /// Allows specifying alignment and a sentinel value.
1816 pub fn readFileAllocOptions(1816 pub fn readFileAllocOptions(
1817 self: Dir,1817 self: Dir,
1818 allocator: *mem.Allocator,1818 allocator: mem.Allocator,
1819 file_path: []const u8,1819 file_path: []const u8,
1820 max_bytes: usize,1820 max_bytes: usize,
1821 size_hint: ?usize,1821 size_hint: ?usize,
...@@ -2464,7 +2464,7 @@ pub const SelfExePathError = os.ReadLinkError || os.SysCtlError || os.RealPathEr...@@ -2464,7 +2464,7 @@ pub const SelfExePathError = os.ReadLinkError || os.SysCtlError || os.RealPathEr
24642464
2465/// `selfExePath` except allocates the result on the heap.2465/// `selfExePath` except allocates the result on the heap.
2466/// Caller owns returned memory.2466/// Caller owns returned memory.
2467pub fn selfExePathAlloc(allocator: *Allocator) ![]u8 {2467pub fn selfExePathAlloc(allocator: Allocator) ![]u8 {
2468 // Use of MAX_PATH_BYTES here is justified as, at least on one tested Linux2468 // Use of MAX_PATH_BYTES here is justified as, at least on one tested Linux
2469 // system, readlink will completely fail to return a result larger than2469 // system, readlink will completely fail to return a result larger than
2470 // PATH_MAX even if given a sufficiently large buffer. This makes it2470 // PATH_MAX even if given a sufficiently large buffer. This makes it
...@@ -2573,7 +2573,7 @@ pub fn selfExePathW() [:0]const u16 {...@@ -2573,7 +2573,7 @@ pub fn selfExePathW() [:0]const u16 {
25732573
2574/// `selfExeDirPath` except allocates the result on the heap.2574/// `selfExeDirPath` except allocates the result on the heap.
2575/// Caller owns returned memory.2575/// Caller owns returned memory.
2576pub fn selfExeDirPathAlloc(allocator: *Allocator) ![]u8 {2576pub fn selfExeDirPathAlloc(allocator: Allocator) ![]u8 {
2577 // Use of MAX_PATH_BYTES here is justified as, at least on one tested Linux2577 // Use of MAX_PATH_BYTES here is justified as, at least on one tested Linux
2578 // system, readlink will completely fail to return a result larger than2578 // system, readlink will completely fail to return a result larger than
2579 // PATH_MAX even if given a sufficiently large buffer. This makes it2579 // PATH_MAX even if given a sufficiently large buffer. This makes it
...@@ -2596,7 +2596,7 @@ pub fn selfExeDirPath(out_buffer: []u8) SelfExePathError![]const u8 {...@@ -2596,7 +2596,7 @@ pub fn selfExeDirPath(out_buffer: []u8) SelfExePathError![]const u8 {
25962596
2597/// `realpath`, except caller must free the returned memory.2597/// `realpath`, except caller must free the returned memory.
2598/// See also `Dir.realpath`.2598/// See also `Dir.realpath`.
2599pub fn realpathAlloc(allocator: *Allocator, pathname: []const u8) ![]u8 {2599pub fn realpathAlloc(allocator: Allocator, pathname: []const u8) ![]u8 {
2600 // Use of MAX_PATH_BYTES here is valid as the realpath function does not2600 // Use of MAX_PATH_BYTES here is valid as the realpath function does not
2601 // have a variant that takes an arbitrary-size buffer.2601 // have a variant that takes an arbitrary-size buffer.
2602 // TODO(#4812): Consider reimplementing realpath or using the POSIX.1-20082602 // TODO(#4812): Consider reimplementing realpath or using the POSIX.1-2008
lib/std/fs/file.zig+2-2
...@@ -420,7 +420,7 @@ pub const File = struct {...@@ -420,7 +420,7 @@ pub const File = struct {
420 /// Reads all the bytes from the current position to the end of the file.420 /// Reads all the bytes from the current position to the end of the file.
421 /// On success, caller owns returned buffer.421 /// On success, caller owns returned buffer.
422 /// If the file is larger than `max_bytes`, returns `error.FileTooBig`.422 /// If the file is larger than `max_bytes`, returns `error.FileTooBig`.
423 pub fn readToEndAlloc(self: File, allocator: *mem.Allocator, max_bytes: usize) ![]u8 {423 pub fn readToEndAlloc(self: File, allocator: mem.Allocator, max_bytes: usize) ![]u8 {
424 return self.readToEndAllocOptions(allocator, max_bytes, null, @alignOf(u8), null);424 return self.readToEndAllocOptions(allocator, max_bytes, null, @alignOf(u8), null);
425 }425 }
426426
...@@ -432,7 +432,7 @@ pub const File = struct {...@@ -432,7 +432,7 @@ pub const File = struct {
432 /// Allows specifying alignment and a sentinel value.432 /// Allows specifying alignment and a sentinel value.
433 pub fn readToEndAllocOptions(433 pub fn readToEndAllocOptions(
434 self: File,434 self: File,
435 allocator: *mem.Allocator,435 allocator: mem.Allocator,
436 max_bytes: usize,436 max_bytes: usize,
437 size_hint: ?usize,437 size_hint: ?usize,
438 comptime alignment: u29,438 comptime alignment: u29,
lib/std/fs/get_app_data_dir.zig+1-1
...@@ -12,7 +12,7 @@ pub const GetAppDataDirError = error{...@@ -12,7 +12,7 @@ pub const GetAppDataDirError = error{
1212
13/// Caller owns returned memory.13/// Caller owns returned memory.
14/// TODO determine if we can remove the allocator requirement14/// TODO determine if we can remove the allocator requirement
15pub fn getAppDataDir(allocator: *mem.Allocator, appname: []const u8) GetAppDataDirError![]u8 {15pub fn getAppDataDir(allocator: mem.Allocator, appname: []const u8) GetAppDataDirError![]u8 {
16 switch (builtin.os.tag) {16 switch (builtin.os.tag) {
17 .windows => {17 .windows => {
18 var dir_path_ptr: [*:0]u16 = undefined;18 var dir_path_ptr: [*:0]u16 = undefined;
lib/std/fs/path.zig+9-9
...@@ -35,7 +35,7 @@ pub fn isSep(byte: u8) bool {...@@ -35,7 +35,7 @@ pub fn isSep(byte: u8) bool {
3535
36/// This is different from mem.join in that the separator will not be repeated if36/// This is different from mem.join in that the separator will not be repeated if
37/// it is found at the end or beginning of a pair of consecutive paths.37/// it is found at the end or beginning of a pair of consecutive paths.
38fn joinSepMaybeZ(allocator: *Allocator, separator: u8, sepPredicate: fn (u8) bool, paths: []const []const u8, zero: bool) ![]u8 {38fn joinSepMaybeZ(allocator: Allocator, separator: u8, sepPredicate: fn (u8) bool, paths: []const []const u8, zero: bool) ![]u8 {
39 if (paths.len == 0) return if (zero) try allocator.dupe(u8, &[1]u8{0}) else &[0]u8{};39 if (paths.len == 0) return if (zero) try allocator.dupe(u8, &[1]u8{0}) else &[0]u8{};
4040
41 // Find first non-empty path index.41 // Find first non-empty path index.
...@@ -99,13 +99,13 @@ fn joinSepMaybeZ(allocator: *Allocator, separator: u8, sepPredicate: fn (u8) boo...@@ -99,13 +99,13 @@ fn joinSepMaybeZ(allocator: *Allocator, separator: u8, sepPredicate: fn (u8) boo
9999
100/// Naively combines a series of paths with the native path seperator.100/// Naively combines a series of paths with the native path seperator.
101/// Allocates memory for the result, which must be freed by the caller.101/// Allocates memory for the result, which must be freed by the caller.
102pub fn join(allocator: *Allocator, paths: []const []const u8) ![]u8 {102pub fn join(allocator: Allocator, paths: []const []const u8) ![]u8 {
103 return joinSepMaybeZ(allocator, sep, isSep, paths, false);103 return joinSepMaybeZ(allocator, sep, isSep, paths, false);
104}104}
105105
106/// Naively combines a series of paths with the native path seperator and null terminator.106/// Naively combines a series of paths with the native path seperator and null terminator.
107/// Allocates memory for the result, which must be freed by the caller.107/// Allocates memory for the result, which must be freed by the caller.
108pub fn joinZ(allocator: *Allocator, paths: []const []const u8) ![:0]u8 {108pub fn joinZ(allocator: Allocator, paths: []const []const u8) ![:0]u8 {
109 const out = try joinSepMaybeZ(allocator, sep, isSep, paths, true);109 const out = try joinSepMaybeZ(allocator, sep, isSep, paths, true);
110 return out[0 .. out.len - 1 :0];110 return out[0 .. out.len - 1 :0];
111}111}
...@@ -445,7 +445,7 @@ fn asciiEqlIgnoreCase(s1: []const u8, s2: []const u8) bool {...@@ -445,7 +445,7 @@ fn asciiEqlIgnoreCase(s1: []const u8, s2: []const u8) bool {
445}445}
446446
447/// On Windows, this calls `resolveWindows` and on POSIX it calls `resolvePosix`.447/// On Windows, this calls `resolveWindows` and on POSIX it calls `resolvePosix`.
448pub fn resolve(allocator: *Allocator, paths: []const []const u8) ![]u8 {448pub fn resolve(allocator: Allocator, paths: []const []const u8) ![]u8 {
449 if (native_os == .windows) {449 if (native_os == .windows) {
450 return resolveWindows(allocator, paths);450 return resolveWindows(allocator, paths);
451 } else {451 } else {
...@@ -461,7 +461,7 @@ pub fn resolve(allocator: *Allocator, paths: []const []const u8) ![]u8 {...@@ -461,7 +461,7 @@ pub fn resolve(allocator: *Allocator, paths: []const []const u8) ![]u8 {
461/// Path separators are canonicalized to '\\' and drives are canonicalized to capital letters.461/// Path separators are canonicalized to '\\' and drives are canonicalized to capital letters.
462/// Note: all usage of this function should be audited due to the existence of symlinks.462/// Note: all usage of this function should be audited due to the existence of symlinks.
463/// Without performing actual syscalls, resolving `..` could be incorrect.463/// Without performing actual syscalls, resolving `..` could be incorrect.
464pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {464pub fn resolveWindows(allocator: Allocator, paths: []const []const u8) ![]u8 {
465 if (paths.len == 0) {465 if (paths.len == 0) {
466 assert(native_os == .windows); // resolveWindows called on non windows can't use getCwd466 assert(native_os == .windows); // resolveWindows called on non windows can't use getCwd
467 return process.getCwdAlloc(allocator);467 return process.getCwdAlloc(allocator);
...@@ -647,7 +647,7 @@ pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {...@@ -647,7 +647,7 @@ pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {
647/// If all paths are relative it uses the current working directory as a starting point.647/// If all paths are relative it uses the current working directory as a starting point.
648/// Note: all usage of this function should be audited due to the existence of symlinks.648/// Note: all usage of this function should be audited due to the existence of symlinks.
649/// Without performing actual syscalls, resolving `..` could be incorrect.649/// Without performing actual syscalls, resolving `..` could be incorrect.
650pub fn resolvePosix(allocator: *Allocator, paths: []const []const u8) ![]u8 {650pub fn resolvePosix(allocator: Allocator, paths: []const []const u8) ![]u8 {
651 if (paths.len == 0) {651 if (paths.len == 0) {
652 assert(native_os != .windows); // resolvePosix called on windows can't use getCwd652 assert(native_os != .windows); // resolvePosix called on windows can't use getCwd
653 return process.getCwdAlloc(allocator);653 return process.getCwdAlloc(allocator);
...@@ -1058,7 +1058,7 @@ fn testBasenameWindows(input: []const u8, expected_output: []const u8) !void {...@@ -1058,7 +1058,7 @@ fn testBasenameWindows(input: []const u8, expected_output: []const u8) !void {
1058/// resolve to the same path (after calling `resolve` on each), a zero-length1058/// resolve to the same path (after calling `resolve` on each), a zero-length
1059/// string is returned.1059/// string is returned.
1060/// On Windows this canonicalizes the drive to a capital letter and paths to `\\`.1060/// On Windows this canonicalizes the drive to a capital letter and paths to `\\`.
1061pub fn relative(allocator: *Allocator, from: []const u8, to: []const u8) ![]u8 {1061pub fn relative(allocator: Allocator, from: []const u8, to: []const u8) ![]u8 {
1062 if (native_os == .windows) {1062 if (native_os == .windows) {
1063 return relativeWindows(allocator, from, to);1063 return relativeWindows(allocator, from, to);
1064 } else {1064 } else {
...@@ -1066,7 +1066,7 @@ pub fn relative(allocator: *Allocator, from: []const u8, to: []const u8) ![]u8 {...@@ -1066,7 +1066,7 @@ pub fn relative(allocator: *Allocator, from: []const u8, to: []const u8) ![]u8 {
1066 }1066 }
1067}1067}
10681068
1069pub fn relativeWindows(allocator: *Allocator, from: []const u8, to: []const u8) ![]u8 {1069pub fn relativeWindows(allocator: Allocator, from: []const u8, to: []const u8) ![]u8 {
1070 const resolved_from = try resolveWindows(allocator, &[_][]const u8{from});1070 const resolved_from = try resolveWindows(allocator, &[_][]const u8{from});
1071 defer allocator.free(resolved_from);1071 defer allocator.free(resolved_from);
10721072
...@@ -1139,7 +1139,7 @@ pub fn relativeWindows(allocator: *Allocator, from: []const u8, to: []const u8)...@@ -1139,7 +1139,7 @@ pub fn relativeWindows(allocator: *Allocator, from: []const u8, to: []const u8)
1139 return [_]u8{};1139 return [_]u8{};
1140}1140}
11411141
1142pub fn relativePosix(allocator: *Allocator, from: []const u8, to: []const u8) ![]u8 {1142pub fn relativePosix(allocator: Allocator, from: []const u8, to: []const u8) ![]u8 {
1143 const resolved_from = try resolvePosix(allocator, &[_][]const u8{from});1143 const resolved_from = try resolvePosix(allocator, &[_][]const u8{from});
1144 defer allocator.free(resolved_from);1144 defer allocator.free(resolved_from);
11451145
lib/std/fs/test.zig+28-22
...@@ -52,9 +52,11 @@ test "accessAbsolute" {...@@ -52,9 +52,11 @@ test "accessAbsolute" {
5252
53 var arena = ArenaAllocator.init(testing.allocator);53 var arena = ArenaAllocator.init(testing.allocator);
54 defer arena.deinit();54 defer arena.deinit();
55 const allocator = arena.allocator();
56
55 const base_path = blk: {57 const base_path = blk: {
56 const relative_path = try fs.path.join(&arena.allocator, &[_][]const u8{ "zig-cache", "tmp", tmp.sub_path[0..] });58 const relative_path = try fs.path.join(allocator, &[_][]const u8{ "zig-cache", "tmp", tmp.sub_path[0..] });
57 break :blk try fs.realpathAlloc(&arena.allocator, relative_path);59 break :blk try fs.realpathAlloc(allocator, relative_path);
58 };60 };
5961
60 try fs.accessAbsolute(base_path, .{});62 try fs.accessAbsolute(base_path, .{});
...@@ -69,9 +71,11 @@ test "openDirAbsolute" {...@@ -69,9 +71,11 @@ test "openDirAbsolute" {
69 try tmp.dir.makeDir("subdir");71 try tmp.dir.makeDir("subdir");
70 var arena = ArenaAllocator.init(testing.allocator);72 var arena = ArenaAllocator.init(testing.allocator);
71 defer arena.deinit();73 defer arena.deinit();
74 const allocator = arena.allocator();
75
72 const base_path = blk: {76 const base_path = blk: {
73 const relative_path = try fs.path.join(&arena.allocator, &[_][]const u8{ "zig-cache", "tmp", tmp.sub_path[0..], "subdir" });77 const relative_path = try fs.path.join(allocator, &[_][]const u8{ "zig-cache", "tmp", tmp.sub_path[0..], "subdir" });
74 break :blk try fs.realpathAlloc(&arena.allocator, relative_path);78 break :blk try fs.realpathAlloc(allocator, relative_path);
75 };79 };
7680
77 {81 {
...@@ -80,8 +84,8 @@ test "openDirAbsolute" {...@@ -80,8 +84,8 @@ test "openDirAbsolute" {
80 }84 }
8185
82 for ([_][]const u8{ ".", ".." }) |sub_path| {86 for ([_][]const u8{ ".", ".." }) |sub_path| {
83 const dir_path = try fs.path.join(&arena.allocator, &[_][]const u8{ base_path, sub_path });87 const dir_path = try fs.path.join(allocator, &[_][]const u8{ base_path, sub_path });
84 defer arena.allocator.free(dir_path);88 defer allocator.free(dir_path);
85 var dir = try fs.openDirAbsolute(dir_path, .{});89 var dir = try fs.openDirAbsolute(dir_path, .{});
86 defer dir.close();90 defer dir.close();
87 }91 }
...@@ -107,12 +111,12 @@ test "readLinkAbsolute" {...@@ -107,12 +111,12 @@ test "readLinkAbsolute" {
107 // Get base abs path111 // Get base abs path
108 var arena = ArenaAllocator.init(testing.allocator);112 var arena = ArenaAllocator.init(testing.allocator);
109 defer arena.deinit();113 defer arena.deinit();
114 const allocator = arena.allocator();
110115
111 const base_path = blk: {116 const base_path = blk: {
112 const relative_path = try fs.path.join(&arena.allocator, &[_][]const u8{ "zig-cache", "tmp", tmp.sub_path[0..] });117 const relative_path = try fs.path.join(allocator, &[_][]const u8{ "zig-cache", "tmp", tmp.sub_path[0..] });
113 break :blk try fs.realpathAlloc(&arena.allocator, relative_path);118 break :blk try fs.realpathAlloc(allocator, relative_path);
114 };119 };
115 const allocator = &arena.allocator;
116120
117 {121 {
118 const target_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "file.txt" });122 const target_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "file.txt" });
...@@ -158,15 +162,16 @@ test "Dir.Iterator" {...@@ -158,15 +162,16 @@ test "Dir.Iterator" {
158162
159 var arena = ArenaAllocator.init(testing.allocator);163 var arena = ArenaAllocator.init(testing.allocator);
160 defer arena.deinit();164 defer arena.deinit();
165 const allocator = arena.allocator();
161166
162 var entries = std.ArrayList(Dir.Entry).init(&arena.allocator);167 var entries = std.ArrayList(Dir.Entry).init(allocator);
163168
164 // Create iterator.169 // Create iterator.
165 var iter = tmp_dir.dir.iterate();170 var iter = tmp_dir.dir.iterate();
166 while (try iter.next()) |entry| {171 while (try iter.next()) |entry| {
167 // We cannot just store `entry` as on Windows, we're re-using the name buffer172 // We cannot just store `entry` as on Windows, we're re-using the name buffer
168 // which means we'll actually share the `name` pointer between entries!173 // which means we'll actually share the `name` pointer between entries!
169 const name = try arena.allocator.dupe(u8, entry.name);174 const name = try allocator.dupe(u8, entry.name);
170 try entries.append(Dir.Entry{ .name = name, .kind = entry.kind });175 try entries.append(Dir.Entry{ .name = name, .kind = entry.kind });
171 }176 }
172177
...@@ -202,25 +207,26 @@ test "Dir.realpath smoke test" {...@@ -202,25 +207,26 @@ test "Dir.realpath smoke test" {
202207
203 var arena = ArenaAllocator.init(testing.allocator);208 var arena = ArenaAllocator.init(testing.allocator);
204 defer arena.deinit();209 defer arena.deinit();
210 const allocator = arena.allocator();
205211
206 const base_path = blk: {212 const base_path = blk: {
207 const relative_path = try fs.path.join(&arena.allocator, &[_][]const u8{ "zig-cache", "tmp", tmp_dir.sub_path[0..] });213 const relative_path = try fs.path.join(allocator, &[_][]const u8{ "zig-cache", "tmp", tmp_dir.sub_path[0..] });
208 break :blk try fs.realpathAlloc(&arena.allocator, relative_path);214 break :blk try fs.realpathAlloc(allocator, relative_path);
209 };215 };
210216
211 // First, test non-alloc version217 // First, test non-alloc version
212 {218 {
213 var buf1: [fs.MAX_PATH_BYTES]u8 = undefined;219 var buf1: [fs.MAX_PATH_BYTES]u8 = undefined;
214 const file_path = try tmp_dir.dir.realpath("test_file", buf1[0..]);220 const file_path = try tmp_dir.dir.realpath("test_file", buf1[0..]);
215 const expected_path = try fs.path.join(&arena.allocator, &[_][]const u8{ base_path, "test_file" });221 const expected_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "test_file" });
216222
217 try testing.expect(mem.eql(u8, file_path, expected_path));223 try testing.expect(mem.eql(u8, file_path, expected_path));
218 }224 }
219225
220 // Next, test alloc version226 // Next, test alloc version
221 {227 {
222 const file_path = try tmp_dir.dir.realpathAlloc(&arena.allocator, "test_file");228 const file_path = try tmp_dir.dir.realpathAlloc(allocator, "test_file");
223 const expected_path = try fs.path.join(&arena.allocator, &[_][]const u8{ base_path, "test_file" });229 const expected_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "test_file" });
224230
225 try testing.expect(mem.eql(u8, file_path, expected_path));231 try testing.expect(mem.eql(u8, file_path, expected_path));
226 }232 }
...@@ -476,11 +482,11 @@ test "renameAbsolute" {...@@ -476,11 +482,11 @@ test "renameAbsolute" {
476 // Get base abs path482 // Get base abs path
477 var arena = ArenaAllocator.init(testing.allocator);483 var arena = ArenaAllocator.init(testing.allocator);
478 defer arena.deinit();484 defer arena.deinit();
479 const allocator = &arena.allocator;485 const allocator = arena.allocator();
480486
481 const base_path = blk: {487 const base_path = blk: {
482 const relative_path = try fs.path.join(&arena.allocator, &[_][]const u8{ "zig-cache", "tmp", tmp_dir.sub_path[0..] });488 const relative_path = try fs.path.join(allocator, &[_][]const u8{ "zig-cache", "tmp", tmp_dir.sub_path[0..] });
483 break :blk try fs.realpathAlloc(&arena.allocator, relative_path);489 break :blk try fs.realpathAlloc(allocator, relative_path);
484 };490 };
485491
486 try testing.expectError(error.FileNotFound, fs.renameAbsolute(492 try testing.expectError(error.FileNotFound, fs.renameAbsolute(
...@@ -987,11 +993,11 @@ test ". and .. in absolute functions" {...@@ -987,11 +993,11 @@ test ". and .. in absolute functions" {
987993
988 var arena = ArenaAllocator.init(testing.allocator);994 var arena = ArenaAllocator.init(testing.allocator);
989 defer arena.deinit();995 defer arena.deinit();
990 const allocator = &arena.allocator;996 const allocator = arena.allocator();
991997
992 const base_path = blk: {998 const base_path = blk: {
993 const relative_path = try fs.path.join(&arena.allocator, &[_][]const u8{ "zig-cache", "tmp", tmp.sub_path[0..] });999 const relative_path = try fs.path.join(allocator, &[_][]const u8{ "zig-cache", "tmp", tmp.sub_path[0..] });
994 break :blk try fs.realpathAlloc(&arena.allocator, relative_path);1000 break :blk try fs.realpathAlloc(allocator, relative_path);
995 };1001 };
9961002
997 const subdir_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "./subdir" });1003 const subdir_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "./subdir" });
lib/std/fs/wasi.zig+1-1
...@@ -80,7 +80,7 @@ pub const PreopenList = struct {...@@ -80,7 +80,7 @@ pub const PreopenList = struct {
80 pub const Error = error{ OutOfMemory, Overflow } || os.UnexpectedError;80 pub const Error = error{ OutOfMemory, Overflow } || os.UnexpectedError;
8181
82 /// Deinitialize with `deinit`.82 /// Deinitialize with `deinit`.
83 pub fn init(allocator: *Allocator) Self {83 pub fn init(allocator: Allocator) Self {
84 return Self{ .buffer = InnerList.init(allocator) };84 return Self{ .buffer = InnerList.init(allocator) };
85 }85 }
8686
lib/std/fs/watch.zig+3-3
...@@ -30,7 +30,7 @@ pub fn Watch(comptime V: type) type {...@@ -30,7 +30,7 @@ pub fn Watch(comptime V: type) type {
30 return struct {30 return struct {
31 channel: event.Channel(Event.Error!Event),31 channel: event.Channel(Event.Error!Event),
32 os_data: OsData,32 os_data: OsData,
33 allocator: *Allocator,33 allocator: Allocator,
3434
35 const OsData = switch (builtin.os.tag) {35 const OsData = switch (builtin.os.tag) {
36 // TODO https://github.com/ziglang/zig/issues/377836 // TODO https://github.com/ziglang/zig/issues/3778
...@@ -96,7 +96,7 @@ pub fn Watch(comptime V: type) type {...@@ -96,7 +96,7 @@ pub fn Watch(comptime V: type) type {
96 pub const Error = WatchEventError;96 pub const Error = WatchEventError;
97 };97 };
9898
99 pub fn init(allocator: *Allocator, event_buf_count: usize) !*Self {99 pub fn init(allocator: Allocator, event_buf_count: usize) !*Self {
100 const self = try allocator.create(Self);100 const self = try allocator.create(Self);
101 errdefer allocator.destroy(self);101 errdefer allocator.destroy(self);
102102
...@@ -648,7 +648,7 @@ test "write a file, watch it, write it again, delete it" {...@@ -648,7 +648,7 @@ test "write a file, watch it, write it again, delete it" {
648 return testWriteWatchWriteDelete(std.testing.allocator);648 return testWriteWatchWriteDelete(std.testing.allocator);
649}649}
650650
651fn testWriteWatchWriteDelete(allocator: *Allocator) !void {651fn testWriteWatchWriteDelete(allocator: Allocator) !void {
652 const file_path = try std.fs.path.join(allocator, &[_][]const u8{ test_tmp_dir, "file.txt" });652 const file_path = try std.fs.path.join(allocator, &[_][]const u8{ test_tmp_dir, "file.txt" });
653 defer allocator.free(file_path);653 defer allocator.free(file_path);
654654
lib/std/hash/auto_hash.zig+1-1
...@@ -309,7 +309,7 @@ test "hash struct deep" {...@@ -309,7 +309,7 @@ test "hash struct deep" {
309309
310 const Self = @This();310 const Self = @This();
311311
312 pub fn init(allocator: *mem.Allocator, a_: u32, b_: u16, c_: bool) !Self {312 pub fn init(allocator: mem.Allocator, a_: u32, b_: u16, c_: bool) !Self {
313 const ptr = try allocator.create(bool);313 const ptr = try allocator.create(bool);
314 ptr.* = c_;314 ptr.* = c_;
315 return Self{ .a = a_, .b = b_, .c = ptr };315 return Self{ .a = a_, .b = b_, .c = ptr };
lib/std/hash/benchmark.zig+1-1
...@@ -165,7 +165,7 @@ pub fn main() !void {...@@ -165,7 +165,7 @@ pub fn main() !void {
165165
166 var buffer: [1024]u8 = undefined;166 var buffer: [1024]u8 = undefined;
167 var fixed = std.heap.FixedBufferAllocator.init(buffer[0..]);167 var fixed = std.heap.FixedBufferAllocator.init(buffer[0..]);
168 const args = try std.process.argsAlloc(&fixed.allocator);168 const args = try std.process.argsAlloc(fixed.allocator());
169169
170 var filter: ?[]u8 = "";170 var filter: ?[]u8 = "";
171 var count: usize = mode(128 * MiB);171 var count: usize = mode(128 * MiB);
lib/std/hash_map.zig+31-31
...@@ -363,7 +363,7 @@ pub fn HashMap(...@@ -363,7 +363,7 @@ pub fn HashMap(
363 comptime verifyContext(Context, K, K, u64);363 comptime verifyContext(Context, K, K, u64);
364 return struct {364 return struct {
365 unmanaged: Unmanaged,365 unmanaged: Unmanaged,
366 allocator: *Allocator,366 allocator: Allocator,
367 ctx: Context,367 ctx: Context,
368368
369 /// The type of the unmanaged hash map underlying this wrapper369 /// The type of the unmanaged hash map underlying this wrapper
...@@ -390,7 +390,7 @@ pub fn HashMap(...@@ -390,7 +390,7 @@ pub fn HashMap(
390 /// Create a managed hash map with an empty context.390 /// Create a managed hash map with an empty context.
391 /// If the context is not zero-sized, you must use391 /// If the context is not zero-sized, you must use
392 /// initContext(allocator, ctx) instead.392 /// initContext(allocator, ctx) instead.
393 pub fn init(allocator: *Allocator) Self {393 pub fn init(allocator: Allocator) Self {
394 if (@sizeOf(Context) != 0) {394 if (@sizeOf(Context) != 0) {
395 @compileError("Context must be specified! Call initContext(allocator, ctx) instead.");395 @compileError("Context must be specified! Call initContext(allocator, ctx) instead.");
396 }396 }
...@@ -402,7 +402,7 @@ pub fn HashMap(...@@ -402,7 +402,7 @@ pub fn HashMap(
402 }402 }
403403
404 /// Create a managed hash map with a context404 /// Create a managed hash map with a context
405 pub fn initContext(allocator: *Allocator, ctx: Context) Self {405 pub fn initContext(allocator: Allocator, ctx: Context) Self {
406 return .{406 return .{
407 .unmanaged = .{},407 .unmanaged = .{},
408 .allocator = allocator,408 .allocator = allocator,
...@@ -636,7 +636,7 @@ pub fn HashMap(...@@ -636,7 +636,7 @@ pub fn HashMap(
636 }636 }
637637
638 /// Creates a copy of this map, using a specified allocator638 /// Creates a copy of this map, using a specified allocator
639 pub fn cloneWithAllocator(self: Self, new_allocator: *Allocator) !Self {639 pub fn cloneWithAllocator(self: Self, new_allocator: Allocator) !Self {
640 var other = try self.unmanaged.cloneContext(new_allocator, self.ctx);640 var other = try self.unmanaged.cloneContext(new_allocator, self.ctx);
641 return other.promoteContext(new_allocator, self.ctx);641 return other.promoteContext(new_allocator, self.ctx);
642 }642 }
...@@ -650,7 +650,7 @@ pub fn HashMap(...@@ -650,7 +650,7 @@ pub fn HashMap(
650 /// Creates a copy of this map, using a specified allocator and context.650 /// Creates a copy of this map, using a specified allocator and context.
651 pub fn cloneWithAllocatorAndContext(651 pub fn cloneWithAllocatorAndContext(
652 self: Self,652 self: Self,
653 new_allocator: *Allocator,653 new_allocator: Allocator,
654 new_ctx: anytype,654 new_ctx: anytype,
655 ) !HashMap(K, V, @TypeOf(new_ctx), max_load_percentage) {655 ) !HashMap(K, V, @TypeOf(new_ctx), max_load_percentage) {
656 var other = try self.unmanaged.cloneContext(new_allocator, new_ctx);656 var other = try self.unmanaged.cloneContext(new_allocator, new_ctx);
...@@ -841,13 +841,13 @@ pub fn HashMapUnmanaged(...@@ -841,13 +841,13 @@ pub fn HashMapUnmanaged(
841841
842 pub const Managed = HashMap(K, V, Context, max_load_percentage);842 pub const Managed = HashMap(K, V, Context, max_load_percentage);
843843
844 pub fn promote(self: Self, allocator: *Allocator) Managed {844 pub fn promote(self: Self, allocator: Allocator) Managed {
845 if (@sizeOf(Context) != 0)845 if (@sizeOf(Context) != 0)
846 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call promoteContext instead.");846 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call promoteContext instead.");
847 return promoteContext(self, allocator, undefined);847 return promoteContext(self, allocator, undefined);
848 }848 }
849849
850 pub fn promoteContext(self: Self, allocator: *Allocator, ctx: Context) Managed {850 pub fn promoteContext(self: Self, allocator: Allocator, ctx: Context) Managed {
851 return .{851 return .{
852 .unmanaged = self,852 .unmanaged = self,
853 .allocator = allocator,853 .allocator = allocator,
...@@ -859,7 +859,7 @@ pub fn HashMapUnmanaged(...@@ -859,7 +859,7 @@ pub fn HashMapUnmanaged(
859 return size * 100 < max_load_percentage * cap;859 return size * 100 < max_load_percentage * cap;
860 }860 }
861861
862 pub fn deinit(self: *Self, allocator: *Allocator) void {862 pub fn deinit(self: *Self, allocator: Allocator) void {
863 self.deallocate(allocator);863 self.deallocate(allocator);
864 self.* = undefined;864 self.* = undefined;
865 }865 }
...@@ -872,20 +872,20 @@ pub fn HashMapUnmanaged(...@@ -872,20 +872,20 @@ pub fn HashMapUnmanaged(
872872
873 pub const ensureCapacity = @compileError("deprecated; call `ensureUnusedCapacity` or `ensureTotalCapacity`");873 pub const ensureCapacity = @compileError("deprecated; call `ensureUnusedCapacity` or `ensureTotalCapacity`");
874874
875 pub fn ensureTotalCapacity(self: *Self, allocator: *Allocator, new_size: Size) !void {875 pub fn ensureTotalCapacity(self: *Self, allocator: Allocator, new_size: Size) !void {
876 if (@sizeOf(Context) != 0)876 if (@sizeOf(Context) != 0)
877 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call ensureTotalCapacityContext instead.");877 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call ensureTotalCapacityContext instead.");
878 return ensureTotalCapacityContext(self, allocator, new_size, undefined);878 return ensureTotalCapacityContext(self, allocator, new_size, undefined);
879 }879 }
880 pub fn ensureTotalCapacityContext(self: *Self, allocator: *Allocator, new_size: Size, ctx: Context) !void {880 pub fn ensureTotalCapacityContext(self: *Self, allocator: Allocator, new_size: Size, ctx: Context) !void {
881 if (new_size > self.size)881 if (new_size > self.size)
882 try self.growIfNeeded(allocator, new_size - self.size, ctx);882 try self.growIfNeeded(allocator, new_size - self.size, ctx);
883 }883 }
884884
885 pub fn ensureUnusedCapacity(self: *Self, allocator: *Allocator, additional_size: Size) !void {885 pub fn ensureUnusedCapacity(self: *Self, allocator: Allocator, additional_size: Size) !void {
886 return ensureUnusedCapacityContext(self, allocator, additional_size, undefined);886 return ensureUnusedCapacityContext(self, allocator, additional_size, undefined);
887 }887 }
888 pub fn ensureUnusedCapacityContext(self: *Self, allocator: *Allocator, additional_size: Size, ctx: Context) !void {888 pub fn ensureUnusedCapacityContext(self: *Self, allocator: Allocator, additional_size: Size, ctx: Context) !void {
889 return ensureTotalCapacityContext(self, allocator, self.count() + additional_size, ctx);889 return ensureTotalCapacityContext(self, allocator, self.count() + additional_size, ctx);
890 }890 }
891891
...@@ -897,7 +897,7 @@ pub fn HashMapUnmanaged(...@@ -897,7 +897,7 @@ pub fn HashMapUnmanaged(
897 }897 }
898 }898 }
899899
900 pub fn clearAndFree(self: *Self, allocator: *Allocator) void {900 pub fn clearAndFree(self: *Self, allocator: Allocator) void {
901 self.deallocate(allocator);901 self.deallocate(allocator);
902 self.size = 0;902 self.size = 0;
903 self.available = 0;903 self.available = 0;
...@@ -962,12 +962,12 @@ pub fn HashMapUnmanaged(...@@ -962,12 +962,12 @@ pub fn HashMapUnmanaged(
962 }962 }
963963
964 /// Insert an entry in the map. Assumes it is not already present.964 /// Insert an entry in the map. Assumes it is not already present.
965 pub fn putNoClobber(self: *Self, allocator: *Allocator, key: K, value: V) !void {965 pub fn putNoClobber(self: *Self, allocator: Allocator, key: K, value: V) !void {
966 if (@sizeOf(Context) != 0)966 if (@sizeOf(Context) != 0)
967 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call putNoClobberContext instead.");967 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call putNoClobberContext instead.");
968 return self.putNoClobberContext(allocator, key, value, undefined);968 return self.putNoClobberContext(allocator, key, value, undefined);
969 }969 }
970 pub fn putNoClobberContext(self: *Self, allocator: *Allocator, key: K, value: V, ctx: Context) !void {970 pub fn putNoClobberContext(self: *Self, allocator: Allocator, key: K, value: V, ctx: Context) !void {
971 assert(!self.containsContext(key, ctx));971 assert(!self.containsContext(key, ctx));
972 try self.growIfNeeded(allocator, 1, ctx);972 try self.growIfNeeded(allocator, 1, ctx);
973973
...@@ -1021,12 +1021,12 @@ pub fn HashMapUnmanaged(...@@ -1021,12 +1021,12 @@ pub fn HashMapUnmanaged(
1021 }1021 }
10221022
1023 /// Inserts a new `Entry` into the hash map, returning the previous one, if any.1023 /// Inserts a new `Entry` into the hash map, returning the previous one, if any.
1024 pub fn fetchPut(self: *Self, allocator: *Allocator, key: K, value: V) !?KV {1024 pub fn fetchPut(self: *Self, allocator: Allocator, key: K, value: V) !?KV {
1025 if (@sizeOf(Context) != 0)1025 if (@sizeOf(Context) != 0)
1026 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call fetchPutContext instead.");1026 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call fetchPutContext instead.");
1027 return self.fetchPutContext(allocator, key, value, undefined);1027 return self.fetchPutContext(allocator, key, value, undefined);
1028 }1028 }
1029 pub fn fetchPutContext(self: *Self, allocator: *Allocator, key: K, value: V, ctx: Context) !?KV {1029 pub fn fetchPutContext(self: *Self, allocator: Allocator, key: K, value: V, ctx: Context) !?KV {
1030 const gop = try self.getOrPutContext(allocator, key, ctx);1030 const gop = try self.getOrPutContext(allocator, key, ctx);
1031 var result: ?KV = null;1031 var result: ?KV = null;
1032 if (gop.found_existing) {1032 if (gop.found_existing) {
...@@ -1157,12 +1157,12 @@ pub fn HashMapUnmanaged(...@@ -1157,12 +1157,12 @@ pub fn HashMapUnmanaged(
1157 }1157 }
11581158
1159 /// Insert an entry if the associated key is not already present, otherwise update preexisting value.1159 /// Insert an entry if the associated key is not already present, otherwise update preexisting value.
1160 pub fn put(self: *Self, allocator: *Allocator, key: K, value: V) !void {1160 pub fn put(self: *Self, allocator: Allocator, key: K, value: V) !void {
1161 if (@sizeOf(Context) != 0)1161 if (@sizeOf(Context) != 0)
1162 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call putContext instead.");1162 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call putContext instead.");
1163 return self.putContext(allocator, key, value, undefined);1163 return self.putContext(allocator, key, value, undefined);
1164 }1164 }
1165 pub fn putContext(self: *Self, allocator: *Allocator, key: K, value: V, ctx: Context) !void {1165 pub fn putContext(self: *Self, allocator: Allocator, key: K, value: V, ctx: Context) !void {
1166 const result = try self.getOrPutContext(allocator, key, ctx);1166 const result = try self.getOrPutContext(allocator, key, ctx);
1167 result.value_ptr.* = value;1167 result.value_ptr.* = value;
1168 }1168 }
...@@ -1231,24 +1231,24 @@ pub fn HashMapUnmanaged(...@@ -1231,24 +1231,24 @@ pub fn HashMapUnmanaged(
1231 return null;1231 return null;
1232 }1232 }
12331233
1234 pub fn getOrPut(self: *Self, allocator: *Allocator, key: K) !GetOrPutResult {1234 pub fn getOrPut(self: *Self, allocator: Allocator, key: K) !GetOrPutResult {
1235 if (@sizeOf(Context) != 0)1235 if (@sizeOf(Context) != 0)
1236 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getOrPutContext instead.");1236 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getOrPutContext instead.");
1237 return self.getOrPutContext(allocator, key, undefined);1237 return self.getOrPutContext(allocator, key, undefined);
1238 }1238 }
1239 pub fn getOrPutContext(self: *Self, allocator: *Allocator, key: K, ctx: Context) !GetOrPutResult {1239 pub fn getOrPutContext(self: *Self, allocator: Allocator, key: K, ctx: Context) !GetOrPutResult {
1240 const gop = try self.getOrPutContextAdapted(allocator, key, ctx, ctx);1240 const gop = try self.getOrPutContextAdapted(allocator, key, ctx, ctx);
1241 if (!gop.found_existing) {1241 if (!gop.found_existing) {
1242 gop.key_ptr.* = key;1242 gop.key_ptr.* = key;
1243 }1243 }
1244 return gop;1244 return gop;
1245 }1245 }
1246 pub fn getOrPutAdapted(self: *Self, allocator: *Allocator, key: anytype, key_ctx: anytype) !GetOrPutResult {1246 pub fn getOrPutAdapted(self: *Self, allocator: Allocator, key: anytype, key_ctx: anytype) !GetOrPutResult {
1247 if (@sizeOf(Context) != 0)1247 if (@sizeOf(Context) != 0)
1248 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getOrPutContextAdapted instead.");1248 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getOrPutContextAdapted instead.");
1249 return self.getOrPutContextAdapted(allocator, key, key_ctx, undefined);1249 return self.getOrPutContextAdapted(allocator, key, key_ctx, undefined);
1250 }1250 }
1251 pub fn getOrPutContextAdapted(self: *Self, allocator: *Allocator, key: anytype, key_ctx: anytype, ctx: Context) !GetOrPutResult {1251 pub fn getOrPutContextAdapted(self: *Self, allocator: Allocator, key: anytype, key_ctx: anytype, ctx: Context) !GetOrPutResult {
1252 self.growIfNeeded(allocator, 1, ctx) catch |err| {1252 self.growIfNeeded(allocator, 1, ctx) catch |err| {
1253 // If allocation fails, try to do the lookup anyway.1253 // If allocation fails, try to do the lookup anyway.
1254 // If we find an existing item, we can return it.1254 // If we find an existing item, we can return it.
...@@ -1341,12 +1341,12 @@ pub fn HashMapUnmanaged(...@@ -1341,12 +1341,12 @@ pub fn HashMapUnmanaged(
1341 };1341 };
1342 }1342 }
13431343
1344 pub fn getOrPutValue(self: *Self, allocator: *Allocator, key: K, value: V) !Entry {1344 pub fn getOrPutValue(self: *Self, allocator: Allocator, key: K, value: V) !Entry {
1345 if (@sizeOf(Context) != 0)1345 if (@sizeOf(Context) != 0)
1346 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getOrPutValueContext instead.");1346 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getOrPutValueContext instead.");
1347 return self.getOrPutValueContext(allocator, key, value, undefined);1347 return self.getOrPutValueContext(allocator, key, value, undefined);
1348 }1348 }
1349 pub fn getOrPutValueContext(self: *Self, allocator: *Allocator, key: K, value: V, ctx: Context) !Entry {1349 pub fn getOrPutValueContext(self: *Self, allocator: Allocator, key: K, value: V, ctx: Context) !Entry {
1350 const res = try self.getOrPutAdapted(allocator, key, ctx);1350 const res = try self.getOrPutAdapted(allocator, key, ctx);
1351 if (!res.found_existing) {1351 if (!res.found_existing) {
1352 res.key_ptr.* = key;1352 res.key_ptr.* = key;
...@@ -1403,18 +1403,18 @@ pub fn HashMapUnmanaged(...@@ -1403,18 +1403,18 @@ pub fn HashMapUnmanaged(
1403 return @truncate(Size, max_load - self.available);1403 return @truncate(Size, max_load - self.available);
1404 }1404 }
14051405
1406 fn growIfNeeded(self: *Self, allocator: *Allocator, new_count: Size, ctx: Context) !void {1406 fn growIfNeeded(self: *Self, allocator: Allocator, new_count: Size, ctx: Context) !void {
1407 if (new_count > self.available) {1407 if (new_count > self.available) {
1408 try self.grow(allocator, capacityForSize(self.load() + new_count), ctx);1408 try self.grow(allocator, capacityForSize(self.load() + new_count), ctx);
1409 }1409 }
1410 }1410 }
14111411
1412 pub fn clone(self: Self, allocator: *Allocator) !Self {1412 pub fn clone(self: Self, allocator: Allocator) !Self {
1413 if (@sizeOf(Context) != 0)1413 if (@sizeOf(Context) != 0)
1414 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call cloneContext instead.");1414 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call cloneContext instead.");
1415 return self.cloneContext(allocator, @as(Context, undefined));1415 return self.cloneContext(allocator, @as(Context, undefined));
1416 }1416 }
1417 pub fn cloneContext(self: Self, allocator: *Allocator, new_ctx: anytype) !HashMapUnmanaged(K, V, @TypeOf(new_ctx), max_load_percentage) {1417 pub fn cloneContext(self: Self, allocator: Allocator, new_ctx: anytype) !HashMapUnmanaged(K, V, @TypeOf(new_ctx), max_load_percentage) {
1418 var other = HashMapUnmanaged(K, V, @TypeOf(new_ctx), max_load_percentage){};1418 var other = HashMapUnmanaged(K, V, @TypeOf(new_ctx), max_load_percentage){};
1419 if (self.size == 0)1419 if (self.size == 0)
1420 return other;1420 return other;
...@@ -1439,7 +1439,7 @@ pub fn HashMapUnmanaged(...@@ -1439,7 +1439,7 @@ pub fn HashMapUnmanaged(
1439 return other;1439 return other;
1440 }1440 }
14411441
1442 fn grow(self: *Self, allocator: *Allocator, new_capacity: Size, ctx: Context) !void {1442 fn grow(self: *Self, allocator: Allocator, new_capacity: Size, ctx: Context) !void {
1443 @setCold(true);1443 @setCold(true);
1444 const new_cap = std.math.max(new_capacity, minimal_capacity);1444 const new_cap = std.math.max(new_capacity, minimal_capacity);
1445 assert(new_cap > self.capacity());1445 assert(new_cap > self.capacity());
...@@ -1470,7 +1470,7 @@ pub fn HashMapUnmanaged(...@@ -1470,7 +1470,7 @@ pub fn HashMapUnmanaged(
1470 std.mem.swap(Self, self, &map);1470 std.mem.swap(Self, self, &map);
1471 }1471 }
14721472
1473 fn allocate(self: *Self, allocator: *Allocator, new_capacity: Size) !void {1473 fn allocate(self: *Self, allocator: Allocator, new_capacity: Size) !void {
1474 const header_align = @alignOf(Header);1474 const header_align = @alignOf(Header);
1475 const key_align = if (@sizeOf(K) == 0) 1 else @alignOf(K);1475 const key_align = if (@sizeOf(K) == 0) 1 else @alignOf(K);
1476 const val_align = if (@sizeOf(V) == 0) 1 else @alignOf(V);1476 const val_align = if (@sizeOf(V) == 0) 1 else @alignOf(V);
...@@ -1503,7 +1503,7 @@ pub fn HashMapUnmanaged(...@@ -1503,7 +1503,7 @@ pub fn HashMapUnmanaged(
1503 self.metadata = @intToPtr([*]Metadata, metadata);1503 self.metadata = @intToPtr([*]Metadata, metadata);
1504 }1504 }
15051505
1506 fn deallocate(self: *Self, allocator: *Allocator) void {1506 fn deallocate(self: *Self, allocator: Allocator) void {
1507 if (self.metadata == null) return;1507 if (self.metadata == null) return;
15081508
1509 const header_align = @alignOf(Header);1509 const header_align = @alignOf(Header);
lib/std/heap.zig+241-192
...@@ -97,13 +97,12 @@ const CAllocator = struct {...@@ -97,13 +97,12 @@ const CAllocator = struct {
97 }97 }
9898
99 fn alloc(99 fn alloc(
100 allocator: *Allocator,100 _: *c_void,
101 len: usize,101 len: usize,
102 alignment: u29,102 alignment: u29,
103 len_align: u29,103 len_align: u29,
104 return_address: usize,104 return_address: usize,
105 ) error{OutOfMemory}![]u8 {105 ) error{OutOfMemory}![]u8 {
106 _ = allocator;
107 _ = return_address;106 _ = return_address;
108 assert(len > 0);107 assert(len > 0);
109 assert(std.math.isPowerOfTwo(alignment));108 assert(std.math.isPowerOfTwo(alignment));
...@@ -124,20 +123,15 @@ const CAllocator = struct {...@@ -124,20 +123,15 @@ const CAllocator = struct {
124 }123 }
125124
126 fn resize(125 fn resize(
127 allocator: *Allocator,126 _: *c_void,
128 buf: []u8,127 buf: []u8,
129 buf_align: u29,128 buf_align: u29,
130 new_len: usize,129 new_len: usize,
131 len_align: u29,130 len_align: u29,
132 return_address: usize,131 return_address: usize,
133 ) Allocator.Error!usize {132 ) ?usize {
134 _ = allocator;
135 _ = buf_align;133 _ = buf_align;
136 _ = return_address;134 _ = return_address;
137 if (new_len == 0) {
138 alignedFree(buf.ptr);
139 return 0;
140 }
141 if (new_len <= buf.len) {135 if (new_len <= buf.len) {
142 return mem.alignAllocLen(buf.len, new_len, len_align);136 return mem.alignAllocLen(buf.len, new_len, len_align);
143 }137 }
...@@ -147,17 +141,32 @@ const CAllocator = struct {...@@ -147,17 +141,32 @@ const CAllocator = struct {
147 return mem.alignAllocLen(full_len, new_len, len_align);141 return mem.alignAllocLen(full_len, new_len, len_align);
148 }142 }
149 }143 }
150 return error.OutOfMemory;144 return null;
145 }
146
147 fn free(
148 _: *c_void,
149 buf: []u8,
150 buf_align: u29,
151 return_address: usize,
152 ) void {
153 _ = buf_align;
154 _ = return_address;
155 alignedFree(buf.ptr);
151 }156 }
152};157};
153158
154/// Supports the full Allocator interface, including alignment, and exploiting159/// Supports the full Allocator interface, including alignment, and exploiting
155/// `malloc_usable_size` if available. For an allocator that directly calls160/// `malloc_usable_size` if available. For an allocator that directly calls
156/// `malloc`/`free`, see `raw_c_allocator`.161/// `malloc`/`free`, see `raw_c_allocator`.
157pub const c_allocator = &c_allocator_state;162pub const c_allocator = Allocator{
158var c_allocator_state = Allocator{163 .ptr = undefined,
159 .allocFn = CAllocator.alloc,164 .vtable = &c_allocator_vtable,
160 .resizeFn = CAllocator.resize,165};
166const c_allocator_vtable = Allocator.VTable{
167 .alloc = CAllocator.alloc,
168 .resize = CAllocator.resize,
169 .free = CAllocator.free,
161};170};
162171
163/// Asserts allocations are within `@alignOf(std.c.max_align_t)` and directly calls172/// Asserts allocations are within `@alignOf(std.c.max_align_t)` and directly calls
...@@ -165,20 +174,23 @@ var c_allocator_state = Allocator{...@@ -165,20 +174,23 @@ var c_allocator_state = Allocator{
165/// This allocator is safe to use as the backing allocator with174/// This allocator is safe to use as the backing allocator with
166/// `ArenaAllocator` for example and is more optimal in such a case175/// `ArenaAllocator` for example and is more optimal in such a case
167/// than `c_allocator`.176/// than `c_allocator`.
168pub const raw_c_allocator = &raw_c_allocator_state;177pub const raw_c_allocator = Allocator{
169var raw_c_allocator_state = Allocator{178 .ptr = undefined,
170 .allocFn = rawCAlloc,179 .vtable = &raw_c_allocator_vtable,
171 .resizeFn = rawCResize,180};
181const raw_c_allocator_vtable = Allocator.VTable{
182 .alloc = rawCAlloc,
183 .resize = rawCResize,
184 .free = rawCFree,
172};185};
173186
174fn rawCAlloc(187fn rawCAlloc(
175 self: *Allocator,188 _: *c_void,
176 len: usize,189 len: usize,
177 ptr_align: u29,190 ptr_align: u29,
178 len_align: u29,191 len_align: u29,
179 ret_addr: usize,192 ret_addr: usize,
180) Allocator.Error![]u8 {193) Allocator.Error![]u8 {
181 _ = self;
182 _ = len_align;194 _ = len_align;
183 _ = ret_addr;195 _ = ret_addr;
184 assert(ptr_align <= @alignOf(std.c.max_align_t));196 assert(ptr_align <= @alignOf(std.c.max_align_t));
...@@ -187,43 +199,46 @@ fn rawCAlloc(...@@ -187,43 +199,46 @@ fn rawCAlloc(
187}199}
188200
189fn rawCResize(201fn rawCResize(
190 self: *Allocator,202 _: *c_void,
191 buf: []u8,203 buf: []u8,
192 old_align: u29,204 old_align: u29,
193 new_len: usize,205 new_len: usize,
194 len_align: u29,206 len_align: u29,
195 ret_addr: usize,207 ret_addr: usize,
196) Allocator.Error!usize {208) ?usize {
197 _ = self;
198 _ = old_align;209 _ = old_align;
199 _ = ret_addr;210 _ = ret_addr;
200 if (new_len == 0) {
201 c.free(buf.ptr);
202 return 0;
203 }
204 if (new_len <= buf.len) {211 if (new_len <= buf.len) {
205 return mem.alignAllocLen(buf.len, new_len, len_align);212 return mem.alignAllocLen(buf.len, new_len, len_align);
206 }213 }
207 return error.OutOfMemory;214 return null;
215}
216
217fn rawCFree(
218 _: *c_void,
219 buf: []u8,
220 old_align: u29,
221 ret_addr: usize,
222) void {
223 _ = old_align;
224 _ = ret_addr;
225 c.free(buf.ptr);
208}226}
209227
210/// This allocator makes a syscall directly for every allocation and free.228/// This allocator makes a syscall directly for every allocation and free.
211/// Thread-safe and lock-free.229/// Thread-safe and lock-free.
212pub const page_allocator = if (builtin.target.isWasm())230pub const page_allocator = if (builtin.target.isWasm())
213 &wasm_page_allocator_state231 Allocator{
232 .ptr = undefined,
233 .vtable = &WasmPageAllocator.vtable,
234 }
214else if (builtin.target.os.tag == .freestanding)235else if (builtin.target.os.tag == .freestanding)
215 root.os.heap.page_allocator236 root.os.heap.page_allocator
216else237else
217 &page_allocator_state;238 Allocator{
218239 .ptr = undefined,
219var page_allocator_state = Allocator{240 .vtable = &PageAllocator.vtable,
220 .allocFn = PageAllocator.alloc,241 };
221 .resizeFn = PageAllocator.resize,
222};
223var wasm_page_allocator_state = Allocator{
224 .allocFn = WasmPageAllocator.alloc,
225 .resizeFn = WasmPageAllocator.resize,
226};
227242
228/// Verifies that the adjusted length will still map to the full length243/// Verifies that the adjusted length will still map to the full length
229pub fn alignPageAllocLen(full_len: usize, len: usize, len_align: u29) usize {244pub fn alignPageAllocLen(full_len: usize, len: usize, len_align: u29) usize {
...@@ -236,8 +251,13 @@ pub fn alignPageAllocLen(full_len: usize, len: usize, len_align: u29) usize {...@@ -236,8 +251,13 @@ pub fn alignPageAllocLen(full_len: usize, len: usize, len_align: u29) usize {
236pub var next_mmap_addr_hint: ?[*]align(mem.page_size) u8 = null;251pub var next_mmap_addr_hint: ?[*]align(mem.page_size) u8 = null;
237252
238const PageAllocator = struct {253const PageAllocator = struct {
239 fn alloc(allocator: *Allocator, n: usize, alignment: u29, len_align: u29, ra: usize) error{OutOfMemory}![]u8 {254 const vtable = Allocator.VTable{
240 _ = allocator;255 .alloc = alloc,
256 .resize = resize,
257 .free = free,
258 };
259
260 fn alloc(_: *c_void, n: usize, alignment: u29, len_align: u29, ra: usize) error{OutOfMemory}![]u8 {
241 _ = ra;261 _ = ra;
242 assert(n > 0);262 assert(n > 0);
243 const aligned_len = mem.alignForward(n, mem.page_size);263 const aligned_len = mem.alignForward(n, mem.page_size);
...@@ -335,30 +355,19 @@ const PageAllocator = struct {...@@ -335,30 +355,19 @@ const PageAllocator = struct {
335 }355 }
336356
337 fn resize(357 fn resize(
338 allocator: *Allocator,358 _: *c_void,
339 buf_unaligned: []u8,359 buf_unaligned: []u8,
340 buf_align: u29,360 buf_align: u29,
341 new_size: usize,361 new_size: usize,
342 len_align: u29,362 len_align: u29,
343 return_address: usize,363 return_address: usize,
344 ) Allocator.Error!usize {364 ) ?usize {
345 _ = allocator;
346 _ = buf_align;365 _ = buf_align;
347 _ = return_address;366 _ = return_address;
348 const new_size_aligned = mem.alignForward(new_size, mem.page_size);367 const new_size_aligned = mem.alignForward(new_size, mem.page_size);
349368
350 if (builtin.os.tag == .windows) {369 if (builtin.os.tag == .windows) {
351 const w = os.windows;370 const w = os.windows;
352 if (new_size == 0) {
353 // From the docs:
354 // "If the dwFreeType parameter is MEM_RELEASE, this parameter
355 // must be 0 (zero). The function frees the entire region that
356 // is reserved in the initial allocation call to VirtualAlloc."
357 // So we can only use MEM_RELEASE when actually releasing the
358 // whole allocation.
359 w.VirtualFree(buf_unaligned.ptr, 0, w.MEM_RELEASE);
360 return 0;
361 }
362 if (new_size <= buf_unaligned.len) {371 if (new_size <= buf_unaligned.len) {
363 const base_addr = @ptrToInt(buf_unaligned.ptr);372 const base_addr = @ptrToInt(buf_unaligned.ptr);
364 const old_addr_end = base_addr + buf_unaligned.len;373 const old_addr_end = base_addr + buf_unaligned.len;
...@@ -378,7 +387,7 @@ const PageAllocator = struct {...@@ -378,7 +387,7 @@ const PageAllocator = struct {
378 if (new_size_aligned <= old_size_aligned) {387 if (new_size_aligned <= old_size_aligned) {
379 return alignPageAllocLen(new_size_aligned, new_size, len_align);388 return alignPageAllocLen(new_size_aligned, new_size, len_align);
380 }389 }
381 return error.OutOfMemory;390 return null;
382 }391 }
383392
384 const buf_aligned_len = mem.alignForward(buf_unaligned.len, mem.page_size);393 const buf_aligned_len = mem.alignForward(buf_unaligned.len, mem.page_size);
...@@ -389,14 +398,25 @@ const PageAllocator = struct {...@@ -389,14 +398,25 @@ const PageAllocator = struct {
389 const ptr = @alignCast(mem.page_size, buf_unaligned.ptr + new_size_aligned);398 const ptr = @alignCast(mem.page_size, buf_unaligned.ptr + new_size_aligned);
390 // TODO: if the next_mmap_addr_hint is within the unmapped range, update it399 // TODO: if the next_mmap_addr_hint is within the unmapped range, update it
391 os.munmap(ptr[0 .. buf_aligned_len - new_size_aligned]);400 os.munmap(ptr[0 .. buf_aligned_len - new_size_aligned]);
392 if (new_size_aligned == 0)
393 return 0;
394 return alignPageAllocLen(new_size_aligned, new_size, len_align);401 return alignPageAllocLen(new_size_aligned, new_size, len_align);
395 }402 }
396403
397 // TODO: call mremap404 // TODO: call mremap
398 // TODO: if the next_mmap_addr_hint is within the remapped range, update it405 // TODO: if the next_mmap_addr_hint is within the remapped range, update it
399 return error.OutOfMemory;406 return null;
407 }
408
409 fn free(_: *c_void, buf_unaligned: []u8, buf_align: u29, return_address: usize) void {
410 _ = buf_align;
411 _ = return_address;
412
413 if (builtin.os.tag == .windows) {
414 os.windows.VirtualFree(buf_unaligned.ptr, 0, os.windows.MEM_RELEASE);
415 } else {
416 const buf_aligned_len = mem.alignForward(buf_unaligned.len, mem.page_size);
417 const ptr = @alignCast(mem.page_size, buf_unaligned.ptr);
418 os.munmap(ptr[0..buf_aligned_len]);
419 }
400 }420 }
401};421};
402422
...@@ -407,6 +427,12 @@ const WasmPageAllocator = struct {...@@ -407,6 +427,12 @@ const WasmPageAllocator = struct {
407 }427 }
408 }428 }
409429
430 const vtable = Allocator.VTable{
431 .alloc = alloc,
432 .resize = resize,
433 .free = free,
434 };
435
410 const PageStatus = enum(u1) {436 const PageStatus = enum(u1) {
411 used = 0,437 used = 0,
412 free = 1,438 free = 1,
...@@ -492,8 +518,7 @@ const WasmPageAllocator = struct {...@@ -492,8 +518,7 @@ const WasmPageAllocator = struct {
492 return mem.alignForward(memsize, mem.page_size) / mem.page_size;518 return mem.alignForward(memsize, mem.page_size) / mem.page_size;
493 }519 }
494520
495 fn alloc(allocator: *Allocator, len: usize, alignment: u29, len_align: u29, ra: usize) error{OutOfMemory}![]u8 {521 fn alloc(_: *c_void, len: usize, alignment: u29, len_align: u29, ra: usize) error{OutOfMemory}![]u8 {
496 _ = allocator;
497 _ = ra;522 _ = ra;
498 const page_count = nPages(len);523 const page_count = nPages(len);
499 const page_idx = try allocPages(page_count, alignment);524 const page_idx = try allocPages(page_count, alignment);
...@@ -548,45 +573,57 @@ const WasmPageAllocator = struct {...@@ -548,45 +573,57 @@ const WasmPageAllocator = struct {
548 }573 }
549574
550 fn resize(575 fn resize(
551 allocator: *Allocator,576 _: *c_void,
552 buf: []u8,577 buf: []u8,
553 buf_align: u29,578 buf_align: u29,
554 new_len: usize,579 new_len: usize,
555 len_align: u29,580 len_align: u29,
556 return_address: usize,581 return_address: usize,
557 ) error{OutOfMemory}!usize {582 ) ?usize {
558 _ = allocator;
559 _ = buf_align;583 _ = buf_align;
560 _ = return_address;584 _ = return_address;
561 const aligned_len = mem.alignForward(buf.len, mem.page_size);585 const aligned_len = mem.alignForward(buf.len, mem.page_size);
562 if (new_len > aligned_len) return error.OutOfMemory;586 if (new_len > aligned_len) return null;
563 const current_n = nPages(aligned_len);587 const current_n = nPages(aligned_len);
564 const new_n = nPages(new_len);588 const new_n = nPages(new_len);
565 if (new_n != current_n) {589 if (new_n != current_n) {
566 const base = nPages(@ptrToInt(buf.ptr));590 const base = nPages(@ptrToInt(buf.ptr));
567 freePages(base + new_n, base + current_n);591 freePages(base + new_n, base + current_n);
568 }592 }
569 return if (new_len == 0) 0 else alignPageAllocLen(new_n * mem.page_size, new_len, len_align);593 return alignPageAllocLen(new_n * mem.page_size, new_len, len_align);
594 }
595
596 fn free(
597 _: *c_void,
598 buf: []u8,
599 buf_align: u29,
600 return_address: usize,
601 ) void {
602 _ = buf_align;
603 _ = return_address;
604 const aligned_len = mem.alignForward(buf.len, mem.page_size);
605 const current_n = nPages(aligned_len);
606 const base = nPages(@ptrToInt(buf.ptr));
607 freePages(base, base + current_n);
570 }608 }
571};609};
572610
573pub const HeapAllocator = switch (builtin.os.tag) {611pub const HeapAllocator = switch (builtin.os.tag) {
574 .windows => struct {612 .windows => struct {
575 allocator: Allocator,
576 heap_handle: ?HeapHandle,613 heap_handle: ?HeapHandle,
577614
578 const HeapHandle = os.windows.HANDLE;615 const HeapHandle = os.windows.HANDLE;
579616
580 pub fn init() HeapAllocator {617 pub fn init() HeapAllocator {
581 return HeapAllocator{618 return HeapAllocator{
582 .allocator = Allocator{
583 .allocFn = alloc,
584 .resizeFn = resize,
585 },
586 .heap_handle = null,619 .heap_handle = null,
587 };620 };
588 }621 }
589622
623 pub fn allocator(self: *HeapAllocator) Allocator {
624 return Allocator.init(self, alloc, resize, free);
625 }
626
590 pub fn deinit(self: *HeapAllocator) void {627 pub fn deinit(self: *HeapAllocator) void {
591 if (self.heap_handle) |heap_handle| {628 if (self.heap_handle) |heap_handle| {
592 os.windows.HeapDestroy(heap_handle);629 os.windows.HeapDestroy(heap_handle);
...@@ -598,14 +635,13 @@ pub const HeapAllocator = switch (builtin.os.tag) {...@@ -598,14 +635,13 @@ pub const HeapAllocator = switch (builtin.os.tag) {
598 }635 }
599636
600 fn alloc(637 fn alloc(
601 allocator: *Allocator,638 self: *HeapAllocator,
602 n: usize,639 n: usize,
603 ptr_align: u29,640 ptr_align: u29,
604 len_align: u29,641 len_align: u29,
605 return_address: usize,642 return_address: usize,
606 ) error{OutOfMemory}![]u8 {643 ) error{OutOfMemory}![]u8 {
607 _ = return_address;644 _ = return_address;
608 const self = @fieldParentPtr(HeapAllocator, "allocator", allocator);
609645
610 const amt = n + ptr_align - 1 + @sizeOf(usize);646 const amt = n + ptr_align - 1 + @sizeOf(usize);
611 const optional_heap_handle = @atomicLoad(?HeapHandle, &self.heap_handle, .SeqCst);647 const optional_heap_handle = @atomicLoad(?HeapHandle, &self.heap_handle, .SeqCst);
...@@ -632,20 +668,15 @@ pub const HeapAllocator = switch (builtin.os.tag) {...@@ -632,20 +668,15 @@ pub const HeapAllocator = switch (builtin.os.tag) {
632 }668 }
633669
634 fn resize(670 fn resize(
635 allocator: *Allocator,671 self: *HeapAllocator,
636 buf: []u8,672 buf: []u8,
637 buf_align: u29,673 buf_align: u29,
638 new_size: usize,674 new_size: usize,
639 len_align: u29,675 len_align: u29,
640 return_address: usize,676 return_address: usize,
641 ) error{OutOfMemory}!usize {677 ) ?usize {
642 _ = buf_align;678 _ = buf_align;
643 _ = return_address;679 _ = return_address;
644 const self = @fieldParentPtr(HeapAllocator, "allocator", allocator);
645 if (new_size == 0) {
646 os.windows.HeapFree(self.heap_handle.?, 0, @intToPtr(*c_void, getRecordPtr(buf).*));
647 return 0;
648 }
649680
650 const root_addr = getRecordPtr(buf).*;681 const root_addr = getRecordPtr(buf).*;
651 const align_offset = @ptrToInt(buf.ptr) - root_addr;682 const align_offset = @ptrToInt(buf.ptr) - root_addr;
...@@ -655,7 +686,7 @@ pub const HeapAllocator = switch (builtin.os.tag) {...@@ -655,7 +686,7 @@ pub const HeapAllocator = switch (builtin.os.tag) {
655 os.windows.HEAP_REALLOC_IN_PLACE_ONLY,686 os.windows.HEAP_REALLOC_IN_PLACE_ONLY,
656 @intToPtr(*c_void, root_addr),687 @intToPtr(*c_void, root_addr),
657 amt,688 amt,
658 ) orelse return error.OutOfMemory;689 ) orelse return null;
659 assert(new_ptr == @intToPtr(*c_void, root_addr));690 assert(new_ptr == @intToPtr(*c_void, root_addr));
660 const return_len = init: {691 const return_len = init: {
661 if (len_align == 0) break :init new_size;692 if (len_align == 0) break :init new_size;
...@@ -667,6 +698,17 @@ pub const HeapAllocator = switch (builtin.os.tag) {...@@ -667,6 +698,17 @@ pub const HeapAllocator = switch (builtin.os.tag) {
667 getRecordPtr(buf.ptr[0..return_len]).* = root_addr;698 getRecordPtr(buf.ptr[0..return_len]).* = root_addr;
668 return return_len;699 return return_len;
669 }700 }
701
702 fn free(
703 self: *HeapAllocator,
704 buf: []u8,
705 buf_align: u29,
706 return_address: usize,
707 ) void {
708 _ = buf_align;
709 _ = return_address;
710 os.windows.HeapFree(self.heap_handle.?, 0, @intToPtr(*c_void, getRecordPtr(buf).*));
711 }
670 },712 },
671 else => @compileError("Unsupported OS"),713 else => @compileError("Unsupported OS"),
672};714};
...@@ -682,21 +724,32 @@ fn sliceContainsSlice(container: []u8, slice: []u8) bool {...@@ -682,21 +724,32 @@ fn sliceContainsSlice(container: []u8, slice: []u8) bool {
682}724}
683725
684pub const FixedBufferAllocator = struct {726pub const FixedBufferAllocator = struct {
685 allocator: Allocator,
686 end_index: usize,727 end_index: usize,
687 buffer: []u8,728 buffer: []u8,
688729
689 pub fn init(buffer: []u8) FixedBufferAllocator {730 pub fn init(buffer: []u8) FixedBufferAllocator {
690 return FixedBufferAllocator{731 return FixedBufferAllocator{
691 .allocator = Allocator{
692 .allocFn = alloc,
693 .resizeFn = resize,
694 },
695 .buffer = buffer,732 .buffer = buffer,
696 .end_index = 0,733 .end_index = 0,
697 };734 };
698 }735 }
699736
737 /// *WARNING* using this at the same time as the interface returned by `threadSafeAllocator` is not thread safe
738 pub fn allocator(self: *FixedBufferAllocator) Allocator {
739 return Allocator.init(self, alloc, resize, free);
740 }
741
742 /// Provides a lock free thread safe `Allocator` interface to the underlying `FixedBufferAllocator`
743 /// *WARNING* using this at the same time as the interface returned by `getAllocator` is not thread safe
744 pub fn threadSafeAllocator(self: *FixedBufferAllocator) Allocator {
745 return Allocator.init(
746 self,
747 threadSafeAlloc,
748 Allocator.NoResize(FixedBufferAllocator).noResize,
749 Allocator.NoOpFree(FixedBufferAllocator).noOpFree,
750 );
751 }
752
700 pub fn ownsPtr(self: *FixedBufferAllocator, ptr: [*]u8) bool {753 pub fn ownsPtr(self: *FixedBufferAllocator, ptr: [*]u8) bool {
701 return sliceContainsPtr(self.buffer, ptr);754 return sliceContainsPtr(self.buffer, ptr);
702 }755 }
...@@ -707,15 +760,14 @@ pub const FixedBufferAllocator = struct {...@@ -707,15 +760,14 @@ pub const FixedBufferAllocator = struct {
707760
708 /// NOTE: this will not work in all cases, if the last allocation had an adjusted_index761 /// NOTE: this will not work in all cases, if the last allocation had an adjusted_index
709 /// then we won't be able to determine what the last allocation was. This is because762 /// then we won't be able to determine what the last allocation was. This is because
710 /// the alignForward operation done in alloc is not reverisible.763 /// the alignForward operation done in alloc is not reversible.
711 pub fn isLastAllocation(self: *FixedBufferAllocator, buf: []u8) bool {764 pub fn isLastAllocation(self: *FixedBufferAllocator, buf: []u8) bool {
712 return buf.ptr + buf.len == self.buffer.ptr + self.end_index;765 return buf.ptr + buf.len == self.buffer.ptr + self.end_index;
713 }766 }
714767
715 fn alloc(allocator: *Allocator, n: usize, ptr_align: u29, len_align: u29, ra: usize) ![]u8 {768 fn alloc(self: *FixedBufferAllocator, n: usize, ptr_align: u29, len_align: u29, ra: usize) ![]u8 {
716 _ = len_align;769 _ = len_align;
717 _ = ra;770 _ = ra;
718 const self = @fieldParentPtr(FixedBufferAllocator, "allocator", allocator);
719 const adjust_off = mem.alignPointerOffset(self.buffer.ptr + self.end_index, ptr_align) orelse771 const adjust_off = mem.alignPointerOffset(self.buffer.ptr + self.end_index, ptr_align) orelse
720 return error.OutOfMemory;772 return error.OutOfMemory;
721 const adjusted_index = self.end_index + adjust_off;773 const adjusted_index = self.end_index + adjust_off;
...@@ -730,97 +782,78 @@ pub const FixedBufferAllocator = struct {...@@ -730,97 +782,78 @@ pub const FixedBufferAllocator = struct {
730 }782 }
731783
732 fn resize(784 fn resize(
733 allocator: *Allocator,785 self: *FixedBufferAllocator,
734 buf: []u8,786 buf: []u8,
735 buf_align: u29,787 buf_align: u29,
736 new_size: usize,788 new_size: usize,
737 len_align: u29,789 len_align: u29,
738 return_address: usize,790 return_address: usize,
739 ) Allocator.Error!usize {791 ) ?usize {
740 _ = buf_align;792 _ = buf_align;
741 _ = return_address;793 _ = return_address;
742 const self = @fieldParentPtr(FixedBufferAllocator, "allocator", allocator);
743 assert(self.ownsSlice(buf)); // sanity check794 assert(self.ownsSlice(buf)); // sanity check
744795
745 if (!self.isLastAllocation(buf)) {796 if (!self.isLastAllocation(buf)) {
746 if (new_size > buf.len)797 if (new_size > buf.len) return null;
747 return error.OutOfMemory;798 return mem.alignAllocLen(buf.len, new_size, len_align);
748 return if (new_size == 0) 0 else mem.alignAllocLen(buf.len, new_size, len_align);
749 }799 }
750800
751 if (new_size <= buf.len) {801 if (new_size <= buf.len) {
752 const sub = buf.len - new_size;802 const sub = buf.len - new_size;
753 self.end_index -= sub;803 self.end_index -= sub;
754 return if (new_size == 0) 0 else mem.alignAllocLen(buf.len - sub, new_size, len_align);804 return mem.alignAllocLen(buf.len - sub, new_size, len_align);
755 }805 }
756806
757 const add = new_size - buf.len;807 const add = new_size - buf.len;
758 if (add + self.end_index > self.buffer.len) {808 if (add + self.end_index > self.buffer.len) return null;
759 return error.OutOfMemory;809
760 }
761 self.end_index += add;810 self.end_index += add;
762 return new_size;811 return new_size;
763 }812 }
764813
765 pub fn reset(self: *FixedBufferAllocator) void {814 fn free(
766 self.end_index = 0;815 self: *FixedBufferAllocator,
767 }816 buf: []u8,
768};817 buf_align: u29,
818 return_address: usize,
819 ) void {
820 _ = buf_align;
821 _ = return_address;
822 assert(self.ownsSlice(buf)); // sanity check
769823
770pub const ThreadSafeFixedBufferAllocator = blk: {824 if (self.isLastAllocation(buf)) {
771 if (builtin.single_threaded) {825 self.end_index -= buf.len;
772 break :blk FixedBufferAllocator;826 }
773 } else {827 }
774 // lock free
775 break :blk struct {
776 allocator: Allocator,
777 end_index: usize,
778 buffer: []u8,
779
780 pub fn init(buffer: []u8) ThreadSafeFixedBufferAllocator {
781 return ThreadSafeFixedBufferAllocator{
782 .allocator = Allocator{
783 .allocFn = alloc,
784 .resizeFn = Allocator.noResize,
785 },
786 .buffer = buffer,
787 .end_index = 0,
788 };
789 }
790828
791 fn alloc(allocator: *Allocator, n: usize, ptr_align: u29, len_align: u29, ra: usize) ![]u8 {829 fn threadSafeAlloc(self: *FixedBufferAllocator, n: usize, ptr_align: u29, len_align: u29, ra: usize) ![]u8 {
792 _ = len_align;830 _ = len_align;
793 _ = ra;831 _ = ra;
794 const self = @fieldParentPtr(ThreadSafeFixedBufferAllocator, "allocator", allocator);832 var end_index = @atomicLoad(usize, &self.end_index, .SeqCst);
795 var end_index = @atomicLoad(usize, &self.end_index, .SeqCst);833 while (true) {
796 while (true) {834 const adjust_off = mem.alignPointerOffset(self.buffer.ptr + end_index, ptr_align) orelse
797 const adjust_off = mem.alignPointerOffset(self.buffer.ptr + end_index, ptr_align) orelse835 return error.OutOfMemory;
798 return error.OutOfMemory;836 const adjusted_index = end_index + adjust_off;
799 const adjusted_index = end_index + adjust_off;837 const new_end_index = adjusted_index + n;
800 const new_end_index = adjusted_index + n;838 if (new_end_index > self.buffer.len) {
801 if (new_end_index > self.buffer.len) {839 return error.OutOfMemory;
802 return error.OutOfMemory;
803 }
804 end_index = @cmpxchgWeak(usize, &self.end_index, end_index, new_end_index, .SeqCst, .SeqCst) orelse return self.buffer[adjusted_index..new_end_index];
805 }
806 }840 }
841 end_index = @cmpxchgWeak(usize, &self.end_index, end_index, new_end_index, .SeqCst, .SeqCst) orelse return self.buffer[adjusted_index..new_end_index];
842 }
843 }
807844
808 pub fn reset(self: *ThreadSafeFixedBufferAllocator) void {845 pub fn reset(self: *FixedBufferAllocator) void {
809 self.end_index = 0;846 self.end_index = 0;
810 }
811 };
812 }847 }
813};848};
814849
815pub fn stackFallback(comptime size: usize, fallback_allocator: *Allocator) StackFallbackAllocator(size) {850pub const ThreadSafeFixedBufferAllocator = @compileError("ThreadSafeFixedBufferAllocator has been replaced with `threadSafeAllocator` on FixedBufferAllocator");
851
852pub fn stackFallback(comptime size: usize, fallback_allocator: Allocator) StackFallbackAllocator(size) {
816 return StackFallbackAllocator(size){853 return StackFallbackAllocator(size){
817 .buffer = undefined,854 .buffer = undefined,
818 .fallback_allocator = fallback_allocator,855 .fallback_allocator = fallback_allocator,
819 .fixed_buffer_allocator = undefined,856 .fixed_buffer_allocator = undefined,
820 .allocator = Allocator{
821 .allocFn = StackFallbackAllocator(size).alloc,
822 .resizeFn = StackFallbackAllocator(size).resize,
823 },
824 };857 };
825}858}
826859
...@@ -829,40 +862,51 @@ pub fn StackFallbackAllocator(comptime size: usize) type {...@@ -829,40 +862,51 @@ pub fn StackFallbackAllocator(comptime size: usize) type {
829 const Self = @This();862 const Self = @This();
830863
831 buffer: [size]u8,864 buffer: [size]u8,
832 allocator: Allocator,865 fallback_allocator: Allocator,
833 fallback_allocator: *Allocator,
834 fixed_buffer_allocator: FixedBufferAllocator,866 fixed_buffer_allocator: FixedBufferAllocator,
835867
836 pub fn get(self: *Self) *Allocator {868 /// WARNING: This functions both fetches a `std.mem.Allocator` interface to this allocator *and* resets the internal buffer allocator
869 pub fn get(self: *Self) Allocator {
837 self.fixed_buffer_allocator = FixedBufferAllocator.init(self.buffer[0..]);870 self.fixed_buffer_allocator = FixedBufferAllocator.init(self.buffer[0..]);
838 return &self.allocator;871 return Allocator.init(self, alloc, resize, free);
839 }872 }
840873
841 fn alloc(874 fn alloc(
842 allocator: *Allocator,875 self: *Self,
843 len: usize,876 len: usize,
844 ptr_align: u29,877 ptr_align: u29,
845 len_align: u29,878 len_align: u29,
846 return_address: usize,879 return_address: usize,
847 ) error{OutOfMemory}![]u8 {880 ) error{OutOfMemory}![]u8 {
848 const self = @fieldParentPtr(Self, "allocator", allocator);881 return FixedBufferAllocator.alloc(&self.fixed_buffer_allocator, len, ptr_align, len_align, return_address) catch
849 return FixedBufferAllocator.alloc(&self.fixed_buffer_allocator.allocator, len, ptr_align, len_align, return_address) catch882 return self.fallback_allocator.rawAlloc(len, ptr_align, len_align, return_address);
850 return self.fallback_allocator.allocFn(self.fallback_allocator, len, ptr_align, len_align, return_address);
851 }883 }
852884
853 fn resize(885 fn resize(
854 allocator: *Allocator,886 self: *Self,
855 buf: []u8,887 buf: []u8,
856 buf_align: u29,888 buf_align: u29,
857 new_len: usize,889 new_len: usize,
858 len_align: u29,890 len_align: u29,
859 return_address: usize,891 return_address: usize,
860 ) error{OutOfMemory}!usize {892 ) ?usize {
861 const self = @fieldParentPtr(Self, "allocator", allocator);
862 if (self.fixed_buffer_allocator.ownsPtr(buf.ptr)) {893 if (self.fixed_buffer_allocator.ownsPtr(buf.ptr)) {
863 return FixedBufferAllocator.resize(&self.fixed_buffer_allocator.allocator, buf, buf_align, new_len, len_align, return_address);894 return FixedBufferAllocator.resize(&self.fixed_buffer_allocator, buf, buf_align, new_len, len_align, return_address);
864 } else {895 } else {
865 return self.fallback_allocator.resizeFn(self.fallback_allocator, buf, buf_align, new_len, len_align, return_address);896 return self.fallback_allocator.rawResize(buf, buf_align, new_len, len_align, return_address);
897 }
898 }
899
900 fn free(
901 self: *Self,
902 buf: []u8,
903 buf_align: u29,
904 return_address: usize,
905 ) void {
906 if (self.fixed_buffer_allocator.ownsPtr(buf.ptr)) {
907 return FixedBufferAllocator.free(&self.fixed_buffer_allocator, buf, buf_align, return_address);
908 } else {
909 return self.fallback_allocator.rawFree(buf, buf_align, return_address);
866 }910 }
867 }911 }
868 };912 };
...@@ -950,8 +994,8 @@ test "HeapAllocator" {...@@ -950,8 +994,8 @@ test "HeapAllocator" {
950 if (builtin.os.tag == .windows) {994 if (builtin.os.tag == .windows) {
951 var heap_allocator = HeapAllocator.init();995 var heap_allocator = HeapAllocator.init();
952 defer heap_allocator.deinit();996 defer heap_allocator.deinit();
997 const allocator = heap_allocator.allocator();
953998
954 const allocator = &heap_allocator.allocator;
955 try testAllocator(allocator);999 try testAllocator(allocator);
956 try testAllocatorAligned(allocator);1000 try testAllocatorAligned(allocator);
957 try testAllocatorLargeAlignment(allocator);1001 try testAllocatorLargeAlignment(allocator);
...@@ -962,36 +1006,39 @@ test "HeapAllocator" {...@@ -962,36 +1006,39 @@ test "HeapAllocator" {
962test "ArenaAllocator" {1006test "ArenaAllocator" {
963 var arena_allocator = ArenaAllocator.init(page_allocator);1007 var arena_allocator = ArenaAllocator.init(page_allocator);
964 defer arena_allocator.deinit();1008 defer arena_allocator.deinit();
1009 const allocator = arena_allocator.allocator();
9651010
966 try testAllocator(&arena_allocator.allocator);1011 try testAllocator(allocator);
967 try testAllocatorAligned(&arena_allocator.allocator);1012 try testAllocatorAligned(allocator);
968 try testAllocatorLargeAlignment(&arena_allocator.allocator);1013 try testAllocatorLargeAlignment(allocator);
969 try testAllocatorAlignedShrink(&arena_allocator.allocator);1014 try testAllocatorAlignedShrink(allocator);
970}1015}
9711016
972var test_fixed_buffer_allocator_memory: [800000 * @sizeOf(u64)]u8 = undefined;1017var test_fixed_buffer_allocator_memory: [800000 * @sizeOf(u64)]u8 = undefined;
973test "FixedBufferAllocator" {1018test "FixedBufferAllocator" {
974 var fixed_buffer_allocator = mem.validationWrap(FixedBufferAllocator.init(test_fixed_buffer_allocator_memory[0..]));1019 var fixed_buffer_allocator = mem.validationWrap(FixedBufferAllocator.init(test_fixed_buffer_allocator_memory[0..]));
1020 const allocator = fixed_buffer_allocator.allocator();
9751021
976 try testAllocator(&fixed_buffer_allocator.allocator);1022 try testAllocator(allocator);
977 try testAllocatorAligned(&fixed_buffer_allocator.allocator);1023 try testAllocatorAligned(allocator);
978 try testAllocatorLargeAlignment(&fixed_buffer_allocator.allocator);1024 try testAllocatorLargeAlignment(allocator);
979 try testAllocatorAlignedShrink(&fixed_buffer_allocator.allocator);1025 try testAllocatorAlignedShrink(allocator);
980}1026}
9811027
982test "FixedBufferAllocator.reset" {1028test "FixedBufferAllocator.reset" {
983 var buf: [8]u8 align(@alignOf(u64)) = undefined;1029 var buf: [8]u8 align(@alignOf(u64)) = undefined;
984 var fba = FixedBufferAllocator.init(buf[0..]);1030 var fba = FixedBufferAllocator.init(buf[0..]);
1031 const allocator = fba.allocator();
9851032
986 const X = 0xeeeeeeeeeeeeeeee;1033 const X = 0xeeeeeeeeeeeeeeee;
987 const Y = 0xffffffffffffffff;1034 const Y = 0xffffffffffffffff;
9881035
989 var x = try fba.allocator.create(u64);1036 var x = try allocator.create(u64);
990 x.* = X;1037 x.* = X;
991 try testing.expectError(error.OutOfMemory, fba.allocator.create(u64));1038 try testing.expectError(error.OutOfMemory, allocator.create(u64));
9921039
993 fba.reset();1040 fba.reset();
994 var y = try fba.allocator.create(u64);1041 var y = try allocator.create(u64);
995 y.* = Y;1042 y.* = Y;
9961043
997 // we expect Y to have overwritten X.1044 // we expect Y to have overwritten X.
...@@ -1014,23 +1061,25 @@ test "FixedBufferAllocator Reuse memory on realloc" {...@@ -1014,23 +1061,25 @@ test "FixedBufferAllocator Reuse memory on realloc" {
1014 // check if we re-use the memory1061 // check if we re-use the memory
1015 {1062 {
1016 var fixed_buffer_allocator = FixedBufferAllocator.init(small_fixed_buffer[0..]);1063 var fixed_buffer_allocator = FixedBufferAllocator.init(small_fixed_buffer[0..]);
1064 const allocator = fixed_buffer_allocator.allocator();
10171065
1018 var slice0 = try fixed_buffer_allocator.allocator.alloc(u8, 5);1066 var slice0 = try allocator.alloc(u8, 5);
1019 try testing.expect(slice0.len == 5);1067 try testing.expect(slice0.len == 5);
1020 var slice1 = try fixed_buffer_allocator.allocator.realloc(slice0, 10);1068 var slice1 = try allocator.realloc(slice0, 10);
1021 try testing.expect(slice1.ptr == slice0.ptr);1069 try testing.expect(slice1.ptr == slice0.ptr);
1022 try testing.expect(slice1.len == 10);1070 try testing.expect(slice1.len == 10);
1023 try testing.expectError(error.OutOfMemory, fixed_buffer_allocator.allocator.realloc(slice1, 11));1071 try testing.expectError(error.OutOfMemory, allocator.realloc(slice1, 11));
1024 }1072 }
1025 // check that we don't re-use the memory if it's not the most recent block1073 // check that we don't re-use the memory if it's not the most recent block
1026 {1074 {
1027 var fixed_buffer_allocator = FixedBufferAllocator.init(small_fixed_buffer[0..]);1075 var fixed_buffer_allocator = FixedBufferAllocator.init(small_fixed_buffer[0..]);
1076 const allocator = fixed_buffer_allocator.allocator();
10281077
1029 var slice0 = try fixed_buffer_allocator.allocator.alloc(u8, 2);1078 var slice0 = try allocator.alloc(u8, 2);
1030 slice0[0] = 1;1079 slice0[0] = 1;
1031 slice0[1] = 2;1080 slice0[1] = 2;
1032 var slice1 = try fixed_buffer_allocator.allocator.alloc(u8, 2);1081 var slice1 = try allocator.alloc(u8, 2);
1033 var slice2 = try fixed_buffer_allocator.allocator.realloc(slice0, 4);1082 var slice2 = try allocator.realloc(slice0, 4);
1034 try testing.expect(slice0.ptr != slice2.ptr);1083 try testing.expect(slice0.ptr != slice2.ptr);
1035 try testing.expect(slice1.ptr != slice2.ptr);1084 try testing.expect(slice1.ptr != slice2.ptr);
1036 try testing.expect(slice2[0] == 1);1085 try testing.expect(slice2[0] == 1);
...@@ -1038,19 +1087,19 @@ test "FixedBufferAllocator Reuse memory on realloc" {...@@ -1038,19 +1087,19 @@ test "FixedBufferAllocator Reuse memory on realloc" {
1038 }1087 }
1039}1088}
10401089
1041test "ThreadSafeFixedBufferAllocator" {1090test "Thread safe FixedBufferAllocator" {
1042 var fixed_buffer_allocator = ThreadSafeFixedBufferAllocator.init(test_fixed_buffer_allocator_memory[0..]);1091 var fixed_buffer_allocator = FixedBufferAllocator.init(test_fixed_buffer_allocator_memory[0..]);
10431092
1044 try testAllocator(&fixed_buffer_allocator.allocator);1093 try testAllocator(fixed_buffer_allocator.threadSafeAllocator());
1045 try testAllocatorAligned(&fixed_buffer_allocator.allocator);1094 try testAllocatorAligned(fixed_buffer_allocator.threadSafeAllocator());
1046 try testAllocatorLargeAlignment(&fixed_buffer_allocator.allocator);1095 try testAllocatorLargeAlignment(fixed_buffer_allocator.threadSafeAllocator());
1047 try testAllocatorAlignedShrink(&fixed_buffer_allocator.allocator);1096 try testAllocatorAlignedShrink(fixed_buffer_allocator.threadSafeAllocator());
1048}1097}
10491098
1050/// This one should not try alignments that exceed what C malloc can handle.1099/// This one should not try alignments that exceed what C malloc can handle.
1051pub fn testAllocator(base_allocator: *mem.Allocator) !void {1100pub fn testAllocator(base_allocator: mem.Allocator) !void {
1052 var validationAllocator = mem.validationWrap(base_allocator);1101 var validationAllocator = mem.validationWrap(base_allocator);
1053 const allocator = &validationAllocator.allocator;1102 const allocator = validationAllocator.allocator();
10541103
1055 var slice = try allocator.alloc(*i32, 100);1104 var slice = try allocator.alloc(*i32, 100);
1056 try testing.expect(slice.len == 100);1105 try testing.expect(slice.len == 100);
...@@ -1094,9 +1143,9 @@ pub fn testAllocator(base_allocator: *mem.Allocator) !void {...@@ -1094,9 +1143,9 @@ pub fn testAllocator(base_allocator: *mem.Allocator) !void {
1094 allocator.free(oversize);1143 allocator.free(oversize);
1095}1144}
10961145
1097pub fn testAllocatorAligned(base_allocator: *mem.Allocator) !void {1146pub fn testAllocatorAligned(base_allocator: mem.Allocator) !void {
1098 var validationAllocator = mem.validationWrap(base_allocator);1147 var validationAllocator = mem.validationWrap(base_allocator);
1099 const allocator = &validationAllocator.allocator;1148 const allocator = validationAllocator.allocator();
11001149
1101 // Test a few alignment values, smaller and bigger than the type's one1150 // Test a few alignment values, smaller and bigger than the type's one
1102 inline for ([_]u29{ 1, 2, 4, 8, 16, 32, 64 }) |alignment| {1151 inline for ([_]u29{ 1, 2, 4, 8, 16, 32, 64 }) |alignment| {
...@@ -1124,9 +1173,9 @@ pub fn testAllocatorAligned(base_allocator: *mem.Allocator) !void {...@@ -1124,9 +1173,9 @@ pub fn testAllocatorAligned(base_allocator: *mem.Allocator) !void {
1124 }1173 }
1125}1174}
11261175
1127pub fn testAllocatorLargeAlignment(base_allocator: *mem.Allocator) !void {1176pub fn testAllocatorLargeAlignment(base_allocator: mem.Allocator) !void {
1128 var validationAllocator = mem.validationWrap(base_allocator);1177 var validationAllocator = mem.validationWrap(base_allocator);
1129 const allocator = &validationAllocator.allocator;1178 const allocator = validationAllocator.allocator();
11301179
1131 //Maybe a platform's page_size is actually the same as or1180 //Maybe a platform's page_size is actually the same as or
1132 // very near usize?1181 // very near usize?
...@@ -1156,12 +1205,12 @@ pub fn testAllocatorLargeAlignment(base_allocator: *mem.Allocator) !void {...@@ -1156,12 +1205,12 @@ pub fn testAllocatorLargeAlignment(base_allocator: *mem.Allocator) !void {
1156 allocator.free(slice);1205 allocator.free(slice);
1157}1206}
11581207
1159pub fn testAllocatorAlignedShrink(base_allocator: *mem.Allocator) !void {1208pub fn testAllocatorAlignedShrink(base_allocator: mem.Allocator) !void {
1160 var validationAllocator = mem.validationWrap(base_allocator);1209 var validationAllocator = mem.validationWrap(base_allocator);
1161 const allocator = &validationAllocator.allocator;1210 const allocator = validationAllocator.allocator();
11621211
1163 var debug_buffer: [1000]u8 = undefined;1212 var debug_buffer: [1000]u8 = undefined;
1164 const debug_allocator = &FixedBufferAllocator.init(&debug_buffer).allocator;1213 const debug_allocator = FixedBufferAllocator.init(&debug_buffer).allocator();
11651214
1166 const alloc_size = mem.page_size * 2 + 50;1215 const alloc_size = mem.page_size * 2 + 50;
1167 var slice = try allocator.alignedAlloc(u8, 16, alloc_size);1216 var slice = try allocator.alignedAlloc(u8, 16, alloc_size);
lib/std/heap/arena_allocator.zig+29-24
...@@ -6,9 +6,7 @@ const Allocator = std.mem.Allocator;...@@ -6,9 +6,7 @@ const Allocator = std.mem.Allocator;
6/// This allocator takes an existing allocator, wraps it, and provides an interface6/// This allocator takes an existing allocator, wraps it, and provides an interface
7/// where you can allocate without freeing, and then free it all together.7/// where you can allocate without freeing, and then free it all together.
8pub const ArenaAllocator = struct {8pub const ArenaAllocator = struct {
9 allocator: Allocator,9 child_allocator: Allocator,
10
11 child_allocator: *Allocator,
12 state: State,10 state: State,
1311
14 /// Inner state of ArenaAllocator. Can be stored rather than the entire ArenaAllocator12 /// Inner state of ArenaAllocator. Can be stored rather than the entire ArenaAllocator
...@@ -17,21 +15,21 @@ pub const ArenaAllocator = struct {...@@ -17,21 +15,21 @@ pub const ArenaAllocator = struct {
17 buffer_list: std.SinglyLinkedList([]u8) = @as(std.SinglyLinkedList([]u8), .{}),15 buffer_list: std.SinglyLinkedList([]u8) = @as(std.SinglyLinkedList([]u8), .{}),
18 end_index: usize = 0,16 end_index: usize = 0,
1917
20 pub fn promote(self: State, child_allocator: *Allocator) ArenaAllocator {18 pub fn promote(self: State, child_allocator: Allocator) ArenaAllocator {
21 return .{19 return .{
22 .allocator = Allocator{
23 .allocFn = alloc,
24 .resizeFn = resize,
25 },
26 .child_allocator = child_allocator,20 .child_allocator = child_allocator,
27 .state = self,21 .state = self,
28 };22 };
29 }23 }
30 };24 };
3125
26 pub fn allocator(self: *ArenaAllocator) Allocator {
27 return Allocator.init(self, alloc, resize, free);
28 }
29
32 const BufNode = std.SinglyLinkedList([]u8).Node;30 const BufNode = std.SinglyLinkedList([]u8).Node;
3331
34 pub fn init(child_allocator: *Allocator) ArenaAllocator {32 pub fn init(child_allocator: Allocator) ArenaAllocator {
35 return (State{}).promote(child_allocator);33 return (State{}).promote(child_allocator);
36 }34 }
3735
...@@ -49,7 +47,7 @@ pub const ArenaAllocator = struct {...@@ -49,7 +47,7 @@ pub const ArenaAllocator = struct {
49 const actual_min_size = minimum_size + (@sizeOf(BufNode) + 16);47 const actual_min_size = minimum_size + (@sizeOf(BufNode) + 16);
50 const big_enough_len = prev_len + actual_min_size;48 const big_enough_len = prev_len + actual_min_size;
51 const len = big_enough_len + big_enough_len / 2;49 const len = big_enough_len + big_enough_len / 2;
52 const buf = try self.child_allocator.allocFn(self.child_allocator, len, @alignOf(BufNode), 1, @returnAddress());50 const buf = try self.child_allocator.rawAlloc(len, @alignOf(BufNode), 1, @returnAddress());
53 const buf_node = @ptrCast(*BufNode, @alignCast(@alignOf(BufNode), buf.ptr));51 const buf_node = @ptrCast(*BufNode, @alignCast(@alignOf(BufNode), buf.ptr));
54 buf_node.* = BufNode{52 buf_node.* = BufNode{
55 .data = buf,53 .data = buf,
...@@ -60,10 +58,9 @@ pub const ArenaAllocator = struct {...@@ -60,10 +58,9 @@ pub const ArenaAllocator = struct {
60 return buf_node;58 return buf_node;
61 }59 }
6260
63 fn alloc(allocator: *Allocator, n: usize, ptr_align: u29, len_align: u29, ra: usize) ![]u8 {61 fn alloc(self: *ArenaAllocator, n: usize, ptr_align: u29, len_align: u29, ra: usize) ![]u8 {
64 _ = len_align;62 _ = len_align;
65 _ = ra;63 _ = ra;
66 const self = @fieldParentPtr(ArenaAllocator, "allocator", allocator);
6764
68 var cur_node = if (self.state.buffer_list.first) |first_node| first_node else try self.createNode(0, n + ptr_align);65 var cur_node = if (self.state.buffer_list.first) |first_node| first_node else try self.createNode(0, n + ptr_align);
69 while (true) {66 while (true) {
...@@ -81,27 +78,23 @@ pub const ArenaAllocator = struct {...@@ -81,27 +78,23 @@ pub const ArenaAllocator = struct {
8178
82 const bigger_buf_size = @sizeOf(BufNode) + new_end_index;79 const bigger_buf_size = @sizeOf(BufNode) + new_end_index;
83 // Try to grow the buffer in-place80 // Try to grow the buffer in-place
84 cur_node.data = self.child_allocator.resize(cur_node.data, bigger_buf_size) catch |err| switch (err) {81 cur_node.data = self.child_allocator.resize(cur_node.data, bigger_buf_size) orelse {
85 error.OutOfMemory => {82 // Allocate a new node if that's not possible
86 // Allocate a new node if that's not possible83 cur_node = try self.createNode(cur_buf.len, n + ptr_align);
87 cur_node = try self.createNode(cur_buf.len, n + ptr_align);84 continue;
88 continue;
89 },
90 };85 };
91 }86 }
92 }87 }
9388
94 fn resize(allocator: *Allocator, buf: []u8, buf_align: u29, new_len: usize, len_align: u29, ret_addr: usize) Allocator.Error!usize {89 fn resize(self: *ArenaAllocator, buf: []u8, buf_align: u29, new_len: usize, len_align: u29, ret_addr: usize) ?usize {
95 _ = buf_align;90 _ = buf_align;
96 _ = len_align;91 _ = len_align;
97 _ = ret_addr;92 _ = ret_addr;
98 const self = @fieldParentPtr(ArenaAllocator, "allocator", allocator);
9993
100 const cur_node = self.state.buffer_list.first orelse return error.OutOfMemory;94 const cur_node = self.state.buffer_list.first orelse return null;
101 const cur_buf = cur_node.data[@sizeOf(BufNode)..];95 const cur_buf = cur_node.data[@sizeOf(BufNode)..];
102 if (@ptrToInt(cur_buf.ptr) + self.state.end_index != @ptrToInt(buf.ptr) + buf.len) {96 if (@ptrToInt(cur_buf.ptr) + self.state.end_index != @ptrToInt(buf.ptr) + buf.len) {
103 if (new_len > buf.len)97 if (new_len > buf.len) return null;
104 return error.OutOfMemory;
105 return new_len;98 return new_len;
106 }99 }
107100
...@@ -112,7 +105,19 @@ pub const ArenaAllocator = struct {...@@ -112,7 +105,19 @@ pub const ArenaAllocator = struct {
112 self.state.end_index += new_len - buf.len;105 self.state.end_index += new_len - buf.len;
113 return new_len;106 return new_len;
114 } else {107 } else {
115 return error.OutOfMemory;108 return null;
109 }
110 }
111
112 fn free(self: *ArenaAllocator, buf: []u8, buf_align: u29, ret_addr: usize) void {
113 _ = buf_align;
114 _ = ret_addr;
115
116 const cur_node = self.state.buffer_list.first orelse return;
117 const cur_buf = cur_node.data[@sizeOf(BufNode)..];
118
119 if (@ptrToInt(cur_buf.ptr) + self.state.end_index == @ptrToInt(buf.ptr) + buf.len) {
120 self.state.end_index -= buf.len;
116 }121 }
117 }122 }
118};123};
lib/std/heap/general_purpose_allocator.zig+209-114
...@@ -172,11 +172,7 @@ pub const Config = struct {...@@ -172,11 +172,7 @@ pub const Config = struct {
172172
173pub fn GeneralPurposeAllocator(comptime config: Config) type {173pub fn GeneralPurposeAllocator(comptime config: Config) type {
174 return struct {174 return struct {
175 allocator: Allocator = Allocator{175 backing_allocator: Allocator = std.heap.page_allocator,
176 .allocFn = alloc,
177 .resizeFn = resize,
178 },
179 backing_allocator: *Allocator = std.heap.page_allocator,
180 buckets: [small_bucket_count]?*BucketHeader = [1]?*BucketHeader{null} ** small_bucket_count,176 buckets: [small_bucket_count]?*BucketHeader = [1]?*BucketHeader{null} ** small_bucket_count,
181 large_allocations: LargeAllocTable = .{},177 large_allocations: LargeAllocTable = .{},
182 empty_buckets: if (config.retain_metadata) ?*BucketHeader else void =178 empty_buckets: if (config.retain_metadata) ?*BucketHeader else void =
...@@ -284,6 +280,10 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {...@@ -284,6 +280,10 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
284 }280 }
285 };281 };
286282
283 pub fn allocator(self: *Self) Allocator {
284 return Allocator.init(self, alloc, resize, free);
285 }
286
287 fn bucketStackTrace(287 fn bucketStackTrace(
288 bucket: *BucketHeader,288 bucket: *BucketHeader,
289 size_class: usize,289 size_class: usize,
...@@ -388,7 +388,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {...@@ -388,7 +388,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
388 var it = self.large_allocations.iterator();388 var it = self.large_allocations.iterator();
389 while (it.next()) |large| {389 while (it.next()) |large| {
390 if (large.value_ptr.freed) {390 if (large.value_ptr.freed) {
391 _ = self.backing_allocator.resizeFn(self.backing_allocator, large.value_ptr.bytes, large.value_ptr.ptr_align, 0, 0, @returnAddress()) catch unreachable;391 self.backing_allocator.rawFree(large.value_ptr.bytes, large.value_ptr.ptr_align, @returnAddress());
392 }392 }
393 }393 }
394 }394 }
...@@ -517,7 +517,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {...@@ -517,7 +517,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
517 new_size: usize,517 new_size: usize,
518 len_align: u29,518 len_align: u29,
519 ret_addr: usize,519 ret_addr: usize,
520 ) Error!usize {520 ) ?usize {
521 const entry = self.large_allocations.getEntry(@ptrToInt(old_mem.ptr)) orelse {521 const entry = self.large_allocations.getEntry(@ptrToInt(old_mem.ptr)) orelse {
522 if (config.safety) {522 if (config.safety) {
523 @panic("Invalid free");523 @panic("Invalid free");
...@@ -529,9 +529,6 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {...@@ -529,9 +529,6 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
529 if (config.retain_metadata and entry.value_ptr.freed) {529 if (config.retain_metadata and entry.value_ptr.freed) {
530 if (config.safety) {530 if (config.safety) {
531 reportDoubleFree(ret_addr, entry.value_ptr.getStackTrace(.alloc), entry.value_ptr.getStackTrace(.free));531 reportDoubleFree(ret_addr, entry.value_ptr.getStackTrace(.alloc), entry.value_ptr.getStackTrace(.free));
532 // Recoverable if this is a free.
533 if (new_size == 0)
534 return @as(usize, 0);
535 @panic("Unrecoverable double free");532 @panic("Unrecoverable double free");
536 } else {533 } else {
537 unreachable;534 unreachable;
...@@ -555,12 +552,12 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {...@@ -555,12 +552,12 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
555552
556 // Do memory limit accounting with requested sizes rather than what backing_allocator returns553 // Do memory limit accounting with requested sizes rather than what backing_allocator returns
557 // because if we want to return error.OutOfMemory, we have to leave allocation untouched, and554 // because if we want to return error.OutOfMemory, we have to leave allocation untouched, and
558 // that is impossible to guarantee after calling backing_allocator.resizeFn.555 // that is impossible to guarantee after calling backing_allocator.rawResize.
559 const prev_req_bytes = self.total_requested_bytes;556 const prev_req_bytes = self.total_requested_bytes;
560 if (config.enable_memory_limit) {557 if (config.enable_memory_limit) {
561 const new_req_bytes = prev_req_bytes + new_size - entry.value_ptr.requested_size;558 const new_req_bytes = prev_req_bytes + new_size - entry.value_ptr.requested_size;
562 if (new_req_bytes > prev_req_bytes and new_req_bytes > self.requested_memory_limit) {559 if (new_req_bytes > prev_req_bytes and new_req_bytes > self.requested_memory_limit) {
563 return error.OutOfMemory;560 return null;
564 }561 }
565 self.total_requested_bytes = new_req_bytes;562 self.total_requested_bytes = new_req_bytes;
566 }563 }
...@@ -568,29 +565,12 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {...@@ -568,29 +565,12 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
568 self.total_requested_bytes = prev_req_bytes;565 self.total_requested_bytes = prev_req_bytes;
569 };566 };
570567
571 const result_len = if (config.never_unmap and new_size == 0)568 const result_len = self.backing_allocator.rawResize(old_mem, old_align, new_size, len_align, ret_addr) orelse return null;
572 0
573 else
574 try self.backing_allocator.resizeFn(self.backing_allocator, old_mem, old_align, new_size, len_align, ret_addr);
575569
576 if (config.enable_memory_limit) {570 if (config.enable_memory_limit) {
577 entry.value_ptr.requested_size = new_size;571 entry.value_ptr.requested_size = new_size;
578 }572 }
579573
580 if (result_len == 0) {
581 if (config.verbose_log) {
582 log.info("large free {d} bytes at {*}", .{ old_mem.len, old_mem.ptr });
583 }
584
585 if (!config.retain_metadata) {
586 assert(self.large_allocations.remove(@ptrToInt(old_mem.ptr)));
587 } else {
588 entry.value_ptr.freed = true;
589 entry.value_ptr.captureStackTrace(ret_addr, .free);
590 }
591 return 0;
592 }
593
594 if (config.verbose_log) {574 if (config.verbose_log) {
595 log.info("large resize {d} bytes at {*} to {d}", .{575 log.info("large resize {d} bytes at {*} to {d}", .{
596 old_mem.len, old_mem.ptr, new_size,576 old_mem.len, old_mem.ptr, new_size,
...@@ -601,20 +581,76 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {...@@ -601,20 +581,76 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
601 return result_len;581 return result_len;
602 }582 }
603583
584 /// This function assumes the object is in the large object storage regardless
585 /// of the parameters.
586 fn freeLarge(
587 self: *Self,
588 old_mem: []u8,
589 old_align: u29,
590 ret_addr: usize,
591 ) void {
592 _ = old_align;
593
594 const entry = self.large_allocations.getEntry(@ptrToInt(old_mem.ptr)) orelse {
595 if (config.safety) {
596 @panic("Invalid free");
597 } else {
598 unreachable;
599 }
600 };
601
602 if (config.retain_metadata and entry.value_ptr.freed) {
603 if (config.safety) {
604 reportDoubleFree(ret_addr, entry.value_ptr.getStackTrace(.alloc), entry.value_ptr.getStackTrace(.free));
605 return;
606 } else {
607 unreachable;
608 }
609 }
610
611 if (config.safety and old_mem.len != entry.value_ptr.bytes.len) {
612 var addresses: [stack_n]usize = [1]usize{0} ** stack_n;
613 var free_stack_trace = StackTrace{
614 .instruction_addresses = &addresses,
615 .index = 0,
616 };
617 std.debug.captureStackTrace(ret_addr, &free_stack_trace);
618 log.err("Allocation size {d} bytes does not match free size {d}. Allocation: {s} Free: {s}", .{
619 entry.value_ptr.bytes.len,
620 old_mem.len,
621 entry.value_ptr.getStackTrace(.alloc),
622 free_stack_trace,
623 });
624 }
625
626 if (config.enable_memory_limit) {
627 self.total_requested_bytes -= entry.value_ptr.requested_size;
628 }
629
630 if (config.verbose_log) {
631 log.info("large free {d} bytes at {*}", .{ old_mem.len, old_mem.ptr });
632 }
633
634 if (!config.retain_metadata) {
635 assert(self.large_allocations.remove(@ptrToInt(old_mem.ptr)));
636 } else {
637 entry.value_ptr.freed = true;
638 entry.value_ptr.captureStackTrace(ret_addr, .free);
639 }
640 }
641
604 pub fn setRequestedMemoryLimit(self: *Self, limit: usize) void {642 pub fn setRequestedMemoryLimit(self: *Self, limit: usize) void {
605 self.requested_memory_limit = limit;643 self.requested_memory_limit = limit;
606 }644 }
607645
608 fn resize(646 fn resize(
609 allocator: *Allocator,647 self: *Self,
610 old_mem: []u8,648 old_mem: []u8,
611 old_align: u29,649 old_align: u29,
612 new_size: usize,650 new_size: usize,
613 len_align: u29,651 len_align: u29,
614 ret_addr: usize,652 ret_addr: usize,
615 ) Error!usize {653 ) ?usize {
616 const self = @fieldParentPtr(Self, "allocator", allocator);
617
618 self.mutex.lock();654 self.mutex.lock();
619 defer self.mutex.unlock();655 defer self.mutex.unlock();
620656
...@@ -658,9 +694,6 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {...@@ -658,9 +694,6 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
658 if (!is_used) {694 if (!is_used) {
659 if (config.safety) {695 if (config.safety) {
660 reportDoubleFree(ret_addr, bucketStackTrace(bucket, size_class, slot_index, .alloc), bucketStackTrace(bucket, size_class, slot_index, .free));696 reportDoubleFree(ret_addr, bucketStackTrace(bucket, size_class, slot_index, .alloc), bucketStackTrace(bucket, size_class, slot_index, .free));
661 // Recoverable if this is a free.
662 if (new_size == 0)
663 return @as(usize, 0);
664 @panic("Unrecoverable double free");697 @panic("Unrecoverable double free");
665 } else {698 } else {
666 unreachable;699 unreachable;
...@@ -672,7 +705,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {...@@ -672,7 +705,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
672 if (config.enable_memory_limit) {705 if (config.enable_memory_limit) {
673 const new_req_bytes = prev_req_bytes + new_size - old_mem.len;706 const new_req_bytes = prev_req_bytes + new_size - old_mem.len;
674 if (new_req_bytes > prev_req_bytes and new_req_bytes > self.requested_memory_limit) {707 if (new_req_bytes > prev_req_bytes and new_req_bytes > self.requested_memory_limit) {
675 return error.OutOfMemory;708 return null;
676 }709 }
677 self.total_requested_bytes = new_req_bytes;710 self.total_requested_bytes = new_req_bytes;
678 }711 }
...@@ -680,52 +713,6 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {...@@ -680,52 +713,6 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
680 self.total_requested_bytes = prev_req_bytes;713 self.total_requested_bytes = prev_req_bytes;
681 };714 };
682715
683 if (new_size == 0) {
684 // Capture stack trace to be the "first free", in case a double free happens.
685 bucket.captureStackTrace(ret_addr, size_class, slot_index, .free);
686
687 used_byte.* &= ~(@as(u8, 1) << used_bit_index);
688 bucket.used_count -= 1;
689 if (bucket.used_count == 0) {
690 if (bucket.next == bucket) {
691 // it's the only bucket and therefore the current one
692 self.buckets[bucket_index] = null;
693 } else {
694 bucket.next.prev = bucket.prev;
695 bucket.prev.next = bucket.next;
696 self.buckets[bucket_index] = bucket.prev;
697 }
698 if (!config.never_unmap) {
699 self.backing_allocator.free(bucket.page[0..page_size]);
700 }
701 if (!config.retain_metadata) {
702 self.freeBucket(bucket, size_class);
703 } else {
704 // move alloc_cursor to end so we can tell size_class later
705 const slot_count = @divExact(page_size, size_class);
706 bucket.alloc_cursor = @truncate(SlotIndex, slot_count);
707 if (self.empty_buckets) |prev_bucket| {
708 // empty_buckets is ordered newest to oldest through prev so that if
709 // config.never_unmap is false and backing_allocator reuses freed memory
710 // then searchBuckets will always return the newer, relevant bucket
711 bucket.prev = prev_bucket;
712 bucket.next = prev_bucket.next;
713 prev_bucket.next = bucket;
714 bucket.next.prev = bucket;
715 } else {
716 bucket.prev = bucket;
717 bucket.next = bucket;
718 }
719 self.empty_buckets = bucket;
720 }
721 } else {
722 @memset(old_mem.ptr, undefined, old_mem.len);
723 }
724 if (config.verbose_log) {
725 log.info("small free {d} bytes at {*}", .{ old_mem.len, old_mem.ptr });
726 }
727 return @as(usize, 0);
728 }
729 const new_aligned_size = math.max(new_size, old_align);716 const new_aligned_size = math.max(new_size, old_align);
730 const new_size_class = math.ceilPowerOfTwoAssert(usize, new_aligned_size);717 const new_size_class = math.ceilPowerOfTwoAssert(usize, new_aligned_size);
731 if (new_size_class <= size_class) {718 if (new_size_class <= size_class) {
...@@ -739,7 +726,115 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {...@@ -739,7 +726,115 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
739 }726 }
740 return new_size;727 return new_size;
741 }728 }
742 return error.OutOfMemory;729 return null;
730 }
731
732 fn free(
733 self: *Self,
734 old_mem: []u8,
735 old_align: u29,
736 ret_addr: usize,
737 ) void {
738 self.mutex.lock();
739 defer self.mutex.unlock();
740
741 assert(old_mem.len != 0);
742
743 const aligned_size = math.max(old_mem.len, old_align);
744 if (aligned_size > largest_bucket_object_size) {
745 self.freeLarge(old_mem, old_align, ret_addr);
746 return;
747 }
748 const size_class_hint = math.ceilPowerOfTwoAssert(usize, aligned_size);
749
750 var bucket_index = math.log2(size_class_hint);
751 var size_class: usize = size_class_hint;
752 const bucket = while (bucket_index < small_bucket_count) : (bucket_index += 1) {
753 if (searchBucket(self.buckets[bucket_index], @ptrToInt(old_mem.ptr))) |bucket| {
754 // move bucket to head of list to optimize search for nearby allocations
755 self.buckets[bucket_index] = bucket;
756 break bucket;
757 }
758 size_class *= 2;
759 } else blk: {
760 if (config.retain_metadata) {
761 if (!self.large_allocations.contains(@ptrToInt(old_mem.ptr))) {
762 // object not in active buckets or a large allocation, so search empty buckets
763 if (searchBucket(self.empty_buckets, @ptrToInt(old_mem.ptr))) |bucket| {
764 // bucket is empty so is_used below will always be false and we exit there
765 break :blk bucket;
766 } else {
767 @panic("Invalid free");
768 }
769 }
770 }
771 self.freeLarge(old_mem, old_align, ret_addr);
772 return;
773 };
774 const byte_offset = @ptrToInt(old_mem.ptr) - @ptrToInt(bucket.page);
775 const slot_index = @intCast(SlotIndex, byte_offset / size_class);
776 const used_byte_index = slot_index / 8;
777 const used_bit_index = @intCast(u3, slot_index % 8);
778 const used_byte = bucket.usedBits(used_byte_index);
779 const is_used = @truncate(u1, used_byte.* >> used_bit_index) != 0;
780 if (!is_used) {
781 if (config.safety) {
782 reportDoubleFree(ret_addr, bucketStackTrace(bucket, size_class, slot_index, .alloc), bucketStackTrace(bucket, size_class, slot_index, .free));
783 // Recoverable if this is a free.
784 return;
785 } else {
786 unreachable;
787 }
788 }
789
790 // Definitely an in-use small alloc now.
791 if (config.enable_memory_limit) {
792 self.total_requested_bytes -= old_mem.len;
793 }
794
795 // Capture stack trace to be the "first free", in case a double free happens.
796 bucket.captureStackTrace(ret_addr, size_class, slot_index, .free);
797
798 used_byte.* &= ~(@as(u8, 1) << used_bit_index);
799 bucket.used_count -= 1;
800 if (bucket.used_count == 0) {
801 if (bucket.next == bucket) {
802 // it's the only bucket and therefore the current one
803 self.buckets[bucket_index] = null;
804 } else {
805 bucket.next.prev = bucket.prev;
806 bucket.prev.next = bucket.next;
807 self.buckets[bucket_index] = bucket.prev;
808 }
809 if (!config.never_unmap) {
810 self.backing_allocator.free(bucket.page[0..page_size]);
811 }
812 if (!config.retain_metadata) {
813 self.freeBucket(bucket, size_class);
814 } else {
815 // move alloc_cursor to end so we can tell size_class later
816 const slot_count = @divExact(page_size, size_class);
817 bucket.alloc_cursor = @truncate(SlotIndex, slot_count);
818 if (self.empty_buckets) |prev_bucket| {
819 // empty_buckets is ordered newest to oldest through prev so that if
820 // config.never_unmap is false and backing_allocator reuses freed memory
821 // then searchBuckets will always return the newer, relevant bucket
822 bucket.prev = prev_bucket;
823 bucket.next = prev_bucket.next;
824 prev_bucket.next = bucket;
825 bucket.next.prev = bucket;
826 } else {
827 bucket.prev = bucket;
828 bucket.next = bucket;
829 }
830 self.empty_buckets = bucket;
831 }
832 } else {
833 @memset(old_mem.ptr, undefined, old_mem.len);
834 }
835 if (config.verbose_log) {
836 log.info("small free {d} bytes at {*}", .{ old_mem.len, old_mem.ptr });
837 }
743 }838 }
744839
745 // Returns true if an allocation of `size` bytes is within the specified840 // Returns true if an allocation of `size` bytes is within the specified
...@@ -755,9 +850,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {...@@ -755,9 +850,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
755 return true;850 return true;
756 }851 }
757852
758 fn alloc(allocator: *Allocator, len: usize, ptr_align: u29, len_align: u29, ret_addr: usize) Error![]u8 {853 fn alloc(self: *Self, len: usize, ptr_align: u29, len_align: u29, ret_addr: usize) Error![]u8 {
759 const self = @fieldParentPtr(Self, "allocator", allocator);
760
761 self.mutex.lock();854 self.mutex.lock();
762 defer self.mutex.unlock();855 defer self.mutex.unlock();
763856
...@@ -768,7 +861,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {...@@ -768,7 +861,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
768 const new_aligned_size = math.max(len, ptr_align);861 const new_aligned_size = math.max(len, ptr_align);
769 if (new_aligned_size > largest_bucket_object_size) {862 if (new_aligned_size > largest_bucket_object_size) {
770 try self.large_allocations.ensureUnusedCapacity(self.backing_allocator, 1);863 try self.large_allocations.ensureUnusedCapacity(self.backing_allocator, 1);
771 const slice = try self.backing_allocator.allocFn(self.backing_allocator, len, ptr_align, len_align, ret_addr);864 const slice = try self.backing_allocator.rawAlloc(len, ptr_align, len_align, ret_addr);
772865
773 const gop = self.large_allocations.getOrPutAssumeCapacity(@ptrToInt(slice.ptr));866 const gop = self.large_allocations.getOrPutAssumeCapacity(@ptrToInt(slice.ptr));
774 if (config.retain_metadata and !config.never_unmap) {867 if (config.retain_metadata and !config.never_unmap) {
...@@ -834,7 +927,7 @@ const test_config = Config{};...@@ -834,7 +927,7 @@ const test_config = Config{};
834test "small allocations - free in same order" {927test "small allocations - free in same order" {
835 var gpa = GeneralPurposeAllocator(test_config){};928 var gpa = GeneralPurposeAllocator(test_config){};
836 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");929 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
837 const allocator = &gpa.allocator;930 const allocator = gpa.allocator();
838931
839 var list = std.ArrayList(*u64).init(std.testing.allocator);932 var list = std.ArrayList(*u64).init(std.testing.allocator);
840 defer list.deinit();933 defer list.deinit();
...@@ -853,7 +946,7 @@ test "small allocations - free in same order" {...@@ -853,7 +946,7 @@ test "small allocations - free in same order" {
853test "small allocations - free in reverse order" {946test "small allocations - free in reverse order" {
854 var gpa = GeneralPurposeAllocator(test_config){};947 var gpa = GeneralPurposeAllocator(test_config){};
855 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");948 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
856 const allocator = &gpa.allocator;949 const allocator = gpa.allocator();
857950
858 var list = std.ArrayList(*u64).init(std.testing.allocator);951 var list = std.ArrayList(*u64).init(std.testing.allocator);
859 defer list.deinit();952 defer list.deinit();
...@@ -872,7 +965,7 @@ test "small allocations - free in reverse order" {...@@ -872,7 +965,7 @@ test "small allocations - free in reverse order" {
872test "large allocations" {965test "large allocations" {
873 var gpa = GeneralPurposeAllocator(test_config){};966 var gpa = GeneralPurposeAllocator(test_config){};
874 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");967 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
875 const allocator = &gpa.allocator;968 const allocator = gpa.allocator();
876969
877 const ptr1 = try allocator.alloc(u64, 42768);970 const ptr1 = try allocator.alloc(u64, 42768);
878 const ptr2 = try allocator.alloc(u64, 52768);971 const ptr2 = try allocator.alloc(u64, 52768);
...@@ -885,7 +978,7 @@ test "large allocations" {...@@ -885,7 +978,7 @@ test "large allocations" {
885test "realloc" {978test "realloc" {
886 var gpa = GeneralPurposeAllocator(test_config){};979 var gpa = GeneralPurposeAllocator(test_config){};
887 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");980 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
888 const allocator = &gpa.allocator;981 const allocator = gpa.allocator();
889982
890 var slice = try allocator.alignedAlloc(u8, @alignOf(u32), 1);983 var slice = try allocator.alignedAlloc(u8, @alignOf(u32), 1);
891 defer allocator.free(slice);984 defer allocator.free(slice);
...@@ -907,7 +1000,7 @@ test "realloc" {...@@ -907,7 +1000,7 @@ test "realloc" {
907test "shrink" {1000test "shrink" {
908 var gpa = GeneralPurposeAllocator(test_config){};1001 var gpa = GeneralPurposeAllocator(test_config){};
909 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");1002 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
910 const allocator = &gpa.allocator;1003 const allocator = gpa.allocator();
9111004
912 var slice = try allocator.alloc(u8, 20);1005 var slice = try allocator.alloc(u8, 20);
913 defer allocator.free(slice);1006 defer allocator.free(slice);
...@@ -930,7 +1023,7 @@ test "shrink" {...@@ -930,7 +1023,7 @@ test "shrink" {
930test "large object - grow" {1023test "large object - grow" {
931 var gpa = GeneralPurposeAllocator(test_config){};1024 var gpa = GeneralPurposeAllocator(test_config){};
932 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");1025 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
933 const allocator = &gpa.allocator;1026 const allocator = gpa.allocator();
9341027
935 var slice1 = try allocator.alloc(u8, page_size * 2 - 20);1028 var slice1 = try allocator.alloc(u8, page_size * 2 - 20);
936 defer allocator.free(slice1);1029 defer allocator.free(slice1);
...@@ -948,7 +1041,7 @@ test "large object - grow" {...@@ -948,7 +1041,7 @@ test "large object - grow" {
948test "realloc small object to large object" {1041test "realloc small object to large object" {
949 var gpa = GeneralPurposeAllocator(test_config){};1042 var gpa = GeneralPurposeAllocator(test_config){};
950 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");1043 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
951 const allocator = &gpa.allocator;1044 const allocator = gpa.allocator();
9521045
953 var slice = try allocator.alloc(u8, 70);1046 var slice = try allocator.alloc(u8, 70);
954 defer allocator.free(slice);1047 defer allocator.free(slice);
...@@ -965,14 +1058,14 @@ test "realloc small object to large object" {...@@ -965,14 +1058,14 @@ test "realloc small object to large object" {
965test "shrink large object to large object" {1058test "shrink large object to large object" {
966 var gpa = GeneralPurposeAllocator(test_config){};1059 var gpa = GeneralPurposeAllocator(test_config){};
967 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");1060 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
968 const allocator = &gpa.allocator;1061 const allocator = gpa.allocator();
9691062
970 var slice = try allocator.alloc(u8, page_size * 2 + 50);1063 var slice = try allocator.alloc(u8, page_size * 2 + 50);
971 defer allocator.free(slice);1064 defer allocator.free(slice);
972 slice[0] = 0x12;1065 slice[0] = 0x12;
973 slice[60] = 0x34;1066 slice[60] = 0x34;
9741067
975 slice = try allocator.resize(slice, page_size * 2 + 1);1068 slice = allocator.resize(slice, page_size * 2 + 1) orelse return;
976 try std.testing.expect(slice[0] == 0x12);1069 try std.testing.expect(slice[0] == 0x12);
977 try std.testing.expect(slice[60] == 0x34);1070 try std.testing.expect(slice[60] == 0x34);
9781071
...@@ -988,10 +1081,10 @@ test "shrink large object to large object" {...@@ -988,10 +1081,10 @@ test "shrink large object to large object" {
988test "shrink large object to large object with larger alignment" {1081test "shrink large object to large object with larger alignment" {
989 var gpa = GeneralPurposeAllocator(test_config){};1082 var gpa = GeneralPurposeAllocator(test_config){};
990 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");1083 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
991 const allocator = &gpa.allocator;1084 const allocator = gpa.allocator();
9921085
993 var debug_buffer: [1000]u8 = undefined;1086 var debug_buffer: [1000]u8 = undefined;
994 const debug_allocator = &std.heap.FixedBufferAllocator.init(&debug_buffer).allocator;1087 const debug_allocator = std.heap.FixedBufferAllocator.init(&debug_buffer).allocator();
9951088
996 const alloc_size = page_size * 2 + 50;1089 const alloc_size = page_size * 2 + 50;
997 var slice = try allocator.alignedAlloc(u8, 16, alloc_size);1090 var slice = try allocator.alignedAlloc(u8, 16, alloc_size);
...@@ -1023,7 +1116,7 @@ test "shrink large object to large object with larger alignment" {...@@ -1023,7 +1116,7 @@ test "shrink large object to large object with larger alignment" {
1023test "realloc large object to small object" {1116test "realloc large object to small object" {
1024 var gpa = GeneralPurposeAllocator(test_config){};1117 var gpa = GeneralPurposeAllocator(test_config){};
1025 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");1118 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
1026 const allocator = &gpa.allocator;1119 const allocator = gpa.allocator();
10271120
1028 var slice = try allocator.alloc(u8, page_size * 2 + 50);1121 var slice = try allocator.alloc(u8, page_size * 2 + 50);
1029 defer allocator.free(slice);1122 defer allocator.free(slice);
...@@ -1041,7 +1134,7 @@ test "overrideable mutexes" {...@@ -1041,7 +1134,7 @@ test "overrideable mutexes" {
1041 .mutex = std.Thread.Mutex{},1134 .mutex = std.Thread.Mutex{},
1042 };1135 };
1043 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");1136 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
1044 const allocator = &gpa.allocator;1137 const allocator = gpa.allocator();
10451138
1046 const ptr = try allocator.create(i32);1139 const ptr = try allocator.create(i32);
1047 defer allocator.destroy(ptr);1140 defer allocator.destroy(ptr);
...@@ -1050,7 +1143,7 @@ test "overrideable mutexes" {...@@ -1050,7 +1143,7 @@ test "overrideable mutexes" {
1050test "non-page-allocator backing allocator" {1143test "non-page-allocator backing allocator" {
1051 var gpa = GeneralPurposeAllocator(.{}){ .backing_allocator = std.testing.allocator };1144 var gpa = GeneralPurposeAllocator(.{}){ .backing_allocator = std.testing.allocator };
1052 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");1145 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
1053 const allocator = &gpa.allocator;1146 const allocator = gpa.allocator();
10541147
1055 const ptr = try allocator.create(i32);1148 const ptr = try allocator.create(i32);
1056 defer allocator.destroy(ptr);1149 defer allocator.destroy(ptr);
...@@ -1059,10 +1152,10 @@ test "non-page-allocator backing allocator" {...@@ -1059,10 +1152,10 @@ test "non-page-allocator backing allocator" {
1059test "realloc large object to larger alignment" {1152test "realloc large object to larger alignment" {
1060 var gpa = GeneralPurposeAllocator(test_config){};1153 var gpa = GeneralPurposeAllocator(test_config){};
1061 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");1154 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
1062 const allocator = &gpa.allocator;1155 const allocator = gpa.allocator();
10631156
1064 var debug_buffer: [1000]u8 = undefined;1157 var debug_buffer: [1000]u8 = undefined;
1065 const debug_allocator = &std.heap.FixedBufferAllocator.init(&debug_buffer).allocator;1158 const debug_allocator = std.heap.FixedBufferAllocator.init(&debug_buffer).allocator();
10661159
1067 var slice = try allocator.alignedAlloc(u8, 16, page_size * 2 + 50);1160 var slice = try allocator.alignedAlloc(u8, 16, page_size * 2 + 50);
1068 defer allocator.free(slice);1161 defer allocator.free(slice);
...@@ -1098,9 +1191,9 @@ test "realloc large object to larger alignment" {...@@ -1098,9 +1191,9 @@ test "realloc large object to larger alignment" {
10981191
1099test "large object shrinks to small but allocation fails during shrink" {1192test "large object shrinks to small but allocation fails during shrink" {
1100 var failing_allocator = std.testing.FailingAllocator.init(std.heap.page_allocator, 3);1193 var failing_allocator = std.testing.FailingAllocator.init(std.heap.page_allocator, 3);
1101 var gpa = GeneralPurposeAllocator(.{}){ .backing_allocator = &failing_allocator.allocator };1194 var gpa = GeneralPurposeAllocator(.{}){ .backing_allocator = failing_allocator.allocator() };
1102 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");1195 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
1103 const allocator = &gpa.allocator;1196 const allocator = gpa.allocator();
11041197
1105 var slice = try allocator.alloc(u8, page_size * 2 + 50);1198 var slice = try allocator.alloc(u8, page_size * 2 + 50);
1106 defer allocator.free(slice);1199 defer allocator.free(slice);
...@@ -1117,7 +1210,7 @@ test "large object shrinks to small but allocation fails during shrink" {...@@ -1117,7 +1210,7 @@ test "large object shrinks to small but allocation fails during shrink" {
1117test "objects of size 1024 and 2048" {1210test "objects of size 1024 and 2048" {
1118 var gpa = GeneralPurposeAllocator(test_config){};1211 var gpa = GeneralPurposeAllocator(test_config){};
1119 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");1212 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
1120 const allocator = &gpa.allocator;1213 const allocator = gpa.allocator();
11211214
1122 const slice = try allocator.alloc(u8, 1025);1215 const slice = try allocator.alloc(u8, 1025);
1123 const slice2 = try allocator.alloc(u8, 3000);1216 const slice2 = try allocator.alloc(u8, 3000);
...@@ -1129,7 +1222,7 @@ test "objects of size 1024 and 2048" {...@@ -1129,7 +1222,7 @@ test "objects of size 1024 and 2048" {
1129test "setting a memory cap" {1222test "setting a memory cap" {
1130 var gpa = GeneralPurposeAllocator(.{ .enable_memory_limit = true }){};1223 var gpa = GeneralPurposeAllocator(.{ .enable_memory_limit = true }){};
1131 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");1224 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
1132 const allocator = &gpa.allocator;1225 const allocator = gpa.allocator();
11331226
1134 gpa.setRequestedMemoryLimit(1010);1227 gpa.setRequestedMemoryLimit(1010);
11351228
...@@ -1158,9 +1251,9 @@ test "double frees" {...@@ -1158,9 +1251,9 @@ test "double frees" {
1158 defer std.testing.expect(!backing_gpa.deinit()) catch @panic("leak");1251 defer std.testing.expect(!backing_gpa.deinit()) catch @panic("leak");
11591252
1160 const GPA = GeneralPurposeAllocator(.{ .safety = true, .never_unmap = true, .retain_metadata = true });1253 const GPA = GeneralPurposeAllocator(.{ .safety = true, .never_unmap = true, .retain_metadata = true });
1161 var gpa = GPA{ .backing_allocator = &backing_gpa.allocator };1254 var gpa = GPA{ .backing_allocator = backing_gpa.allocator() };
1162 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");1255 defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
1163 const allocator = &gpa.allocator;1256 const allocator = gpa.allocator();
11641257
1165 // detect a small allocation double free, even though bucket is emptied1258 // detect a small allocation double free, even though bucket is emptied
1166 const index: usize = 6;1259 const index: usize = 6;
...@@ -1195,10 +1288,12 @@ test "double frees" {...@@ -1195,10 +1288,12 @@ test "double frees" {
1195test "bug 9995 fix, large allocs count requested size not backing size" {1288test "bug 9995 fix, large allocs count requested size not backing size" {
1196 // with AtLeast, buffer likely to be larger than requested, especially when shrinking1289 // with AtLeast, buffer likely to be larger than requested, especially when shrinking
1197 var gpa = GeneralPurposeAllocator(.{ .enable_memory_limit = true }){};1290 var gpa = GeneralPurposeAllocator(.{ .enable_memory_limit = true }){};
1198 var buf = try gpa.allocator.allocAdvanced(u8, 1, page_size + 1, .at_least);1291 const allocator = gpa.allocator();
1292
1293 var buf = try allocator.allocAdvanced(u8, 1, page_size + 1, .at_least);
1199 try std.testing.expect(gpa.total_requested_bytes == page_size + 1);1294 try std.testing.expect(gpa.total_requested_bytes == page_size + 1);
1200 buf = try gpa.allocator.reallocAtLeast(buf, 1);1295 buf = try allocator.reallocAtLeast(buf, 1);
1201 try std.testing.expect(gpa.total_requested_bytes == 1);1296 try std.testing.expect(gpa.total_requested_bytes == 1);
1202 buf = try gpa.allocator.reallocAtLeast(buf, 2);1297 buf = try allocator.reallocAtLeast(buf, 2);
1203 try std.testing.expect(gpa.total_requested_bytes == 2);1298 try std.testing.expect(gpa.total_requested_bytes == 2);
1204}1299}
lib/std/heap/log_to_writer_allocator.zig+30-24
...@@ -5,33 +5,31 @@ const Allocator = std.mem.Allocator;...@@ -5,33 +5,31 @@ const Allocator = std.mem.Allocator;
5/// on every call to the allocator. Writer errors are ignored.5/// on every call to the allocator. Writer errors are ignored.
6pub fn LogToWriterAllocator(comptime Writer: type) type {6pub fn LogToWriterAllocator(comptime Writer: type) type {
7 return struct {7 return struct {
8 allocator: Allocator,8 parent_allocator: Allocator,
9 parent_allocator: *Allocator,
10 writer: Writer,9 writer: Writer,
1110
12 const Self = @This();11 const Self = @This();
1312
14 pub fn init(parent_allocator: *Allocator, writer: Writer) Self {13 pub fn init(parent_allocator: Allocator, writer: Writer) Self {
15 return Self{14 return Self{
16 .allocator = Allocator{
17 .allocFn = alloc,
18 .resizeFn = resize,
19 },
20 .parent_allocator = parent_allocator,15 .parent_allocator = parent_allocator,
21 .writer = writer,16 .writer = writer,
22 };17 };
23 }18 }
2419
20 pub fn allocator(self: *Self) Allocator {
21 return Allocator.init(self, alloc, resize, free);
22 }
23
25 fn alloc(24 fn alloc(
26 allocator: *Allocator,25 self: *Self,
27 len: usize,26 len: usize,
28 ptr_align: u29,27 ptr_align: u29,
29 len_align: u29,28 len_align: u29,
30 ra: usize,29 ra: usize,
31 ) error{OutOfMemory}![]u8 {30 ) error{OutOfMemory}![]u8 {
32 const self = @fieldParentPtr(Self, "allocator", allocator);
33 self.writer.print("alloc : {}", .{len}) catch {};31 self.writer.print("alloc : {}", .{len}) catch {};
34 const result = self.parent_allocator.allocFn(self.parent_allocator, len, ptr_align, len_align, ra);32 const result = self.parent_allocator.rawAlloc(len, ptr_align, len_align, ra);
35 if (result) |_| {33 if (result) |_| {
36 self.writer.print(" success!\n", .{}) catch {};34 self.writer.print(" success!\n", .{}) catch {};
37 } else |_| {35 } else |_| {
...@@ -41,31 +39,39 @@ pub fn LogToWriterAllocator(comptime Writer: type) type {...@@ -41,31 +39,39 @@ pub fn LogToWriterAllocator(comptime Writer: type) type {
41 }39 }
4240
43 fn resize(41 fn resize(
44 allocator: *Allocator,42 self: *Self,
45 buf: []u8,43 buf: []u8,
46 buf_align: u29,44 buf_align: u29,
47 new_len: usize,45 new_len: usize,
48 len_align: u29,46 len_align: u29,
49 ra: usize,47 ra: usize,
50 ) error{OutOfMemory}!usize {48 ) ?usize {
51 const self = @fieldParentPtr(Self, "allocator", allocator);49 if (new_len <= buf.len) {
52 if (new_len == 0) {
53 self.writer.print("free : {}\n", .{buf.len}) catch {};
54 } else if (new_len <= buf.len) {
55 self.writer.print("shrink: {} to {}\n", .{ buf.len, new_len }) catch {};50 self.writer.print("shrink: {} to {}\n", .{ buf.len, new_len }) catch {};
56 } else {51 } else {
57 self.writer.print("expand: {} to {}", .{ buf.len, new_len }) catch {};52 self.writer.print("expand: {} to {}", .{ buf.len, new_len }) catch {};
58 }53 }
59 if (self.parent_allocator.resizeFn(self.parent_allocator, buf, buf_align, new_len, len_align, ra)) |resized_len| {54
55 if (self.parent_allocator.rawResize(buf, buf_align, new_len, len_align, ra)) |resized_len| {
60 if (new_len > buf.len) {56 if (new_len > buf.len) {
61 self.writer.print(" success!\n", .{}) catch {};57 self.writer.print(" success!\n", .{}) catch {};
62 }58 }
63 return resized_len;59 return resized_len;
64 } else |e| {
65 std.debug.assert(new_len > buf.len);
66 self.writer.print(" failure!\n", .{}) catch {};
67 return e;
68 }60 }
61
62 std.debug.assert(new_len > buf.len);
63 self.writer.print(" failure!\n", .{}) catch {};
64 return null;
65 }
66
67 fn free(
68 self: *Self,
69 buf: []u8,
70 buf_align: u29,
71 ra: usize,
72 ) void {
73 self.writer.print("free : {}\n", .{buf.len}) catch {};
74 self.parent_allocator.rawFree(buf, buf_align, ra);
69 }75 }
70 };76 };
71}77}
...@@ -73,7 +79,7 @@ pub fn LogToWriterAllocator(comptime Writer: type) type {...@@ -73,7 +79,7 @@ pub fn LogToWriterAllocator(comptime Writer: type) type {
73/// This allocator is used in front of another allocator and logs to the provided writer79/// This allocator is used in front of another allocator and logs to the provided writer
74/// on every call to the allocator. Writer errors are ignored.80/// on every call to the allocator. Writer errors are ignored.
75pub fn logToWriterAllocator(81pub fn logToWriterAllocator(
76 parent_allocator: *Allocator,82 parent_allocator: Allocator,
77 writer: anytype,83 writer: anytype,
78) LogToWriterAllocator(@TypeOf(writer)) {84) LogToWriterAllocator(@TypeOf(writer)) {
79 return LogToWriterAllocator(@TypeOf(writer)).init(parent_allocator, writer);85 return LogToWriterAllocator(@TypeOf(writer)).init(parent_allocator, writer);
...@@ -85,12 +91,12 @@ test "LogToWriterAllocator" {...@@ -85,12 +91,12 @@ test "LogToWriterAllocator" {
8591
86 var allocator_buf: [10]u8 = undefined;92 var allocator_buf: [10]u8 = undefined;
87 var fixedBufferAllocator = std.mem.validationWrap(std.heap.FixedBufferAllocator.init(&allocator_buf));93 var fixedBufferAllocator = std.mem.validationWrap(std.heap.FixedBufferAllocator.init(&allocator_buf));
88 const allocator = &logToWriterAllocator(&fixedBufferAllocator.allocator, fbs.writer()).allocator;94 const allocator = logToWriterAllocator(fixedBufferAllocator.allocator(), fbs.writer()).allocator();
8995
90 var a = try allocator.alloc(u8, 10);96 var a = try allocator.alloc(u8, 10);
91 a = allocator.shrink(a, 5);97 a = allocator.shrink(a, 5);
92 try std.testing.expect(a.len == 5);98 try std.testing.expect(a.len == 5);
93 try std.testing.expectError(error.OutOfMemory, allocator.resize(a, 20));99 try std.testing.expect(allocator.resize(a, 20) == null);
94 allocator.free(a);100 allocator.free(a);
95101
96 try std.testing.expectEqualSlices(u8,102 try std.testing.expectEqualSlices(u8,
lib/std/heap/logging_allocator.zig+31-27
...@@ -22,21 +22,20 @@ pub fn ScopedLoggingAllocator(...@@ -22,21 +22,20 @@ pub fn ScopedLoggingAllocator(
22 const log = std.log.scoped(scope);22 const log = std.log.scoped(scope);
2323
24 return struct {24 return struct {
25 allocator: Allocator,25 parent_allocator: Allocator,
26 parent_allocator: *Allocator,
2726
28 const Self = @This();27 const Self = @This();
2928
30 pub fn init(parent_allocator: *Allocator) Self {29 pub fn init(parent_allocator: Allocator) Self {
31 return .{30 return .{
32 .allocator = Allocator{
33 .allocFn = alloc,
34 .resizeFn = resize,
35 },
36 .parent_allocator = parent_allocator,31 .parent_allocator = parent_allocator,
37 };32 };
38 }33 }
3934
35 pub fn allocator(self: *Self) Allocator {
36 return Allocator.init(self, alloc, resize, free);
37 }
38
40 // This function is required as the `std.log.log` function is not public39 // This function is required as the `std.log.log` function is not public
41 inline fn logHelper(comptime log_level: std.log.Level, comptime format: []const u8, args: anytype) void {40 inline fn logHelper(comptime log_level: std.log.Level, comptime format: []const u8, args: anytype) void {
42 switch (log_level) {41 switch (log_level) {
...@@ -48,14 +47,13 @@ pub fn ScopedLoggingAllocator(...@@ -48,14 +47,13 @@ pub fn ScopedLoggingAllocator(
48 }47 }
4948
50 fn alloc(49 fn alloc(
51 allocator: *Allocator,50 self: *Self,
52 len: usize,51 len: usize,
53 ptr_align: u29,52 ptr_align: u29,
54 len_align: u29,53 len_align: u29,
55 ra: usize,54 ra: usize,
56 ) error{OutOfMemory}![]u8 {55 ) error{OutOfMemory}![]u8 {
57 const self = @fieldParentPtr(Self, "allocator", allocator);56 const result = self.parent_allocator.rawAlloc(len, ptr_align, len_align, ra);
58 const result = self.parent_allocator.allocFn(self.parent_allocator, len, ptr_align, len_align, ra);
59 if (result) |_| {57 if (result) |_| {
60 logHelper(58 logHelper(
61 success_log_level,59 success_log_level,
...@@ -73,19 +71,15 @@ pub fn ScopedLoggingAllocator(...@@ -73,19 +71,15 @@ pub fn ScopedLoggingAllocator(
73 }71 }
7472
75 fn resize(73 fn resize(
76 allocator: *Allocator,74 self: *Self,
77 buf: []u8,75 buf: []u8,
78 buf_align: u29,76 buf_align: u29,
79 new_len: usize,77 new_len: usize,
80 len_align: u29,78 len_align: u29,
81 ra: usize,79 ra: usize,
82 ) error{OutOfMemory}!usize {80 ) ?usize {
83 const self = @fieldParentPtr(Self, "allocator", allocator);81 if (self.parent_allocator.rawResize(buf, buf_align, new_len, len_align, ra)) |resized_len| {
8482 if (new_len <= buf.len) {
85 if (self.parent_allocator.resizeFn(self.parent_allocator, buf, buf_align, new_len, len_align, ra)) |resized_len| {
86 if (new_len == 0) {
87 logHelper(success_log_level, "free - success - len: {}", .{buf.len});
88 } else if (new_len <= buf.len) {
89 logHelper(83 logHelper(
90 success_log_level,84 success_log_level,
91 "shrink - success - {} to {}, len_align: {}, buf_align: {}",85 "shrink - success - {} to {}, len_align: {}, buf_align: {}",
...@@ -100,15 +94,25 @@ pub fn ScopedLoggingAllocator(...@@ -100,15 +94,25 @@ pub fn ScopedLoggingAllocator(
100 }94 }
10195
102 return resized_len;96 return resized_len;
103 } else |err| {
104 std.debug.assert(new_len > buf.len);
105 logHelper(
106 failure_log_level,
107 "expand - failure: {s} - {} to {}, len_align: {}, buf_align: {}",
108 .{ @errorName(err), buf.len, new_len, len_align, buf_align },
109 );
110 return err;
111 }97 }
98
99 std.debug.assert(new_len > buf.len);
100 logHelper(
101 failure_log_level,
102 "expand - failure - {} to {}, len_align: {}, buf_align: {}",
103 .{ buf.len, new_len, len_align, buf_align },
104 );
105 return null;
106 }
107
108 fn free(
109 self: *Self,
110 buf: []u8,
111 buf_align: u29,
112 ra: usize,
113 ) void {
114 self.parent_allocator.rawFree(buf, buf_align, ra);
115 logHelper(success_log_level, "free - len: {}", .{buf.len});
112 }116 }
113 };117 };
114}118}
...@@ -116,6 +120,6 @@ pub fn ScopedLoggingAllocator(...@@ -116,6 +120,6 @@ pub fn ScopedLoggingAllocator(
116/// This allocator is used in front of another allocator and logs to `std.log`120/// This allocator is used in front of another allocator and logs to `std.log`
117/// on every call to the allocator.121/// on every call to the allocator.
118/// For logging to a `std.io.Writer` see `std.heap.LogToWriterAllocator`122/// For logging to a `std.io.Writer` see `std.heap.LogToWriterAllocator`
119pub fn loggingAllocator(parent_allocator: *Allocator) LoggingAllocator(.debug, .err) {123pub fn loggingAllocator(parent_allocator: Allocator) LoggingAllocator(.debug, .err) {
120 return LoggingAllocator(.debug, .err).init(parent_allocator);124 return LoggingAllocator(.debug, .err).init(parent_allocator);
121}125}
lib/std/io/buffered_atomic_file.zig+2-2
...@@ -7,7 +7,7 @@ pub const BufferedAtomicFile = struct {...@@ -7,7 +7,7 @@ pub const BufferedAtomicFile = struct {
7 atomic_file: fs.AtomicFile,7 atomic_file: fs.AtomicFile,
8 file_writer: File.Writer,8 file_writer: File.Writer,
9 buffered_writer: BufferedWriter,9 buffered_writer: BufferedWriter,
10 allocator: *mem.Allocator,10 allocator: mem.Allocator,
1111
12 pub const buffer_size = 4096;12 pub const buffer_size = 4096;
13 pub const BufferedWriter = std.io.BufferedWriter(buffer_size, File.Writer);13 pub const BufferedWriter = std.io.BufferedWriter(buffer_size, File.Writer);
...@@ -16,7 +16,7 @@ pub const BufferedAtomicFile = struct {...@@ -16,7 +16,7 @@ pub const BufferedAtomicFile = struct {
16 /// TODO when https://github.com/ziglang/zig/issues/2761 is solved16 /// TODO when https://github.com/ziglang/zig/issues/2761 is solved
17 /// this API will not need an allocator17 /// this API will not need an allocator
18 pub fn create(18 pub fn create(
19 allocator: *mem.Allocator,19 allocator: mem.Allocator,
20 dir: fs.Dir,20 dir: fs.Dir,
21 dest_path: []const u8,21 dest_path: []const u8,
22 atomic_file_options: fs.Dir.AtomicFileOptions,22 atomic_file_options: fs.Dir.AtomicFileOptions,
lib/std/io/peek_stream.zig+1-1
...@@ -38,7 +38,7 @@ pub fn PeekStream(...@@ -38,7 +38,7 @@ pub fn PeekStream(
38 }38 }
39 },39 },
40 .Dynamic => struct {40 .Dynamic => struct {
41 pub fn init(base: ReaderType, allocator: *mem.Allocator) Self {41 pub fn init(base: ReaderType, allocator: mem.Allocator) Self {
42 return .{42 return .{
43 .unbuffered_reader = base,43 .unbuffered_reader = base,
44 .fifo = FifoType.init(allocator),44 .fifo = FifoType.init(allocator),
lib/std/io/reader.zig+3-3
...@@ -88,7 +88,7 @@ pub fn Reader(...@@ -88,7 +88,7 @@ pub fn Reader(
88 /// memory would be greater than `max_size`, returns `error.StreamTooLong`.88 /// memory would be greater than `max_size`, returns `error.StreamTooLong`.
89 /// Caller owns returned memory.89 /// Caller owns returned memory.
90 /// If this function returns an error, the contents from the stream read so far are lost.90 /// If this function returns an error, the contents from the stream read so far are lost.
91 pub fn readAllAlloc(self: Self, allocator: *mem.Allocator, max_size: usize) ![]u8 {91 pub fn readAllAlloc(self: Self, allocator: mem.Allocator, max_size: usize) ![]u8 {
92 var array_list = std.ArrayList(u8).init(allocator);92 var array_list = std.ArrayList(u8).init(allocator);
93 defer array_list.deinit();93 defer array_list.deinit();
94 try self.readAllArrayList(&array_list, max_size);94 try self.readAllArrayList(&array_list, max_size);
...@@ -127,7 +127,7 @@ pub fn Reader(...@@ -127,7 +127,7 @@ pub fn Reader(
127 /// If this function returns an error, the contents from the stream read so far are lost.127 /// If this function returns an error, the contents from the stream read so far are lost.
128 pub fn readUntilDelimiterAlloc(128 pub fn readUntilDelimiterAlloc(
129 self: Self,129 self: Self,
130 allocator: *mem.Allocator,130 allocator: mem.Allocator,
131 delimiter: u8,131 delimiter: u8,
132 max_size: usize,132 max_size: usize,
133 ) ![]u8 {133 ) ![]u8 {
...@@ -163,7 +163,7 @@ pub fn Reader(...@@ -163,7 +163,7 @@ pub fn Reader(
163 /// If this function returns an error, the contents from the stream read so far are lost.163 /// If this function returns an error, the contents from the stream read so far are lost.
164 pub fn readUntilDelimiterOrEofAlloc(164 pub fn readUntilDelimiterOrEofAlloc(
165 self: Self,165 self: Self,
166 allocator: *mem.Allocator,166 allocator: mem.Allocator,
167 delimiter: u8,167 delimiter: u8,
168 max_size: usize,168 max_size: usize,
169 ) !?[]u8 {169 ) !?[]u8 {
lib/std/json.zig+16-14
...@@ -1476,7 +1476,7 @@ fn parsedEqual(a: anytype, b: @TypeOf(a)) bool {...@@ -1476,7 +1476,7 @@ fn parsedEqual(a: anytype, b: @TypeOf(a)) bool {
1476}1476}
14771477
1478pub const ParseOptions = struct {1478pub const ParseOptions = struct {
1479 allocator: ?*Allocator = null,1479 allocator: ?Allocator = null,
14801480
1481 /// Behaviour when a duplicate field is encountered.1481 /// Behaviour when a duplicate field is encountered.
1482 duplicate_field_behavior: enum {1482 duplicate_field_behavior: enum {
...@@ -2033,7 +2033,7 @@ test "parse into tagged union" {...@@ -2033,7 +2033,7 @@ test "parse into tagged union" {
20332033
2034 { // failing allocations should be bubbled up instantly without trying next member2034 { // failing allocations should be bubbled up instantly without trying next member
2035 var fail_alloc = testing.FailingAllocator.init(testing.allocator, 0);2035 var fail_alloc = testing.FailingAllocator.init(testing.allocator, 0);
2036 const options = ParseOptions{ .allocator = &fail_alloc.allocator };2036 const options = ParseOptions{ .allocator = fail_alloc.allocator() };
2037 const T = union(enum) {2037 const T = union(enum) {
2038 // both fields here match the input2038 // both fields here match the input
2039 string: []const u8,2039 string: []const u8,
...@@ -2081,7 +2081,7 @@ test "parse union bubbles up AllocatorRequired" {...@@ -2081,7 +2081,7 @@ test "parse union bubbles up AllocatorRequired" {
20812081
2082test "parseFree descends into tagged union" {2082test "parseFree descends into tagged union" {
2083 var fail_alloc = testing.FailingAllocator.init(testing.allocator, 1);2083 var fail_alloc = testing.FailingAllocator.init(testing.allocator, 1);
2084 const options = ParseOptions{ .allocator = &fail_alloc.allocator };2084 const options = ParseOptions{ .allocator = fail_alloc.allocator() };
2085 const T = union(enum) {2085 const T = union(enum) {
2086 int: i32,2086 int: i32,
2087 float: f64,2087 float: f64,
...@@ -2328,7 +2328,7 @@ test "parse into double recursive union definition" {...@@ -2328,7 +2328,7 @@ test "parse into double recursive union definition" {
23282328
2329/// A non-stream JSON parser which constructs a tree of Value's.2329/// A non-stream JSON parser which constructs a tree of Value's.
2330pub const Parser = struct {2330pub const Parser = struct {
2331 allocator: *Allocator,2331 allocator: Allocator,
2332 state: State,2332 state: State,
2333 copy_strings: bool,2333 copy_strings: bool,
2334 // Stores parent nodes and un-combined Values.2334 // Stores parent nodes and un-combined Values.
...@@ -2341,7 +2341,7 @@ pub const Parser = struct {...@@ -2341,7 +2341,7 @@ pub const Parser = struct {
2341 Simple,2341 Simple,
2342 };2342 };
23432343
2344 pub fn init(allocator: *Allocator, copy_strings: bool) Parser {2344 pub fn init(allocator: Allocator, copy_strings: bool) Parser {
2345 return Parser{2345 return Parser{
2346 .allocator = allocator,2346 .allocator = allocator,
2347 .state = .Simple,2347 .state = .Simple,
...@@ -2364,9 +2364,10 @@ pub const Parser = struct {...@@ -2364,9 +2364,10 @@ pub const Parser = struct {
23642364
2365 var arena = ArenaAllocator.init(p.allocator);2365 var arena = ArenaAllocator.init(p.allocator);
2366 errdefer arena.deinit();2366 errdefer arena.deinit();
2367 const allocator = arena.allocator();
23672368
2368 while (try s.next()) |token| {2369 while (try s.next()) |token| {
2369 try p.transition(&arena.allocator, input, s.i - 1, token);2370 try p.transition(allocator, input, s.i - 1, token);
2370 }2371 }
23712372
2372 debug.assert(p.stack.items.len == 1);2373 debug.assert(p.stack.items.len == 1);
...@@ -2379,7 +2380,7 @@ pub const Parser = struct {...@@ -2379,7 +2380,7 @@ pub const Parser = struct {
23792380
2380 // Even though p.allocator exists, we take an explicit allocator so that allocation state2381 // Even though p.allocator exists, we take an explicit allocator so that allocation state
2381 // can be cleaned up on error correctly during a `parse` on call.2382 // can be cleaned up on error correctly during a `parse` on call.
2382 fn transition(p: *Parser, allocator: *Allocator, input: []const u8, i: usize, token: Token) !void {2383 fn transition(p: *Parser, allocator: Allocator, input: []const u8, i: usize, token: Token) !void {
2383 switch (p.state) {2384 switch (p.state) {
2384 .ObjectKey => switch (token) {2385 .ObjectKey => switch (token) {
2385 .ObjectEnd => {2386 .ObjectEnd => {
...@@ -2536,7 +2537,7 @@ pub const Parser = struct {...@@ -2536,7 +2537,7 @@ pub const Parser = struct {
2536 }2537 }
2537 }2538 }
25382539
2539 fn parseString(p: *Parser, allocator: *Allocator, s: std.meta.TagPayload(Token, Token.String), input: []const u8, i: usize) !Value {2540 fn parseString(p: *Parser, allocator: Allocator, s: std.meta.TagPayload(Token, Token.String), input: []const u8, i: usize) !Value {
2540 const slice = s.slice(input, i);2541 const slice = s.slice(input, i);
2541 switch (s.escapes) {2542 switch (s.escapes) {
2542 .None => return Value{ .String = if (p.copy_strings) try allocator.dupe(u8, slice) else slice },2543 .None => return Value{ .String = if (p.copy_strings) try allocator.dupe(u8, slice) else slice },
...@@ -2737,7 +2738,7 @@ test "write json then parse it" {...@@ -2737,7 +2738,7 @@ test "write json then parse it" {
2737 try testing.expect(mem.eql(u8, tree.root.Object.get("str").?.String, "hello"));2738 try testing.expect(mem.eql(u8, tree.root.Object.get("str").?.String, "hello"));
2738}2739}
27392740
2740fn testParse(arena_allocator: *std.mem.Allocator, json_str: []const u8) !Value {2741fn testParse(arena_allocator: std.mem.Allocator, json_str: []const u8) !Value {
2741 var p = Parser.init(arena_allocator, false);2742 var p = Parser.init(arena_allocator, false);
2742 return (try p.parse(json_str)).root;2743 return (try p.parse(json_str)).root;
2743}2744}
...@@ -2745,13 +2746,13 @@ fn testParse(arena_allocator: *std.mem.Allocator, json_str: []const u8) !Value {...@@ -2745,13 +2746,13 @@ fn testParse(arena_allocator: *std.mem.Allocator, json_str: []const u8) !Value {
2745test "parsing empty string gives appropriate error" {2746test "parsing empty string gives appropriate error" {
2746 var arena_allocator = std.heap.ArenaAllocator.init(std.testing.allocator);2747 var arena_allocator = std.heap.ArenaAllocator.init(std.testing.allocator);
2747 defer arena_allocator.deinit();2748 defer arena_allocator.deinit();
2748 try testing.expectError(error.UnexpectedEndOfJson, testParse(&arena_allocator.allocator, ""));2749 try testing.expectError(error.UnexpectedEndOfJson, testParse(arena_allocator.allocator(), ""));
2749}2750}
27502751
2751test "integer after float has proper type" {2752test "integer after float has proper type" {
2752 var arena_allocator = std.heap.ArenaAllocator.init(std.testing.allocator);2753 var arena_allocator = std.heap.ArenaAllocator.init(std.testing.allocator);
2753 defer arena_allocator.deinit();2754 defer arena_allocator.deinit();
2754 const json = try testParse(&arena_allocator.allocator,2755 const json = try testParse(arena_allocator.allocator(),
2755 \\{2756 \\{
2756 \\ "float": 3.14,2757 \\ "float": 3.14,
2757 \\ "ints": [1, 2, 3]2758 \\ "ints": [1, 2, 3]
...@@ -2786,7 +2787,7 @@ test "escaped characters" {...@@ -2786,7 +2787,7 @@ test "escaped characters" {
2786 \\}2787 \\}
2787 ;2788 ;
27882789
2789 const obj = (try testParse(&arena_allocator.allocator, input)).Object;2790 const obj = (try testParse(arena_allocator.allocator(), input)).Object;
27902791
2791 try testing.expectEqualSlices(u8, obj.get("backslash").?.String, "\\");2792 try testing.expectEqualSlices(u8, obj.get("backslash").?.String, "\\");
2792 try testing.expectEqualSlices(u8, obj.get("forwardslash").?.String, "/");2793 try testing.expectEqualSlices(u8, obj.get("forwardslash").?.String, "/");
...@@ -2812,11 +2813,12 @@ test "string copy option" {...@@ -2812,11 +2813,12 @@ test "string copy option" {
28122813
2813 var arena_allocator = std.heap.ArenaAllocator.init(std.testing.allocator);2814 var arena_allocator = std.heap.ArenaAllocator.init(std.testing.allocator);
2814 defer arena_allocator.deinit();2815 defer arena_allocator.deinit();
2816 const allocator = arena_allocator.allocator();
28152817
2816 const tree_nocopy = try Parser.init(&arena_allocator.allocator, false).parse(input);2818 const tree_nocopy = try Parser.init(allocator, false).parse(input);
2817 const obj_nocopy = tree_nocopy.root.Object;2819 const obj_nocopy = tree_nocopy.root.Object;
28182820
2819 const tree_copy = try Parser.init(&arena_allocator.allocator, true).parse(input);2821 const tree_copy = try Parser.init(allocator, true).parse(input);
2820 const obj_copy = tree_copy.root.Object;2822 const obj_copy = tree_copy.root.Object;
28212823
2822 for ([_][]const u8{ "noescape", "simple", "unicode", "surrogatepair" }) |field_name| {2824 for ([_][]const u8{ "noescape", "simple", "unicode", "surrogatepair" }) |field_name| {
lib/std/json/write_stream.zig+2-2
...@@ -243,7 +243,7 @@ test "json write stream" {...@@ -243,7 +243,7 @@ test "json write stream" {
243 try w.beginObject();243 try w.beginObject();
244244
245 try w.objectField("object");245 try w.objectField("object");
246 try w.emitJson(try getJsonObject(&arena_allocator.allocator));246 try w.emitJson(try getJsonObject(arena_allocator.allocator()));
247247
248 try w.objectField("string");248 try w.objectField("string");
249 try w.emitString("This is a string");249 try w.emitString("This is a string");
...@@ -286,7 +286,7 @@ test "json write stream" {...@@ -286,7 +286,7 @@ test "json write stream" {
286 try std.testing.expect(std.mem.eql(u8, expected, result));286 try std.testing.expect(std.mem.eql(u8, expected, result));
287}287}
288288
289fn getJsonObject(allocator: *std.mem.Allocator) !std.json.Value {289fn getJsonObject(allocator: std.mem.Allocator) !std.json.Value {
290 var value = std.json.Value{ .Object = std.json.ObjectMap.init(allocator) };290 var value = std.json.Value{ .Object = std.json.ObjectMap.init(allocator) };
291 try value.Object.put("one", std.json.Value{ .Integer = @intCast(i64, 1) });291 try value.Object.put("one", std.json.Value{ .Integer = @intCast(i64, 1) });
292 try value.Object.put("two", std.json.Value{ .Float = 2.0 });292 try value.Object.put("two", std.json.Value{ .Float = 2.0 });
lib/std/math/big/int.zig+17-17
...@@ -142,7 +142,7 @@ pub const Mutable = struct {...@@ -142,7 +142,7 @@ pub const Mutable = struct {
142142
143 /// Asserts that the allocator owns the limbs memory. If this is not the case,143 /// Asserts that the allocator owns the limbs memory. If this is not the case,
144 /// use `toConst().toManaged()`.144 /// use `toConst().toManaged()`.
145 pub fn toManaged(self: Mutable, allocator: *Allocator) Managed {145 pub fn toManaged(self: Mutable, allocator: Allocator) Managed {
146 return .{146 return .{
147 .allocator = allocator,147 .allocator = allocator,
148 .limbs = self.limbs,148 .limbs = self.limbs,
...@@ -283,7 +283,7 @@ pub const Mutable = struct {...@@ -283,7 +283,7 @@ pub const Mutable = struct {
283 base: u8,283 base: u8,
284 value: []const u8,284 value: []const u8,
285 limbs_buffer: []Limb,285 limbs_buffer: []Limb,
286 allocator: ?*Allocator,286 allocator: ?Allocator,
287 ) error{InvalidCharacter}!void {287 ) error{InvalidCharacter}!void {
288 assert(base >= 2 and base <= 16);288 assert(base >= 2 and base <= 16);
289289
...@@ -608,7 +608,7 @@ pub const Mutable = struct {...@@ -608,7 +608,7 @@ pub const Mutable = struct {
608 /// rma is given by `a.limbs.len + b.limbs.len`.608 /// rma is given by `a.limbs.len + b.limbs.len`.
609 ///609 ///
610 /// `limbs_buffer` is used for temporary storage. The amount required is given by `calcMulLimbsBufferLen`.610 /// `limbs_buffer` is used for temporary storage. The amount required is given by `calcMulLimbsBufferLen`.
611 pub fn mul(rma: *Mutable, a: Const, b: Const, limbs_buffer: []Limb, allocator: ?*Allocator) void {611 pub fn mul(rma: *Mutable, a: Const, b: Const, limbs_buffer: []Limb, allocator: ?Allocator) void {
612 var buf_index: usize = 0;612 var buf_index: usize = 0;
613613
614 const a_copy = if (rma.limbs.ptr == a.limbs.ptr) blk: {614 const a_copy = if (rma.limbs.ptr == a.limbs.ptr) blk: {
...@@ -638,7 +638,7 @@ pub const Mutable = struct {...@@ -638,7 +638,7 @@ pub const Mutable = struct {
638 ///638 ///
639 /// If `allocator` is provided, it will be used for temporary storage to improve639 /// If `allocator` is provided, it will be used for temporary storage to improve
640 /// multiplication performance. `error.OutOfMemory` is handled with a fallback algorithm.640 /// multiplication performance. `error.OutOfMemory` is handled with a fallback algorithm.
641 pub fn mulNoAlias(rma: *Mutable, a: Const, b: Const, allocator: ?*Allocator) void {641 pub fn mulNoAlias(rma: *Mutable, a: Const, b: Const, allocator: ?Allocator) void {
642 assert(rma.limbs.ptr != a.limbs.ptr); // illegal aliasing642 assert(rma.limbs.ptr != a.limbs.ptr); // illegal aliasing
643 assert(rma.limbs.ptr != b.limbs.ptr); // illegal aliasing643 assert(rma.limbs.ptr != b.limbs.ptr); // illegal aliasing
644644
...@@ -674,7 +674,7 @@ pub const Mutable = struct {...@@ -674,7 +674,7 @@ pub const Mutable = struct {
674 signedness: Signedness,674 signedness: Signedness,
675 bit_count: usize,675 bit_count: usize,
676 limbs_buffer: []Limb,676 limbs_buffer: []Limb,
677 allocator: ?*Allocator,677 allocator: ?Allocator,
678 ) void {678 ) void {
679 var buf_index: usize = 0;679 var buf_index: usize = 0;
680 const req_limbs = calcTwosCompLimbCount(bit_count);680 const req_limbs = calcTwosCompLimbCount(bit_count);
...@@ -714,7 +714,7 @@ pub const Mutable = struct {...@@ -714,7 +714,7 @@ pub const Mutable = struct {
714 b: Const,714 b: Const,
715 signedness: Signedness,715 signedness: Signedness,
716 bit_count: usize,716 bit_count: usize,
717 allocator: ?*Allocator,717 allocator: ?Allocator,
718 ) void {718 ) void {
719 assert(rma.limbs.ptr != a.limbs.ptr); // illegal aliasing719 assert(rma.limbs.ptr != a.limbs.ptr); // illegal aliasing
720 assert(rma.limbs.ptr != b.limbs.ptr); // illegal aliasing720 assert(rma.limbs.ptr != b.limbs.ptr); // illegal aliasing
...@@ -763,7 +763,7 @@ pub const Mutable = struct {...@@ -763,7 +763,7 @@ pub const Mutable = struct {
763 ///763 ///
764 /// If `allocator` is provided, it will be used for temporary storage to improve764 /// If `allocator` is provided, it will be used for temporary storage to improve
765 /// multiplication performance. `error.OutOfMemory` is handled with a fallback algorithm.765 /// multiplication performance. `error.OutOfMemory` is handled with a fallback algorithm.
766 pub fn sqrNoAlias(rma: *Mutable, a: Const, opt_allocator: ?*Allocator) void {766 pub fn sqrNoAlias(rma: *Mutable, a: Const, opt_allocator: ?Allocator) void {
767 _ = opt_allocator;767 _ = opt_allocator;
768 assert(rma.limbs.ptr != a.limbs.ptr); // illegal aliasing768 assert(rma.limbs.ptr != a.limbs.ptr); // illegal aliasing
769769
...@@ -1660,7 +1660,7 @@ pub const Const = struct {...@@ -1660,7 +1660,7 @@ pub const Const = struct {
1660 positive: bool,1660 positive: bool,
16611661
1662 /// The result is an independent resource which is managed by the caller.1662 /// The result is an independent resource which is managed by the caller.
1663 pub fn toManaged(self: Const, allocator: *Allocator) Allocator.Error!Managed {1663 pub fn toManaged(self: Const, allocator: Allocator) Allocator.Error!Managed {
1664 const limbs = try allocator.alloc(Limb, math.max(Managed.default_capacity, self.limbs.len));1664 const limbs = try allocator.alloc(Limb, math.max(Managed.default_capacity, self.limbs.len));
1665 mem.copy(Limb, limbs, self.limbs);1665 mem.copy(Limb, limbs, self.limbs);
1666 return Managed{1666 return Managed{
...@@ -1873,7 +1873,7 @@ pub const Const = struct {...@@ -1873,7 +1873,7 @@ pub const Const = struct {
1873 /// Caller owns returned memory.1873 /// Caller owns returned memory.
1874 /// Asserts that `base` is in the range [2, 16].1874 /// Asserts that `base` is in the range [2, 16].
1875 /// See also `toString`, a lower level function than this.1875 /// See also `toString`, a lower level function than this.
1876 pub fn toStringAlloc(self: Const, allocator: *Allocator, base: u8, case: std.fmt.Case) Allocator.Error![]u8 {1876 pub fn toStringAlloc(self: Const, allocator: Allocator, base: u8, case: std.fmt.Case) Allocator.Error![]u8 {
1877 assert(base >= 2);1877 assert(base >= 2);
1878 assert(base <= 16);1878 assert(base <= 16);
18791879
...@@ -2092,7 +2092,7 @@ pub const Managed = struct {...@@ -2092,7 +2092,7 @@ pub const Managed = struct {
2092 pub const default_capacity = 4;2092 pub const default_capacity = 4;
20932093
2094 /// Allocator used by the Managed when requesting memory.2094 /// Allocator used by the Managed when requesting memory.
2095 allocator: *Allocator,2095 allocator: Allocator,
20962096
2097 /// Raw digits. These are:2097 /// Raw digits. These are:
2098 ///2098 ///
...@@ -2109,7 +2109,7 @@ pub const Managed = struct {...@@ -2109,7 +2109,7 @@ pub const Managed = struct {
21092109
2110 /// Creates a new `Managed`. `default_capacity` limbs will be allocated immediately.2110 /// Creates a new `Managed`. `default_capacity` limbs will be allocated immediately.
2111 /// The integer value after initializing is `0`.2111 /// The integer value after initializing is `0`.
2112 pub fn init(allocator: *Allocator) !Managed {2112 pub fn init(allocator: Allocator) !Managed {
2113 return initCapacity(allocator, default_capacity);2113 return initCapacity(allocator, default_capacity);
2114 }2114 }
21152115
...@@ -2131,7 +2131,7 @@ pub const Managed = struct {...@@ -2131,7 +2131,7 @@ pub const Managed = struct {
2131 /// Creates a new `Managed` with value `value`.2131 /// Creates a new `Managed` with value `value`.
2132 ///2132 ///
2133 /// This is identical to an `init`, followed by a `set`.2133 /// This is identical to an `init`, followed by a `set`.
2134 pub fn initSet(allocator: *Allocator, value: anytype) !Managed {2134 pub fn initSet(allocator: Allocator, value: anytype) !Managed {
2135 var s = try Managed.init(allocator);2135 var s = try Managed.init(allocator);
2136 try s.set(value);2136 try s.set(value);
2137 return s;2137 return s;
...@@ -2140,7 +2140,7 @@ pub const Managed = struct {...@@ -2140,7 +2140,7 @@ pub const Managed = struct {
2140 /// Creates a new Managed with a specific capacity. If capacity < default_capacity then the2140 /// Creates a new Managed with a specific capacity. If capacity < default_capacity then the
2141 /// default capacity will be used instead.2141 /// default capacity will be used instead.
2142 /// The integer value after initializing is `0`.2142 /// The integer value after initializing is `0`.
2143 pub fn initCapacity(allocator: *Allocator, capacity: usize) !Managed {2143 pub fn initCapacity(allocator: Allocator, capacity: usize) !Managed {
2144 return Managed{2144 return Managed{
2145 .allocator = allocator,2145 .allocator = allocator,
2146 .metadata = 1,2146 .metadata = 1,
...@@ -2206,7 +2206,7 @@ pub const Managed = struct {...@@ -2206,7 +2206,7 @@ pub const Managed = struct {
2206 return other.cloneWithDifferentAllocator(other.allocator);2206 return other.cloneWithDifferentAllocator(other.allocator);
2207 }2207 }
22082208
2209 pub fn cloneWithDifferentAllocator(other: Managed, allocator: *Allocator) !Managed {2209 pub fn cloneWithDifferentAllocator(other: Managed, allocator: Allocator) !Managed {
2210 return Managed{2210 return Managed{
2211 .allocator = allocator,2211 .allocator = allocator,
2212 .metadata = other.metadata,2212 .metadata = other.metadata,
...@@ -2347,7 +2347,7 @@ pub const Managed = struct {...@@ -2347,7 +2347,7 @@ pub const Managed = struct {
23472347
2348 /// Converts self to a string in the requested base. Memory is allocated from the provided2348 /// Converts self to a string in the requested base. Memory is allocated from the provided
2349 /// allocator and not the one present in self.2349 /// allocator and not the one present in self.
2350 pub fn toString(self: Managed, allocator: *Allocator, base: u8, case: std.fmt.Case) ![]u8 {2350 pub fn toString(self: Managed, allocator: Allocator, base: u8, case: std.fmt.Case) ![]u8 {
2351 _ = allocator;2351 _ = allocator;
2352 if (base < 2 or base > 16) return error.InvalidBase;2352 if (base < 2 or base > 16) return error.InvalidBase;
2353 return self.toConst().toStringAlloc(self.allocator, base, case);2353 return self.toConst().toStringAlloc(self.allocator, base, case);
...@@ -2784,7 +2784,7 @@ const AccOp = enum {...@@ -2784,7 +2784,7 @@ const AccOp = enum {
2784/// r MUST NOT alias any of a or b.2784/// r MUST NOT alias any of a or b.
2785///2785///
2786/// The result is computed modulo `r.len`. When `r.len >= a.len + b.len`, no overflow occurs.2786/// The result is computed modulo `r.len`. When `r.len >= a.len + b.len`, no overflow occurs.
2787fn llmulacc(comptime op: AccOp, opt_allocator: ?*Allocator, r: []Limb, a: []const Limb, b: []const Limb) void {2787fn llmulacc(comptime op: AccOp, opt_allocator: ?Allocator, r: []Limb, a: []const Limb, b: []const Limb) void {
2788 @setRuntimeSafety(debug_safety);2788 @setRuntimeSafety(debug_safety);
2789 assert(r.len >= a.len);2789 assert(r.len >= a.len);
2790 assert(r.len >= b.len);2790 assert(r.len >= b.len);
...@@ -2819,7 +2819,7 @@ fn llmulacc(comptime op: AccOp, opt_allocator: ?*Allocator, r: []Limb, a: []cons...@@ -2819,7 +2819,7 @@ fn llmulacc(comptime op: AccOp, opt_allocator: ?*Allocator, r: []Limb, a: []cons
2819/// The result is computed modulo `r.len`. When `r.len >= a.len + b.len`, no overflow occurs.2819/// The result is computed modulo `r.len`. When `r.len >= a.len + b.len`, no overflow occurs.
2820fn llmulaccKaratsuba(2820fn llmulaccKaratsuba(
2821 comptime op: AccOp,2821 comptime op: AccOp,
2822 allocator: *Allocator,2822 allocator: Allocator,
2823 r: []Limb,2823 r: []Limb,
2824 a: []const Limb,2824 a: []const Limb,
2825 b: []const Limb,2825 b: []const Limb,
lib/std/math/big/rational.zig+1-1
...@@ -29,7 +29,7 @@ pub const Rational = struct {...@@ -29,7 +29,7 @@ pub const Rational = struct {
2929
30 /// Create a new Rational. A small amount of memory will be allocated on initialization.30 /// Create a new Rational. A small amount of memory will be allocated on initialization.
31 /// This will be 2 * Int.default_capacity.31 /// This will be 2 * Int.default_capacity.
32 pub fn init(a: *Allocator) !Rational {32 pub fn init(a: Allocator) !Rational {
33 return Rational{33 return Rational{
34 .p = try Int.init(a),34 .p = try Int.init(a),
35 .q = try Int.initSet(a, 1),35 .q = try Int.initSet(a, 1),
lib/std/mem.zig+53-33
...@@ -37,24 +37,26 @@ pub const Allocator = @import("mem/Allocator.zig");...@@ -37,24 +37,26 @@ pub const Allocator = @import("mem/Allocator.zig");
37pub fn ValidationAllocator(comptime T: type) type {37pub fn ValidationAllocator(comptime T: type) type {
38 return struct {38 return struct {
39 const Self = @This();39 const Self = @This();
40 allocator: Allocator,40
41 underlying_allocator: T,41 underlying_allocator: T,
42 pub fn init(allocator: T) @This() {42
43 pub fn init(underlying_allocator: T) @This() {
43 return .{44 return .{
44 .allocator = .{45 .underlying_allocator = underlying_allocator,
45 .allocFn = alloc,
46 .resizeFn = resize,
47 },
48 .underlying_allocator = allocator,
49 };46 };
50 }47 }
51 fn getUnderlyingAllocatorPtr(self: *@This()) *Allocator {48
52 if (T == *Allocator) return self.underlying_allocator;49 pub fn allocator(self: *Self) Allocator {
53 if (*T == *Allocator) return &self.underlying_allocator;50 return Allocator.init(self, alloc, resize, free);
54 return &self.underlying_allocator.allocator;
55 }51 }
52
53 fn getUnderlyingAllocatorPtr(self: *Self) Allocator {
54 if (T == Allocator) return self.underlying_allocator;
55 return self.underlying_allocator.allocator();
56 }
57
56 pub fn alloc(58 pub fn alloc(
57 allocator: *Allocator,59 self: *Self,
58 n: usize,60 n: usize,
59 ptr_align: u29,61 ptr_align: u29,
60 len_align: u29,62 len_align: u29,
...@@ -67,9 +69,8 @@ pub fn ValidationAllocator(comptime T: type) type {...@@ -67,9 +69,8 @@ pub fn ValidationAllocator(comptime T: type) type {
67 assert(n >= len_align);69 assert(n >= len_align);
68 }70 }
6971
70 const self = @fieldParentPtr(@This(), "allocator", allocator);
71 const underlying = self.getUnderlyingAllocatorPtr();72 const underlying = self.getUnderlyingAllocatorPtr();
72 const result = try underlying.allocFn(underlying, n, ptr_align, len_align, ret_addr);73 const result = try underlying.rawAlloc(n, ptr_align, len_align, ret_addr);
73 assert(mem.isAligned(@ptrToInt(result.ptr), ptr_align));74 assert(mem.isAligned(@ptrToInt(result.ptr), ptr_align));
74 if (len_align == 0) {75 if (len_align == 0) {
75 assert(result.len == n);76 assert(result.len == n);
...@@ -79,22 +80,22 @@ pub fn ValidationAllocator(comptime T: type) type {...@@ -79,22 +80,22 @@ pub fn ValidationAllocator(comptime T: type) type {
79 }80 }
80 return result;81 return result;
81 }82 }
83
82 pub fn resize(84 pub fn resize(
83 allocator: *Allocator,85 self: *Self,
84 buf: []u8,86 buf: []u8,
85 buf_align: u29,87 buf_align: u29,
86 new_len: usize,88 new_len: usize,
87 len_align: u29,89 len_align: u29,
88 ret_addr: usize,90 ret_addr: usize,
89 ) Allocator.Error!usize {91 ) ?usize {
90 assert(buf.len > 0);92 assert(buf.len > 0);
91 if (len_align != 0) {93 if (len_align != 0) {
92 assert(mem.isAlignedAnyAlign(new_len, len_align));94 assert(mem.isAlignedAnyAlign(new_len, len_align));
93 assert(new_len >= len_align);95 assert(new_len >= len_align);
94 }96 }
95 const self = @fieldParentPtr(@This(), "allocator", allocator);
96 const underlying = self.getUnderlyingAllocatorPtr();97 const underlying = self.getUnderlyingAllocatorPtr();
97 const result = try underlying.resizeFn(underlying, buf, buf_align, new_len, len_align, ret_addr);98 const result = underlying.rawResize(buf, buf_align, new_len, len_align, ret_addr) orelse return null;
98 if (len_align == 0) {99 if (len_align == 0) {
99 assert(result == new_len);100 assert(result == new_len);
100 } else {101 } else {
...@@ -103,7 +104,20 @@ pub fn ValidationAllocator(comptime T: type) type {...@@ -103,7 +104,20 @@ pub fn ValidationAllocator(comptime T: type) type {
103 }104 }
104 return result;105 return result;
105 }106 }
106 pub usingnamespace if (T == *Allocator or !@hasDecl(T, "reset")) struct {} else struct {107
108 pub fn free(
109 self: *Self,
110 buf: []u8,
111 buf_align: u29,
112 ret_addr: usize,
113 ) void {
114 _ = self;
115 _ = buf_align;
116 _ = ret_addr;
117 assert(buf.len > 0);
118 }
119
120 pub usingnamespace if (T == Allocator or !@hasDecl(T, "reset")) struct {} else struct {
107 pub fn reset(self: *Self) void {121 pub fn reset(self: *Self) void {
108 self.underlying_allocator.reset();122 self.underlying_allocator.reset();
109 }123 }
...@@ -130,12 +144,18 @@ pub fn alignAllocLen(full_len: usize, alloc_len: usize, len_align: u29) usize {...@@ -130,12 +144,18 @@ pub fn alignAllocLen(full_len: usize, alloc_len: usize, len_align: u29) usize {
130 return adjusted;144 return adjusted;
131}145}
132146
133var failAllocator = Allocator{147const fail_allocator = Allocator{
134 .allocFn = failAllocatorAlloc,148 .ptr = undefined,
135 .resizeFn = Allocator.noResize,149 .vtable = &failAllocator_vtable,
150};
151
152const failAllocator_vtable = Allocator.VTable{
153 .alloc = failAllocatorAlloc,
154 .resize = Allocator.NoResize(c_void).noResize,
155 .free = Allocator.NoOpFree(c_void).noOpFree,
136};156};
137fn failAllocatorAlloc(self: *Allocator, n: usize, alignment: u29, len_align: u29, ra: usize) Allocator.Error![]u8 {157
138 _ = self;158fn failAllocatorAlloc(_: *c_void, n: usize, alignment: u29, len_align: u29, ra: usize) Allocator.Error![]u8 {
139 _ = n;159 _ = n;
140 _ = alignment;160 _ = alignment;
141 _ = len_align;161 _ = len_align;
...@@ -144,8 +164,8 @@ fn failAllocatorAlloc(self: *Allocator, n: usize, alignment: u29, len_align: u29...@@ -144,8 +164,8 @@ fn failAllocatorAlloc(self: *Allocator, n: usize, alignment: u29, len_align: u29
144}164}
145165
146test "mem.Allocator basics" {166test "mem.Allocator basics" {
147 try testing.expectError(error.OutOfMemory, failAllocator.alloc(u8, 1));167 try testing.expectError(error.OutOfMemory, fail_allocator.alloc(u8, 1));
148 try testing.expectError(error.OutOfMemory, failAllocator.allocSentinel(u8, 1, 0));168 try testing.expectError(error.OutOfMemory, fail_allocator.allocSentinel(u8, 1, 0));
149}169}
150170
151test "Allocator.resize" {171test "Allocator.resize" {
...@@ -168,7 +188,7 @@ test "Allocator.resize" {...@@ -168,7 +188,7 @@ test "Allocator.resize" {
168 defer testing.allocator.free(values);188 defer testing.allocator.free(values);
169189
170 for (values) |*v, i| v.* = @intCast(T, i);190 for (values) |*v, i| v.* = @intCast(T, i);
171 values = try testing.allocator.resize(values, values.len + 10);191 values = testing.allocator.resize(values, values.len + 10) orelse return error.OutOfMemory;
172 try testing.expect(values.len == 110);192 try testing.expect(values.len == 110);
173 }193 }
174194
...@@ -183,7 +203,7 @@ test "Allocator.resize" {...@@ -183,7 +203,7 @@ test "Allocator.resize" {
183 defer testing.allocator.free(values);203 defer testing.allocator.free(values);
184204
185 for (values) |*v, i| v.* = @intToFloat(T, i);205 for (values) |*v, i| v.* = @intToFloat(T, i);
186 values = try testing.allocator.resize(values, values.len + 10);206 values = testing.allocator.resize(values, values.len + 10) orelse return error.OutOfMemory;
187 try testing.expect(values.len == 110);207 try testing.expect(values.len == 110);
188 }208 }
189}209}
...@@ -1786,18 +1806,18 @@ pub fn SplitIterator(comptime T: type) type {...@@ -1786,18 +1806,18 @@ pub fn SplitIterator(comptime T: type) type {
17861806
1787/// Naively combines a series of slices with a separator.1807/// Naively combines a series of slices with a separator.
1788/// Allocates memory for the result, which must be freed by the caller.1808/// Allocates memory for the result, which must be freed by the caller.
1789pub fn join(allocator: *Allocator, separator: []const u8, slices: []const []const u8) ![]u8 {1809pub fn join(allocator: Allocator, separator: []const u8, slices: []const []const u8) ![]u8 {
1790 return joinMaybeZ(allocator, separator, slices, false);1810 return joinMaybeZ(allocator, separator, slices, false);
1791}1811}
17921812
1793/// Naively combines a series of slices with a separator and null terminator.1813/// Naively combines a series of slices with a separator and null terminator.
1794/// Allocates memory for the result, which must be freed by the caller.1814/// Allocates memory for the result, which must be freed by the caller.
1795pub fn joinZ(allocator: *Allocator, separator: []const u8, slices: []const []const u8) ![:0]u8 {1815pub fn joinZ(allocator: Allocator, separator: []const u8, slices: []const []const u8) ![:0]u8 {
1796 const out = try joinMaybeZ(allocator, separator, slices, true);1816 const out = try joinMaybeZ(allocator, separator, slices, true);
1797 return out[0 .. out.len - 1 :0];1817 return out[0 .. out.len - 1 :0];
1798}1818}
17991819
1800fn joinMaybeZ(allocator: *Allocator, separator: []const u8, slices: []const []const u8, zero: bool) ![]u8 {1820fn joinMaybeZ(allocator: Allocator, separator: []const u8, slices: []const []const u8, zero: bool) ![]u8 {
1801 if (slices.len == 0) return if (zero) try allocator.dupe(u8, &[1]u8{0}) else &[0]u8{};1821 if (slices.len == 0) return if (zero) try allocator.dupe(u8, &[1]u8{0}) else &[0]u8{};
18021822
1803 const total_len = blk: {1823 const total_len = blk: {
...@@ -1876,7 +1896,7 @@ test "mem.joinZ" {...@@ -1876,7 +1896,7 @@ test "mem.joinZ" {
1876}1896}
18771897
1878/// Copies each T from slices into a new slice that exactly holds all the elements.1898/// Copies each T from slices into a new slice that exactly holds all the elements.
1879pub fn concat(allocator: *Allocator, comptime T: type, slices: []const []const T) ![]T {1899pub fn concat(allocator: Allocator, comptime T: type, slices: []const []const T) ![]T {
1880 if (slices.len == 0) return &[0]T{};1900 if (slices.len == 0) return &[0]T{};
18811901
1882 const total_len = blk: {1902 const total_len = blk: {
...@@ -2318,7 +2338,7 @@ test "replacementSize" {...@@ -2318,7 +2338,7 @@ test "replacementSize" {
2318}2338}
23192339
2320/// Perform a replacement on an allocated buffer of pre-determined size. Caller must free returned memory.2340/// Perform a replacement on an allocated buffer of pre-determined size. Caller must free returned memory.
2321pub fn replaceOwned(comptime T: type, allocator: *Allocator, input: []const T, needle: []const T, replacement: []const T) Allocator.Error![]T {2341pub fn replaceOwned(comptime T: type, allocator: Allocator, input: []const T, needle: []const T, replacement: []const T) Allocator.Error![]T {
2322 var output = try allocator.alloc(T, replacementSize(T, input, needle, replacement));2342 var output = try allocator.alloc(T, replacementSize(T, input, needle, replacement));
2323 _ = replace(T, input, needle, replacement, output);2343 _ = replace(T, input, needle, replacement, output);
2324 return output;2344 return output;
lib/std/mem/Allocator.zig+205-164
...@@ -5,155 +5,168 @@ const assert = std.debug.assert;...@@ -5,155 +5,168 @@ const assert = std.debug.assert;
5const math = std.math;5const math = std.math;
6const mem = std.mem;6const mem = std.mem;
7const Allocator = @This();7const Allocator = @This();
8const builtin = @import("builtin");
89
9pub const Error = error{OutOfMemory};10pub const Error = error{OutOfMemory};
1011
11/// Attempt to allocate at least `len` bytes aligned to `ptr_align`.12// The type erased pointer to the allocator implementation
12///13ptr: *c_void,
13/// If `len_align` is `0`, then the length returned MUST be exactly `len` bytes,14vtable: *const VTable,
14/// otherwise, the length must be aligned to `len_align`.15
15///16pub const VTable = struct {
16/// `len` must be greater than or equal to `len_align` and must be aligned by `len_align`.17 /// Attempt to allocate at least `len` bytes aligned to `ptr_align`.
17///18 ///
18/// `ret_addr` is optionally provided as the first return address of the allocation call stack.19 /// If `len_align` is `0`, then the length returned MUST be exactly `len` bytes,
19/// If the value is `0` it means no return address has been provided.20 /// otherwise, the length must be aligned to `len_align`.
20allocFn: fn (self: *Allocator, len: usize, ptr_align: u29, len_align: u29, ret_addr: usize) Error![]u8,21 ///
22 /// `len` must be greater than or equal to `len_align` and must be aligned by `len_align`.
23 ///
24 /// `ret_addr` is optionally provided as the first return address of the allocation call stack.
25 /// If the value is `0` it means no return address has been provided.
26 alloc: fn (ptr: *c_void, len: usize, ptr_align: u29, len_align: u29, ret_addr: usize) Error![]u8,
27
28 /// Attempt to expand or shrink memory in place. `buf.len` must equal the most recent
29 /// length returned by `alloc` or `resize`. `buf_align` must equal the same value
30 /// that was passed as the `ptr_align` parameter to the original `alloc` call.
31 ///
32 /// `null` can only be returned if `new_len` is greater than `buf.len`.
33 /// If `buf` cannot be expanded to accomodate `new_len`, then the allocation MUST be
34 /// unmodified and `null` MUST be returned.
35 ///
36 /// If `len_align` is `0`, then the length returned MUST be exactly `len` bytes,
37 /// otherwise, the length must be aligned to `len_align`. Note that `len_align` does *not*
38 /// provide a way to modify the alignment of a pointer. Rather it provides an API for
39 /// accepting more bytes of memory from the allocator than requested.
40 ///
41 /// `new_len` must be greater than zero, greater than or equal to `len_align` and must be aligned by `len_align`.
42 ///
43 /// `ret_addr` is optionally provided as the first return address of the allocation call stack.
44 /// If the value is `0` it means no return address has been provided.
45 resize: fn (ptr: *c_void, buf: []u8, buf_align: u29, new_len: usize, len_align: u29, ret_addr: usize) ?usize,
46
47 /// Free and invalidate a buffer. `buf.len` must equal the most recent length returned by `alloc` or `resize`.
48 /// `buf_align` must equal the same value that was passed as the `ptr_align` parameter to the original `alloc` call.
49 ///
50 /// `ret_addr` is optionally provided as the first return address of the allocation call stack.
51 /// If the value is `0` it means no return address has been provided.
52 free: fn (ptr: *c_void, buf: []u8, buf_align: u29, ret_addr: usize) void,
53};
54
55pub fn init(
56 pointer: anytype,
57 comptime allocFn: fn (ptr: @TypeOf(pointer), len: usize, ptr_align: u29, len_align: u29, ret_addr: usize) Error![]u8,
58 comptime resizeFn: fn (ptr: @TypeOf(pointer), buf: []u8, buf_align: u29, new_len: usize, len_align: u29, ret_addr: usize) ?usize,
59 comptime freeFn: fn (ptr: @TypeOf(pointer), buf: []u8, buf_align: u29, ret_addr: usize) void,
60) Allocator {
61 const Ptr = @TypeOf(pointer);
62 const ptr_info = @typeInfo(Ptr);
63
64 assert(ptr_info == .Pointer); // Must be a pointer
65 assert(ptr_info.Pointer.size == .One); // Must be a single-item pointer
66
67 const alignment = ptr_info.Pointer.alignment;
68
69 const gen = struct {
70 fn alloc(ptr: *c_void, len: usize, ptr_align: u29, len_align: u29, ret_addr: usize) Error![]u8 {
71 const self = @ptrCast(Ptr, @alignCast(alignment, ptr));
72 return @call(.{ .modifier = .always_inline }, allocFn, .{ self, len, ptr_align, len_align, ret_addr });
73 }
74 fn resize(ptr: *c_void, buf: []u8, buf_align: u29, new_len: usize, len_align: u29, ret_addr: usize) ?usize {
75 assert(new_len != 0);
76 const self = @ptrCast(Ptr, @alignCast(alignment, ptr));
77 return @call(.{ .modifier = .always_inline }, resizeFn, .{ self, buf, buf_align, new_len, len_align, ret_addr });
78 }
79 fn free(ptr: *c_void, buf: []u8, buf_align: u29, ret_addr: usize) void {
80 const self = @ptrCast(Ptr, @alignCast(alignment, ptr));
81 @call(.{ .modifier = .always_inline }, freeFn, .{ self, buf, buf_align, ret_addr });
82 }
83 };
2184
22/// Attempt to expand or shrink memory in place. `buf.len` must equal the most recent85 const vtable = VTable{
23/// length returned by `allocFn` or `resizeFn`. `buf_align` must equal the same value86 .alloc = gen.alloc,
24/// that was passed as the `ptr_align` parameter to the original `allocFn` call.87 .resize = gen.resize,
25///88 .free = gen.free,
26/// Passing a `new_len` of 0 frees and invalidates the buffer such that it can no89 };
27/// longer be passed to `resizeFn`.
28///
29/// error.OutOfMemory can only be returned if `new_len` is greater than `buf.len`.
30/// If `buf` cannot be expanded to accomodate `new_len`, then the allocation MUST be
31/// unmodified and error.OutOfMemory MUST be returned.
32///
33/// If `len_align` is `0`, then the length returned MUST be exactly `len` bytes,
34/// otherwise, the length must be aligned to `len_align`. Note that `len_align` does *not*
35/// provide a way to modify the alignment of a pointer. Rather it provides an API for
36/// accepting more bytes of memory from the allocator than requested.
37///
38/// `new_len` must be greater than or equal to `len_align` and must be aligned by `len_align`.
39///
40/// `ret_addr` is optionally provided as the first return address of the allocation call stack.
41/// If the value is `0` it means no return address has been provided.
42resizeFn: fn (self: *Allocator, buf: []u8, buf_align: u29, new_len: usize, len_align: u29, ret_addr: usize) Error!usize,
4390
44/// Set to resizeFn if in-place resize is not supported.91 return .{
45pub fn noResize(92 .ptr = pointer,
46 self: *Allocator,93 .vtable = &vtable,
47 buf: []u8,94 };
48 buf_align: u29,
49 new_len: usize,
50 len_align: u29,
51 ret_addr: usize,
52) Error!usize {
53 _ = self;
54 _ = buf_align;
55 _ = len_align;
56 _ = ret_addr;
57 if (new_len > buf.len)
58 return error.OutOfMemory;
59 return new_len;
60}95}
6196
62/// Realloc is used to modify the size or alignment of an existing allocation,97/// Set resizeFn to `NoResize(AllocatorType).noResize` if in-place resize is not supported.
63/// as well as to provide the allocator with an opportunity to move an allocation98pub fn NoResize(comptime AllocatorType: type) type {
64/// to a better location.99 return struct {
65/// When the size/alignment is greater than the previous allocation, this function100 pub fn noResize(
66/// returns `error.OutOfMemory` when the requested new allocation could not be granted.101 self: *AllocatorType,
67/// When the size/alignment is less than or equal to the previous allocation,102 buf: []u8,
68/// this function returns `error.OutOfMemory` when the allocator decides the client103 buf_align: u29,
69/// would be better off keeping the extra alignment/size. Clients will call104 new_len: usize,
70/// `resizeFn` when they require the allocator to track a new alignment/size,105 len_align: u29,
71/// and so this function should only return success when the allocator considers106 ret_addr: usize,
72/// the reallocation desirable from the allocator's perspective.107 ) ?usize {
73/// As an example, `std.ArrayList` tracks a "capacity", and therefore can handle108 _ = self;
74/// reallocation failure, even when `new_n` <= `old_mem.len`. A `FixedBufferAllocator`109 _ = buf_align;
75/// would always return `error.OutOfMemory` for `reallocFn` when the size/alignment110 _ = len_align;
76/// is less than or equal to the old allocation, because it cannot reclaim the memory,111 _ = ret_addr;
77/// and thus the `std.ArrayList` would be better off retaining its capacity.112 return if (new_len > buf.len) null else new_len;
78/// When `reallocFn` returns,113 }
79/// `return_value[0..min(old_mem.len, new_byte_count)]` must be the same114 };
80/// as `old_mem` was when `reallocFn` is called. The bytes of115}
81/// `return_value[old_mem.len..]` have undefined values.
82/// The returned slice must have its pointer aligned at least to `new_alignment` bytes.
83pub fn reallocBytes(
84 self: *Allocator,
85 /// Guaranteed to be the same as what was returned from most recent call to
86 /// `allocFn` or `resizeFn`.
87 /// If `old_mem.len == 0` then this is a new allocation and `new_byte_count`
88 /// is guaranteed to be >= 1.
89 old_mem: []u8,
90 /// If `old_mem.len == 0` then this is `undefined`, otherwise:
91 /// Guaranteed to be the same as what was passed to `allocFn`.
92 /// Guaranteed to be >= 1.
93 /// Guaranteed to be a power of 2.
94 old_alignment: u29,
95 /// If `new_byte_count` is 0 then this is a free and it is guaranteed that
96 /// `old_mem.len != 0`.
97 new_byte_count: usize,
98 /// Guaranteed to be >= 1.
99 /// Guaranteed to be a power of 2.
100 /// Returned slice's pointer must have this alignment.
101 new_alignment: u29,
102 /// 0 indicates the length of the slice returned MUST match `new_byte_count` exactly
103 /// non-zero means the length of the returned slice must be aligned by `len_align`
104 /// `new_len` must be aligned by `len_align`
105 len_align: u29,
106 return_address: usize,
107) Error![]u8 {
108 if (old_mem.len == 0) {
109 const new_mem = try self.allocFn(self, new_byte_count, new_alignment, len_align, return_address);
110 // TODO: https://github.com/ziglang/zig/issues/4298
111 @memset(new_mem.ptr, undefined, new_byte_count);
112 return new_mem;
113 }
114116
115 if (mem.isAligned(@ptrToInt(old_mem.ptr), new_alignment)) {117/// Set freeFn to `NoOpFree(AllocatorType).noOpFree` if free is a no-op.
116 if (new_byte_count <= old_mem.len) {118pub fn NoOpFree(comptime AllocatorType: type) type {
117 const shrunk_len = self.shrinkBytes(old_mem, old_alignment, new_byte_count, len_align, return_address);119 return struct {
118 return old_mem.ptr[0..shrunk_len];120 pub fn noOpFree(
121 self: *AllocatorType,
122 buf: []u8,
123 buf_align: u29,
124 ret_addr: usize,
125 ) void {
126 _ = self;
127 _ = buf;
128 _ = buf_align;
129 _ = ret_addr;
119 }130 }
120 if (self.resizeFn(self, old_mem, old_alignment, new_byte_count, len_align, return_address)) |resized_len| {131 };
121 assert(resized_len >= new_byte_count);
122 // TODO: https://github.com/ziglang/zig/issues/4298
123 @memset(old_mem.ptr + new_byte_count, undefined, resized_len - new_byte_count);
124 return old_mem.ptr[0..resized_len];
125 } else |_| {}
126 }
127 if (new_byte_count <= old_mem.len and new_alignment <= old_alignment) {
128 return error.OutOfMemory;
129 }
130 return self.moveBytes(old_mem, old_alignment, new_byte_count, new_alignment, len_align, return_address);
131}132}
132133
133/// Move the given memory to a new location in the given allocator to accomodate a new134/// Set freeFn to `PanicFree(AllocatorType).noOpFree` if free is not a supported operation.
134/// size and alignment.135pub fn PanicFree(comptime AllocatorType: type) type {
135fn moveBytes(136 return struct {
136 self: *Allocator,137 pub fn noOpFree(
137 old_mem: []u8,138 self: *AllocatorType,
138 old_align: u29,139 buf: []u8,
139 new_len: usize,140 buf_align: u29,
140 new_alignment: u29,141 ret_addr: usize,
141 len_align: u29,142 ) void {
142 return_address: usize,143 _ = self;
143) Error![]u8 {144 _ = buf;
144 assert(old_mem.len > 0);145 _ = buf_align;
145 assert(new_len > 0);146 _ = ret_addr;
146 const new_mem = try self.allocFn(self, new_len, new_alignment, len_align, return_address);147 @panic("free is not a supported operation for the allocator: " ++ @typeName(AllocatorType));
147 @memcpy(new_mem.ptr, old_mem.ptr, math.min(new_len, old_mem.len));148 }
148 // TODO https://github.com/ziglang/zig/issues/4298149 };
149 @memset(old_mem.ptr, undefined, old_mem.len);150}
150 _ = self.shrinkBytes(old_mem, old_align, 0, 0, return_address);151
151 return new_mem;152/// This function is not intended to be called except from within the implementation of an Allocator
153pub inline fn rawAlloc(self: Allocator, len: usize, ptr_align: u29, len_align: u29, ret_addr: usize) Error![]u8 {
154 return self.vtable.alloc(self.ptr, len, ptr_align, len_align, ret_addr);
155}
156
157/// This function is not intended to be called except from within the implementation of an Allocator
158pub inline fn rawResize(self: Allocator, buf: []u8, buf_align: u29, new_len: usize, len_align: u29, ret_addr: usize) ?usize {
159 return self.vtable.resize(self.ptr, buf, buf_align, new_len, len_align, ret_addr);
160}
161
162/// This function is not intended to be called except from within the implementation of an Allocator
163pub inline fn rawFree(self: Allocator, buf: []u8, buf_align: u29, ret_addr: usize) void {
164 return self.vtable.free(self.ptr, buf, buf_align, ret_addr);
152}165}
153166
154/// Returns a pointer to undefined memory.167/// Returns a pointer to undefined memory.
155/// Call `destroy` with the result to free the memory.168/// Call `destroy` with the result to free the memory.
156pub fn create(self: *Allocator, comptime T: type) Error!*T {169pub fn create(self: Allocator, comptime T: type) Error!*T {
157 if (@sizeOf(T) == 0) return @as(*T, undefined);170 if (@sizeOf(T) == 0) return @as(*T, undefined);
158 const slice = try self.allocAdvancedWithRetAddr(T, null, 1, .exact, @returnAddress());171 const slice = try self.allocAdvancedWithRetAddr(T, null, 1, .exact, @returnAddress());
159 return &slice[0];172 return &slice[0];
...@@ -161,12 +174,12 @@ pub fn create(self: *Allocator, comptime T: type) Error!*T {...@@ -161,12 +174,12 @@ pub fn create(self: *Allocator, comptime T: type) Error!*T {
161174
162/// `ptr` should be the return value of `create`, or otherwise175/// `ptr` should be the return value of `create`, or otherwise
163/// have the same address and alignment property.176/// have the same address and alignment property.
164pub fn destroy(self: *Allocator, ptr: anytype) void {177pub fn destroy(self: Allocator, ptr: anytype) void {
165 const info = @typeInfo(@TypeOf(ptr)).Pointer;178 const info = @typeInfo(@TypeOf(ptr)).Pointer;
166 const T = info.child;179 const T = info.child;
167 if (@sizeOf(T) == 0) return;180 if (@sizeOf(T) == 0) return;
168 const non_const_ptr = @intToPtr([*]u8, @ptrToInt(ptr));181 const non_const_ptr = @intToPtr([*]u8, @ptrToInt(ptr));
169 _ = self.shrinkBytes(non_const_ptr[0..@sizeOf(T)], info.alignment, 0, 0, @returnAddress());182 self.rawFree(non_const_ptr[0..@sizeOf(T)], info.alignment, @returnAddress());
170}183}
171184
172/// Allocates an array of `n` items of type `T` and sets all the185/// Allocates an array of `n` items of type `T` and sets all the
...@@ -177,12 +190,12 @@ pub fn destroy(self: *Allocator, ptr: anytype) void {...@@ -177,12 +190,12 @@ pub fn destroy(self: *Allocator, ptr: anytype) void {
177/// call `free` when done.190/// call `free` when done.
178///191///
179/// For allocating a single item, see `create`.192/// For allocating a single item, see `create`.
180pub fn alloc(self: *Allocator, comptime T: type, n: usize) Error![]T {193pub fn alloc(self: Allocator, comptime T: type, n: usize) Error![]T {
181 return self.allocAdvancedWithRetAddr(T, null, n, .exact, @returnAddress());194 return self.allocAdvancedWithRetAddr(T, null, n, .exact, @returnAddress());
182}195}
183196
184pub fn allocWithOptions(197pub fn allocWithOptions(
185 self: *Allocator,198 self: Allocator,
186 comptime Elem: type,199 comptime Elem: type,
187 n: usize,200 n: usize,
188 /// null means naturally aligned201 /// null means naturally aligned
...@@ -193,7 +206,7 @@ pub fn allocWithOptions(...@@ -193,7 +206,7 @@ pub fn allocWithOptions(
193}206}
194207
195pub fn allocWithOptionsRetAddr(208pub fn allocWithOptionsRetAddr(
196 self: *Allocator,209 self: Allocator,
197 comptime Elem: type,210 comptime Elem: type,
198 n: usize,211 n: usize,
199 /// null means naturally aligned212 /// null means naturally aligned
...@@ -227,7 +240,7 @@ fn AllocWithOptionsPayload(comptime Elem: type, comptime alignment: ?u29, compti...@@ -227,7 +240,7 @@ fn AllocWithOptionsPayload(comptime Elem: type, comptime alignment: ?u29, compti
227///240///
228/// For allocating a single item, see `create`.241/// For allocating a single item, see `create`.
229pub fn allocSentinel(242pub fn allocSentinel(
230 self: *Allocator,243 self: Allocator,
231 comptime Elem: type,244 comptime Elem: type,
232 n: usize,245 n: usize,
233 comptime sentinel: Elem,246 comptime sentinel: Elem,
...@@ -236,7 +249,7 @@ pub fn allocSentinel(...@@ -236,7 +249,7 @@ pub fn allocSentinel(
236}249}
237250
238pub fn alignedAlloc(251pub fn alignedAlloc(
239 self: *Allocator,252 self: Allocator,
240 comptime T: type,253 comptime T: type,
241 /// null means naturally aligned254 /// null means naturally aligned
242 comptime alignment: ?u29,255 comptime alignment: ?u29,
...@@ -246,7 +259,7 @@ pub fn alignedAlloc(...@@ -246,7 +259,7 @@ pub fn alignedAlloc(
246}259}
247260
248pub fn allocAdvanced(261pub fn allocAdvanced(
249 self: *Allocator,262 self: Allocator,
250 comptime T: type,263 comptime T: type,
251 /// null means naturally aligned264 /// null means naturally aligned
252 comptime alignment: ?u29,265 comptime alignment: ?u29,
...@@ -259,7 +272,7 @@ pub fn allocAdvanced(...@@ -259,7 +272,7 @@ pub fn allocAdvanced(
259pub const Exact = enum { exact, at_least };272pub const Exact = enum { exact, at_least };
260273
261pub fn allocAdvancedWithRetAddr(274pub fn allocAdvancedWithRetAddr(
262 self: *Allocator,275 self: Allocator,
263 comptime T: type,276 comptime T: type,
264 /// null means naturally aligned277 /// null means naturally aligned
265 comptime alignment: ?u29,278 comptime alignment: ?u29,
...@@ -285,7 +298,7 @@ pub fn allocAdvancedWithRetAddr(...@@ -285,7 +298,7 @@ pub fn allocAdvancedWithRetAddr(
285 .exact => 0,298 .exact => 0,
286 .at_least => size_of_T,299 .at_least => size_of_T,
287 };300 };
288 const byte_slice = try self.allocFn(self, byte_count, a, len_align, return_address);301 const byte_slice = try self.rawAlloc(byte_count, a, len_align, return_address);
289 switch (exact) {302 switch (exact) {
290 .exact => assert(byte_slice.len == byte_count),303 .exact => assert(byte_slice.len == byte_count),
291 .at_least => assert(byte_slice.len >= byte_count),304 .at_least => assert(byte_slice.len >= byte_count),
...@@ -301,7 +314,7 @@ pub fn allocAdvancedWithRetAddr(...@@ -301,7 +314,7 @@ pub fn allocAdvancedWithRetAddr(
301}314}
302315
303/// Increases or decreases the size of an allocation. It is guaranteed to not move the pointer.316/// Increases or decreases the size of an allocation. It is guaranteed to not move the pointer.
304pub fn resize(self: *Allocator, old_mem: anytype, new_n: usize) Error!@TypeOf(old_mem) {317pub fn resize(self: Allocator, old_mem: anytype, new_n: usize) ?@TypeOf(old_mem) {
305 const Slice = @typeInfo(@TypeOf(old_mem)).Pointer;318 const Slice = @typeInfo(@TypeOf(old_mem)).Pointer;
306 const T = Slice.child;319 const T = Slice.child;
307 if (new_n == 0) {320 if (new_n == 0) {
...@@ -309,8 +322,8 @@ pub fn resize(self: *Allocator, old_mem: anytype, new_n: usize) Error!@TypeOf(ol...@@ -309,8 +322,8 @@ pub fn resize(self: *Allocator, old_mem: anytype, new_n: usize) Error!@TypeOf(ol
309 return &[0]T{};322 return &[0]T{};
310 }323 }
311 const old_byte_slice = mem.sliceAsBytes(old_mem);324 const old_byte_slice = mem.sliceAsBytes(old_mem);
312 const new_byte_count = math.mul(usize, @sizeOf(T), new_n) catch return Error.OutOfMemory;325 const new_byte_count = math.mul(usize, @sizeOf(T), new_n) catch return null;
313 const rc = try self.resizeFn(self, old_byte_slice, Slice.alignment, new_byte_count, 0, @returnAddress());326 const rc = self.rawResize(old_byte_slice, Slice.alignment, new_byte_count, 0, @returnAddress()) orelse return null;
314 assert(rc == new_byte_count);327 assert(rc == new_byte_count);
315 const new_byte_slice = old_byte_slice.ptr[0..new_byte_count];328 const new_byte_slice = old_byte_slice.ptr[0..new_byte_count];
316 return mem.bytesAsSlice(T, new_byte_slice);329 return mem.bytesAsSlice(T, new_byte_slice);
...@@ -326,7 +339,7 @@ pub fn resize(self: *Allocator, old_mem: anytype, new_n: usize) Error!@TypeOf(ol...@@ -326,7 +339,7 @@ pub fn resize(self: *Allocator, old_mem: anytype, new_n: usize) Error!@TypeOf(ol
326/// in `std.ArrayList.shrink`.339/// in `std.ArrayList.shrink`.
327/// If you need guaranteed success, call `shrink`.340/// If you need guaranteed success, call `shrink`.
328/// If `new_n` is 0, this is the same as `free` and it always succeeds.341/// If `new_n` is 0, this is the same as `free` and it always succeeds.
329pub fn realloc(self: *Allocator, old_mem: anytype, new_n: usize) t: {342pub fn realloc(self: Allocator, old_mem: anytype, new_n: usize) t: {
330 const Slice = @typeInfo(@TypeOf(old_mem)).Pointer;343 const Slice = @typeInfo(@TypeOf(old_mem)).Pointer;
331 break :t Error![]align(Slice.alignment) Slice.child;344 break :t Error![]align(Slice.alignment) Slice.child;
332} {345} {
...@@ -334,7 +347,7 @@ pub fn realloc(self: *Allocator, old_mem: anytype, new_n: usize) t: {...@@ -334,7 +347,7 @@ pub fn realloc(self: *Allocator, old_mem: anytype, new_n: usize) t: {
334 return self.reallocAdvancedWithRetAddr(old_mem, old_alignment, new_n, .exact, @returnAddress());347 return self.reallocAdvancedWithRetAddr(old_mem, old_alignment, new_n, .exact, @returnAddress());
335}348}
336349
337pub fn reallocAtLeast(self: *Allocator, old_mem: anytype, new_n: usize) t: {350pub fn reallocAtLeast(self: Allocator, old_mem: anytype, new_n: usize) t: {
338 const Slice = @typeInfo(@TypeOf(old_mem)).Pointer;351 const Slice = @typeInfo(@TypeOf(old_mem)).Pointer;
339 break :t Error![]align(Slice.alignment) Slice.child;352 break :t Error![]align(Slice.alignment) Slice.child;
340} {353} {
...@@ -346,7 +359,7 @@ pub fn reallocAtLeast(self: *Allocator, old_mem: anytype, new_n: usize) t: {...@@ -346,7 +359,7 @@ pub fn reallocAtLeast(self: *Allocator, old_mem: anytype, new_n: usize) t: {
346/// a new alignment, which can be larger, smaller, or the same as the old359/// a new alignment, which can be larger, smaller, or the same as the old
347/// allocation.360/// allocation.
348pub fn reallocAdvanced(361pub fn reallocAdvanced(
349 self: *Allocator,362 self: Allocator,
350 old_mem: anytype,363 old_mem: anytype,
351 comptime new_alignment: u29,364 comptime new_alignment: u29,
352 new_n: usize,365 new_n: usize,
...@@ -356,7 +369,7 @@ pub fn reallocAdvanced(...@@ -356,7 +369,7 @@ pub fn reallocAdvanced(
356}369}
357370
358pub fn reallocAdvancedWithRetAddr(371pub fn reallocAdvancedWithRetAddr(
359 self: *Allocator,372 self: Allocator,
360 old_mem: anytype,373 old_mem: anytype,
361 comptime new_alignment: u29,374 comptime new_alignment: u29,
362 new_n: usize,375 new_n: usize,
...@@ -380,8 +393,31 @@ pub fn reallocAdvancedWithRetAddr(...@@ -380,8 +393,31 @@ pub fn reallocAdvancedWithRetAddr(
380 .exact => 0,393 .exact => 0,
381 .at_least => @sizeOf(T),394 .at_least => @sizeOf(T),
382 };395 };
383 const new_byte_slice = try self.reallocBytes(old_byte_slice, Slice.alignment, byte_count, new_alignment, len_align, return_address);396
384 return mem.bytesAsSlice(T, @alignCast(new_alignment, new_byte_slice));397 if (mem.isAligned(@ptrToInt(old_byte_slice.ptr), new_alignment)) {
398 if (byte_count <= old_byte_slice.len) {
399 const shrunk_len = self.shrinkBytes(old_byte_slice, Slice.alignment, byte_count, len_align, return_address);
400 return mem.bytesAsSlice(T, @alignCast(new_alignment, old_byte_slice.ptr[0..shrunk_len]));
401 }
402
403 if (self.rawResize(old_byte_slice, Slice.alignment, byte_count, len_align, return_address)) |resized_len| {
404 // TODO: https://github.com/ziglang/zig/issues/4298
405 @memset(old_byte_slice.ptr + byte_count, undefined, resized_len - byte_count);
406 return mem.bytesAsSlice(T, @alignCast(new_alignment, old_byte_slice.ptr[0..resized_len]));
407 }
408 }
409
410 if (byte_count <= old_byte_slice.len and new_alignment <= Slice.alignment) {
411 return error.OutOfMemory;
412 }
413
414 const new_mem = try self.rawAlloc(byte_count, new_alignment, len_align, return_address);
415 @memcpy(new_mem.ptr, old_byte_slice.ptr, math.min(byte_count, old_byte_slice.len));
416 // TODO https://github.com/ziglang/zig/issues/4298
417 @memset(old_byte_slice.ptr, undefined, old_byte_slice.len);
418 self.rawFree(old_byte_slice, Slice.alignment, return_address);
419
420 return mem.bytesAsSlice(T, @alignCast(new_alignment, new_mem));
385}421}
386422
387/// Prefer calling realloc to shrink if you can tolerate failure, such as423/// Prefer calling realloc to shrink if you can tolerate failure, such as
...@@ -389,7 +425,7 @@ pub fn reallocAdvancedWithRetAddr(...@@ -389,7 +425,7 @@ pub fn reallocAdvancedWithRetAddr(
389/// Shrink always succeeds, and `new_n` must be <= `old_mem.len`.425/// Shrink always succeeds, and `new_n` must be <= `old_mem.len`.
390/// Returned slice has same alignment as old_mem.426/// Returned slice has same alignment as old_mem.
391/// Shrinking to 0 is the same as calling `free`.427/// Shrinking to 0 is the same as calling `free`.
392pub fn shrink(self: *Allocator, old_mem: anytype, new_n: usize) t: {428pub fn shrink(self: Allocator, old_mem: anytype, new_n: usize) t: {
393 const Slice = @typeInfo(@TypeOf(old_mem)).Pointer;429 const Slice = @typeInfo(@TypeOf(old_mem)).Pointer;
394 break :t []align(Slice.alignment) Slice.child;430 break :t []align(Slice.alignment) Slice.child;
395} {431} {
...@@ -401,7 +437,7 @@ pub fn shrink(self: *Allocator, old_mem: anytype, new_n: usize) t: {...@@ -401,7 +437,7 @@ pub fn shrink(self: *Allocator, old_mem: anytype, new_n: usize) t: {
401/// a new alignment, which must be smaller or the same as the old437/// a new alignment, which must be smaller or the same as the old
402/// allocation.438/// allocation.
403pub fn alignedShrink(439pub fn alignedShrink(
404 self: *Allocator,440 self: Allocator,
405 old_mem: anytype,441 old_mem: anytype,
406 comptime new_alignment: u29,442 comptime new_alignment: u29,
407 new_n: usize,443 new_n: usize,
...@@ -413,7 +449,7 @@ pub fn alignedShrink(...@@ -413,7 +449,7 @@ pub fn alignedShrink(
413/// the return address of the first stack frame, which may be relevant for449/// the return address of the first stack frame, which may be relevant for
414/// allocators which collect stack traces.450/// allocators which collect stack traces.
415pub fn alignedShrinkWithRetAddr(451pub fn alignedShrinkWithRetAddr(
416 self: *Allocator,452 self: Allocator,
417 old_mem: anytype,453 old_mem: anytype,
418 comptime new_alignment: u29,454 comptime new_alignment: u29,
419 new_n: usize,455 new_n: usize,
...@@ -424,6 +460,11 @@ pub fn alignedShrinkWithRetAddr(...@@ -424,6 +460,11 @@ pub fn alignedShrinkWithRetAddr(
424460
425 if (new_n == old_mem.len)461 if (new_n == old_mem.len)
426 return old_mem;462 return old_mem;
463 if (new_n == 0) {
464 self.free(old_mem);
465 return @as([*]align(new_alignment) T, undefined)[0..0];
466 }
467
427 assert(new_n < old_mem.len);468 assert(new_n < old_mem.len);
428 assert(new_alignment <= Slice.alignment);469 assert(new_alignment <= Slice.alignment);
429470
...@@ -440,7 +481,7 @@ pub fn alignedShrinkWithRetAddr(...@@ -440,7 +481,7 @@ pub fn alignedShrinkWithRetAddr(
440481
441/// Free an array allocated with `alloc`. To free a single item,482/// Free an array allocated with `alloc`. To free a single item,
442/// see `destroy`.483/// see `destroy`.
443pub fn free(self: *Allocator, memory: anytype) void {484pub fn free(self: Allocator, memory: anytype) void {
444 const Slice = @typeInfo(@TypeOf(memory)).Pointer;485 const Slice = @typeInfo(@TypeOf(memory)).Pointer;
445 const bytes = mem.sliceAsBytes(memory);486 const bytes = mem.sliceAsBytes(memory);
446 const bytes_len = bytes.len + if (Slice.sentinel != null) @sizeOf(Slice.child) else 0;487 const bytes_len = bytes.len + if (Slice.sentinel != null) @sizeOf(Slice.child) else 0;
...@@ -448,30 +489,30 @@ pub fn free(self: *Allocator, memory: anytype) void {...@@ -448,30 +489,30 @@ pub fn free(self: *Allocator, memory: anytype) void {
448 const non_const_ptr = @intToPtr([*]u8, @ptrToInt(bytes.ptr));489 const non_const_ptr = @intToPtr([*]u8, @ptrToInt(bytes.ptr));
449 // TODO: https://github.com/ziglang/zig/issues/4298490 // TODO: https://github.com/ziglang/zig/issues/4298
450 @memset(non_const_ptr, undefined, bytes_len);491 @memset(non_const_ptr, undefined, bytes_len);
451 _ = self.shrinkBytes(non_const_ptr[0..bytes_len], Slice.alignment, 0, 0, @returnAddress());492 self.rawFree(non_const_ptr[0..bytes_len], Slice.alignment, @returnAddress());
452}493}
453494
454/// Copies `m` to newly allocated memory. Caller owns the memory.495/// Copies `m` to newly allocated memory. Caller owns the memory.
455pub fn dupe(allocator: *Allocator, comptime T: type, m: []const T) ![]T {496pub fn dupe(allocator: Allocator, comptime T: type, m: []const T) ![]T {
456 const new_buf = try allocator.alloc(T, m.len);497 const new_buf = try allocator.alloc(T, m.len);
457 mem.copy(T, new_buf, m);498 mem.copy(T, new_buf, m);
458 return new_buf;499 return new_buf;
459}500}
460501
461/// Copies `m` to newly allocated memory, with a null-terminated element. Caller owns the memory.502/// Copies `m` to newly allocated memory, with a null-terminated element. Caller owns the memory.
462pub fn dupeZ(allocator: *Allocator, comptime T: type, m: []const T) ![:0]T {503pub fn dupeZ(allocator: Allocator, comptime T: type, m: []const T) ![:0]T {
463 const new_buf = try allocator.alloc(T, m.len + 1);504 const new_buf = try allocator.alloc(T, m.len + 1);
464 mem.copy(T, new_buf, m);505 mem.copy(T, new_buf, m);
465 new_buf[m.len] = 0;506 new_buf[m.len] = 0;
466 return new_buf[0..m.len :0];507 return new_buf[0..m.len :0];
467}508}
468509
469/// Call `resizeFn`, but caller guarantees that `new_len` <= `buf.len` meaning510/// Call `vtable.resize`, but caller guarantees that `new_len` <= `buf.len` meaning
470/// error.OutOfMemory should be impossible.511/// than a `null` return value should be impossible.
471/// This function allows a runtime `buf_align` value. Callers should generally prefer512/// This function allows a runtime `buf_align` value. Callers should generally prefer
472/// to call `shrink` directly.513/// to call `shrink` directly.
473pub fn shrinkBytes(514pub fn shrinkBytes(
474 self: *Allocator,515 self: Allocator,
475 buf: []u8,516 buf: []u8,
476 buf_align: u29,517 buf_align: u29,
477 new_len: usize,518 new_len: usize,
...@@ -479,5 +520,5 @@ pub fn shrinkBytes(...@@ -479,5 +520,5 @@ pub fn shrinkBytes(
479 return_address: usize,520 return_address: usize,
480) usize {521) usize {
481 assert(new_len <= buf.len);522 assert(new_len <= buf.len);
482 return self.resizeFn(self, buf, buf_align, new_len, len_align, return_address) catch unreachable;523 return self.rawResize(buf, buf_align, new_len, len_align, return_address) orelse unreachable;
483}524}
lib/std/multi_array_list.zig+10-10
...@@ -59,7 +59,7 @@ pub fn MultiArrayList(comptime S: type) type {...@@ -59,7 +59,7 @@ pub fn MultiArrayList(comptime S: type) type {
59 };59 };
60 }60 }
6161
62 pub fn deinit(self: *Slice, gpa: *Allocator) void {62 pub fn deinit(self: *Slice, gpa: Allocator) void {
63 var other = self.toMultiArrayList();63 var other = self.toMultiArrayList();
64 other.deinit(gpa);64 other.deinit(gpa);
65 self.* = undefined;65 self.* = undefined;
...@@ -106,7 +106,7 @@ pub fn MultiArrayList(comptime S: type) type {...@@ -106,7 +106,7 @@ pub fn MultiArrayList(comptime S: type) type {
106 };106 };
107107
108 /// Release all allocated memory.108 /// Release all allocated memory.
109 pub fn deinit(self: *Self, gpa: *Allocator) void {109 pub fn deinit(self: *Self, gpa: Allocator) void {
110 gpa.free(self.allocatedBytes());110 gpa.free(self.allocatedBytes());
111 self.* = undefined;111 self.* = undefined;
112 }112 }
...@@ -161,7 +161,7 @@ pub fn MultiArrayList(comptime S: type) type {...@@ -161,7 +161,7 @@ pub fn MultiArrayList(comptime S: type) type {
161 }161 }
162162
163 /// Extend the list by 1 element. Allocates more memory as necessary.163 /// Extend the list by 1 element. Allocates more memory as necessary.
164 pub fn append(self: *Self, gpa: *Allocator, elem: S) !void {164 pub fn append(self: *Self, gpa: Allocator, elem: S) !void {
165 try self.ensureUnusedCapacity(gpa, 1);165 try self.ensureUnusedCapacity(gpa, 1);
166 self.appendAssumeCapacity(elem);166 self.appendAssumeCapacity(elem);
167 }167 }
...@@ -188,7 +188,7 @@ pub fn MultiArrayList(comptime S: type) type {...@@ -188,7 +188,7 @@ pub fn MultiArrayList(comptime S: type) type {
188 /// after and including the specified index back by one and188 /// after and including the specified index back by one and
189 /// sets the given index to the specified element. May reallocate189 /// sets the given index to the specified element. May reallocate
190 /// and invalidate iterators.190 /// and invalidate iterators.
191 pub fn insert(self: *Self, gpa: *Allocator, index: usize, elem: S) void {191 pub fn insert(self: *Self, gpa: Allocator, index: usize, elem: S) void {
192 try self.ensureUnusedCapacity(gpa, 1);192 try self.ensureUnusedCapacity(gpa, 1);
193 self.insertAssumeCapacity(index, elem);193 self.insertAssumeCapacity(index, elem);
194 }194 }
...@@ -242,7 +242,7 @@ pub fn MultiArrayList(comptime S: type) type {...@@ -242,7 +242,7 @@ pub fn MultiArrayList(comptime S: type) type {
242242
243 /// Adjust the list's length to `new_len`.243 /// Adjust the list's length to `new_len`.
244 /// Does not initialize added items, if any.244 /// Does not initialize added items, if any.
245 pub fn resize(self: *Self, gpa: *Allocator, new_len: usize) !void {245 pub fn resize(self: *Self, gpa: Allocator, new_len: usize) !void {
246 try self.ensureTotalCapacity(gpa, new_len);246 try self.ensureTotalCapacity(gpa, new_len);
247 self.len = new_len;247 self.len = new_len;
248 }248 }
...@@ -250,7 +250,7 @@ pub fn MultiArrayList(comptime S: type) type {...@@ -250,7 +250,7 @@ pub fn MultiArrayList(comptime S: type) type {
250 /// Attempt to reduce allocated capacity to `new_len`.250 /// Attempt to reduce allocated capacity to `new_len`.
251 /// If `new_len` is greater than zero, this may fail to reduce the capacity,251 /// If `new_len` is greater than zero, this may fail to reduce the capacity,
252 /// but the data remains intact and the length is updated to new_len.252 /// but the data remains intact and the length is updated to new_len.
253 pub fn shrinkAndFree(self: *Self, gpa: *Allocator, new_len: usize) void {253 pub fn shrinkAndFree(self: *Self, gpa: Allocator, new_len: usize) void {
254 if (new_len == 0) {254 if (new_len == 0) {
255 gpa.free(self.allocatedBytes());255 gpa.free(self.allocatedBytes());
256 self.* = .{};256 self.* = .{};
...@@ -314,7 +314,7 @@ pub fn MultiArrayList(comptime S: type) type {...@@ -314,7 +314,7 @@ pub fn MultiArrayList(comptime S: type) type {
314 /// Modify the array so that it can hold at least `new_capacity` items.314 /// Modify the array so that it can hold at least `new_capacity` items.
315 /// Implements super-linear growth to achieve amortized O(1) append operations.315 /// Implements super-linear growth to achieve amortized O(1) append operations.
316 /// Invalidates pointers if additional memory is needed.316 /// Invalidates pointers if additional memory is needed.
317 pub fn ensureTotalCapacity(self: *Self, gpa: *Allocator, new_capacity: usize) !void {317 pub fn ensureTotalCapacity(self: *Self, gpa: Allocator, new_capacity: usize) !void {
318 var better_capacity = self.capacity;318 var better_capacity = self.capacity;
319 if (better_capacity >= new_capacity) return;319 if (better_capacity >= new_capacity) return;
320320
...@@ -328,14 +328,14 @@ pub fn MultiArrayList(comptime S: type) type {...@@ -328,14 +328,14 @@ pub fn MultiArrayList(comptime S: type) type {
328328
329 /// Modify the array so that it can hold at least `additional_count` **more** items.329 /// Modify the array so that it can hold at least `additional_count` **more** items.
330 /// Invalidates pointers if additional memory is needed.330 /// Invalidates pointers if additional memory is needed.
331 pub fn ensureUnusedCapacity(self: *Self, gpa: *Allocator, additional_count: usize) !void {331 pub fn ensureUnusedCapacity(self: *Self, gpa: Allocator, additional_count: usize) !void {
332 return self.ensureTotalCapacity(gpa, self.len + additional_count);332 return self.ensureTotalCapacity(gpa, self.len + additional_count);
333 }333 }
334334
335 /// Modify the array so that it can hold exactly `new_capacity` items.335 /// Modify the array so that it can hold exactly `new_capacity` items.
336 /// Invalidates pointers if additional memory is needed.336 /// Invalidates pointers if additional memory is needed.
337 /// `new_capacity` must be greater or equal to `len`.337 /// `new_capacity` must be greater or equal to `len`.
338 pub fn setCapacity(self: *Self, gpa: *Allocator, new_capacity: usize) !void {338 pub fn setCapacity(self: *Self, gpa: Allocator, new_capacity: usize) !void {
339 assert(new_capacity >= self.len);339 assert(new_capacity >= self.len);
340 const new_bytes = try gpa.allocAdvanced(340 const new_bytes = try gpa.allocAdvanced(
341 u8,341 u8,
...@@ -372,7 +372,7 @@ pub fn MultiArrayList(comptime S: type) type {...@@ -372,7 +372,7 @@ pub fn MultiArrayList(comptime S: type) type {
372372
373 /// Create a copy of this list with a new backing store,373 /// Create a copy of this list with a new backing store,
374 /// using the specified allocator.374 /// using the specified allocator.
375 pub fn clone(self: Self, gpa: *Allocator) !Self {375 pub fn clone(self: Self, gpa: Allocator) !Self {
376 var result = Self{};376 var result = Self{};
377 errdefer result.deinit(gpa);377 errdefer result.deinit(gpa);
378 try result.ensureTotalCapacity(gpa, self.len);378 try result.ensureTotalCapacity(gpa, self.len);
lib/std/net.zig+5-5
...@@ -664,7 +664,7 @@ pub const AddressList = struct {...@@ -664,7 +664,7 @@ pub const AddressList = struct {
664};664};
665665
666/// All memory allocated with `allocator` will be freed before this function returns.666/// All memory allocated with `allocator` will be freed before this function returns.
667pub fn tcpConnectToHost(allocator: *mem.Allocator, name: []const u8, port: u16) !Stream {667pub fn tcpConnectToHost(allocator: mem.Allocator, name: []const u8, port: u16) !Stream {
668 const list = try getAddressList(allocator, name, port);668 const list = try getAddressList(allocator, name, port);
669 defer list.deinit();669 defer list.deinit();
670670
...@@ -699,12 +699,12 @@ pub fn tcpConnectToAddress(address: Address) !Stream {...@@ -699,12 +699,12 @@ pub fn tcpConnectToAddress(address: Address) !Stream {
699}699}
700700
701/// Call `AddressList.deinit` on the result.701/// Call `AddressList.deinit` on the result.
702pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !*AddressList {702pub fn getAddressList(allocator: mem.Allocator, name: []const u8, port: u16) !*AddressList {
703 const result = blk: {703 const result = blk: {
704 var arena = std.heap.ArenaAllocator.init(allocator);704 var arena = std.heap.ArenaAllocator.init(allocator);
705 errdefer arena.deinit();705 errdefer arena.deinit();
706706
707 const result = try arena.allocator.create(AddressList);707 const result = try arena.allocator().create(AddressList);
708 result.* = AddressList{708 result.* = AddressList{
709 .arena = arena,709 .arena = arena,
710 .addrs = undefined,710 .addrs = undefined,
...@@ -712,7 +712,7 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !*...@@ -712,7 +712,7 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !*
712 };712 };
713 break :blk result;713 break :blk result;
714 };714 };
715 const arena = &result.arena.allocator;715 const arena = result.arena.allocator();
716 errdefer result.arena.deinit();716 errdefer result.arena.deinit();
717717
718 if (builtin.target.os.tag == .windows or builtin.link_libc) {718 if (builtin.target.os.tag == .windows or builtin.link_libc) {
...@@ -1303,7 +1303,7 @@ const ResolvConf = struct {...@@ -1303,7 +1303,7 @@ const ResolvConf = struct {
13031303
1304/// Ignores lines longer than 512 bytes.1304/// Ignores lines longer than 512 bytes.
1305/// TODO: https://github.com/ziglang/zig/issues/2765 and https://github.com/ziglang/zig/issues/27611305/// TODO: https://github.com/ziglang/zig/issues/2765 and https://github.com/ziglang/zig/issues/2761
1306fn getResolvConf(allocator: *mem.Allocator, rc: *ResolvConf) !void {1306fn getResolvConf(allocator: mem.Allocator, rc: *ResolvConf) !void {
1307 rc.* = ResolvConf{1307 rc.* = ResolvConf{
1308 .ns = std.ArrayList(LookupAddr).init(allocator),1308 .ns = std.ArrayList(LookupAddr).init(allocator),
1309 .search = std.ArrayList(u8).init(allocator),1309 .search = std.ArrayList(u8).init(allocator),
lib/std/net/test.zig+1-1
...@@ -230,7 +230,7 @@ test "listen on ipv4 try connect on ipv6 then ipv4" {...@@ -230,7 +230,7 @@ test "listen on ipv4 try connect on ipv6 then ipv4" {
230 try await client_frame;230 try await client_frame;
231}231}
232232
233fn testClientToHost(allocator: *mem.Allocator, name: []const u8, port: u16) anyerror!void {233fn testClientToHost(allocator: mem.Allocator, name: []const u8, port: u16) anyerror!void {
234 if (builtin.os.tag == .wasi) return error.SkipZigTest;234 if (builtin.os.tag == .wasi) return error.SkipZigTest;
235235
236 const connection = try net.tcpConnectToHost(allocator, name, port);236 const connection = try net.tcpConnectToHost(allocator, name, port);
lib/std/os/test.zig+10-9
...@@ -58,10 +58,11 @@ test "open smoke test" {...@@ -58,10 +58,11 @@ test "open smoke test" {
58 // Get base abs path58 // Get base abs path
59 var arena = ArenaAllocator.init(testing.allocator);59 var arena = ArenaAllocator.init(testing.allocator);
60 defer arena.deinit();60 defer arena.deinit();
61 const allocator = arena.allocator();
6162
62 const base_path = blk: {63 const base_path = blk: {
63 const relative_path = try fs.path.join(&arena.allocator, &[_][]const u8{ "zig-cache", "tmp", tmp.sub_path[0..] });64 const relative_path = try fs.path.join(allocator, &[_][]const u8{ "zig-cache", "tmp", tmp.sub_path[0..] });
64 break :blk try fs.realpathAlloc(&arena.allocator, relative_path);65 break :blk try fs.realpathAlloc(allocator, relative_path);
65 };66 };
6667
67 var file_path: []u8 = undefined;68 var file_path: []u8 = undefined;
...@@ -69,34 +70,34 @@ test "open smoke test" {...@@ -69,34 +70,34 @@ test "open smoke test" {
69 const mode: os.mode_t = if (native_os == .windows) 0 else 0o666;70 const mode: os.mode_t = if (native_os == .windows) 0 else 0o666;
7071
71 // Create some file using `open`.72 // Create some file using `open`.
72 file_path = try fs.path.join(&arena.allocator, &[_][]const u8{ base_path, "some_file" });73 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });
73 fd = try os.open(file_path, os.O.RDWR | os.O.CREAT | os.O.EXCL, mode);74 fd = try os.open(file_path, os.O.RDWR | os.O.CREAT | os.O.EXCL, mode);
74 os.close(fd);75 os.close(fd);
7576
76 // Try this again with the same flags. This op should fail with error.PathAlreadyExists.77 // Try this again with the same flags. This op should fail with error.PathAlreadyExists.
77 file_path = try fs.path.join(&arena.allocator, &[_][]const u8{ base_path, "some_file" });78 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });
78 try expectError(error.PathAlreadyExists, os.open(file_path, os.O.RDWR | os.O.CREAT | os.O.EXCL, mode));79 try expectError(error.PathAlreadyExists, os.open(file_path, os.O.RDWR | os.O.CREAT | os.O.EXCL, mode));
7980
80 // Try opening without `O.EXCL` flag.81 // Try opening without `O.EXCL` flag.
81 file_path = try fs.path.join(&arena.allocator, &[_][]const u8{ base_path, "some_file" });82 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });
82 fd = try os.open(file_path, os.O.RDWR | os.O.CREAT, mode);83 fd = try os.open(file_path, os.O.RDWR | os.O.CREAT, mode);
83 os.close(fd);84 os.close(fd);
8485
85 // Try opening as a directory which should fail.86 // Try opening as a directory which should fail.
86 file_path = try fs.path.join(&arena.allocator, &[_][]const u8{ base_path, "some_file" });87 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });
87 try expectError(error.NotDir, os.open(file_path, os.O.RDWR | os.O.DIRECTORY, mode));88 try expectError(error.NotDir, os.open(file_path, os.O.RDWR | os.O.DIRECTORY, mode));
8889
89 // Create some directory90 // Create some directory
90 file_path = try fs.path.join(&arena.allocator, &[_][]const u8{ base_path, "some_dir" });91 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_dir" });
91 try os.mkdir(file_path, mode);92 try os.mkdir(file_path, mode);
9293
93 // Open dir using `open`94 // Open dir using `open`
94 file_path = try fs.path.join(&arena.allocator, &[_][]const u8{ base_path, "some_dir" });95 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_dir" });
95 fd = try os.open(file_path, os.O.RDONLY | os.O.DIRECTORY, mode);96 fd = try os.open(file_path, os.O.RDONLY | os.O.DIRECTORY, mode);
96 os.close(fd);97 os.close(fd);
9798
98 // Try opening as file which should fail.99 // Try opening as file which should fail.
99 file_path = try fs.path.join(&arena.allocator, &[_][]const u8{ base_path, "some_dir" });100 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_dir" });
100 try expectError(error.IsDir, os.open(file_path, os.O.RDWR, mode));101 try expectError(error.IsDir, os.open(file_path, os.O.RDWR, mode));
101}102}
102103
lib/std/pdb.zig+4-4
...@@ -460,7 +460,7 @@ pub const PDBStringTableHeader = packed struct {...@@ -460,7 +460,7 @@ pub const PDBStringTableHeader = packed struct {
460 ByteSize: u32,460 ByteSize: u32,
461};461};
462462
463fn readSparseBitVector(stream: anytype, allocator: *mem.Allocator) ![]u32 {463fn readSparseBitVector(stream: anytype, allocator: mem.Allocator) ![]u32 {
464 const num_words = try stream.readIntLittle(u32);464 const num_words = try stream.readIntLittle(u32);
465 var list = ArrayList(u32).init(allocator);465 var list = ArrayList(u32).init(allocator);
466 errdefer list.deinit();466 errdefer list.deinit();
...@@ -481,7 +481,7 @@ fn readSparseBitVector(stream: anytype, allocator: *mem.Allocator) ![]u32 {...@@ -481,7 +481,7 @@ fn readSparseBitVector(stream: anytype, allocator: *mem.Allocator) ![]u32 {
481pub const Pdb = struct {481pub const Pdb = struct {
482 in_file: File,482 in_file: File,
483 msf: Msf,483 msf: Msf,
484 allocator: *mem.Allocator,484 allocator: mem.Allocator,
485 string_table: ?*MsfStream,485 string_table: ?*MsfStream,
486 dbi: ?*MsfStream,486 dbi: ?*MsfStream,
487 modules: []Module,487 modules: []Module,
...@@ -500,7 +500,7 @@ pub const Pdb = struct {...@@ -500,7 +500,7 @@ pub const Pdb = struct {
500 checksum_offset: ?usize,500 checksum_offset: ?usize,
501 };501 };
502502
503 pub fn init(allocator: *mem.Allocator, path: []const u8) !Pdb {503 pub fn init(allocator: mem.Allocator, path: []const u8) !Pdb {
504 const file = try fs.cwd().openFile(path, .{ .intended_io_mode = .blocking });504 const file = try fs.cwd().openFile(path, .{ .intended_io_mode = .blocking });
505 errdefer file.close();505 errdefer file.close();
506506
...@@ -858,7 +858,7 @@ const Msf = struct {...@@ -858,7 +858,7 @@ const Msf = struct {
858 directory: MsfStream,858 directory: MsfStream,
859 streams: []MsfStream,859 streams: []MsfStream,
860860
861 fn init(allocator: *mem.Allocator, file: File) !Msf {861 fn init(allocator: mem.Allocator, file: File) !Msf {
862 const in = file.reader();862 const in = file.reader();
863863
864 const superblock = try in.readStruct(SuperBlock);864 const superblock = try in.readStruct(SuperBlock);
lib/std/priority_dequeue.zig+4-4
...@@ -21,10 +21,10 @@ pub fn PriorityDequeue(comptime T: type, comptime compareFn: fn (T, T) Order) ty...@@ -21,10 +21,10 @@ pub fn PriorityDequeue(comptime T: type, comptime compareFn: fn (T, T) Order) ty
2121
22 items: []T,22 items: []T,
23 len: usize,23 len: usize,
24 allocator: *Allocator,24 allocator: Allocator,
2525
26 /// Initialize and return a new priority dequeue.26 /// Initialize and return a new priority dequeue.
27 pub fn init(allocator: *Allocator) Self {27 pub fn init(allocator: Allocator) Self {
28 return Self{28 return Self{
29 .items = &[_]T{},29 .items = &[_]T{},
30 .len = 0,30 .len = 0,
...@@ -336,7 +336,7 @@ pub fn PriorityDequeue(comptime T: type, comptime compareFn: fn (T, T) Order) ty...@@ -336,7 +336,7 @@ pub fn PriorityDequeue(comptime T: type, comptime compareFn: fn (T, T) Order) ty
336 /// Dequeue takes ownership of the passed in slice. The slice must have been336 /// Dequeue takes ownership of the passed in slice. The slice must have been
337 /// allocated with `allocator`.337 /// allocated with `allocator`.
338 /// De-initialize with `deinit`.338 /// De-initialize with `deinit`.
339 pub fn fromOwnedSlice(allocator: *Allocator, items: []T) Self {339 pub fn fromOwnedSlice(allocator: Allocator, items: []T) Self {
340 var queue = Self{340 var queue = Self{
341 .items = items,341 .items = items,
342 .len = items.len,342 .len = items.len,
...@@ -945,7 +945,7 @@ fn fuzzTestMinMax(rng: std.rand.Random, queue_size: usize) !void {...@@ -945,7 +945,7 @@ fn fuzzTestMinMax(rng: std.rand.Random, queue_size: usize) !void {
945 }945 }
946}946}
947947
948fn generateRandomSlice(allocator: *std.mem.Allocator, rng: std.rand.Random, size: usize) ![]u32 {948fn generateRandomSlice(allocator: std.mem.Allocator, rng: std.rand.Random, size: usize) ![]u32 {
949 var array = std.ArrayList(u32).init(allocator);949 var array = std.ArrayList(u32).init(allocator);
950 try array.ensureTotalCapacity(size);950 try array.ensureTotalCapacity(size);
951951
lib/std/priority_queue.zig+3-3
...@@ -20,10 +20,10 @@ pub fn PriorityQueue(comptime T: type, comptime compareFn: fn (a: T, b: T) Order...@@ -20,10 +20,10 @@ pub fn PriorityQueue(comptime T: type, comptime compareFn: fn (a: T, b: T) Order
2020
21 items: []T,21 items: []T,
22 len: usize,22 len: usize,
23 allocator: *Allocator,23 allocator: Allocator,
2424
25 /// Initialize and return a priority queue.25 /// Initialize and return a priority queue.
26 pub fn init(allocator: *Allocator) Self {26 pub fn init(allocator: Allocator) Self {
27 return Self{27 return Self{
28 .items = &[_]T{},28 .items = &[_]T{},
29 .len = 0,29 .len = 0,
...@@ -153,7 +153,7 @@ pub fn PriorityQueue(comptime T: type, comptime compareFn: fn (a: T, b: T) Order...@@ -153,7 +153,7 @@ pub fn PriorityQueue(comptime T: type, comptime compareFn: fn (a: T, b: T) Order
153 /// PriorityQueue takes ownership of the passed in slice. The slice must have been153 /// PriorityQueue takes ownership of the passed in slice. The slice must have been
154 /// allocated with `allocator`.154 /// allocated with `allocator`.
155 /// Deinitialize with `deinit`.155 /// Deinitialize with `deinit`.
156 pub fn fromOwnedSlice(allocator: *Allocator, items: []T) Self {156 pub fn fromOwnedSlice(allocator: Allocator, items: []T) Self {
157 var queue = Self{157 var queue = Self{
158 .items = items,158 .items = items,
159 .len = items.len,159 .len = items.len,
lib/std/process.zig+20-20
...@@ -21,7 +21,7 @@ pub fn getCwd(out_buffer: []u8) ![]u8 {...@@ -21,7 +21,7 @@ pub fn getCwd(out_buffer: []u8) ![]u8 {
21}21}
2222
23/// Caller must free the returned memory.23/// Caller must free the returned memory.
24pub fn getCwdAlloc(allocator: *Allocator) ![]u8 {24pub fn getCwdAlloc(allocator: Allocator) ![]u8 {
25 // The use of MAX_PATH_BYTES here is just a heuristic: most paths will fit25 // The use of MAX_PATH_BYTES here is just a heuristic: most paths will fit
26 // in stack_buf, avoiding an extra allocation in the common case.26 // in stack_buf, avoiding an extra allocation in the common case.
27 var stack_buf: [fs.MAX_PATH_BYTES]u8 = undefined;27 var stack_buf: [fs.MAX_PATH_BYTES]u8 = undefined;
...@@ -54,7 +54,7 @@ test "getCwdAlloc" {...@@ -54,7 +54,7 @@ test "getCwdAlloc" {
54}54}
5555
56/// Caller owns resulting `BufMap`.56/// Caller owns resulting `BufMap`.
57pub fn getEnvMap(allocator: *Allocator) !BufMap {57pub fn getEnvMap(allocator: Allocator) !BufMap {
58 var result = BufMap.init(allocator);58 var result = BufMap.init(allocator);
59 errdefer result.deinit();59 errdefer result.deinit();
6060
...@@ -154,7 +154,7 @@ pub const GetEnvVarOwnedError = error{...@@ -154,7 +154,7 @@ pub const GetEnvVarOwnedError = error{
154};154};
155155
156/// Caller must free returned memory.156/// Caller must free returned memory.
157pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) GetEnvVarOwnedError![]u8 {157pub fn getEnvVarOwned(allocator: mem.Allocator, key: []const u8) GetEnvVarOwnedError![]u8 {
158 if (builtin.os.tag == .windows) {158 if (builtin.os.tag == .windows) {
159 const result_w = blk: {159 const result_w = blk: {
160 const key_w = try std.unicode.utf8ToUtf16LeWithNull(allocator, key);160 const key_w = try std.unicode.utf8ToUtf16LeWithNull(allocator, key);
...@@ -183,10 +183,10 @@ pub fn hasEnvVarConstant(comptime key: []const u8) bool {...@@ -183,10 +183,10 @@ pub fn hasEnvVarConstant(comptime key: []const u8) bool {
183 }183 }
184}184}
185185
186pub fn hasEnvVar(allocator: *Allocator, key: []const u8) error{OutOfMemory}!bool {186pub fn hasEnvVar(allocator: Allocator, key: []const u8) error{OutOfMemory}!bool {
187 if (builtin.os.tag == .windows) {187 if (builtin.os.tag == .windows) {
188 var stack_alloc = std.heap.stackFallback(256 * @sizeOf(u16), allocator);188 var stack_alloc = std.heap.stackFallback(256 * @sizeOf(u16), allocator);
189 const key_w = try std.unicode.utf8ToUtf16LeWithNull(&stack_alloc.allocator, key);189 const key_w = try std.unicode.utf8ToUtf16LeWithNull(stack_alloc.get(), key);
190 defer stack_alloc.allocator.free(key_w);190 defer stack_alloc.allocator.free(key_w);
191 return std.os.getenvW(key_w) != null;191 return std.os.getenvW(key_w) != null;
192 } else {192 } else {
...@@ -227,7 +227,7 @@ pub const ArgIteratorPosix = struct {...@@ -227,7 +227,7 @@ pub const ArgIteratorPosix = struct {
227};227};
228228
229pub const ArgIteratorWasi = struct {229pub const ArgIteratorWasi = struct {
230 allocator: *mem.Allocator,230 allocator: mem.Allocator,
231 index: usize,231 index: usize,
232 args: [][:0]u8,232 args: [][:0]u8,
233233
...@@ -235,7 +235,7 @@ pub const ArgIteratorWasi = struct {...@@ -235,7 +235,7 @@ pub const ArgIteratorWasi = struct {
235235
236 /// You must call deinit to free the internal buffer of the236 /// You must call deinit to free the internal buffer of the
237 /// iterator after you are done.237 /// iterator after you are done.
238 pub fn init(allocator: *mem.Allocator) InitError!ArgIteratorWasi {238 pub fn init(allocator: mem.Allocator) InitError!ArgIteratorWasi {
239 const fetched_args = try ArgIteratorWasi.internalInit(allocator);239 const fetched_args = try ArgIteratorWasi.internalInit(allocator);
240 return ArgIteratorWasi{240 return ArgIteratorWasi{
241 .allocator = allocator,241 .allocator = allocator,
...@@ -244,7 +244,7 @@ pub const ArgIteratorWasi = struct {...@@ -244,7 +244,7 @@ pub const ArgIteratorWasi = struct {
244 };244 };
245 }245 }
246246
247 fn internalInit(allocator: *mem.Allocator) InitError![][:0]u8 {247 fn internalInit(allocator: mem.Allocator) InitError![][:0]u8 {
248 const w = os.wasi;248 const w = os.wasi;
249 var count: usize = undefined;249 var count: usize = undefined;
250 var buf_size: usize = undefined;250 var buf_size: usize = undefined;
...@@ -325,7 +325,7 @@ pub const ArgIteratorWindows = struct {...@@ -325,7 +325,7 @@ pub const ArgIteratorWindows = struct {
325 }325 }
326326
327 /// You must free the returned memory when done.327 /// You must free the returned memory when done.
328 pub fn next(self: *ArgIteratorWindows, allocator: *Allocator) ?(NextError![:0]u8) {328 pub fn next(self: *ArgIteratorWindows, allocator: Allocator) ?(NextError![:0]u8) {
329 // march forward over whitespace329 // march forward over whitespace
330 while (true) : (self.index += 1) {330 while (true) : (self.index += 1) {
331 const character = self.getPointAtIndex();331 const character = self.getPointAtIndex();
...@@ -379,7 +379,7 @@ pub const ArgIteratorWindows = struct {...@@ -379,7 +379,7 @@ pub const ArgIteratorWindows = struct {
379 }379 }
380 }380 }
381381
382 fn internalNext(self: *ArgIteratorWindows, allocator: *Allocator) NextError![:0]u8 {382 fn internalNext(self: *ArgIteratorWindows, allocator: Allocator) NextError![:0]u8 {
383 var buf = std.ArrayList(u16).init(allocator);383 var buf = std.ArrayList(u16).init(allocator);
384 defer buf.deinit();384 defer buf.deinit();
385385
...@@ -423,7 +423,7 @@ pub const ArgIteratorWindows = struct {...@@ -423,7 +423,7 @@ pub const ArgIteratorWindows = struct {
423 }423 }
424 }424 }
425425
426 fn convertFromWindowsCmdLineToUTF8(allocator: *Allocator, buf: []u16) NextError![:0]u8 {426 fn convertFromWindowsCmdLineToUTF8(allocator: Allocator, buf: []u16) NextError![:0]u8 {
427 return std.unicode.utf16leToUtf8AllocZ(allocator, buf) catch |err| switch (err) {427 return std.unicode.utf16leToUtf8AllocZ(allocator, buf) catch |err| switch (err) {
428 error.ExpectedSecondSurrogateHalf,428 error.ExpectedSecondSurrogateHalf,
429 error.DanglingSurrogateHalf,429 error.DanglingSurrogateHalf,
...@@ -463,7 +463,7 @@ pub const ArgIterator = struct {...@@ -463,7 +463,7 @@ pub const ArgIterator = struct {
463 pub const InitError = ArgIteratorWasi.InitError;463 pub const InitError = ArgIteratorWasi.InitError;
464464
465 /// You must deinitialize iterator's internal buffers by calling `deinit` when done.465 /// You must deinitialize iterator's internal buffers by calling `deinit` when done.
466 pub fn initWithAllocator(allocator: *mem.Allocator) InitError!ArgIterator {466 pub fn initWithAllocator(allocator: mem.Allocator) InitError!ArgIterator {
467 if (builtin.os.tag == .wasi and !builtin.link_libc) {467 if (builtin.os.tag == .wasi and !builtin.link_libc) {
468 return ArgIterator{ .inner = try InnerType.init(allocator) };468 return ArgIterator{ .inner = try InnerType.init(allocator) };
469 }469 }
...@@ -474,7 +474,7 @@ pub const ArgIterator = struct {...@@ -474,7 +474,7 @@ pub const ArgIterator = struct {
474 pub const NextError = ArgIteratorWindows.NextError;474 pub const NextError = ArgIteratorWindows.NextError;
475475
476 /// You must free the returned memory when done.476 /// You must free the returned memory when done.
477 pub fn next(self: *ArgIterator, allocator: *Allocator) ?(NextError![:0]u8) {477 pub fn next(self: *ArgIterator, allocator: Allocator) ?(NextError![:0]u8) {
478 if (builtin.os.tag == .windows) {478 if (builtin.os.tag == .windows) {
479 return self.inner.next(allocator);479 return self.inner.next(allocator);
480 } else {480 } else {
...@@ -513,7 +513,7 @@ pub fn args() ArgIterator {...@@ -513,7 +513,7 @@ pub fn args() ArgIterator {
513}513}
514514
515/// You must deinitialize iterator's internal buffers by calling `deinit` when done.515/// You must deinitialize iterator's internal buffers by calling `deinit` when done.
516pub fn argsWithAllocator(allocator: *mem.Allocator) ArgIterator.InitError!ArgIterator {516pub fn argsWithAllocator(allocator: mem.Allocator) ArgIterator.InitError!ArgIterator {
517 return ArgIterator.initWithAllocator(allocator);517 return ArgIterator.initWithAllocator(allocator);
518}518}
519519
...@@ -539,7 +539,7 @@ test "args iterator" {...@@ -539,7 +539,7 @@ test "args iterator" {
539}539}
540540
541/// Caller must call argsFree on result.541/// Caller must call argsFree on result.
542pub fn argsAlloc(allocator: *mem.Allocator) ![][:0]u8 {542pub fn argsAlloc(allocator: mem.Allocator) ![][:0]u8 {
543 // TODO refactor to only make 1 allocation.543 // TODO refactor to only make 1 allocation.
544 var it = if (builtin.os.tag == .wasi) try argsWithAllocator(allocator) else args();544 var it = if (builtin.os.tag == .wasi) try argsWithAllocator(allocator) else args();
545 defer it.deinit();545 defer it.deinit();
...@@ -579,7 +579,7 @@ pub fn argsAlloc(allocator: *mem.Allocator) ![][:0]u8 {...@@ -579,7 +579,7 @@ pub fn argsAlloc(allocator: *mem.Allocator) ![][:0]u8 {
579 return result_slice_list;579 return result_slice_list;
580}580}
581581
582pub fn argsFree(allocator: *mem.Allocator, args_alloc: []const [:0]u8) void {582pub fn argsFree(allocator: mem.Allocator, args_alloc: []const [:0]u8) void {
583 var total_bytes: usize = 0;583 var total_bytes: usize = 0;
584 for (args_alloc) |arg| {584 for (args_alloc) |arg| {
585 total_bytes += @sizeOf([]u8) + arg.len + 1;585 total_bytes += @sizeOf([]u8) + arg.len + 1;
...@@ -741,7 +741,7 @@ pub fn getBaseAddress() usize {...@@ -741,7 +741,7 @@ pub fn getBaseAddress() usize {
741/// requirement from `std.zig.system.NativeTargetInfo.detect`. Most likely this will require741/// requirement from `std.zig.system.NativeTargetInfo.detect`. Most likely this will require
742/// introducing a new, lower-level function which takes a callback function, and then this742/// introducing a new, lower-level function which takes a callback function, and then this
743/// function which takes an allocator can exist on top of it.743/// function which takes an allocator can exist on top of it.
744pub fn getSelfExeSharedLibPaths(allocator: *Allocator) error{OutOfMemory}![][:0]u8 {744pub fn getSelfExeSharedLibPaths(allocator: Allocator) error{OutOfMemory}![][:0]u8 {
745 switch (builtin.link_mode) {745 switch (builtin.link_mode) {
746 .Static => return &[_][:0]u8{},746 .Static => return &[_][:0]u8{},
747 .Dynamic => {},747 .Dynamic => {},
...@@ -833,7 +833,7 @@ pub const ExecvError = std.os.ExecveError || error{OutOfMemory};...@@ -833,7 +833,7 @@ pub const ExecvError = std.os.ExecveError || error{OutOfMemory};
833/// This function also uses the PATH environment variable to get the full path to the executable.833/// This function also uses the PATH environment variable to get the full path to the executable.
834/// Due to the heap-allocation, it is illegal to call this function in a fork() child.834/// Due to the heap-allocation, it is illegal to call this function in a fork() child.
835/// For that use case, use the `std.os` functions directly.835/// For that use case, use the `std.os` functions directly.
836pub fn execv(allocator: *mem.Allocator, argv: []const []const u8) ExecvError {836pub fn execv(allocator: mem.Allocator, argv: []const []const u8) ExecvError {
837 return execve(allocator, argv, null);837 return execve(allocator, argv, null);
838}838}
839839
...@@ -846,7 +846,7 @@ pub fn execv(allocator: *mem.Allocator, argv: []const []const u8) ExecvError {...@@ -846,7 +846,7 @@ pub fn execv(allocator: *mem.Allocator, argv: []const []const u8) ExecvError {
846/// Due to the heap-allocation, it is illegal to call this function in a fork() child.846/// Due to the heap-allocation, it is illegal to call this function in a fork() child.
847/// For that use case, use the `std.os` functions directly.847/// For that use case, use the `std.os` functions directly.
848pub fn execve(848pub fn execve(
849 allocator: *mem.Allocator,849 allocator: mem.Allocator,
850 argv: []const []const u8,850 argv: []const []const u8,
851 env_map: ?*const std.BufMap,851 env_map: ?*const std.BufMap,
852) ExecvError {852) ExecvError {
...@@ -854,7 +854,7 @@ pub fn execve(...@@ -854,7 +854,7 @@ pub fn execve(
854854
855 var arena_allocator = std.heap.ArenaAllocator.init(allocator);855 var arena_allocator = std.heap.ArenaAllocator.init(allocator);
856 defer arena_allocator.deinit();856 defer arena_allocator.deinit();
857 const arena = &arena_allocator.allocator;857 const arena = arena_allocator.allocator();
858858
859 const argv_buf = try arena.allocSentinel(?[*:0]u8, argv.len, null);859 const argv_buf = try arena.allocSentinel(?[*:0]u8, argv.len, null);
860 for (argv) |arg, i| argv_buf[i] = (try arena.dupeZ(u8, arg)).ptr;860 for (argv) |arg, i| argv_buf[i] = (try arena.dupeZ(u8, arg)).ptr;
lib/std/special/build_runner.zig+1-1
...@@ -16,7 +16,7 @@ pub fn main() !void {...@@ -16,7 +16,7 @@ pub fn main() !void {
16 var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);16 var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
17 defer arena.deinit();17 defer arena.deinit();
1818
19 const allocator = &arena.allocator;19 const allocator = arena.allocator();
20 var args = try process.argsAlloc(allocator);20 var args = try process.argsAlloc(allocator);
21 defer process.argsFree(allocator, args);21 defer process.argsFree(allocator, args);
2222
lib/std/special/test_runner.zig+1-1
...@@ -10,7 +10,7 @@ var args_buffer: [std.fs.MAX_PATH_BYTES + std.mem.page_size]u8 = undefined;...@@ -10,7 +10,7 @@ var args_buffer: [std.fs.MAX_PATH_BYTES + std.mem.page_size]u8 = undefined;
10var args_allocator = std.heap.FixedBufferAllocator.init(&args_buffer);10var args_allocator = std.heap.FixedBufferAllocator.init(&args_buffer);
1111
12fn processArgs() void {12fn processArgs() void {
13 const args = std.process.argsAlloc(&args_allocator.allocator) catch {13 const args = std.process.argsAlloc(args_allocator.allocator()) catch {
14 @panic("Too many bytes passed over the CLI to the test runner");14 @panic("Too many bytes passed over the CLI to the test runner");
15 };15 };
16 if (args.len != 2) {16 if (args.len != 2) {
lib/std/target.zig+3-3
...@@ -1323,15 +1323,15 @@ pub const Target = struct {...@@ -1323,15 +1323,15 @@ pub const Target = struct {
13231323
1324 pub const stack_align = 16;1324 pub const stack_align = 16;
13251325
1326 pub fn zigTriple(self: Target, allocator: *mem.Allocator) ![]u8 {1326 pub fn zigTriple(self: Target, allocator: mem.Allocator) ![]u8 {
1327 return std.zig.CrossTarget.fromTarget(self).zigTriple(allocator);1327 return std.zig.CrossTarget.fromTarget(self).zigTriple(allocator);
1328 }1328 }
13291329
1330 pub fn linuxTripleSimple(allocator: *mem.Allocator, cpu_arch: Cpu.Arch, os_tag: Os.Tag, abi: Abi) ![]u8 {1330 pub fn linuxTripleSimple(allocator: mem.Allocator, cpu_arch: Cpu.Arch, os_tag: Os.Tag, abi: Abi) ![]u8 {
1331 return std.fmt.allocPrint(allocator, "{s}-{s}-{s}", .{ @tagName(cpu_arch), @tagName(os_tag), @tagName(abi) });1331 return std.fmt.allocPrint(allocator, "{s}-{s}-{s}", .{ @tagName(cpu_arch), @tagName(os_tag), @tagName(abi) });
1332 }1332 }
13331333
1334 pub fn linuxTriple(self: Target, allocator: *mem.Allocator) ![]u8 {1334 pub fn linuxTriple(self: Target, allocator: mem.Allocator) ![]u8 {
1335 return linuxTripleSimple(allocator, self.cpu.arch, self.os.tag, self.abi);1335 return linuxTripleSimple(allocator, self.cpu.arch, self.os.tag, self.abi);
1336 }1336 }
13371337
lib/std/testing.zig+3-3
...@@ -7,11 +7,11 @@ const print = std.debug.print;...@@ -7,11 +7,11 @@ const print = std.debug.print;
7pub const FailingAllocator = @import("testing/failing_allocator.zig").FailingAllocator;7pub const FailingAllocator = @import("testing/failing_allocator.zig").FailingAllocator;
88
9/// This should only be used in temporary test programs.9/// This should only be used in temporary test programs.
10pub const allocator = &allocator_instance.allocator;10pub const allocator = allocator_instance.allocator();
11pub var allocator_instance = std.heap.GeneralPurposeAllocator(.{}){};11pub var allocator_instance = std.heap.GeneralPurposeAllocator(.{}){};
1212
13pub const failing_allocator = &failing_allocator_instance.allocator;13pub const failing_allocator = failing_allocator_instance.allocator();
14pub var failing_allocator_instance = FailingAllocator.init(&base_allocator_instance.allocator, 0);14pub var failing_allocator_instance = FailingAllocator.init(base_allocator_instance.allocator(), 0);
1515
16pub var base_allocator_instance = std.heap.FixedBufferAllocator.init("");16pub var base_allocator_instance = std.heap.FixedBufferAllocator.init("");
1717
lib/std/testing/failing_allocator.zig+24-22
...@@ -12,10 +12,9 @@ const mem = std.mem;...@@ -12,10 +12,9 @@ const mem = std.mem;
12/// Then use `failing_allocator` anywhere you would have used a12/// Then use `failing_allocator` anywhere you would have used a
13/// different allocator.13/// different allocator.
14pub const FailingAllocator = struct {14pub const FailingAllocator = struct {
15 allocator: mem.Allocator,
16 index: usize,15 index: usize,
17 fail_index: usize,16 fail_index: usize,
18 internal_allocator: *mem.Allocator,17 internal_allocator: mem.Allocator,
19 allocated_bytes: usize,18 allocated_bytes: usize,
20 freed_bytes: usize,19 freed_bytes: usize,
21 allocations: usize,20 allocations: usize,
...@@ -29,34 +28,33 @@ pub const FailingAllocator = struct {...@@ -29,34 +28,33 @@ pub const FailingAllocator = struct {
29 /// var a = try failing_alloc.create(i32);28 /// var a = try failing_alloc.create(i32);
30 /// var b = try failing_alloc.create(i32);29 /// var b = try failing_alloc.create(i32);
31 /// testing.expectError(error.OutOfMemory, failing_alloc.create(i32));30 /// testing.expectError(error.OutOfMemory, failing_alloc.create(i32));
32 pub fn init(allocator: *mem.Allocator, fail_index: usize) FailingAllocator {31 pub fn init(internal_allocator: mem.Allocator, fail_index: usize) FailingAllocator {
33 return FailingAllocator{32 return FailingAllocator{
34 .internal_allocator = allocator,33 .internal_allocator = internal_allocator,
35 .fail_index = fail_index,34 .fail_index = fail_index,
36 .index = 0,35 .index = 0,
37 .allocated_bytes = 0,36 .allocated_bytes = 0,
38 .freed_bytes = 0,37 .freed_bytes = 0,
39 .allocations = 0,38 .allocations = 0,
40 .deallocations = 0,39 .deallocations = 0,
41 .allocator = mem.Allocator{
42 .allocFn = alloc,
43 .resizeFn = resize,
44 },
45 };40 };
46 }41 }
4742
43 pub fn allocator(self: *FailingAllocator) mem.Allocator {
44 return mem.Allocator.init(self, alloc, resize, free);
45 }
46
48 fn alloc(47 fn alloc(
49 allocator: *std.mem.Allocator,48 self: *FailingAllocator,
50 len: usize,49 len: usize,
51 ptr_align: u29,50 ptr_align: u29,
52 len_align: u29,51 len_align: u29,
53 return_address: usize,52 return_address: usize,
54 ) error{OutOfMemory}![]u8 {53 ) error{OutOfMemory}![]u8 {
55 const self = @fieldParentPtr(FailingAllocator, "allocator", allocator);
56 if (self.index == self.fail_index) {54 if (self.index == self.fail_index) {
57 return error.OutOfMemory;55 return error.OutOfMemory;
58 }56 }
59 const result = try self.internal_allocator.allocFn(self.internal_allocator, len, ptr_align, len_align, return_address);57 const result = try self.internal_allocator.rawAlloc(len, ptr_align, len_align, return_address);
60 self.allocated_bytes += result.len;58 self.allocated_bytes += result.len;
61 self.allocations += 1;59 self.allocations += 1;
62 self.index += 1;60 self.index += 1;
...@@ -64,26 +62,30 @@ pub const FailingAllocator = struct {...@@ -64,26 +62,30 @@ pub const FailingAllocator = struct {
64 }62 }
6563
66 fn resize(64 fn resize(
67 allocator: *std.mem.Allocator,65 self: *FailingAllocator,
68 old_mem: []u8,66 old_mem: []u8,
69 old_align: u29,67 old_align: u29,
70 new_len: usize,68 new_len: usize,
71 len_align: u29,69 len_align: u29,
72 ra: usize,70 ra: usize,
73 ) error{OutOfMemory}!usize {71 ) ?usize {
74 const self = @fieldParentPtr(FailingAllocator, "allocator", allocator);72 const r = self.internal_allocator.rawResize(old_mem, old_align, new_len, len_align, ra) orelse return null;
75 const r = self.internal_allocator.resizeFn(self.internal_allocator, old_mem, old_align, new_len, len_align, ra) catch |e| {73 if (r < old_mem.len) {
76 std.debug.assert(new_len > old_mem.len);
77 return e;
78 };
79 if (new_len == 0) {
80 self.deallocations += 1;
81 self.freed_bytes += old_mem.len;
82 } else if (r < old_mem.len) {
83 self.freed_bytes += old_mem.len - r;74 self.freed_bytes += old_mem.len - r;
84 } else {75 } else {
85 self.allocated_bytes += r - old_mem.len;76 self.allocated_bytes += r - old_mem.len;
86 }77 }
87 return r;78 return r;
88 }79 }
80
81 fn free(
82 self: *FailingAllocator,
83 old_mem: []u8,
84 old_align: u29,
85 ra: usize,
86 ) void {
87 self.internal_allocator.rawFree(old_mem, old_align, ra);
88 self.deallocations += 1;
89 self.freed_bytes += old_mem.len;
90 }
89};91};
lib/std/unicode.zig+3-3
...@@ -550,7 +550,7 @@ fn testDecode(bytes: []const u8) !u21 {...@@ -550,7 +550,7 @@ fn testDecode(bytes: []const u8) !u21 {
550}550}
551551
552/// Caller must free returned memory.552/// Caller must free returned memory.
553pub fn utf16leToUtf8Alloc(allocator: *mem.Allocator, utf16le: []const u16) ![]u8 {553pub fn utf16leToUtf8Alloc(allocator: mem.Allocator, utf16le: []const u16) ![]u8 {
554 // optimistically guess that it will all be ascii.554 // optimistically guess that it will all be ascii.
555 var result = try std.ArrayList(u8).initCapacity(allocator, utf16le.len);555 var result = try std.ArrayList(u8).initCapacity(allocator, utf16le.len);
556 errdefer result.deinit();556 errdefer result.deinit();
...@@ -567,7 +567,7 @@ pub fn utf16leToUtf8Alloc(allocator: *mem.Allocator, utf16le: []const u16) ![]u8...@@ -567,7 +567,7 @@ pub fn utf16leToUtf8Alloc(allocator: *mem.Allocator, utf16le: []const u16) ![]u8
567}567}
568568
569/// Caller must free returned memory.569/// Caller must free returned memory.
570pub fn utf16leToUtf8AllocZ(allocator: *mem.Allocator, utf16le: []const u16) ![:0]u8 {570pub fn utf16leToUtf8AllocZ(allocator: mem.Allocator, utf16le: []const u16) ![:0]u8 {
571 // optimistically guess that it will all be ascii.571 // optimistically guess that it will all be ascii.
572 var result = try std.ArrayList(u8).initCapacity(allocator, utf16le.len);572 var result = try std.ArrayList(u8).initCapacity(allocator, utf16le.len);
573 errdefer result.deinit();573 errdefer result.deinit();
...@@ -661,7 +661,7 @@ test "utf16leToUtf8" {...@@ -661,7 +661,7 @@ test "utf16leToUtf8" {
661 }661 }
662}662}
663663
664pub fn utf8ToUtf16LeWithNull(allocator: *mem.Allocator, utf8: []const u8) ![:0]u16 {664pub fn utf8ToUtf16LeWithNull(allocator: mem.Allocator, utf8: []const u8) ![:0]u16 {
665 // optimistically guess that it will not require surrogate pairs665 // optimistically guess that it will not require surrogate pairs
666 var result = try std.ArrayList(u16).initCapacity(allocator, utf8.len + 1);666 var result = try std.ArrayList(u16).initCapacity(allocator, utf8.len + 1);
667 errdefer result.deinit();667 errdefer result.deinit();
lib/std/wasm.zig+1-1
...@@ -361,7 +361,7 @@ pub const Type = struct {...@@ -361,7 +361,7 @@ pub const Type = struct {
361 std.mem.eql(Valtype, self.returns, other.returns);361 std.mem.eql(Valtype, self.returns, other.returns);
362 }362 }
363363
364 pub fn deinit(self: *Type, gpa: *std.mem.Allocator) void {364 pub fn deinit(self: *Type, gpa: std.mem.Allocator) void {
365 gpa.free(self.params);365 gpa.free(self.params);
366 gpa.free(self.returns);366 gpa.free(self.returns);
367 self.* = undefined;367 self.* = undefined;
lib/std/zig.zig+1-1
...@@ -100,7 +100,7 @@ pub const BinNameOptions = struct {...@@ -100,7 +100,7 @@ pub const BinNameOptions = struct {
100};100};
101101
102/// Returns the standard file system basename of a binary generated by the Zig compiler.102/// Returns the standard file system basename of a binary generated by the Zig compiler.
103pub fn binNameAlloc(allocator: *std.mem.Allocator, options: BinNameOptions) error{OutOfMemory}![]u8 {103pub fn binNameAlloc(allocator: std.mem.Allocator, options: BinNameOptions) error{OutOfMemory}![]u8 {
104 const root_name = options.root_name;104 const root_name = options.root_name;
105 const target = options.target;105 const target = options.target;
106 const ofmt = options.object_format orelse target.getObjectFormat();106 const ofmt = options.object_format orelse target.getObjectFormat();
lib/std/zig/Ast.zig+2-2
...@@ -34,7 +34,7 @@ pub const Location = struct {...@@ -34,7 +34,7 @@ pub const Location = struct {
34 line_end: usize,34 line_end: usize,
35};35};
3636
37pub fn deinit(tree: *Tree, gpa: *mem.Allocator) void {37pub fn deinit(tree: *Tree, gpa: mem.Allocator) void {
38 tree.tokens.deinit(gpa);38 tree.tokens.deinit(gpa);
39 tree.nodes.deinit(gpa);39 tree.nodes.deinit(gpa);
40 gpa.free(tree.extra_data);40 gpa.free(tree.extra_data);
...@@ -52,7 +52,7 @@ pub const RenderError = error{...@@ -52,7 +52,7 @@ pub const RenderError = error{
52/// for allocating extra stack memory if needed, because this function utilizes recursion.52/// for allocating extra stack memory if needed, because this function utilizes recursion.
53/// Note: that's not actually true yet, see https://github.com/ziglang/zig/issues/1006.53/// Note: that's not actually true yet, see https://github.com/ziglang/zig/issues/1006.
54/// Caller owns the returned slice of bytes, allocated with `gpa`.54/// Caller owns the returned slice of bytes, allocated with `gpa`.
55pub fn render(tree: Tree, gpa: *mem.Allocator) RenderError![]u8 {55pub fn render(tree: Tree, gpa: mem.Allocator) RenderError![]u8 {
56 var buffer = std.ArrayList(u8).init(gpa);56 var buffer = std.ArrayList(u8).init(gpa);
57 defer buffer.deinit();57 defer buffer.deinit();
5858
lib/std/zig/CrossTarget.zig+4-4
...@@ -520,7 +520,7 @@ pub fn isNative(self: CrossTarget) bool {...@@ -520,7 +520,7 @@ pub fn isNative(self: CrossTarget) bool {
520 return self.isNativeCpu() and self.isNativeOs() and self.isNativeAbi();520 return self.isNativeCpu() and self.isNativeOs() and self.isNativeAbi();
521}521}
522522
523pub fn zigTriple(self: CrossTarget, allocator: *mem.Allocator) error{OutOfMemory}![]u8 {523pub fn zigTriple(self: CrossTarget, allocator: mem.Allocator) error{OutOfMemory}![]u8 {
524 if (self.isNative()) {524 if (self.isNative()) {
525 return allocator.dupe(u8, "native");525 return allocator.dupe(u8, "native");
526 }526 }
...@@ -559,13 +559,13 @@ pub fn zigTriple(self: CrossTarget, allocator: *mem.Allocator) error{OutOfMemory...@@ -559,13 +559,13 @@ pub fn zigTriple(self: CrossTarget, allocator: *mem.Allocator) error{OutOfMemory
559 return result.toOwnedSlice();559 return result.toOwnedSlice();
560}560}
561561
562pub fn allocDescription(self: CrossTarget, allocator: *mem.Allocator) ![]u8 {562pub fn allocDescription(self: CrossTarget, allocator: mem.Allocator) ![]u8 {
563 // TODO is there anything else worthy of the description that is not563 // TODO is there anything else worthy of the description that is not
564 // already captured in the triple?564 // already captured in the triple?
565 return self.zigTriple(allocator);565 return self.zigTriple(allocator);
566}566}
567567
568pub fn linuxTriple(self: CrossTarget, allocator: *mem.Allocator) ![]u8 {568pub fn linuxTriple(self: CrossTarget, allocator: mem.Allocator) ![]u8 {
569 return Target.linuxTripleSimple(allocator, self.getCpuArch(), self.getOsTag(), self.getAbi());569 return Target.linuxTripleSimple(allocator, self.getCpuArch(), self.getOsTag(), self.getAbi());
570}570}
571571
...@@ -576,7 +576,7 @@ pub fn wantSharedLibSymLinks(self: CrossTarget) bool {...@@ -576,7 +576,7 @@ pub fn wantSharedLibSymLinks(self: CrossTarget) bool {
576pub const VcpkgLinkage = std.builtin.LinkMode;576pub const VcpkgLinkage = std.builtin.LinkMode;
577577
578/// Returned slice must be freed by the caller.578/// Returned slice must be freed by the caller.
579pub fn vcpkgTriplet(self: CrossTarget, allocator: *mem.Allocator, linkage: VcpkgLinkage) ![]u8 {579pub fn vcpkgTriplet(self: CrossTarget, allocator: mem.Allocator, linkage: VcpkgLinkage) ![]u8 {
580 const arch = switch (self.getCpuArch()) {580 const arch = switch (self.getCpuArch()) {
581 .i386 => "x86",581 .i386 => "x86",
582 .x86_64 => "x64",582 .x86_64 => "x64",
lib/std/zig/parse.zig+2-2
...@@ -11,7 +11,7 @@ pub const Error = error{ParseError} || Allocator.Error;...@@ -11,7 +11,7 @@ pub const Error = error{ParseError} || Allocator.Error;
1111
12/// Result should be freed with tree.deinit() when there are12/// Result should be freed with tree.deinit() when there are
13/// no more references to any of the tokens or nodes.13/// no more references to any of the tokens or nodes.
14pub fn parse(gpa: *Allocator, source: [:0]const u8) Allocator.Error!Ast {14pub fn parse(gpa: Allocator, source: [:0]const u8) Allocator.Error!Ast {
15 var tokens = Ast.TokenList{};15 var tokens = Ast.TokenList{};
16 defer tokens.deinit(gpa);16 defer tokens.deinit(gpa);
1717
...@@ -81,7 +81,7 @@ const null_node: Node.Index = 0;...@@ -81,7 +81,7 @@ const null_node: Node.Index = 0;
8181
82/// Represents in-progress parsing, will be converted to an Ast after completion.82/// Represents in-progress parsing, will be converted to an Ast after completion.
83const Parser = struct {83const Parser = struct {
84 gpa: *Allocator,84 gpa: Allocator,
85 source: []const u8,85 source: []const u8,
86 token_tags: []const Token.Tag,86 token_tags: []const Token.Tag,
87 token_starts: []const Ast.ByteOffset,87 token_starts: []const Ast.ByteOffset,
lib/std/zig/parser_test.zig+9-8
...@@ -1220,7 +1220,7 @@ test "zig fmt: doc comments on param decl" {...@@ -1220,7 +1220,7 @@ test "zig fmt: doc comments on param decl" {
1220 try testCanonical(1220 try testCanonical(
1221 \\pub const Allocator = struct {1221 \\pub const Allocator = struct {
1222 \\ shrinkFn: fn (1222 \\ shrinkFn: fn (
1223 \\ self: *Allocator,1223 \\ self: Allocator,
1224 \\ /// Guaranteed to be the same as what was returned from most recent call to1224 \\ /// Guaranteed to be the same as what was returned from most recent call to
1225 \\ /// `allocFn`, `reallocFn`, or `shrinkFn`.1225 \\ /// `allocFn`, `reallocFn`, or `shrinkFn`.
1226 \\ old_mem: []u8,1226 \\ old_mem: []u8,
...@@ -4250,7 +4250,7 @@ test "zig fmt: Only indent multiline string literals in function calls" {...@@ -4250,7 +4250,7 @@ test "zig fmt: Only indent multiline string literals in function calls" {
42504250
4251test "zig fmt: Don't add extra newline after if" {4251test "zig fmt: Don't add extra newline after if" {
4252 try testCanonical(4252 try testCanonical(
4253 \\pub fn atomicSymLink(allocator: *Allocator, existing_path: []const u8, new_path: []const u8) !void {4253 \\pub fn atomicSymLink(allocator: Allocator, existing_path: []const u8, new_path: []const u8) !void {
4254 \\ if (cwd().symLink(existing_path, new_path, .{})) {4254 \\ if (cwd().symLink(existing_path, new_path, .{})) {
4255 \\ return;4255 \\ return;
4256 \\ }4256 \\ }
...@@ -5319,7 +5319,7 @@ const maxInt = std.math.maxInt;...@@ -5319,7 +5319,7 @@ const maxInt = std.math.maxInt;
53195319
5320var fixed_buffer_mem: [100 * 1024]u8 = undefined;5320var fixed_buffer_mem: [100 * 1024]u8 = undefined;
53215321
5322fn testParse(source: [:0]const u8, allocator: *mem.Allocator, anything_changed: *bool) ![]u8 {5322fn testParse(source: [:0]const u8, allocator: mem.Allocator, anything_changed: *bool) ![]u8 {
5323 const stderr = io.getStdErr().writer();5323 const stderr = io.getStdErr().writer();
53245324
5325 var tree = try std.zig.parse(allocator, source);5325 var tree = try std.zig.parse(allocator, source);
...@@ -5351,9 +5351,10 @@ fn testTransform(source: [:0]const u8, expected_source: []const u8) !void {...@@ -5351,9 +5351,10 @@ fn testTransform(source: [:0]const u8, expected_source: []const u8) !void {
5351 const needed_alloc_count = x: {5351 const needed_alloc_count = x: {
5352 // Try it once with unlimited memory, make sure it works5352 // Try it once with unlimited memory, make sure it works
5353 var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);5353 var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
5354 var failing_allocator = std.testing.FailingAllocator.init(&fixed_allocator.allocator, maxInt(usize));5354 var failing_allocator = std.testing.FailingAllocator.init(fixed_allocator.allocator(), maxInt(usize));
5355 const allocator = failing_allocator.allocator();
5355 var anything_changed: bool = undefined;5356 var anything_changed: bool = undefined;
5356 const result_source = try testParse(source, &failing_allocator.allocator, &anything_changed);5357 const result_source = try testParse(source, allocator, &anything_changed);
5357 try std.testing.expectEqualStrings(expected_source, result_source);5358 try std.testing.expectEqualStrings(expected_source, result_source);
5358 const changes_expected = source.ptr != expected_source.ptr;5359 const changes_expected = source.ptr != expected_source.ptr;
5359 if (anything_changed != changes_expected) {5360 if (anything_changed != changes_expected) {
...@@ -5361,16 +5362,16 @@ fn testTransform(source: [:0]const u8, expected_source: []const u8) !void {...@@ -5361,16 +5362,16 @@ fn testTransform(source: [:0]const u8, expected_source: []const u8) !void {
5361 return error.TestFailed;5362 return error.TestFailed;
5362 }5363 }
5363 try std.testing.expect(anything_changed == changes_expected);5364 try std.testing.expect(anything_changed == changes_expected);
5364 failing_allocator.allocator.free(result_source);5365 allocator.free(result_source);
5365 break :x failing_allocator.index;5366 break :x failing_allocator.index;
5366 };5367 };
53675368
5368 var fail_index: usize = 0;5369 var fail_index: usize = 0;
5369 while (fail_index < needed_alloc_count) : (fail_index += 1) {5370 while (fail_index < needed_alloc_count) : (fail_index += 1) {
5370 var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);5371 var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
5371 var failing_allocator = std.testing.FailingAllocator.init(&fixed_allocator.allocator, fail_index);5372 var failing_allocator = std.testing.FailingAllocator.init(fixed_allocator.allocator(), fail_index);
5372 var anything_changed: bool = undefined;5373 var anything_changed: bool = undefined;
5373 if (testParse(source, &failing_allocator.allocator, &anything_changed)) |_| {5374 if (testParse(source, failing_allocator.allocator(), &anything_changed)) |_| {
5374 return error.NondeterministicMemoryUsage;5375 return error.NondeterministicMemoryUsage;
5375 } else |err| switch (err) {5376 } else |err| switch (err) {
5376 error.OutOfMemory => {5377 error.OutOfMemory => {
lib/std/zig/perf_test.zig+1-1
...@@ -33,7 +33,7 @@ pub fn main() !void {...@@ -33,7 +33,7 @@ pub fn main() !void {
3333
34fn testOnce() usize {34fn testOnce() usize {
35 var fixed_buf_alloc = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);35 var fixed_buf_alloc = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
36 var allocator = &fixed_buf_alloc.allocator;36 var allocator = fixed_buf_alloc.allocator();
37 _ = std.zig.parse(allocator, source) catch @panic("parse failure");37 _ = std.zig.parse(allocator, source) catch @panic("parse failure");
38 return fixed_buf_alloc.end_index;38 return fixed_buf_alloc.end_index;
39}39}
lib/std/zig/render.zig+24-24
...@@ -37,7 +37,7 @@ pub fn renderTree(buffer: *std.ArrayList(u8), tree: Ast) Error!void {...@@ -37,7 +37,7 @@ pub fn renderTree(buffer: *std.ArrayList(u8), tree: Ast) Error!void {
37}37}
3838
39/// Render all members in the given slice, keeping empty lines where appropriate39/// Render all members in the given slice, keeping empty lines where appropriate
40fn renderMembers(gpa: *Allocator, ais: *Ais, tree: Ast, members: []const Ast.Node.Index) Error!void {40fn renderMembers(gpa: Allocator, ais: *Ais, tree: Ast, members: []const Ast.Node.Index) Error!void {
41 if (members.len == 0) return;41 if (members.len == 0) return;
42 try renderMember(gpa, ais, tree, members[0], .newline);42 try renderMember(gpa, ais, tree, members[0], .newline);
43 for (members[1..]) |member| {43 for (members[1..]) |member| {
...@@ -46,7 +46,7 @@ fn renderMembers(gpa: *Allocator, ais: *Ais, tree: Ast, members: []const Ast.Nod...@@ -46,7 +46,7 @@ fn renderMembers(gpa: *Allocator, ais: *Ais, tree: Ast, members: []const Ast.Nod
46 }46 }
47}47}
4848
49fn renderMember(gpa: *Allocator, ais: *Ais, tree: Ast, decl: Ast.Node.Index, space: Space) Error!void {49fn renderMember(gpa: Allocator, ais: *Ais, tree: Ast, decl: Ast.Node.Index, space: Space) Error!void {
50 const token_tags = tree.tokens.items(.tag);50 const token_tags = tree.tokens.items(.tag);
51 const main_tokens = tree.nodes.items(.main_token);51 const main_tokens = tree.nodes.items(.main_token);
52 const datas = tree.nodes.items(.data);52 const datas = tree.nodes.items(.data);
...@@ -168,7 +168,7 @@ fn renderMember(gpa: *Allocator, ais: *Ais, tree: Ast, decl: Ast.Node.Index, spa...@@ -168,7 +168,7 @@ fn renderMember(gpa: *Allocator, ais: *Ais, tree: Ast, decl: Ast.Node.Index, spa
168}168}
169169
170/// Render all expressions in the slice, keeping empty lines where appropriate170/// Render all expressions in the slice, keeping empty lines where appropriate
171fn renderExpressions(gpa: *Allocator, ais: *Ais, tree: Ast, expressions: []const Ast.Node.Index, space: Space) Error!void {171fn renderExpressions(gpa: Allocator, ais: *Ais, tree: Ast, expressions: []const Ast.Node.Index, space: Space) Error!void {
172 if (expressions.len == 0) return;172 if (expressions.len == 0) return;
173 try renderExpression(gpa, ais, tree, expressions[0], space);173 try renderExpression(gpa, ais, tree, expressions[0], space);
174 for (expressions[1..]) |expression| {174 for (expressions[1..]) |expression| {
...@@ -177,7 +177,7 @@ fn renderExpressions(gpa: *Allocator, ais: *Ais, tree: Ast, expressions: []const...@@ -177,7 +177,7 @@ fn renderExpressions(gpa: *Allocator, ais: *Ais, tree: Ast, expressions: []const
177 }177 }
178}178}
179179
180fn renderExpression(gpa: *Allocator, ais: *Ais, tree: Ast, node: Ast.Node.Index, space: Space) Error!void {180fn renderExpression(gpa: Allocator, ais: *Ais, tree: Ast, node: Ast.Node.Index, space: Space) Error!void {
181 const token_tags = tree.tokens.items(.tag);181 const token_tags = tree.tokens.items(.tag);
182 const main_tokens = tree.nodes.items(.main_token);182 const main_tokens = tree.nodes.items(.main_token);
183 const node_tags = tree.nodes.items(.tag);183 const node_tags = tree.nodes.items(.tag);
...@@ -710,7 +710,7 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: Ast, node: Ast.Node.Index,...@@ -710,7 +710,7 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: Ast, node: Ast.Node.Index,
710}710}
711711
712fn renderArrayType(712fn renderArrayType(
713 gpa: *Allocator,713 gpa: Allocator,
714 ais: *Ais,714 ais: *Ais,
715 tree: Ast,715 tree: Ast,
716 array_type: Ast.full.ArrayType,716 array_type: Ast.full.ArrayType,
...@@ -732,7 +732,7 @@ fn renderArrayType(...@@ -732,7 +732,7 @@ fn renderArrayType(
732}732}
733733
734fn renderPtrType(734fn renderPtrType(
735 gpa: *Allocator,735 gpa: Allocator,
736 ais: *Ais,736 ais: *Ais,
737 tree: Ast,737 tree: Ast,
738 ptr_type: Ast.full.PtrType,738 ptr_type: Ast.full.PtrType,
...@@ -825,7 +825,7 @@ fn renderPtrType(...@@ -825,7 +825,7 @@ fn renderPtrType(
825}825}
826826
827fn renderSlice(827fn renderSlice(
828 gpa: *Allocator,828 gpa: Allocator,
829 ais: *Ais,829 ais: *Ais,
830 tree: Ast,830 tree: Ast,
831 slice_node: Ast.Node.Index,831 slice_node: Ast.Node.Index,
...@@ -861,7 +861,7 @@ fn renderSlice(...@@ -861,7 +861,7 @@ fn renderSlice(
861}861}
862862
863fn renderAsmOutput(863fn renderAsmOutput(
864 gpa: *Allocator,864 gpa: Allocator,
865 ais: *Ais,865 ais: *Ais,
866 tree: Ast,866 tree: Ast,
867 asm_output: Ast.Node.Index,867 asm_output: Ast.Node.Index,
...@@ -891,7 +891,7 @@ fn renderAsmOutput(...@@ -891,7 +891,7 @@ fn renderAsmOutput(
891}891}
892892
893fn renderAsmInput(893fn renderAsmInput(
894 gpa: *Allocator,894 gpa: Allocator,
895 ais: *Ais,895 ais: *Ais,
896 tree: Ast,896 tree: Ast,
897 asm_input: Ast.Node.Index,897 asm_input: Ast.Node.Index,
...@@ -912,7 +912,7 @@ fn renderAsmInput(...@@ -912,7 +912,7 @@ fn renderAsmInput(
912 return renderToken(ais, tree, datas[asm_input].rhs, space); // rparen912 return renderToken(ais, tree, datas[asm_input].rhs, space); // rparen
913}913}
914914
915fn renderVarDecl(gpa: *Allocator, ais: *Ais, tree: Ast, var_decl: Ast.full.VarDecl) Error!void {915fn renderVarDecl(gpa: Allocator, ais: *Ais, tree: Ast, var_decl: Ast.full.VarDecl) Error!void {
916 if (var_decl.visib_token) |visib_token| {916 if (var_decl.visib_token) |visib_token| {
917 try renderToken(ais, tree, visib_token, Space.space); // pub917 try renderToken(ais, tree, visib_token, Space.space); // pub
918 }918 }
...@@ -1019,7 +1019,7 @@ fn renderVarDecl(gpa: *Allocator, ais: *Ais, tree: Ast, var_decl: Ast.full.VarDe...@@ -1019,7 +1019,7 @@ fn renderVarDecl(gpa: *Allocator, ais: *Ais, tree: Ast, var_decl: Ast.full.VarDe
1019 return renderToken(ais, tree, var_decl.ast.mut_token + 2, .newline); // ;1019 return renderToken(ais, tree, var_decl.ast.mut_token + 2, .newline); // ;
1020}1020}
10211021
1022fn renderIf(gpa: *Allocator, ais: *Ais, tree: Ast, if_node: Ast.full.If, space: Space) Error!void {1022fn renderIf(gpa: Allocator, ais: *Ais, tree: Ast, if_node: Ast.full.If, space: Space) Error!void {
1023 return renderWhile(gpa, ais, tree, .{1023 return renderWhile(gpa, ais, tree, .{
1024 .ast = .{1024 .ast = .{
1025 .while_token = if_node.ast.if_token,1025 .while_token = if_node.ast.if_token,
...@@ -1038,7 +1038,7 @@ fn renderIf(gpa: *Allocator, ais: *Ais, tree: Ast, if_node: Ast.full.If, space:...@@ -1038,7 +1038,7 @@ fn renderIf(gpa: *Allocator, ais: *Ais, tree: Ast, if_node: Ast.full.If, space:
10381038
1039/// Note that this function is additionally used to render if and for expressions, with1039/// Note that this function is additionally used to render if and for expressions, with
1040/// respective values set to null.1040/// respective values set to null.
1041fn renderWhile(gpa: *Allocator, ais: *Ais, tree: Ast, while_node: Ast.full.While, space: Space) Error!void {1041fn renderWhile(gpa: Allocator, ais: *Ais, tree: Ast, while_node: Ast.full.While, space: Space) Error!void {
1042 const node_tags = tree.nodes.items(.tag);1042 const node_tags = tree.nodes.items(.tag);
1043 const token_tags = tree.tokens.items(.tag);1043 const token_tags = tree.tokens.items(.tag);
10441044
...@@ -1141,7 +1141,7 @@ fn renderWhile(gpa: *Allocator, ais: *Ais, tree: Ast, while_node: Ast.full.While...@@ -1141,7 +1141,7 @@ fn renderWhile(gpa: *Allocator, ais: *Ais, tree: Ast, while_node: Ast.full.While
1141}1141}
11421142
1143fn renderContainerField(1143fn renderContainerField(
1144 gpa: *Allocator,1144 gpa: Allocator,
1145 ais: *Ais,1145 ais: *Ais,
1146 tree: Ast,1146 tree: Ast,
1147 field: Ast.full.ContainerField,1147 field: Ast.full.ContainerField,
...@@ -1215,7 +1215,7 @@ fn renderContainerField(...@@ -1215,7 +1215,7 @@ fn renderContainerField(
1215}1215}
12161216
1217fn renderBuiltinCall(1217fn renderBuiltinCall(
1218 gpa: *Allocator,1218 gpa: Allocator,
1219 ais: *Ais,1219 ais: *Ais,
1220 tree: Ast,1220 tree: Ast,
1221 builtin_token: Ast.TokenIndex,1221 builtin_token: Ast.TokenIndex,
...@@ -1272,7 +1272,7 @@ fn renderBuiltinCall(...@@ -1272,7 +1272,7 @@ fn renderBuiltinCall(
1272 }1272 }
1273}1273}
12741274
1275fn renderFnProto(gpa: *Allocator, ais: *Ais, tree: Ast, fn_proto: Ast.full.FnProto, space: Space) Error!void {1275fn renderFnProto(gpa: Allocator, ais: *Ais, tree: Ast, fn_proto: Ast.full.FnProto, space: Space) Error!void {
1276 const token_tags = tree.tokens.items(.tag);1276 const token_tags = tree.tokens.items(.tag);
1277 const token_starts = tree.tokens.items(.start);1277 const token_starts = tree.tokens.items(.start);
12781278
...@@ -1488,7 +1488,7 @@ fn renderFnProto(gpa: *Allocator, ais: *Ais, tree: Ast, fn_proto: Ast.full.FnPro...@@ -1488,7 +1488,7 @@ fn renderFnProto(gpa: *Allocator, ais: *Ais, tree: Ast, fn_proto: Ast.full.FnPro
1488}1488}
14891489
1490fn renderSwitchCase(1490fn renderSwitchCase(
1491 gpa: *Allocator,1491 gpa: Allocator,
1492 ais: *Ais,1492 ais: *Ais,
1493 tree: Ast,1493 tree: Ast,
1494 switch_case: Ast.full.SwitchCase,1494 switch_case: Ast.full.SwitchCase,
...@@ -1541,7 +1541,7 @@ fn renderSwitchCase(...@@ -1541,7 +1541,7 @@ fn renderSwitchCase(
1541}1541}
15421542
1543fn renderBlock(1543fn renderBlock(
1544 gpa: *Allocator,1544 gpa: Allocator,
1545 ais: *Ais,1545 ais: *Ais,
1546 tree: Ast,1546 tree: Ast,
1547 block_node: Ast.Node.Index,1547 block_node: Ast.Node.Index,
...@@ -1581,7 +1581,7 @@ fn renderBlock(...@@ -1581,7 +1581,7 @@ fn renderBlock(
1581}1581}
15821582
1583fn renderStructInit(1583fn renderStructInit(
1584 gpa: *Allocator,1584 gpa: Allocator,
1585 ais: *Ais,1585 ais: *Ais,
1586 tree: Ast,1586 tree: Ast,
1587 struct_node: Ast.Node.Index,1587 struct_node: Ast.Node.Index,
...@@ -1640,7 +1640,7 @@ fn renderStructInit(...@@ -1640,7 +1640,7 @@ fn renderStructInit(
1640}1640}
16411641
1642fn renderArrayInit(1642fn renderArrayInit(
1643 gpa: *Allocator,1643 gpa: Allocator,
1644 ais: *Ais,1644 ais: *Ais,
1645 tree: Ast,1645 tree: Ast,
1646 array_init: Ast.full.ArrayInit,1646 array_init: Ast.full.ArrayInit,
...@@ -1859,7 +1859,7 @@ fn renderArrayInit(...@@ -1859,7 +1859,7 @@ fn renderArrayInit(
1859}1859}
18601860
1861fn renderContainerDecl(1861fn renderContainerDecl(
1862 gpa: *Allocator,1862 gpa: Allocator,
1863 ais: *Ais,1863 ais: *Ais,
1864 tree: Ast,1864 tree: Ast,
1865 container_decl_node: Ast.Node.Index,1865 container_decl_node: Ast.Node.Index,
...@@ -1956,7 +1956,7 @@ fn renderContainerDecl(...@@ -1956,7 +1956,7 @@ fn renderContainerDecl(
1956}1956}
19571957
1958fn renderAsm(1958fn renderAsm(
1959 gpa: *Allocator,1959 gpa: Allocator,
1960 ais: *Ais,1960 ais: *Ais,
1961 tree: Ast,1961 tree: Ast,
1962 asm_node: Ast.full.Asm,1962 asm_node: Ast.full.Asm,
...@@ -2105,7 +2105,7 @@ fn renderAsm(...@@ -2105,7 +2105,7 @@ fn renderAsm(
2105}2105}
21062106
2107fn renderCall(2107fn renderCall(
2108 gpa: *Allocator,2108 gpa: Allocator,
2109 ais: *Ais,2109 ais: *Ais,
2110 tree: Ast,2110 tree: Ast,
2111 call: Ast.full.Call,2111 call: Ast.full.Call,
...@@ -2180,7 +2180,7 @@ fn renderCall(...@@ -2180,7 +2180,7 @@ fn renderCall(
21802180
2181/// Renders the given expression indented, popping the indent before rendering2181/// Renders the given expression indented, popping the indent before rendering
2182/// any following line comments2182/// any following line comments
2183fn renderExpressionIndented(gpa: *Allocator, ais: *Ais, tree: Ast, node: Ast.Node.Index, space: Space) Error!void {2183fn renderExpressionIndented(gpa: Allocator, ais: *Ais, tree: Ast, node: Ast.Node.Index, space: Space) Error!void {
2184 const token_starts = tree.tokens.items(.start);2184 const token_starts = tree.tokens.items(.start);
2185 const token_tags = tree.tokens.items(.tag);2185 const token_tags = tree.tokens.items(.tag);
21862186
...@@ -2238,7 +2238,7 @@ fn renderExpressionIndented(gpa: *Allocator, ais: *Ais, tree: Ast, node: Ast.Nod...@@ -2238,7 +2238,7 @@ fn renderExpressionIndented(gpa: *Allocator, ais: *Ais, tree: Ast, node: Ast.Nod
22382238
2239/// Render an expression, and the comma that follows it, if it is present in the source.2239/// Render an expression, and the comma that follows it, if it is present in the source.
2240/// If a comma is present, and `space` is `Space.comma`, render only a single comma.2240/// If a comma is present, and `space` is `Space.comma`, render only a single comma.
2241fn renderExpressionComma(gpa: *Allocator, ais: *Ais, tree: Ast, node: Ast.Node.Index, space: Space) Error!void {2241fn renderExpressionComma(gpa: Allocator, ais: *Ais, tree: Ast, node: Ast.Node.Index, space: Space) Error!void {
2242 const token_tags = tree.tokens.items(.tag);2242 const token_tags = tree.tokens.items(.tag);
2243 const maybe_comma = tree.lastToken(node) + 1;2243 const maybe_comma = tree.lastToken(node) + 1;
2244 if (token_tags[maybe_comma] == .comma and space != .comma) {2244 if (token_tags[maybe_comma] == .comma and space != .comma) {
lib/std/zig/string_literal.zig+2-2
...@@ -131,7 +131,7 @@ pub fn parseAppend(buf: *std.ArrayList(u8), bytes: []const u8) error{OutOfMemory...@@ -131,7 +131,7 @@ pub fn parseAppend(buf: *std.ArrayList(u8), bytes: []const u8) error{OutOfMemory
131131
132/// Higher level API. Does not return extra info about parse errors.132/// Higher level API. Does not return extra info about parse errors.
133/// Caller owns returned memory.133/// Caller owns returned memory.
134pub fn parseAlloc(allocator: *std.mem.Allocator, bytes: []const u8) ParseError![]u8 {134pub fn parseAlloc(allocator: std.mem.Allocator, bytes: []const u8) ParseError![]u8 {
135 var buf = std.ArrayList(u8).init(allocator);135 var buf = std.ArrayList(u8).init(allocator);
136 defer buf.deinit();136 defer buf.deinit();
137137
...@@ -147,7 +147,7 @@ test "parse" {...@@ -147,7 +147,7 @@ test "parse" {
147147
148 var fixed_buf_mem: [32]u8 = undefined;148 var fixed_buf_mem: [32]u8 = undefined;
149 var fixed_buf_alloc = std.heap.FixedBufferAllocator.init(fixed_buf_mem[0..]);149 var fixed_buf_alloc = std.heap.FixedBufferAllocator.init(fixed_buf_mem[0..]);
150 var alloc = &fixed_buf_alloc.allocator;150 var alloc = fixed_buf_alloc.allocator();
151151
152 try expect(eql(u8, "foo", try parseAlloc(alloc, "\"foo\"")));152 try expect(eql(u8, "foo", try parseAlloc(alloc, "\"foo\"")));
153 try expect(eql(u8, "foo", try parseAlloc(alloc, "\"f\x6f\x6f\"")));153 try expect(eql(u8, "foo", try parseAlloc(alloc, "\"f\x6f\x6f\"")));
lib/std/zig/system.zig+3-3
...@@ -21,7 +21,7 @@ pub const NativePaths = struct {...@@ -21,7 +21,7 @@ pub const NativePaths = struct {
21 rpaths: ArrayList([:0]u8),21 rpaths: ArrayList([:0]u8),
22 warnings: ArrayList([:0]u8),22 warnings: ArrayList([:0]u8),
2323
24 pub fn detect(allocator: *Allocator, native_info: NativeTargetInfo) !NativePaths {24 pub fn detect(allocator: Allocator, native_info: NativeTargetInfo) !NativePaths {
25 const native_target = native_info.target;25 const native_target = native_info.target;
2626
27 var self: NativePaths = .{27 var self: NativePaths = .{
...@@ -237,7 +237,7 @@ pub const NativeTargetInfo = struct {...@@ -237,7 +237,7 @@ pub const NativeTargetInfo = struct {
237 /// Any resources this function allocates are released before returning, and so there is no237 /// Any resources this function allocates are released before returning, and so there is no
238 /// deinitialization method.238 /// deinitialization method.
239 /// TODO Remove the Allocator requirement from this function.239 /// TODO Remove the Allocator requirement from this function.
240 pub fn detect(allocator: *Allocator, cross_target: CrossTarget) DetectError!NativeTargetInfo {240 pub fn detect(allocator: Allocator, cross_target: CrossTarget) DetectError!NativeTargetInfo {
241 var os = cross_target.getOsTag().defaultVersionRange(cross_target.getCpuArch());241 var os = cross_target.getOsTag().defaultVersionRange(cross_target.getCpuArch());
242 if (cross_target.os_tag == null) {242 if (cross_target.os_tag == null) {
243 switch (builtin.target.os.tag) {243 switch (builtin.target.os.tag) {
...@@ -441,7 +441,7 @@ pub const NativeTargetInfo = struct {...@@ -441,7 +441,7 @@ pub const NativeTargetInfo = struct {
441 /// we fall back to the defaults.441 /// we fall back to the defaults.
442 /// TODO Remove the Allocator requirement from this function.442 /// TODO Remove the Allocator requirement from this function.
443 fn detectAbiAndDynamicLinker(443 fn detectAbiAndDynamicLinker(
444 allocator: *Allocator,444 allocator: Allocator,
445 cpu: Target.Cpu,445 cpu: Target.Cpu,
446 os: Target.Os,446 os: Target.Os,
447 cross_target: CrossTarget,447 cross_target: CrossTarget,
lib/std/zig/system/darwin.zig+3-3
...@@ -11,7 +11,7 @@ pub const macos = @import("darwin/macos.zig");...@@ -11,7 +11,7 @@ pub const macos = @import("darwin/macos.zig");
11/// Therefore, we resort to the same tool used by Homebrew, namely, invoking `xcode-select --print-path`11/// Therefore, we resort to the same tool used by Homebrew, namely, invoking `xcode-select --print-path`
12/// and checking if the status is nonzero or the returned string in nonempty.12/// and checking if the status is nonzero or the returned string in nonempty.
13/// https://github.com/Homebrew/brew/blob/e119bdc571dcb000305411bc1e26678b132afb98/Library/Homebrew/brew.sh#L63013/// https://github.com/Homebrew/brew/blob/e119bdc571dcb000305411bc1e26678b132afb98/Library/Homebrew/brew.sh#L630
14pub fn isDarwinSDKInstalled(allocator: *Allocator) bool {14pub fn isDarwinSDKInstalled(allocator: Allocator) bool {
15 const argv = &[_][]const u8{ "/usr/bin/xcode-select", "--print-path" };15 const argv = &[_][]const u8{ "/usr/bin/xcode-select", "--print-path" };
16 const result = std.ChildProcess.exec(.{ .allocator = allocator, .argv = argv }) catch return false;16 const result = std.ChildProcess.exec(.{ .allocator = allocator, .argv = argv }) catch return false;
17 defer {17 defer {
...@@ -29,7 +29,7 @@ pub fn isDarwinSDKInstalled(allocator: *Allocator) bool {...@@ -29,7 +29,7 @@ pub fn isDarwinSDKInstalled(allocator: *Allocator) bool {
29/// Calls `xcrun --sdk <target_sdk> --show-sdk-path` which fetches the path to the SDK sysroot (if any).29/// Calls `xcrun --sdk <target_sdk> --show-sdk-path` which fetches the path to the SDK sysroot (if any).
30/// Subsequently calls `xcrun --sdk <target_sdk> --show-sdk-version` which fetches version of the SDK.30/// Subsequently calls `xcrun --sdk <target_sdk> --show-sdk-version` which fetches version of the SDK.
31/// The caller needs to deinit the resulting struct.31/// The caller needs to deinit the resulting struct.
32pub fn getDarwinSDK(allocator: *Allocator, target: Target) ?DarwinSDK {32pub fn getDarwinSDK(allocator: Allocator, target: Target) ?DarwinSDK {
33 const is_simulator_abi = target.abi == .simulator;33 const is_simulator_abi = target.abi == .simulator;
34 const sdk = switch (target.os.tag) {34 const sdk = switch (target.os.tag) {
35 .macos => "macosx",35 .macos => "macosx",
...@@ -82,7 +82,7 @@ pub const DarwinSDK = struct {...@@ -82,7 +82,7 @@ pub const DarwinSDK = struct {
82 path: []const u8,82 path: []const u8,
83 version: Version,83 version: Version,
8484
85 pub fn deinit(self: DarwinSDK, allocator: *Allocator) void {85 pub fn deinit(self: DarwinSDK, allocator: Allocator) void {
86 allocator.free(self.path);86 allocator.free(self.path);
87 }87 }
88};88};
src/Air.zig+1-1
...@@ -841,7 +841,7 @@ pub fn extraData(air: Air, comptime T: type, index: usize) struct { data: T, end...@@ -841,7 +841,7 @@ pub fn extraData(air: Air, comptime T: type, index: usize) struct { data: T, end
841 };841 };
842}842}
843843
844pub fn deinit(air: *Air, gpa: *std.mem.Allocator) void {844pub fn deinit(air: *Air, gpa: std.mem.Allocator) void {
845 air.instructions.deinit(gpa);845 air.instructions.deinit(gpa);
846 gpa.free(air.extra);846 gpa.free(air.extra);
847 gpa.free(air.values);847 gpa.free(air.values);
src/AstGen.zig+17-16
...@@ -16,7 +16,7 @@ const indexToRef = Zir.indexToRef;...@@ -16,7 +16,7 @@ const indexToRef = Zir.indexToRef;
16const trace = @import("tracy.zig").trace;16const trace = @import("tracy.zig").trace;
17const BuiltinFn = @import("BuiltinFn.zig");17const BuiltinFn = @import("BuiltinFn.zig");
1818
19gpa: *Allocator,19gpa: Allocator,
20tree: *const Ast,20tree: *const Ast,
21instructions: std.MultiArrayList(Zir.Inst) = .{},21instructions: std.MultiArrayList(Zir.Inst) = .{},
22extra: ArrayListUnmanaged(u32) = .{},22extra: ArrayListUnmanaged(u32) = .{},
...@@ -33,7 +33,7 @@ source_line: u32 = 0,...@@ -33,7 +33,7 @@ source_line: u32 = 0,
33source_column: u32 = 0,33source_column: u32 = 0,
34/// Used for temporary allocations; freed after AstGen is complete.34/// Used for temporary allocations; freed after AstGen is complete.
35/// The resulting ZIR code has no references to anything in this arena.35/// The resulting ZIR code has no references to anything in this arena.
36arena: *Allocator,36arena: Allocator,
37string_table: std.HashMapUnmanaged(u32, void, StringIndexContext, std.hash_map.default_max_load_percentage) = .{},37string_table: std.HashMapUnmanaged(u32, void, StringIndexContext, std.hash_map.default_max_load_percentage) = .{},
38compile_errors: ArrayListUnmanaged(Zir.Inst.CompileErrors.Item) = .{},38compile_errors: ArrayListUnmanaged(Zir.Inst.CompileErrors.Item) = .{},
39/// The topmost block of the current function.39/// The topmost block of the current function.
...@@ -92,13 +92,13 @@ fn appendRefsAssumeCapacity(astgen: *AstGen, refs: []const Zir.Inst.Ref) void {...@@ -92,13 +92,13 @@ fn appendRefsAssumeCapacity(astgen: *AstGen, refs: []const Zir.Inst.Ref) void {
92 astgen.extra.appendSliceAssumeCapacity(coerced);92 astgen.extra.appendSliceAssumeCapacity(coerced);
93}93}
9494
95pub fn generate(gpa: *Allocator, tree: Ast) Allocator.Error!Zir {95pub fn generate(gpa: Allocator, tree: Ast) Allocator.Error!Zir {
96 var arena = std.heap.ArenaAllocator.init(gpa);96 var arena = std.heap.ArenaAllocator.init(gpa);
97 defer arena.deinit();97 defer arena.deinit();
9898
99 var astgen: AstGen = .{99 var astgen: AstGen = .{
100 .gpa = gpa,100 .gpa = gpa,
101 .arena = &arena.allocator,101 .arena = arena.allocator(),
102 .tree = &tree,102 .tree = &tree,
103 };103 };
104 defer astgen.deinit(gpa);104 defer astgen.deinit(gpa);
...@@ -196,7 +196,7 @@ pub fn generate(gpa: *Allocator, tree: Ast) Allocator.Error!Zir {...@@ -196,7 +196,7 @@ pub fn generate(gpa: *Allocator, tree: Ast) Allocator.Error!Zir {
196 };196 };
197}197}
198198
199pub fn deinit(astgen: *AstGen, gpa: *Allocator) void {199pub fn deinit(astgen: *AstGen, gpa: Allocator) void {
200 astgen.instructions.deinit(gpa);200 astgen.instructions.deinit(gpa);
201 astgen.extra.deinit(gpa);201 astgen.extra.deinit(gpa);
202 astgen.string_table.deinit(gpa);202 astgen.string_table.deinit(gpa);
...@@ -1939,6 +1939,7 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod...@@ -1939,6 +1939,7 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod
19391939
1940 var block_arena = std.heap.ArenaAllocator.init(gz.astgen.gpa);1940 var block_arena = std.heap.ArenaAllocator.init(gz.astgen.gpa);
1941 defer block_arena.deinit();1941 defer block_arena.deinit();
1942 const block_arena_allocator = block_arena.allocator();
19421943
1943 var noreturn_src_node: Ast.Node.Index = 0;1944 var noreturn_src_node: Ast.Node.Index = 0;
1944 var scope = parent_scope;1945 var scope = parent_scope;
...@@ -1959,13 +1960,13 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod...@@ -1959,13 +1960,13 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod
1959 }1960 }
1960 switch (node_tags[statement]) {1961 switch (node_tags[statement]) {
1961 // zig fmt: off1962 // zig fmt: off
1962 .global_var_decl => scope = try varDecl(gz, scope, statement, &block_arena.allocator, tree.globalVarDecl(statement)),1963 .global_var_decl => scope = try varDecl(gz, scope, statement, block_arena_allocator, tree.globalVarDecl(statement)),
1963 .local_var_decl => scope = try varDecl(gz, scope, statement, &block_arena.allocator, tree.localVarDecl(statement)),1964 .local_var_decl => scope = try varDecl(gz, scope, statement, block_arena_allocator, tree.localVarDecl(statement)),
1964 .simple_var_decl => scope = try varDecl(gz, scope, statement, &block_arena.allocator, tree.simpleVarDecl(statement)),1965 .simple_var_decl => scope = try varDecl(gz, scope, statement, block_arena_allocator, tree.simpleVarDecl(statement)),
1965 .aligned_var_decl => scope = try varDecl(gz, scope, statement, &block_arena.allocator, tree.alignedVarDecl(statement)),1966 .aligned_var_decl => scope = try varDecl(gz, scope, statement, block_arena_allocator, tree.alignedVarDecl(statement)),
19661967
1967 .@"defer" => scope = try makeDeferScope(gz.astgen, scope, statement, &block_arena.allocator, .defer_normal),1968 .@"defer" => scope = try makeDeferScope(gz.astgen, scope, statement, block_arena_allocator, .defer_normal),
1968 .@"errdefer" => scope = try makeDeferScope(gz.astgen, scope, statement, &block_arena.allocator, .defer_error),1969 .@"errdefer" => scope = try makeDeferScope(gz.astgen, scope, statement, block_arena_allocator, .defer_error),
19691970
1970 .assign => try assign(gz, scope, statement),1971 .assign => try assign(gz, scope, statement),
19711972
...@@ -2460,7 +2461,7 @@ fn makeDeferScope(...@@ -2460,7 +2461,7 @@ fn makeDeferScope(
2460 astgen: *AstGen,2461 astgen: *AstGen,
2461 scope: *Scope,2462 scope: *Scope,
2462 node: Ast.Node.Index,2463 node: Ast.Node.Index,
2463 block_arena: *Allocator,2464 block_arena: Allocator,
2464 scope_tag: Scope.Tag,2465 scope_tag: Scope.Tag,
2465) InnerError!*Scope {2466) InnerError!*Scope {
2466 const tree = astgen.tree;2467 const tree = astgen.tree;
...@@ -2486,7 +2487,7 @@ fn varDecl(...@@ -2486,7 +2487,7 @@ fn varDecl(
2486 gz: *GenZir,2487 gz: *GenZir,
2487 scope: *Scope,2488 scope: *Scope,
2488 node: Ast.Node.Index,2489 node: Ast.Node.Index,
2489 block_arena: *Allocator,2490 block_arena: Allocator,
2490 var_decl: Ast.full.VarDecl,2491 var_decl: Ast.full.VarDecl,
2491) InnerError!*Scope {2492) InnerError!*Scope {
2492 try emitDbgNode(gz, node);2493 try emitDbgNode(gz, node);
...@@ -3030,7 +3031,7 @@ const WipMembers = struct {...@@ -3030,7 +3031,7 @@ const WipMembers = struct {
3030 /// (4 for src_hash + line + name + value + align + link_section + address_space)3031 /// (4 for src_hash + line + name + value + align + link_section + address_space)
3031 const max_decl_size = 10;3032 const max_decl_size = 10;
30323033
3033 pub fn init(gpa: *Allocator, payload: *ArrayListUnmanaged(u32), decl_count: u32, field_count: u32, comptime bits_per_field: u32, comptime max_field_size: u32) Allocator.Error!Self {3034 pub fn init(gpa: Allocator, payload: *ArrayListUnmanaged(u32), decl_count: u32, field_count: u32, comptime bits_per_field: u32, comptime max_field_size: u32) Allocator.Error!Self {
3034 const payload_top = @intCast(u32, payload.items.len);3035 const payload_top = @intCast(u32, payload.items.len);
3035 const decls_start = payload_top + (decl_count + decls_per_u32 - 1) / decls_per_u32;3036 const decls_start = payload_top + (decl_count + decls_per_u32 - 1) / decls_per_u32;
3036 const field_bits_start = decls_start + decl_count * max_decl_size;3037 const field_bits_start = decls_start + decl_count * max_decl_size;
...@@ -6178,7 +6179,7 @@ fn tunnelThroughClosure(...@@ -6178,7 +6179,7 @@ fn tunnelThroughClosure(
6178 ns: ?*Scope.Namespace,6179 ns: ?*Scope.Namespace,
6179 value: Zir.Inst.Ref,6180 value: Zir.Inst.Ref,
6180 token: Ast.TokenIndex,6181 token: Ast.TokenIndex,
6181 gpa: *Allocator,6182 gpa: Allocator,
6182) !Zir.Inst.Ref {6183) !Zir.Inst.Ref {
6183 // For trivial values, we don't need a tunnel.6184 // For trivial values, we don't need a tunnel.
6184 // Just return the ref.6185 // Just return the ref.
...@@ -8852,7 +8853,7 @@ const Scope = struct {...@@ -8852,7 +8853,7 @@ const Scope = struct {
8852 /// ref of the capture for decls in this namespace8853 /// ref of the capture for decls in this namespace
8853 captures: std.AutoArrayHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index) = .{},8854 captures: std.AutoArrayHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index) = .{},
88548855
8855 pub fn deinit(self: *Namespace, gpa: *Allocator) void {8856 pub fn deinit(self: *Namespace, gpa: Allocator) void {
8856 self.decls.deinit(gpa);8857 self.decls.deinit(gpa);
8857 self.captures.deinit(gpa);8858 self.captures.deinit(gpa);
8858 self.* = undefined;8859 self.* = undefined;
src/Cache.zig+2-2
...@@ -1,4 +1,4 @@...@@ -1,4 +1,4 @@
1gpa: *Allocator,1gpa: Allocator,
2manifest_dir: fs.Dir,2manifest_dir: fs.Dir,
3hash: HashHelper = .{},3hash: HashHelper = .{},
44
...@@ -48,7 +48,7 @@ pub const File = struct {...@@ -48,7 +48,7 @@ pub const File = struct {
48 bin_digest: BinDigest,48 bin_digest: BinDigest,
49 contents: ?[]const u8,49 contents: ?[]const u8,
5050
51 pub fn deinit(self: *File, allocator: *Allocator) void {51 pub fn deinit(self: *File, allocator: Allocator) void {
52 if (self.path) |owned_slice| {52 if (self.path) |owned_slice| {
53 allocator.free(owned_slice);53 allocator.free(owned_slice);
54 self.path = null;54 self.path = null;
src/Compilation.zig+49-46
...@@ -36,7 +36,7 @@ const libtsan = @import("libtsan.zig");...@@ -36,7 +36,7 @@ const libtsan = @import("libtsan.zig");
36const Zir = @import("Zir.zig");36const Zir = @import("Zir.zig");
3737
38/// General-purpose allocator. Used for both temporary and long-term storage.38/// General-purpose allocator. Used for both temporary and long-term storage.
39gpa: *Allocator,39gpa: Allocator,
40/// Arena-allocated memory used during initialization. Should be untouched until deinit.40/// Arena-allocated memory used during initialization. Should be untouched until deinit.
41arena_state: std.heap.ArenaAllocator.State,41arena_state: std.heap.ArenaAllocator.State,
42bin_file: *link.File,42bin_file: *link.File,
...@@ -164,7 +164,7 @@ pub const CRTFile = struct {...@@ -164,7 +164,7 @@ pub const CRTFile = struct {
164 lock: Cache.Lock,164 lock: Cache.Lock,
165 full_object_path: []const u8,165 full_object_path: []const u8,
166166
167 fn deinit(self: *CRTFile, gpa: *Allocator) void {167 fn deinit(self: *CRTFile, gpa: Allocator) void {
168 self.lock.release();168 self.lock.release();
169 gpa.free(self.full_object_path);169 gpa.free(self.full_object_path);
170 self.* = undefined;170 self.* = undefined;
...@@ -253,14 +253,14 @@ pub const CObject = struct {...@@ -253,14 +253,14 @@ pub const CObject = struct {
253 line: u32,253 line: u32,
254 column: u32,254 column: u32,
255255
256 pub fn destroy(em: *ErrorMsg, gpa: *Allocator) void {256 pub fn destroy(em: *ErrorMsg, gpa: Allocator) void {
257 gpa.free(em.msg);257 gpa.free(em.msg);
258 gpa.destroy(em);258 gpa.destroy(em);
259 }259 }
260 };260 };
261261
262 /// Returns if there was failure.262 /// Returns if there was failure.
263 pub fn clearStatus(self: *CObject, gpa: *Allocator) bool {263 pub fn clearStatus(self: *CObject, gpa: Allocator) bool {
264 switch (self.status) {264 switch (self.status) {
265 .new => return false,265 .new => return false,
266 .failure, .failure_retryable => {266 .failure, .failure_retryable => {
...@@ -276,7 +276,7 @@ pub const CObject = struct {...@@ -276,7 +276,7 @@ pub const CObject = struct {
276 }276 }
277 }277 }
278278
279 pub fn destroy(self: *CObject, gpa: *Allocator) void {279 pub fn destroy(self: *CObject, gpa: Allocator) void {
280 _ = self.clearStatus(gpa);280 _ = self.clearStatus(gpa);
281 gpa.destroy(self);281 gpa.destroy(self);
282 }282 }
...@@ -305,7 +305,7 @@ pub const MiscError = struct {...@@ -305,7 +305,7 @@ pub const MiscError = struct {
305 msg: []u8,305 msg: []u8,
306 children: ?AllErrors = null,306 children: ?AllErrors = null,
307307
308 pub fn deinit(misc_err: *MiscError, gpa: *Allocator) void {308 pub fn deinit(misc_err: *MiscError, gpa: Allocator) void {
309 gpa.free(misc_err.msg);309 gpa.free(misc_err.msg);
310 if (misc_err.children) |*children| {310 if (misc_err.children) |*children| {
311 children.deinit(gpa);311 children.deinit(gpa);
...@@ -402,7 +402,7 @@ pub const AllErrors = struct {...@@ -402,7 +402,7 @@ pub const AllErrors = struct {
402 }402 }
403 };403 };
404404
405 pub fn deinit(self: *AllErrors, gpa: *Allocator) void {405 pub fn deinit(self: *AllErrors, gpa: Allocator) void {
406 self.arena.promote(gpa).deinit();406 self.arena.promote(gpa).deinit();
407 }407 }
408408
...@@ -412,28 +412,29 @@ pub const AllErrors = struct {...@@ -412,28 +412,29 @@ pub const AllErrors = struct {
412 errors: *std.ArrayList(Message),412 errors: *std.ArrayList(Message),
413 module_err_msg: Module.ErrorMsg,413 module_err_msg: Module.ErrorMsg,
414 ) !void {414 ) !void {
415 const notes = try arena.allocator.alloc(Message, module_err_msg.notes.len);415 const allocator = arena.allocator();
416 const notes = try allocator.alloc(Message, module_err_msg.notes.len);
416 for (notes) |*note, i| {417 for (notes) |*note, i| {
417 const module_note = module_err_msg.notes[i];418 const module_note = module_err_msg.notes[i];
418 const source = try module_note.src_loc.file_scope.getSource(module.gpa);419 const source = try module_note.src_loc.file_scope.getSource(module.gpa);
419 const byte_offset = try module_note.src_loc.byteOffset(module.gpa);420 const byte_offset = try module_note.src_loc.byteOffset(module.gpa);
420 const loc = std.zig.findLineColumn(source, byte_offset);421 const loc = std.zig.findLineColumn(source, byte_offset);
421 const file_path = try module_note.src_loc.file_scope.fullPath(&arena.allocator);422 const file_path = try module_note.src_loc.file_scope.fullPath(allocator);
422 note.* = .{423 note.* = .{
423 .src = .{424 .src = .{
424 .src_path = file_path,425 .src_path = file_path,
425 .msg = try arena.allocator.dupe(u8, module_note.msg),426 .msg = try allocator.dupe(u8, module_note.msg),
426 .byte_offset = byte_offset,427 .byte_offset = byte_offset,
427 .line = @intCast(u32, loc.line),428 .line = @intCast(u32, loc.line),
428 .column = @intCast(u32, loc.column),429 .column = @intCast(u32, loc.column),
429 .source_line = try arena.allocator.dupe(u8, loc.source_line),430 .source_line = try allocator.dupe(u8, loc.source_line),
430 },431 },
431 };432 };
432 }433 }
433 if (module_err_msg.src_loc.lazy == .entire_file) {434 if (module_err_msg.src_loc.lazy == .entire_file) {
434 try errors.append(.{435 try errors.append(.{
435 .plain = .{436 .plain = .{
436 .msg = try arena.allocator.dupe(u8, module_err_msg.msg),437 .msg = try allocator.dupe(u8, module_err_msg.msg),
437 },438 },
438 });439 });
439 return;440 return;
...@@ -441,22 +442,22 @@ pub const AllErrors = struct {...@@ -441,22 +442,22 @@ pub const AllErrors = struct {
441 const source = try module_err_msg.src_loc.file_scope.getSource(module.gpa);442 const source = try module_err_msg.src_loc.file_scope.getSource(module.gpa);
442 const byte_offset = try module_err_msg.src_loc.byteOffset(module.gpa);443 const byte_offset = try module_err_msg.src_loc.byteOffset(module.gpa);
443 const loc = std.zig.findLineColumn(source, byte_offset);444 const loc = std.zig.findLineColumn(source, byte_offset);
444 const file_path = try module_err_msg.src_loc.file_scope.fullPath(&arena.allocator);445 const file_path = try module_err_msg.src_loc.file_scope.fullPath(allocator);
445 try errors.append(.{446 try errors.append(.{
446 .src = .{447 .src = .{
447 .src_path = file_path,448 .src_path = file_path,
448 .msg = try arena.allocator.dupe(u8, module_err_msg.msg),449 .msg = try allocator.dupe(u8, module_err_msg.msg),
449 .byte_offset = byte_offset,450 .byte_offset = byte_offset,
450 .line = @intCast(u32, loc.line),451 .line = @intCast(u32, loc.line),
451 .column = @intCast(u32, loc.column),452 .column = @intCast(u32, loc.column),
452 .notes = notes,453 .notes = notes,
453 .source_line = try arena.allocator.dupe(u8, loc.source_line),454 .source_line = try allocator.dupe(u8, loc.source_line),
454 },455 },
455 });456 });
456 }457 }
457458
458 pub fn addZir(459 pub fn addZir(
459 arena: *Allocator,460 arena: Allocator,
460 errors: *std.ArrayList(Message),461 errors: *std.ArrayList(Message),
461 file: *Module.File,462 file: *Module.File,
462 ) !void {463 ) !void {
...@@ -548,18 +549,19 @@ pub const AllErrors = struct {...@@ -548,18 +549,19 @@ pub const AllErrors = struct {
548 msg: []const u8,549 msg: []const u8,
549 optional_children: ?AllErrors,550 optional_children: ?AllErrors,
550 ) !void {551 ) !void {
551 const duped_msg = try arena.allocator.dupe(u8, msg);552 const allocator = arena.allocator();
553 const duped_msg = try allocator.dupe(u8, msg);
552 if (optional_children) |*children| {554 if (optional_children) |*children| {
553 try errors.append(.{ .plain = .{555 try errors.append(.{ .plain = .{
554 .msg = duped_msg,556 .msg = duped_msg,
555 .notes = try dupeList(children.list, &arena.allocator),557 .notes = try dupeList(children.list, allocator),
556 } });558 } });
557 } else {559 } else {
558 try errors.append(.{ .plain = .{ .msg = duped_msg } });560 try errors.append(.{ .plain = .{ .msg = duped_msg } });
559 }561 }
560 }562 }
561563
562 fn dupeList(list: []const Message, arena: *Allocator) Allocator.Error![]Message {564 fn dupeList(list: []const Message, arena: Allocator) Allocator.Error![]Message {
563 const duped_list = try arena.alloc(Message, list.len);565 const duped_list = try arena.alloc(Message, list.len);
564 for (list) |item, i| {566 for (list) |item, i| {
565 duped_list[i] = switch (item) {567 duped_list[i] = switch (item) {
...@@ -589,7 +591,7 @@ pub const Directory = struct {...@@ -589,7 +591,7 @@ pub const Directory = struct {
589 path: ?[]const u8,591 path: ?[]const u8,
590 handle: std.fs.Dir,592 handle: std.fs.Dir,
591593
592 pub fn join(self: Directory, allocator: *Allocator, paths: []const []const u8) ![]u8 {594 pub fn join(self: Directory, allocator: Allocator, paths: []const []const u8) ![]u8 {
593 if (self.path) |p| {595 if (self.path) |p| {
594 // TODO clean way to do this with only 1 allocation596 // TODO clean way to do this with only 1 allocation
595 const part2 = try std.fs.path.join(allocator, paths);597 const part2 = try std.fs.path.join(allocator, paths);
...@@ -600,7 +602,7 @@ pub const Directory = struct {...@@ -600,7 +602,7 @@ pub const Directory = struct {
600 }602 }
601 }603 }
602604
603 pub fn joinZ(self: Directory, allocator: *Allocator, paths: []const []const u8) ![:0]u8 {605 pub fn joinZ(self: Directory, allocator: Allocator, paths: []const []const u8) ![:0]u8 {
604 if (self.path) |p| {606 if (self.path) |p| {
605 // TODO clean way to do this with only 1 allocation607 // TODO clean way to do this with only 1 allocation
606 const part2 = try std.fs.path.join(allocator, paths);608 const part2 = try std.fs.path.join(allocator, paths);
...@@ -786,7 +788,7 @@ fn addPackageTableToCacheHash(...@@ -786,7 +788,7 @@ fn addPackageTableToCacheHash(
786 seen_table: *std.AutoHashMap(*Package, void),788 seen_table: *std.AutoHashMap(*Package, void),
787 hash_type: union(enum) { path_bytes, files: *Cache.Manifest },789 hash_type: union(enum) { path_bytes, files: *Cache.Manifest },
788) (error{OutOfMemory} || std.os.GetCwdError)!void {790) (error{OutOfMemory} || std.os.GetCwdError)!void {
789 const allocator = &arena.allocator;791 const allocator = arena.allocator();
790792
791 const packages = try allocator.alloc(Package.Table.KV, pkg_table.count());793 const packages = try allocator.alloc(Package.Table.KV, pkg_table.count());
792 {794 {
...@@ -829,7 +831,7 @@ fn addPackageTableToCacheHash(...@@ -829,7 +831,7 @@ fn addPackageTableToCacheHash(
829 }831 }
830}832}
831833
832pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {834pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
833 const is_dyn_lib = switch (options.output_mode) {835 const is_dyn_lib = switch (options.output_mode) {
834 .Obj, .Exe => false,836 .Obj, .Exe => false,
835 .Lib => (options.link_mode orelse .Static) == .Dynamic,837 .Lib => (options.link_mode orelse .Static) == .Dynamic,
...@@ -850,7 +852,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -850,7 +852,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
850 // initialization and then is freed in deinit().852 // initialization and then is freed in deinit().
851 var arena_allocator = std.heap.ArenaAllocator.init(gpa);853 var arena_allocator = std.heap.ArenaAllocator.init(gpa);
852 errdefer arena_allocator.deinit();854 errdefer arena_allocator.deinit();
853 const arena = &arena_allocator.allocator;855 const arena = arena_allocator.allocator();
854856
855 // We put the `Compilation` itself in the arena. Freeing the arena will free the module.857 // We put the `Compilation` itself in the arena. Freeing the arena will free the module.
856 // It's initialized later after we prepare the initialization options.858 // It's initialized later after we prepare the initialization options.
...@@ -1212,7 +1214,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -1212,7 +1214,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
1212 {1214 {
1213 var local_arena = std.heap.ArenaAllocator.init(gpa);1215 var local_arena = std.heap.ArenaAllocator.init(gpa);
1214 defer local_arena.deinit();1216 defer local_arena.deinit();
1215 var seen_table = std.AutoHashMap(*Package, void).init(&local_arena.allocator);1217 var seen_table = std.AutoHashMap(*Package, void).init(local_arena.allocator());
1216 try addPackageTableToCacheHash(&hash, &local_arena, main_pkg.table, &seen_table, .path_bytes);1218 try addPackageTableToCacheHash(&hash, &local_arena, main_pkg.table, &seen_table, .path_bytes);
1217 }1219 }
1218 hash.add(valgrind);1220 hash.add(valgrind);
...@@ -2015,6 +2017,7 @@ pub fn totalErrorCount(self: *Compilation) usize {...@@ -2015,6 +2017,7 @@ pub fn totalErrorCount(self: *Compilation) usize {
2015pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {2017pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {
2016 var arena = std.heap.ArenaAllocator.init(self.gpa);2018 var arena = std.heap.ArenaAllocator.init(self.gpa);
2017 errdefer arena.deinit();2019 errdefer arena.deinit();
2020 const arena_allocator = arena.allocator();
20182021
2019 var errors = std.ArrayList(AllErrors.Message).init(self.gpa);2022 var errors = std.ArrayList(AllErrors.Message).init(self.gpa);
2020 defer errors.deinit();2023 defer errors.deinit();
...@@ -2028,8 +2031,8 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {...@@ -2028,8 +2031,8 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {
2028 // C error reporting bubbling up.2031 // C error reporting bubbling up.
2029 try errors.append(.{2032 try errors.append(.{
2030 .src = .{2033 .src = .{
2031 .src_path = try arena.allocator.dupe(u8, c_object.src.src_path),2034 .src_path = try arena_allocator.dupe(u8, c_object.src.src_path),
2032 .msg = try std.fmt.allocPrint(&arena.allocator, "unable to build C object: {s}", .{2035 .msg = try std.fmt.allocPrint(arena_allocator, "unable to build C object: {s}", .{
2033 err_msg.msg,2036 err_msg.msg,
2034 }),2037 }),
2035 .byte_offset = 0,2038 .byte_offset = 0,
...@@ -2054,7 +2057,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {...@@ -2054,7 +2057,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {
2054 // must have completed successfully.2057 // must have completed successfully.
2055 const tree = try entry.key_ptr.*.getTree(module.gpa);2058 const tree = try entry.key_ptr.*.getTree(module.gpa);
2056 assert(tree.errors.len == 0);2059 assert(tree.errors.len == 0);
2057 try AllErrors.addZir(&arena.allocator, &errors, entry.key_ptr.*);2060 try AllErrors.addZir(arena_allocator, &errors, entry.key_ptr.*);
2058 }2061 }
2059 }2062 }
2060 }2063 }
...@@ -2093,7 +2096,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {...@@ -2093,7 +2096,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {
2093 if (errors.items.len == 0 and self.link_error_flags.no_entry_point_found) {2096 if (errors.items.len == 0 and self.link_error_flags.no_entry_point_found) {
2094 try errors.append(.{2097 try errors.append(.{
2095 .plain = .{2098 .plain = .{
2096 .msg = try std.fmt.allocPrint(&arena.allocator, "no entry point found", .{}),2099 .msg = try std.fmt.allocPrint(arena_allocator, "no entry point found", .{}),
2097 },2100 },
2098 });2101 });
2099 }2102 }
...@@ -2125,7 +2128,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {...@@ -2125,7 +2128,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {
2125 assert(errors.items.len == self.totalErrorCount());2128 assert(errors.items.len == self.totalErrorCount());
21262129
2127 return AllErrors{2130 return AllErrors{
2128 .list = try arena.allocator.dupe(AllErrors.Message, errors.items),2131 .list = try arena_allocator.dupe(AllErrors.Message, errors.items),
2129 .arena = arena.state,2132 .arena = arena.state,
2130 };2133 };
2131}2134}
...@@ -2296,7 +2299,7 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress...@@ -2296,7 +2299,7 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress
22962299
2297 var tmp_arena = std.heap.ArenaAllocator.init(gpa);2300 var tmp_arena = std.heap.ArenaAllocator.init(gpa);
2298 defer tmp_arena.deinit();2301 defer tmp_arena.deinit();
2299 const sema_arena = &tmp_arena.allocator;2302 const sema_arena = tmp_arena.allocator();
23002303
2301 const sema_frame = tracy.namedFrame("sema");2304 const sema_frame = tracy.namedFrame("sema");
2302 var sema_frame_ended = false;2305 var sema_frame_ended = false;
...@@ -2391,7 +2394,7 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress...@@ -2391,7 +2394,7 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress
2391 .decl = decl,2394 .decl = decl,
2392 .fwd_decl = fwd_decl.toManaged(gpa),2395 .fwd_decl = fwd_decl.toManaged(gpa),
2393 .typedefs = c_codegen.TypedefMap.init(gpa),2396 .typedefs = c_codegen.TypedefMap.init(gpa),
2394 .typedefs_arena = &typedefs_arena.allocator,2397 .typedefs_arena = typedefs_arena.allocator(),
2395 };2398 };
2396 defer dg.fwd_decl.deinit();2399 defer dg.fwd_decl.deinit();
2397 defer dg.typedefs.deinit();2400 defer dg.typedefs.deinit();
...@@ -2845,7 +2848,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {...@@ -2845,7 +2848,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {
2845 const digest = if (!actual_hit) digest: {2848 const digest = if (!actual_hit) digest: {
2846 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);2849 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
2847 defer arena_allocator.deinit();2850 defer arena_allocator.deinit();
2848 const arena = &arena_allocator.allocator;2851 const arena = arena_allocator.allocator();
28492852
2850 const tmp_digest = man.hash.peek();2853 const tmp_digest = man.hash.peek();
2851 const tmp_dir_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &tmp_digest });2854 const tmp_dir_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &tmp_digest });
...@@ -3100,7 +3103,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P...@@ -3100,7 +3103,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P
31003103
3101 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);3104 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
3102 defer arena_allocator.deinit();3105 defer arena_allocator.deinit();
3103 const arena = &arena_allocator.allocator;3106 const arena = arena_allocator.allocator();
31043107
3105 const c_source_basename = std.fs.path.basename(c_object.src.src_path);3108 const c_source_basename = std.fs.path.basename(c_object.src.src_path);
31063109
...@@ -3267,7 +3270,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P...@@ -3267,7 +3270,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P
3267 };3270 };
3268}3271}
32693272
3270pub fn tmpFilePath(comp: *Compilation, arena: *Allocator, suffix: []const u8) error{OutOfMemory}![]const u8 {3273pub fn tmpFilePath(comp: *Compilation, arena: Allocator, suffix: []const u8) error{OutOfMemory}![]const u8 {
3271 const s = std.fs.path.sep_str;3274 const s = std.fs.path.sep_str;
3272 const rand_int = std.crypto.random.int(u64);3275 const rand_int = std.crypto.random.int(u64);
3273 if (comp.local_cache_directory.path) |p| {3276 if (comp.local_cache_directory.path) |p| {
...@@ -3279,7 +3282,7 @@ pub fn tmpFilePath(comp: *Compilation, arena: *Allocator, suffix: []const u8) er...@@ -3279,7 +3282,7 @@ pub fn tmpFilePath(comp: *Compilation, arena: *Allocator, suffix: []const u8) er
32793282
3280pub fn addTranslateCCArgs(3283pub fn addTranslateCCArgs(
3281 comp: *Compilation,3284 comp: *Compilation,
3282 arena: *Allocator,3285 arena: Allocator,
3283 argv: *std.ArrayList([]const u8),3286 argv: *std.ArrayList([]const u8),
3284 ext: FileExt,3287 ext: FileExt,
3285 out_dep_path: ?[]const u8,3288 out_dep_path: ?[]const u8,
...@@ -3293,7 +3296,7 @@ pub fn addTranslateCCArgs(...@@ -3293,7 +3296,7 @@ pub fn addTranslateCCArgs(
3293/// Add common C compiler args between translate-c and C object compilation.3296/// Add common C compiler args between translate-c and C object compilation.
3294pub fn addCCArgs(3297pub fn addCCArgs(
3295 comp: *const Compilation,3298 comp: *const Compilation,
3296 arena: *Allocator,3299 arena: Allocator,
3297 argv: *std.ArrayList([]const u8),3300 argv: *std.ArrayList([]const u8),
3298 ext: FileExt,3301 ext: FileExt,
3299 out_dep_path: ?[]const u8,3302 out_dep_path: ?[]const u8,
...@@ -3780,7 +3783,7 @@ const LibCDirs = struct {...@@ -3780,7 +3783,7 @@ const LibCDirs = struct {
3780 libc_installation: ?*const LibCInstallation,3783 libc_installation: ?*const LibCInstallation,
3781};3784};
37823785
3783fn getZigShippedLibCIncludeDirsDarwin(arena: *Allocator, zig_lib_dir: []const u8, target: Target) !LibCDirs {3786fn getZigShippedLibCIncludeDirsDarwin(arena: Allocator, zig_lib_dir: []const u8, target: Target) !LibCDirs {
3784 const arch_name = @tagName(target.cpu.arch);3787 const arch_name = @tagName(target.cpu.arch);
3785 const os_name = try std.fmt.allocPrint(arena, "{s}.{d}", .{3788 const os_name = try std.fmt.allocPrint(arena, "{s}.{d}", .{
3786 @tagName(target.os.tag),3789 @tagName(target.os.tag),
...@@ -3812,7 +3815,7 @@ fn getZigShippedLibCIncludeDirsDarwin(arena: *Allocator, zig_lib_dir: []const u8...@@ -3812,7 +3815,7 @@ fn getZigShippedLibCIncludeDirsDarwin(arena: *Allocator, zig_lib_dir: []const u8
3812}3815}
38133816
3814fn detectLibCIncludeDirs(3817fn detectLibCIncludeDirs(
3815 arena: *Allocator,3818 arena: Allocator,
3816 zig_lib_dir: []const u8,3819 zig_lib_dir: []const u8,
3817 target: Target,3820 target: Target,
3818 is_native_abi: bool,3821 is_native_abi: bool,
...@@ -3937,7 +3940,7 @@ fn detectLibCIncludeDirs(...@@ -3937,7 +3940,7 @@ fn detectLibCIncludeDirs(
3937 };3940 };
3938}3941}
39393942
3940fn detectLibCFromLibCInstallation(arena: *Allocator, target: Target, lci: *const LibCInstallation) !LibCDirs {3943fn detectLibCFromLibCInstallation(arena: Allocator, target: Target, lci: *const LibCInstallation) !LibCDirs {
3941 var list = try std.ArrayList([]const u8).initCapacity(arena, 4);3944 var list = try std.ArrayList([]const u8).initCapacity(arena, 4);
39423945
3943 list.appendAssumeCapacity(lci.include_dir.?);3946 list.appendAssumeCapacity(lci.include_dir.?);
...@@ -3969,7 +3972,7 @@ fn detectLibCFromLibCInstallation(arena: *Allocator, target: Target, lci: *const...@@ -3969,7 +3972,7 @@ fn detectLibCFromLibCInstallation(arena: *Allocator, target: Target, lci: *const
3969 };3972 };
3970}3973}
39713974
3972pub fn get_libc_crt_file(comp: *Compilation, arena: *Allocator, basename: []const u8) ![]const u8 {3975pub fn get_libc_crt_file(comp: *Compilation, arena: Allocator, basename: []const u8) ![]const u8 {
3973 if (comp.wantBuildGLibCFromSource() or3976 if (comp.wantBuildGLibCFromSource() or
3974 comp.wantBuildMuslFromSource() or3977 comp.wantBuildMuslFromSource() or
3975 comp.wantBuildMinGWFromSource() or3978 comp.wantBuildMinGWFromSource() or
...@@ -4070,7 +4073,7 @@ pub fn dump_argv(argv: []const []const u8) void {...@@ -4070,7 +4073,7 @@ pub fn dump_argv(argv: []const []const u8) void {
4070 std.debug.print("{s}\n", .{argv[argv.len - 1]});4073 std.debug.print("{s}\n", .{argv[argv.len - 1]});
4071}4074}
40724075
4073pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) Allocator.Error![]u8 {4076pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Allocator.Error![]u8 {
4074 const t = trace(@src());4077 const t = trace(@src());
4075 defer t.end();4078 defer t.end();
40764079
...@@ -4421,7 +4424,7 @@ fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node...@@ -4421,7 +4424,7 @@ fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node
44214424
4422 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);4425 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
4423 defer arena_allocator.deinit();4426 defer arena_allocator.deinit();
4424 const arena = &arena_allocator.allocator;4427 const arena = arena_allocator.allocator();
44254428
4426 // Here we use the legacy stage1 C++ compiler to compile Zig code.4429 // Here we use the legacy stage1 C++ compiler to compile Zig code.
4427 const mod = comp.bin_file.options.module.?;4430 const mod = comp.bin_file.options.module.?;
...@@ -4458,7 +4461,7 @@ fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node...@@ -4458,7 +4461,7 @@ fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node
44584461
4459 _ = try man.addFile(main_zig_file, null);4462 _ = try man.addFile(main_zig_file, null);
4460 {4463 {
4461 var seen_table = std.AutoHashMap(*Package, void).init(&arena_allocator.allocator);4464 var seen_table = std.AutoHashMap(*Package, void).init(arena_allocator.allocator());
4462 try addPackageTableToCacheHash(&man.hash, &arena_allocator, mod.main_pkg.table, &seen_table, .{ .files = &man });4465 try addPackageTableToCacheHash(&man.hash, &arena_allocator, mod.main_pkg.table, &seen_table, .{ .files = &man });
4463 }4466 }
4464 man.hash.add(comp.bin_file.options.valgrind);4467 man.hash.add(comp.bin_file.options.valgrind);
...@@ -4721,14 +4724,14 @@ fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node...@@ -4721,14 +4724,14 @@ fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node
4721 comp.stage1_lock = man.toOwnedLock();4724 comp.stage1_lock = man.toOwnedLock();
4722}4725}
47234726
4724fn stage1LocPath(arena: *Allocator, opt_loc: ?EmitLoc, cache_directory: Directory) ![]const u8 {4727fn stage1LocPath(arena: Allocator, opt_loc: ?EmitLoc, cache_directory: Directory) ![]const u8 {
4725 const loc = opt_loc orelse return "";4728 const loc = opt_loc orelse return "";
4726 const directory = loc.directory orelse cache_directory;4729 const directory = loc.directory orelse cache_directory;
4727 return directory.join(arena, &[_][]const u8{loc.basename});4730 return directory.join(arena, &[_][]const u8{loc.basename});
4728}4731}
47294732
4730fn createStage1Pkg(4733fn createStage1Pkg(
4731 arena: *Allocator,4734 arena: Allocator,
4732 name: []const u8,4735 name: []const u8,
4733 pkg: *Package,4736 pkg: *Package,
4734 parent_pkg: ?*stage1.Pkg,4737 parent_pkg: ?*stage1.Pkg,
src/DepTokenizer.zig+1-1
...@@ -878,7 +878,7 @@ test "error prereq - continuation expecting end-of-line" {...@@ -878,7 +878,7 @@ test "error prereq - continuation expecting end-of-line" {
878// - tokenize input, emit textual representation, and compare to expect878// - tokenize input, emit textual representation, and compare to expect
879fn depTokenizer(input: []const u8, expect: []const u8) !void {879fn depTokenizer(input: []const u8, expect: []const u8) !void {
880 var arena_allocator = std.heap.ArenaAllocator.init(std.testing.allocator);880 var arena_allocator = std.heap.ArenaAllocator.init(std.testing.allocator);
881 const arena = &arena_allocator.allocator;881 const arena = arena_allocator.allocator();
882 defer arena_allocator.deinit();882 defer arena_allocator.deinit();
883883
884 var it: Tokenizer = .{ .bytes = input };884 var it: Tokenizer = .{ .bytes = input };
src/Liveness.zig+3-3
...@@ -51,7 +51,7 @@ pub const SwitchBr = struct {...@@ -51,7 +51,7 @@ pub const SwitchBr = struct {
51 else_death_count: u32,51 else_death_count: u32,
52};52};
5353
54pub fn analyze(gpa: *Allocator, air: Air, zir: Zir) Allocator.Error!Liveness {54pub fn analyze(gpa: Allocator, air: Air, zir: Zir) Allocator.Error!Liveness {
55 const tracy = trace(@src());55 const tracy = trace(@src());
56 defer tracy.end();56 defer tracy.end();
5757
...@@ -136,7 +136,7 @@ pub fn getCondBr(l: Liveness, inst: Air.Inst.Index) CondBrSlices {...@@ -136,7 +136,7 @@ pub fn getCondBr(l: Liveness, inst: Air.Inst.Index) CondBrSlices {
136 };136 };
137}137}
138138
139pub fn deinit(l: *Liveness, gpa: *Allocator) void {139pub fn deinit(l: *Liveness, gpa: Allocator) void {
140 gpa.free(l.tomb_bits);140 gpa.free(l.tomb_bits);
141 gpa.free(l.extra);141 gpa.free(l.extra);
142 l.special.deinit(gpa);142 l.special.deinit(gpa);
...@@ -150,7 +150,7 @@ pub const OperandInt = std.math.Log2Int(Bpi);...@@ -150,7 +150,7 @@ pub const OperandInt = std.math.Log2Int(Bpi);
150150
151/// In-progress data; on successful analysis converted into `Liveness`.151/// In-progress data; on successful analysis converted into `Liveness`.
152const Analysis = struct {152const Analysis = struct {
153 gpa: *Allocator,153 gpa: Allocator,
154 air: Air,154 air: Air,
155 table: std.AutoHashMapUnmanaged(Air.Inst.Index, void),155 table: std.AutoHashMapUnmanaged(Air.Inst.Index, void),
156 tomb_bits: []usize,156 tomb_bits: []usize,
src/Module.zig+66-61
...@@ -30,7 +30,7 @@ const target_util = @import("target.zig");...@@ -30,7 +30,7 @@ const target_util = @import("target.zig");
30const build_options = @import("build_options");30const build_options = @import("build_options");
3131
32/// General-purpose allocator. Used for both temporary and long-term storage.32/// General-purpose allocator. Used for both temporary and long-term storage.
33gpa: *Allocator,33gpa: Allocator,
34comp: *Compilation,34comp: *Compilation,
3535
36/// Where our incremental compilation metadata serialization will go.36/// Where our incremental compilation metadata serialization will go.
...@@ -299,10 +299,10 @@ pub const CaptureScope = struct {...@@ -299,10 +299,10 @@ pub const CaptureScope = struct {
299pub const WipCaptureScope = struct {299pub const WipCaptureScope = struct {
300 scope: *CaptureScope,300 scope: *CaptureScope,
301 finalized: bool,301 finalized: bool,
302 gpa: *Allocator,302 gpa: Allocator,
303 perm_arena: *Allocator,303 perm_arena: Allocator,
304304
305 pub fn init(gpa: *Allocator, perm_arena: *Allocator, parent: ?*CaptureScope) !@This() {305 pub fn init(gpa: Allocator, perm_arena: Allocator, parent: ?*CaptureScope) !@This() {
306 const scope = try perm_arena.create(CaptureScope);306 const scope = try perm_arena.create(CaptureScope);
307 scope.* = .{ .parent = parent };307 scope.* = .{ .parent = parent };
308 return @This(){308 return @This(){
...@@ -469,7 +469,7 @@ pub const Decl = struct {...@@ -469,7 +469,7 @@ pub const Decl = struct {
469469
470 pub const DepsTable = std.AutoArrayHashMapUnmanaged(*Decl, void);470 pub const DepsTable = std.AutoArrayHashMapUnmanaged(*Decl, void);
471471
472 pub fn clearName(decl: *Decl, gpa: *Allocator) void {472 pub fn clearName(decl: *Decl, gpa: Allocator) void {
473 gpa.free(mem.sliceTo(decl.name, 0));473 gpa.free(mem.sliceTo(decl.name, 0));
474 decl.name = undefined;474 decl.name = undefined;
475 }475 }
...@@ -499,7 +499,7 @@ pub const Decl = struct {...@@ -499,7 +499,7 @@ pub const Decl = struct {
499 }499 }
500 }500 }
501501
502 pub fn clearValues(decl: *Decl, gpa: *Allocator) void {502 pub fn clearValues(decl: *Decl, gpa: Allocator) void {
503 if (decl.getFunction()) |func| {503 if (decl.getFunction()) |func| {
504 func.deinit(gpa);504 func.deinit(gpa);
505 gpa.destroy(func);505 gpa.destroy(func);
...@@ -517,7 +517,7 @@ pub const Decl = struct {...@@ -517,7 +517,7 @@ pub const Decl = struct {
517517
518 pub fn finalizeNewArena(decl: *Decl, arena: *std.heap.ArenaAllocator) !void {518 pub fn finalizeNewArena(decl: *Decl, arena: *std.heap.ArenaAllocator) !void {
519 assert(decl.value_arena == null);519 assert(decl.value_arena == null);
520 const arena_state = try arena.allocator.create(std.heap.ArenaAllocator.State);520 const arena_state = try arena.allocator().create(std.heap.ArenaAllocator.State);
521 arena_state.* = arena.state;521 arena_state.* = arena.state;
522 decl.value_arena = arena_state;522 decl.value_arena = arena_state;
523 }523 }
...@@ -636,7 +636,7 @@ pub const Decl = struct {...@@ -636,7 +636,7 @@ pub const Decl = struct {
636 return decl.src_namespace.renderFullyQualifiedDebugName(unqualified_name, writer);636 return decl.src_namespace.renderFullyQualifiedDebugName(unqualified_name, writer);
637 }637 }
638638
639 pub fn getFullyQualifiedName(decl: Decl, gpa: *Allocator) ![:0]u8 {639 pub fn getFullyQualifiedName(decl: Decl, gpa: Allocator) ![:0]u8 {
640 var buffer = std.ArrayList(u8).init(gpa);640 var buffer = std.ArrayList(u8).init(gpa);
641 defer buffer.deinit();641 defer buffer.deinit();
642 try decl.renderFullyQualifiedName(buffer.writer());642 try decl.renderFullyQualifiedName(buffer.writer());
...@@ -855,7 +855,7 @@ pub const Struct = struct {...@@ -855,7 +855,7 @@ pub const Struct = struct {
855 is_comptime: bool,855 is_comptime: bool,
856 };856 };
857857
858 pub fn getFullyQualifiedName(s: *Struct, gpa: *Allocator) ![:0]u8 {858 pub fn getFullyQualifiedName(s: *Struct, gpa: Allocator) ![:0]u8 {
859 return s.owner_decl.getFullyQualifiedName(gpa);859 return s.owner_decl.getFullyQualifiedName(gpa);
860 }860 }
861861
...@@ -999,7 +999,7 @@ pub const Union = struct {...@@ -999,7 +999,7 @@ pub const Union = struct {
999999
1000 pub const Fields = std.StringArrayHashMapUnmanaged(Field);1000 pub const Fields = std.StringArrayHashMapUnmanaged(Field);
10011001
1002 pub fn getFullyQualifiedName(s: *Union, gpa: *Allocator) ![:0]u8 {1002 pub fn getFullyQualifiedName(s: *Union, gpa: Allocator) ![:0]u8 {
1003 return s.owner_decl.getFullyQualifiedName(gpa);1003 return s.owner_decl.getFullyQualifiedName(gpa);
1004 }1004 }
10051005
...@@ -1178,7 +1178,7 @@ pub const Opaque = struct {...@@ -1178,7 +1178,7 @@ pub const Opaque = struct {
1178 };1178 };
1179 }1179 }
11801180
1181 pub fn getFullyQualifiedName(s: *Opaque, gpa: *Allocator) ![:0]u8 {1181 pub fn getFullyQualifiedName(s: *Opaque, gpa: Allocator) ![:0]u8 {
1182 return s.owner_decl.getFullyQualifiedName(gpa);1182 return s.owner_decl.getFullyQualifiedName(gpa);
1183 }1183 }
1184};1184};
...@@ -1225,7 +1225,7 @@ pub const Fn = struct {...@@ -1225,7 +1225,7 @@ pub const Fn = struct {
1225 success,1225 success,
1226 };1226 };
12271227
1228 pub fn deinit(func: *Fn, gpa: *Allocator) void {1228 pub fn deinit(func: *Fn, gpa: Allocator) void {
1229 if (func.getInferredErrorSet()) |map| {1229 if (func.getInferredErrorSet()) |map| {
1230 map.deinit(gpa);1230 map.deinit(gpa);
1231 }1231 }
...@@ -1422,27 +1422,27 @@ pub const File = struct {...@@ -1422,27 +1422,27 @@ pub const File = struct {
1422 /// successful, this field is unloaded.1422 /// successful, this field is unloaded.
1423 prev_zir: ?*Zir = null,1423 prev_zir: ?*Zir = null,
14241424
1425 pub fn unload(file: *File, gpa: *Allocator) void {1425 pub fn unload(file: *File, gpa: Allocator) void {
1426 file.unloadTree(gpa);1426 file.unloadTree(gpa);
1427 file.unloadSource(gpa);1427 file.unloadSource(gpa);
1428 file.unloadZir(gpa);1428 file.unloadZir(gpa);
1429 }1429 }
14301430
1431 pub fn unloadTree(file: *File, gpa: *Allocator) void {1431 pub fn unloadTree(file: *File, gpa: Allocator) void {
1432 if (file.tree_loaded) {1432 if (file.tree_loaded) {
1433 file.tree_loaded = false;1433 file.tree_loaded = false;
1434 file.tree.deinit(gpa);1434 file.tree.deinit(gpa);
1435 }1435 }
1436 }1436 }
14371437
1438 pub fn unloadSource(file: *File, gpa: *Allocator) void {1438 pub fn unloadSource(file: *File, gpa: Allocator) void {
1439 if (file.source_loaded) {1439 if (file.source_loaded) {
1440 file.source_loaded = false;1440 file.source_loaded = false;
1441 gpa.free(file.source);1441 gpa.free(file.source);
1442 }1442 }
1443 }1443 }
14441444
1445 pub fn unloadZir(file: *File, gpa: *Allocator) void {1445 pub fn unloadZir(file: *File, gpa: Allocator) void {
1446 if (file.zir_loaded) {1446 if (file.zir_loaded) {
1447 file.zir_loaded = false;1447 file.zir_loaded = false;
1448 file.zir.deinit(gpa);1448 file.zir.deinit(gpa);
...@@ -1466,7 +1466,7 @@ pub const File = struct {...@@ -1466,7 +1466,7 @@ pub const File = struct {
1466 file.* = undefined;1466 file.* = undefined;
1467 }1467 }
14681468
1469 pub fn getSource(file: *File, gpa: *Allocator) ![:0]const u8 {1469 pub fn getSource(file: *File, gpa: Allocator) ![:0]const u8 {
1470 if (file.source_loaded) return file.source;1470 if (file.source_loaded) return file.source;
14711471
1472 const root_dir_path = file.pkg.root_src_directory.path orelse ".";1472 const root_dir_path = file.pkg.root_src_directory.path orelse ".";
...@@ -1499,7 +1499,7 @@ pub const File = struct {...@@ -1499,7 +1499,7 @@ pub const File = struct {
1499 return source;1499 return source;
1500 }1500 }
15011501
1502 pub fn getTree(file: *File, gpa: *Allocator) !*const Ast {1502 pub fn getTree(file: *File, gpa: Allocator) !*const Ast {
1503 if (file.tree_loaded) return &file.tree;1503 if (file.tree_loaded) return &file.tree;
15041504
1505 const source = try file.getSource(gpa);1505 const source = try file.getSource(gpa);
...@@ -1531,7 +1531,7 @@ pub const File = struct {...@@ -1531,7 +1531,7 @@ pub const File = struct {
1531 };1531 };
1532 }1532 }
15331533
1534 pub fn fullyQualifiedNameZ(file: File, gpa: *Allocator) ![:0]u8 {1534 pub fn fullyQualifiedNameZ(file: File, gpa: Allocator) ![:0]u8 {
1535 var buf = std.ArrayList(u8).init(gpa);1535 var buf = std.ArrayList(u8).init(gpa);
1536 defer buf.deinit();1536 defer buf.deinit();
1537 try file.renderFullyQualifiedName(buf.writer());1537 try file.renderFullyQualifiedName(buf.writer());
...@@ -1539,7 +1539,7 @@ pub const File = struct {...@@ -1539,7 +1539,7 @@ pub const File = struct {
1539 }1539 }
15401540
1541 /// Returns the full path to this file relative to its package.1541 /// Returns the full path to this file relative to its package.
1542 pub fn fullPath(file: File, ally: *Allocator) ![]u8 {1542 pub fn fullPath(file: File, ally: Allocator) ![]u8 {
1543 return file.pkg.root_src_directory.join(ally, &[_][]const u8{file.sub_file_path});1543 return file.pkg.root_src_directory.join(ally, &[_][]const u8{file.sub_file_path});
1544 }1544 }
15451545
...@@ -1594,7 +1594,7 @@ pub const ErrorMsg = struct {...@@ -1594,7 +1594,7 @@ pub const ErrorMsg = struct {
1594 notes: []ErrorMsg = &.{},1594 notes: []ErrorMsg = &.{},
15951595
1596 pub fn create(1596 pub fn create(
1597 gpa: *Allocator,1597 gpa: Allocator,
1598 src_loc: SrcLoc,1598 src_loc: SrcLoc,
1599 comptime format: []const u8,1599 comptime format: []const u8,
1600 args: anytype,1600 args: anytype,
...@@ -1607,13 +1607,13 @@ pub const ErrorMsg = struct {...@@ -1607,13 +1607,13 @@ pub const ErrorMsg = struct {
16071607
1608 /// Assumes the ErrorMsg struct and msg were both allocated with `gpa`,1608 /// Assumes the ErrorMsg struct and msg were both allocated with `gpa`,
1609 /// as well as all notes.1609 /// as well as all notes.
1610 pub fn destroy(err_msg: *ErrorMsg, gpa: *Allocator) void {1610 pub fn destroy(err_msg: *ErrorMsg, gpa: Allocator) void {
1611 err_msg.deinit(gpa);1611 err_msg.deinit(gpa);
1612 gpa.destroy(err_msg);1612 gpa.destroy(err_msg);
1613 }1613 }
16141614
1615 pub fn init(1615 pub fn init(
1616 gpa: *Allocator,1616 gpa: Allocator,
1617 src_loc: SrcLoc,1617 src_loc: SrcLoc,
1618 comptime format: []const u8,1618 comptime format: []const u8,
1619 args: anytype,1619 args: anytype,
...@@ -1624,7 +1624,7 @@ pub const ErrorMsg = struct {...@@ -1624,7 +1624,7 @@ pub const ErrorMsg = struct {
1624 };1624 };
1625 }1625 }
16261626
1627 pub fn deinit(err_msg: *ErrorMsg, gpa: *Allocator) void {1627 pub fn deinit(err_msg: *ErrorMsg, gpa: Allocator) void {
1628 for (err_msg.notes) |*note| {1628 for (err_msg.notes) |*note| {
1629 note.deinit(gpa);1629 note.deinit(gpa);
1630 }1630 }
...@@ -1651,7 +1651,7 @@ pub const SrcLoc = struct {...@@ -1651,7 +1651,7 @@ pub const SrcLoc = struct {
1651 return @bitCast(Ast.Node.Index, offset + @bitCast(i32, src_loc.parent_decl_node));1651 return @bitCast(Ast.Node.Index, offset + @bitCast(i32, src_loc.parent_decl_node));
1652 }1652 }
16531653
1654 pub fn byteOffset(src_loc: SrcLoc, gpa: *Allocator) !u32 {1654 pub fn byteOffset(src_loc: SrcLoc, gpa: Allocator) !u32 {
1655 switch (src_loc.lazy) {1655 switch (src_loc.lazy) {
1656 .unneeded => unreachable,1656 .unneeded => unreachable,
1657 .entire_file => return 0,1657 .entire_file => return 0,
...@@ -2066,7 +2066,7 @@ pub const SrcLoc = struct {...@@ -2066,7 +2066,7 @@ pub const SrcLoc = struct {
20662066
2067 pub fn byteOffsetBuiltinCallArg(2067 pub fn byteOffsetBuiltinCallArg(
2068 src_loc: SrcLoc,2068 src_loc: SrcLoc,
2069 gpa: *Allocator,2069 gpa: Allocator,
2070 node_off: i32,2070 node_off: i32,
2071 arg_index: u32,2071 arg_index: u32,
2072 ) !u32 {2072 ) !u32 {
...@@ -2464,7 +2464,7 @@ pub fn deinit(mod: *Module) void {...@@ -2464,7 +2464,7 @@ pub fn deinit(mod: *Module) void {
2464 }2464 }
2465}2465}
24662466
2467fn freeExportList(gpa: *Allocator, export_list: []*Export) void {2467fn freeExportList(gpa: Allocator, export_list: []*Export) void {
2468 for (export_list) |exp| {2468 for (export_list) |exp| {
2469 gpa.free(exp.options.name);2469 gpa.free(exp.options.name);
2470 if (exp.options.section) |s| gpa.free(s);2470 if (exp.options.section) |s| gpa.free(s);
...@@ -2871,7 +2871,7 @@ pub fn astGenFile(mod: *Module, file: *File) !void {...@@ -2871,7 +2871,7 @@ pub fn astGenFile(mod: *Module, file: *File) !void {
2871/// * Decl.zir_index2871/// * Decl.zir_index
2872/// * Fn.zir_body_inst2872/// * Fn.zir_body_inst
2873/// * Decl.zir_decl_index2873/// * Decl.zir_decl_index
2874fn updateZirRefs(gpa: *Allocator, file: *File, old_zir: Zir) !void {2874fn updateZirRefs(gpa: Allocator, file: *File, old_zir: Zir) !void {
2875 const new_zir = file.zir;2875 const new_zir = file.zir;
28762876
2877 // Maps from old ZIR to new ZIR, struct_decl, enum_decl, etc. Any instruction which2877 // Maps from old ZIR to new ZIR, struct_decl, enum_decl, etc. Any instruction which
...@@ -2965,7 +2965,7 @@ fn updateZirRefs(gpa: *Allocator, file: *File, old_zir: Zir) !void {...@@ -2965,7 +2965,7 @@ fn updateZirRefs(gpa: *Allocator, file: *File, old_zir: Zir) !void {
2965}2965}
29662966
2967pub fn mapOldZirToNew(2967pub fn mapOldZirToNew(
2968 gpa: *Allocator,2968 gpa: Allocator,
2969 old_zir: Zir,2969 old_zir: Zir,
2970 new_zir: Zir,2970 new_zir: Zir,
2971 inst_map: *std.AutoHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index),2971 inst_map: *std.AutoHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index),
...@@ -3159,10 +3159,11 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {...@@ -3159,10 +3159,11 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
3159 const gpa = mod.gpa;3159 const gpa = mod.gpa;
3160 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);3160 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);
3161 errdefer new_decl_arena.deinit();3161 errdefer new_decl_arena.deinit();
3162 const new_decl_arena_allocator = new_decl_arena.allocator();
31623163
3163 const struct_obj = try new_decl_arena.allocator.create(Module.Struct);3164 const struct_obj = try new_decl_arena_allocator.create(Module.Struct);
3164 const struct_ty = try Type.Tag.@"struct".create(&new_decl_arena.allocator, struct_obj);3165 const struct_ty = try Type.Tag.@"struct".create(new_decl_arena_allocator, struct_obj);
3165 const struct_val = try Value.Tag.ty.create(&new_decl_arena.allocator, struct_ty);3166 const struct_val = try Value.Tag.ty.create(new_decl_arena_allocator, struct_ty);
3166 const ty_ty = comptime Type.initTag(.type);3167 const ty_ty = comptime Type.initTag(.type);
3167 struct_obj.* = .{3168 struct_obj.* = .{
3168 .owner_decl = undefined, // set below3169 .owner_decl = undefined, // set below
...@@ -3202,12 +3203,13 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {...@@ -3202,12 +3203,13 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
32023203
3203 var sema_arena = std.heap.ArenaAllocator.init(gpa);3204 var sema_arena = std.heap.ArenaAllocator.init(gpa);
3204 defer sema_arena.deinit();3205 defer sema_arena.deinit();
3206 const sema_arena_allocator = sema_arena.allocator();
32053207
3206 var sema: Sema = .{3208 var sema: Sema = .{
3207 .mod = mod,3209 .mod = mod,
3208 .gpa = gpa,3210 .gpa = gpa,
3209 .arena = &sema_arena.allocator,3211 .arena = sema_arena_allocator,
3210 .perm_arena = &new_decl_arena.allocator,3212 .perm_arena = new_decl_arena_allocator,
3211 .code = file.zir,3213 .code = file.zir,
3212 .owner_decl = new_decl,3214 .owner_decl = new_decl,
3213 .func = null,3215 .func = null,
...@@ -3216,7 +3218,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {...@@ -3216,7 +3218,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
3216 };3218 };
3217 defer sema.deinit();3219 defer sema.deinit();
32183220
3219 var wip_captures = try WipCaptureScope.init(gpa, &new_decl_arena.allocator, null);3221 var wip_captures = try WipCaptureScope.init(gpa, new_decl_arena_allocator, null);
3220 defer wip_captures.deinit();3222 defer wip_captures.deinit();
32213223
3222 var block_scope: Sema.Block = .{3224 var block_scope: Sema.Block = .{
...@@ -3265,15 +3267,17 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -3265,15 +3267,17 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
3265 // We need the memory for the Type to go into the arena for the Decl3267 // We need the memory for the Type to go into the arena for the Decl
3266 var decl_arena = std.heap.ArenaAllocator.init(gpa);3268 var decl_arena = std.heap.ArenaAllocator.init(gpa);
3267 errdefer decl_arena.deinit();3269 errdefer decl_arena.deinit();
3270 const decl_arena_allocator = decl_arena.allocator();
32683271
3269 var analysis_arena = std.heap.ArenaAllocator.init(gpa);3272 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
3270 defer analysis_arena.deinit();3273 defer analysis_arena.deinit();
3274 const analysis_arena_allocator = analysis_arena.allocator();
32713275
3272 var sema: Sema = .{3276 var sema: Sema = .{
3273 .mod = mod,3277 .mod = mod,
3274 .gpa = gpa,3278 .gpa = gpa,
3275 .arena = &analysis_arena.allocator,3279 .arena = analysis_arena_allocator,
3276 .perm_arena = &decl_arena.allocator,3280 .perm_arena = decl_arena_allocator,
3277 .code = zir,3281 .code = zir,
3278 .owner_decl = decl,3282 .owner_decl = decl,
3279 .func = null,3283 .func = null,
...@@ -3296,7 +3300,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -3296,7 +3300,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
3296 }3300 }
3297 log.debug("semaDecl {*} ({s})", .{ decl, decl.name });3301 log.debug("semaDecl {*} ({s})", .{ decl, decl.name });
32983302
3299 var wip_captures = try WipCaptureScope.init(gpa, &decl_arena.allocator, decl.src_scope);3303 var wip_captures = try WipCaptureScope.init(gpa, decl_arena_allocator, decl.src_scope);
3300 defer wip_captures.deinit();3304 defer wip_captures.deinit();
33013305
3302 var block_scope: Sema.Block = .{3306 var block_scope: Sema.Block = .{
...@@ -3356,7 +3360,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -3356,7 +3360,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
3356 // not the struct itself.3360 // not the struct itself.
3357 try sema.resolveTypeLayout(&block_scope, src, decl_tv.ty);3361 try sema.resolveTypeLayout(&block_scope, src, decl_tv.ty);
33583362
3359 const decl_arena_state = try decl_arena.allocator.create(std.heap.ArenaAllocator.State);3363 const decl_arena_state = try decl_arena_allocator.create(std.heap.ArenaAllocator.State);
33603364
3361 if (decl.is_usingnamespace) {3365 if (decl.is_usingnamespace) {
3362 const ty_ty = Type.initTag(.type);3366 const ty_ty = Type.initTag(.type);
...@@ -3370,7 +3374,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -3370,7 +3374,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
3370 }3374 }
33713375
3372 decl.ty = ty_ty;3376 decl.ty = ty_ty;
3373 decl.val = try Value.Tag.ty.create(&decl_arena.allocator, ty);3377 decl.val = try Value.Tag.ty.create(decl_arena_allocator, ty);
3374 decl.align_val = Value.initTag(.null_value);3378 decl.align_val = Value.initTag(.null_value);
3375 decl.linksection_val = Value.initTag(.null_value);3379 decl.linksection_val = Value.initTag(.null_value);
3376 decl.has_tv = true;3380 decl.has_tv = true;
...@@ -3400,10 +3404,10 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -3400,10 +3404,10 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
3400 decl.clearValues(gpa);3404 decl.clearValues(gpa);
3401 }3405 }
34023406
3403 decl.ty = try decl_tv.ty.copy(&decl_arena.allocator);3407 decl.ty = try decl_tv.ty.copy(decl_arena_allocator);
3404 decl.val = try decl_tv.val.copy(&decl_arena.allocator);3408 decl.val = try decl_tv.val.copy(decl_arena_allocator);
3405 decl.align_val = try align_val.copy(&decl_arena.allocator);3409 decl.align_val = try align_val.copy(decl_arena_allocator);
3406 decl.linksection_val = try linksection_val.copy(&decl_arena.allocator);3410 decl.linksection_val = try linksection_val.copy(decl_arena_allocator);
3407 decl.@"addrspace" = address_space;3411 decl.@"addrspace" = address_space;
3408 decl.has_tv = true;3412 decl.has_tv = true;
3409 decl.owns_tv = owns_tv;3413 decl.owns_tv = owns_tv;
...@@ -3453,7 +3457,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -3453,7 +3457,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
3453 decl.owns_tv = true;3457 decl.owns_tv = true;
3454 queue_linker_work = true;3458 queue_linker_work = true;
34553459
3456 const copied_init = try variable.init.copy(&decl_arena.allocator);3460 const copied_init = try variable.init.copy(decl_arena_allocator);
3457 variable.init = copied_init;3461 variable.init = copied_init;
3458 }3462 }
3459 },3463 },
...@@ -3476,10 +3480,10 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -3476,10 +3480,10 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
3476 },3480 },
3477 }3481 }
34783482
3479 decl.ty = try decl_tv.ty.copy(&decl_arena.allocator);3483 decl.ty = try decl_tv.ty.copy(decl_arena_allocator);
3480 decl.val = try decl_tv.val.copy(&decl_arena.allocator);3484 decl.val = try decl_tv.val.copy(decl_arena_allocator);
3481 decl.align_val = try align_val.copy(&decl_arena.allocator);3485 decl.align_val = try align_val.copy(decl_arena_allocator);
3482 decl.linksection_val = try linksection_val.copy(&decl_arena.allocator);3486 decl.linksection_val = try linksection_val.copy(decl_arena_allocator);
3483 decl.@"addrspace" = address_space;3487 decl.@"addrspace" = address_space;
3484 decl.has_tv = true;3488 decl.has_tv = true;
3485 decl_arena_state.* = decl_arena.state;3489 decl_arena_state.* = decl_arena.state;
...@@ -4119,7 +4123,7 @@ fn deleteDeclExports(mod: *Module, decl: *Decl) void {...@@ -4119,7 +4123,7 @@ fn deleteDeclExports(mod: *Module, decl: *Decl) void {
4119 mod.gpa.free(kv.value);4123 mod.gpa.free(kv.value);
4120}4124}
41214125
4122pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn, arena: *Allocator) SemaError!Air {4126pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn, arena: Allocator) SemaError!Air {
4123 const tracy = trace(@src());4127 const tracy = trace(@src());
4124 defer tracy.end();4128 defer tracy.end();
41254129
...@@ -4128,12 +4132,13 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn, arena: *Allocator) Se...@@ -4128,12 +4132,13 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn, arena: *Allocator) Se
4128 // Use the Decl's arena for captured values.4132 // Use the Decl's arena for captured values.
4129 var decl_arena = decl.value_arena.?.promote(gpa);4133 var decl_arena = decl.value_arena.?.promote(gpa);
4130 defer decl.value_arena.?.* = decl_arena.state;4134 defer decl.value_arena.?.* = decl_arena.state;
4135 const decl_arena_allocator = decl_arena.allocator();
41314136
4132 var sema: Sema = .{4137 var sema: Sema = .{
4133 .mod = mod,4138 .mod = mod,
4134 .gpa = gpa,4139 .gpa = gpa,
4135 .arena = arena,4140 .arena = arena,
4136 .perm_arena = &decl_arena.allocator,4141 .perm_arena = decl_arena_allocator,
4137 .code = decl.getFileScope().zir,4142 .code = decl.getFileScope().zir,
4138 .owner_decl = decl,4143 .owner_decl = decl,
4139 .func = func,4144 .func = func,
...@@ -4147,7 +4152,7 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn, arena: *Allocator) Se...@@ -4147,7 +4152,7 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn, arena: *Allocator) Se
4147 try sema.air_extra.ensureTotalCapacity(gpa, reserved_count);4152 try sema.air_extra.ensureTotalCapacity(gpa, reserved_count);
4148 sema.air_extra.items.len += reserved_count;4153 sema.air_extra.items.len += reserved_count;
41494154
4150 var wip_captures = try WipCaptureScope.init(gpa, &decl_arena.allocator, decl.src_scope);4155 var wip_captures = try WipCaptureScope.init(gpa, decl_arena_allocator, decl.src_scope);
4151 defer wip_captures.deinit();4156 defer wip_captures.deinit();
41524157
4153 var inner_block: Sema.Block = .{4158 var inner_block: Sema.Block = .{
...@@ -4427,7 +4432,7 @@ pub fn getNextAnonNameIndex(mod: *Module) usize {...@@ -4427,7 +4432,7 @@ pub fn getNextAnonNameIndex(mod: *Module) usize {
4427 return @atomicRmw(usize, &mod.next_anon_name_index, .Add, 1, .Monotonic);4432 return @atomicRmw(usize, &mod.next_anon_name_index, .Add, 1, .Monotonic);
4428}4433}
44294434
4430pub fn makeIntType(arena: *Allocator, signedness: std.builtin.Signedness, bits: u16) !Type {4435pub fn makeIntType(arena: Allocator, signedness: std.builtin.Signedness, bits: u16) !Type {
4431 const int_payload = try arena.create(Type.Payload.Bits);4436 const int_payload = try arena.create(Type.Payload.Bits);
4432 int_payload.* = .{4437 int_payload.* = .{
4433 .base = .{4438 .base = .{
...@@ -4459,7 +4464,7 @@ pub fn errNoteNonLazy(...@@ -4459,7 +4464,7 @@ pub fn errNoteNonLazy(
4459}4464}
44604465
4461pub fn errorUnionType(4466pub fn errorUnionType(
4462 arena: *Allocator,4467 arena: Allocator,
4463 error_set: Type,4468 error_set: Type,
4464 payload: Type,4469 payload: Type,
4465) Allocator.Error!Type {4470) Allocator.Error!Type {
...@@ -4511,7 +4516,7 @@ pub const SwitchProngSrc = union(enum) {...@@ -4511,7 +4516,7 @@ pub const SwitchProngSrc = union(enum) {
4511 /// the LazySrcLoc in order to emit a compile error.4516 /// the LazySrcLoc in order to emit a compile error.
4512 pub fn resolve(4517 pub fn resolve(
4513 prong_src: SwitchProngSrc,4518 prong_src: SwitchProngSrc,
4514 gpa: *Allocator,4519 gpa: Allocator,
4515 decl: *Decl,4520 decl: *Decl,
4516 switch_node_offset: i32,4521 switch_node_offset: i32,
4517 range_expand: RangeExpand,4522 range_expand: RangeExpand,
...@@ -4605,7 +4610,7 @@ pub const PeerTypeCandidateSrc = union(enum) {...@@ -4605,7 +4610,7 @@ pub const PeerTypeCandidateSrc = union(enum) {
46054610
4606 pub fn resolve(4611 pub fn resolve(
4607 self: PeerTypeCandidateSrc,4612 self: PeerTypeCandidateSrc,
4608 gpa: *Allocator,4613 gpa: Allocator,
4609 decl: *Decl,4614 decl: *Decl,
4610 candidate_i: usize,4615 candidate_i: usize,
4611 ) ?LazySrcLoc {4616 ) ?LazySrcLoc {
...@@ -4751,7 +4756,7 @@ pub fn populateTestFunctions(mod: *Module) !void {...@@ -4751,7 +4756,7 @@ pub fn populateTestFunctions(mod: *Module) !void {
4751 // decl reference it as a slice.4756 // decl reference it as a slice.
4752 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);4757 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);
4753 errdefer new_decl_arena.deinit();4758 errdefer new_decl_arena.deinit();
4754 const arena = &new_decl_arena.allocator;4759 const arena = new_decl_arena.allocator();
47554760
4756 const test_fn_vals = try arena.alloc(Value, mod.test_functions.count());4761 const test_fn_vals = try arena.alloc(Value, mod.test_functions.count());
4757 const array_decl = try mod.createAnonymousDeclFromDecl(decl, decl.src_namespace, null, .{4762 const array_decl = try mod.createAnonymousDeclFromDecl(decl, decl.src_namespace, null, .{
...@@ -4770,10 +4775,10 @@ pub fn populateTestFunctions(mod: *Module) !void {...@@ -4770,10 +4775,10 @@ pub fn populateTestFunctions(mod: *Module) !void {
4770 const test_name_decl = n: {4775 const test_name_decl = n: {
4771 var name_decl_arena = std.heap.ArenaAllocator.init(gpa);4776 var name_decl_arena = std.heap.ArenaAllocator.init(gpa);
4772 errdefer name_decl_arena.deinit();4777 errdefer name_decl_arena.deinit();
4773 const bytes = try name_decl_arena.allocator.dupe(u8, test_name_slice);4778 const bytes = try arena.dupe(u8, test_name_slice);
4774 const test_name_decl = try mod.createAnonymousDeclFromDecl(array_decl, array_decl.src_namespace, null, .{4779 const test_name_decl = try mod.createAnonymousDeclFromDecl(array_decl, array_decl.src_namespace, null, .{
4775 .ty = try Type.Tag.array_u8.create(&name_decl_arena.allocator, bytes.len),4780 .ty = try Type.Tag.array_u8.create(arena, bytes.len),
4776 .val = try Value.Tag.bytes.create(&name_decl_arena.allocator, bytes),4781 .val = try Value.Tag.bytes.create(arena, bytes),
4777 });4782 });
4778 try test_name_decl.finalizeNewArena(&name_decl_arena);4783 try test_name_decl.finalizeNewArena(&name_decl_arena);
4779 break :n test_name_decl;4784 break :n test_name_decl;
...@@ -4802,7 +4807,7 @@ pub fn populateTestFunctions(mod: *Module) !void {...@@ -4802,7 +4807,7 @@ pub fn populateTestFunctions(mod: *Module) !void {
4802 {4807 {
4803 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);4808 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);
4804 errdefer new_decl_arena.deinit();4809 errdefer new_decl_arena.deinit();
4805 const arena = &new_decl_arena.allocator;4810 const arena = new_decl_arena.allocator();
48064811
4807 // This copy accesses the old Decl Type/Value so it must be done before `clearValues`.4812 // This copy accesses the old Decl Type/Value so it must be done before `clearValues`.
4808 const new_ty = try Type.Tag.const_slice.create(arena, try tmp_test_fn_ty.copy(arena));4813 const new_ty = try Type.Tag.const_slice.create(arena, try tmp_test_fn_ty.copy(arena));
src/Package.zig+6-6
...@@ -21,7 +21,7 @@ root_src_directory_owned: bool = false,...@@ -21,7 +21,7 @@ root_src_directory_owned: bool = false,
2121
22/// Allocate a Package. No references to the slices passed are kept.22/// Allocate a Package. No references to the slices passed are kept.
23pub fn create(23pub fn create(
24 gpa: *Allocator,24 gpa: Allocator,
25 /// Null indicates the current working directory25 /// Null indicates the current working directory
26 root_src_dir_path: ?[]const u8,26 root_src_dir_path: ?[]const u8,
27 /// Relative to root_src_dir_path27 /// Relative to root_src_dir_path
...@@ -49,7 +49,7 @@ pub fn create(...@@ -49,7 +49,7 @@ pub fn create(
49}49}
5050
51pub fn createWithDir(51pub fn createWithDir(
52 gpa: *Allocator,52 gpa: Allocator,
53 directory: Compilation.Directory,53 directory: Compilation.Directory,
54 /// Relative to `directory`. If null, means `directory` is the root src dir54 /// Relative to `directory`. If null, means `directory` is the root src dir
55 /// and is owned externally.55 /// and is owned externally.
...@@ -87,7 +87,7 @@ pub fn createWithDir(...@@ -87,7 +87,7 @@ pub fn createWithDir(
8787
88/// Free all memory associated with this package. It does not destroy any packages88/// Free all memory associated with this package. It does not destroy any packages
89/// inside its table; the caller is responsible for calling destroy() on them.89/// inside its table; the caller is responsible for calling destroy() on them.
90pub fn destroy(pkg: *Package, gpa: *Allocator) void {90pub fn destroy(pkg: *Package, gpa: Allocator) void {
91 gpa.free(pkg.root_src_path);91 gpa.free(pkg.root_src_path);
9292
93 if (pkg.root_src_directory_owned) {93 if (pkg.root_src_directory_owned) {
...@@ -104,7 +104,7 @@ pub fn destroy(pkg: *Package, gpa: *Allocator) void {...@@ -104,7 +104,7 @@ pub fn destroy(pkg: *Package, gpa: *Allocator) void {
104}104}
105105
106/// Only frees memory associated with the table.106/// Only frees memory associated with the table.
107pub fn deinitTable(pkg: *Package, gpa: *Allocator) void {107pub fn deinitTable(pkg: *Package, gpa: Allocator) void {
108 var it = pkg.table.keyIterator();108 var it = pkg.table.keyIterator();
109 while (it.next()) |key| {109 while (it.next()) |key| {
110 gpa.free(key.*);110 gpa.free(key.*);
...@@ -113,13 +113,13 @@ pub fn deinitTable(pkg: *Package, gpa: *Allocator) void {...@@ -113,13 +113,13 @@ pub fn deinitTable(pkg: *Package, gpa: *Allocator) void {
113 pkg.table.deinit(gpa);113 pkg.table.deinit(gpa);
114}114}
115115
116pub fn add(pkg: *Package, gpa: *Allocator, name: []const u8, package: *Package) !void {116pub fn add(pkg: *Package, gpa: Allocator, name: []const u8, package: *Package) !void {
117 try pkg.table.ensureUnusedCapacity(gpa, 1);117 try pkg.table.ensureUnusedCapacity(gpa, 1);
118 const name_dupe = try gpa.dupe(u8, name);118 const name_dupe = try gpa.dupe(u8, name);
119 pkg.table.putAssumeCapacityNoClobber(name_dupe, package);119 pkg.table.putAssumeCapacityNoClobber(name_dupe, package);
120}120}
121121
122pub fn addAndAdopt(parent: *Package, gpa: *Allocator, name: []const u8, child: *Package) !void {122pub fn addAndAdopt(parent: *Package, gpa: Allocator, name: []const u8, child: *Package) !void {
123 assert(child.parent == null); // make up your mind, who is the parent??123 assert(child.parent == null); // make up your mind, who is the parent??
124 child.parent = parent;124 child.parent = parent;
125 return parent.add(gpa, name, child);125 return parent.add(gpa, name, child);
src/RangeSet.zig+1-1
...@@ -13,7 +13,7 @@ pub const Range = struct {...@@ -13,7 +13,7 @@ pub const Range = struct {
13 src: SwitchProngSrc,13 src: SwitchProngSrc,
14};14};
1515
16pub fn init(allocator: *std.mem.Allocator) RangeSet {16pub fn init(allocator: std.mem.Allocator) RangeSet {
17 return .{17 return .{
18 .ranges = std.ArrayList(Range).init(allocator),18 .ranges = std.ArrayList(Range).init(allocator),
19 };19 };
src/Sema.zig+73-63
...@@ -7,13 +7,13 @@...@@ -7,13 +7,13 @@
77
8mod: *Module,8mod: *Module,
9/// Alias to `mod.gpa`.9/// Alias to `mod.gpa`.
10gpa: *Allocator,10gpa: Allocator,
11/// Points to the temporary arena allocator of the Sema.11/// Points to the temporary arena allocator of the Sema.
12/// This arena will be cleared when the sema is destroyed.12/// This arena will be cleared when the sema is destroyed.
13arena: *Allocator,13arena: Allocator,
14/// Points to the arena allocator for the owner_decl.14/// Points to the arena allocator for the owner_decl.
15/// This arena will persist until the decl is invalidated.15/// This arena will persist until the decl is invalidated.
16perm_arena: *Allocator,16perm_arena: Allocator,
17code: Zir,17code: Zir,
18air_instructions: std.MultiArrayList(Air.Inst) = .{},18air_instructions: std.MultiArrayList(Air.Inst) = .{},
19air_extra: std.ArrayListUnmanaged(u32) = .{},19air_extra: std.ArrayListUnmanaged(u32) = .{},
...@@ -417,8 +417,8 @@ pub const Block = struct {...@@ -417,8 +417,8 @@ pub const Block = struct {
417 new_decl_arena: std.heap.ArenaAllocator,417 new_decl_arena: std.heap.ArenaAllocator,
418 finished: bool,418 finished: bool,
419419
420 pub fn arena(wad: *WipAnonDecl) *Allocator {420 pub fn arena(wad: *WipAnonDecl) Allocator {
421 return &wad.new_decl_arena.allocator;421 return wad.new_decl_arena.allocator();
422 }422 }
423423
424 pub fn deinit(wad: *WipAnonDecl) void {424 pub fn deinit(wad: *WipAnonDecl) void {
...@@ -1594,10 +1594,11 @@ fn zirStructDecl(...@@ -1594,10 +1594,11 @@ fn zirStructDecl(
15941594
1595 var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa);1595 var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa);
1596 errdefer new_decl_arena.deinit();1596 errdefer new_decl_arena.deinit();
1597 const new_decl_arena_allocator = new_decl_arena.allocator();
15971598
1598 const struct_obj = try new_decl_arena.allocator.create(Module.Struct);1599 const struct_obj = try new_decl_arena_allocator.create(Module.Struct);
1599 const struct_ty = try Type.Tag.@"struct".create(&new_decl_arena.allocator, struct_obj);1600 const struct_ty = try Type.Tag.@"struct".create(new_decl_arena_allocator, struct_obj);
1600 const struct_val = try Value.Tag.ty.create(&new_decl_arena.allocator, struct_ty);1601 const struct_val = try Value.Tag.ty.create(new_decl_arena_allocator, struct_ty);
1601 const type_name = try sema.createTypeName(block, small.name_strategy);1602 const type_name = try sema.createTypeName(block, small.name_strategy);
1602 const new_decl = try sema.mod.createAnonymousDeclNamed(block, .{1603 const new_decl = try sema.mod.createAnonymousDeclNamed(block, .{
1603 .ty = Type.type,1604 .ty = Type.type,
...@@ -1698,15 +1699,16 @@ fn zirEnumDecl(...@@ -1698,15 +1699,16 @@ fn zirEnumDecl(
16981699
1699 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);1700 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);
1700 errdefer new_decl_arena.deinit();1701 errdefer new_decl_arena.deinit();
1702 const new_decl_arena_allocator = new_decl_arena.allocator();
17011703
1702 const enum_obj = try new_decl_arena.allocator.create(Module.EnumFull);1704 const enum_obj = try new_decl_arena_allocator.create(Module.EnumFull);
1703 const enum_ty_payload = try new_decl_arena.allocator.create(Type.Payload.EnumFull);1705 const enum_ty_payload = try new_decl_arena_allocator.create(Type.Payload.EnumFull);
1704 enum_ty_payload.* = .{1706 enum_ty_payload.* = .{
1705 .base = .{ .tag = if (small.nonexhaustive) .enum_nonexhaustive else .enum_full },1707 .base = .{ .tag = if (small.nonexhaustive) .enum_nonexhaustive else .enum_full },
1706 .data = enum_obj,1708 .data = enum_obj,
1707 };1709 };
1708 const enum_ty = Type.initPayload(&enum_ty_payload.base);1710 const enum_ty = Type.initPayload(&enum_ty_payload.base);
1709 const enum_val = try Value.Tag.ty.create(&new_decl_arena.allocator, enum_ty);1711 const enum_val = try Value.Tag.ty.create(new_decl_arena_allocator, enum_ty);
1710 const type_name = try sema.createTypeName(block, small.name_strategy);1712 const type_name = try sema.createTypeName(block, small.name_strategy);
1711 const new_decl = try mod.createAnonymousDeclNamed(block, .{1713 const new_decl = try mod.createAnonymousDeclNamed(block, .{
1712 .ty = Type.type,1714 .ty = Type.type,
...@@ -1790,17 +1792,17 @@ fn zirEnumDecl(...@@ -1790,17 +1792,17 @@ fn zirEnumDecl(
1790 break :blk try sema.resolveType(block, src, tag_type_ref);1792 break :blk try sema.resolveType(block, src, tag_type_ref);
1791 }1793 }
1792 const bits = std.math.log2_int_ceil(usize, fields_len);1794 const bits = std.math.log2_int_ceil(usize, fields_len);
1793 break :blk try Type.Tag.int_unsigned.create(&new_decl_arena.allocator, bits);1795 break :blk try Type.Tag.int_unsigned.create(new_decl_arena_allocator, bits);
1794 };1796 };
1795 enum_obj.tag_ty = tag_ty;1797 enum_obj.tag_ty = tag_ty;
1796 }1798 }
17971799
1798 try enum_obj.fields.ensureTotalCapacity(&new_decl_arena.allocator, fields_len);1800 try enum_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);
1799 const any_values = for (sema.code.extra[body_end..][0..bit_bags_count]) |bag| {1801 const any_values = for (sema.code.extra[body_end..][0..bit_bags_count]) |bag| {
1800 if (bag != 0) break true;1802 if (bag != 0) break true;
1801 } else false;1803 } else false;
1802 if (any_values) {1804 if (any_values) {
1803 try enum_obj.values.ensureTotalCapacityContext(&new_decl_arena.allocator, fields_len, .{1805 try enum_obj.values.ensureTotalCapacityContext(new_decl_arena_allocator, fields_len, .{
1804 .ty = enum_obj.tag_ty,1806 .ty = enum_obj.tag_ty,
1805 });1807 });
1806 }1808 }
...@@ -1820,7 +1822,7 @@ fn zirEnumDecl(...@@ -1820,7 +1822,7 @@ fn zirEnumDecl(
1820 extra_index += 1;1822 extra_index += 1;
18211823
1822 // This string needs to outlive the ZIR code.1824 // This string needs to outlive the ZIR code.
1823 const field_name = try new_decl_arena.allocator.dupe(u8, field_name_zir);1825 const field_name = try new_decl_arena_allocator.dupe(u8, field_name_zir);
18241826
1825 const gop = enum_obj.fields.getOrPutAssumeCapacity(field_name);1827 const gop = enum_obj.fields.getOrPutAssumeCapacity(field_name);
1826 if (gop.found_existing) {1828 if (gop.found_existing) {
...@@ -1843,12 +1845,12 @@ fn zirEnumDecl(...@@ -1843,12 +1845,12 @@ fn zirEnumDecl(
1843 // that points to this default value expression rather than the struct.1845 // that points to this default value expression rather than the struct.
1844 // But only resolve the source location if we need to emit a compile error.1846 // But only resolve the source location if we need to emit a compile error.
1845 const tag_val = (try sema.resolveInstConst(block, src, tag_val_ref)).val;1847 const tag_val = (try sema.resolveInstConst(block, src, tag_val_ref)).val;
1846 const copied_tag_val = try tag_val.copy(&new_decl_arena.allocator);1848 const copied_tag_val = try tag_val.copy(new_decl_arena_allocator);
1847 enum_obj.values.putAssumeCapacityNoClobberContext(copied_tag_val, {}, .{1849 enum_obj.values.putAssumeCapacityNoClobberContext(copied_tag_val, {}, .{
1848 .ty = enum_obj.tag_ty,1850 .ty = enum_obj.tag_ty,
1849 });1851 });
1850 } else if (any_values) {1852 } else if (any_values) {
1851 const tag_val = try Value.Tag.int_u64.create(&new_decl_arena.allocator, field_i);1853 const tag_val = try Value.Tag.int_u64.create(new_decl_arena_allocator, field_i);
1852 enum_obj.values.putAssumeCapacityNoClobberContext(tag_val, {}, .{ .ty = enum_obj.tag_ty });1854 enum_obj.values.putAssumeCapacityNoClobberContext(tag_val, {}, .{ .ty = enum_obj.tag_ty });
1853 }1855 }
1854 }1856 }
...@@ -1887,16 +1889,17 @@ fn zirUnionDecl(...@@ -1887,16 +1889,17 @@ fn zirUnionDecl(
18871889
1888 var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa);1890 var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa);
1889 errdefer new_decl_arena.deinit();1891 errdefer new_decl_arena.deinit();
1892 const new_decl_arena_allocator = new_decl_arena.allocator();
18901893
1891 const union_obj = try new_decl_arena.allocator.create(Module.Union);1894 const union_obj = try new_decl_arena_allocator.create(Module.Union);
1892 const type_tag: Type.Tag = if (small.has_tag_type or small.auto_enum_tag) .union_tagged else .@"union";1895 const type_tag: Type.Tag = if (small.has_tag_type or small.auto_enum_tag) .union_tagged else .@"union";
1893 const union_payload = try new_decl_arena.allocator.create(Type.Payload.Union);1896 const union_payload = try new_decl_arena_allocator.create(Type.Payload.Union);
1894 union_payload.* = .{1897 union_payload.* = .{
1895 .base = .{ .tag = type_tag },1898 .base = .{ .tag = type_tag },
1896 .data = union_obj,1899 .data = union_obj,
1897 };1900 };
1898 const union_ty = Type.initPayload(&union_payload.base);1901 const union_ty = Type.initPayload(&union_payload.base);
1899 const union_val = try Value.Tag.ty.create(&new_decl_arena.allocator, union_ty);1902 const union_val = try Value.Tag.ty.create(new_decl_arena_allocator, union_ty);
1900 const type_name = try sema.createTypeName(block, small.name_strategy);1903 const type_name = try sema.createTypeName(block, small.name_strategy);
1901 const new_decl = try sema.mod.createAnonymousDeclNamed(block, .{1904 const new_decl = try sema.mod.createAnonymousDeclNamed(block, .{
1902 .ty = Type.type,1905 .ty = Type.type,
...@@ -1955,15 +1958,16 @@ fn zirOpaqueDecl(...@@ -1955,15 +1958,16 @@ fn zirOpaqueDecl(
19551958
1956 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);1959 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);
1957 errdefer new_decl_arena.deinit();1960 errdefer new_decl_arena.deinit();
1961 const new_decl_arena_allocator = new_decl_arena.allocator();
19581962
1959 const opaque_obj = try new_decl_arena.allocator.create(Module.Opaque);1963 const opaque_obj = try new_decl_arena_allocator.create(Module.Opaque);
1960 const opaque_ty_payload = try new_decl_arena.allocator.create(Type.Payload.Opaque);1964 const opaque_ty_payload = try new_decl_arena_allocator.create(Type.Payload.Opaque);
1961 opaque_ty_payload.* = .{1965 opaque_ty_payload.* = .{
1962 .base = .{ .tag = .@"opaque" },1966 .base = .{ .tag = .@"opaque" },
1963 .data = opaque_obj,1967 .data = opaque_obj,
1964 };1968 };
1965 const opaque_ty = Type.initPayload(&opaque_ty_payload.base);1969 const opaque_ty = Type.initPayload(&opaque_ty_payload.base);
1966 const opaque_val = try Value.Tag.ty.create(&new_decl_arena.allocator, opaque_ty);1970 const opaque_val = try Value.Tag.ty.create(new_decl_arena_allocator, opaque_ty);
1967 const type_name = try sema.createTypeName(block, small.name_strategy);1971 const type_name = try sema.createTypeName(block, small.name_strategy);
1968 const new_decl = try mod.createAnonymousDeclNamed(block, .{1972 const new_decl = try mod.createAnonymousDeclNamed(block, .{
1969 .ty = Type.type,1973 .ty = Type.type,
...@@ -2008,10 +2012,11 @@ fn zirErrorSetDecl(...@@ -2008,10 +2012,11 @@ fn zirErrorSetDecl(
20082012
2009 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);2013 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);
2010 errdefer new_decl_arena.deinit();2014 errdefer new_decl_arena.deinit();
2015 const new_decl_arena_allocator = new_decl_arena.allocator();
20112016
2012 const error_set = try new_decl_arena.allocator.create(Module.ErrorSet);2017 const error_set = try new_decl_arena_allocator.create(Module.ErrorSet);
2013 const error_set_ty = try Type.Tag.error_set.create(&new_decl_arena.allocator, error_set);2018 const error_set_ty = try Type.Tag.error_set.create(new_decl_arena_allocator, error_set);
2014 const error_set_val = try Value.Tag.ty.create(&new_decl_arena.allocator, error_set_ty);2019 const error_set_val = try Value.Tag.ty.create(new_decl_arena_allocator, error_set_ty);
2015 const type_name = try sema.createTypeName(block, name_strategy);2020 const type_name = try sema.createTypeName(block, name_strategy);
2016 const new_decl = try sema.mod.createAnonymousDeclNamed(block, .{2021 const new_decl = try sema.mod.createAnonymousDeclNamed(block, .{
2017 .ty = Type.type,2022 .ty = Type.type,
...@@ -2019,9 +2024,9 @@ fn zirErrorSetDecl(...@@ -2019,9 +2024,9 @@ fn zirErrorSetDecl(
2019 }, type_name);2024 }, type_name);
2020 new_decl.owns_tv = true;2025 new_decl.owns_tv = true;
2021 errdefer sema.mod.abortAnonDecl(new_decl);2026 errdefer sema.mod.abortAnonDecl(new_decl);
2022 const names = try new_decl_arena.allocator.alloc([]const u8, fields.len);2027 const names = try new_decl_arena_allocator.alloc([]const u8, fields.len);
2023 for (fields) |str_index, i| {2028 for (fields) |str_index, i| {
2024 names[i] = try new_decl_arena.allocator.dupe(u8, sema.code.nullTerminatedString(str_index));2029 names[i] = try new_decl_arena_allocator.dupe(u8, sema.code.nullTerminatedString(str_index));
2025 }2030 }
2026 error_set.* = .{2031 error_set.* = .{
2027 .owner_decl = new_decl,2032 .owner_decl = new_decl,
...@@ -3935,7 +3940,7 @@ fn analyzeCall(...@@ -3935,7 +3940,7 @@ fn analyzeCall(
3935 {3940 {
3936 var arena_allocator = std.heap.ArenaAllocator.init(gpa);3941 var arena_allocator = std.heap.ArenaAllocator.init(gpa);
3937 errdefer arena_allocator.deinit();3942 errdefer arena_allocator.deinit();
3938 const arena = &arena_allocator.allocator;3943 const arena = arena_allocator.allocator();
39393944
3940 for (memoized_call_key.args) |*arg| {3945 for (memoized_call_key.args) |*arg| {
3941 arg.* = try arg.*.copy(arena);3946 arg.* = try arg.*.copy(arena);
...@@ -4069,6 +4074,7 @@ fn analyzeCall(...@@ -4069,6 +4074,7 @@ fn analyzeCall(
40694074
4070 var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa);4075 var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa);
4071 errdefer new_decl_arena.deinit();4076 errdefer new_decl_arena.deinit();
4077 const new_decl_arena_allocator = new_decl_arena.allocator();
40724078
4073 // Re-run the block that creates the function, with the comptime parameters4079 // Re-run the block that creates the function, with the comptime parameters
4074 // pre-populated inside `inst_map`. This causes `param_comptime` and4080 // pre-populated inside `inst_map`. This causes `param_comptime` and
...@@ -4078,13 +4084,13 @@ fn analyzeCall(...@@ -4078,13 +4084,13 @@ fn analyzeCall(
4078 .mod = mod,4084 .mod = mod,
4079 .gpa = gpa,4085 .gpa = gpa,
4080 .arena = sema.arena,4086 .arena = sema.arena,
4081 .perm_arena = &new_decl_arena.allocator,4087 .perm_arena = new_decl_arena_allocator,
4082 .code = fn_zir,4088 .code = fn_zir,
4083 .owner_decl = new_decl,4089 .owner_decl = new_decl,
4084 .func = null,4090 .func = null,
4085 .fn_ret_ty = Type.void,4091 .fn_ret_ty = Type.void,
4086 .owner_func = null,4092 .owner_func = null,
4087 .comptime_args = try new_decl_arena.allocator.alloc(TypedValue, uncasted_args.len),4093 .comptime_args = try new_decl_arena_allocator.alloc(TypedValue, uncasted_args.len),
4088 .comptime_args_fn_inst = module_fn.zir_body_inst,4094 .comptime_args_fn_inst = module_fn.zir_body_inst,
4089 .preallocated_new_func = new_module_func,4095 .preallocated_new_func = new_module_func,
4090 };4096 };
...@@ -4168,7 +4174,7 @@ fn analyzeCall(...@@ -4168,7 +4174,7 @@ fn analyzeCall(
4168 else => continue,4174 else => continue,
4169 }4175 }
4170 const arg = child_sema.inst_map.get(inst).?;4176 const arg = child_sema.inst_map.get(inst).?;
4171 const copied_arg_ty = try child_sema.typeOf(arg).copy(&new_decl_arena.allocator);4177 const copied_arg_ty = try child_sema.typeOf(arg).copy(new_decl_arena_allocator);
4172 if (child_sema.resolveMaybeUndefValAllowVariables(4178 if (child_sema.resolveMaybeUndefValAllowVariables(
4173 &child_block,4179 &child_block,
4174 .unneeded,4180 .unneeded,
...@@ -4176,7 +4182,7 @@ fn analyzeCall(...@@ -4176,7 +4182,7 @@ fn analyzeCall(
4176 ) catch unreachable) |arg_val| {4182 ) catch unreachable) |arg_val| {
4177 child_sema.comptime_args[arg_i] = .{4183 child_sema.comptime_args[arg_i] = .{
4178 .ty = copied_arg_ty,4184 .ty = copied_arg_ty,
4179 .val = try arg_val.copy(&new_decl_arena.allocator),4185 .val = try arg_val.copy(new_decl_arena_allocator),
4180 };4186 };
4181 } else {4187 } else {
4182 child_sema.comptime_args[arg_i] = .{4188 child_sema.comptime_args[arg_i] = .{
...@@ -4191,8 +4197,8 @@ fn analyzeCall(...@@ -4191,8 +4197,8 @@ fn analyzeCall(
4191 try wip_captures.finalize();4197 try wip_captures.finalize();
41924198
4193 // Populate the Decl ty/val with the function and its type.4199 // Populate the Decl ty/val with the function and its type.
4194 new_decl.ty = try child_sema.typeOf(new_func_inst).copy(&new_decl_arena.allocator);4200 new_decl.ty = try child_sema.typeOf(new_func_inst).copy(new_decl_arena_allocator);
4195 new_decl.val = try Value.Tag.function.create(&new_decl_arena.allocator, new_func);4201 new_decl.val = try Value.Tag.function.create(new_decl_arena_allocator, new_func);
4196 new_decl.analysis = .complete;4202 new_decl.analysis = .complete;
41974203
4198 log.debug("generic function '{s}' instantiated with type {}", .{4204 log.debug("generic function '{s}' instantiated with type {}", .{
...@@ -6047,8 +6053,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -6047,8 +6053,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
6047 defer arena.deinit();6053 defer arena.deinit();
60486054
6049 const target = sema.mod.getTarget();6055 const target = sema.mod.getTarget();
6050 const min_int = try operand_ty.minInt(&arena.allocator, target);6056 const min_int = try operand_ty.minInt(arena.allocator(), target);
6051 const max_int = try operand_ty.maxInt(&arena.allocator, target);6057 const max_int = try operand_ty.maxInt(arena.allocator(), target);
6052 if (try range_set.spans(min_int, max_int, operand_ty)) {6058 if (try range_set.spans(min_int, max_int, operand_ty)) {
6053 if (special_prong == .@"else") {6059 if (special_prong == .@"else") {
6054 return sema.fail(6060 return sema.fail(
...@@ -12793,9 +12799,9 @@ const ComptimePtrMutationKit = struct {...@@ -12793,9 +12799,9 @@ const ComptimePtrMutationKit = struct {
12793 ty: Type,12799 ty: Type,
12794 decl_arena: std.heap.ArenaAllocator = undefined,12800 decl_arena: std.heap.ArenaAllocator = undefined,
1279512801
12796 fn beginArena(self: *ComptimePtrMutationKit, gpa: *Allocator) *Allocator {12802 fn beginArena(self: *ComptimePtrMutationKit, gpa: Allocator) Allocator {
12797 self.decl_arena = self.decl_ref_mut.decl.value_arena.?.promote(gpa);12803 self.decl_arena = self.decl_ref_mut.decl.value_arena.?.promote(gpa);
12798 return &self.decl_arena.allocator;12804 return self.decl_arena.allocator();
12799 }12805 }
1280012806
12801 fn finishArena(self: *ComptimePtrMutationKit) void {12807 fn finishArena(self: *ComptimePtrMutationKit) void {
...@@ -14287,6 +14293,7 @@ fn semaStructFields(...@@ -14287,6 +14293,7 @@ fn semaStructFields(
1428714293
14288 var decl_arena = decl.value_arena.?.promote(gpa);14294 var decl_arena = decl.value_arena.?.promote(gpa);
14289 defer decl.value_arena.?.* = decl_arena.state;14295 defer decl.value_arena.?.* = decl_arena.state;
14296 const decl_arena_allocator = decl_arena.allocator();
1429014297
14291 var analysis_arena = std.heap.ArenaAllocator.init(gpa);14298 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
14292 defer analysis_arena.deinit();14299 defer analysis_arena.deinit();
...@@ -14294,8 +14301,8 @@ fn semaStructFields(...@@ -14294,8 +14301,8 @@ fn semaStructFields(
14294 var sema: Sema = .{14301 var sema: Sema = .{
14295 .mod = mod,14302 .mod = mod,
14296 .gpa = gpa,14303 .gpa = gpa,
14297 .arena = &analysis_arena.allocator,14304 .arena = analysis_arena.allocator(),
14298 .perm_arena = &decl_arena.allocator,14305 .perm_arena = decl_arena_allocator,
14299 .code = zir,14306 .code = zir,
14300 .owner_decl = decl,14307 .owner_decl = decl,
14301 .func = null,14308 .func = null,
...@@ -14304,7 +14311,7 @@ fn semaStructFields(...@@ -14304,7 +14311,7 @@ fn semaStructFields(
14304 };14311 };
14305 defer sema.deinit();14312 defer sema.deinit();
1430614313
14307 var wip_captures = try WipCaptureScope.init(gpa, &decl_arena.allocator, decl.src_scope);14314 var wip_captures = try WipCaptureScope.init(gpa, decl_arena_allocator, decl.src_scope);
14308 defer wip_captures.deinit();14315 defer wip_captures.deinit();
1430914316
14310 var block_scope: Block = .{14317 var block_scope: Block = .{
...@@ -14328,7 +14335,7 @@ fn semaStructFields(...@@ -14328,7 +14335,7 @@ fn semaStructFields(
1432814335
14329 try wip_captures.finalize();14336 try wip_captures.finalize();
1433014337
14331 try struct_obj.fields.ensureTotalCapacity(&decl_arena.allocator, fields_len);14338 try struct_obj.fields.ensureTotalCapacity(decl_arena_allocator, fields_len);
1433214339
14333 const bits_per_field = 4;14340 const bits_per_field = 4;
14334 const fields_per_u32 = 32 / bits_per_field;14341 const fields_per_u32 = 32 / bits_per_field;
...@@ -14359,7 +14366,7 @@ fn semaStructFields(...@@ -14359,7 +14366,7 @@ fn semaStructFields(
14359 extra_index += 1;14366 extra_index += 1;
1436014367
14361 // This string needs to outlive the ZIR code.14368 // This string needs to outlive the ZIR code.
14362 const field_name = try decl_arena.allocator.dupe(u8, field_name_zir);14369 const field_name = try decl_arena_allocator.dupe(u8, field_name_zir);
14363 const field_ty: Type = if (field_type_ref == .none)14370 const field_ty: Type = if (field_type_ref == .none)
14364 Type.initTag(.noreturn)14371 Type.initTag(.noreturn)
14365 else14372 else
...@@ -14371,7 +14378,7 @@ fn semaStructFields(...@@ -14371,7 +14378,7 @@ fn semaStructFields(
14371 const gop = struct_obj.fields.getOrPutAssumeCapacity(field_name);14378 const gop = struct_obj.fields.getOrPutAssumeCapacity(field_name);
14372 assert(!gop.found_existing);14379 assert(!gop.found_existing);
14373 gop.value_ptr.* = .{14380 gop.value_ptr.* = .{
14374 .ty = try field_ty.copy(&decl_arena.allocator),14381 .ty = try field_ty.copy(decl_arena_allocator),
14375 .abi_align = Value.initTag(.abi_align_default),14382 .abi_align = Value.initTag(.abi_align_default),
14376 .default_val = Value.initTag(.unreachable_value),14383 .default_val = Value.initTag(.unreachable_value),
14377 .is_comptime = is_comptime,14384 .is_comptime = is_comptime,
...@@ -14385,7 +14392,7 @@ fn semaStructFields(...@@ -14385,7 +14392,7 @@ fn semaStructFields(
14385 // that points to this alignment expression rather than the struct.14392 // that points to this alignment expression rather than the struct.
14386 // But only resolve the source location if we need to emit a compile error.14393 // But only resolve the source location if we need to emit a compile error.
14387 const abi_align_val = (try sema.resolveInstConst(&block_scope, src, align_ref)).val;14394 const abi_align_val = (try sema.resolveInstConst(&block_scope, src, align_ref)).val;
14388 gop.value_ptr.abi_align = try abi_align_val.copy(&decl_arena.allocator);14395 gop.value_ptr.abi_align = try abi_align_val.copy(decl_arena_allocator);
14389 }14396 }
14390 if (has_default) {14397 if (has_default) {
14391 const default_ref = @intToEnum(Zir.Inst.Ref, zir.extra[extra_index]);14398 const default_ref = @intToEnum(Zir.Inst.Ref, zir.extra[extra_index]);
...@@ -14396,7 +14403,7 @@ fn semaStructFields(...@@ -14396,7 +14403,7 @@ fn semaStructFields(
14396 // But only resolve the source location if we need to emit a compile error.14403 // But only resolve the source location if we need to emit a compile error.
14397 const default_val = (try sema.resolveMaybeUndefVal(&block_scope, src, default_inst)) orelse14404 const default_val = (try sema.resolveMaybeUndefVal(&block_scope, src, default_inst)) orelse
14398 return sema.failWithNeededComptime(&block_scope, src);14405 return sema.failWithNeededComptime(&block_scope, src);
14399 gop.value_ptr.default_val = try default_val.copy(&decl_arena.allocator);14406 gop.value_ptr.default_val = try default_val.copy(decl_arena_allocator);
14400 }14407 }
14401 }14408 }
14402}14409}
...@@ -14454,6 +14461,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -14454,6 +14461,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
1445414461
14455 var decl_arena = union_obj.owner_decl.value_arena.?.promote(gpa);14462 var decl_arena = union_obj.owner_decl.value_arena.?.promote(gpa);
14456 defer union_obj.owner_decl.value_arena.?.* = decl_arena.state;14463 defer union_obj.owner_decl.value_arena.?.* = decl_arena.state;
14464 const decl_arena_allocator = decl_arena.allocator();
1445714465
14458 var analysis_arena = std.heap.ArenaAllocator.init(gpa);14466 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
14459 defer analysis_arena.deinit();14467 defer analysis_arena.deinit();
...@@ -14461,8 +14469,8 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -14461,8 +14469,8 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
14461 var sema: Sema = .{14469 var sema: Sema = .{
14462 .mod = mod,14470 .mod = mod,
14463 .gpa = gpa,14471 .gpa = gpa,
14464 .arena = &analysis_arena.allocator,14472 .arena = analysis_arena.allocator(),
14465 .perm_arena = &decl_arena.allocator,14473 .perm_arena = decl_arena_allocator,
14466 .code = zir,14474 .code = zir,
14467 .owner_decl = decl,14475 .owner_decl = decl,
14468 .func = null,14476 .func = null,
...@@ -14471,7 +14479,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -14471,7 +14479,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
14471 };14479 };
14472 defer sema.deinit();14480 defer sema.deinit();
1447314481
14474 var wip_captures = try WipCaptureScope.init(gpa, &decl_arena.allocator, decl.src_scope);14482 var wip_captures = try WipCaptureScope.init(gpa, decl_arena_allocator, decl.src_scope);
14475 defer wip_captures.deinit();14483 defer wip_captures.deinit();
1447614484
14477 var block_scope: Block = .{14485 var block_scope: Block = .{
...@@ -14495,7 +14503,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -14495,7 +14503,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
1449514503
14496 try wip_captures.finalize();14504 try wip_captures.finalize();
1449714505
14498 try union_obj.fields.ensureTotalCapacity(&decl_arena.allocator, fields_len);14506 try union_obj.fields.ensureTotalCapacity(decl_arena_allocator, fields_len);
1449914507
14500 var int_tag_ty: Type = undefined;14508 var int_tag_ty: Type = undefined;
14501 var enum_field_names: ?*Module.EnumNumbered.NameMap = null;14509 var enum_field_names: ?*Module.EnumNumbered.NameMap = null;
...@@ -14571,7 +14579,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -14571,7 +14579,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
14571 }14579 }
1457214580
14573 // This string needs to outlive the ZIR code.14581 // This string needs to outlive the ZIR code.
14574 const field_name = try decl_arena.allocator.dupe(u8, field_name_zir);14582 const field_name = try decl_arena_allocator.dupe(u8, field_name_zir);
14575 if (enum_field_names) |set| {14583 if (enum_field_names) |set| {
14576 set.putAssumeCapacity(field_name, {});14584 set.putAssumeCapacity(field_name, {});
14577 }14585 }
...@@ -14589,7 +14597,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -14589,7 +14597,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
14589 const gop = union_obj.fields.getOrPutAssumeCapacity(field_name);14597 const gop = union_obj.fields.getOrPutAssumeCapacity(field_name);
14590 assert(!gop.found_existing);14598 assert(!gop.found_existing);
14591 gop.value_ptr.* = .{14599 gop.value_ptr.* = .{
14592 .ty = try field_ty.copy(&decl_arena.allocator),14600 .ty = try field_ty.copy(decl_arena_allocator),
14593 .abi_align = Value.initTag(.abi_align_default),14601 .abi_align = Value.initTag(.abi_align_default),
14594 };14602 };
1459514603
...@@ -14598,7 +14606,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -14598,7 +14606,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
14598 // that points to this alignment expression rather than the struct.14606 // that points to this alignment expression rather than the struct.
14599 // But only resolve the source location if we need to emit a compile error.14607 // But only resolve the source location if we need to emit a compile error.
14600 const abi_align_val = (try sema.resolveInstConst(&block_scope, src, align_ref)).val;14608 const abi_align_val = (try sema.resolveInstConst(&block_scope, src, align_ref)).val;
14601 gop.value_ptr.abi_align = try abi_align_val.copy(&decl_arena.allocator);14609 gop.value_ptr.abi_align = try abi_align_val.copy(decl_arena_allocator);
14602 } else {14610 } else {
14603 gop.value_ptr.abi_align = Value.initTag(.abi_align_default);14611 gop.value_ptr.abi_align = Value.initTag(.abi_align_default);
14604 }14612 }
...@@ -14615,15 +14623,16 @@ fn generateUnionTagTypeNumbered(...@@ -14615,15 +14623,16 @@ fn generateUnionTagTypeNumbered(
1461514623
14616 var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa);14624 var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa);
14617 errdefer new_decl_arena.deinit();14625 errdefer new_decl_arena.deinit();
14626 const new_decl_arena_allocator = new_decl_arena.allocator();
1461814627
14619 const enum_obj = try new_decl_arena.allocator.create(Module.EnumNumbered);14628 const enum_obj = try new_decl_arena_allocator.create(Module.EnumNumbered);
14620 const enum_ty_payload = try new_decl_arena.allocator.create(Type.Payload.EnumNumbered);14629 const enum_ty_payload = try new_decl_arena_allocator.create(Type.Payload.EnumNumbered);
14621 enum_ty_payload.* = .{14630 enum_ty_payload.* = .{
14622 .base = .{ .tag = .enum_numbered },14631 .base = .{ .tag = .enum_numbered },
14623 .data = enum_obj,14632 .data = enum_obj,
14624 };14633 };
14625 const enum_ty = Type.initPayload(&enum_ty_payload.base);14634 const enum_ty = Type.initPayload(&enum_ty_payload.base);
14626 const enum_val = try Value.Tag.ty.create(&new_decl_arena.allocator, enum_ty);14635 const enum_val = try Value.Tag.ty.create(new_decl_arena_allocator, enum_ty);
14627 // TODO better type name14636 // TODO better type name
14628 const new_decl = try mod.createAnonymousDecl(block, .{14637 const new_decl = try mod.createAnonymousDecl(block, .{
14629 .ty = Type.type,14638 .ty = Type.type,
...@@ -14640,8 +14649,8 @@ fn generateUnionTagTypeNumbered(...@@ -14640,8 +14649,8 @@ fn generateUnionTagTypeNumbered(
14640 .node_offset = 0,14649 .node_offset = 0,
14641 };14650 };
14642 // Here we pre-allocate the maps using the decl arena.14651 // Here we pre-allocate the maps using the decl arena.
14643 try enum_obj.fields.ensureTotalCapacity(&new_decl_arena.allocator, fields_len);14652 try enum_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);
14644 try enum_obj.values.ensureTotalCapacityContext(&new_decl_arena.allocator, fields_len, .{ .ty = int_ty });14653 try enum_obj.values.ensureTotalCapacityContext(new_decl_arena_allocator, fields_len, .{ .ty = int_ty });
14645 try new_decl.finalizeNewArena(&new_decl_arena);14654 try new_decl.finalizeNewArena(&new_decl_arena);
14646 return enum_ty;14655 return enum_ty;
14647}14656}
...@@ -14651,15 +14660,16 @@ fn generateUnionTagTypeSimple(sema: *Sema, block: *Block, fields_len: u32) !Type...@@ -14651,15 +14660,16 @@ fn generateUnionTagTypeSimple(sema: *Sema, block: *Block, fields_len: u32) !Type
1465114660
14652 var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa);14661 var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa);
14653 errdefer new_decl_arena.deinit();14662 errdefer new_decl_arena.deinit();
14663 const new_decl_arena_allocator = new_decl_arena.allocator();
1465414664
14655 const enum_obj = try new_decl_arena.allocator.create(Module.EnumSimple);14665 const enum_obj = try new_decl_arena_allocator.create(Module.EnumSimple);
14656 const enum_ty_payload = try new_decl_arena.allocator.create(Type.Payload.EnumSimple);14666 const enum_ty_payload = try new_decl_arena_allocator.create(Type.Payload.EnumSimple);
14657 enum_ty_payload.* = .{14667 enum_ty_payload.* = .{
14658 .base = .{ .tag = .enum_simple },14668 .base = .{ .tag = .enum_simple },
14659 .data = enum_obj,14669 .data = enum_obj,
14660 };14670 };
14661 const enum_ty = Type.initPayload(&enum_ty_payload.base);14671 const enum_ty = Type.initPayload(&enum_ty_payload.base);
14662 const enum_val = try Value.Tag.ty.create(&new_decl_arena.allocator, enum_ty);14672 const enum_val = try Value.Tag.ty.create(new_decl_arena_allocator, enum_ty);
14663 // TODO better type name14673 // TODO better type name
14664 const new_decl = try mod.createAnonymousDecl(block, .{14674 const new_decl = try mod.createAnonymousDecl(block, .{
14665 .ty = Type.type,14675 .ty = Type.type,
...@@ -14674,7 +14684,7 @@ fn generateUnionTagTypeSimple(sema: *Sema, block: *Block, fields_len: u32) !Type...@@ -14674,7 +14684,7 @@ fn generateUnionTagTypeSimple(sema: *Sema, block: *Block, fields_len: u32) !Type
14674 .node_offset = 0,14684 .node_offset = 0,
14675 };14685 };
14676 // Here we pre-allocate the maps using the decl arena.14686 // Here we pre-allocate the maps using the decl arena.
14677 try enum_obj.fields.ensureTotalCapacity(&new_decl_arena.allocator, fields_len);14687 try enum_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);
14678 try new_decl.finalizeNewArena(&new_decl_arena);14688 try new_decl.finalizeNewArena(&new_decl_arena);
14679 return enum_ty;14689 return enum_ty;
14680}14690}
src/ThreadPool.zig+2-2
...@@ -9,7 +9,7 @@ const ThreadPool = @This();...@@ -9,7 +9,7 @@ const ThreadPool = @This();
99
10mutex: std.Thread.Mutex = .{},10mutex: std.Thread.Mutex = .{},
11is_running: bool = true,11is_running: bool = true,
12allocator: *std.mem.Allocator,12allocator: std.mem.Allocator,
13workers: []Worker,13workers: []Worker,
14run_queue: RunQueue = .{},14run_queue: RunQueue = .{},
15idle_queue: IdleQueue = .{},15idle_queue: IdleQueue = .{},
...@@ -55,7 +55,7 @@ const Worker = struct {...@@ -55,7 +55,7 @@ const Worker = struct {
55 }55 }
56};56};
5757
58pub fn init(self: *ThreadPool, allocator: *std.mem.Allocator) !void {58pub fn init(self: *ThreadPool, allocator: std.mem.Allocator) !void {
59 self.* = .{59 self.* = .{
60 .allocator = allocator,60 .allocator = allocator,
61 .workers = &[_]Worker{},61 .workers = &[_]Worker{},
src/TypedValue.zig+2-2
...@@ -16,14 +16,14 @@ pub const Managed = struct {...@@ -16,14 +16,14 @@ pub const Managed = struct {
16 /// If this is `null` then there is no memory management needed.16 /// If this is `null` then there is no memory management needed.
17 arena: ?*std.heap.ArenaAllocator.State = null,17 arena: ?*std.heap.ArenaAllocator.State = null,
1818
19 pub fn deinit(self: *Managed, allocator: *Allocator) void {19 pub fn deinit(self: *Managed, allocator: Allocator) void {
20 if (self.arena) |a| a.promote(allocator).deinit();20 if (self.arena) |a| a.promote(allocator).deinit();
21 self.* = undefined;21 self.* = undefined;
22 }22 }
23};23};
2424
25/// Assumes arena allocation. Does a recursive copy.25/// Assumes arena allocation. Does a recursive copy.
26pub fn copy(self: TypedValue, arena: *Allocator) error{OutOfMemory}!TypedValue {26pub fn copy(self: TypedValue, arena: Allocator) error{OutOfMemory}!TypedValue {
27 return TypedValue{27 return TypedValue{
28 .ty = try self.ty.copy(arena),28 .ty = try self.ty.copy(arena),
29 .val = try self.val.copy(arena),29 .val = try self.val.copy(arena),
src/Zir.zig+1-1
...@@ -101,7 +101,7 @@ pub fn hasCompileErrors(code: Zir) bool {...@@ -101,7 +101,7 @@ pub fn hasCompileErrors(code: Zir) bool {
101 return code.extra[@enumToInt(ExtraIndex.compile_errors)] != 0;101 return code.extra[@enumToInt(ExtraIndex.compile_errors)] != 0;
102}102}
103103
104pub fn deinit(code: *Zir, gpa: *Allocator) void {104pub fn deinit(code: *Zir, gpa: Allocator) void {
105 code.instructions.deinit(gpa);105 code.instructions.deinit(gpa);
106 gpa.free(code.string_bytes);106 gpa.free(code.string_bytes);
107 gpa.free(code.extra);107 gpa.free(code.extra);
src/arch/aarch64/CodeGen.zig+2-2
...@@ -33,7 +33,7 @@ const InnerError = error{...@@ -33,7 +33,7 @@ const InnerError = error{
33 CodegenFail,33 CodegenFail,
34};34};
3535
36gpa: *Allocator,36gpa: Allocator,
37air: Air,37air: Air,
38liveness: Liveness,38liveness: Liveness,
39bin_file: *link.File,39bin_file: *link.File,
...@@ -164,7 +164,7 @@ const MCValue = union(enum) {...@@ -164,7 +164,7 @@ const MCValue = union(enum) {
164const Branch = struct {164const Branch = struct {
165 inst_table: std.AutoArrayHashMapUnmanaged(Air.Inst.Index, MCValue) = .{},165 inst_table: std.AutoArrayHashMapUnmanaged(Air.Inst.Index, MCValue) = .{},
166166
167 fn deinit(self: *Branch, gpa: *Allocator) void {167 fn deinit(self: *Branch, gpa: Allocator) void {
168 self.inst_table.deinit(gpa);168 self.inst_table.deinit(gpa);
169 self.* = undefined;169 self.* = undefined;
170 }170 }
src/arch/aarch64/Mir.zig+1-1
...@@ -229,7 +229,7 @@ pub const Inst = struct {...@@ -229,7 +229,7 @@ pub const Inst = struct {
229 // }229 // }
230};230};
231231
232pub fn deinit(mir: *Mir, gpa: *std.mem.Allocator) void {232pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void {
233 mir.instructions.deinit(gpa);233 mir.instructions.deinit(gpa);
234 gpa.free(mir.extra);234 gpa.free(mir.extra);
235 mir.* = undefined;235 mir.* = undefined;
src/arch/arm/CodeGen.zig+2-2
...@@ -33,7 +33,7 @@ const InnerError = error{...@@ -33,7 +33,7 @@ const InnerError = error{
33 CodegenFail,33 CodegenFail,
34};34};
3535
36gpa: *Allocator,36gpa: Allocator,
37air: Air,37air: Air,
38liveness: Liveness,38liveness: Liveness,
39bin_file: *link.File,39bin_file: *link.File,
...@@ -164,7 +164,7 @@ const MCValue = union(enum) {...@@ -164,7 +164,7 @@ const MCValue = union(enum) {
164const Branch = struct {164const Branch = struct {
165 inst_table: std.AutoArrayHashMapUnmanaged(Air.Inst.Index, MCValue) = .{},165 inst_table: std.AutoArrayHashMapUnmanaged(Air.Inst.Index, MCValue) = .{},
166166
167 fn deinit(self: *Branch, gpa: *Allocator) void {167 fn deinit(self: *Branch, gpa: Allocator) void {
168 self.inst_table.deinit(gpa);168 self.inst_table.deinit(gpa);
169 self.* = undefined;169 self.* = undefined;
170 }170 }
src/arch/arm/Mir.zig+1-1
...@@ -193,7 +193,7 @@ pub const Inst = struct {...@@ -193,7 +193,7 @@ pub const Inst = struct {
193 // }193 // }
194};194};
195195
196pub fn deinit(mir: *Mir, gpa: *std.mem.Allocator) void {196pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void {
197 mir.instructions.deinit(gpa);197 mir.instructions.deinit(gpa);
198 gpa.free(mir.extra);198 gpa.free(mir.extra);
199 mir.* = undefined;199 mir.* = undefined;
src/arch/riscv64/CodeGen.zig+2-2
...@@ -33,7 +33,7 @@ const InnerError = error{...@@ -33,7 +33,7 @@ const InnerError = error{
33 CodegenFail,33 CodegenFail,
34};34};
3535
36gpa: *Allocator,36gpa: Allocator,
37air: Air,37air: Air,
38liveness: Liveness,38liveness: Liveness,
39bin_file: *link.File,39bin_file: *link.File,
...@@ -158,7 +158,7 @@ const MCValue = union(enum) {...@@ -158,7 +158,7 @@ const MCValue = union(enum) {
158const Branch = struct {158const Branch = struct {
159 inst_table: std.AutoArrayHashMapUnmanaged(Air.Inst.Index, MCValue) = .{},159 inst_table: std.AutoArrayHashMapUnmanaged(Air.Inst.Index, MCValue) = .{},
160160
161 fn deinit(self: *Branch, gpa: *Allocator) void {161 fn deinit(self: *Branch, gpa: Allocator) void {
162 self.inst_table.deinit(gpa);162 self.inst_table.deinit(gpa);
163 self.* = undefined;163 self.* = undefined;
164 }164 }
src/arch/riscv64/Mir.zig+1-1
...@@ -101,7 +101,7 @@ pub const Inst = struct {...@@ -101,7 +101,7 @@ pub const Inst = struct {
101 // }101 // }
102};102};
103103
104pub fn deinit(mir: *Mir, gpa: *std.mem.Allocator) void {104pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void {
105 mir.instructions.deinit(gpa);105 mir.instructions.deinit(gpa);
106 gpa.free(mir.extra);106 gpa.free(mir.extra);
107 mir.* = undefined;107 mir.* = undefined;
src/arch/wasm/CodeGen.zig+2-2
...@@ -508,7 +508,7 @@ const Self = @This();...@@ -508,7 +508,7 @@ const Self = @This();
508decl: *Decl,508decl: *Decl,
509air: Air,509air: Air,
510liveness: Liveness,510liveness: Liveness,
511gpa: *mem.Allocator,511gpa: mem.Allocator,
512/// Table to save `WValue`'s generated by an `Air.Inst`512/// Table to save `WValue`'s generated by an `Air.Inst`
513values: ValueTable,513values: ValueTable,
514/// Mapping from Air.Inst.Index to block ids514/// Mapping from Air.Inst.Index to block ids
...@@ -983,7 +983,7 @@ const CallWValues = struct {...@@ -983,7 +983,7 @@ const CallWValues = struct {
983 args: []WValue,983 args: []WValue,
984 return_value: WValue,984 return_value: WValue,
985985
986 fn deinit(self: *CallWValues, gpa: *Allocator) void {986 fn deinit(self: *CallWValues, gpa: Allocator) void {
987 gpa.free(self.args);987 gpa.free(self.args);
988 self.* = undefined;988 self.* = undefined;
989 }989 }
src/arch/wasm/Mir.zig+1-1
...@@ -411,7 +411,7 @@ pub const Inst = struct {...@@ -411,7 +411,7 @@ pub const Inst = struct {
411 };411 };
412};412};
413413
414pub fn deinit(self: *Mir, gpa: *std.mem.Allocator) void {414pub fn deinit(self: *Mir, gpa: std.mem.Allocator) void {
415 self.instructions.deinit(gpa);415 self.instructions.deinit(gpa);
416 gpa.free(self.extra);416 gpa.free(self.extra);
417 self.* = undefined;417 self.* = undefined;
src/arch/x86_64/CodeGen.zig+2-2
...@@ -33,7 +33,7 @@ const InnerError = error{...@@ -33,7 +33,7 @@ const InnerError = error{
33 CodegenFail,33 CodegenFail,
34};34};
3535
36gpa: *Allocator,36gpa: Allocator,
37air: Air,37air: Air,
38liveness: Liveness,38liveness: Liveness,
39bin_file: *link.File,39bin_file: *link.File,
...@@ -174,7 +174,7 @@ pub const MCValue = union(enum) {...@@ -174,7 +174,7 @@ pub const MCValue = union(enum) {
174const Branch = struct {174const Branch = struct {
175 inst_table: std.AutoArrayHashMapUnmanaged(Air.Inst.Index, MCValue) = .{},175 inst_table: std.AutoArrayHashMapUnmanaged(Air.Inst.Index, MCValue) = .{},
176176
177 fn deinit(self: *Branch, gpa: *Allocator) void {177 fn deinit(self: *Branch, gpa: Allocator) void {
178 self.inst_table.deinit(gpa);178 self.inst_table.deinit(gpa);
179 self.* = undefined;179 self.* = undefined;
180 }180 }
src/arch/x86_64/Mir.zig+1-1
...@@ -347,7 +347,7 @@ pub const ArgDbgInfo = struct {...@@ -347,7 +347,7 @@ pub const ArgDbgInfo = struct {
347 arg_index: u32,347 arg_index: u32,
348};348};
349349
350pub fn deinit(mir: *Mir, gpa: *std.mem.Allocator) void {350pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void {
351 mir.instructions.deinit(gpa);351 mir.instructions.deinit(gpa);
352 gpa.free(mir.extra);352 gpa.free(mir.extra);
353 mir.* = undefined;353 mir.* = undefined;
src/codegen/c.zig+4-3
...@@ -163,14 +163,14 @@ pub const Object = struct {...@@ -163,14 +163,14 @@ pub const Object = struct {
163163
164/// This data is available both when outputting .c code and when outputting an .h file.164/// This data is available both when outputting .c code and when outputting an .h file.
165pub const DeclGen = struct {165pub const DeclGen = struct {
166 gpa: *std.mem.Allocator,166 gpa: std.mem.Allocator,
167 module: *Module,167 module: *Module,
168 decl: *Decl,168 decl: *Decl,
169 fwd_decl: std.ArrayList(u8),169 fwd_decl: std.ArrayList(u8),
170 error_msg: ?*Module.ErrorMsg,170 error_msg: ?*Module.ErrorMsg,
171 /// The key of this map is Type which has references to typedefs_arena.171 /// The key of this map is Type which has references to typedefs_arena.
172 typedefs: TypedefMap,172 typedefs: TypedefMap,
173 typedefs_arena: *std.mem.Allocator,173 typedefs_arena: std.mem.Allocator,
174174
175 fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } {175 fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } {
176 @setCold(true);176 @setCold(true);
...@@ -390,6 +390,7 @@ pub const DeclGen = struct {...@@ -390,6 +390,7 @@ pub const DeclGen = struct {
390 // Fall back to generic implementation.390 // Fall back to generic implementation.
391 var arena = std.heap.ArenaAllocator.init(dg.module.gpa);391 var arena = std.heap.ArenaAllocator.init(dg.module.gpa);
392 defer arena.deinit();392 defer arena.deinit();
393 const arena_allocator = arena.allocator();
393394
394 try writer.writeAll("{");395 try writer.writeAll("{");
395 var index: usize = 0;396 var index: usize = 0;
...@@ -397,7 +398,7 @@ pub const DeclGen = struct {...@@ -397,7 +398,7 @@ pub const DeclGen = struct {
397 const elem_ty = ty.elemType();398 const elem_ty = ty.elemType();
398 while (index < len) : (index += 1) {399 while (index < len) : (index += 1) {
399 if (index != 0) try writer.writeAll(",");400 if (index != 0) try writer.writeAll(",");
400 const elem_val = try val.elemValue(&arena.allocator, index);401 const elem_val = try val.elemValue(arena_allocator, index);
401 try dg.renderValue(writer, elem_ty, elem_val);402 try dg.renderValue(writer, elem_ty, elem_val);
402 }403 }
403 if (ty.sentinel()) |sentinel_val| {404 if (ty.sentinel()) |sentinel_val| {
src/codegen/llvm.zig+13-13
...@@ -23,7 +23,7 @@ const LazySrcLoc = Module.LazySrcLoc;...@@ -23,7 +23,7 @@ const LazySrcLoc = Module.LazySrcLoc;
2323
24const Error = error{ OutOfMemory, CodegenFail };24const Error = error{ OutOfMemory, CodegenFail };
2525
26pub fn targetTriple(allocator: *Allocator, target: std.Target) ![:0]u8 {26pub fn targetTriple(allocator: Allocator, target: std.Target) ![:0]u8 {
27 const llvm_arch = switch (target.cpu.arch) {27 const llvm_arch = switch (target.cpu.arch) {
28 .arm => "arm",28 .arm => "arm",
29 .armeb => "armeb",29 .armeb => "armeb",
...@@ -190,14 +190,14 @@ pub const Object = struct {...@@ -190,14 +190,14 @@ pub const Object = struct {
190 std.hash_map.default_max_load_percentage,190 std.hash_map.default_max_load_percentage,
191 );191 );
192192
193 pub fn create(gpa: *Allocator, sub_path: []const u8, options: link.Options) !*Object {193 pub fn create(gpa: Allocator, sub_path: []const u8, options: link.Options) !*Object {
194 const obj = try gpa.create(Object);194 const obj = try gpa.create(Object);
195 errdefer gpa.destroy(obj);195 errdefer gpa.destroy(obj);
196 obj.* = try Object.init(gpa, sub_path, options);196 obj.* = try Object.init(gpa, sub_path, options);
197 return obj;197 return obj;
198 }198 }
199199
200 pub fn init(gpa: *Allocator, sub_path: []const u8, options: link.Options) !Object {200 pub fn init(gpa: Allocator, sub_path: []const u8, options: link.Options) !Object {
201 const context = llvm.Context.create();201 const context = llvm.Context.create();
202 errdefer context.dispose();202 errdefer context.dispose();
203203
...@@ -287,7 +287,7 @@ pub const Object = struct {...@@ -287,7 +287,7 @@ pub const Object = struct {
287 };287 };
288 }288 }
289289
290 pub fn deinit(self: *Object, gpa: *Allocator) void {290 pub fn deinit(self: *Object, gpa: Allocator) void {
291 self.target_machine.dispose();291 self.target_machine.dispose();
292 self.llvm_module.dispose();292 self.llvm_module.dispose();
293 self.context.dispose();293 self.context.dispose();
...@@ -297,13 +297,13 @@ pub const Object = struct {...@@ -297,13 +297,13 @@ pub const Object = struct {
297 self.* = undefined;297 self.* = undefined;
298 }298 }
299299
300 pub fn destroy(self: *Object, gpa: *Allocator) void {300 pub fn destroy(self: *Object, gpa: Allocator) void {
301 self.deinit(gpa);301 self.deinit(gpa);
302 gpa.destroy(self);302 gpa.destroy(self);
303 }303 }
304304
305 fn locPath(305 fn locPath(
306 arena: *Allocator,306 arena: Allocator,
307 opt_loc: ?Compilation.EmitLoc,307 opt_loc: ?Compilation.EmitLoc,
308 cache_directory: Compilation.Directory,308 cache_directory: Compilation.Directory,
309 ) !?[*:0]u8 {309 ) !?[*:0]u8 {
...@@ -331,7 +331,7 @@ pub const Object = struct {...@@ -331,7 +331,7 @@ pub const Object = struct {
331331
332 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);332 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
333 defer arena_allocator.deinit();333 defer arena_allocator.deinit();
334 const arena = &arena_allocator.allocator;334 const arena = arena_allocator.allocator();
335335
336 const mod = comp.bin_file.options.module.?;336 const mod = comp.bin_file.options.module.?;
337 const cache_dir = mod.zig_cache_artifact_directory;337 const cache_dir = mod.zig_cache_artifact_directory;
...@@ -554,7 +554,7 @@ pub const DeclGen = struct {...@@ -554,7 +554,7 @@ pub const DeclGen = struct {
554 object: *Object,554 object: *Object,
555 module: *Module,555 module: *Module,
556 decl: *Module.Decl,556 decl: *Module.Decl,
557 gpa: *Allocator,557 gpa: Allocator,
558 err_msg: ?*Module.ErrorMsg,558 err_msg: ?*Module.ErrorMsg,
559559
560 fn todo(self: *DeclGen, comptime format: []const u8, args: anytype) Error {560 fn todo(self: *DeclGen, comptime format: []const u8, args: anytype) Error {
...@@ -779,7 +779,7 @@ pub const DeclGen = struct {...@@ -779,7 +779,7 @@ pub const DeclGen = struct {
779779
780 // The Type memory is ephemeral; since we want to store a longer-lived780 // The Type memory is ephemeral; since we want to store a longer-lived
781 // reference, we need to copy it here.781 // reference, we need to copy it here.
782 gop.key_ptr.* = try t.copy(&dg.object.type_map_arena.allocator);782 gop.key_ptr.* = try t.copy(dg.object.type_map_arena.allocator());
783783
784 const opaque_obj = t.castTag(.@"opaque").?.data;784 const opaque_obj = t.castTag(.@"opaque").?.data;
785 const name = try opaque_obj.getFullyQualifiedName(gpa);785 const name = try opaque_obj.getFullyQualifiedName(gpa);
...@@ -837,7 +837,7 @@ pub const DeclGen = struct {...@@ -837,7 +837,7 @@ pub const DeclGen = struct {
837837
838 // The Type memory is ephemeral; since we want to store a longer-lived838 // The Type memory is ephemeral; since we want to store a longer-lived
839 // reference, we need to copy it here.839 // reference, we need to copy it here.
840 gop.key_ptr.* = try t.copy(&dg.object.type_map_arena.allocator);840 gop.key_ptr.* = try t.copy(dg.object.type_map_arena.allocator());
841841
842 const struct_obj = t.castTag(.@"struct").?.data;842 const struct_obj = t.castTag(.@"struct").?.data;
843843
...@@ -871,7 +871,7 @@ pub const DeclGen = struct {...@@ -871,7 +871,7 @@ pub const DeclGen = struct {
871871
872 // The Type memory is ephemeral; since we want to store a longer-lived872 // The Type memory is ephemeral; since we want to store a longer-lived
873 // reference, we need to copy it here.873 // reference, we need to copy it here.
874 gop.key_ptr.* = try t.copy(&dg.object.type_map_arena.allocator);874 gop.key_ptr.* = try t.copy(dg.object.type_map_arena.allocator());
875875
876 const union_obj = t.cast(Type.Payload.Union).?.data;876 const union_obj = t.cast(Type.Payload.Union).?.data;
877 const target = dg.module.getTarget();877 const target = dg.module.getTarget();
...@@ -1621,7 +1621,7 @@ pub const DeclGen = struct {...@@ -1621,7 +1621,7 @@ pub const DeclGen = struct {
1621};1621};
16221622
1623pub const FuncGen = struct {1623pub const FuncGen = struct {
1624 gpa: *Allocator,1624 gpa: Allocator,
1625 dg: *DeclGen,1625 dg: *DeclGen,
1626 air: Air,1626 air: Air,
1627 liveness: Liveness,1627 liveness: Liveness,
...@@ -2485,7 +2485,7 @@ pub const FuncGen = struct {...@@ -2485,7 +2485,7 @@ pub const FuncGen = struct {
24852485
2486 var arena_allocator = std.heap.ArenaAllocator.init(self.gpa);2486 var arena_allocator = std.heap.ArenaAllocator.init(self.gpa);
2487 defer arena_allocator.deinit();2487 defer arena_allocator.deinit();
2488 const arena = &arena_allocator.allocator;2488 const arena = arena_allocator.allocator();
24892489
2490 const llvm_params_len = args.len;2490 const llvm_params_len = args.len;
2491 const llvm_param_types = try arena.alloc(*const llvm.Type, llvm_params_len);2491 const llvm_param_types = try arena.alloc(*const llvm.Type, llvm_params_len);
src/codegen/spirv.zig+2-2
...@@ -70,7 +70,7 @@ pub fn writeInstructionWithString(code: *std.ArrayList(Word), opcode: Opcode, ar...@@ -70,7 +70,7 @@ pub fn writeInstructionWithString(code: *std.ArrayList(Word), opcode: Opcode, ar
70/// of data which needs to be persistent over different calls to Decl code generation.70/// of data which needs to be persistent over different calls to Decl code generation.
71pub const SPIRVModule = struct {71pub const SPIRVModule = struct {
72 /// A general-purpose allocator which may be used to allocate temporary resources required for compilation.72 /// A general-purpose allocator which may be used to allocate temporary resources required for compilation.
73 gpa: *Allocator,73 gpa: Allocator,
7474
75 /// The parent module.75 /// The parent module.
76 module: *Module,76 module: *Module,
...@@ -103,7 +103,7 @@ pub const SPIRVModule = struct {...@@ -103,7 +103,7 @@ pub const SPIRVModule = struct {
103 /// just the ones for OpLine. Note that OpLine needs the result of OpString, and not that of OpSource.103 /// just the ones for OpLine. Note that OpLine needs the result of OpString, and not that of OpSource.
104 file_names: std.StringHashMap(ResultId),104 file_names: std.StringHashMap(ResultId),
105105
106 pub fn init(gpa: *Allocator, module: *Module) SPIRVModule {106 pub fn init(gpa: Allocator, module: *Module) SPIRVModule {
107 return .{107 return .{
108 .gpa = gpa,108 .gpa = gpa,
109 .module = module,109 .module = module,
src/crash_report.zig+1-1
...@@ -85,7 +85,7 @@ fn dumpStatusReport() !void {...@@ -85,7 +85,7 @@ fn dumpStatusReport() !void {
85 const anal = zir_state orelse return;85 const anal = zir_state orelse return;
86 // Note: We have the panic mutex here, so we can safely use the global crash heap.86 // Note: We have the panic mutex here, so we can safely use the global crash heap.
87 var fba = std.heap.FixedBufferAllocator.init(&crash_heap);87 var fba = std.heap.FixedBufferAllocator.init(&crash_heap);
88 const allocator = &fba.allocator;88 const allocator = fba.allocator();
8989
90 const stderr = io.getStdErr().writer();90 const stderr = io.getStdErr().writer();
91 const block: *Sema.Block = anal.block;91 const block: *Sema.Block = anal.block;
src/glibc.zig+12-12
...@@ -34,7 +34,7 @@ pub const ABI = struct {...@@ -34,7 +34,7 @@ pub const ABI = struct {
34 version_table: std.AutoHashMapUnmanaged(target_util.ArchOsAbi, [*]VerList),34 version_table: std.AutoHashMapUnmanaged(target_util.ArchOsAbi, [*]VerList),
35 arena_state: std.heap.ArenaAllocator.State,35 arena_state: std.heap.ArenaAllocator.State,
3636
37 pub fn destroy(abi: *ABI, gpa: *Allocator) void {37 pub fn destroy(abi: *ABI, gpa: Allocator) void {
38 abi.version_table.deinit(gpa);38 abi.version_table.deinit(gpa);
39 abi.arena_state.promote(gpa).deinit(); // Frees the ABI memory too.39 abi.arena_state.promote(gpa).deinit(); // Frees the ABI memory too.
40 }40 }
...@@ -59,13 +59,13 @@ pub const LoadMetaDataError = error{...@@ -59,13 +59,13 @@ pub const LoadMetaDataError = error{
5959
60/// This function will emit a log error when there is a problem with the zig installation and then return60/// This function will emit a log error when there is a problem with the zig installation and then return
61/// `error.ZigInstallationCorrupt`.61/// `error.ZigInstallationCorrupt`.
62pub fn loadMetaData(gpa: *Allocator, zig_lib_dir: std.fs.Dir) LoadMetaDataError!*ABI {62pub fn loadMetaData(gpa: Allocator, zig_lib_dir: std.fs.Dir) LoadMetaDataError!*ABI {
63 const tracy = trace(@src());63 const tracy = trace(@src());
64 defer tracy.end();64 defer tracy.end();
6565
66 var arena_allocator = std.heap.ArenaAllocator.init(gpa);66 var arena_allocator = std.heap.ArenaAllocator.init(gpa);
67 errdefer arena_allocator.deinit();67 errdefer arena_allocator.deinit();
68 const arena = &arena_allocator.allocator;68 const arena = arena_allocator.allocator();
6969
70 var all_versions = std.ArrayListUnmanaged(std.builtin.Version){};70 var all_versions = std.ArrayListUnmanaged(std.builtin.Version){};
71 var all_functions = std.ArrayListUnmanaged(Fn){};71 var all_functions = std.ArrayListUnmanaged(Fn){};
...@@ -256,7 +256,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {...@@ -256,7 +256,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
256 const gpa = comp.gpa;256 const gpa = comp.gpa;
257 var arena_allocator = std.heap.ArenaAllocator.init(gpa);257 var arena_allocator = std.heap.ArenaAllocator.init(gpa);
258 defer arena_allocator.deinit();258 defer arena_allocator.deinit();
259 const arena = &arena_allocator.allocator;259 const arena = arena_allocator.allocator();
260260
261 switch (crt_file) {261 switch (crt_file) {
262 .crti_o => {262 .crti_o => {
...@@ -433,7 +433,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {...@@ -433,7 +433,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
433 }433 }
434}434}
435435
436fn start_asm_path(comp: *Compilation, arena: *Allocator, basename: []const u8) ![]const u8 {436fn start_asm_path(comp: *Compilation, arena: Allocator, basename: []const u8) ![]const u8 {
437 const arch = comp.getTarget().cpu.arch;437 const arch = comp.getTarget().cpu.arch;
438 const is_ppc = arch == .powerpc or arch == .powerpc64 or arch == .powerpc64le;438 const is_ppc = arch == .powerpc or arch == .powerpc64 or arch == .powerpc64le;
439 const is_aarch64 = arch == .aarch64 or arch == .aarch64_be;439 const is_aarch64 = arch == .aarch64 or arch == .aarch64_be;
...@@ -493,7 +493,7 @@ fn start_asm_path(comp: *Compilation, arena: *Allocator, basename: []const u8) !...@@ -493,7 +493,7 @@ fn start_asm_path(comp: *Compilation, arena: *Allocator, basename: []const u8) !
493 return result.items;493 return result.items;
494}494}
495495
496fn add_include_dirs(comp: *Compilation, arena: *Allocator, args: *std.ArrayList([]const u8)) error{OutOfMemory}!void {496fn add_include_dirs(comp: *Compilation, arena: Allocator, args: *std.ArrayList([]const u8)) error{OutOfMemory}!void {
497 const target = comp.getTarget();497 const target = comp.getTarget();
498 const arch = target.cpu.arch;498 const arch = target.cpu.arch;
499 const opt_nptl: ?[]const u8 = if (target.os.tag == .linux) "nptl" else "htl";499 const opt_nptl: ?[]const u8 = if (target.os.tag == .linux) "nptl" else "htl";
...@@ -566,7 +566,7 @@ fn add_include_dirs(comp: *Compilation, arena: *Allocator, args: *std.ArrayList(...@@ -566,7 +566,7 @@ fn add_include_dirs(comp: *Compilation, arena: *Allocator, args: *std.ArrayList(
566}566}
567567
568fn add_include_dirs_arch(568fn add_include_dirs_arch(
569 arena: *Allocator,569 arena: Allocator,
570 args: *std.ArrayList([]const u8),570 args: *std.ArrayList([]const u8),
571 arch: std.Target.Cpu.Arch,571 arch: std.Target.Cpu.Arch,
572 opt_nptl: ?[]const u8,572 opt_nptl: ?[]const u8,
...@@ -677,14 +677,14 @@ fn add_include_dirs_arch(...@@ -677,14 +677,14 @@ fn add_include_dirs_arch(
677 }677 }
678}678}
679679
680fn path_from_lib(comp: *Compilation, arena: *Allocator, sub_path: []const u8) ![]const u8 {680fn path_from_lib(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const u8 {
681 return path.join(arena, &[_][]const u8{ comp.zig_lib_directory.path.?, sub_path });681 return path.join(arena, &[_][]const u8{ comp.zig_lib_directory.path.?, sub_path });
682}682}
683683
684const lib_libc = "libc" ++ path.sep_str;684const lib_libc = "libc" ++ path.sep_str;
685const lib_libc_glibc = lib_libc ++ "glibc" ++ path.sep_str;685const lib_libc_glibc = lib_libc ++ "glibc" ++ path.sep_str;
686686
687fn lib_path(comp: *Compilation, arena: *Allocator, sub_path: []const u8) ![]const u8 {687fn lib_path(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const u8 {
688 return path.join(arena, &[_][]const u8{ comp.zig_lib_directory.path.?, sub_path });688 return path.join(arena, &[_][]const u8{ comp.zig_lib_directory.path.?, sub_path });
689}689}
690690
...@@ -692,7 +692,7 @@ pub const BuiltSharedObjects = struct {...@@ -692,7 +692,7 @@ pub const BuiltSharedObjects = struct {
692 lock: Cache.Lock,692 lock: Cache.Lock,
693 dir_path: []u8,693 dir_path: []u8,
694694
695 pub fn deinit(self: *BuiltSharedObjects, gpa: *Allocator) void {695 pub fn deinit(self: *BuiltSharedObjects, gpa: Allocator) void {
696 self.lock.release();696 self.lock.release();
697 gpa.free(self.dir_path);697 gpa.free(self.dir_path);
698 self.* = undefined;698 self.* = undefined;
...@@ -711,7 +711,7 @@ pub fn buildSharedObjects(comp: *Compilation) !void {...@@ -711,7 +711,7 @@ pub fn buildSharedObjects(comp: *Compilation) !void {
711711
712 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);712 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
713 defer arena_allocator.deinit();713 defer arena_allocator.deinit();
714 const arena = &arena_allocator.allocator;714 const arena = arena_allocator.allocator();
715715
716 const target = comp.getTarget();716 const target = comp.getTarget();
717 const target_version = target.os.version_range.linux.glibc;717 const target_version = target.os.version_range.linux.glibc;
...@@ -915,7 +915,7 @@ pub fn buildSharedObjects(comp: *Compilation) !void {...@@ -915,7 +915,7 @@ pub fn buildSharedObjects(comp: *Compilation) !void {
915915
916fn buildSharedLib(916fn buildSharedLib(
917 comp: *Compilation,917 comp: *Compilation,
918 arena: *Allocator,918 arena: Allocator,
919 zig_cache_directory: Compilation.Directory,919 zig_cache_directory: Compilation.Directory,
920 bin_directory: Compilation.Directory,920 bin_directory: Compilation.Directory,
921 asm_file_basename: []const u8,921 asm_file_basename: []const u8,
src/introspect.zig+3-3
...@@ -33,7 +33,7 @@ fn testZigInstallPrefix(base_dir: fs.Dir) ?Compilation.Directory {...@@ -33,7 +33,7 @@ fn testZigInstallPrefix(base_dir: fs.Dir) ?Compilation.Directory {
33}33}
3434
35/// Both the directory handle and the path are newly allocated resources which the caller now owns.35/// Both the directory handle and the path are newly allocated resources which the caller now owns.
36pub fn findZigLibDir(gpa: *mem.Allocator) !Compilation.Directory {36pub fn findZigLibDir(gpa: mem.Allocator) !Compilation.Directory {
37 const self_exe_path = try fs.selfExePathAlloc(gpa);37 const self_exe_path = try fs.selfExePathAlloc(gpa);
38 defer gpa.free(self_exe_path);38 defer gpa.free(self_exe_path);
3939
...@@ -42,7 +42,7 @@ pub fn findZigLibDir(gpa: *mem.Allocator) !Compilation.Directory {...@@ -42,7 +42,7 @@ pub fn findZigLibDir(gpa: *mem.Allocator) !Compilation.Directory {
4242
43/// Both the directory handle and the path are newly allocated resources which the caller now owns.43/// Both the directory handle and the path are newly allocated resources which the caller now owns.
44pub fn findZigLibDirFromSelfExe(44pub fn findZigLibDirFromSelfExe(
45 allocator: *mem.Allocator,45 allocator: mem.Allocator,
46 self_exe_path: []const u8,46 self_exe_path: []const u8,
47) error{ OutOfMemory, FileNotFound }!Compilation.Directory {47) error{ OutOfMemory, FileNotFound }!Compilation.Directory {
48 const cwd = fs.cwd();48 const cwd = fs.cwd();
...@@ -61,7 +61,7 @@ pub fn findZigLibDirFromSelfExe(...@@ -61,7 +61,7 @@ pub fn findZigLibDirFromSelfExe(
61}61}
6262
63/// Caller owns returned memory.63/// Caller owns returned memory.
64pub fn resolveGlobalCacheDir(allocator: *mem.Allocator) ![]u8 {64pub fn resolveGlobalCacheDir(allocator: mem.Allocator) ![]u8 {
65 if (std.process.getEnvVarOwned(allocator, "ZIG_GLOBAL_CACHE_DIR")) |value| {65 if (std.process.getEnvVarOwned(allocator, "ZIG_GLOBAL_CACHE_DIR")) |value| {
66 if (value.len > 0) {66 if (value.len > 0) {
67 return value;67 return value;
src/libc_installation.zig+4-4
...@@ -39,7 +39,7 @@ pub const LibCInstallation = struct {...@@ -39,7 +39,7 @@ pub const LibCInstallation = struct {
39 };39 };
4040
41 pub fn parse(41 pub fn parse(
42 allocator: *Allocator,42 allocator: Allocator,
43 libc_file: []const u8,43 libc_file: []const u8,
44 target: std.zig.CrossTarget,44 target: std.zig.CrossTarget,
45 ) !LibCInstallation {45 ) !LibCInstallation {
...@@ -175,7 +175,7 @@ pub const LibCInstallation = struct {...@@ -175,7 +175,7 @@ pub const LibCInstallation = struct {
175 }175 }
176176
177 pub const FindNativeOptions = struct {177 pub const FindNativeOptions = struct {
178 allocator: *Allocator,178 allocator: Allocator,
179179
180 /// If enabled, will print human-friendly errors to stderr.180 /// If enabled, will print human-friendly errors to stderr.
181 verbose: bool = false,181 verbose: bool = false,
...@@ -234,7 +234,7 @@ pub const LibCInstallation = struct {...@@ -234,7 +234,7 @@ pub const LibCInstallation = struct {
234 }234 }
235235
236 /// Must be the same allocator passed to `parse` or `findNative`.236 /// Must be the same allocator passed to `parse` or `findNative`.
237 pub fn deinit(self: *LibCInstallation, allocator: *Allocator) void {237 pub fn deinit(self: *LibCInstallation, allocator: Allocator) void {
238 const fields = std.meta.fields(LibCInstallation);238 const fields = std.meta.fields(LibCInstallation);
239 inline for (fields) |field| {239 inline for (fields) |field| {
240 if (@field(self, field.name)) |payload| {240 if (@field(self, field.name)) |payload| {
...@@ -562,7 +562,7 @@ pub const LibCInstallation = struct {...@@ -562,7 +562,7 @@ pub const LibCInstallation = struct {
562};562};
563563
564pub const CCPrintFileNameOptions = struct {564pub const CCPrintFileNameOptions = struct {
565 allocator: *Allocator,565 allocator: Allocator,
566 search_basename: []const u8,566 search_basename: []const u8,
567 want_dirname: enum { full_path, only_dir },567 want_dirname: enum { full_path, only_dir },
568 verbose: bool = false,568 verbose: bool = false,
src/libcxx.zig+2-2
...@@ -89,7 +89,7 @@ pub fn buildLibCXX(comp: *Compilation) !void {...@@ -89,7 +89,7 @@ pub fn buildLibCXX(comp: *Compilation) !void {
8989
90 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);90 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
91 defer arena_allocator.deinit();91 defer arena_allocator.deinit();
92 const arena = &arena_allocator.allocator;92 const arena = arena_allocator.allocator();
9393
94 const root_name = "c++";94 const root_name = "c++";
95 const output_mode = .Lib;95 const output_mode = .Lib;
...@@ -236,7 +236,7 @@ pub fn buildLibCXXABI(comp: *Compilation) !void {...@@ -236,7 +236,7 @@ pub fn buildLibCXXABI(comp: *Compilation) !void {
236236
237 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);237 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
238 defer arena_allocator.deinit();238 defer arena_allocator.deinit();
239 const arena = &arena_allocator.allocator;239 const arena = arena_allocator.allocator();
240240
241 const root_name = "c++abi";241 const root_name = "c++abi";
242 const output_mode = .Lib;242 const output_mode = .Lib;
src/libtsan.zig+1-1
...@@ -15,7 +15,7 @@ pub fn buildTsan(comp: *Compilation) !void {...@@ -15,7 +15,7 @@ pub fn buildTsan(comp: *Compilation) !void {
1515
16 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);16 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
17 defer arena_allocator.deinit();17 defer arena_allocator.deinit();
18 const arena = &arena_allocator.allocator;18 const arena = arena_allocator.allocator();
1919
20 const root_name = "tsan";20 const root_name = "tsan";
21 const output_mode = .Lib;21 const output_mode = .Lib;
src/libunwind.zig+1-1
...@@ -17,7 +17,7 @@ pub fn buildStaticLib(comp: *Compilation) !void {...@@ -17,7 +17,7 @@ pub fn buildStaticLib(comp: *Compilation) !void {
1717
18 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);18 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
19 defer arena_allocator.deinit();19 defer arena_allocator.deinit();
20 const arena = &arena_allocator.allocator;20 const arena = arena_allocator.allocator();
2121
22 const root_name = "unwind";22 const root_name = "unwind";
23 const output_mode = .Lib;23 const output_mode = .Lib;
src/link.zig+3-3
...@@ -165,7 +165,7 @@ pub const File = struct {...@@ -165,7 +165,7 @@ pub const File = struct {
165 tag: Tag,165 tag: Tag,
166 options: Options,166 options: Options,
167 file: ?fs.File,167 file: ?fs.File,
168 allocator: *Allocator,168 allocator: Allocator,
169 /// When linking with LLD, this linker code will output an object file only at169 /// When linking with LLD, this linker code will output an object file only at
170 /// this location, and then this path can be placed on the LLD linker line.170 /// this location, and then this path can be placed on the LLD linker line.
171 intermediary_basename: ?[]const u8 = null,171 intermediary_basename: ?[]const u8 = null,
...@@ -221,7 +221,7 @@ pub const File = struct {...@@ -221,7 +221,7 @@ pub const File = struct {
221 /// incremental linking fails, falls back to truncating the file and221 /// incremental linking fails, falls back to truncating the file and
222 /// rewriting it. A malicious file is detected as incremental link failure222 /// rewriting it. A malicious file is detected as incremental link failure
223 /// and does not cause Illegal Behavior. This operation is not atomic.223 /// and does not cause Illegal Behavior. This operation is not atomic.
224 pub fn openPath(allocator: *Allocator, options: Options) !*File {224 pub fn openPath(allocator: Allocator, options: Options) !*File {
225 if (options.object_format == .macho) {225 if (options.object_format == .macho) {
226 return &(try MachO.openPath(allocator, options)).base;226 return &(try MachO.openPath(allocator, options)).base;
227 }227 }
...@@ -628,7 +628,7 @@ pub const File = struct {...@@ -628,7 +628,7 @@ pub const File = struct {
628628
629 var arena_allocator = std.heap.ArenaAllocator.init(base.allocator);629 var arena_allocator = std.heap.ArenaAllocator.init(base.allocator);
630 defer arena_allocator.deinit();630 defer arena_allocator.deinit();
631 const arena = &arena_allocator.allocator;631 const arena = arena_allocator.allocator();
632632
633 const directory = base.options.emit.?.directory; // Just an alias to make it shorter to type.633 const directory = base.options.emit.?.directory; // Just an alias to make it shorter to type.
634634
src/link/C.zig+5-5
...@@ -36,7 +36,7 @@ const DeclBlock = struct {...@@ -36,7 +36,7 @@ const DeclBlock = struct {
36 /// Any arena memory the Type points to lives in the `arena` field of `C`.36 /// Any arena memory the Type points to lives in the `arena` field of `C`.
37 typedefs: codegen.TypedefMap.Unmanaged = .{},37 typedefs: codegen.TypedefMap.Unmanaged = .{},
3838
39 fn deinit(db: *DeclBlock, gpa: *Allocator) void {39 fn deinit(db: *DeclBlock, gpa: Allocator) void {
40 db.code.deinit(gpa);40 db.code.deinit(gpa);
41 db.fwd_decl.deinit(gpa);41 db.fwd_decl.deinit(gpa);
42 for (db.typedefs.values()) |typedef| {42 for (db.typedefs.values()) |typedef| {
...@@ -47,7 +47,7 @@ const DeclBlock = struct {...@@ -47,7 +47,7 @@ const DeclBlock = struct {
47 }47 }
48};48};
4949
50pub fn openPath(gpa: *Allocator, sub_path: []const u8, options: link.Options) !*C {50pub fn openPath(gpa: Allocator, sub_path: []const u8, options: link.Options) !*C {
51 assert(options.object_format == .c);51 assert(options.object_format == .c);
5252
53 if (options.use_llvm) return error.LLVMHasNoCBackend;53 if (options.use_llvm) return error.LLVMHasNoCBackend;
...@@ -128,7 +128,7 @@ pub fn updateFunc(self: *C, module: *Module, func: *Module.Fn, air: Air, livenes...@@ -128,7 +128,7 @@ pub fn updateFunc(self: *C, module: *Module, func: *Module.Fn, air: Air, livenes
128 .decl = decl,128 .decl = decl,
129 .fwd_decl = fwd_decl.toManaged(module.gpa),129 .fwd_decl = fwd_decl.toManaged(module.gpa),
130 .typedefs = typedefs.promote(module.gpa),130 .typedefs = typedefs.promote(module.gpa),
131 .typedefs_arena = &self.arena.allocator,131 .typedefs_arena = self.arena.allocator(),
132 },132 },
133 .code = code.toManaged(module.gpa),133 .code = code.toManaged(module.gpa),
134 .indent_writer = undefined, // set later so we can get a pointer to object.code134 .indent_writer = undefined, // set later so we can get a pointer to object.code
...@@ -193,7 +193,7 @@ pub fn updateDecl(self: *C, module: *Module, decl: *Module.Decl) !void {...@@ -193,7 +193,7 @@ pub fn updateDecl(self: *C, module: *Module, decl: *Module.Decl) !void {
193 .decl = decl,193 .decl = decl,
194 .fwd_decl = fwd_decl.toManaged(module.gpa),194 .fwd_decl = fwd_decl.toManaged(module.gpa),
195 .typedefs = typedefs.promote(module.gpa),195 .typedefs = typedefs.promote(module.gpa),
196 .typedefs_arena = &self.arena.allocator,196 .typedefs_arena = self.arena.allocator(),
197 },197 },
198 .code = code.toManaged(module.gpa),198 .code = code.toManaged(module.gpa),
199 .indent_writer = undefined, // set later so we can get a pointer to object.code199 .indent_writer = undefined, // set later so we can get a pointer to object.code
...@@ -336,7 +336,7 @@ const Flush = struct {...@@ -336,7 +336,7 @@ const Flush = struct {
336 std.hash_map.default_max_load_percentage,336 std.hash_map.default_max_load_percentage,
337 );337 );
338338
339 fn deinit(f: *Flush, gpa: *Allocator) void {339 fn deinit(f: *Flush, gpa: Allocator) void {
340 f.all_buffers.deinit(gpa);340 f.all_buffers.deinit(gpa);
341 f.err_typedef_buf.deinit(gpa);341 f.err_typedef_buf.deinit(gpa);
342 f.typedefs.deinit(gpa);342 f.typedefs.deinit(gpa);
src/link/Coff.zig+4-4
...@@ -125,7 +125,7 @@ pub const TextBlock = struct {...@@ -125,7 +125,7 @@ pub const TextBlock = struct {
125125
126pub const SrcFn = void;126pub const SrcFn = void;
127127
128pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Options) !*Coff {128pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*Coff {
129 assert(options.object_format == .coff);129 assert(options.object_format == .coff);
130130
131 if (build_options.have_llvm and options.use_llvm) {131 if (build_options.have_llvm and options.use_llvm) {
...@@ -396,7 +396,7 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio...@@ -396,7 +396,7 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio
396 return self;396 return self;
397}397}
398398
399pub fn createEmpty(gpa: *Allocator, options: link.Options) !*Coff {399pub fn createEmpty(gpa: Allocator, options: link.Options) !*Coff {
400 const ptr_width: PtrWidth = switch (options.target.cpu.arch.ptrBitWidth()) {400 const ptr_width: PtrWidth = switch (options.target.cpu.arch.ptrBitWidth()) {
401 0...32 => .p32,401 0...32 => .p32,
402 33...64 => .p64,402 33...64 => .p64,
...@@ -877,7 +877,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {...@@ -877,7 +877,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {
877877
878 var arena_allocator = std.heap.ArenaAllocator.init(self.base.allocator);878 var arena_allocator = std.heap.ArenaAllocator.init(self.base.allocator);
879 defer arena_allocator.deinit();879 defer arena_allocator.deinit();
880 const arena = &arena_allocator.allocator;880 const arena = arena_allocator.allocator();
881881
882 const directory = self.base.options.emit.?.directory; // Just an alias to make it shorter to type.882 const directory = self.base.options.emit.?.directory; // Just an alias to make it shorter to type.
883883
...@@ -1394,7 +1394,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {...@@ -1394,7 +1394,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {
1394 }1394 }
1395}1395}
13961396
1397fn findLib(self: *Coff, arena: *Allocator, name: []const u8) !?[]const u8 {1397fn findLib(self: *Coff, arena: Allocator, name: []const u8) !?[]const u8 {
1398 for (self.base.options.lib_dirs) |lib_dir| {1398 for (self.base.options.lib_dirs) |lib_dir| {
1399 const full_path = try fs.path.join(arena, &.{ lib_dir, name });1399 const full_path = try fs.path.join(arena, &.{ lib_dir, name });
1400 fs.cwd().access(full_path, .{}) catch |err| switch (err) {1400 fs.cwd().access(full_path, .{}) catch |err| switch (err) {
src/link/Elf.zig+5-5
...@@ -228,7 +228,7 @@ pub const SrcFn = struct {...@@ -228,7 +228,7 @@ pub const SrcFn = struct {
228 };228 };
229};229};
230230
231pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Options) !*Elf {231pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*Elf {
232 assert(options.object_format == .elf);232 assert(options.object_format == .elf);
233233
234 if (build_options.have_llvm and options.use_llvm) {234 if (build_options.have_llvm and options.use_llvm) {
...@@ -281,7 +281,7 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio...@@ -281,7 +281,7 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio
281 return self;281 return self;
282}282}
283283
284pub fn createEmpty(gpa: *Allocator, options: link.Options) !*Elf {284pub fn createEmpty(gpa: Allocator, options: link.Options) !*Elf {
285 const ptr_width: PtrWidth = switch (options.target.cpu.arch.ptrBitWidth()) {285 const ptr_width: PtrWidth = switch (options.target.cpu.arch.ptrBitWidth()) {
286 0...32 => .p32,286 0...32 => .p32,
287 33...64 => .p64,287 33...64 => .p64,
...@@ -1243,7 +1243,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {...@@ -1243,7 +1243,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
12431243
1244 var arena_allocator = std.heap.ArenaAllocator.init(self.base.allocator);1244 var arena_allocator = std.heap.ArenaAllocator.init(self.base.allocator);
1245 defer arena_allocator.deinit();1245 defer arena_allocator.deinit();
1246 const arena = &arena_allocator.allocator;1246 const arena = arena_allocator.allocator();
12471247
1248 const directory = self.base.options.emit.?.directory; // Just an alias to make it shorter to type.1248 const directory = self.base.options.emit.?.directory; // Just an alias to make it shorter to type.
12491249
...@@ -2205,7 +2205,7 @@ pub fn freeDecl(self: *Elf, decl: *Module.Decl) void {...@@ -2205,7 +2205,7 @@ pub fn freeDecl(self: *Elf, decl: *Module.Decl) void {
2205 }2205 }
2206}2206}
22072207
2208fn deinitRelocs(gpa: *Allocator, table: *File.DbgInfoTypeRelocsTable) void {2208fn deinitRelocs(gpa: Allocator, table: *File.DbgInfoTypeRelocsTable) void {
2209 var it = table.valueIterator();2209 var it = table.valueIterator();
2210 while (it.next()) |value| {2210 while (it.next()) |value| {
2211 value.relocs.deinit(gpa);2211 value.relocs.deinit(gpa);
...@@ -3360,7 +3360,7 @@ const CsuObjects = struct {...@@ -3360,7 +3360,7 @@ const CsuObjects = struct {
3360 crtend: ?[]const u8 = null,3360 crtend: ?[]const u8 = null,
3361 crtn: ?[]const u8 = null,3361 crtn: ?[]const u8 = null,
33623362
3363 fn init(arena: *mem.Allocator, link_options: link.Options, comp: *const Compilation) !CsuObjects {3363 fn init(arena: mem.Allocator, link_options: link.Options, comp: *const Compilation) !CsuObjects {
3364 // crt objects are only required for libc.3364 // crt objects are only required for libc.
3365 if (!link_options.link_libc) return CsuObjects{};3365 if (!link_options.link_libc) return CsuObjects{};
33663366
src/link/MachO.zig+8-8
...@@ -280,7 +280,7 @@ pub const SrcFn = struct {...@@ -280,7 +280,7 @@ pub const SrcFn = struct {
280 };280 };
281};281};
282282
283pub fn openPath(allocator: *Allocator, options: link.Options) !*MachO {283pub fn openPath(allocator: Allocator, options: link.Options) !*MachO {
284 assert(options.object_format == .macho);284 assert(options.object_format == .macho);
285285
286 const use_stage1 = build_options.is_stage1 and options.use_stage1;286 const use_stage1 = build_options.is_stage1 and options.use_stage1;
...@@ -366,7 +366,7 @@ pub fn openPath(allocator: *Allocator, options: link.Options) !*MachO {...@@ -366,7 +366,7 @@ pub fn openPath(allocator: *Allocator, options: link.Options) !*MachO {
366 return self;366 return self;
367}367}
368368
369pub fn createEmpty(gpa: *Allocator, options: link.Options) !*MachO {369pub fn createEmpty(gpa: Allocator, options: link.Options) !*MachO {
370 const self = try gpa.create(MachO);370 const self = try gpa.create(MachO);
371 const cpu_arch = options.target.cpu.arch;371 const cpu_arch = options.target.cpu.arch;
372 const os_tag = options.target.os.tag;372 const os_tag = options.target.os.tag;
...@@ -412,7 +412,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {...@@ -412,7 +412,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {
412412
413 var arena_allocator = std.heap.ArenaAllocator.init(self.base.allocator);413 var arena_allocator = std.heap.ArenaAllocator.init(self.base.allocator);
414 defer arena_allocator.deinit();414 defer arena_allocator.deinit();
415 const arena = &arena_allocator.allocator;415 const arena = arena_allocator.allocator();
416416
417 const directory = self.base.options.emit.?.directory; // Just an alias to make it shorter to type.417 const directory = self.base.options.emit.?.directory; // Just an alias to make it shorter to type.
418418
...@@ -1032,7 +1032,7 @@ pub fn flushObject(self: *MachO, comp: *Compilation) !void {...@@ -1032,7 +1032,7 @@ pub fn flushObject(self: *MachO, comp: *Compilation) !void {
1032}1032}
10331033
1034fn resolveSearchDir(1034fn resolveSearchDir(
1035 arena: *Allocator,1035 arena: Allocator,
1036 dir: []const u8,1036 dir: []const u8,
1037 syslibroot: ?[]const u8,1037 syslibroot: ?[]const u8,
1038) !?[]const u8 {1038) !?[]const u8 {
...@@ -1074,7 +1074,7 @@ fn resolveSearchDir(...@@ -1074,7 +1074,7 @@ fn resolveSearchDir(
1074}1074}
10751075
1076fn resolveLib(1076fn resolveLib(
1077 arena: *Allocator,1077 arena: Allocator,
1078 search_dirs: []const []const u8,1078 search_dirs: []const []const u8,
1079 name: []const u8,1079 name: []const u8,
1080 ext: []const u8,1080 ext: []const u8,
...@@ -1098,7 +1098,7 @@ fn resolveLib(...@@ -1098,7 +1098,7 @@ fn resolveLib(
1098}1098}
10991099
1100fn resolveFramework(1100fn resolveFramework(
1101 arena: *Allocator,1101 arena: Allocator,
1102 search_dirs: []const []const u8,1102 search_dirs: []const []const u8,
1103 name: []const u8,1103 name: []const u8,
1104 ext: []const u8,1104 ext: []const u8,
...@@ -1288,7 +1288,7 @@ fn parseDependentLibs(self: *MachO, syslibroot: ?[]const u8, dependent_libs: any...@@ -1288,7 +1288,7 @@ fn parseDependentLibs(self: *MachO, syslibroot: ?[]const u8, dependent_libs: any
1288 // TODO this should not be performed if the user specifies `-flat_namespace` flag.1288 // TODO this should not be performed if the user specifies `-flat_namespace` flag.
1289 // See ld64 manpages.1289 // See ld64 manpages.
1290 var arena_alloc = std.heap.ArenaAllocator.init(self.base.allocator);1290 var arena_alloc = std.heap.ArenaAllocator.init(self.base.allocator);
1291 const arena = &arena_alloc.allocator;1291 const arena = arena_alloc.allocator();
1292 defer arena_alloc.deinit();1292 defer arena_alloc.deinit();
12931293
1294 while (dependent_libs.readItem()) |*id| {1294 while (dependent_libs.readItem()) |*id| {
...@@ -5379,7 +5379,7 @@ fn snapshotState(self: *MachO) !void {...@@ -5379,7 +5379,7 @@ fn snapshotState(self: *MachO) !void {
53795379
5380 var arena_allocator = std.heap.ArenaAllocator.init(self.base.allocator);5380 var arena_allocator = std.heap.ArenaAllocator.init(self.base.allocator);
5381 defer arena_allocator.deinit();5381 defer arena_allocator.deinit();
5382 const arena = &arena_allocator.allocator;5382 const arena = arena_allocator.allocator();
53835383
5384 const out_file = try emit.directory.handle.createFile("snapshots.json", .{5384 const out_file = try emit.directory.handle.createFile("snapshots.json", .{
5385 .truncate = self.cold_start,5385 .truncate = self.cold_start,
src/link/MachO/Archive.zig+5-5
...@@ -92,7 +92,7 @@ const ar_hdr = extern struct {...@@ -92,7 +92,7 @@ const ar_hdr = extern struct {
92 }92 }
93};93};
9494
95pub fn deinit(self: *Archive, allocator: *Allocator) void {95pub fn deinit(self: *Archive, allocator: Allocator) void {
96 for (self.toc.keys()) |*key| {96 for (self.toc.keys()) |*key| {
97 allocator.free(key.*);97 allocator.free(key.*);
98 }98 }
...@@ -103,7 +103,7 @@ pub fn deinit(self: *Archive, allocator: *Allocator) void {...@@ -103,7 +103,7 @@ pub fn deinit(self: *Archive, allocator: *Allocator) void {
103 allocator.free(self.name);103 allocator.free(self.name);
104}104}
105105
106pub fn parse(self: *Archive, allocator: *Allocator, target: std.Target) !void {106pub fn parse(self: *Archive, allocator: Allocator, target: std.Target) !void {
107 const reader = self.file.reader();107 const reader = self.file.reader();
108 self.library_offset = try fat.getLibraryOffset(reader, target);108 self.library_offset = try fat.getLibraryOffset(reader, target);
109 try self.file.seekTo(self.library_offset);109 try self.file.seekTo(self.library_offset);
...@@ -128,7 +128,7 @@ pub fn parse(self: *Archive, allocator: *Allocator, target: std.Target) !void {...@@ -128,7 +128,7 @@ pub fn parse(self: *Archive, allocator: *Allocator, target: std.Target) !void {
128 try reader.context.seekTo(0);128 try reader.context.seekTo(0);
129}129}
130130
131fn parseName(allocator: *Allocator, header: ar_hdr, reader: anytype) ![]u8 {131fn parseName(allocator: Allocator, header: ar_hdr, reader: anytype) ![]u8 {
132 const name_or_length = try header.nameOrLength();132 const name_or_length = try header.nameOrLength();
133 var name: []u8 = undefined;133 var name: []u8 = undefined;
134 switch (name_or_length) {134 switch (name_or_length) {
...@@ -146,7 +146,7 @@ fn parseName(allocator: *Allocator, header: ar_hdr, reader: anytype) ![]u8 {...@@ -146,7 +146,7 @@ fn parseName(allocator: *Allocator, header: ar_hdr, reader: anytype) ![]u8 {
146 return name;146 return name;
147}147}
148148
149fn parseTableOfContents(self: *Archive, allocator: *Allocator, reader: anytype) !void {149fn parseTableOfContents(self: *Archive, allocator: Allocator, reader: anytype) !void {
150 const symtab_size = try reader.readIntLittle(u32);150 const symtab_size = try reader.readIntLittle(u32);
151 var symtab = try allocator.alloc(u8, symtab_size);151 var symtab = try allocator.alloc(u8, symtab_size);
152 defer allocator.free(symtab);152 defer allocator.free(symtab);
...@@ -188,7 +188,7 @@ fn parseTableOfContents(self: *Archive, allocator: *Allocator, reader: anytype)...@@ -188,7 +188,7 @@ fn parseTableOfContents(self: *Archive, allocator: *Allocator, reader: anytype)
188 }188 }
189}189}
190190
191pub fn parseObject(self: Archive, allocator: *Allocator, target: std.Target, offset: u32) !Object {191pub fn parseObject(self: Archive, allocator: Allocator, target: std.Target, offset: u32) !Object {
192 const reader = self.file.reader();192 const reader = self.file.reader();
193 try reader.context.seekTo(offset + self.library_offset);193 try reader.context.seekTo(offset + self.library_offset);
194194
src/link/MachO/Atom.zig+2-2
...@@ -195,7 +195,7 @@ pub const empty = Atom{...@@ -195,7 +195,7 @@ pub const empty = Atom{
195 .dbg_info_len = undefined,195 .dbg_info_len = undefined,
196};196};
197197
198pub fn deinit(self: *Atom, allocator: *Allocator) void {198pub fn deinit(self: *Atom, allocator: Allocator) void {
199 self.dices.deinit(allocator);199 self.dices.deinit(allocator);
200 self.lazy_bindings.deinit(allocator);200 self.lazy_bindings.deinit(allocator);
201 self.bindings.deinit(allocator);201 self.bindings.deinit(allocator);
...@@ -246,7 +246,7 @@ pub fn freeListEligible(self: Atom, macho_file: MachO) bool {...@@ -246,7 +246,7 @@ pub fn freeListEligible(self: Atom, macho_file: MachO) bool {
246246
247const RelocContext = struct {247const RelocContext = struct {
248 base_addr: u64 = 0,248 base_addr: u64 = 0,
249 allocator: *Allocator,249 allocator: Allocator,
250 object: *Object,250 object: *Object,
251 macho_file: *MachO,251 macho_file: *MachO,
252};252};
src/link/MachO/CodeSignature.zig+2-2
...@@ -58,7 +58,7 @@ cdir: ?CodeDirectory = null,...@@ -58,7 +58,7 @@ cdir: ?CodeDirectory = null,
5858
59pub fn calcAdhocSignature(59pub fn calcAdhocSignature(
60 self: *CodeSignature,60 self: *CodeSignature,
61 allocator: *Allocator,61 allocator: Allocator,
62 file: fs.File,62 file: fs.File,
63 id: []const u8,63 id: []const u8,
64 text_segment: macho.segment_command_64,64 text_segment: macho.segment_command_64,
...@@ -145,7 +145,7 @@ pub fn write(self: CodeSignature, writer: anytype) !void {...@@ -145,7 +145,7 @@ pub fn write(self: CodeSignature, writer: anytype) !void {
145 try self.cdir.?.write(writer);145 try self.cdir.?.write(writer);
146}146}
147147
148pub fn deinit(self: *CodeSignature, allocator: *Allocator) void {148pub fn deinit(self: *CodeSignature, allocator: Allocator) void {
149 if (self.cdir) |*cdir| {149 if (self.cdir) |*cdir| {
150 cdir.data.deinit(allocator);150 cdir.data.deinit(allocator);
151 }151 }
src/link/MachO/DebugSymbols.zig+9-9
...@@ -104,7 +104,7 @@ const min_nop_size = 2;...@@ -104,7 +104,7 @@ const min_nop_size = 2;
104104
105/// You must call this function *after* `MachO.populateMissingMetadata()`105/// You must call this function *after* `MachO.populateMissingMetadata()`
106/// has been called to get a viable debug symbols output.106/// has been called to get a viable debug symbols output.
107pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void {107pub fn populateMissingMetadata(self: *DebugSymbols, allocator: Allocator) !void {
108 if (self.uuid_cmd_index == null) {108 if (self.uuid_cmd_index == null) {
109 const base_cmd = self.base.load_commands.items[self.base.uuid_cmd_index.?];109 const base_cmd = self.base.load_commands.items[self.base.uuid_cmd_index.?];
110 self.uuid_cmd_index = @intCast(u16, self.load_commands.items.len);110 self.uuid_cmd_index = @intCast(u16, self.load_commands.items.len);
...@@ -268,7 +268,7 @@ fn allocateSection(self: *DebugSymbols, sectname: []const u8, size: u64, alignme...@@ -268,7 +268,7 @@ fn allocateSection(self: *DebugSymbols, sectname: []const u8, size: u64, alignme
268 return index;268 return index;
269}269}
270270
271pub fn flushModule(self: *DebugSymbols, allocator: *Allocator, options: link.Options) !void {271pub fn flushModule(self: *DebugSymbols, allocator: Allocator, options: link.Options) !void {
272 // TODO This linker code currently assumes there is only 1 compilation unit and it corresponds to the272 // TODO This linker code currently assumes there is only 1 compilation unit and it corresponds to the
273 // Zig source code.273 // Zig source code.
274 const module = options.module orelse return error.LinkingWithoutZigSourceUnimplemented;274 const module = options.module orelse return error.LinkingWithoutZigSourceUnimplemented;
...@@ -577,7 +577,7 @@ pub fn flushModule(self: *DebugSymbols, allocator: *Allocator, options: link.Opt...@@ -577,7 +577,7 @@ pub fn flushModule(self: *DebugSymbols, allocator: *Allocator, options: link.Opt
577 assert(!self.debug_string_table_dirty);577 assert(!self.debug_string_table_dirty);
578}578}
579579
580pub fn deinit(self: *DebugSymbols, allocator: *Allocator) void {580pub fn deinit(self: *DebugSymbols, allocator: Allocator) void {
581 self.dbg_info_decl_free_list.deinit(allocator);581 self.dbg_info_decl_free_list.deinit(allocator);
582 self.dbg_line_fn_free_list.deinit(allocator);582 self.dbg_line_fn_free_list.deinit(allocator);
583 self.debug_string_table.deinit(allocator);583 self.debug_string_table.deinit(allocator);
...@@ -588,7 +588,7 @@ pub fn deinit(self: *DebugSymbols, allocator: *Allocator) void {...@@ -588,7 +588,7 @@ pub fn deinit(self: *DebugSymbols, allocator: *Allocator) void {
588 self.file.close();588 self.file.close();
589}589}
590590
591fn copySegmentCommand(self: *DebugSymbols, allocator: *Allocator, base_cmd: SegmentCommand) !SegmentCommand {591fn copySegmentCommand(self: *DebugSymbols, allocator: Allocator, base_cmd: SegmentCommand) !SegmentCommand {
592 var cmd = SegmentCommand{592 var cmd = SegmentCommand{
593 .inner = .{593 .inner = .{
594 .segname = undefined,594 .segname = undefined,
...@@ -648,7 +648,7 @@ fn updateDwarfSegment(self: *DebugSymbols) void {...@@ -648,7 +648,7 @@ fn updateDwarfSegment(self: *DebugSymbols) void {
648}648}
649649
650/// Writes all load commands and section headers.650/// Writes all load commands and section headers.
651fn writeLoadCommands(self: *DebugSymbols, allocator: *Allocator) !void {651fn writeLoadCommands(self: *DebugSymbols, allocator: Allocator) !void {
652 if (!self.load_commands_dirty) return;652 if (!self.load_commands_dirty) return;
653653
654 var sizeofcmds: u32 = 0;654 var sizeofcmds: u32 = 0;
...@@ -834,7 +834,7 @@ pub const DeclDebugBuffers = struct {...@@ -834,7 +834,7 @@ pub const DeclDebugBuffers = struct {
834/// Caller owns the returned memory.834/// Caller owns the returned memory.
835pub fn initDeclDebugBuffers(835pub fn initDeclDebugBuffers(
836 self: *DebugSymbols,836 self: *DebugSymbols,
837 allocator: *Allocator,837 allocator: Allocator,
838 module: *Module,838 module: *Module,
839 decl: *Module.Decl,839 decl: *Module.Decl,
840) !DeclDebugBuffers {840) !DeclDebugBuffers {
...@@ -930,7 +930,7 @@ pub fn initDeclDebugBuffers(...@@ -930,7 +930,7 @@ pub fn initDeclDebugBuffers(
930930
931pub fn commitDeclDebugInfo(931pub fn commitDeclDebugInfo(
932 self: *DebugSymbols,932 self: *DebugSymbols,
933 allocator: *Allocator,933 allocator: Allocator,
934 module: *Module,934 module: *Module,
935 decl: *Module.Decl,935 decl: *Module.Decl,
936 debug_buffers: *DeclDebugBuffers,936 debug_buffers: *DeclDebugBuffers,
...@@ -1141,7 +1141,7 @@ fn addDbgInfoType(...@@ -1141,7 +1141,7 @@ fn addDbgInfoType(
11411141
1142fn updateDeclDebugInfoAllocation(1142fn updateDeclDebugInfoAllocation(
1143 self: *DebugSymbols,1143 self: *DebugSymbols,
1144 allocator: *Allocator,1144 allocator: Allocator,
1145 text_block: *TextBlock,1145 text_block: *TextBlock,
1146 len: u32,1146 len: u32,
1147) !void {1147) !void {
...@@ -1256,7 +1256,7 @@ fn getDebugLineProgramEnd(self: DebugSymbols) u32 {...@@ -1256,7 +1256,7 @@ fn getDebugLineProgramEnd(self: DebugSymbols) u32 {
1256}1256}
12571257
1258/// TODO Improve this to use a table.1258/// TODO Improve this to use a table.
1259fn makeDebugString(self: *DebugSymbols, allocator: *Allocator, bytes: []const u8) !u32 {1259fn makeDebugString(self: *DebugSymbols, allocator: Allocator, bytes: []const u8) !u32 {
1260 try self.debug_string_table.ensureUnusedCapacity(allocator, bytes.len + 1);1260 try self.debug_string_table.ensureUnusedCapacity(allocator, bytes.len + 1);
1261 const result = self.debug_string_table.items.len;1261 const result = self.debug_string_table.items.len;
1262 self.debug_string_table.appendSliceAssumeCapacity(bytes);1262 self.debug_string_table.appendSliceAssumeCapacity(bytes);
src/link/MachO/Dylib.zig+16-16
...@@ -44,7 +44,7 @@ pub const Id = struct {...@@ -44,7 +44,7 @@ pub const Id = struct {
44 current_version: u32,44 current_version: u32,
45 compatibility_version: u32,45 compatibility_version: u32,
4646
47 pub fn default(allocator: *Allocator, name: []const u8) !Id {47 pub fn default(allocator: Allocator, name: []const u8) !Id {
48 return Id{48 return Id{
49 .name = try allocator.dupe(u8, name),49 .name = try allocator.dupe(u8, name),
50 .timestamp = 2,50 .timestamp = 2,
...@@ -53,7 +53,7 @@ pub const Id = struct {...@@ -53,7 +53,7 @@ pub const Id = struct {
53 };53 };
54 }54 }
5555
56 pub fn fromLoadCommand(allocator: *Allocator, lc: commands.GenericCommandWithData(macho.dylib_command)) !Id {56 pub fn fromLoadCommand(allocator: Allocator, lc: commands.GenericCommandWithData(macho.dylib_command)) !Id {
57 const dylib = lc.inner.dylib;57 const dylib = lc.inner.dylib;
58 const dylib_name = @ptrCast([*:0]const u8, lc.data[dylib.name - @sizeOf(macho.dylib_command) ..]);58 const dylib_name = @ptrCast([*:0]const u8, lc.data[dylib.name - @sizeOf(macho.dylib_command) ..]);
59 const name = try allocator.dupe(u8, mem.sliceTo(dylib_name, 0));59 const name = try allocator.dupe(u8, mem.sliceTo(dylib_name, 0));
...@@ -66,7 +66,7 @@ pub const Id = struct {...@@ -66,7 +66,7 @@ pub const Id = struct {
66 };66 };
67 }67 }
6868
69 pub fn deinit(id: *Id, allocator: *Allocator) void {69 pub fn deinit(id: *Id, allocator: Allocator) void {
70 allocator.free(id.name);70 allocator.free(id.name);
71 }71 }
7272
...@@ -125,7 +125,7 @@ pub const Id = struct {...@@ -125,7 +125,7 @@ pub const Id = struct {
125 }125 }
126};126};
127127
128pub fn deinit(self: *Dylib, allocator: *Allocator) void {128pub fn deinit(self: *Dylib, allocator: Allocator) void {
129 for (self.load_commands.items) |*lc| {129 for (self.load_commands.items) |*lc| {
130 lc.deinit(allocator);130 lc.deinit(allocator);
131 }131 }
...@@ -143,7 +143,7 @@ pub fn deinit(self: *Dylib, allocator: *Allocator) void {...@@ -143,7 +143,7 @@ pub fn deinit(self: *Dylib, allocator: *Allocator) void {
143 }143 }
144}144}
145145
146pub fn parse(self: *Dylib, allocator: *Allocator, target: std.Target, dependent_libs: anytype) !void {146pub fn parse(self: *Dylib, allocator: Allocator, target: std.Target, dependent_libs: anytype) !void {
147 log.debug("parsing shared library '{s}'", .{self.name});147 log.debug("parsing shared library '{s}'", .{self.name});
148148
149 self.library_offset = try fat.getLibraryOffset(self.file.reader(), target);149 self.library_offset = try fat.getLibraryOffset(self.file.reader(), target);
...@@ -170,7 +170,7 @@ pub fn parse(self: *Dylib, allocator: *Allocator, target: std.Target, dependent_...@@ -170,7 +170,7 @@ pub fn parse(self: *Dylib, allocator: *Allocator, target: std.Target, dependent_
170 try self.parseSymbols(allocator);170 try self.parseSymbols(allocator);
171}171}
172172
173fn readLoadCommands(self: *Dylib, allocator: *Allocator, reader: anytype, dependent_libs: anytype) !void {173fn readLoadCommands(self: *Dylib, allocator: Allocator, reader: anytype, dependent_libs: anytype) !void {
174 const should_lookup_reexports = self.header.?.flags & macho.MH_NO_REEXPORTED_DYLIBS == 0;174 const should_lookup_reexports = self.header.?.flags & macho.MH_NO_REEXPORTED_DYLIBS == 0;
175175
176 try self.load_commands.ensureUnusedCapacity(allocator, self.header.?.ncmds);176 try self.load_commands.ensureUnusedCapacity(allocator, self.header.?.ncmds);
...@@ -203,7 +203,7 @@ fn readLoadCommands(self: *Dylib, allocator: *Allocator, reader: anytype, depend...@@ -203,7 +203,7 @@ fn readLoadCommands(self: *Dylib, allocator: *Allocator, reader: anytype, depend
203 }203 }
204}204}
205205
206fn parseId(self: *Dylib, allocator: *Allocator) !void {206fn parseId(self: *Dylib, allocator: Allocator) !void {
207 const index = self.id_cmd_index orelse {207 const index = self.id_cmd_index orelse {
208 log.debug("no LC_ID_DYLIB load command found; using hard-coded defaults...", .{});208 log.debug("no LC_ID_DYLIB load command found; using hard-coded defaults...", .{});
209 self.id = try Id.default(allocator, self.name);209 self.id = try Id.default(allocator, self.name);
...@@ -212,7 +212,7 @@ fn parseId(self: *Dylib, allocator: *Allocator) !void {...@@ -212,7 +212,7 @@ fn parseId(self: *Dylib, allocator: *Allocator) !void {
212 self.id = try Id.fromLoadCommand(allocator, self.load_commands.items[index].Dylib);212 self.id = try Id.fromLoadCommand(allocator, self.load_commands.items[index].Dylib);
213}213}
214214
215fn parseSymbols(self: *Dylib, allocator: *Allocator) !void {215fn parseSymbols(self: *Dylib, allocator: Allocator) !void {
216 const index = self.symtab_cmd_index orelse return;216 const index = self.symtab_cmd_index orelse return;
217 const symtab_cmd = self.load_commands.items[index].Symtab;217 const symtab_cmd = self.load_commands.items[index].Symtab;
218218
...@@ -236,7 +236,7 @@ fn parseSymbols(self: *Dylib, allocator: *Allocator) !void {...@@ -236,7 +236,7 @@ fn parseSymbols(self: *Dylib, allocator: *Allocator) !void {
236 }236 }
237}237}
238238
239fn addObjCClassSymbol(self: *Dylib, allocator: *Allocator, sym_name: []const u8) !void {239fn addObjCClassSymbol(self: *Dylib, allocator: Allocator, sym_name: []const u8) !void {
240 const expanded = &[_][]const u8{240 const expanded = &[_][]const u8{
241 try std.fmt.allocPrint(allocator, "_OBJC_CLASS_$_{s}", .{sym_name}),241 try std.fmt.allocPrint(allocator, "_OBJC_CLASS_$_{s}", .{sym_name}),
242 try std.fmt.allocPrint(allocator, "_OBJC_METACLASS_$_{s}", .{sym_name}),242 try std.fmt.allocPrint(allocator, "_OBJC_METACLASS_$_{s}", .{sym_name}),
...@@ -248,29 +248,29 @@ fn addObjCClassSymbol(self: *Dylib, allocator: *Allocator, sym_name: []const u8)...@@ -248,29 +248,29 @@ fn addObjCClassSymbol(self: *Dylib, allocator: *Allocator, sym_name: []const u8)
248 }248 }
249}249}
250250
251fn addObjCIVarSymbol(self: *Dylib, allocator: *Allocator, sym_name: []const u8) !void {251fn addObjCIVarSymbol(self: *Dylib, allocator: Allocator, sym_name: []const u8) !void {
252 const expanded = try std.fmt.allocPrint(allocator, "_OBJC_IVAR_$_{s}", .{sym_name});252 const expanded = try std.fmt.allocPrint(allocator, "_OBJC_IVAR_$_{s}", .{sym_name});
253 if (self.symbols.contains(expanded)) return;253 if (self.symbols.contains(expanded)) return;
254 try self.symbols.putNoClobber(allocator, expanded, .{});254 try self.symbols.putNoClobber(allocator, expanded, .{});
255}255}
256256
257fn addObjCEhTypeSymbol(self: *Dylib, allocator: *Allocator, sym_name: []const u8) !void {257fn addObjCEhTypeSymbol(self: *Dylib, allocator: Allocator, sym_name: []const u8) !void {
258 const expanded = try std.fmt.allocPrint(allocator, "_OBJC_EHTYPE_$_{s}", .{sym_name});258 const expanded = try std.fmt.allocPrint(allocator, "_OBJC_EHTYPE_$_{s}", .{sym_name});
259 if (self.symbols.contains(expanded)) return;259 if (self.symbols.contains(expanded)) return;
260 try self.symbols.putNoClobber(allocator, expanded, .{});260 try self.symbols.putNoClobber(allocator, expanded, .{});
261}261}
262262
263fn addSymbol(self: *Dylib, allocator: *Allocator, sym_name: []const u8) !void {263fn addSymbol(self: *Dylib, allocator: Allocator, sym_name: []const u8) !void {
264 if (self.symbols.contains(sym_name)) return;264 if (self.symbols.contains(sym_name)) return;
265 try self.symbols.putNoClobber(allocator, try allocator.dupe(u8, sym_name), {});265 try self.symbols.putNoClobber(allocator, try allocator.dupe(u8, sym_name), {});
266}266}
267267
268const TargetMatcher = struct {268const TargetMatcher = struct {
269 allocator: *Allocator,269 allocator: Allocator,
270 target: std.Target,270 target: std.Target,
271 target_strings: std.ArrayListUnmanaged([]const u8) = .{},271 target_strings: std.ArrayListUnmanaged([]const u8) = .{},
272272
273 fn init(allocator: *Allocator, target: std.Target) !TargetMatcher {273 fn init(allocator: Allocator, target: std.Target) !TargetMatcher {
274 var self = TargetMatcher{274 var self = TargetMatcher{
275 .allocator = allocator,275 .allocator = allocator,
276 .target = target,276 .target = target,
...@@ -297,7 +297,7 @@ const TargetMatcher = struct {...@@ -297,7 +297,7 @@ const TargetMatcher = struct {
297 self.target_strings.deinit(self.allocator);297 self.target_strings.deinit(self.allocator);
298 }298 }
299299
300 fn targetToAppleString(allocator: *Allocator, target: std.Target) ![]const u8 {300 fn targetToAppleString(allocator: Allocator, target: std.Target) ![]const u8 {
301 const arch = switch (target.cpu.arch) {301 const arch = switch (target.cpu.arch) {
302 .aarch64 => "arm64",302 .aarch64 => "arm64",
303 .x86_64 => "x86_64",303 .x86_64 => "x86_64",
...@@ -336,7 +336,7 @@ const TargetMatcher = struct {...@@ -336,7 +336,7 @@ const TargetMatcher = struct {
336336
337pub fn parseFromStub(337pub fn parseFromStub(
338 self: *Dylib,338 self: *Dylib,
339 allocator: *Allocator,339 allocator: Allocator,
340 target: std.Target,340 target: std.Target,
341 lib_stub: LibStub,341 lib_stub: LibStub,
342 dependent_libs: anytype,342 dependent_libs: anytype,
src/link/MachO/Object.zig+11-11
...@@ -74,7 +74,7 @@ const DebugInfo = struct {...@@ -74,7 +74,7 @@ const DebugInfo = struct {
74 debug_line: []u8,74 debug_line: []u8,
75 debug_ranges: []u8,75 debug_ranges: []u8,
7676
77 pub fn parseFromObject(allocator: *Allocator, object: *const Object) !?DebugInfo {77 pub fn parseFromObject(allocator: Allocator, object: *const Object) !?DebugInfo {
78 var debug_info = blk: {78 var debug_info = blk: {
79 const index = object.dwarf_debug_info_index orelse return null;79 const index = object.dwarf_debug_info_index orelse return null;
80 break :blk try object.readSection(allocator, index);80 break :blk try object.readSection(allocator, index);
...@@ -118,7 +118,7 @@ const DebugInfo = struct {...@@ -118,7 +118,7 @@ const DebugInfo = struct {
118 };118 };
119 }119 }
120120
121 pub fn deinit(self: *DebugInfo, allocator: *Allocator) void {121 pub fn deinit(self: *DebugInfo, allocator: Allocator) void {
122 allocator.free(self.debug_info);122 allocator.free(self.debug_info);
123 allocator.free(self.debug_abbrev);123 allocator.free(self.debug_abbrev);
124 allocator.free(self.debug_str);124 allocator.free(self.debug_str);
...@@ -130,7 +130,7 @@ const DebugInfo = struct {...@@ -130,7 +130,7 @@ const DebugInfo = struct {
130 }130 }
131};131};
132132
133pub fn deinit(self: *Object, allocator: *Allocator) void {133pub fn deinit(self: *Object, allocator: Allocator) void {
134 for (self.load_commands.items) |*lc| {134 for (self.load_commands.items) |*lc| {
135 lc.deinit(allocator);135 lc.deinit(allocator);
136 }136 }
...@@ -160,7 +160,7 @@ pub fn deinit(self: *Object, allocator: *Allocator) void {...@@ -160,7 +160,7 @@ pub fn deinit(self: *Object, allocator: *Allocator) void {
160 }160 }
161}161}
162162
163pub fn free(self: *Object, allocator: *Allocator, macho_file: *MachO) void {163pub fn free(self: *Object, allocator: Allocator, macho_file: *MachO) void {
164 log.debug("freeObject {*}", .{self});164 log.debug("freeObject {*}", .{self});
165165
166 var it = self.end_atoms.iterator();166 var it = self.end_atoms.iterator();
...@@ -227,7 +227,7 @@ fn freeAtoms(self: *Object, macho_file: *MachO) void {...@@ -227,7 +227,7 @@ fn freeAtoms(self: *Object, macho_file: *MachO) void {
227 }227 }
228}228}
229229
230pub fn parse(self: *Object, allocator: *Allocator, target: std.Target) !void {230pub fn parse(self: *Object, allocator: Allocator, target: std.Target) !void {
231 const reader = self.file.reader();231 const reader = self.file.reader();
232 if (self.file_offset) |offset| {232 if (self.file_offset) |offset| {
233 try reader.context.seekTo(offset);233 try reader.context.seekTo(offset);
...@@ -263,7 +263,7 @@ pub fn parse(self: *Object, allocator: *Allocator, target: std.Target) !void {...@@ -263,7 +263,7 @@ pub fn parse(self: *Object, allocator: *Allocator, target: std.Target) !void {
263 try self.parseDebugInfo(allocator);263 try self.parseDebugInfo(allocator);
264}264}
265265
266pub fn readLoadCommands(self: *Object, allocator: *Allocator, reader: anytype) !void {266pub fn readLoadCommands(self: *Object, allocator: Allocator, reader: anytype) !void {
267 const header = self.header orelse unreachable; // Unreachable here signifies a fatal unexplored condition.267 const header = self.header orelse unreachable; // Unreachable here signifies a fatal unexplored condition.
268 const offset = self.file_offset orelse 0;268 const offset = self.file_offset orelse 0;
269269
...@@ -381,7 +381,7 @@ fn filterDice(dices: []macho.data_in_code_entry, start_addr: u64, end_addr: u64)...@@ -381,7 +381,7 @@ fn filterDice(dices: []macho.data_in_code_entry, start_addr: u64, end_addr: u64)
381 return dices[start..end];381 return dices[start..end];
382}382}
383383
384pub fn parseIntoAtoms(self: *Object, allocator: *Allocator, macho_file: *MachO) !void {384pub fn parseIntoAtoms(self: *Object, allocator: Allocator, macho_file: *MachO) !void {
385 const tracy = trace(@src());385 const tracy = trace(@src());
386 defer tracy.end();386 defer tracy.end();
387387
...@@ -555,7 +555,7 @@ pub fn parseIntoAtoms(self: *Object, allocator: *Allocator, macho_file: *MachO)...@@ -555,7 +555,7 @@ pub fn parseIntoAtoms(self: *Object, allocator: *Allocator, macho_file: *MachO)
555 }555 }
556}556}
557557
558fn parseSymtab(self: *Object, allocator: *Allocator) !void {558fn parseSymtab(self: *Object, allocator: Allocator) !void {
559 const index = self.symtab_cmd_index orelse return;559 const index = self.symtab_cmd_index orelse return;
560 const symtab_cmd = self.load_commands.items[index].Symtab;560 const symtab_cmd = self.load_commands.items[index].Symtab;
561561
...@@ -571,7 +571,7 @@ fn parseSymtab(self: *Object, allocator: *Allocator) !void {...@@ -571,7 +571,7 @@ fn parseSymtab(self: *Object, allocator: *Allocator) !void {
571 try self.strtab.appendSlice(allocator, strtab);571 try self.strtab.appendSlice(allocator, strtab);
572}572}
573573
574pub fn parseDebugInfo(self: *Object, allocator: *Allocator) !void {574pub fn parseDebugInfo(self: *Object, allocator: Allocator) !void {
575 log.debug("parsing debug info in '{s}'", .{self.name});575 log.debug("parsing debug info in '{s}'", .{self.name});
576576
577 var debug_info = blk: {577 var debug_info = blk: {
...@@ -603,7 +603,7 @@ pub fn parseDebugInfo(self: *Object, allocator: *Allocator) !void {...@@ -603,7 +603,7 @@ pub fn parseDebugInfo(self: *Object, allocator: *Allocator) !void {
603 }603 }
604}604}
605605
606pub fn parseDataInCode(self: *Object, allocator: *Allocator) !void {606pub fn parseDataInCode(self: *Object, allocator: Allocator) !void {
607 const index = self.data_in_code_cmd_index orelse return;607 const index = self.data_in_code_cmd_index orelse return;
608 const data_in_code = self.load_commands.items[index].LinkeditData;608 const data_in_code = self.load_commands.items[index].LinkeditData;
609609
...@@ -623,7 +623,7 @@ pub fn parseDataInCode(self: *Object, allocator: *Allocator) !void {...@@ -623,7 +623,7 @@ pub fn parseDataInCode(self: *Object, allocator: *Allocator) !void {
623 }623 }
624}624}
625625
626fn readSection(self: Object, allocator: *Allocator, index: u16) ![]u8 {626fn readSection(self: Object, allocator: Allocator, index: u16) ![]u8 {
627 const seg = self.load_commands.items[self.segment_cmd_index.?].Segment;627 const seg = self.load_commands.items[self.segment_cmd_index.?].Segment;
628 const sect = seg.sections.items[index];628 const sect = seg.sections.items[index];
629 var buffer = try allocator.alloc(u8, @intCast(usize, sect.size));629 var buffer = try allocator.alloc(u8, @intCast(usize, sect.size));
src/link/MachO/Trie.zig+9-9
...@@ -65,7 +65,7 @@ pub const Node = struct {...@@ -65,7 +65,7 @@ pub const Node = struct {
65 to: *Node,65 to: *Node,
66 label: []u8,66 label: []u8,
6767
68 fn deinit(self: *Edge, allocator: *Allocator) void {68 fn deinit(self: *Edge, allocator: Allocator) void {
69 self.to.deinit(allocator);69 self.to.deinit(allocator);
70 allocator.destroy(self.to);70 allocator.destroy(self.to);
71 allocator.free(self.label);71 allocator.free(self.label);
...@@ -75,7 +75,7 @@ pub const Node = struct {...@@ -75,7 +75,7 @@ pub const Node = struct {
75 }75 }
76 };76 };
7777
78 fn deinit(self: *Node, allocator: *Allocator) void {78 fn deinit(self: *Node, allocator: Allocator) void {
79 for (self.edges.items) |*edge| {79 for (self.edges.items) |*edge| {
80 edge.deinit(allocator);80 edge.deinit(allocator);
81 }81 }
...@@ -83,7 +83,7 @@ pub const Node = struct {...@@ -83,7 +83,7 @@ pub const Node = struct {
83 }83 }
8484
85 /// Inserts a new node starting from `self`.85 /// Inserts a new node starting from `self`.
86 fn put(self: *Node, allocator: *Allocator, label: []const u8) !*Node {86 fn put(self: *Node, allocator: Allocator, label: []const u8) !*Node {
87 // Check for match with edges from this node.87 // Check for match with edges from this node.
88 for (self.edges.items) |*edge| {88 for (self.edges.items) |*edge| {
89 const match = mem.indexOfDiff(u8, edge.label, label) orelse return edge.to;89 const match = mem.indexOfDiff(u8, edge.label, label) orelse return edge.to;
...@@ -126,7 +126,7 @@ pub const Node = struct {...@@ -126,7 +126,7 @@ pub const Node = struct {
126 }126 }
127127
128 /// Recursively parses the node from the input byte stream.128 /// Recursively parses the node from the input byte stream.
129 fn read(self: *Node, allocator: *Allocator, reader: anytype) Trie.ReadError!usize {129 fn read(self: *Node, allocator: Allocator, reader: anytype) Trie.ReadError!usize {
130 self.node_dirty = true;130 self.node_dirty = true;
131 const trie_offset = try reader.context.getPos();131 const trie_offset = try reader.context.getPos();
132 self.trie_offset = trie_offset;132 self.trie_offset = trie_offset;
...@@ -308,7 +308,7 @@ pub const ExportSymbol = struct {...@@ -308,7 +308,7 @@ pub const ExportSymbol = struct {
308/// Insert a symbol into the trie, updating the prefixes in the process.308/// Insert a symbol into the trie, updating the prefixes in the process.
309/// This operation may change the layout of the trie by splicing edges in309/// This operation may change the layout of the trie by splicing edges in
310/// certain circumstances.310/// certain circumstances.
311pub fn put(self: *Trie, allocator: *Allocator, symbol: ExportSymbol) !void {311pub fn put(self: *Trie, allocator: Allocator, symbol: ExportSymbol) !void {
312 try self.createRoot(allocator);312 try self.createRoot(allocator);
313 const node = try self.root.?.put(allocator, symbol.name);313 const node = try self.root.?.put(allocator, symbol.name);
314 node.terminal_info = .{314 node.terminal_info = .{
...@@ -322,7 +322,7 @@ pub fn put(self: *Trie, allocator: *Allocator, symbol: ExportSymbol) !void {...@@ -322,7 +322,7 @@ pub fn put(self: *Trie, allocator: *Allocator, symbol: ExportSymbol) !void {
322/// This step performs multiple passes through the trie ensuring322/// This step performs multiple passes through the trie ensuring
323/// there are no gaps after every `Node` is ULEB128 encoded.323/// there are no gaps after every `Node` is ULEB128 encoded.
324/// Call this method before trying to `write` the trie to a byte stream.324/// Call this method before trying to `write` the trie to a byte stream.
325pub fn finalize(self: *Trie, allocator: *Allocator) !void {325pub fn finalize(self: *Trie, allocator: Allocator) !void {
326 if (!self.trie_dirty) return;326 if (!self.trie_dirty) return;
327327
328 self.ordered_nodes.shrinkRetainingCapacity(0);328 self.ordered_nodes.shrinkRetainingCapacity(0);
...@@ -361,7 +361,7 @@ const ReadError = error{...@@ -361,7 +361,7 @@ const ReadError = error{
361};361};
362362
363/// Parse the trie from a byte stream.363/// Parse the trie from a byte stream.
364pub fn read(self: *Trie, allocator: *Allocator, reader: anytype) ReadError!usize {364pub fn read(self: *Trie, allocator: Allocator, reader: anytype) ReadError!usize {
365 try self.createRoot(allocator);365 try self.createRoot(allocator);
366 return self.root.?.read(allocator, reader);366 return self.root.?.read(allocator, reader);
367}367}
...@@ -377,7 +377,7 @@ pub fn write(self: Trie, writer: anytype) !u64 {...@@ -377,7 +377,7 @@ pub fn write(self: Trie, writer: anytype) !u64 {
377 return counting_writer.bytes_written;377 return counting_writer.bytes_written;
378}378}
379379
380pub fn deinit(self: *Trie, allocator: *Allocator) void {380pub fn deinit(self: *Trie, allocator: Allocator) void {
381 if (self.root) |root| {381 if (self.root) |root| {
382 root.deinit(allocator);382 root.deinit(allocator);
383 allocator.destroy(root);383 allocator.destroy(root);
...@@ -385,7 +385,7 @@ pub fn deinit(self: *Trie, allocator: *Allocator) void {...@@ -385,7 +385,7 @@ pub fn deinit(self: *Trie, allocator: *Allocator) void {
385 self.ordered_nodes.deinit(allocator);385 self.ordered_nodes.deinit(allocator);
386}386}
387387
388fn createRoot(self: *Trie, allocator: *Allocator) !void {388fn createRoot(self: *Trie, allocator: Allocator) !void {
389 if (self.root == null) {389 if (self.root == null) {
390 const root = try allocator.create(Node);390 const root = try allocator.create(Node);
391 root.* = .{ .base = self };391 root.* = .{ .base = self };
src/link/MachO/commands.zig+8-8
...@@ -50,7 +50,7 @@ pub const LoadCommand = union(enum) {...@@ -50,7 +50,7 @@ pub const LoadCommand = union(enum) {
50 Rpath: GenericCommandWithData(macho.rpath_command),50 Rpath: GenericCommandWithData(macho.rpath_command),
51 Unknown: GenericCommandWithData(macho.load_command),51 Unknown: GenericCommandWithData(macho.load_command),
5252
53 pub fn read(allocator: *Allocator, reader: anytype) !LoadCommand {53 pub fn read(allocator: Allocator, reader: anytype) !LoadCommand {
54 const header = try reader.readStruct(macho.load_command);54 const header = try reader.readStruct(macho.load_command);
55 var buffer = try allocator.alloc(u8, header.cmdsize);55 var buffer = try allocator.alloc(u8, header.cmdsize);
56 defer allocator.free(buffer);56 defer allocator.free(buffer);
...@@ -177,7 +177,7 @@ pub const LoadCommand = union(enum) {...@@ -177,7 +177,7 @@ pub const LoadCommand = union(enum) {
177 };177 };
178 }178 }
179179
180 pub fn deinit(self: *LoadCommand, allocator: *Allocator) void {180 pub fn deinit(self: *LoadCommand, allocator: Allocator) void {
181 return switch (self.*) {181 return switch (self.*) {
182 .Segment => |*x| x.deinit(allocator),182 .Segment => |*x| x.deinit(allocator),
183 .Dylinker => |*x| x.deinit(allocator),183 .Dylinker => |*x| x.deinit(allocator),
...@@ -218,7 +218,7 @@ pub const SegmentCommand = struct {...@@ -218,7 +218,7 @@ pub const SegmentCommand = struct {
218 inner: macho.segment_command_64,218 inner: macho.segment_command_64,
219 sections: std.ArrayListUnmanaged(macho.section_64) = .{},219 sections: std.ArrayListUnmanaged(macho.section_64) = .{},
220220
221 pub fn read(alloc: *Allocator, reader: anytype) !SegmentCommand {221 pub fn read(alloc: Allocator, reader: anytype) !SegmentCommand {
222 const inner = try reader.readStruct(macho.segment_command_64);222 const inner = try reader.readStruct(macho.segment_command_64);
223 var segment = SegmentCommand{223 var segment = SegmentCommand{
224 .inner = inner,224 .inner = inner,
...@@ -241,7 +241,7 @@ pub const SegmentCommand = struct {...@@ -241,7 +241,7 @@ pub const SegmentCommand = struct {
241 }241 }
242 }242 }
243243
244 pub fn deinit(self: *SegmentCommand, alloc: *Allocator) void {244 pub fn deinit(self: *SegmentCommand, alloc: Allocator) void {
245 self.sections.deinit(alloc);245 self.sections.deinit(alloc);
246 }246 }
247247
...@@ -299,7 +299,7 @@ pub fn GenericCommandWithData(comptime Cmd: type) type {...@@ -299,7 +299,7 @@ pub fn GenericCommandWithData(comptime Cmd: type) type {
299299
300 const Self = @This();300 const Self = @This();
301301
302 pub fn read(allocator: *Allocator, reader: anytype) !Self {302 pub fn read(allocator: Allocator, reader: anytype) !Self {
303 const inner = try reader.readStruct(Cmd);303 const inner = try reader.readStruct(Cmd);
304 var data = try allocator.alloc(u8, inner.cmdsize - @sizeOf(Cmd));304 var data = try allocator.alloc(u8, inner.cmdsize - @sizeOf(Cmd));
305 errdefer allocator.free(data);305 errdefer allocator.free(data);
...@@ -315,7 +315,7 @@ pub fn GenericCommandWithData(comptime Cmd: type) type {...@@ -315,7 +315,7 @@ pub fn GenericCommandWithData(comptime Cmd: type) type {
315 try writer.writeAll(self.data);315 try writer.writeAll(self.data);
316 }316 }
317317
318 pub fn deinit(self: *Self, allocator: *Allocator) void {318 pub fn deinit(self: *Self, allocator: Allocator) void {
319 allocator.free(self.data);319 allocator.free(self.data);
320 }320 }
321321
...@@ -327,7 +327,7 @@ pub fn GenericCommandWithData(comptime Cmd: type) type {...@@ -327,7 +327,7 @@ pub fn GenericCommandWithData(comptime Cmd: type) type {
327}327}
328328
329pub fn createLoadDylibCommand(329pub fn createLoadDylibCommand(
330 allocator: *Allocator,330 allocator: Allocator,
331 name: []const u8,331 name: []const u8,
332 timestamp: u32,332 timestamp: u32,
333 current_version: u32,333 current_version: u32,
...@@ -395,7 +395,7 @@ pub fn sectionIsDontDeadStripIfReferencesLive(sect: macho.section_64) bool {...@@ -395,7 +395,7 @@ pub fn sectionIsDontDeadStripIfReferencesLive(sect: macho.section_64) bool {
395 return sectionAttrs(sect) & macho.S_ATTR_LIVE_SUPPORT != 0;395 return sectionAttrs(sect) & macho.S_ATTR_LIVE_SUPPORT != 0;
396}396}
397397
398fn testRead(allocator: *Allocator, buffer: []const u8, expected: anytype) !void {398fn testRead(allocator: Allocator, buffer: []const u8, expected: anytype) !void {
399 var stream = io.fixedBufferStream(buffer);399 var stream = io.fixedBufferStream(buffer);
400 var given = try LoadCommand.read(allocator, stream.reader());400 var given = try LoadCommand.read(allocator, stream.reader());
401 defer given.deinit(allocator);401 defer given.deinit(allocator);
src/link/Plan9.zig+3-3
...@@ -132,7 +132,7 @@ pub fn defaultBaseAddrs(arch: std.Target.Cpu.Arch) Bases {...@@ -132,7 +132,7 @@ pub fn defaultBaseAddrs(arch: std.Target.Cpu.Arch) Bases {
132132
133pub const PtrWidth = enum { p32, p64 };133pub const PtrWidth = enum { p32, p64 };
134134
135pub fn createEmpty(gpa: *Allocator, options: link.Options) !*Plan9 {135pub fn createEmpty(gpa: Allocator, options: link.Options) !*Plan9 {
136 if (options.use_llvm)136 if (options.use_llvm)
137 return error.LLVMBackendDoesNotSupportPlan9;137 return error.LLVMBackendDoesNotSupportPlan9;
138 const sixtyfour_bit: bool = switch (options.target.cpu.arch.ptrBitWidth()) {138 const sixtyfour_bit: bool = switch (options.target.cpu.arch.ptrBitWidth()) {
...@@ -168,7 +168,7 @@ fn putFn(self: *Plan9, decl: *Module.Decl, out: FnDeclOutput) !void {...@@ -168,7 +168,7 @@ fn putFn(self: *Plan9, decl: *Module.Decl, out: FnDeclOutput) !void {
168 try fn_map_res.value_ptr.functions.put(gpa, decl, out);168 try fn_map_res.value_ptr.functions.put(gpa, decl, out);
169 } else {169 } else {
170 const file = decl.getFileScope();170 const file = decl.getFileScope();
171 const arena = &self.path_arena.allocator;171 const arena = self.path_arena.allocator();
172 // each file gets a symbol172 // each file gets a symbol
173 fn_map_res.value_ptr.* = .{173 fn_map_res.value_ptr.* = .{
174 .sym_index = blk: {174 .sym_index = blk: {
...@@ -621,7 +621,7 @@ pub fn deinit(self: *Plan9) void {...@@ -621,7 +621,7 @@ pub fn deinit(self: *Plan9) void {
621621
622pub const Export = ?usize;622pub const Export = ?usize;
623pub const base_tag = .plan9;623pub const base_tag = .plan9;
624pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Options) !*Plan9 {624pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*Plan9 {
625 if (options.use_llvm)625 if (options.use_llvm)
626 return error.LLVMBackendDoesNotSupportPlan9;626 return error.LLVMBackendDoesNotSupportPlan9;
627 assert(options.object_format == .plan9);627 assert(options.object_format == .plan9);
src/link/SpirV.zig+2-2
...@@ -58,7 +58,7 @@ const DeclGenContext = struct {...@@ -58,7 +58,7 @@ const DeclGenContext = struct {
58 liveness: Liveness,58 liveness: Liveness,
59};59};
6060
61pub fn createEmpty(gpa: *Allocator, options: link.Options) !*SpirV {61pub fn createEmpty(gpa: Allocator, options: link.Options) !*SpirV {
62 const spirv = try gpa.create(SpirV);62 const spirv = try gpa.create(SpirV);
63 spirv.* = .{63 spirv.* = .{
64 .base = .{64 .base = .{
...@@ -87,7 +87,7 @@ pub fn createEmpty(gpa: *Allocator, options: link.Options) !*SpirV {...@@ -87,7 +87,7 @@ pub fn createEmpty(gpa: *Allocator, options: link.Options) !*SpirV {
87 return spirv;87 return spirv;
88}88}
8989
90pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Options) !*SpirV {90pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*SpirV {
91 assert(options.object_format == .spirv);91 assert(options.object_format == .spirv);
9292
93 if (options.use_llvm) return error.LLVM_BackendIsTODO_ForSpirV; // TODO: LLVM Doesn't support SpirV at all.93 if (options.use_llvm) return error.LLVM_BackendIsTODO_ForSpirV; // TODO: LLVM Doesn't support SpirV at all.
src/link/Wasm.zig+3-3
...@@ -97,7 +97,7 @@ pub const FnData = struct {...@@ -97,7 +97,7 @@ pub const FnData = struct {
97 };97 };
98};98};
9999
100pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Options) !*Wasm {100pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*Wasm {
101 assert(options.object_format == .wasm);101 assert(options.object_format == .wasm);
102102
103 if (build_options.have_llvm and options.use_llvm) {103 if (build_options.have_llvm and options.use_llvm) {
...@@ -138,7 +138,7 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio...@@ -138,7 +138,7 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio
138 return wasm_bin;138 return wasm_bin;
139}139}
140140
141pub fn createEmpty(gpa: *Allocator, options: link.Options) !*Wasm {141pub fn createEmpty(gpa: Allocator, options: link.Options) !*Wasm {
142 const wasm_bin = try gpa.create(Wasm);142 const wasm_bin = try gpa.create(Wasm);
143 wasm_bin.* = .{143 wasm_bin.* = .{
144 .base = .{144 .base = .{
...@@ -950,7 +950,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {...@@ -950,7 +950,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
950950
951 var arena_allocator = std.heap.ArenaAllocator.init(self.base.allocator);951 var arena_allocator = std.heap.ArenaAllocator.init(self.base.allocator);
952 defer arena_allocator.deinit();952 defer arena_allocator.deinit();
953 const arena = &arena_allocator.allocator;953 const arena = arena_allocator.allocator();
954954
955 const directory = self.base.options.emit.?.directory; // Just an alias to make it shorter to type.955 const directory = self.base.options.emit.?.directory; // Just an alias to make it shorter to type.
956956
src/link/Wasm/Atom.zig+1-1
...@@ -42,7 +42,7 @@ pub const empty: Atom = .{...@@ -42,7 +42,7 @@ pub const empty: Atom = .{
42};42};
4343
44/// Frees all resources owned by this `Atom`.44/// Frees all resources owned by this `Atom`.
45pub fn deinit(self: *Atom, gpa: *Allocator) void {45pub fn deinit(self: *Atom, gpa: Allocator) void {
46 self.relocs.deinit(gpa);46 self.relocs.deinit(gpa);
47 self.code.deinit(gpa);47 self.code.deinit(gpa);
48}48}
src/link/tapi.zig+5-5
...@@ -106,7 +106,7 @@ pub const LibStub = struct {...@@ -106,7 +106,7 @@ pub const LibStub = struct {
106 /// Typed contents of the tbd file.106 /// Typed contents of the tbd file.
107 inner: []Tbd,107 inner: []Tbd,
108108
109 pub fn loadFromFile(allocator: *Allocator, file: fs.File) !LibStub {109 pub fn loadFromFile(allocator: Allocator, file: fs.File) !LibStub {
110 const source = try file.readToEndAlloc(allocator, std.math.maxInt(u32));110 const source = try file.readToEndAlloc(allocator, std.math.maxInt(u32));
111 defer allocator.free(source);111 defer allocator.free(source);
112112
...@@ -120,7 +120,7 @@ pub const LibStub = struct {...@@ -120,7 +120,7 @@ pub const LibStub = struct {
120 err: {120 err: {
121 log.debug("trying to parse as []TbdV4", .{});121 log.debug("trying to parse as []TbdV4", .{});
122 const inner = lib_stub.yaml.parse([]TbdV4) catch break :err;122 const inner = lib_stub.yaml.parse([]TbdV4) catch break :err;
123 var out = try lib_stub.yaml.arena.allocator.alloc(Tbd, inner.len);123 var out = try lib_stub.yaml.arena.allocator().alloc(Tbd, inner.len);
124 for (inner) |doc, i| {124 for (inner) |doc, i| {
125 out[i] = .{ .v4 = doc };125 out[i] = .{ .v4 = doc };
126 }126 }
...@@ -130,7 +130,7 @@ pub const LibStub = struct {...@@ -130,7 +130,7 @@ pub const LibStub = struct {
130 err: {130 err: {
131 log.debug("trying to parse as TbdV4", .{});131 log.debug("trying to parse as TbdV4", .{});
132 const inner = lib_stub.yaml.parse(TbdV4) catch break :err;132 const inner = lib_stub.yaml.parse(TbdV4) catch break :err;
133 var out = try lib_stub.yaml.arena.allocator.alloc(Tbd, 1);133 var out = try lib_stub.yaml.arena.allocator().alloc(Tbd, 1);
134 out[0] = .{ .v4 = inner };134 out[0] = .{ .v4 = inner };
135 break :blk out;135 break :blk out;
136 }136 }
...@@ -138,7 +138,7 @@ pub const LibStub = struct {...@@ -138,7 +138,7 @@ pub const LibStub = struct {
138 err: {138 err: {
139 log.debug("trying to parse as []TbdV3", .{});139 log.debug("trying to parse as []TbdV3", .{});
140 const inner = lib_stub.yaml.parse([]TbdV3) catch break :err;140 const inner = lib_stub.yaml.parse([]TbdV3) catch break :err;
141 var out = try lib_stub.yaml.arena.allocator.alloc(Tbd, inner.len);141 var out = try lib_stub.yaml.arena.allocator().alloc(Tbd, inner.len);
142 for (inner) |doc, i| {142 for (inner) |doc, i| {
143 out[i] = .{ .v3 = doc };143 out[i] = .{ .v3 = doc };
144 }144 }
...@@ -148,7 +148,7 @@ pub const LibStub = struct {...@@ -148,7 +148,7 @@ pub const LibStub = struct {
148 err: {148 err: {
149 log.debug("trying to parse as TbdV3", .{});149 log.debug("trying to parse as TbdV3", .{});
150 const inner = lib_stub.yaml.parse(TbdV3) catch break :err;150 const inner = lib_stub.yaml.parse(TbdV3) catch break :err;
151 var out = try lib_stub.yaml.arena.allocator.alloc(Tbd, 1);151 var out = try lib_stub.yaml.arena.allocator().alloc(Tbd, 1);
152 out[0] = .{ .v3 = inner };152 out[0] = .{ .v3 = inner };
153 break :blk out;153 break :blk out;
154 }154 }
src/link/tapi/parse.zig+7-7
...@@ -37,7 +37,7 @@ pub const Node = struct {...@@ -37,7 +37,7 @@ pub const Node = struct {
37 return @fieldParentPtr(T, "base", self);37 return @fieldParentPtr(T, "base", self);
38 }38 }
3939
40 pub fn deinit(self: *Node, allocator: *Allocator) void {40 pub fn deinit(self: *Node, allocator: Allocator) void {
41 switch (self.tag) {41 switch (self.tag) {
42 .doc => @fieldParentPtr(Node.Doc, "base", self).deinit(allocator),42 .doc => @fieldParentPtr(Node.Doc, "base", self).deinit(allocator),
43 .map => @fieldParentPtr(Node.Map, "base", self).deinit(allocator),43 .map => @fieldParentPtr(Node.Map, "base", self).deinit(allocator),
...@@ -69,7 +69,7 @@ pub const Node = struct {...@@ -69,7 +69,7 @@ pub const Node = struct {
6969
70 pub const base_tag: Node.Tag = .doc;70 pub const base_tag: Node.Tag = .doc;
7171
72 pub fn deinit(self: *Doc, allocator: *Allocator) void {72 pub fn deinit(self: *Doc, allocator: Allocator) void {
73 if (self.value) |node| {73 if (self.value) |node| {
74 node.deinit(allocator);74 node.deinit(allocator);
75 allocator.destroy(node);75 allocator.destroy(node);
...@@ -113,7 +113,7 @@ pub const Node = struct {...@@ -113,7 +113,7 @@ pub const Node = struct {
113 value: *Node,113 value: *Node,
114 };114 };
115115
116 pub fn deinit(self: *Map, allocator: *Allocator) void {116 pub fn deinit(self: *Map, allocator: Allocator) void {
117 for (self.values.items) |entry| {117 for (self.values.items) |entry| {
118 entry.value.deinit(allocator);118 entry.value.deinit(allocator);
119 allocator.destroy(entry.value);119 allocator.destroy(entry.value);
...@@ -149,7 +149,7 @@ pub const Node = struct {...@@ -149,7 +149,7 @@ pub const Node = struct {
149149
150 pub const base_tag: Node.Tag = .list;150 pub const base_tag: Node.Tag = .list;
151151
152 pub fn deinit(self: *List, allocator: *Allocator) void {152 pub fn deinit(self: *List, allocator: Allocator) void {
153 for (self.values.items) |node| {153 for (self.values.items) |node| {
154 node.deinit(allocator);154 node.deinit(allocator);
155 allocator.destroy(node);155 allocator.destroy(node);
...@@ -198,12 +198,12 @@ pub const Node = struct {...@@ -198,12 +198,12 @@ pub const Node = struct {
198};198};
199199
200pub const Tree = struct {200pub const Tree = struct {
201 allocator: *Allocator,201 allocator: Allocator,
202 source: []const u8,202 source: []const u8,
203 tokens: []Token,203 tokens: []Token,
204 docs: std.ArrayListUnmanaged(*Node) = .{},204 docs: std.ArrayListUnmanaged(*Node) = .{},
205205
206 pub fn init(allocator: *Allocator) Tree {206 pub fn init(allocator: Allocator) Tree {
207 return .{207 return .{
208 .allocator = allocator,208 .allocator = allocator,
209 .source = undefined,209 .source = undefined,
...@@ -266,7 +266,7 @@ pub const Tree = struct {...@@ -266,7 +266,7 @@ pub const Tree = struct {
266};266};
267267
268const Parser = struct {268const Parser = struct {
269 allocator: *Allocator,269 allocator: Allocator,
270 tree: *Tree,270 tree: *Tree,
271 token_it: *TokenIterator,271 token_it: *TokenIterator,
272 scopes: std.ArrayListUnmanaged(Scope) = .{},272 scopes: std.ArrayListUnmanaged(Scope) = .{},
src/link/tapi/yaml.zig+9-8
...@@ -149,7 +149,7 @@ pub const Value = union(ValueType) {...@@ -149,7 +149,7 @@ pub const Value = union(ValueType) {
149 };149 };
150 }150 }
151151
152 fn fromNode(arena: *Allocator, tree: *const Tree, node: *const Node, type_hint: ?ValueType) YamlError!Value {152 fn fromNode(arena: Allocator, tree: *const Tree, node: *const Node, type_hint: ?ValueType) YamlError!Value {
153 if (node.cast(Node.Doc)) |doc| {153 if (node.cast(Node.Doc)) |doc| {
154 const inner = doc.value orelse {154 const inner = doc.value orelse {
155 // empty doc155 // empty doc
...@@ -246,17 +246,18 @@ pub const Yaml = struct {...@@ -246,17 +246,18 @@ pub const Yaml = struct {
246 }246 }
247 }247 }
248248
249 pub fn load(allocator: *Allocator, source: []const u8) !Yaml {249 pub fn load(allocator: Allocator, source: []const u8) !Yaml {
250 var arena = ArenaAllocator.init(allocator);250 var arena = ArenaAllocator.init(allocator);
251 const arena_allocator = arena.allocator();
251252
252 var tree = Tree.init(&arena.allocator);253 var tree = Tree.init(arena_allocator);
253 try tree.parse(source);254 try tree.parse(source);
254255
255 var docs = std.ArrayList(Value).init(&arena.allocator);256 var docs = std.ArrayList(Value).init(arena_allocator);
256 try docs.ensureUnusedCapacity(tree.docs.items.len);257 try docs.ensureUnusedCapacity(tree.docs.items.len);
257258
258 for (tree.docs.items) |node| {259 for (tree.docs.items) |node| {
259 const value = try Value.fromNode(&arena.allocator, &tree, node, null);260 const value = try Value.fromNode(arena_allocator, &tree, node, null);
260 docs.appendAssumeCapacity(value);261 docs.appendAssumeCapacity(value);
261 }262 }
262263
...@@ -299,7 +300,7 @@ pub const Yaml = struct {...@@ -299,7 +300,7 @@ pub const Yaml = struct {
299 .Pointer => |info| {300 .Pointer => |info| {
300 switch (info.size) {301 switch (info.size) {
301 .Slice => {302 .Slice => {
302 var parsed = try self.arena.allocator.alloc(info.child, self.docs.items.len);303 var parsed = try self.arena.allocator().alloc(info.child, self.docs.items.len);
303 for (self.docs.items) |doc, i| {304 for (self.docs.items) |doc, i| {
304 parsed[i] = try self.parseValue(info.child, doc);305 parsed[i] = try self.parseValue(info.child, doc);
305 }306 }
...@@ -361,7 +362,7 @@ pub const Yaml = struct {...@@ -361,7 +362,7 @@ pub const Yaml = struct {
361362
362 inline for (struct_info.fields) |field| {363 inline for (struct_info.fields) |field| {
363 const value: ?Value = map.get(field.name) orelse blk: {364 const value: ?Value = map.get(field.name) orelse blk: {
364 const field_name = try mem.replaceOwned(u8, &self.arena.allocator, field.name, "_", "-");365 const field_name = try mem.replaceOwned(u8, self.arena.allocator(), field.name, "_", "-");
365 break :blk map.get(field_name);366 break :blk map.get(field_name);
366 };367 };
367368
...@@ -382,7 +383,7 @@ pub const Yaml = struct {...@@ -382,7 +383,7 @@ pub const Yaml = struct {
382383
383 fn parsePointer(self: *Yaml, comptime T: type, value: Value) Error!T {384 fn parsePointer(self: *Yaml, comptime T: type, value: Value) Error!T {
384 const ptr_info = @typeInfo(T).Pointer;385 const ptr_info = @typeInfo(T).Pointer;
385 const arena = &self.arena.allocator;386 const arena = self.arena.allocator();
386387
387 switch (ptr_info.size) {388 switch (ptr_info.size) {
388 .Slice => {389 .Slice => {
src/main.zig+36-36
...@@ -139,7 +139,7 @@ pub fn main() anyerror!void {...@@ -139,7 +139,7 @@ pub fn main() anyerror!void {
139 const gpa = gpa: {139 const gpa = gpa: {
140 if (!builtin.link_libc) {140 if (!builtin.link_libc) {
141 gpa_need_deinit = true;141 gpa_need_deinit = true;
142 break :gpa &general_purpose_allocator.allocator;142 break :gpa general_purpose_allocator.allocator();
143 }143 }
144 // We would prefer to use raw libc allocator here, but cannot144 // We would prefer to use raw libc allocator here, but cannot
145 // use it if it won't support the alignment we need.145 // use it if it won't support the alignment we need.
...@@ -153,19 +153,19 @@ pub fn main() anyerror!void {...@@ -153,19 +153,19 @@ pub fn main() anyerror!void {
153 };153 };
154 var arena_instance = std.heap.ArenaAllocator.init(gpa);154 var arena_instance = std.heap.ArenaAllocator.init(gpa);
155 defer arena_instance.deinit();155 defer arena_instance.deinit();
156 const arena = &arena_instance.allocator;156 const arena = arena_instance.allocator();
157157
158 const args = try process.argsAlloc(arena);158 const args = try process.argsAlloc(arena);
159159
160 if (tracy.enable_allocation) {160 if (tracy.enable_allocation) {
161 var gpa_tracy = tracy.tracyAllocator(gpa);161 var gpa_tracy = tracy.tracyAllocator(gpa);
162 return mainArgs(&gpa_tracy.allocator, arena, args);162 return mainArgs(gpa_tracy.allocator(), arena, args);
163 }163 }
164164
165 return mainArgs(gpa, arena, args);165 return mainArgs(gpa, arena, args);
166}166}
167167
168pub fn mainArgs(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !void {168pub fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
169 if (args.len <= 1) {169 if (args.len <= 1) {
170 std.log.info("{s}", .{usage});170 std.log.info("{s}", .{usage});
171 fatal("expected command argument", .{});171 fatal("expected command argument", .{});
...@@ -536,7 +536,7 @@ const Emit = union(enum) {...@@ -536,7 +536,7 @@ const Emit = union(enum) {
536 }536 }
537};537};
538538
539fn optionalStringEnvVar(arena: *Allocator, name: []const u8) !?[]const u8 {539fn optionalStringEnvVar(arena: Allocator, name: []const u8) !?[]const u8 {
540 if (std.process.getEnvVarOwned(arena, name)) |value| {540 if (std.process.getEnvVarOwned(arena, name)) |value| {
541 return value;541 return value;
542 } else |err| switch (err) {542 } else |err| switch (err) {
...@@ -555,8 +555,8 @@ const ArgMode = union(enum) {...@@ -555,8 +555,8 @@ const ArgMode = union(enum) {
555};555};
556556
557fn buildOutputType(557fn buildOutputType(
558 gpa: *Allocator,558 gpa: Allocator,
559 arena: *Allocator,559 arena: Allocator,
560 all_args: []const []const u8,560 all_args: []const []const u8,
561 arg_mode: ArgMode,561 arg_mode: ArgMode,
562) !void {562) !void {
...@@ -2648,7 +2648,7 @@ fn buildOutputType(...@@ -2648,7 +2648,7 @@ fn buildOutputType(
2648}2648}
26492649
2650fn parseCrossTargetOrReportFatalError(2650fn parseCrossTargetOrReportFatalError(
2651 allocator: *Allocator,2651 allocator: Allocator,
2652 opts: std.zig.CrossTarget.ParseOptions,2652 opts: std.zig.CrossTarget.ParseOptions,
2653) !std.zig.CrossTarget {2653) !std.zig.CrossTarget {
2654 var opts_with_diags = opts;2654 var opts_with_diags = opts;
...@@ -2689,8 +2689,8 @@ fn parseCrossTargetOrReportFatalError(...@@ -2689,8 +2689,8 @@ fn parseCrossTargetOrReportFatalError(
26892689
2690fn runOrTest(2690fn runOrTest(
2691 comp: *Compilation,2691 comp: *Compilation,
2692 gpa: *Allocator,2692 gpa: Allocator,
2693 arena: *Allocator,2693 arena: Allocator,
2694 emit_bin_loc: ?Compilation.EmitLoc,2694 emit_bin_loc: ?Compilation.EmitLoc,
2695 test_exec_args: []const ?[]const u8,2695 test_exec_args: []const ?[]const u8,
2696 self_exe_path: []const u8,2696 self_exe_path: []const u8,
...@@ -2821,7 +2821,7 @@ const AfterUpdateHook = union(enum) {...@@ -2821,7 +2821,7 @@ const AfterUpdateHook = union(enum) {
2821 update: []const u8,2821 update: []const u8,
2822};2822};
28232823
2824fn updateModule(gpa: *Allocator, comp: *Compilation, hook: AfterUpdateHook) !void {2824fn updateModule(gpa: Allocator, comp: *Compilation, hook: AfterUpdateHook) !void {
2825 try comp.update();2825 try comp.update();
28262826
2827 var errors = try comp.getAllErrorsAlloc();2827 var errors = try comp.getAllErrorsAlloc();
...@@ -2875,7 +2875,7 @@ fn updateModule(gpa: *Allocator, comp: *Compilation, hook: AfterUpdateHook) !voi...@@ -2875,7 +2875,7 @@ fn updateModule(gpa: *Allocator, comp: *Compilation, hook: AfterUpdateHook) !voi
2875 }2875 }
2876}2876}
28772877
2878fn freePkgTree(gpa: *Allocator, pkg: *Package, free_parent: bool) void {2878fn freePkgTree(gpa: Allocator, pkg: *Package, free_parent: bool) void {
2879 {2879 {
2880 var it = pkg.table.valueIterator();2880 var it = pkg.table.valueIterator();
2881 while (it.next()) |value| {2881 while (it.next()) |value| {
...@@ -2887,7 +2887,7 @@ fn freePkgTree(gpa: *Allocator, pkg: *Package, free_parent: bool) void {...@@ -2887,7 +2887,7 @@ fn freePkgTree(gpa: *Allocator, pkg: *Package, free_parent: bool) void {
2887 }2887 }
2888}2888}
28892889
2890fn cmdTranslateC(comp: *Compilation, arena: *Allocator, enable_cache: bool) !void {2890fn cmdTranslateC(comp: *Compilation, arena: Allocator, enable_cache: bool) !void {
2891 if (!build_options.have_llvm)2891 if (!build_options.have_llvm)
2892 fatal("cannot translate-c: compiler built without LLVM extensions", .{});2892 fatal("cannot translate-c: compiler built without LLVM extensions", .{});
28932893
...@@ -3034,7 +3034,7 @@ pub const usage_libc =...@@ -3034,7 +3034,7 @@ pub const usage_libc =
3034 \\3034 \\
3035;3035;
30363036
3037pub fn cmdLibC(gpa: *Allocator, args: []const []const u8) !void {3037pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void {
3038 var input_file: ?[]const u8 = null;3038 var input_file: ?[]const u8 = null;
3039 var target_arch_os_abi: []const u8 = "native";3039 var target_arch_os_abi: []const u8 = "native";
3040 {3040 {
...@@ -3103,8 +3103,8 @@ pub const usage_init =...@@ -3103,8 +3103,8 @@ pub const usage_init =
3103;3103;
31043104
3105pub fn cmdInit(3105pub fn cmdInit(
3106 gpa: *Allocator,3106 gpa: Allocator,
3107 arena: *Allocator,3107 arena: Allocator,
3108 args: []const []const u8,3108 args: []const []const u8,
3109 output_mode: std.builtin.OutputMode,3109 output_mode: std.builtin.OutputMode,
3110) !void {3110) !void {
...@@ -3199,7 +3199,7 @@ pub const usage_build =...@@ -3199,7 +3199,7 @@ pub const usage_build =
3199 \\3199 \\
3200;3200;
32013201
3202pub fn cmdBuild(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !void {3202pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
3203 var prominent_compile_errors: bool = false;3203 var prominent_compile_errors: bool = false;
32043204
3205 // We want to release all the locks before executing the child process, so we make a nice3205 // We want to release all the locks before executing the child process, so we make a nice
...@@ -3439,7 +3439,7 @@ pub fn cmdBuild(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !v...@@ -3439,7 +3439,7 @@ pub fn cmdBuild(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !v
3439 }3439 }
3440}3440}
34413441
3442fn argvCmd(allocator: *Allocator, argv: []const []const u8) ![]u8 {3442fn argvCmd(allocator: Allocator, argv: []const []const u8) ![]u8 {
3443 var cmd = std.ArrayList(u8).init(allocator);3443 var cmd = std.ArrayList(u8).init(allocator);
3444 defer cmd.deinit();3444 defer cmd.deinit();
3445 for (argv[0 .. argv.len - 1]) |arg| {3445 for (argv[0 .. argv.len - 1]) |arg| {
...@@ -3451,7 +3451,7 @@ fn argvCmd(allocator: *Allocator, argv: []const []const u8) ![]u8 {...@@ -3451,7 +3451,7 @@ fn argvCmd(allocator: *Allocator, argv: []const []const u8) ![]u8 {
3451}3451}
34523452
3453fn readSourceFileToEndAlloc(3453fn readSourceFileToEndAlloc(
3454 allocator: *mem.Allocator,3454 allocator: mem.Allocator,
3455 input: *const fs.File,3455 input: *const fs.File,
3456 size_hint: ?usize,3456 size_hint: ?usize,
3457) ![:0]u8 {3457) ![:0]u8 {
...@@ -3521,14 +3521,14 @@ const Fmt = struct {...@@ -3521,14 +3521,14 @@ const Fmt = struct {
3521 any_error: bool,3521 any_error: bool,
3522 check_ast: bool,3522 check_ast: bool,
3523 color: Color,3523 color: Color,
3524 gpa: *Allocator,3524 gpa: Allocator,
3525 arena: *Allocator,3525 arena: Allocator,
3526 out_buffer: std.ArrayList(u8),3526 out_buffer: std.ArrayList(u8),
35273527
3528 const SeenMap = std.AutoHashMap(fs.File.INode, void);3528 const SeenMap = std.AutoHashMap(fs.File.INode, void);
3529};3529};
35303530
3531pub fn cmdFmt(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !void {3531pub fn cmdFmt(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
3532 var color: Color = .auto;3532 var color: Color = .auto;
3533 var stdin_flag: bool = false;3533 var stdin_flag: bool = false;
3534 var check_flag: bool = false;3534 var check_flag: bool = false;
...@@ -3622,7 +3622,7 @@ pub fn cmdFmt(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !voi...@@ -3622,7 +3622,7 @@ pub fn cmdFmt(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !voi
3622 var errors = std.ArrayList(Compilation.AllErrors.Message).init(gpa);3622 var errors = std.ArrayList(Compilation.AllErrors.Message).init(gpa);
3623 defer errors.deinit();3623 defer errors.deinit();
36243624
3625 try Compilation.AllErrors.addZir(&arena_instance.allocator, &errors, &file);3625 try Compilation.AllErrors.addZir(arena_instance.allocator(), &errors, &file);
3626 const ttyconf: std.debug.TTY.Config = switch (color) {3626 const ttyconf: std.debug.TTY.Config = switch (color) {
3627 .auto => std.debug.detectTTYConfig(),3627 .auto => std.debug.detectTTYConfig(),
3628 .on => .escape_codes,3628 .on => .escape_codes,
...@@ -3821,7 +3821,7 @@ fn fmtPathFile(...@@ -3821,7 +3821,7 @@ fn fmtPathFile(
3821 var errors = std.ArrayList(Compilation.AllErrors.Message).init(fmt.gpa);3821 var errors = std.ArrayList(Compilation.AllErrors.Message).init(fmt.gpa);
3822 defer errors.deinit();3822 defer errors.deinit();
38233823
3824 try Compilation.AllErrors.addZir(&arena_instance.allocator, &errors, &file);3824 try Compilation.AllErrors.addZir(arena_instance.allocator(), &errors, &file);
3825 const ttyconf: std.debug.TTY.Config = switch (fmt.color) {3825 const ttyconf: std.debug.TTY.Config = switch (fmt.color) {
3826 .auto => std.debug.detectTTYConfig(),3826 .auto => std.debug.detectTTYConfig(),
3827 .on => .escape_codes,3827 .on => .escape_codes,
...@@ -3858,8 +3858,8 @@ fn fmtPathFile(...@@ -3858,8 +3858,8 @@ fn fmtPathFile(
3858}3858}
38593859
3860fn printErrMsgToStdErr(3860fn printErrMsgToStdErr(
3861 gpa: *mem.Allocator,3861 gpa: mem.Allocator,
3862 arena: *mem.Allocator,3862 arena: mem.Allocator,
3863 parse_error: Ast.Error,3863 parse_error: Ast.Error,
3864 tree: Ast,3864 tree: Ast,
3865 path: []const u8,3865 path: []const u8,
...@@ -3941,7 +3941,7 @@ extern "c" fn ZigClang_main(argc: c_int, argv: [*:null]?[*:0]u8) c_int;...@@ -3941,7 +3941,7 @@ extern "c" fn ZigClang_main(argc: c_int, argv: [*:null]?[*:0]u8) c_int;
3941extern "c" fn ZigLlvmAr_main(argc: c_int, argv: [*:null]?[*:0]u8) c_int;3941extern "c" fn ZigLlvmAr_main(argc: c_int, argv: [*:null]?[*:0]u8) c_int;
39423942
3943/// TODO https://github.com/ziglang/zig/issues/32573943/// TODO https://github.com/ziglang/zig/issues/3257
3944fn punt_to_clang(arena: *Allocator, args: []const []const u8) error{OutOfMemory} {3944fn punt_to_clang(arena: Allocator, args: []const []const u8) error{OutOfMemory} {
3945 if (!build_options.have_llvm)3945 if (!build_options.have_llvm)
3946 fatal("`zig cc` and `zig c++` unavailable: compiler built without LLVM extensions", .{});3946 fatal("`zig cc` and `zig c++` unavailable: compiler built without LLVM extensions", .{});
3947 // Convert the args to the format Clang expects.3947 // Convert the args to the format Clang expects.
...@@ -3955,7 +3955,7 @@ fn punt_to_clang(arena: *Allocator, args: []const []const u8) error{OutOfMemory}...@@ -3955,7 +3955,7 @@ fn punt_to_clang(arena: *Allocator, args: []const []const u8) error{OutOfMemory}
3955}3955}
39563956
3957/// TODO https://github.com/ziglang/zig/issues/32573957/// TODO https://github.com/ziglang/zig/issues/3257
3958fn punt_to_llvm_ar(arena: *Allocator, args: []const []const u8) error{OutOfMemory} {3958fn punt_to_llvm_ar(arena: Allocator, args: []const []const u8) error{OutOfMemory} {
3959 if (!build_options.have_llvm)3959 if (!build_options.have_llvm)
3960 fatal("`zig ar`, `zig dlltool`, `zig ranlib', and `zig lib` unavailable: compiler built without LLVM extensions", .{});3960 fatal("`zig ar`, `zig dlltool`, `zig ranlib', and `zig lib` unavailable: compiler built without LLVM extensions", .{});
39613961
...@@ -3976,7 +3976,7 @@ fn punt_to_llvm_ar(arena: *Allocator, args: []const []const u8) error{OutOfMemor...@@ -3976,7 +3976,7 @@ fn punt_to_llvm_ar(arena: *Allocator, args: []const []const u8) error{OutOfMemor
3976/// * `lld-link` - COFF3976/// * `lld-link` - COFF
3977/// * `wasm-ld` - WebAssembly3977/// * `wasm-ld` - WebAssembly
3978/// TODO https://github.com/ziglang/zig/issues/32573978/// TODO https://github.com/ziglang/zig/issues/3257
3979pub fn punt_to_lld(arena: *Allocator, args: []const []const u8) error{OutOfMemory} {3979pub fn punt_to_lld(arena: Allocator, args: []const []const u8) error{OutOfMemory} {
3980 if (!build_options.have_llvm)3980 if (!build_options.have_llvm)
3981 fatal("`zig {s}` unavailable: compiler built without LLVM extensions", .{args[0]});3981 fatal("`zig {s}` unavailable: compiler built without LLVM extensions", .{args[0]});
3982 // Convert the args to the format LLD expects.3982 // Convert the args to the format LLD expects.
...@@ -4012,7 +4012,7 @@ pub const ClangArgIterator = struct {...@@ -4012,7 +4012,7 @@ pub const ClangArgIterator = struct {
4012 argv: []const []const u8,4012 argv: []const []const u8,
4013 next_index: usize,4013 next_index: usize,
4014 root_args: ?*Args,4014 root_args: ?*Args,
4015 allocator: *Allocator,4015 allocator: Allocator,
40164016
4017 pub const ZigEquivalent = enum {4017 pub const ZigEquivalent = enum {
4018 target,4018 target,
...@@ -4072,7 +4072,7 @@ pub const ClangArgIterator = struct {...@@ -4072,7 +4072,7 @@ pub const ClangArgIterator = struct {
4072 argv: []const []const u8,4072 argv: []const []const u8,
4073 };4073 };
40744074
4075 fn init(allocator: *Allocator, argv: []const []const u8) ClangArgIterator {4075 fn init(allocator: Allocator, argv: []const []const u8) ClangArgIterator {
4076 return .{4076 return .{
4077 .next_index = 2, // `zig cc foo` this points to `foo`4077 .next_index = 2, // `zig cc foo` this points to `foo`
4078 .has_next = argv.len > 2,4078 .has_next = argv.len > 2,
...@@ -4311,7 +4311,7 @@ test "fds" {...@@ -4311,7 +4311,7 @@ test "fds" {
4311 gimmeMoreOfThoseSweetSweetFileDescriptors();4311 gimmeMoreOfThoseSweetSweetFileDescriptors();
4312}4312}
43134313
4314fn detectNativeTargetInfo(gpa: *Allocator, cross_target: std.zig.CrossTarget) !std.zig.system.NativeTargetInfo {4314fn detectNativeTargetInfo(gpa: Allocator, cross_target: std.zig.CrossTarget) !std.zig.system.NativeTargetInfo {
4315 return std.zig.system.NativeTargetInfo.detect(gpa, cross_target);4315 return std.zig.system.NativeTargetInfo.detect(gpa, cross_target);
4316}4316}
43174317
...@@ -4346,8 +4346,8 @@ const usage_ast_check =...@@ -4346,8 +4346,8 @@ const usage_ast_check =
4346;4346;
43474347
4348pub fn cmdAstCheck(4348pub fn cmdAstCheck(
4349 gpa: *Allocator,4349 gpa: Allocator,
4350 arena: *Allocator,4350 arena: Allocator,
4351 args: []const []const u8,4351 args: []const []const u8,
4352) !void {4352) !void {
4353 const Module = @import("Module.zig");4353 const Module = @import("Module.zig");
...@@ -4516,8 +4516,8 @@ pub fn cmdAstCheck(...@@ -4516,8 +4516,8 @@ pub fn cmdAstCheck(
45164516
4517/// This is only enabled for debug builds.4517/// This is only enabled for debug builds.
4518pub fn cmdChangelist(4518pub fn cmdChangelist(
4519 gpa: *Allocator,4519 gpa: Allocator,
4520 arena: *Allocator,4520 arena: Allocator,
4521 args: []const []const u8,4521 args: []const []const u8,
4522) !void {4522) !void {
4523 const Module = @import("Module.zig");4523 const Module = @import("Module.zig");
src/mingw.zig+4-4
...@@ -25,7 +25,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {...@@ -25,7 +25,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
25 }25 }
26 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);26 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
27 defer arena_allocator.deinit();27 defer arena_allocator.deinit();
28 const arena = &arena_allocator.allocator;28 const arena = arena_allocator.allocator();
2929
30 switch (crt_file) {30 switch (crt_file) {
31 .crt2_o => {31 .crt2_o => {
...@@ -252,7 +252,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {...@@ -252,7 +252,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
252252
253fn add_cc_args(253fn add_cc_args(
254 comp: *Compilation,254 comp: *Compilation,
255 arena: *Allocator,255 arena: Allocator,
256 args: *std.ArrayList([]const u8),256 args: *std.ArrayList([]const u8),
257) error{OutOfMemory}!void {257) error{OutOfMemory}!void {
258 try args.appendSlice(&[_][]const u8{258 try args.appendSlice(&[_][]const u8{
...@@ -281,7 +281,7 @@ fn add_cc_args(...@@ -281,7 +281,7 @@ fn add_cc_args(
281pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {281pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
282 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);282 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
283 defer arena_allocator.deinit();283 defer arena_allocator.deinit();
284 const arena = &arena_allocator.allocator;284 const arena = arena_allocator.allocator();
285285
286 const def_file_path = findDef(comp, arena, lib_name) catch |err| switch (err) {286 const def_file_path = findDef(comp, arena, lib_name) catch |err| switch (err) {
287 error.FileNotFound => {287 error.FileNotFound => {
...@@ -428,7 +428,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {...@@ -428,7 +428,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
428}428}
429429
430/// This function body is verbose but all it does is test 3 different paths and see if a .def file exists.430/// This function body is verbose but all it does is test 3 different paths and see if a .def file exists.
431fn findDef(comp: *Compilation, allocator: *Allocator, lib_name: []const u8) ![]u8 {431fn findDef(comp: *Compilation, allocator: Allocator, lib_name: []const u8) ![]u8 {
432 const target = comp.getTarget();432 const target = comp.getTarget();
433433
434 const lib_path = switch (target.cpu.arch) {434 const lib_path = switch (target.cpu.arch) {
src/musl.zig+4-4
...@@ -25,7 +25,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {...@@ -25,7 +25,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
25 const gpa = comp.gpa;25 const gpa = comp.gpa;
26 var arena_allocator = std.heap.ArenaAllocator.init(gpa);26 var arena_allocator = std.heap.ArenaAllocator.init(gpa);
27 defer arena_allocator.deinit();27 defer arena_allocator.deinit();
28 const arena = &arena_allocator.allocator;28 const arena = arena_allocator.allocator();
2929
30 switch (crt_file) {30 switch (crt_file) {
31 .crti_o => {31 .crti_o => {
...@@ -310,7 +310,7 @@ const Ext = enum {...@@ -310,7 +310,7 @@ const Ext = enum {
310 o3,310 o3,
311};311};
312312
313fn addSrcFile(arena: *Allocator, source_table: *std.StringArrayHashMap(Ext), file_path: []const u8) !void {313fn addSrcFile(arena: Allocator, source_table: *std.StringArrayHashMap(Ext), file_path: []const u8) !void {
314 const ext: Ext = ext: {314 const ext: Ext = ext: {
315 if (mem.endsWith(u8, file_path, ".c")) {315 if (mem.endsWith(u8, file_path, ".c")) {
316 if (mem.startsWith(u8, file_path, "musl/src/malloc/") or316 if (mem.startsWith(u8, file_path, "musl/src/malloc/") or
...@@ -344,7 +344,7 @@ fn addSrcFile(arena: *Allocator, source_table: *std.StringArrayHashMap(Ext), fil...@@ -344,7 +344,7 @@ fn addSrcFile(arena: *Allocator, source_table: *std.StringArrayHashMap(Ext), fil
344344
345fn addCcArgs(345fn addCcArgs(
346 comp: *Compilation,346 comp: *Compilation,
347 arena: *Allocator,347 arena: Allocator,
348 args: *std.ArrayList([]const u8),348 args: *std.ArrayList([]const u8),
349 want_O3: bool,349 want_O3: bool,
350) error{OutOfMemory}!void {350) error{OutOfMemory}!void {
...@@ -394,7 +394,7 @@ fn addCcArgs(...@@ -394,7 +394,7 @@ fn addCcArgs(
394 });394 });
395}395}
396396
397fn start_asm_path(comp: *Compilation, arena: *Allocator, basename: []const u8) ![]const u8 {397fn start_asm_path(comp: *Compilation, arena: Allocator, basename: []const u8) ![]const u8 {
398 const target = comp.getTarget();398 const target = comp.getTarget();
399 return comp.zig_lib_directory.join(arena, &[_][]const u8{399 return comp.zig_lib_directory.join(arena, &[_][]const u8{
400 "libc", "musl", "crt", archName(target.cpu.arch), basename,400 "libc", "musl", "crt", archName(target.cpu.arch), basename,
src/print_air.zig+4-4
...@@ -8,7 +8,7 @@ const Zir = @import("Zir.zig");...@@ -8,7 +8,7 @@ const Zir = @import("Zir.zig");
8const Air = @import("Air.zig");8const Air = @import("Air.zig");
9const Liveness = @import("Liveness.zig");9const Liveness = @import("Liveness.zig");
1010
11pub fn dump(gpa: *Allocator, air: Air, zir: Zir, liveness: Liveness) void {11pub fn dump(gpa: Allocator, air: Air, zir: Zir, liveness: Liveness) void {
12 const instruction_bytes = air.instructions.len *12 const instruction_bytes = air.instructions.len *
13 // Here we don't use @sizeOf(Air.Inst.Data) because it would include13 // Here we don't use @sizeOf(Air.Inst.Data) because it would include
14 // the debug safety tag but we want to measure release size.14 // the debug safety tag but we want to measure release size.
...@@ -47,7 +47,7 @@ pub fn dump(gpa: *Allocator, air: Air, zir: Zir, liveness: Liveness) void {...@@ -47,7 +47,7 @@ pub fn dump(gpa: *Allocator, air: Air, zir: Zir, liveness: Liveness) void {
4747
48 var writer: Writer = .{48 var writer: Writer = .{
49 .gpa = gpa,49 .gpa = gpa,
50 .arena = &arena.allocator,50 .arena = arena.allocator(),
51 .air = air,51 .air = air,
52 .zir = zir,52 .zir = zir,
53 .liveness = liveness,53 .liveness = liveness,
...@@ -60,8 +60,8 @@ pub fn dump(gpa: *Allocator, air: Air, zir: Zir, liveness: Liveness) void {...@@ -60,8 +60,8 @@ pub fn dump(gpa: *Allocator, air: Air, zir: Zir, liveness: Liveness) void {
60}60}
6161
62const Writer = struct {62const Writer = struct {
63 gpa: *Allocator,63 gpa: Allocator,
64 arena: *Allocator,64 arena: Allocator,
65 air: Air,65 air: Air,
66 zir: Zir,66 zir: Zir,
67 liveness: Liveness,67 liveness: Liveness,
src/print_env.zig+1-1
...@@ -4,7 +4,7 @@ const introspect = @import("introspect.zig");...@@ -4,7 +4,7 @@ const introspect = @import("introspect.zig");
4const Allocator = std.mem.Allocator;4const Allocator = std.mem.Allocator;
5const fatal = @import("main.zig").fatal;5const fatal = @import("main.zig").fatal;
66
7pub fn cmdEnv(gpa: *Allocator, args: []const []const u8, stdout: std.fs.File.Writer) !void {7pub fn cmdEnv(gpa: Allocator, args: []const []const u8, stdout: std.fs.File.Writer) !void {
8 _ = args;8 _ = args;
9 const self_exe_path = try std.fs.selfExePathAlloc(gpa);9 const self_exe_path = try std.fs.selfExePathAlloc(gpa);
10 defer gpa.free(self_exe_path);10 defer gpa.free(self_exe_path);
src/print_targets.zig+1-1
...@@ -11,7 +11,7 @@ const introspect = @import("introspect.zig");...@@ -11,7 +11,7 @@ const introspect = @import("introspect.zig");
11const fatal = @import("main.zig").fatal;11const fatal = @import("main.zig").fatal;
1212
13pub fn cmdTargets(13pub fn cmdTargets(
14 allocator: *Allocator,14 allocator: Allocator,
15 args: []const []const u8,15 args: []const []const u8,
16 /// Output stream16 /// Output stream
17 stdout: anytype,17 stdout: anytype,
src/print_zir.zig+8-8
...@@ -10,7 +10,7 @@ const LazySrcLoc = Module.LazySrcLoc;...@@ -10,7 +10,7 @@ const LazySrcLoc = Module.LazySrcLoc;
1010
11/// Write human-readable, debug formatted ZIR code to a file.11/// Write human-readable, debug formatted ZIR code to a file.
12pub fn renderAsTextToFile(12pub fn renderAsTextToFile(
13 gpa: *Allocator,13 gpa: Allocator,
14 scope_file: *Module.File,14 scope_file: *Module.File,
15 fs_file: std.fs.File,15 fs_file: std.fs.File,
16) !void {16) !void {
...@@ -19,7 +19,7 @@ pub fn renderAsTextToFile(...@@ -19,7 +19,7 @@ pub fn renderAsTextToFile(
1919
20 var writer: Writer = .{20 var writer: Writer = .{
21 .gpa = gpa,21 .gpa = gpa,
22 .arena = &arena.allocator,22 .arena = arena.allocator(),
23 .file = scope_file,23 .file = scope_file,
24 .code = scope_file.zir,24 .code = scope_file.zir,
25 .indent = 0,25 .indent = 0,
...@@ -61,7 +61,7 @@ pub fn renderAsTextToFile(...@@ -61,7 +61,7 @@ pub fn renderAsTextToFile(
61}61}
6262
63pub fn renderInstructionContext(63pub fn renderInstructionContext(
64 gpa: *Allocator,64 gpa: Allocator,
65 block: []const Zir.Inst.Index,65 block: []const Zir.Inst.Index,
66 block_index: usize,66 block_index: usize,
67 scope_file: *Module.File,67 scope_file: *Module.File,
...@@ -74,7 +74,7 @@ pub fn renderInstructionContext(...@@ -74,7 +74,7 @@ pub fn renderInstructionContext(
7474
75 var writer: Writer = .{75 var writer: Writer = .{
76 .gpa = gpa,76 .gpa = gpa,
77 .arena = &arena.allocator,77 .arena = arena.allocator(),
78 .file = scope_file,78 .file = scope_file,
79 .code = scope_file.zir,79 .code = scope_file.zir,
80 .indent = if (indent < 2) 2 else indent,80 .indent = if (indent < 2) 2 else indent,
...@@ -94,7 +94,7 @@ pub fn renderInstructionContext(...@@ -94,7 +94,7 @@ pub fn renderInstructionContext(
94}94}
9595
96pub fn renderSingleInstruction(96pub fn renderSingleInstruction(
97 gpa: *Allocator,97 gpa: Allocator,
98 inst: Zir.Inst.Index,98 inst: Zir.Inst.Index,
99 scope_file: *Module.File,99 scope_file: *Module.File,
100 parent_decl_node: Ast.Node.Index,100 parent_decl_node: Ast.Node.Index,
...@@ -106,7 +106,7 @@ pub fn renderSingleInstruction(...@@ -106,7 +106,7 @@ pub fn renderSingleInstruction(
106106
107 var writer: Writer = .{107 var writer: Writer = .{
108 .gpa = gpa,108 .gpa = gpa,
109 .arena = &arena.allocator,109 .arena = arena.allocator(),
110 .file = scope_file,110 .file = scope_file,
111 .code = scope_file.zir,111 .code = scope_file.zir,
112 .indent = indent,112 .indent = indent,
...@@ -120,8 +120,8 @@ pub fn renderSingleInstruction(...@@ -120,8 +120,8 @@ pub fn renderSingleInstruction(
120}120}
121121
122const Writer = struct {122const Writer = struct {
123 gpa: *Allocator,123 gpa: Allocator,
124 arena: *Allocator,124 arena: Allocator,
125 file: *Module.File,125 file: *Module.File,
126 code: Zir,126 code: Zir,
127 indent: u32,127 indent: u32,
src/register_manager.zig+1-1
...@@ -254,7 +254,7 @@ const MockRegister2 = enum(u2) {...@@ -254,7 +254,7 @@ const MockRegister2 = enum(u2) {
254254
255fn MockFunction(comptime Register: type) type {255fn MockFunction(comptime Register: type) type {
256 return struct {256 return struct {
257 allocator: *Allocator,257 allocator: Allocator,
258 register_manager: RegisterManager(Self, Register, &Register.callee_preserved_regs) = .{},258 register_manager: RegisterManager(Self, Register, &Register.callee_preserved_regs) = .{},
259 spilled: std.ArrayListUnmanaged(Register) = .{},259 spilled: std.ArrayListUnmanaged(Register) = .{},
260260
src/stage1.zig+1-1
...@@ -38,7 +38,7 @@ pub fn main(argc: c_int, argv: [*][*:0]u8) callconv(.C) c_int {...@@ -38,7 +38,7 @@ pub fn main(argc: c_int, argv: [*][*:0]u8) callconv(.C) c_int {
38 const gpa = std.heap.c_allocator;38 const gpa = std.heap.c_allocator;
39 var arena_instance = std.heap.ArenaAllocator.init(gpa);39 var arena_instance = std.heap.ArenaAllocator.init(gpa);
40 defer arena_instance.deinit();40 defer arena_instance.deinit();
41 const arena = &arena_instance.allocator;41 const arena = arena_instance.allocator();
4242
43 const args = arena.alloc([]const u8, @intCast(usize, argc)) catch fatal("{s}", .{"OutOfMemory"});43 const args = arena.alloc([]const u8, @intCast(usize, argc)) catch fatal("{s}", .{"OutOfMemory"});
44 for (args) |*arg, i| {44 for (args) |*arg, i| {
src/test.zig+2-2
...@@ -680,7 +680,7 @@ pub const TestContext = struct {...@@ -680,7 +680,7 @@ pub const TestContext = struct {
680 }680 }
681681
682 fn runOneCase(682 fn runOneCase(
683 allocator: *Allocator,683 allocator: Allocator,
684 root_node: *std.Progress.Node,684 root_node: *std.Progress.Node,
685 case: Case,685 case: Case,
686 zig_lib_directory: Compilation.Directory,686 zig_lib_directory: Compilation.Directory,
...@@ -692,7 +692,7 @@ pub const TestContext = struct {...@@ -692,7 +692,7 @@ pub const TestContext = struct {
692692
693 var arena_allocator = std.heap.ArenaAllocator.init(allocator);693 var arena_allocator = std.heap.ArenaAllocator.init(allocator);
694 defer arena_allocator.deinit();694 defer arena_allocator.deinit();
695 const arena = &arena_allocator.allocator;695 const arena = arena_allocator.allocator();
696696
697 var tmp = std.testing.tmpDir(.{});697 var tmp = std.testing.tmpDir(.{});
698 defer tmp.cleanup();698 defer tmp.cleanup();
src/tracy.zig+27-26
...@@ -103,29 +103,27 @@ pub inline fn traceNamed(comptime src: std.builtin.SourceLocation, comptime name...@@ -103,29 +103,27 @@ pub inline fn traceNamed(comptime src: std.builtin.SourceLocation, comptime name
103 }103 }
104}104}
105105
106pub fn tracyAllocator(allocator: *std.mem.Allocator) TracyAllocator(null) {106pub fn tracyAllocator(allocator: std.mem.Allocator) TracyAllocator(null) {
107 return TracyAllocator(null).init(allocator);107 return TracyAllocator(null).init(allocator);
108}108}
109109
110pub fn TracyAllocator(comptime name: ?[:0]const u8) type {110pub fn TracyAllocator(comptime name: ?[:0]const u8) type {
111 return struct {111 return struct {
112 allocator: std.mem.Allocator,112 parent_allocator: std.mem.Allocator,
113 parent_allocator: *std.mem.Allocator,
114113
115 const Self = @This();114 const Self = @This();
116115
117 pub fn init(allocator: *std.mem.Allocator) Self {116 pub fn init(parent_allocator: std.mem.Allocator) Self {
118 return .{117 return .{
119 .parent_allocator = allocator,118 .parent_allocator = parent_allocator,
120 .allocator = .{
121 .allocFn = allocFn,
122 .resizeFn = resizeFn,
123 },
124 };119 };
125 }120 }
126121
127 fn allocFn(allocator: *std.mem.Allocator, len: usize, ptr_align: u29, len_align: u29, ret_addr: usize) std.mem.Allocator.Error![]u8 {122 pub fn allocator(self: *Self) std.mem.Allocator {
128 const self = @fieldParentPtr(Self, "allocator", allocator);123 return std.mem.Allocator.init(self, allocFn, resizeFn, freeFn);
124 }
125
126 fn allocFn(self: *Self, len: usize, ptr_align: u29, len_align: u29, ret_addr: usize) std.mem.Allocator.Error![]u8 {
129 const result = self.parent_allocator.allocFn(self.parent_allocator, len, ptr_align, len_align, ret_addr);127 const result = self.parent_allocator.allocFn(self.parent_allocator, len, ptr_align, len_align, ret_addr);
130 if (result) |data| {128 if (result) |data| {
131 if (data.len != 0) {129 if (data.len != 0) {
...@@ -141,9 +139,7 @@ pub fn TracyAllocator(comptime name: ?[:0]const u8) type {...@@ -141,9 +139,7 @@ pub fn TracyAllocator(comptime name: ?[:0]const u8) type {
141 return result;139 return result;
142 }140 }
143141
144 fn resizeFn(allocator: *std.mem.Allocator, buf: []u8, buf_align: u29, new_len: usize, len_align: u29, ret_addr: usize) std.mem.Allocator.Error!usize {142 fn resizeFn(self: *Self, buf: []u8, buf_align: u29, new_len: usize, len_align: u29, ret_addr: usize) std.mem.Allocator.Error!usize {
145 const self = @fieldParentPtr(Self, "allocator", allocator);
146
147 if (self.parent_allocator.resizeFn(self.parent_allocator, buf, buf_align, new_len, len_align, ret_addr)) |resized_len| {143 if (self.parent_allocator.resizeFn(self.parent_allocator, buf, buf_align, new_len, len_align, ret_addr)) |resized_len| {
148 // this condition is to handle free being called on an empty slice that was never even allocated144 // this condition is to handle free being called on an empty slice that was never even allocated
149 // example case: `std.process.getSelfExeSharedLibPaths` can return `&[_][:0]u8{}`145 // example case: `std.process.getSelfExeSharedLibPaths` can return `&[_][:0]u8{}`
...@@ -155,21 +151,26 @@ pub fn TracyAllocator(comptime name: ?[:0]const u8) type {...@@ -155,21 +151,26 @@ pub fn TracyAllocator(comptime name: ?[:0]const u8) type {
155 }151 }
156 }152 }
157153
158 if (resized_len != 0) {154 if (name) |n| {
159 // this was a shrink or a resize155 allocNamed(buf.ptr, resized_len, n);
160 if (name) |n| {156 } else {
161 allocNamed(buf.ptr, resized_len, n);157 alloc(buf.ptr, resized_len);
162 } else {
163 alloc(buf.ptr, resized_len);
164 }
165 }158 }
166159
167 return resized_len;160 return resized_len;
168 } else |err| {161 }
169 // this is not really an error condition, during normal operation the compiler hits this case thousands of times162
170 // due to this emitting messages for it is both slow and causes clutter163 // during normal operation the compiler hits this case thousands of times due to this
171 // messageColor("allocation resize failed", 0xFF0000);164 // emitting messages for it is both slow and causes clutter
172 return err;165 return null;
166 }
167
168 fn freeFn(self: *Self, buf: []u8, buf_align: u29, ret_addr: usize) void {
169 self.parent_allocator.rawFree(buf, buf_align, ret_addr);
170 if (name) |n| {
171 freeNamed(buf.ptr, n);
172 } else {
173 free(buf.ptr);
173 }174 }
174 }175 }
175 };176 };
src/translate_c.zig+15-14
...@@ -305,8 +305,8 @@ const Scope = struct {...@@ -305,8 +305,8 @@ const Scope = struct {
305};305};
306306
307pub const Context = struct {307pub const Context = struct {
308 gpa: *mem.Allocator,308 gpa: mem.Allocator,
309 arena: *mem.Allocator,309 arena: mem.Allocator,
310 source_manager: *clang.SourceManager,310 source_manager: *clang.SourceManager,
311 decl_table: std.AutoArrayHashMapUnmanaged(usize, []const u8) = .{},311 decl_table: std.AutoArrayHashMapUnmanaged(usize, []const u8) = .{},
312 alias_list: AliasList,312 alias_list: AliasList,
...@@ -351,7 +351,7 @@ pub const Context = struct {...@@ -351,7 +351,7 @@ pub const Context = struct {
351};351};
352352
353pub fn translate(353pub fn translate(
354 gpa: *mem.Allocator,354 gpa: mem.Allocator,
355 args_begin: [*]?[*]const u8,355 args_begin: [*]?[*]const u8,
356 args_end: [*]?[*]const u8,356 args_end: [*]?[*]const u8,
357 errors: *[]ClangErrMsg,357 errors: *[]ClangErrMsg,
...@@ -373,13 +373,14 @@ pub fn translate(...@@ -373,13 +373,14 @@ pub fn translate(
373 // from this function.373 // from this function.
374 var arena = std.heap.ArenaAllocator.init(gpa);374 var arena = std.heap.ArenaAllocator.init(gpa);
375 errdefer arena.deinit();375 errdefer arena.deinit();
376 const arena_allocator = arena.allocator();
376377
377 var context = Context{378 var context = Context{
378 .gpa = gpa,379 .gpa = gpa,
379 .arena = &arena.allocator,380 .arena = arena_allocator,
380 .source_manager = ast_unit.getSourceManager(),381 .source_manager = ast_unit.getSourceManager(),
381 .alias_list = AliasList.init(gpa),382 .alias_list = AliasList.init(gpa),
382 .global_scope = try arena.allocator.create(Scope.Root),383 .global_scope = try arena_allocator.create(Scope.Root),
383 .clang_context = ast_unit.getASTContext(),384 .clang_context = ast_unit.getASTContext(),
384 .pattern_list = try PatternList.init(gpa),385 .pattern_list = try PatternList.init(gpa),
385 };386 };
...@@ -1448,7 +1449,7 @@ fn makeShuffleMask(c: *Context, scope: *Scope, expr: *const clang.ShuffleVectorE...@@ -1448,7 +1449,7 @@ fn makeShuffleMask(c: *Context, scope: *Scope, expr: *const clang.ShuffleVectorE
1448}1449}
14491450
1450/// @typeInfo(@TypeOf(vec_node)).Vector.<field>1451/// @typeInfo(@TypeOf(vec_node)).Vector.<field>
1451fn vectorTypeInfo(arena: *mem.Allocator, vec_node: Node, field: []const u8) TransError!Node {1452fn vectorTypeInfo(arena: mem.Allocator, vec_node: Node, field: []const u8) TransError!Node {
1452 const typeof_call = try Tag.typeof.create(arena, vec_node);1453 const typeof_call = try Tag.typeof.create(arena, vec_node);
1453 const typeinfo_call = try Tag.typeinfo.create(arena, typeof_call);1454 const typeinfo_call = try Tag.typeinfo.create(arena, typeof_call);
1454 const vector_type_info = try Tag.field_access.create(arena, .{ .lhs = typeinfo_call, .field_name = "Vector" });1455 const vector_type_info = try Tag.field_access.create(arena, .{ .lhs = typeinfo_call, .field_name = "Vector" });
...@@ -1536,7 +1537,7 @@ fn transOffsetOfExpr(...@@ -1536,7 +1537,7 @@ fn transOffsetOfExpr(
1536/// will become very large positive numbers but that is ok since we only use this in1537/// will become very large positive numbers but that is ok since we only use this in
1537/// pointer arithmetic expressions, where wraparound will ensure we get the correct value.1538/// pointer arithmetic expressions, where wraparound will ensure we get the correct value.
1538/// node -> @bitCast(usize, @intCast(isize, node))1539/// node -> @bitCast(usize, @intCast(isize, node))
1539fn usizeCastForWrappingPtrArithmetic(gpa: *mem.Allocator, node: Node) TransError!Node {1540fn usizeCastForWrappingPtrArithmetic(gpa: mem.Allocator, node: Node) TransError!Node {
1540 const intcast_node = try Tag.int_cast.create(gpa, .{1541 const intcast_node = try Tag.int_cast.create(gpa, .{
1541 .lhs = try Tag.type.create(gpa, "isize"),1542 .lhs = try Tag.type.create(gpa, "isize"),
1542 .rhs = node,1543 .rhs = node,
...@@ -5072,7 +5073,7 @@ const PatternList = struct {...@@ -5072,7 +5073,7 @@ const PatternList = struct {
5072 };5073 };
50735074
5074 /// Assumes that `ms` represents a tokenized function-like macro.5075 /// Assumes that `ms` represents a tokenized function-like macro.
5075 fn buildArgsHash(allocator: *mem.Allocator, ms: MacroSlicer, hash: *ArgsPositionMap) MacroProcessingError!void {5076 fn buildArgsHash(allocator: mem.Allocator, ms: MacroSlicer, hash: *ArgsPositionMap) MacroProcessingError!void {
5076 assert(ms.tokens.len > 2);5077 assert(ms.tokens.len > 2);
5077 assert(ms.tokens[0].id == .Identifier);5078 assert(ms.tokens[0].id == .Identifier);
5078 assert(ms.tokens[1].id == .LParen);5079 assert(ms.tokens[1].id == .LParen);
...@@ -5098,7 +5099,7 @@ const PatternList = struct {...@@ -5098,7 +5099,7 @@ const PatternList = struct {
5098 impl: []const u8,5099 impl: []const u8,
5099 args_hash: ArgsPositionMap,5100 args_hash: ArgsPositionMap,
51005101
5101 fn init(self: *Pattern, allocator: *mem.Allocator, template: [2][]const u8) Error!void {5102 fn init(self: *Pattern, allocator: mem.Allocator, template: [2][]const u8) Error!void {
5102 const source = template[0];5103 const source = template[0];
5103 const impl = template[1];5104 const impl = template[1];
51045105
...@@ -5120,7 +5121,7 @@ const PatternList = struct {...@@ -5120,7 +5121,7 @@ const PatternList = struct {
5120 };5121 };
5121 }5122 }
51225123
5123 fn deinit(self: *Pattern, allocator: *mem.Allocator) void {5124 fn deinit(self: *Pattern, allocator: mem.Allocator) void {
5124 self.args_hash.deinit(allocator);5125 self.args_hash.deinit(allocator);
5125 allocator.free(self.tokens);5126 allocator.free(self.tokens);
5126 }5127 }
...@@ -5171,7 +5172,7 @@ const PatternList = struct {...@@ -5171,7 +5172,7 @@ const PatternList = struct {
5171 }5172 }
5172 };5173 };
51735174
5174 fn init(allocator: *mem.Allocator) Error!PatternList {5175 fn init(allocator: mem.Allocator) Error!PatternList {
5175 const patterns = try allocator.alloc(Pattern, templates.len);5176 const patterns = try allocator.alloc(Pattern, templates.len);
5176 for (templates) |template, i| {5177 for (templates) |template, i| {
5177 try patterns[i].init(allocator, template);5178 try patterns[i].init(allocator, template);
...@@ -5179,12 +5180,12 @@ const PatternList = struct {...@@ -5179,12 +5180,12 @@ const PatternList = struct {
5179 return PatternList{ .patterns = patterns };5180 return PatternList{ .patterns = patterns };
5180 }5181 }
51815182
5182 fn deinit(self: *PatternList, allocator: *mem.Allocator) void {5183 fn deinit(self: *PatternList, allocator: mem.Allocator) void {
5183 for (self.patterns) |*pattern| pattern.deinit(allocator);5184 for (self.patterns) |*pattern| pattern.deinit(allocator);
5184 allocator.free(self.patterns);5185 allocator.free(self.patterns);
5185 }5186 }
51865187
5187 fn match(self: PatternList, allocator: *mem.Allocator, ms: MacroSlicer) Error!?Pattern {5188 fn match(self: PatternList, allocator: mem.Allocator, ms: MacroSlicer) Error!?Pattern {
5188 var args_hash: ArgsPositionMap = .{};5189 var args_hash: ArgsPositionMap = .{};
5189 defer args_hash.deinit(allocator);5190 defer args_hash.deinit(allocator);
51905191
...@@ -5211,7 +5212,7 @@ const MacroSlicer = struct {...@@ -5211,7 +5212,7 @@ const MacroSlicer = struct {
5211test "Macro matching" {5212test "Macro matching" {
5212 const helper = struct {5213 const helper = struct {
5213 const MacroFunctions = @import("std").zig.c_translation.Macros;5214 const MacroFunctions = @import("std").zig.c_translation.Macros;
5214 fn checkMacro(allocator: *mem.Allocator, pattern_list: PatternList, source: []const u8, comptime expected_match: ?[]const u8) !void {5215 fn checkMacro(allocator: mem.Allocator, pattern_list: PatternList, source: []const u8, comptime expected_match: ?[]const u8) !void {
5215 var tok_list = std.ArrayList(CToken).init(allocator);5216 var tok_list = std.ArrayList(CToken).init(allocator);
5216 defer tok_list.deinit();5217 defer tok_list.deinit();
5217 try tokenizeMacro(source, &tok_list);5218 try tokenizeMacro(source, &tok_list);
src/translate_c/ast.zig+3-3
...@@ -378,7 +378,7 @@ pub const Node = extern union {...@@ -378,7 +378,7 @@ pub const Node = extern union {
378 return .{ .tag_if_small_enough = @enumToInt(t) };378 return .{ .tag_if_small_enough = @enumToInt(t) };
379 }379 }
380380
381 pub fn create(comptime t: Tag, ally: *Allocator, data: Data(t)) error{OutOfMemory}!Node {381 pub fn create(comptime t: Tag, ally: Allocator, data: Data(t)) error{OutOfMemory}!Node {
382 const ptr = try ally.create(t.Type());382 const ptr = try ally.create(t.Type());
383 ptr.* = .{383 ptr.* = .{
384 .base = .{ .tag = t },384 .base = .{ .tag = t },
...@@ -717,7 +717,7 @@ pub const Payload = struct {...@@ -717,7 +717,7 @@ pub const Payload = struct {
717717
718/// Converts the nodes into a Zig Ast.718/// Converts the nodes into a Zig Ast.
719/// Caller must free the source slice.719/// Caller must free the source slice.
720pub fn render(gpa: *Allocator, nodes: []const Node) !std.zig.Ast {720pub fn render(gpa: Allocator, nodes: []const Node) !std.zig.Ast {
721 var ctx = Context{721 var ctx = Context{
722 .gpa = gpa,722 .gpa = gpa,
723 .buf = std.ArrayList(u8).init(gpa),723 .buf = std.ArrayList(u8).init(gpa),
...@@ -783,7 +783,7 @@ const TokenIndex = std.zig.Ast.TokenIndex;...@@ -783,7 +783,7 @@ const TokenIndex = std.zig.Ast.TokenIndex;
783const TokenTag = std.zig.Token.Tag;783const TokenTag = std.zig.Token.Tag;
784784
785const Context = struct {785const Context = struct {
786 gpa: *Allocator,786 gpa: Allocator,
787 buf: std.ArrayList(u8) = .{},787 buf: std.ArrayList(u8) = .{},
788 nodes: std.zig.Ast.NodeList = .{},788 nodes: std.zig.Ast.NodeList = .{},
789 extra_data: std.ArrayListUnmanaged(std.zig.Ast.Node.Index) = .{},789 extra_data: std.ArrayListUnmanaged(std.zig.Ast.Node.Index) = .{},
src/type.zig+15-15
...@@ -728,7 +728,7 @@ pub const Type = extern union {...@@ -728,7 +728,7 @@ pub const Type = extern union {
728 }728 }
729 };729 };
730730
731 pub fn copy(self: Type, allocator: *Allocator) error{OutOfMemory}!Type {731 pub fn copy(self: Type, allocator: Allocator) error{OutOfMemory}!Type {
732 if (@enumToInt(self.tag_if_small_enough) < Tag.no_payload_count) {732 if (@enumToInt(self.tag_if_small_enough) < Tag.no_payload_count) {
733 return Type{ .tag_if_small_enough = self.tag_if_small_enough };733 return Type{ .tag_if_small_enough = self.tag_if_small_enough };
734 } else switch (self.ptr_otherwise.tag) {734 } else switch (self.ptr_otherwise.tag) {
...@@ -905,7 +905,7 @@ pub const Type = extern union {...@@ -905,7 +905,7 @@ pub const Type = extern union {
905 }905 }
906 }906 }
907907
908 fn copyPayloadShallow(self: Type, allocator: *Allocator, comptime T: type) error{OutOfMemory}!Type {908 fn copyPayloadShallow(self: Type, allocator: Allocator, comptime T: type) error{OutOfMemory}!Type {
909 const payload = self.cast(T).?;909 const payload = self.cast(T).?;
910 const new_payload = try allocator.create(T);910 const new_payload = try allocator.create(T);
911 new_payload.* = payload.*;911 new_payload.* = payload.*;
...@@ -1198,7 +1198,7 @@ pub const Type = extern union {...@@ -1198,7 +1198,7 @@ pub const Type = extern union {
1198 }1198 }
11991199
1200 /// Returns a name suitable for `@typeName`.1200 /// Returns a name suitable for `@typeName`.
1201 pub fn nameAlloc(ty: Type, arena: *Allocator) Allocator.Error![:0]const u8 {1201 pub fn nameAlloc(ty: Type, arena: Allocator) Allocator.Error![:0]const u8 {
1202 const t = ty.tag();1202 const t = ty.tag();
1203 switch (t) {1203 switch (t) {
1204 .inferred_alloc_const => unreachable,1204 .inferred_alloc_const => unreachable,
...@@ -1421,7 +1421,7 @@ pub const Type = extern union {...@@ -1421,7 +1421,7 @@ pub const Type = extern union {
1421 };1421 };
1422 }1422 }
14231423
1424 pub fn toValue(self: Type, allocator: *Allocator) Allocator.Error!Value {1424 pub fn toValue(self: Type, allocator: Allocator) Allocator.Error!Value {
1425 switch (self.tag()) {1425 switch (self.tag()) {
1426 .u1 => return Value.initTag(.u1_type),1426 .u1 => return Value.initTag(.u1_type),
1427 .u8 => return Value.initTag(.u8_type),1427 .u8 => return Value.initTag(.u8_type),
...@@ -2676,7 +2676,7 @@ pub const Type = extern union {...@@ -2676,7 +2676,7 @@ pub const Type = extern union {
2676 /// For [*]T, returns *T2676 /// For [*]T, returns *T
2677 /// For []T, returns *T2677 /// For []T, returns *T
2678 /// Handles const-ness and address spaces in particular.2678 /// Handles const-ness and address spaces in particular.
2679 pub fn elemPtrType(ptr_ty: Type, arena: *Allocator) !Type {2679 pub fn elemPtrType(ptr_ty: Type, arena: Allocator) !Type {
2680 return try Type.ptr(arena, .{2680 return try Type.ptr(arena, .{
2681 .pointee_type = ptr_ty.elemType2(),2681 .pointee_type = ptr_ty.elemType2(),
2682 .mutable = ptr_ty.ptrIsMutable(),2682 .mutable = ptr_ty.ptrIsMutable(),
...@@ -2731,7 +2731,7 @@ pub const Type = extern union {...@@ -2731,7 +2731,7 @@ pub const Type = extern union {
27312731
2732 /// Asserts that the type is an optional.2732 /// Asserts that the type is an optional.
2733 /// Same as `optionalChild` but allocates the buffer if needed.2733 /// Same as `optionalChild` but allocates the buffer if needed.
2734 pub fn optionalChildAlloc(ty: Type, allocator: *Allocator) !Type {2734 pub fn optionalChildAlloc(ty: Type, allocator: Allocator) !Type {
2735 switch (ty.tag()) {2735 switch (ty.tag()) {
2736 .optional => return ty.castTag(.optional).?.data,2736 .optional => return ty.castTag(.optional).?.data,
2737 .optional_single_mut_pointer => {2737 .optional_single_mut_pointer => {
...@@ -3379,7 +3379,7 @@ pub const Type = extern union {...@@ -3379,7 +3379,7 @@ pub const Type = extern union {
3379 }3379 }
33803380
3381 /// Asserts that self.zigTypeTag() == .Int.3381 /// Asserts that self.zigTypeTag() == .Int.
3382 pub fn minInt(self: Type, arena: *Allocator, target: Target) !Value {3382 pub fn minInt(self: Type, arena: Allocator, target: Target) !Value {
3383 assert(self.zigTypeTag() == .Int);3383 assert(self.zigTypeTag() == .Int);
3384 const info = self.intInfo(target);3384 const info = self.intInfo(target);
33853385
...@@ -3404,7 +3404,7 @@ pub const Type = extern union {...@@ -3404,7 +3404,7 @@ pub const Type = extern union {
3404 }3404 }
34053405
3406 /// Asserts that self.zigTypeTag() == .Int.3406 /// Asserts that self.zigTypeTag() == .Int.
3407 pub fn maxInt(self: Type, arena: *Allocator, target: Target) !Value {3407 pub fn maxInt(self: Type, arena: Allocator, target: Target) !Value {
3408 assert(self.zigTypeTag() == .Int);3408 assert(self.zigTypeTag() == .Int);
3409 const info = self.intInfo(target);3409 const info = self.intInfo(target);
34103410
...@@ -4008,7 +4008,7 @@ pub const Type = extern union {...@@ -4008,7 +4008,7 @@ pub const Type = extern union {
4008 return .{ .tag_if_small_enough = t };4008 return .{ .tag_if_small_enough = t };
4009 }4009 }
40104010
4011 pub fn create(comptime t: Tag, ally: *Allocator, data: Data(t)) error{OutOfMemory}!file_struct.Type {4011 pub fn create(comptime t: Tag, ally: Allocator, data: Data(t)) error{OutOfMemory}!file_struct.Type {
4012 const p = try ally.create(t.Type());4012 const p = try ally.create(t.Type());
4013 p.* = .{4013 p.* = .{
4014 .base = .{ .tag = t },4014 .base = .{ .tag = t },
...@@ -4104,7 +4104,7 @@ pub const Type = extern union {...@@ -4104,7 +4104,7 @@ pub const Type = extern union {
4104 functions: std.AutoHashMapUnmanaged(*Module.Fn, void),4104 functions: std.AutoHashMapUnmanaged(*Module.Fn, void),
4105 is_anyerror: bool,4105 is_anyerror: bool,
41064106
4107 pub fn addErrorSet(self: *Data, gpa: *Allocator, err_set_ty: Type) !void {4107 pub fn addErrorSet(self: *Data, gpa: Allocator, err_set_ty: Type) !void {
4108 switch (err_set_ty.tag()) {4108 switch (err_set_ty.tag()) {
4109 .error_set => {4109 .error_set => {
4110 const names = err_set_ty.castTag(.error_set).?.data.names();4110 const names = err_set_ty.castTag(.error_set).?.data.names();
...@@ -4225,7 +4225,7 @@ pub const Type = extern union {...@@ -4225,7 +4225,7 @@ pub const Type = extern union {
4225 pub const @"type" = initTag(.type);4225 pub const @"type" = initTag(.type);
4226 pub const @"anyerror" = initTag(.anyerror);4226 pub const @"anyerror" = initTag(.anyerror);
42274227
4228 pub fn ptr(arena: *Allocator, d: Payload.Pointer.Data) !Type {4228 pub fn ptr(arena: Allocator, d: Payload.Pointer.Data) !Type {
4229 assert(d.host_size == 0 or d.bit_offset < d.host_size * 8);4229 assert(d.host_size == 0 or d.bit_offset < d.host_size * 8);
42304230
4231 if (d.sentinel != null or d.@"align" != 0 or d.@"addrspace" != .generic or4231 if (d.sentinel != null or d.@"align" != 0 or d.@"addrspace" != .generic or
...@@ -4260,7 +4260,7 @@ pub const Type = extern union {...@@ -4260,7 +4260,7 @@ pub const Type = extern union {
4260 }4260 }
42614261
4262 pub fn array(4262 pub fn array(
4263 arena: *Allocator,4263 arena: Allocator,
4264 len: u64,4264 len: u64,
4265 sent: ?Value,4265 sent: ?Value,
4266 elem_type: Type,4266 elem_type: Type,
...@@ -4289,14 +4289,14 @@ pub const Type = extern union {...@@ -4289,14 +4289,14 @@ pub const Type = extern union {
4289 });4289 });
4290 }4290 }
42914291
4292 pub fn vector(arena: *Allocator, len: u64, elem_type: Type) Allocator.Error!Type {4292 pub fn vector(arena: Allocator, len: u64, elem_type: Type) Allocator.Error!Type {
4293 return Tag.vector.create(arena, .{4293 return Tag.vector.create(arena, .{
4294 .len = len,4294 .len = len,
4295 .elem_type = elem_type,4295 .elem_type = elem_type,
4296 });4296 });
4297 }4297 }
42984298
4299 pub fn optional(arena: *Allocator, child_type: Type) Allocator.Error!Type {4299 pub fn optional(arena: Allocator, child_type: Type) Allocator.Error!Type {
4300 switch (child_type.tag()) {4300 switch (child_type.tag()) {
4301 .single_const_pointer => return Type.Tag.optional_single_const_pointer.create(4301 .single_const_pointer => return Type.Tag.optional_single_const_pointer.create(
4302 arena,4302 arena,
...@@ -4317,7 +4317,7 @@ pub const Type = extern union {...@@ -4317,7 +4317,7 @@ pub const Type = extern union {
4317 return @intCast(u16, base + @boolToInt(upper < max));4317 return @intCast(u16, base + @boolToInt(upper < max));
4318 }4318 }
43194319
4320 pub fn smallestUnsignedInt(arena: *Allocator, max: u64) !Type {4320 pub fn smallestUnsignedInt(arena: Allocator, max: u64) !Type {
4321 const bits = smallestUnsignedBits(max);4321 const bits = smallestUnsignedBits(max);
4322 return switch (bits) {4322 return switch (bits) {
4323 1 => initTag(.u1),4323 1 => initTag(.u1),
src/value.zig+46-46
...@@ -297,7 +297,7 @@ pub const Value = extern union {...@@ -297,7 +297,7 @@ pub const Value = extern union {
297 };297 };
298 }298 }
299299
300 pub fn create(comptime t: Tag, ally: *Allocator, data: Data(t)) error{OutOfMemory}!Value {300 pub fn create(comptime t: Tag, ally: Allocator, data: Data(t)) error{OutOfMemory}!Value {
301 const ptr = try ally.create(t.Type());301 const ptr = try ally.create(t.Type());
302 ptr.* = .{302 ptr.* = .{
303 .base = .{ .tag = t },303 .base = .{ .tag = t },
...@@ -363,7 +363,7 @@ pub const Value = extern union {...@@ -363,7 +363,7 @@ pub const Value = extern union {
363363
364 /// It's intentional that this function is not passed a corresponding Type, so that364 /// It's intentional that this function is not passed a corresponding Type, so that
365 /// a Value can be copied from a Sema to a Decl prior to resolving struct/union field types.365 /// a Value can be copied from a Sema to a Decl prior to resolving struct/union field types.
366 pub fn copy(self: Value, arena: *Allocator) error{OutOfMemory}!Value {366 pub fn copy(self: Value, arena: Allocator) error{OutOfMemory}!Value {
367 if (@enumToInt(self.tag_if_small_enough) < Tag.no_payload_count) {367 if (@enumToInt(self.tag_if_small_enough) < Tag.no_payload_count) {
368 return Value{ .tag_if_small_enough = self.tag_if_small_enough };368 return Value{ .tag_if_small_enough = self.tag_if_small_enough };
369 } else switch (self.ptr_otherwise.tag) {369 } else switch (self.ptr_otherwise.tag) {
...@@ -578,7 +578,7 @@ pub const Value = extern union {...@@ -578,7 +578,7 @@ pub const Value = extern union {
578 }578 }
579 }579 }
580580
581 fn copyPayloadShallow(self: Value, arena: *Allocator, comptime T: type) error{OutOfMemory}!Value {581 fn copyPayloadShallow(self: Value, arena: Allocator, comptime T: type) error{OutOfMemory}!Value {
582 const payload = self.cast(T).?;582 const payload = self.cast(T).?;
583 const new_payload = try arena.create(T);583 const new_payload = try arena.create(T);
584 new_payload.* = payload.*;584 new_payload.* = payload.*;
...@@ -747,7 +747,7 @@ pub const Value = extern union {...@@ -747,7 +747,7 @@ pub const Value = extern union {
747747
748 /// Asserts that the value is representable as an array of bytes.748 /// Asserts that the value is representable as an array of bytes.
749 /// Copies the value into a freshly allocated slice of memory, which is owned by the caller.749 /// Copies the value into a freshly allocated slice of memory, which is owned by the caller.
750 pub fn toAllocatedBytes(val: Value, ty: Type, allocator: *Allocator) ![]u8 {750 pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator) ![]u8 {
751 switch (val.tag()) {751 switch (val.tag()) {
752 .bytes => {752 .bytes => {
753 const bytes = val.castTag(.bytes).?.data;753 const bytes = val.castTag(.bytes).?.data;
...@@ -1035,7 +1035,7 @@ pub const Value = extern union {...@@ -1035,7 +1035,7 @@ pub const Value = extern union {
1035 }1035 }
1036 }1036 }
10371037
1038 pub fn readFromMemory(ty: Type, target: Target, buffer: []const u8, arena: *Allocator) !Value {1038 pub fn readFromMemory(ty: Type, target: Target, buffer: []const u8, arena: Allocator) !Value {
1039 switch (ty.zigTypeTag()) {1039 switch (ty.zigTypeTag()) {
1040 .Int => {1040 .Int => {
1041 const int_info = ty.intInfo(target);1041 const int_info = ty.intInfo(target);
...@@ -1185,7 +1185,7 @@ pub const Value = extern union {...@@ -1185,7 +1185,7 @@ pub const Value = extern union {
1185 }1185 }
1186 }1186 }
11871187
1188 pub fn popCount(val: Value, ty: Type, target: Target, arena: *Allocator) !Value {1188 pub fn popCount(val: Value, ty: Type, target: Target, arena: Allocator) !Value {
1189 assert(!val.isUndef());1189 assert(!val.isUndef());
11901190
1191 const info = ty.intInfo(target);1191 const info = ty.intInfo(target);
...@@ -1273,7 +1273,7 @@ pub const Value = extern union {...@@ -1273,7 +1273,7 @@ pub const Value = extern union {
12731273
1274 /// Converts an integer or a float to a float. May result in a loss of information.1274 /// Converts an integer or a float to a float. May result in a loss of information.
1275 /// Caller can find out by equality checking the result against the operand.1275 /// Caller can find out by equality checking the result against the operand.
1276 pub fn floatCast(self: Value, arena: *Allocator, dest_ty: Type) !Value {1276 pub fn floatCast(self: Value, arena: Allocator, dest_ty: Type) !Value {
1277 switch (dest_ty.tag()) {1277 switch (dest_ty.tag()) {
1278 .f16 => return Value.Tag.float_16.create(arena, self.toFloat(f16)),1278 .f16 => return Value.Tag.float_16.create(arena, self.toFloat(f16)),
1279 .f32 => return Value.Tag.float_32.create(arena, self.toFloat(f32)),1279 .f32 => return Value.Tag.float_32.create(arena, self.toFloat(f32)),
...@@ -1678,7 +1678,7 @@ pub const Value = extern union {...@@ -1678,7 +1678,7 @@ pub const Value = extern union {
16781678
1679 /// Asserts the value is a single-item pointer to an array, or an array,1679 /// Asserts the value is a single-item pointer to an array, or an array,
1680 /// or an unknown-length pointer, and returns the element value at the index.1680 /// or an unknown-length pointer, and returns the element value at the index.
1681 pub fn elemValue(val: Value, arena: *Allocator, index: usize) !Value {1681 pub fn elemValue(val: Value, arena: Allocator, index: usize) !Value {
1682 return elemValueAdvanced(val, index, arena, undefined);1682 return elemValueAdvanced(val, index, arena, undefined);
1683 }1683 }
16841684
...@@ -1691,7 +1691,7 @@ pub const Value = extern union {...@@ -1691,7 +1691,7 @@ pub const Value = extern union {
1691 pub fn elemValueAdvanced(1691 pub fn elemValueAdvanced(
1692 val: Value,1692 val: Value,
1693 index: usize,1693 index: usize,
1694 arena: ?*Allocator,1694 arena: ?Allocator,
1695 buffer: *ElemValueBuffer,1695 buffer: *ElemValueBuffer,
1696 ) error{OutOfMemory}!Value {1696 ) error{OutOfMemory}!Value {
1697 switch (val.tag()) {1697 switch (val.tag()) {
...@@ -1732,7 +1732,7 @@ pub const Value = extern union {...@@ -1732,7 +1732,7 @@ pub const Value = extern union {
1732 }1732 }
1733 }1733 }
17341734
1735 pub fn fieldValue(val: Value, allocator: *Allocator, index: usize) error{OutOfMemory}!Value {1735 pub fn fieldValue(val: Value, allocator: Allocator, index: usize) error{OutOfMemory}!Value {
1736 _ = allocator;1736 _ = allocator;
1737 switch (val.tag()) {1737 switch (val.tag()) {
1738 .@"struct" => {1738 .@"struct" => {
...@@ -1760,7 +1760,7 @@ pub const Value = extern union {...@@ -1760,7 +1760,7 @@ pub const Value = extern union {
1760 }1760 }
17611761
1762 /// Returns a pointer to the element value at the index.1762 /// Returns a pointer to the element value at the index.
1763 pub fn elemPtr(self: Value, allocator: *Allocator, index: usize) !Value {1763 pub fn elemPtr(self: Value, allocator: Allocator, index: usize) !Value {
1764 switch (self.tag()) {1764 switch (self.tag()) {
1765 .elem_ptr => {1765 .elem_ptr => {
1766 const elem_ptr = self.castTag(.elem_ptr).?.data;1766 const elem_ptr = self.castTag(.elem_ptr).?.data;
...@@ -1874,7 +1874,7 @@ pub const Value = extern union {...@@ -1874,7 +1874,7 @@ pub const Value = extern union {
1874 };1874 };
1875 }1875 }
18761876
1877 pub fn intToFloat(val: Value, arena: *Allocator, dest_ty: Type, target: Target) !Value {1877 pub fn intToFloat(val: Value, arena: Allocator, dest_ty: Type, target: Target) !Value {
1878 switch (val.tag()) {1878 switch (val.tag()) {
1879 .undef, .zero, .one => return val,1879 .undef, .zero, .one => return val,
1880 .the_only_possible_value => return Value.initTag(.zero), // for i0, u01880 .the_only_possible_value => return Value.initTag(.zero), // for i0, u0
...@@ -1898,7 +1898,7 @@ pub const Value = extern union {...@@ -1898,7 +1898,7 @@ pub const Value = extern union {
1898 }1898 }
1899 }1899 }
19001900
1901 fn intToFloatInner(x: anytype, arena: *Allocator, dest_ty: Type, target: Target) !Value {1901 fn intToFloatInner(x: anytype, arena: Allocator, dest_ty: Type, target: Target) !Value {
1902 switch (dest_ty.floatBits(target)) {1902 switch (dest_ty.floatBits(target)) {
1903 16 => return Value.Tag.float_16.create(arena, @intToFloat(f16, x)),1903 16 => return Value.Tag.float_16.create(arena, @intToFloat(f16, x)),
1904 32 => return Value.Tag.float_32.create(arena, @intToFloat(f32, x)),1904 32 => return Value.Tag.float_32.create(arena, @intToFloat(f32, x)),
...@@ -1908,7 +1908,7 @@ pub const Value = extern union {...@@ -1908,7 +1908,7 @@ pub const Value = extern union {
1908 }1908 }
1909 }1909 }
19101910
1911 fn floatToValue(float: f128, arena: *Allocator, dest_ty: Type, target: Target) !Value {1911 fn floatToValue(float: f128, arena: Allocator, dest_ty: Type, target: Target) !Value {
1912 switch (dest_ty.floatBits(target)) {1912 switch (dest_ty.floatBits(target)) {
1913 16 => return Value.Tag.float_16.create(arena, @floatCast(f16, float)),1913 16 => return Value.Tag.float_16.create(arena, @floatCast(f16, float)),
1914 32 => return Value.Tag.float_32.create(arena, @floatCast(f32, float)),1914 32 => return Value.Tag.float_32.create(arena, @floatCast(f32, float)),
...@@ -1918,7 +1918,7 @@ pub const Value = extern union {...@@ -1918,7 +1918,7 @@ pub const Value = extern union {
1918 }1918 }
1919 }1919 }
19201920
1921 pub fn floatToInt(val: Value, arena: *Allocator, dest_ty: Type, target: Target) error{ FloatCannotFit, OutOfMemory }!Value {1921 pub fn floatToInt(val: Value, arena: Allocator, dest_ty: Type, target: Target) error{ FloatCannotFit, OutOfMemory }!Value {
1922 const Limb = std.math.big.Limb;1922 const Limb = std.math.big.Limb;
19231923
1924 var value = val.toFloat(f64); // TODO: f128 ?1924 var value = val.toFloat(f64); // TODO: f128 ?
...@@ -1969,7 +1969,7 @@ pub const Value = extern union {...@@ -1969,7 +1969,7 @@ pub const Value = extern union {
1969 lhs: Value,1969 lhs: Value,
1970 rhs: Value,1970 rhs: Value,
1971 ty: Type,1971 ty: Type,
1972 arena: *Allocator,1972 arena: Allocator,
1973 target: Target,1973 target: Target,
1974 ) !Value {1974 ) !Value {
1975 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);1975 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
...@@ -1993,7 +1993,7 @@ pub const Value = extern union {...@@ -1993,7 +1993,7 @@ pub const Value = extern union {
1993 return fromBigInt(arena, result_bigint.toConst());1993 return fromBigInt(arena, result_bigint.toConst());
1994 }1994 }
19951995
1996 fn fromBigInt(arena: *Allocator, big_int: BigIntConst) !Value {1996 fn fromBigInt(arena: Allocator, big_int: BigIntConst) !Value {
1997 if (big_int.positive) {1997 if (big_int.positive) {
1998 if (big_int.to(u64)) |x| {1998 if (big_int.to(u64)) |x| {
1999 return Value.Tag.int_u64.create(arena, x);1999 return Value.Tag.int_u64.create(arena, x);
...@@ -2014,7 +2014,7 @@ pub const Value = extern union {...@@ -2014,7 +2014,7 @@ pub const Value = extern union {
2014 lhs: Value,2014 lhs: Value,
2015 rhs: Value,2015 rhs: Value,
2016 ty: Type,2016 ty: Type,
2017 arena: *Allocator,2017 arena: Allocator,
2018 target: Target,2018 target: Target,
2019 ) !Value {2019 ) !Value {
2020 assert(!lhs.isUndef());2020 assert(!lhs.isUndef());
...@@ -2040,7 +2040,7 @@ pub const Value = extern union {...@@ -2040,7 +2040,7 @@ pub const Value = extern union {
2040 lhs: Value,2040 lhs: Value,
2041 rhs: Value,2041 rhs: Value,
2042 ty: Type,2042 ty: Type,
2043 arena: *Allocator,2043 arena: Allocator,
2044 target: Target,2044 target: Target,
2045 ) !Value {2045 ) !Value {
2046 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);2046 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
...@@ -2069,7 +2069,7 @@ pub const Value = extern union {...@@ -2069,7 +2069,7 @@ pub const Value = extern union {
2069 lhs: Value,2069 lhs: Value,
2070 rhs: Value,2070 rhs: Value,
2071 ty: Type,2071 ty: Type,
2072 arena: *Allocator,2072 arena: Allocator,
2073 target: Target,2073 target: Target,
2074 ) !Value {2074 ) !Value {
2075 assert(!lhs.isUndef());2075 assert(!lhs.isUndef());
...@@ -2095,7 +2095,7 @@ pub const Value = extern union {...@@ -2095,7 +2095,7 @@ pub const Value = extern union {
2095 lhs: Value,2095 lhs: Value,
2096 rhs: Value,2096 rhs: Value,
2097 ty: Type,2097 ty: Type,
2098 arena: *Allocator,2098 arena: Allocator,
2099 target: Target,2099 target: Target,
2100 ) !Value {2100 ) !Value {
2101 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);2101 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
...@@ -2129,7 +2129,7 @@ pub const Value = extern union {...@@ -2129,7 +2129,7 @@ pub const Value = extern union {
2129 lhs: Value,2129 lhs: Value,
2130 rhs: Value,2130 rhs: Value,
2131 ty: Type,2131 ty: Type,
2132 arena: *Allocator,2132 arena: Allocator,
2133 target: Target,2133 target: Target,
2134 ) !Value {2134 ) !Value {
2135 assert(!lhs.isUndef());2135 assert(!lhs.isUndef());
...@@ -2185,7 +2185,7 @@ pub const Value = extern union {...@@ -2185,7 +2185,7 @@ pub const Value = extern union {
2185 }2185 }
21862186
2187 /// operands must be integers; handles undefined.2187 /// operands must be integers; handles undefined.
2188 pub fn bitwiseNot(val: Value, ty: Type, arena: *Allocator, target: Target) !Value {2188 pub fn bitwiseNot(val: Value, ty: Type, arena: Allocator, target: Target) !Value {
2189 if (val.isUndef()) return Value.initTag(.undef);2189 if (val.isUndef()) return Value.initTag(.undef);
21902190
2191 const info = ty.intInfo(target);2191 const info = ty.intInfo(target);
...@@ -2205,7 +2205,7 @@ pub const Value = extern union {...@@ -2205,7 +2205,7 @@ pub const Value = extern union {
2205 }2205 }
22062206
2207 /// operands must be integers; handles undefined. 2207 /// operands must be integers; handles undefined.
2208 pub fn bitwiseAnd(lhs: Value, rhs: Value, arena: *Allocator) !Value {2208 pub fn bitwiseAnd(lhs: Value, rhs: Value, arena: Allocator) !Value {
2209 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);2209 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
22102210
2211 // TODO is this a performance issue? maybe we should try the operation without2211 // TODO is this a performance issue? maybe we should try the operation without
...@@ -2225,7 +2225,7 @@ pub const Value = extern union {...@@ -2225,7 +2225,7 @@ pub const Value = extern union {
2225 }2225 }
22262226
2227 /// operands must be integers; handles undefined. 2227 /// operands must be integers; handles undefined.
2228 pub fn bitwiseNand(lhs: Value, rhs: Value, ty: Type, arena: *Allocator, target: Target) !Value {2228 pub fn bitwiseNand(lhs: Value, rhs: Value, ty: Type, arena: Allocator, target: Target) !Value {
2229 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);2229 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
22302230
2231 const anded = try bitwiseAnd(lhs, rhs, arena);2231 const anded = try bitwiseAnd(lhs, rhs, arena);
...@@ -2239,7 +2239,7 @@ pub const Value = extern union {...@@ -2239,7 +2239,7 @@ pub const Value = extern union {
2239 }2239 }
22402240
2241 /// operands must be integers; handles undefined. 2241 /// operands must be integers; handles undefined.
2242 pub fn bitwiseOr(lhs: Value, rhs: Value, arena: *Allocator) !Value {2242 pub fn bitwiseOr(lhs: Value, rhs: Value, arena: Allocator) !Value {
2243 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);2243 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
22442244
2245 // TODO is this a performance issue? maybe we should try the operation without2245 // TODO is this a performance issue? maybe we should try the operation without
...@@ -2258,7 +2258,7 @@ pub const Value = extern union {...@@ -2258,7 +2258,7 @@ pub const Value = extern union {
2258 }2258 }
22592259
2260 /// operands must be integers; handles undefined. 2260 /// operands must be integers; handles undefined.
2261 pub fn bitwiseXor(lhs: Value, rhs: Value, arena: *Allocator) !Value {2261 pub fn bitwiseXor(lhs: Value, rhs: Value, arena: Allocator) !Value {
2262 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);2262 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
22632263
2264 // TODO is this a performance issue? maybe we should try the operation without2264 // TODO is this a performance issue? maybe we should try the operation without
...@@ -2277,7 +2277,7 @@ pub const Value = extern union {...@@ -2277,7 +2277,7 @@ pub const Value = extern union {
2277 return fromBigInt(arena, result_bigint.toConst());2277 return fromBigInt(arena, result_bigint.toConst());
2278 }2278 }
22792279
2280 pub fn intAdd(lhs: Value, rhs: Value, allocator: *Allocator) !Value {2280 pub fn intAdd(lhs: Value, rhs: Value, allocator: Allocator) !Value {
2281 // TODO is this a performance issue? maybe we should try the operation without2281 // TODO is this a performance issue? maybe we should try the operation without
2282 // resorting to BigInt first.2282 // resorting to BigInt first.
2283 var lhs_space: Value.BigIntSpace = undefined;2283 var lhs_space: Value.BigIntSpace = undefined;
...@@ -2293,7 +2293,7 @@ pub const Value = extern union {...@@ -2293,7 +2293,7 @@ pub const Value = extern union {
2293 return fromBigInt(allocator, result_bigint.toConst());2293 return fromBigInt(allocator, result_bigint.toConst());
2294 }2294 }
22952295
2296 pub fn intSub(lhs: Value, rhs: Value, allocator: *Allocator) !Value {2296 pub fn intSub(lhs: Value, rhs: Value, allocator: Allocator) !Value {
2297 // TODO is this a performance issue? maybe we should try the operation without2297 // TODO is this a performance issue? maybe we should try the operation without
2298 // resorting to BigInt first.2298 // resorting to BigInt first.
2299 var lhs_space: Value.BigIntSpace = undefined;2299 var lhs_space: Value.BigIntSpace = undefined;
...@@ -2309,7 +2309,7 @@ pub const Value = extern union {...@@ -2309,7 +2309,7 @@ pub const Value = extern union {
2309 return fromBigInt(allocator, result_bigint.toConst());2309 return fromBigInt(allocator, result_bigint.toConst());
2310 }2310 }
23112311
2312 pub fn intDiv(lhs: Value, rhs: Value, allocator: *Allocator) !Value {2312 pub fn intDiv(lhs: Value, rhs: Value, allocator: Allocator) !Value {
2313 // TODO is this a performance issue? maybe we should try the operation without2313 // TODO is this a performance issue? maybe we should try the operation without
2314 // resorting to BigInt first.2314 // resorting to BigInt first.
2315 var lhs_space: Value.BigIntSpace = undefined;2315 var lhs_space: Value.BigIntSpace = undefined;
...@@ -2334,7 +2334,7 @@ pub const Value = extern union {...@@ -2334,7 +2334,7 @@ pub const Value = extern union {
2334 return fromBigInt(allocator, result_q.toConst());2334 return fromBigInt(allocator, result_q.toConst());
2335 }2335 }
23362336
2337 pub fn intDivFloor(lhs: Value, rhs: Value, allocator: *Allocator) !Value {2337 pub fn intDivFloor(lhs: Value, rhs: Value, allocator: Allocator) !Value {
2338 // TODO is this a performance issue? maybe we should try the operation without2338 // TODO is this a performance issue? maybe we should try the operation without
2339 // resorting to BigInt first.2339 // resorting to BigInt first.
2340 var lhs_space: Value.BigIntSpace = undefined;2340 var lhs_space: Value.BigIntSpace = undefined;
...@@ -2359,7 +2359,7 @@ pub const Value = extern union {...@@ -2359,7 +2359,7 @@ pub const Value = extern union {
2359 return fromBigInt(allocator, result_q.toConst());2359 return fromBigInt(allocator, result_q.toConst());
2360 }2360 }
23612361
2362 pub fn intRem(lhs: Value, rhs: Value, allocator: *Allocator) !Value {2362 pub fn intRem(lhs: Value, rhs: Value, allocator: Allocator) !Value {
2363 // TODO is this a performance issue? maybe we should try the operation without2363 // TODO is this a performance issue? maybe we should try the operation without
2364 // resorting to BigInt first.2364 // resorting to BigInt first.
2365 var lhs_space: Value.BigIntSpace = undefined;2365 var lhs_space: Value.BigIntSpace = undefined;
...@@ -2386,7 +2386,7 @@ pub const Value = extern union {...@@ -2386,7 +2386,7 @@ pub const Value = extern union {
2386 return fromBigInt(allocator, result_r.toConst());2386 return fromBigInt(allocator, result_r.toConst());
2387 }2387 }
23882388
2389 pub fn intMod(lhs: Value, rhs: Value, allocator: *Allocator) !Value {2389 pub fn intMod(lhs: Value, rhs: Value, allocator: Allocator) !Value {
2390 // TODO is this a performance issue? maybe we should try the operation without2390 // TODO is this a performance issue? maybe we should try the operation without
2391 // resorting to BigInt first.2391 // resorting to BigInt first.
2392 var lhs_space: Value.BigIntSpace = undefined;2392 var lhs_space: Value.BigIntSpace = undefined;
...@@ -2422,21 +2422,21 @@ pub const Value = extern union {...@@ -2422,21 +2422,21 @@ pub const Value = extern union {
2422 };2422 };
2423 }2423 }
24242424
2425 pub fn floatRem(lhs: Value, rhs: Value, allocator: *Allocator) !Value {2425 pub fn floatRem(lhs: Value, rhs: Value, allocator: Allocator) !Value {
2426 _ = lhs;2426 _ = lhs;
2427 _ = rhs;2427 _ = rhs;
2428 _ = allocator;2428 _ = allocator;
2429 @panic("TODO implement Value.floatRem");2429 @panic("TODO implement Value.floatRem");
2430 }2430 }
24312431
2432 pub fn floatMod(lhs: Value, rhs: Value, allocator: *Allocator) !Value {2432 pub fn floatMod(lhs: Value, rhs: Value, allocator: Allocator) !Value {
2433 _ = lhs;2433 _ = lhs;
2434 _ = rhs;2434 _ = rhs;
2435 _ = allocator;2435 _ = allocator;
2436 @panic("TODO implement Value.floatMod");2436 @panic("TODO implement Value.floatMod");
2437 }2437 }
24382438
2439 pub fn intMul(lhs: Value, rhs: Value, allocator: *Allocator) !Value {2439 pub fn intMul(lhs: Value, rhs: Value, allocator: Allocator) !Value {
2440 // TODO is this a performance issue? maybe we should try the operation without2440 // TODO is this a performance issue? maybe we should try the operation without
2441 // resorting to BigInt first.2441 // resorting to BigInt first.
2442 var lhs_space: Value.BigIntSpace = undefined;2442 var lhs_space: Value.BigIntSpace = undefined;
...@@ -2457,7 +2457,7 @@ pub const Value = extern union {...@@ -2457,7 +2457,7 @@ pub const Value = extern union {
2457 return fromBigInt(allocator, result_bigint.toConst());2457 return fromBigInt(allocator, result_bigint.toConst());
2458 }2458 }
24592459
2460 pub fn intTrunc(val: Value, allocator: *Allocator, signedness: std.builtin.Signedness, bits: u16) !Value {2460 pub fn intTrunc(val: Value, allocator: Allocator, signedness: std.builtin.Signedness, bits: u16) !Value {
2461 var val_space: Value.BigIntSpace = undefined;2461 var val_space: Value.BigIntSpace = undefined;
2462 const val_bigint = val.toBigInt(&val_space);2462 const val_bigint = val.toBigInt(&val_space);
24632463
...@@ -2471,7 +2471,7 @@ pub const Value = extern union {...@@ -2471,7 +2471,7 @@ pub const Value = extern union {
2471 return fromBigInt(allocator, result_bigint.toConst());2471 return fromBigInt(allocator, result_bigint.toConst());
2472 }2472 }
24732473
2474 pub fn shl(lhs: Value, rhs: Value, allocator: *Allocator) !Value {2474 pub fn shl(lhs: Value, rhs: Value, allocator: Allocator) !Value {
2475 // TODO is this a performance issue? maybe we should try the operation without2475 // TODO is this a performance issue? maybe we should try the operation without
2476 // resorting to BigInt first.2476 // resorting to BigInt first.
2477 var lhs_space: Value.BigIntSpace = undefined;2477 var lhs_space: Value.BigIntSpace = undefined;
...@@ -2494,7 +2494,7 @@ pub const Value = extern union {...@@ -2494,7 +2494,7 @@ pub const Value = extern union {
2494 lhs: Value,2494 lhs: Value,
2495 rhs: Value,2495 rhs: Value,
2496 ty: Type,2496 ty: Type,
2497 arena: *Allocator,2497 arena: Allocator,
2498 target: Target,2498 target: Target,
2499 ) !Value {2499 ) !Value {
2500 // TODO is this a performance issue? maybe we should try the operation without2500 // TODO is this a performance issue? maybe we should try the operation without
...@@ -2517,7 +2517,7 @@ pub const Value = extern union {...@@ -2517,7 +2517,7 @@ pub const Value = extern union {
2517 return fromBigInt(arena, result_bigint.toConst());2517 return fromBigInt(arena, result_bigint.toConst());
2518 }2518 }
25192519
2520 pub fn shr(lhs: Value, rhs: Value, allocator: *Allocator) !Value {2520 pub fn shr(lhs: Value, rhs: Value, allocator: Allocator) !Value {
2521 // TODO is this a performance issue? maybe we should try the operation without2521 // TODO is this a performance issue? maybe we should try the operation without
2522 // resorting to BigInt first.2522 // resorting to BigInt first.
2523 var lhs_space: Value.BigIntSpace = undefined;2523 var lhs_space: Value.BigIntSpace = undefined;
...@@ -2540,7 +2540,7 @@ pub const Value = extern union {...@@ -2540,7 +2540,7 @@ pub const Value = extern union {
2540 lhs: Value,2540 lhs: Value,
2541 rhs: Value,2541 rhs: Value,
2542 float_type: Type,2542 float_type: Type,
2543 arena: *Allocator,2543 arena: Allocator,
2544 ) !Value {2544 ) !Value {
2545 switch (float_type.tag()) {2545 switch (float_type.tag()) {
2546 .f16 => {2546 .f16 => {
...@@ -2571,7 +2571,7 @@ pub const Value = extern union {...@@ -2571,7 +2571,7 @@ pub const Value = extern union {
2571 lhs: Value,2571 lhs: Value,
2572 rhs: Value,2572 rhs: Value,
2573 float_type: Type,2573 float_type: Type,
2574 arena: *Allocator,2574 arena: Allocator,
2575 ) !Value {2575 ) !Value {
2576 switch (float_type.tag()) {2576 switch (float_type.tag()) {
2577 .f16 => {2577 .f16 => {
...@@ -2602,7 +2602,7 @@ pub const Value = extern union {...@@ -2602,7 +2602,7 @@ pub const Value = extern union {
2602 lhs: Value,2602 lhs: Value,
2603 rhs: Value,2603 rhs: Value,
2604 float_type: Type,2604 float_type: Type,
2605 arena: *Allocator,2605 arena: Allocator,
2606 ) !Value {2606 ) !Value {
2607 switch (float_type.tag()) {2607 switch (float_type.tag()) {
2608 .f16 => {2608 .f16 => {
...@@ -2633,7 +2633,7 @@ pub const Value = extern union {...@@ -2633,7 +2633,7 @@ pub const Value = extern union {
2633 lhs: Value,2633 lhs: Value,
2634 rhs: Value,2634 rhs: Value,
2635 float_type: Type,2635 float_type: Type,
2636 arena: *Allocator,2636 arena: Allocator,
2637 ) !Value {2637 ) !Value {
2638 switch (float_type.tag()) {2638 switch (float_type.tag()) {
2639 .f16 => {2639 .f16 => {
...@@ -2664,7 +2664,7 @@ pub const Value = extern union {...@@ -2664,7 +2664,7 @@ pub const Value = extern union {
2664 lhs: Value,2664 lhs: Value,
2665 rhs: Value,2665 rhs: Value,
2666 float_type: Type,2666 float_type: Type,
2667 arena: *Allocator,2667 arena: Allocator,
2668 ) !Value {2668 ) !Value {
2669 switch (float_type.tag()) {2669 switch (float_type.tag()) {
2670 .f16 => {2670 .f16 => {
...@@ -2695,7 +2695,7 @@ pub const Value = extern union {...@@ -2695,7 +2695,7 @@ pub const Value = extern union {
2695 lhs: Value,2695 lhs: Value,
2696 rhs: Value,2696 rhs: Value,
2697 float_type: Type,2697 float_type: Type,
2698 arena: *Allocator,2698 arena: Allocator,
2699 ) !Value {2699 ) !Value {
2700 switch (float_type.tag()) {2700 switch (float_type.tag()) {
2701 .f16 => {2701 .f16 => {
src/wasi_libc.zig+5-5
...@@ -67,7 +67,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {...@@ -67,7 +67,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
67 const gpa = comp.gpa;67 const gpa = comp.gpa;
68 var arena_allocator = std.heap.ArenaAllocator.init(gpa);68 var arena_allocator = std.heap.ArenaAllocator.init(gpa);
69 defer arena_allocator.deinit();69 defer arena_allocator.deinit();
70 const arena = &arena_allocator.allocator;70 const arena = arena_allocator.allocator();
7171
72 switch (crt_file) {72 switch (crt_file) {
73 .crt1_reactor_o => {73 .crt1_reactor_o => {
...@@ -243,7 +243,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {...@@ -243,7 +243,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
243 }243 }
244}244}
245245
246fn sanitize(arena: *Allocator, file_path: []const u8) ![]const u8 {246fn sanitize(arena: Allocator, file_path: []const u8) ![]const u8 {
247 // TODO do this at comptime on the comptime data rather than at runtime247 // TODO do this at comptime on the comptime data rather than at runtime
248 // probably best to wait until self-hosted is done and our comptime execution248 // probably best to wait until self-hosted is done and our comptime execution
249 // is faster and uses less memory.249 // is faster and uses less memory.
...@@ -261,7 +261,7 @@ fn sanitize(arena: *Allocator, file_path: []const u8) ![]const u8 {...@@ -261,7 +261,7 @@ fn sanitize(arena: *Allocator, file_path: []const u8) ![]const u8 {
261261
262fn addCCArgs(262fn addCCArgs(
263 comp: *Compilation,263 comp: *Compilation,
264 arena: *Allocator,264 arena: Allocator,
265 args: *std.ArrayList([]const u8),265 args: *std.ArrayList([]const u8),
266 want_O3: bool,266 want_O3: bool,
267) error{OutOfMemory}!void {267) error{OutOfMemory}!void {
...@@ -292,7 +292,7 @@ fn addCCArgs(...@@ -292,7 +292,7 @@ fn addCCArgs(
292292
293fn addLibcBottomHalfIncludes(293fn addLibcBottomHalfIncludes(
294 comp: *Compilation,294 comp: *Compilation,
295 arena: *Allocator,295 arena: Allocator,
296 args: *std.ArrayList([]const u8),296 args: *std.ArrayList([]const u8),
297) error{OutOfMemory}!void {297) error{OutOfMemory}!void {
298 try args.appendSlice(&[_][]const u8{298 try args.appendSlice(&[_][]const u8{
...@@ -328,7 +328,7 @@ fn addLibcBottomHalfIncludes(...@@ -328,7 +328,7 @@ fn addLibcBottomHalfIncludes(
328328
329fn addLibcTopHalfIncludes(329fn addLibcTopHalfIncludes(
330 comp: *Compilation,330 comp: *Compilation,
331 arena: *Allocator,331 arena: Allocator,
332 args: *std.ArrayList([]const u8),332 args: *std.ArrayList([]const u8),
333) error{OutOfMemory}!void {333) error{OutOfMemory}!void {
334 try args.appendSlice(&[_][]const u8{334 try args.appendSlice(&[_][]const u8{
test/behavior/async_fn.zig+3-3
...@@ -713,7 +713,7 @@ fn testAsyncAwaitTypicalUsage(...@@ -713,7 +713,7 @@ fn testAsyncAwaitTypicalUsage(
713 }713 }
714714
715 var global_download_frame: anyframe = undefined;715 var global_download_frame: anyframe = undefined;
716 fn fetchUrl(allocator: *std.mem.Allocator, url: []const u8) anyerror![]u8 {716 fn fetchUrl(allocator: std.mem.Allocator, url: []const u8) anyerror![]u8 {
717 _ = url;717 _ = url;
718 const result = try allocator.dupe(u8, "expected download text");718 const result = try allocator.dupe(u8, "expected download text");
719 errdefer allocator.free(result);719 errdefer allocator.free(result);
...@@ -727,7 +727,7 @@ fn testAsyncAwaitTypicalUsage(...@@ -727,7 +727,7 @@ fn testAsyncAwaitTypicalUsage(
727 }727 }
728728
729 var global_file_frame: anyframe = undefined;729 var global_file_frame: anyframe = undefined;
730 fn readFile(allocator: *std.mem.Allocator, filename: []const u8) anyerror![]u8 {730 fn readFile(allocator: std.mem.Allocator, filename: []const u8) anyerror![]u8 {
731 _ = filename;731 _ = filename;
732 const result = try allocator.dupe(u8, "expected file text");732 const result = try allocator.dupe(u8, "expected file text");
733 errdefer allocator.free(result);733 errdefer allocator.free(result);
...@@ -912,7 +912,7 @@ test "recursive async function" {...@@ -912,7 +912,7 @@ test "recursive async function" {
912912
913fn recursiveAsyncFunctionTest(comptime suspending_implementation: bool) type {913fn recursiveAsyncFunctionTest(comptime suspending_implementation: bool) type {
914 return struct {914 return struct {
915 fn fib(allocator: *std.mem.Allocator, x: u32) error{OutOfMemory}!u32 {915 fn fib(allocator: std.mem.Allocator, x: u32) error{OutOfMemory}!u32 {
916 if (x <= 1) return x;916 if (x <= 1) return x;
917917
918 if (suspending_implementation) {918 if (suspending_implementation) {
test/cli.zig+2-2
...@@ -5,7 +5,7 @@ const process = std.process;...@@ -5,7 +5,7 @@ const process = std.process;
5const fs = std.fs;5const fs = std.fs;
6const ChildProcess = std.ChildProcess;6const ChildProcess = std.ChildProcess;
77
8var a: *std.mem.Allocator = undefined;8var a: std.mem.Allocator = undefined;
99
10pub fn main() !void {10pub fn main() !void {
11 var arena = std.heap.ArenaAllocator.init(std.testing.allocator);11 var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
...@@ -16,7 +16,7 @@ pub fn main() !void {...@@ -16,7 +16,7 @@ pub fn main() !void {
16 // skip my own exe name16 // skip my own exe name
17 _ = arg_it.skip();17 _ = arg_it.skip();
1818
19 a = &arena.allocator;19 a = arena.allocator();
2020
21 const zig_exe_rel = try (arg_it.next(a) orelse {21 const zig_exe_rel = try (arg_it.next(a) orelse {
22 std.debug.print("Expected first argument to be path to zig compiler\n", .{});22 std.debug.print("Expected first argument to be path to zig compiler\n", .{});
test/compare_output.zig+4-4
...@@ -491,12 +491,12 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -491,12 +491,12 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
491 \\pub fn main() !void {491 \\pub fn main() !void {
492 \\ var allocator_buf: [10]u8 = undefined;492 \\ var allocator_buf: [10]u8 = undefined;
493 \\ var fixedBufferAllocator = std.mem.validationWrap(std.heap.FixedBufferAllocator.init(&allocator_buf));493 \\ var fixedBufferAllocator = std.mem.validationWrap(std.heap.FixedBufferAllocator.init(&allocator_buf));
494 \\ const allocator = &std.heap.loggingAllocator(&fixedBufferAllocator.allocator).allocator;494 \\ const allocator = std.heap.loggingAllocator(fixedBufferAllocator.allocator()).allocator();
495 \\495 \\
496 \\ var a = try allocator.alloc(u8, 10);496 \\ var a = try allocator.alloc(u8, 10);
497 \\ a = allocator.shrink(a, 5);497 \\ a = allocator.shrink(a, 5);
498 \\ try std.testing.expect(a.len == 5);498 \\ try std.testing.expect(a.len == 5);
499 \\ try std.testing.expectError(error.OutOfMemory, allocator.resize(a, 20));499 \\ try std.testing.expect(allocator.resize(a, 20) == null);
500 \\ allocator.free(a);500 \\ allocator.free(a);
501 \\}501 \\}
502 \\502 \\
...@@ -514,8 +514,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -514,8 +514,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
514 ,514 ,
515 \\debug: alloc - success - len: 10, ptr_align: 1, len_align: 0515 \\debug: alloc - success - len: 10, ptr_align: 1, len_align: 0
516 \\debug: shrink - success - 10 to 5, len_align: 0, buf_align: 1516 \\debug: shrink - success - 10 to 5, len_align: 0, buf_align: 1
517 \\error: expand - failure: OutOfMemory - 5 to 20, len_align: 0, buf_align: 1517 \\error: expand - failure - 5 to 20, len_align: 0, buf_align: 1
518 \\debug: free - success - len: 5518 \\debug: free - len: 5
519 \\519 \\
520 );520 );
521}521}
test/compile_errors.zig+1-1
...@@ -7569,7 +7569,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -7569,7 +7569,7 @@ pub fn addCases(ctx: *TestContext) !void {
7569 \\7569 \\
7570 \\export fn entry() void {7570 \\export fn entry() void {
7571 \\ const a = MdNode.Header {7571 \\ const a = MdNode.Header {
7572 \\ .text = MdText.init(&std.testing.allocator),7572 \\ .text = MdText.init(std.testing.allocator),
7573 \\ .weight = HeaderWeight.H1,7573 \\ .weight = HeaderWeight.H1,
7574 \\ };7574 \\ };
7575 \\ _ = a;7575 \\ _ = a;
test/standalone/brace_expansion/main.zig+1-1
...@@ -16,7 +16,7 @@ const Token = union(enum) {...@@ -16,7 +16,7 @@ const Token = union(enum) {
16};16};
1717
18var gpa = std.heap.GeneralPurposeAllocator(.{}){};18var gpa = std.heap.GeneralPurposeAllocator(.{}){};
19var global_allocator = &gpa.allocator;19var global_allocator = gpa.allocator();
2020
21fn tokenize(input: []const u8) !ArrayList(Token) {21fn tokenize(input: []const u8) !ArrayList(Token) {
22 const State = enum {22 const State = enum {
test/standalone/cat/main.zig+1-1
...@@ -8,7 +8,7 @@ const warn = std.log.warn;...@@ -8,7 +8,7 @@ const warn = std.log.warn;
8pub fn main() !void {8pub fn main() !void {
9 var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator);9 var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator);
10 defer arena_instance.deinit();10 defer arena_instance.deinit();
11 const arena = &arena_instance.allocator;11 const arena = arena_instance.allocator();
1212
13 const args = try process.argsAlloc(arena);13 const args = try process.argsAlloc(arena);
1414
tools/gen_spirv_spec.zig+1-1
...@@ -4,7 +4,7 @@ const g = @import("spirv/grammar.zig");...@@ -4,7 +4,7 @@ const g = @import("spirv/grammar.zig");
4pub fn main() !void {4pub fn main() !void {
5 var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);5 var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
6 defer arena.deinit();6 defer arena.deinit();
7 const allocator = &arena.allocator;7 const allocator = arena.allocator();
88
9 const args = try std.process.argsAlloc(allocator);9 const args = try std.process.argsAlloc(allocator);
10 if (args.len != 2) {10 if (args.len != 2) {
tools/gen_stubs.zig+1-1
...@@ -25,7 +25,7 @@ pub fn main() !void {...@@ -25,7 +25,7 @@ pub fn main() !void {
2525
26 var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);26 var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
27 defer arena.deinit();27 defer arena.deinit();
28 const ally = &arena.allocator;28 const ally = arena.allocator();
2929
30 var symbols = std.ArrayList(Symbol).init(ally);30 var symbols = std.ArrayList(Symbol).init(ally);
31 var sections = std.ArrayList([]const u8).init(ally);31 var sections = std.ArrayList([]const u8).init(ally);
tools/merge_anal_dumps.zig+3-3
...@@ -9,7 +9,7 @@ pub fn main() anyerror!void {...@@ -9,7 +9,7 @@ pub fn main() anyerror!void {
9 var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);9 var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
10 defer arena.deinit();10 defer arena.deinit();
1111
12 const allocator = &arena.allocator;12 const allocator = arena.allocator();
1313
14 const args = try std.process.argsAlloc(allocator);14 const args = try std.process.argsAlloc(allocator);
1515
...@@ -160,7 +160,7 @@ const Dump = struct {...@@ -160,7 +160,7 @@ const Dump = struct {
160 const ErrorMap = std.HashMap(Error, usize, Error.hash, Error.eql, 80);160 const ErrorMap = std.HashMap(Error, usize, Error.hash, Error.eql, 80);
161 const TypeMap = std.HashMap(Type, usize, Type.hash, Type.eql, 80);161 const TypeMap = std.HashMap(Type, usize, Type.hash, Type.eql, 80);
162162
163 fn init(allocator: *mem.Allocator) Dump {163 fn init(allocator: mem.Allocator) Dump {
164 return Dump{164 return Dump{
165 .targets = std.ArrayList([]const u8).init(allocator),165 .targets = std.ArrayList([]const u8).init(allocator),
166 .file_list = std.ArrayList([]const u8).init(allocator),166 .file_list = std.ArrayList([]const u8).init(allocator),
...@@ -434,7 +434,7 @@ const Dump = struct {...@@ -434,7 +434,7 @@ const Dump = struct {
434 try jw.endObject();434 try jw.endObject();
435 }435 }
436436
437 fn a(self: Dump) *mem.Allocator {437 fn a(self: Dump) mem.Allocator {
438 return self.targets.allocator;438 return self.targets.allocator;
439 }439 }
440440
tools/process_headers.zig+1-1
...@@ -284,7 +284,7 @@ const LibCVendor = enum {...@@ -284,7 +284,7 @@ const LibCVendor = enum {
284284
285pub fn main() !void {285pub fn main() !void {
286 var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);286 var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
287 const allocator = &arena.allocator;287 const allocator = arena.allocator();
288 const args = try std.process.argsAlloc(allocator);288 const args = try std.process.argsAlloc(allocator);
289 var search_paths = std.ArrayList([]const u8).init(allocator);289 var search_paths = std.ArrayList([]const u8).init(allocator);
290 var opt_out_dir: ?[]const u8 = null;290 var opt_out_dir: ?[]const u8 = null;
tools/update-license-headers.zig+1-1
...@@ -10,7 +10,7 @@ pub fn main() !void {...@@ -10,7 +10,7 @@ pub fn main() !void {
10 defer root_node.end();10 defer root_node.end();
1111
12 var arena_allocator = std.heap.ArenaAllocator.init(std.heap.page_allocator);12 var arena_allocator = std.heap.ArenaAllocator.init(std.heap.page_allocator);
13 const arena = &arena_allocator.allocator;13 const arena = arena_allocator.allocator();
1414
15 const args = try std.process.argsAlloc(arena);15 const args = try std.process.argsAlloc(arena);
16 const path_to_walk = args[1];16 const path_to_walk = args[1];
tools/update-linux-headers.zig+1-1
...@@ -131,7 +131,7 @@ const PathTable = std.StringHashMap(*TargetToHash);...@@ -131,7 +131,7 @@ const PathTable = std.StringHashMap(*TargetToHash);
131131
132pub fn main() !void {132pub fn main() !void {
133 var arena_state = std.heap.ArenaAllocator.init(std.heap.page_allocator);133 var arena_state = std.heap.ArenaAllocator.init(std.heap.page_allocator);
134 const arena = &arena_state.allocator;134 const arena = arena_state.allocator();
135 const args = try std.process.argsAlloc(arena);135 const args = try std.process.argsAlloc(arena);
136 var search_paths = std.ArrayList([]const u8).init(arena);136 var search_paths = std.ArrayList([]const u8).init(arena);
137 var opt_out_dir: ?[]const u8 = null;137 var opt_out_dir: ?[]const u8 = null;
tools/update_clang_options.zig+1-1
...@@ -450,8 +450,8 @@ const cpu_targets = struct {...@@ -450,8 +450,8 @@ const cpu_targets = struct {
450pub fn main() anyerror!void {450pub fn main() anyerror!void {
451 var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);451 var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
452 defer arena.deinit();452 defer arena.deinit();
453 const allocator = &arena.allocator;
454453
454 const allocator = arena.allocator();
455 const args = try std.process.argsAlloc(allocator);455 const args = try std.process.argsAlloc(allocator);
456456
457 if (args.len <= 1) {457 if (args.len <= 1) {
tools/update_cpu_features.zig+5-5
...@@ -769,7 +769,7 @@ const llvm_targets = [_]LlvmTarget{...@@ -769,7 +769,7 @@ const llvm_targets = [_]LlvmTarget{
769pub fn main() anyerror!void {769pub fn main() anyerror!void {
770 var arena_state = std.heap.ArenaAllocator.init(std.heap.page_allocator);770 var arena_state = std.heap.ArenaAllocator.init(std.heap.page_allocator);
771 defer arena_state.deinit();771 defer arena_state.deinit();
772 const arena = &arena_state.allocator;772 const arena = arena_state.allocator();
773773
774 const args = try std.process.argsAlloc(arena);774 const args = try std.process.argsAlloc(arena);
775 if (args.len <= 1) {775 if (args.len <= 1) {
...@@ -845,7 +845,7 @@ fn processOneTarget(job: Job) anyerror!void {...@@ -845,7 +845,7 @@ fn processOneTarget(job: Job) anyerror!void {
845845
846 var arena_state = std.heap.ArenaAllocator.init(std.heap.page_allocator);846 var arena_state = std.heap.ArenaAllocator.init(std.heap.page_allocator);
847 defer arena_state.deinit();847 defer arena_state.deinit();
848 const arena = &arena_state.allocator;848 const arena = arena_state.allocator();
849849
850 var progress_node = job.root_progress.start(llvm_target.zig_name, 3);850 var progress_node = job.root_progress.start(llvm_target.zig_name, 3);
851 progress_node.activate();851 progress_node.activate();
...@@ -1244,7 +1244,7 @@ fn asciiLessThan(context: void, a: []const u8, b: []const u8) bool {...@@ -1244,7 +1244,7 @@ fn asciiLessThan(context: void, a: []const u8, b: []const u8) bool {
1244 return std.ascii.lessThanIgnoreCase(a, b);1244 return std.ascii.lessThanIgnoreCase(a, b);
1245}1245}
12461246
1247fn llvmNameToZigName(arena: *mem.Allocator, llvm_name: []const u8) ![]const u8 {1247fn llvmNameToZigName(arena: mem.Allocator, llvm_name: []const u8) ![]const u8 {
1248 const duped = try arena.dupe(u8, llvm_name);1248 const duped = try arena.dupe(u8, llvm_name);
1249 for (duped) |*byte| switch (byte.*) {1249 for (duped) |*byte| switch (byte.*) {
1250 '-', '.' => byte.* = '_',1250 '-', '.' => byte.* = '_',
...@@ -1254,7 +1254,7 @@ fn llvmNameToZigName(arena: *mem.Allocator, llvm_name: []const u8) ![]const u8 {...@@ -1254,7 +1254,7 @@ fn llvmNameToZigName(arena: *mem.Allocator, llvm_name: []const u8) ![]const u8 {
1254}1254}
12551255
1256fn llvmNameToZigNameOmit(1256fn llvmNameToZigNameOmit(
1257 arena: *mem.Allocator,1257 arena: mem.Allocator,
1258 llvm_target: LlvmTarget,1258 llvm_target: LlvmTarget,
1259 llvm_name: []const u8,1259 llvm_name: []const u8,
1260) !?[]const u8 {1260) !?[]const u8 {
...@@ -1279,7 +1279,7 @@ fn hasSuperclass(obj: *json.ObjectMap, class_name: []const u8) bool {...@@ -1279,7 +1279,7 @@ fn hasSuperclass(obj: *json.ObjectMap, class_name: []const u8) bool {
1279}1279}
12801280
1281fn pruneFeatures(1281fn pruneFeatures(
1282 arena: *mem.Allocator,1282 arena: mem.Allocator,
1283 features_table: std.StringHashMap(Feature),1283 features_table: std.StringHashMap(Feature),
1284 deps_set: *std.StringHashMap(void),1284 deps_set: *std.StringHashMap(void),
1285) !void {1285) !void {
tools/update_glibc.zig+1-1
...@@ -133,7 +133,7 @@ const Function = struct {...@@ -133,7 +133,7 @@ const Function = struct {
133133
134pub fn main() !void {134pub fn main() !void {
135 var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);135 var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
136 const allocator = &arena.allocator;136 const allocator = arena.allocator();
137 const args = try std.process.argsAlloc(allocator);137 const args = try std.process.argsAlloc(allocator);
138 const in_glibc_dir = args[1]; // path to the unzipped tarball of glibc, e.g. ~/downloads/glibc-2.25138 const in_glibc_dir = args[1]; // path to the unzipped tarball of glibc, e.g. ~/downloads/glibc-2.25
139 const zig_src_dir = args[2]; // path to the source checkout of zig, lib dir, e.g. ~/zig-src/lib139 const zig_src_dir = args[2]; // path to the source checkout of zig, lib dir, e.g. ~/zig-src/lib
tools/update_spirv_features.zig+3-3
...@@ -48,7 +48,7 @@ const Version = struct {...@@ -48,7 +48,7 @@ const Version = struct {
48pub fn main() !void {48pub fn main() !void {
49 var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);49 var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
50 defer arena.deinit();50 defer arena.deinit();
51 const allocator = &arena.allocator;51 const allocator = arena.allocator();
5252
53 const args = try std.process.argsAlloc(allocator);53 const args = try std.process.argsAlloc(allocator);
5454
...@@ -216,7 +216,7 @@ pub fn main() !void {...@@ -216,7 +216,7 @@ pub fn main() !void {
216/// The *.grammar.json in SPIRV-Headers should have most of these as well, but with this we're sure to get only the actually216/// The *.grammar.json in SPIRV-Headers should have most of these as well, but with this we're sure to get only the actually
217/// registered ones.217/// registered ones.
218/// TODO: Unfortunately, neither repository contains a machine-readable list of extension dependencies.218/// TODO: Unfortunately, neither repository contains a machine-readable list of extension dependencies.
219fn gather_extensions(allocator: *Allocator, spirv_registry_root: []const u8) ![]const []const u8 {219fn gather_extensions(allocator: Allocator, spirv_registry_root: []const u8) ![]const []const u8 {
220 const extensions_path = try fs.path.join(allocator, &.{ spirv_registry_root, "extensions" });220 const extensions_path = try fs.path.join(allocator, &.{ spirv_registry_root, "extensions" });
221 var extensions_dir = try fs.cwd().openDir(extensions_path, .{ .iterate = true });221 var extensions_dir = try fs.cwd().openDir(extensions_path, .{ .iterate = true });
222 defer extensions_dir.close();222 defer extensions_dir.close();
...@@ -286,7 +286,7 @@ fn insertVersion(versions: *std.ArrayList(Version), version: ?[]const u8) !void...@@ -286,7 +286,7 @@ fn insertVersion(versions: *std.ArrayList(Version), version: ?[]const u8) !void
286 try versions.append(ver);286 try versions.append(ver);
287}287}
288288
289fn gatherVersions(allocator: *Allocator, registry: g.CoreRegistry) ![]const Version {289fn gatherVersions(allocator: Allocator, registry: g.CoreRegistry) ![]const Version {
290 // Expected number of versions is small290 // Expected number of versions is small
291 var versions = std.ArrayList(Version).init(allocator);291 var versions = std.ArrayList(Version).init(allocator);
292292