From c9a34e2259320858670f9015d899cd78a517dbc9 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sun, 26 Apr 2026 09:55:11 +1000 Subject: [PATCH] Corrected usage of 'Toy_allocateTable' --- repl/main.c | 2 +- source/toy_array.c | 2 +- source/toy_scope.c | 2 +- source/toy_stack.c | 2 +- source/toy_table.c | 17 ++++++++++++++--- source/toy_table.h | 2 +- source/toy_value.c | 2 +- source/toy_vm.c | 17 ++--------------- tests/units/test_table.c | 30 +++++++++++++++--------------- 9 files changed, 37 insertions(+), 39 deletions(-) diff --git a/repl/main.c b/repl/main.c index 988c39c..9e01beb 100644 --- a/repl/main.c +++ b/repl/main.c @@ -206,7 +206,7 @@ CmdLine parseCmdLine(int argc, const char* argv[]) { //total space to reserve cmd.infileLength = strlen(argv[i]) + 1; - cmd.infileLength = (cmd.infileLength + 3) & ~3; //BUGFIX: align to word size for malloc() + cmd.infileLength = (cmd.infileLength + 3) & ~3; //BUGFIX: align to word size cmd.infile = malloc(cmd.infileLength); if (cmd.infile == NULL) { diff --git a/source/toy_array.c b/source/toy_array.c index aa778f4..fcaa60f 100644 --- a/source/toy_array.c +++ b/source/toy_array.c @@ -20,7 +20,7 @@ Toy_Array* Toy_resizeArray(Toy_Array* paramArray, unsigned int capacity) { unsigned int originalCapacity = paramArray == NULL ? 0 : paramArray->capacity; - Toy_Array* array = realloc(paramArray, capacity * sizeof(Toy_Value) + sizeof(Toy_Array)); + Toy_Array* array = realloc(paramArray, capacity * sizeof(Toy_Value) + sizeof(Toy_Array)); //URGENT: Swap to a bucket if (array == NULL) { fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to resize a 'Toy_Array' from %d to %d capacity\n" TOY_CC_RESET, (int)originalCapacity, (int)capacity); diff --git a/source/toy_scope.c b/source/toy_scope.c index 68f0e49..f65412b 100644 --- a/source/toy_scope.c +++ b/source/toy_scope.c @@ -71,7 +71,7 @@ static void probeAndInsert(Toy_Scope* scope, Toy_String* key, Toy_Value value, T static Toy_ScopeEntry* adjustScopeEntries(Toy_Scope* scope, unsigned int newCapacity) { //allocate and zero a new Toy_ScopeEntry array in memory - Toy_ScopeEntry* newEntries = malloc(newCapacity * sizeof(Toy_ScopeEntry)); //URGENT: could use a bucket instead? + Toy_ScopeEntry* newEntries = malloc(newCapacity * sizeof(Toy_ScopeEntry)); //URGENT: Swap to a bucket if (newEntries == NULL) { fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to allocate space for 'Toy_Scope' entries\n" TOY_CC_RESET); diff --git a/source/toy_stack.c b/source/toy_stack.c index 763deba..0009c0a 100644 --- a/source/toy_stack.c +++ b/source/toy_stack.c @@ -5,7 +5,7 @@ #include Toy_Stack* Toy_allocateStack(void) { - Toy_Stack* stack = malloc(TOY_STACK_INITIAL_CAPACITY * sizeof(Toy_Value) + sizeof(Toy_Stack)); + Toy_Stack* stack = malloc(TOY_STACK_INITIAL_CAPACITY * sizeof(Toy_Value) + sizeof(Toy_Stack)); //URGENT: Swap to a bucket (4 instances) if (stack == NULL) { fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to allocate a 'Toy_Stack' of %d capacity (%d space in memory)\n" TOY_CC_RESET, TOY_STACK_INITIAL_CAPACITY, (int)(TOY_STACK_INITIAL_CAPACITY * sizeof(Toy_Value) + sizeof(Toy_Stack))); diff --git a/source/toy_table.c b/source/toy_table.c index 6d37b99..65420fd 100644 --- a/source/toy_table.c +++ b/source/toy_table.c @@ -46,7 +46,7 @@ static void probeAndInsert(Toy_Table** tableHandle, Toy_Value key, Toy_Value val //exposed functions Toy_Table* Toy_private_adjustTableCapacity(Toy_Table* oldTable, unsigned int newCapacity) { //allocate and zero a new table in memory - Toy_Table* newTable = malloc(newCapacity * sizeof(Toy_TableEntry) + sizeof(Toy_Table)); + Toy_Table* newTable = malloc(newCapacity * sizeof(Toy_TableEntry) + sizeof(Toy_Table)); //URGENT: Swap to a bucket if (newTable == NULL) { fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to allocate a 'Toy_Table'\n" TOY_CC_RESET); @@ -76,8 +76,19 @@ Toy_Table* Toy_private_adjustTableCapacity(Toy_Table* oldTable, unsigned int new return newTable; } -Toy_Table* Toy_allocateTable(void) { - return Toy_private_adjustTableCapacity(NULL, TOY_TABLE_INITIAL_CAPACITY); +Toy_Table* Toy_allocateTable(unsigned int minCapacity) { + minCapacity = minCapacity > TOY_TABLE_INITIAL_CAPACITY ? minCapacity : TOY_TABLE_INITIAL_CAPACITY; + + //neat trick to find the next power of two, inclusive + minCapacity--; + minCapacity |= minCapacity >> 1; + minCapacity |= minCapacity >> 2; + minCapacity |= minCapacity >> 4; + minCapacity |= minCapacity >> 8; + minCapacity |= minCapacity >> 16; + minCapacity++; + + return Toy_private_adjustTableCapacity(NULL, minCapacity); } void Toy_freeTable(Toy_Table* table) { diff --git a/source/toy_table.h b/source/toy_table.h index 4335b5a..ee85d4b 100644 --- a/source/toy_table.h +++ b/source/toy_table.h @@ -18,7 +18,7 @@ typedef struct Toy_Table { //32 | 64 BITNESS Toy_TableEntry data[]; //- | - } Toy_Table; //12 | 12 -TOY_API Toy_Table* Toy_allocateTable(void); +TOY_API Toy_Table* Toy_allocateTable(unsigned int minCapacity); //minCapacity of 0 uses the default TOY_API void Toy_freeTable(Toy_Table* table); TOY_API void Toy_insertTable(Toy_Table** tableHandle, Toy_Value key, Toy_Value value); TOY_API Toy_Value Toy_lookupTable(Toy_Table** tableHandle, Toy_Value key); diff --git a/source/toy_value.c b/source/toy_value.c index 91410f1..e5689dc 100644 --- a/source/toy_value.c +++ b/source/toy_value.c @@ -122,7 +122,7 @@ Toy_Value Toy_copyValue(Toy_Bucket** bucketHandle, Toy_Value value) { case TOY_VALUE_TABLE: { //TODO: switch to buckets //tables probably won't get copied much Toy_Table* ptr = value.as.table; - Toy_Table* result = Toy_private_adjustTableCapacity(NULL, ptr->capacity); + Toy_Table* result = Toy_allocateTable(ptr->capacity); for (unsigned int i = 0; i < ptr->capacity; i++) { if (TOY_VALUE_IS_NULL(ptr->data[i].key) != true) { diff --git a/source/toy_vm.c b/source/toy_vm.c index df0c3fa..9c537dd 100644 --- a/source/toy_vm.c +++ b/source/toy_vm.c @@ -121,21 +121,8 @@ static void processRead(Toy_VM* vm) { //the number of values to read from the stack unsigned int count = (unsigned int)READ_INT(vm); - //capacity covers keys AND values - unsigned int capacity = count / 2; - capacity = capacity > TOY_TABLE_INITIAL_CAPACITY ? capacity : TOY_TABLE_INITIAL_CAPACITY; - - //neat trick to find the next power of two, inclusive (restriction of the table system) - capacity--; - capacity |= capacity >> 1; - capacity |= capacity >> 2; - capacity |= capacity >> 4; - capacity |= capacity >> 8; - capacity |= capacity >> 16; - capacity++; - - //create the table and read in the key-values - Toy_Table* table = Toy_private_adjustTableCapacity(NULL, capacity); + //create the table (count covers keys AND values) + Toy_Table* table = Toy_allocateTable(count / 2); //read in backwards from the stack for (unsigned int i = 0; i < count / 2; i++) { diff --git a/tests/units/test_table.c b/tests/units/test_table.c index a88a450..c7340d7 100644 --- a/tests/units/test_table.c +++ b/tests/units/test_table.c @@ -7,7 +7,7 @@ int test_table_allocation(void) { //allocate and free a table { //setup - Toy_Table* table = Toy_allocateTable(); + Toy_Table* table = Toy_allocateTable(0); //check if (table == NULL) @@ -28,7 +28,7 @@ int test_table_simple_insert_lookup_and_remove(void) { //simple insert { //setup - Toy_Table* table = Toy_allocateTable(); + Toy_Table* table = Toy_allocateTable(0); Toy_Value key = TOY_VALUE_FROM_INTEGER(1); Toy_Value value = TOY_VALUE_FROM_INTEGER(42); @@ -90,7 +90,7 @@ int test_table_contents_no_expansion(void) { //single insert { //setup - Toy_Table* table = Toy_allocateTable(); + Toy_Table* table = Toy_allocateTable(0); //insert a key and value Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(1), TOY_VALUE_FROM_INTEGER(42)); @@ -115,7 +115,7 @@ int test_table_contents_no_expansion(void) { //multiple inserts, no collisions { //setup - Toy_Table* table = Toy_allocateTable(); + Toy_Table* table = Toy_allocateTable(0); //inserts Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(1), TOY_VALUE_FROM_INTEGER(42)); //hash: 7 @@ -144,7 +144,7 @@ int test_table_contents_no_expansion(void) { //multiple inserts, with collisions { //setup - Toy_Table* table = Toy_allocateTable(); + Toy_Table* table = Toy_allocateTable(0); //inserts Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(5), TOY_VALUE_FROM_INTEGER(42)); //hash: 2 @@ -175,7 +175,7 @@ int test_table_contents_no_expansion(void) { //multiple inserts, with collisions, modulo wrap { //setup - Toy_Table* table = Toy_allocateTable(); + Toy_Table* table = Toy_allocateTable(0); //inserts Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(1), TOY_VALUE_FROM_INTEGER(42)); //hash: 7 @@ -207,7 +207,7 @@ int test_table_contents_no_expansion(void) { //lookup, with collisions, modulo wrap { //setup - Toy_Table* table = Toy_allocateTable(); + Toy_Table* table = Toy_allocateTable(0); //inserts Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(17), TOY_VALUE_FROM_INTEGER(42)); //hash: 7 @@ -238,7 +238,7 @@ int test_table_contents_no_expansion(void) { //multiple inserts, with collisions, modulo wrap, psl overlap { //setup - Toy_Table* table = Toy_allocateTable(); + Toy_Table* table = Toy_allocateTable(0); //inserts Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(17), TOY_VALUE_FROM_INTEGER(42)); //hash: 7 @@ -269,7 +269,7 @@ int test_table_contents_no_expansion(void) { //multiple inserts, with collisions, modulo wrap, psl overlap, psl shift { //setup - Toy_Table* table = Toy_allocateTable(); + Toy_Table* table = Toy_allocateTable(0); //inserts Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(17), TOY_VALUE_FROM_INTEGER(42)); //hash: 7 @@ -306,7 +306,7 @@ int test_table_contents_with_expansions(void) { //simple expansion { //setup - Toy_Table* table = Toy_allocateTable(); + Toy_Table* table = Toy_allocateTable(0); //insert a key and value for (int i = 0; i < 20; i++) { @@ -331,7 +331,7 @@ int test_table_contents_with_expansions(void) { //expansion, multiple inserts, no collisions { //setup - Toy_Table* table = Toy_allocateTable(); + Toy_Table* table = Toy_allocateTable(0); //inserts Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(0), TOY_VALUE_FROM_INTEGER(42)); //hash: 0 @@ -395,7 +395,7 @@ int test_table_contents_with_expansions(void) { //multiple inserts, with collisions { //setup - Toy_Table* table = Toy_allocateTable(); + Toy_Table* table = Toy_allocateTable(0); //inserts Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(0), TOY_VALUE_FROM_INTEGER(42)); //hash: 0 @@ -464,7 +464,7 @@ int test_table_contents_with_expansions(void) { //multiple inserts, with collisions, modulo wrap { //setup - Toy_Table* table = Toy_allocateTable(); + Toy_Table* table = Toy_allocateTable(0); //inserts Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(123), TOY_VALUE_FROM_INTEGER(42)); //hash: 20 @@ -533,7 +533,7 @@ int test_table_contents_with_expansions(void) { //lookup, with collisions, modulo wrap { //setup - Toy_Table* table = Toy_allocateTable(); + Toy_Table* table = Toy_allocateTable(0); //inserts for (int i = 0; i < 20; i++) { //enough to expand @@ -573,7 +573,7 @@ int test_table_expansions_under_stress(void) { //multiple expansions, find one value { //setup - Toy_Table* table = Toy_allocateTable(); + Toy_Table* table = Toy_allocateTable(0); int top = 300;