From ed5d627e3f8cc3d88e28897cec968e4ccd8f570b Mon Sep 17 00:00:00 2001 From: VegOwOtenks Date: Sun, 12 Jan 2025 23:30:57 +0100 Subject: [PATCH] Implemented heap-functionality for object-types --- src/interpreter.c | 51 ++++++++++++++++------------------------------- src/interpreter.h | 4 ---- src/object-type.c | 48 ++++++++++++++++++++++++++++++++++++++++---- src/object-type.h | 7 ++++++- src/object.h | 2 +- 5 files changed, 68 insertions(+), 44 deletions(-) diff --git a/src/interpreter.c b/src/interpreter.c index 72207de..102f466 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -34,22 +34,28 @@ const BuiltinFunction standard_builtin_functions[] = { }; static TracingHeapDataDestructor heap_destructors[] = { - [HEAPDATAKIND_OBJECT] = (TracingHeapDataDestructor) Object_Destroy, + [HEAPDATAKIND_OBJECT] = (TracingHeapDataDestructor) Object_Destroy, + [HEAPDATAKIND_OBJECTTYPE] = (TracingHeapDataDestructor) ObjectType_ContextualDestroy, }; static void* heap_destructor_args[] = { - [HEAPDATAKIND_OBJECT] = NULL, + [HEAPDATAKIND_OBJECT] = NULL, + [HEAPDATAKIND_OBJECTTYPE] = NULL, }; static TracingHeapSizeQuery heap_size_queries[] = { [HEAPDATAKIND_OBJECT] = (TracingHeapSizeQuery) Object_SizeQuery, + [HEAPDATAKIND_OBJECTTYPE] = (TracingHeapSizeQuery) ObjectType_SizeQuery, }; static void* heap_size_queries_args[] = { [HEAPDATAKIND_OBJECT] = NULL, + [HEAPDATAKIND_OBJECTTYPE] = NULL, }; static TracingHeapTraceData heap_trace_data[] = { [HEAPDATAKIND_OBJECT] = (TracingHeapTraceData) Object_ReferenceTrace, + [HEAPDATAKIND_OBJECTTYPE] = (TracingHeapTraceData) ObjectType_TraceReferences, }; static void* heap_trace_data_args[] = { [HEAPDATAKIND_OBJECT] = NULL, + [HEAPDATAKIND_OBJECTTYPE] = NULL, }; static void _Interpreter_WriteHeapConfig(TracingHeap* heap) @@ -339,7 +345,7 @@ int Interpreter_GetParenthesizedRange(Interpreter* self, CallFrame* top_frame, s return EXIT_SUCCESS; } -Object* _Interpreter_MakeObject(Interpreter* self, ObjectType* otype) +Object* _Interpreter_AllocateObject(Interpreter* self, ObjectType* otype) { size_t object_size = Object_AllocationSizeForType(otype); Object* new_object = TracingHeap_Allocate(&self->heap, object_size, HEAPDATAKIND_OBJECT); @@ -347,9 +353,16 @@ Object* _Interpreter_MakeObject(Interpreter* self, ObjectType* otype) return new_object; } +static ObjectType* _Interpreter_AllocateObjectType(Interpreter* self) +{ + ObjectType* new_type = TracingHeap_Allocate(&self->heap, sizeof(ObjectType), HEAPDATAKIND_OBJECTTYPE); + + return new_type; +} + static int _Interpreter_ConstructString(Interpreter* self, StringView view) { - Object* string_head = _Interpreter_MakeObject(self, self->native_list_type); + // TODO: Implement this return EXIT_SUCCESS; } @@ -687,36 +700,6 @@ int Interpreter_Run(Interpreter* self) int Interpreter_Startup(Interpreter* self, CallFrame* root_frame) { - ObjectType* base_type = CallFrame_Reserve(root_frame, sizeof(ObjectType), alignof(ObjectType)); - if (ObjectType_Create(base_type, StringView_FromString("Base"), base_type, 0, NULL)) { - return ENOMEM; - } - - ObjectType* list_type = CallFrame_Reserve(root_frame, sizeof(ObjectType), alignof(ObjectType)); - if (ObjectType_Create(list_type, StringView_FromString("List"), base_type, 2, NULL)) { - return ENOMEM; - } - if (ObjectType_DefineObjectAttribute(list_type, base_type, StringView_FromString("value"))) { - return ENOMEM; - } - if (ObjectType_DefineObjectAttribute(list_type, list_type, StringView_FromString("tail"))) { - return ENOMEM; - } - if (CallFrame_DefineObjectType(root_frame, list_type)) { - return ENOMEM; - } - - ObjectType* char_type = CallFrame_Reserve(root_frame, sizeof(ObjectType), alignof(ObjectType)); - if (ObjectType_Create(char_type, StringView_FromString("Char"), base_type, 2, NULL)) { - return ENOMEM; - } - if (ObjectType_DefinePrimitiveAttribute(list_type, VALUETYPE_BYTE, StringView_FromString("char"))) { - return ENOMEM; - } - - self->implicit_char_type = char_type; - self->implicit_base_type = base_type; - self->native_list_type = list_type; return EXIT_SUCCESS; } diff --git a/src/interpreter.h b/src/interpreter.h index e86822d..5bc7d8d 100644 --- a/src/interpreter.h +++ b/src/interpreter.h @@ -23,10 +23,6 @@ struct Interpreter_s { TracingHeap heap; - // global stuff - ObjectType* implicit_char_type; - ObjectType* implicit_base_type; - ObjectType* native_list_type; }; int Interpreter_Create(Interpreter* self, DynamicArray* tokens); diff --git a/src/object-type.c b/src/object-type.c index 3abc250..10edc40 100644 --- a/src/object-type.c +++ b/src/object-type.c @@ -1,4 +1,5 @@ #include "object-type.h" +#include "value.h" int ObjectType_Create(ObjectType* self, StringView name, ObjectType* supertype, size_t attribute_count_guess, allocator_t* allocator) { @@ -9,16 +10,12 @@ int ObjectType_Create(ObjectType* self, StringView name, ObjectType* supertype, return hashmap_code; } self->name = name; - self->reference_count = 0; - supertype->reference_count++; return EXIT_SUCCESS; } void ObjectType_Destroy(ObjectType* self) { - self->supertype->reference_count--; - // TODO: Emit a warning when there are still references? HashMap_Destroy(&self->attributes); } @@ -48,3 +45,46 @@ 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; +} diff --git a/src/object-type.h b/src/object-type.h index dcd44bf..4dcfb97 100644 --- a/src/object-type.h +++ b/src/object-type.h @@ -22,6 +22,7 @@ #include "../submodules/utilitiec/src/hashmap/hashmap.h" #include "../submodules/utilitiec/src/StringView/StringView.h" +#include "../submodules/utilitiec/src/TracingHeap/TracingHeap.h" typedef struct ObjectType_s ObjectType; @@ -37,7 +38,6 @@ typedef struct ObjectTypeAttribute_s { struct ObjectType_s { hashmap_t attributes; // map of (char* name) -> (ObjectTypeAttribute entry) StringView name; - size_t reference_count; // count of references from subtypes and object instances struct ObjectType_s* supertype; }; @@ -46,6 +46,11 @@ int ObjectType_Create(ObjectType* self, StringView name, ObjectType* supertype, int ObjectType_DefineObjectAttribute(ObjectType* self, ObjectType* attribute_type, StringView attribute_name); int ObjectType_DefinePrimitiveAttribute(ObjectType* self, enum ValueType attribute_type, StringView attribute_name); +// TracingHeap-related functions +int ObjectType_TraceReferences(void* context, ObjectType* type, TracingHeapVisit trace_callback, void* callback_context); +size_t ObjectType_SizeQuery(void* arg, ObjectType* self); +int ObjectType_ContextualDestroy(void* arg, ObjectType* self); + size_t ObjectType_GetAttributeCount(ObjectType* self); #endif diff --git a/src/object.h b/src/object.h index 7d784e2..a0e6b0a 100644 --- a/src/object.h +++ b/src/object.h @@ -34,6 +34,6 @@ size_t Object_AllocationSizeForType(ObjectType* otype); // No-op int Object_Destroy(void* arg, Object* o); size_t Object_SizeQuery(void* arg, Object* o); -int Object_ReferenceTrace(void* context, Object* data, TracingHeapVisit trace_callback, void* callback_context); +int Object_ReferenceTrace(void* context, Object* data, TracingHeapVisit trace_callback, void* callback_context); #endif