test/refactor: changed things for working with more edge cases

This commit is contained in:
2026-04-11 21:15:31 -06:00
parent d069a108ce
commit 15b5cc382f
3 changed files with 141 additions and 18 deletions

View File

@@ -70,34 +70,50 @@ ArenaErr arena_ensure_capacity(Arena *arena, size_t size, size_t alignment) {
return ARENA_NULL_ARG;
}
if (size < 1) {
if (size == 0 || size == SIZE_MAX) {
return ARENA_INVALID_SIZE;
}
if (alignment < 1) {
if (alignment == 0 || (alignment & (alignment - 1)) != 0) {
return ARENA_INVALID_ALIGN;
}
SizeResult padding = arena_get_align_padding(arena, alignment);
if (!padding.is_valid) {
return padding.err;
SizeResult padding_res = arena_get_align_padding(arena, alignment);
if (!padding_res.is_valid) {
return padding_res.err;
}
size_t padding = padding_res.val;
while (true) {
if (arena->offset > SIZE_MAX - padding.val - size) {
size_t required;
if (arena->offset > SIZE_MAX - padding) {
return ARENA_CAPACITY_OVERFLOW;
}
required = arena->offset + padding;
size_t required = arena->offset + padding.val + size;
if (required > SIZE_MAX - size) {
return ARENA_CAPACITY_OVERFLOW;
}
required += size;
if (required <= arena->capacity) {
return ARENA_OK;
}
size_t new_capacity;
if (mul_size_t_safe(arena->capacity, 2, &new_capacity)) {
if (arena->capacity > SIZE_MAX / 2) {
return ARENA_CAPACITY_OVERFLOW;
}
new_capacity = arena->capacity * 2;
if (new_capacity < required) {
new_capacity = required;
}
ArenaErr err = arena_realloc(arena, new_capacity);
if (err != ARENA_OK) {
return err;
@@ -159,17 +175,22 @@ ArenaErr arena_realloc(Arena *arena, size_t new_capacity) {
SizeResult arena_get_align_padding(Arena *arena, size_t alignment) {
if (arena == NULL) {
return (SizeResult) {.is_valid = false, .err = ARENA_NULL_ARG};
return (SizeResult){ .is_valid = false, .err = ARENA_NULL_ARG };
}
if (alignment < 1) {
return (SizeResult) {.is_valid = false, .err = ARENA_INVALID_ALIGN};
if (alignment == 0 || (alignment & (alignment - 1)) != 0) {
return (SizeResult){ .is_valid = false, .err = ARENA_INVALID_ALIGN };
}
uintptr_t current_address = (uintptr_t) (arena->buffer + arena->offset);
uintptr_t aligned = ((current_address + (alignment - 1)) & ~(alignment - 1));
uintptr_t current_address = (uintptr_t)(arena->buffer + arena->offset);
return (SizeResult) {.is_valid = true, .err = aligned - current_address};
size_t mask = alignment - 1;
size_t padding = (size_t)(-current_address) & mask;
return (SizeResult){
.is_valid = true,
.val = padding
};
}
void *arena_unwrap_pointer(ArenaPointer p) {
@@ -179,7 +200,17 @@ void *arena_unwrap_pointer(ArenaPointer p) {
return p.arena->buffer + p.offset;
}
bool mul_size_t_safe(size_t a, size_t b, size_t *out) {
static inline bool is_power_of_two(size_t x) {
return x != 0 && (x & (x - 1)) == 0;
}
static inline bool add_size_t_safe(size_t a, size_t b, size_t *out) {
if (a > SIZE_MAX - b) return true;
*out = a + b;
return false;
}
static inline bool mul_size_t_safe(size_t a, size_t b, size_t *out) {
if (out == NULL) {
return true;
}