Compare commits

..

3 Commits

Author SHA1 Message Date
Ed_
ac05262c8d finished arena (lottes.c) 2025-11-05 22:21:44 -05:00
Ed_
3bb46692e1 Update lottes hybrid 2025-11-05 20:43:42 -05:00
Ed_
a7d17a8b70 changes to watl.v0.msvc.c
Made everything internal linkage.
Moved memory operations impl to header section (keeping same loc as I have for the lottes variants).
arena__grow && arena__shirnk lifted to definitions.
2025-11-05 20:00:41 -05:00
6 changed files with 769 additions and 718 deletions

View File

@@ -12,7 +12,7 @@ https://youtu.be/RrL7121MOeA
#pragma clang diagnostic ignored "-Wpre-c11-compat" #pragma clang diagnostic ignored "-Wpre-c11-compat"
// #pragma clang diagnostic ignored "-Wc++-keyword" // #pragma clang diagnostic ignored "-Wc++-keyword"
#pragma clang diagnostic ignored "-Wcast-qual" #pragma clang diagnostic ignored "-Wcast-qual"
#pragma clang diagnostic ignored "-Wunused-const-variable" // #pragma clang diagnostic ignored "-Wunused-constvariable"
#pragma clang diagnostic ignored "-Wunused-but-set-variable" #pragma clang diagnostic ignored "-Wunused-but-set-variable"
#pragma clang diagnostic ignored "-Wswitch" #pragma clang diagnostic ignored "-Wswitch"
#pragma clang diagnostic ignored "-Wunused-variable" #pragma clang diagnostic ignored "-Wunused-variable"
@@ -40,15 +40,14 @@ https://youtu.be/RrL7121MOeA
#pragma region Header #pragma region Header
#pragma region DSL #pragma region DSL
#define local_persist static #define LP_ static
#define global static #define G_ static
#define internal static
#define A_(x) __attribute__((aligned (x))) #define A_(x) __attribute__((aligned (x)))
#define E_(x,y) __builtin_expect(x,y) #define E_(x,y) __builtin_expect(x,y)
#define S_ static #define S_ static
#define I_ internal inline __attribute__((always_inline)) #define I_ S_ inline __attribute__((always_inline))
#define N_ internal __attribute__((noinline)) #define N_ S_ __attribute__((noinline))
#define R_ __restrict #define R_ __restrict
#define V_ volatile #define V_ volatile
#define W_ __attribute((__stdcall__)) __attribute__((__force_align_arg_pointer__)) #define W_ __attribute((__stdcall__)) __attribute__((__force_align_arg_pointer__))
@@ -206,7 +205,7 @@ typedef def_struct(Slice_Str8) { U8 ptr; U8 len; };
} \ } \
} while(0) } while(0)
// Deviation from Lottes's Convention: Don't want to mess with passing in typeless strings to the assert handler. // Deviation from Lottes's Convention: Don't want to mess with passing in typeless strings to the assert handler.
void assert_handler(UTF8*R_ condition, UTF8*R_ file, UTF8*R_ function, S4 line, UTF8*R_ msg, ... ); S_ void assert_handler(UTF8*R_ condition, UTF8*R_ file, UTF8*R_ function, S4 line, UTF8*R_ msg, ... );
#else #else
#define debug_trap() #define debug_trap()
#define assert_trap(cond) #define assert_trap(cond)
@@ -439,8 +438,8 @@ I_ Slice_Mem mem__shrink(AllocatorInfo ainfo, Slice_Mem mem, U8 size, Opts_mem_s
#define mem_resize(ainfo, mem, size, ...) mem__resize(ainfo, mem, size, opt_args(Opts_mem_resize, __VA_ARGS__)) #define mem_resize(ainfo, mem, size, ...) mem__resize(ainfo, mem, size, opt_args(Opts_mem_resize, __VA_ARGS__))
#define mem_shrink(ainfo, mem, size, ...) mem__shrink(ainfo, mem, size, opt_args(Opts_mem_shrink, __VA_ARGS__)) #define mem_shrink(ainfo, mem, size, ...) mem__shrink(ainfo, mem, size, opt_args(Opts_mem_shrink, __VA_ARGS__))
#define alloc_type(ainfo, type, ...) (type*) mem__alloc(ainfo, size_of(type), opt_args(Opts_mem_alloc, __VA_ARGS__)).ptr #define alloc_type(ainfo, type, ...) (type*) mem__alloc(ainfo, size_of(type), opt_args(Opts_mem_alloc, __VA_ARGS__)).ptr
#define alloc_slice(ainfo, type, num, ...) (tmpl(Slice,type)){ (type*)mem__alloc(ainfo, size_of(type) * num, opt_args(Opts_mem_alloc, __VA_ARGS__)).ptr, num } #define alloc_slice(ainfo, type, num, ...) (tmpl(Slice,type)){ (type*)mem__alloc(ainfo, size_of(type) * num, opt_args(Opts_mem_alloc, __VA_ARGS__)).ptr, num }
#pragma endregion Allocator Interface #pragma endregion Allocator Interface
#pragma region FArena (Fixed-Sized Arena) #pragma region FArena (Fixed-Sized Arena)
@@ -454,7 +453,7 @@ typedef def_struct(FArena) {
}; };
I_ void farena_init__u (U8 arena, U8 mem_ptr, U8 mem_len); I_ void farena_init__u (U8 arena, U8 mem_ptr, U8 mem_len);
void farena__push__u (U8 arena, U8 amount, U8 type_width, U8 alignment, U8 slice_addr); S_ void farena__push__u (U8 arena, U8 amount, U8 type_width, U8 alignment, U8 slice_addr);
I_ void farena_reset__u (U8 arena); I_ void farena_reset__u (U8 arena);
I_ void farena_rewind__u(U8 arena, U8 sp_slot); I_ void farena_rewind__u(U8 arena, U8 sp_slot);
I_ void farena_save__u (U8 arena, U8 sp); I_ void farena_save__u (U8 arena, U8 sp);
@@ -466,7 +465,7 @@ I_ void farena_reset (FArena_R arena);
I_ void farena_rewind(FArena_R arena, AllocatorSP save_point); I_ void farena_rewind(FArena_R arena, AllocatorSP save_point);
I_ AllocatorSP farena_save (FArena arena); I_ AllocatorSP farena_save (FArena arena);
void farena_allocator_proc(U8 data, U8 requested_size, U8 alignment, U8 old_ptr, U8 old_len, U4 op, /*AllocatorProc_Out*/U8 out); S_ void farena_allocator_proc(U8 data, U8 requested_size, U8 alignment, U8 old_ptr, U8 old_len, U4 op, /*AllocatorProc_Out*/U8 out);
#define ainfo_farena(arena) (AllocatorInfo){ .proc = farena_allocator_proc, .data = u8_(& arena) } #define ainfo_farena(arena) (AllocatorInfo){ .proc = farena_allocator_proc, .data = u8_(& arena) }
#define farena_push_mem(arena, amount, ...) farena__push(arena, amount, 1, opt_args(Opts_farena, lit(stringify(B1)), __VA_ARGS__)) #define farena_push_mem(arena, amount, ...) farena__push(arena, amount, 1, opt_args(Opts_farena, lit(stringify(B1)), __VA_ARGS__))
@@ -483,10 +482,10 @@ typedef def_struct(OS_SystemInfo) { U8 target_page_size; };
typedef def_struct(Opts_vmem) { U8 base_addr; B4 no_large_pages; A4_B1 _PAD_; }; typedef def_struct(Opts_vmem) { U8 base_addr; B4 no_large_pages; A4_B1 _PAD_; };
typedef def_struct(OS_Windows_State) { OS_SystemInfo system_info; }; typedef def_struct(OS_Windows_State) { OS_SystemInfo system_info; };
global OS_Windows_State os__windows_info; G_ OS_Windows_State os__windows_info;
I_ OS_SystemInfo* os_system_info(void); I_ U8 os_system_info(void);
void os_init (void); S_ void os_init (void);
I_ U8 os_vmem_reserve__u( U8 size, B4 no_large_pages, U8 base_addr); I_ U8 os_vmem_reserve__u( U8 size, B4 no_large_pages, U8 base_addr);
I_ B4 os_vmem_commit__u (U8 vm, U8 size, B4 no_large_pages); I_ B4 os_vmem_commit__u (U8 vm, U8 size, B4 no_large_pages);
@@ -520,14 +519,14 @@ typedef def_struct(Opts_varena_make) {
VArenaFlags flags; VArenaFlags flags;
}; };
U8 varena__make__u (U8 reserve_size, U8 commit_size, U4 flags, U8 base_addr); S_ U8 varena__make__u (U8 reserve_size, U8 commit_size, U4 flags, U8 base_addr);
I_ void varena_release__u(U8 arena); I_ void varena_release__u(U8 arena);
I_ void varena_reset__u (U8 arena); I_ void varena_reset__u (U8 arena);
I_ void varena_rewind__u (U8 arena, U8 sp_slot); I_ void varena_rewind__u (U8 arena, U8 sp_slot);
I_ void varena_save__u (U8 arena, U8 sp_addr); I_ void varena_save__u (U8 arena, U8 sp_addr);
void varena__push__u (U8 arena, U8 amount, U8 type_width, U8 alignment, U8 slice_addr); S_ void varena__push__u (U8 arena, U8 amount, U8 type_width, U8 alignment, U8 slice_addr);
void varena__grow__u (U8 result, U8 arena, U8 old_ptr, U8 old_len, U8 requested_size, U8 alignment, B4 should_zero); S_ void varena__grow__u (U8 result, U8 arena, U8 old_ptr, U8 old_len, U8 requested_size, U8 alignment, B4 should_zero);
void varena__shrink__u(U8 result, U8 arena, U8 old_ptr, U8 old_len, U8 requested_size, U8 alignment); S_ void varena__shrink__u(U8 result, U8 arena, U8 old_ptr, U8 old_len, U8 requested_size, U8 alignment);
I_ VArena* varena__make (Opts_varena_make*R_ opts); I_ VArena* varena__make (Opts_varena_make*R_ opts);
I_ Slice_Mem varena__push (VArena_R arena, U8 amount, U8 type_width, Opts_varena*R_ opts); I_ Slice_Mem varena__push (VArena_R arena, U8 amount, U8 type_width, Opts_varena*R_ opts);
@@ -539,7 +538,7 @@ I_ AllocatorSP varena_save (VArena_R arena);
#define varena_make(...) varena__make(opt_args(Opts_varena_make, __VA_ARGS__)) #define varena_make(...) varena__make(opt_args(Opts_varena_make, __VA_ARGS__))
void varena_allocator_proc(U8 data, U8 requested_size, U8 alignment, U8 old_ptr, U8 old_len, U4 op, /*AllocatorProc_Out*/U8 out); S_ void varena_allocator_proc(U8 data, U8 requested_size, U8 alignment, U8 old_ptr, U8 old_len, U4 op, /*AllocatorProc_Out*/U8 out);
#define ainfo_varena(arena) (AllocatorInfo){ .proc = varena_allocator_proc, .data = u8_(arena) } #define ainfo_varena(arena) (AllocatorInfo){ .proc = varena_allocator_proc, .data = u8_(arena) }
@@ -568,22 +567,22 @@ typedef def_struct(Arena) {
A4_B1 _PAD_; A4_B1 _PAD_;
}; };
U8 arena_make__u (U8 reserve_size, U8 commit_size, U4 flags, U8 base_addr); S_ U8 arena_make__u (U8 reserve_size, U8 commit_size, U4 flags, U8 base_addr);
void arena__push__u (U8 arena, U8 amount, U8 type_width, U8 alignemnt, U8 out_mem); S_ void arena__push__u (U8 arena, U8 amount, U8 type_width, U8 alignemnt, U8 out_mem);
void arena_release__u(U8 arena); I_ void arena_release__u(U8 arena);
void arena_reset__u (U8 arena); I_ void arena_reset__u (U8 arena);
void arena_rewind__u (U8 arena, U8 slot); S_ void arena_rewind__u (U8 arena, U8 slot);
void arena_save__u (U8 arena, U8 out_sp); I_ void arena_save__u (U8 arena, U8 out_sp);
typedef Opts_varena_make Opts_arena_make; typedef Opts_varena_make Opts_arena_make;
Arena* arena__make (Opts_arena_make*R_ opts); S_ Arena* arena__make (Opts_arena_make*R_ opts);
Slice_Mem arena__push (Arena_R arena, U8 amount, U8 type_width, Opts_arena*R_ opts); S_ Slice_Mem arena__push (Arena_R arena, U8 amount, U8 type_width, Opts_arena*R_ opts);
I_ void arena_release(Arena_R arena); I_ void arena_release(Arena_R arena);
I_ void arena_reset (Arena_R arena); I_ void arena_reset (Arena_R arena);
void arena_rewind (Arena_R arena, AllocatorSP save_point); S_ void arena_rewind (Arena_R arena, AllocatorSP save_point);
I_ AllocatorSP arena_save (Arena_R arena); I_ AllocatorSP arena_save (Arena_R arena);
void arena_allocator_proc(U8 data, U8 requested_size, U8 alignment, U8 old_ptr, U8 old_len, U4 op, /*AllocatorProc_Out*/U8 out); S_ void arena_allocator_proc(U8 data, U8 requested_size, U8 alignment, U8 old_ptr, U8 old_len, U4 op, /*AllocatorProc_Out*/U8 out);
#define ainfo_arena(arena) (AllocatorInfo){ .proc = & arena_allocator_proc, .data = u8_(arena) } #define ainfo_arena(arena) (AllocatorInfo){ .proc = & arena_allocator_proc, .data = u8_(arena) }
#define arena_make(...) arena__make(opt_args(Opts_arena_make, __VA_ARGS__)) #define arena_make(...) arena__make(opt_args(Opts_arena_make, __VA_ARGS__))
@@ -599,7 +598,7 @@ cast(type*, arena__push(arena, 1, size_of(type), opt_args(Opts_arena, lit(string
#pragma region Hashing #pragma region Hashing
I_ void hash64_fnv1a__u(U8 hash, U8 data_ptr, U8 data_len, U8 seed) { I_ void hash64_fnv1a__u(U8 hash, U8 data_ptr, U8 data_len, U8 seed) {
local_persist U8 const default_seed = 0xcbf29ce484222325; LP_ U8 const default_seed = 0xcbf29ce484222325;
if (seed != 0) { u8_r(hash)[0] = seed; } if (seed != 0) { u8_r(hash)[0] = seed; }
else { u8_r(hash)[0] = default_seed; } else { u8_r(hash)[0] = default_seed; }
U8 elem = data_ptr; U8 elem = data_ptr;
@@ -642,7 +641,7 @@ typedef def_farray(Str8, 2);
typedef def_Slice(A2_Str8); typedef def_Slice(A2_Str8);
typedef def_KTL_Slot(Str8); typedef def_KTL_Slot(Str8);
typedef def_KTL(Str8); typedef def_KTL(Str8);
void ktl_populate_slice_a2_str8(U8 kt, U8 backing_proc, U8 backing_data, U8 values); I_ void ktl_populate_slice_a2_str8(U8 kt, U8 backing_proc, U8 backing_data, U8 values);
#pragma endregion KTL #pragma endregion KTL
#pragma region Key Table 1-Layer Chained-Chunked-Cells (KT1CX) #pragma region Key Table 1-Layer Chained-Chunked-Cells (KT1CX)
@@ -651,7 +650,7 @@ void ktl_populate_slice_a2_str8(U8 kt, U8 backing_proc, U8 backing_data, U8 valu
#pragma region String Operations #pragma region String Operations
#pragma endregion String Operations #pragma endregion String Operations
#pragma region FIle System #pragma region File System
#pragma endregion FIle System #pragma endregion FIle System
#pragma region WATL #pragma region WATL
@@ -747,8 +746,8 @@ I_ void farena_init__u(U8 arena, U8 mem_ptr, U8 mem_len) {
u8_r(arena + soff(FArena, capacity))[0] = mem_len; u8_r(arena + soff(FArena, capacity))[0] = mem_len;
u8_r(arena + soff(FArena, used) )[0] = 0; u8_r(arena + soff(FArena, used) )[0] = 0;
} }
inline void farena__push__u(U8 arena, U8 amount, U8 type_width, U8 alignment, U8 result) { S_ inline void farena__push__u(U8 arena, U8 amount, U8 type_width, U8 alignment, U8 result) {
if (amount == 0) { struct_zero(Slice_Mem, result); } if (amount == 0) { slice_clear(result); }
U8 desired = type_width * amount; U8 desired = type_width * amount;
U8 to_commit = align_pow2(desired, alignment ? alignment : MEMORY_ALIGNMENT_DEFAULT); U8 to_commit = align_pow2(desired, alignment ? alignment : MEMORY_ALIGNMENT_DEFAULT);
U8_R used = u8_r(arena + soff(FArena, used)); U8_R used = u8_r(arena + soff(FArena, used));
@@ -757,7 +756,7 @@ inline void farena__push__u(U8 arena, U8 amount, U8 type_width, U8 alignment, U8
used[0] += to_commit; used[0] += to_commit;
slice_assign_comp(result, ptr, desired); slice_assign_comp(result, ptr, desired);
} }
inline void farena__grow__u(U8 result, U8 arena, U8 old_ptr, U8 old_len, U8 requested_size, U8 alignment, B4 should_zero) { S_ inline void farena__grow__u(U8 result, U8 arena, U8 old_ptr, U8 old_len, U8 requested_size, U8 alignment, B4 should_zero) {
assert(result != null); assert(result != null);
assert(arena != null); assert(arena != null);
U8_R used = u8_r(arena + soff(FArena, used)); U8_R used = u8_r(arena + soff(FArena, used));
@@ -783,7 +782,7 @@ inline void farena__grow__u(U8 result, U8 arena, U8 old_ptr, U8 old_len, U8 requ
slice_assign_comp(result, old_ptr, aligned_grow + requested_size); slice_assign_comp(result, old_ptr, aligned_grow + requested_size);
mem_zero(old_ptr + old_len, grow_amount * cast(U8, should_zero)); mem_zero(old_ptr + old_len, grow_amount * cast(U8, should_zero));
} }
inline void farena__shrink__u(U8 result, U8 arena, U8 old_ptr, U8 old_len, U8 requested_size, U8 alignment) { S_ inline void farena__shrink__u(U8 result, U8 arena, U8 old_ptr, U8 old_len, U8 requested_size, U8 alignment) {
assert(result != null); assert(result != null);
assert(arena != null); assert(arena != null);
U8_R used = u8_r(arena + soff(FArena, used)); U8_R used = u8_r(arena + soff(FArena, used));
@@ -812,7 +811,7 @@ I_ void farena_save__u(U8 arena, U8 sp) {
u8_r(sp + soff(AllocatorSP, type_sig))[0] = (U8)& farena_allocator_proc; u8_r(sp + soff(AllocatorSP, type_sig))[0] = (U8)& farena_allocator_proc;
u8_r(sp + soff(AllocatorSP, slot ))[0] = u8_r(arena + soff(FArena, used))[0]; u8_r(sp + soff(AllocatorSP, slot ))[0] = u8_r(arena + soff(FArena, used))[0];
} }
void farena_allocator_proc(U8 arena, U8 requested_size, U8 alignment, U8 old_ptr, U8 old_len, U4 op, /*AllocatorProc_Out*/U8 out) S_ void farena_allocator_proc(U8 arena, U8 requested_size, U8 alignment, U8 old_ptr, U8 old_len, U4 op, /*AllocatorProc_Out*/U8 out)
{ {
assert(out != null); assert(out != null);
assert(arena != null); assert(arena != null);
@@ -910,8 +909,8 @@ W_ MS_LPVOID ms_virtual_alloc(MS_LPVOID lpAddress, U8 dwSize, MS_DWORD flAllocat
W_ MS_BOOL ms_virtual_free(MS_LPVOID lpAddress, U8 dwSize, MS_DWORD dwFreeType) __asm__("VirtualFree"); W_ MS_BOOL ms_virtual_free(MS_LPVOID lpAddress, U8 dwSize, MS_DWORD dwFreeType) __asm__("VirtualFree");
#pragma warning(pop) #pragma warning(pop)
I_ OS_SystemInfo* os_system_info(void) { I_ U8 os_system_info(void) {
return & os__windows_info.system_info; return u8_(& os__windows_info.system_info);
} }
I_ void os__enable_large_pages(void) { I_ void os__enable_large_pages(void) {
MS_HANDLE token; MS_HANDLE token;
@@ -927,10 +926,10 @@ I_ void os__enable_large_pages(void) {
ms_close_handle(token); ms_close_handle(token);
} }
} }
inline S_ inline
void os_init(void) { void os_init(void) {
// os__enable_large_pages(); // os__enable_large_pages();
os_system_info()->target_page_size = ms_get_larg_page_minimum(); u8_r(os_system_info() + soff(OS_SystemInfo, target_page_size))[0] = ms_get_larg_page_minimum();
} }
I_ U8 os_vmem_reserve__u(U8 size, B4 no_large_pages, U8 base_addr) { I_ U8 os_vmem_reserve__u(U8 size, B4 no_large_pages, U8 base_addr) {
return cast(U8, ms_virtual_alloc(cast(MS_LPVOID, base_addr), size, MS_MEM_RESERVE, return cast(U8, ms_virtual_alloc(cast(MS_LPVOID, base_addr), size, MS_MEM_RESERVE,
@@ -957,10 +956,10 @@ I_ void os_vmem_release(U8 vm, U8 size) { os_vmem_release__u(vm, size); }
#pragma region VArena (Virtual Address Space Arena) #pragma region VArena (Virtual Address Space Arena)
I_ U8 varena_header_size(void) { return align_pow2(size_of(VArena), MEMORY_ALIGNMENT_DEFAULT); } I_ U8 varena_header_size(void) { return align_pow2(size_of(VArena), MEMORY_ALIGNMENT_DEFAULT); }
inline U8 varena__make__u(U8 reserve_size, U8 commit_size, U4 flags, U8 base_addr) { S_ inline U8 varena__make__u(U8 reserve_size, U8 commit_size, U4 flags, U8 base_addr) {
if (reserve_size == 0) { reserve_size = mega(64); } if (reserve_size == 0) { reserve_size = mega(64); }
if (commit_size == 0) { commit_size = mega(64); } if (commit_size == 0) { commit_size = mega(64); }
U8 page = os_system_info()->target_page_size; U8 page = u8_r(os_system_info() + soff(OS_SystemInfo, target_page_size))[0];
U8 reserve_sz = align_pow2(reserve_size, page); U8 reserve_sz = align_pow2(reserve_size, page);
U8 commit_sz = align_pow2(commit_size, page); U8 commit_sz = align_pow2(commit_size, page);
B4 no_large = (flags & VArenaFlag_NoLargePages) != 0; B4 no_large = (flags & VArenaFlag_NoLargePages) != 0;
@@ -976,18 +975,17 @@ inline U8 varena__make__u(U8 reserve_size, U8 commit_size, U4 flags, U8 base_add
u4_r(base + soff(VArena, flags ))[0] = flags; u4_r(base + soff(VArena, flags ))[0] = flags;
return base; return base;
} }
inline S_ inline void varena__push__u(U8 vm, U8 amount, U8 type_width, U8 alignment, U8 result) {
void varena__push__u(U8 vm, U8 amount, U8 type_width, U8 alignment, U8 result) {
assert(result != null); assert(result != null);
assert(vm != null); assert(vm != null);
if (amount == 0) { slice_clear(result); return; } if (amount == 0) { slice_clear(result); return; }
alignment = alignment == 0 ? alignment : MEMORY_ALIGNMENT_DEFAULT; alignment = alignment == 0 ? alignment : MEMORY_ALIGNMENT_DEFAULT;
U8 requested_size = amount * type_width; U8 requested_size = amount * type_width;
U8 aligned_size = align_pow2(requested_size, alignment); U8 aligned_size = align_pow2(requested_size, alignment);
U8_R commit_used = u8_r(vm + soff(VArena, commit_used )); U8_R commit_used = u8_r(vm + soff(VArena, commit_used));
U8 to_be_used = commit_used[0] + aligned_size; U8 to_be_used = commit_used[0] + aligned_size;
U8 reserve_left = u8_r(vm + soff(VArena, reserve ))[0] - commit_used[0]; U8 reserve_left = u8_r(vm + soff(VArena, reserve ))[0] - commit_used[0];
U8 committed = u8_r(vm + soff(VArena, committed ))[0]; U8 committed = u8_r(vm + soff(VArena, committed))[0];
U8 commit_left = committed - commit_used[0]; U8 commit_left = committed - commit_used[0];
assert(to_be_used< reserve_left); assert(to_be_used< reserve_left);
if (/*exhausted?*/commit_left < aligned_size) { if (/*exhausted?*/commit_left < aligned_size) {
@@ -997,7 +995,7 @@ void varena__push__u(U8 vm, U8 amount, U8 type_width, U8 alignment, U8 result) {
B4 no_large_pages = (u4_r(vm + soff(VArena, flags))[0] & VArenaFlag_NoLargePages) != 0; B4 no_large_pages = (u4_r(vm + soff(VArena, flags))[0] & VArenaFlag_NoLargePages) != 0;
U8 next_commit_start = vm + committed; U8 next_commit_start = vm + committed;
if (os_vmem_commit__u(next_commit_start, next_commit_size, no_large_pages) == false) { if (os_vmem_commit__u(next_commit_start, next_commit_size, no_large_pages) == false) {
struct_zero(Slice_Mem, result); slice_clear(result);
return; return;
} }
committed += next_commit_size; committed += next_commit_size;
@@ -1006,14 +1004,13 @@ void varena__push__u(U8 vm, U8 amount, U8 type_width, U8 alignment, U8 result) {
} }
commit_used[0] += aligned_size; commit_used[0] += aligned_size;
U8 current_offset = u8_r(vm + soff(VArena, reserve_start))[0] + commit_used[0]; U8 current_offset = u8_r(vm + soff(VArena, reserve_start))[0] + commit_used[0];
slice_assign(result, (U8)& slice_mem(current_offset, requested_size)); slice_assign_comp(result, current_offset, requested_size);
} }
inline S_ inline void varena__grow__u(U8 result, U8 vm, U8 old_ptr, U8 old_len, U8 requested_size, U8 alignment, B4 should_zero) {
void varena__grow__u(U8 result, U8 vm, U8 old_ptr, U8 old_len, U8 requested_size, U8 alignment, B4 should_zero) {
assert(vm != null); assert(vm != null);
assert(result != null); assert(result != null);
U8 grow_amount = requested_size - old_len; U8 grow_amount = requested_size - old_len;
if (grow_amount == 0) { slice_assign(result, (U8)& slice_mem(old_ptr, old_len)); return; } if (grow_amount == 0) { slice_assign_comp(result, old_ptr, old_len); return; }
U8 current_offset = u8_r(vm + soff(VArena, reserve_start))[0] + u8_r(vm + soff(VArena, commit_used))[0]; U8 current_offset = u8_r(vm + soff(VArena, reserve_start))[0] + u8_r(vm + soff(VArena, commit_used))[0];
// Growing when not the last allocation not allowed // Growing when not the last allocation not allowed
assert(old_ptr == current_offset); assert(old_ptr == current_offset);
@@ -1022,18 +1019,17 @@ void varena__grow__u(U8 result, U8 vm, U8 old_ptr, U8 old_len, U8 requested_size
U8 a_len = u8_r(allocation + soff(Slice_Mem, len))[0]; U8 a_len = u8_r(allocation + soff(Slice_Mem, len))[0];
assert(a_ptr != 0); assert(a_ptr != 0);
mem_zero(a_ptr, a_len * should_zero); mem_zero(a_ptr, a_len * should_zero);
slice_assign(result, (U8)& slice_mem(old_ptr, old_len + a_len)); slice_assign_comp(result, old_ptr, old_len + a_len);
} }
inline S_ inline void varena__shrink__u(U8 result, U8 vm, U8 old_ptr, U8 old_len, U8 requested_size, U8 alignment) {
void varena__shrink__u(U8 result, U8 vm, U8 old_ptr, U8 old_len, U8 requested_size, U8 alignment) {
assert(vm != null); assert(vm != null);
assert(result != null); assert(result != null);
U8 shrink_amount = old_len - requested_size; U8 shrink_amount = old_len - requested_size;
if (lt_s(shrink_amount, 0)) { slice_assign(result, (U8)& slice_mem(old_ptr, old_len)); return; } if (lt_s(shrink_amount, 0)) { slice_assign_comp(result, old_ptr, old_len); return; }
U8_R commit_used = u8_r(vm + soff(VArena, commit_used)); U8_R commit_used = u8_r(vm + soff(VArena, commit_used));
U8 current_offset = u8_r(vm + soff(VArena, reserve_start))[0] + commit_used[0]; assert(old_ptr == current_offset); U8 current_offset = u8_r(vm + soff(VArena, reserve_start))[0] + commit_used[0]; assert(old_ptr == current_offset);
commit_used[0] -= shrink_amount; commit_used[0] -= shrink_amount;
slice_assign(result, (U8)& slice_mem(old_ptr, requested_size)); slice_assign_comp(result, old_ptr, requested_size);
} }
I_ void varena_release__u(U8 vm) { I_ void varena_release__u(U8 vm) {
assert(vm != null); assert(vm != null);
@@ -1079,8 +1075,7 @@ I_ void varena_rewind (VArena_R vm, AllocatorSP save_point) {
varena_rewind__u(u8_(vm), save_point.slot); varena_rewind__u(u8_(vm), save_point.slot);
} }
I_ AllocatorSP varena_save(VArena_R vm) { AllocatorSP sp; varena_save__u(u8_(vm), u8_(& sp)); return sp; } I_ AllocatorSP varena_save(VArena_R vm) { AllocatorSP sp; varena_save__u(u8_(vm), u8_(& sp)); return sp; }
S_ void varena_allocator_proc(U8 vm, U8 requested_size, U8 alignment, U8 old_ptr, U8 old_len, U4 op, U8 out_addr)
void varena_allocator_proc(U8 vm, U8 requested_size, U8 alignment, U8 old_ptr, U8 old_len, U4 op, U8 out_addr)
{ {
assert(vm != null); assert(vm != null);
assert(out_addr != null); assert(out_addr != null);
@@ -1108,7 +1103,7 @@ void varena_allocator_proc(U8 vm, U8 requested_size, U8 alignment, U8 old_ptr, U
varena__shrink__u(out_allocation, vm, old_ptr, old_len, requested_size, alignment); varena__shrink__u(out_allocation, vm, old_ptr, old_len, requested_size, alignment);
break; break;
case AllocatorOp_Rewind: varena_rewind__u(vm, old_len); break; case AllocatorOp_Rewind: varena_rewind__u(vm, old_len); break;
case AllocatorOp_SavePoint: varena_save__u (vm, out_addr + soff(AllocatorProc_Out, save_point)); break; case AllocatorOp_SavePoint: varena_save__u (vm, out_addr + soff(AllocatorProc_Out, save_point)); break;
case AllocatorOp_Query: case AllocatorOp_Query:
@@ -1133,7 +1128,7 @@ void varena_allocator_proc(U8 vm, U8 requested_size, U8 alignment, U8 old_ptr, U
#pragma region Arena #pragma region Arena
I_ U8 arena_header_size(void) { return align_pow2(size_of(Arena), MEMORY_ALIGNMENT_DEFAULT); } I_ U8 arena_header_size(void) { return align_pow2(size_of(Arena), MEMORY_ALIGNMENT_DEFAULT); }
U8 arena_make__u(U8 reserve_size, U8 commit_size, U4 flags, U8 base_addr) { S_ inline U8 arena_make__u(U8 reserve_size, U8 commit_size, U4 flags, U8 base_addr) {
U8 header_size = arena_header_size(); U8 header_size = arena_header_size();
U8 current = varena__make__u(reserve_size, commit_size, flags, base_addr); assert(current != null); U8 current = varena__make__u(reserve_size, commit_size, flags, base_addr); assert(current != null);
U8 arena; varena__push__u(current, header_size, 1, MEMORY_ALIGNMENT_DEFAULT, (U8)& arena); U8 arena; varena__push__u(current, header_size, 1, MEMORY_ALIGNMENT_DEFAULT, (U8)& arena);
@@ -1145,7 +1140,7 @@ U8 arena_make__u(U8 reserve_size, U8 commit_size, U4 flags, U8 base_addr) {
u8_r(arena + soff(Arena, flags ))[0] = flags; u8_r(arena + soff(Arena, flags ))[0] = flags;
return arena; return arena;
} }
void arena__push__u(U8 arena, U8 amount, U8 type_width, U8 alignment, U8 out_mem) { S_ inline void arena__push__u(U8 arena, U8 amount, U8 type_width, U8 alignment, U8 out_mem) {
assert(arena != null); assert(arena != null);
U8 active = u8_r(arena + soff(Arena, current ))[0]; U8 active = u8_r(arena + soff(Arena, current ))[0];
U8 size_requested = amount * type_width; U8 size_requested = amount * type_width;
@@ -1178,6 +1173,42 @@ void arena__push__u(U8 arena, U8 amount, U8 type_width, U8 alignment, U8 out_mem
assert(u8_r(out_mem + soff(Slice_Mem, len))[0] > 0); assert(u8_r(out_mem + soff(Slice_Mem, len))[0] > 0);
u8_r(active + soff(Arena, pos))[0] = pos_pst; u8_r(active + soff(Arena, pos))[0] = pos_pst;
} }
S_ inline void arena__grow__u(U8 arena, U8 old_ptr, U8 old_len, U8 requested_size, U8 alignment, B4 should_zero, U8 out_mem) {
U8 active = arena + soff(Arena, current);
U8_R active_pos = u8_r(active + soff(Arena, pos));
U8 alloc_end = old_ptr + old_len;
U8 arena_end = active + active_pos[0];
if (alloc_end == arena_end)
{
U8 grow_amount = requested_size - old_len;
U8 aligned_grow = align_pow2(grow_amount, alignment ? alignment : MEMORY_ALIGNMENT_DEFAULT);
if (active_pos[0] + aligned_grow <= u8_r(active + soff(Arena, backing) + soff(VArena, reserve))[0]) {
uvar(Slice_Mem, vresult); varena__push__u(u8_r(active + soff(Arena, backing))[0], aligned_grow, 1, alignment, (U8)vresult);
if (u8_r(vresult + soff(Slice_Mem, ptr))[0] != null) {
active_pos[0] += aligned_grow;
mem_zero(old_ptr + old_len, aligned_grow * should_zero);
slice_assign_comp(out_mem, u8_(vresult) + soff(Slice_Mem, ptr), u8_(vresult) + soff(Slice_Mem, len));
return;
}
}
}
arena__push__u(arena, requested_size, 1, alignment, out_mem);
if (u8_r(out_mem + soff(Slice_Mem, ptr))[0] == null) { slice_assign_comp(out_mem, 0, 0); return; }
mem_copy(u8_r(out_mem + soff(Slice_Mem, ptr))[0], old_ptr, old_len);
mem_zero(u8_r(out_mem + soff(Slice_Mem, ptr))[0], (u8_r(out_mem + soff(Slice_Mem, len))[0] - old_len) * should_zero);
}
S_ inline void arena__shrink__u(U8 arena, U8 old_ptr, U8 old_len, U8 requested_size, U8 alignment, U8 out_mem) {
U8 active = arena + soff(Arena, current);
U8_R active_pos = u8_r(active + soff(Arena, pos));
U8 alloc_end = old_ptr + old_len;
U8 arena_end = active + active_pos[0];
if (alloc_end != arena_end) { slice_assign_comp(out_mem, old_ptr, old_len); return; }
U8 aligned_original = align_pow2(old_len, MEMORY_ALIGNMENT_DEFAULT);
U8 aligned_new = align_pow2(requested_size, alignment ? alignment : MEMORY_ALIGNMENT_DEFAULT);
U8 pos_reduction = aligned_original - aligned_new;
u8_r(active + soff(Arena, pos))[0] -= pos_reduction;
varena__shrink__u(out_mem, active + soff(Arena, backing), old_ptr, old_len, requested_size, alignment);
}
I_ void arena_release__u(U8 arena) { I_ void arena_release__u(U8 arena) {
assert(arena != null); assert(arena != null);
U8 curr = arena + soff(Arena, current); U8 curr = arena + soff(Arena, current);
@@ -1193,7 +1224,7 @@ void arena_rewind__u(U8 arena, U8 slot) {
U8 header_size = arena_header_size(); U8 header_size = arena_header_size();
U8 curr = arena + soff(Arena, current); U8 curr = arena + soff(Arena, current);
U8 big_pos = clamp_bot(header_size, slot); U8 big_pos = clamp_bot(header_size, slot);
for (U8 prev = null; u8_r(curr, soff(Arena, base_pos))[0] >= big_pos; u8_r(curr) = prev) { for (U8 prev = null; u8_r(curr + soff(Arena, base_pos))[0] >= big_pos; u8_r(curr)[0] = prev) {
prev = u8_r(curr + soff(Arena, prev))[0]; prev = u8_r(curr + soff(Arena, prev))[0];
varena_release__u(u8_r(curr + soff(Arena, backing))[0]); varena_release__u(u8_r(curr + soff(Arena, backing))[0]);
} }
@@ -1202,35 +1233,57 @@ void arena_rewind__u(U8 arena, U8 slot) {
u8_r(curr + soff(Arena, pos))[0] = new_pos; u8_r(curr + soff(Arena, pos))[0] = new_pos;
} }
I_ void arena_save__u(U8 arena, U8 out_sp) { I_ void arena_save__u(U8 arena, U8 out_sp) {
u8_r(out_sp + soff(AllocatorSP, type_sig))[0] = arena_allocator_proc; u8_r(out_sp + soff(AllocatorSP, type_sig))[0] = (U8)& arena_allocator_proc;
u8_r(out_sp + soff(AllocatorSP, slot ))[0] = u8_r(out_sp + soff(AllocatorSP, slot ))[0] =
u8_r(arena + soff(Arena, base_pos) )[0] u8_r(arena + soff(Arena, base_pos) )[0]
+ u8_r(arena + soff(Arena, current) + soff(Arena, pos))[0]; + u8_r(arena + soff(Arena, current) + soff(Arena, pos))[0];
} }
void arena_allocator_proc(U8 arena, U8 requested_size, U8 alignment, U8 old_ptr, U8 old_len, U4 op, U8 out_addr) S_ inline void arena_allocator_proc(U8 arena, U8 requested_size, U8 alignment, U8 old_ptr, U8 old_len, U4 op, U8 out_addr)
{ {
assert(out_addr != null); assert(out_addr != null);
assert(arena != null); assert(arena != null);
U8 out_allocation = out_addr + soff(AllocatorProc_Out, allocation);
switch (op) switch (op)
{ {
case AllocatorOp_Alloc: case AllocatorOp_Alloc:
case AllocatorOp_Alloc_NoZero: case AllocatorOp_Alloc_NoZero:
arena__push__u(arena, requested_size, 1, alignment, out_allocation);
mem_zero(out_allocation, u8_r(out_allocation + soff(Slice_Mem, len))[0] * op);
break; break;
case AllocatorOp_Free: break; case AllocatorOp_Free: break;
case AllocatorOp_Reset: break; case AllocatorOp_Reset: arena_reset__u(arena); break;
case AllocatorOp_Grow: case AllocatorOp_Grow:
case AllocatorOp_Grow_NoZero: break; case AllocatorOp_Grow_NoZero:
case AllocatorOp_Shrink: break; arena__grow__u(arena, old_ptr, old_len, requested_size, alignment, op - AllocatorOp_Grow_NoZero, out_allocation);
break;
case AllocatorOp_Shrink:
arena__shrink__u(arena, old_ptr, old_len, requested_size, alignment, out_allocation);
break;
case AllocatorOp_Rewind: break; case AllocatorOp_Rewind: arena_rewind__u(arena, old_len); break;
case AllocatorOp_SavePoint: break; case AllocatorOp_SavePoint: arena_save__u(arena, out_addr + soff(AllocatorProc_Out, save_point)); break;
case AllocatorOp_Query: case AllocatorOp_Query:
u4_r(out_addr + soff(AllocatorQueryInfo, features))[0] =
AllocatorQuery_Alloc
| AllocatorQuery_Resize
| AllocatorQuery_Reset
| AllocatorQuery_Rewind
;
u8_r(out_addr + soff(AllocatorQueryInfo, max_alloc ))[0] = u8_r(arena + soff(Arena, backing) + soff(VArena, reserve))[0];
u8_r(out_addr + soff(AllocatorQueryInfo, min_alloc ))[0] = kilo(4);
u8_r(out_addr + soff(AllocatorQueryInfo, left ))[0] = u8_r(out_addr + soff(AllocatorQueryInfo, max_alloc))[0] - u8_r(arena + soff(Arena, backing) + soff(VArena, commit_used))[0];
arena_save__u(arena, out_addr + soff(AllocatorQueryInfo, save_point));
break; break;
} }
} }
I_ Arena* arena__make(Opts_arena_make*R_ opts) {
assert(opts != nullptr);
return cast(Arena*, arena_make__u(opts->reserve_size, opts->commit_size, opts->flags, opts->base_addr));
}
#pragma endregion Arena #pragma endregion Arena
#pragma region Key Table Linear (KTL) #pragma region Key Table Linear (KTL)
@@ -1241,7 +1294,7 @@ I_ void ktl_populate_slice_a2_str8(U8 kt, U8 backing_ptr, U8 backing_len, U8 val
mem__alloc__u(kt, backing_ptr, backing_len, size_of(KTL_Slot_Str8) * values_len, 0, false); mem__alloc__u(kt, backing_ptr, backing_len, size_of(KTL_Slot_Str8) * values_len, 0, false);
for (U8 id = 0; id < values_len; ++id) { for (U8 id = 0; id < values_len; ++id) {
U8 kt_slot = kt + soff(KTL_Str8, ptr) * id; U8 kt_slot = kt + soff(KTL_Str8, ptr) * id;
U8 value = u8_r(values + soff(Slice_A2_Str8, ptr))[0] + size_of(A2_Str8) * id; U8 value = u8_r(values + soff(Slice_A2_Str8, ptr) + size_of(A2_Str8) * id)[0];
mem_copy (kt_slot + soff(KTL_Slot_Str8, value), value + size_of(Str8) * 1, size_of(Str8)); mem_copy (kt_slot + soff(KTL_Slot_Str8, value), value + size_of(Str8) * 1, size_of(Str8));
hash64__fnv1a__u(kt_slot + soff(KTL_Slot_Str8, key), value); hash64__fnv1a__u(kt_slot + soff(KTL_Slot_Str8, key), value);
} }
@@ -1276,11 +1329,10 @@ typedef def_struct(__crt_locale_pointers) { struct __crt_locale_data* locinfo; s
typedef __crt_locale_pointers* _locale_t; typedef __crt_locale_pointers* _locale_t;
typedef char* va_list; typedef char* va_list;
MS_FILE* __cdecl __acrt_iob_func(unsigned _Ix); MS_FILE* __cdecl __acrt_iob_func(unsigned _Ix);
N_ N_ U8* __cdecl __local_stdio_printf_options(void) {
U8* __cdecl __local_stdio_printf_options(void) {
// NOTE(CRT): This function must not be inlined into callers to avoid ODR violations. The // NOTE(CRT): This function must not be inlined into callers to avoid ODR violations. The
// static local variable has different names in C and in C++ translation units. // static local variable has different names in C and in C++ translation units.
local_persist U8 _OptionsStorage; return &_OptionsStorage; LP_ U8 _OptionsStorage; return &_OptionsStorage;
} }
int __cdecl __stdio_common_vfprintf_s( int __cdecl __stdio_common_vfprintf_s(
U8 _Options, U8 _Options,
@@ -1298,7 +1350,7 @@ I_ int printf_err(char const* fmt, ...) {
va_end(args); va_end(args);
return result; return result;
} }
void assert_handler( UTF8*R_ condition, UTF8*R_ file, UTF8*R_ function, S4 line, UTF8*R_ msg, ... ) { S_ inline void assert_handler( UTF8*R_ condition, UTF8*R_ file, UTF8*R_ function, S4 line, UTF8*R_ msg, ... ) {
printf_err( "%s - %s:(%d): Assert Failure: ", file, function, line ); printf_err( "%s - %s:(%d): Assert Failure: ", file, function, line );
if ( condition ) if ( condition )
printf_err( "`%s` \n", condition ); printf_err( "`%s` \n", condition );
@@ -1349,7 +1401,7 @@ int main(void)
// .ainfo_lines = ainfo_arena(a_lines), // .ainfo_lines = ainfo_arena(a_lines),
// .str_cache = & str_cache // .str_cache = & str_cache
// ); // );
// assert((parse_res.signal & WATL_ParseStatus_MemFail_SliceConstraintFail) == 0); //assert((parse_res.signal & WATL_ParseStatus_MemFail_SliceConstraintFail) == 0);
// arena_reset(a_msgs); // arena_reset(a_msgs);
// arena_reset(a_toks); // arena_reset(a_toks);

View File

@@ -4,7 +4,7 @@ Version: 0 (From Scratch, 1-Stage Compilation, LLVM & WinAPI Only, Win CRT Mul
Host: Windows 11 (x86-64) Host: Windows 11 (x86-64)
Toolchain: LLVM (2025-08-30), C-Stanard: 11 Toolchain: LLVM (2025-08-30), C-Stanard: 11
Based on: Neokineogfx - Fixing C, personalized to include typeinfo more readily. Based on: Neokineogfx - Fixing C, personalized to utilize typeinfo.
https://youtu.be/RrL7121MOeA https://youtu.be/RrL7121MOeA
*/ */
@@ -185,7 +185,7 @@ typedef def_struct(Slice_Str8) { Str8* ptr; U8 len; };
debug_trap(); \ debug_trap(); \
} \ } \
} while(0) } while(0)
void assert_handler(UTF8*R_ condition, UTF8*R_ file, UTF8*R_ function, S4 line, UTF8*R_ msg, ... ); internal void assert_handler(UTF8*R_ condition, UTF8*R_ file, UTF8*R_ function, S4 line, UTF8*R_ msg, ... );
#else #else
#define debug_trap() #define debug_trap()
#define assert_trap(cond) #define assert_trap(cond)
@@ -404,14 +404,14 @@ typedef def_struct(FArena) {
U8 capacity; U8 capacity;
U8 used; U8 used;
}; };
finline FArena farena_make (Slice_Mem mem); finline FArena farena_make (Slice_Mem mem);
finline void farena_init (FArena_R arena, Slice_Mem byte); finline void farena_init (FArena_R arena, Slice_Mem byte);
Slice_Mem farena__push (FArena_R arena, U8 amount, U8 type_width, Opts_farena*R_ opts); internal Slice_Mem farena__push (FArena_R arena, U8 amount, U8 type_width, Opts_farena*R_ opts);
finline void farena_reset (FArena_R arena); finline void farena_reset (FArena_R arena);
finline void farena_rewind(FArena_R arena, AllocatorSP save_point); finline void farena_rewind(FArena_R arena, AllocatorSP save_point);
finline AllocatorSP farena_save (FArena arena); finline AllocatorSP farena_save (FArena arena);
void farena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out_R out); internal void farena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out_R out);
#define ainfo_farena(arena) (AllocatorInfo){ .proc = farena_allocator_proc, .data = u8_(& arena) } #define ainfo_farena(arena) (AllocatorInfo){ .proc = farena_allocator_proc, .data = u8_(& arena) }
#define farena_push_mem(arena, amount, ...) farena__push(arena, amount, 1, opt_args(Opts_farena, lit(stringify(B1)), __VA_ARGS__)) #define farena_push_mem(arena, amount, ...) farena__push(arena, amount, 1, opt_args(Opts_farena, lit(stringify(B1)), __VA_ARGS__))
@@ -435,8 +435,8 @@ typedef def_struct(Opts_vmem) {
B4 no_large_pages; B4 no_large_pages;
A4_B1 _PAD_; A4_B1 _PAD_;
}; };
void os_init(void); internal void os_init (void);
finline OS_SystemInfo* os_system_info(void); finline OS_SystemInfo* os_system_info(void);
finline B4 os__vmem_commit (U8 vm, U8 size, Opts_vmem*R_ opts); finline B4 os__vmem_commit (U8 vm, U8 size, Opts_vmem*R_ opts);
finline U8 os__vmem_reserve( U8 size, Opts_vmem*R_ opts); finline U8 os__vmem_reserve( U8 size, Opts_vmem*R_ opts);
@@ -467,17 +467,17 @@ typedef def_struct(Opts_varena_make) {
VArenaFlags flags; VArenaFlags flags;
A4_B1 _PAD_; A4_B1 _PAD_;
}; };
VArena* varena__make(Opts_varena_make*R_ opts); internal VArena* varena__make(Opts_varena_make*R_ opts);
#define varena_make(...) varena__make(opt_args(Opts_varena_make, __VA_ARGS__)) #define varena_make(...) varena__make(opt_args(Opts_varena_make, __VA_ARGS__))
Slice_Mem varena__push (VArena_R arena, U8 amount, U8 type_width, Opts_varena*R_ opts); internal Slice_Mem varena__push (VArena_R arena, U8 amount, U8 type_width, Opts_varena*R_ opts);
finline void varena_release(VArena_R arena); finline void varena_release(VArena_R arena);
finline void varena_rewind (VArena_R arena, AllocatorSP save_point); finline void varena_rewind (VArena_R arena, AllocatorSP save_point);
void varena_reset (VArena_R arena); internal void varena_reset (VArena_R arena);
Slice_Mem varena__shrink(VArena_R arena, Slice_Mem old_allocation, U8 requested_size); internal Slice_Mem varena__shrink(VArena_R arena, Slice_Mem old_allocation, U8 requested_size);
finline AllocatorSP varena_save (VArena_R arena); finline AllocatorSP varena_save (VArena_R arena);
void varena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out_R out); internal void varena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out_R out);
#define ainfo_varena(varena) (AllocatorInfo) { .proc = & varena_allocator_proc, .data = u8_(varena) } #define ainfo_varena(varena) (AllocatorInfo) { .proc = & varena_allocator_proc, .data = u8_(varena) }
#define varena_push_mem(arena, amount, ...) varena__push(arena, amount, 1, opt_args(Opts_varena, lit(stringify(B1)), __VA_ARGS__)) #define varena_push_mem(arena, amount, ...) varena__push(arena, amount, 1, opt_args(Opts_varena, lit(stringify(B1)), __VA_ARGS__))
@@ -505,14 +505,14 @@ typedef def_struct(Arena) {
A4_B1 _PAD_; A4_B1 _PAD_;
}; };
typedef Opts_varena_make Opts_arena_make; typedef Opts_varena_make Opts_arena_make;
Arena* arena__make (Opts_arena_make*R_ opts); internal Arena* arena__make (Opts_arena_make*R_ opts);
Slice_Mem arena__push (Arena_R arena, U8 amount, U8 type_width, Opts_arena*R_ opts); internal Slice_Mem arena__push (Arena_R arena, U8 amount, U8 type_width, Opts_arena*R_ opts);
finline void arena_release(Arena_R arena); finline void arena_release(Arena_R arena);
finline void arena_reset (Arena_R arena); finline void arena_reset (Arena_R arena);
void arena_rewind (Arena_R arena, AllocatorSP save_point); internal void arena_rewind (Arena_R arena, AllocatorSP save_point);
finline AllocatorSP arena_save (Arena_R arena); finline AllocatorSP arena_save (Arena_R arena);
void arena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out_R out); internal void arena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out_R out);
#define ainfo_arena(arena) (AllocatorInfo){ .proc = & arena_allocator_proc, .data = u8_(arena) } #define ainfo_arena(arena) (AllocatorInfo){ .proc = & arena_allocator_proc, .data = u8_(arena) }
#define arena_make(...) arena__make(opt_args(Opts_arena_make, __VA_ARGS__)) #define arena_make(...) arena__make(opt_args(Opts_arena_make, __VA_ARGS__))
@@ -568,7 +568,7 @@ typedef def_farray(Str8, 2);
typedef def_Slice(A2_Str8); typedef def_Slice(A2_Str8);
typedef def_KTL_Slot(Str8); typedef def_KTL_Slot(Str8);
typedef def_KTL(Str8); typedef def_KTL(Str8);
void ktl_populate_slice_a2_str8(KTL_Str8*R_ kt, AllocatorInfo backing, Slice_A2_Str8 values); finline void ktl_populate_slice_a2_str8(KTL_Str8*R_ kt, AllocatorInfo backing, Slice_A2_Str8 values);
#pragma endregion KTL #pragma endregion KTL
#pragma region Key Table 1-Layer Chained-Chunked-Cells (KT1CX) #pragma region Key Table 1-Layer Chained-Chunked-Cells (KT1CX)
@@ -623,11 +623,11 @@ typedef def_struct(KT1CX_Info) {
AllocatorInfo backing_table; AllocatorInfo backing_table;
AllocatorInfo backing_cells; AllocatorInfo backing_cells;
}; };
void kt1cx_init (KT1CX_Info info, KT1CX_InfoMeta m, KT1CX_Byte*R_ result); internal void kt1cx_init (KT1CX_Info info, KT1CX_InfoMeta m, KT1CX_Byte*R_ result);
void kt1cx_clear (KT1CX_Byte kt, KT1CX_ByteMeta meta); internal void kt1cx_clear (KT1CX_Byte kt, KT1CX_ByteMeta meta);
finline U8 kt1cx_slot_id(KT1CX_Byte kt, U8 key, KT1CX_ByteMeta meta); finline U8 kt1cx_slot_id(KT1CX_Byte kt, U8 key, KT1CX_ByteMeta meta);
U8 kt1cx_get (KT1CX_Byte kt, U8 key, KT1CX_ByteMeta meta); internal U8 kt1cx_get (KT1CX_Byte kt, U8 key, KT1CX_ByteMeta meta);
U8 kt1cx_set (KT1CX_Byte kt, U8 key, Slice_Mem value, AllocatorInfo backing_cells, KT1CX_ByteMeta meta); internal U8 kt1cx_set (KT1CX_Byte kt, U8 key, Slice_Mem value, AllocatorInfo backing_cells, KT1CX_ByteMeta meta);
#define kt1cx_assert(kt) do { \ #define kt1cx_assert(kt) do { \
slice_assert(kt.table); \ slice_assert(kt.table); \
@@ -642,14 +642,14 @@ finline U1 integer_symbols(U1 value) {
local_persist U1 lookup_table[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F', }; return lookup_table[cast(U1, value)]; local_persist U1 lookup_table[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F', }; return lookup_table[cast(U1, value)];
} }
finline char* str8_to_cstr_capped(Str8 content, Slice_Mem mem); finline char* str8_to_cstr_capped(Str8 content, Slice_Mem mem);
Str8 str8_from_u32(AllocatorInfo ainfo, U4 num, U4 radix, U4 min_digits, U4 digit_group_separator); internal Str8 str8_from_u32(AllocatorInfo ainfo, U4 num, U4 radix, U4 min_digits, U4 digit_group_separator);
finline Str8 str8__fmt_backed(AllocatorInfo tbl_backing, AllocatorInfo buf_backing, Str8 fmt_template, Slice_A2_Str8*R_ entries); finline Str8 str8__fmt_backed(AllocatorInfo tbl_backing, AllocatorInfo buf_backing, Str8 fmt_template, Slice_A2_Str8*R_ entries);
#define str8_fmt_backed(tbl_backing, buf_backing, fmt_template, ...) \ #define str8_fmt_backed(tbl_backing, buf_backing, fmt_template, ...) \
str8__fmt_backed(tbl_backing, buf_backing, lit(fmt_template), slice_arg_from_array(A2_Str8, __VA_ARGS__)) str8__fmt_backed(tbl_backing, buf_backing, lit(fmt_template), slice_arg_from_array(A2_Str8, __VA_ARGS__))
Str8 str8__fmt(Str8 fmt_template, Slice_A2_Str8*R_ entries); internal Str8 str8__fmt(Str8 fmt_template, Slice_A2_Str8*R_ entries);
#define str8_fmt(fmt_template, ...) str8__fmt(lit(fmt_template), slice_arg_from_array(A2_Str8, __VA_ARGS__)) #define str8_fmt(fmt_template, ...) str8__fmt(lit(fmt_template), slice_arg_from_array(A2_Str8, __VA_ARGS__))
#define Str8Cache_CELL_DEPTH 4 #define Str8Cache_CELL_DEPTH 4
@@ -672,8 +672,8 @@ typedef def_struct(Opts_str8cache_init) {
U8 cell_pool_size; U8 cell_pool_size;
U8 table_size; U8 table_size;
}; };
void str8cache__init(Str8Cache_R cache, Opts_str8cache_init*R_ opts); internal void str8cache__init(Str8Cache_R cache, Opts_str8cache_init*R_ opts);
finline Str8Cache str8cache__make( Opts_str8cache_init*R_ opts); finline Str8Cache str8cache__make( Opts_str8cache_init*R_ opts);
#define str8cache_init(cache, ...) str8cache__init(cache, opt_args(Opts_str8cache_init, __VA_ARGS__)) #define str8cache_init(cache, ...) str8cache__init(cache, opt_args(Opts_str8cache_init, __VA_ARGS__))
#define str8cache_make(...) str8cache__make( opt_args(Opts_str8cache_init, __VA_ARGS__)) #define str8cache_make(...) str8cache__make( opt_args(Opts_str8cache_init, __VA_ARGS__))
@@ -697,8 +697,8 @@ finline Str8Gen str8gen_make( AllocatorInfo backing);
finline Str8 str8_from_str8gen(Str8Gen gen) { return (Str8){ cast(UTF8_R, gen.ptr), gen.len}; } finline Str8 str8_from_str8gen(Str8Gen gen) { return (Str8){ cast(UTF8_R, gen.ptr), gen.len}; }
finline void str8gen_append_str8(Str8Gen_R gen, Str8 str); finline void str8gen_append_str8(Str8Gen_R gen, Str8 str);
void str8gen__append_fmt(Str8Gen_R gen, Str8 fmt_template, Slice_A2_Str8*R_ tokens); internal void str8gen__append_fmt(Str8Gen_R gen, Str8 fmt_template, Slice_A2_Str8*R_ tokens);
#define str8gen_append_fmt(gen, fmt_template, ...) str8gen__append_fmt(gen, lit(fmt_template), slice_arg_from_array(A2_Str8, __VA_ARGS__)) #define str8gen_append_fmt(gen, fmt_template, ...) str8gen__append_fmt(gen, lit(fmt_template), slice_arg_from_array(A2_Str8, __VA_ARGS__))
#pragma endregion String Operations #pragma endregion String Operations
@@ -712,8 +712,8 @@ typedef def_struct(Opts_read_file_contents) {
B4 zero_backing; B4 zero_backing;
A4_B1 _PAD_; A4_B1 _PAD_;
}; };
void api_file_read_contents(FileOpInfo_R result, Str8 path, Opts_read_file_contents opts); internal void api_file_read_contents(FileOpInfo_R result, Str8 path, Opts_read_file_contents opts);
void file_write_str8 (Str8 path, Str8 content); internal void file_write_str8 (Str8 path, Str8 content);
finline FileOpInfo file__read_contents(Str8 path, Opts_read_file_contents*R_ opts); finline FileOpInfo file__read_contents(Str8 path, Opts_read_file_contents*R_ opts);
#define file_read_contents(path, ...) file__read_contents(path, opt_args(Opts_read_file_contents, __VA_ARGS__)) #define file_read_contents(path, ...) file__read_contents(path, opt_args(Opts_read_file_contents, __VA_ARGS__))
@@ -756,8 +756,8 @@ typedef def_struct(Opts_watl_lex) {
B1 failon_slice_constraint_fail; B1 failon_slice_constraint_fail;
A4_B1 _PAD_; A4_B1 _PAD_;
}; };
void api_watl_lex(WATL_LexInfo_R info, Str8 source, Opts_watl_lex*R_ opts); internal void api_watl_lex(WATL_LexInfo_R info, Str8 source, Opts_watl_lex*R_ opts);
WATL_LexInfo watl__lex ( Str8 source, Opts_watl_lex*R_ opts); finline WATL_LexInfo watl__lex ( Str8 source, Opts_watl_lex*R_ opts);
#define watl_lex(source, ...) watl__lex(source, opt_args(Opts_watl_lex, __VA_ARGS__)) #define watl_lex(source, ...) watl__lex(source, opt_args(Opts_watl_lex, __VA_ARGS__))
typedef Str8 WATL_Node; typedef def_ptr_set(WATL_Node); typedef Str8 WATL_Node; typedef def_ptr_set(WATL_Node);
@@ -788,11 +788,11 @@ typedef def_struct(Opts_watl_parse) {
B4 failon_slice_constraint_fail; B4 failon_slice_constraint_fail;
A4_B1 _PAD_; A4_B1 _PAD_;
}; };
void api_watl_parse(WATL_ParseInfo_R info, Slice_WATL_Tok tokens, Opts_watl_parse*R_ opts); internal void api_watl_parse(WATL_ParseInfo_R info, Slice_WATL_Tok tokens, Opts_watl_parse*R_ opts);
WATL_ParseInfo watl__parse ( Slice_WATL_Tok tokens, Opts_watl_parse*R_ opts); finline WATL_ParseInfo watl__parse ( Slice_WATL_Tok tokens, Opts_watl_parse*R_ opts);
#define watl_parse(tokens, ...) watl__parse(tokens, opt_args(Opts_watl_parse, __VA_ARGS__)) #define watl_parse(tokens, ...) watl__parse(tokens, opt_args(Opts_watl_parse, __VA_ARGS__))
Str8 watl_dump_listing(AllocatorInfo buffer, Slice_WATL_Line lines); internal Str8 watl_dump_listing(AllocatorInfo buffer, Slice_WATL_Line lines);
#pragma endregion WATL #pragma endregion WATL
#pragma endregion Header #pragma endregion Header
@@ -824,8 +824,7 @@ void mem_rewind(AllocatorInfo ainfo, AllocatorSP save_point) {
finline finline
AllocatorSP mem_save_point(AllocatorInfo ainfo) { AllocatorSP mem_save_point(AllocatorInfo ainfo) {
assert(ainfo.proc != nullptr); assert(ainfo.proc != nullptr);
AllocatorProc_Out out; AllocatorProc_Out out; ainfo.proc((AllocatorProc_In){.data = ainfo.data, .op = AllocatorOp_SavePoint}, & out);
ainfo.proc((AllocatorProc_In){.data = ainfo.data, .op = AllocatorOp_SavePoint}, & out);
return out.save_point; return out.save_point;
} }
finline finline
@@ -838,8 +837,7 @@ Slice_Mem mem__alloc(AllocatorInfo ainfo, U8 size, Opts_mem_alloc*R_ opts) {
.requested_size = size, .requested_size = size,
.alignment = opts->alignment, .alignment = opts->alignment,
}; };
AllocatorProc_Out out; AllocatorProc_Out out; ainfo.proc(in, & out);
ainfo.proc(in, & out);
return out.allocation; return out.allocation;
} }
finline finline
@@ -853,8 +851,7 @@ Slice_Mem mem__grow(AllocatorInfo ainfo, Slice_Mem mem, U8 size, Opts_mem_grow*R
.alignment = opts->alignment, .alignment = opts->alignment,
.old_allocation = mem .old_allocation = mem
}; };
AllocatorProc_Out out; AllocatorProc_Out out; ainfo.proc(in, & out);
ainfo.proc(in, & out);
return (Slice_Mem){ out.allocation.ptr, opts->give_actual ? out.allocation.len : in.requested_size }; return (Slice_Mem){ out.allocation.ptr, opts->give_actual ? out.allocation.len : in.requested_size };
} }
finline finline
@@ -868,8 +865,7 @@ Slice_Mem mem__resize(AllocatorInfo ainfo, Slice_Mem mem, U8 size, Opts_mem_resi
.alignment = opts->alignment, .alignment = opts->alignment,
.old_allocation = mem, .old_allocation = mem,
}; };
AllocatorProc_Out out; AllocatorProc_Out out; ainfo.proc(in, & out);
ainfo.proc(in, & out);
return (Slice_Mem){ out.allocation.ptr, opts->give_actual ? out.allocation.len : in.requested_size }; return (Slice_Mem){ out.allocation.ptr, opts->give_actual ? out.allocation.len : in.requested_size };
} }
finline finline
@@ -883,8 +879,7 @@ Slice_Mem mem__shrink(AllocatorInfo ainfo, Slice_Mem mem, U8 size, Opts_mem_shri
.alignment = opts->alignment, .alignment = opts->alignment,
.old_allocation = mem .old_allocation = mem
}; };
AllocatorProc_Out out; AllocatorProc_Out out; ainfo.proc(in, & out);
ainfo.proc(in, & out);
return out.allocation; return out.allocation;
} }
#pragma endregion Allocator Interface #pragma endregion Allocator Interface
@@ -898,7 +893,7 @@ void farena_init(FArena_R arena, Slice_Mem mem) {
arena->used = 0; arena->used = 0;
} }
finline FArena farena_make(Slice_Mem mem) { FArena a; farena_init(& a, mem); return a; } finline FArena farena_make(Slice_Mem mem) { FArena a; farena_init(& a, mem); return a; }
inline internal inline
Slice_Mem farena__push(FArena_R arena, U8 amount, U8 type_width, Opts_farena*R_ opts) { Slice_Mem farena__push(FArena_R arena, U8 amount, U8 type_width, Opts_farena*R_ opts) {
assert(opts != nullptr); assert(opts != nullptr);
if (amount == 0) { return (Slice_Mem){}; } if (amount == 0) { return (Slice_Mem){}; }
@@ -909,7 +904,7 @@ Slice_Mem farena__push(FArena_R arena, U8 amount, U8 type_width, Opts_farena*R_
arena->used += to_commit; arena->used += to_commit;
return (Slice_Mem){ptr, desired}; return (Slice_Mem){ptr, desired};
} }
inline internal inline
Slice_Mem farena__grow(FArena_R arena, Slice_Mem old_allocation, U8 requested_size, U8 alignment, B4 should_zero) { Slice_Mem farena__grow(FArena_R arena, Slice_Mem old_allocation, U8 requested_size, U8 alignment, B4 should_zero) {
// Check if the allocation is at the end of the arena // Check if the allocation is at the end of the arena
U8 alloc_end = old_allocation.ptr + old_allocation.len; U8 alloc_end = old_allocation.ptr + old_allocation.len;
@@ -927,11 +922,10 @@ Slice_Mem farena__grow(FArena_R arena, Slice_Mem old_allocation, U8 requested_si
return (Slice_Mem){0}; return (Slice_Mem){0};
} }
arena->used += aligned_grow; arena->used += aligned_grow;
Slice_Mem result = (Slice_Mem){ old_allocation.ptr, aligned_grow + requested_size };
mem_zero(old_allocation.ptr + old_allocation.len, grow_amount * cast(U8, should_zero)); mem_zero(old_allocation.ptr + old_allocation.len, grow_amount * cast(U8, should_zero));
return result; return (Slice_Mem){ old_allocation.ptr, aligned_grow + requested_size };
} }
inline internal inline
Slice_Mem farena__shrink(FArena_R arena, Slice_Mem old_allocation, U8 requested_size, U8 alignment) Slice_Mem farena__shrink(FArena_R arena, Slice_Mem old_allocation, U8 requested_size, U8 alignment)
{ {
// Check if the allocation is at the end of the arena // Check if the allocation is at the end of the arena
@@ -957,6 +951,7 @@ finline
AllocatorSP farena_save (FArena arena) { AllocatorSP farena_save (FArena arena) {
return (AllocatorSP){ .type_sig = & farena_allocator_proc, .slot = arena.used }; return (AllocatorSP){ .type_sig = & farena_allocator_proc, .slot = arena.used };
} }
internal
void farena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out*R_ out) void farena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out*R_ out)
{ {
assert(out != nullptr); assert(out != nullptr);
@@ -964,38 +959,38 @@ void farena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out*R_ out)
FArena_R arena = cast(FArena_R, in.data); FArena_R arena = cast(FArena_R, in.data);
switch (in.op) switch (in.op)
{ {
case AllocatorOp_Alloc: case AllocatorOp_Alloc:
case AllocatorOp_Alloc_NoZero: case AllocatorOp_Alloc_NoZero:
out->allocation = farena_push_mem(arena, in.requested_size, .alignment = in.alignment); out->allocation = farena_push_mem(arena, in.requested_size, .alignment = in.alignment);
mem_zero(out->allocation.ptr, out->allocation.len * in.op); mem_zero(out->allocation.ptr, out->allocation.len * in.op);
break; break;
case AllocatorOp_Free: break; case AllocatorOp_Free: break;
case AllocatorOp_Reset: farena_reset(arena); break; case AllocatorOp_Reset: farena_reset(arena); break;
case AllocatorOp_Grow: case AllocatorOp_Grow:
case AllocatorOp_Grow_NoZero: case AllocatorOp_Grow_NoZero:
out->allocation = farena__grow(arena, in.old_allocation, in.requested_size, in.alignment, in.op - AllocatorOp_Grow_NoZero); out->allocation = farena__grow(arena, in.old_allocation, in.requested_size, in.alignment, in.op - AllocatorOp_Grow_NoZero);
break; break;
case AllocatorOp_Shrink: case AllocatorOp_Shrink:
out->allocation = farena__shrink(arena, in.old_allocation, in.requested_size, in.alignment); out->allocation = farena__shrink(arena, in.old_allocation, in.requested_size, in.alignment);
break; break;
case AllocatorOp_Rewind: farena_rewind(arena, in.save_point); break; case AllocatorOp_Rewind: farena_rewind(arena, in.save_point); break;
case AllocatorOp_SavePoint: out->save_point = farena_save(arena[0]); break; case AllocatorOp_SavePoint: out->save_point = farena_save(arena[0]); break;
case AllocatorOp_Query: case AllocatorOp_Query:
out->features = out->features =
AllocatorQuery_Alloc AllocatorQuery_Alloc
| AllocatorQuery_Reset | AllocatorQuery_Reset
| AllocatorQuery_Resize | AllocatorQuery_Resize
| AllocatorQuery_Rewind | AllocatorQuery_Rewind
; ;
out->max_alloc = arena->capacity - arena->used; out->max_alloc = arena->capacity - arena->used;
out->min_alloc = 0; out->min_alloc = 0;
out->left = out->max_alloc; out->left = out->max_alloc;
out->save_point = farena_save(arena[0]); out->save_point = farena_save(arena[0]);
break; break;
} }
return; return;
} }
@@ -1057,7 +1052,7 @@ typedef def_struct(OS_Windows_State) { OS_SystemInfo system_info; };
global OS_Windows_State os__windows_info; global OS_Windows_State os__windows_info;
finline OS_SystemInfo* os_system_info(void) { return & os__windows_info.system_info; } finline OS_SystemInfo* os_system_info(void) { return & os__windows_info.system_info; }
inline internal inline
void os__enable_large_pages(void) { void os__enable_large_pages(void) {
MS_HANDLE token; MS_HANDLE token;
if (OpenProcessToken(GetCurrentProcess(), MS_TOKEN_ADJUST_PRIVILEGES | MS_TOKEN_QUERY, &token)) if (OpenProcessToken(GetCurrentProcess(), MS_TOKEN_ADJUST_PRIVILEGES | MS_TOKEN_QUERY, &token))
@@ -1074,7 +1069,7 @@ void os__enable_large_pages(void) {
CloseHandle(token); CloseHandle(token);
} }
} }
inline internal inline
void os_init(void) { void os_init(void) {
os__enable_large_pages(); os__enable_large_pages();
OS_SystemInfo*R_ info = & os__windows_info.system_info; OS_SystemInfo*R_ info = & os__windows_info.system_info;
@@ -1096,12 +1091,12 @@ finline B4 os__vmem_commit(U8 vm, U8 size, Opts_vmem*R_ opts) {
B4 result = (VirtualAlloc(cast(MS_LPVOID, vm), size, MS_MEM_COMMIT, MS_PAGE_READWRITE) != 0); B4 result = (VirtualAlloc(cast(MS_LPVOID, vm), size, MS_MEM_COMMIT, MS_PAGE_READWRITE) != 0);
return result; return result;
} }
inline void os_vmem_release(U8 vm, U8 size) { VirtualFree(cast(MS_LPVOID, vm), 0, MS_MEM_RESERVE); } internal inline void os_vmem_release(U8 vm, U8 size) { VirtualFree(cast(MS_LPVOID, vm), 0, MS_MEM_RESERVE); }
#pragma endregion OS #pragma endregion OS
#pragma region VArena (Virutal Address Space Arena) #pragma region VArena (Virutal Address Space Arena)
finline U8 varena_header_size(void) { return align_pow2(size_of(VArena), MEMORY_ALIGNMENT_DEFAULT); } finline U8 varena_header_size(void) { return align_pow2(size_of(VArena), MEMORY_ALIGNMENT_DEFAULT); }
inline internal inline
VArena* varena__make(Opts_varena_make*R_ opts) { VArena* varena__make(Opts_varena_make*R_ opts) {
assert(opts != nullptr); assert(opts != nullptr);
if (opts->reserve_size == 0) { opts->reserve_size = mega(64); } if (opts->reserve_size == 0) { opts->reserve_size = mega(64); }
@@ -1123,7 +1118,7 @@ VArena* varena__make(Opts_varena_make*R_ opts) {
}; };
return vm; return vm;
} }
inline internal inline
Slice_Mem varena__push(VArena_R vm, U8 amount, U8 type_width, Opts_varena*R_ opts) { Slice_Mem varena__push(VArena_R vm, U8 amount, U8 type_width, Opts_varena*R_ opts) {
assert(vm != nullptr); assert(vm != nullptr);
assert(amount != 0); assert(amount != 0);
@@ -1146,11 +1141,11 @@ Slice_Mem varena__push(VArena_R vm, U8 amount, U8 type_width, Opts_varena*R_ opt
vm->committed += next_commit_size; vm->committed += next_commit_size;
} }
} }
vm->commit_used = to_be_used;
U8 current_offset = vm->reserve_start + vm->commit_used; U8 current_offset = vm->reserve_start + vm->commit_used;
vm->commit_used = to_be_used;
return (Slice_Mem){.ptr = current_offset, .len = requested_size}; return (Slice_Mem){.ptr = current_offset, .len = requested_size};
} }
inline internal inline
Slice_Mem varena__grow(VArena_R vm, Slice_Mem old_allocation, U8 requested_size, U8 alignment, B4 should_zero) { Slice_Mem varena__grow(VArena_R vm, Slice_Mem old_allocation, U8 requested_size, U8 alignment, B4 should_zero) {
U8 grow_amount = requested_size - old_allocation.len; U8 grow_amount = requested_size - old_allocation.len;
if (grow_amount == 0) { return old_allocation; } // Growing when not the last allocation not allowed if (grow_amount == 0) { return old_allocation; } // Growing when not the last allocation not allowed
@@ -1160,7 +1155,7 @@ Slice_Mem varena__grow(VArena_R vm, Slice_Mem old_allocation, U8 requested_size,
return (Slice_Mem){ old_allocation.ptr, old_allocation.len + allocation.len }; return (Slice_Mem){ old_allocation.ptr, old_allocation.len + allocation.len };
} }
finline void varena_release(VArena_R arena) { os_vmem_release(u8_(arena), arena->reserve); } finline void varena_release(VArena_R arena) { os_vmem_release(u8_(arena), arena->reserve); }
inline internal inline
Slice_Mem varena__shrink(VArena_R vm, Slice_Mem old_allocation, U8 requested_size) { Slice_Mem varena__shrink(VArena_R vm, Slice_Mem old_allocation, U8 requested_size) {
U8 shrink_amount = old_allocation.len - requested_size; U8 shrink_amount = old_allocation.len - requested_size;
if (lt_s(shrink_amount, 0)) { return old_allocation; } if (lt_s(shrink_amount, 0)) { return old_allocation; }
@@ -1175,6 +1170,7 @@ void varena_rewind(VArena_R vm, AllocatorSP sp) {
vm->commit_used = max(sp.slot, sizeof(VArena)); vm->commit_used = max(sp.slot, sizeof(VArena));
} }
finline AllocatorSP varena_save(VArena_R vm) { return (AllocatorSP){varena_allocator_proc, vm->commit_used}; } finline AllocatorSP varena_save(VArena_R vm) { return (AllocatorSP){varena_allocator_proc, vm->commit_used}; }
internal
void varena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out) void varena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out)
{ {
VArena_R vm = cast(VArena_R, in.data); VArena_R vm = cast(VArena_R, in.data);
@@ -1218,7 +1214,7 @@ void varena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out)
#pragma region Arena (Chained Arena) #pragma region Arena (Chained Arena)
finline U8 arena_header_size(void) { return align_pow2(size_of(Arena), MEMORY_ALIGNMENT_DEFAULT); } finline U8 arena_header_size(void) { return align_pow2(size_of(Arena), MEMORY_ALIGNMENT_DEFAULT); }
inline internal inline
Arena* arena__make(Opts_arena_make*R_ opts) { Arena* arena__make(Opts_arena_make*R_ opts) {
assert(opts != nullptr); assert(opts != nullptr);
U8 header_size = arena_header_size(); U8 header_size = arena_header_size();
@@ -1233,6 +1229,7 @@ Arena* arena__make(Opts_arena_make*R_ opts) {
}; };
return arena; return arena;
} }
internal inline
Slice_Mem arena__push(Arena_R arena, U8 amount, U8 type_width, Opts_arena* opts) { Slice_Mem arena__push(Arena_R arena, U8 amount, U8 type_width, Opts_arena* opts) {
assert(arena != nullptr); assert(arena != nullptr);
assert(opts != nullptr); assert(opts != nullptr);
@@ -1264,6 +1261,45 @@ Slice_Mem arena__push(Arena_R arena, U8 amount, U8 type_width, Opts_arena* opts)
active->pos = pos_pst; active->pos = pos_pst;
return vresult; return vresult;
} }
internal inline
Slice_Mem arena__grow(Arena_R arena, Slice_Mem old_allocation, U8 requested_size, U8 alignment, B4 should_zero) {
Arena_R active = arena->current;
U8 alloc_end = old_allocation.ptr + old_allocation.len + requested_size;
U8 arena_end = u8_(active) + active->pos;
if (alloc_end == arena_end)
{
U8 grow_amount = requested_size - old_allocation.len;
U8 aligned_grow = align_pow2(grow_amount, alignment ? alignment : MEMORY_ALIGNMENT_DEFAULT);
if (active->pos + aligned_grow <= active->backing->reserve) {
Slice_Mem vresult = varena_push_mem(active->backing, aligned_grow, .alignment = alignment);
if (vresult.ptr != null) {
active->pos += aligned_grow;
mem_zero(old_allocation.ptr + old_allocation.len, aligned_grow * (U8)should_zero);
return (Slice_Mem){old_allocation.ptr, aligned_grow + old_allocation.len};
}
}
}
#pragma diagnostic push
#pragma clang diagnostic ignored "-Wnrvo"
Slice_Mem new_alloc = arena__push(arena, requested_size, 1, &(Opts_arena){.alignment = alignment});
if (new_alloc.ptr == null) { return (Slice_Mem){0}; }
mem_copy(new_alloc.ptr, old_allocation.ptr, old_allocation.len);
mem_zero(new_alloc.ptr + old_allocation.len, (new_alloc.len - old_allocation.len) * (U8)should_zero);
return new_alloc;
#pragma diagnostic pop
}
internal inline
Slice_Mem arena__shrink(Arena_R arena, Slice_Mem old_allocation, U8 requested_size, U8 alignment) {
Arena_R active = arena->current;
U8 alloc_end = old_allocation.ptr + old_allocation.len;
U8 arena_end = u8_(active) + active->pos;
if (alloc_end != arena_end) { return (Slice_Mem){old_allocation.ptr, requested_size}; }
U8 aligned_original = align_pow2(old_allocation.len, MEMORY_ALIGNMENT_DEFAULT);
U8 aligned_new = align_pow2(requested_size, alignment ? alignment : MEMORY_ALIGNMENT_DEFAULT);
U8 pos_reduction = aligned_original - aligned_new;
active->pos -= pos_reduction;
return varena__shrink(active->backing, old_allocation, requested_size);
}
finline finline
void arena_release(Arena_R arena) { void arena_release(Arena_R arena) {
assert(arena != nullptr); assert(arena != nullptr);
@@ -1275,6 +1311,7 @@ void arena_release(Arena_R arena) {
} }
} }
finline void arena_reset(Arena_R arena) { arena_rewind(arena, (AllocatorSP){.type_sig = arena_allocator_proc, .slot = 0}); } finline void arena_reset(Arena_R arena) { arena_rewind(arena, (AllocatorSP){.type_sig = arena_allocator_proc, .slot = 0}); }
internal inline
void arena_rewind(Arena_R arena, AllocatorSP save_point) { void arena_rewind(Arena_R arena, AllocatorSP save_point) {
assert(arena != nullptr); assert(arena != nullptr);
assert(save_point.type_sig == arena_allocator_proc); assert(save_point.type_sig == arena_allocator_proc);
@@ -1291,6 +1328,7 @@ void arena_rewind(Arena_R arena, AllocatorSP save_point) {
varena_rewind(curr->backing, (AllocatorSP){varena_allocator_proc, curr->pos + size_of(VArena)}); varena_rewind(curr->backing, (AllocatorSP){varena_allocator_proc, curr->pos + size_of(VArena)});
} }
finline AllocatorSP arena_save(Arena_R arena) { return (AllocatorSP){arena_allocator_proc, arena->base_pos + arena->current->pos}; } finline AllocatorSP arena_save(Arena_R arena) { return (AllocatorSP){arena_allocator_proc, arena->base_pos + arena->current->pos}; }
internal
void arena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out*R_ out) void arena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out*R_ out)
{ {
assert(out != nullptr); assert(out != nullptr);
@@ -1308,53 +1346,11 @@ void arena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out*R_ out)
case AllocatorOp_Reset: arena_reset(arena); break; case AllocatorOp_Reset: arena_reset(arena); break;
case AllocatorOp_Grow: case AllocatorOp_Grow:
case AllocatorOp_Grow_NoZero: { case AllocatorOp_Grow_NoZero:
Arena_R active = arena->current; out->allocation = arena__grow(arena, in.old_allocation, in.requested_size, in.alignment, in.op - AllocatorOp_Grow_NoZero);
U8 alloc_end = in.old_allocation.ptr + in.old_allocation.len;
U8 arena_end = u8_(active) + active->pos;
if (alloc_end == arena_end)
{
U8 grow_amount = in.requested_size - in.old_allocation.len;
U8 aligned_grow = align_pow2(grow_amount, in.alignment ? in.alignment : MEMORY_ALIGNMENT_DEFAULT);
if (active->pos + aligned_grow <= active->backing->reserve)
{
Slice_Mem vresult = varena_push_mem(active->backing, aligned_grow, .alignment = in.alignment);
if (vresult.ptr != null)
{
active->pos += aligned_grow;
out->allocation = (Slice_Mem){in.old_allocation.ptr, in.requested_size};
mem_zero(in.old_allocation.ptr + in.old_allocation.len, grow_amount * in.op - AllocatorOp_Grow_NoZero);
break;
}
}
}
Slice_Mem new_alloc = arena__push(arena, in.requested_size, 1, &(Opts_arena){.alignment = in.alignment});
if (new_alloc.ptr == null) {
out->allocation = (Slice_Mem){0};
break;
}
mem_copy(new_alloc.ptr, in.old_allocation.ptr, in.old_allocation.len);
mem_zero(new_alloc.ptr + in.old_allocation.len, (in.requested_size - in.old_allocation.len) * in.op - AllocatorOp_Grow_NoZero);
out->allocation = new_alloc;
}
break; break;
case AllocatorOp_Shrink:
case AllocatorOp_Shrink: { out->allocation = arena__shrink(arena, in.old_allocation, in.requested_size, in.alignment);
Arena_R active = arena->current;
U8 alloc_end = in.old_allocation.ptr + in.old_allocation.len;
U8 arena_end = u8_(active) + active->pos;
if (alloc_end != arena_end) {
out->allocation = (Slice_Mem){in.old_allocation.ptr, in.requested_size};
break;
}
//SSIZE shrink_amount = in.old_allocation.len - in.requested_size;
U8 aligned_original = align_pow2(in.old_allocation.len, MEMORY_ALIGNMENT_DEFAULT);
U8 aligned_new = align_pow2(in.requested_size, in.alignment ? in.alignment : MEMORY_ALIGNMENT_DEFAULT);
U8 pos_reduction = aligned_original - aligned_new;
active->pos -= pos_reduction;
varena__shrink(active->backing, in.old_allocation, in.requested_size);
out->allocation = (Slice_Mem){in.old_allocation.ptr, in.requested_size};
}
break; break;
case AllocatorOp_Rewind: arena_rewind(arena, in.save_point); break; case AllocatorOp_Rewind: arena_rewind(arena, in.save_point); break;
@@ -1377,7 +1373,7 @@ void arena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out*R_ out)
#pragma endregion Arena #pragma endregion Arena
#pragma region Key Table Linear (KTL) #pragma region Key Table Linear (KTL)
inline finline
void ktl_populate_slice_a2_str8(KTL_Str8*R_ kt, AllocatorInfo backing, Slice_A2_Str8 values) { void ktl_populate_slice_a2_str8(KTL_Str8*R_ kt, AllocatorInfo backing, Slice_A2_Str8 values) {
assert(kt != nullptr); assert(kt != nullptr);
if (values.len == 0) return; if (values.len == 0) return;
@@ -1390,7 +1386,7 @@ void ktl_populate_slice_a2_str8(KTL_Str8*R_ kt, AllocatorInfo backing, Slice_A2_
#pragma endregion KTL #pragma endregion KTL
#pragma region Key Table 1-Layer Chained-Chunked_Cells (KT1CX) #pragma region Key Table 1-Layer Chained-Chunked_Cells (KT1CX)
inline internal inline
void kt1cx_init(KT1CX_Info info, KT1CX_InfoMeta m, KT1CX_Byte*R_ result) { void kt1cx_init(KT1CX_Info info, KT1CX_InfoMeta m, KT1CX_Byte*R_ result) {
assert(result != nullptr); assert(result != nullptr);
assert(info.backing_cells.proc != nullptr); assert(info.backing_cells.proc != nullptr);
@@ -1402,7 +1398,7 @@ void kt1cx_init(KT1CX_Info info, KT1CX_InfoMeta m, KT1CX_Byte*R_ result) {
result->table = mem_alloc(info.backing_table, m.table_size * m.cell_size); slice_assert(result->table); result->table = mem_alloc(info.backing_table, m.table_size * m.cell_size); slice_assert(result->table);
result->table.len = m.table_size; // Setting to the table number of elements instead of byte length. result->table.len = m.table_size; // Setting to the table number of elements instead of byte length.
} }
inline internal inline
void kt1cx_clear(KT1CX_Byte kt, KT1CX_ByteMeta m) { void kt1cx_clear(KT1CX_Byte kt, KT1CX_ByteMeta m) {
U8 cell_cursor = kt.table.ptr; U8 cell_cursor = kt.table.ptr;
U8 table_len = kt.table.len * m.cell_size; U8 table_len = kt.table.len * m.cell_size;
@@ -1425,9 +1421,9 @@ void kt1cx_clear(KT1CX_Byte kt, KT1CX_ByteMeta m) {
} }
finline finline
U8 kt1cx_slot_id(KT1CX_Byte kt, U8 key, KT1CX_ByteMeta m) { U8 kt1cx_slot_id(KT1CX_Byte kt, U8 key, KT1CX_ByteMeta m) {
U8 hash_index = key % kt.table.len; return key % kt.table.len;
return hash_index;
} }
inline
U8 kt1cx_get(KT1CX_Byte kt, U8 key, KT1CX_ByteMeta m) { U8 kt1cx_get(KT1CX_Byte kt, U8 key, KT1CX_ByteMeta m) {
U8 hash_index = kt1cx_slot_id(kt, key, m); U8 hash_index = kt1cx_slot_id(kt, key, m);
U8 cell_offset = hash_index * m.cell_size; U8 cell_offset = hash_index * m.cell_size;
@@ -1454,7 +1450,7 @@ U8 kt1cx_get(KT1CX_Byte kt, U8 key, KT1CX_ByteMeta m) {
} }
} }
} }
inline internal
U8 kt1cx_set(KT1CX_Byte kt, U8 key, Slice_Mem value, AllocatorInfo backing_cells, KT1CX_ByteMeta m) { U8 kt1cx_set(KT1CX_Byte kt, U8 key, Slice_Mem value, AllocatorInfo backing_cells, KT1CX_ByteMeta m) {
U8 hash_index = kt1cx_slot_id(kt, key, m); U8 hash_index = kt1cx_slot_id(kt, key, m);
U8 cell_offset = hash_index * m.cell_size; U8 cell_offset = hash_index * m.cell_size;
@@ -1504,24 +1500,25 @@ char* str8_to_cstr_capped(Str8 content, Slice_Mem mem) {
u1_r(mem.ptr)[copy_len] = '\0'; u1_r(mem.ptr)[copy_len] = '\0';
return cast(char*, mem.ptr); return cast(char*, mem.ptr);
} }
internal
Str8 str8_from_u32(AllocatorInfo ainfo, U4 num, U4 radix, U4 min_digits, U4 digit_group_separator) Str8 str8_from_u32(AllocatorInfo ainfo, U4 num, U4 radix, U4 min_digits, U4 digit_group_separator)
{ {
Str8 result = {0}; Str8 result = {0};
Str8 prefix = {0}; Str8 prefix = {0};
switch (radix) { switch (radix) {
case 16: { prefix = lit("0x"); } break; case 16: { prefix = lit("0x"); } break;
case 8: { prefix = lit("0o"); } break; case 8: { prefix = lit("0o"); } break;
case 2: { prefix = lit("0b"); } break; case 2: { prefix = lit("0b"); } break;
} }
U4 digit_group_size = 3; U4 digit_group_size = 3;
switch (radix) { switch (radix) {
default: break; default: break;
case 2: case 2:
case 8: case 8:
case 16: { case 16: {
digit_group_size = 4; digit_group_size = 4;
} }
break; break;
} }
U4 needed_leading_zeros = 0; U4 needed_leading_zeros = 0;
{ {
@@ -1663,17 +1660,16 @@ finline
Str8 str8__fmt_backed(AllocatorInfo tbl_backing, AllocatorInfo buf_backing, Str8 fmt_template, Slice_A2_Str8*R_ entries) { Str8 str8__fmt_backed(AllocatorInfo tbl_backing, AllocatorInfo buf_backing, Str8 fmt_template, Slice_A2_Str8*R_ entries) {
KTL_Str8 kt; kt1l_populate_slice_a2_str8(& kt, tbl_backing, entries[0] ); KTL_Str8 kt; kt1l_populate_slice_a2_str8(& kt, tbl_backing, entries[0] );
U8 buf_size = kilo(64); Slice_Mem buffer = mem_alloc(buf_backing, buf_size); U8 buf_size = kilo(64); Slice_Mem buffer = mem_alloc(buf_backing, buf_size);
Str8 result = str8__fmt_ktl(buf_backing, & buffer, kt, fmt_template); return str8__fmt_ktl(buf_backing, & buffer, kt, fmt_template);
return result;
} }
finline
Str8 str8__fmt(Str8 fmt_template, Slice_A2_Str8*R_ entries) { Str8 str8__fmt(Str8 fmt_template, Slice_A2_Str8*R_ entries) {
local_persist B1 tbl_mem[kilo(32)]; FArena tbl_arena = farena_make(slice_fmem(tbl_mem)); local_persist B1 tbl_mem[kilo(32)]; FArena tbl_arena = farena_make(slice_fmem(tbl_mem));
local_persist B1 buf_mem[kilo(64)]; local_persist B1 buf_mem[kilo(64)];
KTL_Str8 kt = {0}; ktl_populate_slice_a2_str8(& kt, ainfo_farena(tbl_arena), entries[0] ); KTL_Str8 kt = {0}; ktl_populate_slice_a2_str8(& kt, ainfo_farena(tbl_arena), entries[0] );
Str8 result = str8__fmt_ktl((AllocatorInfo){0}, & slice_fmem(buf_mem), kt, fmt_template); return str8__fmt_ktl((AllocatorInfo){0}, & slice_fmem(buf_mem), kt, fmt_template);
return result;
} }
inline internal inline
void str8cache__init(Str8Cache_R cache, Opts_str8cache_init*R_ opts) { void str8cache__init(Str8Cache_R cache, Opts_str8cache_init*R_ opts) {
assert(cache != nullptr); assert(cache != nullptr);
assert(opts != nullptr); assert(opts != nullptr);
@@ -1761,8 +1757,7 @@ finline
Str8 cache_str8(Str8Cache_R cache, Str8 str) { Str8 cache_str8(Str8Cache_R cache, Str8 str) {
assert(cache != nullptr); assert(cache != nullptr);
U8 key = 0; hash64_fnv1a(& key, slice_mem_s(str)); U8 key = 0; hash64_fnv1a(& key, slice_mem_s(str));
Str8_R result = str8cache_set(cache->kt, key, str, cache->str_reserve, cache->cell_reserve); return str8cache_set(cache->kt, key, str, cache->str_reserve, cache->cell_reserve)[0];
return result[0];
} }
finline finline
void str8gen_init(Str8Gen_R gen, AllocatorInfo backing) { void str8gen_init(Str8Gen_R gen, AllocatorInfo backing) {
@@ -1784,6 +1779,7 @@ void str8gen_append_str8(Str8Gen_R gen, Str8 str){
gen->len += str.len; gen->len += str.len;
gen->cap = result.len; gen->cap = result.len;
} }
internal inline
void str8gen__append_fmt(Str8Gen_R gen, Str8 fmt_template, Slice_A2_Str8*R_ entries){ void str8gen__append_fmt(Str8Gen_R gen, Str8 fmt_template, Slice_A2_Str8*R_ entries){
local_persist B1 tbl_mem[kilo(32)]; FArena tbl_arena = farena_make(slice_fmem(tbl_mem)); local_persist B1 tbl_mem[kilo(32)]; FArena tbl_arena = farena_make(slice_fmem(tbl_mem));
KTL_Str8 kt = {0}; ktl_populate_slice_a2_str8(& kt, ainfo_farena(tbl_arena), entries[0] ); KTL_Str8 kt = {0}; ktl_populate_slice_a2_str8(& kt, ainfo_farena(tbl_arena), entries[0] );
@@ -1839,6 +1835,7 @@ FileOpInfo file__read_contents(Str8 path, Opts_read_file_contents*R_ opts) {
FileOpInfo result = {0}; api_file_read_contents(& result, path, opts[0]); FileOpInfo result = {0}; api_file_read_contents(& result, path, opts[0]);
return result; return result;
} }
internal
void api_file_read_contents(FileOpInfo_R result, Str8 path, Opts_read_file_contents opts) void api_file_read_contents(FileOpInfo_R result, Str8 path, Opts_read_file_contents opts)
{ {
assert(result != nullptr); assert(result != nullptr);
@@ -1898,6 +1895,7 @@ void api_file_read_contents(FileOpInfo_R result, Str8 path, Opts_read_file_conte
result->content.len = u8_(file_size.QuadPart); result->content.len = u8_(file_size.QuadPart);
return; return;
} }
internal
void file_write_str8(Str8 path, Str8 content) void file_write_str8(Str8 path, Str8 content)
{ {
slice_assert(path); slice_assert(path);
@@ -1972,6 +1970,7 @@ int printf_err(char const* fmt, ...) {
va_end(args); va_end(args);
return result; return result;
} }
internal inline
void assert_handler( UTF8*R_ condition, UTF8*R_ file, UTF8*R_ function, S4 line, UTF8*R_ msg, ... ) { void assert_handler( UTF8*R_ condition, UTF8*R_ file, UTF8*R_ function, S4 line, UTF8*R_ msg, ... ) {
printf_err( "%s - %s:(%d): Assert Failure: ", file, function, line ); printf_err( "%s - %s:(%d): Assert Failure: ", file, function, line );
if ( condition ) if ( condition )
@@ -1988,6 +1987,7 @@ void assert_handler( UTF8*R_ condition, UTF8*R_ file, UTF8*R_ function, S4 line,
#pragma endregion Debug #pragma endregion Debug
#pragma region WATL #pragma region WATL
internal
void api_watl_lex(WATL_LexInfo_R info, Str8 source, Opts_watl_lex*R_ opts) void api_watl_lex(WATL_LexInfo_R info, Str8 source, Opts_watl_lex*R_ opts)
{ {
if (source.len == 0) { return; } if (source.len == 0) { return; }
@@ -2009,52 +2009,52 @@ void api_watl_lex(WATL_LexInfo_R info, Str8 source, Opts_watl_lex*R_ opts)
#define alloc_tok() alloc_type(opts->ainfo_toks, WATL_Tok, .alignment = alignof(WATL_Tok), .no_zero = true) #define alloc_tok() alloc_type(opts->ainfo_toks, WATL_Tok, .alignment = alignof(WATL_Tok), .no_zero = true)
switch (code) switch (code)
{ {
case WATL_Tok_Space: case WATL_Tok_Space:
case WATL_Tok_Tab: case WATL_Tok_Tab:
{ {
if (prev[0] != cursor[0]) { if (prev[0] != cursor[0]) {
WATL_Tok_R new_tok = alloc_tok(); if (new_tok - 1 != tok && tok != nullptr) { goto slice_constraint_fail; }
tok = new_tok;
tok[0] = (WATL_Tok){ cursor, 0 };
was_formatting = true;
++ num;
}
cursor += 1;
tok->len += 1;
}
break;
case WATL_Tok_LineFeed: {
WATL_Tok_R new_tok = alloc_tok(); if (new_tok - 1 != tok && tok != nullptr) { goto slice_constraint_fail; } WATL_Tok_R new_tok = alloc_tok(); if (new_tok - 1 != tok && tok != nullptr) { goto slice_constraint_fail; }
tok = new_tok; tok = new_tok;
tok[0] = (WATL_Tok){ cursor, 1 }; tok[0] = (WATL_Tok){ cursor, 0 };
cursor += 1;
was_formatting = true; was_formatting = true;
++ num; ++ num;
} }
break; cursor += 1;
// Assuming what comes after is line feed. tok->len += 1;
case WATL_Tok_CarriageReturn: { }
break;
case WATL_Tok_LineFeed: {
WATL_Tok_R new_tok = alloc_tok(); if (new_tok - 1 != tok && tok != nullptr) { goto slice_constraint_fail; }
tok = new_tok;
tok[0] = (WATL_Tok){ cursor, 1 };
cursor += 1;
was_formatting = true;
++ num;
}
break;
// Assuming what comes after is line feed.
case WATL_Tok_CarriageReturn: {
WATL_Tok_R new_tok = alloc_tok(); if (new_tok - 1 != tok && tok != nullptr) { goto slice_constraint_fail; }
tok = new_tok;
tok[0] = (WATL_Tok){ cursor, 2 };
cursor += 2;
was_formatting = true;
++ num;
}
break;
default:
{
if (was_formatting) {
WATL_Tok_R new_tok = alloc_tok(); if (new_tok - 1 != tok && tok != nullptr) { goto slice_constraint_fail; } WATL_Tok_R new_tok = alloc_tok(); if (new_tok - 1 != tok && tok != nullptr) { goto slice_constraint_fail; }
tok = new_tok; tok = new_tok;
tok[0] = (WATL_Tok){ cursor, 2 }; tok[0] = (WATL_Tok){ cursor, 0 };
cursor += 2; was_formatting = false;
was_formatting = true;
++ num; ++ num;
} }
break; cursor += 1;
default: tok->len += 1;
{ }
if (was_formatting) { break;
WATL_Tok_R new_tok = alloc_tok(); if (new_tok - 1 != tok && tok != nullptr) { goto slice_constraint_fail; }
tok = new_tok;
tok[0] = (WATL_Tok){ cursor, 0 };
was_formatting = false;
++ num;
}
cursor += 1;
tok->len += 1;
}
break;
} }
prev = cursor - 1; prev = cursor - 1;
code = cursor[0]; code = cursor[0];
@@ -2077,7 +2077,7 @@ slice_constraint_fail:
return; return;
} }
inline WATL_LexInfo watl__lex(Str8 source, Opts_watl_lex*R_ opts) { WATL_LexInfo info = {0}; api_watl_lex(& info, source, opts); return info; } inline WATL_LexInfo watl__lex(Str8 source, Opts_watl_lex*R_ opts) { WATL_LexInfo info = {0}; api_watl_lex(& info, source, opts); return info; }
internal
void api_watl_parse(WATL_ParseInfo_R info, Slice_WATL_Tok tokens, Opts_watl_parse*R_ opts) void api_watl_parse(WATL_ParseInfo_R info, Slice_WATL_Tok tokens, Opts_watl_parse*R_ opts)
{ {
if (tokens.len == 0) { return; } if (tokens.len == 0) { return; }
@@ -2097,49 +2097,49 @@ void api_watl_parse(WATL_ParseInfo_R info, Slice_WATL_Tok tokens, Opts_watl_pars
{ {
switch(token->ptr[0]) switch(token->ptr[0])
{ {
case WATL_Tok_CarriageReturn: case WATL_Tok_CarriageReturn:
case WATL_Tok_LineFeed: case WATL_Tok_LineFeed:
{ {
WATL_Line_R new_line = alloc_type(opts->ainfo_lines, WATL_Line); if (new_line - 1 != line) { WATL_Line_R new_line = alloc_type(opts->ainfo_lines, WATL_Line); if (new_line - 1 != line) {
info->signal |= WATL_ParseStatus_MemFail_SliceConstraintFail; info->signal |= WATL_ParseStatus_MemFail_SliceConstraintFail;
WATL_ParseMsg_R msg = alloc_type(opts->ainfo_msgs, WATL_ParseMsg); WATL_ParseMsg_R msg = alloc_type(opts->ainfo_msgs, WATL_ParseMsg);
msg->content = lit("Line slice allocation was not contiguous"); msg->content = lit("Line slice allocation was not contiguous");
msg->pos = (WATL_Pos){cast(S4, info->lines.len), cast(S4, line->len)}; msg->pos = (WATL_Pos){cast(S4, info->lines.len), cast(S4, line->len)};
msg->line = line; msg->line = line;
msg->tok = token; msg->tok = token;
sll_queue_push_n(info->msgs, msg_last, msg, next); sll_queue_push_n(info->msgs, msg_last, msg, next);
assert(opts->failon_slice_constraint_fail == false); assert(opts->failon_slice_constraint_fail == false);
return; return;
}
line = new_line;
line->ptr = curr;
info->lines.len += 1;
} }
continue; line = new_line;
line->ptr = curr;
default: info->lines.len += 1;
break;
} }
curr[0] = cache_str8(opts->str_cache, token[0]);
WATL_Node_R new_node = alloc_type(opts->ainfo_nodes, WATL_Node); if (new_node - 1 != curr) {
info->signal |= WATL_ParseStatus_MemFail_SliceConstraintFail;
WATL_ParseMsg_R msg = alloc_type(opts->ainfo_msgs, WATL_ParseMsg);
msg->content = lit("Nodes slice allocation was not contiguous");
msg->pos = (WATL_Pos){cast(S4, info->lines.len), cast(S4, line->len)};
msg->line = line;
msg->tok = token;
sll_queue_push_n(info->msgs, msg_last, msg, next);
assert(opts->failon_slice_constraint_fail == false);
return;
}
curr = new_node;
line->len += 1;
continue; continue;
default:
break;
}
curr[0] = cache_str8(opts->str_cache, token[0]);
WATL_Node_R new_node = alloc_type(opts->ainfo_nodes, WATL_Node); if (new_node - 1 != curr) {
info->signal |= WATL_ParseStatus_MemFail_SliceConstraintFail;
WATL_ParseMsg_R msg = alloc_type(opts->ainfo_msgs, WATL_ParseMsg);
msg->content = lit("Nodes slice allocation was not contiguous");
msg->pos = (WATL_Pos){cast(S4, info->lines.len), cast(S4, line->len)};
msg->line = line;
msg->tok = token;
sll_queue_push_n(info->msgs, msg_last, msg, next);
assert(opts->failon_slice_constraint_fail == false);
return;
}
curr = new_node;
line->len += 1;
continue;
} }
return; return;
} }
inline WATL_ParseInfo watl__parse(Slice_WATL_Tok tokens, Opts_watl_parse*R_ opts) { WATL_ParseInfo info = {0}; api_watl_parse(& info, tokens, opts); return info; } finline WATL_ParseInfo watl__parse(Slice_WATL_Tok tokens, Opts_watl_parse*R_ opts) { WATL_ParseInfo info = {0}; api_watl_parse(& info, tokens, opts); return info; }
internal
Str8 watl_dump_listing(AllocatorInfo buffer, Slice_WATL_Line lines) Str8 watl_dump_listing(AllocatorInfo buffer, Slice_WATL_Line lines)
{ {
local_persist B1 scratch[kilo(64)] = {0}; FArena sarena = farena_make(slice_fmem(scratch)); AllocatorInfo sinfo = ainfo_farena(sarena); local_persist B1 scratch[kilo(64)] = {0}; FArena sarena = farena_make(slice_fmem(scratch)); AllocatorInfo sinfo = ainfo_farena(sarena);
@@ -2159,11 +2159,10 @@ Str8 watl_dump_listing(AllocatorInfo buffer, Slice_WATL_Line lines)
for slice_iter(line[0], chunk) for slice_iter(line[0], chunk)
{ {
Str8 id; Str8 id;
switch (chunk->ptr[0]) switch (chunk->ptr[0]) {
{ case WATL_Tok_Space: id = lit("Space"); break;
case WATL_Tok_Space: id = lit("Space"); break; case WATL_Tok_Tab: id = lit("Tab"); break;
case WATL_Tok_Tab: id = lit("Tab"); break; default: id = lit("Visible"); break;
default: id = lit("Visible"); break;
} }
Str8 str_chunk_len = str8_from_u32(sinfo, cast(U4, chunk->len), 10, 0, 0); Str8 str_chunk_len = str8_from_u32(sinfo, cast(U4, chunk->len), 10, 0, 0);
str8gen_append_fmt(& result, "\t<id>(<size>): '<chunk>'\n" str8gen_append_fmt(& result, "\t<id>(<size>): '<chunk>'\n"
@@ -2180,7 +2179,6 @@ Str8 watl_dump_listing(AllocatorInfo buffer, Slice_WATL_Line lines)
#pragma endregion WATL #pragma endregion WATL
#pragma endregion Implementation #pragma endregion Implementation
int main(void) int main(void)
{ {
os_init(); os_init();

File diff suppressed because it is too large Load Diff

View File

@@ -118,8 +118,8 @@ $compiler_args += $flag_full_src_path
# $compiler_args += $flag_optimize_speed_max # $compiler_args += $flag_optimize_speed_max
# $compiler_args += $flag_optimize_fast # $compiler_args += $flag_optimize_fast
# $compiler_args += $flag_optimize_size # $compiler_args += $flag_optimize_size
# $compiler_args += $flag_optimize_intrinsics $compiler_args += $flag_optimize_intrinsics
$compiler_args += $flag_no_optimization # $compiler_args += $flag_no_optimization
# Debug setup # Debug setup
$compiler_args += ($flag_define + 'BUILD_DEBUG') $compiler_args += ($flag_define + 'BUILD_DEBUG')

View File

@@ -118,8 +118,8 @@ $compiler_args += $flag_full_src_path
# $compiler_args += $flag_optimize_speed_max # $compiler_args += $flag_optimize_speed_max
# $compiler_args += $flag_optimize_fast # $compiler_args += $flag_optimize_fast
# $compiler_args += $flag_optimize_size # $compiler_args += $flag_optimize_size
# $compiler_args += $flag_optimize_intrinsics $compiler_args += $flag_optimize_intrinsics
$compiler_args += $flag_no_optimization # $compiler_args += $flag_no_optimization
# Debug setup # Debug setup
$compiler_args += ($flag_define + 'BUILD_DEBUG') $compiler_args += ($flag_define + 'BUILD_DEBUG')

View File

@@ -117,8 +117,8 @@ $compiler_args += $flag_full_src_path
# $compiler_args += $flag_optimize_speed_max # $compiler_args += $flag_optimize_speed_max
# $compiler_args += $flag_optimize_fast # $compiler_args += $flag_optimize_fast
# $compiler_args += $flag_optimize_size # $compiler_args += $flag_optimize_size
# $compiler_args += $flag_optimize_intrinsics $compiler_args += $flag_optimize_intrinsics
$compiler_args += $flag_no_optimization # $compiler_args += $flag_no_optimization
# Debug setup # Debug setup
$compiler_args += ($flag_define + 'BUILD_DEBUG') $compiler_args += ($flag_define + 'BUILD_DEBUG')
@@ -139,7 +139,10 @@ $compiler_args += $flag_compile, $unit
$compiler_args | ForEach-Object { Write-Host $_ } $compiler_args | ForEach-Object { Write-Host $_ }
# Compile the unit # Compile the unit
& $compiler $compiler_args $compilation_time = Measure-Command {
& $compiler $compiler_args
}
write-host "Compilation took $($compilation_time.TotalMilliseconds)ms"
write-host write-host
$binary = join-path $path_build "$unit_name.exe" $binary = join-path $path_build "$unit_name.exe"
@@ -168,8 +171,9 @@ if ($true) {
# Diagnoistc print for the args # Diagnoistc print for the args
$linker_args | ForEach-Object { Write-Host $_ } $linker_args | ForEach-Object { Write-Host $_ }
& $linker $linker_args $linking_time = Measure-Command { & $linker $linker_args }
# & $radlink $linker_args # & $radlink $linker_args
write-host "Linking took $($linking_time.TotalMilliseconds)ms"
write-host write-host
} }