Refactor allocator to use offsets instead of absolute pointers

JLANG_malloc now returns size_t offsets relative to the heap buffer,
making all references stable across heap growth (realloc). Object API
updated accordingly: constructors return offsets, obj_print/obj_free
receive (allocator, offset). Added heap auto-grow when out of space.
This commit is contained in:
Jose Luis Montañes Ojados
2026-02-15 23:16:45 +01:00
parent 5dc0946a19
commit 13c9d052a0
3 changed files with 118 additions and 100 deletions

View File

@@ -1,101 +1,97 @@
#include "../memory/allocator.h"
typedef enum
{
OBJ_INT,
OBJ_FLOAT,
OBJ_STRING,
OBJ_LIST,
OBJ_NONE
} ObjectType;
#define JLANG_RESOLVE(alloc, offset) \
((void *)(((JLANG_memory_allocator *)(alloc))->memory + (offset)))
typedef struct Object
{
ObjectType type;
union
{
int int_val;
double float_val;
struct
{
char *chars;
int length;
} string_val;
struct
{
struct Object **items;
int count;
int capacity;
} list_val;
} data;
typedef enum { OBJ_INT, OBJ_FLOAT, OBJ_STRING, OBJ_LIST, OBJ_NONE } ObjectType;
typedef struct Object {
ObjectType type;
union {
int int_val;
double float_val;
struct {
size_t chars;
int length;
} string_val;
struct {
struct Object **items;
int count;
int capacity;
} list_val;
} data;
} Object;
Object *obj_new_int(void *allocator, int value)
{
Object *objPtr = (Object *)JLANG_malloc(allocator, sizeof(Object));
objPtr->type = OBJ_INT;
objPtr->data.int_val = value;
return objPtr;
size_t obj_new_int(void *allocator, int value) {
// Object *objPtr = (Object *)JLANG_malloc(allocator, sizeof(Object));
size_t offset = JLANG_malloc(allocator, sizeof(Object));
Object *objPtr = (Object *)JLANG_RESOLVE(allocator, offset);
objPtr->type = OBJ_INT;
objPtr->data.int_val = value;
return offset;
}
Object *obj_new_float(void *allocator, float value)
{
Object *objPtr = (Object *)JLANG_malloc(allocator, sizeof(Object));
objPtr->type = OBJ_FLOAT;
objPtr->data.float_val = value;
return objPtr;
size_t obj_new_float(void *allocator, float value) {
size_t offset = JLANG_malloc(allocator, sizeof(Object));
Object *objPtr = (Object *)JLANG_RESOLVE(allocator, offset);
objPtr->type = OBJ_FLOAT;
objPtr->data.float_val = value;
return offset;
}
Object *obj_new_string(void *allocator, const char *str)
{
Object *objPtr = (Object *)JLANG_malloc(allocator, sizeof(Object));
objPtr->type = OBJ_STRING;
size_t obj_new_string(void *allocator, const char *str) {
size_t offset = JLANG_malloc(allocator, sizeof(Object));
Object *objPtr = (Object *)JLANG_RESOLVE(allocator, offset);
int len = strlen(str);
char *buffer = (char *)JLANG_malloc(allocator, len + 1);
memcpy(buffer, str, len + 1);
objPtr->type = OBJ_STRING;
objPtr->data.string_val.chars = buffer;
objPtr->data.string_val.length = len;
int len = strlen(str);
return objPtr;
// !! CUIDADO CON ESTE DOBLE MALLOC SI DISPARA EL GROW !!
size_t bufferOffset = JLANG_malloc(allocator, len + 1);
char *buffer = (char *)JLANG_RESOLVE(allocator, bufferOffset);
memcpy(buffer, str, len + 1);
objPtr->data.string_val.chars = bufferOffset;
objPtr->data.string_val.length = len;
return offset;
}
Object *obj_new_list(void *allocator)
{
Object *objPtr = (Object *)JLANG_malloc(allocator, sizeof(Object));
objPtr->type = OBJ_LIST;
return objPtr;
size_t obj_new_list(void *allocator) {
size_t offset = JLANG_malloc(allocator, sizeof(Object));
Object *objPtr = (Object *)JLANG_RESOLVE(allocator, offset);
objPtr->type = OBJ_LIST;
return offset;
}
void obj_free(void *allocator, Object* obj) {
if (obj->type == OBJ_STRING) {
JLANG_free(allocator, obj->data.string_val.chars);
}
void obj_free(void *allocator, size_t offset) {
// if (obj->type == OBJ_STRING) {
// JLANG_free(allocator, obj->data.string_val.chars);
// }
JLANG_free(allocator, obj);
JLANG_free(allocator, offset);
}
void obj_print(Object *obj)
{
switch (obj->type)
{
case OBJ_INT:
printf("%d", obj->data.int_val);
break;
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_STRING:
printf("%s", obj->data.string_val.chars);
break;
default:
break;
}
void obj_print(void *allocator, size_t offset) {
Object *obj = (Object *)JLANG_RESOLVE(allocator, offset);
switch (obj->type) {
case OBJ_INT:
printf("%d", obj->data.int_val);
break;
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_STRING:
printf("%s", (char *)JLANG_RESOLVE(allocator, obj->data.string_val.chars));
break;
default:
break;
}
}