mirror of
https://github.com/sigmasternchen/macrofuck
synced 2025-03-15 15:18:56 +00:00
feat: Add band module for memory and variable management
This commit is contained in:
parent
d1a8fb2229
commit
e5b1996845
2 changed files with 154 additions and 0 deletions
116
src/band.c
Normal file
116
src/band.c
Normal file
|
@ -0,0 +1,116 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "band.h"
|
||||
#include "list.h"
|
||||
#include "dict.h"
|
||||
#include "alloc.h"
|
||||
|
||||
band_t* band_init(void) {
|
||||
band_t* band = safe_malloc(sizeof(band_t));
|
||||
band->regions = list_new(region_t);
|
||||
band->variables = dict_new();
|
||||
band->addr_lookup = list_new(region_t);
|
||||
return band;
|
||||
}
|
||||
|
||||
region_t* band_region_for_addr(band_t* band, band_addr_t addr) {
|
||||
size_t band_length = list_size(band->band);
|
||||
if (band_length >= addr) {
|
||||
return NULL;
|
||||
} else {
|
||||
return band->band[addr];
|
||||
}
|
||||
}
|
||||
|
||||
region_t* band_region_for_var(band_t* band, const char* variable) {
|
||||
return dict_get(band->variables, variable);
|
||||
}
|
||||
|
||||
band_addr_t band_find_gap(band_t* band, size_t size) {
|
||||
size_t band_size = list_size(band->band);
|
||||
|
||||
size_t current = 0;
|
||||
for (size_t i = 0; i < band_size; i++) {
|
||||
if (band->band[i] == NULL) {
|
||||
current++;
|
||||
if (current >= size) {
|
||||
return i - current;
|
||||
}
|
||||
} else {
|
||||
current = 0;
|
||||
}
|
||||
}
|
||||
|
||||
size_t missing_size = size - current;
|
||||
|
||||
band->band = list_ensure_space(band->band, sizeof(region_t*), missing_size);
|
||||
|
||||
return band_size - current;
|
||||
}
|
||||
|
||||
size_t band_find_empty_region_index(band_t* band) {
|
||||
size_t regions_size = list_size(band->regions);
|
||||
for (size_t i = 0; i < regions_size; i++) {
|
||||
if (band->regions[i] == NULL) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
band->regions = list_ensure_space(band->regions, sizeof(region_t*), 1);
|
||||
return regions_size;
|
||||
}
|
||||
|
||||
region_t* band_allocate_region(band_t* band, size_t size) {
|
||||
region_t* region = safe_malloc(sizeof(region_t));
|
||||
band_addr_t addr = band_find_gap(band, size);
|
||||
size_t regions_index = band_find_empty_region_index(band);
|
||||
|
||||
region->start = addr;
|
||||
region->size = size;
|
||||
region->index = regions_index;
|
||||
|
||||
band->regions[regions_index] = region;
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
band->band[addr + i] = region;
|
||||
}
|
||||
|
||||
return region;
|
||||
}
|
||||
|
||||
region_t* band_allocate_var(band_t* band, size_t size, const char* variable) {
|
||||
region_t* region = band_allocate_region(band, size);
|
||||
|
||||
region->variable = variable;
|
||||
region->is_temp = false;
|
||||
|
||||
dict_put(band->variables, variable, region);
|
||||
|
||||
return region;
|
||||
}
|
||||
|
||||
region_t* band_allocate_tmp(band_t* band, size_t size) {
|
||||
region_t* region = band_allocate_region(band, size);
|
||||
|
||||
region->variable = NULL;
|
||||
region->is_temp = true;
|
||||
|
||||
return region;
|
||||
}
|
||||
|
||||
void band_region_free(band_t* band, region_t* region) {
|
||||
band->regions[region->index] = NULL;
|
||||
for (size_t i = 0; i < region->size; i++) {
|
||||
band->band[region->start + i] = NULL;
|
||||
}
|
||||
|
||||
if (region->variable) {
|
||||
dict_remove(band->variables, region->variable);
|
||||
}
|
||||
|
||||
free(region);
|
||||
}
|
||||
|
||||
void band_region_free_raw(band_t* band, band_addr_t addr) {
|
||||
band_free(band, band->band[addr]);
|
||||
}
|
38
src/band.h
Normal file
38
src/band.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
#ifndef BAND_H
|
||||
#define BAND_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "list.h"
|
||||
#include "dict.h"
|
||||
|
||||
typedef size_t band_addr_t;
|
||||
|
||||
typedef struct {
|
||||
band_addr_t start;
|
||||
size_t index;
|
||||
size_t size;
|
||||
const char* variable;
|
||||
bool is_temp;
|
||||
} region_t;
|
||||
|
||||
typedef struct {
|
||||
region_t** regions;
|
||||
dict_t* variables;
|
||||
region_t** band;
|
||||
} band_t;
|
||||
|
||||
band_t* band_init(void);
|
||||
|
||||
region_t* band_region_for_addr(band_t*, band_addr_t);
|
||||
region_t* band_region_for_var(band_t*, const char*);
|
||||
|
||||
region_t* band_allocate_var(band_t*, size_t, const char*);
|
||||
region_t* band_allocate_tmp(band_t*, size_t);
|
||||
|
||||
void band_region_free(band_t*, region_t*);
|
||||
void band_region_free_raw(band_t*, band_addr_t);
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue