From 8dd0c4f27aae02dd60f029db4cf03f9902cba26f Mon Sep 17 00:00:00 2001 From: Linnnus Date: Tue, 8 Apr 2025 01:07:22 +0000 Subject: feat: Initial commit At this point we have some allocation routines but no work on the actual language has been done. --- src/core/allocator.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 src/core/allocator.c (limited to 'src/core/allocator.c') diff --git a/src/core/allocator.c b/src/core/allocator.c new file mode 100644 index 0000000..5444b39 --- /dev/null +++ b/src/core/allocator.c @@ -0,0 +1,87 @@ +#include "allocator.h" + +#include +#include +#include +#include + +#define DEFAULT_ALIGNMENT ((size_t)_Alignof(max_align_t)) + +void *sand_allocate_aligned(SandAllocator *a, size_t size, size_t alignment) { + assert(a != NULL); + assert(size > 0); + assert(alignment > 0); + void *ptr = a->allocate(size, alignment, a->user_data); + assert(ptr == NULL || sand_pointer_is_aligned(ptr, alignment)); + return ptr; +} + +void *sand_allocate(SandAllocator *a, size_t size) { + return sand_allocate_aligned(a, size, DEFAULT_ALIGNMENT); +} + +void *sand_reallocate_aligned(SandAllocator *a, void *old_ptr, size_t old_size, size_t new_size, size_t alignment) { + assert(a != NULL); + assert(old_ptr != NULL); + assert(old_size > 0); + assert(new_size > 0); + assert(alignment > 0); + + if (a->reallocate != NULL) { + void *new_ptr = a->reallocate(old_ptr, old_size, new_size, alignment, a->user_data); + assert(sand_pointer_is_aligned(new_ptr, alignment)); + return new_ptr; + } else { + void *new_ptr = a->allocate(new_size, alignment, a->user_data); + if (new_ptr == NULL) { + return NULL; // Note that we HAVEN'T freed `old_ptr`! + } + assert(sand_pointer_is_aligned(new_ptr, alignment)); + memmove(new_ptr, old_ptr, old_size); // Can't know if they overlap. + a->deallocate(old_ptr, old_size, a->user_data); + return new_ptr; + } +} + +void *sand_reallocate(SandAllocator *a, void *old_ptr, size_t old_size, size_t new_size) { + return sand_reallocate_aligned(a, old_ptr, old_size, new_size, DEFAULT_ALIGNMENT); +} + +void sand_deallocate(SandAllocator *a, void *old_ptr, size_t old_size) { + assert(a != NULL); + assert(old_ptr != NULL); + assert(old_size > 0); + + if (old_ptr == NULL) { + return; + } + a->deallocate(old_ptr, old_size, a->user_data); +} + +bool sand_is_valid_alignment(size_t alignment) { + // Only powers of two are allowed as alignments for simplicity. + return alignment % 2 == 0; +} + +void *sand_align_pointer_forward(void *ptr, size_t alignment) { + intptr_t p = (intptr_t)ptr; + intptr_t a = alignment; + intptr_t ap = ((p + a - 1) & ~(a - 1)); + void *result = (void *)ap; + assert(sand_pointer_is_aligned(result, alignment)); + return result; +} + +size_t sand_align_size_forward(size_t n, size_t alignment) { + size_t result = ((n + alignment - 1) & ~(alignment - 1)); + assert(sand_size_is_aligned(result, alignment)); + return result; +} + +bool sand_pointer_is_aligned(void *pointer, size_t alignment) { + return ((uintptr_t)pointer & (alignment - 1)) == 0; +} + +bool sand_size_is_aligned(size_t n, size_t alignment) { + return (n & (alignment - 1)) == 0; +} -- cgit v1.2.3