From 2bbe654047f2370c1a1ac442015174e1af59cb33 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Fri, 10 Oct 2025 23:11:46 -0400 Subject: [PATCH] updated odin's str8_fmt_kt1l --- C/watl.v0.llvm.lottes_hybrid.c | 4 +- Odin/watl.v0.win32.odin | 117 ++++++++++++++---------------- scripts/build.c_lottes_hybrid.ps1 | 2 +- scripts/build.odin.odin | 7 +- scripts/build.odin.ps1 | 2 +- 5 files changed, 62 insertions(+), 70 deletions(-) diff --git a/C/watl.v0.llvm.lottes_hybrid.c b/C/watl.v0.llvm.lottes_hybrid.c index 339fc36..561e666 100644 --- a/C/watl.v0.llvm.lottes_hybrid.c +++ b/C/watl.v0.llvm.lottes_hybrid.c @@ -401,7 +401,7 @@ void farena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out_R out); #define farena_push_mem(arena, amount, ...) farena__push(arena, amount, 1, opt_args(Opts_farena, lit(stringify(B1)), __VA_ARGS__)) #define farena_push(arena, type, ...) \ -cast(type*R_, farena__push(arena, size_of(type), 1, opt_args(Opts_farena, lit(stringify(type)), __VA_ARGS__))).ptr +cast(type*, farena__push(arena, size_of(type), 1, opt_args(Opts_farena, lit(stringify(type)), __VA_ARGS__))).ptr #define farena_push_array(arena, type, amount, ...) \ (Slice ## type){ farena__push(arena, size_of(type), amount, opt_args(Opts_farena, lit(stringify(type)), __VA_ARGS__)).ptr, amount } @@ -504,7 +504,7 @@ void arena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out_R out); #define arena_push_mem(arena, amount, ...) arena__push(arena, amount, 1, opt_args(Opts_arena, lit(stringify(B1)), __VA_ARGS__)) #define arena_push(arena, type, ...) \ -cast(type*R_, arena__push(arena, 1, size_of(type), opt_args(Opts_arena, lit(stringify(type)), __VA_ARGS__) ).ptr) +cast(type*, arena__push(arena, 1, size_of(type), opt_args(Opts_arena, lit(stringify(type)), __VA_ARGS__) ).ptr) #define arena_push_array(arena, type, amount, ...) \ (tmpl(Slice,type)){ arena__push(arena, size_of(type), amount, opt_args(Opts_arena, lit(stringify(type)), __VA_ARGS__)).ptr, amount } diff --git a/Odin/watl.v0.win32.odin b/Odin/watl.v0.win32.odin index 12f3ea5..06029e1 100644 --- a/Odin/watl.v0.win32.odin +++ b/Odin/watl.v0.win32.odin @@ -2,7 +2,7 @@ WATL Exercise Version: 0 (From Scratch, 1-Stage Compilation, WinAPI Only, Win CRT Multi-threaded Static Linkage) Host: Windows 11 (x86-64) -Toolchain: odin-lang/Odin dev-2025-07 +Toolchain: odin-lang/Odin dev-2025-09 */ package odin @@ -31,9 +31,9 @@ copy :: proc { slice_copy, string_copy, } -copy_non_overlapping :: proc { - memory_copy_non_overlapping, - slice_copy_non_overlapping, +copy_overlapping :: proc { + memory_copy_overlapping, + slice_copy_overlapping, } cursor :: proc { ptr_cursor, @@ -109,15 +109,33 @@ memory_zero_explicit :: proc "contextless" (data: rawptr, len: int) -> rawptr { intrinsics.atomic_thread_fence(.Seq_Cst) // Prevent reordering return data } -memory_copy :: proc "contextless" (dst, src: rawptr, len: int) -> rawptr { +memory_copy_overlapping :: proc "contextless" (dst, src: rawptr, len: int) -> rawptr { intrinsics.mem_copy(dst, src, len) return dst } -memory_copy_non_overlapping :: proc "contextless" (dst, src: rawptr, len: int) -> rawptr { +memory_copy :: proc "contextless" (dst, src: rawptr, len: int) -> rawptr { intrinsics.mem_copy_non_overlapping(dst, src, len) return dst } +sll_stack_push_n :: proc "contextless" (curr, n, n_link: ^^$Type) { + (n_link ^) = (curr ^) + (curr ^) = (n ^) +} +sll_queue_push_nz :: proc "contextless" (first: ^$ParentType, last, n: ^^$Type, nil_val: ^Type) { + if (first ^) == nil_val { + (first ^) = n^ + (last ^) = n^ + n^.next = nil_val + } + else { + (last ^).next = n^ + (last ^) = n^ + n^.next = nil_val + } +} +sll_queue_push_n :: #force_inline proc "contextless" (first: $ParentType, last, n: ^^$Type) { sll_queue_push_nz(first, last, n, nil) } + SliceByte :: struct { data: [^]byte, len: int @@ -139,37 +157,19 @@ slice_end :: #force_inline proc "contextless" (s : $SliceType / []$Type) -> ^Typ slice_zero :: proc "contextless" (data: $SliceType / []$Type) { memory_zero(raw_data(data), size_of(Type) * len(data)) } slice_copy :: proc "contextless" (dst, src: $SliceType / []$Type) -> int { - n := max(0, min(len(dst), len(src))) - if n > 0 { - intrinsics.mem_copy(raw_data(dst), raw_data(src), n * size_of(Type)) - } - return n -} -slice_copy_non_overlapping :: proc "contextless" (dst, src: $SliceType / []$Type) -> int { n := max(0, min(len(dst), len(src))) if n > 0 { intrinsics.mem_copy_non_overlapping(raw_data(dst), raw_data(src), n * size_of(Type)) } return n } - -sll_stack_push_n :: proc "contextless" (curr, n, n_link: ^^$Type) { - (n_link ^) = (curr ^) - (curr ^) = (n ^) -} -sll_queue_push_nz :: proc "contextless" (first: ^$ParentType, last, n: ^^$Type, nil_val: ^Type) { - if (first ^) == nil_val { - (first ^) = n^ - (last ^) = n^ - n^.next = nil_val - } - else { - (last ^).next = n^ - (last ^) = n^ - n^.next = nil_val +slice_copy_overlapping :: proc "contextless" (dst, src: $SliceType / []$Type) -> int { + n := max(0, min(len(dst), len(src))) + if n > 0 { + intrinsics.mem_copy(raw_data(dst), raw_data(src), n * size_of(Type)) } + return n } -sll_queue_push_n :: #force_inline proc "contextless" (first: $ParentType, last, n: ^^$Type) { sll_queue_push_nz(first, last, n, nil) } //endregion Memory //region Allocator Interface @@ -1220,35 +1220,36 @@ str8_fmt_kt1l :: proc(ainfo: AllocatorInfo, _buffer: ^[]byte, table: []KT1L_Slot cursor_buffer := cursor(buffer) buffer_remaining := len(buffer) - curr_code := fmt_template[0] cursor_fmt := cursor(transmute([]u8) fmt_template) left_fmt := len(fmt_template) for ; left_fmt > 0 && buffer_remaining > 0; { // Forward until we hit the delimiter '<' or the template's contents are exhausted. - for ; curr_code != '<' && cursor_fmt != end(fmt_template); { - cursor_buffer[0] = cursor_fmt [0] - cursor_buffer = cursor_buffer[1:] - cursor_fmt = cursor_fmt [1:] - curr_code = cursor_fmt [0] - buffer_remaining -= 1 - left_fmt -= 1 + copy_offset : int = 0 + for ; cursor_fmt[copy_offset] != '<' && cursor_fmt[copy_offset:] != end(fmt_template); { + copy_offset += 1 } - if curr_code == '<' + copy(cursor_buffer, cursor_fmt, copy_offset) + buffer_remaining -= copy_offset + left_fmt -= copy_offset + cursor_buffer = cursor_buffer[copy_offset:] + cursor_fmt = cursor_fmt [copy_offset:] + + if cursor_fmt[0] == '<' { - cursor_potential_token := cursor_fmt[1:] - potential_token_length := 0 + potential_token_cursor := cursor_fmt[1:] + potential_token_len := 0 fmt_overflow := b32(false) for ;; { - cursor := cursor_potential_token[potential_token_length:] + cursor := potential_token_cursor[potential_token_len:] fmt_overflow = cursor >= end(fmt_template) - found_terminator := cast(b32) (cursor_potential_token[potential_token_length] == '>') + found_terminator := cast(b32) (potential_token_cursor[potential_token_len] == '>') if fmt_overflow || found_terminator do break - potential_token_length += 1 + potential_token_len += 1 } if fmt_overflow do continue // Hashing the potential token and cross checking it with our token table - key : u64 = 0; hash64_djb8(& key, slice(cursor_potential_token, potential_token_length)) + key : u64 = 0; hash64_djb8(& key, slice(potential_token_cursor, potential_token_len)) value : ^string = nil for & token in table { @@ -1261,32 +1262,26 @@ str8_fmt_kt1l :: proc(ainfo: AllocatorInfo, _buffer: ^[]byte, table: []KT1L_Slot if value != nil { // We're going to appending the string, make sure we have enough space in our buffer. - if ainfo.procedure != nil && (buffer_remaining - potential_token_length) <= 0 { - buffer = mem_grow(ainfo, buffer, len(buffer) + potential_token_length) - buffer_remaining += potential_token_length - } - left := len(value) - cursor_value := cursor(transmute([]u8) value^) - for ; left > 0 && buffer_remaining > 0; { - cursor_buffer[0] = cursor_value [0] - cursor_buffer = cursor_buffer[1:] - cursor_value = cursor_value [1:] - cursor_fmt = cursor_fmt [1:] - buffer_remaining -= 1 - left -= 1 + if ainfo.procedure != nil && (buffer_remaining - potential_token_len) <= 0 { + buffer = mem_grow(ainfo, buffer, len(buffer) + potential_token_len) + buffer_remaining += potential_token_len } + assert((buffer_remaining - potential_token_len) > 0) + copy(cursor_buffer, cursor(value ^), len(value)) // Sync cursor format to after the processed token - cursor_fmt = cursor_potential_token[potential_token_length + 1:] - curr_code = cursor_fmt[0] - left_fmt -= potential_token_length + 2 // The 2 here are the '<' & '>' delimiters being omitted. + cursor_buffer = cursor_buffer[len(value):] + buffer_remaining -= len(value) + cursor_fmt = potential_token_cursor[potential_token_len + 1:] + left_fmt -= potential_token_len + 2 // The 2 here are the '<' & '>' delimiters being omitted. continue } + // If not a subsitution, we do a single copy for the '<' and continue. cursor_buffer[0] = cursor_fmt [0] cursor_buffer = cursor_buffer[1:] cursor_fmt = cursor_fmt [1:] - curr_code = cursor_fmt [0] buffer_remaining -= 1 left_fmt -= 1 + continue } } _buffer ^ = buffer diff --git a/scripts/build.c_lottes_hybrid.ps1 b/scripts/build.c_lottes_hybrid.ps1 index 970c28b..22e618a 100644 --- a/scripts/build.c_lottes_hybrid.ps1 +++ b/scripts/build.c_lottes_hybrid.ps1 @@ -126,7 +126,7 @@ $compiler_args += ($flag_define + 'BUILD_DEBUG') $compiler_args += $flag_debug $compiler_args += ( $flag_path_debug + $path_build + '\' ) # Use the static, multithreaded, debug runtime library -$compiler_args += $flag_link_win_rt_static_debug +# $compiler_args += $flag_link_win_rt_static_debug # Include setup $compiler_args += ($flag_include + $path_root) diff --git a/scripts/build.odin.odin b/scripts/build.odin.odin index 4f9e991..f31c1d1 100644 --- a/scripts/build.odin.odin +++ b/scripts/build.odin.odin @@ -85,7 +85,6 @@ msvc_link_default_base_address :: 0x180000000 //endregion Script Grime build :: proc(working_dir : string, args : []string) -> (stdout : string, stderr : string) { - fmt.println("Building:", args) res, errs : []byte; _, res, errs, _ = os.process_exec({ working_dir = working_dir, command = args}, context.allocator) return transmute(string)res, transmute(string)errs; } @@ -106,8 +105,8 @@ main :: proc() { file_source, flag_file, join_str(flag_output_path, file_exe), - // flag_optimize_none, - falg_optimize_aggressive, + flag_optimize_none, + // falg_optimize_aggressive, flag_default_allocator_nil, flag_debug, flag_microarch_zen5, @@ -117,6 +116,4 @@ main :: proc() { flag_use_lld, join_str(flag_subsystem, "console"), }) - fmt.println(res) - fmt.println(errs) } diff --git a/scripts/build.odin.ps1 b/scripts/build.odin.ps1 index 9ee2437..e141717 100644 --- a/scripts/build.odin.ps1 +++ b/scripts/build.odin.ps1 @@ -44,5 +44,5 @@ $build_args += $flag_dyn_map_calls $build_args += $flag_default_allocator_nil $build_args += $flag_output_path + $exe if ($need_rebuild) { & $odin $build_args } -pop-location & $exe +pop-location