/** ****************************************************************************** * @file : object.cpp * @author : simon * @brief : None * @attention : None * @date : 2023/8/23 ****************************************************************************** */ #include #include #include "memory.h" #include "table.h" #include "object.h" #include "vm.h" static Obj *allocateObject(size_t size, ObjType type); static uint32_t hashString(const char *key, int length); #define ALLOCATE_OBJ(type, objectType) \ (type *) allocateObject(sizeof(type), objectType) static ObjString *allocateString(char *chars, int length, uint32_t hash) { ObjString *string = ALLOCATE_OBJ(ObjString, OBJ_STRING); string->length = length; string->chars = chars; string->hash = hash; tableSet(&vm.strings, string, NIL_VAL); return string; } ObjString *copyString(const char *chars, int length) { uint32_t hash = hashString(chars, length); ObjString *interned = tableFindString(&vm.strings, chars, length, hash); if (interned != NULL) return interned; char *heapChars = ALLOCATE(char, length + 1); memcpy(heapChars, chars, length); heapChars[length] = '\0'; return allocateString(heapChars, length, hash); } void printObject(Value value) { switch (OBJ_TYPE(value)) { case OBJ_STRING: printf("%s", AS_CSTRING(value)); break; } } ObjString *takeString(char *chars, int length) { uint32_t hash = hashString(chars, length); ObjString *interned = tableFindString(&vm.strings, chars, length, hash); if (interned != NULL) { FREE_ARRAY(char, chars, length + 1); return interned; } return allocateString(chars, length, hash); } static Obj *allocateObject(size_t size, ObjType type) { Obj *object = (Obj *) reallocate(NULL, 0, size); object->type = type; object->next = vm.objects; vm.objects = object; return object; } /// Hash 函数 -- 使用 FNV-1a 算法 /// \param key /// \param length /// \return static uint32_t hashString(const char *key, int length) { uint32_t hash = 2166136261u; for (int i = 0; i < length; i++) { hash ^= (uint8_t) key[i]; hash *= 16777619; } return hash; }