mirror of
https://github.com/Noratrieb/riverdelta.git
synced 2026-01-14 16:35:03 +01:00
list or whatever
This commit is contained in:
parent
179c4b3505
commit
b2b80fe2ee
5 changed files with 59 additions and 33 deletions
|
|
@ -75,7 +75,7 @@ it("should compute single field struct layout correctly", () => {
|
|||
],
|
||||
},
|
||||
],
|
||||
"size": 8,
|
||||
"size": 16,
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -42,8 +42,8 @@ const WASM_PAGE = 65536;
|
|||
|
||||
const DUMMY_IDX = 9999999;
|
||||
|
||||
const ALLOCATE_ITEM: string[] = ["std", "rt", "alloc", "allocateItem"];
|
||||
const DEALLOCATE_ITEM: string[] = ["std", "rt", "alloc", "deallocateItem"];
|
||||
const ALLOCATE: string[] = ["std", "rt", "alloc", "allocate"];
|
||||
const DEALLOCATE: string[] = ["std", "rt", "alloc", "deallocate"];
|
||||
|
||||
type RelocationKind =
|
||||
| {
|
||||
|
|
@ -118,7 +118,7 @@ function appendData(cx: Context, newData: Uint8Array): number {
|
|||
}
|
||||
}
|
||||
|
||||
const KNOWN_DEF_PATHS = [ALLOCATE_ITEM, DEALLOCATE_ITEM];
|
||||
const KNOWN_DEF_PATHS = [ALLOCATE, DEALLOCATE];
|
||||
|
||||
function getKnownDefPaths(pkgs: Pkg<Typecked>[]): ComplexMap<string[], ItemId> {
|
||||
const knows = new ComplexMap<string[], ItemId>();
|
||||
|
|
@ -384,7 +384,7 @@ function lowerFunc(cx: Context, func: ItemFunction<Typecked>) {
|
|||
fcx.wasm.body = body.instructions;
|
||||
} else {
|
||||
lowerExpr(fcx, wasmFunc.body, body);
|
||||
paramLocations.forEach((local) => {
|
||||
paramLocations.forEach((local) => {
|
||||
const refcount = needsRefcount(local.ty);
|
||||
if (refcount !== undefined) {
|
||||
// TODO: correctly deal with tuples
|
||||
|
|
@ -814,7 +814,10 @@ function lowerExpr(
|
|||
const { res } = expr.lhs.value;
|
||||
if (res.kind === "builtin") {
|
||||
const assertArgs = (n: number) => {
|
||||
if (expr.args.length !== n) unreachable("nope");
|
||||
if (expr.args.length !== n)
|
||||
unreachable(
|
||||
`wrong amount of arguments for ${res.name}: expected ${n} found ${expr.args.length}`,
|
||||
);
|
||||
};
|
||||
switch (res.name) {
|
||||
case "trap": {
|
||||
|
|
@ -842,7 +845,7 @@ function lowerExpr(
|
|||
break exprKind;
|
||||
}
|
||||
case "__i64_store": {
|
||||
assertArgs(3);
|
||||
assertArgs(2);
|
||||
lowerExpr(fcx, instrs, expr.args[0]);
|
||||
lowerExpr(fcx, instrs, expr.args[1]);
|
||||
instrs.push({ kind: "i64.store", imm: {} });
|
||||
|
|
@ -1053,7 +1056,7 @@ function lowerExpr(
|
|||
instrs.push({ kind: "i32.const", imm: BigInt(layout.size) });
|
||||
instrs.push({ kind: "i32.const", imm: BigInt(layout.align) });
|
||||
const allocate: wasm.Instr = { kind: "call", func: DUMMY_IDX };
|
||||
const allocateItemId = fcx.cx.knownDefPaths.get(ALLOCATE_ITEM);
|
||||
const allocateItemId = fcx.cx.knownDefPaths.get(ALLOCATE);
|
||||
if (!allocateItemId) {
|
||||
unreachable("std.rt.allocateItem not found");
|
||||
}
|
||||
|
|
@ -1384,9 +1387,6 @@ export function layoutOfStruct(ty_: TyStruct | TyRawPtr): StructLayout {
|
|||
return value;
|
||||
});
|
||||
|
||||
// we ignore the refcount for struct size.
|
||||
offset -= 4;
|
||||
|
||||
if (align === 8 && offset % 8 !== 0) {
|
||||
offset += 4;
|
||||
}
|
||||
|
|
@ -1508,7 +1508,7 @@ function subRefcount(
|
|||
instrs: wasm.Instr[],
|
||||
kind: StructLayout | "string",
|
||||
) {
|
||||
const deallocateItemId = fcx.cx.knownDefPaths.get(DEALLOCATE_ITEM);
|
||||
const deallocateItemId = fcx.cx.knownDefPaths.get(DEALLOCATE);
|
||||
if (!deallocateItemId) {
|
||||
unreachable("std.rt.deallocateItem not found");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -286,6 +286,10 @@ export function checkBody(
|
|||
let ty: Ty;
|
||||
let fieldIdx: number | undefined;
|
||||
switch (lhs.ty.kind) {
|
||||
case "error": {
|
||||
ty = tyErrorFrom(lhs.ty);
|
||||
break;
|
||||
}
|
||||
case "tuple": {
|
||||
const { elems } = lhs.ty;
|
||||
if (typeof field.value === "number") {
|
||||
|
|
@ -777,6 +781,11 @@ function checkCall(
|
|||
const args = expr.args.map((arg) => fcx.checkExpr(arg));
|
||||
|
||||
const lhsTy = lhs.ty;
|
||||
|
||||
if (lhsTy.kind === "error") {
|
||||
return { ...expr, lhs, args, ty: lhsTy };
|
||||
}
|
||||
|
||||
if (lhsTy.kind !== "fn") {
|
||||
const ty = tyError(
|
||||
fcx.cx,
|
||||
|
|
|
|||
41
std/list.nil
41
std/list.nil
|
|
@ -1,21 +1,48 @@
|
|||
type List[T] = struct {
|
||||
ptr: Int,
|
||||
len: Int,
|
||||
cap: Int,
|
||||
ptr: I32,
|
||||
len: I32,
|
||||
cap: I32,
|
||||
};
|
||||
|
||||
function new(): List[Int] = (
|
||||
List { ptr: 0, len: 0, cap: 0 }
|
||||
List { ptr: 0_I32, len: 0_I32, cap: 0_I32 }
|
||||
);
|
||||
|
||||
function push(list: List[Int], elem: Int) = (
|
||||
growIfNeeded(list, 1);
|
||||
growIfNeeded(list, 1_I32);
|
||||
let addr = list.ptr + (SIZEOF * list.len);
|
||||
__i64_store(addr, elem);
|
||||
list.len = list.len + 1_I32;
|
||||
);
|
||||
|
||||
function debugPrint(list: List[Int]) = (
|
||||
let i = 0_I32;
|
||||
print("[");
|
||||
loop (
|
||||
if i >= list.len then (
|
||||
break;
|
||||
);
|
||||
let elem = __i64_load(list.ptr + (i * SIZEOF));
|
||||
std.printInt(elem);
|
||||
if (i + 1_I32) < list.len then print(", ");
|
||||
|
||||
i = i + 1_I32;
|
||||
);
|
||||
std.println("]");
|
||||
);
|
||||
|
||||
// PRIVATE:
|
||||
|
||||
function growIfNeeded(list: List[Int], elems: Int) = (
|
||||
global SIZEOF: I32 = 8_I32;
|
||||
global ALIGNOF: I32 = 8_I32;
|
||||
|
||||
function growIfNeeded(list: List[Int], elems: I32) = (
|
||||
if (list.len + elems) < list.cap then (
|
||||
let newMemory = std.rt.alloc.allocateItem(0_I32, 0_I32);
|
||||
let newMemory = std.rt.alloc.allocate(SIZEOF * list.cap * 2_I32, ALIGNOF);
|
||||
let oldMemory = list.ptr;
|
||||
let amount = SIZEOF * list.len;
|
||||
std.rt.memcpy(newMemory, oldMemory, amount);
|
||||
|
||||
if list.cap > 0_I32 then std.rt.alloc.deallocate(list.ptr, list.cap * SIZEOF);
|
||||
);
|
||||
);
|
||||
|
|
|
|||
|
|
@ -7,23 +7,13 @@ global HEAD_PTR: I32 = 1024_I32;
|
|||
|
||||
// Allocate a new item. We do not deallocate anything yet.
|
||||
// lol.
|
||||
function allocateItem(objSize: I32, align: I32): I32 = (
|
||||
function allocate(size: 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;
|
||||
let newHeadPtr = alignedPtr + size;
|
||||
|
||||
if newHeadPtr > __memory_size() then (
|
||||
// 16 pages, very arbitrary.
|
||||
|
|
@ -36,10 +26,10 @@ function allocateItem(objSize: I32, align: I32): I32 = (
|
|||
|
||||
HEAD_PTR = newHeadPtr;
|
||||
|
||||
actualObjPtr
|
||||
alignedPtr
|
||||
);
|
||||
|
||||
function deallocateItem(ptr: I32, objSize: I32) = (
|
||||
function deallocate(ptr: I32, size: I32) = (
|
||||
std.println("uwu deawwocate :3");
|
||||
);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue