From 81b10104535bc38646996e48e73a39e931c48a7d Mon Sep 17 00:00:00 2001 From: Mid <> Date: Tue, 29 Jul 2025 17:54:13 +0300 Subject: [PATCH] Basic allocators with unmanaged list (broken) --- examples/Alloc.nct | 4 ++++ examples/Allocator.nct | 5 ----- examples/ListDLU.nct | 43 ++++++++++++++++++++++++++++++++++++++++ examples/UserListDLU.nct | 26 ++++++++++++++++++++++++ src/x86/cg.c | 28 +++++++++++++++----------- 5 files changed, 89 insertions(+), 17 deletions(-) create mode 100644 examples/Alloc.nct delete mode 100644 examples/Allocator.nct create mode 100644 examples/ListDLU.nct create mode 100644 examples/UserListDLU.nct diff --git a/examples/Alloc.nct b/examples/Alloc.nct new file mode 100644 index 0000000..db3693a --- /dev/null +++ b/examples/Alloc.nct @@ -0,0 +1,4 @@ +record Alloc { + u8* userdata; + u8*(u8* userdata, u8* ptr, u32 sz)* realloc; +} diff --git a/examples/Allocator.nct b/examples/Allocator.nct deleted file mode 100644 index ca5d2aa..0000000 --- a/examples/Allocator.nct +++ /dev/null @@ -1,5 +0,0 @@ -record Allocator { - u8* userdata; - u8*(u8* userdata, u8* original, u32 size) realloc; -} - diff --git a/examples/ListDLU.nct b/examples/ListDLU.nct new file mode 100644 index 0000000..d23ae88 --- /dev/null +++ b/examples/ListDLU.nct @@ -0,0 +1,43 @@ +/* + * ListDLU: Dynamic, Linear growth, unmanaged +*/ + +use Alloc; + +record ListDLU[T, S; growth] { + S capacity; + S size; + T[?]* data; +} + +ListDLU_remove: [T, S; growth]u0(ListDLU[T, S; growth]* this, S index) -> { + T* data0 = &((*((*this).data))[index]); + T* data1 = data0 + @sizeof T; + S sz = (*this).size; + (*this).size = (*this).size - 1; + loop { + if(index == sz) { + break; + } + + *data0 = *data1; + + data0 = data0 + @sizeof T; + data1 = data1 + @sizeof T; + index = index + 1; + } + return; +}; + +ListDLU_add: [T, S; growth]u0(ListDLU[T, S; growth]* this, Alloc *alloc, T value) -> { + if((*this).size == (*this).capacity) { + u32 newcap = (*this).capacity + growth; + (*this).capacity = newcap; + (*this).data = ((*alloc).realloc)((*alloc).userdata, (*this).data, newcap * @sizeof T); + } + + (*((*this).data))[(*this).size] = value; + (*this).size = (*this).size + 1; + + return; +}; diff --git a/examples/UserListDLU.nct b/examples/UserListDLU.nct new file mode 100644 index 0000000..a68fd11 --- /dev/null +++ b/examples/UserListDLU.nct @@ -0,0 +1,26 @@ +use ListDLU; + +@section(".text"); + +@instantiate ListDLU_remove[u32, u32; 9]; +@instantiate ListDLU_add[u32, u32; 9]; + +extern u8*(u8* ptr, u32 sz) realloc; +libc_realloc: u8*(u8* userdata, u8* ptr, u32 sz) -> { + return realloc(ptr, sz); +}; + +main: u0() -> { + Alloc libc; + libc.realloc = &libc_realloc; + + ListDLU[u32, u32; 9] list; + ListDLU_add[u32, u32; 9](&list, &libc, 1234); + ListDLU_add[u32, u32; 9](&list, &libc, 4321); + ListDLU_add[u32, u32; 9](&list, &libc, 7777); + ListDLU_add[u32, u32; 9](&list, &libc, 6969); + ListDLU_remove[u32, u32; 9](&list, 1); + return; +}; + +@section(".bss"); diff --git a/src/x86/cg.c b/src/x86/cg.c index 484c2f5..a79712c 100644 --- a/src/x86/cg.c +++ b/src/x86/cg.c @@ -131,12 +131,14 @@ static AST *is_field_access(AST *e) { static const char *xop_sz(AST *tlc, AST *e, int sz) { #define XOPBUFS 16 -#define XOPBUFSZ 24 +#define XOPBUFSZ 32 static char bufs[XOPBUFS][XOPBUFSZ]; static int bufidx = 0; char *ret = bufs[bufidx]; + int pr = 0; + if(e->nodeKind == AST_EXPR_UNARY_OP && e->exprUnOp.operator == UNOP_DEREF) { AST *p = e->exprUnOp.operand; @@ -145,12 +147,12 @@ static const char *xop_sz(AST *tlc, AST *e, int sz) { } if(p->nodeKind == AST_EXPR_BINARY_OP && p->exprBinOp.operator == BINOP_ADD && p->exprBinOp.operands[0]->nodeKind == AST_EXPR_VAR && p->exprBinOp.operands[1]->nodeKind == AST_EXPR_VAR && p->exprBinOp.operands[0]->exprVar.thing->kind == SCOPEITEM_VAR && p->exprBinOp.operands[1]->exprVar.thing->kind == SCOPEITEM_VAR) { - snprintf(ret, XOPBUFSZ, "%s [%s + %s]", + pr = snprintf(ret, XOPBUFSZ, "%s [%s + %s]", spec(sz), xv_sz(p->exprBinOp.operands[0]->exprVar.thing, 0), xv_sz(p->exprBinOp.operands[1]->exprVar.thing, 0)); } else if(p->nodeKind == AST_EXPR_BINARY_OP && p->exprBinOp.operator == BINOP_ADD && p->exprBinOp.operands[0]->nodeKind == AST_EXPR_UNARY_OP && p->exprBinOp.operands[1]->nodeKind == AST_EXPR_VAR && p->exprBinOp.operands[0]->exprUnOp.operator == UNOP_REF && p->exprBinOp.operands[0]->exprUnOp.operand->nodeKind == AST_EXPR_VAR && p->exprBinOp.operands[0]->exprUnOp.operand->exprVar.thing->kind == SCOPEITEM_SYMBOL && p->exprBinOp.operands[1]->exprVar.thing->kind == SCOPEITEM_VAR) { - snprintf(ret, XOPBUFSZ, "%s [%s + %s]", + pr = snprintf(ret, XOPBUFSZ, "%s [%s + %s]", spec(sz), p->exprBinOp.operands[0]->exprUnOp.operand->exprVar.thing->data.symbol.name, xv_sz(p->exprBinOp.operands[1]->exprVar.thing, 0)); @@ -160,7 +162,7 @@ static const char *xop_sz(AST *tlc, AST *e, int sz) { if(e->exprBinOp.operands[0]->nodeKind == AST_EXPR_UNARY_OP) { assert(e->exprBinOp.operands[0]->exprUnOp.operator == UNOP_REF); - snprintf(ret, XOPBUFSZ, "%s [%s + %i]", + pr = snprintf(ret, XOPBUFSZ, "%s [%s + %i]", spec(sz), e->exprBinOp.operands[0]->exprUnOp.operand->exprVar.thing->data.symbol.name, e->exprBinOp.operands[1]->exprPrim.val); @@ -169,43 +171,45 @@ static const char *xop_sz(AST *tlc, AST *e, int sz) { ScopeItem *vte = e->exprBinOp.operands[0]->exprVar.thing; - snprintf(ret, XOPBUFSZ, "%s [%s + %i]", + pr = snprintf(ret, XOPBUFSZ, "%s [%s + %i]", spec(sz), REG_CLASSES[vte->data.var.registerClass].rsN[vte->data.var.color], e->exprBinOp.operands[1]->exprPrim.val); } } else if(p->nodeKind == AST_EXPR_BINARY_OP && p->exprBinOp.operator == BINOP_ADD && p->exprBinOp.operands[0]->nodeKind == AST_EXPR_UNARY_OP && p->exprBinOp.operands[1]->nodeKind == AST_EXPR_BINARY_OP && p->exprBinOp.operands[0]->exprUnOp.operator == UNOP_REF && p->exprBinOp.operands[0]->exprUnOp.operand->nodeKind == AST_EXPR_VAR && p->exprBinOp.operands[0]->exprUnOp.operand->exprVar.thing->kind == SCOPEITEM_SYMBOL && p->exprBinOp.operands[1]->exprBinOp.operator == BINOP_MUL && p->exprBinOp.operands[1]->exprBinOp.operands[1]->nodeKind == AST_EXPR_VAR && p->exprBinOp.operands[1]->exprBinOp.operands[0]->nodeKind == AST_EXPR_PRIMITIVE && p->exprBinOp.operands[1]->exprBinOp.operands[1]->exprVar.thing->kind == SCOPEITEM_VAR) { - snprintf(ret, XOPBUFSZ, "%s [%s + %i * %s]", + pr = snprintf(ret, XOPBUFSZ, "%s [%s + %i * %s]", spec(sz), p->exprBinOp.operands[0]->exprUnOp.operand->exprVar.thing->data.symbol.name, p->exprBinOp.operands[1]->exprBinOp.operands[0]->exprPrim.val, xv_sz(p->exprBinOp.operands[1]->exprBinOp.operands[1]->exprVar.thing, 0)); } else if(p->nodeKind == AST_EXPR_VAR && p->exprVar.thing->kind == SCOPEITEM_VAR) { - snprintf(ret, XOPBUFSZ, "%s [%s]", spec(sz), xv_sz(p->exprVar.thing, 0)); + pr = snprintf(ret, XOPBUFSZ, "%s [%s]", spec(sz), xv_sz(p->exprVar.thing, 0)); } else if(p->nodeKind == AST_EXPR_BINARY_OP && p->exprBinOp.operator == BINOP_ADD && p->exprBinOp.operands[0]->nodeKind == AST_EXPR_STACK_POINTER && p->exprBinOp.operands[1]->nodeKind == AST_EXPR_PRIMITIVE) { - snprintf(ret, XOPBUFSZ, "[esp + %i]", p->exprBinOp.operands[1]->exprPrim.val); + pr = snprintf(ret, XOPBUFSZ, "[esp + %i]", p->exprBinOp.operands[1]->exprPrim.val); } else { return NULL; } } else if(e->nodeKind == AST_EXPR_STACK_POINTER) { - snprintf(ret, XOPBUFSZ, "esp"); + pr = snprintf(ret, XOPBUFSZ, "esp"); } else if(e->nodeKind == AST_EXPR_VAR) { ScopeItem *v = e->exprVar.thing; if(v->kind == SCOPEITEM_VAR) { return xv_sz(v, sz); } else if(v->kind == SCOPEITEM_SYMBOL) { - snprintf(ret, XOPBUFSZ, "%s [%s]", spec(sz), v->data.symbol.name); + pr = snprintf(ret, XOPBUFSZ, "%s [%s]", spec(sz), v->data.symbol.name); } else abort(); } else if(e->nodeKind == AST_EXPR_PRIMITIVE) { - snprintf(ret, XOPBUFSZ, "%s %i", spec(type_size(e->exprPrim.type)), e->exprPrim.val); + pr = snprintf(ret, XOPBUFSZ, "%s %i", spec(type_size(e->exprPrim.type)), e->exprPrim.val); } else if(e->nodeKind == AST_EXPR_UNARY_OP && e->exprUnOp.operator == UNOP_REF && e->exprUnOp.operand->nodeKind == AST_EXPR_VAR && e->exprUnOp.operand->exprVar.thing->kind == SCOPEITEM_SYMBOL) { - snprintf(ret, XOPBUFSZ, "%s", e->exprUnOp.operand->exprVar.thing->data.symbol.name); + pr = snprintf(ret, XOPBUFSZ, "%s", e->exprUnOp.operand->exprVar.thing->data.symbol.name); } else { return NULL; } + assert(pr < XOPBUFSZ && "XOPBUF OVERFLOW"); + bufidx = (bufidx + 1) % XOPBUFS; return ret;