From 3f30662cdea8a97799ac6579a1d6209fe4334916 Mon Sep 17 00:00:00 2001 From: Jacob Date: Sat, 10 May 2025 10:43:36 -0400 Subject: [PATCH] Fixed some memory bugs. --- src/ast.c | 15 ++++++++++++++- src/exec.c | 40 ++++++++++++++++++++++++++++++++++++---- src/htab.c | 3 +-- src/include/exec.h | 6 ++++++ src/include/scope.h | 5 +++-- src/scope.c | 7 +++++++ test/Unity | 2 +- 7 files changed, 68 insertions(+), 10 deletions(-) diff --git a/src/ast.c b/src/ast.c index 360cecd..10f1be6 100644 --- a/src/ast.c +++ b/src/ast.c @@ -53,7 +53,20 @@ void ast_destroy(AST* ast) { log_dbgf("Unknown ast type %d (max: %d)", ast->type, AST_TYPE_MAX); } - scope_destroy_psv(ast->scope); + // If there're no more `AST`s linked to the scope, free. + if (ast->scope) { + log_dbgf("%p: there is scope.", ast->scope); + ast->scope->uses--; + log_dbgf( + "%p: were %d uses, now %d", ast->scope, ast->scope->uses + 1, + ast->scope->uses + ); + if (!ast->scope->uses) { + log_dbgf("%p: no more uses, gonna free", ast->scope); + scope_destroy_psv(ast->scope); + } + } + free(ast); } diff --git a/src/exec.c b/src/exec.c index 4b5987e..6c167be 100644 --- a/src/exec.c +++ b/src/exec.c @@ -13,6 +13,9 @@ AST* exec_start(AST* ast) { log_dbg("Started execution."); Scope* global = scope_init(NULL); + global->uses = 1; + + // Maybe root ast here should set global as scope? for (int i = 0; i < BUILTIN_FNS_LN; i++) htab_ins( @@ -22,7 +25,10 @@ AST* exec_start(AST* ast) { log_dbg("Completed startup sequence."); - return exec_exp(ast, global); + AST* res = exec_exp(ast, global); + log_dbgf("global addr %p uses %d", global, global->uses); + scope_destroy_psv(global); + return res; } AST* exec_exp(AST* ast, Scope* parent) { @@ -41,7 +47,10 @@ AST* exec_block(AST* ast, Scope* parent) { ASTBlockData* block = (ASTBlockData*)ast->data; // Blocks create their own scope, shared among their expressions. - ast->scope = scope_init(parent); + // ast->scope = scope_init(parent); + + // HERE + exec_new_scope(ast, parent); // Loop through all but last ast. for (int i = 0; i < block->ln - 1; i++) @@ -91,7 +100,11 @@ AST* exec_cf(AST* ast, size_t argc, AST** argv) { AST* exec_vdef(AST* ast, Scope* parent) { // Use parent's scope. - ast->scope = parent; + // ast->scope = parent; + + // HERE + exec_inherit_scope(ast, parent); + ASTVDefData* data = (ASTVDefData*)ast->data; AST* val = data->val; char* key = data->name; @@ -101,7 +114,10 @@ AST* exec_vdef(AST* ast, Scope* parent) { AST* exec_vref(AST* ast, Scope* parent) { // Use parent's scope. - ast->scope = parent; + // ast->scope = parent; + + // HERE + exec_inherit_scope(ast, parent); log_dbg("attempting to reference var"); ASTVrefData* vref = (ASTVrefData*)ast->data; @@ -130,3 +146,19 @@ AST* exec_fdef(AST* ast, Scope* parent) { } void exec_print(double n) { printf("= %lf\n", n); } + +inline void exec_new_scope(AST* ast, Scope* inherit) { + Scope* scope = scope_init(inherit); + ast->scope = scope; + + // Update linked status. + scope->uses++; + // if (inherit) inherit->uses++; +} + +inline void exec_inherit_scope(AST* ast, Scope* inherit) { + ast->scope = inherit; + + // Update uses. + inherit->uses++; +} diff --git a/src/htab.c b/src/htab.c index 300b74d..76a8cfc 100644 --- a/src/htab.c +++ b/src/htab.c @@ -12,8 +12,7 @@ HTab* htab_init() { return htab; } -void htab_destroy(HTab* htab) { // free(htab); -} +void htab_destroy(HTab* htab) { free(htab); } // Get the index of a key. size_t geti(char* key) { diff --git a/src/include/exec.h b/src/include/exec.h index abfd6df..8836e21 100644 --- a/src/include/exec.h +++ b/src/include/exec.h @@ -23,4 +23,10 @@ AST* exec_fdef(AST* ast, Scope* parent); // Print the result of an execution. void exec_print(double n); +// Create a new scope and mark it as linked. Also update inherited scope. +void exec_new_scope(AST* ast, Scope* inherit); + +// Inherit from another scope and mark it as linked. +void exec_inherit_scope(AST* ast, Scope* inherit); + #endif diff --git a/src/include/scope.h b/src/include/scope.h index 9df1a9f..b91490a 100644 --- a/src/include/scope.h +++ b/src/include/scope.h @@ -5,8 +5,9 @@ // Represents the reverse linked tree of scope. typedef struct SCOPE_T { - HTab* here; - struct SCOPE_T* inherit; + HTab* here; // This scope's hash table. + struct SCOPE_T* inherit; // The scope to inherit from. + int uses; // How many `AST`s are linked to this scope. } Scope; // Create a new `Scope`. Creates new empty `HTab` for current scope. diff --git a/src/scope.c b/src/scope.c index 02c1b5f..51d3d90 100644 --- a/src/scope.c +++ b/src/scope.c @@ -1,5 +1,7 @@ #include "include/scope.h" #include "include/htab.h" +#include "include/util.h" +#include #include Scope* scope_init(Scope* inherit) { @@ -7,6 +9,9 @@ Scope* scope_init(Scope* inherit) { scope->here = htab_init(); scope->inherit = inherit; + scope->uses = 0; + + log_dbgf("%p: new scope, inherits from %p", scope, inherit); return scope; } @@ -19,10 +24,12 @@ void scope_destroy(Scope* scope) { } void scope_destroy_psv(Scope* scope) { + log_dbgf("%p got here", scope); if (!scope) return; htab_destroy(scope->here); scope->inherit = NULL; free(scope); + log_dbgf("%p got here 2", scope); } inline void scope_add(Scope* scope, char* key, void* val) { diff --git a/test/Unity b/test/Unity index cdf1d02..73237c5 160000 --- a/test/Unity +++ b/test/Unity @@ -1 +1 @@ -Subproject commit cdf1d0297effc2736ee847e557b4275b4f02310b +Subproject commit 73237c5d224169c7b4d2ec8321f9ac92e8071708