Implementation for TracingHeap-Requirements for Objects
This commit is contained in:
parent
d7bfe97210
commit
43f0ed0250
5 changed files with 143 additions and 5 deletions
19
src/heap.h
19
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
|
#ifndef FLUP_HEAP_H
|
||||||
#define FLUP_HEAP_H
|
#define FLUP_HEAP_H
|
||||||
|
|
||||||
|
|
|
@ -33,14 +33,49 @@ const BuiltinFunction standard_builtin_functions[] = {
|
||||||
BuiltinFunction_Print,
|
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)
|
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)) {
|
if (DynamicArray_Create(&self->call_frames, sizeof(CallFrame), 16, NULL)) {
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_Interpreter_WriteHeapConfig(&self->heap);
|
||||||
|
if (TracingHeap_Create(&self->heap, NULL)) {
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
self->tokens = tokens;
|
self->tokens = tokens;
|
||||||
|
|
||||||
self->builtin_names = standard_builtin_names;
|
self->builtin_names = standard_builtin_names;
|
||||||
|
@ -512,8 +547,8 @@ int Interpreter_ExecuteNext(Interpreter* self, size_t stop_token)
|
||||||
if (construct_code) {
|
if (construct_code) {
|
||||||
return construct_code;
|
return construct_code;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case TOKENTYPE_PIPE:
|
case TOKENTYPE_PIPE:
|
||||||
case TOKENTYPE_SEMICOLON:
|
case TOKENTYPE_SEMICOLON:
|
||||||
|
|
|
@ -30,7 +30,7 @@ typedef struct ObjectType_s ObjectType;
|
||||||
typedef struct ObjectTypeAttribute_s {
|
typedef struct ObjectTypeAttribute_s {
|
||||||
StringView name;
|
StringView name;
|
||||||
enum ValueType type;
|
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;
|
uint32_t index;
|
||||||
} ObjectTypeAttribute;
|
} ObjectTypeAttribute;
|
||||||
|
|
||||||
|
|
78
src/object.c
78
src/object.c
|
@ -1,6 +1,84 @@
|
||||||
#include "object.h"
|
#include "object.h"
|
||||||
|
#include "object-type.h"
|
||||||
|
#include "value-content.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
size_t Object_AllocationSizeForType(ObjectType* otype)
|
size_t Object_AllocationSizeForType(ObjectType* otype)
|
||||||
{
|
{
|
||||||
return sizeof(Object) + sizeof(union ValueContent) * ObjectType_GetAttributeCount(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;
|
||||||
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#define FLUP_OBJECT_H
|
#define FLUP_OBJECT_H
|
||||||
|
|
||||||
#include "object-type.h"
|
#include "object-type.h"
|
||||||
|
#include "../submodules/utilitiec/src/TracingHeap/TracingHeap.h"
|
||||||
|
|
||||||
struct Object_s {
|
struct Object_s {
|
||||||
struct Object_s* next; // linked list of all objects
|
struct Object_s* next; // linked list of all objects
|
||||||
|
@ -30,4 +31,9 @@ struct Object_s {
|
||||||
|
|
||||||
size_t Object_AllocationSizeForType(ObjectType* otype);
|
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
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue