diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2019-10-25 17:18:41 -0400 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2019-10-25 17:18:41 -0400 |
commit | e7432359e33880e7d705d1e86397fe676e601505 (patch) | |
tree | d7a74aee21214d900825f9833f82a21840fbda56 | |
parent | 7352f2c357619e23ed348bdadd48f38f9acd4d86 (diff) |
started fixing leaking
-rw-r--r-- | allocator.c | 2 | ||||
-rw-r--r-- | eval.c | 40 | ||||
-rw-r--r-- | scope.c | 12 | ||||
-rw-r--r-- | test.toc | 14 | ||||
-rw-r--r-- | types.c | 2 |
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)) @@ -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; @@ -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 */ } @@ -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(); }; @@ -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); |