fix a couple errant oversights, squash a few memory leaks
authorcassowarii <2374677+cassowarii@users.noreply.github.com>
Sun, 5 Jul 2026 22:56:44 +0000 (15:56 -0700)
committercassowarii <2374677+cassowarii@users.noreply.github.com>
Sun, 5 Jul 2026 22:56:44 +0000 (15:56 -0700)
src/compile/emit.c
src/compile/ir.c
src/compile/ir.h
src/compile/print_ir.c
src/data/data.c
src/main.c
src/mem/pool.c
src/parse/parser.c

index ffee6d2..cb3688e 100644 (file)
@@ -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) {
index 6bd6545..4bd7a47 100644 (file)
@@ -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) {
index a1044fc..99bb029 100644 (file)
@@ -153,6 +153,7 @@ typedef struct sbIrProgram {
   sbArena arena;
   sbBuffer varmapping;
   sbBuffer chunks;
+  sbBuffer buffers;
   i32 error_count;
 } sbIrProgram;
 
index 8643d0a..9a86a62 100644 (file)
@@ -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:
index 9d8d5a9..49817ce 100644 (file)
@@ -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();
 }
index 40701b8..b76c2eb 100644 (file)
@@ -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 */
index 1c7a215..990f91d 100644 (file)
@@ -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;
index 09076ad..069580e 100644 (file)
@@ -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;
 }