From: cassowarii <2374677+cassowarii@users.noreply.github.com> Date: Sun, 5 Jul 2026 22:56:44 +0000 (-0700) Subject: fix a couple errant oversights, squash a few memory leaks X-Git-Url: https://git.cassowary.me/gitweb.cgi?a=commitdiff_plain;h=8ec1e4d7a95984858e56d527f677f196341a8b81;p=sarabande.git fix a couple errant oversights, squash a few memory leaks --- diff --git a/src/compile/emit.c b/src/compile/emit.c index ffee6d2..cb3688e 100644 --- a/src/compile/emit.c +++ b/src/compile/emit.c @@ -84,6 +84,11 @@ void compile_chunk(sbVmCompiler *cm, sbIrChunk *chunk) { /* TODO re-add checking this */ //EMIT(BC_NUMARG); //EARG(chunk->num_args); + + if (chunk->num_args == 0) { + /* if no arguments, pop the 0 off the stack. TODO we need to check it's the right amount */ + EMIT(BC_POP); + } } if (chunk->variable_count > 0) { diff --git a/src/compile/ir.c b/src/compile/ir.c index 6bd6545..4bd7a47 100644 --- a/src/compile/ir.c +++ b/src/compile/ir.c @@ -26,6 +26,7 @@ void sbIrProgram_initialize(hIrProgram ir, usize initial_arena_size) { sbArena_initialize(&ir->arena, initial_arena_size); sbBuffer_initialize(&ir->chunks, 4096); sbBuffer_initialize(&ir->varmapping, 4096); + sbBuffer_initialize(&ir->buffers, 4096); } void sbIrProgram_deinitialize(hIrProgram ir) { @@ -35,8 +36,14 @@ void sbIrProgram_deinitialize(hIrProgram ir) { chunk_deinitialize(ck); } - sbArena_deinitialize(&ir->arena); sbBuffer_deinitialize(&ir->chunks); + sbBuffer_deinitialize(&ir->varmapping); + BUFFER_ITER(ir->buffers, sbBuffer*, buf) { + sbBuffer_deinitialize(*buf); + } + sbBuffer_deinitialize(&ir->buffers); + sbArena_deinitialize(&ir->arena); + *ir = (sbIrProgram) {0}; } @@ -71,6 +78,11 @@ static void chunk_error(hIrChunk ck, const char *error, ...) { va_end(args); } +static void init_buffer(hIrProgram ir, sbBuffer *b, usize capacity) { + sbBuffer_initialize(b, capacity); + sbBuffer_append(&ir->buffers, &b, sizeof(sbBuffer*)); +} + static sbIrChunk *new_chunk(hIrProgram ir) { usize nchunks = ir->chunks.size / sizeof(sbIrChunk*); sbIrChunk *chunk = sbArena_alloc(&ir->arena, sizeof(sbIrChunk)); @@ -92,6 +104,7 @@ static sbIrChunk *new_chunk(hIrProgram ir) { static void chunk_deinitialize(hIrChunk ck) { sbBuffer_deinitialize(&ck->stmts); + sbBuffer_deinitialize(&ck->closed_vars); } /* find variables that already exist */ @@ -270,18 +283,18 @@ static sbIrExpr *expr_func(hIrChunk ck, sbIrChunk *func) { * set, but if we have multiple functions closing over different variables we * need to know which is which, and also these closed variables might be upvalues * to ck as well. */ - sbBuffer bound; - sbBuffer_initialize(&bound, 256); + sbIrExpr *e = new_expr(ck, &(sbIrExpr) { + .type = IR_E_FUNC, + .func.chunk = func, + }); + + init_buffer(ck->program, &e->func.bound, 256); BUFFER_ITER(func->closed_vars, sbIrVariable*, var) { sbIrVariable *outer_ref = bind_upvalue(ck, (*var)->mapping_index); - sbBuffer_append(&bound, &outer_ref, sizeof(sbIrVariable*)); + sbBuffer_append(&e->func.bound, &outer_ref, sizeof(sbIrVariable*)); } - return new_expr(ck, &(sbIrExpr) { - .type = IR_E_FUNC, - .func.chunk = func, - .func.bound = bound, - }); + return e; } static flag int_constant_fold(sbAstOp op, hInteger left, hInteger right, hInteger *result) { diff --git a/src/compile/ir.h b/src/compile/ir.h index a1044fc..99bb029 100644 --- a/src/compile/ir.h +++ b/src/compile/ir.h @@ -153,6 +153,7 @@ typedef struct sbIrProgram { sbArena arena; sbBuffer varmapping; sbBuffer chunks; + sbBuffer buffers; i32 error_count; } sbIrProgram; diff --git a/src/compile/print_ir.c b/src/compile/print_ir.c index 8643d0a..9a86a62 100644 --- a/src/compile/print_ir.c +++ b/src/compile/print_ir.c @@ -75,7 +75,9 @@ static void print_expr(sbIrExpr *e) { debug("CALL: "); print_expr(e->call.func); debug(" with params ("); - print_expr(e->call.param); + if (e->call.param) { + print_expr(e->call.param); + } debug(")"); break; case IR_E_SEND: diff --git a/src/data/data.c b/src/data/data.c index 9d8d5a9..49817ce 100644 --- a/src/data/data.c +++ b/src/data/data.c @@ -7,6 +7,8 @@ #include "data/reference.h" #include "data/closure.h" +extern sbPool g_closure_pool; + void data_sys_init() { sbString_sys_init(); sbHash_sys_init(); @@ -20,7 +22,7 @@ void data_sys_deinit() { sbList_sys_deinit(); sbSymbol_sys_deinit(); sbRef_sys_deinit(); - sbClosure_sys_init(); + sbClosure_sys_deinit(); sbHash_sys_deinit(); sbString_sys_deinit(); } diff --git a/src/main.c b/src/main.c index 40701b8..b76c2eb 100644 --- a/src/main.c +++ b/src/main.c @@ -32,10 +32,10 @@ int main(int argc, char **argv) { if (parse_result == NULL) { fprintf(stderr, "fatal error: Could not open script '%s'\n", filename); - return -2; + return -1; } else if (parse_result->type == AST_ERROR) { fprintf(stderr, "fatal error: Could not run '%s' due to syntax errors.\n", filename); - return -1; + return -2; } /* syntax is valid, now try to compile */ diff --git a/src/mem/pool.c b/src/mem/pool.c index 1c7a215..990f91d 100644 --- a/src/mem/pool.c +++ b/src/mem/pool.c @@ -45,6 +45,8 @@ void sbPool_deinitialize(hPool pl) { for (usize i = 0; i < pl->num_blocks; i++) { free(pl->block_ptrs[i]); } + free(pl->block_ptrs); + free(pl->used_counts); *pl = (sbPool) {0}; } @@ -96,11 +98,13 @@ void alloc_new_block(hPool pl) { void *new_block = calloc(1, sizeof(Block) + pl->block_size + pl->elem_size * pl->block_size); if (pl->num_blocks >= pl->block_ptr_capacity) { usize new_capacity = pl->block_ptr_capacity * 2; - void **new_data = realloc(pl->block_ptrs, new_capacity); - if (!new_data) { + void **new_block_ptrs = realloc(pl->block_ptrs, new_capacity * sizeof(void*)); + u16 *new_used_counts = realloc(pl->used_counts, new_capacity * sizeof(u16)); + if (!new_block_ptrs || !new_used_counts) { PANIC("This should probably trigger the garbage collector or something!"); } - pl->block_ptrs = new_data; + pl->block_ptrs = new_block_ptrs; + pl->used_counts = new_used_counts; } pl->block_ptrs[pl->num_blocks] = new_block; diff --git a/src/parse/parser.c b/src/parse/parser.c index 09076ad..069580e 100644 --- a/src/parse/parser.c +++ b/src/parse/parser.c @@ -488,6 +488,9 @@ static sbAst parse_inside_hash(hParser pr) { put_here = &(*put_here)->seq.right; } while (expect(pr, ',')); + /* errant semicolon ok at the end of a hash because the ASI may insert it here */ + expect(pr, ';'); + return result; }