Skip to content

Commit

Permalink
Merge pull request #707 from dictu-lang/feature/table
Browse files Browse the repository at this point in the history
Fix an issue with internal table type
  • Loading branch information
Jason2605 authored Dec 1, 2023
2 parents 9ce90a2 + 14196fd commit 4747121
Show file tree
Hide file tree
Showing 9 changed files with 37 additions and 41 deletions.
2 changes: 1 addition & 1 deletion src/optionals/unittest/unittest.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ static Value mockNative(DictuVM *vm, int argCount, Value *args) {
pop(vm);
push(vm, OBJ_VAL(mockedClass));

for (int i = 0; i <= klass->publicMethods.capacityMask; ++i) {
for (int i = 0; i < klass->publicMethods.capacity; ++i) {
if (klass->publicMethods.entries[i].key == NULL) {
continue;
}
Expand Down
2 changes: 1 addition & 1 deletion src/vm/datatypes/class.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ static Value methods(DictuVM *vm, int argCount, Value *args) {
ObjList *list = newList(vm);
push(vm, OBJ_VAL(list));

for (int i = 0; i <= klass->publicMethods.capacityMask; ++i) {
for (int i = 0; i < klass->publicMethods.capacity; ++i) {
if (klass->publicMethods.entries[i].key == NULL) {
continue;
}
Expand Down
4 changes: 2 additions & 2 deletions src/vm/datatypes/copy.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ ObjInstance *copyInstance(DictuVM* vm, ObjInstance *oldInstance, bool shallow) {
if (shallow) {
tableAddAll(vm, &oldInstance->publicAttributes, &instance->publicAttributes);
} else {
for (int i = 0; i <= oldInstance->publicAttributes.capacityMask; i++) {
for (int i = 0; i < oldInstance->publicAttributes.capacity; i++) {
Entry *entry = &oldInstance->publicAttributes.entries[i];
if (entry->key != NULL) {
Value val = entry->value;
Expand All @@ -90,7 +90,7 @@ ObjInstance *copyInstance(DictuVM* vm, ObjInstance *oldInstance, bool shallow) {
}
}

for (int i = 0; i <= oldInstance->privateAttributes.capacityMask; i++) {
for (int i = 0; i < oldInstance->privateAttributes.capacity; i++) {
Entry *entry = &oldInstance->privateAttributes.entries[i];
if (entry->key != NULL) {
Value val = entry->value;
Expand Down
2 changes: 1 addition & 1 deletion src/vm/datatypes/enums.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ static Value values(DictuVM *vm, int argCount, Value *args) {
ObjDict *dict = newDict(vm);
push(vm, OBJ_VAL(dict));

for (int i = 0; i < objEnum->values.capacityMask + 1; ++i) {
for (int i = 0; i < objEnum->values.capacity; ++i) {
if (objEnum->values.entries[i].key == NULL) {
continue;
}
Expand Down
10 changes: 5 additions & 5 deletions src/vm/datatypes/instance.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ static Value getAttributes(DictuVM *vm, int argCount, Value *args) {

// Walk the inheritance chain
while (klass != NULL) {
for (int i = 0; i < klass->variables.capacityMask + 1; i++) {
for (int i = 0; i < klass->variables.capacity; i++) {
if (klass->variables.entries[i].key == NULL) {
continue;
}
Expand All @@ -144,7 +144,7 @@ static Value getAttributes(DictuVM *vm, int argCount, Value *args) {
writeValueArray(vm, &fields->values, OBJ_VAL(klass->variables.entries[i].key));
}

for (int i = 0; i < klass->constants.capacityMask + 1; i++) {
for (int i = 0; i < klass->constants.capacity; i++) {
if (klass->constants.entries[i].key == NULL) {
continue;
}
Expand All @@ -170,7 +170,7 @@ static Value getAttributes(DictuVM *vm, int argCount, Value *args) {
ObjList *attributes = newList(vm);
push(vm, OBJ_VAL(attributes));

for (int i = 0; i < instance->publicAttributes.capacityMask + 1; i++) {
for (int i = 0; i < instance->publicAttributes.capacity; i++) {
if (instance->publicAttributes.entries[i].key == NULL) {
continue;
}
Expand All @@ -193,7 +193,7 @@ static Value getAttributes(DictuVM *vm, int argCount, Value *args) {
ObjList *methods = newList(vm);
push(vm, OBJ_VAL(methods));

for (int i = 0; i <= instance->klass->publicMethods.capacityMask; ++i) {
for (int i = 0; i < instance->klass->publicMethods.capacity; ++i) {
if (instance->klass->publicMethods.entries[i].key == NULL) {
continue;
}
Expand Down Expand Up @@ -295,7 +295,7 @@ static Value methods(DictuVM *vm, int argCount, Value *args) {
ObjList *list = newList(vm);
push(vm, OBJ_VAL(list));

for (int i = 0; i <= instance->klass->publicMethods.capacityMask; ++i) {
for (int i = 0; i < instance->klass->publicMethods.capacity; ++i) {
if (instance->klass->publicMethods.entries[i].key == NULL) {
continue;
}
Expand Down
6 changes: 3 additions & 3 deletions src/vm/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -550,21 +550,21 @@ ObjDict *classToDict(DictuVM *vm, Value value) {
push(vm, OBJ_VAL(methodsList));

while (klass != NULL) {
for (int i = 0; i < klass->variables.capacityMask + 1; i++) {
for (int i = 0; i < klass->variables.capacity; i++) {
if (klass->variables.entries[i].key == NULL) {
continue;
}
dictSet(vm, variablesDict, OBJ_VAL(klass->variables.entries[i].key), klass->variables.entries[i].value);
}

for (int i = 0; i < klass->constants.capacityMask + 1; i++) {
for (int i = 0; i < klass->constants.capacity; i++) {
if (klass->constants.entries[i].key == NULL) {
continue;
}
dictSet(vm, constantsDict, OBJ_VAL(klass->constants.entries[i].key), klass->constants.entries[i].value);
}

for (int i = 0; i < klass->publicMethods.capacityMask + 1; i++) {
for (int i = 0; i < klass->publicMethods.capacity; i++) {
if (klass->publicMethods.entries[i].key == NULL) {
continue;
}
Expand Down
48 changes: 22 additions & 26 deletions src/vm/table.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@

void initTable(Table *table) {
table->count = 0;
table->capacityMask = -1;
table->capacity = 0;
table->entries = NULL;
}

void freeTable(DictuVM *vm, Table *table) {
FREE_ARRAY(vm, Entry, table->entries, table->capacityMask + 1);
FREE_ARRAY(vm, Entry, table->entries, table->capacity);
initTable(table);
}

static Entry *findEntry(Entry *entries, int capacityMask,
ObjString *key) {
uint32_t index = key->hash & capacityMask;
uint32_t index = key->hash & (capacityMask - 1);
Entry *tombstone = NULL;

for (;;) {
Expand All @@ -40,30 +40,30 @@ static Entry *findEntry(Entry *entries, int capacityMask,
return entry;
}

index = (index + 1) & capacityMask;
index = (index + 1) & (capacityMask - 1);
}
}

bool tableGet(Table *table, ObjString *key, Value *value) {
if (table->count == 0) return false;

Entry *entry = findEntry(table->entries, table->capacityMask, key);
Entry *entry = findEntry(table->entries, table->capacity, key);
if (entry->key == NULL) return false;

*value = entry->value;
return true;
}

static void adjustCapacity(DictuVM *vm, Table *table, int capacityMask) {
Entry *entries = ALLOCATE(vm, Entry, capacityMask + 1);
for (int i = 0; i <= capacityMask; i++) {
Entry *entries = ALLOCATE(vm, Entry, capacityMask);
for (int i = 0; i < capacityMask; i++) {
entries[i].key = NULL;
entries[i].value = NIL_VAL;
}

table->count = 0;

for (int i = 0; i <= table->capacityMask; i++) {
for (int i = 0; i < table->capacity; i++) {
Entry *entry = &table->entries[i];
if (entry->key == NULL) continue;

Expand All @@ -73,19 +73,18 @@ static void adjustCapacity(DictuVM *vm, Table *table, int capacityMask) {
table->count++;
}

FREE_ARRAY(vm, Entry, table->entries, table->capacityMask + 1);
FREE_ARRAY(vm, Entry, table->entries, table->capacity);
table->entries = entries;
table->capacityMask = capacityMask;
table->capacity = capacityMask;
}

bool tableSet(DictuVM *vm, Table *table, ObjString *key, Value value) {
if (table->count + 1 > (table->capacityMask + 1) * TABLE_MAX_LOAD) {
// Figure out the new table size.
int capacityMask = GROW_CAPACITY(table->capacityMask + 1) - 1;
adjustCapacity(vm, table, capacityMask);
if (table->count + 1 > table->capacity * TABLE_MAX_LOAD) {
int capacity = GROW_CAPACITY(table->capacity);
adjustCapacity(vm, table, capacity);
}

Entry *entry = findEntry(table->entries, table->capacityMask, key);
Entry *entry = findEntry(table->entries, table->capacity, key);
bool isNewKey = entry->key == NULL;
entry->key = key;
entry->value = value;
Expand All @@ -99,19 +98,18 @@ bool tableDelete(DictuVM *vm, Table *table, ObjString *key) {
UNUSED(vm);
if (table->count == 0) return false;

Entry *entry = findEntry(table->entries, table->capacityMask, key);
// Find the entry.
Entry *entry = findEntry(table->entries, table->capacity, key);
if (entry->key == NULL) return false;

// Place a tombstone in the entry.
table->count--;
entry->key = NULL;
entry->value = BOOL_VAL(true);

return true;
}

void tableAddAll(DictuVM *vm, Table *from, Table *to) {
for (int i = 0; i <= from->capacityMask; i++) {
for (int i = 0; i < from->capacity; i++) {
Entry *entry = &from->entries[i];
if (entry->key != NULL) {
tableSet(vm, to, entry->key, entry->value);
Expand All @@ -127,13 +125,12 @@ ObjString *tableFindString(Table *table, const char *chars, int length,

// Figure out where to insert it in the table. Use open addressing and
// basic linear probing.

uint32_t index = hash & table->capacityMask;
uint32_t index = hash & (table->capacity - 1);

for (;;) {
Entry *entry = &table->entries[index];

if (entry->key == NULL) {
// Stop if we find an empty non-tombstone entry.
if (IS_NIL(entry->value)) return NULL;
} else if (entry->key->length == length &&
entry->key->hash == hash &&
Expand All @@ -142,13 +139,12 @@ ObjString *tableFindString(Table *table, const char *chars, int length,
return entry->key;
}

// Try the next slot.
index = (index + 1) & table->capacityMask;
index = (index + 1) & (table->capacity - 1);
}
}

void tableRemoveWhite(DictuVM *vm, Table *table) {
for (int i = 0; i <= table->capacityMask; i++) {
for (int i = 0; i < table->capacity; i++) {
Entry *entry = &table->entries[i];
if (entry->key != NULL && !entry->key->obj.isDark) {
tableDelete(vm, table, entry->key);
Expand All @@ -157,7 +153,7 @@ void tableRemoveWhite(DictuVM *vm, Table *table) {
}

void grayTable(DictuVM *vm, Table *table) {
for (int i = 0; i <= table->capacityMask; i++) {
for (int i = 0; i < table->capacity; i++) {
Entry *entry = &table->entries[i];
grayObject(vm, (Obj *) entry->key);
grayValue(vm, entry->value);
Expand Down
2 changes: 1 addition & 1 deletion src/vm/table.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ typedef struct {

typedef struct {
int count;
int capacityMask;
int capacity;
Entry *entries;
} Table;

Expand Down
2 changes: 1 addition & 1 deletion src/vm/vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2276,7 +2276,7 @@ static DictuInterpretResult run(DictuVM *vm) {
ObjClass *klass = AS_CLASS(peek(vm, 0));

// If super class is abstract, ensure we have defined all abstract methods
for (int i = 0; i < klass->abstractMethods.capacityMask + 1; i++) {
for (int i = 0; i < klass->abstractMethods.capacity; i++) {
if (klass->abstractMethods.entries[i].key == NULL) {
continue;
}
Expand Down

0 comments on commit 4747121

Please sign in to comment.