add JLANG_free and Object
This commit is contained in:
20
src/main.c
20
src/main.c
@@ -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;
|
||||||
}
|
}
|
||||||
@@ -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
101
src/objects/object.h
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user