move rt to separate file and make loader understand it

This commit is contained in:
nora 2023-08-02 20:19:14 +02:00
parent 309a286a1a
commit a1d04d264e
5 changed files with 100 additions and 61 deletions

38
std/rt.nil Normal file
View file

@ -0,0 +1,38 @@
// Start the heap at 1024. In practice this could probably be as low as we want.
// TODO: The compiler should set this global to whatever it has calculated the heap
// start to be. But well, 1024 ought to be enough for now. lol.
global HEAD_PTR: I32 = 1024_I32;
// Every struct has a header of an I32 as a refcount.
// Allocate a new item. We do not deallocate anything yet.
// lol.
function allocateItem(objSize: I32, align: I32): I32 = (
if align < 4_I32 then std.abort("invalid alignment");
// Include the refcount header.
let actualSize = 4_I32 + objSize;
// Let's see whether we can fit the refcount into the align bits.
// I happen to know that everything will always be at least 4 bytes aligned.
let alignedPtr = std.alignUp(HEAD_PTR, align);
let actualObjPtr = if (alignedPtr - HEAD_PTR) > align then (
alignedPtr - 4_I32
) else (
// Take up the next spot.
alignedPtr + align - 4_I32
);
let newHeadPtr = actualObjPtr + actualSize;
if newHeadPtr > __memory_size() then (
// 16 pages, very arbitrary.
let result = __memory_grow(16_I32);
// If allocation failed we get -1. We don't have negative numbers yet, lol.
if result > 4294967295_I32 then (
std.abort("failed to grow memory");
);
);
actualObjPtr
);

View file

@ -1,3 +1,5 @@
mod rt;
function printlnI32(x: I32) = (
printI32(x);
print("\n");
@ -65,48 +67,6 @@ function println(s: String) = (
print("\n");
);
mod rt (
// Start the heap at 1024. In practice this could probably be as low as we want.
global BASE_PTR: I32 = 1024_I32;
global HEAD_PTR: I32 = 1024_I32;
/*
Every struct has a header of an I32 as a refcount.
*/
// Allocate a new item. We do not deallocate anything yet.
// lol.
function allocateItem(objSize: I32, align: I32): I32 = (
if align < 4_I32 then std.abort("invalid alignment");
// Include the refcount header.
let actualSize = 4_I32 + objSize;
// Let's see whether we can fit the refcount into the align bits.
// I happen to know that everything will always be at least 4 bytes aligned.
let alignedPtr = std.alignUp(HEAD_PTR, align);
let actualObjPtr = if (alignedPtr - HEAD_PTR) > align then (
alignedPtr - 4_I32
) else (
// Take up the next spot.
alignedPtr + align - 4_I32
);
let newHeadPtr = actualObjPtr + actualSize;
if newHeadPtr > __memory_size() then (
// 16 pages, very arbitrary.
let result = __memory_grow(16_I32);
// If allocation failed we get -1. We don't have negative numbers yet, lol.
if result > 4294967295_I32 then (
std.abort("failed to grow memory");
);
);
actualObjPtr
);
);
function alignUp(x: I32, align: I32): I32 = (x + (align - 1_I32)) & !(align - 1_I32);
function i32ToInt(x: I32): Int = __i32_extend_to_i64_u(x);