From efc9fe1406cab63098657f4f68dcd656bd4ed904 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sun, 26 Apr 2026 10:14:19 +1000 Subject: [PATCH] Tweaked stack allocation when inheriting VMs --- repl/main.c | 2 +- source/toy_stack.c | 4 +++- source/toy_vm.c | 26 ++++++++++++++------------ source/toy_vm.h | 5 ++--- tests/units/test_vm.c | 6 +++--- 5 files changed, 23 insertions(+), 20 deletions(-) diff --git a/repl/main.c b/repl/main.c index 9e01beb..3d11ab1 100644 --- a/repl/main.c +++ b/repl/main.c @@ -379,7 +379,7 @@ int repl(const char* filepath, bool verbose) { } //free the memory, and leave the VM ready for the next loop - Toy_resetVM(&vm, true); + Toy_resetVM(&vm, true, true); free(bytecode); printf("%s> ", prompt); //shows the terminal prompt diff --git a/source/toy_stack.c b/source/toy_stack.c index 0009c0a..597f1d5 100644 --- a/source/toy_stack.c +++ b/source/toy_stack.c @@ -3,8 +3,9 @@ #include #include +#include -Toy_Stack* Toy_allocateStack(void) { +Toy_Stack* Toy_allocateStack(void) { //TODO: add initial size as parameter Toy_Stack* stack = malloc(TOY_STACK_INITIAL_CAPACITY * sizeof(Toy_Value) + sizeof(Toy_Stack)); //URGENT: Swap to a bucket (4 instances) if (stack == NULL) { @@ -42,6 +43,7 @@ void Toy_resetStack(Toy_Stack** stackHandle) { //reset to the stack's default state if ((*stackHandle)->capacity > TOY_STACK_INITIAL_CAPACITY) { (*stackHandle) = realloc((*stackHandle), TOY_STACK_INITIAL_CAPACITY * sizeof(Toy_Value) + sizeof(Toy_Stack)); + memset((*stackHandle), 0, TOY_STACK_INITIAL_CAPACITY * sizeof(Toy_Value) + sizeof(Toy_Stack)); (*stackHandle)->capacity = TOY_STACK_INITIAL_CAPACITY; } diff --git a/source/toy_vm.c b/source/toy_vm.c index 9c537dd..204d71e 100644 --- a/source/toy_vm.c +++ b/source/toy_vm.c @@ -355,7 +355,7 @@ static void processInvoke(Toy_VM* vm) { case TOY_FUNCTION_CUSTOM: { //spin up a new sub-vm Toy_VM subVM; - Toy_inheritVM(&subVM, vm); + Toy_inheritVM(vm, &subVM); Toy_bindVM(&subVM, fn->bytecode.code, fn->bytecode.parentScope); //check args count @@ -1070,7 +1070,7 @@ static unsigned int process(Toy_VM* vm) { } //exposed functions -void Toy_resetVM(Toy_VM* vm, bool preserveScope) { +void Toy_resetVM(Toy_VM* vm, bool preserveScope, bool preserveStack) { vm->code = NULL; vm->jumpsCount = 0; @@ -1086,9 +1086,11 @@ void Toy_resetVM(Toy_VM* vm, bool preserveScope) { vm->programCounter = 0; - Toy_resetStack(&vm->stack); + if (!preserveStack) { + Toy_resetStack(&vm->stack); //NOTE: has a realloc() + } - if (preserveScope == false) { + if (!preserveScope) { vm->scope = Toy_popScope(vm->scope); } @@ -1103,18 +1105,18 @@ void Toy_initVM(Toy_VM* vm) { vm->parentBucketHandle = NULL; - Toy_resetVM(vm, true); + Toy_resetVM(vm, true, true); } -void Toy_inheritVM(Toy_VM* vm, Toy_VM* parent) { +void Toy_inheritVM(Toy_VM* parentVM, Toy_VM* subVM) { //inherent persistent memory - vm->scope = NULL; - vm->stack = Toy_allocateStack(); - vm->memoryBucket = parent->memoryBucket; + subVM->scope = NULL; + subVM->stack = Toy_allocateStack(); + subVM->memoryBucket = parentVM->memoryBucket; - vm->parentBucketHandle = &parent->memoryBucket; //track this to update it later + subVM->parentBucketHandle = &parentVM->memoryBucket; //track this to update it later - Toy_resetVM(vm, true); + Toy_resetVM(subVM, true, true); } void Toy_bindVM(Toy_VM* vm, unsigned char* bytecode, Toy_Scope* parentScope) { @@ -1163,7 +1165,7 @@ unsigned int Toy_runVM(Toy_VM* vm) { } void Toy_freeVM(Toy_VM* vm) { - Toy_resetVM(vm, false); + Toy_resetVM(vm, false, true); //clear the persistent memory Toy_freeStack(vm->stack); diff --git a/source/toy_vm.h b/source/toy_vm.h index 3b705b3..a0c8446 100644 --- a/source/toy_vm.h +++ b/source/toy_vm.h @@ -42,10 +42,10 @@ typedef struct Toy_VM { Toy_Bucket** parentBucketHandle; } Toy_VM; -TOY_API void Toy_resetVM(Toy_VM* vm, bool preserveScope); +TOY_API void Toy_resetVM(Toy_VM* vm, bool preserveScope, bool preserveStack); TOY_API void Toy_initVM(Toy_VM* vm); //creates memory -TOY_API void Toy_inheritVM(Toy_VM* vm, Toy_VM* parent); //inherits scope bucket +TOY_API void Toy_inheritVM(Toy_VM* parentVM, Toy_VM* subVM); //inherits scope bucket void Toy_bindVM(Toy_VM* vm, unsigned char* bytecode, Toy_Scope* parentScope); TOY_API unsigned int Toy_runVM(Toy_VM* vm); @@ -53,4 +53,3 @@ TOY_API void Toy_freeVM(Toy_VM* vm); TOY_API Toy_Array* Toy_extractResultsFromVM(Toy_VM* parentVM, Toy_VM* subVM, unsigned int resultCount); -//TODO: inject extra data (hook system for external libraries) diff --git a/tests/units/test_vm.c b/tests/units/test_vm.c index 696b39d..bef630c 100644 --- a/tests/units/test_vm.c +++ b/tests/units/test_vm.c @@ -740,7 +740,7 @@ int test_vm_reuse(Toy_Bucket** bucketHandle) { Toy_bindVM(&vm, bytecode1, NULL); Toy_runVM(&vm); - Toy_resetVM(&vm, true); + Toy_resetVM(&vm, true, false); if (callbackUtilReceived == NULL || strcmp(callbackUtilReceived, "Hello world!") != 0) { fprintf(stderr, TOY_CC_ERROR "ERROR: Unexpected value '%s' found in VM reuse run 1\n" TOY_CC_RESET, callbackUtilReceived != NULL ? callbackUtilReceived : "NULL"); @@ -760,7 +760,7 @@ int test_vm_reuse(Toy_Bucket** bucketHandle) { Toy_bindVM(&vm, bytecode2, NULL); //preserve during repeated calls Toy_runVM(&vm); - Toy_resetVM(&vm, true); + Toy_resetVM(&vm, true, false); if (callbackUtilReceived == NULL || strcmp(callbackUtilReceived, "Hello world!") != 0) { fprintf(stderr, TOY_CC_ERROR "ERROR: Unexpected value '%s' found in VM reuse run 2\n" TOY_CC_RESET, callbackUtilReceived != NULL ? callbackUtilReceived : "NULL"); @@ -780,7 +780,7 @@ int test_vm_reuse(Toy_Bucket** bucketHandle) { Toy_bindVM(&vm, bytecode3, NULL); //preserve during repeated calls Toy_runVM(&vm); - Toy_resetVM(&vm, true); + Toy_resetVM(&vm, true, false); if (callbackUtilReceived == NULL || strcmp(callbackUtilReceived, "Hello world!") != 0) { fprintf(stderr, TOY_CC_ERROR "ERROR: Unexpected value '%s' found in VM reuse run 3\n" TOY_CC_RESET, callbackUtilReceived != NULL ? callbackUtilReceived : "NULL");