From b88916214fa721ad1d7d3b9b67c9d486873e4aa1 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Mon, 26 Jun 2023 21:34:36 +0200 Subject: [PATCH] Fix of allocator gen. --- lib/std/core/allocators/heap_allocator.c3 | 10 +++--- lib/std/core/mem_allocator.c3 | 38 ++++++++++++++++++++--- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/lib/std/core/allocators/heap_allocator.c3 b/lib/std/core/allocators/heap_allocator.c3 index 5b7aae96b..2c56f4a48 100644 --- a/lib/std/core/allocators/heap_allocator.c3 +++ b/lib/std/core/allocators/heap_allocator.c3 @@ -38,18 +38,18 @@ fn void*! SimpleHeapAllocator.realloc(SimpleHeapAllocator* this, void* old_point void* new = this.alloc(bytes)!; usz max_to_copy = math::min(block.size, bytes); mem::copy(new, old_pointer, max_to_copy); - this.free(old_pointer); + (void)this.free(old_pointer); return new; } -fn void*! SimpleHeapAllocator.calloc(SimpleHeapAllocator* this, usz bytes) @local +fn void*! SimpleHeapAllocator.calloc(SimpleHeapAllocator* this, usz bytes) { void* data = this.alloc(bytes)!; mem::clear(data, bytes, mem::DEFAULT_MEM_ALIGNMENT); return data; } -fn void*! SimpleHeapAllocator.alloc(SimpleHeapAllocator* this, usz bytes) @local +fn void*! SimpleHeapAllocator.alloc(SimpleHeapAllocator* this, usz bytes) { usz aligned_bytes = mem::aligned_offset(bytes, mem::DEFAULT_MEM_ALIGNMENT); if (!this.free_list) @@ -105,11 +105,11 @@ fn void! SimpleHeapAllocator.add_block(SimpleHeapAllocator* this, usz aligned_by Header* new_block = (Header*)result.ptr; new_block.size = result.len - Header.sizeof; new_block.next = null; - this.free(new_block + 1); + (void)this.free(new_block + 1); } -fn void SimpleHeapAllocator.free(SimpleHeapAllocator* this, void* ptr) @local +fn void! SimpleHeapAllocator.free(SimpleHeapAllocator* this, void* ptr) { // Empty ptr -> do nothing. if (!ptr) return; diff --git a/lib/std/core/mem_allocator.c3 b/lib/std/core/mem_allocator.c3 index 01312364e..f951e3fb7 100644 --- a/lib/std/core/mem_allocator.c3 +++ b/lib/std/core/mem_allocator.c3 @@ -8,20 +8,48 @@ const Allocator* LIBC_ALLOCATOR = &_SYSTEM_ALLOCATOR; def AllocatorFunction = fn void*!(Allocator* allocator, usz new_size, usz alignment, usz offset, void* old_pointer, AllocationKind kind); +macro bool is_allocator($Type) +{ + return $checks( + $Type mem, + usz sz = 1, + void*! x = mem.alloc(sz), + void*! y = mem.calloc(sz), + void*! z = mem.realloc(x, sz), + (void)mem.free(x) + ); +} +macro bool is_valid_aligned_allocator($Type) +{ + return !$checks($Type.alloc_aligned) || + $checks( + $Type mem, + usz sz = 1, + void*! x = mem.alloc_aligned(sz, sz, az), + void*! y = mem.calloc_aligned(sz, sz, sz), + void*! z = mem.realloc_aligned(x, sz, sz, sz), + (void)mem.free_aligned(x, sz, sz) + ); +} + +/** + * @require is_allocator($AllocatorType) : "Type does not implement all allocator methods" + * @require is_valid_aligned_allocator($AllocatorType) : "Type does not implement all aligned methods" + **/ macro AllocatorFunction allocator_fn($AllocatorType) { return fn void*!(Allocator* data, usz size, usz alignment, usz offset, void* old_pointer, AllocationKind kind) { $AllocatorType* allocator = ($AllocatorType*)data; - bool $supports_aligned = $defined(allocator.aligned_alloc); + bool $supports_aligned = $defined(allocator.alloc_aligned); switch (kind) { case CALLOC: return allocator.calloc(size) @inline; case ALIGNED_CALLOC: $if $supports_aligned: - return allocator.aligned_calloc(size, alignment, offset) @inline; + return allocator.calloc_aligned(size, alignment, offset) @inline; $else return @aligned_calloc(allocator.calloc, size, alignment, offset); $endif @@ -29,7 +57,7 @@ macro AllocatorFunction allocator_fn($AllocatorType) return allocator.alloc(size); case ALIGNED_ALLOC: $if $supports_aligned: - return allocator.aligned_alloc(size, alignment, offset) @inline; + return allocator.alloc_aligned(size, alignment, offset) @inline; $else return @aligned_alloc(allocator.alloc, size, alignment, offset); $endif @@ -37,13 +65,13 @@ macro AllocatorFunction allocator_fn($AllocatorType) return allocator.realloc(old_pointer, size) @inline; case ALIGNED_REALLOC: $if $supports_aligned: - return allocator.aligned_realloc(old_pointer, size, alignment, offset) @inline; + return allocator.realloc_aligned(old_pointer, size, alignment, offset) @inline; $else return @aligned_realloc(allocator.alloc, allocator.free, old_pointer, size, alignment, offset); $endif case ALIGNED_FREE: $if $supports_aligned: - allocator.aligned_free(old_pointer, alignment, offset) @inline!; + allocator.free_aligned(old_pointer, alignment, offset) @inline!; return null; $else @aligned_free(allocator.free, old_pointer) @inline!;