Implemented heap-functionality for object-types
This commit is contained in:
parent
43f0ed0250
commit
ed5d627e3f
5 changed files with 68 additions and 44 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue