diff --git a/resources/lib/std/mem.c3 b/resources/lib/std/mem.c3 index 3aa7c3036..eeee4e926 100644 --- a/resources/lib/std/mem.c3 +++ b/resources/lib/std/mem.c3 @@ -1,9 +1,118 @@ module std::mem; extern func void* _malloc(usize bytes) @cname("malloc"); +extern func void* _realloc(void* ptr, usize bytes) @cname("realloc"); extern func void* _calloc(usize bytes, usize elements) @cname("calloc"); extern func void _free(void* ptr) @cname("free"); +public enum AllocationKind +{ + ALLOC, + REALLOC, + FREE, +} + +public enum AllocationFailureKind +{ + OUT_OF_MEMORY +} + +public error AllocationFailure +{ + AllocationFailureKind failureKind; +} + +public typedef func void!(void *data, void** pointer, usize bytes, usize alignment, AllocationKind kind) as AllocatorFunction; + +public struct Allocator +{ + AllocatorFunction allocation_function; + void *data; +} + +public func void! system_malloc_function(void *unused, void** pointer, usize bytes, usize alignment, AllocationKind kind) @inline +{ + switch (kind) + { + case ALLOC: + void* data = _malloc(bytes); + if (!data) return AllocationFailure({ OUT_OF_MEMORY })!; + *pointer = data; + return; + case REALLOC: + void* data = _realloc(*pointer, bytes); + if (!data) return AllocationFailure({ OUT_OF_MEMORY })!; + *pointer = data; + return; + case FREE: + _free(*pointer); + *pointer = null; + return; + } + $unreachable; +} + +public struct RingAllocator +{ + char *data; + usize size; + usize offset; +} + + +public func void* RingAllocator.alloc(RingAllocator *allocator, usize size) +{ + if (size > allocator.size) return null; + // Wraparound? If so, start at the beginning. + if (allocator.offset + size > allocator.size) + { + allocator.offset = size; + return allocator.data; + } + void* data = allocator.offset + allocator.data; + allocator.offset = (allocator.offset + size) & allocator.size; + return data; +} + +public func void* RingAllocator.realloc(RingAllocator *allocator, void* ptr, usize size) +{ + if (size > allocator.size) return null; + assert(allocator.data >= ptr && ptr < allocator.data + size, "Realloc on other allocator."); + // 1. The pointer is before the allocator + if (allocator.data + allocator.offset > ptr) + { + if (allocator.data + allocator.size < ptr + size) + { + // 1a. There is not enough space, we need to copy to the start. + usize pointer_offset = ptr - allocator.data; + usize copy_len = pointer_offset + size > allocator.offset ? allocator.offset - pointer_offset : size; + //memcpy(allocator.data, ptr, copy_len); + allocator.offset = size; + return allocator.data; + } + // 1b. There is enough space, so we just change the offset: + allocator.offset = ptr - allocator.data + size; + return ptr; + } + // 2. The pointer is after the allocator + // 2a. Is there sufficient space? + if (ptr + size <= allocator.data + allocator.size) + { + // Good, if so we simply change the offset and return the pointer. + allocator.offset = ptr - allocator.data + size; + return ptr; + } + // 2b. Not sufficient space, we copy to the beginning. + usize pointer_offset = ptr - allocator.data; + usize copy_len = allocator.size - (ptr - allocator.data); + if (copy_len > size) copy_len = size; + //memcpy(allocator.data, ptr, copy_len); + allocator.offset = size; + return allocator.data; +} + +public Allocator main_allocator = { &system_malloc_function, null }; + public macro malloc($Type) { // TODO: return cast(_malloc($Type.sizeof) as $Type*); diff --git a/resources/lib/std/runtime.c3 b/resources/lib/std/runtime.c3 new file mode 100644 index 000000000..d8a053108 --- /dev/null +++ b/resources/lib/std/runtime.c3 @@ -0,0 +1,32 @@ +module std::runtime; + +struct VirtualAny +{ + void* ptr; + typeid type_id; +} + +struct VirtualContainer +{ + void* ptr; + void* impl_ptr; +} + +struct SubArrayContainer +{ + void* ptr; + usize len; +} + +struct VarArrayHeader +{ + usize size; + usize capacity; + void *allocator; + +} + +struct VarArrayContainer +{ + +} diff --git a/src/build/build_options.c b/src/build/build_options.c index 54277be95..f1d7d0d05 100644 --- a/src/build/build_options.c +++ b/src/build/build_options.c @@ -63,7 +63,8 @@ static void usage(void) OUTPUT(" headers [ ...] Analyse files and generate C headers for public methods."); OUTPUT(""); OUTPUT("Options:"); - OUTPUT(" --lib - Use this directory as the c3 library path."); + OUTPUT(" --stdlib - Use this directory as the C3 standard library path."); + OUTPUT(" --lib - Use this directory as the C3 library path."); OUTPUT(" --path - Use this as the base directory for the current command."); OUTPUT(" --template