Merge pull request #173 from birth-software/delete-zig-allocator

Reduce to min dependency on std.mem.Allocator
This commit is contained in:
David 2024-04-27 11:44:02 -06:00 committed by GitHub
commit 4022cf46da
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 128 additions and 105 deletions

View File

@ -17,7 +17,6 @@ const first_slice = library.first_slice;
const starts_with_slice = library.starts_with_slice; const starts_with_slice = library.starts_with_slice;
const PinnedArray = library.PinnedArray; const PinnedArray = library.PinnedArray;
const PinnedArrayAdvanced = library.PinnedArrayAdvanced; const PinnedArrayAdvanced = library.PinnedArrayAdvanced;
const MyAllocator = library.MyAllocator;
const PinnedHashMap = library.PinnedHashMap; const PinnedHashMap = library.PinnedHashMap;
const span = library.span; const span = library.span;
const format_int = library.format_int; const format_int = library.format_int;
@ -68,18 +67,18 @@ const Optimization = enum {
aggressively_optimize_for_size, aggressively_optimize_for_size,
}; };
pub fn createContext(allocator: Allocator) !*const Context { pub fn createContext() !*const Context {
const context: *Context = try allocator.create(Context); const arena = try Arena.init(4 * 1024 * 1024);
const context = try arena.new(Context);
const self_exe_path = try std.fs.selfExePathAlloc(allocator); const self_exe_absolute_path = try self_exe_path(arena);
const self_exe_dir_path = std.fs.path.dirname(self_exe_path).?; const self_exe_dir_path = std.fs.path.dirname(self_exe_absolute_path).?;
context.* = .{ context.* = .{
.allocator = allocator, .cwd_absolute_path = try realpath(arena, std.fs.cwd(), "."),
.cwd_absolute_path = try realpathAlloc(allocator, "."), .executable_absolute_path = self_exe_absolute_path,
.executable_absolute_path = self_exe_path,
.directory_absolute_path = self_exe_dir_path, .directory_absolute_path = self_exe_dir_path,
.build_directory = try std.fs.cwd().makeOpenPath("nat", .{}), .build_directory = try std.fs.cwd().makeOpenPath("nat", .{}),
.arena = try Arena.init(4 * 1024 * 1024), .arena = arena,
}; };
try context.build_directory.makePath(cache_dir_name); try context.build_directory.makePath(cache_dir_name);
@ -120,9 +119,14 @@ pub fn compileBuildExecutable(context: *const Context, arguments: []const []cons
}); });
try unit.compile(context); try unit.compile(context);
const argv: []const []const u8 = &.{ "nat/build", "-compiler_path", context.executable_absolute_path }; const argv: []const []const u8 = &.{ "nat/build", "-compiler_path", context.executable_absolute_path };
var arena_allocator = std.heap.ArenaAllocator.init(std.heap.page_allocator);
const allocator = arena_allocator.allocator();
const result = try std.ChildProcess.run(.{ const result = try std.ChildProcess.run(.{
.allocator = context.allocator, .allocator = allocator,
.argv = argv, .argv = argv,
}); });
@ -147,8 +151,8 @@ pub fn compileBuildExecutable(context: *const Context, arguments: []const []cons
} }
} }
fn clang_job(arguments: []const []const u8) !void { fn clang_job(arena: *Arena, arguments: []const []const u8) !void {
const exit_code = try clangMain(std.heap.page_allocator, arguments); const exit_code = try clangMain(arena, arguments);
if (exit_code != 0) unreachable; if (exit_code != 0) unreachable;
} }
@ -167,7 +171,7 @@ const MuslContext = struct {
fn init(context: *const Context) !MuslContext { fn init(context: *const Context) !MuslContext {
const home_dir = std.posix.getenv("HOME") orelse unreachable; const home_dir = std.posix.getenv("HOME") orelse unreachable;
return .{ return .{
.global_cache_dir = try std.mem.concat(context.allocator, u8, &.{ home_dir, "/.cache/nat/musl/" }), .global_cache_dir = try context.arena.join(&.{ home_dir, "/.cache/nat/musl/" }),
.arch_include_path = try context.pathFromCompiler(musl_lib_dir_relative_path ++ "arch/x86_64"), .arch_include_path = try context.pathFromCompiler(musl_lib_dir_relative_path ++ "arch/x86_64"),
.arch_generic_include_path = try context.pathFromCompiler(musl_lib_dir_relative_path ++ "arch/generic"), .arch_generic_include_path = try context.pathFromCompiler(musl_lib_dir_relative_path ++ "arch/generic"),
.src_include_path = try context.pathFromCompiler(musl_lib_dir_relative_path ++ "src/include"), .src_include_path = try context.pathFromCompiler(musl_lib_dir_relative_path ++ "src/include"),
@ -189,7 +193,7 @@ const MuslContext = struct {
context.executable_absolute_path, "--no-default-config", "-fno-caret-diagnostics", "-target", "x86_64-unknown-linux-musl", "-std=c99", "-ffreestanding", "-mred-zone", "-fno-omit-frame-pointer", "-fno-stack-protector", "-O2", "-fno-unwind-tables", "-fno-asynchronous-unwind-tables", "-ffunction-sections", "-fdata-sections", "-gdwarf-4", "-gdwarf32", "-Wa,--noexecstack", "-D_XOPEN_SOURCE=700", context.executable_absolute_path, "--no-default-config", "-fno-caret-diagnostics", "-target", "x86_64-unknown-linux-musl", "-std=c99", "-ffreestanding", "-mred-zone", "-fno-omit-frame-pointer", "-fno-stack-protector", "-O2", "-fno-unwind-tables", "-fno-asynchronous-unwind-tables", "-ffunction-sections", "-fdata-sections", "-gdwarf-4", "-gdwarf32", "-Wa,--noexecstack", "-D_XOPEN_SOURCE=700",
"-I", musl.arch_include_path, "-I", musl.arch_generic_include_path, "-I", musl.src_include_path, "-I", musl.src_internal_path, "-I", musl.include_path, "-I", musl.triple_include_path, "-I", musl.generic_include_path, "-c", src_file_path, "-o", target_path, "-I", musl.arch_include_path, "-I", musl.arch_generic_include_path, "-I", musl.src_include_path, "-I", musl.src_internal_path, "-I", musl.include_path, "-I", musl.triple_include_path, "-I", musl.generic_include_path, "-c", src_file_path, "-o", target_path,
}; };
const exit_code = try clangMain(context.allocator, args); const exit_code = try clangMain(context.arena, args);
if (exit_code != 0) unreachable; if (exit_code != 0) unreachable;
} }
}; };
@ -218,15 +222,15 @@ fn compileMusl(context: *const Context) MuslContext {
var ar_args = BoundedArray([]const u8, 4096){}; var ar_args = BoundedArray([]const u8, 4096){};
ar_args.appendAssumeCapacity("ar"); ar_args.appendAssumeCapacity("ar");
ar_args.appendAssumeCapacity("rcs"); ar_args.appendAssumeCapacity("rcs");
ar_args.appendAssumeCapacity(try std.mem.concat(context.allocator, u8, &.{ musl.global_cache_dir, "libc.a" })); ar_args.appendAssumeCapacity(try context.arena.join(&.{ musl.global_cache_dir, "libc.a" }));
for (generic_musl_source_files) |src_file_relative_path| { for (generic_musl_source_files) |src_file_relative_path| {
const basename = std.fs.path.basename(src_file_relative_path); const basename = std.fs.path.basename(src_file_relative_path);
const target = try context.allocator.dupe(u8, basename); const target = try context.arena.duplicate_bytes(basename);
target[target.len - 1] = 'o'; target[target.len - 1] = 'o';
const hash = my_hash(src_file_relative_path); const hash = my_hash(src_file_relative_path);
const hash_string = format_int(&buffer, hash, 16, false); const hash_string = format_int(&buffer, hash, 16, false);
const target_path = try std.mem.concat(context.allocator, u8, &.{ musl.global_cache_dir, hash_string, target }); const target_path = try context.arena.join(&.{ musl.global_cache_dir, hash_string, target });
try musl.compileFileWithClang(context, src_file_relative_path, target_path); try musl.compileFileWithClang(context, src_file_relative_path, target_path);
ar_args.appendAssumeCapacity(target_path); ar_args.appendAssumeCapacity(target_path);
@ -234,41 +238,41 @@ fn compileMusl(context: *const Context) MuslContext {
for (musl_x86_64_source_files) |src_file_relative_path| { for (musl_x86_64_source_files) |src_file_relative_path| {
const basename = std.fs.path.basename(src_file_relative_path); const basename = std.fs.path.basename(src_file_relative_path);
const target = try context.allocator.dupe(u8, basename); const target = try context.arena.duplicate_bytes(u8, basename);
target[target.len - 1] = 'o'; target[target.len - 1] = 'o';
const hash = my_hash(src_file_relative_path); const hash = my_hash(src_file_relative_path);
const hash_string = format_int(&buffer, hash, 16, false); const hash_string = format_int(&buffer, hash, 16, false);
const target_path = try std.mem.concat(context.allocator, u8, &.{ musl.global_cache_dir, hash_string, target }); const target_path = try context.arena.join(&.{ musl.global_cache_dir, hash_string, target });
try musl.compileFileWithClang(context, src_file_relative_path, target_path); try musl.compileFileWithClang(context, src_file_relative_path, target_path);
ar_args.appendAssumeCapacity(target_path); ar_args.appendAssumeCapacity(target_path);
} }
if (try arMain(context.allocator, ar_args.slice()) != 0) { if (try arMain(context.arena, ar_args.slice()) != 0) {
unreachable; unreachable;
} }
const crt1_output_path = try std.mem.concat(context.allocator, u8, &.{ musl.global_cache_dir, "crt1.o" }); const crt1_output_path = try context.arena.join(&.{ musl.global_cache_dir, "crt1.o" });
{ {
const crt_path = try context.pathFromCompiler("lib/libc/musl/crt/crt1.c"); const crt_path = try context.pathFromCompiler("lib/libc/musl/crt/crt1.c");
const args: []const []const u8 = &.{ const args: []const []const u8 = &.{
context.executable_absolute_path, "--no-default-config", "-fno-caret-diagnostics", "-target", "x86_64-unknown-linux-musl", "-std=c99", "-ffreestanding", "-mred-zone", "-fno-omit-frame-pointer", "-fno-stack-protector", "-O2", "-fno-unwind-tables", "-fno-asynchronous-unwind-tables", "-ffunction-sections", "-fdata-sections", "-gdwarf-4", "-gdwarf32", "-Wa,--noexecstack", "-D_XOPEN_SOURCE=700", "-DCRT", context.executable_absolute_path, "--no-default-config", "-fno-caret-diagnostics", "-target", "x86_64-unknown-linux-musl", "-std=c99", "-ffreestanding", "-mred-zone", "-fno-omit-frame-pointer", "-fno-stack-protector", "-O2", "-fno-unwind-tables", "-fno-asynchronous-unwind-tables", "-ffunction-sections", "-fdata-sections", "-gdwarf-4", "-gdwarf32", "-Wa,--noexecstack", "-D_XOPEN_SOURCE=700", "-DCRT",
"-I", musl.arch_include_path, "-I", musl.arch_generic_include_path, "-I", musl.src_include_path, "-I", musl.src_internal_path, "-I", musl.include_path, "-I", musl.triple_include_path, "-I", musl.generic_include_path, "-c", crt_path, "-o", crt1_output_path, "-I", musl.arch_include_path, "-I", musl.arch_generic_include_path, "-I", musl.src_include_path, "-I", musl.src_internal_path, "-I", musl.include_path, "-I", musl.triple_include_path, "-I", musl.generic_include_path, "-c", crt_path, "-o", crt1_output_path,
}; };
const exit_code = try clangMain(context.allocator, args); const exit_code = try clangMain(context.arena, args);
if (exit_code != 0) { if (exit_code != 0) {
unreachable; unreachable;
} }
} }
const crti_output_path = try std.mem.concat(context.allocator, u8, &.{ musl.global_cache_dir, "crti.o" }); const crti_output_path = try context.arena.join(&.{ musl.global_cache_dir, "crti.o" });
{ {
const crt_path = try context.pathFromCompiler("lib/libc/musl/crt/crti.c"); const crt_path = try context.pathFromCompiler("lib/libc/musl/crt/crti.c");
const args: []const []const u8 = &.{ const args: []const []const u8 = &.{
context.executable_absolute_path, "--no-default-config", "-fno-caret-diagnostics", "-target", "x86_64-unknown-linux-musl", "-std=c99", "-ffreestanding", "-mred-zone", "-fno-omit-frame-pointer", "-fno-stack-protector", "-O2", "-fno-unwind-tables", "-fno-asynchronous-unwind-tables", "-ffunction-sections", "-fdata-sections", "-gdwarf-4", "-gdwarf32", "-Wa,--noexecstack", "-D_XOPEN_SOURCE=700", "-DCRT", context.executable_absolute_path, "--no-default-config", "-fno-caret-diagnostics", "-target", "x86_64-unknown-linux-musl", "-std=c99", "-ffreestanding", "-mred-zone", "-fno-omit-frame-pointer", "-fno-stack-protector", "-O2", "-fno-unwind-tables", "-fno-asynchronous-unwind-tables", "-ffunction-sections", "-fdata-sections", "-gdwarf-4", "-gdwarf32", "-Wa,--noexecstack", "-D_XOPEN_SOURCE=700", "-DCRT",
"-I", musl.arch_include_path, "-I", musl.arch_generic_include_path, "-I", musl.src_include_path, "-I", musl.src_internal_path, "-I", musl.include_path, "-I", musl.triple_include_path, "-I", musl.generic_include_path, "-c", crt_path, "-o", crti_output_path, "-I", musl.arch_include_path, "-I", musl.arch_generic_include_path, "-I", musl.src_include_path, "-I", musl.src_internal_path, "-I", musl.include_path, "-I", musl.triple_include_path, "-I", musl.generic_include_path, "-c", crt_path, "-o", crti_output_path,
}; };
const exit_code = try clangMain(context.allocator, args); const exit_code = try clangMain(context.arena, args);
if (exit_code != 0) { if (exit_code != 0) {
unreachable; unreachable;
} }
@ -276,12 +280,12 @@ fn compileMusl(context: *const Context) MuslContext {
{ {
const crt_path = try context.pathFromCompiler("lib/libc/musl/crt/x86_64/crtn.s"); const crt_path = try context.pathFromCompiler("lib/libc/musl/crt/x86_64/crtn.s");
const crt_output_path = try std.mem.concat(context.allocator, u8, &.{ musl.global_cache_dir, "crtn.o" }); const crt_output_path = try context.arena.join(&.{ musl.global_cache_dir, "crtn.o" });
const args: []const []const u8 = &.{ const args: []const []const u8 = &.{
context.executable_absolute_path, "--no-default-config", "-fno-caret-diagnostics", "-target", "x86_64-unknown-linux-musl", "-std=c99", "-ffreestanding", "-mred-zone", "-fno-omit-frame-pointer", "-fno-stack-protector", "-O2", "-fno-unwind-tables", "-fno-asynchronous-unwind-tables", "-ffunction-sections", "-fdata-sections", "-gdwarf-4", "-gdwarf32", "-Wa,--noexecstack", "-D_XOPEN_SOURCE=700", context.executable_absolute_path, "--no-default-config", "-fno-caret-diagnostics", "-target", "x86_64-unknown-linux-musl", "-std=c99", "-ffreestanding", "-mred-zone", "-fno-omit-frame-pointer", "-fno-stack-protector", "-O2", "-fno-unwind-tables", "-fno-asynchronous-unwind-tables", "-ffunction-sections", "-fdata-sections", "-gdwarf-4", "-gdwarf32", "-Wa,--noexecstack", "-D_XOPEN_SOURCE=700",
"-I", musl.arch_include_path, "-I", musl.arch_generic_include_path, "-I", musl.src_include_path, "-I", musl.src_internal_path, "-I", musl.include_path, "-I", musl.triple_include_path, "-I", musl.generic_include_path, "-c", crt_path, "-o", crt_output_path, "-I", musl.arch_include_path, "-I", musl.arch_generic_include_path, "-I", musl.src_include_path, "-I", musl.src_internal_path, "-I", musl.include_path, "-I", musl.triple_include_path, "-I", musl.generic_include_path, "-c", crt_path, "-o", crt_output_path,
}; };
const exit_code = try clangMain(context.allocator, args); const exit_code = try clangMain(context.arena, args);
if (exit_code != 0) { if (exit_code != 0) {
unreachable; unreachable;
} }
@ -598,7 +602,7 @@ pub fn compileCSourceFile(context: *const Context, arguments: []const []const u8
const object_path = switch (mode) { const object_path = switch (mode) {
.object => out_path.?, .object => out_path.?,
.link => try std.mem.concat(context.allocator, u8, &.{ if (out_path) |op| op else "a.o", ".o" }), .link => try context.arena.join(&.{ if (out_path) |op| op else "a.o", ".o" }),
}; };
link_objects.appendAssumeCapacity(.{ link_objects.appendAssumeCapacity(.{
@ -753,7 +757,7 @@ pub fn compileCSourceFile(context: *const Context, arguments: []const []const u8
if (debug_clang_args) { if (debug_clang_args) {
std.debug.print("Argv: {s}\n", .{argv.slice()}); std.debug.print("Argv: {s}\n", .{argv.slice()});
} }
const result = try clangMain(context.allocator, argv.slice()); const result = try clangMain(context.arena, argv.slice());
if (result != 0) { if (result != 0) {
unreachable; unreachable;
} }
@ -763,7 +767,7 @@ pub fn compileCSourceFile(context: *const Context, arguments: []const []const u8
argv.appendAssumeCapacity("clang"); argv.appendAssumeCapacity("clang");
argv.appendAssumeCapacity("--no-default-config"); argv.appendAssumeCapacity("--no-default-config");
argv.appendSliceAssumeCapacity(cc_argv.slice()); argv.appendSliceAssumeCapacity(cc_argv.slice());
const result = try clangMain(context.allocator, argv.slice()); const result = try clangMain(context.arena, argv.slice());
if (result != 0) { if (result != 0) {
unreachable; unreachable;
} }
@ -884,13 +888,13 @@ pub fn compileCSourceFile(context: *const Context, arguments: []const []const u8
// try clang_args.appendAssumeCapacity(span(arg)); // try clang_args.appendAssumeCapacity(span(arg));
// } // }
// //
// const result = try clangMain(context.allocator, clang_args.slice()); // const result = try clangMain(context.arena, clang_args.slice());
// if (result != 0) { // if (result != 0) {
// unreachable; // unreachable;
// } // }
// const output_object_file = "nat/main.o"; // const output_object_file = "nat/main.o";
// const exit_code = try clangMain(context.allocator, &.{ context.executable_absolute_path, "--no-default-config", "-target", "x86_64-unknown-linux-musl", "-nostdinc", "-fno-spell-checking", "-isystem", "lib/include", "-isystem", "lib/libc/include/x86_64-linux-musl", "-isystem", "lib/libc/include/generic-musl", "-isystem", "lib/libc/include/x86-linux-any", "-isystem", "lib/libc/include/any-linux-any", "-c", argument, "-o", output_object_file }); // const exit_code = try clangMain(context.arena, &.{ context.executable_absolute_path, "--no-default-config", "-target", "x86_64-unknown-linux-musl", "-nostdinc", "-fno-spell-checking", "-isystem", "lib/include", "-isystem", "lib/libc/include/x86_64-linux-musl", "-isystem", "lib/libc/include/generic-musl", "-isystem", "lib/libc/include/x86-linux-any", "-isystem", "lib/libc/include/any-linux-any", "-c", argument, "-o", output_object_file });
// if (exit_code != 0) { // if (exit_code != 0) {
// unreachable; // unreachable;
// } // }
@ -910,12 +914,12 @@ pub fn compileCSourceFile(context: *const Context, arguments: []const []const u8
// try lld_args.appendAssumeCapacity("-static"); // try lld_args.appendAssumeCapacity("-static");
// try lld_args.appendAssumeCapacity("-o"); // try lld_args.appendAssumeCapacity("-o");
// try lld_args.appendAssumeCapacity("nat/main"); // try lld_args.appendAssumeCapacity("nat/main");
// try lld_args.appendAssumeCapacity(try std.mem.joinZ(context.allocator, "", &.{ musl.global_cache_dir, "crt1.o" })); // try lld_args.appendAssumeCapacity(try std.mem.joinZ(context.arena, "", &.{ musl.global_cache_dir, "crt1.o" }));
// try lld_args.appendAssumeCapacity(try std.mem.joinZ(context.allocator, "", &.{ musl.global_cache_dir, "crti.o" })); // try lld_args.appendAssumeCapacity(try std.mem.joinZ(context.arena, "", &.{ musl.global_cache_dir, "crti.o" }));
// try lld_args.appendAssumeCapacity(output_object_file); // try lld_args.appendAssumeCapacity(output_object_file);
// try lld_args.appendAssumeCapacity("--as-needed"); // try lld_args.appendAssumeCapacity("--as-needed");
// try lld_args.appendAssumeCapacity(try std.mem.joinZ(context.allocator, "", &.{ musl.global_cache_dir, "libc.a" })); // try lld_args.appendAssumeCapacity(try std.mem.joinZ(context.arena, "", &.{ musl.global_cache_dir, "libc.a" }));
// try lld_args.appendAssumeCapacity(try std.mem.joinZ(context.allocator, "", &.{ musl.global_cache_dir, "crtn.o" })); // try lld_args.appendAssumeCapacity(try std.mem.joinZ(context.arena, "", &.{ musl.global_cache_dir, "crtn.o" }));
// //
// var stdout_ptr: [*]const u8 = undefined; // var stdout_ptr: [*]const u8 = undefined;
// var stdout_len: usize = 0; // var stdout_len: usize = 0;
@ -2735,24 +2739,27 @@ const musl_arch_files = [_][]const u8{
musl_lib_dir_relative_path ++ "src/unistd/x32/lseek.c", musl_lib_dir_relative_path ++ "src/unistd/x32/lseek.c",
}; };
pub fn argsCopyZ(alloc: Allocator, args: []const []const u8) ![:null]?[*:0]u8 { pub fn argsCopyZ(arena: *Arena, args: []const []const u8) ![:null]?[*:0]u8 {
var argv = try alloc.allocSentinel(?[*:0]u8, args.len, null); var result = try arena.new_array(?[*:0]u8, args.len + 1);
for (args, 0..) |arg, i| { result[args.len] = null;
argv[i] = try alloc.dupeZ(u8, arg); // TODO If there was an argsAllocZ we could avoid this allocation.
for (args, 0..) |argument, i| {
result[i] = try arena.duplicate_bytes_zero_terminated(argument);
} }
return argv;
return result[0..args.len:null];
} }
extern "c" fn NativityLLVMArchiverMain(argc: c_int, argv: [*:null]?[*:0]u8) c_int; extern "c" fn NativityLLVMArchiverMain(argc: c_int, argv: [*:null]?[*:0]u8) c_int;
fn arMain(allocator: Allocator, arguments: []const []const u8) !u8 { fn arMain(arena: *Arena, arguments: []const []const u8) !u8 {
const argv = try argsCopyZ(allocator, arguments); const argv = try argsCopyZ(arena, arguments);
const exit_code = NativityLLVMArchiverMain(@as(c_int, @intCast(arguments.len)), argv.ptr); const exit_code = NativityLLVMArchiverMain(@as(c_int, @intCast(arguments.len)), argv.ptr);
return @as(u8, @bitCast(@as(i8, @truncate(exit_code)))); return @as(u8, @bitCast(@as(i8, @truncate(exit_code))));
} }
extern "c" fn NativityClangMain(argc: c_int, argv: [*:null]?[*:0]u8) c_int; extern "c" fn NativityClangMain(argc: c_int, argv: [*:null]?[*:0]u8) c_int;
pub fn clangMain(allocator: Allocator, arguments: []const []const u8) !u8 { pub fn clangMain(arena: *Arena, arguments: []const []const u8) !u8 {
const argv = try argsCopyZ(allocator, arguments); const argv = try argsCopyZ(arena, arguments);
const exit_code = NativityClangMain(@as(c_int, @intCast(arguments.len)), argv.ptr); const exit_code = NativityClangMain(@as(c_int, @intCast(arguments.len)), argv.ptr);
return @as(u8, @bitCast(@as(i8, @truncate(exit_code)))); return @as(u8, @bitCast(@as(i8, @truncate(exit_code))));
} }
@ -2958,12 +2965,12 @@ pub fn buildExecutable(context: *const Context, arguments: []const []const u8, o
const executable_path = maybe_executable_path orelse blk: { const executable_path = maybe_executable_path orelse blk: {
assert(executable_name.len > 0); assert(executable_name.len > 0);
const result = try std.mem.concat(context.allocator, u8, &.{ "nat/", executable_name }); const result = try context.arena.join(&.{ "nat/", executable_name });
break :blk result; break :blk result;
}; };
const object_file_path = blk: { const object_file_path = blk: {
const slice = try context.allocator.alloc(u8, executable_path.len + 2); const slice = try context.arena.new_array(u8, executable_path.len + 2);
@memcpy(slice[0..executable_path.len], executable_path); @memcpy(slice[0..executable_path.len], executable_path);
slice[executable_path.len] = '.'; slice[executable_path.len] = '.';
slice[executable_path.len + 1] = 'o'; slice[executable_path.len + 1] = 'o';
@ -3004,7 +3011,7 @@ fn createUnit(context: *const Context, arguments: struct {
is_test: bool, is_test: bool,
c_source_files: []const []const u8, c_source_files: []const []const u8,
}) !*Unit { }) !*Unit {
const unit = try context.allocator.create(Unit); const unit = try context.arena.new(Unit);
unit.* = .{ unit.* = .{
.descriptor = .{ .descriptor = .{
.main_package_path = arguments.main_package_path, .main_package_path = arguments.main_package_path,
@ -3080,10 +3087,17 @@ fn createUnit(context: *const Context, arguments: struct {
return unit; return unit;
} }
fn realpathAlloc(allocator: Allocator, pathname: []const u8) ![]const u8 { pub fn self_exe_path(arena: *Arena) ![]const u8 {
var path_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined; var buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
const realpathInStack = try std.posix.realpath(pathname, &path_buffer); return try arena.duplicate_bytes(try std.fs.selfExePath(&buffer));
return allocator.dupe(u8, realpathInStack); }
pub fn realpath(arena: *Arena, dir: std.fs.Dir, relative_path: []const u8) ![]const u8 {
var buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
const stack_realpath = try dir.realpath(relative_path, &buffer);
const heap_realpath = try arena.new_array(u8, stack_realpath.len);
@memcpy(heap_realpath, stack_realpath);
return heap_realpath;
} }
pub const ContainerType = enum { pub const ContainerType = enum {
@ -4129,7 +4143,6 @@ pub const Struct = struct {
}; };
pub const Context = struct { pub const Context = struct {
allocator: Allocator,
arena: *Arena, arena: *Arena,
cwd_absolute_path: []const u8, cwd_absolute_path: []const u8,
directory_absolute_path: []const u8, directory_absolute_path: []const u8,
@ -4146,7 +4159,7 @@ pub const Context = struct {
}; };
pub fn joinPath(context: *const Context, a: []const u8, b: []const u8) ![]const u8 { pub fn joinPath(context: *const Context, a: []const u8, b: []const u8) ![]const u8 {
return if (a.len != 0 and b.len != 0) try std.mem.concat(context.allocator, u8, &.{ a, "/", b }) else b; return if (a.len != 0 and b.len != 0) try context.arena.join(&.{ a, "/", b }) else b;
} }
pub const PolymorphicFunction = struct { pub const PolymorphicFunction = struct {
@ -4427,8 +4440,8 @@ pub const Debug = struct {
analyzed, analyzed,
}; };
pub fn getPath(file: *File, allocator: Allocator) ![]const u8 { pub fn getPath(file: *File, arena: *Arena) ![]const u8 {
return try std.mem.concat(allocator, u8, &.{ file.package.directory.path, "/", file.relative_path }); return try arena.join(&.{ file.package.directory.path, "/", file.relative_path });
} }
}; };
}; };
@ -5103,7 +5116,7 @@ pub const Builder = struct {
.enum_value => |enum_field_index| { .enum_value => |enum_field_index| {
const enum_field = unit.enum_fields.get(enum_field_index); const enum_field = unit.enum_fields.get(enum_field_index);
const enum_name = unit.getIdentifier(enum_field.name); const enum_name = unit.getIdentifier(enum_field.name);
const enum_name_z = try context.allocator.dupeZ(u8, enum_name); const enum_name_z = try context.arena.duplicate_bytes_zero_terminated(enum_name);
const string_literal = try builder.processStringLiteralFromStringAndDebugInfo(unit, context, enum_name_z, .{ const string_literal = try builder.processStringLiteralFromStringAndDebugInfo(unit, context, enum_name_z, .{
.line = 0, .line = 0,
.column = 0, .column = 0,
@ -5288,7 +5301,7 @@ pub const Builder = struct {
const case_block = try builder.newBasicBlock(unit); const case_block = try builder.newBasicBlock(unit);
builder.current_basic_block = case_block; builder.current_basic_block = case_block;
const identifier = unit.getIdentifier(enum_field.name); const identifier = unit.getIdentifier(enum_field.name);
const identifier_z = try context.allocator.dupeZ(u8, identifier); const identifier_z = try context.arena.duplicate_bytes_zero_terminated(identifier);
const string_literal = try builder.processStringLiteralFromStringAndDebugInfo(unit, context, identifier_z, .{ const string_literal = try builder.processStringLiteralFromStringAndDebugInfo(unit, context, identifier_z, .{
.line = 0, .line = 0,
.column = 0, .column = 0,
@ -5345,7 +5358,12 @@ pub const Builder = struct {
const global = unit.global_declarations.append(.{ const global = unit.global_declarations.append(.{
.declaration = .{ .declaration = .{
.scope = builder.current_scope, .scope = builder.current_scope,
.name = try unit.processIdentifier(context, try std.fmt.allocPrint(context.allocator, "get_enum_name_{}", .{@intFromEnum(type_index)})), .name = b: {
var buffer: [65]u8 = undefined;
const slice = format_int(&buffer, @intFromEnum(type_index), 10, false);
const name = try context.arena.join(&.{"get_enum_name_", slice});
break :b try unit.processIdentifier(context, name);
},
.type = function_type_index, .type = function_type_index,
.line = 0, .line = 0,
.column = 0, .column = 0,
@ -7601,7 +7619,7 @@ pub const Builder = struct {
.discard => b: { .discard => b: {
var buffer: [65]u8 = undefined; var buffer: [65]u8 = undefined;
const formatted_int = format_int(&buffer, argument_index, 10, false); const formatted_int = format_int(&buffer, argument_index, 10, false);
break :b try std.mem.concat(context.allocator, u8, &.{ "_anon_arg_", formatted_int }); break :b try context.arena.join(&.{ "_anon_arg_", formatted_int });
}, },
else => |t| @panic(@tagName(t)), else => |t| @panic(@tagName(t)),
}; };
@ -8926,7 +8944,7 @@ pub const Builder = struct {
const identifier = switch (unit.token_buffer.tokens.get(field_node.token).id) { const identifier = switch (unit.token_buffer.tokens.get(field_node.token).id) {
.identifier => unit.getExpectedTokenBytes(field_node.token, .identifier), .identifier => unit.getExpectedTokenBytes(field_node.token, .identifier),
.string_literal => try unit.fixupStringLiteral(context, field_node.token), .string_literal => try unit.fixupStringLiteral(context, field_node.token),
.discard => try std.mem.concat(context.allocator, u8, &.{ "_", &.{'0' + b: { .discard => try context.arena.join(&.{ "_", &.{'0' + b: {
const ch = '0' + ignore_field_count; const ch = '0' + ignore_field_count;
ignore_field_count += 1; ignore_field_count += 1;
break :b ch; break :b ch;
@ -16815,7 +16833,7 @@ pub const Builder = struct {
const token_debug_info = builder.getTokenDebugInfo(unit, err_node.token); const token_debug_info = builder.getTokenDebugInfo(unit, err_node.token);
const line = token_debug_info.line + 1; const line = token_debug_info.line + 1;
const column = token_debug_info.column + 1; const column = token_debug_info.column + 1;
const file_path = file.getPath(context.allocator) catch unreachable; const file_path = file.getPath(context.arena) catch unreachable;
write(.panic, file_path) catch unreachable; write(.panic, file_path) catch unreachable;
write(.panic, ":") catch unreachable; write(.panic, ":") catch unreachable;
Unit.dumpInt(line, 10, false) catch unreachable; Unit.dumpInt(line, 10, false) catch unreachable;
@ -16836,7 +16854,7 @@ pub const Builder = struct {
_ = file; // autofix _ = file; // autofix
const token_debug_info = builder.getTokenDebugInfo(unit, err_node.token); const token_debug_info = builder.getTokenDebugInfo(unit, err_node.token);
_ = token_debug_info; // autofix _ = token_debug_info; // autofix
// std.io.getStdOut().writer().print("{s}:{}:{}: \x1b[31merror:\x1b[0m ", .{ file.getPath(context.allocator) catch unreachable, token_debug_info.line + 1, token_debug_info.column + 1 }) catch unreachable; // std.io.getStdOut().writer().print("{s}:{}:{}: \x1b[31merror:\x1b[0m ", .{ file.getPath(context.arena) catch unreachable, token_debug_info.line + 1, token_debug_info.column + 1 }) catch unreachable;
// std.io.getStdOut().writer().print(format, args) catch unreachable; // std.io.getStdOut().writer().print(format, args) catch unreachable;
// std.io.getStdOut().writer().writeByte('\n') catch unreachable; // std.io.getStdOut().writer().writeByte('\n') catch unreachable;
std.os.abort(); std.os.abort();
@ -17607,7 +17625,7 @@ pub const Unit = struct {
}; };
const file_size = try source_file.getEndPos(); const file_size = try source_file.getEndPos();
var file_buffer = try context.allocator.alloc(u8, file_size); var file_buffer = try context.arena.new_array(u8, file_size);
const read_byte_count = try source_file.readAll(file_buffer); const read_byte_count = try source_file.readAll(file_buffer);
assert(read_byte_count == file_size); assert(read_byte_count == file_size);
@ -17632,7 +17650,7 @@ pub const Unit = struct {
} }
fn importPackage(unit: *Unit, context: *const Context, package: *Package) !ImportPackageResult { fn importPackage(unit: *Unit, context: *const Context, package: *Package) !ImportPackageResult {
const full_path = try package.directory.handle.realpathAlloc(context.allocator, package.source_path); //try std.fs.path.resolve(context.allocator, &.{ package.directory.path, package.source_path }); const full_path = try realpath(context.arena, package.directory.handle, package.source_path); //try std.fs.path.resolve(context.arena, &.{ package.directory.path, package.source_path });
// logln(.compilation, .import, "Import full path: {s}\n", .{full_path}); // logln(.compilation, .import, "Import full path: {s}\n", .{full_path});
const import_file = try unit.getFile(full_path, package.source_path, package); const import_file = try unit.getFile(full_path, package.source_path, package);
@ -17762,7 +17780,7 @@ pub const Unit = struct {
}; };
unit.root_package = if (unit.descriptor.is_test) blk: { unit.root_package = if (unit.descriptor.is_test) blk: {
const package = try context.allocator.create(Package); const package = try context.arena.new(Package);
const directory_path = try context.pathFromCompiler("lib"); const directory_path = try context.pathFromCompiler("lib");
package.* = .{ package.* = .{
.directory = .{ .directory = .{
@ -17789,7 +17807,7 @@ pub const Unit = struct {
.{ .{
.name = "builtin", .name = "builtin",
.directory_path = blk: { .directory_path = blk: {
const result = try cache_dir.realpathAlloc(context.allocator, "."); const result = try realpath(context.arena, cache_dir, ".");
cache_dir.close(); cache_dir.close();
break :blk result; break :blk result;
}, },
@ -17798,13 +17816,13 @@ pub const Unit = struct {
var packages: [package_descriptors.len]*Package = undefined; var packages: [package_descriptors.len]*Package = undefined;
for (package_descriptors, &packages) |package_descriptor, *package_ptr| { for (package_descriptors, &packages) |package_descriptor, *package_ptr| {
const package = try context.allocator.create(Package); const package = try context.arena.new(Package);
package.* = .{ package.* = .{
.directory = .{ .directory = .{
.path = package_descriptor.directory_path, .path = package_descriptor.directory_path,
.handle = try std.fs.openDirAbsolute(package_descriptor.directory_path, .{}), .handle = try std.fs.openDirAbsolute(package_descriptor.directory_path, .{}),
}, },
.source_path = try std.mem.concat(context.allocator, u8, &.{ package_descriptor.name, ".nat" }), .source_path = try context.arena.join(&.{ package_descriptor.name, ".nat" }),
.dependencies = try PinnedHashMap([]const u8, *Package).init(std.mem.page_size), .dependencies = try PinnedHashMap([]const u8, *Package).init(std.mem.page_size),
}; };
@ -17839,11 +17857,8 @@ pub const Unit = struct {
const dot_index = last_byte(c_source_file, '.') orelse unreachable; const dot_index = last_byte(c_source_file, '.') orelse unreachable;
const path_without_extension = c_source_file[0..dot_index]; const path_without_extension = c_source_file[0..dot_index];
const basename = std.fs.path.basename(path_without_extension); const basename = std.fs.path.basename(path_without_extension);
const o_file = try std.mem.concat(context.allocator, u8, &.{ basename, ".o" }); const o_file = try context.arena.join(&.{ basename, ".o" });
const object_path = try std.mem.concat(context.allocator, u8, &.{ const object_path = try context.arena.join(&.{ "nat/", o_file });
"nat/",
o_file,
});
var arguments = [_][]const u8{ "-c", c_source_file, "-o", object_path, "-g", "-fno-stack-protector" }; var arguments = [_][]const u8{ "-c", c_source_file, "-o", object_path, "-g", "-fno-stack-protector" };
try compileCSourceFile(context, &arguments, .c); try compileCSourceFile(context, &arguments, .c);

View File

@ -1,5 +1,4 @@
const std = @import("std"); const std = @import("std");
const Allocator = std.mem.Allocator;
const assert = std.debug.assert; const assert = std.debug.assert;
const Compilation = @import("../Compilation.zig"); const Compilation = @import("../Compilation.zig");
const write = Compilation.write; const write = Compilation.write;
@ -2043,7 +2042,7 @@ pub const LLVM = struct {
fn createBasicBlock(llvm: *LLVM, context: *const Compilation.Context, basic_block_index: Compilation.BasicBlock.Index, name: []const u8) !*BasicBlockList.Node { fn createBasicBlock(llvm: *LLVM, context: *const Compilation.Context, basic_block_index: Compilation.BasicBlock.Index, name: []const u8) !*BasicBlockList.Node {
const basic_block = llvm.context.createBasicBlock(name.ptr, name.len, llvm.function, null) orelse return Error.basic_block; const basic_block = llvm.context.createBasicBlock(name.ptr, name.len, llvm.function, null) orelse return Error.basic_block;
const basic_block_node = try context.allocator.create(BasicBlockList.Node); const basic_block_node = try context.arena.new(BasicBlockList.Node);
basic_block_node.* = .{ basic_block_node.* = .{
.data = basic_block_index, .data = basic_block_index,
}; };
@ -2435,7 +2434,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
}; };
if (unit.descriptor.generate_debug_information) { if (unit.descriptor.generate_debug_information) {
const full_path = try std.fs.cwd().realpathAlloc(context.allocator, unit.descriptor.main_package_path); const full_path = try Compilation.realpath(context.arena, std.fs.cwd(), unit.descriptor.main_package_path);
const filename = std.fs.path.basename(full_path); const filename = std.fs.path.basename(full_path);
const directory = full_path[0 .. full_path.len - filename.len]; const directory = full_path[0 .. full_path.len - filename.len];
const debug_info_file = llvm.debug_info_builder.createFile(filename.ptr, filename.len, directory.ptr, directory.len) orelse unreachable; const debug_info_file = llvm.debug_info_builder.createFile(filename.ptr, filename.len, directory.ptr, directory.len) orelse unreachable;
@ -2679,7 +2678,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
_ = assembly_statements.pop(); _ = assembly_statements.pop();
// try constraints.append_slice(context.allocator, ",~{dirflag},~{fpsr},~{flags}"); // try constraints.append_slice(context.arena, ",~{dirflag},~{fpsr},~{flags}");
}, },
.aarch64 => { .aarch64 => {
for (assembly_block.instructions) |assembly_instruction_index| { for (assembly_block.instructions) |assembly_instruction_index| {
@ -3427,7 +3426,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
llvm.module.setTargetTriple(target_triple.ptr, target_triple.len); llvm.module.setTargetTriple(target_triple.ptr, target_triple.len);
const file_path = unit.descriptor.executable_path; const file_path = unit.descriptor.executable_path;
const object_file_path = blk: { const object_file_path = blk: {
const slice = try context.allocator.alloc(u8, file_path.len + 3); const slice = try context.arena.new_array(u8, file_path.len + 3);
@memcpy(slice[0..file_path.len], file_path); @memcpy(slice[0..file_path.len], file_path);
slice[file_path.len] = '.'; slice[file_path.len] = '.';
slice[file_path.len + 1] = 'o'; slice[file_path.len + 1] = 'o';

View File

@ -1,5 +1,4 @@
const std = @import("std"); const std = @import("std");
const Allocator = std.mem.Allocator;
const assert = std.debug.assert; const assert = std.debug.assert;
const log = std.log; const log = std.log;
@ -7,14 +6,12 @@ const library = @import("../library.zig");
const byte_equal = library.byte_equal; const byte_equal = library.byte_equal;
const enumFromString = library.enumFromString; const enumFromString = library.enumFromString;
const exit_with_error = library.exit_with_error; const exit_with_error = library.exit_with_error;
const MyAllocator = library.MyAllocator;
const PinnedArray = library.PinnedArray; const PinnedArray = library.PinnedArray;
const Compilation = @import("../Compilation.zig"); const Compilation = @import("../Compilation.zig");
const File = Compilation.File; const File = Compilation.File;
const logln = Compilation.logln; const logln = Compilation.logln;
const Token = Compilation.Token; const Token = Compilation.Token;
const fs = @import("../fs.zig");
// Needed information // Needed information
// Token: u8 // Token: u8
@ -69,10 +66,6 @@ pub fn analyze(text: []const u8, token_buffer: *Token.Buffer) !Result {
var index: u32 = 0; var index: u32 = 0;
var line_index: u32 = lexer.line_offset; var line_index: u32 = lexer.line_offset;
// try token_buffer.ensure_with_capacity(allocator, len / 3);
// logln(.lexer, .end, "START LEXER - TOKEN OFFSET: {} - LINE OFFSET: {}", .{ Token.unwrap(lexer.offset), lexer.line_offset });
while (index < len) { while (index < len) {
const start_index = index; const start_index = index;
const start_character = text[index]; const start_character = text[index];

View File

@ -1,7 +0,0 @@
const std = @import("std");
const Allocator = std.mem.Allocator;
pub fn readFile(allocator: Allocator, file_relative_path: []const u8) ![]const u8 {
const file = try std.fs.cwd().readFileAlloc(allocator, file_relative_path, std.math.maxInt(usize));
return file;
}

View File

@ -8,7 +8,6 @@ pub fn assert(ok: bool) void {
if (!ok) unreachable; if (!ok) unreachable;
} }
pub const Allocator = std.mem.Allocator;
pub const BoundedArray = std.BoundedArray; pub const BoundedArray = std.BoundedArray;
pub const Arena = struct { pub const Arena = struct {
@ -86,6 +85,32 @@ pub const Arena = struct {
@memcpy(slice, bytes); @memcpy(slice, bytes);
return slice; return slice;
} }
pub fn duplicate_bytes_zero_terminated(arena: *Arena, bytes: []const u8) ![:0]u8 {
const slice = try arena.new_array(u8, bytes.len + 1);
slice[bytes.len] = 0;
@memcpy(slice[0..bytes.len], bytes);
return slice[0..bytes.len:0];
}
pub fn join(arena: *Arena, slices: []const []const u8) ![]u8 {
var byte_count: usize = 0;
for (slices) |slice| {
byte_count += slice.len;
}
const result = try arena.new_array(u8, byte_count);
byte_count = 0;
for (slices) |slice| {
@memcpy(result[byte_count..][0..slice.len], slice);
byte_count += slice.len;
}
return result;
}
}; };
pub fn DynamicBoundedArray(comptime T: type) type { pub fn DynamicBoundedArray(comptime T: type) type {

View File

@ -138,10 +138,10 @@ pub fn link(context: *const Compilation.Context, options: linker.Options) !void
} }
for (options.libraries) |lib| { for (options.libraries) |lib| {
_ = argv.append(try std.mem.concat(context.allocator, u8, &.{ "-l", lib.path })); _ = argv.append(try context.arena.join(&.{"-l", lib.path}));
} }
const argv_zero_terminated = try Compilation.argsCopyZ(context.allocator, argv.const_slice()); const argv_zero_terminated = try Compilation.argsCopyZ(context.arena, argv.const_slice());
var stdout_ptr: [*]const u8 = undefined; var stdout_ptr: [*]const u8 = undefined;
var stdout_len: usize = 0; var stdout_len: usize = 0;

View File

@ -1,5 +1,4 @@
const std = @import("std"); const std = @import("std");
const Allocator = std.mem.Allocator;
const assert = std.debug.assert; const assert = std.debug.assert;
const Compilation = @import("Compilation.zig"); const Compilation = @import("Compilation.zig");
@ -7,8 +6,6 @@ pub const panic = Compilation.panic;
const library = @import("library.zig"); const library = @import("library.zig");
const byte_equal = library.byte_equal; const byte_equal = library.byte_equal;
const MyAllocator = library.MyAllocator;
const PageAllocator = library.PageAllocator;
const env_detecting_libc_paths = "NATIVITY_IS_DETECTING_LIBC_PATHS"; const env_detecting_libc_paths = "NATIVITY_IS_DETECTING_LIBC_PATHS";
@ -22,10 +19,13 @@ fn todo() noreturn {
} }
pub fn main() !void { pub fn main() !void {
var arena_allocator = std.heap.ArenaAllocator.init(std.heap.page_allocator); var arg_iterator = std.process.ArgIterator.init();
const allocator = arena_allocator.allocator(); var buffer = library.BoundedArray([]const u8, 512){};
const arguments: []const []const u8 = try std.process.argsAlloc(allocator); while (arg_iterator.next()) |argument| {
const context = try Compilation.createContext(allocator); buffer.appendAssumeCapacity(argument);
}
const arguments = buffer.slice();
const context = try Compilation.createContext();
if (arguments.len <= 1) { if (arguments.len <= 1) {
return error.InvalidInput; return error.InvalidInput;
@ -41,7 +41,7 @@ pub fn main() !void {
if (byte_equal(command, "build")) { if (byte_equal(command, "build")) {
try Compilation.compileBuildExecutable(context, command_arguments); try Compilation.compileBuildExecutable(context, command_arguments);
} else if (byte_equal(command, "clang") or byte_equal(command, "-cc1") or byte_equal(command, "-cc1as")) { } else if (byte_equal(command, "clang") or byte_equal(command, "-cc1") or byte_equal(command, "-cc1as")) {
const exit_code = try Compilation.clangMain(allocator, arguments); const exit_code = try Compilation.clangMain(context.arena, arguments);
std.process.exit(exit_code); std.process.exit(exit_code);
} else if (byte_equal(command, "cc")) { } else if (byte_equal(command, "cc")) {
try Compilation.compileCSourceFile(context, command_arguments, .c); try Compilation.compileCSourceFile(context, command_arguments, .c);

View File

@ -244,8 +244,6 @@ fn runStdTests(allocator: Allocator, args: struct {
var errors = false; var errors = false;
std.debug.print("std... ", .{}); std.debug.print("std... ", .{});
std.debug.print("CWD: {s}\n", .{std.fs.cwd().realpathAlloc(allocator, ".") catch unreachable});
const argv = &.{ args.compiler_path, "test", "-main_source_file", "lib/std/std.nat", "-name", "std" }; const argv = &.{ args.compiler_path, "test", "-main_source_file", "lib/std/std.nat", "-name", "std" };
const result = std.ChildProcess.run(.{ const result = std.ChildProcess.run(.{