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 DUMMY_IDX = 9999999;
|
||||||
|
|
||||||
const ALLOCATE_ITEM: string[] = ["std", "rt", "alloc", "allocateItem"];
|
const ALLOCATE: string[] = ["std", "rt", "alloc", "allocate"];
|
||||||
const DEALLOCATE_ITEM: string[] = ["std", "rt", "alloc", "deallocateItem"];
|
const DEALLOCATE: string[] = ["std", "rt", "alloc", "deallocate"];
|
||||||
|
|
||||||
type RelocationKind =
|
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> {
|
function getKnownDefPaths(pkgs: Pkg<Typecked>[]): ComplexMap<string[], ItemId> {
|
||||||
const knows = new 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;
|
fcx.wasm.body = body.instructions;
|
||||||
} else {
|
} else {
|
||||||
lowerExpr(fcx, wasmFunc.body, body);
|
lowerExpr(fcx, wasmFunc.body, body);
|
||||||
paramLocations.forEach((local) => {
|
paramLocations.forEach((local) => {
|
||||||
const refcount = needsRefcount(local.ty);
|
const refcount = needsRefcount(local.ty);
|
||||||
if (refcount !== undefined) {
|
if (refcount !== undefined) {
|
||||||
// TODO: correctly deal with tuples
|
// TODO: correctly deal with tuples
|
||||||
|
|
@ -814,7 +814,10 @@ function lowerExpr(
|
||||||
const { res } = expr.lhs.value;
|
const { res } = expr.lhs.value;
|
||||||
if (res.kind === "builtin") {
|
if (res.kind === "builtin") {
|
||||||
const assertArgs = (n: number) => {
|
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) {
|
switch (res.name) {
|
||||||
case "trap": {
|
case "trap": {
|
||||||
|
|
@ -842,7 +845,7 @@ function lowerExpr(
|
||||||
break exprKind;
|
break exprKind;
|
||||||
}
|
}
|
||||||
case "__i64_store": {
|
case "__i64_store": {
|
||||||
assertArgs(3);
|
assertArgs(2);
|
||||||
lowerExpr(fcx, instrs, expr.args[0]);
|
lowerExpr(fcx, instrs, expr.args[0]);
|
||||||
lowerExpr(fcx, instrs, expr.args[1]);
|
lowerExpr(fcx, instrs, expr.args[1]);
|
||||||
instrs.push({ kind: "i64.store", imm: {} });
|
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.size) });
|
||||||
instrs.push({ kind: "i32.const", imm: BigInt(layout.align) });
|
instrs.push({ kind: "i32.const", imm: BigInt(layout.align) });
|
||||||
const allocate: wasm.Instr = { kind: "call", func: DUMMY_IDX };
|
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) {
|
if (!allocateItemId) {
|
||||||
unreachable("std.rt.allocateItem not found");
|
unreachable("std.rt.allocateItem not found");
|
||||||
}
|
}
|
||||||
|
|
@ -1384,9 +1387,6 @@ export function layoutOfStruct(ty_: TyStruct | TyRawPtr): StructLayout {
|
||||||
return value;
|
return value;
|
||||||
});
|
});
|
||||||
|
|
||||||
// we ignore the refcount for struct size.
|
|
||||||
offset -= 4;
|
|
||||||
|
|
||||||
if (align === 8 && offset % 8 !== 0) {
|
if (align === 8 && offset % 8 !== 0) {
|
||||||
offset += 4;
|
offset += 4;
|
||||||
}
|
}
|
||||||
|
|
@ -1508,7 +1508,7 @@ function subRefcount(
|
||||||
instrs: wasm.Instr[],
|
instrs: wasm.Instr[],
|
||||||
kind: StructLayout | "string",
|
kind: StructLayout | "string",
|
||||||
) {
|
) {
|
||||||
const deallocateItemId = fcx.cx.knownDefPaths.get(DEALLOCATE_ITEM);
|
const deallocateItemId = fcx.cx.knownDefPaths.get(DEALLOCATE);
|
||||||
if (!deallocateItemId) {
|
if (!deallocateItemId) {
|
||||||
unreachable("std.rt.deallocateItem not found");
|
unreachable("std.rt.deallocateItem not found");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -286,6 +286,10 @@ export function checkBody(
|
||||||
let ty: Ty;
|
let ty: Ty;
|
||||||
let fieldIdx: number | undefined;
|
let fieldIdx: number | undefined;
|
||||||
switch (lhs.ty.kind) {
|
switch (lhs.ty.kind) {
|
||||||
|
case "error": {
|
||||||
|
ty = tyErrorFrom(lhs.ty);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case "tuple": {
|
case "tuple": {
|
||||||
const { elems } = lhs.ty;
|
const { elems } = lhs.ty;
|
||||||
if (typeof field.value === "number") {
|
if (typeof field.value === "number") {
|
||||||
|
|
@ -777,6 +781,11 @@ function checkCall(
|
||||||
const args = expr.args.map((arg) => fcx.checkExpr(arg));
|
const args = expr.args.map((arg) => fcx.checkExpr(arg));
|
||||||
|
|
||||||
const lhsTy = lhs.ty;
|
const lhsTy = lhs.ty;
|
||||||
|
|
||||||
|
if (lhsTy.kind === "error") {
|
||||||
|
return { ...expr, lhs, args, ty: lhsTy };
|
||||||
|
}
|
||||||
|
|
||||||
if (lhsTy.kind !== "fn") {
|
if (lhsTy.kind !== "fn") {
|
||||||
const ty = tyError(
|
const ty = tyError(
|
||||||
fcx.cx,
|
fcx.cx,
|
||||||
|
|
|
||||||
41
std/list.nil
41
std/list.nil
|
|
@ -1,21 +1,48 @@
|
||||||
type List[T] = struct {
|
type List[T] = struct {
|
||||||
ptr: Int,
|
ptr: I32,
|
||||||
len: Int,
|
len: I32,
|
||||||
cap: Int,
|
cap: I32,
|
||||||
};
|
};
|
||||||
|
|
||||||
function new(): List[Int] = (
|
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) = (
|
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:
|
// 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 (
|
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.
|
// Allocate a new item. We do not deallocate anything yet.
|
||||||
// lol.
|
// lol.
|
||||||
function allocateItem(objSize: I32, align: I32): I32 = (
|
function allocate(size: I32, align: I32): I32 = (
|
||||||
if align < 4_I32 then std.abort("invalid alignment");
|
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.
|
// 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.
|
// I happen to know that everything will always be at least 4 bytes aligned.
|
||||||
let alignedPtr = std.alignUp(HEAD_PTR, align);
|
let alignedPtr = std.alignUp(HEAD_PTR, align);
|
||||||
let actualObjPtr = if (alignedPtr - HEAD_PTR) > align then (
|
let newHeadPtr = alignedPtr + size;
|
||||||
alignedPtr - 4_I32
|
|
||||||
) else (
|
|
||||||
// Take up the next spot.
|
|
||||||
alignedPtr + align - 4_I32
|
|
||||||
);
|
|
||||||
|
|
||||||
let newHeadPtr = actualObjPtr + actualSize;
|
|
||||||
|
|
||||||
if newHeadPtr > __memory_size() then (
|
if newHeadPtr > __memory_size() then (
|
||||||
// 16 pages, very arbitrary.
|
// 16 pages, very arbitrary.
|
||||||
|
|
@ -36,10 +26,10 @@ function allocateItem(objSize: I32, align: I32): I32 = (
|
||||||
|
|
||||||
HEAD_PTR = newHeadPtr;
|
HEAD_PTR = newHeadPtr;
|
||||||
|
|
||||||
actualObjPtr
|
alignedPtr
|
||||||
);
|
);
|
||||||
|
|
||||||
function deallocateItem(ptr: I32, objSize: I32) = (
|
function deallocate(ptr: I32, size: I32) = (
|
||||||
std.println("uwu deawwocate :3");
|
std.println("uwu deawwocate :3");
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue