#include <ghostty/vt.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdbool.h>
#define STROP_VT_MEMORY_LIMIT (32u * 1024u * 1024u)
#define STROP_VT_ALLOCATION_LIMIT 65536u
typedef struct {
size_t bytes;
size_t allocations;
bool failed;
} StropVtMemory;
static void *strop_vt_alloc(void *context, size_t length, uint8_t alignment, uintptr_t address) {
(void)address;
StropVtMemory *memory = context;
size_t size = length ? length : 1;
if (alignment > _Alignof(max_align_t) || size > STROP_VT_MEMORY_LIMIT - memory->bytes ||
memory->allocations == STROP_VT_ALLOCATION_LIMIT) {
memory->failed = true;
return NULL;
}
void *result = malloc(size);
if (!result) {
memory->failed = true;
return NULL;
}
memory->bytes += size;
memory->allocations++;
return result;
}
static bool strop_vt_resize_memory(void *context, void *pointer, size_t old_length,
uint8_t alignment, size_t new_length, uintptr_t address) {
(void)context; (void)pointer; (void)alignment; (void)address;
return old_length == new_length;
}
static void *strop_vt_remap(void *context, void *pointer, size_t old_length,
uint8_t alignment, size_t new_length, uintptr_t address) {
(void)address;
StropVtMemory *memory = context;
size_t old_size = old_length ? old_length : 1;
size_t new_size = new_length ? new_length : 1;
if (alignment > _Alignof(max_align_t) || old_size > memory->bytes ||
new_size > STROP_VT_MEMORY_LIMIT - (memory->bytes - old_size)) {
memory->failed = true;
return NULL;
}
void *result = realloc(pointer, new_size);
if (!result) {
memory->failed = true;
return NULL;
}
memory->bytes = memory->bytes - old_size + new_size;
return result;
}
static void strop_vt_release_memory(void *context, void *pointer, size_t length,
uint8_t alignment, uintptr_t address) {
(void)alignment; (void)address;
StropVtMemory *memory = context;
size_t size = length ? length : 1;
if (size > memory->bytes || memory->allocations == 0) {
memory->failed = true;
} else {
memory->bytes -= size;
memory->allocations--;
}
free(pointer);
}
static const GhosttyAllocatorVtable strop_vt_allocator_vtable = {
.alloc = strop_vt_alloc,
.resize = strop_vt_resize_memory,
.remap = strop_vt_remap,
.free = strop_vt_release_memory,
};