summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--allocator.c2
-rw-r--r--eval.c40
-rw-r--r--scope.c12
-rw-r--r--test.toc14
-rw-r--r--types.c2
5 files changed, 54 insertions, 16 deletions
diff --git a/allocator.c b/allocator.c
index 14b1a40..588483a 100644
--- a/allocator.c
+++ b/allocator.c
@@ -1,4 +1,4 @@
-#define NO_ALLOCATOR 1 /* useful for debugging; valgrind checks writing past the end of a malloc, but that won't work with an allocator */
+/* #define NO_ALLOCATOR 1 /\* useful for debugging; valgrind checks writing past the end of a malloc, but that won't work with an allocator *\/ */
/* number of bytes a page hold, not including the header */
#define PAGE_BYTES (16384 - sizeof(Page))
#define PAGE_MAX_ALIGNS (PAGE_BYTES / sizeof(max_align_t))
diff --git a/eval.c b/eval.c
index 564d409..f742e0a 100644
--- a/eval.c
+++ b/eval.c
@@ -141,7 +141,11 @@ static void u64_to_val(Value *v, BuiltinType v_type, U64 x) {
i64_to_val(v, v_type, (I64)x);
}
-static void val_copy(Value *dest, Value *src, Type *t) {
+/*
+IMPORTANT: Only pass an evaluator if you want it to use its allocator.
+Otherwise, pass NULL.
+*/
+static void val_copy(Evaluator *ev, Value *dest, Value *src, Type *t) {
switch (t->kind) {
case TYPE_BUILTIN:
case TYPE_FN:
@@ -153,17 +157,41 @@ static void val_copy(Value *dest, Value *src, Type *t) {
break;
case TYPE_ARR: {
size_t bytes = t->arr.n * compiler_sizeof(t->arr.of);
- dest->arr = err_malloc(bytes);
+ if (ev)
+ dest->arr = evalr_malloc(ev, bytes);
+ else
+ dest->arr = err_malloc(bytes);
memcpy(dest->arr, src->arr, bytes);
} break;
case TYPE_TUPLE: {
size_t bytes = arr_len(t->tuple) * sizeof(*dest->tuple);
- dest->tuple = malloc(bytes);
+ if (ev)
+ dest->tuple = evalr_malloc(ev, bytes);
+ else
+ dest->tuple = err_malloc(bytes);
memcpy(dest->tuple, src->tuple, bytes);
} break;
}
}
+static void val_free(Value *v, Type *t) {
+ switch (t->kind) {
+ case TYPE_BUILTIN:
+ case TYPE_FN:
+ case TYPE_PTR:
+ case TYPE_SLICE:
+ case TYPE_VOID:
+ case TYPE_UNKNOWN:
+ break;
+ case TYPE_ARR:
+ free(v->arr);
+ break;
+ case TYPE_TUPLE:
+ free(v->tuple);
+ break;
+ }
+}
+
#define builtin_casts_to_int(x) \
case BUILTIN_I8: \
vout->i8 = (I8)vin->x; break; \
@@ -946,13 +974,13 @@ static bool eval_decl(Evaluator *ev, Declaration *d) {
arr_foreach(d->idents, Identifier, i) {
IdentDecl *id = ident_decl(*i);
if (has_expr && d->expr.kind == EXPR_TUPLE) {
- val_copy(&id->val, &val.tuple[index], &d->type.tuple[index]);
+ val_copy(ev, &id->val, &val.tuple[index], &d->type.tuple[index]);
index++;
} else if (!has_expr && d->type.kind == TYPE_ARR) {
/* "stack" array */
id->val.arr = err_calloc(d->type.arr.n, compiler_sizeof(d->type.arr.of));
} else {
- val_copy(&id->val, &val, &d->type);
+ val_copy(ev, &id->val, &val, &d->type);
}
id->flags |= IDECL_FLAG_HAS_VAL;
}
@@ -993,7 +1021,7 @@ static bool eval_block(Evaluator *ev, Block *b, Type *t, Value *v) {
if (!eval_expr(ev, b->ret_expr, returning))
return false;
}
- if (returning) val_copy(v, returning, t);
+ if (returning) val_copy(NULL, v, returning, t); /* LEAK */adfjfhskjdahfkj
block_exit(b, b->stmts);
return true;
diff --git a/scope.c b/scope.c
index e715cc3..8aed1a8 100644
--- a/scope.c
+++ b/scope.c
@@ -1,5 +1,8 @@
#define SCOPE_FLAG_CHECK_REDECL 0x0001
+
+static void val_free(Value *v, Type *t);
+
static bool add_ident_decls(Block *b, Declaration *d, U32 flags) {
bool ret = true;
arr_foreach(d->idents, Identifier, ident) {
@@ -20,17 +23,16 @@ static bool add_ident_decls(Block *b, Declaration *d, U32 flags) {
}
static void remove_ident_decls(Block *b, Declaration *d) {
+ U64 i = 0;
arr_foreach(d->idents, Identifier, ident) {
IdentTree *id_info = *ident;
IdentDecl **decls = &id_info->decls;
IdentDecl *last_decl = arr_last(*decls);
if (last_decl && last_decl->scope == b) {
if ((last_decl->flags & IDECL_FLAG_HAS_VAL)
- /* don't free const arrays (there's only one per decl) */
- && !(last_decl->decl->flags & DECL_FLAG_CONST)
- && last_decl->decl->type.kind == TYPE_ARR) {
- /* free array on stack */
- free(last_decl->val.arr);
+ /* don't free const vals (there's only one per decl) */
+ && !(last_decl->decl->flags & DECL_FLAG_CONST)) {
+ val_free(&last_decl->decl->val, d->type.kind == TYPE_TUPLE ? &d->type.tuple[i++] : &d->type);
}
arr_remove_last(decls); /* remove that declaration */
}
diff --git a/test.toc b/test.toc
index 15d782a..b865734 100644
--- a/test.toc
+++ b/test.toc
@@ -36,8 +36,16 @@ pascal @= fn() [N][]int {
x
};
+foo @= fn() [3]int {
+ x : [3]int;
+ x[0] = 0;
+ x[1] = 1;
+ x[2] = 2;
+ x
+};
+
main @= fn() {
- ptriangle @= pascal();
- puti(ptriangle[49][25]);
-
+ // ptriangle @= pascal();
+ // puti(ptriangle[49][25]);
+ x @= foo();
};
diff --git a/types.c b/types.c
index d93770f..aeea037 100644
--- a/types.c
+++ b/types.c
@@ -705,7 +705,7 @@ static bool types_expr(Typer *tr, Expression *e) {
FnExpr *fn_decl = NULL;
Expression *new_args = NULL;
arr_set_lena(&new_args, nparams, &tr->allocr);
- bool *params_set = typer_calloc(tr, nparams, sizeof *params_set);
+ bool *params_set = nparams ? typer_calloc(tr, nparams, sizeof *params_set) : NULL;
if (f->kind == EXPR_IDENT) {
IdentDecl *decl = ident_decl(f->ident);
assert(decl);