#include "object-type.h" #include "value.h" int ObjectType_Create(ObjectType* self, StringView name, ObjectType* supertype, size_t attribute_count_guess, allocator_t* allocator) { struct HashMapConfig config = HashMap_DefaultConfig(); config.allocator = allocator; int hashmap_code = HashMap_Create(&self->attributes, &config, attribute_count_guess * (1 / config.load_factor) + 1); if (hashmap_code) { return hashmap_code; } self->name = name; return EXIT_SUCCESS; } void ObjectType_Destroy(ObjectType* self) { HashMap_Destroy(&self->attributes); } int ObjectType_DefineObjectAttribute(ObjectType* self, ObjectType* attribute_type, StringView attribute_name) { ObjectTypeAttribute attribute = { .name = attribute_name, VALUETYPE_OBJECT, attribute_type, HashMap_Size(&self->attributes), }; return HashMap_Put(&self->attributes, attribute_name.source, attribute_name.length, &attribute); } int ObjectType_DefinePrimitiveAttribute(ObjectType* self, enum ValueType attribute_type, StringView attribute_name) { ObjectTypeAttribute attribute = { .name = attribute_name, attribute_type, NULL, HashMap_Size(&self->attributes), }; return HashMap_Put(&self->attributes, attribute_name.source, attribute_name.length, &attribute); } size_t ObjectType_GetAttributeCount(ObjectType* self) { return HashMap_Size(&self->attributes); } int ObjectType_ContextualDestroy(void* arg, ObjectType* self) { (void) arg; ObjectType_Destroy(self); return EXIT_SUCCESS; } size_t ObjectType_SizeQuery(void* arg, ObjectType* self) { return sizeof(*self); } typedef struct AttributeVisitorContext_s { TracingHeapVisit visit; void* visit_context; } AttributeVisitorContext; static int _ObjectType_VisitAttribute(AttributeVisitorContext* context, char* name, size_t name_length, ObjectTypeAttribute* attribute) { if (attribute->type == VALUETYPE_OBJECT) { return context->visit(context->visit_context, attribute->object_type); } return EXIT_SUCCESS; } int ObjectType_TraceReferences(void* context, ObjectType* type, TracingHeapVisit trace_callback, void* callback_context) { int trace_code = trace_callback(callback_context, type->supertype); if (trace_code != EXIT_SUCCESS) { return trace_code; } AttributeVisitorContext visitor_context = { .visit = trace_callback, .visit_context = callback_context, }; HashMap_ForEach(&type->attributes, (HashMapVisitFunction) _ObjectType_VisitAttribute, &visitor_context); return EXIT_SUCCESS; }