Implemented heap-functionality for object-types

This commit is contained in:
VegOwOtenks 2025-01-12 23:30:57 +01:00
parent 43f0ed0250
commit ed5d627e3f
5 changed files with 68 additions and 44 deletions

View file

@ -34,22 +34,28 @@ const BuiltinFunction standard_builtin_functions[] = {
}; };
static TracingHeapDataDestructor heap_destructors[] = { static TracingHeapDataDestructor heap_destructors[] = {
[HEAPDATAKIND_OBJECT] = (TracingHeapDataDestructor) Object_Destroy, [HEAPDATAKIND_OBJECT] = (TracingHeapDataDestructor) Object_Destroy,
[HEAPDATAKIND_OBJECTTYPE] = (TracingHeapDataDestructor) ObjectType_ContextualDestroy,
}; };
static void* heap_destructor_args[] = { static void* heap_destructor_args[] = {
[HEAPDATAKIND_OBJECT] = NULL, [HEAPDATAKIND_OBJECT] = NULL,
[HEAPDATAKIND_OBJECTTYPE] = NULL,
}; };
static TracingHeapSizeQuery heap_size_queries[] = { static TracingHeapSizeQuery heap_size_queries[] = {
[HEAPDATAKIND_OBJECT] = (TracingHeapSizeQuery) Object_SizeQuery, [HEAPDATAKIND_OBJECT] = (TracingHeapSizeQuery) Object_SizeQuery,
[HEAPDATAKIND_OBJECTTYPE] = (TracingHeapSizeQuery) ObjectType_SizeQuery,
}; };
static void* heap_size_queries_args[] = { static void* heap_size_queries_args[] = {
[HEAPDATAKIND_OBJECT] = NULL, [HEAPDATAKIND_OBJECT] = NULL,
[HEAPDATAKIND_OBJECTTYPE] = NULL,
}; };
static TracingHeapTraceData heap_trace_data[] = { static TracingHeapTraceData heap_trace_data[] = {
[HEAPDATAKIND_OBJECT] = (TracingHeapTraceData) Object_ReferenceTrace, [HEAPDATAKIND_OBJECT] = (TracingHeapTraceData) Object_ReferenceTrace,
[HEAPDATAKIND_OBJECTTYPE] = (TracingHeapTraceData) ObjectType_TraceReferences,
}; };
static void* heap_trace_data_args[] = { static void* heap_trace_data_args[] = {
[HEAPDATAKIND_OBJECT] = NULL, [HEAPDATAKIND_OBJECT] = NULL,
[HEAPDATAKIND_OBJECTTYPE] = NULL,
}; };
static void _Interpreter_WriteHeapConfig(TracingHeap* heap) static void _Interpreter_WriteHeapConfig(TracingHeap* heap)
@ -339,7 +345,7 @@ int Interpreter_GetParenthesizedRange(Interpreter* self, CallFrame* top_frame, s
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
Object* _Interpreter_MakeObject(Interpreter* self, ObjectType* otype) Object* _Interpreter_AllocateObject(Interpreter* self, ObjectType* otype)
{ {
size_t object_size = Object_AllocationSizeForType(otype); size_t object_size = Object_AllocationSizeForType(otype);
Object* new_object = TracingHeap_Allocate(&self->heap, object_size, HEAPDATAKIND_OBJECT); 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; 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) static int _Interpreter_ConstructString(Interpreter* self, StringView view)
{ {
Object* string_head = _Interpreter_MakeObject(self, self->native_list_type); // TODO: Implement this
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
@ -687,36 +700,6 @@ int Interpreter_Run(Interpreter* self)
int Interpreter_Startup(Interpreter* self, CallFrame* root_frame) 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; return EXIT_SUCCESS;
} }

View file

@ -23,10 +23,6 @@ struct Interpreter_s {
TracingHeap heap; TracingHeap heap;
// global stuff
ObjectType* implicit_char_type;
ObjectType* implicit_base_type;
ObjectType* native_list_type;
}; };
int Interpreter_Create(Interpreter* self, DynamicArray* tokens); int Interpreter_Create(Interpreter* self, DynamicArray* tokens);

View file

@ -1,4 +1,5 @@
#include "object-type.h" #include "object-type.h"
#include "value.h"
int ObjectType_Create(ObjectType* self, StringView name, ObjectType* supertype, size_t attribute_count_guess, allocator_t* allocator) 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; return hashmap_code;
} }
self->name = name; self->name = name;
self->reference_count = 0;
supertype->reference_count++;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
void ObjectType_Destroy(ObjectType* self) void ObjectType_Destroy(ObjectType* self)
{ {
self->supertype->reference_count--;
// TODO: Emit a warning when there are still references?
HashMap_Destroy(&self->attributes); HashMap_Destroy(&self->attributes);
} }
@ -48,3 +45,46 @@ size_t ObjectType_GetAttributeCount(ObjectType* self)
{ {
return HashMap_Size(&self->attributes); 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;
}

View file

@ -22,6 +22,7 @@
#include "../submodules/utilitiec/src/hashmap/hashmap.h" #include "../submodules/utilitiec/src/hashmap/hashmap.h"
#include "../submodules/utilitiec/src/StringView/StringView.h" #include "../submodules/utilitiec/src/StringView/StringView.h"
#include "../submodules/utilitiec/src/TracingHeap/TracingHeap.h"
typedef struct ObjectType_s ObjectType; typedef struct ObjectType_s ObjectType;
@ -37,7 +38,6 @@ typedef struct ObjectTypeAttribute_s {
struct ObjectType_s { struct ObjectType_s {
hashmap_t attributes; // map of (char* name) -> (ObjectTypeAttribute entry) hashmap_t attributes; // map of (char* name) -> (ObjectTypeAttribute entry)
StringView name; StringView name;
size_t reference_count; // count of references from subtypes and object instances
struct ObjectType_s* supertype; 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_DefineObjectAttribute(ObjectType* self, ObjectType* attribute_type, StringView attribute_name);
int ObjectType_DefinePrimitiveAttribute(ObjectType* self, enum ValueType 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); size_t ObjectType_GetAttributeCount(ObjectType* self);
#endif #endif

View file

@ -34,6 +34,6 @@ size_t Object_AllocationSizeForType(ObjectType* otype);
// No-op // No-op
int Object_Destroy(void* arg, Object* o); int Object_Destroy(void* arg, Object* o);
size_t Object_SizeQuery(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 #endif