add JLANG_free and Object

This commit is contained in:
Jose Luis Montañes Ojados
2026-02-15 22:12:19 +01:00
parent c90883ac27
commit 5dc0946a19
4 changed files with 262 additions and 151 deletions

BIN
run.exe

Binary file not shown.

View File

@@ -1,4 +1,4 @@
#include "memory/allocator.h" #include "objects/object.h"
int main() { int main() {
JLANG_memory_allocator *allocPtr = JLANG_CreateAllocator(); JLANG_memory_allocator *allocPtr = JLANG_CreateAllocator();
@@ -7,12 +7,24 @@ int main() {
printf("memoryPtr=%p\n", allocPtr->memory); printf("memoryPtr=%p\n", allocPtr->memory);
printf("size=%zu\n", allocPtr->size); printf("size=%zu\n", allocPtr->size);
JLANG_visualize(allocPtr); // Create object
Object *intVar1 = obj_new_int(allocPtr, 66);
obj_print(intVar1);
void *var1 = JLANG_malloc(allocPtr, 512); Object *stringVar1 = obj_new_string(allocPtr, "\nHello world!\n");
printf("var1Ptr=%p\n", var1); obj_print(stringVar1);
JLANG_visualize(allocPtr); JLANG_visualize(allocPtr);
for (int i = 0; i < 10; i++) {
Object *intVar1 = obj_new_int(allocPtr, 66);
obj_print(intVar1);
}
obj_free(allocPtr, intVar1);
void* newPtr = JLANG_malloc(allocPtr, 8);
obj_print(stringVar1);
JLANG_visualize(allocPtr);
return 0; return 0;
} }

View File

@@ -1,11 +1,12 @@
#include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
/* /*
Custom Memory Allocator Custom Memory Allocator
Implementacion custom de un memory allocator que opera sobre un array de bytes usandolo como "heap" Implementacion custom de un memory allocator que opera sobre un array de
bytes usandolo como "heap"
*/ */
#define JLANG_OK 0 #define JLANG_OK 0
@@ -15,82 +16,79 @@
#define JLANG_PAYLOAD 2 #define JLANG_PAYLOAD 2
/* /*
La estructura de Metadata se encarga de almacenar el tamaño del bloque y si está en uso. La estructura de Metadata se encarga de almacenar el tamaño del bloque y si
Se añadirá al principio de cada bloque está en uso. Se añadirá al principio de cada bloque [BLOCK_METADATA] +
[BLOCK_METADATA] + [BLOCK_BYTES] [BLOCK_BYTES]
*/ */
typedef struct typedef struct {
{
size_t size; // 8 bytes size_t size; // 8 bytes
int in_use; // 4 bytes int in_use; // 4 bytes
// --- aquí el compilador mete 4 bytes invisibles --- // --- aquí el compilador mete 4 bytes invisibles ---
} JLANG_metadata; } JLANG_metadata;
/* /*
La estructura de Memory Allocator se encarga de almancenar el array de memoria y el tamaño de esta. La estructura de Memory Allocator se encarga de almancenar el array de
memoria y el tamaño de esta.
*/ */
typedef struct typedef struct {
{
char *memory; // 8 bytes char *memory; // 8 bytes
size_t size; // 8 bytes size_t size; // 8 bytes
} JLANG_memory_allocator; } JLANG_memory_allocator;
void *JLANG_CreateAllocator() void *JLANG_CreateAllocator() {
{
// Allocate memory in heap for JLANG_memory_allocator // Allocate memory in heap for JLANG_memory_allocator
JLANG_memory_allocator *allocator = (JLANG_memory_allocator *)malloc(sizeof(JLANG_memory_allocator)); JLANG_memory_allocator *allocator =
(JLANG_memory_allocator *)malloc(sizeof(JLANG_memory_allocator));
// Assign default free bytes // Assign default free bytes
allocator->memory = (char *)malloc(1 * 1024); allocator->memory = (char *)malloc(1 * 1024);
allocator->size = 1 * 1024; allocator->size = 1 * 1024;
// ensure all memory is zero // ensure all memory is zero
for (int i = 0; i < 1 * 1024; i++) for (int i = 0; i < 1 * 1024; i++) {
{
allocator->memory[i] = 0; allocator->memory[i] = 0;
} }
return allocator; return allocator;
} }
size_t JLANG_used(void *ptr) size_t JLANG_used(void *ptr) {
{
JLANG_memory_allocator *allocPtr = (JLANG_memory_allocator *)ptr; JLANG_memory_allocator *allocPtr = (JLANG_memory_allocator *)ptr;
// Iterate memory parsing only metadata // Iterate memory parsing only metadata
JLANG_metadata *currentHeader = (JLANG_metadata *)allocPtr->memory; JLANG_metadata *currentHeader = (JLANG_metadata *)allocPtr->memory;
size_t used = 0; size_t used = 0;
while (currentHeader->in_use != 0 && used < allocPtr->size) while (currentHeader->in_use != 0 && used < allocPtr->size) {
{
used += sizeof(JLANG_metadata) + currentHeader->size; used += sizeof(JLANG_metadata) + currentHeader->size;
// Current block is in_use, jump to next block // Current block is in_use, jump to next block
currentHeader = (JLANG_metadata *)((char *)currentHeader + sizeof(JLANG_metadata) + currentHeader->size); currentHeader =
(JLANG_metadata *)((char *)currentHeader + sizeof(JLANG_metadata) +
currentHeader->size);
} }
return used; return used;
} }
void *JLANG_last_free(void *ptr) void *JLANG_last_free(void *ptr) {
{
JLANG_memory_allocator *allocPtr = (JLANG_memory_allocator *)ptr; JLANG_memory_allocator *allocPtr = (JLANG_memory_allocator *)ptr;
// Iterate memory parsing only metadata // Iterate memory parsing only metadata
JLANG_metadata *currentHeader = (JLANG_metadata *)allocPtr->memory; JLANG_metadata *currentHeader = (JLANG_metadata *)allocPtr->memory;
size_t used = 0; size_t used = 0;
while (currentHeader->in_use != 0 && used < allocPtr->size) while (currentHeader->in_use != 0 && used < allocPtr->size) {
{
used += sizeof(JLANG_metadata) + currentHeader->size; used += sizeof(JLANG_metadata) + currentHeader->size;
// Current block is in_use, jump to next block // Current block is in_use, jump to next block
currentHeader = (JLANG_metadata *)((char *)currentHeader + sizeof(JLANG_metadata) + currentHeader->size); currentHeader =
(JLANG_metadata *)((char *)currentHeader + sizeof(JLANG_metadata) +
currentHeader->size);
} }
return currentHeader; return currentHeader;
} }
void *JLANG_malloc(void *ptr, size_t size) void *JLANG_malloc(void *ptr, size_t size) {
{
JLANG_memory_allocator *allocPtr = (JLANG_memory_allocator *)ptr; JLANG_memory_allocator *allocPtr = (JLANG_memory_allocator *)ptr;
// 1. Hay bloques disponibles?? // 1. Hay bloques disponibles??
@@ -98,8 +96,7 @@ void *JLANG_malloc(void *ptr, size_t size)
size_t available = allocPtr->size - used; size_t available = allocPtr->size - used;
// chequear si hay suficiente espacio libre // chequear si hay suficiente espacio libre
if (available > size + sizeof(JLANG_metadata)) if (available > size + sizeof(JLANG_metadata)) {
{
JLANG_metadata *freeHeader = (JLANG_metadata *)JLANG_last_free(ptr); JLANG_metadata *freeHeader = (JLANG_metadata *)JLANG_last_free(ptr);
freeHeader->size = size; freeHeader->size = size;
freeHeader->in_use = 1; freeHeader->in_use = 1;
@@ -110,26 +107,34 @@ void *JLANG_malloc(void *ptr, size_t size)
return NULL; // TODO return NULL; // TODO
} }
void JLANG_free(void *ptr, void *blockPtr) {
JLANG_memory_allocator *allocPtr = (JLANG_memory_allocator *)ptr;
// Get block header
JLANG_metadata *blockHeader =
(JLANG_metadata *)((char *)blockPtr - sizeof(JLANG_metadata));
// Set block as not_used
blockHeader->in_use = 0;
}
/* /*
Debug Visualization Debug Visualization
[FF FF FF FF FF FF FF ] [FF FF FF FF FF FF FF ]
*/ */
int _ceil(float v) int _ceil(float v) {
{
int n = (int)v; int n = (int)v;
float r = v - n; float r = v - n;
if (r > 0) if (r > 0) {
{
return n + 1; return n + 1;
} }
return n; return n;
} }
void JLANG_visualize(void *ptr) void JLANG_visualize(void *ptr) {
{
JLANG_memory_allocator *allocPtr = (JLANG_memory_allocator *)ptr; JLANG_memory_allocator *allocPtr = (JLANG_memory_allocator *)ptr;
// Step 1. Get byte type // Step 1. Get byte type
@@ -138,10 +143,8 @@ void JLANG_visualize(void *ptr)
JLANG_metadata *currentHeader = (JLANG_metadata *)allocPtr->memory; JLANG_metadata *currentHeader = (JLANG_metadata *)allocPtr->memory;
long used = 0; long used = 0;
while (used < allocPtr->size) while (used < allocPtr->size) {
{
long blockIndex = (char *)currentHeader - (char *)allocPtr->memory; long blockIndex = (char *)currentHeader - (char *)allocPtr->memory;
printf("blockIndex=%u\n", blockIndex);
used += sizeof(JLANG_metadata) + currentHeader->size; used += sizeof(JLANG_metadata) + currentHeader->size;
/* /*
@@ -149,19 +152,16 @@ void JLANG_visualize(void *ptr)
blockIndex + sizeof(JLANG_metadata) blockIndex + sizeof(JLANG_metadata)
*/ */
if (currentHeader->size > 0) if (currentHeader->size > 0) {
{
byteMapPtr[blockIndex] = JLANG_HEADER; byteMapPtr[blockIndex] = JLANG_HEADER;
for (int i = 0; i < sizeof(JLANG_metadata); i++) for (int i = 0; i < sizeof(JLANG_metadata); i++) {
{
byteMapPtr[blockIndex + i] = JLANG_HEADER; byteMapPtr[blockIndex + i] = JLANG_HEADER;
} }
/* /*
PAYLOAD PAYLOAD
*/ */
for (int i = 0; i < currentHeader->size; i++) for (int i = 0; i < currentHeader->size; i++) {
{
byteMapPtr[blockIndex + sizeof(JLANG_metadata) + i] = JLANG_PAYLOAD; byteMapPtr[blockIndex + sizeof(JLANG_metadata) + i] = JLANG_PAYLOAD;
} }
} else { } else {
@@ -169,7 +169,9 @@ void JLANG_visualize(void *ptr)
} }
// Jump to next block // Jump to next block
currentHeader = (JLANG_metadata *)((char *)currentHeader + sizeof(JLANG_metadata) + currentHeader->size); currentHeader =
(JLANG_metadata *)((char *)currentHeader + sizeof(JLANG_metadata) +
currentHeader->size);
} }
// Step 2. Draw // Step 2. Draw
@@ -180,16 +182,13 @@ void JLANG_visualize(void *ptr)
char *currentMemPtr = allocPtr->memory; char *currentMemPtr = allocPtr->memory;
for (int i = 0; i < totalRows; i++) for (int i = 0; i < totalRows; i++) {
{
printf("["); printf("[");
for (int n = 0; n < bytePerRow; n++) for (int n = 0; n < bytePerRow; n++) {
{
int index = n + i * bytePerRow; int index = n + i * bytePerRow;
switch (byteMapPtr[index]) switch (byteMapPtr[index]) {
{
case JLANG_HEADER: case JLANG_HEADER:
printf("\033[46m"); printf("\033[46m");
break; break;
@@ -203,8 +202,7 @@ void JLANG_visualize(void *ptr)
printf("%.2x", (unsigned char)*(currentMemPtr + (n + i * bytePerRow))); printf("%.2x", (unsigned char)*(currentMemPtr + (n + i * bytePerRow)));
if (n < bytePerRow - 1) if (n < bytePerRow - 1) {
{
printf(" "); printf(" ");
} }

101
src/objects/object.h Normal file
View File

@@ -0,0 +1,101 @@
#include "../memory/allocator.h"
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
{
char *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;
}
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;
}
Object *obj_new_string(void *allocator, const char *str)
{
Object *objPtr = (Object *)JLANG_malloc(allocator, sizeof(Object));
objPtr->type = OBJ_STRING;
int len = strlen(str);
char *buffer = (char *)JLANG_malloc(allocator, len + 1);
memcpy(buffer, str, len + 1);
objPtr->data.string_val.chars = buffer;
objPtr->data.string_val.length = len;
return objPtr;
}
Object *obj_new_list(void *allocator)
{
Object *objPtr = (Object *)JLANG_malloc(allocator, sizeof(Object));
objPtr->type = OBJ_LIST;
return objPtr;
}
void obj_free(void *allocator, Object* obj) {
if (obj->type == OBJ_STRING) {
JLANG_free(allocator, obj->data.string_val.chars);
}
JLANG_free(allocator, obj);
}
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;
}
}