diff --git a/byterun/include/module_manager.h b/byterun/include/module_manager.h index 0f2f141c3..22a7c732a 100644 --- a/byterun/include/module_manager.h +++ b/byterun/include/module_manager.h @@ -11,6 +11,8 @@ struct ModSearchResult { Bytefile *mod_file; // = NULL => not found }; +void mod_cleanup(); + void mod_add_search_path(const char *path); const char *mod_get_name(uint32_t id); diff --git a/byterun/src/cli.cpp b/byterun/src/cli.cpp index c4d17ce39..fefeb7a30 100644 --- a/byterun/src/cli.cpp +++ b/byterun/src/cli.cpp @@ -52,6 +52,7 @@ int main(int argc, char **argv) { #endif print_file(*f, std::cout); + free(f); } if (do_verification || do_interpretation) { #ifdef DEBUG_VERSION @@ -76,5 +77,7 @@ int main(int argc, char **argv) { } } + mod_cleanup(); + return 0; } diff --git a/byterun/src/interpreter.c b/byterun/src/interpreter.c index e860e3ca4..1a2517831 100644 --- a/byterun/src/interpreter.c +++ b/byterun/src/interpreter.c @@ -107,14 +107,26 @@ void run_mod_rec(uint mod_id, int argc, char **argv, bool do_verification) { run_prepare_exec(argc, argv); // args for module main run_mod(mod_id, argc, argv); + + cleanup_state(&s); } static inline void call_Barray(size_t elem_count, char** ip, void** buffer) { // size_t elem_count = ip_read_int(ip); - void **opr_buffer = (void**)(elem_count > BUFFER_SIZE + bool use_new_buffer = (elem_count > BUFFER_SIZE); + + void **opr_buffer = (void**)(use_new_buffer ? alloc(elem_count * sizeof(void *)) : buffer); + + if (use_new_buffer) { + for (size_t i = 0; i < elem_count; ++i) { + opr_buffer[i] = 0; + push_extra_root(&opr_buffer[i]); + } + } + for (size_t i = 0; i < elem_count; ++i) { opr_buffer[elem_count - i - 1] = s_pop(); } @@ -128,6 +140,13 @@ static inline void call_Barray(size_t elem_count, char** ip, void** buffer) { // void *array = Barray((aint *)s_peek(), BOX(elem_count)); s_push(array); + + if (use_new_buffer) { + for (size_t i = 0; i < elem_count; ++i) { + pop_extra_root(&opr_buffer[i]); + } + free(opr_buffer); + } } void run_mod(uint mod_id, int argc, char **argv) { @@ -218,10 +237,19 @@ void run_mod(uint mod_id, int argc, char **argv) { args_count); #endif - void **opr_buffer = (void**)(args_count >= BUFFER_SIZE + bool use_new_buffer = (args_count >= BUFFER_SIZE); + + void **opr_buffer = (void**)(use_new_buffer ? alloc((args_count + 1) * sizeof(void *)) : buffer); + if (use_new_buffer) { + for (size_t i = 0; i <= args_count; ++i) { + opr_buffer[i] = 0; + push_extra_root(&opr_buffer[i]); + } + } + // s_put_nth(args_count, (void *)LtagHash((char *)name)); for (size_t i = 1; i <= args_count; ++i) { @@ -234,6 +262,13 @@ void run_mod(uint mod_id, int argc, char **argv) { // s_popn(args_count + 1); s_push(sexp); + + if (use_new_buffer) { + for (size_t i = 0; i <= args_count; ++i) { + pop_extra_root(&opr_buffer[i]); + } + free(opr_buffer); + } break; } diff --git a/byterun/src/module_manager.cpp b/byterun/src/module_manager.cpp index 1a9f66382..27a48b9d9 100644 --- a/byterun/src/module_manager.cpp +++ b/byterun/src/module_manager.cpp @@ -79,6 +79,12 @@ uint32_t path_mod_load(const char *name, std::filesystem::path &&path, extern "C" { +void mod_cleanup() { + for (auto &mod : manager.modules) { + free(mod.bf); + } +} + void mod_add_search_path(const char *path) { manager.search_paths.emplace_back(path); } diff --git a/byterun/src/types.c b/byterun/src/types.c index 0337d6c07..e2df5881a 100644 --- a/byterun/src/types.c +++ b/byterun/src/types.c @@ -15,21 +15,20 @@ void init_state(struct State* s, void** stack) { __init(); s->stack = stack; + s->fp = NULL; s->bf = NULL; + s->current_line = 0; s->is_closure_call = false; s->current_module_id = 0; s->call_module_id = 0; s->ip = NULL; //s->bf->code_ptr; s->instr_ip = NULL; //s->bf->code_ptr; s->call_ip = NULL; - s->current_line = 0; for (size_t i = 0; i < STACK_SIZE; ++i) { s->stack[i] = NULL; } - s->fp = NULL; - __gc_stack_bottom = (size_t)(s->stack + STACK_SIZE); __gc_stack_top = __gc_stack_bottom;