Add list type, obj_free for compound types, and self-reference guard
- Implement OBJ_LIST with offset-based items array and capacity - obj_free now releases child allocations (string buffer, list items) - obj_print detects self-referencing lists to prevent infinite recursion - Visualizer distinguishes freed blocks (JLANG_NOT_USE) from active ones - JLANG_free now zeroes payload on release
This commit is contained in:
34
src/main.c
34
src/main.c
@@ -1,24 +1,32 @@
|
||||
#include "objects/object.h"
|
||||
|
||||
int main() {
|
||||
// Creamos un allocator
|
||||
JLANG_memory_allocator *allocPtr = JLANG_CreateAllocator();
|
||||
|
||||
printf("allocatorPtr=%p\n", allocPtr);
|
||||
printf("memoryPtr=%p\n", allocPtr->memory);
|
||||
printf("size=%zu\n", allocPtr->size);
|
||||
size_t stringVar1 = obj_new_string(allocPtr, "Hello world!");
|
||||
size_t floatVar1 = obj_new_float(allocPtr, 3.14);
|
||||
size_t listVar1 = obj_new_list(allocPtr, 3);
|
||||
Object *list = (Object *)JLANG_RESOLVE(allocPtr, listVar1);
|
||||
|
||||
size_t stringVar1 = obj_new_string(allocPtr, "\nHello world!\n");
|
||||
obj_print(allocPtr, stringVar1);
|
||||
size_t *items = (size_t *)JLANG_RESOLVE(allocPtr, list->data.list_val.items);
|
||||
items[0] = floatVar1;
|
||||
items[1] = stringVar1;
|
||||
items[2] = listVar1;
|
||||
|
||||
obj_print(allocPtr, listVar1, "");
|
||||
|
||||
obj_free(allocPtr, stringVar1);
|
||||
|
||||
stringVar1 = obj_new_string(allocPtr, "Hola Mundo!");
|
||||
items[1] = stringVar1;
|
||||
items[2] = stringVar1;
|
||||
|
||||
|
||||
|
||||
obj_print(allocPtr, listVar1, "");
|
||||
|
||||
JLANG_visualize(allocPtr);
|
||||
|
||||
// obj_free(allocPtr, stringVar1);
|
||||
|
||||
for (int i = 0; i < 20; i++) {
|
||||
obj_new_string(allocPtr, "FFFFFFFFFFFFFF");
|
||||
}
|
||||
|
||||
obj_print(allocPtr, stringVar1);
|
||||
JLANG_visualize(allocPtr);
|
||||
return 0;
|
||||
}
|
||||
@@ -14,6 +14,7 @@
|
||||
#define JLANG_FREE 0
|
||||
#define JLANG_HEADER 1
|
||||
#define JLANG_PAYLOAD 2
|
||||
#define JLANG_NOT_USE 3
|
||||
|
||||
/*
|
||||
La estructura de Metadata se encarga de almacenar el tamaño del bloque y si
|
||||
@@ -129,7 +130,7 @@ size_t JLANG_malloc(void *ptr, size_t size) {
|
||||
freeHeader->size = size;
|
||||
freeHeader->in_use = 1;
|
||||
|
||||
void *payloadPtr = (char *) freeHeader + sizeof(JLANG_metadata);
|
||||
void *payloadPtr = (char *)freeHeader + sizeof(JLANG_metadata);
|
||||
return (char *)payloadPtr - allocPtr->memory;
|
||||
}
|
||||
|
||||
@@ -144,6 +145,9 @@ void JLANG_free(void *ptr, size_t blockOffset) {
|
||||
|
||||
// Set block as not_used
|
||||
blockHeader->in_use = 0;
|
||||
|
||||
// Set to 0 payload
|
||||
memset(blockPtr, 0, blockHeader->size);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -181,16 +185,21 @@ void JLANG_visualize(void *ptr) {
|
||||
*/
|
||||
|
||||
if (currentHeader->size > 0) {
|
||||
byteMapPtr[blockIndex] = JLANG_HEADER;
|
||||
for (int i = 0; i < sizeof(JLANG_metadata); i++) {
|
||||
byteMapPtr[blockIndex + i] = JLANG_HEADER;
|
||||
}
|
||||
if (currentHeader->in_use == 1) {
|
||||
byteMapPtr[blockIndex] = JLANG_HEADER;
|
||||
for (int i = 0; i < sizeof(JLANG_metadata); i++) {
|
||||
byteMapPtr[blockIndex + i] = JLANG_HEADER;
|
||||
}
|
||||
|
||||
/*
|
||||
PAYLOAD
|
||||
*/
|
||||
for (int i = 0; i < currentHeader->size; i++) {
|
||||
byteMapPtr[blockIndex + sizeof(JLANG_metadata) + i] = JLANG_PAYLOAD;
|
||||
/*
|
||||
PAYLOAD
|
||||
*/
|
||||
for (int i = 0; i < currentHeader->size; i++) {
|
||||
byteMapPtr[blockIndex + sizeof(JLANG_metadata) + i] = JLANG_PAYLOAD;
|
||||
}
|
||||
} else {
|
||||
// Mark all block as JLANG_NOT_USE
|
||||
memset(byteMapPtr + blockIndex, JLANG_NOT_USE, sizeof(JLANG_metadata) + currentHeader->size);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
@@ -223,6 +232,9 @@ void JLANG_visualize(void *ptr) {
|
||||
case JLANG_FREE:
|
||||
printf("\033[32m");
|
||||
break;
|
||||
case JLANG_NOT_USE:
|
||||
printf("\033[47;5;224m");
|
||||
break;
|
||||
default:
|
||||
printf("\033[41m");
|
||||
break;
|
||||
|
||||
@@ -15,7 +15,7 @@ typedef struct Object {
|
||||
int length;
|
||||
} string_val;
|
||||
struct {
|
||||
struct Object **items;
|
||||
size_t items;
|
||||
int count;
|
||||
int capacity;
|
||||
} list_val;
|
||||
@@ -58,22 +58,39 @@ size_t obj_new_string(void *allocator, const char *str) {
|
||||
return offset;
|
||||
}
|
||||
|
||||
size_t obj_new_list(void *allocator) {
|
||||
size_t obj_new_list(void *allocator, int capacity) {
|
||||
size_t offset = JLANG_malloc(allocator, sizeof(Object));
|
||||
Object *objPtr = (Object *)JLANG_RESOLVE(allocator, offset);
|
||||
objPtr->type = OBJ_LIST;
|
||||
|
||||
size_t itemsOffset = JLANG_malloc(allocator, capacity * sizeof(size_t));
|
||||
|
||||
// Re-resolver por si malloc disparó grow
|
||||
objPtr = (Object *)JLANG_RESOLVE(allocator, offset);
|
||||
|
||||
objPtr->data.list_val.capacity = capacity;
|
||||
objPtr->data.list_val.items = itemsOffset;
|
||||
objPtr->data.list_val.count = 0;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
void obj_list_append(void *allocator, size_t offset) {}
|
||||
|
||||
void obj_free(void *allocator, size_t offset) {
|
||||
// if (obj->type == OBJ_STRING) {
|
||||
// JLANG_free(allocator, obj->data.string_val.chars);
|
||||
// }
|
||||
Object *obj = (Object *)JLANG_RESOLVE(allocator, offset);
|
||||
if (obj->type == OBJ_STRING) {
|
||||
JLANG_free(allocator, obj->data.string_val.chars);
|
||||
}
|
||||
|
||||
if (obj->type == OBJ_LIST) {
|
||||
JLANG_free(allocator, obj->data.list_val.items);
|
||||
}
|
||||
|
||||
JLANG_free(allocator, offset);
|
||||
}
|
||||
|
||||
void obj_print(void *allocator, size_t offset) {
|
||||
void obj_print(void *allocator, size_t offset, const char *preffix) {
|
||||
Object *obj = (Object *)JLANG_RESOLVE(allocator, offset);
|
||||
|
||||
switch (obj->type) {
|
||||
@@ -83,15 +100,40 @@ void obj_print(void *allocator, size_t offset) {
|
||||
case OBJ_FLOAT:
|
||||
printf("%f", obj->data.float_val);
|
||||
break;
|
||||
// case OBJ_LIST:
|
||||
// for (int i = 0; i < obj->data.list_val.count; i++) {
|
||||
// obj_print(obj->data.list_val.items[i]);
|
||||
// }
|
||||
// break;
|
||||
case OBJ_LIST: {
|
||||
|
||||
// Iterate items
|
||||
size_t *items =
|
||||
(size_t *)JLANG_RESOLVE(allocator, obj->data.list_val.items);
|
||||
|
||||
printf("[");
|
||||
for (int i = 0; i < obj->data.list_val.capacity; i++) {
|
||||
|
||||
// Check if the item is the list itself
|
||||
if (items[i] == offset) {
|
||||
printf("<self:0x%zu>", offset);
|
||||
} else {
|
||||
obj_print(allocator, items[i], "\"");
|
||||
}
|
||||
|
||||
if (i < obj->data.list_val.capacity - 1) {
|
||||
printf(", ");
|
||||
}
|
||||
}
|
||||
printf("]\n");
|
||||
break;
|
||||
}
|
||||
case OBJ_STRING:
|
||||
if (strcmp(preffix, "") != 0) {
|
||||
printf("%s", preffix);
|
||||
}
|
||||
printf("%s", (char *)JLANG_RESOLVE(allocator, obj->data.string_val.chars));
|
||||
|
||||
if (strcmp(preffix, "") != 0) {
|
||||
printf("%s", preffix);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user