145 lines
4.2 KiB
Plaintext
145 lines
4.2 KiB
Plaintext
comptime {
|
|
_ = start;
|
|
}
|
|
|
|
const build = #import("build.nat");
|
|
const builtin = #import("builtin.nat");
|
|
const os = #import("os.nat");
|
|
const start = #import("start.nat");
|
|
|
|
const assert = fn(ok: bool) void {
|
|
if (!ok) {
|
|
unreachable;
|
|
}
|
|
}
|
|
|
|
const print = fn(bytes: []const u8) void {
|
|
const file_descriptor = os.StdFileDescriptor.get(descriptor = .stdout);
|
|
const file_writer = FileWriter{
|
|
.descriptor = file_descriptor,
|
|
};
|
|
_ = file_writer.writeAll(bytes);
|
|
}
|
|
|
|
const Allocator = struct {
|
|
handler: &const fn(allocator: &Allocator, old_ptr: ?[&]const u8, old_size: usize, new_size: usize, alignment: u16) ?[&]u8,
|
|
|
|
const allocate = fn (allocator: &Allocator, size: usize, alignment: u16) ?[]u8 {
|
|
if (allocator.handler(allocator, old_ptr = null, old_size = 0, new_size = size, alignment)) |result| {
|
|
return result[0..size];
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
const free = fn (allocator: &Allocator, bytes_ptr: [&]const u8, bytes_len: usize) bool {
|
|
if (allocator.handler(allocator, old_ptr = bytes_ptr, old_size = bytes_len, new_size = 0, alignment = 0)) |_| {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
const duplicate_bytes = fn (allocator: &Allocator, bytes: []const u8) ?[]u8 {
|
|
if (allocator.allocate(size = bytes.len, alignment = 0)) |result| {
|
|
copy_bytes(destination = result, source = bytes);
|
|
return result;
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
};
|
|
|
|
const PageAllocator = struct{
|
|
allocator: Allocator = .{
|
|
.handler = handler.&,
|
|
},
|
|
|
|
const allocate = fn (a: &PageAllocator, size: usize, alignment: u16) ?[]u8 {
|
|
const result = a.allocator.allocate(size, alignment);
|
|
return result;
|
|
}
|
|
|
|
const free = fn (a: &PageAllocator, bytes_ptr: [&]const u8, bytes_len: usize) bool {
|
|
const result = a.allocator.free(bytes_ptr, bytes_len);
|
|
return result;
|
|
}
|
|
|
|
const handler = fn (allocator: &Allocator, maybe_old_ptr: ?[&]const u8, old_size: usize, new_size: usize, alignment: u16) ?[&]u8{
|
|
var maybe_new_ptr: ?[&]u8 = null;
|
|
if (new_size > 0) {
|
|
const general_protection_flags = os.ProtectionFlags{
|
|
.read = true,
|
|
.write = true,
|
|
.execute = false,
|
|
};
|
|
const general_map_flags = os.MapFlags{
|
|
.reserve = true,
|
|
.commit = true,
|
|
};
|
|
|
|
maybe_new_ptr = os.allocate_virtual_memory(address = null, length = new_size, general_protection_flags, general_map_flags);
|
|
}
|
|
|
|
if (maybe_old_ptr) |old_ptr| {
|
|
if (maybe_new_ptr) |new_ptr| {
|
|
unreachable;
|
|
}
|
|
|
|
const result = os.free_virtual_memory(bytes_ptr = old_ptr, bytes_len = old_size);
|
|
if (result) {
|
|
return #cast(old_ptr);
|
|
} else {
|
|
return null;
|
|
}
|
|
} else {
|
|
return maybe_new_ptr;
|
|
}
|
|
}
|
|
|
|
const get_allocator = fn(page_allocator: &PageAllocator) &Allocator {
|
|
return page_allocator.allocator.&;
|
|
}
|
|
};
|
|
|
|
const Writer = struct{
|
|
callback: &const fn(writer: &Writer, bytes: []const u8) ?usize,
|
|
};
|
|
|
|
const FileWriter = struct{
|
|
descriptor: os.FileDescriptor,
|
|
|
|
const write = fn(file_writer: FileWriter, bytes: []const u8) ?usize {
|
|
return file_writer.descriptor.write(bytes);
|
|
}
|
|
|
|
const writeAll = fn(file_writer: FileWriter, bytes: []const u8) bool {
|
|
var bytes_written: usize = 0;
|
|
|
|
while (bytes_written < bytes.len) {
|
|
if (file_writer.write(bytes = bytes[bytes_written..])) |iteration_written_byte_count| {
|
|
bytes_written += iteration_written_byte_count;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return bytes_written == bytes.len;
|
|
}
|
|
};
|
|
|
|
const copy_bytes = fn(destination: []u8, source: []const u8) void {
|
|
assert(ok = destination.len == source.len);
|
|
for (0..destination.len) |i| {
|
|
destination[i] = source[i];
|
|
}
|
|
}
|
|
|
|
const Target = struct {
|
|
cpu: builtin.Cpu,
|
|
os: builtin.Os,
|
|
abi: builtin.Abi,
|
|
};
|
|
|
|
var page_allocator = PageAllocator{};
|