From 43f0ed0250b925495ed6f1028a935c2b064a79ef Mon Sep 17 00:00:00 2001 From: VegOwOtenks Date: Sun, 12 Jan 2025 21:33:43 +0100 Subject: [PATCH] Implementation for TracingHeap-Requirements for Objects --- src/heap.h | 19 ++++++++++++ src/interpreter.c | 43 +++++++++++++++++++++++--- src/object-type.h | 2 +- src/object.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++ src/object.h | 6 ++++ 5 files changed, 143 insertions(+), 5 deletions(-) diff --git a/src/heap.h b/src/heap.h index e871960..dbe2717 100644 --- a/src/heap.h +++ b/src/heap.h @@ -1,3 +1,22 @@ +/* + * This code is part of the programming language flup + * flup comes with ABSOLUTELY NO WARRANTY and is licensed under AGPL-3.0 or later. + * Copyright (C) 2024 VegOwOtenks + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ #ifndef FLUP_HEAP_H #define FLUP_HEAP_H diff --git a/src/interpreter.c b/src/interpreter.c index cc3cada..72207de 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -33,14 +33,49 @@ const BuiltinFunction standard_builtin_functions[] = { BuiltinFunction_Print, }; +static TracingHeapDataDestructor heap_destructors[] = { + [HEAPDATAKIND_OBJECT] = (TracingHeapDataDestructor) Object_Destroy, +}; +static void* heap_destructor_args[] = { + [HEAPDATAKIND_OBJECT] = NULL, +}; +static TracingHeapSizeQuery heap_size_queries[] = { + [HEAPDATAKIND_OBJECT] = (TracingHeapSizeQuery) Object_SizeQuery, +}; +static void* heap_size_queries_args[] = { + [HEAPDATAKIND_OBJECT] = NULL, +}; +static TracingHeapTraceData heap_trace_data[] = { + [HEAPDATAKIND_OBJECT] = (TracingHeapTraceData) Object_ReferenceTrace, +}; +static void* heap_trace_data_args[] = { + [HEAPDATAKIND_OBJECT] = NULL, +}; + +static void _Interpreter_WriteHeapConfig(TracingHeap* heap) +{ + heap->config = (TracingHeapConfig) { + .destructor = heap_destructors, + .destructor_context = heap_destructor_args, + .size_query = heap_size_queries, + .size_query_context = heap_size_queries_args, + .trace_data = heap_trace_data, + .trace_context = heap_trace_data_args, + }; + + return; +} + int Interpreter_Create(Interpreter* self, DynamicArray* tokens) { - if (TracingHeap_Create(&self->heap, NULL)) { - return EXIT_FAILURE; - } if (DynamicArray_Create(&self->call_frames, sizeof(CallFrame), 16, NULL)) { return ENOMEM; } + + _Interpreter_WriteHeapConfig(&self->heap); + if (TracingHeap_Create(&self->heap, NULL)) { + return EXIT_FAILURE; + } self->tokens = tokens; self->builtin_names = standard_builtin_names; @@ -512,8 +547,8 @@ int Interpreter_ExecuteNext(Interpreter* self, size_t stop_token) if (construct_code) { return construct_code; } - } break; + } case TOKENTYPE_PIPE: case TOKENTYPE_SEMICOLON: diff --git a/src/object-type.h b/src/object-type.h index c9015cf..dcd44bf 100644 --- a/src/object-type.h +++ b/src/object-type.h @@ -30,7 +30,7 @@ typedef struct ObjectType_s ObjectType; typedef struct ObjectTypeAttribute_s { StringView name; enum ValueType type; - ObjectType* object_type; // only active if there type is VALUETYPE_OBJECT + ObjectType* object_type; // only active if the type is VALUETYPE_OBJECT uint32_t index; } ObjectTypeAttribute; diff --git a/src/object.c b/src/object.c index 4dd26fd..cba580e 100644 --- a/src/object.c +++ b/src/object.c @@ -1,6 +1,84 @@ #include "object.h" +#include "object-type.h" +#include "value-content.h" +#include size_t Object_AllocationSizeForType(ObjectType* otype) { return sizeof(Object) + sizeof(union ValueContent) * ObjectType_GetAttributeCount(otype); } + +int Object_Destroy(void* arg, Object* o) +{ + (void) o; + (void) arg; + return EXIT_SUCCESS; +} + +size_t Object_SizeQuery(void* arg, Object* o) +{ + (void) arg; + return Object_AllocationSizeForType(o->type); +} + +typedef struct AttributeVisitorContext_s { + Object* self; + TracingHeapVisit trace_visit; + void* visit_context; +} AttributeVisitorContext; + +static int _Object_AttributeVisitor(AttributeVisitorContext* context, char* attribute_name, size_t attribute_name_length, ObjectTypeAttribute* value) +{ + (void) attribute_name; + (void) attribute_name_length; + switch (value->type) { + case VALUETYPE_BYTE: + case VALUETYPE_INT64: + case VALUETYPE_DOUBLE: + case VALUETYPE_BOOLEAN: + break; + + case VALUETYPE_OBJECT: + { + union ValueContent attribute_value = context->self->attributes[value->index]; + // visit all object attributes + int visit_code = context->trace_visit(context->visit_context, attribute_value.object); + if (visit_code != EXIT_SUCCESS) { + return visit_code; + } + break; + } + } + return EXIT_SUCCESS; +} + +int Object_ReferenceTrace(void* context, Object* object, TracingHeapVisit trace_callback, void* callback_context) +{ + (void) context; + ObjectType* type = object->type; + + + AttributeVisitorContext visitor_context = { + .self = object, + .trace_visit = trace_callback, + .visit_context = callback_context, + }; + + while (type != NULL) { + // object has a reference to its type + int type_visit = trace_callback(callback_context, type); + if (type_visit != EXIT_SUCCESS) { + return type_visit; + } + + int hashmap_visit = HashMap_ForEach(&type->attributes, (HashMapVisitFunction) _Object_AttributeVisitor, &visitor_context); + if (hashmap_visit != EXIT_SUCCESS) { + return hashmap_visit; + } + + type = type->supertype; + } + + + return EXIT_SUCCESS; +} diff --git a/src/object.h b/src/object.h index fca9973..7d784e2 100644 --- a/src/object.h +++ b/src/object.h @@ -21,6 +21,7 @@ #define FLUP_OBJECT_H #include "object-type.h" +#include "../submodules/utilitiec/src/TracingHeap/TracingHeap.h" struct Object_s { struct Object_s* next; // linked list of all objects @@ -30,4 +31,9 @@ struct Object_s { 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); + #endif