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) {
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};
}
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));
static void chunk_deinitialize(hIrChunk ck) {
sbBuffer_deinitialize(&ck->stmts);
+ sbBuffer_deinitialize(&ck->closed_vars);
}
/* find variables that already exist */
* 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) {
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};
}
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;