diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 2c9dc30ae..d3f14ca9e 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -124,13 +124,13 @@ jobs: build_macos: name: MacOS Build if: github.repository == 'odin-lang/Odin' - runs-on: macos-13 + runs-on: macos-14 # Intel machine steps: - uses: actions/checkout@v4 - name: Download LLVM and setup PATH run: | brew update - brew install llvm@20 dylibbundler lld + brew install llvm@20 dylibbundler lld@20 - name: build odin # These -L makes the linker prioritize system libraries over LLVM libraries, this is mainly to @@ -169,7 +169,7 @@ jobs: - name: Download LLVM and setup PATH run: | brew update - brew install llvm@20 dylibbundler lld + brew install llvm@20 dylibbundler lld@20 - name: build odin # These -L makes the linker prioritize system libraries over LLVM libraries, this is mainly to diff --git a/.gitignore b/.gitignore index ec5a45a7e..7f02a93c1 100644 --- a/.gitignore +++ b/.gitignore @@ -303,3 +303,9 @@ codegen/build/gen_src.map .cache/ .clangd compile_commands.json + +# Dev cmake helpers +build/ +cmake-build*/ +CMakeLists.txt +sandbox/ diff --git a/base/intrinsics/intrinsics.odin b/base/intrinsics/intrinsics.odin index 2d940cf67..952f927bd 100644 --- a/base/intrinsics/intrinsics.odin +++ b/base/intrinsics/intrinsics.odin @@ -138,10 +138,13 @@ type_is_rune :: proc($T: typeid) -> bool --- type_is_float :: proc($T: typeid) -> bool --- type_is_complex :: proc($T: typeid) -> bool --- type_is_quaternion :: proc($T: typeid) -> bool --- -type_is_string :: proc($T: typeid) -> bool --- type_is_typeid :: proc($T: typeid) -> bool --- type_is_any :: proc($T: typeid) -> bool --- +type_is_string :: proc($T: typeid) -> bool --- type_is_string16 :: proc($T: typeid) -> bool --- +type_is_cstring :: proc($T: typeid) -> bool --- +type_is_cstring16 :: proc($T: typeid) -> bool --- + type_is_endian_platform :: proc($T: typeid) -> bool --- type_is_endian_little :: proc($T: typeid) -> bool --- @@ -154,6 +157,7 @@ type_is_indexable :: proc($T: typeid) -> bool --- type_is_sliceable :: proc($T: typeid) -> bool --- type_is_comparable :: proc($T: typeid) -> bool --- type_is_simple_compare :: proc($T: typeid) -> bool --- // easily compared using memcmp (== and !=) +type_is_nearly_simple_compare :: proc($T: typeid) -> bool --- // easily compared using memcmp (including floats) type_is_dereferenceable :: proc($T: typeid) -> bool --- type_is_valid_map_key :: proc($T: typeid) -> bool --- type_is_valid_matrix_elements :: proc($T: typeid) -> bool --- @@ -344,6 +348,9 @@ simd_lanes_rotate_right :: proc(a: #simd[N]T, $offset: int) -> #simd[N]T --- has_target_feature :: proc($test: $T) -> bool where type_is_string(T) || type_is_proc(T) --- +// Utility Calls +concatentate :: proc(x, y: $T, z: ..T) -> T where type_is_array(T) || type_is_slice(T) --- + // Returns the value of the procedure where `x` must be a call expression procedure_of :: proc(x: $T) -> T where type_is_proc(T) --- @@ -374,10 +381,11 @@ objc_selector :: struct{} objc_class :: struct{} objc_ivar :: struct{} -objc_id :: ^objc_object -objc_SEL :: ^objc_selector -objc_Class :: ^objc_class -objc_Ivar :: ^objc_ivar +objc_id :: ^objc_object +objc_SEL :: ^objc_selector +objc_Class :: ^objc_class +objc_Ivar :: ^objc_ivar +objc_instancetype :: distinct objc_id objc_find_selector :: proc($name: string) -> objc_SEL --- objc_register_selector :: proc($name: string) -> objc_SEL --- @@ -385,6 +393,7 @@ objc_find_class :: proc($name: string) -> objc_Class --- objc_register_class :: proc($name: string) -> objc_Class --- objc_ivar_get :: proc(self: ^$T) -> ^$U --- objc_block :: proc(invoke: $T, ..any) -> ^Objc_Block(T) where type_is_proc(T) --- +objc_super :: proc(obj: ^$T) -> ^$U where type_is_subtype_of(T, objc_object) && type_is_subtype_of(U, objc_object) --- valgrind_client_request :: proc(default: uintptr, request: uintptr, a0, a1, a2, a3, a4: uintptr) -> uintptr --- diff --git a/base/runtime/core.odin b/base/runtime/core.odin index 478a3d307..71e560700 100644 --- a/base/runtime/core.odin +++ b/base/runtime/core.odin @@ -636,6 +636,8 @@ _cleanup_runtime_contextless :: proc "contextless" () { ///////////////////////////// +// type_info_base returns the base-type of a `^Type_Info` stripping the `distinct`ness from the first level +@(require_results) type_info_base :: proc "contextless" (info: ^Type_Info) -> ^Type_Info { if info == nil { return nil @@ -652,6 +654,10 @@ type_info_base :: proc "contextless" (info: ^Type_Info) -> ^Type_Info { } +// type_info_core returns the core-type of a `^Type_Info` stripping the `distinct`ness from the first level AND/OR +// returns the backing integer type of an enum or bit_set `^Type_Info`. +// This is also aliased as `type_info_base_without_enum` +@(require_results) type_info_core :: proc "contextless" (info: ^Type_Info) -> ^Type_Info { if info == nil { return nil @@ -668,6 +674,10 @@ type_info_core :: proc "contextless" (info: ^Type_Info) -> ^Type_Info { } return base } + +// type_info_base_without_enum returns the core-type of a `^Type_Info` stripping the `distinct`ness from the first level AND/OR +// returns the backing integer type of an enum or bit_set `^Type_Info`. +// This is also aliased as `type_info_core` type_info_base_without_enum :: type_info_core __type_info_of :: proc "contextless" (id: typeid) -> ^Type_Info #no_bounds_check { @@ -684,15 +694,23 @@ __type_info_of :: proc "contextless" (id: typeid) -> ^Type_Info #no_bounds_check } when !ODIN_NO_RTTI { + // typeid_base returns the base-type of a `typeid` stripping the `distinct`ness from the first level typeid_base :: proc "contextless" (id: typeid) -> typeid { ti := type_info_of(id) ti = type_info_base(ti) return ti.id } + // typeid_core returns the core-type of a `typeid` stripping the `distinct`ness from the first level AND/OR + // returns the backing integer type of an enum or bit_set `typeid`. + // This is also aliased as `typeid_base_without_enum` typeid_core :: proc "contextless" (id: typeid) -> typeid { ti := type_info_core(type_info_of(id)) return ti.id } + + // typeid_base_without_enum returns the core-type of a `typeid` stripping the `distinct`ness from the first level AND/OR + // returns the backing integer type of an enum or bit_set `typeid`. + // This is also aliased as `typeid_core` typeid_base_without_enum :: typeid_core } @@ -708,11 +726,15 @@ default_logger_proc :: proc(data: rawptr, level: Logger_Level, text: string, opt // Nothing } +// Returns the default logger used by `context.logger` +@(require_results) default_logger :: proc() -> Logger { return Logger{default_logger_proc, nil, Logger_Level.Debug, nil} } +// Returns the default `context` +@(require_results) default_context :: proc "contextless" () -> Context { c: Context __init_context(&c) diff --git a/base/runtime/core_builtin.odin b/base/runtime/core_builtin.odin index f264da3aa..a465dd11b 100644 --- a/base/runtime/core_builtin.odin +++ b/base/runtime/core_builtin.odin @@ -62,6 +62,8 @@ when !NO_DEFAULT_TEMP_ALLOCATOR { } } +// Initializes the global temporary allocator used as the default `context.temp_allocator`. +// This is ignored when `NO_DEFAULT_TEMP_ALLOCATOR` is true. @(builtin, disabled=NO_DEFAULT_TEMP_ALLOCATOR) init_global_temporary_allocator :: proc(size: int, backup_allocator := context.allocator) { when !NO_DEFAULT_TEMP_ALLOCATOR { @@ -565,6 +567,7 @@ _append_elem :: #force_no_inline proc(array: ^Raw_Dynamic_Array, size_of_elem, a return } +// `append_elem` appends an element to the end of a dynamic array. @builtin append_elem :: proc(array: ^$T/[dynamic]$E, #no_broadcast arg: E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { when size_of(E) == 0 { @@ -576,6 +579,9 @@ append_elem :: proc(array: ^$T/[dynamic]$E, #no_broadcast arg: E, loc := #caller } } +// `non_zero_append_elem` appends an element to the end of a dynamic array, without zeroing any reserved memory +// +// Note: Prefer using the procedure group `non_zero_append @builtin non_zero_append_elem :: proc(array: ^$T/[dynamic]$E, #no_broadcast arg: E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { when size_of(E) == 0 { @@ -614,6 +620,9 @@ _append_elems :: #force_no_inline proc(array: ^Raw_Dynamic_Array, size_of_elem, return arg_len, err } +// `append_elems` appends `args` to the end of a dynamic array. +// +// Note: Prefer using the procedure group `append`. @builtin append_elems :: proc(array: ^$T/[dynamic]$E, #no_broadcast args: ..E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { when size_of(E) == 0 { @@ -625,6 +634,9 @@ append_elems :: proc(array: ^$T/[dynamic]$E, #no_broadcast args: ..E, loc := #ca } } +// `non_zero_append_elems` appends `args` to the end of a dynamic array, without zeroing any reserved memory +// +// Note: Prefer using the procedure group `non_zero_append @builtin non_zero_append_elems :: proc(array: ^$T/[dynamic]$E, #no_broadcast args: ..E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { when size_of(E) == 0 { @@ -641,10 +653,16 @@ _append_elem_string :: proc(array: ^$T/[dynamic]$E/u8, arg: $A/string, should_ze return _append_elems((^Raw_Dynamic_Array)(array), 1, 1, should_zero, loc, raw_data(arg), len(arg)) } +// `append_elem_string` appends a string to the end of a dynamic array of bytes +// +// Note: Prefer using the procedure group `append`. @builtin append_elem_string :: proc(array: ^$T/[dynamic]$E/u8, arg: $A/string, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { return _append_elem_string(array, arg, true, loc) } +// `non_zero_append_elem_string` appends a string to the end of a dynamic array of bytes, without zeroing any reserved memory +// +// Note: Prefer using the procedure group `non_zero_append`. @builtin non_zero_append_elem_string :: proc(array: ^$T/[dynamic]$E/u8, arg: $A/string, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { return _append_elem_string(array, arg, false, loc) @@ -652,6 +670,8 @@ non_zero_append_elem_string :: proc(array: ^$T/[dynamic]$E/u8, arg: $A/string, l // The append_string built-in procedure appends multiple strings to the end of a [dynamic]u8 like type +// +// Note: Prefer using the procedure group `append`. @builtin append_string :: proc(array: ^$T/[dynamic]$E/u8, args: ..string, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { n_arg: int @@ -666,7 +686,8 @@ append_string :: proc(array: ^$T/[dynamic]$E/u8, args: ..string, loc := #caller_ } // The append built-in procedure appends elements to the end of a dynamic array -@builtin append :: proc{ +@builtin +append :: proc{ append_elem, append_elems, append_elem_string, @@ -675,7 +696,8 @@ append_string :: proc(array: ^$T/[dynamic]$E/u8, args: ..string, loc := #caller_ append_soa_elems, } -@builtin non_zero_append :: proc{ +@builtin +non_zero_append :: proc{ non_zero_append_elem, non_zero_append_elems, non_zero_append_elem_string, @@ -685,6 +707,8 @@ append_string :: proc(array: ^$T/[dynamic]$E/u8, args: ..string, loc := #caller_ } +// `append_nothing` appends an empty value to a dynamic array. It returns `1, nil` if successful, and `0, err` when it was not possible, +// whatever `err` happens to be. @builtin append_nothing :: proc(array: ^$T/[dynamic]$E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { if array == nil { @@ -696,6 +720,7 @@ append_nothing :: proc(array: ^$T/[dynamic]$E, loc := #caller_location) -> (n: i } +// `inject_at_elem` injects an element in a dynamic array at a specified index and moves the previous elements after that index "across" @builtin inject_at_elem :: proc(array: ^$T/[dynamic]$E, #any_int index: int, #no_broadcast arg: E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error { when !ODIN_NO_BOUNDS_CHECK { @@ -717,6 +742,7 @@ inject_at_elem :: proc(array: ^$T/[dynamic]$E, #any_int index: int, #no_broadcas return } +// `inject_at_elems` injects multiple elements in a dynamic array at a specified index and moves the previous elements after that index "across" @builtin inject_at_elems :: proc(array: ^$T/[dynamic]$E, #any_int index: int, #no_broadcast args: ..E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error { when !ODIN_NO_BOUNDS_CHECK { @@ -743,6 +769,7 @@ inject_at_elems :: proc(array: ^$T/[dynamic]$E, #any_int index: int, #no_broadca return } +// `inject_at_elem_string` injects a string into a dynamic array at a specified index and moves the previous elements after that index "across" @builtin inject_at_elem_string :: proc(array: ^$T/[dynamic]$E/u8, #any_int index: int, arg: string, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error { when !ODIN_NO_BOUNDS_CHECK { @@ -767,10 +794,13 @@ inject_at_elem_string :: proc(array: ^$T/[dynamic]$E/u8, #any_int index: int, ar return } +// `inject_at` injects something into a dynamic array at a specified index and moves the previous elements after that index "across" @builtin inject_at :: proc{inject_at_elem, inject_at_elems, inject_at_elem_string} +// `assign_at_elem` assigns a value at a given index. If the requested index is smaller than the current +// size of the dynamic array, it will attempt to `resize` the a new length of `index+1` and then assign as `index`. @builtin assign_at_elem :: proc(array: ^$T/[dynamic]$E, #any_int index: int, arg: E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error { if index < len(array) { @@ -785,6 +815,8 @@ assign_at_elem :: proc(array: ^$T/[dynamic]$E, #any_int index: int, arg: E, loc } +// `assign_at_elems` assigns a values at a given index. If the requested index is smaller than the current +// size of the dynamic array, it will attempt to `resize` the a new length of `index+len(args)` and then assign as `index`. @builtin assign_at_elems :: proc(array: ^$T/[dynamic]$E, #any_int index: int, #no_broadcast args: ..E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error { new_size := index + len(args) @@ -801,7 +833,8 @@ assign_at_elems :: proc(array: ^$T/[dynamic]$E, #any_int index: int, #no_broadca return } - +// `assign_at_elem_string` assigns a string at a given index. If the requested index is smaller than the current +// size of the dynamic array, it will attempt to `resize` the a new length of `index+len(arg)` and then assign as `index`. @builtin assign_at_elem_string :: proc(array: ^$T/[dynamic]$E/u8, #any_int index: int, arg: string, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error { new_size := index + len(arg) @@ -818,7 +851,14 @@ assign_at_elem_string :: proc(array: ^$T/[dynamic]$E/u8, #any_int index: int, ar return } -@builtin assign_at :: proc{assign_at_elem, assign_at_elems, assign_at_elem_string} +// `assign_at` assigns a value at a given index. If the requested index is smaller than the current +// size of the dynamic array, it will attempt to `resize` the a new length of `index+size_needed` and then assign as `index`. +@builtin +assign_at :: proc{ + assign_at_elem, + assign_at_elems, + assign_at_elem_string, +} @@ -835,6 +875,8 @@ clear_dynamic_array :: proc "contextless" (array: ^$T/[dynamic]$E) { // `reserve_dynamic_array` will try to reserve memory of a passed dynamic array or map to the requested element count (setting the `cap`). // +// When a memory resize allocation is required, the memory will be asked to be zeroed (i.e. it calls `mem_resize`). +// // Note: Prefer the procedure group `reserve`. _reserve_dynamic_array :: #force_no_inline proc(a: ^Raw_Dynamic_Array, size_of_elem, align_of_elem: int, capacity: int, should_zero: bool, loc := #caller_location) -> Allocator_Error { if a == nil { @@ -870,11 +912,21 @@ _reserve_dynamic_array :: #force_no_inline proc(a: ^Raw_Dynamic_Array, size_of_e return nil } +// `reserve_dynamic_array` will try to reserve memory of a passed dynamic array or map to the requested element count (setting the `cap`). +// +// When a memory resize allocation is required, the memory will be asked to be zeroed (i.e. it calls `mem_resize`). +// +// Note: Prefer the procedure group `reserve`. @builtin reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, #any_int capacity: int, loc := #caller_location) -> Allocator_Error { return _reserve_dynamic_array((^Raw_Dynamic_Array)(array), size_of(E), align_of(E), capacity, true, loc) } +// `non_zero_reserve_dynamic_array` will try to reserve memory of a passed dynamic array or map to the requested element count (setting the `cap`). +// +// When a memory resize allocation is required, the memory will be asked to not be zeroed (i.e. it calls `non_zero_mem_resize`). +// +// Note: Prefer the procedure group `non_zero_reserve`. @builtin non_zero_reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, #any_int capacity: int, loc := #caller_location) -> Allocator_Error { return _reserve_dynamic_array((^Raw_Dynamic_Array)(array), size_of(E), align_of(E), capacity, false, loc) @@ -924,28 +976,33 @@ _resize_dynamic_array :: #force_no_inline proc(a: ^Raw_Dynamic_Array, size_of_el // `resize_dynamic_array` will try to resize memory of a passed dynamic array or map to the requested element count (setting the `len`, and possibly `cap`). // +// When a memory resize allocation is required, the memory will be asked to be zeroed (i.e. it calls `mem_resize`). +// // Note: Prefer the procedure group `resize` @builtin resize_dynamic_array :: proc(array: ^$T/[dynamic]$E, #any_int length: int, loc := #caller_location) -> Allocator_Error { return _resize_dynamic_array((^Raw_Dynamic_Array)(array), size_of(E), align_of(E), length, true, loc=loc) } +// `non_zero_resize_dynamic_array` will try to resize memory of a passed dynamic array or map to the requested element count (setting the `len`, and possibly `cap`). +// +// When a memory resize allocation is required, the memory will be asked to not be zeroed (i.e. it calls `non_zero_mem_resize`). +// +// Note: Prefer the procedure group `non_zero_resize` @builtin non_zero_resize_dynamic_array :: proc(array: ^$T/[dynamic]$E, #any_int length: int, loc := #caller_location) -> Allocator_Error { return _resize_dynamic_array((^Raw_Dynamic_Array)(array), size_of(E), align_of(E), length, false, loc=loc) } -/* - Shrinks the capacity of a dynamic array down to the current length, or the given capacity. - - If `new_cap` is negative, then `len(array)` is used. - - Returns false if `cap(array) < new_cap`, or the allocator report failure. - - If `len(array) < new_cap`, then `len(array)` will be left unchanged. - - Note: Prefer the procedure group `shrink` -*/ +// Shrinks the capacity of a dynamic array down to the current length, or the given capacity. +// +// If `new_cap` is negative, then `len(array)` is used. +// +// Returns false if `cap(array) < new_cap`, or the allocator report failure. +// +// If `len(array) < new_cap`, then `len(array)` will be left unchanged. +// +// Note: Prefer the procedure group `shrink` shrink_dynamic_array :: proc(array: ^$T/[dynamic]$E, #any_int new_cap := -1, loc := #caller_location) -> (did_shrink: bool, err: Allocator_Error) { return _shrink_dynamic_array((^Raw_Dynamic_Array)(array), size_of(E), align_of(E), new_cap, loc) } @@ -1027,6 +1084,7 @@ map_entry :: proc(m: ^$T/map[$K]$V, key: K, loc := #caller_location) -> (key_ptr } +// `card` returns the number of bits that are set in a bit_set—its cardinality @builtin card :: proc "contextless" (s: $S/bit_set[$E; $U]) -> int { return int(intrinsics.count_ones(transmute(intrinsics.type_bit_set_underlying_type(S))s)) @@ -1034,6 +1092,10 @@ card :: proc "contextless" (s: $S/bit_set[$E; $U]) -> int { +// Evaluates the condition and panics the program iff the condition is false. +// This uses the `context.assertion_failure_procedure` to assert. +// +// This routine will be ignored when `ODIN_DISABLE_ASSERT` is true. @builtin @(disabled=ODIN_DISABLE_ASSERT) assert :: proc(condition: bool, message := #caller_expression(condition), loc := #caller_location) { @@ -1054,9 +1116,9 @@ assert :: proc(condition: bool, message := #caller_expression(condition), loc := } } -// Evaluates the condition and aborts the program iff the condition is -// false. This routine ignores `ODIN_DISABLE_ASSERT`, and will always -// execute. +// Evaluates the condition and panics the program iff the condition is false. +// This uses the `context.assertion_failure_procedure` to assert. +// This routine ignores `ODIN_DISABLE_ASSERT`, and will always execute. @builtin ensure :: proc(condition: bool, message := #caller_expression(condition), loc := #caller_location) { if !condition { @@ -1072,6 +1134,8 @@ ensure :: proc(condition: bool, message := #caller_expression(condition), loc := } } +// Panics the program with a message. +// This uses the `context.assertion_failure_procedure` to panic. @builtin panic :: proc(message: string, loc := #caller_location) -> ! { p := context.assertion_failure_proc @@ -1081,6 +1145,8 @@ panic :: proc(message: string, loc := #caller_location) -> ! { p("panic", message, loc) } +// Panics the program with a message to indicate something has yet to be implemented. +// This uses the `context.assertion_failure_procedure` to assert. @builtin unimplemented :: proc(message := "", loc := #caller_location) -> ! { p := context.assertion_failure_proc @@ -1090,7 +1156,10 @@ unimplemented :: proc(message := "", loc := #caller_location) -> ! { p("not yet implemented", message, loc) } - +// Evaluates the condition and panics the program iff the condition is false. +// This uses the `default_assertion_contextless_failure_proc` to assert. +// +// This routine will be ignored when `ODIN_DISABLE_ASSERT` is true. @builtin @(disabled=ODIN_DISABLE_ASSERT) assert_contextless :: proc "contextless" (condition: bool, message := #caller_expression(condition), loc := #caller_location) { @@ -1107,6 +1176,8 @@ assert_contextless :: proc "contextless" (condition: bool, message := #caller_ex } } +// Evaluates the condition and panics the program iff the condition is false. +// This uses the `default_assertion_contextless_failure_proc` to assert. @builtin ensure_contextless :: proc "contextless" (condition: bool, message := #caller_expression(condition), loc := #caller_location) { if !condition { @@ -1118,11 +1189,15 @@ ensure_contextless :: proc "contextless" (condition: bool, message := #caller_ex } } +// Panics the program with a message to indicate something has yet to be implemented. +// This uses the `default_assertion_contextless_failure_proc` to assert. @builtin panic_contextless :: proc "contextless" (message: string, loc := #caller_location) -> ! { default_assertion_contextless_failure_proc("panic", message, loc) } +// Panics the program with a message. +// This uses the `default_assertion_contextless_failure_proc` to assert. @builtin unimplemented_contextless :: proc "contextless" (message := "", loc := #caller_location) -> ! { default_assertion_contextless_failure_proc("not yet implemented", message, loc) diff --git a/base/runtime/default_allocators_nil.odin b/base/runtime/default_allocators_nil.odin index f5ebad28f..2f2edb40a 100644 --- a/base/runtime/default_allocators_nil.odin +++ b/base/runtime/default_allocators_nil.odin @@ -23,6 +23,14 @@ nil_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, return nil, .None } +// nil_allocator returns an allocator which will return `nil` for any result. +// * `.Alloc`, `.Alloc_Non_Zero`, `.Resize`, `.Resize_Non_Zeroed` will return `nil, .Out_Of_Memory` +// * `.Free` will return `nil, .None` +// * `.Free_All` will return `nil, .Mode_Not_Implemented` +// * `.Query_Features`, `.Query_Info` will return `nil, .Mode_Not_Implemented` +// +// This is extremely useful for creating a dynamic array from a buffer which does not nothing +// on a resize/reserve beyond the originally allocated memory. @(require_results) nil_allocator :: proc "contextless" () -> Allocator { return Allocator{ @@ -73,6 +81,9 @@ panic_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, return nil, nil } +// panic_allocator returns an allocator which will panic for any non-zero-sized allocation or `query_info` +// +// This is extremely useful for to check when something does a memory operation when it should not, and thus panic. @(require_results) panic_allocator :: proc() -> Allocator { return Allocator{ diff --git a/base/runtime/default_temporary_allocator.odin b/base/runtime/default_temporary_allocator.odin index 34a169b48..6e16d896b 100644 --- a/base/runtime/default_temporary_allocator.odin +++ b/base/runtime/default_temporary_allocator.odin @@ -4,6 +4,7 @@ DEFAULT_TEMP_ALLOCATOR_BACKING_SIZE: int : #config(DEFAULT_TEMP_ALLOCATOR_BACKIN NO_DEFAULT_TEMP_ALLOCATOR: bool : ODIN_OS == .Freestanding || ODIN_DEFAULT_TO_NIL_ALLOCATOR when NO_DEFAULT_TEMP_ALLOCATOR { + // `Default_Temp_Allocator` is a `nil_allocator` when `NO_DEFAULT_TEMP_ALLOCATOR` is `true`. Default_Temp_Allocator :: struct {} default_temp_allocator_init :: proc(s: ^Default_Temp_Allocator, size: int, backing_allocator := context.allocator) {} @@ -20,6 +21,11 @@ when NO_DEFAULT_TEMP_ALLOCATOR { default_temp_allocator_temp_end :: proc(temp: Arena_Temp, loc := #caller_location) { } } else { + // `Default_Temp_Allocator` is an `Arena` based type of allocator. See `runtime.Arena` for its implementation. + // The default `context.temp_allocator` is typically called with `free_all(context.temp_allocator)` once per "frame-loop" + // to prevent it from "leaking" memory. + // + // Note: `Default_Temp_Allocator` is a `nil_allocator` when `NO_DEFAULT_TEMP_ALLOCATOR` is `true`. Default_Temp_Allocator :: struct { arena: Arena, } diff --git a/base/runtime/procs_darwin.odin b/base/runtime/procs_darwin.odin index d176f0f63..0ffe68e49 100644 --- a/base/runtime/procs_darwin.odin +++ b/base/runtime/procs_darwin.odin @@ -15,16 +15,25 @@ objc_SEL :: ^intrinsics.objc_selector objc_Ivar :: ^intrinsics.objc_ivar objc_BOOL :: bool +objc_super :: struct { + receiver: objc_id, + super_class: objc_Class, +} objc_IMP :: proc "c" (object: objc_id, sel: objc_SEL, #c_vararg args: ..any) -> objc_id foreign ObjC { sel_registerName :: proc "c" (name: cstring) -> objc_SEL --- - objc_msgSend :: proc "c" (self: objc_id, op: objc_SEL, #c_vararg args: ..any) --- - objc_msgSend_fpret :: proc "c" (self: objc_id, op: objc_SEL, #c_vararg args: ..any) -> f64 --- - objc_msgSend_fp2ret :: proc "c" (self: objc_id, op: objc_SEL, #c_vararg args: ..any) -> complex128 --- - objc_msgSend_stret :: proc "c" (self: objc_id, op: objc_SEL, #c_vararg args: ..any) --- + objc_msgSend :: proc "c" (self: objc_id, op: objc_SEL, #c_vararg args: ..any) --- + objc_msgSend_fpret :: proc "c" (self: objc_id, op: objc_SEL, #c_vararg args: ..any) -> f64 --- + objc_msgSend_fp2ret :: proc "c" (self: objc_id, op: objc_SEL, #c_vararg args: ..any) -> complex128 --- + objc_msgSend_stret :: proc "c" (self: objc_id, op: objc_SEL, #c_vararg args: ..any) --- + + // See: https://github.com/opensource-apple/objc4/blob/cd5e62a5597ea7a31dccef089317abb3a661c154/runtime/objc-abi.h#L111 + objc_msgSendSuper2 :: proc "c" (super: rawptr, op: objc_SEL, #c_vararg args: ..any) -> objc_id --- + objc_msgSendSuper2_stret :: proc "c" (super: ^objc_super, op: objc_SEL, #c_vararg args: ..any) --- + objc_lookUpClass :: proc "c" (name: cstring) -> objc_Class --- objc_allocateClassPair :: proc "c" (superclass: objc_Class, name: cstring, extraBytes: uint) -> objc_Class --- @@ -33,6 +42,7 @@ foreign ObjC { class_addIvar :: proc "c" (cls: objc_Class, name: cstring, size: uint, alignment: u8, types: cstring) -> objc_BOOL --- class_getInstanceVariable :: proc "c" (cls : objc_Class, name: cstring) -> objc_Ivar --- class_getInstanceSize :: proc "c" (cls : objc_Class) -> uint --- + class_getSuperclass :: proc "c" (cls : objc_Class) -> objc_Class --- ivar_getOffset :: proc "c" (v: objc_Ivar) -> uintptr --- object_getClass :: proc "c" (obj: objc_id) -> objc_Class --- } diff --git a/core/bufio/doc.odin b/core/bufio/doc.odin new file mode 100644 index 000000000..683f68f07 --- /dev/null +++ b/core/bufio/doc.odin @@ -0,0 +1,2 @@ +// Wraps an `io.Stream` interface to provide buffered I/O. +package bufio \ No newline at end of file diff --git a/core/bufio/reader.odin b/core/bufio/reader.odin index b78cac6e1..4aa1e6c5d 100644 --- a/core/bufio/reader.odin +++ b/core/bufio/reader.odin @@ -29,6 +29,7 @@ MIN_READ_BUFFER_SIZE :: 16 @(private) DEFAULT_MAX_CONSECUTIVE_EMPTY_READS :: 128 +// reader_init initializes using an `allocator` reader_init :: proc(b: ^Reader, rd: io.Reader, size: int = DEFAULT_BUF_SIZE, allocator := context.allocator, loc := #caller_location) { size := size size = max(size, MIN_READ_BUFFER_SIZE) @@ -37,6 +38,7 @@ reader_init :: proc(b: ^Reader, rd: io.Reader, size: int = DEFAULT_BUF_SIZE, all b.buf = make([]byte, size, allocator, loc) } +// reader_init initializes using a user provided bytes buffer `buf` reader_init_with_buf :: proc(b: ^Reader, rd: io.Reader, buf: []byte) { reader_reset(b, rd) b.buf_allocator = {} @@ -49,10 +51,12 @@ reader_destroy :: proc(b: ^Reader) { b^ = {} } +// reader_size returns the number of bytes in the backing buffer reader_size :: proc(b: ^Reader) -> int { return len(b.buf) } +// reader_reset resets the read and write positions, and the error values reader_reset :: proc(b: ^Reader, r: io.Reader) { b.rd = r b.r, b.w = 0, 0 diff --git a/core/bufio/scanner.odin b/core/bufio/scanner.odin index ee2d5d1f6..27d29c685 100644 --- a/core/bufio/scanner.odin +++ b/core/bufio/scanner.odin @@ -46,6 +46,7 @@ DEFAULT_MAX_SCAN_TOKEN_SIZE :: 1<<16 @(private) _INIT_BUF_SIZE :: 4096 +// Initializes a Scanner buffer an allocator `buf_allocator` scanner_init :: proc(s: ^Scanner, r: io.Reader, buf_allocator := context.allocator) -> ^Scanner { s.r = r s.split = scan_lines @@ -53,6 +54,8 @@ scanner_init :: proc(s: ^Scanner, r: io.Reader, buf_allocator := context.allocat s.buf.allocator = buf_allocator return s } + +// Initializes a Scanner buffer a user provided bytes buffer `buf` scanner_init_with_buffer :: proc(s: ^Scanner, r: io.Reader, buf: []byte) -> ^Scanner { s.r = r s.split = scan_lines @@ -75,24 +78,27 @@ scanner_error :: proc(s: ^Scanner) -> Scanner_Error { return s._err } -// Returns the most recent token created by scanner_scan. +// Returns the most recent token created by 'scan'. // The underlying array may point to data that may be overwritten -// by another call to scanner_scan. +// by another call to 'scan'. // Treat the returned value as if it is immutable. scanner_bytes :: proc(s: ^Scanner) -> []byte { return s.token } -// Returns the most recent token created by scanner_scan. +// Returns the most recent token created by 'scan'. // The underlying array may point to data that may be overwritten -// by another call to scanner_scan. +// by another call to 'scan'. // Treat the returned value as if it is immutable. scanner_text :: proc(s: ^Scanner) -> string { return string(s.token) } -// scanner_scan advances the scanner -scanner_scan :: proc(s: ^Scanner) -> bool { +// scanner_scan is an alias of scan +scanner_scan :: scan + +// scan advances the Scanner +scan :: proc(s: ^Scanner) -> bool { set_err :: proc(s: ^Scanner, err: Scanner_Error) { switch s._err { case nil, .EOF: @@ -229,6 +235,7 @@ scanner_scan :: proc(s: ^Scanner) -> bool { } } +// scan_bytes is a splitting procedure that returns each byte as a token scan_bytes :: proc(data: []byte, at_eof: bool) -> (advance: int, token: []byte, err: Scanner_Error, final_token: bool) { if at_eof && len(data) == 0 { return @@ -236,6 +243,10 @@ scan_bytes :: proc(data: []byte, at_eof: bool) -> (advance: int, token: []byte, return 1, data[0:1], nil, false } +// scan_runes is a splitting procedure that returns each UTF-8 encoded rune as a token. +// The lsit of runes return is equivalent to that of iterating over a string in a 'for in' loop, meaning any +// erroneous UTF-8 encodings will be returned as U+FFFD. Unfortunately this means it is impossible for the "client" +// to know whether a U+FFFD is an expected replacement rune or an encoding of an error. scan_runes :: proc(data: []byte, at_eof: bool) -> (advance: int, token: []byte, err: Scanner_Error, final_token: bool) { if at_eof && len(data) == 0 { return @@ -264,7 +275,8 @@ scan_runes :: proc(data: []byte, at_eof: bool) -> (advance: int, token: []byte, token = ERROR_RUNE return } - +// scan_words is a splitting procedure that returns each Unicode-space-separated word of text, excluding the surrounded spaces. +// It will never return return an empty string. scan_words :: proc(data: []byte, at_eof: bool) -> (advance: int, token: []byte, err: Scanner_Error, final_token: bool) { is_space :: proc "contextless" (r: rune) -> bool { switch r { @@ -312,6 +324,8 @@ scan_words :: proc(data: []byte, at_eof: bool) -> (advance: int, token: []byte, return } +// scan_lines is a splitting procedure that returns each line of text stripping of any trailing newline and an optional preceding carriage return (\r?\n). +// A new line is allowed to be empty. scan_lines :: proc(data: []byte, at_eof: bool) -> (advance: int, token: []byte, err: Scanner_Error, final_token: bool) { trim_carriage_return :: proc "contextless" (data: []byte) -> []byte { if len(data) > 0 && data[len(data)-1] == '\r' { diff --git a/core/bufio/writer.odin b/core/bufio/writer.odin index 5edd3dd6b..9c73baf87 100644 --- a/core/bufio/writer.odin +++ b/core/bufio/writer.odin @@ -19,6 +19,7 @@ Writer :: struct { } +// Initialized a Writer with an `allocator` writer_init :: proc(b: ^Writer, wr: io.Writer, size: int = DEFAULT_BUF_SIZE, allocator := context.allocator) { size := size size = max(size, MIN_READ_BUFFER_SIZE) @@ -27,6 +28,7 @@ writer_init :: proc(b: ^Writer, wr: io.Writer, size: int = DEFAULT_BUF_SIZE, all b.buf = make([]byte, size, allocator) } +// Initialized a Writer with a user provided buffer `buf` writer_init_with_buf :: proc(b: ^Writer, wr: io.Writer, buf: []byte) { writer_reset(b, wr) b.buf_allocator = {} diff --git a/core/bytes/bytes.odin b/core/bytes/bytes.odin index 71b6ef70c..79de89d2f 100644 --- a/core/bytes/bytes.odin +++ b/core/bytes/bytes.odin @@ -1,3 +1,4 @@ +// Procedures for manipulation of `[]byte` slices. package bytes import "base:intrinsics" @@ -134,8 +135,13 @@ equal_fold :: proc(u, v: []byte) -> bool { return false } - // TODO(bill): Unicode folding - + r := unicode.simple_fold(sr) + for r != sr && r < tr { + r = unicode.simple_fold(sr) + } + if r == tr { + continue loop + } return false } diff --git a/core/c/c.odin b/core/c/c.odin index 73727d8d5..8266bf38a 100644 --- a/core/c/c.odin +++ b/core/c/c.odin @@ -1,3 +1,4 @@ +// Defines the basic types used by `C` programs for foreign function and data structure interop. package c import builtin "base:builtin" diff --git a/core/c/libc/doc.odin b/core/c/libc/doc.odin new file mode 100644 index 000000000..856ee41c6 --- /dev/null +++ b/core/c/libc/doc.odin @@ -0,0 +1,2 @@ +// Declares the commonly used things in `libc` (`C` standard library). +package libc diff --git a/core/compress/common.odin b/core/compress/common.odin index f4429b667..796a60071 100644 --- a/core/compress/common.odin +++ b/core/compress/common.odin @@ -1,3 +1,6 @@ +// A collection of utilities to aid with other `compress`ion packages. +package compress + /* Copyright 2021 Jeroen van Rijn . Made available under Odin's BSD-3 license. @@ -6,10 +9,6 @@ Jeroen van Rijn: Initial implementation, optimization. */ - -// package compress is a collection of utilities to aid with other compression packages -package compress - import "core:io" import "core:bytes" import "base:runtime" diff --git a/core/compress/gzip/doc.odin b/core/compress/gzip/doc.odin index fd7ef5a19..18f2259cb 100644 --- a/core/compress/gzip/doc.odin +++ b/core/compress/gzip/doc.odin @@ -1,15 +1,6 @@ /* - Copyright 2021 Jeroen van Rijn . - Made available under Odin's BSD-3 license. +A small `GZIP` unpacker. - List of contributors: - Jeroen van Rijn: Initial implementation. - Ginger Bill: Cosmetic changes. - - A small GZIP implementation as an example. -*/ - -/* Example: import "core:bytes" import "core:os" @@ -88,3 +79,14 @@ Example: } */ package compress_gzip + +/* + Copyright 2021 Jeroen van Rijn . + Made available under Odin's BSD-3 license. + + List of contributors: + Jeroen van Rijn: Initial implementation. + Ginger Bill: Cosmetic changes. + + A small GZIP implementation as an example. +*/ \ No newline at end of file diff --git a/core/compress/shoco/model.odin b/core/compress/shoco/model.odin index 919563441..bca58386b 100644 --- a/core/compress/shoco/model.odin +++ b/core/compress/shoco/model.odin @@ -1,11 +1,11 @@ +package compress_shoco + /* This file was generated, so don't edit this by hand. Transliterated from https://github.com/Ed-von-Schleck/shoco/blob/master/shoco_model.h, which is an English word model. */ -package compress_shoco - DEFAULT_MODEL :: Shoco_Model { min_char = 39, max_char = 122, diff --git a/core/compress/shoco/shoco.odin b/core/compress/shoco/shoco.odin index b393b8356..be079df19 100644 --- a/core/compress/shoco/shoco.odin +++ b/core/compress/shoco/shoco.odin @@ -1,3 +1,6 @@ +// `Shoco` short string compression and decompression. +package compress_shoco + /* Copyright 2022 Jeroen van Rijn . Made available under Odin's BSD-3 license. @@ -8,9 +11,6 @@ An implementation of [shoco](https://github.com/Ed-von-Schleck/shoco) by Christian Schramm. */ -// package shoco is an implementation of the shoco short string compressor. -package compress_shoco - import "base:intrinsics" import "core:compress" diff --git a/core/compress/zlib/doc.odin b/core/compress/zlib/doc.odin index 6ae537a87..6923c2a60 100644 --- a/core/compress/zlib/doc.odin +++ b/core/compress/zlib/doc.odin @@ -1,14 +1,6 @@ /* - Copyright 2021 Jeroen van Rijn . - Made available under Odin's BSD-3 license. +`Deflate` decompression of raw and `ZLIB`-type streams. - List of contributors: - Jeroen van Rijn: Initial implementation. - - An example of how to use `zlib.inflate`. -*/ - -/* Example: package main @@ -49,3 +41,13 @@ Example: } */ package compress_zlib + +/* + Copyright 2021 Jeroen van Rijn . + Made available under Odin's BSD-3 license. + + List of contributors: + Jeroen van Rijn: Initial implementation. + + An example of how to use `zlib.inflate`. +*/ \ No newline at end of file diff --git a/core/container/avl/avl.odin b/core/container/avl/avl.odin index 8a9d1f3d9..6c7216c29 100644 --- a/core/container/avl/avl.odin +++ b/core/container/avl/avl.odin @@ -1,8 +1,4 @@ -/* -package avl implements an AVL tree. - -The implementation is non-intrusive, and non-recursive. -*/ +// A non-intrusive and non-recursive implementation of `AVL` trees. package container_avl @(require) import "base:intrinsics" diff --git a/core/container/bit_array/doc.odin b/core/container/bit_array/doc.odin index 36bf90002..e86059ecd 100644 --- a/core/container/bit_array/doc.odin +++ b/core/container/bit_array/doc.odin @@ -1,7 +1,9 @@ /* +A dynamically-sized array of bits. + The Bit Array can be used in several ways: -By default you don't need to instantiate a Bit Array. +By default you don't need to instantiate a `Bit_Array`. Example: package test @@ -18,11 +20,11 @@ Example: // returns `false`, `false`, because this Bit Array wasn't created to allow negative indices. was_set, was_retrieved := get(&bits, -1) - fmt.println(was_set, was_retrieved) + fmt.println(was_set, was_retrieved) destroy(&bits) } -A Bit Array can optionally allow for negative indices, if the minimum value was given during creation. +A `Bit_Array` can optionally allow for negative indices, if the minimum value was given during creation. Example: package test @@ -49,4 +51,4 @@ Example: fmt.printf("Freed.\n") } */ -package container_dynamic_bit_array +package container_dynamic_bit_array \ No newline at end of file diff --git a/core/container/intrusive/list/doc.odin b/core/container/intrusive/list/doc.odin index 155f1dfe2..a50c27216 100644 --- a/core/container/intrusive/list/doc.odin +++ b/core/container/intrusive/list/doc.odin @@ -1,7 +1,7 @@ /* -Package list implements an intrusive doubly-linked list. +An intrusive doubly-linked list. -An intrusive container requires a `Node` to be embedded in your own structure, like this. +The intrusive container requires a `Node` to be embedded in your own structure, like this. Example: My_String :: struct { node: list.Node, @@ -46,4 +46,4 @@ Output: Hello World */ -package container_intrusive_list +package container_intrusive_list \ No newline at end of file diff --git a/core/container/lru/lru_cache.odin b/core/container/lru/lru_cache.odin index d95e8e1d2..23d3e1eb9 100644 --- a/core/container/lru/lru_cache.odin +++ b/core/container/lru/lru_cache.odin @@ -1,3 +1,4 @@ +// A least-recently-used (`LRU`) cache. It automatically removes older entries if its capacity is reached. package container_lru import "base:runtime" diff --git a/core/container/priority_queue/priority_queue.odin b/core/container/priority_queue/priority_queue.odin index c62a821f4..c9ef807c5 100644 --- a/core/container/priority_queue/priority_queue.odin +++ b/core/container/priority_queue/priority_queue.odin @@ -1,3 +1,4 @@ +// A priority queue data structure. package container_priority_queue import "base:builtin" diff --git a/core/container/queue/queue.odin b/core/container/queue/queue.odin index 8de8d55c0..37f3a923f 100644 --- a/core/container/queue/queue.odin +++ b/core/container/queue/queue.odin @@ -1,3 +1,4 @@ +// A dynamically resizable double-ended queue/ring-buffer. package container_queue import "base:builtin" diff --git a/core/container/rbtree/rbtree.odin b/core/container/rbtree/rbtree.odin index 090551367..35ce21413 100644 --- a/core/container/rbtree/rbtree.odin +++ b/core/container/rbtree/rbtree.odin @@ -1,4 +1,4 @@ -// This package implements a red-black tree +// A red-black tree with the same API as our AVL tree. package container_rbtree @(require) import "base:intrinsics" @@ -128,9 +128,9 @@ find_value :: proc(t: ^$T/Tree($Key, $Value), key: Key) -> (value: Value, ok: bo return } -// find_or_insert attempts to insert the value into the tree, and returns -// the node, a boolean indicating if the value was inserted, and the -// node allocator error if relevant. If the value is already present, the existing node is updated. +// find_or_insert attempts to insert the key-value pair into the tree, and returns +// the node, a boolean indicating if a new node was inserted, and the +// node allocator error if relevant. If the key is already present, the existing node is updated and returned. find_or_insert :: proc(t: ^$T/Tree($Key, $Value), key: Key, value: Value) -> (n: ^Node(Key, Value), inserted: bool, err: runtime.Allocator_Error) { n_ptr := &t._root for n_ptr^ != nil { @@ -141,6 +141,7 @@ find_or_insert :: proc(t: ^$T/Tree($Key, $Value), key: Key, value: Value) -> (n: case .Greater: n_ptr = &n._right case .Equal: + n.value = value return } } diff --git a/core/container/small_array/doc.odin b/core/container/small_array/doc.odin index f3e9acd57..21d000a10 100644 --- a/core/container/small_array/doc.odin +++ b/core/container/small_array/doc.odin @@ -1,8 +1,7 @@ /* -Package small_array implements a dynamic array like -interface on a stack-allocated, fixed-size array. +A dynamic array-like interface on a stack-allocated, fixed-size array. -The Small_Array type is optimal for scenarios where you need +The `Small_Array` type is optimal for scenarios where you need a container for a fixed number of elements of a specific type, with the total number known at compile time but the exact number to be used determined at runtime. @@ -33,7 +32,7 @@ Example: return } - // the Small_Array can be an ordinary parameter 'generic' over + // the `Small_Array` can be an ordinary parameter 'generic' over // the actual length to be usable with different sizes print_elements :: proc(arr: ^small_array.Small_Array($N, rune)) { for r in small_array.slice(arr) { @@ -52,4 +51,4 @@ Output: Hellope */ -package container_small_array +package container_small_array \ No newline at end of file diff --git a/core/container/topological_sort/topological_sort.odin b/core/container/topological_sort/topological_sort.odin index 10765958e..a49d04b49 100644 --- a/core/container/topological_sort/topological_sort.odin +++ b/core/container/topological_sort/topological_sort.odin @@ -1,6 +1,5 @@ -// The following is a generic O(V+E) topological sorter implementation. -// This is the fastest known method for topological sorting and Odin's -// map type is being used to accelerate lookups. +// A generic `O(V+E)` topological sorter implementation. This is the fastest known method for topological sorting. +// Odin's map type is being used to accelerate lookups. package container_topological_sort import "base:intrinsics" diff --git a/core/crypto/aead/doc.odin b/core/crypto/aead/doc.odin index 93be674a0..811dd564d 100644 --- a/core/crypto/aead/doc.odin +++ b/core/crypto/aead/doc.odin @@ -1,6 +1,5 @@ /* -package aead provides a generic interface to the supported Authenticated -Encryption with Associated Data algorithms. +A generic interface to Authenticated Encryption with Associated Data (`AEAD`) algorithms. Both a one-shot and context based interface are provided, with similar usage. If multiple messages are to be sealed/opened via the same key, @@ -54,4 +53,4 @@ Example: assert(bytes.equal(opened_pt, plaintext)) } */ -package aead +package aead \ No newline at end of file diff --git a/core/crypto/aegis/aegis.odin b/core/crypto/aegis/aegis.odin index adecce91f..41b7ad5be 100644 --- a/core/crypto/aegis/aegis.odin +++ b/core/crypto/aegis/aegis.odin @@ -1,6 +1,7 @@ /* -package aegis implements the AEGIS-128L and AEGIS-256 Authenticated -Encryption with Additional Data algorithms. +`AEGIS-128L` and `AEGIS-256` AEAD algorithms. + +Where AEAD stands for Authenticated Encryption with Additional Data. See: - [[ https://www.ietf.org/archive/id/draft-irtf-cfrg-aegis-aead-12.txt ]] diff --git a/core/crypto/aes/aes.odin b/core/crypto/aes/aes.odin index 57f49acf4..661acd88f 100644 --- a/core/crypto/aes/aes.odin +++ b/core/crypto/aes/aes.odin @@ -1,5 +1,5 @@ /* -package aes implements the AES block cipher and some common modes. +The `AES` block cipher and some common modes. See: - [[ https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.197-upd1.pdf ]] diff --git a/core/crypto/blake2b/blake2b.odin b/core/crypto/blake2b/blake2b.odin index 3b3fc6649..c2822cbaf 100644 --- a/core/crypto/blake2b/blake2b.odin +++ b/core/crypto/blake2b/blake2b.odin @@ -1,5 +1,5 @@ /* -package blake2b implements the BLAKE2b hash algorithm. +`BLAKE2b` hash algorithm. See: - [[ https://datatracker.ietf.org/doc/html/rfc7693 ]] diff --git a/core/crypto/blake2s/blake2s.odin b/core/crypto/blake2s/blake2s.odin index 9bbd44541..c2a07a6dc 100644 --- a/core/crypto/blake2s/blake2s.odin +++ b/core/crypto/blake2s/blake2s.odin @@ -1,5 +1,5 @@ /* -package blake2s implements the BLAKE2s hash algorithm. +`BLAKE2s` hash algorithm. See: - [[ https://datatracker.ietf.org/doc/html/rfc7693 ]] diff --git a/core/crypto/chacha20/chacha20.odin b/core/crypto/chacha20/chacha20.odin index e8d67eb3e..a91c6a24a 100644 --- a/core/crypto/chacha20/chacha20.odin +++ b/core/crypto/chacha20/chacha20.odin @@ -1,5 +1,5 @@ /* -package chacha20 implements the ChaCha20 and XChaCha20 stream ciphers. +`ChaCha20` and `XChaCha20` stream ciphers. See: - [[ https://datatracker.ietf.org/doc/html/rfc8439 ]] diff --git a/core/crypto/chacha20poly1305/chacha20poly1305.odin b/core/crypto/chacha20poly1305/chacha20poly1305.odin index 6706b3820..9840d357e 100644 --- a/core/crypto/chacha20poly1305/chacha20poly1305.odin +++ b/core/crypto/chacha20poly1305/chacha20poly1305.odin @@ -1,7 +1,7 @@ /* -package chacha20poly1305 implements the AEAD_CHACHA20_POLY1305 and -AEAD_XChaCha20_Poly1305 Authenticated Encryption with Additional Data -algorithms. +`AEAD_CHACHA20_POLY1305` and `AEAD_XChaCha20_Poly1305` algorithms. + +Where AEAD stands for Authenticated Encryption with Additional Data. See: - [[ https://www.rfc-editor.org/rfc/rfc8439 ]] diff --git a/core/crypto/crypto.odin b/core/crypto/crypto.odin index 323cc45d6..89e92e35f 100644 --- a/core/crypto/crypto.odin +++ b/core/crypto/crypto.odin @@ -1,7 +1,4 @@ -/* -package crypto implements a selection of cryptography algorithms and useful -helper routines. -*/ +// A selection of cryptography algorithms and useful helper routines. package crypto import "base:runtime" diff --git a/core/crypto/deoxysii/deoxysii.odin b/core/crypto/deoxysii/deoxysii.odin index cead770e2..3ebcfea30 100644 --- a/core/crypto/deoxysii/deoxysii.odin +++ b/core/crypto/deoxysii/deoxysii.odin @@ -1,6 +1,5 @@ /* -package deoxysii implements the Deoxys-II-256 Authenticated Encryption -with Additional Data algorithm. +`Deoxys-II-256` Authenticated Encryption with Additional Data (`AEAD`) algorithm. - [[ https://sites.google.com/view/deoxyscipher ]] - [[ https://thomaspeyrin.github.io/web/assets/docs/papers/Jean-etal-JoC2021.pdf ]] diff --git a/core/crypto/ed25519/ed25519.odin b/core/crypto/ed25519/ed25519.odin index deeb80685..0382a6739 100644 --- a/core/crypto/ed25519/ed25519.odin +++ b/core/crypto/ed25519/ed25519.odin @@ -1,5 +1,5 @@ /* -package ed25519 implements the Ed25519 EdDSA signature algorithm. +`Ed25519` EdDSA signature algorithm. See: - [[ https://datatracker.ietf.org/doc/html/rfc8032 ]] diff --git a/core/crypto/hash/doc.odin b/core/crypto/hash/doc.odin index 1dfd97de2..992e47e86 100644 --- a/core/crypto/hash/doc.odin +++ b/core/crypto/hash/doc.odin @@ -1,5 +1,5 @@ /* -package hash provides a generic interface to the supported hash algorithms. +A generic interface to the supported hash algorithms. A high-level convenience procedure group `hash` is provided to easily accomplish common tasks. diff --git a/core/crypto/hkdf/hkdf.odin b/core/crypto/hkdf/hkdf.odin index bffe09eff..b3a6bf303 100644 --- a/core/crypto/hkdf/hkdf.odin +++ b/core/crypto/hkdf/hkdf.odin @@ -1,6 +1,5 @@ /* -package hkdf implements the HKDF HMAC-based Extract-and-Expand Key -Derivation Function. +`HKDF` HMAC-based Extract-and-Expand Key Derivation Function. See: [[ https://www.rfc-editor.org/rfc/rfc5869 ]] */ diff --git a/core/crypto/hmac/hmac.odin b/core/crypto/hmac/hmac.odin index f74d6492f..1427baf34 100644 --- a/core/crypto/hmac/hmac.odin +++ b/core/crypto/hmac/hmac.odin @@ -1,5 +1,5 @@ /* -package hmac implements the HMAC MAC algorithm. +`HMAC` message authentication code (`MAC`) algorithm. See: - [[ https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.198-1.pdf ]] diff --git a/core/crypto/kmac/kmac.odin b/core/crypto/kmac/kmac.odin index 6f58e20a7..4ecff4f12 100644 --- a/core/crypto/kmac/kmac.odin +++ b/core/crypto/kmac/kmac.odin @@ -1,5 +1,5 @@ /* -package kmac implements the KMAC MAC algorithm. +`KMAC` message authentication code (`MAC`) algorithm. See: - [[ https://nvlpubs.nist.gov/nistpubs/specialpublications/nist.sp.800-185.pdf ]] diff --git a/core/crypto/legacy/keccak/keccak.odin b/core/crypto/legacy/keccak/keccak.odin index 40fc2729f..369eee0d9 100644 --- a/core/crypto/legacy/keccak/keccak.odin +++ b/core/crypto/legacy/keccak/keccak.odin @@ -1,5 +1,5 @@ /* -package keccak implements the Keccak hash algorithm family. +`Keccak` hash algorithm family. During the SHA-3 standardization process, the padding scheme was changed thus Keccac and SHA-3 produce different outputs. Most users should use diff --git a/core/crypto/legacy/md5/md5.odin b/core/crypto/legacy/md5/md5.odin index 050501d98..2d58837c3 100644 --- a/core/crypto/legacy/md5/md5.odin +++ b/core/crypto/legacy/md5/md5.odin @@ -1,5 +1,5 @@ /* -package md5 implements the MD5 hash algorithm. +`MD5` hash algorithm. WARNING: The MD5 algorithm is known to be insecure and should only be used for interoperating with legacy applications. diff --git a/core/crypto/legacy/sha1/sha1.odin b/core/crypto/legacy/sha1/sha1.odin index 5a2b57005..ea74997af 100644 --- a/core/crypto/legacy/sha1/sha1.odin +++ b/core/crypto/legacy/sha1/sha1.odin @@ -1,5 +1,5 @@ /* -package sha1 implements the SHA1 hash algorithm. +`SHA1` hash algorithm. WARNING: The SHA1 algorithm is known to be insecure and should only be used for interoperating with legacy applications. diff --git a/core/crypto/pbkdf2/pbkdf2.odin b/core/crypto/pbkdf2/pbkdf2.odin index 8bb5cb73e..c96855b9c 100644 --- a/core/crypto/pbkdf2/pbkdf2.odin +++ b/core/crypto/pbkdf2/pbkdf2.odin @@ -1,5 +1,5 @@ /* -package pbkdf2 implements the PBKDF2 password-based key derivation function. +`PBKDF2` password-based key derivation function. See: [[ https://www.rfc-editor.org/rfc/rfc2898 ]] */ diff --git a/core/crypto/poly1305/poly1305.odin b/core/crypto/poly1305/poly1305.odin index 3dd915da7..d90f2ad54 100644 --- a/core/crypto/poly1305/poly1305.odin +++ b/core/crypto/poly1305/poly1305.odin @@ -1,5 +1,5 @@ /* -package poly1305 implements the Poly1305 one-time MAC algorithm. +`Poly1305` one-time MAC algorithm. See: - [[ https://datatracker.ietf.org/doc/html/rfc8439 ]] diff --git a/core/crypto/ristretto255/ristretto255.odin b/core/crypto/ristretto255/ristretto255.odin index 20a002900..78bf45c28 100644 --- a/core/crypto/ristretto255/ristretto255.odin +++ b/core/crypto/ristretto255/ristretto255.odin @@ -1,5 +1,5 @@ /* -package ristretto255 implement the ristretto255 prime-order group. +Ristretto255 prime-order group. See: - [[ https://www.rfc-editor.org/rfc/rfc9496 ]] diff --git a/core/crypto/sha2/sha2.odin b/core/crypto/sha2/sha2.odin index bf9b81601..9290650e7 100644 --- a/core/crypto/sha2/sha2.odin +++ b/core/crypto/sha2/sha2.odin @@ -1,5 +1,5 @@ /* -package sha2 implements the SHA2 hash algorithm family. +`SHA2` hash algorithm family. See: - [[ https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf ]] diff --git a/core/crypto/sha3/sha3.odin b/core/crypto/sha3/sha3.odin index 3b7bdedd7..738e7be0d 100644 --- a/core/crypto/sha3/sha3.odin +++ b/core/crypto/sha3/sha3.odin @@ -1,5 +1,5 @@ /* -package sha3 implements the SHA3 hash algorithm family. +`SHA3` hash algorithm family. The SHAKE XOF can be found in crypto/shake. While discouraged if the pre-standardization Keccak algorithm is required, it can be found in diff --git a/core/crypto/shake/shake.odin b/core/crypto/shake/shake.odin index e20795b43..6fcf5dd8d 100644 --- a/core/crypto/shake/shake.odin +++ b/core/crypto/shake/shake.odin @@ -1,5 +1,5 @@ /* -package shake implements the SHAKE and cSHAKE XOF algorithm families. +`SHAKE` and `cSHAKE` XOF algorithm families. The SHA3 hash algorithm can be found in the crypto/sha3. diff --git a/core/crypto/siphash/siphash.odin b/core/crypto/siphash/siphash.odin index f9fe50cb0..a091dfd4d 100644 --- a/core/crypto/siphash/siphash.odin +++ b/core/crypto/siphash/siphash.odin @@ -1,5 +1,5 @@ /* -package siphash Implements the SipHash hashing algorithm. +`SipHash` hashing algorithm. Use the specific procedures for a certain setup. The generic procedures will default to Siphash 2-4. diff --git a/core/crypto/sm3/sm3.odin b/core/crypto/sm3/sm3.odin index 6487c5e8c..ce62cfe49 100644 --- a/core/crypto/sm3/sm3.odin +++ b/core/crypto/sm3/sm3.odin @@ -1,5 +1,5 @@ /* -package sm3 implements the SM3 hash algorithm. +`SM3` hash algorithm. See: - [[ https://datatracker.ietf.org/doc/html/draft-sca-cfrg-sm3-02 ]] diff --git a/core/crypto/tuplehash/tuplehash.odin b/core/crypto/tuplehash/tuplehash.odin index e5caaa9c9..5c8d8e39b 100644 --- a/core/crypto/tuplehash/tuplehash.odin +++ b/core/crypto/tuplehash/tuplehash.odin @@ -1,5 +1,5 @@ /* -package tuplehash implements the TupleHash and TupleHashXOF algorithms. +`TupleHash` and `TupleHashXOF` algorithms. See: - [[ https://nvlpubs.nist.gov/nistpubs/specialpublications/nist.sp.800-185.pdf ]] diff --git a/core/crypto/x25519/x25519.odin b/core/crypto/x25519/x25519.odin index 6805c3ff8..e25d1831f 100644 --- a/core/crypto/x25519/x25519.odin +++ b/core/crypto/x25519/x25519.odin @@ -1,6 +1,5 @@ /* -package x25519 implements the X25519 (aka curve25519) Elliptic-Curve -Diffie-Hellman key exchange protocol. +`X25519` (aka `curve25519`) Elliptic-Curve Diffie-Hellman key exchange protocol. See: - [[ https://www.rfc-editor.org/rfc/rfc7748 ]] diff --git a/core/crypto/x448/x448.odin b/core/crypto/x448/x448.odin index 43c5d25e0..75693e055 100644 --- a/core/crypto/x448/x448.odin +++ b/core/crypto/x448/x448.odin @@ -1,6 +1,5 @@ /* -package x448 implements the X448 (aka curve448) Elliptic-Curve -Diffie-Hellman key exchange protocol. +`X448` (aka `curve448`) Elliptic-Curve Diffie-Hellman key exchange protocol. See: - [[ https://www.rfc-editor.org/rfc/rfc7748 ]] diff --git a/core/debug/pe/pe.odin b/core/debug/pe/pe.odin index 587c01e8e..d04ed5098 100644 --- a/core/debug/pe/pe.odin +++ b/core/debug/pe/pe.odin @@ -1,3 +1,4 @@ +// A reader for the Windows `PE` executable format for debug purposes. package debug_pe PE_SIGNATURE_OFFSET_INDEX_POS :: 0x3c diff --git a/core/debug/trace/doc.odin b/core/debug/trace/doc.odin index e65548769..e5fd3f7c2 100644 --- a/core/debug/trace/doc.odin +++ b/core/debug/trace/doc.odin @@ -1,5 +1,5 @@ /* -A debug stack trace library. Only works when debug symbols are enabled `-debug`. +Stack trace library. Only works when debug symbols are enabled using `-debug`. Example: import "base:runtime" diff --git a/core/dynlib/doc.odin b/core/dynlib/doc.odin index 487fcb715..f727a299c 100644 --- a/core/dynlib/doc.odin +++ b/core/dynlib/doc.odin @@ -1,5 +1,5 @@ /* -Package `core:dynlib` implements loading of shared libraries/DLLs and their symbols. +Cross-platform loading of shared libraries/DLLs and their symbols. The behaviour of dynamically loaded libraries is specific to the target platform of the program. For in depth detail on the underlying behaviour please refer to your target platform's documentation. diff --git a/core/dynlib/example/example.odin b/core/dynlib/example/example.odin index 78fb5a98c..84ee103e3 100644 --- a/core/dynlib/example/example.odin +++ b/core/dynlib/example/example.odin @@ -44,4 +44,4 @@ main :: proc() { fmt.println("84 - 13 =", sym.sub(84, 13)) fmt.println("hellope =", sym.hellope^) } -} +} \ No newline at end of file diff --git a/core/encoding/base32/base32.odin b/core/encoding/base32/base32.odin index 2267a872b..34de2ff53 100644 --- a/core/encoding/base32/base32.odin +++ b/core/encoding/base32/base32.odin @@ -1,19 +1,20 @@ -// Base32 encoding/decoding implementation as specified in RFC 4648. -// [[ More; https://www.rfc-editor.org/rfc/rfc4648.html ]] +/* +`Base32` encoding and decoding, as specified in [[ RFC 4648; https://www.rfc-editor.org/rfc/rfc4648.html ]]. + +A secondary param can be used to supply a custom alphabet to `encode` and a matching decoding table to `decode`. + +If none is supplied it just uses the standard Base32 alphabet. +In case your specific version does not use padding, you may +truncate it from the encoded output. + +Error represents errors that can occur during base32 decoding operations. +As per RFC 4648: +- Section 3.3: Invalid character handling +- Section 3.2: Padding requirements +- Section 6: Base32 encoding specifics (including block size requirements) +*/ package encoding_base32 -// @note(zh): Encoding utility for Base32 -// A secondary param can be used to supply a custom alphabet to -// @link(encode) and a matching decoding table to @link(decode). -// If none is supplied it just uses the standard Base32 alphabet. -// In case your specific version does not use padding, you may -// truncate it from the encoded output. - -// Error represents errors that can occur during base32 decoding operations. -// As per RFC 4648: -// - Section 3.3: Invalid character handling -// - Section 3.2: Padding requirements -// - Section 6: Base32 encoding specifics (including block size requirements) Error :: enum { None, Invalid_Character, // Input contains characters outside the specified alphabet diff --git a/core/encoding/base64/base64.odin b/core/encoding/base64/base64.odin index 1013a7d0b..2cd7227b5 100644 --- a/core/encoding/base64/base64.odin +++ b/core/encoding/base64/base64.odin @@ -1,16 +1,18 @@ +/* +`Base64` encoding and decoding. + +A secondary param can be used to supply a custom alphabet to `encode` and a matching decoding table to `decode`. + +If none is supplied it just uses the standard Base64 alphabet. +In case your specific version does not use padding, you may +truncate it from the encoded output. +*/ package encoding_base64 import "core:io" import "core:mem" import "core:strings" -// @note(zh): Encoding utility for Base64 -// A secondary param can be used to supply a custom alphabet to -// @link(encode) and a matching decoding table to @link(decode). -// If none is supplied it just uses the standard Base64 alphabet. -// Incase your specific version does not use padding, you may -// truncate it from the encoded output. - ENC_TABLE := [64]byte { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', diff --git a/core/encoding/cbor/doc.odin b/core/encoding/cbor/doc.odin index b3fa36130..370c5aaa9 100644 --- a/core/encoding/cbor/doc.odin +++ b/core/encoding/cbor/doc.odin @@ -1,5 +1,6 @@ /* -Package cbor encodes, decodes, marshals and unmarshals types from/into RCF 8949 compatible CBOR binary. +Encodes and decodes types from/into [[ RCF 8949; https://www.rfc-editor.org/rfc/rfc8949.html ]] compatible `CBOR` binary. + Also provided are conversion to and from JSON and the CBOR diagnostic format. **Allocations:** @@ -165,5 +166,4 @@ Output: "str": "Hello, World!" } */ -package encoding_cbor - +package encoding_cbor \ No newline at end of file diff --git a/core/encoding/csv/doc.odin b/core/encoding/csv/doc.odin index 7abe2be49..50b8e3d1a 100644 --- a/core/encoding/csv/doc.odin +++ b/core/encoding/csv/doc.odin @@ -1,6 +1,5 @@ /* -package csv reads and writes comma-separated values (CSV) files. -This package supports the format described in [[ RFC 4180; https://tools.ietf.org/html/rfc4180.html ]] +Reader and writer for comma-separated values (`CSV`) files, per [[ RFC 4180 ; https://tools.ietf.org/html/rfc4180.html ]]. Example: package main diff --git a/core/encoding/endian/doc.odin b/core/encoding/endian/doc.odin index 0b43e3097..7cc9da1b7 100644 --- a/core/encoding/endian/doc.odin +++ b/core/encoding/endian/doc.odin @@ -1,6 +1,5 @@ /* - Package endian implements a simple translation between bytes and numbers with - specific endian encodings. + A simple translation between bytes and numbers with specific endian encodings. Example: buf: [100]u8 diff --git a/core/encoding/entity/entity.odin b/core/encoding/entity/entity.odin index cb8fa8611..28ff58170 100644 --- a/core/encoding/entity/entity.odin +++ b/core/encoding/entity/entity.odin @@ -1,13 +1,5 @@ /* - Copyright 2021 Jeroen van Rijn . - Made available under Odin's BSD-3 license. - - List of contributors: - Jeroen van Rijn: Initial implementation. -*/ - -/* - A unicode entity encoder/decoder. + Encode and decode `rune`s to/from a Unicode `&entity;`. This code has several procedures to map unicode runes to/from different textual encodings. - SGML/XML/HTML entity @@ -21,6 +13,14 @@ */ package encoding_unicode_entity +/* + Copyright 2021 Jeroen van Rijn . + Made available under Odin's BSD-3 license. + + List of contributors: + Jeroen van Rijn: Initial implementation. +*/ + import "core:unicode/utf8" import "core:unicode" import "core:strings" diff --git a/core/encoding/hex/hex.odin b/core/encoding/hex/hex.odin index c1753003e..318e52ace 100644 --- a/core/encoding/hex/hex.odin +++ b/core/encoding/hex/hex.odin @@ -1,3 +1,4 @@ +// Encoding and decoding of hex-encoded binary, e.g. `0x23` -> `#`. package encoding_hex import "core:io" diff --git a/core/encoding/hxa/doc.odin b/core/encoding/hxa/doc.odin index b696bef7e..902428668 100644 --- a/core/encoding/hxa/doc.odin +++ b/core/encoding/hxa/doc.odin @@ -1,5 +1,6 @@ /* -Implementation of the HxA 3D asset format +Eskil Steenberg's `HxA` 3D asset interchange format. + HxA is a interchangeable graphics asset format. Designed by Eskil Steenberg. @quelsolaar / eskil 'at' obsession 'dot' se / www.quelsolaar.com diff --git a/core/encoding/ini/ini.odin b/core/encoding/ini/ini.odin index c32b1deb5..a119b0f2e 100644 --- a/core/encoding/ini/ini.odin +++ b/core/encoding/ini/ini.odin @@ -1,3 +1,4 @@ +// Reader and writer for a variant of the `.ini` file format with `key = value` entries in `[sections]`. package encoding_ini import "base:runtime" diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin index cdb00a354..e563c326a 100644 --- a/core/encoding/json/marshal.odin +++ b/core/encoding/json/marshal.odin @@ -176,7 +176,11 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: return .Unsupported_Type case runtime.Type_Info_Pointer: - return .Unsupported_Type + if v.id == typeid_of(Null) { + io.write_string(w, "null") or_return + } else { + return .Unsupported_Type + } case runtime.Type_Info_Multi_Pointer: return .Unsupported_Type diff --git a/core/encoding/json/types.odin b/core/encoding/json/types.odin index 41eb21377..1da17a0db 100644 --- a/core/encoding/json/types.odin +++ b/core/encoding/json/types.odin @@ -1,14 +1,13 @@ -package encoding_json - -import "core:strings" - /* - JSON +Encoding and decoding JSON in strict `JSON`, [[ JSON5 ; https://json5.org/ ]] and [[ BitSquid ; https://bitsquid.blogspot.com/2009/10/simplified-json-notation.html ]] variants. + +Using one of these `Specification`s. + JSON strict JSON - JSON5 + JSON5 pure superset of JSON and valid JavaScript https://json5.org/ - + * Object keys may be an ECMAScript 5.1 IdentifierName. * Objects may have a single trailing comma. * Arrays may have a single trailing comma. @@ -21,17 +20,21 @@ import "core:strings" * Numbers may begin with an explicit plus sign. * Single and multi-line comments are allowed. * Additional white space characters are allowed. - + MJSON pure superset of JSON5, may not be valid JavaScript https://bitsquid.blogspot.com/2009/10/simplified-json-notation.html - + * All the same features as JSON5 plus extras. * Assume an object definition at the root level (no need to surround entire file with { } ). * Commas are optional, using comma insertion rules with newlines. * Quotes around object keys are optional if the keys are valid identifiers. * : can be replaced with = */ +package encoding_json + +import "core:strings" + Specification :: enum { JSON, JSON5, // https://json5.org/ diff --git a/core/encoding/uuid/doc.odin b/core/encoding/uuid/doc.odin index f910c33d8..a5f01ca7c 100644 --- a/core/encoding/uuid/doc.odin +++ b/core/encoding/uuid/doc.odin @@ -1,6 +1,5 @@ /* -package uuid implements Universally Unique Identifiers according to the -standard originally outlined in RFC 4122 with additions from RFC 9562. +Universally Unique Identifiers (`UUID`) according to [[ RFC 4122 ; https://tools.ietf.org/html/rfc4122.html ]], with additions from [[ RFC 9562 ; https://tools.ietf.org/html/rfc9562.html ]]. The UUIDs are textually represented and read in the following string format: `00000000-0000-v000-V000-000000000000` diff --git a/core/encoding/uuid/legacy/legacy.odin b/core/encoding/uuid/legacy/legacy.odin index d5f3df617..fe5c88e23 100644 --- a/core/encoding/uuid/legacy/legacy.odin +++ b/core/encoding/uuid/legacy/legacy.odin @@ -1,7 +1,6 @@ /* -package uuid/legacy implements versions 3 and 5 of UUID generation, both of -which are using hashing algorithms (MD5 and SHA1, respectively) that are known -these days to no longer be secure. +Versions 3 and 5 of `UUID` generation, both of which use legacy (`MD5` + `SHA1`) hashes. +Those are known these days to no longer be secure. */ package uuid_legacy diff --git a/core/encoding/varint/doc.odin b/core/encoding/varint/doc.odin index a00cfed15..e17faec49 100644 --- a/core/encoding/varint/doc.odin +++ b/core/encoding/varint/doc.odin @@ -1,7 +1,5 @@ /* -Implementation of the LEB128 variable integer encoding as used by DWARF encoding and DEX files, among others. - -Author of this Odin package: Jeroen van Rijn +`LEB128` variable integer encoding and decoding, as used by `DWARF` & `DEX` files. Example: package main @@ -24,4 +22,4 @@ Example: fmt.printf("Decoded as %v, using %v byte%v\n", decoded_val, decode_size, "" if decode_size == 1 else "s") } */ -package encoding_varint +package encoding_varint \ No newline at end of file diff --git a/core/encoding/varint/leb128.odin b/core/encoding/varint/leb128.odin index 606c57ba7..876a1ba76 100644 --- a/core/encoding/varint/leb128.odin +++ b/core/encoding/varint/leb128.odin @@ -1,3 +1,5 @@ +package encoding_varint + /* Copyright 2022 Jeroen van Rijn . Made available under Odin's BSD-3 license. @@ -6,8 +8,6 @@ Jeroen van Rijn: Initial implementation. */ -package encoding_varint - // In theory we should use the bigint package. In practice, varints bigger than this indicate a corrupted file. // Instead we'll set limits on the values we'll encode/decode // 18 * 7 bits = 126, which means that a possible 19th byte may at most be `0b0000_0011`. diff --git a/core/encoding/xml/doc.odin b/core/encoding/xml/doc.odin index 10d9f78be..9030cd400 100644 --- a/core/encoding/xml/doc.odin +++ b/core/encoding/xml/doc.odin @@ -1,7 +1,7 @@ /* -XML 1.0 / 1.1 parser +A parser for a useful subset of the `XML` specification. -A from-scratch XML implementation, loosely modelled on the [[ spec; https://www.w3.org/TR/2006/REC-xml11-20060816 ]]. +A from-scratch `XML` implementation, loosely modelled on the [[ spec; https://www.w3.org/TR/2006/REC-xml11-20060816 ]]. Features: - Supports enough of the XML 1.0/1.1 spec to handle the 99.9% of XML documents in common current usage. @@ -11,8 +11,8 @@ Caveats: - We do NOT support HTML in this package, as that may or may not be valid XML. If it works, great. If it doesn't, that's not considered a bug. -- We do NOT support UTF-16. If you have a UTF-16 XML file, please convert it to UTF-8 first. Also, our condolences. -- <[!ELEMENT and <[!ATTLIST are not supported, and will be either ignored or return an error depending on the parser options. +- We do NOT support `UTF-16`. If you have a `UTF-16` XML file, please convert it to `UTF-8` first. Also, our condolences. +- `<[!ELEMENT` and `<[!ATTLIST` are not supported, and will be either ignored or return an error depending on the parser options. MAYBE: - XML writer? diff --git a/core/encoding/xml/xml_reader.odin b/core/encoding/xml/xml_reader.odin index 707d2b3f3..621c9c2d0 100644 --- a/core/encoding/xml/xml_reader.odin +++ b/core/encoding/xml/xml_reader.odin @@ -1,4 +1,7 @@ +package encoding_xml /* + An XML 1.0 / 1.1 parser + 2021-2022 Jeroen van Rijn . available under Odin's BSD-3 license. @@ -6,9 +9,6 @@ - Jeroen van Rijn: Initial implementation. */ -package encoding_xml -// An XML 1.0 / 1.1 parser - import "core:bytes" import "core:encoding/entity" import "base:intrinsics" diff --git a/core/flags/doc.odin b/core/flags/doc.odin index 440acd52c..183b86f41 100644 --- a/core/flags/doc.odin +++ b/core/flags/doc.odin @@ -1,5 +1,5 @@ /* -package flags implements a command-line argument parser. +Command-line argument parser. It works by using Odin's run-time type information to determine where and how to store data on a struct provided by the program. Type conversion is handled diff --git a/core/fmt/doc.odin b/core/fmt/doc.odin index eeebd33f7..c0d6d5289 100644 --- a/core/fmt/doc.odin +++ b/core/fmt/doc.odin @@ -1,5 +1,5 @@ /* -package fmt implements formatted I/O with procedures similar to C's printf and Python's format. +Formatted `I/O` with procedures similar to `C`'s printf and `Python`'s format. The format 'verbs' are derived from C's but simpler. Printing diff --git a/core/hash/doc.odin b/core/hash/doc.odin new file mode 100644 index 000000000..d7531a4c2 --- /dev/null +++ b/core/hash/doc.odin @@ -0,0 +1,2 @@ +// `crc32`, `crc64`, `adler32`, `djb`, `fnv`, `jenkins`, `murmur` and other hashes. +package hash \ No newline at end of file diff --git a/core/hash/xxhash/common.odin b/core/hash/xxhash/common.odin index 636393b52..ce98f21f9 100644 --- a/core/hash/xxhash/common.odin +++ b/core/hash/xxhash/common.odin @@ -1,3 +1,8 @@ +// Yann Collet's `xxhash`. +// +// [[ xxhash Fast Hash Algorithm; https://cyan4973.github.io/xxHash/ ]] +package xxhash + /* Copyright 2021 Jeroen van Rijn . @@ -7,9 +12,6 @@ Jeroen van Rijn: Initial implementation. */ -// An implementation of Yann Collet's [[ xxhash Fast Hash Algorithm; https://cyan4973.github.io/xxHash/ ]]. -package xxhash - import "base:intrinsics" import "base:runtime" diff --git a/core/hash/xxhash/streaming.odin b/core/hash/xxhash/streaming.odin index f77edf3e9..699a089c9 100644 --- a/core/hash/xxhash/streaming.odin +++ b/core/hash/xxhash/streaming.odin @@ -1,3 +1,5 @@ +package xxhash + /* An implementation of Yann Collet's [xxhash Fast Hash Algorithm](https://cyan4973.github.io/xxHash/). Copyright 2021 Jeroen van Rijn . @@ -8,8 +10,6 @@ Jeroen van Rijn: Initial implementation. */ -package xxhash - import "core:mem" import "base:intrinsics" diff --git a/core/hash/xxhash/xxhash_3.odin b/core/hash/xxhash/xxhash_3.odin index fe92f16d9..20dd8e596 100644 --- a/core/hash/xxhash/xxhash_3.odin +++ b/core/hash/xxhash/xxhash_3.odin @@ -1,3 +1,5 @@ +package xxhash + /* An implementation of Yann Collet's [xxhash Fast Hash Algorithm](https://cyan4973.github.io/xxHash/). Copyright 2021 Jeroen van Rijn . @@ -8,8 +10,6 @@ Jeroen van Rijn: Initial implementation. */ -package xxhash - import "base:intrinsics" /* diff --git a/core/hash/xxhash/xxhash_32.odin b/core/hash/xxhash/xxhash_32.odin index 28cd4e177..8e53d564b 100644 --- a/core/hash/xxhash/xxhash_32.odin +++ b/core/hash/xxhash/xxhash_32.odin @@ -1,3 +1,5 @@ +package xxhash + /* An implementation of Yann Collet's [xxhash Fast Hash Algorithm](https://cyan4973.github.io/xxHash/). Copyright 2021 Jeroen van Rijn . @@ -8,8 +10,6 @@ Jeroen van Rijn: Initial implementation. */ -package xxhash - import "base:intrinsics" /* diff --git a/core/hash/xxhash/xxhash_64.odin b/core/hash/xxhash/xxhash_64.odin index 87e8916d6..16a70bd2e 100644 --- a/core/hash/xxhash/xxhash_64.odin +++ b/core/hash/xxhash/xxhash_64.odin @@ -1,3 +1,5 @@ +package xxhash + /* An implementation of Yann Collet's [xxhash Fast Hash Algorithm](https://cyan4973.github.io/xxHash/). Copyright 2021 Jeroen van Rijn . @@ -8,8 +10,6 @@ Jeroen van Rijn: Initial implementation. */ -package xxhash - import "base:intrinsics" /* diff --git a/core/image/bmp/bmp.odin b/core/image/bmp/bmp.odin index d5a094e83..efb0dd7d9 100644 --- a/core/image/bmp/bmp.odin +++ b/core/image/bmp/bmp.odin @@ -1,4 +1,4 @@ -// package bmp implements a Microsoft BMP image reader +// Reader and writer for Microsoft `BMP` images. package core_image_bmp import "core:image" diff --git a/core/image/common.odin b/core/image/common.odin index 4014e2ae6..11212953e 100644 --- a/core/image/common.odin +++ b/core/image/common.odin @@ -1,3 +1,5 @@ +package image + /* Copyright 2021 Jeroen van Rijn . Made available under Odin's BSD-3 license. @@ -7,9 +9,6 @@ Ginger Bill: Cosmetic changes. */ -// package image implements a general 2D image library to be used with other image related packages -package image - import "core:bytes" import "core:mem" import "core:io" diff --git a/core/image/doc.odin b/core/image/doc.odin new file mode 100644 index 000000000..1e44cca59 --- /dev/null +++ b/core/image/doc.odin @@ -0,0 +1,2 @@ +// General 2D image types and procedures to be used with other image related packages. +package image \ No newline at end of file diff --git a/core/image/jpeg/jpeg.odin b/core/image/jpeg/jpeg.odin index 818bd13d5..241066273 100644 --- a/core/image/jpeg/jpeg.odin +++ b/core/image/jpeg/jpeg.odin @@ -1,3 +1,4 @@ +// Reader for baseline `JPEG` images. package jpeg import "core:bytes" diff --git a/core/image/netpbm/doc.odin b/core/image/netpbm/doc.odin index 7106e023e..bac893b0f 100644 --- a/core/image/netpbm/doc.odin +++ b/core/image/netpbm/doc.odin @@ -1,4 +1,6 @@ /* +Readers and writers for `PBM`, `PGM`, `PPM`, `PAM` and `PFM` images. + Formats: PBM (P1, P4): Portable Bit Map, stores black and white images (1 channel) diff --git a/core/image/png/doc.odin b/core/image/png/doc.odin index 623c13077..034a6775f 100644 --- a/core/image/png/doc.odin +++ b/core/image/png/doc.odin @@ -1,5 +1,5 @@ /* -package png implements a PNG image reader +Reader for `PNG` images. The PNG specification is at [[ https://www.w3.org/TR/PNG/ ]]. diff --git a/core/image/png/helpers.odin b/core/image/png/helpers.odin index 97e70226c..527ac486c 100644 --- a/core/image/png/helpers.odin +++ b/core/image/png/helpers.odin @@ -1,3 +1,5 @@ +package png + /* Copyright 2021 Jeroen van Rijn . Made available under Odin's BSD-2 license. @@ -9,8 +11,6 @@ These are a few useful utility functions to work with PNG images. */ -package png - import "core:image" import "core:compress/zlib" import coretime "core:time" diff --git a/core/image/png/png.odin b/core/image/png/png.odin index 3516fc8d3..4e67700f2 100644 --- a/core/image/png/png.odin +++ b/core/image/png/png.odin @@ -1,3 +1,6 @@ +#+vet !using-stmt +package png + /* Copyright 2021 Jeroen van Rijn . Made available under Odin's BSD-3 license. @@ -7,10 +10,6 @@ Ginger Bill: Cosmetic changes. */ - -#+vet !using-stmt -package png - import "core:compress" import "core:compress/zlib" import "core:image" diff --git a/core/image/qoi/qoi.odin b/core/image/qoi/qoi.odin index ded8d7971..a2b38a7a6 100644 --- a/core/image/qoi/qoi.odin +++ b/core/image/qoi/qoi.odin @@ -1,3 +1,8 @@ +// Reader and writer for `QOI` images. +// +// The QOI specification is at [[ https://qoiformat.org ]]. +package qoi + /* Copyright 2022 Jeroen van Rijn . Made available under Odin's BSD-3 license. @@ -6,12 +11,6 @@ Jeroen van Rijn: Initial implementation. */ - -// package qoi implements a QOI image reader -// -// The QOI specification is at [[ https://qoiformat.org ]]. -package qoi - import "core:image" import "core:compress" import "core:bytes" diff --git a/core/image/tga/tga.odin b/core/image/tga/tga.odin index 5fda803c5..ad939e7ff 100644 --- a/core/image/tga/tga.odin +++ b/core/image/tga/tga.odin @@ -1,3 +1,6 @@ +// Reader and writer for 8-bit RGB and RGBA `TGA` images. +package tga + /* Copyright 2022 Jeroen van Rijn . Made available under Odin's BSD-3 license. @@ -7,10 +10,6 @@ Benoit Jacquier: tga loader */ - -// package tga implements a TGA image writer for 8-bit RGB and RGBA images. -package tga - import "core:mem" import "core:image" import "core:bytes" diff --git a/core/io/io.odin b/core/io/io.odin index c4eb6a073..2c9b4379f 100644 --- a/core/io/io.odin +++ b/core/io/io.odin @@ -1,4 +1,4 @@ -// package io provides basic interfaces for generic data stream primitives. +// Basic interfaces for generic data stream primitives. // The purpose of this package is wrap existing data structures and their // operations into an abstracted stream interface. package io diff --git a/core/log/log.odin b/core/log/log.odin index b2efe8beb..4209a2850 100644 --- a/core/log/log.odin +++ b/core/log/log.odin @@ -1,3 +1,4 @@ +// Implementations of the `context.Logger` interface. package log import "base:runtime" diff --git a/core/log/log_allocator.odin b/core/log/log_allocator.odin index 16f1abe31..3ef5b4e25 100644 --- a/core/log/log_allocator.odin +++ b/core/log/log_allocator.odin @@ -2,26 +2,30 @@ package log import "base:runtime" import "core:fmt" +import "core:sync" Log_Allocator_Format :: enum { Bytes, // Actual number of bytes. Human, // Bytes in human units like bytes, kibibytes, etc. as appropriate. } + +// Log_Allocator is an allocator which calls `context.logger` on each of its allocations operations. +// The format can be changed by setting the `size_fmt: Log_Allocator_Format` field to either `Bytes` or `Human`. Log_Allocator :: struct { allocator: runtime.Allocator, level: Level, prefix: string, - locked: bool, + lock: sync.Mutex, size_fmt: Log_Allocator_Format, } log_allocator_init :: proc(la: ^Log_Allocator, level: Level, size_fmt := Log_Allocator_Format.Bytes, allocator := context.allocator, prefix := "") { la.allocator = allocator - la.level = level - la.prefix = prefix - la.locked = false + la.level = level + la.prefix = prefix + la.lock = {} la.size_fmt = size_fmt } @@ -46,83 +50,78 @@ log_allocator_proc :: proc(allocator_data: rawptr, mode: runtime.Allocator_Mode, buf: [256]byte = --- - if !la.locked { - la.locked = true - defer la.locked = false + sync.lock(&la.lock) + switch mode { + case .Alloc: + format: string + switch la.size_fmt { + case .Bytes: format = "%s%s>>> ALLOCATOR(mode=.Alloc, size=%d, alignment=%d)" + case .Human: format = "%s%s>>> ALLOCATOR(mode=.Alloc, size=%m, alignment=%d)" + } + str := fmt.bprintf(buf[:], format, la.prefix, padding, size, alignment) + context.logger.procedure(context.logger.data, la.level, str, context.logger.options, location) - switch mode { - case .Alloc: + case .Alloc_Non_Zeroed: + format: string + switch la.size_fmt { + case .Bytes: format = "%s%s>>> ALLOCATOR(mode=.Alloc_Non_Zeroed, size=%d, alignment=%d)" + case .Human: format = "%s%s>>> ALLOCATOR(mode=.Alloc_Non_Zeroed, size=%m, alignment=%d)" + } + str := fmt.bprintf(buf[:], format, la.prefix, padding, size, alignment) + context.logger.procedure(context.logger.data, la.level, str, context.logger.options, location) + + case .Free: + if old_size != 0 { format: string switch la.size_fmt { - case .Bytes: format = "%s%s>>> ALLOCATOR(mode=.Alloc, size=%d, alignment=%d)" - case .Human: format = "%s%s>>> ALLOCATOR(mode=.Alloc, size=%m, alignment=%d)" + case .Bytes: format = "%s%s<<< ALLOCATOR(mode=.Free, ptr=%p, size=%d)" + case .Human: format = "%s%s<<< ALLOCATOR(mode=.Free, ptr=%p, size=%m)" } - str := fmt.bprintf(buf[:], format, la.prefix, padding, size, alignment) + str := fmt.bprintf(buf[:], format, la.prefix, padding, old_memory, old_size) context.logger.procedure(context.logger.data, la.level, str, context.logger.options, location) - - case .Alloc_Non_Zeroed: - format: string - switch la.size_fmt { - case .Bytes: format = "%s%s>>> ALLOCATOR(mode=.Alloc_Non_Zeroed, size=%d, alignment=%d)" - case .Human: format = "%s%s>>> ALLOCATOR(mode=.Alloc_Non_Zeroed, size=%m, alignment=%d)" - } - str := fmt.bprintf(buf[:], format, la.prefix, padding, size, alignment) - context.logger.procedure(context.logger.data, la.level, str, context.logger.options, location) - - case .Free: - if old_size != 0 { - format: string - switch la.size_fmt { - case .Bytes: format = "%s%s<<< ALLOCATOR(mode=.Free, ptr=%p, size=%d)" - case .Human: format = "%s%s<<< ALLOCATOR(mode=.Free, ptr=%p, size=%m)" - } - str := fmt.bprintf(buf[:], format, la.prefix, padding, old_memory, old_size) - context.logger.procedure(context.logger.data, la.level, str, context.logger.options, location) - } else { - str := fmt.bprintf(buf[:], "%s%s<<< ALLOCATOR(mode=.Free, ptr=%p)", la.prefix, padding, old_memory) - context.logger.procedure(context.logger.data, la.level, str, context.logger.options, location) - } - - case .Free_All: - str := fmt.bprintf(buf[:], "%s%s<<< ALLOCATOR(mode=.Free_All)", la.prefix, padding) - context.logger.procedure(context.logger.data, la.level, str, context.logger.options, location) - - case .Resize: - format: string - switch la.size_fmt { - case .Bytes: format = "%s%s>>> ALLOCATOR(mode=.Resize, ptr=%p, old_size=%d, size=%d, alignment=%d)" - case .Human: format = "%s%s>>> ALLOCATOR(mode=.Resize, ptr=%p, old_size=%m, size=%m, alignment=%d)" - } - str := fmt.bprintf(buf[:], format, la.prefix, padding, old_memory, old_size, size, alignment) - context.logger.procedure(context.logger.data, la.level, str, context.logger.options, location) - - case .Resize_Non_Zeroed: - format: string - switch la.size_fmt { - case .Bytes: format = "%s%s>>> ALLOCATOR(mode=.Resize_Non_Zeroed, ptr=%p, old_size=%d, size=%d, alignment=%d)" - case .Human: format = "%s%s>>> ALLOCATOR(mode=.Resize_Non_Zeroed, ptr=%p, old_size=%m, size=%m, alignment=%d)" - } - str := fmt.bprintf(buf[:], format, la.prefix, padding, old_memory, old_size, size, alignment) - context.logger.procedure(context.logger.data, la.level, str, context.logger.options, location) - - case .Query_Features: - str := fmt.bprintf(buf[:], "%s%sALLOCATOR(mode=.Query_Features)", la.prefix, padding) - context.logger.procedure(context.logger.data, la.level, str, context.logger.options, location) - - case .Query_Info: - str := fmt.bprintf(buf[:], "%s%sALLOCATOR(mode=.Query_Info)", la.prefix, padding) + } else { + str := fmt.bprintf(buf[:], "%s%s<<< ALLOCATOR(mode=.Free, ptr=%p)", la.prefix, padding, old_memory) context.logger.procedure(context.logger.data, la.level, str, context.logger.options, location) } + + case .Free_All: + str := fmt.bprintf(buf[:], "%s%s<<< ALLOCATOR(mode=.Free_All)", la.prefix, padding) + context.logger.procedure(context.logger.data, la.level, str, context.logger.options, location) + + case .Resize: + format: string + switch la.size_fmt { + case .Bytes: format = "%s%s>>> ALLOCATOR(mode=.Resize, ptr=%p, old_size=%d, size=%d, alignment=%d)" + case .Human: format = "%s%s>>> ALLOCATOR(mode=.Resize, ptr=%p, old_size=%m, size=%m, alignment=%d)" + } + str := fmt.bprintf(buf[:], format, la.prefix, padding, old_memory, old_size, size, alignment) + context.logger.procedure(context.logger.data, la.level, str, context.logger.options, location) + + case .Resize_Non_Zeroed: + format: string + switch la.size_fmt { + case .Bytes: format = "%s%s>>> ALLOCATOR(mode=.Resize_Non_Zeroed, ptr=%p, old_size=%d, size=%d, alignment=%d)" + case .Human: format = "%s%s>>> ALLOCATOR(mode=.Resize_Non_Zeroed, ptr=%p, old_size=%m, size=%m, alignment=%d)" + } + str := fmt.bprintf(buf[:], format, la.prefix, padding, old_memory, old_size, size, alignment) + context.logger.procedure(context.logger.data, la.level, str, context.logger.options, location) + + case .Query_Features: + str := fmt.bprintf(buf[:], "%s%sALLOCATOR(mode=.Query_Features)", la.prefix, padding) + context.logger.procedure(context.logger.data, la.level, str, context.logger.options, location) + + case .Query_Info: + str := fmt.bprintf(buf[:], "%s%sALLOCATOR(mode=.Query_Info)", la.prefix, padding) + context.logger.procedure(context.logger.data, la.level, str, context.logger.options, location) } + sync.unlock(&la.lock) data, err := la.allocator.procedure(la.allocator.data, mode, size, alignment, old_memory, old_size, location) - if !la.locked { - la.locked = true - defer la.locked = false - if err != nil { - str := fmt.bprintf(buf[:], "%s%sALLOCATOR ERROR=%v", la.prefix, padding, err) - context.logger.procedure(context.logger.data, la.level, str, context.logger.options, location) - } + if err != nil { + sync.lock(&la.lock) + str := fmt.bprintf(buf[:], "%s%sALLOCATOR ERROR=%v", la.prefix, padding, err) + context.logger.procedure(context.logger.data, la.level, str, context.logger.options, location) + sync.unlock(&la.lock) } return data, err } diff --git a/core/math/big/api.odin b/core/math/big/api.odin index 70e134a90..668afa534 100644 --- a/core/math/big/api.odin +++ b/core/math/big/api.odin @@ -1,3 +1,5 @@ +package math_big + /* Copyright 2021 Jeroen van Rijn . Made available under Odin's BSD-3 license. @@ -5,8 +7,6 @@ This file collects public proc maps and their aliases. */ - -package math_big /* === === === === === === === === === === === === === === === === === === === === === === === === diff --git a/core/math/big/common.odin b/core/math/big/common.odin index 22655293f..66a29e715 100644 --- a/core/math/big/common.odin +++ b/core/math/big/common.odin @@ -1,11 +1,10 @@ +package math_big + /* Copyright 2021 Jeroen van Rijn . Made available under Odin's BSD-3 license. */ - -package math_big - import "base:intrinsics" /* diff --git a/core/math/big/doc.odin b/core/math/big/doc.odin deleted file mode 100644 index 0f9b88d01..000000000 --- a/core/math/big/doc.odin +++ /dev/null @@ -1,6 +0,0 @@ -/* -A BigInt implementation in Odin. -For the theoretical underpinnings, see Knuth's The Art of Computer Programming, Volume 2, section 4.3. -The code started out as an idiomatic source port of libTomMath, which is in the public domain, with thanks. -*/ -package math_big diff --git a/core/math/big/helpers.odin b/core/math/big/helpers.odin index 9ee35c45a..e8dc792c6 100644 --- a/core/math/big/helpers.odin +++ b/core/math/big/helpers.odin @@ -1,11 +1,10 @@ +package math_big + /* Copyright 2021 Jeroen van Rijn . Made available under Odin's BSD-3 license. */ - -package math_big - import "base:intrinsics" import "base:runtime" import rnd "core:math/rand" diff --git a/core/math/big/internal.odin b/core/math/big/internal.odin index e0bc1ae06..4b76f3b2e 100644 --- a/core/math/big/internal.odin +++ b/core/math/big/internal.odin @@ -1,3 +1,5 @@ +package math_big + /* Copyright 2021 Jeroen van Rijn . Made available under Odin's BSD-3 license. @@ -25,8 +27,6 @@ TODO: Handle +/- Infinity and NaN. */ -package math_big - import "base:builtin" import "base:intrinsics" import "core:mem" diff --git a/core/math/big/logical.odin b/core/math/big/logical.odin index 00134228b..df7744a9a 100644 --- a/core/math/big/logical.odin +++ b/core/math/big/logical.odin @@ -1,3 +1,5 @@ +package math_big + /* Copyright 2021 Jeroen van Rijn . Made available under Odin's BSD-3 license. @@ -9,9 +11,6 @@ This file contains logical operations like `and`, `or` and `xor`. */ - -package math_big - /* The `and`, `or` and `xor` binops differ in two lines only. We could handle those with a switch, but that adds overhead. diff --git a/core/math/big/prime.odin b/core/math/big/prime.odin index 832c75119..8efa97174 100644 --- a/core/math/big/prime.odin +++ b/core/math/big/prime.odin @@ -1,3 +1,5 @@ +package math_big + /* Copyright 2021 Jeroen van Rijn . Made available under Odin's BSD-3 license. @@ -9,9 +11,6 @@ This file contains prime finding operations. */ - -package math_big - /* Determines if an Integer is divisible by one of the _PRIME_TABLE primes. Returns true if it is, false if not. diff --git a/core/math/big/private.odin b/core/math/big/private.odin index c42bad0c6..692b1d088 100644 --- a/core/math/big/private.odin +++ b/core/math/big/private.odin @@ -1,3 +1,5 @@ +package math_big + /* Copyright 2021 Jeroen van Rijn . Made available under Odin's BSD-3 license. @@ -16,9 +18,6 @@ These aren't exported for the same reasons. */ - -package math_big - import "base:intrinsics" import "core:mem" diff --git a/core/math/big/public.odin b/core/math/big/public.odin index 070c45283..dfefbc91a 100644 --- a/core/math/big/public.odin +++ b/core/math/big/public.odin @@ -1,3 +1,6 @@ +// Arbitrary precision integers and rationals. +package math_big + /* Copyright 2021 Jeroen van Rijn . Made available under Odin's BSD-3 license. @@ -9,9 +12,6 @@ This file contains basic arithmetic operations like `add`, `sub`, `mul`, `div`, ... */ - -package math_big - import "base:intrinsics" /* diff --git a/core/math/big/radix.odin b/core/math/big/radix.odin index 73c4452ac..bc9ae068d 100644 --- a/core/math/big/radix.odin +++ b/core/math/big/radix.odin @@ -1,3 +1,5 @@ +package math_big + /* Copyright 2021 Jeroen van Rijn . Made available under Odin's BSD-3 license. @@ -13,9 +15,6 @@ - Also look at extracting and splatting several digits at once. */ - -package math_big - import "base:intrinsics" import "core:mem" import "core:os" diff --git a/core/math/big/tune.odin b/core/math/big/tune.odin index eab36b951..1d24a1325 100644 --- a/core/math/big/tune.odin +++ b/core/math/big/tune.odin @@ -1,3 +1,6 @@ +#+build ignore +package math_big + /* Copyright 2021 Jeroen van Rijn . Made available under Odin's BSD-3 license. @@ -7,9 +10,6 @@ The code started out as an idiomatic source port of libTomMath, which is in the public domain, with thanks. */ -#+build ignore -package math_big - import "core:time" import "base:runtime" diff --git a/core/math/bits/bits.odin b/core/math/bits/bits.odin index 154b5a142..effcf4985 100644 --- a/core/math/bits/bits.odin +++ b/core/math/bits/bits.odin @@ -1,3 +1,4 @@ +// Bit-level operations, including the ability to set or toggle individual bits in an integer. package math_bits import "base:intrinsics" diff --git a/core/math/cmplx/cmplx.odin b/core/math/cmplx/cmplx.odin index d1c70ca61..f5c572cc6 100644 --- a/core/math/cmplx/cmplx.odin +++ b/core/math/cmplx/cmplx.odin @@ -1,3 +1,4 @@ +// Trigonometric and other mathematic operations on complex numbers. package math_cmplx import "base:builtin" diff --git a/core/math/ease/ease.odin b/core/math/ease/ease.odin index 5ed0dd56a..c6dd56dbc 100644 --- a/core/math/ease/ease.odin +++ b/core/math/ease/ease.odin @@ -1,4 +1,4 @@ -// easing procedures and flux easing used for animations +// Easing procedures and flux easing used for animations. package ease import "core:math" diff --git a/core/math/fixed/fixed.odin b/core/math/fixed/fixed.odin index 9af6d7599..28f87b6d2 100644 --- a/core/math/fixed/fixed.odin +++ b/core/math/fixed/fixed.odin @@ -1,3 +1,4 @@ +// Fixed-point rational numbers and conversion to/from `f64`. package math_fixed import "core:math" diff --git a/core/math/linalg/doc.odin b/core/math/linalg/doc.odin index 4bc9b674d..38a894148 100644 --- a/core/math/linalg/doc.odin +++ b/core/math/linalg/doc.odin @@ -1,2 +1,2 @@ -// core:math/linalg implements linear algebra procedures useful for 3D spatial transformations +// Linear algebra procedures useful for 3D spatial transformations. package linalg diff --git a/core/math/linalg/glsl/linalg_glsl.odin b/core/math/linalg/glsl/linalg_glsl.odin index bd2cf416a..46ee7a6f7 100644 --- a/core/math/linalg/glsl/linalg_glsl.odin +++ b/core/math/linalg/glsl/linalg_glsl.odin @@ -1,4 +1,4 @@ -// core:math/linalg/glsl implements a GLSL-like mathematics library plus numerous other utility procedures +// `GLSL`-like mathematics library plus numerous other utility procedures. package math_linalg_glsl import "base:builtin" diff --git a/core/math/linalg/hlsl/linalg_hlsl.odin b/core/math/linalg/hlsl/linalg_hlsl.odin index cca70f9c8..5c78bd8b1 100644 --- a/core/math/linalg/hlsl/linalg_hlsl.odin +++ b/core/math/linalg/hlsl/linalg_hlsl.odin @@ -1,4 +1,4 @@ -// core:math/linalg/hlsl implements a HLSL-like mathematics library plus numerous other utility procedures +// `HLSL`-like mathematics library plus numerous other utility procedures. package math_linalg_hlsl import "base:builtin" diff --git a/core/math/linalg/specific.odin b/core/math/linalg/specific.odin index c23feddce..3c37d4d25 100644 --- a/core/math/linalg/specific.odin +++ b/core/math/linalg/specific.odin @@ -164,25 +164,25 @@ orthogonal :: proc{vector2_orthogonal, vector3_orthogonal} @(require_results) vector4_srgb_to_linear_f16 :: proc "contextless" (col: Vector4f16) -> Vector4f16 { - r := math.pow(col.x, 2.2) - g := math.pow(col.y, 2.2) - b := math.pow(col.z, 2.2) + r := math.pow((col.x + 0.055) / 1.055, 2.4) if col.x > 0.04045 else col.x / 12.92 + g := math.pow((col.y + 0.055) / 1.055, 2.4) if col.y > 0.04045 else col.y / 12.92 + b := math.pow((col.z + 0.055) / 1.055, 2.4) if col.z > 0.04045 else col.z / 12.92 a := col.w return {r, g, b, a} } @(require_results) vector4_srgb_to_linear_f32 :: proc "contextless" (col: Vector4f32) -> Vector4f32 { - r := math.pow(col.x, 2.2) - g := math.pow(col.y, 2.2) - b := math.pow(col.z, 2.2) + r := math.pow((col.x + 0.055) / 1.055, 2.4) if col.x > 0.04045 else col.x / 12.92 + g := math.pow((col.y + 0.055) / 1.055, 2.4) if col.y > 0.04045 else col.y / 12.92 + b := math.pow((col.z + 0.055) / 1.055, 2.4) if col.z > 0.04045 else col.z / 12.92 a := col.w return {r, g, b, a} } @(require_results) vector4_srgb_to_linear_f64 :: proc "contextless" (col: Vector4f64) -> Vector4f64 { - r := math.pow(col.x, 2.2) - g := math.pow(col.y, 2.2) - b := math.pow(col.z, 2.2) + r := math.pow((col.x + 0.055) / 1.055, 2.4) if col.x > 0.04045 else col.x / 12.92 + g := math.pow((col.y + 0.055) / 1.055, 2.4) if col.y > 0.04045 else col.y / 12.92 + b := math.pow((col.z + 0.055) / 1.055, 2.4) if col.z > 0.04045 else col.z / 12.92 a := col.w return {r, g, b, a} } @@ -192,70 +192,55 @@ vector4_srgb_to_linear :: proc{ vector4_srgb_to_linear_f64, } +@(require_results) +vector3_srgb_to_linear_f16 :: proc "contextless" (col: Vector3f16) -> Vector3f16 { + r := math.pow((col.x + 0.055) / 1.055, 2.4) if col.x > 0.04045 else col.x / 12.92 + g := math.pow((col.y + 0.055) / 1.055, 2.4) if col.y > 0.04045 else col.y / 12.92 + b := math.pow((col.z + 0.055) / 1.055, 2.4) if col.z > 0.04045 else col.z / 12.92 + return {r, g, b} +} +@(require_results) +vector3_srgb_to_linear_f32 :: proc "contextless" (col: Vector3f32) -> Vector3f32 { + r := math.pow((col.x + 0.055) / 1.055, 2.4) if col.x > 0.04045 else col.x / 12.92 + g := math.pow((col.y + 0.055) / 1.055, 2.4) if col.y > 0.04045 else col.y / 12.92 + b := math.pow((col.z + 0.055) / 1.055, 2.4) if col.z > 0.04045 else col.z / 12.92 + return {r, g, b} +} +@(require_results) +vector3_srgb_to_linear_f64 :: proc "contextless" (col: Vector3f64) -> Vector3f64 { + r := math.pow((col.x + 0.055) / 1.055, 2.4) if col.x > 0.04045 else col.x / 12.92 + g := math.pow((col.y + 0.055) / 1.055, 2.4) if col.y > 0.04045 else col.y / 12.92 + b := math.pow((col.z + 0.055) / 1.055, 2.4) if col.z > 0.04045 else col.z / 12.92 + return {r, g, b} +} +vector3_srgb_to_linear :: proc{ + vector3_srgb_to_linear_f16, + vector3_srgb_to_linear_f32, + vector3_srgb_to_linear_f64, +} + @(require_results) vector4_linear_to_srgb_f16 :: proc "contextless" (col: Vector4f16) -> Vector4f16 { - a :: 2.51 - b :: 0.03 - c :: 2.43 - d :: 0.59 - e :: 0.14 - - x := col.x - y := col.y - z := col.z - - x = (x * (a * x + b)) / (x * (c * x + d) + e) - y = (y * (a * y + b)) / (y * (c * y + d) + e) - z = (z * (a * z + b)) / (z * (c * z + d) + e) - - x = math.pow(clamp(x, 0, 1), 1.0 / 2.2) - y = math.pow(clamp(y, 0, 1), 1.0 / 2.2) - z = math.pow(clamp(z, 0, 1), 1.0 / 2.2) + x := 1.055 * math.pow(col.x, 1.0 / 2.4) - 0.055 if col.x > 0.0031308 else 12.92 * col.x + y := 1.055 * math.pow(col.y, 1.0 / 2.4) - 0.055 if col.y > 0.0031308 else 12.92 * col.y + z := 1.055 * math.pow(col.z, 1.0 / 2.4) - 0.055 if col.z > 0.0031308 else 12.92 * col.z return {x, y, z, col.w} } @(require_results) vector4_linear_to_srgb_f32 :: proc "contextless" (col: Vector4f32) -> Vector4f32 { - a :: 2.51 - b :: 0.03 - c :: 2.43 - d :: 0.59 - e :: 0.14 - - x := col.x - y := col.y - z := col.z - - x = (x * (a * x + b)) / (x * (c * x + d) + e) - y = (y * (a * y + b)) / (y * (c * y + d) + e) - z = (z * (a * z + b)) / (z * (c * z + d) + e) - - x = math.pow(clamp(x, 0, 1), 1.0 / 2.2) - y = math.pow(clamp(y, 0, 1), 1.0 / 2.2) - z = math.pow(clamp(z, 0, 1), 1.0 / 2.2) + x := 1.055 * math.pow(col.x, 1.0 / 2.4) - 0.055 if col.x > 0.0031308 else 12.92 * col.x + y := 1.055 * math.pow(col.y, 1.0 / 2.4) - 0.055 if col.y > 0.0031308 else 12.92 * col.y + z := 1.055 * math.pow(col.z, 1.0 / 2.4) - 0.055 if col.z > 0.0031308 else 12.92 * col.z return {x, y, z, col.w} } @(require_results) vector4_linear_to_srgb_f64 :: proc "contextless" (col: Vector4f64) -> Vector4f64 { - a :: 2.51 - b :: 0.03 - c :: 2.43 - d :: 0.59 - e :: 0.14 - - x := col.x - y := col.y - z := col.z - - x = (x * (a * x + b)) / (x * (c * x + d) + e) - y = (y * (a * y + b)) / (y * (c * y + d) + e) - z = (z * (a * z + b)) / (z * (c * z + d) + e) - - x = math.pow(clamp(x, 0, 1), 1.0 / 2.2) - y = math.pow(clamp(y, 0, 1), 1.0 / 2.2) - z = math.pow(clamp(z, 0, 1), 1.0 / 2.2) + x := 1.055 * math.pow(col.x, 1.0 / 2.4) - 0.055 if col.x > 0.0031308 else 12.92 * col.x + y := 1.055 * math.pow(col.y, 1.0 / 2.4) - 0.055 if col.y > 0.0031308 else 12.92 * col.y + z := 1.055 * math.pow(col.z, 1.0 / 2.4) - 0.055 if col.z > 0.0031308 else 12.92 * col.z return {x, y, z, col.w} } @@ -265,6 +250,36 @@ vector4_linear_to_srgb :: proc{ vector4_linear_to_srgb_f64, } +@(require_results) +vector3_linear_to_srgb_f16 :: proc "contextless" (col: Vector3f16) -> Vector3f16 { + x := 1.055 * math.pow(col.x, 1.0 / 2.4) - 0.055 if col.x > 0.0031308 else 12.92 * col.x + y := 1.055 * math.pow(col.y, 1.0 / 2.4) - 0.055 if col.y > 0.0031308 else 12.92 * col.y + z := 1.055 * math.pow(col.z, 1.0 / 2.4) - 0.055 if col.z > 0.0031308 else 12.92 * col.z + + return {x, y, z} +} +@(require_results) +vector3_linear_to_srgb_f32 :: proc "contextless" (col: Vector3f32) -> Vector3f32 { + x := 1.055 * math.pow(col.x, 1.0 / 2.4) - 0.055 if col.x > 0.0031308 else 12.92 * col.x + y := 1.055 * math.pow(col.y, 1.0 / 2.4) - 0.055 if col.y > 0.0031308 else 12.92 * col.y + z := 1.055 * math.pow(col.z, 1.0 / 2.4) - 0.055 if col.z > 0.0031308 else 12.92 * col.z + + return {x, y, z} +} +@(require_results) +vector3_linear_to_srgb_f64 :: proc "contextless" (col: Vector3f64) -> Vector3f64 { + x := 1.055 * math.pow(col.x, 1.0 / 2.4) - 0.055 if col.x > 0.0031308 else 12.92 * col.x + y := 1.055 * math.pow(col.y, 1.0 / 2.4) - 0.055 if col.y > 0.0031308 else 12.92 * col.y + z := 1.055 * math.pow(col.z, 1.0 / 2.4) - 0.055 if col.z > 0.0031308 else 12.92 * col.z + + return {x, y, z} +} +vector3_linear_to_srgb :: proc{ + vector3_linear_to_srgb_f16, + vector3_linear_to_srgb_f32, + vector3_linear_to_srgb_f64, +} + @(require_results) vector4_hsl_to_rgb_f16 :: proc "contextless" (h, s, l: f16, a: f16 = 1) -> Vector4f16 { diff --git a/core/math/math.odin b/core/math/math.odin index b99a97bc1..34642049c 100644 --- a/core/math/math.odin +++ b/core/math/math.odin @@ -1,3 +1,4 @@ +// Typical trignometric and other basic math routines. package math import "base:intrinsics" @@ -402,7 +403,12 @@ remap :: proc "contextless" (old_value, old_min, old_max, new_min, new_max: $T) if old_range == 0 { return new_range / 2 } - return ((old_value - old_min) / old_range) * new_range + new_min + + when intrinsics.type_is_integer(T) { + return (((old_value - old_min)) * new_range) / old_range + new_min + } else { + return ((old_value - old_min) / old_range) * new_range + new_min + } } @(require_results) diff --git a/core/math/noise/internal.odin b/core/math/noise/internal.odin index f75c0ee87..af3e16ad8 100644 --- a/core/math/noise/internal.odin +++ b/core/math/noise/internal.odin @@ -1,11 +1,12 @@ +#+private +package math_noise + /* OpenSimplex2 noise implementation. Ported from https://github.com/KdotJPG/OpenSimplex2. Copyright 2022 Yuki2 (https://github.com/NoahR02) */ -#+private -package math_noise /* Private implementation details follow. diff --git a/core/math/noise/opensimplex2.odin b/core/math/noise/opensimplex2.odin index 634c32948..0fabdf3cf 100644 --- a/core/math/noise/opensimplex2.odin +++ b/core/math/noise/opensimplex2.odin @@ -1,7 +1,7 @@ /* - OpenSimplex2 noise implementation. + [[ OpenSimplex2 ; https://github.com/KdotJPG/OpenSimplex2 ]] noise algorithm. - Ported from [[ https://github.com/KdotJPG/OpenSimplex2 }]. + Ported from [[ https://github.com/KdotJPG/OpenSimplex2 ]]. Copyright 2022 Yuki2 [[ https://github.com/NoahR02 ]] */ package math_noise diff --git a/core/math/rand/rand.odin b/core/math/rand/rand.odin index 6b9a73395..8e270b7df 100644 --- a/core/math/rand/rand.odin +++ b/core/math/rand/rand.odin @@ -1,7 +1,4 @@ - -/* -Package core:math/rand implements various random number generators -*/ +// Random number generators. package rand import "base:intrinsics" diff --git a/core/mem/doc.odin b/core/mem/doc.odin index 580b08c96..657251902 100644 --- a/core/mem/doc.odin +++ b/core/mem/doc.odin @@ -1,6 +1,5 @@ /* -The `mem` package implements various allocators and provides utility procedures -for dealing with memory, pointers and slices. +Various allocators and provides helpers for dealing with memory, pointers and slices. The documentation below describes basic concepts, applicable to the `mem` package. diff --git a/core/mem/raw.odin b/core/mem/raw.odin index 41c91555e..0a608db31 100644 --- a/core/mem/raw.odin +++ b/core/mem/raw.odin @@ -18,6 +18,17 @@ Memory layout of the `cstring` type. */ Raw_Cstring :: runtime.Raw_Cstring + +/* +Memory layout of the `string16` type. +*/ +Raw_String16 :: runtime.Raw_String16 + +/* +Memory layout of the `cstring16` type. +*/ +Raw_Cstring16 :: runtime.Raw_Cstring16 + /* Memory layout of `[]T` types. */ diff --git a/core/mem/tlsf/tlsf.odin b/core/mem/tlsf/tlsf.odin index 0ae8c28e0..37c6858ec 100644 --- a/core/mem/tlsf/tlsf.odin +++ b/core/mem/tlsf/tlsf.odin @@ -1,3 +1,6 @@ +// Two Level Segregated Fit memory allocator. +package mem_tlsf + /* Copyright 2024 Jeroen van Rijn . Made available under Odin's BSD-3 license. @@ -7,9 +10,6 @@ Jeroen van Rijn: Source port */ -// package mem_tlsf implements a Two Level Segregated Fit memory allocator. -package mem_tlsf - import "base:intrinsics" import "base:runtime" diff --git a/core/mem/virtual/doc.odin b/core/mem/virtual/doc.odin new file mode 100644 index 000000000..614e290c3 --- /dev/null +++ b/core/mem/virtual/doc.odin @@ -0,0 +1,62 @@ +/* +A platform agnostic way to reserve/commit/decommit virtual memory. + + +virtual.Arena usage + +Example: + // Source: https://github.com/odin-lang/examples/blob/master/arena_allocator/arena_allocator.odin + import "core:fmt" + import "core:os" + + // virtual package implements a multi-purpose arena allocator. If you are on a + // platform that does not support virtual memory, then there is also a similar + // arena in `core:mem`. + import vmem "core:mem/virtual" + + load_files :: proc() -> ([]string, vmem.Arena) { + // This creates a growing virtual memory arena. It uses virtual memory and + // can grow as things are added to it. + arena: vmem.Arena + arena_err := vmem.arena_init_growing(&arena) + ensure(arena_err == nil) + arena_alloc := vmem.arena_allocator(&arena) + + // See arena_init_static for an arena that uses virtual memory, but cannot grow. + + // See arena_init_buffer for an arena that does not use virtual memory, + // instead it relies on you feeding it a buffer. + + f1, f1_ok := os.read_entire_file("file1.txt", arena_alloc) + ensure(f1_ok) + + f2, f2_ok := os.read_entire_file("file2.txt", arena_alloc) + ensure(f2_ok) + + f3, f3_ok := os.read_entire_file("file3.txt", arena_alloc) + ensure(f3_ok) + + res := make([]string, 3, arena_alloc) + res[0] = string(f1) + res[1] = string(f2) + res[2] = string(f3) + + return res, arena + } + + main :: proc() { + files, arena := load_files() + + for f in files { + fmt.println(f) + } + + // This deallocates everything that was allocated on the arena: + // The loaded content of the files as well as the `files` slice. + vmem.arena_destroy(&arena) + } + + +*/ +package mem_virtual + diff --git a/core/net/doc.odin b/core/net/doc.odin index ed720c0ae..082a1497a 100644 --- a/core/net/doc.odin +++ b/core/net/doc.odin @@ -1,20 +1,5 @@ /* - Copyright 2022 Tetralux - Copyright 2022 Colin Davidson - Copyright 2022 Jeroen van Rijn . - Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. - - List of contributors: - Tetralux: Initial implementation - Colin Davidson: Linux platform code, OSX platform code, Odin-native DNS resolver - Jeroen van Rijn: Cross platform unification, code style, documentation - Feoramund: FreeBSD platform code -*/ - -/* -Package net implements cross-platform Berkeley Sockets, DNS resolution and associated procedures. -For other protocols and their features, see subdirectories of this package. +Cross-platform Berkeley Sockets, `DNS` resolution and associated procedures. Features: - Supports Windows, Linux and OSX. @@ -44,3 +29,17 @@ or worse. This means that should you replace the temp allocator with an insuffic we'll do our best to loudly complain the first time you try it. */ package net + +/* + Copyright 2022 Tetralux + Copyright 2022 Colin Davidson + Copyright 2022 Jeroen van Rijn . + Copyright 2024 Feoramund . + Made available under Odin's BSD-3 license. + + List of contributors: + Tetralux: Initial implementation + Colin Davidson: Linux platform code, OSX platform code, Odin-native DNS resolver + Jeroen van Rijn: Cross platform unification, code style, documentation + Feoramund: FreeBSD platform code +*/ \ No newline at end of file diff --git a/core/odin/ast/ast.odin b/core/odin/ast/ast.odin index 3b8998b31..4dcc1f215 100644 --- a/core/odin/ast/ast.odin +++ b/core/odin/ast/ast.odin @@ -1,3 +1,4 @@ +// Abstract Syntax Tree for the `Odin` parser packages. package odin_ast import "core:odin/tokenizer" @@ -70,7 +71,7 @@ File :: struct { src: string, tags: [dynamic]tokenizer.Token, - docs: ^Comment_Group, + docs: ^Comment_Group, // possibly nil pkg_decl: ^Package_Decl, pkg_token: tokenizer.Token, @@ -137,26 +138,26 @@ Basic_Directive :: struct { Ellipsis :: struct { using node: Expr, tok: tokenizer.Token_Kind, - expr: ^Expr, + expr: ^Expr, // possibly nil } Proc_Lit :: struct { using node: Expr, - type: ^Proc_Type, - body: ^Stmt, - tags: Proc_Tags, - inlining: Proc_Inlining, - where_token: tokenizer.Token, + type: ^Proc_Type, + body: ^Stmt, // nil when it represents a foreign procedure + tags: Proc_Tags, + inlining: Proc_Inlining, + where_token: tokenizer.Token, where_clauses: []^Expr, } Comp_Lit :: struct { using node: Expr, - type: ^Expr, - open: tokenizer.Pos, + type: ^Expr, // nil when type is inferred + open: tokenizer.Pos, elems: []^Expr, close: tokenizer.Pos, - tag: ^Expr, + tag: ^Expr, // possibly nil } @@ -170,7 +171,7 @@ Tag_Expr :: struct { Unary_Expr :: struct { using node: Expr, op: tokenizer.Token, - expr: ^Expr, + expr: ^Expr, // nil in the case of `[?]T` or `x.?` } Binary_Expr :: struct { @@ -224,9 +225,9 @@ Slice_Expr :: struct { using node: Expr, expr: ^Expr, open: tokenizer.Pos, - low: ^Expr, + low: ^Expr, // possibly nil interval: tokenizer.Token, - high: ^Expr, + high: ^Expr, // possibly nil close: tokenizer.Pos, } @@ -291,7 +292,7 @@ Or_Branch_Expr :: struct { using node: Expr, expr: ^Expr, token: tokenizer.Token, - label: ^Expr, + label: ^Expr, // possibly nil when not used } Type_Assertion :: struct { @@ -384,13 +385,13 @@ Block_Stmt :: struct { If_Stmt :: struct { using node: Stmt, - label: ^Expr, + label: ^Expr, // possibly nil if_pos: tokenizer.Pos, - init: ^Stmt, + init: ^Stmt, // possibly nil cond: ^Expr, body: ^Stmt, else_pos: tokenizer.Pos, - else_stmt: ^Stmt, + else_stmt: ^Stmt, // possibly nil } When_Stmt :: struct { @@ -398,7 +399,7 @@ When_Stmt :: struct { when_pos: tokenizer.Pos, cond: ^Expr, body: ^Stmt, - else_stmt: ^Stmt, + else_stmt: ^Stmt, // possibly nil } Return_Stmt :: struct { @@ -413,17 +414,17 @@ Defer_Stmt :: struct { For_Stmt :: struct { using node: Stmt, - label: ^Expr, + label: ^Expr, // possibly nil for_pos: tokenizer.Pos, - init: ^Stmt, - cond: ^Expr, - post: ^Stmt, + init: ^Stmt, // possibly nil + cond: ^Expr, // possibly nil + post: ^Stmt, // possibly nil body: ^Stmt, } Range_Stmt :: struct { using node: Stmt, - label: ^Expr, + label: ^Expr, // possibly nil for_pos: tokenizer.Pos, vals: []^Expr, in_pos: tokenizer.Pos, @@ -436,12 +437,12 @@ Inline_Range_Stmt :: Unroll_Range_Stmt Unroll_Range_Stmt :: struct { using node: Stmt, - label: ^Expr, + label: ^Expr, // possibly nil unroll_pos: tokenizer.Pos, args: []^Expr, for_pos: tokenizer.Pos, val0: ^Expr, - val1: ^Expr, + val1: ^Expr, // possibly nil in_pos: tokenizer.Pos, expr: ^Expr, body: ^Stmt, @@ -460,9 +461,9 @@ Case_Clause :: struct { Switch_Stmt :: struct { using node: Stmt, - label: ^Expr, + label: ^Expr, // possibly nil switch_pos: tokenizer.Pos, - init: ^Stmt, + init: ^Stmt, // possibly nil cond: ^Expr, body: ^Stmt, partial: bool, @@ -470,7 +471,7 @@ Switch_Stmt :: struct { Type_Switch_Stmt :: struct { using node: Stmt, - label: ^Expr, + label: ^Expr, // possibly nil switch_pos: tokenizer.Pos, tag: ^Stmt, expr: ^Expr, @@ -481,7 +482,7 @@ Type_Switch_Stmt :: struct { Branch_Stmt :: struct { using node: Stmt, tok: tokenizer.Token, - label: ^Ident, + label: ^Ident, // possibly nil } Using_Stmt :: struct { @@ -498,55 +499,55 @@ Bad_Decl :: struct { Value_Decl :: struct { using node: Decl, - docs: ^Comment_Group, + docs: ^Comment_Group, // possibly nil attributes: [dynamic]^Attribute, // dynamic as parsing will add to them lazily names: []^Expr, - type: ^Expr, + type: ^Expr, // possibly nil values: []^Expr, - comment: ^Comment_Group, + comment: ^Comment_Group, // possibly nil is_using: bool, is_mutable: bool, } Package_Decl :: struct { using node: Decl, - docs: ^Comment_Group, + docs: ^Comment_Group, // possibly nil token: tokenizer.Token, name: string, - comment: ^Comment_Group, + comment: ^Comment_Group, // possibly nil } Import_Decl :: struct { using node: Decl, - docs: ^Comment_Group, + docs: ^Comment_Group, // possibly nil attributes: [dynamic]^Attribute, // dynamic as parsing will add to them lazily is_using: bool, import_tok: tokenizer.Token, name: tokenizer.Token, relpath: tokenizer.Token, fullpath: string, - comment: ^Comment_Group, + comment: ^Comment_Group, // possibly nil } Foreign_Block_Decl :: struct { using node: Decl, - docs: ^Comment_Group, + docs: ^Comment_Group, // possibly nil attributes: [dynamic]^Attribute, // dynamic as parsing will add to them lazily tok: tokenizer.Token, - foreign_library: ^Expr, - body: ^Stmt, + foreign_library: ^Expr, // possibly nil + body: ^Stmt, // possibly nil } Foreign_Import_Decl :: struct { using node: Decl, - docs: ^Comment_Group, + docs: ^Comment_Group, // possibly nil attributes: [dynamic]^Attribute, // dynamic as parsing will add to them lazily foreign_tok: tokenizer.Token, import_tok: tokenizer.Token, - name: ^Ident, + name: ^Ident, // possibly nil collection_name: string, fullpaths: []^Expr, - comment: ^Comment_Group, + comment: ^Comment_Group, // possibly nil } @@ -689,13 +690,13 @@ Attribute :: struct { Field :: struct { using node: Node, - docs: ^Comment_Group, + docs: ^Comment_Group, // possibly nil names: []^Expr, // Could be polymorphic type: ^Expr, - default_value: ^Expr, + default_value: ^Expr, // possibly nil tag: tokenizer.Token, flags: Field_Flags, - comment: ^Comment_Group, + comment: ^Comment_Group, // possibly nil } Field_List :: struct { @@ -710,7 +711,7 @@ Field_List :: struct { Typeid_Type :: struct { using node: Expr, tok: tokenizer.Token_Kind, - specialization: ^Expr, + specialization: ^Expr, // possibly nil } Helper_Type :: struct { @@ -729,7 +730,7 @@ Poly_Type :: struct { using node: Expr, dollar: tokenizer.Pos, type: ^Ident, - specialization: ^Expr, + specialization: ^Expr, // possibly nil } Proc_Type :: struct { @@ -746,7 +747,7 @@ Proc_Type :: struct { Pointer_Type :: struct { using node: Expr, - tag: ^Expr, + tag: ^Expr, // possibly nil pointer: tokenizer.Pos, elem: ^Expr, } @@ -762,7 +763,7 @@ Multi_Pointer_Type :: struct { Array_Type :: struct { using node: Expr, open: tokenizer.Pos, - tag: ^Expr, + tag: ^Expr, // possibly nil len: ^Expr, // Unary_Expr node for [?]T array types, nil for slice types close: tokenizer.Pos, elem: ^Expr, @@ -770,7 +771,7 @@ Array_Type :: struct { Dynamic_Array_Type :: struct { using node: Expr, - tag: ^Expr, + tag: ^Expr, // possibly nil open: tokenizer.Pos, dynamic_pos: tokenizer.Pos, close: tokenizer.Pos, @@ -780,10 +781,10 @@ Dynamic_Array_Type :: struct { Struct_Type :: struct { using node: Expr, tok_pos: tokenizer.Pos, - poly_params: ^Field_List, - align: ^Expr, - min_field_align: ^Expr, - max_field_align: ^Expr, + poly_params: ^Field_List, // possibly nil + align: ^Expr, // possibly nil + min_field_align: ^Expr, // possibly nil + max_field_align: ^Expr, // possibly nil where_token: tokenizer.Token, where_clauses: []^Expr, is_packed: bool, @@ -803,8 +804,8 @@ Union_Type_Kind :: enum u8 { Union_Type :: struct { using node: Expr, tok_pos: tokenizer.Pos, - poly_params: ^Field_List, - align: ^Expr, + poly_params: ^Field_List, // possibly nil + align: ^Expr, // possibly nil kind: Union_Type_Kind, where_token: tokenizer.Token, where_clauses: []^Expr, @@ -814,7 +815,7 @@ Union_Type :: struct { Enum_Type :: struct { using node: Expr, tok_pos: tokenizer.Pos, - base_type: ^Expr, + base_type: ^Expr, // possibly nil open: tokenizer.Pos, fields: []^Expr, close: tokenizer.Pos, @@ -827,7 +828,7 @@ Bit_Set_Type :: struct { tok_pos: tokenizer.Pos, open: tokenizer.Pos, elem: ^Expr, - underlying: ^Expr, + underlying: ^Expr, // possibly nil close: tokenizer.Pos, } @@ -864,12 +865,12 @@ Bit_Field_Type :: struct { Bit_Field_Field :: struct { using node: Node, - docs: ^Comment_Group, + docs: ^Comment_Group, // possibly nil name: ^Expr, type: ^Expr, bit_size: ^Expr, tag: tokenizer.Token, - comments: ^Comment_Group, + comments: ^Comment_Group, // possibly nil } Any_Node :: union { diff --git a/core/odin/doc-format/doc_format.odin b/core/odin/doc-format/doc_format.odin index e6804c981..e37092948 100644 --- a/core/odin/doc-format/doc_format.odin +++ b/core/odin/doc-format/doc_format.odin @@ -1,3 +1,4 @@ +// The `.odin-doc` file format, as used by these package docs at `pkg.odin-lang.org`. package odin_doc_format import "core:mem" diff --git a/core/odin/doc.odin b/core/odin/doc.odin new file mode 100644 index 000000000..40aeaea7f --- /dev/null +++ b/core/odin/doc.odin @@ -0,0 +1,2 @@ +// A lexer and parser for the `Odin` language for the purposes of writing tooling. +package odin \ No newline at end of file diff --git a/core/odin/parser/parser.odin b/core/odin/parser/parser.odin index dab2d5d6a..94ea649f9 100644 --- a/core/odin/parser/parser.odin +++ b/core/odin/parser/parser.odin @@ -1,3 +1,4 @@ +// The `Odin` file parser to be used in tooling. package odin_parser import "core:odin/ast" diff --git a/core/odin/tokenizer/tokenizer.odin b/core/odin/tokenizer/tokenizer.odin index a9d367a4d..9f46f2ed6 100644 --- a/core/odin/tokenizer/tokenizer.odin +++ b/core/odin/tokenizer/tokenizer.odin @@ -1,3 +1,4 @@ +// The tokenizer (lexer) for `Odin` files, used to create tooling. package odin_tokenizer import "core:fmt" diff --git a/core/os/os.odin b/core/os/os.odin index fe08edff4..da7b0c151 100644 --- a/core/os/os.odin +++ b/core/os/os.odin @@ -1,3 +1,4 @@ +// Cross-platform `OS` interactions like file `I/O`. package os import "base:intrinsics" diff --git a/core/os/os2/path_linux.odin b/core/os/os2/path_linux.odin index 8b185f419..1c9927843 100644 --- a/core/os/os2/path_linux.odin +++ b/core/os/os2/path_linux.odin @@ -199,7 +199,7 @@ _get_full_path :: proc(fd: linux.Fd, allocator: runtime.Allocator) -> (fullpath: buf: [32]u8 copy(buf[:], PROC_FD_PATH) - strconv.itoa(buf[len(PROC_FD_PATH):], int(fd)) + strconv.write_int(buf[len(PROC_FD_PATH):], i64(fd), 10) if fullpath, err = _read_link_cstr(cstring(&buf[0]), allocator); err != nil || fullpath[0] != '/' { delete(fullpath, allocator) diff --git a/core/os/os_linux.odin b/core/os/os_linux.odin index 15d230820..f0f9b401c 100644 --- a/core/os/os_linux.odin +++ b/core/os/os_linux.odin @@ -908,7 +908,7 @@ _dup :: proc(fd: Handle) -> (Handle, Error) { @(require_results) absolute_path_from_handle :: proc(fd: Handle) -> (string, Error) { buf : [256]byte - fd_str := strconv.itoa( buf[:], cast(int)fd ) + fd_str := strconv.write_int( buf[:], cast(i64)fd, 10 ) procfs_path := strings.concatenate( []string{ "/proc/self/fd/", fd_str } ) defer delete(procfs_path) diff --git a/core/path/filepath/path.odin b/core/path/filepath/path.odin index e23183b02..14a9181c3 100644 --- a/core/path/filepath/path.odin +++ b/core/path/filepath/path.odin @@ -1,5 +1,5 @@ -// The path/filepath package uses either forward slashes or backslashes depending on the operating system -// To process paths such as URLs that depend on forward slashes regardless of the OS, use the path package +// Process paths using either forward slashes or backslashes depending on the operating system. +// To process paths such as URLs that depend on forward slashes regardless of the OS, use the slashpath package. package filepath import "base:runtime" diff --git a/core/path/slashpath/path.odin b/core/path/slashpath/path.odin index 52b4878bc..1d2a24453 100644 --- a/core/path/slashpath/path.odin +++ b/core/path/slashpath/path.odin @@ -1,5 +1,4 @@ -// The slashpath package is only to be used for paths separated by forward slashes, -// e.g. paths in URLs +// Process paths separated by forward slashes only, e.g. paths in `URL`s. // // This package does not deal with Windows/NT paths with volume letters or backslashes // To manipulate operating system specific paths, use the path/filepath package diff --git a/core/prof/spall/doc.odin b/core/prof/spall/doc.odin index b007ad4cb..e07a00a26 100644 --- a/core/prof/spall/doc.odin +++ b/core/prof/spall/doc.odin @@ -1,4 +1,8 @@ /* +Profiling using the "`spall`" format. + +See: [[ https://gravitymoth.com/spall/ ]] + Example: package main diff --git a/core/reflect/doc.odin b/core/reflect/doc.odin new file mode 100644 index 000000000..5ec5e7070 --- /dev/null +++ b/core/reflect/doc.odin @@ -0,0 +1,51 @@ +// Utility procedures and types to perform runtime type introspection/reflection (`RTTI`). +// +// WARNING! THIS IS ADVANCED BEHAVIOUR FOR ODIN! THIS SHOULD NOT BE USED BY BEGINNERS TO ODIN! +// +// This package is only to be used by individuals who know exactly how the RTTI works as well as EXACTLY how `any` works. +// Especially since `any` can be unintuitive in its use to many, it can be dangerous to use. It is highly recommend that you **do not** +// use `any` unless you know exactly what you are doing. +// +// RTTI is an extremely powerful tool which should only be used when absolutely necessary (such runtime-type-safe formatted printing). +// +// ## The Type System of Odin +// +// It is important to understand how the type systems works in Odin before using any RTTI. A good example of this is Odin's `distinct` type system. +// In Odin, `distinct` types are represented by `Type_Info_Named`. A named struct is a `Type_Info_Named` which then points to a `Type_Info_Struct`. +// This means you must use something like `type_info_base` to restrict the `Type_Info_Named` aspect and get the base-type directly. Doing a type-assertion +// on the variant will not work as (incorrectly) expected without doing this. +// +// ## Advanced Information of How `any` Works +// +// An overview of how `any` works: +// +// An `any` type can reference any data type. It is functionally equivalent to `struct {data: rawptr, id: typeid}` with extra semantics on +// how assignment and type assertion works. +// +// This is commonly used to construct runtime-type-safe printing, such as in `core:fmt`. +// The use of `any` outside of this is heavily discourage and should be only used by people who FULLY understand its semantics. +// +// The `any` value is only valid as long as the underlying data is still valid. Passing a literal to an `any` will allocate the literal in +// the current stack frame. +// +// Example: +// x: int = 123 +// a: any = x +// // equivalent to +// a: any +// a.data = &x +// a.id = typeid_of(type_of(x)) +// // With literals +// v: any = 123 +// // equivalent to +// v: any +// _tmp: int = 123 +// v.data = &_tmp +// v.id = typeid_of(type_of(_tmp)) +// +// +// `any` is a topologically-dual to a `union` in terms of its usage. Both support assignments of differing types +// (`any` being open to any type, `union` being closed to a specific set of types), type assertions (`x.(T)`), and `switch in`. +// The main internal difference is how the memory is stored. `any` being open is a pointer+typeid, a `union` +// is a blob+tag. A `union` does not need to store a `typeid` because it is a closed ABI-consistent set of variant types. +package reflect \ No newline at end of file diff --git a/core/reflect/iterator.odin b/core/reflect/iterator.odin index 090fe04cc..e96019f68 100644 --- a/core/reflect/iterator.odin +++ b/core/reflect/iterator.odin @@ -2,6 +2,10 @@ package reflect import "base:runtime" +// An iterator to dynamically iterate across something that is array-like (or pointer-to-array-like) +// Example: +// it: int // used as a tracking value +// for elem, idx in iterate_array(any_array_val, &it) { ... } @(require_results) iterate_array :: proc(val: any, it: ^int) -> (elem: any, index: int, ok: bool) { if val == nil || it == nil { @@ -45,6 +49,10 @@ iterate_array :: proc(val: any, it: ^int) -> (elem: any, index: int, ok: bool) { return } +// An iterator to dynamically iterate across map (or pointer-to-map) +// Example: +// it: int // used as a tracking value +// for key, val in iterate_map(any_map_val, &it) { ... } @(require_results) iterate_map :: proc(val: any, it: ^int) -> (key, value: any, ok: bool) { if val == nil || it == nil { diff --git a/core/reflect/reflect.odin b/core/reflect/reflect.odin index b3315a0c3..5fbff08c2 100644 --- a/core/reflect/reflect.odin +++ b/core/reflect/reflect.odin @@ -70,6 +70,7 @@ Type_Kind :: enum { } +// type_kind returns a enum `Type_Kind` to state what kind of type a typeid is @(require_results) type_kind :: proc(T: typeid) -> Type_Kind { ti := type_info_of(T) @@ -108,31 +109,51 @@ type_kind :: proc(T: typeid) -> Type_Kind { return .Invalid } -// TODO(bill): Better name +// Returns the `Type_Kind` of the base-type of a typeid. @(require_results) underlying_type_kind :: proc(T: typeid) -> Type_Kind { return type_kind(runtime.typeid_base(T)) } -// TODO(bill): Better name +// Returns the `Type_Kind` of the core-type of a typeid. See @(require_results) backing_type_kind :: proc(T: typeid) -> Type_Kind { return type_kind(runtime.typeid_core(T)) } +// type_info_base returns the base-type of a `^Type_Info` stripping the `distinct`ness from the first level type_info_base :: runtime.type_info_base + +// type_info_core returns the core-type of a `^Type_Info` stripping the `distinct`ness from the first level AND/OR +// returns the backing integer type of an enum or bit_set `^Type_Info`. +// This is also aliased as `type_info_base_without_enum` type_info_core :: runtime.type_info_core + + +// type_info_base_without_enum returns the core-type of a `^Type_Info` stripping the `distinct`ness from the first level AND/OR +// returns the backing integer type of an enum or bit_set `^Type_Info`. +// This is also aliased as `type_info_core` type_info_base_without_enum :: type_info_core when !ODIN_NO_RTTI { + // typeid_base returns the base-type of a `typeid` stripping the `distinct`ness from the first level typeid_base :: runtime.typeid_base + + // typeid_core returns the core-type of a `typeid` stripping the `distinct`ness from the first level AND/OR + // returns the backing integer type of an enum or bit_set `typeid`. + // This is also aliased as `typeid_base_without_enum` typeid_core :: runtime.typeid_core + + // typeid_base_without_enum returns the core-type of a `typeid` stripping the `distinct`ness from the first level AND/OR + // returns the backing integer type of an enum or bit_set `typeid`. + // This is also aliased as `typeid_core` typeid_base_without_enum :: typeid_core } +// any_base returns an `any` where the `typeid` has been replaced with the `base-type` equivalent @(require_results) any_base :: proc(v: any) -> any { v := v @@ -141,6 +162,8 @@ any_base :: proc(v: any) -> any { } return v } + +// any_core returns an `any` where the `typeid` has been replaced with the `core-type` equivalent @(require_results) any_core :: proc(v: any) -> any { v := v @@ -150,6 +173,20 @@ any_core :: proc(v: any) -> any { return v } +// typeid_elem returns a `typeid` of the element-type of a type if possible, otherwise it returns itself +// complex32 -> f16 +// complex64 -> f32 +// complex128 -> f64 +// quaternion64 -> f16 +// quaternion128 -> f32 +// quaternion256 -> f64 +// ^T -> T +// [^]T -> T +// #soa^T -> T +// [N]T -> T +// []T -> T +// [dynamic]T -> T +// #simd[N]T -> T @(require_results) typeid_elem :: proc(id: typeid) -> typeid { ti := type_info_of(id) @@ -160,11 +197,13 @@ typeid_elem :: proc(id: typeid) -> typeid { #partial switch v in ti.variant { case Type_Info_Complex: switch bits { + case 32: return f16 case 64: return f32 case 128: return f64 } case Type_Info_Quaternion: switch bits { + case 64: return f16 case 128: return f32 case 256: return f64 } @@ -181,6 +220,7 @@ typeid_elem :: proc(id: typeid) -> typeid { } +// returns the size of the type that the passed typeid represents @(require_results) size_of_typeid :: proc(T: typeid) -> int { if ti := type_info_of(T); ti != nil { @@ -189,6 +229,7 @@ size_of_typeid :: proc(T: typeid) -> int { return 0 } +// returns the alignment of the type that the passed typeid represents @(require_results) align_of_typeid :: proc(T: typeid) -> int { if ti := type_info_of(T); ti != nil { @@ -197,6 +238,7 @@ align_of_typeid :: proc(T: typeid) -> int { return 1 } +// Reinterprets the data stored at `v` as a slice of bytes @(require_results) as_bytes :: proc(v: any) -> []byte { if v != nil { @@ -206,11 +248,13 @@ as_bytes :: proc(v: any) -> []byte { return nil } +// Splits the data stored in `any` into its two components: `data` and `id` @(require_results) any_data :: #force_inline proc(v: any) -> (data: rawptr, id: typeid) { return v.data, v.id } +// Returns true if the `any` value is either `nil` or the data stored at the address is all zeroed @(require_results) is_nil :: proc(v: any) -> bool { if v == nil { @@ -228,6 +272,16 @@ is_nil :: proc(v: any) -> bool { return true } + +// Returns the length of the type that represents the `any` value, or returns 0 if not possible +// len(^T) -> len(T) +// len([N]T) -> N +// len(#simd[N]T) -> N +// len([]T) +// len([dynamic]T) +// len(map[K]V) +// len(string) or len(cstring) +// len(string16) or len(cstring16) @(require_results) length :: proc(val: any) -> int { if val == nil { return 0 } @@ -255,10 +309,19 @@ length :: proc(val: any) -> int { return runtime.map_len((^runtime.Raw_Map)(val.data)^) case Type_Info_String: - if a.is_cstring { - return len((^cstring)(val.data)^) - } else { - return (^runtime.Raw_String)(val.data).len + switch a.encoding { + case .UTF_8: + if a.is_cstring { + return len((^cstring)(val.data)^) + } else { + return (^runtime.Raw_String)(val.data).len + } + case .UTF_16: + if a.is_cstring { + return len((^cstring16)(val.data)^) + } else { + return (^runtime.Raw_String16)(val.data).len + } } case Type_Info_Simd_Vector: @@ -268,6 +331,12 @@ length :: proc(val: any) -> int { return 0 } +// Returns the capacity of the type that represents the `any` value, or returns 0 if not possible +// cap(^T) -> cap(T) +// cap([N]T) -> N +// cap(#simd[N]T) -> N +// cap([dynamic]T) +// cap(map[K]V) @(require_results) capacity :: proc(val: any) -> int { if val == nil { return 0 } @@ -299,6 +368,7 @@ capacity :: proc(val: any) -> int { } +// Dynamically indexes `any` as an indexable-type if possible. Returns `nil` if not possible @(require_results) index :: proc(val: any, i: int, loc := #caller_location) -> any { if val == nil { return nil } @@ -350,15 +420,25 @@ index :: proc(val: any, i: int, loc := #caller_location) -> any { case Type_Info_String: if a.is_cstring { return nil } - raw := (^runtime.Raw_String)(val.data) - runtime.bounds_check_error_loc(loc, i, raw.len) - offset := uintptr(size_of(u8) * i) - data := rawptr(uintptr(raw.data) + offset) - return any{data, typeid_of(u8)} + switch a.encoding { + case .UTF_8: + raw := (^runtime.Raw_String)(val.data) + runtime.bounds_check_error_loc(loc, i, raw.len) + offset := uintptr(size_of(u8) * i) + data := rawptr(uintptr(raw.data) + offset) + return any{data, typeid_of(u8)} + case .UTF_16: + raw := (^runtime.Raw_String16)(val.data) + runtime.bounds_check_error_loc(loc, i, raw.len) + offset := uintptr(size_of(u16) * i) + data := rawptr(uintptr(raw.data) + offset) + return any{data, typeid_of(u16)} + } } return nil } +// Dereferences `any` if it represents a pointer-based value (`^T -> T`) @(require_results) deref :: proc(val: any) -> any { if val != nil { @@ -375,20 +455,22 @@ deref :: proc(val: any) -> any { -// Struct_Tag represents the type of the string of a struct field +// `Struct_Tag` represents the type of the `string` of a struct field // -// Through convention, tags are the concatenation of optionally space separationed key:"value" pairs. +// Through convention, tags are the concatenation of optionally space-separated key:"value" pairs. // Each key is a non-empty string which contains no control characters other than space, quotes, and colon. Struct_Tag :: distinct string +// `Struct_Field` represents a information of a field of a struct Struct_Field :: struct { name: string, type: ^Type_Info, tag: Struct_Tag, - offset: uintptr, + offset: uintptr, // in bytes is_using: bool, } +// Returns a `Struct_Field` containing the information for a struct field of a typeid `T` at index `i` @(require_results) struct_field_at :: proc(T: typeid, i: int) -> (field: Struct_Field) { ti := runtime.type_info_base(type_info_of(T)) @@ -404,6 +486,7 @@ struct_field_at :: proc(T: typeid, i: int) -> (field: Struct_Field) { return } +// Returns a `Struct_Field` containing the information for a struct field by `name` of a typeid `T` @(require_results) struct_field_by_name :: proc(T: typeid, name: string) -> (field: Struct_Field) { ti := runtime.type_info_base(type_info_of(T)) @@ -422,6 +505,10 @@ struct_field_by_name :: proc(T: typeid, name: string) -> (field: Struct_Field) { return } +// Returns an `any` of a struct field specified by name +// Example: +// v := struct_field_value_by_name(the_struct, "field_name") +// nested_value_through_using := struct_field_value_by_name(the_struct, "field_name", allow_using=true) @(require_results) struct_field_value_by_name :: proc(a: any, field: string, allow_using := false) -> any { if a == nil { return nil } @@ -452,6 +539,10 @@ struct_field_value_by_name :: proc(a: any, field: string, allow_using := false) return nil } +// Returns an `any` of a struct field specified by a `Struct_Field` +// Example: +// field := struct_field_value_by_name(the_struct, "field_name") +// value_by_field := struct_field_value(the_struct, field) @(require_results) struct_field_value :: proc(a: any, field: Struct_Field) -> any { if a == nil { return nil } @@ -461,6 +552,7 @@ struct_field_value :: proc(a: any, field: Struct_Field) -> any { } } +// Returns a `[]string` of the names of the struct fields of type `T` @(require_results) struct_field_names :: proc(T: typeid) -> []string { ti := runtime.type_info_base(type_info_of(T)) @@ -470,6 +562,7 @@ struct_field_names :: proc(T: typeid) -> []string { return nil } +// Returns a `[]^Type_Info` of the types of the struct fields of type `T` @(require_results) struct_field_types :: proc(T: typeid) -> []^Type_Info { ti := runtime.type_info_base(type_info_of(T)) @@ -480,6 +573,7 @@ struct_field_types :: proc(T: typeid) -> []^Type_Info { } +// Returns a `[]Struct_Tag` of the tags of the struct fields of type `T` @(require_results) struct_field_tags :: proc(T: typeid) -> []Struct_Tag { ti := runtime.type_info_base(type_info_of(T)) @@ -489,6 +583,7 @@ struct_field_tags :: proc(T: typeid) -> []Struct_Tag { return nil } +// Returns a `[]uintptr` of the offsets in bytes of the struct fields of type `T` @(require_results) struct_field_offsets :: proc(T: typeid) -> []uintptr { ti := runtime.type_info_base(type_info_of(T)) @@ -498,6 +593,7 @@ struct_field_offsets :: proc(T: typeid) -> []uintptr { return nil } +// Struct_Field_Count_Method is the count method used by `struct_field_count` in order to find the number of fields Struct_Field_Count_Method :: enum { Top_Level, Using, @@ -556,6 +652,10 @@ struct_field_count :: proc(T: typeid, method := Struct_Field_Count_Method.Top_Le return } +// Returns the fields of a struct type `T` as an `#soa` slice. +// This is useful to iterate over. +// Example: +// for field, i in reflect.struct_fields_zipped(Foo) { ... } @(require_results) struct_fields_zipped :: proc(T: typeid) -> (fields: #soa[]Struct_Field) { ti := runtime.type_info_base(type_info_of(T)) @@ -572,13 +672,26 @@ struct_fields_zipped :: proc(T: typeid) -> (fields: #soa[]Struct_Field) { } - +// struct_tag_get returns the value associated with a key in the tag string. +// If the key is present in the tag, the value (which might be empty) is returned. Otherwise an empty string is returned. +// This is just a wrapper around `struct_tag_lookup` with the `ok` value being ignored. +// +// The convention for struct tags is usually of the form: +// +// `key:"value" another:"set" and:"whatever"` @(require_results) struct_tag_get :: proc(tag: Struct_Tag, key: string) -> (value: string) { v, _ := struct_tag_lookup(tag, key) - return string(v) + return v } +// struct_tag_lookup returns the value associated with a key in the tag string. +// If the key is present in the tag, the value (which might be empty) is return. Otherwise an empty string is returned. +// The `ok` value returns whether the value was explicit set in the tag string. +// +// The convention for struct tags is usually of the form: +// +// `key:"value" another:"set" and:"whatever"` @(require_results) struct_tag_lookup :: proc(tag: Struct_Tag, key: string) -> (value: string, ok: bool) { for t := tag; t != ""; /**/ { @@ -638,6 +751,7 @@ struct_tag_lookup :: proc(tag: Struct_Tag, key: string) -> (value: string, ok: b } +// Returns the string representation of an enum value. It will panic if the value passed is not an enum. @(require_results) enum_string :: proc(a: any) -> string { if a == nil { return "" } @@ -656,7 +770,7 @@ enum_string :: proc(a: any) -> string { return "" } -// Given a enum type and a value name, get the enum value. +// Given an enum type and a value name, get the enum value. @(require_results) enum_from_name :: proc($Enum_Type: typeid, name: string) -> (value: Enum_Type, ok: bool) { ti := type_info_base(type_info_of(Enum_Type)) @@ -674,6 +788,7 @@ enum_from_name :: proc($Enum_Type: typeid, name: string) -> (value: Enum_Type, o return } +// enum_from_name_any returns the value of an enum field's name if found, returns `0, false` otherwise. @(require_results) enum_from_name_any :: proc(Enum_Type: typeid, name: string) -> (value: Type_Info_Enum_Value, ok: bool) { ti := runtime.type_info_base(type_info_of(Enum_Type)) @@ -690,6 +805,7 @@ enum_from_name_any :: proc(Enum_Type: typeid, name: string) -> (value: Type_Info return } +// enum_name_from_value returns the name of enum field if a valid name using parametric polymorphism, otherwise returns `"", false` @(require_results) enum_name_from_value :: proc(value: $Enum_Type) -> (name: string, ok: bool) where intrinsics.type_is_enum(Enum_Type) { ti := type_info_base(type_info_of(Enum_Type)) @@ -706,6 +822,7 @@ enum_name_from_value :: proc(value: $Enum_Type) -> (name: string, ok: bool) wher return } +// enum_name_from_value_any returns the name of enum field if a valid name using reflection, otherwise returns `"", false` @(require_results) enum_name_from_value_any :: proc(value: any) -> (name: string, ok: bool) { if value.id == nil { @@ -725,9 +842,7 @@ enum_name_from_value_any :: proc(value: any) -> (name: string, ok: bool) { return } -/* -Returns whether the value given has a defined name in the enum type. -*/ +// Returns whether the value given has a defined name in the enum type. @(require_results) enum_value_has_name :: proc(value: $T) -> bool where intrinsics.type_is_enum(T) { when len(T) == cap(T) { @@ -749,6 +864,7 @@ enum_value_has_name :: proc(value: $T) -> bool where intrinsics.type_is_enum(T) +// enum_field_names returns `[]string` of the names of the fields of type `Enum_Type` @(require_results) enum_field_names :: proc(Enum_Type: typeid) -> []string { ti := runtime.type_info_base(type_info_of(Enum_Type)) @@ -757,6 +873,7 @@ enum_field_names :: proc(Enum_Type: typeid) -> []string { } return nil } +// enum_field_values returns `[]Type_Info_Enum_Value` of the values of the fields of type `Enum_Type` @(require_results) enum_field_values :: proc(Enum_Type: typeid) -> []Type_Info_Enum_Value { ti := runtime.type_info_base(type_info_of(Enum_Type)) @@ -766,11 +883,16 @@ enum_field_values :: proc(Enum_Type: typeid) -> []Type_Info_Enum_Value { return nil } +// Represents an `Enum_Field` storing the `name` and `value` Enum_Field :: struct { name: string, value: Type_Info_Enum_Value, } +// Returns a #soa slice of the enum field information of type `Enum_Type` +// This is useful to iterate over. +// Example: +// for field, i in reflect.enum_fields_zipped(Foo) { ... } @(require_results) enum_fields_zipped :: proc(Enum_Type: typeid) -> (fields: #soa[]Enum_Field) { ti := runtime.type_info_base(type_info_of(Enum_Type)) @@ -782,17 +904,20 @@ enum_fields_zipped :: proc(Enum_Type: typeid) -> (fields: #soa[]Enum_Field) { +// Returns `^Type_Info` of a any-encoded union type. Panics if a union was not passed. @(require_results) union_variant_type_info :: proc(a: any) -> ^Type_Info { id := union_variant_typeid(a) return type_info_of(id) } +// Returns whether the `Type_Info_Union` store no tag (called a "pure maybe"). @(require_results) type_info_union_is_pure_maybe :: proc(info: runtime.Type_Info_Union) -> bool { return len(info.variants) == 1 && is_pointer_internally(info.variants[0]) } +// UNSAFE: Returns `typeid` of a any-encoded union type. Panics if a union was not passed. @(require_results) union_variant_typeid :: proc(a: any) -> typeid { if a == nil { return nil } @@ -833,6 +958,7 @@ union_variant_typeid :: proc(a: any) -> typeid { panic("expected a union to reflect.union_variant_typeid") } +// UNSAFE: Returns the underlying tag value of a union. Panics if a union was not passed. @(require_results) get_union_variant_raw_tag :: proc(a: any) -> i64 { if a == nil { return -1 } @@ -864,6 +990,7 @@ get_union_variant_raw_tag :: proc(a: any) -> i64 { panic("expected a union to reflect.get_union_variant_raw_tag") } +// Returns the underlying variant value of a union. Panics if a union was not passed. @(require_results) get_union_variant :: proc(a: any) -> any { if a == nil { @@ -876,6 +1003,14 @@ get_union_variant :: proc(a: any) -> any { return any{a.data, id} } +// Converts a pointer to a union, to a union containing the pointers to the variant types, and stores a pointer of the variant value in the new union +// +// Example: +// val: union{i32, f32, string} +// val = "123" +// ptr: union{^i32, ^f32, ^string} = get_union_as_ptr_variants(&val) +// sp := ptr.(^string) +// assert(sp^ == "123") @(require_results) get_union_as_ptr_variants :: proc(val: ^$T) -> (res: intrinsics.type_convert_variants_to_pointers(T)) where intrinsics.type_is_union(T) { ptr := rawptr(val) @@ -886,7 +1021,7 @@ get_union_as_ptr_variants :: proc(val: ^$T) -> (res: intrinsics.type_convert_var } - +// UNSAFE: Manually set the tag value of a union using an integer. Panics if a union was not passed. set_union_variant_raw_tag :: proc(a: any, tag: i64) { if a == nil { return } @@ -917,6 +1052,7 @@ set_union_variant_raw_tag :: proc(a: any, tag: i64) { panic("expected a union to reflect.set_union_variant_raw_tag") } +// UNSAFE: Manually set the tag value of a union using a `typeid`. Panics if a union was not passed. set_union_variant_typeid :: proc(a: any, id: typeid) { if a == nil { return } @@ -947,6 +1083,7 @@ set_union_variant_typeid :: proc(a: any, id: typeid) { panic("expected a union to reflect.set_union_variant_typeid") } +// UNSAFE: Manually set the tag value of a union using a `^Type_Info`. Panics if a union was not passed. set_union_variant_type_info :: proc(a: any, tag_ti: ^Type_Info) { if a == nil { return } @@ -977,6 +1114,7 @@ set_union_variant_type_info :: proc(a: any, tag_ti: ^Type_Info) { panic("expected a union to reflect.set_union_variant_type_info") } +// UNSAFE: Manually set the variant value of a union using an `any`. Panics if a union was not passed. set_union_value :: proc(dst: any, value: any) -> bool { if dst == nil { return false } @@ -1015,6 +1153,7 @@ set_union_value :: proc(dst: any, value: any) -> bool { panic("expected a union to reflect.set_union_variant_typeid") } +// UNSAFE: Checks to see if the data stored is a `bit_set` and is big endian. Panics if a `bit_set` was not passed. @(require_results) bit_set_is_big_endian :: proc(value: any, loc := #caller_location) -> bool { if value == nil { return ODIN_ENDIAN == .Big } @@ -1046,6 +1185,10 @@ Bit_Field :: struct { tag: Struct_Tag, } +// Returns the fields of a `bit_field` type `T` as an `#soa` slice. +// This is useful to iterate over. +// Example: +// for field, i in reflect.bit_fields_zipped(Foo_Bit_Field) { ... } @(require_results) bit_fields_zipped :: proc(T: typeid) -> (fields: #soa[]Bit_Field) { ti := runtime.type_info_base(type_info_of(T)) @@ -1061,6 +1204,7 @@ bit_fields_zipped :: proc(T: typeid) -> (fields: #soa[]Bit_Field) { return nil } +// bit_field_names returns a `[]string` of the field names of a `bit_field` type `T` @(require_results) bit_field_names :: proc(T: typeid) -> []string { ti := runtime.type_info_base(type_info_of(T)) @@ -1070,6 +1214,7 @@ bit_field_names :: proc(T: typeid) -> []string { return nil } +// bit_field_types returns a `[]^Type_Info` of the field representation types of a `bit_field` type `T`, not the backing integer-bit-width types @(require_results) bit_field_types :: proc(T: typeid) -> []^Type_Info { ti := runtime.type_info_base(type_info_of(T)) @@ -1079,6 +1224,7 @@ bit_field_types :: proc(T: typeid) -> []^Type_Info { return nil } +// bit_field_types returns a `[]uintptr` of the field bit-width-sizes of a `bit_field` type `T` @(require_results) bit_field_sizes :: proc(T: typeid) -> []uintptr { ti := runtime.type_info_base(type_info_of(T)) @@ -1088,6 +1234,7 @@ bit_field_sizes :: proc(T: typeid) -> []uintptr { return nil } +// bit_field_types returns a `[]uintptr` of the field offsets in bits of a `bit_field` type `T` @(require_results) bit_field_offsets :: proc(T: typeid) -> []uintptr { ti := runtime.type_info_base(type_info_of(T)) @@ -1097,6 +1244,7 @@ bit_field_offsets :: proc(T: typeid) -> []uintptr { return nil } +// bit_field_types returns a `[]Struct_Tag` of the field tags of a `bit_field` type `T` @(require_results) bit_field_tags :: proc(T: typeid) -> []Struct_Tag { ti := runtime.type_info_base(type_info_of(T)) @@ -1106,6 +1254,7 @@ bit_field_tags :: proc(T: typeid) -> []Struct_Tag { return nil } +// as_bool attempts to convert an `any` to a `bool`. @(require_results) as_bool :: proc(a: any) -> (value: bool, valid: bool) { if a == nil { return } @@ -1129,6 +1278,7 @@ as_bool :: proc(a: any) -> (value: bool, valid: bool) { return } +// as_int attempts to convert an `any` to a `int`. @(require_results) as_int :: proc(a: any) -> (value: int, valid: bool) { v: i64 @@ -1137,6 +1287,7 @@ as_int :: proc(a: any) -> (value: int, valid: bool) { return } +// as_uint attempts to convert an `any` to a `uint`. @(require_results) as_uint :: proc(a: any) -> (value: uint, valid: bool) { v: u64 @@ -1145,6 +1296,7 @@ as_uint :: proc(a: any) -> (value: uint, valid: bool) { return } +// as_i64 attempts to convert an `any` to a `i64`. @(require_results) as_i64 :: proc(a: any) -> (value: i64, valid: bool) { if a == nil { return } @@ -1253,6 +1405,7 @@ as_i64 :: proc(a: any) -> (value: i64, valid: bool) { return } +// as_u64 attempts to convert an `any` to a `u64`. @(require_results) as_u64 :: proc(a: any) -> (value: u64, valid: bool) { if a == nil { return } @@ -1363,6 +1516,7 @@ as_u64 :: proc(a: any) -> (value: u64, valid: bool) { } +// as_f64 attempts to convert an `any` to a `f64`. @(require_results) as_f64 :: proc(a: any) -> (value: f64, valid: bool) { if a == nil { return } @@ -1480,6 +1634,7 @@ as_f64 :: proc(a: any) -> (value: f64, valid: bool) { } +// as_string attempts to convert an `any` to a `string`. @(require_results) as_string :: proc(a: any) -> (value: string, valid: bool) { if a == nil { return } @@ -1500,6 +1655,27 @@ as_string :: proc(a: any) -> (value: string, valid: bool) { return } +// as_string16 attempts to convert an `any` to a `string16`. +@(require_results) +as_string16 :: proc(a: any) -> (value: string16, valid: bool) { + if a == nil { return } + a := a + ti := runtime.type_info_core(type_info_of(a.id)) + a.id = ti.id + + #partial switch info in ti.variant { + case Type_Info_String: + valid = true + switch v in a { + case string16: value = v + case cstring16: value = string16(v) + case: valid = false + } + } + + return +} + @(require_results) relative_pointer_to_absolute_raw :: proc(data: rawptr, base_integer_id: typeid) -> rawptr { _handle :: proc(ptr: ^$T) -> rawptr where intrinsics.type_is_integer(T) { @@ -1543,6 +1719,8 @@ relative_pointer_to_absolute_raw :: proc(data: rawptr, base_integer_id: typeid) +// as_pointer attempts to convert an `any` to a `rawptr`. +// This only works for `^T`, `[^]T`, `cstring`, `cstring16` based types @(require_results) as_pointer :: proc(a: any) -> (value: rawptr, valid: bool) { if a == nil { return } @@ -1551,14 +1729,15 @@ as_pointer :: proc(a: any) -> (value: rawptr, valid: bool) { a.id = ti.id #partial switch info in ti.variant { - case Type_Info_Pointer: + case Type_Info_Pointer, Type_Info_Multi_Pointer: valid = true value = (^rawptr)(a.data)^ case Type_Info_String: valid = true switch v in a { - case cstring: value = rawptr(v) + case cstring: value = rawptr(v) + case cstring16: value = rawptr(v) case: valid = false } } @@ -1567,6 +1746,7 @@ as_pointer :: proc(a: any) -> (value: rawptr, valid: bool) { } +// Returns the equivalent of doing `raw_data(v)` where `v` is a non-any value @(require_results) as_raw_data :: proc(a: any) -> (value: rawptr, valid: bool) { if a == nil { return } @@ -1578,8 +1758,10 @@ as_raw_data :: proc(a: any) -> (value: rawptr, valid: bool) { case Type_Info_String: valid = true switch v in a { - case string: value = raw_data(v) - case cstring: value = rawptr(v) // just in case + case string: value = raw_data(v) + case cstring: value = rawptr(v) // just in case + case string16: value = raw_data(v) + case cstring16: value = rawptr(v) // just in case case: valid = false } @@ -1604,10 +1786,13 @@ ne :: not_equal DEFAULT_EQUAL_MAX_RECURSION_LEVEL :: 32 +// Checks to see if two `any` values are not semantically equivalent @(require_results) not_equal :: proc(a, b: any, including_indirect_array_recursion := false, recursion_level := 0) -> bool { return !equal(a, b, including_indirect_array_recursion, recursion_level) } + +// Checks to see if two `any` values are semantically equivalent @(require_results) equal :: proc(a, b: any, including_indirect_array_recursion := false, recursion_level := 0) -> bool { if a == nil && b == nil { @@ -1702,14 +1887,27 @@ equal :: proc(a, b: any, including_indirect_array_recursion := false, recursion_ return runtime.memory_compare(a.data, b.data, t.size) == 0 case Type_Info_String: - if v.is_cstring { - x := string((^cstring)(a.data)^) - y := string((^cstring)(b.data)^) - return x == y - } else { - x := (^string)(a.data)^ - y := (^string)(b.data)^ - return x == y + switch v.encoding { + case .UTF_8: + if v.is_cstring { + x := string((^cstring)(a.data)^) + y := string((^cstring)(b.data)^) + return x == y + } else { + x := (^string)(a.data)^ + y := (^string)(b.data)^ + return x == y + } + case .UTF_16: + if v.is_cstring { + x := string16((^cstring16)(a.data)^) + y := string16((^cstring16)(b.data)^) + return x == y + } else { + x := (^string16)(a.data)^ + y := (^string16)(b.data)^ + return x == y + } } return true case Type_Info_Array: diff --git a/core/reflect/types.odin b/core/reflect/types.odin index 98b7b368f..2e82e29b1 100644 --- a/core/reflect/types.odin +++ b/core/reflect/types.odin @@ -3,6 +3,10 @@ package reflect import "core:io" import "core:strings" + +// Returns true when the `^Type_Info`s are semantically equivalent types +// Note: The pointers being identical should be enough to check but this is done to make sure in certain cases where it is non-trivial +// and each value wants to be checked directly. @(require_results) are_types_identical :: proc(a, b: ^Type_Info) -> bool { if a == b { @@ -187,6 +191,7 @@ are_types_identical :: proc(a, b: ^Type_Info) -> bool { return false } +// Returns true if the base-type is a signed integer or just a float, false otherwise. @(require_results) is_signed :: proc(info: ^Type_Info) -> bool { if info == nil { return false } @@ -196,6 +201,7 @@ is_signed :: proc(info: ^Type_Info) -> bool { } return false } +// Returns true if the base-type is an usigned integer, false otherwise. @(require_results) is_unsigned :: proc(info: ^Type_Info) -> bool { if info == nil { return false } @@ -206,6 +212,7 @@ is_unsigned :: proc(info: ^Type_Info) -> bool { return false } +// Returns true when it is a 1-byte wide integer type, false otherwise. @(require_results) is_byte :: proc(info: ^Type_Info) -> bool { if info == nil { return false } @@ -216,78 +223,108 @@ is_byte :: proc(info: ^Type_Info) -> bool { } +// Returns true the base-type is an integer of any kind, false otherwise. @(require_results) is_integer :: proc(info: ^Type_Info) -> bool { if info == nil { return false } _, ok := type_info_base(info).variant.(Type_Info_Integer) return ok } +// Returns true the base-type is a rune, false otherwise. @(require_results) is_rune :: proc(info: ^Type_Info) -> bool { if info == nil { return false } _, ok := type_info_base(info).variant.(Type_Info_Rune) return ok } +// Returns true the base-type is a float of any kind, false otherwise. @(require_results) is_float :: proc(info: ^Type_Info) -> bool { if info == nil { return false } _, ok := type_info_base(info).variant.(Type_Info_Float) return ok } +// Returns true the base-type is a complex-type of any kind, false otherwise. @(require_results) is_complex :: proc(info: ^Type_Info) -> bool { if info == nil { return false } _, ok := type_info_base(info).variant.(Type_Info_Complex) return ok } +// Returns true the base-type is a quaternions any kind, false otherwise. @(require_results) is_quaternion :: proc(info: ^Type_Info) -> bool { if info == nil { return false } _, ok := type_info_base(info).variant.(Type_Info_Quaternion) return ok } +// Returns true the base-type is an `any`, false otherwise. @(require_results) is_any :: proc(info: ^Type_Info) -> bool { if info == nil { return false } _, ok := type_info_base(info).variant.(Type_Info_Any) return ok } + +// Returns true the base-type is a string of any kind (string, cstring, string16, cstring16), false otherwise. @(require_results) is_string :: proc(info: ^Type_Info) -> bool { if info == nil { return false } _, ok := type_info_base(info).variant.(Type_Info_String) return ok } +// Returns true the base-type is a cstring of any kind (cstring, cstring16), false otherwise. @(require_results) is_cstring :: proc(info: ^Type_Info) -> bool { if info == nil { return false } v, ok := type_info_base(info).variant.(Type_Info_String) return ok && v.is_cstring } + +// Returns true the base-type is a string of any kind (string16, cstring16), false otherwise. +@(require_results) +is_string16 :: proc(info: ^Type_Info) -> bool { + if info == nil { return false } + v, ok := type_info_base(info).variant.(Type_Info_String) + return ok && v.encoding == .UTF_16 +} +// Returns true the base-type is a cstring of any kind (cstring16), false otherwise. +@(require_results) +is_cstring16 :: proc(info: ^Type_Info) -> bool { + if info == nil { return false } + v, ok := type_info_base(info).variant.(Type_Info_String) + return ok && v.is_cstring && v.encoding == .UTF_16 +} + +// Returns true the base-type is a boolean of any kind, false otherwise. @(require_results) is_boolean :: proc(info: ^Type_Info) -> bool { if info == nil { return false } _, ok := type_info_base(info).variant.(Type_Info_Boolean) return ok } +// Returns true the base-type is a pointer-type of any kind (^T or rawptr), false otherwise. @(require_results) is_pointer :: proc(info: ^Type_Info) -> bool { if info == nil { return false } _, ok := type_info_base(info).variant.(Type_Info_Pointer) return ok } +// Returns true the base-type is a pointer-type of any kind ([^]T), false otherwise. @(require_results) is_multi_pointer :: proc(info: ^Type_Info) -> bool { if info == nil { return false } _, ok := type_info_base(info).variant.(Type_Info_Multi_Pointer) return ok } +// Returns true the base-type is a pointer-type of any kind (#soa^T), false otherwise. @(require_results) is_soa_pointer :: proc(info: ^Type_Info) -> bool { if info == nil { return false } _, ok := type_info_base(info).variant.(Type_Info_Soa_Pointer) return ok } +// Returns true when the type is a pointer-like type, false otherwise. @(require_results) is_pointer_internally :: proc(info: ^Type_Info) -> bool { if info == nil { return false } @@ -300,78 +337,91 @@ is_pointer_internally :: proc(info: ^Type_Info) -> bool { } return false } +// Returns true when the type is a procedure type, false otherwise. @(require_results) is_procedure :: proc(info: ^Type_Info) -> bool { if info == nil { return false } _, ok := type_info_base(info).variant.(Type_Info_Procedure) return ok } +// Returns true when the type is a fixed-array type ([N]T), false otherwise. @(require_results) is_array :: proc(info: ^Type_Info) -> bool { if info == nil { return false } _, ok := type_info_base(info).variant.(Type_Info_Array) return ok } +// Returns true when the type is an enumerated-array type ([Enum]T), false otherwise. @(require_results) is_enumerated_array :: proc(info: ^Type_Info) -> bool { if info == nil { return false } _, ok := type_info_base(info).variant.(Type_Info_Enumerated_Array) return ok } +// Returns true when the type is a dynamic-array type ([dynamic]T), false otherwise. @(require_results) is_dynamic_array :: proc(info: ^Type_Info) -> bool { if info == nil { return false } _, ok := type_info_base(info).variant.(Type_Info_Dynamic_Array) return ok } +// Returns true when the type is a map type (map[K]V), false otherwise. @(require_results) is_dynamic_map :: proc(info: ^Type_Info) -> bool { if info == nil { return false } _, ok := type_info_base(info).variant.(Type_Info_Map) return ok } +// Returns true when the type is a bit_set type, false otherwise. @(require_results) is_bit_set :: proc(info: ^Type_Info) -> bool { if info == nil { return false } _, ok := type_info_base(info).variant.(Type_Info_Bit_Set) return ok } +// Returns true when the type is a slice type ([]T), false otherwise. @(require_results) is_slice :: proc(info: ^Type_Info) -> bool { if info == nil { return false } _, ok := type_info_base(info).variant.(Type_Info_Slice) return ok } +// Returns true when the type represents a set of parameters for a procedure (inputs or outputs), false otherwise. @(require_results) is_parameters :: proc(info: ^Type_Info) -> bool { if info == nil { return false } _, ok := type_info_base(info).variant.(Type_Info_Parameters) return ok } +// Returns true when the type is a struct type, `#raw_union` will be false. All other types will be false otherwise. @(require_results) is_struct :: proc(info: ^Type_Info) -> bool { if info == nil { return false } s, ok := type_info_base(info).variant.(Type_Info_Struct) return ok && .raw_union not_in s.flags } +// Returns true when the type is a struct type with `#raw_union` applied, when `#raw_union` is not applied, the value will be false. All other types will be false otherwise. @(require_results) is_raw_union :: proc(info: ^Type_Info) -> bool { if info == nil { return false } s, ok := type_info_base(info).variant.(Type_Info_Struct) return ok && .raw_union in s.flags } +// Returns true when the type is a union type (not `#raw_union`), false otherwise. @(require_results) is_union :: proc(info: ^Type_Info) -> bool { if info == nil { return false } _, ok := type_info_base(info).variant.(Type_Info_Union) return ok } +// Returns true when the type is an enum type, false otherwise. @(require_results) is_enum :: proc(info: ^Type_Info) -> bool { if info == nil { return false } _, ok := type_info_base(info).variant.(Type_Info_Enum) return ok } +// Returns true when the type is a #simd-array type (#simd[N]T), false otherwise. @(require_results) is_simd_vector :: proc(info: ^Type_Info) -> bool { if info == nil { return false } @@ -380,6 +430,9 @@ is_simd_vector :: proc(info: ^Type_Info) -> bool { } +// Returns true when the core-type is represented with a platform-native endian type, and returns false otherwise. +// This will also return false when the type is not an integer, pointer, or bit_set. +// If the type is the same as the platform-native endian type (e.g. `u32le` on a little-endian system), this will return false. @(require_results) is_endian_platform :: proc(info: ^Type_Info) -> bool { if info == nil { return false} @@ -399,6 +452,9 @@ is_endian_platform :: proc(info: ^Type_Info) -> bool { return false } +// Returns true when the core-type is represented with a platform-native endian type or the same endianness as the system. +// This will also return false when the type is not an integer, pointer, or bit_set. +// If the type is the same as the platform-native endian type (e.g. `u32le` on a little-endian system), this will return true. @(require_results) is_endian_little :: proc(info: ^Type_Info) -> bool { if info == nil { return false} @@ -421,6 +477,9 @@ is_endian_little :: proc(info: ^Type_Info) -> bool { return ODIN_ENDIAN == .Little } +// Returns true when the core-type is represented with a platform-native endian type or the same endianness as the system. +// This will also return false when the type is not an integer, pointer, or bit_set. +// If the type is the same as the platform-native endian type (e.g. `u32be` on a big-endian system), this will return true. @(require_results) is_endian_big :: proc(info: ^Type_Info) -> bool { if info == nil { return false} @@ -446,27 +505,33 @@ is_endian_big :: proc(info: ^Type_Info) -> bool { +// Writes a typeid in standard (non-canonical) form to a `strings.Builder` write_typeid_builder :: proc(buf: ^strings.Builder, id: typeid, n_written: ^int = nil) -> (n: int, err: io.Error) { return write_type_writer(strings.to_writer(buf), type_info_of(id)) } +// Writes a typeid in standard (non-canonical) form to an `io.Writer` write_typeid_writer :: proc(writer: io.Writer, id: typeid, n_written: ^int = nil) -> (n: int, err: io.Error) { return write_type_writer(writer, type_info_of(id), n_written) } +// Writes a typeid in standard (non-canonical) form write_typeid :: proc{ write_typeid_builder, write_typeid_writer, } +// Writes a `^Type_Info` in standard (non-canonical) form write_type :: proc{ write_type_builder, write_type_writer, } +// Writes a `^Type_Info` in standard (non-canonical) form to a `strings.Builder` write_type_builder :: proc(buf: ^strings.Builder, ti: ^Type_Info) -> int { n, _ := write_type_writer(strings.to_writer(buf), ti) return n } +// Writes a `^Type_Info` in standard (non-canonical) form to an `io.Writer` write_type_writer :: #force_no_inline proc(w: io.Writer, ti: ^Type_Info, n_written: ^int = nil) -> (n: int, err: io.Error) { defer if n_written != nil { n_written^ += n diff --git a/core/relative/relative.odin b/core/relative/relative.odin index 30a7b86ae..791ac6f7d 100644 --- a/core/relative/relative.odin +++ b/core/relative/relative.odin @@ -1,3 +1,4 @@ +// Relative pointers and slices. package relative_types import "base:intrinsics" diff --git a/core/simd/simd.odin b/core/simd/simd.odin index 303eceb97..bca661757 100644 --- a/core/simd/simd.odin +++ b/core/simd/simd.odin @@ -1,5 +1,5 @@ /* -The SIMD support package. +Cross-platform `SIMD` support types and procedures. SIMD (Single Instruction Multiple Data), is a CPU hardware feature that introduce special registers and instructions which operate on multiple units @@ -271,7 +271,7 @@ Inputs: Returns: - A vector that is the sum of two input vectors. -**Operation**: +Operation: for i in 0 ..< len(res) { res[i] = a[i] + b[i] @@ -307,7 +307,7 @@ Inputs: Returns: - A vector that is the difference of two vectors, `a` - `b`. -**Operation**: +Operation: for i in 0 ..< len(res) { res[i] = a[i] - b[i] @@ -342,7 +342,7 @@ Inputs: Returns: - A vector that is the product of two vectors. -**Operation**: +Operation: for i in 0 ..< len(res) { res[i] = a[i] * b[i] @@ -380,7 +380,7 @@ Inputs: Returns: - A vector that is the quotient of two vectors, `a` / `b`. -**Operation**: +Operation: for i in 0 ..< len(res) { res[i] = a[i] / b[i] @@ -420,7 +420,7 @@ Result: - A vector, where each lane is the lane from `a` shifted left by the amount specified in the corresponding lane of the vector `b`. -**Operation**: +Operation: for i in 0 ..< len(res) { if b[i] < 8*size_of(a[i]) { @@ -470,7 +470,7 @@ Result: - A vector, where each lane is the lane from `a` shifted right by the amount specified in the corresponding lane of the vector `b`. -**Operation**: +Operation: for i in 0 ..< len(res) { if b[i] < 8*size_of(a[i]) { @@ -515,7 +515,7 @@ Result: - A vector, where each lane is the lane from `a` shifted left by the amount specified in the corresponding lane of the vector `b`. -**Operation**: +Operation: for i in 0 ..< len(res) { mask := 8*size_of(a[i]) - 1 @@ -561,7 +561,7 @@ Result: - A vector, where each lane is the lane from `a` shifted right by the amount specified in the corresponding lane of the vector `b`. -**Operation**: +Operation: for i in 0 ..< len(res) { mask := 8*size_of(a[i]) - 1 @@ -604,7 +604,7 @@ Inputs: Returns: - The saturated sum of the two vectors. -**Operation**: +Operation: for i in 0 ..< len(res) { switch { @@ -653,7 +653,7 @@ Inputs: Returns: - The saturated difference of the two vectors. -**Operation**: +Operation: for i in 0 ..< len(res) { switch { @@ -697,7 +697,7 @@ Inputs: Returns: - A vector that is the result of the bitwise AND operation between two vectors. -**Operation**: +Operation: for i in 0 ..< len(res) { res[i] = a[i] & b[i] @@ -732,7 +732,7 @@ Inputs: Returns: - A vector that is the result of the bitwise OR operation between two vectors. -**Operation**: +Operation: for i in 0 ..< len(res) { res[i] = a[i] | b[i] @@ -767,7 +767,7 @@ Inputs: Returns: - A vector that is the result of the bitwise XOR operation between two vectors. -**Operation**: +Operation: for i in 0 ..< len(res) { res[i] = a[i] ~ b[i] @@ -802,7 +802,7 @@ Inputs: Returns: - A vector that is the result of the bitwise AND NOT operation between two vectors. -**Operation**: +Operation: for i in 0 ..< len(res) { res[i] = a[i] &~ b[i] @@ -836,7 +836,7 @@ Inputs: Returns: - The negated version of the vector `a`. -**Operation**: +Operation: for i in 0 ..< len(res) { res[i] = -a[i] @@ -867,7 +867,7 @@ Inputs: Returns: - The absolute value of a vector. -**Operation**: +Operation: for i in 0 ..< len(res) { switch { @@ -903,7 +903,7 @@ Inputs: Returns: - A vector containing with minimum values from corresponding lanes of `a` and `b`. -**Operation**: +Operation: for i in 0 ..< len(res) { if a[i] < b[i] { @@ -942,7 +942,7 @@ Inputs: Returns: - A vector containing with maximum values from corresponding lanes of `a` and `b`. -**Operation**: +Operation: for i in 0 ..< len(res) { if a[i] > b[i] { @@ -983,7 +983,7 @@ Inputs: Returns: - A vector containing clamped values in each lane. -**Operation**: +Operation: for i in 0 ..< len(res) { val := v[i] @@ -1029,7 +1029,7 @@ Returns: - A vector of unsigned integers of the same size as the input vector's lanes, containing the comparison results for each lane. -**Operation**: +Operation: for i in 0 ..< len(res) { if a[i] == b[i] { @@ -1071,7 +1071,7 @@ Returns: - A vector of unsigned integers of the same size as the input vector's lanes, containing the comparison results for each lane. -**Operation**: +Operation: for i in 0 ..< len(res) { if a[i] != b[i] { @@ -1113,7 +1113,7 @@ Returns: - A vector of unsigned integers of the same size as the input vector's lanes, containing the comparison results for each lane. -**Operation**: +Operation: for i in 0 ..< len(res) { if a[i] < b[i] { @@ -1156,7 +1156,7 @@ Returns: - A vector of unsigned integers of the same size as the input vector's lanes, containing the comparison results for each lane. -**Operation**: +Operation: for i in 0 ..< len(res) { if a[i] <= b[i] { @@ -1199,7 +1199,7 @@ Returns: - A vector of unsigned integers of the same size as the input vector's lanes, containing the comparison results for each lane. -**Operation**: +Operation: for i in 0 ..< len(res) { if a[i] > b[i] { @@ -1242,7 +1242,7 @@ Returns: - A vector of unsigned integers of the same size as the input vector's lanes, containing the comparison results for each lane. -**Operation**: +Operation: for i in 0 ..< len(res) { if a[i] >= b[i] { @@ -1301,7 +1301,7 @@ Returns: loaded from the pointer vector `ptr`, and all values from masked indices loaded from the value vector `val`. -**Operation**: +Operation: for i in 0 ..< len(res) { if mask[i]&1 == 1 { @@ -1384,7 +1384,7 @@ Inputs: set), the corresponding lane is written into memory. Otherwise it's not written into memory. -**Operation**: +Operation: for i in 0 ..< len(ptr) { if mask[i]&1 == 1 { @@ -1457,7 +1457,7 @@ Returns: - The loaded vector. The lanes for which the mask was set are loaded from memory, and the other lanes are loaded from the `val` vector. -**Operation**: +Operation: for i in 0 ..< len(res) { if mask[i]&1 == 1 { @@ -1525,7 +1525,7 @@ Inputs: - `val`: The vector to store. - `mask`: The mask, selecting which lanes of the vector to store into memory. -**Operation**: +Operation: for i in 0 ..< len(val) { if mask[i]&1 == 1 { @@ -1594,7 +1594,7 @@ Inputs: Returns: - The result vector, holding masked memory values unmasked default values. -**Operation**: +Operation: mem_idx := 0 for i in 0 ..< len(mask) { @@ -1667,7 +1667,7 @@ Inputs: - `val`: The vector to store into memory. - `mask`: The mask that selects which values to store into memory. -**Operation**: +Operation: mem_idx := 0 for i in 0 ..< len(mask) { @@ -1729,7 +1729,7 @@ Inputs: Returns: - The value of the lane at the specified index. -**Operation**: +Operation: return a[idx] */ @@ -1749,7 +1749,7 @@ Inputs: Returns: - Vector with the specified lane replaced. -**Operation**: +Operation: a[idx] = elem */ @@ -1775,7 +1775,7 @@ Inputs: Result: - Sum of all lanes, as a scalar. -**Operation**: +Operation: for n > 1 { n = n / 2 @@ -1823,7 +1823,7 @@ Inputs: Result: - Product of all lanes, as a scalar. -**Operation**: +Operation: for n > 1 { n = n / 2 @@ -1865,7 +1865,7 @@ Inputs: Result: - Sum of all lanes, as a scalar. -**Operation**: +Operation: res := 0 for i in 0 ..< len(a) { @@ -1888,7 +1888,7 @@ Inputs: Result: - Product of all lanes, as a scalar. -**Operation**: +Operation: res := 1 for i in 0 ..< len(a) { @@ -1916,7 +1916,7 @@ Inputs: Result: - Sum of all lanes, as a scalar. -**Operation**: +Operation: for n > 1 { n = n / 2 @@ -1964,7 +1964,7 @@ Inputs: Result: - Product of all lanes, as a scalar. -**Operation**: +Operation: for n > 1 { n = n / 2 @@ -2003,7 +2003,7 @@ Inputs: Result: - Minimum value of all lanes, as a scalar. -**Operation**: +Operation: res := 0 for i in 0 ..< len(a) { @@ -2024,7 +2024,7 @@ Inputs: Result: - Maximum value of all lanes, as a scalar. -**Operation**: +Operation: res := 0 for i in 0 ..< len(a) { @@ -2045,7 +2045,7 @@ Inputs: Result: - Bitwise AND of all lanes, as a scalar. -**Operation**: +Operation: res := 0 for i in 0 ..< len(a) { @@ -2066,7 +2066,7 @@ Inputs: Result: - Bitwise OR of all lanes, as a scalar. -**Operation**: +Operation: res := 0 for i in 0 ..< len(a) { @@ -2087,7 +2087,7 @@ Inputs: Result: - Bitwise XOR of all lanes, as a scalar. -**Operation**: +Operation: res := 0 for i in 0 ..< len(a) { @@ -2108,7 +2108,7 @@ Inputs: Result: - Bitwise OR of all lanes, as a scalar. -**Operation**: +Operation: res := 0 for i in 0 ..< len(a) { @@ -2129,7 +2129,7 @@ Inputs: Result: - Bitwise AND of all lanes, as a scalar. -**Operation**: +Operation: res := 0 for i in 0 ..< len(a) { @@ -2154,7 +2154,7 @@ Inputs: Result: - Swizzled input vector. -**Operation**: +Operation: res = {} for i in 0 ..< len(indices) { @@ -2220,7 +2220,7 @@ Result: - A bitset of integers, corresponding to the indexes of the lanes, whose MSBs are set. -**Operation**: +Operation: bits_per_lane = 8*size_of(a[0]) res = bit_set {} @@ -2266,7 +2266,7 @@ Result: - A bitset of integers, corresponding to the indexes of the lanes, whose LSBs are set. -**Operation**: +Operation: res = bit_set {} for i in 0 ..< len(a) { @@ -2314,7 +2314,7 @@ Inputs: Result: - Input vectors, shuffled according to the indices. -**Operation**: +Operation: res = {} for i in 0 ..< len(indices) { @@ -2386,7 +2386,7 @@ Inputs: Result: - The result of selecting values from the two input vectors. -**Operation**: +Operation: res = {} for i in 0 ..< len(cond) { @@ -2672,7 +2672,7 @@ Perform binary not operation on a SIMD vector. This procedure returns a vector where each lane is the result of the binary NOT operation of the corresponding lane in the vector `a`. -**Operation**: +Operation: for i in 0 ..< len(res) { res[i] = ~a[i] @@ -2728,7 +2728,7 @@ Inputs: Returns: - Negated vector. -**Operation**: +Operation: for i in 0 ..< len(res) { res[i] = 1.0 / a[i] @@ -2756,7 +2756,7 @@ Inputs: - `V`: The type of the vector to create. Result: - A vector of the given type, where each lane contains the index of that lane. -**Operation**: +Operation: for i in 0 ..< N { res[i] = i } diff --git a/core/simd/x86/doc.odin b/core/simd/x86/doc.odin new file mode 100644 index 000000000..dcdc30abd --- /dev/null +++ b/core/simd/x86/doc.odin @@ -0,0 +1,2 @@ +// `SIMD` intrinsics specific to the Intel `x86` and `AMD64` architectures. +package simd_x86 \ No newline at end of file diff --git a/core/slice/heap/heap.odin b/core/slice/heap/heap.odin index 7480a1673..dd088f250 100644 --- a/core/slice/heap/heap.odin +++ b/core/slice/heap/heap.odin @@ -1,3 +1,6 @@ +// A generic in-place max heap on a slice for any type. +package heap + /* Copyright 2022 Dale Weiler . Made available under Odin's BSD-3 license. @@ -6,9 +9,6 @@ Dale Weiler: Initial implementation */ -// Package implements a generic max heap in-place on a slice for any type. -package heap - /* Constructs a max heap in slice given by data with comparator. A max heap is a range of elements which has the following properties: diff --git a/core/slice/ptr.odin b/core/slice/ptr.odin index 99d4157c3..b52853375 100644 --- a/core/slice/ptr.odin +++ b/core/slice/ptr.odin @@ -3,14 +3,14 @@ package slice import "base:builtin" import "base:runtime" -ptr_add :: proc(p: $P/^$T, x: int) -> ^T { +ptr_add :: proc "contextless" (p: $P/^$T, x: int) -> ^T { return ([^]T)(p)[x:] } -ptr_sub :: proc(p: $P/^$T, x: int) -> ^T { +ptr_sub :: proc "contextless" (p: $P/^$T, x: int) -> ^T { return ([^]T)(p)[-x:] } -ptr_swap_non_overlapping :: proc(x, y: rawptr, len: int) { +ptr_swap_non_overlapping :: proc "contextless" (x, y: rawptr, len: int) { if len <= 0 { return } @@ -44,7 +44,7 @@ ptr_swap_non_overlapping :: proc(x, y: rawptr, len: int) { } } -ptr_swap_overlapping :: proc(x, y: rawptr, len: int) { +ptr_swap_overlapping :: proc "contextless" (x, y: rawptr, len: int) { if len <= 0 { return } @@ -68,7 +68,7 @@ ptr_swap_overlapping :: proc(x, y: rawptr, len: int) { } -ptr_rotate :: proc(left: int, mid: ^$T, right: int) { +ptr_rotate :: proc "contextless" (left: int, mid: ^$T, right: int) { when size_of(T) != 0 { left, mid, right := left, mid, right diff --git a/core/slice/slice.odin b/core/slice/slice.odin index 8337a9728..0d0cadefa 100644 --- a/core/slice/slice.odin +++ b/core/slice/slice.odin @@ -1,3 +1,4 @@ +// Utility procedures for working with slices, including sorting and searching them. package slice import "base:intrinsics" diff --git a/core/slice/sort.odin b/core/slice/sort.odin index 3b4119afa..1e2a8ff59 100644 --- a/core/slice/sort.odin +++ b/core/slice/sort.odin @@ -6,6 +6,8 @@ Ordering :: enum { Greater = +1, } +Generic_Cmp :: #type proc(lhs, rhs: rawptr, user_data: rawptr) -> Ordering + @(require_results) cmp :: proc(a, b: $E) -> Ordering where ORD(E) { switch { @@ -35,7 +37,16 @@ cmp_proc :: proc($E: typeid) -> (proc(E, E) -> Ordering) where ORD(E) { sort :: proc(data: $T/[]$E) where ORD(E) { when size_of(E) != 0 { if n := len(data); n > 1 { - _quick_sort_general(data, 0, n, _max_depth(n), struct{}{}, .Ordered) + raw := ([^]byte)(raw_data(data)) + _smoothsort(raw, uint(len(data)), size_of(E), proc(lhs, rhs: rawptr, user_data: rawptr) -> Ordering { + x, y := (^E)(lhs)^, (^E)(rhs)^ + if x < y { + return .Less + } else if x > y { + return .Greater + } + return .Equal + }, nil) } } } @@ -70,6 +81,23 @@ sort_by_indices_overwrite :: proc(data: $T/[]$E, indices: []int) { swap_with_slice(data, temp) } +sort_from_permutation_indices :: proc(data: $T/[]$E, indices: []int) { + assert(len(data) == len(indices)) + if len(indices) <= 1 { + return + } + + for i in 0.. (indices: []int) where ORD(E) { @@ -79,7 +107,22 @@ sort_with_indices :: proc(data: $T/[]$E, allocator := context.allocator) -> (ind for _, idx in indices { indices[idx] = idx } - _quick_sort_general_with_indices(data, indices, 0, n, _max_depth(n), struct{}{}, .Ordered) + + raw := ([^]byte)(raw_data(indices)) + _smoothsort(raw, uint(len(indices)), size_of(int), proc(lhs, rhs: rawptr, user_data: rawptr) -> Ordering { + data := ([^]E)(user_data) + + xi, yi := (^int)(lhs)^, (^int)(rhs)^ + #no_bounds_check x, y := data[xi], data[yi] + if x < y { + return .Less + } else if x > y { + return .Greater + } + return .Equal + }, raw_data(data)) + + sort_from_permutation_indices(data, indices) } return indices } @@ -91,7 +134,39 @@ sort_with_indices :: proc(data: $T/[]$E, allocator := context.allocator) -> (ind sort_by :: proc(data: $T/[]$E, less: proc(i, j: E) -> bool) { when size_of(E) != 0 { if n := len(data); n > 1 { - _quick_sort_general(data, 0, n, _max_depth(n), less, .Less) + raw := ([^]byte)(raw_data(data)) + _smoothsort(raw, uint(len(data)), size_of(E), proc(lhs, rhs: rawptr, user_data: rawptr) -> Ordering { + x, y := (^E)(lhs)^, (^E)(rhs)^ + less := (proc(E, E) -> bool)(user_data) + switch { + case less(x, y): return .Less + case less(y, x): return .Greater + } + return .Equal + }, rawptr(less)) + } + } +} + +sort_by_with_data :: proc(data: $T/[]$E, less: proc(i, j: E, user_data: rawptr) -> bool, user_data: rawptr) { + when size_of(E) != 0 { + if n := len(data); n > 1 { + Context :: struct { + less: proc(i, j: E, user_data: rawptr) -> bool, + user_data: rawptr, + } + ctx := &Context{less, user_data} + + raw := ([^]byte)(raw_data(data)) + _smoothsort(raw, uint(len(data)), size_of(E), proc(lhs, rhs: rawptr, user_data: rawptr) -> Ordering { + x, y := (^E)(lhs)^, (^E)(rhs)^ + ctx := (^Context)(user_data) + switch { + case ctx.less(x, y, ctx.user_data): return .Less + case ctx.less(y, x, ctx.user_data): return .Greater + } + return .Equal + }, ctx) } } } @@ -105,8 +180,59 @@ sort_by_with_indices :: proc(data: $T/[]$E, less: proc(i, j: E) -> bool, allocat for _, idx in indices { indices[idx] = idx } - _quick_sort_general_with_indices(data, indices, 0, n, _max_depth(n), less, .Less) - return indices + + Context :: struct{ + less: proc(i, j: E) -> bool, + data: T, + } + ctx := &Context{less, data} + + raw := ([^]byte)(raw_data(indices)) + _smoothsort(raw, uint(len(indices)), size_of(int), proc(lhs, rhs: rawptr, user_data: rawptr) -> Ordering { + ctx := (^Context)(user_data) + xi, yi := (^int)(lhs)^, (^int)(rhs)^ + x, y := ctx.data[xi], ctx.data[yi] + switch { + case ctx.less(x, y): return .Less + case ctx.less(y, x): return .Greater + } + return .Equal + }, ctx) + + sort_from_permutation_indices(data, indices) + } + } + return indices +} + +sort_by_with_indices_with_data :: proc(data: $T/[]$E, less: proc(i, j: E, user_data: rawptr) -> bool, user_data: rawptr, allocator := context.allocator) -> (indices : []int) { + indices = make([]int, len(data), allocator) + when size_of(E) != 0 { + if n := len(data); n > 1 { + for _, idx in indices { + indices[idx] = idx + } + + Context :: struct{ + less: proc(i, j: E, user_data: rawptr) -> bool, + data: T, + user_data: rawptr, + } + ctx := &Context{less, data, user_data} + + raw := ([^]byte)(raw_data(indices)) + _smoothsort(raw, uint(len(indices)), size_of(int), proc(lhs, rhs: rawptr, user_data: rawptr) -> Ordering { + ctx := (^Context)(user_data) + xi, yi := (^int)(lhs)^, (^int)(rhs)^ + x, y := ctx.data[xi], ctx.data[yi] + switch { + case ctx.less(x, y, ctx.user_data): return .Less + case ctx.less(y, x, ctx.user_data): return .Greater + } + return .Equal + }, ctx) + + sort_from_permutation_indices(data, indices) } } return indices @@ -115,11 +241,47 @@ sort_by_with_indices :: proc(data: $T/[]$E, less: proc(i, j: E) -> bool, allocat sort_by_cmp :: proc(data: $T/[]$E, cmp: proc(i, j: E) -> Ordering) { when size_of(E) != 0 { if n := len(data); n > 1 { - _quick_sort_general(data, 0, n, _max_depth(n), cmp, .Cmp) + raw := ([^]byte)(raw_data(data)) + _smoothsort(raw, uint(len(data)), size_of(E), proc(lhs, rhs: rawptr, user_data: rawptr) -> Ordering { + x, y := (^E)(lhs)^, (^E)(rhs)^ + cmp := cast(proc(E, E) -> Ordering)(user_data) + return cmp(x, y) + }, rawptr(cmp)) } } } + +sort_by_cmp_with_data :: proc(data: $T/[]$E, cmp: proc(i, j: E, user_data: rawptr) -> Ordering, user_data: rawptr) { + when size_of(E) != 0 { + if n := len(data); n > 1 { + Context :: struct{ + cmp: proc(i, j: E, user_data: rawptr) -> Ordering, + user_data: rawptr, + } + ctx := &Context{cmp, user_data} + + raw := ([^]byte)(raw_data(data)) + _smoothsort(raw, uint(len(data)), size_of(E), proc(lhs, rhs: rawptr, user_data: rawptr) -> Ordering { + x, y := (^E)(lhs)^, (^E)(rhs)^ + ctx := (^Context)(user_data) + return ctx.cmp(x, y, ctx.user_data) + }, ctx) + } + } +} + + +sort_by_generic_cmp :: proc(data: $T/[]$E, cmp: Generic_Cmp, user_data: rawptr) { + when size_of(E) != 0 { + if n := len(data); n > 1 { + raw := ([^]byte)(raw_data(data)) + _smoothsort(raw, uint(len(data)), size_of(E), cmp, user_data) + } + } +} + + // stable_sort sorts a slice stable_sort :: proc(data: $T/[]$E) where ORD(E) { when size_of(E) != 0 { @@ -188,37 +350,59 @@ reverse_sort :: proc(data: $T/[]$E) where ORD(E) { reverse_sort_by :: proc(data: $T/[]$E, less: proc(i, j: E) -> bool) { - context._internal = rawptr(less) - sort_by(data, proc(i, j: E) -> bool { - k := (proc(i, j: E) -> bool)(context._internal) - return k(j, i) - }) + sort_by_with_data(data, proc(i, j: E, user_data: rawptr) -> bool { + less := (proc(E, E) -> bool)(user_data) + return less(j, i) + }, rawptr(less)) } reverse_sort_by_cmp :: proc(data: $T/[]$E, cmp: proc(i, j: E) -> Ordering) { - context._internal = rawptr(cmp) - sort_by_cmp(data, proc(i, j: E) -> Ordering { - k := (proc(i, j: E) -> Ordering)(context._internal) + sort_by_cmp_with_data(data, proc(i, j: E, user_data: rawptr) -> Ordering { + k := (proc(i, j: E) -> Ordering)(user_data) return k(j, i) - }) + }, rawptr(data)) } // TODO(bill): Should `sort_by_key` exist or is `sort_by` more than enough? sort_by_key :: proc(data: $T/[]$E, key: proc(E) -> $K) where ORD(K) { - context._internal = rawptr(key) - sort_by(data, proc(i, j: E) -> bool { - k := (proc(E) -> K)(context._internal) - return k(i) < k(j) - }) + Context :: struct { + key: proc(E) -> K, + } + ctx := &Context{key} + + sort_by_generic_cmp(data, proc(lhs, rhs: rawptr, user_data: rawptr) -> Ordering { + i, j := (^E)(lhs)^, (^E)(rhs)^ + + ctx := (^Context)(user_data) + a := ctx.key(i) + b := ctx.key(j) + switch { + case a < b: return .Less + case a > b: return .Greater + } + return .Equal + }, ctx) } reverse_sort_by_key :: proc(data: $T/[]$E, key: proc(E) -> $K) where ORD(K) { - context._internal = rawptr(key) - sort_by(data, proc(i, j: E) -> bool { - k := (proc(E) -> K)(context._internal) - return k(j) < k(i) - }) + Context :: struct { + key: proc(E) -> K, + } + ctx := &Context{key} + + sort_by_generic_cmp(data, proc(lhs, rhs: rawptr, user_data: rawptr) -> Ordering { + i, j := (^E)(lhs)^, (^E)(rhs)^ + + ctx := (^Context)(user_data) + a := ctx.key(i) + b := ctx.key(j) + switch { + case a < b: return .Greater + case a > b: return .Less + } + return .Equal + }, ctx) } @(require_results) @@ -229,12 +413,4 @@ is_sorted_by_key :: proc(array: $T/[]$E, key: proc(E) -> $K) -> bool where ORD(K } } return true -} - -@(private, require_results) -_max_depth :: proc(n: int) -> (depth: int) { // 2*ceil(log2(n+1)) - for i := n; i > 0; i >>= 1 { - depth += 1 - } - return depth * 2 -} +} \ No newline at end of file diff --git a/core/slice/sort_private.odin b/core/slice/sort_private.odin index 36637c4cd..efa9c596b 100644 --- a/core/slice/sort_private.odin +++ b/core/slice/sort_private.odin @@ -1,6 +1,7 @@ #+private package slice +import "base:builtin" import "base:intrinsics" _ :: intrinsics @@ -12,171 +13,6 @@ Sort_Kind :: enum { Cmp, } -_quick_sort_general :: proc(data: $T/[]$E, a, b, max_depth: int, call: $P, $KIND: Sort_Kind) where (ORD(E) && KIND == .Ordered) || (KIND != .Ordered) #no_bounds_check { - less :: #force_inline proc(a, b: E, call: P) -> bool { - when KIND == .Ordered { - return a < b - } else when KIND == .Less { - return call(a, b) - } else when KIND == .Cmp { - return call(a, b) == .Less - } else { - #panic("unhandled Sort_Kind") - } - } - - insertion_sort :: proc(data: $T/[]$E, a, b: int, call: P) #no_bounds_check { - for i in a+1.. a && less(data[j], data[j-1], call); j -= 1 { - swap(data, j, j-1) - } - } - } - - heap_sort :: proc(data: $T/[]$E, a, b: int, call: P) #no_bounds_check { - sift_down :: proc(data: T, lo, hi, first: int, call: P) #no_bounds_check { - root := lo - for { - child := 2*root + 1 - if child >= hi { - break - } - if child+1 < hi && less(data[first+child], data[first+child+1], call) { - child += 1 - } - if !less(data[first+root], data[first+child], call) { - return - } - swap(data, first+root, first+child) - root = child - } - } - - - first, lo, hi := a, 0, b-a - - for i := (hi-1)/2; i >= 0; i -= 1 { - sift_down(data, i, hi, first, call) - } - - for i := hi-1; i >= 0; i -= 1 { - swap(data, first, first+i) - sift_down(data, lo, i, first, call) - } - } - - median3 :: proc(data: T, m1, m0, m2: int, call: P) #no_bounds_check { - if less(data[m1], data[m0], call) { - swap(data, m1, m0) - } - if less(data[m2], data[m1], call) { - swap(data, m2, m1) - if less(data[m1], data[m0], call) { - swap(data, m1, m0) - } - } - } - - do_pivot :: proc(data: T, lo, hi: int, call: P) -> (midlo, midhi: int) #no_bounds_check { - m := int(uint(lo+hi)>>1) - if hi-lo > 40 { - s := (hi-lo)/8 - median3(data, lo, lo+s, lo+s*2, call) - median3(data, m, m-s, m+s, call) - median3(data, hi-1, hi-1-s, hi-1-s*2, call) - } - median3(data, lo, m, hi-1, call) - - pivot := lo - a, c := lo+1, hi-1 - - - for ; a < c && less(data[a], data[pivot], call); a += 1 { - } - b := a - - for { - for ; b < c && !less(data[pivot], data[b], call); b += 1 { // data[b] <= pivot - } - for ; b < c && less(data[pivot], data[c-1], call); c -=1 { // data[c-1] > pivot - } - if b >= c { - break - } - - swap(data, b, c-1) - b += 1 - c -= 1 - } - - protect := hi-c < 5 - if !protect && hi-c < (hi-lo)/4 { - dups := 0 - if !less(data[pivot], data[hi-1], call) { - swap(data, c, hi-1) - c += 1 - dups += 1 - } - if !less(data[b-1], data[pivot], call) { - b -= 1 - dups += 1 - } - - if !less(data[m], data[pivot], call) { - swap(data, m, b-1) - b -= 1 - dups += 1 - } - protect = dups > 1 - } - if protect { - for { - for ; a < b && !less(data[b-1], data[pivot], call); b -= 1 { - } - for ; a < b && less(data[a], data[pivot], call); a += 1 { - } - if a >= b { - break - } - swap(data, a, b-1) - a += 1 - b -= 1 - } - } - swap(data, pivot, b-1) - return b-1, c - } - - - a, b, max_depth := a, b, max_depth - - for b-a > 12 { // only use shell sort for lengths <= 12 - if max_depth == 0 { - heap_sort(data, a, b, call) - return - } - max_depth -= 1 - mlo, mhi := do_pivot(data, a, b, call) - if mlo-a < b-mhi { - _quick_sort_general(data, a, mlo, max_depth, call, KIND) - a = mhi - } else { - _quick_sort_general(data, mhi, b, max_depth, call, KIND) - b = mlo - } - } - if b-a > 1 { - // Shell short with gap 6 - for i in a+6.. bool { when KIND == .Ordered { @@ -200,179 +36,181 @@ _stable_sort_general :: proc(data: $T/[]$E, call: $P, $KIND: Sort_Kind) where (O } } -_quick_sort_general_with_indices :: proc(data: $T/[]$E, indices: []int, a, b, max_depth: int, call: $P, $KIND: Sort_Kind) where (ORD(E) && KIND == .Ordered) || (KIND != .Ordered) #no_bounds_check { - less :: #force_inline proc(a, b: E, call: P) -> bool { - when KIND == .Ordered { - return a < b - } else when KIND == .Less { - return call(a, b) - } else when KIND == .Cmp { - return call(a, b) == .Less - } else { - #panic("unhandled Sort_Kind") +@(private) +_smoothsort :: proc(base: [^]byte, nel: uint, width: uint, cmp: Generic_Cmp, arg: rawptr) { + pntz :: proc "contextless" (p: [2]uint) -> int { + r := intrinsics.count_trailing_zeros(p[0] - 1) + if r != 0 { + return int(r) } + r = (8*size_of(uint) + intrinsics.count_trailing_zeros(p[1])) + if r != 8*size_of(uint) { + return int(r) + } + return 0 } - insertion_sort :: proc(data: $T/[]$E, indices: []int, a, b: int, call: P) #no_bounds_check { - for i in a+1.. a && less(data[j], data[j-1], call); j -= 1 { - swap(data, j, j-1) - swap(indices, j, j-1) - } + shl :: proc "contextless" (p: []uint, n: int) { + n := n + if n >= 8*size_of(uint) { + n -= 8*size_of(uint) + p[1] = p[0] + p[0] = 0 } + p[1] <<= uint(n) + p[0] |= p[0] >> uint(8*size_of(uint) - n) + p[0] <<= uint(n) + } + shr :: proc "contextless" (p: []uint, n: int) { + n := n + if n >= 8*size_of(uint) { + n -= 8*size_of(uint) + p[0] = p[1] + p[1] = 0 + } + p[0] >>= uint(n) + p[0] |= p[1] << uint(8*size_of(uint) - n) + p[1] >>= uint(n) } - heap_sort :: proc(data: $T/[]$E, indices: []int, a, b: int, call: P) #no_bounds_check { - sift_down :: proc(data: T, indices: []int, lo, hi, first: int, call: P) #no_bounds_check { - root := lo - for { - child := 2*root + 1 - if child >= hi { - break - } - if child+1 < hi && less(data[first+child], data[first+child+1], call) { - child += 1 - } - if !less(data[first+root], data[first+child], call) { - return - } - swap(data, first+root, first+child) - swap(indices, first+root, first+child) - root = child - } - } - - - first, lo, hi := a, 0, b-a - - for i := (hi-1)/2; i >= 0; i -= 1 { - sift_down(data, indices, i, hi, first, call) - } - - for i := hi-1; i >= 0; i -= 1 { - swap(data, first, first+i) - swap(indices, first, first+i) - sift_down(data, indices, lo, i, first, call) - } - } - - median3 :: proc(data: T, indices: []int, m1, m0, m2: int, call: P) #no_bounds_check { - if less(data[m1], data[m0], call) { - swap(data, m1, m0) - swap(indices, m1, m0) - } - if less(data[m2], data[m1], call) { - swap(data, m2, m1) - swap(indices, m2, m1) - if less(data[m1], data[m0], call) { - swap(data, m1, m0) - swap(indices, m1, m0) - } - } - } - - do_pivot :: proc(data: T, indices: []int, lo, hi: int, call: P) -> (midlo, midhi: int) #no_bounds_check { - m := int(uint(lo+hi)>>1) - if hi-lo > 40 { - s := (hi-lo)/8 - median3(data, indices, lo, lo+s, lo+s*2, call) - median3(data, indices, m, m-s, m+s, call) - median3(data, indices, hi-1, hi-1-s, hi-1-s*2, call) - } - median3(data, indices, lo, m, hi-1, call) - - pivot := lo - a, c := lo+1, hi-1 - - - for ; a < c && less(data[a], data[pivot], call); a += 1 { - } - b := a - - for { - for ; b < c && !less(data[pivot], data[b], call); b += 1 { // data[b] <= pivot - } - for ; b < c && less(data[pivot], data[c-1], call); c -=1 { // data[c-1] > pivot - } - if b >= c { - break - } - - swap(data, b, c-1) - swap(indices, b, c-1) - b += 1 - c -= 1 - } - - protect := hi-c < 5 - if !protect && hi-c < (hi-lo)/4 { - dups := 0 - if !less(data[pivot], data[hi-1], call) { - swap(data, c, hi-1) - swap(indices, c, hi-1) - c += 1 - dups += 1 - } - if !less(data[b-1], data[pivot], call) { - b -= 1 - dups += 1 - } - - if !less(data[m], data[pivot], call) { - swap(data, m, b-1) - swap(indices, m, b-1) - b -= 1 - dups += 1 - } - protect = dups > 1 - } - if protect { - for { - for ; a < b && !less(data[b-1], data[pivot], call); b -= 1 { - } - for ; a < b && less(data[a], data[pivot], call); a += 1 { - } - if a >= b { - break - } - swap(data, a, b-1) - swap(indices, a, b-1) - a += 1 - b -= 1 - } - } - swap(data, pivot, b-1) - swap(indices, pivot, b-1) - return b-1, c - } - - assert(len(data) == len(indices)) - - a, b, max_depth := a, b, max_depth - - for b-a > 12 { // only use shell sort for lengths <= 12 - if max_depth == 0 { - heap_sort(data, indices, a, b, call) + cycle :: proc "contextless" (width: uint, data: [][^]byte, n: int) { + if len(data) < 2 { return } - max_depth -= 1 - mlo, mhi := do_pivot(data, indices, a, b, call) - if mlo-a < b-mhi { - _quick_sort_general_with_indices(data, indices, a, mlo, max_depth, call, KIND) - a = mhi - } else { - _quick_sort_general_with_indices(data, indices, mhi, b, max_depth, call, KIND) - b = mlo + buf: [256]u8 = --- + data[n] = raw_data(buf[:]) + width := width + for width != 0 { + l := builtin.min(size_of(buf), int(width)) + copy(data[n][:l], data[0][:l]) + for i in 0.. 1 { - // Shell short with gap 6 - for i in a+6.. 1 { + rt := head[-width:] + lf := head[-width:][-lp[pshift - 2]:] + if cmp(buf[0], lf, arg) >= .Equal && cmp(buf[0], rt, arg) >= .Equal { + break + } + if cmp(lf, rt, arg) >= .Equal { + buf[i], head = lf, lf + pshift -= 1 + } else { + buf[i], head = rt, rt + pshift -= 2 + } + i += 1 + } + cycle(width, buf[:], i) + } + + trinkle :: proc(head: [^]byte, width: uint, cmp: Generic_Cmp, arg: rawptr, pp: []uint, pshift: int, trusty: bool, lp: []uint) { + head := head + + p := [2]uint{pp[0], pp[1]} + + buf: [14*size_of(uint)+1][^]byte = --- + buf[0] = head + + i := 1 + trail := 0 + pshift := pshift + trusty := trusty + for p[0] != 1 || p[1] != 0 { + stepson := head[-lp[pshift]:] + if cmp(stepson, buf[0], arg) <= .Equal { + break + } + if !trusty && pshift > 1 { + rt := head[-width:] + lf := head[-width:][-lp[pshift-2]:] + if cmp(rt, stepson, arg) >= .Equal || cmp(lf, stepson, arg) >= .Equal { + break + } + } + buf[i] = stepson + head = stepson + trail = pntz(p) + shr(p[:], trail) + pshift += trail + trusty = false + i += 1 + } + if trusty { + return + } + cycle(width, buf[:], i) + sift(head, width, cmp, arg, pshift, lp) + } + + size := nel * width + if size == 0 { + return + } + + lp: [12*size_of(uint)]uint = --- + lp[1] = width + lp[0] = lp[1] + for i := 2; true; i += 1 { + lp[i] = lp[i-2] + lp[i-1] + width + if lp[i] >= size { + break + } + } + + head := base + high := head[size - width:] + p := [2]uint{1, 0} + pshift := 1 + for head < high { + if (p[0] & 3) == 3 { + sift(head, width, cmp, arg, pshift, lp[:]) + shr(p[:], 2) + pshift += 2 + } else { + if lp[pshift - 1] >= uint(uintptr(high) - uintptr(head)) { + trinkle(head, width, cmp, arg, p[:], pshift, false, lp[:]) + } else { + sift(head, width, cmp, arg, pshift, lp[:]) + } + if pshift == 1 { + shl(p[:], 1) + pshift = 0 + } else { + shl(p[:], pshift - 1) + pshift = 1 } } - insertion_sort(data, indices, a, b, call) + p[0] |= 1 + head = head[width:] } -} + trinkle(head, width, cmp, arg, p[:], pshift, false, lp[:]) + for pshift != 1 || p[0] != 1 || p[1] != 0 { + if pshift <= 1 { + trail := pntz(p) + shr(p[:], trail) + pshift += trail + } else { + shl(p[:], 2) + pshift -= 2 + p[0] ~= 7 + shr(p[:], 1) + trinkle(head[-width:][-lp[pshift]:], width, cmp, arg, p[:], pshift + 1, true, lp[:]) + shl(p[:], 1) + p[0] |= 1 + trinkle(head[-width:], width, cmp, arg, p[:], pshift, true, lp[:]) + } + head = head[-width:] + } +} \ No newline at end of file diff --git a/core/sort/sort.odin b/core/sort/sort.odin index c4aca4188..63cb50490 100644 --- a/core/sort/sort.odin +++ b/core/sort/sort.odin @@ -1,3 +1,4 @@ +// A sorting interface and algorithms. package sort import "core:mem" diff --git a/core/strconv/decimal/decimal.odin b/core/strconv/decimal/decimal.odin index 5a878d0e1..98891a548 100644 --- a/core/strconv/decimal/decimal.odin +++ b/core/strconv/decimal/decimal.odin @@ -1,5 +1,6 @@ -// Multiple precision decimal numbers -// NOTE: This is only for floating point printing and nothing else +// Multiple precision decimal numbers for use by the `strconv` package. +// +// NOTE: This is only for floating point printing and nothing else. package strconv_decimal Decimal :: struct { diff --git a/core/strconv/deprecated.odin b/core/strconv/deprecated.odin index 883822e4b..c644d331e 100644 --- a/core/strconv/deprecated.odin +++ b/core/strconv/deprecated.odin @@ -36,3 +36,27 @@ append_u128 :: proc(buf: []byte, u: u128, base: int) -> string { append_float :: proc(buf: []byte, f: f64, fmt: byte, prec, bit_size: int) -> string { return write_float(buf, f, fmt, prec, bit_size) } + +// 2025-10-03 Deprecated C short names and implementations + +@(deprecated="Use strconv.write_int() instead") +itoa :: proc(buf: []byte, i: int) -> string { + return write_int(buf, i64(i), 10) +} + +@(deprecated="Use strconv.parse_int() instead") +atoi :: proc(s: string) -> int { + v, _ := parse_int(s) + return v +} + +@(deprecated="Use strconv.parse_f64() instead") +atof :: proc(s: string) -> f64 { + v, _ := parse_f64(s) + return v +} + +@(deprecated="Use strconv.write_float() instead") +ftoa :: proc(buf: []byte, f: f64, fmt: byte, prec, bit_size: int) -> string { + return string(generic_ftoa(buf, f, fmt, prec, bit_size)) +} \ No newline at end of file diff --git a/core/strconv/strconv.odin b/core/strconv/strconv.odin index 652da1adb..48a75d972 100644 --- a/core/strconv/strconv.odin +++ b/core/strconv/strconv.odin @@ -1,3 +1,4 @@ +// Conversions to and from `string` representations of other data types like integers and booleans. package strconv import "core:unicode/utf8" @@ -1547,85 +1548,8 @@ write_u128 :: proc(buf: []byte, u: u128, base: int) -> string { } /* -Converts an integer value to a string and stores it in the given buffer +`ftoa` C name deprecated, use `write_float` instead (same procedure) -**Inputs** -- buf: The buffer to store the resulting string -- i: The integer value to be converted - -Example: - - import "core:fmt" - import "core:strconv" - itoa_example :: proc() { - buf: [4]byte - result := strconv.itoa(buf[:], 42) - fmt.println(result, buf) // "42" - } - -Output: - - 42 [52, 50, 0, 0] - -**Returns** -- The resulting string after converting the integer value -*/ -itoa :: proc(buf: []byte, i: int) -> string { - return write_int(buf, i64(i), 10) -} -/* -Converts a string to an integer value - -**Inputs** -- s: The string to be converted - -Example: - - import "core:fmt" - import "core:strconv" - atoi_example :: proc() { - fmt.println(strconv.atoi("42")) - } - -Output: - - 42 - -**Returns** -- The resulting integer value -*/ -atoi :: proc(s: string) -> int { - v, _ := parse_int(s) - return v -} -/* -Converts a string to a float64 value - -**Inputs** -- s: The string to be converted - -Example: - - import "core:fmt" - import "core:strconv" - atof_example :: proc() { - fmt.printfln("%.3f", strconv.atof("3.14")) - } - -Output: - - 3.140 - -**Returns** -- The resulting float64 value after converting the string -*/ -atof :: proc(s: string) -> f64 { - v, _ := parse_f64(s) - return v -} -// Alias to `write_float` -ftoa :: write_float -/* Writes a float64 value as a string to the given buffer with the specified format and precision **Inputs** diff --git a/core/strings/strings.odin b/core/strings/strings.odin index ffa11f219..d13b45022 100644 --- a/core/strings/strings.odin +++ b/core/strings/strings.odin @@ -1,4 +1,4 @@ -// Procedures to manipulate UTF-8 encoded strings +// A `string` builder, as well as procedures to manipulate `UTF-8` encoded strings. package strings import "base:intrinsics" @@ -436,8 +436,13 @@ equal_fold :: proc(u, v: string) -> (res: bool) { return false } - // TODO(bill): Unicode folding - + r := unicode.simple_fold(sr) + for r != sr && r < tr { + r = unicode.simple_fold(sr) + } + if r == tr { + continue loop + } return false } diff --git a/core/sync/chan/doc.odin b/core/sync/chan/doc.odin index 5d65d7410..63e633531 100644 --- a/core/sync/chan/doc.odin +++ b/core/sync/chan/doc.odin @@ -1,6 +1,5 @@ /* -This package provides both high-level and low-level channel types -for thread-safe communication. +High-level and low-level channel types for thread-safe communication. While channels are essentially thread-safe queues under the hood, their primary purpose is to facilitate safe communication between diff --git a/core/sync/doc.odin b/core/sync/doc.odin index 320732ea7..faae245c4 100644 --- a/core/sync/doc.odin +++ b/core/sync/doc.odin @@ -1,11 +1,7 @@ /* -Synchronization primitives +Various synchronization primitives useful to mediate threads' access to shared memory. -This package implements various synchronization primitives that can be used to -synchronize threads' access to shared memory. - -To limit or control the threads' access to shared memory typically the -following approaches are used: +To limit or control the threads' access to shared memory typically the following approaches are used: - Locks - Lock-free diff --git a/core/sys/info/doc.odin b/core/sys/info/doc.odin index 2a4f71642..7859b4e60 100644 --- a/core/sys/info/doc.odin +++ b/core/sys/info/doc.odin @@ -1,15 +1,5 @@ /* -Copyright 2022 Jeroen van Rijn . -Made available under Odin's BSD-3 license. - -List of contributors: - Jeroen van Rijn: Initial implementation. - Laytan: ARM and RISC-V CPU feature detection, iOS/macOS platform overhaul. -*/ - -/* -Package `core:sys/info` gathers system information on: -Windows, Linux, macOS, FreeBSD & OpenBSD. +Gathers system information on `Windows`, `Linux`, `macOS`, `FreeBSD` & `OpenBSD`. Simply import the package and you'll have access to the OS version, RAM amount and CPU information. @@ -33,9 +23,6 @@ Example: fmt.printfln("CPU cores: %vc/%vt", si.cpu.physical_cores, si.cpu.logical_cores) fmt.printfln("RAM: %#.1M", si.ram.total_ram) - // fmt.printfln("Features: %v", si.cpu.features) - // fmt.printfln("MacOS version: %v", si.macos_version) - fmt.println() for gpu, i in si.gpus { fmt.printfln("GPU #%v:", i) @@ -47,26 +34,30 @@ Example: - Example Windows output: - Odin: dev-2022-09 - OS: Windows 10 Professional (version: 20H2), build: 19042.1466 - OS: OS_Version{ + Odin: dev-2025-10 + OS: Windows 10 Professional (version: 22H2), build: 19045.6396 + OS: OS_Version{ platform = "Windows", - major = 10, - minor = 0, - patch = 0, + _ = Version{ + major = 10, + minor = 0, + patch = 0, + }, build = [ - 19042, - 1466, + 19045, + 6396, ], - version = "20H2", - as_string = "Windows 10 Professional (version: 20H2), build: 19042.1466", + version = "22H2", + as_string = "Windows 10 Professional (version: 22H2), build: 19045.6396", } - CPU: AMD Ryzen 7 1800X Eight-Core Processor - RAM: 64.0 GiB + CPU: AMD Ryzen 9 5950X 16-Core Processor + CPU cores: 16c/32t + RAM: 63.9 GiB + GPU #0: Vendor: Advanced Micro Devices, Inc. - Model: Radeon RX Vega - VRAM: 8.0 GiB + Model: AMD Radeon RX 9070 + VRAM: 15.9 GiB - Example macOS output: @@ -87,3 +78,12 @@ Example: RAM: 8.0 GiB */ package sysinfo + +/* +Copyright 2022 Jeroen van Rijn . +Made available under Odin's BSD-3 license. + +List of contributors: + Jeroen van Rijn: Initial implementation. + Laytan: ARM and RISC-V CPU feature detection, iOS/macOS platform overhaul. +*/ \ No newline at end of file diff --git a/core/sys/info/platform_windows.odin b/core/sys/info/platform_windows.odin index ff8ebe2ee..bad99f811 100644 --- a/core/sys/info/platform_windows.odin +++ b/core/sys/info/platform_windows.odin @@ -3,9 +3,10 @@ package sysinfo import sys "core:sys/windows" import "base:intrinsics" import "core:strings" +import "core:strconv" import "core:unicode/utf16" -import "core:fmt" +// import "core:fmt" import "base:runtime" @(private) @@ -280,30 +281,67 @@ init_ram :: proc "contextless" () { @(init, private) init_gpu_info :: proc "contextless" () { - GPU_INFO_BASE :: "SYSTEM\\ControlSet001\\Control\\Class\\{4d36e968-e325-11ce-bfc1-08002be10318}\\" + GPU_ROOT_KEY :: `SYSTEM\ControlSet001\Control\Class\{4d36e968-e325-11ce-bfc1-08002be10318}` context = runtime.default_context() + runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() + + gpu_key: sys.HKEY + if status := sys.RegOpenKeyExW( + sys.HKEY_LOCAL_MACHINE, + GPU_ROOT_KEY, + 0, + sys.KEY_ENUMERATE_SUB_KEYS, + &gpu_key, + ); status != i32(sys.ERROR_SUCCESS) { + return + } + defer sys.RegCloseKey(gpu_key) gpu_list: [dynamic]GPU - gpu_index: int + gpu: ^GPU + index := sys.DWORD(0) for { - key := fmt.tprintf("%v\\%04d", GPU_INFO_BASE, gpu_index) + defer index += 1 - if vendor, ok := read_reg_string(sys.HKEY_LOCAL_MACHINE, key, "ProviderName"); ok { - append(&gpu_list, GPU{vendor_name = vendor}) - } else { + buf_wstring: [100]u16 + buf_len := u32(len(buf_wstring)) + buf_utf8: [4 * len(buf_wstring)]u8 + + if status := sys.RegEnumKeyW( + gpu_key, + index, + &buf_wstring[0], + &buf_len, + ); status != i32(sys.ERROR_SUCCESS) { break } + utf16.decode_to_utf8(buf_utf8[:], buf_wstring[:]) + leaf := string(cstring(&buf_utf8[0])) + + // Skip leafs that are not of the form 000x + if _, is_integer := strconv.parse_int(leaf, 10); !is_integer { + continue + } + + key := strings.concatenate({GPU_ROOT_KEY, "\\", leaf}, context.temp_allocator) + + if vendor, ok := read_reg_string(sys.HKEY_LOCAL_MACHINE, key, "ProviderName"); ok { + idx := append(&gpu_list, GPU{vendor_name = vendor}) + gpu = &gpu_list[idx - 1] + } else { + continue + } + if desc, ok := read_reg_string(sys.HKEY_LOCAL_MACHINE, key, "DriverDesc"); ok { - gpu_list[gpu_index].model_name = desc + gpu.model_name = desc } if vram, ok := read_reg_i64(sys.HKEY_LOCAL_MACHINE, key, "HardwareInformation.qwMemorySize"); ok { - gpu_list[gpu_index].total_ram = int(vram) + gpu.total_ram = int(vram) } - gpu_index += 1 } gpus = gpu_list[:] } diff --git a/core/sys/orca/macros.odin b/core/sys/orca/macros.odin index 12adfdb91..14b270bef 100644 --- a/core/sys/orca/macros.odin +++ b/core/sys/orca/macros.odin @@ -1,7 +1,7 @@ -// File contains implementations of the Orca API that are defined as macros in Orca. - package orca +// Implementations of the `Orca` API that are defined as macros in Orca. + //////////////////////////////////////////////////////////////////////////////// // Helpers for logging, asserting and aborting. //////////////////////////////////////////////////////////////////////////////// diff --git a/core/sys/orca/odin.odin b/core/sys/orca/odin.odin index c59b990cf..bdda9aa5b 100644 --- a/core/sys/orca/odin.odin +++ b/core/sys/orca/odin.odin @@ -1,7 +1,7 @@ -// File contains Odin specific helpers. - package orca +// File contains Odin specific helpers. + import "base:runtime" create_odin_logger :: proc(lowest := runtime.Logger_Level.Debug, ident := "") -> runtime.Logger { diff --git a/core/sys/orca/orca.odin b/core/sys/orca/orca.odin index abcf42fe2..a36c5fa2a 100644 --- a/core/sys/orca/orca.odin +++ b/core/sys/orca/orca.odin @@ -1,3 +1,6 @@ +// Bindings for the Orca platform +// +// See: [[ https://orca-app.dev ]] package orca import "core:c" diff --git a/core/sys/posix/posix.odin b/core/sys/posix/posix.odin index 3dcf36a5e..49353e875 100644 --- a/core/sys/posix/posix.odin +++ b/core/sys/posix/posix.odin @@ -1,5 +1,5 @@ /* -Raw bindings for most POSIX APIs. +Raw bindings for most `POSIX` APIs. Targets glibc and musl compatibility. diff --git a/core/sys/wasm/js/odin.js b/core/sys/wasm/js/odin.js index 2a8ccdd5e..f4f73a42a 100644 --- a/core/sys/wasm/js/odin.js +++ b/core/sys/wasm/js/odin.js @@ -1937,7 +1937,7 @@ function odinSetupDefaultImports(wasmMemoryInterface, consoleElement, memory) { if (buf_len > 0 && buf_ptr) { let n = Math.min(buf_len, str.length); str = str.substring(0, n); - this.mem.loadBytes(buf_ptr, buf_len).set(new TextEncoder().encode(str)) + wasmMemoryInterface.loadBytes(buf_ptr, buf_len).set(new TextEncoder().encode(str)) return n; } } @@ -2001,7 +2001,7 @@ function odinSetupDefaultImports(wasmMemoryInterface, consoleElement, memory) { if (buf_len > 0 && buf_ptr) { let n = Math.min(buf_len, str.length); str = str.substring(0, n); - this.mem.loadBytes(buf_ptr, buf_len).set(new TextEncoder().encode(str)) + wasmMemoryInterface.loadBytes(buf_ptr, buf_len).set(new TextEncoder().encode(str)) return n; } } diff --git a/core/sys/windows/advapi32.odin b/core/sys/windows/advapi32.odin index f834511d4..22cb27863 100644 --- a/core/sys/windows/advapi32.odin +++ b/core/sys/windows/advapi32.odin @@ -167,6 +167,13 @@ foreign advapi32 { lpftLastWriteTime: ^FILETIME, ) -> LSTATUS --- + RegEnumKeyW :: proc( + hKey: HKEY, + dwIndex: DWORD, + lpName: LPWSTR, + lpcchName: LPDWORD, + ) -> LSTATUS --- + RegEnumKeyExW :: proc( hKey: HKEY, dwIndex: DWORD, diff --git a/core/terminal/ansi/doc.odin b/core/terminal/ansi/doc.odin index 966e6be00..7f1d30b1b 100644 --- a/core/terminal/ansi/doc.odin +++ b/core/terminal/ansi/doc.odin @@ -1,7 +1,6 @@ /* -package ansi implements constant references to many widely-supported ANSI -escape codes, primarily used in terminal emulators for enhanced graphics, such -as colors, text styling, and animated displays. +Constant references to many widely-supported `ANSI` escape codes. +Primarily used in terminal emulators for enhanced graphics, such as colors, text styling, and animated displays. For example, you can print out a line of cyan text like this: fmt.println(ansi.CSI + ansi.FG_CYAN + ansi.SGR + "Hellope!" + ansi.CSI + ansi.RESET + ansi.SGR) diff --git a/core/terminal/doc.odin b/core/terminal/doc.odin deleted file mode 100644 index 490e9d398..000000000 --- a/core/terminal/doc.odin +++ /dev/null @@ -1,4 +0,0 @@ -/* -This package is for interacting with the command line interface of the system. -*/ -package terminal diff --git a/core/terminal/terminal.odin b/core/terminal/terminal.odin index 1e5566295..37fdaff36 100644 --- a/core/terminal/terminal.odin +++ b/core/terminal/terminal.odin @@ -1,3 +1,4 @@ +// Interaction with the command line interface (`CLI`) of the system. package terminal import "core:os" diff --git a/core/testing/testing.odin b/core/testing/testing.odin index 1357a4683..a0b046a46 100644 --- a/core/testing/testing.odin +++ b/core/testing/testing.odin @@ -1,3 +1,4 @@ +// The implementation of the `odin test` runner and procedures user tests can use for this purpose. package testing /* diff --git a/core/text/edit/text_edit.odin b/core/text/edit/text_edit.odin index 49adad4d9..8713f6eff 100644 --- a/core/text/edit/text_edit.odin +++ b/core/text/edit/text_edit.odin @@ -1,4 +1,6 @@ /* +Text edit primitives to use in a text box. + Based off the articles by rxi: - [[ https://rxi.github.io/textbox_behaviour.html ]] - [[ https://rxi.github.io/a_simple_undo_system.html ]] diff --git a/core/text/i18n/doc.odin b/core/text/i18n/doc.odin index d590fd123..f316c5a6d 100644 --- a/core/text/i18n/doc.odin +++ b/core/text/i18n/doc.odin @@ -1,6 +1,6 @@ /* -The `i18n` package is a flexible and easy to use way to localise applications. +A flexible and easy way to add translations/internationalization (`i18n`) to applications. It has two calls to get a translation: `get()` and `get_n()`, which the user can alias into something like `T` and `Tn` with statements like: diff --git a/core/text/match/strlib.odin b/core/text/match/strlib.odin index 819f464c5..c836253ec 100644 --- a/core/text/match/strlib.odin +++ b/core/text/match/strlib.odin @@ -1,3 +1,4 @@ +// A Lua-like string match algorithm. package text_match import "base:runtime" @@ -9,11 +10,12 @@ MAX_CAPTURES :: 32 Capture :: struct { init: int, - len: int, + len: int, } Match :: struct { - byte_start, byte_end: int, + byte_start: int, + byte_end: int, } Error :: enum { @@ -27,18 +29,19 @@ Error :: enum { Match_Invalid, } -L_ESC :: '%' -CAP_POSITION :: -2 +L_ESC :: '%' +CAP_POSITION :: -2 CAP_UNFINISHED :: -1 -INVALID :: -1 +INVALID :: -1 Match_State :: struct { - src: string, + src: string, pattern: string, - level: int, + level: int, capture: [MAX_CAPTURES]Capture, } +@(require_results) match_class :: proc(c: rune, cl: rune) -> (res: bool) { switch unicode.to_lower(cl) { case 'a': res = is_alpha(c) @@ -65,19 +68,23 @@ is_punct :: unicode.is_punct is_space :: unicode.is_space is_cntrl :: unicode.is_control +@(require_results) is_alnum :: proc(c: rune) -> bool { return unicode.is_alpha(c) || unicode.is_digit(c) } +@(require_results) is_graph :: proc(c: rune) -> bool { return (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') || unicode.is_digit(c) } +@(require_results) is_xdigit :: proc(c: rune) -> bool { return (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') || unicode.is_digit(c) } // find the first utf8 charater and its size, return an error if the character is an error +@(require_results) utf8_peek :: proc(bytes: string) -> (c: rune, size: int, err: Error) { c, size = utf8.decode_rune_in_string(bytes) @@ -90,6 +97,7 @@ utf8_peek :: proc(bytes: string) -> (c: rune, size: int, err: Error) { // find the first utf8 charater and its size and advance the index // return an error if the character is an error +@(require_results) utf8_advance :: proc(bytes: string, index: ^int) -> (c: rune, err: Error) { size: int c, size = utf8.decode_rune_in_string(bytes[index^:]) @@ -103,10 +111,12 @@ utf8_advance :: proc(bytes: string, index: ^int) -> (c: rune, err: Error) { } // continuation byte? +@(require_results) is_cont :: proc(b: byte) -> bool { return b & 0xc0 == 0x80 } +@(require_results) utf8_prev :: proc(bytes: string, a, b: int) -> int { b := b @@ -117,6 +127,7 @@ utf8_prev :: proc(bytes: string, a, b: int) -> int { return a < b ? b - 1 : a } +@(require_results) utf8_next :: proc(bytes: string, a: int) -> int { a := a b := len(bytes) @@ -128,6 +139,7 @@ utf8_next :: proc(bytes: string, a: int) -> int { return a < b ? a + 1 : b } +@(require_results) check_capture :: proc(ms: ^Match_State, l: rune) -> (int, Error) { l := int(l - '1') @@ -138,6 +150,7 @@ check_capture :: proc(ms: ^Match_State, l: rune) -> (int, Error) { return l, .OK } +@(require_results) capture_to_close :: proc(ms: ^Match_State) -> (int, Error) { level := ms.level - 1 @@ -152,6 +165,7 @@ capture_to_close :: proc(ms: ^Match_State) -> (int, Error) { return 0, .Invalid_Pattern_Capture } +@(require_results) class_end :: proc(ms: ^Match_State, p: int) -> (step: int, err: Error) { step = p ch := utf8_advance(ms.pattern, &step) or_return @@ -163,7 +177,7 @@ class_end :: proc(ms: ^Match_State, p: int) -> (step: int, err: Error) { return } - utf8_advance(ms.pattern, &step) or_return + _ = utf8_advance(ms.pattern, &step) or_return case '[': // fine with step by 1 @@ -198,6 +212,7 @@ class_end :: proc(ms: ^Match_State, p: int) -> (step: int, err: Error) { return } +@(require_results) match_bracket_class :: proc(ms: ^Match_State, c: rune, p, ec: int) -> (sig: bool, err: Error) { sig = true p := p @@ -240,6 +255,7 @@ match_bracket_class :: proc(ms: ^Match_State, c: rune, p, ec: int) -> (sig: bool return } +@(require_results) single_match :: proc(ms: ^Match_State, s, p, ep: int) -> (matched: bool, schar_size: int, err: Error) { if s >= len(ms.src) { return @@ -254,13 +270,16 @@ single_match :: proc(ms: ^Match_State, s, p, ep: int) -> (matched: bool, schar_s case L_ESC: pchar_next, _ := utf8_peek(ms.pattern[p + psize:]) or_return matched = match_class(schar, pchar_next) - case '[': matched = match_bracket_class(ms, schar, p, ep - 1) or_return - case: matched = schar == pchar + case '[': + matched = match_bracket_class(ms, schar, p, ep - 1) or_return + case: + matched = schar == pchar } return } +@(require_results) match_balance :: proc(ms: ^Match_State, s, p: int) -> (unused: int, err: Error) { if p >= len(ms.pattern) - 1 { return INVALID, .Invalid_Pattern_Capture @@ -300,13 +319,13 @@ match_balance :: proc(ms: ^Match_State, s, p: int) -> (unused: int, err: Error) return INVALID, .OK } +@(require_results) max_expand :: proc(ms: ^Match_State, s, p, ep: int) -> (res: int, err: Error) { m := s // count up matches for { matched, size := single_match(ms, m, p, ep) or_return - if !matched { break } @@ -316,7 +335,6 @@ max_expand :: proc(ms: ^Match_State, s, p, ep: int) -> (res: int, err: Error) { for s <= m { result := match(ms, m, ep + 1) or_return - if result != INVALID { return result, .OK } @@ -331,6 +349,7 @@ max_expand :: proc(ms: ^Match_State, s, p, ep: int) -> (res: int, err: Error) { return INVALID, .OK } +@(require_results) min_expand :: proc(ms: ^Match_State, s, p, ep: int) -> (res: int, err: Error) { s := s @@ -339,19 +358,19 @@ min_expand :: proc(ms: ^Match_State, s, p, ep: int) -> (res: int, err: Error) { if result != INVALID { return result, .OK - } else { - // TODO receive next step maybe? - matched, rune_size := single_match(ms, s, p, ep) or_return + } + // TODO receive next step maybe? + matched, rune_size := single_match(ms, s, p, ep) or_return - if matched { - s += rune_size - } else { - return INVALID, .OK - } + if matched { + s += rune_size + } else { + return INVALID, .OK } } } +@(require_results) start_capture :: proc(ms: ^Match_State, s, p, what: int) -> (res: int, err: Error) { level := ms.level @@ -366,6 +385,7 @@ start_capture :: proc(ms: ^Match_State, s, p, what: int) -> (res: int, err: Erro return } +@(require_results) end_capture :: proc(ms: ^Match_State, s, p: int) -> (res: int, err: Error) { l := capture_to_close(ms) or_return @@ -379,6 +399,7 @@ end_capture :: proc(ms: ^Match_State, s, p: int) -> (res: int, err: Error) { return } +@(require_results) match_capture :: proc(ms: ^Match_State, s: int, char: rune) -> (res: int, err: Error) { index := check_capture(ms, char) or_return length := ms.capture[index].len @@ -390,6 +411,7 @@ match_capture :: proc(ms: ^Match_State, s: int, char: rune) -> (res: int, err: E return INVALID, .OK } +@(require_results) match :: proc(ms: ^Match_State, s, p: int) -> (unused: int, err: Error) { s := s p := p @@ -431,7 +453,6 @@ match :: proc(ms: ^Match_State, s, p: int) -> (unused: int, err: Error) { // balanced string case 'b': s = match_balance(ms, s, p + 2) or_return - if s != INVALID { // eg after %b() return match(ms, s, p + 4) @@ -460,7 +481,7 @@ match :: proc(ms: ^Match_State, s, p: int) -> (unused: int, err: Error) { } m1 := match_bracket_class(ms, previous, p, ep - 1) or_return - m2 := match_bracket_class(ms, current, p, ep - 1) or_return + m2 := match_bracket_class(ms, current, p, ep - 1) or_return if !m1 && m2 { return match(ms, s, ep) @@ -486,6 +507,7 @@ match :: proc(ms: ^Match_State, s, p: int) -> (unused: int, err: Error) { return s, .OK } +@(require_results) match_default :: proc(ms: ^Match_State, s, p: int) -> (unused: int, err: Error) { s := s ep := class_end(ms, p) or_return @@ -495,8 +517,10 @@ match_default :: proc(ms: ^Match_State, s, p: int) -> (unused: int, err: Error) epc := ep < len(ms.pattern) ? ms.pattern[ep] : 0 switch epc { - case '*', '?', '-': return match(ms, s, ep + 1) - case: s = INVALID + case '*', '?', '-': + return match(ms, s, ep + 1) + case: + s = INVALID } } else { epc := ep < len(ms.pattern) ? ms.pattern[ep] : 0 @@ -505,22 +529,23 @@ match_default :: proc(ms: ^Match_State, s, p: int) -> (unused: int, err: Error) case '?': result := match(ms, s + ssize, ep + 1) or_return - if result != INVALID { - s = result - } else { + if result == INVALID { return match(ms, s, ep + 1) } + s = result case '+': s = max_expand(ms, s + ssize, p, ep) or_return - case '*': s = max_expand(ms, s, p, ep) or_return - case '-': s = min_expand(ms, s, p, ep) or_return - case: return match(ms, s + ssize, ep) + case '*': s = max_expand(ms, s, p, ep) or_return + case '-': s = min_expand(ms, s, p, ep) or_return + case: + return match(ms, s + ssize, ep) } } return s, .OK } +@(require_results) push_onecapture :: proc(ms: ^Match_State, i: int, s: int, e: int, matches: []Match) -> (err: Error) { if i >= ms.level { if i == 0 { @@ -533,22 +558,21 @@ push_onecapture :: proc(ms: ^Match_State, i: int, s: int, e: int, matches: []M length := ms.capture[i].len switch length { - case CAP_UNFINISHED: err = .Unfinished_Capture - case CAP_POSITION: matches[i] = { init, init + 1 } - case: matches[i] = { init, init + length } + case CAP_UNFINISHED: + err = .Unfinished_Capture + case CAP_POSITION: + matches[i] = { init, init + 1 } + case: + matches[i] = { init, init + length } } } return } -push_captures :: proc( - ms: ^Match_State, - s: int, - e: int, - matches: []Match, -) -> (nlevels: int, err: Error) { - nlevels = 1 if ms.level == 0 && s != -1 else ms.level +@(require_results) +push_captures :: proc(ms: ^Match_State, s, e: int, matches: []Match) -> (nlevels: int, err: Error) { + nlevels = 1 if ms.level == 0 && s >= 0 else ms.level for i in 0.. int { for i in 0.. int { return -1 } +@(require_results) lmem_find :: proc(s1, s2: string) -> int { l1 := len(s1) l2 := len(s2) if l2 == 0 { return 0 - } else if l2 > l1 { + } + if l2 > l1 { return -1 - } else { - init := strings.index_byte(s1, s2[0]) - end := init + l2 + } - for end <= l1 && init != -1 { - init += 1 + init := strings.index_byte(s1, s2[0]) + end := init + l2 - if s1[init - 1:end] == s2 { - return init - 1 - } else { - next := strings.index_byte(s1[init:], s2[0]) + for end <= l1 && init >= 0 { + init += 1 - if next == -1 { - return -1 - } else { - init = init + next - end = init + l2 - } - } + if s1[init - 1:end] == s2 { + return init - 1 } + next := strings.index_byte(s1[init:], s2[0]) + + if next == -1 { + return -1 + } + init = init + next + end = init + l2 } return -1 @@ -618,36 +644,28 @@ lmem_find :: proc(s1, s2: string) -> int { // find a pattern with in a haystack with an offset // allow_memfind will speed up simple searches -find_aux :: proc( - haystack: string, - pattern: string, - offset: int, - allow_memfind: bool, - matches: ^[MAX_CAPTURES]Match, -) -> (captures: int, err: Error) { +find_aux :: proc(haystack, pattern: string, offset: int, allow_memfind: bool, matches: ^[MAX_CAPTURES]Match) -> (captures: int, err: Error) { s := offset p := 0 specials_idx := index_special(pattern) if allow_memfind && specials_idx == -1 { - if index := lmem_find(haystack[s:], pattern); index != -1 { + if index := lmem_find(haystack[s:], pattern); index >= 0 { matches[0] = { index + s, index + s + len(pattern) } captures = 1 - return - } else { - return } + return } pattern := pattern anchor: bool if len(pattern) > 0 && pattern[0] == '^' { - anchor = true + anchor = true pattern = pattern[1:] } ms := Match_State { - src = haystack, + src = haystack, pattern = pattern, } @@ -684,11 +702,8 @@ find_aux :: proc( // rest has to be used from captures // assumes captures is zeroed on first iteration // resets captures to zero on last iteration -gmatch :: proc( - haystack: ^string, - pattern: string, - captures: ^[MAX_CAPTURES]Match, -) -> (res: string, ok: bool) { +@(require_results) +gmatch :: proc(haystack: ^string, pattern: string, captures: ^[MAX_CAPTURES]Match) -> (res: string, ok: bool) { haystack^ = haystack[captures[0].byte_end:] if len(haystack) > 0 { length, err := find_aux(haystack^, pattern, 0, false, captures) @@ -707,24 +722,17 @@ gmatch :: proc( } // gsub with builder, replace patterns found with the replace content -gsub_builder :: proc( - builder: ^strings.Builder, - haystack: string, - pattern: string, - replace: string, -) -> string { +@(require_results) +gsub_builder :: proc(builder: ^strings.Builder, haystack, pattern, replace: string) -> string { // find matches captures: [MAX_CAPTURES]Match haystack := haystack for { length, err := find_aux(haystack, pattern, 0, false, &captures) - - // done - if length == 0 { + if length == 0 { // done break } - if err != .OK { return {} } @@ -746,21 +754,17 @@ gsub_builder :: proc( } // uses temp builder to build initial string - then allocates the result -gsub_allocator :: proc( - haystack: string, - pattern: string, - replace: string, - allocator := context.allocator, -) -> string { +@(require_results) +gsub_allocator :: proc(haystack, pattern, replace: string, allocator := context.allocator) -> string { builder := strings.builder_make(0, 256, context.temp_allocator) return gsub_builder(&builder, haystack, pattern, replace) } Gsub_Proc :: proc( // optional passed data - data: rawptr, + data: rawptr, // word match found - word: string, + word: string, // current haystack for found captures haystack: string, // found captures - empty for no captures @@ -768,20 +772,14 @@ Gsub_Proc :: proc( ) // call a procedure on every match in the haystack -gsub_with :: proc( - haystack: string, - pattern: string, - data: rawptr, - call: Gsub_Proc, -) { +gsub_with :: proc(haystack, pattern: string, data: rawptr, call: Gsub_Proc) { // find matches captures: [MAX_CAPTURES]Match haystack := haystack for { length := find_aux(haystack, pattern, 0, false, &captures) or_break - // done - if length == 0 { + if length == 0 { // done break } @@ -800,11 +798,8 @@ gsub :: proc { gsub_builder, gsub_allocator } // iterative find with zeroth capture only // assumes captures is zeroed on first iteration // resets captures to zero on last iteration -gfind :: proc( - haystack: ^string, - pattern: string, - captures: ^[MAX_CAPTURES]Match, -) -> (res: string, ok: bool) { +@(require_results) +gfind :: proc(haystack: ^string, pattern: string, captures: ^[MAX_CAPTURES]Match) -> (res: string, ok: bool) { haystack^ = haystack[captures[0].byte_end:] if len(haystack) > 0 { length, err := find_aux(haystack^, pattern, 0, true, captures) @@ -822,10 +817,8 @@ gfind :: proc( } // rebuilds a pattern into a case insensitive pattern -pattern_case_insensitive_builder :: proc( - builder: ^strings.Builder, - pattern: string, -) -> (res: string) { +@(require_results) +pattern_case_insensitive_builder :: proc(builder: ^strings.Builder, pattern: string) -> string { p := pattern last_percent: bool @@ -849,11 +842,8 @@ pattern_case_insensitive_builder :: proc( return strings.to_string(builder^) } -pattern_case_insensitive_allocator :: proc( - pattern: string, - cap: int = 256, - allocator := context.allocator, -) -> (res: string) { +@(require_results) +pattern_case_insensitive_allocator :: proc(pattern: string, cap: int = 256, allocator := context.allocator) -> string { builder := strings.builder_make(0, cap, context.temp_allocator) return pattern_case_insensitive_builder(&builder, pattern) } @@ -877,6 +867,7 @@ Matcher :: struct { } // init using haystack & pattern and an optional byte offset +@(require_results) matcher_init :: proc(haystack, pattern: string, offset: int = 0) -> (res: Matcher) { res.haystack = haystack res.pattern = pattern @@ -886,13 +877,14 @@ matcher_init :: proc(haystack, pattern: string, offset: int = 0) -> (res: Matche } // find the first match and return the byte start / end position in the string, true on success +@(require_results) matcher_find :: proc(matcher: ^Matcher) -> (start, end: int, ok: bool) #no_bounds_check { matcher.captures_length, matcher.err = find_aux( matcher.haystack, matcher.pattern, matcher.offset, - true, - &matcher.captures, + allow_memfind=true, + matches=&matcher.captures, ) ok = matcher.captures_length > 0 && matcher.err == .OK match := matcher.captures[0] @@ -902,13 +894,14 @@ matcher_find :: proc(matcher: ^Matcher) -> (start, end: int, ok: bool) #no_bound } // find the first match and return the matched word, true on success +@(require_results) matcher_match :: proc(matcher: ^Matcher) -> (word: string, ok: bool) #no_bounds_check { matcher.captures_length, matcher.err = find_aux( matcher.haystack, matcher.pattern, matcher.offset, - false, - &matcher.captures, + allow_memfind=false, + matches=&matcher.captures, ) ok = matcher.captures_length > 0 && matcher.err == .OK match := matcher.captures[0] @@ -917,6 +910,7 @@ matcher_match :: proc(matcher: ^Matcher) -> (word: string, ok: bool) #no_bounds_ } // get the capture at the "correct" spot, as spot 0 is reserved for the first match +@(require_results) matcher_capture :: proc(matcher: ^Matcher, index: int, loc := #caller_location) -> string #no_bounds_check { runtime.bounds_check_error_loc(loc, index + 1, MAX_CAPTURES - 1) cap := matcher.captures[index + 1] @@ -924,6 +918,7 @@ matcher_capture :: proc(matcher: ^Matcher, index: int, loc := #caller_location) } // get the raw match out of the captures, skipping spot 0 +@(require_results) matcher_capture_raw :: proc(matcher: ^Matcher, index: int, loc := #caller_location) -> Match #no_bounds_check { runtime.bounds_check_error_loc(loc, index + 1, MAX_CAPTURES - 1) return matcher.captures[index + 1] @@ -933,6 +928,7 @@ matcher_capture_raw :: proc(matcher: ^Matcher, index: int, loc := #caller_locati matcher_gmatch :: matcher_match_iter // iteratively match the haystack till it cant find any matches +@(require_results) matcher_match_iter :: proc(matcher: ^Matcher) -> (res: string, index: int, ok: bool) { if len(matcher.iter) > 0 { matcher.captures_length, matcher.err = find_aux( @@ -962,6 +958,7 @@ matcher_match_iter :: proc(matcher: ^Matcher) -> (res: string, index: int, ok: b } // get a slice of all valid captures above the first match +@(require_results) matcher_captures_slice :: proc(matcher: ^Matcher) -> []Match { return matcher.captures[1:matcher.captures_length] } diff --git a/core/text/regex/common/common.odin b/core/text/regex/common/common.odin index e60bef58f..0abd48e4b 100644 --- a/core/text/regex/common/common.odin +++ b/core/text/regex/common/common.odin @@ -1,4 +1,4 @@ -// This package helps break dependency cycles. +// This package helps break dependency cycles for the regular expression engine. package regex_common /* diff --git a/core/text/regex/compiler/doc.odin b/core/text/regex/compiler/doc.odin index 8c876d837..ec33ae8c9 100644 --- a/core/text/regex/compiler/doc.odin +++ b/core/text/regex/compiler/doc.odin @@ -1,6 +1,5 @@ /* -package regex_compiler implements a bytecode compiler for the virtual machine -included alongside it. +A bytecode compiler for the virtual machine included alongside it. Operands larger than u8 are written in system endian order. diff --git a/core/text/regex/doc.odin b/core/text/regex/doc.odin index 61ab8b80e..ba29659dc 100644 --- a/core/text/regex/doc.odin +++ b/core/text/regex/doc.odin @@ -1,6 +1,5 @@ /* -package regex implements a complete suite for using Regular Expressions to -match and capture text. +A complete suite for using Regular Expressions to match and capture text. Regular expressions are used to describe how a piece of text can match to another, using a pattern language. diff --git a/core/text/regex/optimizer/doc.odin b/core/text/regex/optimizer/doc.odin index 7f2c84c8d..279cbafba 100644 --- a/core/text/regex/optimizer/doc.odin +++ b/core/text/regex/optimizer/doc.odin @@ -1,6 +1,7 @@ /* -package regex_optimizer implements an optimizer which acts upon the AST of a -parsed regular expression pattern, transforming it in-place without moving to a +An optimizer for the regular expression AST. + +Acts upon the AST of a parsed regular expression pattern, transforming it in-place without moving to a compilation step. Where possible, it aims to reduce branching as much as possible in the diff --git a/core/text/regex/parser/doc.odin b/core/text/regex/parser/doc.odin index f518e518d..1f78a0b99 100644 --- a/core/text/regex/parser/doc.odin +++ b/core/text/regex/parser/doc.odin @@ -1,6 +1,5 @@ /* -package regex_parser implements a Pratt parser, also known as a Top-Down -Operator Precedence parser, for parsing tokenized regular expression patterns. +A `Pratt` parser (a.k.a. Top-Down Operator Precedence parser) for parsing tokenized regular expression patterns. References: - https://dl.acm.org/doi/10.1145/512927.512931 diff --git a/core/text/regex/tokenizer/tokenizer.odin b/core/text/regex/tokenizer/tokenizer.odin index 447fe4329..556423a07 100644 --- a/core/text/regex/tokenizer/tokenizer.odin +++ b/core/text/regex/tokenizer/tokenizer.odin @@ -1,3 +1,4 @@ +// Tokenizes regular expressions. package regex_tokenizer /* diff --git a/core/text/regex/virtual_machine/doc.odin b/core/text/regex/virtual_machine/doc.odin index d599dbb1c..ba7441399 100644 --- a/core/text/regex/virtual_machine/doc.odin +++ b/core/text/regex/virtual_machine/doc.odin @@ -1,7 +1,6 @@ /* -package regex_vm implements a threaded virtual machine for interpreting -regular expressions, based on the designs described by Russ Cox and attributed -to both Ken Thompson and Rob Pike. +A threaded virtual machine for interpreting regular expressions. +Based on the designs described by Russ Cox and attributed to both Ken Thompson and Rob Pike. The virtual machine executes all threads in lock step, i.e. the string pointer does not advance until all threads have finished processing the current rune. diff --git a/core/text/scanner/scanner.odin b/core/text/scanner/scanner.odin index 96109f614..649b4d2d7 100644 --- a/core/text/scanner/scanner.odin +++ b/core/text/scanner/scanner.odin @@ -1,4 +1,4 @@ -// package text/scanner provides a scanner and tokenizer for UTF-8-encoded text. +// A scanner and tokenizer for UTF-8-encoded text. // It takes a string providing the source, which then can be tokenized through // repeated calls to the scan procedure. // For compatibility with existing tooling and languages, the NUL character is not allowed. diff --git a/core/text/table/doc.odin b/core/text/table/doc.odin index 63275bbc1..4b8d76893 100644 --- a/core/text/table/doc.odin +++ b/core/text/table/doc.odin @@ -1,5 +1,5 @@ /* -The package `table` implements plain-text/markdown/HTML/custom rendering of tables. +Plain-text/markdown/HTML/custom rendering of tables. **Custom rendering.** Example: diff --git a/core/thread/thread.odin b/core/thread/thread.odin index 194c7bfef..26c1a3e27 100644 --- a/core/thread/thread.odin +++ b/core/thread/thread.odin @@ -1,3 +1,4 @@ +// Multi-threading operations to spawn threads and thread pools. package thread import "base:runtime" diff --git a/core/time/time.odin b/core/time/time.odin index b488f951c..ac68346b3 100644 --- a/core/time/time.odin +++ b/core/time/time.odin @@ -1,3 +1,4 @@ +// `Time`-related procedures and types, including `sleep`, `now`, and string formatting of moments. package time import "base:intrinsics" diff --git a/core/time/timezone/tzdate.odin b/core/time/timezone/tzdate.odin index 8e900ec11..f01553573 100644 --- a/core/time/timezone/tzdate.odin +++ b/core/time/timezone/tzdate.odin @@ -1,3 +1,4 @@ +// Timezone lookup. package timezone import "core:fmt" diff --git a/core/unicode/doc.odin b/core/unicode/doc.odin new file mode 100644 index 000000000..302fd59e1 --- /dev/null +++ b/core/unicode/doc.odin @@ -0,0 +1,2 @@ +// Data and procedures to test properties of `Unicode` code points. +package unicode \ No newline at end of file diff --git a/core/unicode/fold.odin b/core/unicode/fold.odin new file mode 100644 index 000000000..2e0d7225c --- /dev/null +++ b/core/unicode/fold.odin @@ -0,0 +1,79 @@ +package unicode + +// simple_fold iterates over the Unicode code points equivalent under the Unicode defined simple case folding. +// simple_fold returns the smallest rune > r if one exists, or the smallest rune >= 0. +// If no valid Unicode code point exists, r is returned. +// +// Example: +// simple_fold('A') == 'a' +// simple_fold('a') == 'A' +// simple_fold('Z') == 'z' +// simple_fold('z') == 'Z' +// simple_fold('7') == '7' +// simple_fold('k') == '\u212a' (Kelvin symbol, K) +// simple_fold('\u212a') == 'k' +// simple_fold(-3) == -3 +@(require_results) +simple_fold :: proc(r: rune) -> rune #no_bounds_check { + Fold_Pair :: struct { + from: u16, + to: u16, + } + + @(static, rodata) + ASCII_FOLD := [MAX_ASCII + 1]u16{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x212a, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x017f, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + } + + @(static, rodata) + CASE_ORBIT := [?]Fold_Pair{ + {0x004B, 0x006B}, {0x0053, 0x0073}, {0x006B, 0x212A}, {0x0073, 0x017F}, {0x00B5, 0x039C}, {0x00C5, 0x00E5}, {0x00DF, 0x1E9E}, + {0x00E5, 0x212B}, {0x0130, 0x0130}, {0x0131, 0x0131}, {0x017F, 0x0053}, {0x01C4, 0x01C5}, {0x01C5, 0x01C6}, {0x01C6, 0x01C4}, + {0x01C7, 0x01C8}, {0x01C8, 0x01C9}, {0x01C9, 0x01C7}, {0x01CA, 0x01CB}, {0x01CB, 0x01CC}, {0x01CC, 0x01CA}, {0x01F1, 0x01F2}, + {0x01F2, 0x01F3}, {0x01F3, 0x01F1}, {0x0345, 0x0399}, {0x0392, 0x03B2}, {0x0395, 0x03B5}, {0x0398, 0x03B8}, {0x0399, 0x03B9}, + {0x039A, 0x03BA}, {0x039C, 0x03BC}, {0x03A0, 0x03C0}, {0x03A1, 0x03C1}, {0x03A3, 0x03C2}, {0x03A6, 0x03C6}, {0x03A9, 0x03C9}, + {0x03B2, 0x03D0}, {0x03B5, 0x03F5}, {0x03B8, 0x03D1}, {0x03B9, 0x1FBE}, {0x03BA, 0x03F0}, {0x03BC, 0x00B5}, {0x03C0, 0x03D6}, + {0x03C1, 0x03F1}, {0x03C2, 0x03C3}, {0x03C3, 0x03A3}, {0x03C6, 0x03D5}, {0x03C9, 0x2126}, {0x03D0, 0x0392}, {0x03D1, 0x03F4}, + {0x03D5, 0x03A6}, {0x03D6, 0x03A0}, {0x03F0, 0x039A}, {0x03F1, 0x03A1}, {0x03F4, 0x0398}, {0x03F5, 0x0395}, {0x0412, 0x0432}, + {0x0414, 0x0434}, {0x041E, 0x043E}, {0x0421, 0x0441}, {0x0422, 0x0442}, {0x042A, 0x044A}, {0x0432, 0x1C80}, {0x0434, 0x1C81}, + {0x043E, 0x1C82}, {0x0441, 0x1C83}, {0x0442, 0x1C84}, {0x044A, 0x1C86}, {0x0462, 0x0463}, {0x0463, 0x1C87}, {0x1C80, 0x0412}, + {0x1C81, 0x0414}, {0x1C82, 0x041E}, {0x1C83, 0x0421}, {0x1C84, 0x1C85}, {0x1C85, 0x0422}, {0x1C86, 0x042A}, {0x1C87, 0x0462}, + {0x1C88, 0xA64A}, {0x1E60, 0x1E61}, {0x1E61, 0x1E9B}, {0x1E9B, 0x1E60}, {0x1E9E, 0x00DF}, {0x1FBE, 0x0345}, {0x2126, 0x03A9}, + {0x212A, 0x004B}, {0x212B, 0x00C5}, {0xA64A, 0xA64B}, {0xA64B, 0x1C88}, + } + + if r < 0 || r > MAX_RUNE { + return r + } + if int(r) < len(ASCII_FOLD) { + return rune(ASCII_FOLD[r]) + } + + lo, hi := 0, len(CASE_ORBIT) + for lo < hi { + m := int(uint(lo+hi) >> 1) + if rune(CASE_ORBIT[m].from) < r { + lo = m + 1 + } else { + hi = m + } + } + + if lo < len(CASE_ORBIT) && rune(CASE_ORBIT[lo].from) == r { + return rune(CASE_ORBIT[lo].to) + } + + + l := to_lower(r) + if l != r { + return l + } + return to_upper(r) +} diff --git a/core/unicode/letter.odin b/core/unicode/letter.odin index e6d0261c6..a1024dd6c 100644 --- a/core/unicode/letter.odin +++ b/core/unicode/letter.odin @@ -1,5 +1,7 @@ package unicode +import "base:runtime" + MAX_RUNE :: '\U00010fff' // Maximum valid unicode code point REPLACEMENT_CHAR :: '\ufffd' // Represented an invalid code point MAX_ASCII :: '\u007f' // Maximum ASCII value @@ -11,7 +13,8 @@ ZERO_WIDTH_JOINER :: '\u200D' WORD_JOINER :: '\u2060' @(require_results) -binary_search :: proc(c: i32, table: []i32, length, stride: int) -> int { +binary_search :: proc(c: i32, table: []i32, length, stride: int, loc := #caller_location) -> int #no_bounds_check { + runtime.bounds_check_error_loc(loc, length*stride-1, len(table)) n := length t := 0 for n > 1 { @@ -31,7 +34,7 @@ binary_search :: proc(c: i32, table: []i32, length, stride: int) -> int { } @(require_results) -to_lower :: proc(r: rune) -> rune { +to_lower :: proc(r: rune) -> rune #no_bounds_check { c := i32(r) p := binary_search(c, to_lower_ranges[:], len(to_lower_ranges)/3, 3) if p >= 0 && to_lower_ranges[p] <= c && c <= to_lower_ranges[p+1] { @@ -44,7 +47,7 @@ to_lower :: proc(r: rune) -> rune { return rune(c) } @(require_results) -to_upper :: proc(r: rune) -> rune { +to_upper :: proc(r: rune) -> rune #no_bounds_check { c := i32(r) p := binary_search(c, to_upper_ranges[:], len(to_upper_ranges)/3, 3) if p >= 0 && to_upper_ranges[p] <= c && c <= to_upper_ranges[p+1] { @@ -57,7 +60,7 @@ to_upper :: proc(r: rune) -> rune { return rune(c) } @(require_results) -to_title :: proc(r: rune) -> rune { +to_title :: proc(r: rune) -> rune #no_bounds_check { c := i32(r) p := binary_search(c, to_upper_singlets[:], len(to_title_singlets)/2, 2) if p >= 0 && c == to_upper_singlets[p] { @@ -68,7 +71,7 @@ to_title :: proc(r: rune) -> rune { @(require_results) -is_lower :: proc(r: rune) -> bool { +is_lower :: proc(r: rune) -> bool #no_bounds_check { if r <= MAX_ASCII { return u32(r)-'a' < 26 } @@ -85,7 +88,7 @@ is_lower :: proc(r: rune) -> bool { } @(require_results) -is_upper :: proc(r: rune) -> bool { +is_upper :: proc(r: rune) -> bool #no_bounds_check { if r <= MAX_ASCII { return u32(r)-'A' < 26 } @@ -103,7 +106,7 @@ is_upper :: proc(r: rune) -> bool { is_alpha :: is_letter @(require_results) -is_letter :: proc(r: rune) -> bool { +is_letter :: proc(r: rune) -> bool #no_bounds_check { if u32(r) <= MAX_LATIN1 { return char_properties[u8(r)]&pLmask != 0 } @@ -139,7 +142,7 @@ is_digit :: proc(r: rune) -> bool { is_white_space :: is_space @(require_results) -is_space :: proc(r: rune) -> bool { +is_space :: proc(r: rune) -> bool #no_bounds_check { if u32(r) <= MAX_LATIN1 { switch r { case '\t', '\n', '\v', '\f', '\r', ' ', 0x85, 0xa0: @@ -177,7 +180,7 @@ is_graphic :: proc(r: rune) -> bool { } @(require_results) -is_print :: proc(r: rune) -> bool { +is_print :: proc(r: rune) -> bool #no_bounds_check { if u32(r) <= MAX_LATIN1 { return char_properties[u8(r)]&pp != 0 } @@ -185,7 +188,7 @@ is_print :: proc(r: rune) -> bool { } @(require_results) -is_control :: proc(r: rune) -> bool { +is_control :: proc(r: rune) -> bool #no_bounds_check { if u32(r) <= MAX_LATIN1 { return char_properties[u8(r)]&pC != 0 } @@ -193,7 +196,7 @@ is_control :: proc(r: rune) -> bool { } @(require_results) -is_number :: proc(r: rune) -> bool { +is_number :: proc(r: rune) -> bool #no_bounds_check { if u32(r) <= MAX_LATIN1 { return char_properties[u8(r)]&pN != 0 } @@ -201,7 +204,7 @@ is_number :: proc(r: rune) -> bool { } @(require_results) -is_punct :: proc(r: rune) -> bool { +is_punct :: proc(r: rune) -> bool #no_bounds_check { if u32(r) <= MAX_LATIN1 { return char_properties[u8(r)]&pP != 0 } @@ -209,7 +212,7 @@ is_punct :: proc(r: rune) -> bool { } @(require_results) -is_symbol :: proc(r: rune) -> bool { +is_symbol :: proc(r: rune) -> bool #no_bounds_check { if u32(r) <= MAX_LATIN1 { return char_properties[u8(r)]&pS != 0 } @@ -267,7 +270,7 @@ is_prepended_concatenation_mark :: proc(r: rune) -> bool { // General_Category=Spacing_Mark @(require_results) -is_spacing_mark :: proc(r: rune) -> bool { +is_spacing_mark :: proc(r: rune) -> bool #no_bounds_check { c := i32(r) p := binary_search(c, spacing_mark_ranges[:], len(spacing_mark_ranges)/2, 2) if p >= 0 && spacing_mark_ranges[p] <= c && c <= spacing_mark_ranges[p+1] { @@ -278,7 +281,7 @@ is_spacing_mark :: proc(r: rune) -> bool { // General_Category=Nonspacing_Mark @(require_results) -is_nonspacing_mark :: proc(r: rune) -> bool { +is_nonspacing_mark :: proc(r: rune) -> bool #no_bounds_check { c := i32(r) p := binary_search(c, nonspacing_mark_ranges[:], len(nonspacing_mark_ranges)/2, 2) if p >= 0 && nonspacing_mark_ranges[p] <= c && c <= nonspacing_mark_ranges[p+1] { @@ -289,7 +292,7 @@ is_nonspacing_mark :: proc(r: rune) -> bool { // Extended_Pictographic @(require_results) -is_emoji_extended_pictographic :: proc(r: rune) -> bool { +is_emoji_extended_pictographic :: proc(r: rune) -> bool #no_bounds_check { c := i32(r) p := binary_search(c, emoji_extended_pictographic_ranges[:], len(emoji_extended_pictographic_ranges)/2, 2) if p >= 0 && emoji_extended_pictographic_ranges[p] <= c && c <= emoji_extended_pictographic_ranges[p+1] { @@ -300,7 +303,7 @@ is_emoji_extended_pictographic :: proc(r: rune) -> bool { // Grapheme_Extend @(require_results) -is_grapheme_extend :: proc(r: rune) -> bool { +is_grapheme_extend :: proc(r: rune) -> bool #no_bounds_check { c := i32(r) p := binary_search(c, grapheme_extend_ranges[:], len(grapheme_extend_ranges)/2, 2) if p >= 0 && grapheme_extend_ranges[p] <= c && c <= grapheme_extend_ranges[p+1] { @@ -330,7 +333,7 @@ is_hangul_syllable_trailing :: proc(r: rune) -> bool { // Hangul_Syllable_Type=LV_Syllable @(require_results) -is_hangul_syllable_lv :: proc(r: rune) -> bool { +is_hangul_syllable_lv :: proc(r: rune) -> bool #no_bounds_check { c := i32(r) p := binary_search(c, hangul_syllable_lv_singlets[:], len(hangul_syllable_lv_singlets), 1) if p >= 0 && c == hangul_syllable_lv_singlets[p] { @@ -341,7 +344,7 @@ is_hangul_syllable_lv :: proc(r: rune) -> bool { // Hangul_Syllable_Type=LVT_Syllable @(require_results) -is_hangul_syllable_lvt :: proc(r: rune) -> bool { +is_hangul_syllable_lvt :: proc(r: rune) -> bool #no_bounds_check { c := i32(r) p := binary_search(c, hangul_syllable_lvt_ranges[:], len(hangul_syllable_lvt_ranges)/2, 2) if p >= 0 && hangul_syllable_lvt_ranges[p] <= c && c <= hangul_syllable_lvt_ranges[p+1] { @@ -397,7 +400,7 @@ is_indic_conjunct_break_linker :: proc(r: rune) -> bool { // Indic_Conjunct_Break=Consonant @(require_results) -is_indic_conjunct_break_consonant :: proc(r: rune) -> bool { +is_indic_conjunct_break_consonant :: proc(r: rune) -> bool #no_bounds_check { c := i32(r) p := binary_search(c, indic_conjunct_break_consonant_ranges[:], len(indic_conjunct_break_consonant_ranges)/2, 2) if p >= 0 && indic_conjunct_break_consonant_ranges[p] <= c && c <= indic_conjunct_break_consonant_ranges[p+1] { @@ -408,7 +411,7 @@ is_indic_conjunct_break_consonant :: proc(r: rune) -> bool { // Indic_Conjunct_Break=Extend @(require_results) -is_indic_conjunct_break_extend :: proc(r: rune) -> bool { +is_indic_conjunct_break_extend :: proc(r: rune) -> bool #no_bounds_check { c := i32(r) p := binary_search(c, indic_conjunct_break_extend_ranges[:], len(indic_conjunct_break_extend_ranges)/2, 2) if p >= 0 && indic_conjunct_break_extend_ranges[p] <= c && c <= indic_conjunct_break_extend_ranges[p+1] { @@ -459,7 +462,7 @@ is_gcb_extend_class :: proc(r: rune) -> bool { // - 1 in all other cases. // @(require_results) -normalized_east_asian_width :: proc(r: rune) -> int { +normalized_east_asian_width :: proc(r: rune) -> int #no_bounds_check { // This is a different interpretation of the BOM which occurs in the middle of text. ZERO_WIDTH_NO_BREAK_SPACE :: '\uFEFF' diff --git a/core/unicode/utf16/utf16.odin b/core/unicode/utf16/utf16.odin index d3f98584b..990d5bafa 100644 --- a/core/unicode/utf16/utf16.odin +++ b/core/unicode/utf16/utf16.odin @@ -1,3 +1,4 @@ +// Procedures and constants to support text-encoding in the `UTF-16` character encoding. package utf16 import "core:unicode/utf8" diff --git a/core/unicode/utf8/utf8.odin b/core/unicode/utf8/utf8.odin index 67f8a8be9..281e36f43 100644 --- a/core/unicode/utf8/utf8.odin +++ b/core/unicode/utf8/utf8.odin @@ -1,3 +1,4 @@ +// Procedures and constants to support text-encoding in the `UTF-8` character encoding. package utf8 RUNE_ERROR :: '\ufffd' @@ -108,7 +109,7 @@ decode_rune_in_bytes :: proc "contextless" (s: []u8) -> (rune, int) { if n < 1 { return RUNE_ERROR, 0 } - s0 := s[0] + #no_bounds_check s0 := s[0] x := accept_sizes[s0] if x >= 0xF0 { mask := rune(x) << 31 >> 31 // NOTE(bill): Create 0x0000 or 0xffff. diff --git a/core/unicode/utf8/utf8string/string.odin b/core/unicode/utf8/utf8string/string.odin index 4b0fe7241..7ece469a4 100644 --- a/core/unicode/utf8/utf8string/string.odin +++ b/core/unicode/utf8/utf8string/string.odin @@ -1,3 +1,4 @@ +// A convenient and efficient way to index strings by `Unicode` code point (`rune`) rather than byte. package utf8string import "core:unicode/utf8" diff --git a/examples/all/all_vendor.odin b/examples/all/all_vendor.odin index 71bb6ef86..80f6c52bb 100644 --- a/examples/all/all_vendor.odin +++ b/examples/all/all_vendor.odin @@ -31,6 +31,7 @@ package all @(require) import "core:sys/darwin/Foundation" @(require) import "core:sys/darwin/CoreFoundation" @(require) import "core:sys/darwin/Security" +@(require) import "vendor:darwin/CoreVideo" @(require) import "vendor:darwin/Metal" @(require) import "vendor:darwin/MetalKit" @(require) import "vendor:darwin/QuartzCore" diff --git a/examples/all/all_vendor_windows.odin b/examples/all/all_vendor_windows.odin index b71b69a5a..8a0c29eaf 100644 --- a/examples/all/all_vendor_windows.odin +++ b/examples/all/all_vendor_windows.odin @@ -1,6 +1,7 @@ #+build windows package all +@(require) import "vendor:compress/lz4" @(require) import "vendor:wgpu/glfwglue" @(require) import "vendor:wgpu/sdl2glue" @(require) import "vendor:wgpu" diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 5f2e69546..398797900 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -20,6 +20,8 @@ gb_global BuiltinTypeIsProc *builtin_type_is_procs[BuiltinProc__type_simple_bool is_type_quaternion, is_type_string, is_type_string16, + is_type_cstring, + is_type_cstring16, is_type_typeid, is_type_any, is_type_endian_platform, @@ -55,6 +57,7 @@ gb_global BuiltinTypeIsProc *builtin_type_is_procs[BuiltinProc__type_simple_bool is_type_bit_field, is_type_simd_vector, is_type_matrix, + is_type_raw_union, is_type_polymorphic_record_specialized, is_type_polymorphic_record_unspecialized, @@ -210,7 +213,7 @@ gb_internal ObjcMsgKind get_objc_proc_kind(Type *return_type) { return ObjcMsg_normal; } -gb_internal void add_objc_proc_type(CheckerContext *c, Ast *call, Type *return_type, Slice param_types) { +void add_objc_proc_type(CheckerContext *c, Ast *call, Type *return_type, Slice param_types) { ObjcMsgKind kind = get_objc_proc_kind(return_type); Scope *scope = create_scope(c->info, nullptr); @@ -248,6 +251,12 @@ gb_internal void add_objc_proc_type(CheckerContext *c, Ast *call, Type *return_t try_to_add_package_dependency(c, "runtime", "objc_msgSend_fpret"); try_to_add_package_dependency(c, "runtime", "objc_msgSend_fp2ret"); try_to_add_package_dependency(c, "runtime", "objc_msgSend_stret"); + + Slice args = call->CallExpr.args; + if (args.count > 0 && args[0]->tav.objc_super_target) { + try_to_add_package_dependency(c, "runtime", "objc_msgSendSuper2"); + try_to_add_package_dependency(c, "runtime", "objc_msgSendSuper2_stret"); + } } gb_internal bool is_constant_string(CheckerContext *c, String const &builtin_name, Ast *expr, String *name_) { @@ -466,8 +475,8 @@ gb_internal bool check_builtin_objc_procedure(CheckerContext *c, Operand *operan isize capture_arg_count = ce->args.count - 1; - // NOTE(harold): The first parameter is already checked at check_builtin_procedure(). - // Checking again would invalidate the Entity -> Value map for direct parameters if it's the handler proc. + // NOTE(harold): The first argument is already checked at check_builtin_procedure(). + // Checking again would invalidate the Entity -> Value map for direct arguments if it's the handler proc. param_operands[0] = *operand; for (isize i = 0; i < ce->args.count-1; i++) { @@ -680,6 +689,52 @@ gb_internal bool check_builtin_objc_procedure(CheckerContext *c, Operand *operan operand->mode = Addressing_Value; return true; } break; + + case BuiltinProc_objc_super: + { + // Must be a pointer to an Objective-C object. + Type *objc_obj = operand->type; + if (!is_type_objc_ptr_to_object(objc_obj)) { + gbString e = expr_to_string(operand->expr); + gbString t = type_to_string(objc_obj); + error(operand->expr, "'%.*s' expected a pointer to an Objective-C object, but got '%s' of type %s", LIT(builtin_name), e, t); + gb_string_free(t); + gb_string_free(e); + return false; + } + + if (operand->mode != Addressing_Value && operand->mode != Addressing_Variable) { + gbString e = expr_to_string(operand->expr); + gbString t = type_to_string(operand->type); + error(operand->expr, "'%.*s' expression '%s', of type %s, must be a value or variable.", LIT(builtin_name), e, t); + gb_string_free(t); + gb_string_free(e); + return false; + } + + Type *obj_type = type_deref(objc_obj); + GB_ASSERT(obj_type->kind == Type_Named); + + // NOTE(harold) Track original type before transforming it to the superclass. + // This is needed because objc_msgSendSuper2 must start its search on the subclass, not the superclass. + call->tav.objc_super_target = obj_type; + + // The superclass type must be known at compile time. We require this so that the selector method expressions + // methods are resolved to the superclass's methods instead of the subclass's. + Type *superclass = obj_type->Named.type_name->TypeName.objc_superclass; + if (superclass == nullptr) { + gbString t = type_to_string(obj_type); + error(operand->expr, "'%.*s' target object '%.*s' does not have an Objective-C superclass. One must be set via the @(objc_superclass) attribute", LIT(builtin_name), t); + gb_string_free(t); + return false; + } + + GB_ASSERT(superclass->Named.type_name->TypeName.objc_class_name.len > 0); + + operand->type = alloc_type_pointer(superclass); + return true; + + } break; } } @@ -2516,6 +2571,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As case BuiltinProc_objc_register_class: case BuiltinProc_objc_ivar_get: case BuiltinProc_objc_block: + case BuiltinProc_objc_super: return check_builtin_objc_procedure(c, operand, call, id, type_hint); case BuiltinProc___entry_point: @@ -4830,6 +4886,138 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As break; } + case BuiltinProc_concatenate: { + Operand lhs = {}; + + check_expr_with_type_hint(c, &lhs, ce->args[0], type_hint); + if (lhs.mode == Addressing_Invalid) { + return false; + } + if (lhs.mode != Addressing_Constant) { + error(lhs.expr, "'%.*s' expects a constant array or slice", LIT(builtin_name)); + return false; + } + operand->type = lhs.type; + operand->mode = Addressing_Value; + + if (!is_type_slice(lhs.type) && !is_type_array(lhs.type)) { + gbString a = type_to_string(lhs.type); + error(lhs.expr, "'%.*s' expects a constant array or slice, got %s", LIT(builtin_name), a); + gb_string_free(a); + return false; + } + if (lhs.value.kind != ExactValue_Compound) { + gbString a = exact_value_to_string(lhs.value); + error(lhs.expr, "Expected a compound literal value for '%.*s', got '%s'", LIT(builtin_name), a); + gb_string_free(a); + return false; + } + + ast_node(lhs_cl, CompoundLit, lhs.value.value_compound); + + for (Ast *elem : lhs_cl->elems) { + if (elem->kind == Ast_FieldValue) { + error(elem, "'%.*s' does not allow the use of 'field = value' to be concatenated together", LIT(builtin_name)); + return false; + } + } + + Type *elem_type = base_any_array_type(lhs.type); + + for (isize i = 1; i < ce->args.count; i++) { + Operand extra = {}; + if (is_type_slice(lhs.type)) { + check_expr_with_type_hint(c, &extra, ce->args[i], lhs.type); + } else { + check_expr(c, &extra, ce->args[i]); + } + if (extra.mode == Addressing_Invalid) { + return false; + } + if (extra.mode != Addressing_Constant) { + error(extra.expr, "'%.*s' expects a constant array or slice", LIT(builtin_name)); + return false; + } + + if (is_type_slice(lhs.type)) { + if (!are_types_identical(lhs.type, extra.type)) { + gbString a = type_to_string(lhs.type); + gbString b = type_to_string(extra.type); + error(extra.expr, "'%.*s' expects constant values of the same slice type, got '%s' vs '%s'", LIT(builtin_name), a, b); + gb_string_free(b); + gb_string_free(a); + return false; + } + } else if (is_type_array(lhs.type)) { + if (!is_type_array(extra.type)) { + gbString a = type_to_string(extra.type); + error(extra.expr, "'%.*s' expects a constant array or slice, got %s", LIT(builtin_name), a); + gb_string_free(a); + return false; + } + Type *extra_elem_type = base_array_type(extra.type); + if (!are_types_identical(elem_type, extra_elem_type)) { + gbString a = type_to_string(elem_type); + gbString b = type_to_string(extra_elem_type); + error(extra.expr, "'%.*s' expects constant values of the same element-type, got '%s' vs '%s'", LIT(builtin_name), a, b); + gb_string_free(b); + gb_string_free(a); + return false; + } + } else { + GB_PANIC("Unhandled type: %s", type_to_string(lhs.type)); + } + + if (extra.value.kind != ExactValue_Compound) { + gbString a = exact_value_to_string(extra.value); + error(extra.expr, "Expected a compound literal value for '%.*s', got '%s'", LIT(builtin_name), a); + gb_string_free(a); + return false; + } + + ast_node(extra_cl, CompoundLit, extra.value.value_compound); + + + for (Ast *elem : extra_cl->elems) { + if (elem->kind == Ast_FieldValue) { + error(elem, "'%.*s' does not allow the use of 'field = value' to be concatenated together", LIT(builtin_name)); + return false; + } + } + } + + isize count_needed = 0; + + for (Ast *arg : ce->args) { + ExactValue value = arg->tav.value; + GB_ASSERT(value.kind == ExactValue_Compound); + ast_node(cl, CompoundLit, value.value_compound); + count_needed += cl->elems.count; + } + + Array new_elems = {}; + array_init(&new_elems, permanent_allocator(), 0, count_needed); + + for (Ast *arg : ce->args) { + ExactValue value = arg->tav.value; + GB_ASSERT(value.kind == ExactValue_Compound); + ast_node(cl, CompoundLit, value.value_compound); + array_add_elems(&new_elems, cl->elems.data, cl->elems.count); + } + + Ast *new_compound_lit = ast_compound_lit(lhs.expr->file(), nullptr, new_elems, ast_token(lhs.expr), ast_end_token(ce->args[ce->args.count-1])); + + operand->mode = Addressing_Constant; + operand->value = exact_value_compound(new_compound_lit); + + if (is_type_slice(lhs.type)) { + operand->type = lhs.type; + } else { + operand->type = alloc_type_array(elem_type, new_elems.count); + } + break; + } + case BuiltinProc_alloca: { Operand sz = {}; @@ -6370,10 +6558,12 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As case BuiltinProc_type_is_float: case BuiltinProc_type_is_complex: case BuiltinProc_type_is_quaternion: - case BuiltinProc_type_is_string: - case BuiltinProc_type_is_string16: case BuiltinProc_type_is_typeid: case BuiltinProc_type_is_any: + case BuiltinProc_type_is_string: + case BuiltinProc_type_is_string16: + case BuiltinProc_type_is_cstring: + case BuiltinProc_type_is_cstring16: case BuiltinProc_type_is_endian_platform: case BuiltinProc_type_is_endian_little: case BuiltinProc_type_is_endian_big: @@ -6405,6 +6595,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As case BuiltinProc_type_is_bit_field: case BuiltinProc_type_is_simd_vector: case BuiltinProc_type_is_matrix: + case BuiltinProc_type_is_raw_union: case BuiltinProc_type_is_specialized_polymorphic_record: case BuiltinProc_type_is_unspecialized_polymorphic_record: case BuiltinProc_type_has_nil: @@ -6467,7 +6658,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As check_expr(c, &x, ce->args[1]); if (!is_type_string(x.type) || x.mode != Addressing_Constant || x.value.kind != ExactValue_String) { - error(ce->args[1], "Expected a const string for field argument"); + error(ce->args[1], "Expected a constant string for field argument"); return false; } @@ -6547,7 +6738,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As check_expr(c, &x, ce->args[1]); if (!is_type_string(x.type) || x.mode != Addressing_Constant || x.value.kind != ExactValue_String) { - error(ce->args[1], "Expected a const string for field argument"); + error(ce->args[1], "Expected a constant string for field argument"); return false; } @@ -6684,9 +6875,13 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As // NOTE(jakubtomsu): forces calculation of variant_block_size type_size_of(u); - // NOTE(Jeroen): A tag offset of zero is perfectly fine if all members of the union are empty structs. - // What matters is that the tag size is > 0. - GB_ASSERT(u->Union.tag_size > 0); + if (u->Union.tag_size == 0) { + GB_ASSERT(is_type_union_maybe_pointer(u)); + } else { + // NOTE(Jeroen): A tag offset of zero is perfectly fine if all members of the union are empty structs. + // What matters is that the tag size is > 0. + GB_ASSERT(u->Union.tag_size > 0); + } operand->mode = Addressing_Constant; operand->type = t_untyped_integer; @@ -7180,7 +7375,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As check_expr(c, &x, ce->args[1]); if (!is_type_string(x.type) || x.mode != Addressing_Constant || x.value.kind != ExactValue_String) { - error(ce->args[1], "Expected a const string for field argument"); + error(ce->args[1], "Expected a constant string for field argument"); return false; } diff --git a/src/check_decl.cpp b/src/check_decl.cpp index b61c23fa7..e54943d80 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -559,6 +559,11 @@ gb_internal void check_type_decl(CheckerContext *ctx, Entity *e, Ast *init_expr, Type *super = ac.objc_superclass; while (super != nullptr) { + if (super->kind != Type_Named) { + error(e->token, "@(objc_superclass) Referenced type must be a named struct"); + break; + } + if (type_set_update(&super_set, super)) { error(e->token, "@(objc_superclass) Superclass hierarchy cycle encountered"); break; @@ -566,11 +571,6 @@ gb_internal void check_type_decl(CheckerContext *ctx, Entity *e, Ast *init_expr, check_single_global_entity(ctx->checker, super->Named.type_name, super->Named.type_name->decl_info); - if (super->kind != Type_Named) { - error(e->token, "@(objc_superclass) Referenced type must be a named struct"); - break; - } - Type* named_type = base_named_type(super); GB_ASSERT(named_type->kind == Type_Named); @@ -587,9 +587,7 @@ gb_internal void check_type_decl(CheckerContext *ctx, Entity *e, Ast *init_expr, super = named_type->Named.type_name->TypeName.objc_superclass; } } else { - if (ac.objc_superclass != nullptr) { - error(e->token, "@(objc_superclass) may only be applied when the @(obj_implement) attribute is also applied"); - } else if (ac.objc_ivar != nullptr) { + if (ac.objc_ivar != nullptr) { error(e->token, "@(objc_ivar) may only be applied when the @(obj_implement) attribute is also applied"); } else if (ac.objc_context_provider != nullptr) { error(e->token, "@(objc_context_provider) may only be applied when the @(obj_implement) attribute is also applied"); @@ -1084,61 +1082,100 @@ gb_internal void check_objc_methods(CheckerContext *ctx, Entity *e, AttributeCon // Enable implementation by default if the class is an implementer too and // @objc_implement was not set to false explicitly in this proc. bool implement = tn->TypeName.objc_is_implementation; + if( ac.objc_is_implementation && !tn->TypeName.objc_is_implementation ) { + error(e->token, "Cannot apply @(objc_is_implement) to a procedure whose type does not also have @(objc_is_implement) set"); + } + if (ac.objc_is_disabled_implement) { implement = false; } - if (implement) { - GB_ASSERT(e->kind == Entity_Procedure); + String objc_selector = ac.objc_selector != "" ? ac.objc_selector : ac.objc_name; + + if (e->kind == Entity_Procedure) { + bool has_body = e->decl_info->proc_lit->ProcLit.body != nullptr; + e->Procedure.is_objc_impl_or_import = implement || !has_body; + e->Procedure.is_objc_class_method = ac.objc_is_class_method; + e->Procedure.objc_selector_name = objc_selector; + e->Procedure.objc_class = tn; auto &proc = e->type->Proc; Type *first_param = proc.param_count > 0 ? proc.params->Tuple.variables[0]->type : t_untyped_nil; - if (!tn->TypeName.objc_is_implementation) { - error(e->token, "@(objc_is_implement) attribute may only be applied to procedures whose class also have @(objc_is_implement) applied"); - } else if (!ac.objc_is_class_method && !(first_param->kind == Type_Pointer && internal_check_is_assignable_to(t, first_param->Pointer.elem))) { - error(e->token, "Objective-C instance methods implementations require the first parameter to be a pointer to the class type set by @(objc_type)"); - } else if (proc.calling_convention == ProcCC_Odin && !tn->TypeName.objc_context_provider) { - error(e->token, "Objective-C methods with Odin calling convention can only be used with classes that have @(objc_context_provider) set"); - } else if (ac.objc_is_class_method && proc.calling_convention != ProcCC_CDecl) { - error(e->token, "Objective-C class methods (objc_is_class_method=true) that have @objc_is_implementation can only use \"c\" calling convention"); - } else if (proc.result_count > 1) { - error(e->token, "Objective-C method implementations may return at most 1 value"); - } else { - // Always export unconditionally - // NOTE(harold): This means check_objc_methods() MUST be called before - // e->Procedure.is_export is set in check_proc_decl()! - if (ac.is_export) { - error(e->token, "Explicit export not allowed when @(objc_implement) is set. It set exported implicitly"); - } - if (ac.link_name != "") { - error(e->token, "Explicit linkage not allowed when @(objc_implement) is set. It set to \"strong\" implicitly"); - } - - ac.is_export = true; - ac.linkage = STR_LIT("strong"); - - auto method = ObjcMethodData{ ac, e }; - method.ac.objc_selector = ac.objc_selector != "" ? ac.objc_selector : ac.objc_name; - - CheckerInfo *info = ctx->info; - mutex_lock(&info->objc_method_mutex); - defer (mutex_unlock(&info->objc_method_mutex)); - - Array* method_list = map_get(&info->objc_method_implementations, t); - if (method_list) { - array_add(method_list, method); + if (implement) { + if( !has_body ) { + error(e->token, "Procedures with @(objc_is_implement) must have a body"); + } else if (!tn->TypeName.objc_is_implementation) { + error(e->token, "@(objc_is_implement) attribute may only be applied to procedures whose class also have @(objc_is_implement) applied"); + } else if (!ac.objc_is_class_method && !(first_param->kind == Type_Pointer && internal_check_is_assignable_to(t, first_param->Pointer.elem))) { + error(e->token, "Objective-C instance methods implementations require the first parameter to be a pointer to the class type set by @(objc_type)"); + } else if (proc.calling_convention == ProcCC_Odin && !tn->TypeName.objc_context_provider) { + error(e->token, "Objective-C methods with Odin calling convention can only be used with classes that have @(objc_context_provider) set"); + } else if (ac.objc_is_class_method && proc.calling_convention != ProcCC_CDecl) { + error(e->token, "Objective-C class methods (objc_is_class_method=true) that have @objc_is_implementation can only use \"c\" calling convention"); + } else if (proc.result_count > 1) { + error(e->token, "Objective-C method implementations may return at most 1 value"); } else { - auto list = array_make(permanent_allocator(), 1, 8); - list[0] = method; + // Always export unconditionally + // NOTE(harold): This means check_objc_methods() MUST be called before + // e->Procedure.is_export is set in check_proc_decl()! + if (ac.is_export) { + error(e->token, "Explicit export not allowed when @(objc_implement) is set. It set exported implicitly"); + } + if (ac.link_name != "") { + error(e->token, "Explicit linkage not allowed when @(objc_implement) is set. It set to \"strong\" implicitly"); + } - map_set(&info->objc_method_implementations, t, list); + ac.is_export = true; + ac.linkage = STR_LIT("strong"); + + auto method = ObjcMethodData{ ac, e }; + method.ac.objc_selector = objc_selector; + + CheckerInfo *info = ctx->info; + mutex_lock(&info->objc_method_mutex); + defer (mutex_unlock(&info->objc_method_mutex)); + + Array* method_list = map_get(&info->objc_method_implementations, t); + if (method_list) { + array_add(method_list, method); + } else { + auto list = array_make(permanent_allocator(), 1, 8); + list[0] = method; + + map_set(&info->objc_method_implementations, t, list); + } + } + } else if (!has_body) { + if (ac.objc_selector == "The @(objc_selector) attribute is required for imported Objective-C methods.") { + return; + } else if (proc.calling_convention != ProcCC_CDecl) { + error(e->token, "Imported Objective-C methods must use the \"c\" calling convention"); + return; + } else if (tn->TypeName.objc_context_provider) { + error(e->token, "Imported Objective-C class '%.*s' must not declare context providers.", tn->type->Named.name); + return; + } else if (tn->TypeName.objc_is_implementation) { + error(e->token, "Imported Objective-C methods used in a class with @(objc_implement) is not allowed."); + return; + } else if (!ac.objc_is_class_method && !(first_param->kind == Type_Pointer && internal_check_is_assignable_to(t, first_param->Pointer.elem))) { + error(e->token, "Objective-C instance methods require the first parameter to be a pointer to the class type set by @(objc_type)"); + return; } } - } else if (ac.objc_selector != "") { - error(e->token, "@(objc_selector) may only be applied to procedures that are Objective-C implementations."); + else if(ac.objc_selector != "") { + error(e->token, "@(objc_selector) may only be applied to procedures that are Objective-C method implementations or are imported."); + return; + } + } else { + GB_ASSERT(e->kind == Entity_ProcGroup); + if (tn->TypeName.objc_is_implementation) { + error(e->token, "Objective-C procedure groups cannot use the @(objc_implement) attribute."); + return; + } } + mutex_lock(&global_type_name_objc_metadata_mutex); defer (mutex_unlock(&global_type_name_objc_metadata_mutex)); @@ -1523,7 +1560,7 @@ gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { if (!pt->is_polymorphic) { check_procedure_later(ctx->checker, ctx->file, e->token, d, proc_type, pl->body, pl->tags); } - } else if (!is_foreign) { + } else if (!is_foreign && !e->Procedure.is_objc_impl_or_import) { if (e->Procedure.is_export) { error(e->token, "Foreign export procedures must have a body"); } else { @@ -1571,6 +1608,7 @@ gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { // NOTE(bill): this must be delayed because the foreign import paths might not be evaluated yet until much later mpsc_enqueue(&ctx->info->foreign_decls_to_check, e); } else { + // TODO(harold): Check if it's an objective-C foreign, if so, I don't think we need to check it. check_foreign_procedure(ctx, e, d); } } else { diff --git a/src/check_expr.cpp b/src/check_expr.cpp index c6f7e022e..e22f12323 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -3239,6 +3239,9 @@ gb_internal void check_shift(CheckerContext *c, Operand *x, Operand *y, Ast *nod } gb_internal bool check_is_castable_to(CheckerContext *c, Operand *operand, Type *y) { + if (are_types_identical(operand->type, y)) { + return true; + } if (check_is_assignable_to(c, operand, y)) { return true; } @@ -3523,20 +3526,31 @@ gb_internal bool check_cast_internal(CheckerContext *c, Operand *x, Type *type) Type *bt = base_type(type); if (is_const_expr && is_type_constant_type(bt)) { + Type *elem = core_array_type(bt); + if (core_type(bt)->kind == Type_Basic) { - if (check_representable_as_constant(c, x->value, bt, &x->value)) { + if (check_representable_as_constant(c, x->value, type, &x->value)) { return true; - } else if (check_is_castable_to(c, x, type)) { - if (is_type_pointer(type)) { - return true; - } } + goto check_castable; + } else if (!are_types_identical(elem, bt) && + elem->kind == Type_Basic && + check_representable_as_constant(c, x->value, elem, &x->value)) { + if (check_representable_as_constant(c, x->value, type, &x->value)) { + return true; + } + goto check_castable; } else if (check_is_castable_to(c, x, type)) { x->value = {}; x->mode = Addressing_Value; return true; } - } else if (check_is_castable_to(c, x, type)) { + + return false; + } + +check_castable: + if (check_is_castable_to(c, x, type)) { if (x->mode != Addressing_Constant) { x->mode = Addressing_Value; } else if (is_type_slice(type) && is_type_string(x->type)) { @@ -6211,7 +6225,6 @@ gb_internal isize get_procedure_param_count_excluding_defaults(Type *pt, isize * continue; } } - break; } } @@ -7483,8 +7496,6 @@ gb_internal CallArgumentData check_call_arguments_proc_group(CheckerContext *c, Entity *e = proc_entities[valids[0].index]; GB_ASSERT(e != nullptr); - Array named_operands = {}; - check_call_arguments_single(c, call, operand, e, e->type, positional_operands, named_operands, @@ -8146,6 +8157,73 @@ gb_internal ExprKind check_call_expr_as_type_cast(CheckerContext *c, Operand *op } +void add_objc_proc_type(CheckerContext *c, Ast *call, Type *return_type, Slice param_types); + +gb_internal void check_objc_call_expr(CheckerContext *c, Operand *operand, Ast *call, Entity *proc_entity, Type *proc_type) { + auto &proc = proc_type->Proc; + Slice params = proc.params ? proc.params->Tuple.variables : Slice{}; + + Type *self_type = nullptr; + isize params_start = 1; + + ast_node(ce, CallExpr, call); + + Type *return_type = proc.result_count == 0 ? nullptr : proc.results->Tuple.variables[0]->type; + bool is_return_instancetype = return_type != nullptr && return_type == t_objc_instancetype; + + if (params.count == 0 || !is_type_objc_ptr_to_object(params[0]->type)) { + if (!proc_entity->Procedure.is_objc_class_method) { + // Not a class method, invalid call + error(call, "Invalid Objective-C call: The Objective-C method is not a class method but this first parameter is not an Objective-C object pointer."); + return; + } + + if (is_return_instancetype) { + if (ce->proc->kind == Ast_SelectorExpr) { + ast_node(se, SelectorExpr, ce->proc); + + // NOTE(harold): These should have already been checked, right? + GB_ASSERT(se->expr->tav.mode == Addressing_Type && se->expr->tav.type->kind == Type_Named); + + return_type = alloc_type_pointer(se->expr->tav.type); + } else { + return_type = proc_entity->Procedure.objc_class->type; + } + } + + self_type = t_objc_Class; + params_start = 0; + } else if (ce->args.count > 0) { + GB_ASSERT(is_type_objc_ptr_to_object(params[0]->type)); + + if (ce->args[0]->tav.objc_super_target) { + self_type = t_objc_super_ptr; + } else { + self_type = ce->args[0]->tav.type; + } + + if (is_return_instancetype) { + // NOTE(harold): These should have already been checked, right? + GB_ASSERT(ce->args[0]->tav.type && ce->args[0]->tav.type->kind == Type_Pointer && ce->args[0]->tav.type->Pointer.elem->kind == Type_Named); + + return_type = ce->args[0]->tav.type; + } + } + + auto param_types = slice_make(permanent_allocator(), proc.param_count + 2 - params_start); + param_types[0] = self_type; + param_types[1] = t_objc_SEL; + + for (isize i = params_start; i < params.count; i++) { + param_types[i+2-params_start] = params[i]->type; + } + + if (is_return_instancetype) { + operand->type = return_type; + } + + add_objc_proc_type(c, call, return_type, param_types); +} gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *call, Ast *proc, Slice const &args, ProcInlining inlining, Type *type_hint) { if (proc != nullptr && @@ -8409,6 +8487,12 @@ gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *c } } + Entity *proc_entity = entity_from_expr(call->CallExpr.proc); + bool is_objc_call = proc_entity && proc_entity->kind == Entity_Procedure && proc_entity->Procedure.is_objc_impl_or_import; + if (is_objc_call) { + check_objc_call_expr(c, operand, call, proc_entity, pt); + } + return Expr_Expr; } diff --git a/src/checker.cpp b/src/checker.cpp index 32bda2e43..8b3638c9d 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1416,6 +1416,8 @@ gb_internal void init_universal(void) { t_objc_SEL = alloc_type_pointer(t_objc_selector); t_objc_Class = alloc_type_pointer(t_objc_class); t_objc_Ivar = alloc_type_pointer(t_objc_ivar); + + t_objc_instancetype = add_global_type_name(intrinsics_pkg->scope, str_lit("objc_instancetype"), t_objc_id); } } @@ -1499,9 +1501,12 @@ gb_internal void destroy_checker_info(CheckerInfo *i) { map_destroy(&i->objc_msgSend_types); string_set_destroy(&i->obcj_class_name_set); - mpsc_destroy(&i->objc_class_implementations); map_destroy(&i->objc_method_implementations); + // NOTE(harold): Disabling this: It can cause the 'count == 0' assert to trigger + // when there's checker errors and the queue is still full as it did not reach the generation stage. + // mpsc_destroy(&i->objc_class_implementations); + string_map_destroy(&i->load_file_cache); string_map_destroy(&i->load_directory_cache); map_destroy(&i->load_directory_map); @@ -3386,12 +3391,20 @@ gb_internal void init_core_map_type(Checker *c) { t_raw_map_ptr = alloc_type_pointer(t_raw_map); } +gb_internal void init_core_objc_c(Checker *c) { + if (build_context.metrics.os == TargetOs_darwin) { + t_objc_super = find_core_type(c, str_lit("objc_super")); + t_objc_super_ptr = alloc_type_pointer(t_objc_super); + } +} + gb_internal void init_preload(Checker *c) { init_core_type_info(c); init_mem_allocator(c); init_core_context(c); init_core_source_code_location(c); init_core_map_type(c); + init_core_objc_c(c); } gb_internal ExactValue check_decl_attribute_value(CheckerContext *c, Ast *value) { @@ -5080,26 +5093,22 @@ gb_internal void add_import_dependency_node(Checker *c, Ast *decl, PtrMapscope != nullptr); + AstPackage *child_pkg = *found; + GB_ASSERT(child_pkg->scope != nullptr); - id->package = pkg; + id->package = child_pkg; - ImportGraphNode **found_node = nullptr; - ImportGraphNode *m = nullptr; - ImportGraphNode *n = nullptr; - - found_node = map_get(M, pkg); + ImportGraphNode **found_node = map_get(M, child_pkg); GB_ASSERT(found_node != nullptr); - m = *found_node; + ImportGraphNode *child = *found_node; found_node = map_get(M, parent_pkg); GB_ASSERT(found_node != nullptr); - n = *found_node; + ImportGraphNode *parent = *found_node; - import_graph_node_set_add(&n->succ, m); - import_graph_node_set_add(&m->pred, n); - ptr_set_add(&m->scope->imported, n->scope); + import_graph_node_set_add(&parent->succ, child); + import_graph_node_set_add(&child->pred, parent); + ptr_set_add(&parent->scope->imported, child->scope); case_end; case_ast_node(ws, WhenStmt, decl); diff --git a/src/checker_builtin_procs.hpp b/src/checker_builtin_procs.hpp index c6071bf98..01502128a 100644 --- a/src/checker_builtin_procs.hpp +++ b/src/checker_builtin_procs.hpp @@ -56,6 +56,8 @@ enum BuiltinProcId { BuiltinProc_soa_struct, + BuiltinProc_concatenate, + BuiltinProc_alloca, BuiltinProc_cpu_relax, BuiltinProc_trap, @@ -251,6 +253,8 @@ BuiltinProc__type_simple_boolean_begin, BuiltinProc_type_is_quaternion, BuiltinProc_type_is_string, BuiltinProc_type_is_string16, + BuiltinProc_type_is_cstring, + BuiltinProc_type_is_cstring16, BuiltinProc_type_is_typeid, BuiltinProc_type_is_any, @@ -285,6 +289,8 @@ BuiltinProc__type_simple_boolean_begin, BuiltinProc_type_is_bit_set, BuiltinProc_type_is_simd_vector, BuiltinProc_type_is_matrix, + BuiltinProc_type_is_raw_union, + BuiltinProc_type_is_specialized_polymorphic_record, BuiltinProc_type_is_unspecialized_polymorphic_record, @@ -354,6 +360,7 @@ BuiltinProc__type_end, BuiltinProc_objc_register_class, BuiltinProc_objc_ivar_get, BuiltinProc_objc_block, + BuiltinProc_objc_super, BuiltinProc_constant_utf16_cstring, @@ -422,6 +429,8 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { {STR_LIT("soa_struct"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, // Type + {STR_LIT("concatenate"), 2, true, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("alloca"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("cpu_relax"), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, @@ -611,10 +620,12 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { {STR_LIT("type_is_float"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_complex"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_quaternion"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("type_is_string"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("type_is_string16"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_typeid"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_any"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("type_is_string"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("type_is_string16"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("type_is_cstring"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("type_is_cstring16"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_endian_platform"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_endian_little"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, @@ -648,6 +659,7 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { {STR_LIT("type_is_bit_field"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_simd_vector"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_matrix"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("type_is_raw_union"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_specialized_polymorphic_record"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_unspecialized_polymorphic_record"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, @@ -715,7 +727,8 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { {STR_LIT("objc_register_selector"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true}, {STR_LIT("objc_register_class"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true}, {STR_LIT("objc_ivar_get"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true}, - {STR_LIT("objc_block"), 1, true, Expr_Expr, BuiltinProcPkg_intrinsics, false, true}, + {STR_LIT("objc_block"), 1, true, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("objc_super"), 1, true, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("constant_utf16_cstring"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, diff --git a/src/entity.cpp b/src/entity.cpp index d6d8f58de..2b21fdcac 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -251,6 +251,8 @@ struct Entity { String link_name; String link_prefix; String link_suffix; + String objc_selector_name; + Entity *objc_class; DeferredProcedure deferred_procedure; struct GenProcsData *gen_procs; @@ -266,6 +268,8 @@ struct Entity { bool is_anonymous : 1; bool no_sanitize_address : 1; bool no_sanitize_memory : 1; + bool is_objc_impl_or_import : 1; + bool is_objc_class_method : 1; } Procedure; struct { Array entities; diff --git a/src/exact_value.cpp b/src/exact_value.cpp index f2aed84c2..e7077bd5b 100644 --- a/src/exact_value.cpp +++ b/src/exact_value.cpp @@ -908,8 +908,8 @@ gb_internal ExactValue exact_binary_operator_value(TokenKind op, ExactValue x, E if (op != Token_Add) goto error; // NOTE(bill): How do you minimize this over allocation? - String sx = x.value_string; - String sy = y.value_string; + String16 sx = x.value_string16; + String16 sy = y.value_string16; isize len = sx.len+sy.len; u16 *data = gb_alloc_array(permanent_allocator(), u16, len); gb_memmove(data, sx.text, sx.len*gb_size_of(u16)); diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index ab0811085..c2decf091 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -1417,8 +1417,21 @@ String lb_get_objc_type_encoding(Type *t, isize pointer_depth = 0) { return str_lit("?"); case Type_Proc: return str_lit("?"); - case Type_BitSet: - return lb_get_objc_type_encoding(t->BitSet.underlying, pointer_depth); + case Type_BitSet: { + Type *bitset_integer_type = t->BitSet.underlying; + if (!bitset_integer_type) { + switch (t->cached_size) { + case 1: bitset_integer_type = t_u8; break; + case 2: bitset_integer_type = t_u16; break; + case 4: bitset_integer_type = t_u32; break; + case 8: bitset_integer_type = t_u64; break; + case 16: bitset_integer_type = t_u128; break; + } + } + GB_ASSERT_MSG(bitset_integer_type, "Could not determine bit_set integer size for objc_type_encoding"); + + return lb_get_objc_type_encoding(bitset_integer_type, pointer_depth); + } case Type_SimdVector: { String type_str = lb_get_objc_type_encoding(t->SimdVector.elem, pointer_depth); @@ -1452,7 +1465,10 @@ String lb_get_objc_type_encoding(Type *t, isize pointer_depth = 0) { struct lbObjCGlobalClass { lbObjCGlobal g; - lbValue class_value; // Local registered class value + union { + lbValue class_value; // Local registered class value + lbAddr class_global; // Global class pointer. Placeholder for class implementations which are registered in order of definition. + }; }; gb_internal void lb_register_objc_thing( @@ -1482,44 +1498,43 @@ gb_internal void lb_register_objc_thing( LLVMSetInitializer(v.value, LLVMConstNull(t)); } - lbValue class_ptr = {}; - lbValue class_name = lb_const_value(m, t_cstring, exact_value_string(g.name)); - // If this class requires an implementation, save it for registration below. if (g.class_impl_type != nullptr) { // Make sure the superclass has been initialized before us - lbValue superclass_value = lb_const_nil(m, t_objc_Class); - auto &tn = g.class_impl_type->Named.type_name->TypeName; Type *superclass = tn.objc_superclass; if (superclass != nullptr) { auto& superclass_global = string_map_must_get(&class_map, superclass->Named.type_name->TypeName.objc_class_name); lb_register_objc_thing(handled, m, args, class_impls, class_map, p, superclass_global.g, call); - GB_ASSERT(superclass_global.class_value.value); - - superclass_value = superclass_global.class_value; + GB_ASSERT(superclass_global.class_global.addr.value); } - args.count = 3; - args[0] = superclass_value; - args[1] = class_name; - args[2] = lb_const_int(m, t_uint, 0); - class_ptr = lb_emit_runtime_call(p, "objc_allocateClassPair", args); + lbObjCGlobalClass impl_global = {}; + impl_global.g = g; + impl_global.class_global = addr; - array_add(&class_impls, lbObjCGlobalClass{g, class_ptr}); + array_add(&class_impls, impl_global); + + lbObjCGlobalClass* class_global = string_map_get(&class_map, g.name); + if (class_global != nullptr) { + class_global->class_global = addr; + } } else { + lbValue class_ptr = {}; + lbValue class_name = lb_const_value(m, t_cstring, exact_value_string(g.name)); + args.count = 1; args[0] = class_name; class_ptr = lb_emit_runtime_call(p, call, args); - } - lb_addr_store(p, addr, class_ptr); + lb_addr_store(p, addr, class_ptr); - lbObjCGlobalClass* class_global = string_map_get(&class_map, g.name); - if (class_global != nullptr) { - class_global->class_value = class_ptr; + lbObjCGlobalClass* class_global = string_map_get(&class_map, g.name); + if (class_global != nullptr) { + class_global->class_value = class_ptr; + } } } @@ -1582,7 +1597,7 @@ gb_internal void lb_finalize_objc_names(lbGenerator *gen, lbProcedure *p) { string_map_init(&global_class_map, (usize)gen->objc_classes.count); defer (string_map_destroy(&global_class_map)); - for (lbObjCGlobal g :referenced_classes) { + for (lbObjCGlobal g : referenced_classes) { string_map_set(&global_class_map, g.name, lbObjCGlobalClass{g}); } @@ -1629,9 +1644,36 @@ gb_internal void lb_finalize_objc_names(lbGenerator *gen, lbProcedure *p) { for (const auto &cd : class_impls) { auto &g = cd.g; - Type *class_type = g.class_impl_type; + + Type *class_type = g.class_impl_type; Type *class_ptr_type = alloc_type_pointer(class_type); - lbValue class_value = cd.class_value; + + // Begin class registration: create class pair and update global reference + lbValue class_value = {}; + + { + lbValue superclass_value = lb_const_nil(m, t_objc_Class); + + auto& tn = class_type->Named.type_name->TypeName; + Type *superclass = tn.objc_superclass; + + if (superclass != nullptr) { + auto& superclass_global = string_map_must_get(&global_class_map, superclass->Named.type_name->TypeName.objc_class_name); + superclass_value = superclass_global.class_value; + } + + args.count = 3; + args[0] = superclass_value; + args[1] = lb_const_value(m, t_cstring, exact_value_string(g.name)); + args[2] = lb_const_int(m, t_uint, 0); + class_value = lb_emit_runtime_call(p, "objc_allocateClassPair", args); + + lbObjCGlobalClass &mapped_global = string_map_must_get(&global_class_map, tn.objc_class_name); + lb_addr_store(p, mapped_global.class_global, class_value); + + mapped_global.class_value = class_value; + } + Type *ivar_type = class_type->Named.type_name->TypeName.objc_ivar; @@ -1651,7 +1693,6 @@ gb_internal void lb_finalize_objc_names(lbGenerator *gen, lbProcedure *p) { is_context_provider_ivar = ivar_type != nullptr && internal_check_is_assignable_to(contex_provider_self_named_type, ivar_type); } - Array *methods = map_get(&m->info->objc_method_implementations, class_type); if (!methods) { continue; @@ -1710,17 +1751,21 @@ gb_internal void lb_finalize_objc_names(lbGenerator *gen, lbProcedure *p) { wrapper_results_tuple, method_type->Proc.result_count, false, ProcCC_CDecl); lbProcedure *wrapper_proc = lb_create_dummy_procedure(m, proc_name, wrapper_proc_type); - lb_add_attribute_to_proc(wrapper_proc->module, wrapper_proc->value, "nounwind"); + + lb_add_function_type_attributes(wrapper_proc->value, lb_get_function_type(m, wrapper_proc_type), ProcCC_CDecl); // Emit the wrapper - LLVMSetLinkage(wrapper_proc->value, LLVMExternalLinkage); + // LLVMSetLinkage(wrapper_proc->value, LLVMInternalLinkage); + LLVMSetDLLStorageClass(wrapper_proc->value, LLVMDLLExportStorageClass); + lb_add_attribute_to_proc(wrapper_proc->module, wrapper_proc->value, "nounwind"); + lb_begin_procedure_body(wrapper_proc); { + LLVMValueRef context_addr = nullptr; if (method_type->Proc.calling_convention == ProcCC_Odin) { GB_ASSERT(context_provider); // Emit the get odin context call - get_context_args[0] = lbValue { wrapper_proc->raw_input_parameters[0], contex_provider_self_ptr_type, @@ -1736,44 +1781,58 @@ gb_internal void lb_finalize_objc_names(lbGenerator *gen, lbProcedure *p) { get_context_args[0] = lb_handle_objc_ivar_for_objc_object_pointer(wrapper_proc, real_self); } - lbValue context = lb_emit_call(wrapper_proc, context_provider_proc_value, get_context_args); - lbAddr context_addr = lb_addr(lb_address_from_load_or_generate_local(wrapper_proc, context)); - lb_push_context_onto_stack(wrapper_proc, context_addr); + lbValue context = lb_emit_call(wrapper_proc, context_provider_proc_value, get_context_args); + context_addr = lb_address_from_load(wrapper_proc, context).value;//lb_address_from_load_or_generate_local(wrapper_proc, context)); + // context_addr = LLVMGetOperand(context.value, 0); } + isize method_forward_arg_count = method_param_count + method_param_offset; + isize method_forward_return_arg_offset = 0; + auto raw_method_args = array_make(temporary_allocator(), 0, method_forward_arg_count+1); - auto method_call_args = array_make(temporary_allocator(), method_param_count + method_param_offset); + lbValue method_proc_value = lb_find_procedure_value_from_entity(m, md.proc_entity); + lbFunctionType* ft = lb_get_function_type(m, method_type); + bool has_return = false; + lbArgKind return_kind = {}; + + if (wrapper_results_tuple != nullptr) { + has_return = true; + return_kind = ft->ret.kind; + + if (return_kind == lbArg_Indirect) { + method_forward_return_arg_offset = 1; + array_add(&raw_method_args, wrapper_proc->return_ptr.addr.value); + } + } if (!md.ac.objc_is_class_method) { - method_call_args[0] = lbValue { - wrapper_proc->raw_input_parameters[0], - class_ptr_type, - }; + array_add(&raw_method_args, wrapper_proc->raw_input_parameters[method_forward_return_arg_offset]); } for (isize i = 0; i < method_param_count; i++) { - method_call_args[i+method_param_offset] = lbValue { - wrapper_proc->raw_input_parameters[i+2], - method_type->Proc.params->Tuple.variables[i+method_param_offset]->type, - }; + array_add(&raw_method_args, wrapper_proc->raw_input_parameters[i+2+method_forward_return_arg_offset]); + } + + if (method_type->Proc.calling_convention == ProcCC_Odin) { + array_add(&raw_method_args, context_addr); } - lbValue method_proc_value = lb_find_procedure_value_from_entity(m, md.proc_entity); // Call real procedure for method from here, passing the parameters expected, if any. - lbValue return_value = lb_emit_call(wrapper_proc, method_proc_value, method_call_args); + LLVMTypeRef fnp = lb_type_internal_for_procedures_raw(m, method_type); + LLVMValueRef ret_val_raw = LLVMBuildCall2(wrapper_proc->builder, fnp, method_proc_value.value, raw_method_args.data, (unsigned)raw_method_args.count, ""); - if (wrapper_results_tuple != nullptr) { - auto &result_var = method_type->Proc.results->Tuple.variables[0]; - return_value = lb_emit_conv(wrapper_proc, return_value, result_var->type); - lb_build_return_stmt_internal(wrapper_proc, return_value, result_var->token.pos); + if (has_return && return_kind != lbArg_Indirect) { + LLVMBuildRet(wrapper_proc->builder, ret_val_raw); + } + else { + LLVMBuildRetVoid(wrapper_proc->builder); } } lb_end_procedure_body(wrapper_proc); - // Add the method to the class String method_encoding = str_lit("v"); - // TODO (harold): Checker must ensure that objc_methods have a single return value or none! + GB_ASSERT(method_type->Proc.result_count <= 1); if (method_type->Proc.result_count != 0) { method_encoding = lb_get_objc_type_encoding(method_type->Proc.results->Tuple.variables[0]->type); @@ -1785,8 +1844,8 @@ gb_internal void lb_finalize_objc_names(lbGenerator *gen, lbProcedure *p) { method_encoding = concatenate_strings(temporary_allocator(), method_encoding, str_lit("#:")); } - for (isize i = method_param_offset; i < method_param_count; i++) { - Type *param_type = method_type->Proc.params->Tuple.variables[i]->type; + for (isize i = 0; i < method_param_count; i++) { + Type *param_type = method_type->Proc.params->Tuple.variables[i + method_param_offset]->type; String param_encoding = lb_get_objc_type_encoding(param_type); method_encoding = concatenate_strings(temporary_allocator(), method_encoding, param_encoding); @@ -1805,7 +1864,7 @@ gb_internal void lb_finalize_objc_names(lbGenerator *gen, lbProcedure *p) { args[2] = lbValue { wrapper_proc->value, wrapper_proc->type }; args[3] = lb_const_value(m, t_cstring, exact_value_string(method_encoding)); - // TODO(harold): Emit check BOOL result and panic if false. + // TODO(harold): Emit check BOOL result and panic if false? lb_emit_runtime_call(p, "class_addMethod", args); } // End methods @@ -1853,7 +1912,7 @@ gb_internal void lb_finalize_objc_names(lbGenerator *gen, lbProcedure *p) { // Defined in an external package, define it now in the main package LLVMTypeRef t = lb_type(m, t_int); - lbValue global{}; + lbValue global = {}; global.value = LLVMAddGlobal(m->mod, t, g.global_name); global.type = t_int_ptr; @@ -2041,7 +2100,8 @@ gb_internal void lb_create_startup_runtime_generate_body(lbModule *m, lbProcedur lb_end_procedure_body(dummy); LLVMValueRef context_ptr = lb_find_or_generate_context_ptr(p).addr.value; - LLVMBuildCall2(p->builder, raw_dummy_type, dummy->value, &context_ptr, 1, ""); + LLVMValueRef cast_ctx = LLVMBuildBitCast(p->builder, context_ptr, LLVMPointerType(LLVMInt8TypeInContext(m->ctx), 0), ""); + LLVMBuildCall2(p->builder, raw_dummy_type, dummy->value, &cast_ctx, 1, ""); } else { lb_init_global_var(m, p, e, init_expr, var); } @@ -2192,6 +2252,11 @@ gb_internal void lb_create_global_procedures_and_types(lbGenerator *gen, Checker GB_ASSERT(m != nullptr); if (e->kind == Entity_Procedure) { + if (e->Procedure.is_foreign && e->Procedure.is_objc_impl_or_import) { + // Do not generate declarations for foreign Objective-C methods. These are called indirectly through the Objective-C runtime. + continue; + } + array_add(&m->global_procedures_to_create, e); } else if (e->kind == Entity_TypeName) { array_add(&m->global_types_to_create, e); diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index 6870f6259..9969aaa06 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -206,7 +206,7 @@ struct lbModule { StringMap objc_classes; StringMap objc_selectors; StringMap objc_ivars; - isize objc_next_block_id; // Used to name objective-c blocks, per module + isize objc_next_block_id; // Used to name objective-c blocks. Tracked per module. PtrMap map_cell_info_map; // address of runtime.Map_Info PtrMap map_info_map; // address of runtime.Map_Cell_Info diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index 193bffe08..4c154c85a 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -81,7 +81,7 @@ gb_internal String lb_get_const_string(lbModule *m, lbValue value) { } -gb_internal LLVMValueRef llvm_const_cast(LLVMValueRef val, LLVMTypeRef dst, bool *failure_) { +gb_internal LLVMValueRef llvm_const_cast(lbModule *m, LLVMValueRef val, LLVMTypeRef dst, bool *failure_) { LLVMTypeRef src = LLVMTypeOf(val); if (src == dst) { return val; @@ -93,14 +93,33 @@ gb_internal LLVMValueRef llvm_const_cast(LLVMValueRef val, LLVMTypeRef dst, bool GB_ASSERT_MSG(lb_sizeof(dst) == lb_sizeof(src), "%s vs %s", LLVMPrintTypeToString(dst), LLVMPrintTypeToString(src)); LLVMTypeKind kind = LLVMGetTypeKind(dst); switch (kind) { - case LLVMPointerTypeKind: + case LLVMPointerTypeKind: { return LLVMConstPointerCast(val, dst); - case LLVMStructTypeKind: - if (LLVMTypeOf(val) != dst) { - if (failure_) *failure_ = true; - } - return val; } + case LLVMStructTypeKind: { + unsigned src_n = LLVMCountStructElementTypes(src); + unsigned dst_n = LLVMCountStructElementTypes(dst); + if (src_n != dst_n) goto failure; + + LLVMValueRef *field_vals = temporary_alloc_array(dst_n); + for (unsigned i = 0; i < dst_n; i++) { + LLVMValueRef field_val = llvm_const_extract_value(m, val, i); + if (field_val == nullptr) goto failure; + + LLVMTypeRef dst_elem_ty = LLVMStructGetTypeAtIndex(dst, i); + field_vals[i] = llvm_const_cast(m, field_val, dst_elem_ty, failure_); + if (failure_ && *failure_) goto failure; + } + + if (!LLVMIsLiteralStruct(dst)) { + return LLVMConstNamedStruct(dst, field_vals, dst_n); + } else { + return LLVMConstStructInContext(m->ctx, field_vals, dst_n, LLVMIsPackedStruct(dst)); + } + } + } + +failure: if (failure_) *failure_ = true; return val; } @@ -192,7 +211,7 @@ gb_internal LLVMValueRef llvm_const_named_struct_internal(lbModule *m, LLVMTypeR bool failure = false; for (unsigned i = 0; i < elem_count; i++) { LLVMTypeRef elem_type = LLVMStructGetTypeAtIndex(t, i); - values[i] = llvm_const_cast(values[i], elem_type, &failure); + values[i] = llvm_const_cast(m, values[i], elem_type, &failure); } if (failure) { @@ -205,7 +224,7 @@ gb_internal LLVMValueRef llvm_const_array(lbModule *m, LLVMTypeRef elem_type, LL unsigned value_count = cast(unsigned)value_count_; bool failure = false; for (unsigned i = 0; i < value_count; i++) { - values[i] = llvm_const_cast(values[i], elem_type, &failure); + values[i] = llvm_const_cast(m, values[i], elem_type, &failure); } if (failure) { return LLVMConstStructInContext(m->ctx, values, value_count, false); @@ -549,6 +568,104 @@ gb_internal bool lb_is_nested_possibly_constant(Type *ft, Selection const &sel, return lb_is_elem_const(elem, ft); } +#if LLVM_VERSION_MAJOR == 14 +LLVMValueRef llvm_const_pad_to_size(lbModule *m, LLVMValueRef val, LLVMTypeRef dst_ty) { + LLVMContextRef ctx = m->ctx; + LLVMTargetDataRef td = LLVMGetModuleDataLayout(m->mod); + LLVMTypeRef src_ty = LLVMTypeOf(val); + unsigned src_bits = (unsigned)LLVMSizeOfTypeInBits(td, src_ty); + unsigned dst_bits = (unsigned)LLVMSizeOfTypeInBits(td, dst_ty); + + LLVMValueRef as_int = nullptr; + LLVMTypeKind src_kind = LLVMGetTypeKind(src_ty); + + if (src_kind == LLVMIntegerTypeKind || + src_kind == LLVMFloatTypeKind || + src_kind == LLVMDoubleTypeKind || + src_kind == LLVMPointerTypeKind || + src_kind == LLVMVectorTypeKind) { + LLVMTypeRef src_int_ty = LLVMIntTypeInContext(ctx, src_bits); + as_int = LLVMConstBitCast(val, src_int_ty); + + } else if (src_kind == LLVMArrayTypeKind) { + unsigned elem_count = LLVMGetArrayLength(src_ty); + LLVMTypeRef elem_ty = LLVMGetElementType(src_ty); + unsigned elem_bits = (unsigned)LLVMSizeOfTypeInBits(td, elem_ty); + LLVMTypeRef src_int_ty = LLVMIntTypeInContext(ctx, src_bits); + as_int = LLVMConstInt(src_int_ty, 0, false); + + for (unsigned i = 0; i < elem_count; i++) { + LLVMValueRef elem = llvm_const_extract_value(m, val, i); + LLVMTypeRef elem_int_ty = LLVMIntTypeInContext(ctx, elem_bits); + LLVMValueRef elem_int = llvm_const_pad_to_size(m, elem, elem_int_ty); + LLVMValueRef shifted = LLVMConstShl(LLVMConstZExt(elem_int, src_int_ty), LLVMConstInt(src_int_ty, i * elem_bits, false)); + as_int = LLVMConstOr(as_int, shifted); + } + } else if (src_kind == LLVMStructTypeKind) { + unsigned field_count = LLVMCountStructElementTypes(src_ty); + LLVMTypeRef src_int_ty = LLVMIntTypeInContext(ctx, src_bits); + as_int = LLVMConstInt(src_int_ty, 0, false); + + for (unsigned i = 0; i < field_count; i++) { + LLVMTypeRef field_ty = LLVMStructGetTypeAtIndex(src_ty, i); + unsigned field_bits = (unsigned)LLVMSizeOfTypeInBits(td, field_ty); + LLVMValueRef field = llvm_const_extract_value(m, val, i); + + LLVMTypeRef field_int_ty = LLVMIntTypeInContext(ctx, field_bits); + LLVMValueRef field_int = llvm_const_pad_to_size(m, field, field_int_ty); + + uint64_t field_offset_bytes = LLVMOffsetOfElement(td, src_ty, i); + uint64_t field_offset_bits = field_offset_bytes * 8; + + LLVMValueRef shifted = LLVMConstShl(LLVMConstZExt(field_int, src_int_ty), LLVMConstInt(src_int_ty, field_offset_bits, false)); + as_int = LLVMConstOr(as_int, shifted); + } + } else { + gb_printf_err("unsupported const_pad source type: %s\n", LLVMPrintTypeToString(src_ty)); + return nullptr; + } + + if (src_bits != dst_bits) { + LLVMTypeRef dst_int_ty = LLVMIntTypeInContext(ctx, dst_bits); + if (src_bits < dst_bits) { + as_int = LLVMConstZExt(as_int, dst_int_ty); + } else { + as_int = LLVMConstTrunc(as_int, dst_int_ty); + } + } + + LLVMTypeKind dst_kind = LLVMGetTypeKind(dst_ty); + + if (dst_kind == LLVMIntegerTypeKind || + dst_kind == LLVMFloatTypeKind || + dst_kind == LLVMDoubleTypeKind || + dst_kind == LLVMPointerTypeKind || + dst_kind == LLVMVectorTypeKind) { + return LLVMConstBitCast(as_int, dst_ty); + + } else if (dst_kind == LLVMArrayTypeKind) { + unsigned elem_count = LLVMGetArrayLength(dst_ty); + LLVMTypeRef elem_ty = LLVMGetElementType(dst_ty); + unsigned elem_bits = (unsigned)LLVMSizeOfTypeInBits(td, elem_ty); + + LLVMValueRef *elems = temporary_alloc_array(elem_count); + LLVMTypeRef as_int_ty = LLVMTypeOf(as_int); + + for (unsigned i = 0; i < elem_count; i++) { + LLVMValueRef shifted = LLVMConstLShr(as_int, LLVMConstInt(as_int_ty, i * elem_bits, false)); + LLVMTypeRef elem_int_ty = LLVMIntTypeInContext(ctx, elem_bits); + LLVMValueRef trunc = LLVMConstTrunc(shifted, elem_int_ty); + elems[i] = llvm_const_pad_to_size(m, trunc, elem_ty); + } + + return LLVMConstArray(elem_ty, elems, elem_count); + } + + gb_printf_err("unsupported const_pad destination type: %s\n", LLVMPrintTypeToString(dst_ty)); + return nullptr; +} +#endif + gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, lbConstContext cc, Type *value_type) { if (cc.allow_local) { cc.is_rodata = false; @@ -637,11 +754,16 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, lb LLVMValueRef values[4] = {}; unsigned value_count = 0; + #if LLVM_VERSION_MAJOR == 14 + LLVMTypeRef block_type = lb_type_internal_union_block_type(m, bt); + values[value_count++] = llvm_const_pad_to_size(m, cv.value, block_type); + #else values[value_count++] = cv.value; if (type_size_of(variant_type) != block_size) { LLVMTypeRef padding_type = lb_type_padding_filler(m, block_size - type_size_of(variant_type), 1); values[value_count++] = LLVMConstNull(padding_type); } + #endif Type *tag_type = union_tag_type(bt); LLVMTypeRef llvm_tag_type = lb_type(m, tag_type); @@ -870,7 +992,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, lb Type *elem = type->Matrix.elem; lbValue single_elem = lb_const_value(m, elem, value, cc); - single_elem.value = llvm_const_cast(single_elem.value, lb_type(m, elem), /*failure_*/nullptr); + single_elem.value = llvm_const_cast(m, single_elem.value, lb_type(m, elem), /*failure_*/nullptr); i64 total_elem_count = matrix_type_total_internal_elems(type); LLVMValueRef *elems = gb_alloc_array(permanent_allocator(), LLVMValueRef, cast(isize)total_elem_count); @@ -892,7 +1014,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, lb Type *elem = type->SimdVector.elem; lbValue single_elem = lb_const_value(m, elem, value, cc); - single_elem.value = llvm_const_cast(single_elem.value, lb_type(m, elem), /*failure_*/nullptr); + single_elem.value = llvm_const_cast(m, single_elem.value, lb_type(m, elem), /*failure_*/nullptr); LLVMValueRef *elems = gb_alloc_array(permanent_allocator(), LLVMValueRef, count); for (i64 i = 0; i < count; i++) { @@ -1472,7 +1594,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, lb values[i] = LLVMConstNull(et); } for (isize i = 0; i < total_elem_count; i++) { - values[i] = llvm_const_cast(values[i], et, /*failure_*/nullptr); + values[i] = llvm_const_cast(m, values[i], et, /*failure_*/nullptr); } res.value = LLVMConstVector(values, cast(unsigned)total_elem_count); diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index a058e6ef0..38609bd4e 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -3792,6 +3792,7 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu case BuiltinProc_objc_register_class: return lb_handle_objc_register_class(p, expr); case BuiltinProc_objc_ivar_get: return lb_handle_objc_ivar_get(p, expr); case BuiltinProc_objc_block: return lb_handle_objc_block(p, expr); + case BuiltinProc_objc_super: return lb_handle_objc_super(p, expr); case BuiltinProc_constant_utf16_cstring: @@ -4161,21 +4162,23 @@ gb_internal lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr) { } Ast *proc_expr = unparen_expr(ce->proc); + Entity *proc_entity = entity_of_node(proc_expr); + if (proc_mode == Addressing_Builtin) { - Entity *e = entity_of_node(proc_expr); BuiltinProcId id = BuiltinProc_Invalid; - if (e != nullptr) { - id = cast(BuiltinProcId)e->Builtin.id; + if (proc_entity != nullptr) { + id = cast(BuiltinProcId)proc_entity->Builtin.id; } else { id = BuiltinProc_DIRECTIVE; } return lb_build_builtin_proc(p, expr, tv, id); } + bool is_objc_call = proc_entity && proc_entity->Procedure.is_objc_impl_or_import; + // NOTE(bill): Regular call lbValue value = {}; - Entity *proc_entity = entity_of_node(proc_expr); if (proc_entity != nullptr) { if (proc_entity->flags & EntityFlag_Disabled) { GB_ASSERT(tv.type == nullptr); @@ -4209,11 +4212,13 @@ gb_internal lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr) { } } - if (value.value == nullptr) { + if (is_objc_call) { + value.type = proc_tv.type; + } else if (value.value == nullptr) { value = lb_build_expr(p, proc_expr); } - GB_ASSERT(value.value != nullptr); + GB_ASSERT(value.value != nullptr || is_objc_call); Type *proc_type_ = base_type(value.type); GB_ASSERT(proc_type_->kind == Type_Proc); TypeProc *pt = &proc_type_->Proc; @@ -4441,6 +4446,11 @@ gb_internal lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr) { isize final_count = is_c_vararg ? args.count : pt->param_count; auto call_args = array_slice(args, 0, final_count); + + if (is_objc_call) { + return lb_handle_objc_auto_send(p, expr, slice(call_args, 0, call_args.count)); + } + return lb_emit_call(p, value, call_args, ce->inlining); } diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index 155c55675..2cddd23d9 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -286,7 +286,14 @@ gb_internal lbValue lb_emit_transmute(lbProcedure *p, lbValue value, Type *t) { } } + bool is_simd_vector_bitcastable = false; if (is_type_simd_vector(src) && is_type_simd_vector(dst)) { + if (!is_type_internally_pointer_like(src->SimdVector.elem) && !is_type_internally_pointer_like(dst->SimdVector.elem)) { + is_simd_vector_bitcastable = true; + } + } + + if (is_simd_vector_bitcastable) { res.value = LLVMBuildBitCast(p->builder, value.value, lb_type(p->module, t), ""); return res; } else if (is_type_array_like(src) && (is_type_simd_vector(dst) || is_type_integer_128bit(dst))) { @@ -2264,12 +2271,12 @@ gb_internal lbValue lb_handle_objc_ivar_get(lbProcedure *p, Ast *expr) { } gb_internal void lb_create_objc_block_helper_procs( - lbModule *m, LLVMTypeRef block_lit_type, isize capture_field_offset, + lbModule *m, LLVMTypeRef block_lit_type, isize capture_field_offset, isize block_id, Slice capture_values, Slice objc_object_indices, lbProcedure *&out_copy_helper, lbProcedure *&out_dispose_helper ) { - gbString copy_helper_name = gb_string_append_fmt(gb_string_make(temporary_allocator(), ""), "__$objc_block_copy_helper_%lld", m->objc_next_block_id); - gbString dispose_helper_name = gb_string_append_fmt(gb_string_make(temporary_allocator(), ""), "__$objc_block_dispose_helper_%lld", m->objc_next_block_id); + gbString copy_helper_name = gb_string_append_fmt(gb_string_make(temporary_allocator(), ""), "__$%s::objc_block_copy_helper_%lld", m->module_name, block_id); + gbString dispose_helper_name = gb_string_append_fmt(gb_string_make(temporary_allocator(), ""), "__$%s::objc_block_dispose_helper_%lld", m->module_name, block_id); // copy: Block_Literal *dst, Block_Literal *src, i32 field_apropos // dispose: Block_Literal *src, i32 field_apropos @@ -2373,14 +2380,12 @@ gb_internal lbValue lb_handle_objc_block(lbProcedure *p, Ast *expr) { /// https://www.newosxbook.com/src.php?tree=xnu&file=/libkern/libkern/Block_private.h /// https://github.com/llvm/llvm-project/blob/21f1f9558df3830ffa637def364e3c0cb0dbb3c0/compiler-rt/lib/BlocksRuntime/Block_private.h /// https://github.com/apple-oss-distributions/libclosure/blob/3668b0837f47be3cc1c404fb5e360f4ff178ca13/runtime.cpp - ast_node(ce, CallExpr, expr); GB_ASSERT(ce->args.count > 0); lbModule *m = p->module; - m->objc_next_block_id += 1; - + const isize block_id = m->objc_next_block_id++; const isize capture_arg_count = ce->args.count - 1; Type *block_result_type = type_of_expr(expr); @@ -2425,7 +2430,7 @@ gb_internal lbValue lb_handle_objc_block(lbProcedure *p, Ast *expr) { // Create proc with the block signature // (takes a block literal pointer as the first parameter, followed by any expected ones from the user's proc) - gbString block_invoker_name = gb_string_append_fmt(gb_string_make(permanent_allocator(), ""), "__$objc_block_invoker_%lld", m->objc_next_block_id); + gbString block_invoker_name = gb_string_append_fmt(gb_string_make(permanent_allocator(), ""), "__$%s::objc_block_invoker_%lld", m->module_name, block_id); // Add + 1 because the first parameter received is the block literal pointer itself auto invoker_args = array_make(temporary_allocator(), block_forward_args + 1, block_forward_args + 1); @@ -2452,14 +2457,16 @@ gb_internal lbValue lb_handle_objc_block(lbProcedure *p, Ast *expr) { lbProcedure *invoker_proc = lb_create_dummy_procedure(m, make_string((u8*)block_invoker_name, gb_string_length(block_invoker_name)), invoker_proc_type); + LLVMSetLinkage(invoker_proc->value, LLVMPrivateLinkage); + lb_add_function_type_attributes(invoker_proc->value, lb_get_function_type(m, invoker_proc_type), ProcCC_CDecl); // Create the block descriptor and block literal - gbString block_lit_type_name = gb_string_make(temporary_allocator(), "__$ObjC_Block_Literal_"); - block_lit_type_name = gb_string_append_fmt(block_lit_type_name, "%lld", m->objc_next_block_id); + gbString block_lit_type_name = gb_string_make(temporary_allocator(), ""); + block_lit_type_name = gb_string_append_fmt(block_lit_type_name, "__$%s::ObjC_Block_Literal_%lld", m->module_name, block_id); - gbString block_desc_type_name = gb_string_make(temporary_allocator(), "__$ObjC_Block_Descriptor_"); - block_desc_type_name = gb_string_append_fmt(block_desc_type_name, "%lld", m->objc_next_block_id); + gbString block_desc_type_name = gb_string_make(temporary_allocator(), ""); + block_desc_type_name = gb_string_append_fmt(block_desc_type_name, "__$%s::ObjC_Block_Descriptor_%lld", m->module_name,block_id); LLVMTypeRef block_lit_type = {}; LLVMTypeRef block_desc_type = {}; @@ -2503,7 +2510,7 @@ gb_internal lbValue lb_handle_objc_block(lbProcedure *p, Ast *expr) { // Generate copy and dispose helper functions for captured params that are Objective-C objects (or a Block) if (has_objc_fields) { - lb_create_objc_block_helper_procs(m, block_lit_type, capture_fields_offset, + lb_create_objc_block_helper_procs(m, block_lit_type, capture_fields_offset, block_id, slice(captured_values, 0, captured_values.count), slice(objc_captures, 0, objc_captures.count), copy_helper, dispose_helper); @@ -2521,8 +2528,8 @@ gb_internal lbValue lb_handle_objc_block(lbProcedure *p, Ast *expr) { } // Create global block descriptor - gbString desc_global_name = gb_string_make(temporary_allocator(), "__$objc_block_desc_"); - desc_global_name = gb_string_append_fmt(desc_global_name, "%lld", m->objc_next_block_id); + gbString desc_global_name = gb_string_make(temporary_allocator(), ""); + desc_global_name = gb_string_append_fmt(desc_global_name, "__$%s::objc_block_desc_%lld", m->module_name, block_id); LLVMValueRef p_descriptor = LLVMAddGlobal(m->mod, block_desc_type, desc_global_name); LLVMSetInitializer(p_descriptor, block_desc_initializer); @@ -2531,45 +2538,66 @@ gb_internal lbValue lb_handle_objc_block(lbProcedure *p, Ast *expr) { /// Invoker body lb_begin_procedure_body(invoker_proc); { - auto call_args = array_make(temporary_allocator(), user_proc.param_count, user_proc.param_count); + // Reserve 2 extra arguments for: Indirect return values and context. + auto call_args = array_make(temporary_allocator(), 0, user_proc.param_count + 2); - for (isize i = 1; i < invoker_proc->raw_input_parameters.count; i++) { - lbValue arg = {}; - arg.type = invoker_args[i]; - arg.value = invoker_proc->raw_input_parameters[i], - call_args[i-1] = arg; + isize block_literal_arg_index = 0; + + lbFunctionType* user_proc_ft = lb_get_function_type(m, user_proc_value.type); + + lbArgKind return_kind = {}; + + GB_ASSERT(user_proc.result_count <= 1); + if (user_proc.result_count > 0) { + return_kind = user_proc_ft->ret.kind; + + if (return_kind == lbArg_Indirect) { + // Forward indirect return value + array_add(&call_args, invoker_proc->raw_input_parameters[0]); + block_literal_arg_index = 1; + } } - LLVMValueRef block_literal = invoker_proc->raw_input_parameters[0]; + // Forward raw arguments + for (isize i = block_literal_arg_index+1; i < invoker_proc->raw_input_parameters.count; i++) { + array_add(&call_args, invoker_proc->raw_input_parameters[i]); + } + + LLVMValueRef block_literal = invoker_proc->raw_input_parameters[block_literal_arg_index]; + + // Copy capture parameters from the block literal + isize capture_arg_in_user_proc_start_index = user_proc_ft->args.count - capture_arg_count; + if (user_proc.calling_convention == ProcCC_Odin) { + capture_arg_in_user_proc_start_index -= 1; + } + + for (isize i = 0; i < capture_arg_count; i++) { + LLVMValueRef cap_value = LLVMBuildStructGEP2(invoker_proc->builder, block_lit_type, block_literal, unsigned(capture_fields_offset + i), ""); + + // Don't emit load if indirect. Pass the pointer as-is + isize cap_arg_index_in_user_proc = capture_arg_in_user_proc_start_index + i; + + if (user_proc_ft->args[cap_arg_index_in_user_proc].kind != lbArg_Indirect) { + cap_value = OdinLLVMBuildLoad(invoker_proc, lb_type(invoker_proc->module, captured_values[i].type), cap_value); + } + + array_add(&call_args, cap_value); + } // Push context, if needed if (user_proc.calling_convention == ProcCC_Odin) { LLVMValueRef p_context = LLVMBuildStructGEP2(invoker_proc->builder, block_lit_type, block_literal, 5, "context"); - lbValue ctx_val = {}; - ctx_val.type = t_context_ptr; - ctx_val.value = p_context; - - lb_push_context_onto_stack(invoker_proc, lb_addr(ctx_val)); + array_add(&call_args, p_context); } - // Copy capture parameters from the block literal - for (isize i = 0; i < capture_arg_count; i++) { - LLVMValueRef cap_value = LLVMBuildStructGEP2(invoker_proc->builder, block_lit_type, block_literal, unsigned(capture_fields_offset + i), ""); + LLVMTypeRef fnp = lb_type_internal_for_procedures_raw(m, user_proc_value.type); + LLVMValueRef ret_val = LLVMBuildCall2(invoker_proc->builder, fnp, user_proc_value.value, call_args.data, (unsigned)call_args.count, ""); - lbValue cap_arg = {}; - cap_arg.value = cap_value; - cap_arg.type = alloc_type_pointer(captured_values[i].type); - - lbValue arg = lb_emit_load(invoker_proc, cap_arg); - call_args[block_forward_args+i] = arg; + if (user_proc.result_count > 0 && return_kind != lbArg_Indirect) { + LLVMBuildRet(invoker_proc->builder, ret_val); } - - lbValue result = lb_emit_call(invoker_proc, user_proc_value, call_args, proc_lit->ProcLit.inlining); - - GB_ASSERT(user_proc.result_count <= 1); - if (user_proc.result_count > 0) { - GB_ASSERT(result.value != nullptr); - LLVMBuildRet(p->builder, result.value); + else { + LLVMBuildRetVoid(invoker_proc->builder); } } lb_end_procedure_body(invoker_proc); @@ -2585,10 +2613,10 @@ gb_internal lbValue lb_handle_objc_block(lbProcedure *p, Ast *expr) { } gbString block_var_name = gb_string_make(temporary_allocator(), "__$objc_block_literal_"); - block_var_name = gb_string_append_fmt(block_var_name, "%lld", m->objc_next_block_id); + block_var_name = gb_string_append_fmt(block_var_name, "%lld", block_id); - lbValue result = {}; - result.type = block_result_type; + lbValue block_result = {}; + block_result.type = block_result_type; lbValue isa_val = lb_find_runtime_value(m, is_global ? str_lit("_NSConcreteGlobalBlock") : str_lit("_NSConcreteStackBlock")); lbValue flags_val = lb_const_int(m, t_i32, (u64)raw_flags); @@ -2596,7 +2624,7 @@ gb_internal lbValue lb_handle_objc_block(lbProcedure *p, Ast *expr) { if (is_global) { LLVMValueRef p_block_lit = LLVMAddGlobal(m->mod, block_lit_type, block_var_name); - result.value = p_block_lit; + block_result.value = p_block_lit; LLVMValueRef fields_values[5] = { isa_val.value, // isa @@ -2611,7 +2639,7 @@ gb_internal lbValue lb_handle_objc_block(lbProcedure *p, Ast *expr) { } else { LLVMValueRef p_block_lit = llvm_alloca(p, block_lit_type, lb_alignof(block_lit_type), block_var_name); - result.value = p_block_lit; + block_result.value = p_block_lit; // Initialize it LLVMValueRef f_isa = LLVMBuildStructGEP2(p->builder, block_lit_type, p_block_lit, 0, "isa"); @@ -2651,7 +2679,20 @@ gb_internal lbValue lb_handle_objc_block(lbProcedure *p, Ast *expr) { } } - return result; + return block_result; +} + +gb_internal lbValue lb_handle_objc_block_invoke(lbProcedure *p, Ast *expr) { + return {}; +} + +gb_internal lbValue lb_handle_objc_super(lbProcedure *p, Ast *expr) { + ast_node(ce, CallExpr, expr); + GB_ASSERT(ce->args.count == 1); + + // NOTE(harold): This doesn't actually do anything by itself, + // it has an effect when used on the left side of a selector call expression. + return lb_build_expr(p, ce->args[0]); } gb_internal lbValue lb_handle_objc_find_selector(lbProcedure *p, Ast *expr) { @@ -2767,6 +2808,120 @@ gb_internal lbValue lb_handle_objc_send(lbProcedure *p, Ast *expr) { return lb_emit_call(p, the_proc, args); } +gb_internal lbValue lb_handle_objc_auto_send(lbProcedure *p, Ast *expr, Slice const arg_values) { + ast_node(ce, CallExpr, expr); + + lbModule *m = p->module; + CheckerInfo *info = m->info; + ObjcMsgData data = map_must_get(&info->objc_msgSend_types, expr); + + Type *proc_type = data.proc_type; + GB_ASSERT(proc_type != nullptr); + + Entity *objc_method_ent = entity_of_node(ce->proc); + GB_ASSERT(objc_method_ent != nullptr); + GB_ASSERT(objc_method_ent->kind == Entity_Procedure); + GB_ASSERT(objc_method_ent->Procedure.objc_selector_name.len > 0); + + auto &proc = proc_type->Proc; + GB_ASSERT(proc.param_count >= 2); + + Type *objc_super_orig_type = nullptr; + if (ce->args.count > 0) { + objc_super_orig_type = unparen_expr(ce->args[0])->tav.objc_super_target; + } + + isize arg_offset = 1; + lbValue id = {}; + if (!objc_method_ent->Procedure.is_objc_class_method) { + GB_ASSERT(ce->args.count > 0); + id = arg_values[0]; + + if (objc_super_orig_type) { + GB_ASSERT(objc_super_orig_type->kind == Type_Named); + + auto& tn = objc_super_orig_type->Named.type_name->TypeName; + lbAddr p_supercls = lb_handle_objc_find_or_register_class(p, tn.objc_class_name, tn.objc_is_implementation ? objc_super_orig_type : nullptr); + + lbValue supercls = lb_addr_load(p, p_supercls); + lbAddr p_objc_super = lb_add_local_generated(p, t_objc_super, false); + + lbValue f_id = lb_emit_struct_ep(p, p_objc_super.addr, 0); + lbValue f_superclass = lb_emit_struct_ep(p, p_objc_super.addr, 1); + + id = lb_emit_conv(p, id, t_objc_id); + lb_emit_store(p, f_id, id); + lb_emit_store(p, f_superclass, supercls); + + id = p_objc_super.addr; + } + } else { + Entity *objc_class = objc_method_ent->Procedure.objc_class; + if (ce->proc->kind == Ast_SelectorExpr) { + // NOTE (harold): If called via a selector expression (ex: Foo.alloc()), then we should use + // the lhs-side to determine the class. This allows for class methods to be called + // with the correct class as the target, even when the method is defined in a superclass. + ast_node(se, SelectorExpr, ce->proc); + GB_ASSERT(se->expr->tav.mode == Addressing_Type && se->expr->tav.type->kind == Type_Named); + + objc_class = entity_from_expr(se->expr); + + GB_ASSERT(objc_class); + GB_ASSERT(objc_class->kind == Entity_TypeName); + GB_ASSERT(objc_class->TypeName.objc_class_name != ""); + } + + Type *class_impl_type = objc_class->TypeName.objc_is_implementation ? objc_class->type : nullptr; + + id = lb_addr_load(p, lb_handle_objc_find_or_register_class(p, objc_class->TypeName.objc_class_name, class_impl_type)); + arg_offset = 0; + } + + lbValue sel = lb_addr_load(p, lb_handle_objc_find_or_register_selector(p, objc_method_ent->Procedure.objc_selector_name)); + + auto args = array_make(permanent_allocator(), 0, arg_values.count + 2 - arg_offset); + + array_add(&args, id); + array_add(&args, sel); + + for (isize i = arg_offset; i < ce->args.count; i++) { + array_add(&args, arg_values[i]); + } + + lbValue the_proc = {}; + + if (!objc_super_orig_type) { + switch (data.kind) { + default: + GB_PANIC("unhandled ObjcMsgKind %u", data.kind); + break; + case ObjcMsg_normal: the_proc = lb_lookup_runtime_procedure(m, str_lit("objc_msgSend")); break; + case ObjcMsg_fpret: the_proc = lb_lookup_runtime_procedure(m, str_lit("objc_msgSend_fpret")); break; + case ObjcMsg_fp2ret: the_proc = lb_lookup_runtime_procedure(m, str_lit("objc_msgSend_fp2ret")); break; + case ObjcMsg_stret: the_proc = lb_lookup_runtime_procedure(m, str_lit("objc_msgSend_stret")); break; + } + } else { + switch (data.kind) { + default: + GB_PANIC("unhandled ObjcMsgKind %u", data.kind); + break; + case ObjcMsg_normal: + case ObjcMsg_fpret: + case ObjcMsg_fp2ret: + the_proc = lb_lookup_runtime_procedure(m, str_lit("objc_msgSendSuper2")); + break; + case ObjcMsg_stret: + the_proc = lb_lookup_runtime_procedure(m, str_lit("objc_msgSendSuper2_stret")); + break; + } + } + + the_proc = lb_emit_conv(p, the_proc, data.proc_type); + + return lb_emit_call(p, the_proc, args); +} + + gb_internal LLVMAtomicOrdering llvm_atomic_ordering_from_odin(ExactValue const &value) { GB_ASSERT(value.kind == ExactValue_Integer); i64 v = exact_value_to_i64(value); diff --git a/src/parser.cpp b/src/parser.cpp index 23226528d..17590d240 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -6462,6 +6462,7 @@ gb_internal u64 parse_feature_tag(Token token_for_pos, String s) { switch (flag) { case OptInFeatureFlag_IntegerDivisionByZero_Trap: case OptInFeatureFlag_IntegerDivisionByZero_Zero: + case OptInFeatureFlag_IntegerDivisionByZero_AllBits: syntax_error(token_for_pos, "Feature flag does not support notting with '!' - '%.*s'", LIT(p)); break; } @@ -6474,6 +6475,7 @@ gb_internal u64 parse_feature_tag(Token token_for_pos, String s) { error_line("\tinteger-division-by-zero:trap\n"); error_line("\tinteger-division-by-zero:zero\n"); error_line("\tinteger-division-by-zero:self\n"); + error_line("\tinteger-division-by-zero:all-bits\n"); return OptInFeatureFlag_NONE; } } diff --git a/src/parser.hpp b/src/parser.hpp index 979b44618..6127468d4 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -48,7 +48,8 @@ gb_global String const addressing_mode_strings[] = { struct TypeAndValue { Type * type; AddressingMode mode; - bool is_lhs; // Debug info + bool is_lhs; // Debug info + Type * objc_super_target; // Original type of the Obj-C object before being converted to the superclass' type by the objc_super() intrinsic. ExactValue value; }; diff --git a/src/types.cpp b/src/types.cpp index effa8ef64..cb830d08d 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -410,7 +410,7 @@ gb_internal u32 type_info_flags_of_type(Type *type) { flags |= TypeInfoFlag_Comparable; } if (is_type_simple_compare(type)) { - flags |= TypeInfoFlag_Comparable; + flags |= TypeInfoFlag_Comparable|TypeInfoFlag_Simple_Compare; } return flags; } @@ -752,11 +752,14 @@ gb_global Type *t_objc_object = nullptr; gb_global Type *t_objc_selector = nullptr; gb_global Type *t_objc_class = nullptr; gb_global Type *t_objc_ivar = nullptr; +gb_global Type *t_objc_super = nullptr; // Struct used in lieu of the 'self' instance when calling objc_msgSendSuper. +gb_global Type *t_objc_super_ptr = nullptr; gb_global Type *t_objc_id = nullptr; gb_global Type *t_objc_SEL = nullptr; gb_global Type *t_objc_Class = nullptr; gb_global Type *t_objc_Ivar = nullptr; +gb_global Type *t_objc_instancetype = nullptr; // Special distinct variant of t_objc_id used mimic auto-typing of instancetype* in Objective-C enum OdinAtomicMemoryOrder : i32 { OdinAtomicMemoryOrder_relaxed = 0, // unordered @@ -1722,7 +1725,7 @@ gb_internal bool is_type_u8_ptr(Type *t) { t = base_type(t); if (t == nullptr) { return false; } if (t->kind == Type_Pointer) { - return is_type_u8(t->Slice.elem); + return is_type_u8(t->Pointer.elem); } return false; } @@ -1763,7 +1766,7 @@ gb_internal bool is_type_u16_ptr(Type *t) { t = base_type(t); if (t == nullptr) { return false; } if (t->kind == Type_Pointer) { - return is_type_u16(t->Slice.elem); + return is_type_u16(t->Pointer.elem); } return false; } @@ -4735,6 +4738,14 @@ gb_internal bool is_type_objc_object(Type *t) { return internal_check_is_assignable_to(t, t_objc_object); } +gb_internal bool is_type_objc_ptr_to_object(Type *t) { + // NOTE (harold): is_type_objc_object() returns true if it's a pointer to an object or the object itself. + // This returns true ONLY if Type is a shallow pointer to an Objective-C object. + + Type *elem = type_deref(t); + return elem != t && elem->kind == Type_Named && is_type_objc_object(elem); +} + gb_internal Type *get_struct_field_type(Type *t, isize index) { t = base_type(type_deref(t)); GB_ASSERT(t->kind == Type_Struct); diff --git a/core/encoding/base32/base32_test.odin b/tests/core/encoding/base32/base32.odin similarity index 87% rename from core/encoding/base32/base32_test.odin rename to tests/core/encoding/base32/base32.odin index 07d5c8080..f757e99e5 100644 --- a/core/encoding/base32/base32_test.odin +++ b/tests/core/encoding/base32/base32.odin @@ -1,8 +1,11 @@ #+test -package encoding_base32 +package test_encoding_base32 import "core:testing" import "core:bytes" +import "core:encoding/base32" + +Error :: base32.Error @(test) test_base32_decode_valid :: proc(t: ^testing.T) { @@ -20,7 +23,7 @@ test_base32_decode_valid :: proc(t: ^testing.T) { } for c in cases { - output, err := decode(c.input) + output, err := base32.decode(c.input) if output != nil { defer delete(output) } @@ -50,7 +53,7 @@ test_base32_encode :: proc(t: ^testing.T) { } for c in cases { - output := encode(transmute([]byte)c.input) + output := base32.encode(transmute([]byte)c.input) defer delete(output) testing.expect(t, output == c.expected) } @@ -62,7 +65,7 @@ test_base32_decode_invalid :: proc(t: ^testing.T) { { // Characters outside alphabet input := "MZ1W6YTB" // '1' not in alphabet (A-Z, 2-7) - output, err := decode(input) + output, err := base32.decode(input) if output != nil { defer delete(output) } @@ -71,7 +74,7 @@ test_base32_decode_invalid :: proc(t: ^testing.T) { { // Lowercase not allowed input := "mzxq====" - output, err := decode(input) + output, err := base32.decode(input) if output != nil { defer delete(output) } @@ -82,7 +85,7 @@ test_base32_decode_invalid :: proc(t: ^testing.T) { { // Padding must only be at end input := "MZ=Q====" - output, err := decode(input) + output, err := base32.decode(input) if output != nil { defer delete(output) } @@ -91,7 +94,7 @@ test_base32_decode_invalid :: proc(t: ^testing.T) { { // Missing padding input := "MZXQ" // Should be MZXQ==== - output, err := decode(input) + output, err := base32.decode(input) if output != nil { defer delete(output) } @@ -100,7 +103,7 @@ test_base32_decode_invalid :: proc(t: ^testing.T) { { // Incorrect padding length input := "MZXQ=" // Needs 4 padding chars - output, err := decode(input) + output, err := base32.decode(input) if output != nil { defer delete(output) } @@ -109,7 +112,7 @@ test_base32_decode_invalid :: proc(t: ^testing.T) { { // Too much padding input := "MY=========" // Extra padding chars - output, err := decode(input) + output, err := base32.decode(input) if output != nil { defer delete(output) } @@ -120,7 +123,7 @@ test_base32_decode_invalid :: proc(t: ^testing.T) { { // Single character (invalid block) input := "M" - output, err := decode(input) + output, err := base32.decode(input) if output != nil { defer delete(output) } @@ -141,9 +144,9 @@ test_base32_roundtrip :: proc(t: ^testing.T) { } for input in cases { - encoded := encode(transmute([]byte)input) + encoded := base32.encode(transmute([]byte)input) defer delete(encoded) - decoded, err := decode(encoded) + decoded, err := base32.decode(encoded) if decoded != nil { defer delete(decoded) } @@ -188,7 +191,7 @@ test_base32_custom_alphabet :: proc(t: ^testing.T) { */ custom_validate :: proc(c: byte) -> bool { - return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'V') || c == byte(PADDING) + return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'V') || c == byte(base32.PADDING) } cases := [?]struct { @@ -202,12 +205,12 @@ test_base32_custom_alphabet :: proc(t: ^testing.T) { for c in cases { // Test encoding - encoded := encode(transmute([]byte)c.input, custom_enc_table) + encoded := base32.encode(transmute([]byte)c.input, custom_enc_table) defer delete(encoded) testing.expect(t, encoded == c.enc_expected) // Test decoding - decoded, err := decode(encoded, custom_dec_table, custom_validate) + decoded, err := base32.decode(encoded, custom_dec_table, custom_validate) defer if decoded != nil { delete(decoded) } @@ -219,10 +222,10 @@ test_base32_custom_alphabet :: proc(t: ^testing.T) { // Test invalid character detection { input := "WXY=====" // Contains chars not in our alphabet - output, err := decode(input, custom_dec_table, custom_validate) + output, err := base32.decode(input, custom_dec_table, custom_validate) if output != nil { delete(output) } testing.expect_value(t, err, Error.Invalid_Character) } -} +} \ No newline at end of file diff --git a/tests/core/normal.odin b/tests/core/normal.odin index fe69acf64..a16657ea8 100644 --- a/tests/core/normal.odin +++ b/tests/core/normal.odin @@ -13,6 +13,7 @@ download_assets :: proc "contextless" () { @(require) import "c/libc" @(require) import "compress" @(require) import "container" +@(require) import "encoding/base32" @(require) import "encoding/base64" @(require) import "encoding/cbor" @(require) import "encoding/hex" diff --git a/tests/core/sys/posix/posix.odin b/tests/core/sys/posix/posix.odin index 68a6a87cd..7a7cbd392 100644 --- a/tests/core/sys/posix/posix.odin +++ b/tests/core/sys/posix/posix.odin @@ -79,7 +79,7 @@ test_dirent :: proc(t: ^testing.T) { } name := string(cstring(raw_data(entry.d_name[:]))) - testing.expectf(t, name in test_map, "%v in %v", name, test_map) + testing.expectf(t, name in test_map, "scandir: %v in %v", name, test_map) } } @@ -109,7 +109,7 @@ test_dirent :: proc(t: ^testing.T) { } name := string(cstring(raw_data(entry.d_name[:]))) - testing.expectf(t, name in test_map, "%v in %v", name, test_map) + testing.expectf(t, name in test_map, "readdir: %v in %v", name, test_map) } } } @@ -220,7 +220,7 @@ test_stat :: proc(t: ^testing.T) { @(test) test_pthreads :: proc(t: ^testing.T) { - testing.set_fail_timeout(t, time.Second) + testing.set_fail_timeout(t, 3 * time.Second) NTHREADS :: 3 thread_ids: [NTHREADS]posix.pthread_t diff --git a/vendor/ENet/enet.odin b/vendor/ENet/enet.odin index b4ef3fe70..235cc5684 100644 --- a/vendor/ENet/enet.odin +++ b/vendor/ENet/enet.odin @@ -1,3 +1,4 @@ +// Bindings for [[ ENet ; https://github.com/lsalzman/enet ]]. package ENet when ODIN_OS == .Windows { diff --git a/vendor/OpenEXRCore/exr_base.odin b/vendor/OpenEXRCore/exr_base.odin index cf059ffcf..4dffe86e3 100644 --- a/vendor/OpenEXRCore/exr_base.odin +++ b/vendor/OpenEXRCore/exr_base.odin @@ -1,3 +1,4 @@ +// Bindings for [[ OpenEXRCore ; https://github.com/AcademySoftwareFoundation/openexr/tree/main/src/lib/OpenEXRCore ]]. package vendor_openexr OPENEXRCORE_SHARED :: #config(OPENEXRCORE_SHARED, false) diff --git a/vendor/OpenGL/helpers.odin b/vendor/OpenGL/helpers.odin index 0bd8e451b..84e3eae81 100644 --- a/vendor/OpenGL/helpers.odin +++ b/vendor/OpenGL/helpers.odin @@ -1,3 +1,4 @@ +// OpenGL function pointer loader implemented in Odin. Supports the `core` profile up to version 4.6. package vendor_gl // Helper for loading shaders into a program diff --git a/vendor/box2d/box2d.odin b/vendor/box2d/box2d.odin index 8b0a57a4e..27d3fd177 100644 --- a/vendor/box2d/box2d.odin +++ b/vendor/box2d/box2d.odin @@ -1,3 +1,4 @@ +// Bindings for [[ Box2D ; https://box2d.org ]]. package vendor_box2d import "base:intrinsics" diff --git a/vendor/cgltf/cgltf.odin b/vendor/cgltf/cgltf.odin index bab58d851..aeceb14c5 100644 --- a/vendor/cgltf/cgltf.odin +++ b/vendor/cgltf/cgltf.odin @@ -1,3 +1,4 @@ +// Bindings for [[ Cgtlf ; https://github.com/jkuhlmann/cgltf ]]. package cgltf @(private) diff --git a/vendor/commonmark/cmark.odin b/vendor/commonmark/cmark.odin index 6b07f157f..fd1be45fd 100644 --- a/vendor/commonmark/cmark.odin +++ b/vendor/commonmark/cmark.odin @@ -1,9 +1,3 @@ -/* - Bindings against CMark (https://github.com/commonmark/cmark) - - Original authors: John MacFarlane, Vicent Marti, Kārlis Gaņģis, Nick Wellnhofer. - See LICENSE for license details. -*/ package vendor_commonmark import "core:c" diff --git a/vendor/commonmark/doc.odin b/vendor/commonmark/doc.odin index ef788fb8f..648226234 100644 --- a/vendor/commonmark/doc.odin +++ b/vendor/commonmark/doc.odin @@ -1,18 +1,13 @@ -#+build ignore /* - Bindings against CMark (https://github.com/commonmark/cmark) +Bindings for [[ CMark; https://github.com/commonmark/cmark ]]. - Original authors: John MacFarlane, Vicent Marti, Kārlis Gaņģis, Nick Wellnhofer. - See LICENSE for license details. -*/ -package vendor_commonmark +Original authors: John MacFarlane, Vicent Marti, Kārlis Gaņģis, Nick Wellnhofer. +See LICENSE for license details. -/* - Parsing - Simple interface: - - ```odin +Example: import cm "vendor:commonmark" + // Parsing - Simple interface hellope_world :: proc() { fmt.printf("CMark version: %v\n", cm.version_string()) @@ -25,13 +20,8 @@ package vendor_commonmark fmt.println(html) } - ``` - - Parsing - Streaming interface: - - ```odin - import cm "vendor:commonmark" + // Parsing - Streaming interface streaming :: proc() { using cm @@ -67,26 +57,23 @@ package vendor_commonmark fmt.println(html) } - ``` +An iterator will walk through a tree of nodes, starting from a root +node, returning one node at a time, together with information about +whether the node is being entered or exited. - An iterator will walk through a tree of nodes, starting from a root - node, returning one node at a time, together with information about - whether the node is being entered or exited. +The iterator will first descend to a child node, if there is one. +When there is no child, the iterator will go to the next sibling. +When there is no next sibling, the iterator will return to the parent +(but with an `Event_Type.Exit`). - The iterator will first descend to a child node, if there is one. - When there is no child, the iterator will go to the next sibling. - When there is no next sibling, the iterator will return to the parent - (but with an `Event_Type.Exit`). +The iterator will return `.Done` when it reaches the root node again. - The iterator will return `.Done` when it reaches the root node again. +One natural application is an HTML renderer, where an `.Enter` event +outputs an open tag and an `.Exit` event outputs a close tag. - One natural application is an HTML renderer, where an `.Enter` event - outputs an open tag and an `.Exit` event outputs a close tag. +An iterator might also be used to transform an AST in some systematic +way, for example, turning all level-3 headings into regular paragraphs. - An iterator might also be used to transform an AST in some systematic - way, for example, turning all level-3 headings into regular paragraphs. - - ```odin usage_example(root: ^Node) { ev_type: Event_Type iter := iter_new(root) @@ -98,20 +85,20 @@ package vendor_commonmark // Do something with `cur` and `ev_type` } } - ``` - Iterators will never return `.Exit` events for leaf nodes, - which are nodes of type: +Iterators will never return `.Exit` events for leaf nodes, +which are nodes of type: - * HTML_Block - * Thematic_Break - * Code_Block - * Text - * Soft_Break - * Line_Break - * Code - * HTML_Inline +* HTML_Block +* Thematic_Break +* Code_Block +* Text +* Soft_Break +* Line_Break +* Code +* HTML_Inline - Nodes must only be modified after an `.Exit` event, or an `.Enter` event for - leaf nodes. -*/ \ No newline at end of file +Nodes must only be modified after an `.Exit` event, or an `.Enter` event for +leaf nodes. +*/ +package vendor_commonmark \ No newline at end of file diff --git a/vendor/compress/lz4/lz4.odin b/vendor/compress/lz4/lz4.odin index 310248d56..35acaeb5a 100644 --- a/vendor/compress/lz4/lz4.odin +++ b/vendor/compress/lz4/lz4.odin @@ -1,3 +1,4 @@ +// Bindings for [[LZ4 ; https://github.com/lz4/lz4]]. package vendor_compress_lz4 when ODIN_OS == .Windows { diff --git a/vendor/darwin/CoreVideo/CVDisplayLink.odin b/vendor/darwin/CoreVideo/CVDisplayLink.odin index fae988e0a..73d11d739 100644 --- a/vendor/darwin/CoreVideo/CVDisplayLink.odin +++ b/vendor/darwin/CoreVideo/CVDisplayLink.odin @@ -1,3 +1,4 @@ +// Bindings for [[ CoreVideo ; https://developer.apple.com/documentation/corevideo ]]. package CoreVideo DisplayLinkRef :: distinct rawptr diff --git a/vendor/darwin/Metal/MetalClasses.odin b/vendor/darwin/Metal/MetalClasses.odin index 67cf84f1e..c01c6311a 100644 --- a/vendor/darwin/Metal/MetalClasses.odin +++ b/vendor/darwin/Metal/MetalClasses.odin @@ -1,3 +1,4 @@ +// Bindings for [[ Metal ; https://developer.apple.com/documentation/metal ]]. package objc_Metal import NS "core:sys/darwin/Foundation" diff --git a/vendor/darwin/MetalKit/MetalKit.odin b/vendor/darwin/MetalKit/MetalKit.odin index 34a87cf42..3a4491a21 100644 --- a/vendor/darwin/MetalKit/MetalKit.odin +++ b/vendor/darwin/MetalKit/MetalKit.odin @@ -1,3 +1,4 @@ +// Bindings for [[ MetalKit ; https://developer.apple.com/documentation/metalkit ]]. package objc_MetalKit import NS "core:sys/darwin/Foundation" diff --git a/vendor/darwin/QuartzCore/QuartzCore.odin b/vendor/darwin/QuartzCore/QuartzCore.odin index b19a5fec5..0e54b3d30 100644 --- a/vendor/darwin/QuartzCore/QuartzCore.odin +++ b/vendor/darwin/QuartzCore/QuartzCore.odin @@ -1,3 +1,4 @@ +// Bindings for [[ QuartzCore ; https://developer.apple.com/documentation/quartzcore ]]. package objc_QuartzCore import NS "core:sys/darwin/Foundation" diff --git a/vendor/directx/d3d11/d3d11.odin b/vendor/directx/d3d11/d3d11.odin index c15f19934..835655bbf 100644 --- a/vendor/directx/d3d11/d3d11.odin +++ b/vendor/directx/d3d11/d3d11.odin @@ -1,3 +1,4 @@ +// Bindings for [[ Direct3D 11 ; https://learn.microsoft.com/en-us/windows/win32/direct3d11/atoc-dx-graphics-direct3d-11 ]]. package directx_d3d11 foreign import "system:d3d11.lib" diff --git a/vendor/directx/d3d12/d3d12.odin b/vendor/directx/d3d12/d3d12.odin index 0d4dbc4e0..75e94c833 100644 --- a/vendor/directx/d3d12/d3d12.odin +++ b/vendor/directx/d3d12/d3d12.odin @@ -1,3 +1,4 @@ +// Bindings for [[ Direct3D 12 ; https://learn.microsoft.com/en-us/windows/win32/direct3d12/direct3d-12-graphics ]]. package directx_d3d12 foreign import "system:d3d12.lib" diff --git a/vendor/directx/d3d_compiler/d3d_compiler.odin b/vendor/directx/d3d_compiler/d3d_compiler.odin index 5a7178aff..6f9f3fe89 100644 --- a/vendor/directx/d3d_compiler/d3d_compiler.odin +++ b/vendor/directx/d3d_compiler/d3d_compiler.odin @@ -1,3 +1,4 @@ +// Bindings for [[ Direct3D Shader Compiler ; https://learn.microsoft.com/en-us/windows/win32/api/d3dcompiler/ ]]. package directx_d3d_compiler foreign import d3dcompiler "d3dcompiler_47.lib" diff --git a/vendor/directx/dxc/dxcapi.odin b/vendor/directx/dxc/dxcapi.odin index d9f8401db..1d3155feb 100644 --- a/vendor/directx/dxc/dxcapi.odin +++ b/vendor/directx/dxc/dxcapi.odin @@ -1,3 +1,4 @@ +// Bindings for [[ DXC ; https://learn.microsoft.com/en-us/windows/win32/api/dxcapi/ ]]. package directx_dxc when ODIN_OS == .Windows { diff --git a/vendor/directx/dxgi/dxgi.odin b/vendor/directx/dxgi/dxgi.odin index 0056b6a66..05b3925ff 100644 --- a/vendor/directx/dxgi/dxgi.odin +++ b/vendor/directx/dxgi/dxgi.odin @@ -1,3 +1,4 @@ +// Bindings for [[ DXGI ; https://learn.microsoft.com/en-us/windows/win32/api/dxgi/ ]]. package directx_dxgi foreign import dxgi { diff --git a/vendor/egl/egl.odin b/vendor/egl/egl.odin index 985d58457..fe52a7fce 100644 --- a/vendor/egl/egl.odin +++ b/vendor/egl/egl.odin @@ -1,3 +1,4 @@ +// Bindings for [[ EGL ; https://registry.khronos.org/EGL/sdk/docs/man/html/eglIntro.xhtml ]]. #+build linux package egl diff --git a/vendor/fontstash/fontstash.odin b/vendor/fontstash/fontstash.odin index 8563277b1..772e379f0 100644 --- a/vendor/fontstash/fontstash.odin +++ b/vendor/fontstash/fontstash.odin @@ -1,3 +1,4 @@ +// An Odin-native source port of [[ Fontstash ; https://github.com/memononen/fontstash ]]. #+vet !using-param package fontstash @@ -323,11 +324,15 @@ __AtlasAddWhiteRect :: proc(ctx: ^FontContext, w, h: int) -> bool { // push a font to the font stack // optionally init with ascii characters at a wanted size +// +// 'fontIndex' controls which font you want to load within a multi-font format such +// as TTC. Leave it as zero if you are loading a single-font format such as TTF. AddFontMem :: proc( ctx: ^FontContext, name: string, data: []u8, freeLoadedData: bool, + fontIndex: int = 0, ) -> int { append(&ctx.fonts, Font{}) res := &ctx.fonts[len(ctx.fonts) - 1] @@ -335,7 +340,10 @@ AddFontMem :: proc( res.freeLoadedData = freeLoadedData res.name = strings.clone(name) - stbtt.InitFont(&res.info, &res.loadedData[0], 0) + num_fonts := stbtt.GetNumberOfFonts(raw_data(data)) + font_index_clamped := num_fonts > 0 ? clamp(i32(fontIndex), 0, num_fonts-1) : 0 + font_offset := stbtt.GetFontOffsetForIndex(raw_data(data), font_index_clamped) + stbtt.InitFont(&res.info, raw_data(data), font_offset) ascent, descent, line_gap: i32 stbtt.GetFontVMetrics(&res.info, &ascent, &descent, &line_gap) diff --git a/vendor/fontstash/fontstash_os.odin b/vendor/fontstash/fontstash_os.odin index ed453926f..e510a4834 100644 --- a/vendor/fontstash/fontstash_os.odin +++ b/vendor/fontstash/fontstash_os.odin @@ -4,10 +4,13 @@ package fontstash import "core:log" import "core:os" +// 'fontIndex' controls which font you want to load within a multi-font format such +// as TTC. Leave it as zero if you are loading a single-font format such as TTF. AddFontPath :: proc( ctx: ^FontContext, name: string, path: string, + fontIndex: int = 0, ) -> int { data, ok := os.read_entire_file(path) @@ -15,6 +18,6 @@ AddFontPath :: proc( log.panicf("FONT: failed to read font at %s", path) } - return AddFontMem(ctx, name, data, true) + return AddFontMem(ctx, name, data, true, fontIndex) } diff --git a/vendor/fontstash/fontstash_other.odin b/vendor/fontstash/fontstash_other.odin index edb76d9db..b0a0e2ab9 100644 --- a/vendor/fontstash/fontstash_other.odin +++ b/vendor/fontstash/fontstash_other.odin @@ -5,6 +5,7 @@ AddFontPath :: proc( ctx: ^FontContext, name: string, path: string, + fontIndex: int = 0, ) -> int { panic("fontstash.AddFontPath is unsupported on the JS target") } diff --git a/vendor/ggpo/ggpo.odin b/vendor/ggpo/ggpo.odin index 59321326a..80b6a0d4a 100644 --- a/vendor/ggpo/ggpo.odin +++ b/vendor/ggpo/ggpo.odin @@ -1,4 +1,6 @@ /* +Bindings for [[ GGPO ; https://www.ggpo.net ]] rollback networking. + Created in 2009, the GGPO networking SDK pioneered the use of rollback networking in peer-to-peer games. It's designed specifically to hide network latency in fast paced, twitch style games which require very precise inputs and frame perfect execution. diff --git a/vendor/glfw/types.odin b/vendor/glfw/types.odin index cfe810fe5..a89e0d1ba 100644 --- a/vendor/glfw/types.odin +++ b/vendor/glfw/types.odin @@ -1,3 +1,4 @@ +// Bindings for [[ GLFW ; https://www.glfw.org ]] package glfw import glfw "bindings" diff --git a/vendor/kb_text_shape/kb_text_shape_procs.odin b/vendor/kb_text_shape/kb_text_shape_procs.odin index efcdcc4ed..a033402bc 100644 --- a/vendor/kb_text_shape/kb_text_shape_procs.odin +++ b/vendor/kb_text_shape/kb_text_shape_procs.odin @@ -1,3 +1,4 @@ +// Bindings for [[ Jimmy Lefevre's Text Shape ; https://github.com/JimmyLefevre/kb ]] Unicode text segmentation and OpenType shaping. package vendor_kb_text_shape when ODIN_OS == .Windows { diff --git a/vendor/libc/stdlib.odin b/vendor/libc/stdlib.odin index bb9233a28..cffc66ed2 100644 --- a/vendor/libc/stdlib.odin +++ b/vendor/libc/stdlib.odin @@ -1,3 +1,4 @@ +// A (very small) subset of a libc implementation over Odin libraries for use with `vendor:*` packages. package odin_libc import "base:intrinsics" diff --git a/vendor/lua/5.1/lua.odin b/vendor/lua/5.1/lua.odin index 5b7482931..19a2d9085 100644 --- a/vendor/lua/5.1/lua.odin +++ b/vendor/lua/5.1/lua.odin @@ -1,3 +1,4 @@ +// Bindings for [[ Lua 5.1 ; https://www.lua.org/manual/5.1/ ]]. package lua_5_1 import "base:intrinsics" diff --git a/vendor/lua/5.2/lua.odin b/vendor/lua/5.2/lua.odin index bc47479e3..95105703c 100644 --- a/vendor/lua/5.2/lua.odin +++ b/vendor/lua/5.2/lua.odin @@ -1,3 +1,4 @@ +// Bindings for [[ Lua 5.2 ; https://www.lua.org/manual/5.2/ ]]. package lua_5_2 import "base:intrinsics" diff --git a/vendor/lua/5.3/lua.odin b/vendor/lua/5.3/lua.odin index 47215a327..02b1c83ad 100644 --- a/vendor/lua/5.3/lua.odin +++ b/vendor/lua/5.3/lua.odin @@ -1,3 +1,4 @@ +// Bindings for [[ Lua 5.3 ; https://www.lua.org/manual/5.3/ ]]. package lua_5_3 import "base:intrinsics" diff --git a/vendor/lua/5.4/lua.odin b/vendor/lua/5.4/lua.odin index a45de4d49..1bda09542 100644 --- a/vendor/lua/5.4/lua.odin +++ b/vendor/lua/5.4/lua.odin @@ -1,3 +1,4 @@ +// Bindings for [[ Lua 5.4 ; https://www.lua.org/manual/5.4/ ]]. package lua_5_4 import "base:intrinsics" diff --git a/vendor/microui/microui.odin b/vendor/microui/microui.odin index 08a96acf2..5f5646cc2 100644 --- a/vendor/microui/microui.odin +++ b/vendor/microui/microui.odin @@ -1,4 +1,6 @@ /* +An Odin-native source port of [[ rxi's microui ; https://github.com/rxi/microui ]] immediate mode UI. + ** Original work: Copyright (c) 2020 rxi ** Modified work: Copyright (c) 2020 oskarnp ** Modified work: Copyright (c) 2021 gingerBill @@ -21,7 +23,6 @@ ** FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS ** IN THE SOFTWARE. */ - package microui import "core:fmt" diff --git a/vendor/miniaudio/data_conversion.odin b/vendor/miniaudio/data_conversion.odin index d95607dd9..a6df39e3b 100644 --- a/vendor/miniaudio/data_conversion.odin +++ b/vendor/miniaudio/data_conversion.odin @@ -566,9 +566,9 @@ foreign lib { pcm_rb_uninit :: proc(pRB: ^pcm_rb) --- pcm_rb_reset :: proc(pRB: ^pcm_rb) --- pcm_rb_acquire_read :: proc(pRB: ^pcm_rb, pSizeInFrames: ^u32, ppBufferOut: ^rawptr) -> result --- - pcm_rb_commit_read :: proc(pRB: ^pcm_rb, sizeInFrames: u32, pBufferOut: rawptr) -> result --- + pcm_rb_commit_read :: proc(pRB: ^pcm_rb, sizeInFrames: u32) -> result --- pcm_rb_acquire_write :: proc(pRB: ^pcm_rb, pSizeInFrames: ^u32, ppBufferOut: ^rawptr) -> result --- - pcm_rb_commit_write :: proc(pRB: ^pcm_rb, sizeInFrames: u32, pBufferOut: rawptr) -> result --- + pcm_rb_commit_write :: proc(pRB: ^pcm_rb, sizeInFrames: u32) -> result --- pcm_rb_seek_read :: proc(pRB: ^pcm_rb, offsetInFrames: u32) -> result --- pcm_rb_seek_write :: proc(pRB: ^pcm_rb, offsetInFrames: u32) -> result --- pcm_rb_pointer_distance :: proc(pRB: ^pcm_rb) -> i32 --- /* Return value is in frames. */ diff --git a/vendor/miniaudio/doc.odin b/vendor/miniaudio/doc.odin index ff7924b89..58b13b845 100644 --- a/vendor/miniaudio/doc.odin +++ b/vendor/miniaudio/doc.odin @@ -1,7 +1,7 @@ -package miniaudio - /* -Audio playback and capture library. Choice of public domain or MIT-0. See license statements at the end of this file. +Bindings for [[ miniaudio ; https://miniaud.io/docs ]] audio playback and capture library. + +Choice of public domain or MIT-0. See license statements at the end of this file. miniaudio - v0.11.21 - 2023-11-15 David Reid - mackron@gmail.com @@ -9,9 +9,7 @@ David Reid - mackron@gmail.com Website: https://miniaud.io Documentation: https://miniaud.io/docs GitHub: https://github.com/mackron/miniaudio -*/ -/* 1. Introduction =============== miniaudio is a single file library for audio playback and capture. To use it, do the following in @@ -3736,3 +3734,4 @@ See below for some tips on improving performance. - When compiling with VC6 and earlier, decoding is restricted to files less than 2GB in size. This is due to 64-bit file APIs not being available. */ +package miniaudio \ No newline at end of file diff --git a/vendor/nanovg/gl/gl.odin b/vendor/nanovg/gl/gl.odin index 5af7ed4bc..e43f07354 100644 --- a/vendor/nanovg/gl/gl.odin +++ b/vendor/nanovg/gl/gl.odin @@ -1,3 +1,4 @@ +// An Odin-native source port of [[ nanovg ; https://github.com/memononen/nanovg ]]'s GL backend. #+build windows, linux, darwin package nanovg_gl diff --git a/vendor/nanovg/nanovg.odin b/vendor/nanovg/nanovg.odin index 540ca47cf..70ba90681 100644 --- a/vendor/nanovg/nanovg.odin +++ b/vendor/nanovg/nanovg.odin @@ -1,3 +1,4 @@ +// An Odin-native source port of [[ nanovg ; https://github.com/memononen/nanovg ]]. #+build windows, linux, darwin package nanovg diff --git a/vendor/portmidi/doc.odin b/vendor/portmidi/doc.odin index 6a3d5331a..3e6b0b3b2 100644 --- a/vendor/portmidi/doc.odin +++ b/vendor/portmidi/doc.odin @@ -1,3 +1,4 @@ +// Bindings for [[ PortMidi ; http://sourceforge.net/projects/portmedia ]] Portable Real-Time MIDI Library. package portmidi /* diff --git a/vendor/raylib/raylib.odin b/vendor/raylib/raylib.odin index bb8f0e894..7dae19f4b 100644 --- a/vendor/raylib/raylib.odin +++ b/vendor/raylib/raylib.odin @@ -1,5 +1,5 @@ /* -Package vendor:raylib implements bindings for version 5.5 of the raylib library (https://www.raylib.com/) +Bindings for [[ raylib v5.5 ; https://www.raylib.com ]]. ********************************************************************************************* * diff --git a/vendor/sdl2/image/sdl_image.odin b/vendor/sdl2/image/sdl_image.odin index 204ec9a0d..de9b74cac 100644 --- a/vendor/sdl2/image/sdl_image.odin +++ b/vendor/sdl2/image/sdl_image.odin @@ -1,3 +1,4 @@ +// Bindings for [[ SDL2 Image; https://wiki.libsdl.org/SDL2/FrontPage ]]. package sdl2_image import "core:c" diff --git a/vendor/sdl2/mixer/sdl_mixer.odin b/vendor/sdl2/mixer/sdl_mixer.odin index b0c16871d..a3032a08c 100644 --- a/vendor/sdl2/mixer/sdl_mixer.odin +++ b/vendor/sdl2/mixer/sdl_mixer.odin @@ -1,3 +1,4 @@ +// Bindings for [[ SDL2 Mixer ; https://wiki.libsdl.org/SDL2/FrontPage ]]. package sdl2_mixer import "core:c" diff --git a/vendor/sdl2/net/sdl_net.odin b/vendor/sdl2/net/sdl_net.odin index 579f245e5..2e13a7406 100644 --- a/vendor/sdl2/net/sdl_net.odin +++ b/vendor/sdl2/net/sdl_net.odin @@ -1,3 +1,4 @@ +// Bindings for [[ SDL2 Net ; https://wiki.libsdl.org/SDL2/FrontPage ]]. package sdl2_net import "core:c" diff --git a/vendor/sdl2/sdl2.odin b/vendor/sdl2/sdl2.odin index 5bc52b70e..ffe70c330 100644 --- a/vendor/sdl2/sdl2.odin +++ b/vendor/sdl2/sdl2.odin @@ -1,3 +1,4 @@ +// Bindings for [[ SDL2 ; https://wiki.libsdl.org/SDL2/FrontPage ]]. package sdl2 /* diff --git a/vendor/sdl2/ttf/sdl_ttf.odin b/vendor/sdl2/ttf/sdl_ttf.odin index ca9beded0..15c861847 100644 --- a/vendor/sdl2/ttf/sdl_ttf.odin +++ b/vendor/sdl2/ttf/sdl_ttf.odin @@ -1,3 +1,4 @@ +// Bindings for [[ SDL2 TTF ; https://wiki.libsdl.org/SDL2/FrontPage ]]. package sdl2_ttf import "core:c" diff --git a/vendor/sdl3/image/sdl_image.odin b/vendor/sdl3/image/sdl_image.odin index d2c628a86..d43885644 100644 --- a/vendor/sdl3/image/sdl_image.odin +++ b/vendor/sdl3/image/sdl_image.odin @@ -1,3 +1,4 @@ +// Bindings for [[ SDL3 Image ; https://wiki.libsdl.org/SDL3/FrontPage ]]. package sdl3_image import "core:c" diff --git a/vendor/sdl3/sdl3_main.odin b/vendor/sdl3/sdl3_main.odin index f5f9b7f52..103372bed 100644 --- a/vendor/sdl3/sdl3_main.odin +++ b/vendor/sdl3/sdl3_main.odin @@ -1,3 +1,4 @@ +// Bindings for [[ SDL3 ; https://wiki.libsdl.org/SDL3/FrontPage ]]. package sdl3 import "core:c" diff --git a/vendor/sdl3/sdl3_rect.odin b/vendor/sdl3/sdl3_rect.odin index 53470dec4..6af9dc937 100644 --- a/vendor/sdl3/sdl3_rect.odin +++ b/vendor/sdl3/sdl3_rect.odin @@ -29,6 +29,12 @@ PointInRect :: proc "c" (p: Point, r: Rect) -> bool { (p.y >= r.y) && (p.y < (r.y + r.h)) ) } +@(require_results) +PointInRectFloat :: proc "c" (p: FPoint, r: FRect) -> bool { + return ( (p.x >= r.x) && (p.x <= (r.x + r.w)) && + (p.y >= r.y) && (p.y <= (r.y + r.h)) ) +} + @(require_results) RectEmpty :: proc "c" (r: Rect) -> bool { return r.w <= 0 || r.h <= 0 diff --git a/vendor/sdl3/ttf/sdl3_ttf.odin b/vendor/sdl3/ttf/sdl3_ttf.odin index ada1de833..7fb583726 100644 --- a/vendor/sdl3/ttf/sdl3_ttf.odin +++ b/vendor/sdl3/ttf/sdl3_ttf.odin @@ -1,3 +1,4 @@ +// Bindings for [[ SDL3 TTF ; https://wiki.libsdl.org/SDL3/FrontPage ]]. package sdl3_ttf import "core:c" diff --git a/vendor/stb/easy_font/stb_easy_font.odin b/vendor/stb/easy_font/stb_easy_font.odin index 0208ca316..17e8127e9 100644 --- a/vendor/stb/easy_font/stb_easy_font.odin +++ b/vendor/stb/easy_font/stb_easy_font.odin @@ -1,26 +1,7 @@ -package stb_easy_font - /* - Source port of stb_easy_font.h - - Original port: gingerBill - Bugfixes: Florian Behr & Jeroen van Rijn - Additions: Jeroen van Rijn - - Changelog: - 2022-04-03 - Bug fixes - Add `print(x, y, text, color, quad_buffer)` version that takes `[]quad`. - (Same internal memory layout as []u8 API, but more convenient for the caller.) - Add optional `scale := f32(1.0)` param to `print` to embiggen the glyph quads. - - 2021-09-14 - Original Odin version -*/ - -/* - // Example for use with vendor:raylib +An Odin-native source port of [[ stb_easy_font.h ; https://github.com/nothings/stb/blob/master/stb_easy_font.h ]]. +Example: quads: [999]easy_font.Quad = --- color := rl.GREEN @@ -38,7 +19,24 @@ package stb_easy_font // And in practice this code will likely not live as close to the `easy_font` call. rl.DrawRectangleRec(r, color) } + + +Changelog: + 2022-04-03 + Bug fixes + Add `print(x, y, text, color, quad_buffer)` version that takes `[]quad`. + (Same internal memory layout as []u8 API, but more convenient for the caller.) + Add optional `scale := f32(1.0)` param to `print` to embiggen the glyph quads. + + 2021-09-14 + Original Odin version + +Credits: + Original port: gingerBill + Bugfixes: Florian Behr & Jeroen van Rijn + Additions: Jeroen van Rijn */ +package stb_easy_font import "core:math" import "core:mem" diff --git a/vendor/stb/image/stb_image.odin b/vendor/stb/image/stb_image.odin index 1ba63dc47..ac0892d0a 100644 --- a/vendor/stb/image/stb_image.odin +++ b/vendor/stb/image/stb_image.odin @@ -1,3 +1,4 @@ +// Bindings for [[ stb_image.h ; https://github.com/nothings/stb/blob/master/stb_image.h ]]. package stb_image import "core:c" diff --git a/vendor/stb/rect_pack/stb_rect_pack.odin b/vendor/stb/rect_pack/stb_rect_pack.odin index 696b9c8c0..0ba975b15 100644 --- a/vendor/stb/rect_pack/stb_rect_pack.odin +++ b/vendor/stb/rect_pack/stb_rect_pack.odin @@ -1,3 +1,4 @@ +// Bindings for [[ stb_rect_pack.h ; https://github.com/nothings/stb/blob/master/stb_rect_pack.h ]]. package stb_rect_pack import "core:c" diff --git a/vendor/stb/truetype/stb_truetype.odin b/vendor/stb/truetype/stb_truetype.odin index bd521c63b..cb829a514 100644 --- a/vendor/stb/truetype/stb_truetype.odin +++ b/vendor/stb/truetype/stb_truetype.odin @@ -1,3 +1,4 @@ +// Bindings for [[ stb_truetype.h ; https://github.com/nothings/stb/blob/master/stb_truetype.h ]]. package stb_truetype import c "core:c" diff --git a/vendor/stb/vorbis/stb_vorbis.odin b/vendor/stb/vorbis/stb_vorbis.odin index 867ffb86d..38bba4f29 100644 --- a/vendor/stb/vorbis/stb_vorbis.odin +++ b/vendor/stb/vorbis/stb_vorbis.odin @@ -1,3 +1,4 @@ +// Bindings for [[ stb_vorbis.c ; https://github.com/nothings/stb/blob/master/stb_vorbis.c ]]. package stb_vorbis import c "core:c/libc" diff --git a/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py b/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py index 2d78179e7..4900d52b7 100644 --- a/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py +++ b/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py @@ -6,6 +6,13 @@ import string import os.path import math +PACKAGE_LINE = "package vulkan" + +BASE = """ +// Vulkan wrapper generated from [[ vulkan_core.h ; https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/master/include/vulkan/vulkan_core.h ]]. +"""[1::] + + file_and_urls = [ ("vk_platform.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/main/include/vulkan/vk_platform.h', True), ("vulkan_core.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/main/include/vulkan/vulkan_core.h', False), @@ -301,7 +308,7 @@ def parse_constants(f): f.write("\n// Vendor Constants\n") fixes = '|'.join(ext_suffixes) - inner = r"((?:(?:" + fixes + r")\w+)|(?:\w+" + fixes + r"))" + inner = r"((?:(?:" + fixes + r")\w+)|(?:\w+(?:" + fixes + r")\b))" pattern = r"#define\s+VK_" + inner + r"\s*(.*?)\n" data = re.findall(pattern, src, re.S) @@ -311,7 +318,11 @@ def parse_constants(f): for name, value in data: value = remove_prefix(value, 'VK_') v = number_suffix_re.findall(value) - if v: + if value == "(~0U)": + value = "~u32(0)" + elif value == "(~0ULL)": + value = "~u64(0)" + elif v: value = v[0] f.write("{}{} :: {}\n".format(name, "".rjust(max_len-len(name)), value)) f.write("\n") @@ -885,18 +896,9 @@ load_proc_addresses :: proc{ }\n """[1::]) - - -BASE = """ -// -// Vulkan wrapper generated from "https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/master/include/vulkan/vulkan_core.h" -// -package vulkan -"""[1::] - - with open("../core.odin", 'w', encoding='utf-8') as f: f.write(BASE) + f.write(PACKAGE_LINE) f.write(""" // Core API API_VERSION_1_0 :: (1<<22) | (0<<12) | (0) @@ -935,7 +937,6 @@ FALSE :: 0 QUEUE_FAMILY_IGNORED :: ~u32(0) SUBPASS_EXTERNAL :: ~u32(0) MAX_PHYSICAL_DEVICE_NAME_SIZE :: 256 -MAX_SHADER_MODULE_IDENTIFIER_SIZE_EXT :: 32 UUID_SIZE :: 16 MAX_MEMORY_TYPES :: 32 MAX_MEMORY_HEAPS :: 16 @@ -946,7 +947,6 @@ LUID_SIZE_KHX :: 8 LUID_SIZE :: 8 MAX_QUEUE_FAMILY_EXTERNAL :: ~u32(1) MAX_GLOBAL_PRIORITY_SIZE :: 16 -MAX_GLOBAL_PRIORITY_SIZE_EXT :: MAX_GLOBAL_PRIORITY_SIZE QUEUE_FAMILY_EXTERNAL :: MAX_QUEUE_FAMILY_EXTERNAL // Vulkan Video API Constants @@ -972,13 +972,13 @@ MAKE_VIDEO_STD_VERSION :: MAKE_VERSION f.write("\n\n") parse_flags_def(f) with open("../enums.odin", 'w', encoding='utf-8') as f: - f.write(BASE) + f.write(PACKAGE_LINE) f.write("\n") parse_enums(f) parse_fake_enums(f) f.write("\n\n") with open("../structs.odin", 'w', encoding='utf-8') as f: - f.write(BASE) + f.write(PACKAGE_LINE) f.write(""" import "core:c" @@ -1039,7 +1039,7 @@ MTLCommandQueue_id :: rawptr parse_structs(f) f.write("\n\n") with open("../procedures.odin", 'w', encoding='utf-8') as f: - f.write(BASE) + f.write(PACKAGE_LINE) f.write("\n") parse_procedures(f) f.write("\n") diff --git a/vendor/vulkan/core.odin b/vendor/vulkan/core.odin index a80bdc73b..c3cb59a16 100644 --- a/vendor/vulkan/core.odin +++ b/vendor/vulkan/core.odin @@ -1,6 +1,4 @@ -// -// Vulkan wrapper generated from "https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/master/include/vulkan/vulkan_core.h" -// +// Vulkan wrapper generated from [[ vulkan_core.h ; https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/master/include/vulkan/vulkan_core.h ]]. package vulkan // Core API API_VERSION_1_0 :: (1<<22) | (0<<12) | (0) @@ -39,7 +37,6 @@ FALSE :: 0 QUEUE_FAMILY_IGNORED :: ~u32(0) SUBPASS_EXTERNAL :: ~u32(0) MAX_PHYSICAL_DEVICE_NAME_SIZE :: 256 -MAX_SHADER_MODULE_IDENTIFIER_SIZE_EXT :: 32 UUID_SIZE :: 16 MAX_MEMORY_TYPES :: 32 MAX_MEMORY_HEAPS :: 16 @@ -50,7 +47,6 @@ LUID_SIZE_KHX :: 8 LUID_SIZE :: 8 MAX_QUEUE_FAMILY_EXTERNAL :: ~u32(1) MAX_GLOBAL_PRIORITY_SIZE :: 16 -MAX_GLOBAL_PRIORITY_SIZE_EXT :: MAX_GLOBAL_PRIORITY_SIZE QUEUE_FAMILY_EXTERNAL :: MAX_QUEUE_FAMILY_EXTERNAL // Vulkan Video API Constants @@ -140,1069 +136,1075 @@ VULKAN_VIDEO_CODEC_H265_DECODE_EXTENSION_NAME :: "VK_STD_vulkan_video_codec_h265 VULKAN_VIDEO_CODEC_H265_ENCODE_EXTENSION_NAME :: "VK_STD_vulkan_video_codec_h265_encode" // Vendor Constants -KHR_surface :: 1 -KHR_SURFACE_SPEC_VERSION :: 25 -KHR_SURFACE_EXTENSION_NAME :: "VK_KHR_surface" -KHR_swapchain :: 1 -KHR_SWAPCHAIN_SPEC_VERSION :: 70 -KHR_SWAPCHAIN_EXTENSION_NAME :: "VK_KHR_swapchain" -KHR_display :: 1 -KHR_DISPLAY_SPEC_VERSION :: 23 -KHR_DISPLAY_EXTENSION_NAME :: "VK_KHR_display" -KHR_display_swapchain :: 1 -KHR_DISPLAY_SWAPCHAIN_SPEC_VERSION :: 10 -KHR_DISPLAY_SWAPCHAIN_EXTENSION_NAME :: "VK_KHR_display_swapchain" -KHR_sampler_mirror_clamp_to_edge :: 1 -KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_SPEC_VERSION :: 3 -KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME :: "VK_KHR_sampler_mirror_clamp_to_edge" -KHR_video_queue :: 1 -KHR_VIDEO_QUEUE_SPEC_VERSION :: 8 -KHR_VIDEO_QUEUE_EXTENSION_NAME :: "VK_KHR_video_queue" -KHR_video_decode_queue :: 1 -KHR_VIDEO_DECODE_QUEUE_SPEC_VERSION :: 8 -KHR_VIDEO_DECODE_QUEUE_EXTENSION_NAME :: "VK_KHR_video_decode_queue" -KHR_video_encode_h264 :: 1 -KHR_VIDEO_ENCODE_H264_SPEC_VERSION :: 14 -KHR_VIDEO_ENCODE_H264_EXTENSION_NAME :: "VK_KHR_video_encode_h264" -KHR_video_encode_h265 :: 1 -KHR_VIDEO_ENCODE_H265_SPEC_VERSION :: 14 -KHR_VIDEO_ENCODE_H265_EXTENSION_NAME :: "VK_KHR_video_encode_h265" -KHR_video_decode_h264 :: 1 -KHR_VIDEO_DECODE_H264_SPEC_VERSION :: 9 -KHR_VIDEO_DECODE_H264_EXTENSION_NAME :: "VK_KHR_video_decode_h264" -KHR_dynamic_rendering :: 1 -KHR_DYNAMIC_RENDERING_SPEC_VERSION :: 1 -KHR_DYNAMIC_RENDERING_EXTENSION_NAME :: "VK_KHR_dynamic_rendering" -KHR_multiview :: 1 -KHR_MULTIVIEW_SPEC_VERSION :: 1 -KHR_MULTIVIEW_EXTENSION_NAME :: "VK_KHR_multiview" -KHR_get_physical_device_properties2 :: 1 -KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_SPEC_VERSION :: 2 -KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME :: "VK_KHR_get_physical_device_properties2" -KHR_device_group :: 1 -KHR_DEVICE_GROUP_SPEC_VERSION :: 4 -KHR_DEVICE_GROUP_EXTENSION_NAME :: "VK_KHR_device_group" -KHR_shader_draw_parameters :: 1 -KHR_SHADER_DRAW_PARAMETERS_SPEC_VERSION :: 1 -KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME :: "VK_KHR_shader_draw_parameters" -KHR_maintenance1 :: 1 -KHR_MAINTENANCE_1_SPEC_VERSION :: 2 -KHR_MAINTENANCE_1_EXTENSION_NAME :: "VK_KHR_maintenance1" -KHR_MAINTENANCE1_SPEC_VERSION :: KHR_MAINTENANCE_1_SPEC_VERSION -KHR_MAINTENANCE1_EXTENSION_NAME :: KHR_MAINTENANCE_1_EXTENSION_NAME -KHR_device_group_creation :: 1 -KHR_DEVICE_GROUP_CREATION_SPEC_VERSION :: 1 -KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME :: "VK_KHR_device_group_creation" -MAX_DEVICE_GROUP_SIZE_KHR :: MAX_DEVICE_GROUP_SIZE -KHR_external_memory_capabilities :: 1 -KHR_EXTERNAL_MEMORY_CAPABILITIES_SPEC_VERSION :: 1 -KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME :: "VK_KHR_external_memory_capabilities" -LUID_SIZE_KHR :: LUID_SIZE -KHR_external_memory :: 1 -KHR_EXTERNAL_MEMORY_SPEC_VERSION :: 1 -KHR_EXTERNAL_MEMORY_EXTENSION_NAME :: "VK_KHR_external_memory" -QUEUE_FAMILY_EXTERNAL_KHR :: QUEUE_FAMILY_EXTERNAL -KHR_external_memory_fd :: 1 -KHR_EXTERNAL_MEMORY_FD_SPEC_VERSION :: 1 -KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME :: "VK_KHR_external_memory_fd" -KHR_external_semaphore_capabilities :: 1 -KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_SPEC_VERSION :: 1 -KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME :: "VK_KHR_external_semaphore_capabilities" -KHR_external_semaphore :: 1 -KHR_EXTERNAL_SEMAPHORE_SPEC_VERSION :: 1 -KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME :: "VK_KHR_external_semaphore" -KHR_external_semaphore_fd :: 1 -KHR_EXTERNAL_SEMAPHORE_FD_SPEC_VERSION :: 1 -KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME :: "VK_KHR_external_semaphore_fd" -KHR_push_descriptor :: 1 -KHR_PUSH_DESCRIPTOR_SPEC_VERSION :: 2 -KHR_PUSH_DESCRIPTOR_EXTENSION_NAME :: "VK_KHR_push_descriptor" -KHR_shader_float16_int8 :: 1 -KHR_SHADER_FLOAT16_INT8_SPEC_VERSION :: 1 -KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME :: "VK_KHR_shader_float16_int8" -KHR_16bit_storage :: 1 -KHR_16BIT_STORAGE_SPEC_VERSION :: 1 -KHR_16BIT_STORAGE_EXTENSION_NAME :: "VK_KHR_16bit_storage" -KHR_incremental_present :: 1 -KHR_INCREMENTAL_PRESENT_SPEC_VERSION :: 2 -KHR_INCREMENTAL_PRESENT_EXTENSION_NAME :: "VK_KHR_incremental_present" -KHR_descriptor_update_template :: 1 -KHR_DESCRIPTOR_UPDATE_TEMPLATE_SPEC_VERSION :: 1 -KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME :: "VK_KHR_descriptor_update_template" -KHR_imageless_framebuffer :: 1 -KHR_IMAGELESS_FRAMEBUFFER_SPEC_VERSION :: 1 -KHR_IMAGELESS_FRAMEBUFFER_EXTENSION_NAME :: "VK_KHR_imageless_framebuffer" -KHR_create_renderpass2 :: 1 -KHR_CREATE_RENDERPASS_2_SPEC_VERSION :: 1 -KHR_CREATE_RENDERPASS_2_EXTENSION_NAME :: "VK_KHR_create_renderpass2" -KHR_shared_presentable_image :: 1 -KHR_SHARED_PRESENTABLE_IMAGE_SPEC_VERSION :: 1 -KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME :: "VK_KHR_shared_presentable_image" -KHR_external_fence_capabilities :: 1 -KHR_EXTERNAL_FENCE_CAPABILITIES_SPEC_VERSION :: 1 -KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME :: "VK_KHR_external_fence_capabilities" -KHR_external_fence :: 1 -KHR_EXTERNAL_FENCE_SPEC_VERSION :: 1 -KHR_EXTERNAL_FENCE_EXTENSION_NAME :: "VK_KHR_external_fence" -KHR_external_fence_fd :: 1 -KHR_EXTERNAL_FENCE_FD_SPEC_VERSION :: 1 -KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME :: "VK_KHR_external_fence_fd" -KHR_performance_query :: 1 -KHR_PERFORMANCE_QUERY_SPEC_VERSION :: 1 -KHR_PERFORMANCE_QUERY_EXTENSION_NAME :: "VK_KHR_performance_query" -KHR_maintenance2 :: 1 -KHR_MAINTENANCE_2_SPEC_VERSION :: 1 -KHR_MAINTENANCE_2_EXTENSION_NAME :: "VK_KHR_maintenance2" -KHR_MAINTENANCE2_SPEC_VERSION :: KHR_MAINTENANCE_2_SPEC_VERSION -KHR_MAINTENANCE2_EXTENSION_NAME :: KHR_MAINTENANCE_2_EXTENSION_NAME -KHR_get_surface_capabilities2 :: 1 -KHR_GET_SURFACE_CAPABILITIES_2_SPEC_VERSION :: 1 -KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME :: "VK_KHR_get_surface_capabilities2" -KHR_variable_pointers :: 1 -KHR_VARIABLE_POINTERS_SPEC_VERSION :: 1 -KHR_VARIABLE_POINTERS_EXTENSION_NAME :: "VK_KHR_variable_pointers" -KHR_get_display_properties2 :: 1 -KHR_GET_DISPLAY_PROPERTIES_2_SPEC_VERSION :: 1 -KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME :: "VK_KHR_get_display_properties2" -KHR_dedicated_allocation :: 1 -KHR_DEDICATED_ALLOCATION_SPEC_VERSION :: 3 -KHR_DEDICATED_ALLOCATION_EXTENSION_NAME :: "VK_KHR_dedicated_allocation" -KHR_storage_buffer_storage_class :: 1 -KHR_STORAGE_BUFFER_STORAGE_CLASS_SPEC_VERSION :: 1 -KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME :: "VK_KHR_storage_buffer_storage_class" -KHR_relaxed_block_layout :: 1 -KHR_RELAXED_BLOCK_LAYOUT_SPEC_VERSION :: 1 -KHR_RELAXED_BLOCK_LAYOUT_EXTENSION_NAME :: "VK_KHR_relaxed_block_layout" -KHR_get_memory_requirements2 :: 1 -KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION :: 1 -KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME :: "VK_KHR_get_memory_requirements2" -KHR_image_format_list :: 1 -KHR_IMAGE_FORMAT_LIST_SPEC_VERSION :: 1 -KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME :: "VK_KHR_image_format_list" -KHR_sampler_ycbcr_conversion :: 1 -KHR_SAMPLER_YCBCR_CONVERSION_SPEC_VERSION :: 14 -KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME :: "VK_KHR_sampler_ycbcr_conversion" -KHR_bind_memory2 :: 1 -KHR_BIND_MEMORY_2_SPEC_VERSION :: 1 -KHR_BIND_MEMORY_2_EXTENSION_NAME :: "VK_KHR_bind_memory2" -KHR_maintenance3 :: 1 -KHR_MAINTENANCE_3_SPEC_VERSION :: 1 -KHR_MAINTENANCE_3_EXTENSION_NAME :: "VK_KHR_maintenance3" -KHR_MAINTENANCE3_SPEC_VERSION :: KHR_MAINTENANCE_3_SPEC_VERSION -KHR_MAINTENANCE3_EXTENSION_NAME :: KHR_MAINTENANCE_3_EXTENSION_NAME -KHR_draw_indirect_count :: 1 -KHR_DRAW_INDIRECT_COUNT_SPEC_VERSION :: 1 -KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME :: "VK_KHR_draw_indirect_count" -KHR_shader_subgroup_extended_types :: 1 -KHR_SHADER_SUBGROUP_EXTENDED_TYPES_SPEC_VERSION :: 1 -KHR_SHADER_SUBGROUP_EXTENDED_TYPES_EXTENSION_NAME :: "VK_KHR_shader_subgroup_extended_types" -KHR_8bit_storage :: 1 -KHR_8BIT_STORAGE_SPEC_VERSION :: 1 -KHR_8BIT_STORAGE_EXTENSION_NAME :: "VK_KHR_8bit_storage" -KHR_shader_atomic_int64 :: 1 -KHR_SHADER_ATOMIC_INT64_SPEC_VERSION :: 1 -KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME :: "VK_KHR_shader_atomic_int64" -KHR_shader_clock :: 1 -KHR_SHADER_CLOCK_SPEC_VERSION :: 1 -KHR_SHADER_CLOCK_EXTENSION_NAME :: "VK_KHR_shader_clock" -KHR_video_decode_h265 :: 1 -KHR_VIDEO_DECODE_H265_SPEC_VERSION :: 8 -KHR_VIDEO_DECODE_H265_EXTENSION_NAME :: "VK_KHR_video_decode_h265" -KHR_global_priority :: 1 -KHR_GLOBAL_PRIORITY_SPEC_VERSION :: 1 -KHR_GLOBAL_PRIORITY_EXTENSION_NAME :: "VK_KHR_global_priority" -MAX_GLOBAL_PRIORITY_SIZE_KHR :: MAX_GLOBAL_PRIORITY_SIZE -KHR_driver_properties :: 1 -KHR_DRIVER_PROPERTIES_SPEC_VERSION :: 1 -KHR_DRIVER_PROPERTIES_EXTENSION_NAME :: "VK_KHR_driver_properties" -MAX_DRIVER_NAME_SIZE_KHR :: MAX_DRIVER_NAME_SIZE -MAX_DRIVER_INFO_SIZE_KHR :: MAX_DRIVER_INFO_SIZE -KHR_shader_float_controls :: 1 -KHR_SHADER_FLOAT_CONTROLS_SPEC_VERSION :: 4 -KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME :: "VK_KHR_shader_float_controls" -KHR_depth_stencil_resolve :: 1 -KHR_DEPTH_STENCIL_RESOLVE_SPEC_VERSION :: 1 -KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME :: "VK_KHR_depth_stencil_resolve" -KHR_swapchain_mutable_format :: 1 -KHR_SWAPCHAIN_MUTABLE_FORMAT_SPEC_VERSION :: 1 -KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME :: "VK_KHR_swapchain_mutable_format" -KHR_timeline_semaphore :: 1 -KHR_TIMELINE_SEMAPHORE_SPEC_VERSION :: 2 -KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME :: "VK_KHR_timeline_semaphore" -KHR_vulkan_memory_model :: 1 -KHR_VULKAN_MEMORY_MODEL_SPEC_VERSION :: 3 -KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME :: "VK_KHR_vulkan_memory_model" -KHR_shader_terminate_invocation :: 1 -KHR_SHADER_TERMINATE_INVOCATION_SPEC_VERSION :: 1 -KHR_SHADER_TERMINATE_INVOCATION_EXTENSION_NAME :: "VK_KHR_shader_terminate_invocation" -KHR_fragment_shading_rate :: 1 -KHR_FRAGMENT_SHADING_RATE_SPEC_VERSION :: 2 -KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME :: "VK_KHR_fragment_shading_rate" -KHR_dynamic_rendering_local_read :: 1 -KHR_DYNAMIC_RENDERING_LOCAL_READ_SPEC_VERSION :: 1 -KHR_DYNAMIC_RENDERING_LOCAL_READ_EXTENSION_NAME :: "VK_KHR_dynamic_rendering_local_read" -KHR_shader_quad_control :: 1 -KHR_SHADER_QUAD_CONTROL_SPEC_VERSION :: 1 -KHR_SHADER_QUAD_CONTROL_EXTENSION_NAME :: "VK_KHR_shader_quad_control" -KHR_spirv_1_4 :: 1 -KHR_SPIRV_1_4_SPEC_VERSION :: 1 -KHR_SPIRV_1_4_EXTENSION_NAME :: "VK_KHR_spirv_1_4" -KHR_surface_protected_capabilities :: 1 -KHR_SURFACE_PROTECTED_CAPABILITIES_SPEC_VERSION :: 1 -KHR_SURFACE_PROTECTED_CAPABILITIES_EXTENSION_NAME :: "VK_KHR_surface_protected_capabilities" -KHR_separate_depth_stencil_layouts :: 1 -KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_SPEC_VERSION :: 1 -KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_EXTENSION_NAME :: "VK_KHR_separate_depth_stencil_layouts" -KHR_present_wait :: 1 -KHR_PRESENT_WAIT_SPEC_VERSION :: 1 -KHR_PRESENT_WAIT_EXTENSION_NAME :: "VK_KHR_present_wait" -KHR_uniform_buffer_standard_layout :: 1 -KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_SPEC_VERSION :: 1 -KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME :: "VK_KHR_uniform_buffer_standard_layout" -KHR_buffer_device_address :: 1 -KHR_BUFFER_DEVICE_ADDRESS_SPEC_VERSION :: 1 -KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME :: "VK_KHR_buffer_device_address" -KHR_deferred_host_operations :: 1 -KHR_DEFERRED_HOST_OPERATIONS_SPEC_VERSION :: 4 -KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME :: "VK_KHR_deferred_host_operations" -KHR_pipeline_executable_properties :: 1 -KHR_PIPELINE_EXECUTABLE_PROPERTIES_SPEC_VERSION :: 1 -KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME :: "VK_KHR_pipeline_executable_properties" -KHR_map_memory2 :: 1 -KHR_MAP_MEMORY_2_SPEC_VERSION :: 1 -KHR_MAP_MEMORY_2_EXTENSION_NAME :: "VK_KHR_map_memory2" -KHR_shader_integer_dot_product :: 1 -KHR_SHADER_INTEGER_DOT_PRODUCT_SPEC_VERSION :: 1 -KHR_SHADER_INTEGER_DOT_PRODUCT_EXTENSION_NAME :: "VK_KHR_shader_integer_dot_product" -KHR_pipeline_library :: 1 -KHR_PIPELINE_LIBRARY_SPEC_VERSION :: 1 -KHR_PIPELINE_LIBRARY_EXTENSION_NAME :: "VK_KHR_pipeline_library" -KHR_shader_non_semantic_info :: 1 -KHR_SHADER_NON_SEMANTIC_INFO_SPEC_VERSION :: 1 -KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME :: "VK_KHR_shader_non_semantic_info" -KHR_present_id :: 1 -KHR_PRESENT_ID_SPEC_VERSION :: 1 -KHR_PRESENT_ID_EXTENSION_NAME :: "VK_KHR_present_id" -KHR_video_encode_queue :: 1 -KHR_VIDEO_ENCODE_QUEUE_SPEC_VERSION :: 12 -KHR_VIDEO_ENCODE_QUEUE_EXTENSION_NAME :: "VK_KHR_video_encode_queue" -KHR_synchronization2 :: 1 -KHR_SYNCHRONIZATION_2_SPEC_VERSION :: 1 -KHR_SYNCHRONIZATION_2_EXTENSION_NAME :: "VK_KHR_synchronization2" -KHR_fragment_shader_barycentric :: 1 -KHR_FRAGMENT_SHADER_BARYCENTRIC_SPEC_VERSION :: 1 -KHR_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME :: "VK_KHR_fragment_shader_barycentric" -KHR_shader_subgroup_uniform_control_flow :: 1 -KHR_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_SPEC_VERSION :: 1 -KHR_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_EXTENSION_NAME :: "VK_KHR_shader_subgroup_uniform_control_flow" -KHR_zero_initialize_workgroup_memory :: 1 -KHR_ZERO_INITIALIZE_WORKGROUP_MEMORY_SPEC_VERSION :: 1 -KHR_ZERO_INITIALIZE_WORKGROUP_MEMORY_EXTENSION_NAME :: "VK_KHR_zero_initialize_workgroup_memory" -KHR_workgroup_memory_explicit_layout :: 1 -KHR_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_SPEC_VERSION :: 1 -KHR_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_EXTENSION_NAME :: "VK_KHR_workgroup_memory_explicit_layout" -KHR_copy_commands2 :: 1 -KHR_COPY_COMMANDS_2_SPEC_VERSION :: 1 -KHR_COPY_COMMANDS_2_EXTENSION_NAME :: "VK_KHR_copy_commands2" -KHR_format_feature_flags2 :: 1 -KHR_FORMAT_FEATURE_FLAGS_2_SPEC_VERSION :: 2 -KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME :: "VK_KHR_format_feature_flags2" -KHR_ray_tracing_maintenance1 :: 1 -KHR_RAY_TRACING_MAINTENANCE_1_SPEC_VERSION :: 1 -KHR_RAY_TRACING_MAINTENANCE_1_EXTENSION_NAME :: "VK_KHR_ray_tracing_maintenance1" -KHR_portability_enumeration :: 1 -KHR_PORTABILITY_ENUMERATION_SPEC_VERSION :: 1 -KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME :: "VK_KHR_portability_enumeration" -KHR_maintenance4 :: 1 -KHR_MAINTENANCE_4_SPEC_VERSION :: 2 -KHR_MAINTENANCE_4_EXTENSION_NAME :: "VK_KHR_maintenance4" -KHR_shader_subgroup_rotate :: 1 -KHR_SHADER_SUBGROUP_ROTATE_SPEC_VERSION :: 2 -KHR_SHADER_SUBGROUP_ROTATE_EXTENSION_NAME :: "VK_KHR_shader_subgroup_rotate" -KHR_shader_maximal_reconvergence :: 1 -KHR_SHADER_MAXIMAL_RECONVERGENCE_SPEC_VERSION :: 1 -KHR_SHADER_MAXIMAL_RECONVERGENCE_EXTENSION_NAME :: "VK_KHR_shader_maximal_reconvergence" -KHR_maintenance5 :: 1 -KHR_MAINTENANCE_5_SPEC_VERSION :: 1 -KHR_MAINTENANCE_5_EXTENSION_NAME :: "VK_KHR_maintenance5" -KHR_ray_tracing_position_fetch :: 1 -KHR_RAY_TRACING_POSITION_FETCH_SPEC_VERSION :: 1 -KHR_RAY_TRACING_POSITION_FETCH_EXTENSION_NAME :: "VK_KHR_ray_tracing_position_fetch" -KHR_pipeline_binary :: 1 -MAX_PIPELINE_BINARY_KEY_SIZE_KHR :: 32 -KHR_PIPELINE_BINARY_SPEC_VERSION :: 1 -KHR_PIPELINE_BINARY_EXTENSION_NAME :: "VK_KHR_pipeline_binary" -KHR_cooperative_matrix :: 1 -KHR_COOPERATIVE_MATRIX_SPEC_VERSION :: 2 -KHR_COOPERATIVE_MATRIX_EXTENSION_NAME :: "VK_KHR_cooperative_matrix" -KHR_compute_shader_derivatives :: 1 -KHR_COMPUTE_SHADER_DERIVATIVES_SPEC_VERSION :: 1 -KHR_COMPUTE_SHADER_DERIVATIVES_EXTENSION_NAME :: "VK_KHR_compute_shader_derivatives" -KHR_video_decode_av1 :: 1 -MAX_VIDEO_AV1_REFERENCES_PER_FRAME_KHR :: 7 -KHR_VIDEO_DECODE_AV1_SPEC_VERSION :: 1 -KHR_VIDEO_DECODE_AV1_EXTENSION_NAME :: "VK_KHR_video_decode_av1" -KHR_video_encode_av1 :: 1 -KHR_VIDEO_ENCODE_AV1_SPEC_VERSION :: 1 -KHR_VIDEO_ENCODE_AV1_EXTENSION_NAME :: "VK_KHR_video_encode_av1" -KHR_video_maintenance1 :: 1 -KHR_VIDEO_MAINTENANCE_1_SPEC_VERSION :: 1 -KHR_VIDEO_MAINTENANCE_1_EXTENSION_NAME :: "VK_KHR_video_maintenance1" -KHR_vertex_attribute_divisor :: 1 -KHR_VERTEX_ATTRIBUTE_DIVISOR_SPEC_VERSION :: 1 -KHR_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME :: "VK_KHR_vertex_attribute_divisor" -KHR_load_store_op_none :: 1 -KHR_LOAD_STORE_OP_NONE_SPEC_VERSION :: 1 -KHR_LOAD_STORE_OP_NONE_EXTENSION_NAME :: "VK_KHR_load_store_op_none" -KHR_shader_float_controls2 :: 1 -KHR_SHADER_FLOAT_CONTROLS_2_SPEC_VERSION :: 1 -KHR_SHADER_FLOAT_CONTROLS_2_EXTENSION_NAME :: "VK_KHR_shader_float_controls2" -KHR_index_type_uint8 :: 1 -KHR_INDEX_TYPE_UINT8_SPEC_VERSION :: 1 -KHR_INDEX_TYPE_UINT8_EXTENSION_NAME :: "VK_KHR_index_type_uint8" -KHR_line_rasterization :: 1 -KHR_LINE_RASTERIZATION_SPEC_VERSION :: 1 -KHR_LINE_RASTERIZATION_EXTENSION_NAME :: "VK_KHR_line_rasterization" -KHR_calibrated_timestamps :: 1 -KHR_CALIBRATED_TIMESTAMPS_SPEC_VERSION :: 1 -KHR_CALIBRATED_TIMESTAMPS_EXTENSION_NAME :: "VK_KHR_calibrated_timestamps" -KHR_shader_expect_assume :: 1 -KHR_SHADER_EXPECT_ASSUME_SPEC_VERSION :: 1 -KHR_SHADER_EXPECT_ASSUME_EXTENSION_NAME :: "VK_KHR_shader_expect_assume" -KHR_maintenance6 :: 1 -KHR_MAINTENANCE_6_SPEC_VERSION :: 1 -KHR_MAINTENANCE_6_EXTENSION_NAME :: "VK_KHR_maintenance6" -KHR_video_encode_quantization_map :: 1 -KHR_VIDEO_ENCODE_QUANTIZATION_MAP_SPEC_VERSION :: 2 -KHR_VIDEO_ENCODE_QUANTIZATION_MAP_EXTENSION_NAME :: "VK_KHR_video_encode_quantization_map" -KHR_shader_relaxed_extended_instruction :: 1 -KHR_SHADER_RELAXED_EXTENDED_INSTRUCTION_SPEC_VERSION :: 1 -KHR_SHADER_RELAXED_EXTENDED_INSTRUCTION_EXTENSION_NAME :: "VK_KHR_shader_relaxed_extended_instruction" -KHR_maintenance7 :: 1 -KHR_MAINTENANCE_7_SPEC_VERSION :: 1 -KHR_MAINTENANCE_7_EXTENSION_NAME :: "VK_KHR_maintenance7" -KHR_maintenance8 :: 1 -KHR_MAINTENANCE_8_SPEC_VERSION :: 1 -KHR_MAINTENANCE_8_EXTENSION_NAME :: "VK_KHR_maintenance8" -KHR_video_maintenance2 :: 1 -KHR_VIDEO_MAINTENANCE_2_SPEC_VERSION :: 1 -KHR_VIDEO_MAINTENANCE_2_EXTENSION_NAME :: "VK_KHR_video_maintenance2" -KHR_depth_clamp_zero_one :: 1 -KHR_DEPTH_CLAMP_ZERO_ONE_SPEC_VERSION :: 1 -KHR_DEPTH_CLAMP_ZERO_ONE_EXTENSION_NAME :: "VK_KHR_depth_clamp_zero_one" -EXT_debug_report :: 1 -EXT_DEBUG_REPORT_SPEC_VERSION :: 10 -EXT_DEBUG_REPORT_EXTENSION_NAME :: "VK_EXT_debug_report" -NV_glsl_shader :: 1 -NV_GLSL_SHADER_SPEC_VERSION :: 1 -NV_GLSL_SHADER_EXTENSION_NAME :: "VK_NV_glsl_shader" -EXT_depth_range_unrestricted :: 1 -EXT_DEPTH_RANGE_UNRESTRICTED_SPEC_VERSION :: 1 -EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME :: "VK_EXT_depth_range_unrestricted" -AMD_rasterization_order :: 1 -AMD_RASTERIZATION_ORDER_SPEC_VERSION :: 1 -AMD_RASTERIZATION_ORDER_EXTENSION_NAME :: "VK_AMD_rasterization_order" -AMD_shader_trinary_minmax :: 1 -AMD_SHADER_TRINARY_MINMAX_SPEC_VERSION :: 1 -AMD_SHADER_TRINARY_MINMAX_EXTENSION_NAME :: "VK_AMD_shader_trinary_minmax" -AMD_shader_explicit_vertex_parameter :: 1 -AMD_SHADER_EXPLICIT_VERTEX_PARAMETER_SPEC_VERSION :: 1 -AMD_SHADER_EXPLICIT_VERTEX_PARAMETER_EXTENSION_NAME :: "VK_AMD_shader_explicit_vertex_parameter" -EXT_debug_marker :: 1 -EXT_DEBUG_MARKER_SPEC_VERSION :: 4 -EXT_DEBUG_MARKER_EXTENSION_NAME :: "VK_EXT_debug_marker" -AMD_gcn_shader :: 1 -AMD_GCN_SHADER_SPEC_VERSION :: 1 -AMD_GCN_SHADER_EXTENSION_NAME :: "VK_AMD_gcn_shader" -NV_dedicated_allocation :: 1 -NV_DEDICATED_ALLOCATION_SPEC_VERSION :: 1 -NV_DEDICATED_ALLOCATION_EXTENSION_NAME :: "VK_NV_dedicated_allocation" -EXT_transform_feedback :: 1 -EXT_TRANSFORM_FEEDBACK_SPEC_VERSION :: 1 -EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME :: "VK_EXT_transform_feedback" -NVX_binary_import :: 1 -NVX_BINARY_IMPORT_SPEC_VERSION :: 2 -NVX_BINARY_IMPORT_EXTENSION_NAME :: "VK_NVX_binary_import" -NVX_image_view_handle :: 1 -NVX_IMAGE_VIEW_HANDLE_SPEC_VERSION :: 3 -NVX_IMAGE_VIEW_HANDLE_EXTENSION_NAME :: "VK_NVX_image_view_handle" -AMD_draw_indirect_count :: 1 -AMD_DRAW_INDIRECT_COUNT_SPEC_VERSION :: 2 -AMD_DRAW_INDIRECT_COUNT_EXTENSION_NAME :: "VK_AMD_draw_indirect_count" -AMD_negative_viewport_height :: 1 -AMD_NEGATIVE_VIEWPORT_HEIGHT_SPEC_VERSION :: 1 -AMD_NEGATIVE_VIEWPORT_HEIGHT_EXTENSION_NAME :: "VK_AMD_negative_viewport_height" -AMD_gpu_shader_half_float :: 1 -AMD_GPU_SHADER_HALF_FLOAT_SPEC_VERSION :: 2 -AMD_GPU_SHADER_HALF_FLOAT_EXTENSION_NAME :: "VK_AMD_gpu_shader_half_float" -AMD_shader_ballot :: 1 -AMD_SHADER_BALLOT_SPEC_VERSION :: 1 -AMD_SHADER_BALLOT_EXTENSION_NAME :: "VK_AMD_shader_ballot" -AMD_texture_gather_bias_lod :: 1 -AMD_TEXTURE_GATHER_BIAS_LOD_SPEC_VERSION :: 1 -AMD_TEXTURE_GATHER_BIAS_LOD_EXTENSION_NAME :: "VK_AMD_texture_gather_bias_lod" -AMD_shader_info :: 1 -AMD_SHADER_INFO_SPEC_VERSION :: 1 -AMD_SHADER_INFO_EXTENSION_NAME :: "VK_AMD_shader_info" -AMD_shader_image_load_store_lod :: 1 -AMD_SHADER_IMAGE_LOAD_STORE_LOD_SPEC_VERSION :: 1 -AMD_SHADER_IMAGE_LOAD_STORE_LOD_EXTENSION_NAME :: "VK_AMD_shader_image_load_store_lod" -NV_corner_sampled_image :: 1 -NV_CORNER_SAMPLED_IMAGE_SPEC_VERSION :: 2 -NV_CORNER_SAMPLED_IMAGE_EXTENSION_NAME :: "VK_NV_corner_sampled_image" -NV_external_memory_capabilities :: 1 -NV_EXTERNAL_MEMORY_CAPABILITIES_SPEC_VERSION :: 1 -NV_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME :: "VK_NV_external_memory_capabilities" -NV_external_memory :: 1 -NV_EXTERNAL_MEMORY_SPEC_VERSION :: 1 -NV_EXTERNAL_MEMORY_EXTENSION_NAME :: "VK_NV_external_memory" -EXT_validation_flags :: 1 -EXT_VALIDATION_FLAGS_SPEC_VERSION :: 3 -EXT_VALIDATION_FLAGS_EXTENSION_NAME :: "VK_EXT_validation_flags" -EXT_shader_subgroup_ballot :: 1 -EXT_SHADER_SUBGROUP_BALLOT_SPEC_VERSION :: 1 -EXT_SHADER_SUBGROUP_BALLOT_EXTENSION_NAME :: "VK_EXT_shader_subgroup_ballot" -EXT_shader_subgroup_vote :: 1 -EXT_SHADER_SUBGROUP_VOTE_SPEC_VERSION :: 1 -EXT_SHADER_SUBGROUP_VOTE_EXTENSION_NAME :: "VK_EXT_shader_subgroup_vote" -EXT_texture_compression_astc_hdr :: 1 -EXT_TEXTURE_COMPRESSION_ASTC_HDR_SPEC_VERSION :: 1 -EXT_TEXTURE_COMPRESSION_ASTC_HDR_EXTENSION_NAME :: "VK_EXT_texture_compression_astc_hdr" -EXT_astc_decode_mode :: 1 -EXT_ASTC_DECODE_MODE_SPEC_VERSION :: 1 -EXT_ASTC_DECODE_MODE_EXTENSION_NAME :: "VK_EXT_astc_decode_mode" -EXT_pipeline_robustness :: 1 -EXT_PIPELINE_ROBUSTNESS_SPEC_VERSION :: 1 -EXT_PIPELINE_ROBUSTNESS_EXTENSION_NAME :: "VK_EXT_pipeline_robustness" -EXT_conditional_rendering :: 1 -EXT_CONDITIONAL_RENDERING_SPEC_VERSION :: 2 -EXT_CONDITIONAL_RENDERING_EXTENSION_NAME :: "VK_EXT_conditional_rendering" -NV_clip_space_w_scaling :: 1 -NV_CLIP_SPACE_W_SCALING_SPEC_VERSION :: 1 -NV_CLIP_SPACE_W_SCALING_EXTENSION_NAME :: "VK_NV_clip_space_w_scaling" -EXT_direct_mode_display :: 1 -EXT_DIRECT_MODE_DISPLAY_SPEC_VERSION :: 1 -EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME :: "VK_EXT_direct_mode_display" -EXT_display_surface_counter :: 1 -EXT_DISPLAY_SURFACE_COUNTER_SPEC_VERSION :: 1 -EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME :: "VK_EXT_display_surface_counter" -EXT_display_control :: 1 -EXT_DISPLAY_CONTROL_SPEC_VERSION :: 1 -EXT_DISPLAY_CONTROL_EXTENSION_NAME :: "VK_EXT_display_control" -GOOGLE_display_timing :: 1 -GOOGLE_DISPLAY_TIMING_SPEC_VERSION :: 1 -GOOGLE_DISPLAY_TIMING_EXTENSION_NAME :: "VK_GOOGLE_display_timing" -NV_sample_mask_override_coverage :: 1 -NV_SAMPLE_MASK_OVERRIDE_COVERAGE_SPEC_VERSION :: 1 -NV_SAMPLE_MASK_OVERRIDE_COVERAGE_EXTENSION_NAME :: "VK_NV_sample_mask_override_coverage" -NV_geometry_shader_passthrough :: 1 -NV_GEOMETRY_SHADER_PASSTHROUGH_SPEC_VERSION :: 1 -NV_GEOMETRY_SHADER_PASSTHROUGH_EXTENSION_NAME :: "VK_NV_geometry_shader_passthrough" -NV_viewport_array2 :: 1 -NV_VIEWPORT_ARRAY_2_SPEC_VERSION :: 1 -NV_VIEWPORT_ARRAY_2_EXTENSION_NAME :: "VK_NV_viewport_array2" -NV_VIEWPORT_ARRAY2_SPEC_VERSION :: NV_VIEWPORT_ARRAY_2_SPEC_VERSION -NV_VIEWPORT_ARRAY2_EXTENSION_NAME :: NV_VIEWPORT_ARRAY_2_EXTENSION_NAME -NVX_multiview_per_view_attributes :: 1 -NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES_SPEC_VERSION :: 1 -NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES_EXTENSION_NAME :: "VK_NVX_multiview_per_view_attributes" -NV_viewport_swizzle :: 1 -NV_VIEWPORT_SWIZZLE_SPEC_VERSION :: 1 -NV_VIEWPORT_SWIZZLE_EXTENSION_NAME :: "VK_NV_viewport_swizzle" -EXT_discard_rectangles :: 1 -EXT_DISCARD_RECTANGLES_SPEC_VERSION :: 2 -EXT_DISCARD_RECTANGLES_EXTENSION_NAME :: "VK_EXT_discard_rectangles" -EXT_conservative_rasterization :: 1 -EXT_CONSERVATIVE_RASTERIZATION_SPEC_VERSION :: 1 -EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME :: "VK_EXT_conservative_rasterization" -EXT_depth_clip_enable :: 1 -EXT_DEPTH_CLIP_ENABLE_SPEC_VERSION :: 1 -EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME :: "VK_EXT_depth_clip_enable" -EXT_swapchain_colorspace :: 1 -EXT_SWAPCHAIN_COLOR_SPACE_SPEC_VERSION :: 5 -EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME :: "VK_EXT_swapchain_colorspace" -EXT_hdr_metadata :: 1 -EXT_HDR_METADATA_SPEC_VERSION :: 3 -EXT_HDR_METADATA_EXTENSION_NAME :: "VK_EXT_hdr_metadata" -EXT_external_memory_dma_buf :: 1 -EXT_EXTERNAL_MEMORY_DMA_BUF_SPEC_VERSION :: 1 -EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME :: "VK_EXT_external_memory_dma_buf" -EXT_queue_family_foreign :: 1 -EXT_QUEUE_FAMILY_FOREIGN_SPEC_VERSION :: 1 -EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME :: "VK_EXT_queue_family_foreign" -EXT_debug_utils :: 1 -EXT_DEBUG_UTILS_SPEC_VERSION :: 2 -EXT_DEBUG_UTILS_EXTENSION_NAME :: "VK_EXT_debug_utils" -EXT_sampler_filter_minmax :: 1 -EXT_SAMPLER_FILTER_MINMAX_SPEC_VERSION :: 2 -EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME :: "VK_EXT_sampler_filter_minmax" -AMD_gpu_shader_int16 :: 1 -AMD_GPU_SHADER_INT16_SPEC_VERSION :: 2 -AMD_GPU_SHADER_INT16_EXTENSION_NAME :: "VK_AMD_gpu_shader_int16" -AMD_mixed_attachment_samples :: 1 -AMD_MIXED_ATTACHMENT_SAMPLES_SPEC_VERSION :: 1 -AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME :: "VK_AMD_mixed_attachment_samples" -AMD_shader_fragment_mask :: 1 -AMD_SHADER_FRAGMENT_MASK_SPEC_VERSION :: 1 -AMD_SHADER_FRAGMENT_MASK_EXTENSION_NAME :: "VK_AMD_shader_fragment_mask" -EXT_inline_uniform_block :: 1 -EXT_INLINE_UNIFORM_BLOCK_SPEC_VERSION :: 1 -EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME :: "VK_EXT_inline_uniform_block" -EXT_shader_stencil_export :: 1 -EXT_SHADER_STENCIL_EXPORT_SPEC_VERSION :: 1 -EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME :: "VK_EXT_shader_stencil_export" -EXT_sample_locations :: 1 -EXT_SAMPLE_LOCATIONS_SPEC_VERSION :: 1 -EXT_SAMPLE_LOCATIONS_EXTENSION_NAME :: "VK_EXT_sample_locations" -EXT_blend_operation_advanced :: 1 -EXT_BLEND_OPERATION_ADVANCED_SPEC_VERSION :: 2 -EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME :: "VK_EXT_blend_operation_advanced" -NV_fragment_coverage_to_color :: 1 -NV_FRAGMENT_COVERAGE_TO_COLOR_SPEC_VERSION :: 1 -NV_FRAGMENT_COVERAGE_TO_COLOR_EXTENSION_NAME :: "VK_NV_fragment_coverage_to_color" -NV_framebuffer_mixed_samples :: 1 -NV_FRAMEBUFFER_MIXED_SAMPLES_SPEC_VERSION :: 1 -NV_FRAMEBUFFER_MIXED_SAMPLES_EXTENSION_NAME :: "VK_NV_framebuffer_mixed_samples" -NV_fill_rectangle :: 1 -NV_FILL_RECTANGLE_SPEC_VERSION :: 1 -NV_FILL_RECTANGLE_EXTENSION_NAME :: "VK_NV_fill_rectangle" -NV_shader_sm_builtins :: 1 -NV_SHADER_SM_BUILTINS_SPEC_VERSION :: 1 -NV_SHADER_SM_BUILTINS_EXTENSION_NAME :: "VK_NV_shader_sm_builtins" -EXT_post_depth_coverage :: 1 -EXT_POST_DEPTH_COVERAGE_SPEC_VERSION :: 1 -EXT_POST_DEPTH_COVERAGE_EXTENSION_NAME :: "VK_EXT_post_depth_coverage" -EXT_image_drm_format_modifier :: 1 -EXT_IMAGE_DRM_FORMAT_MODIFIER_SPEC_VERSION :: 2 -EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME :: "VK_EXT_image_drm_format_modifier" -EXT_validation_cache :: 1 -EXT_VALIDATION_CACHE_SPEC_VERSION :: 1 -EXT_VALIDATION_CACHE_EXTENSION_NAME :: "VK_EXT_validation_cache" -EXT_descriptor_indexing :: 1 -EXT_DESCRIPTOR_INDEXING_SPEC_VERSION :: 2 -EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME :: "VK_EXT_descriptor_indexing" -EXT_shader_viewport_index_layer :: 1 -EXT_SHADER_VIEWPORT_INDEX_LAYER_SPEC_VERSION :: 1 -EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME :: "VK_EXT_shader_viewport_index_layer" -NV_shading_rate_image :: 1 -NV_SHADING_RATE_IMAGE_SPEC_VERSION :: 3 -NV_SHADING_RATE_IMAGE_EXTENSION_NAME :: "VK_NV_shading_rate_image" -NV_ray_tracing :: 1 -NV_RAY_TRACING_SPEC_VERSION :: 3 -NV_RAY_TRACING_EXTENSION_NAME :: "VK_NV_ray_tracing" -SHADER_UNUSED_KHR :: 0 -NV_representative_fragment_test :: 1 -NV_REPRESENTATIVE_FRAGMENT_TEST_SPEC_VERSION :: 2 -NV_REPRESENTATIVE_FRAGMENT_TEST_EXTENSION_NAME :: "VK_NV_representative_fragment_test" -EXT_filter_cubic :: 1 -EXT_FILTER_CUBIC_SPEC_VERSION :: 3 -EXT_FILTER_CUBIC_EXTENSION_NAME :: "VK_EXT_filter_cubic" -EXT_global_priority :: 1 -EXT_GLOBAL_PRIORITY_SPEC_VERSION :: 2 -EXT_GLOBAL_PRIORITY_EXTENSION_NAME :: "VK_EXT_global_priority" -EXT_external_memory_host :: 1 -EXT_EXTERNAL_MEMORY_HOST_SPEC_VERSION :: 1 -EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME :: "VK_EXT_external_memory_host" -AMD_buffer_marker :: 1 -AMD_BUFFER_MARKER_SPEC_VERSION :: 1 -AMD_BUFFER_MARKER_EXTENSION_NAME :: "VK_AMD_buffer_marker" -AMD_pipeline_compiler_control :: 1 -AMD_PIPELINE_COMPILER_CONTROL_SPEC_VERSION :: 1 -AMD_PIPELINE_COMPILER_CONTROL_EXTENSION_NAME :: "VK_AMD_pipeline_compiler_control" -EXT_calibrated_timestamps :: 1 -EXT_CALIBRATED_TIMESTAMPS_SPEC_VERSION :: 2 -EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME :: "VK_EXT_calibrated_timestamps" -AMD_shader_core_properties :: 1 -AMD_SHADER_CORE_PROPERTIES_SPEC_VERSION :: 2 -AMD_SHADER_CORE_PROPERTIES_EXTENSION_NAME :: "VK_AMD_shader_core_properties" -AMD_memory_overallocation_behavior :: 1 -AMD_MEMORY_OVERALLOCATION_BEHAVIOR_SPEC_VERSION :: 1 -AMD_MEMORY_OVERALLOCATION_BEHAVIOR_EXTENSION_NAME :: "VK_AMD_memory_overallocation_behavior" -EXT_vertex_attribute_divisor :: 1 -EXT_VERTEX_ATTRIBUTE_DIVISOR_SPEC_VERSION :: 3 -EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME :: "VK_EXT_vertex_attribute_divisor" -EXT_pipeline_creation_feedback :: 1 -EXT_PIPELINE_CREATION_FEEDBACK_SPEC_VERSION :: 1 -EXT_PIPELINE_CREATION_FEEDBACK_EXTENSION_NAME :: "VK_EXT_pipeline_creation_feedback" -NV_shader_subgroup_partitioned :: 1 -NV_SHADER_SUBGROUP_PARTITIONED_SPEC_VERSION :: 1 -NV_SHADER_SUBGROUP_PARTITIONED_EXTENSION_NAME :: "VK_NV_shader_subgroup_partitioned" -NV_compute_shader_derivatives :: 1 -NV_COMPUTE_SHADER_DERIVATIVES_SPEC_VERSION :: 1 -NV_COMPUTE_SHADER_DERIVATIVES_EXTENSION_NAME :: "VK_NV_compute_shader_derivatives" -NV_mesh_shader :: 1 -NV_MESH_SHADER_SPEC_VERSION :: 1 -NV_MESH_SHADER_EXTENSION_NAME :: "VK_NV_mesh_shader" -NV_fragment_shader_barycentric :: 1 -NV_FRAGMENT_SHADER_BARYCENTRIC_SPEC_VERSION :: 1 -NV_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME :: "VK_NV_fragment_shader_barycentric" -NV_shader_image_footprint :: 1 -NV_SHADER_IMAGE_FOOTPRINT_SPEC_VERSION :: 2 -NV_SHADER_IMAGE_FOOTPRINT_EXTENSION_NAME :: "VK_NV_shader_image_footprint" -NV_scissor_exclusive :: 1 -NV_SCISSOR_EXCLUSIVE_SPEC_VERSION :: 2 -NV_SCISSOR_EXCLUSIVE_EXTENSION_NAME :: "VK_NV_scissor_exclusive" -NV_device_diagnostic_checkpoints :: 1 -NV_DEVICE_DIAGNOSTIC_CHECKPOINTS_SPEC_VERSION :: 2 -NV_DEVICE_DIAGNOSTIC_CHECKPOINTS_EXTENSION_NAME :: "VK_NV_device_diagnostic_checkpoints" -EXT_pci_bus_info :: 1 -EXT_PCI_BUS_INFO_SPEC_VERSION :: 2 -EXT_PCI_BUS_INFO_EXTENSION_NAME :: "VK_EXT_pci_bus_info" -AMD_display_native_hdr :: 1 -AMD_DISPLAY_NATIVE_HDR_SPEC_VERSION :: 1 -AMD_DISPLAY_NATIVE_HDR_EXTENSION_NAME :: "VK_AMD_display_native_hdr" -EXT_fragment_density_map :: 1 -EXT_FRAGMENT_DENSITY_MAP_SPEC_VERSION :: 2 -EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME :: "VK_EXT_fragment_density_map" -EXT_scalar_block_layout :: 1 -EXT_SCALAR_BLOCK_LAYOUT_SPEC_VERSION :: 1 -EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME :: "VK_EXT_scalar_block_layout" -GOOGLE_hlsl_functionality1 :: 1 -GOOGLE_HLSL_FUNCTIONALITY_1_SPEC_VERSION :: 1 -GOOGLE_HLSL_FUNCTIONALITY_1_EXTENSION_NAME :: "VK_GOOGLE_hlsl_functionality1" -GOOGLE_HLSL_FUNCTIONALITY1_SPEC_VERSION :: GOOGLE_HLSL_FUNCTIONALITY_1_SPEC_VERSION -GOOGLE_HLSL_FUNCTIONALITY1_EXTENSION_NAME :: GOOGLE_HLSL_FUNCTIONALITY_1_EXTENSION_NAME -GOOGLE_decorate_string :: 1 -GOOGLE_DECORATE_STRING_SPEC_VERSION :: 1 -GOOGLE_DECORATE_STRING_EXTENSION_NAME :: "VK_GOOGLE_decorate_string" -EXT_subgroup_size_control :: 1 -EXT_SUBGROUP_SIZE_CONTROL_SPEC_VERSION :: 2 -EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME :: "VK_EXT_subgroup_size_control" -AMD_shader_core_properties2 :: 1 -AMD_SHADER_CORE_PROPERTIES_2_SPEC_VERSION :: 1 -AMD_SHADER_CORE_PROPERTIES_2_EXTENSION_NAME :: "VK_AMD_shader_core_properties2" -AMD_device_coherent_memory :: 1 -AMD_DEVICE_COHERENT_MEMORY_SPEC_VERSION :: 1 -AMD_DEVICE_COHERENT_MEMORY_EXTENSION_NAME :: "VK_AMD_device_coherent_memory" -EXT_shader_image_atomic_int64 :: 1 -EXT_SHADER_IMAGE_ATOMIC_INT64_SPEC_VERSION :: 1 -EXT_SHADER_IMAGE_ATOMIC_INT64_EXTENSION_NAME :: "VK_EXT_shader_image_atomic_int64" -EXT_memory_budget :: 1 -EXT_MEMORY_BUDGET_SPEC_VERSION :: 1 -EXT_MEMORY_BUDGET_EXTENSION_NAME :: "VK_EXT_memory_budget" -EXT_memory_priority :: 1 -EXT_MEMORY_PRIORITY_SPEC_VERSION :: 1 -EXT_MEMORY_PRIORITY_EXTENSION_NAME :: "VK_EXT_memory_priority" -NV_dedicated_allocation_image_aliasing :: 1 -NV_DEDICATED_ALLOCATION_IMAGE_ALIASING_SPEC_VERSION :: 1 -NV_DEDICATED_ALLOCATION_IMAGE_ALIASING_EXTENSION_NAME :: "VK_NV_dedicated_allocation_image_aliasing" -EXT_buffer_device_address :: 1 -EXT_BUFFER_DEVICE_ADDRESS_SPEC_VERSION :: 2 -EXT_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME :: "VK_EXT_buffer_device_address" -EXT_tooling_info :: 1 -EXT_TOOLING_INFO_SPEC_VERSION :: 1 -EXT_TOOLING_INFO_EXTENSION_NAME :: "VK_EXT_tooling_info" -EXT_separate_stencil_usage :: 1 -EXT_SEPARATE_STENCIL_USAGE_SPEC_VERSION :: 1 -EXT_SEPARATE_STENCIL_USAGE_EXTENSION_NAME :: "VK_EXT_separate_stencil_usage" -EXT_validation_features :: 1 -EXT_VALIDATION_FEATURES_SPEC_VERSION :: 6 -EXT_VALIDATION_FEATURES_EXTENSION_NAME :: "VK_EXT_validation_features" -NV_cooperative_matrix :: 1 -NV_COOPERATIVE_MATRIX_SPEC_VERSION :: 1 -NV_COOPERATIVE_MATRIX_EXTENSION_NAME :: "VK_NV_cooperative_matrix" -NV_coverage_reduction_mode :: 1 -NV_COVERAGE_REDUCTION_MODE_SPEC_VERSION :: 1 -NV_COVERAGE_REDUCTION_MODE_EXTENSION_NAME :: "VK_NV_coverage_reduction_mode" -EXT_fragment_shader_interlock :: 1 -EXT_FRAGMENT_SHADER_INTERLOCK_SPEC_VERSION :: 1 -EXT_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME :: "VK_EXT_fragment_shader_interlock" -EXT_ycbcr_image_arrays :: 1 -EXT_YCBCR_IMAGE_ARRAYS_SPEC_VERSION :: 1 -EXT_YCBCR_IMAGE_ARRAYS_EXTENSION_NAME :: "VK_EXT_ycbcr_image_arrays" -EXT_provoking_vertex :: 1 -EXT_PROVOKING_VERTEX_SPEC_VERSION :: 1 -EXT_PROVOKING_VERTEX_EXTENSION_NAME :: "VK_EXT_provoking_vertex" -EXT_headless_surface :: 1 -EXT_HEADLESS_SURFACE_SPEC_VERSION :: 1 -EXT_HEADLESS_SURFACE_EXTENSION_NAME :: "VK_EXT_headless_surface" -EXT_line_rasterization :: 1 -EXT_LINE_RASTERIZATION_SPEC_VERSION :: 1 -EXT_LINE_RASTERIZATION_EXTENSION_NAME :: "VK_EXT_line_rasterization" -EXT_shader_atomic_float :: 1 -EXT_SHADER_ATOMIC_FLOAT_SPEC_VERSION :: 1 -EXT_SHADER_ATOMIC_FLOAT_EXTENSION_NAME :: "VK_EXT_shader_atomic_float" -EXT_host_query_reset :: 1 -EXT_HOST_QUERY_RESET_SPEC_VERSION :: 1 -EXT_HOST_QUERY_RESET_EXTENSION_NAME :: "VK_EXT_host_query_reset" -EXT_index_type_uint8 :: 1 -EXT_INDEX_TYPE_UINT8_SPEC_VERSION :: 1 -EXT_INDEX_TYPE_UINT8_EXTENSION_NAME :: "VK_EXT_index_type_uint8" -EXT_extended_dynamic_state :: 1 -EXT_EXTENDED_DYNAMIC_STATE_SPEC_VERSION :: 1 -EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME :: "VK_EXT_extended_dynamic_state" -EXT_host_image_copy :: 1 -EXT_HOST_IMAGE_COPY_SPEC_VERSION :: 1 -EXT_HOST_IMAGE_COPY_EXTENSION_NAME :: "VK_EXT_host_image_copy" -EXT_map_memory_placed :: 1 -EXT_MAP_MEMORY_PLACED_SPEC_VERSION :: 1 -EXT_MAP_MEMORY_PLACED_EXTENSION_NAME :: "VK_EXT_map_memory_placed" -EXT_shader_atomic_float2 :: 1 -EXT_SHADER_ATOMIC_FLOAT_2_SPEC_VERSION :: 1 -EXT_SHADER_ATOMIC_FLOAT_2_EXTENSION_NAME :: "VK_EXT_shader_atomic_float2" -EXT_surface_maintenance1 :: 1 -EXT_SURFACE_MAINTENANCE_1_SPEC_VERSION :: 1 -EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME :: "VK_EXT_surface_maintenance1" -EXT_swapchain_maintenance1 :: 1 -EXT_SWAPCHAIN_MAINTENANCE_1_SPEC_VERSION :: 1 -EXT_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME :: "VK_EXT_swapchain_maintenance1" -EXT_shader_demote_to_helper_invocation :: 1 -EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_SPEC_VERSION :: 1 -EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME :: "VK_EXT_shader_demote_to_helper_invocation" -NV_device_generated_commands :: 1 -NV_DEVICE_GENERATED_COMMANDS_SPEC_VERSION :: 3 -NV_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME :: "VK_NV_device_generated_commands" -NV_inherited_viewport_scissor :: 1 -NV_INHERITED_VIEWPORT_SCISSOR_SPEC_VERSION :: 1 -NV_INHERITED_VIEWPORT_SCISSOR_EXTENSION_NAME :: "VK_NV_inherited_viewport_scissor" -EXT_texel_buffer_alignment :: 1 -EXT_TEXEL_BUFFER_ALIGNMENT_SPEC_VERSION :: 1 -EXT_TEXEL_BUFFER_ALIGNMENT_EXTENSION_NAME :: "VK_EXT_texel_buffer_alignment" -EXT_depth_bias_control :: 1 -EXT_DEPTH_BIAS_CONTROL_SPEC_VERSION :: 1 -EXT_DEPTH_BIAS_CONTROL_EXTENSION_NAME :: "VK_EXT_depth_bias_control" -EXT_device_memory_report :: 1 -EXT_DEVICE_MEMORY_REPORT_SPEC_VERSION :: 2 -EXT_DEVICE_MEMORY_REPORT_EXTENSION_NAME :: "VK_EXT_device_memory_report" -EXT_acquire_drm_display :: 1 -EXT_ACQUIRE_DRM_DISPLAY_SPEC_VERSION :: 1 -EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME :: "VK_EXT_acquire_drm_display" -EXT_robustness2 :: 1 -EXT_ROBUSTNESS_2_SPEC_VERSION :: 1 -EXT_ROBUSTNESS_2_EXTENSION_NAME :: "VK_EXT_robustness2" -EXT_custom_border_color :: 1 -EXT_CUSTOM_BORDER_COLOR_SPEC_VERSION :: 12 -EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME :: "VK_EXT_custom_border_color" -GOOGLE_user_type :: 1 -GOOGLE_USER_TYPE_SPEC_VERSION :: 1 -GOOGLE_USER_TYPE_EXTENSION_NAME :: "VK_GOOGLE_user_type" -NV_present_barrier :: 1 -NV_PRESENT_BARRIER_SPEC_VERSION :: 1 -NV_PRESENT_BARRIER_EXTENSION_NAME :: "VK_NV_present_barrier" -EXT_private_data :: 1 -EXT_PRIVATE_DATA_SPEC_VERSION :: 1 -EXT_PRIVATE_DATA_EXTENSION_NAME :: "VK_EXT_private_data" -EXT_pipeline_creation_cache_control :: 1 -EXT_PIPELINE_CREATION_CACHE_CONTROL_SPEC_VERSION :: 3 -EXT_PIPELINE_CREATION_CACHE_CONTROL_EXTENSION_NAME :: "VK_EXT_pipeline_creation_cache_control" -NV_device_diagnostics_config :: 1 -NV_DEVICE_DIAGNOSTICS_CONFIG_SPEC_VERSION :: 2 -NV_DEVICE_DIAGNOSTICS_CONFIG_EXTENSION_NAME :: "VK_NV_device_diagnostics_config" -NV_cuda_kernel_launch :: 1 -NV_CUDA_KERNEL_LAUNCH_SPEC_VERSION :: 2 -NV_CUDA_KERNEL_LAUNCH_EXTENSION_NAME :: "VK_NV_cuda_kernel_launch" -NV_low_latency :: 1 -NV_LOW_LATENCY_SPEC_VERSION :: 1 -NV_LOW_LATENCY_EXTENSION_NAME :: "VK_NV_low_latency" -EXT_descriptor_buffer :: 1 -EXT_DESCRIPTOR_BUFFER_SPEC_VERSION :: 1 -EXT_DESCRIPTOR_BUFFER_EXTENSION_NAME :: "VK_EXT_descriptor_buffer" -EXT_graphics_pipeline_library :: 1 -EXT_GRAPHICS_PIPELINE_LIBRARY_SPEC_VERSION :: 1 -EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME :: "VK_EXT_graphics_pipeline_library" -AMD_shader_early_and_late_fragment_tests :: 1 -AMD_SHADER_EARLY_AND_LATE_FRAGMENT_TESTS_SPEC_VERSION :: 1 -AMD_SHADER_EARLY_AND_LATE_FRAGMENT_TESTS_EXTENSION_NAME :: "VK_AMD_shader_early_and_late_fragment_tests" -NV_fragment_shading_rate_enums :: 1 -NV_FRAGMENT_SHADING_RATE_ENUMS_SPEC_VERSION :: 1 -NV_FRAGMENT_SHADING_RATE_ENUMS_EXTENSION_NAME :: "VK_NV_fragment_shading_rate_enums" -NV_ray_tracing_motion_blur :: 1 -NV_RAY_TRACING_MOTION_BLUR_SPEC_VERSION :: 1 -NV_RAY_TRACING_MOTION_BLUR_EXTENSION_NAME :: "VK_NV_ray_tracing_motion_blur" -EXT_ycbcr_2plane_444_formats :: 1 -EXT_YCBCR_2PLANE_444_FORMATS_SPEC_VERSION :: 1 -EXT_YCBCR_2PLANE_444_FORMATS_EXTENSION_NAME :: "VK_EXT_ycbcr_2plane_444_formats" -EXT_fragment_density_map2 :: 1 -EXT_FRAGMENT_DENSITY_MAP_2_SPEC_VERSION :: 1 -EXT_FRAGMENT_DENSITY_MAP_2_EXTENSION_NAME :: "VK_EXT_fragment_density_map2" -EXT_image_robustness :: 1 -EXT_IMAGE_ROBUSTNESS_SPEC_VERSION :: 1 -EXT_IMAGE_ROBUSTNESS_EXTENSION_NAME :: "VK_EXT_image_robustness" -EXT_image_compression_control :: 1 -EXT_IMAGE_COMPRESSION_CONTROL_SPEC_VERSION :: 1 -EXT_IMAGE_COMPRESSION_CONTROL_EXTENSION_NAME :: "VK_EXT_image_compression_control" -EXT_attachment_feedback_loop_layout :: 1 -EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_SPEC_VERSION :: 2 -EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_EXTENSION_NAME :: "VK_EXT_attachment_feedback_loop_layout" -EXT_4444_formats :: 1 -EXT_4444_FORMATS_SPEC_VERSION :: 1 -EXT_4444_FORMATS_EXTENSION_NAME :: "VK_EXT_4444_formats" -EXT_device_fault :: 1 -EXT_DEVICE_FAULT_SPEC_VERSION :: 2 -EXT_DEVICE_FAULT_EXTENSION_NAME :: "VK_EXT_device_fault" -EXT_rgba10x6_formats :: 1 -EXT_RGBA10X6_FORMATS_SPEC_VERSION :: 1 -EXT_RGBA10X6_FORMATS_EXTENSION_NAME :: "VK_EXT_rgba10x6_formats" -EXT_vertex_input_dynamic_state :: 1 -EXT_VERTEX_INPUT_DYNAMIC_STATE_SPEC_VERSION :: 2 -EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME :: "VK_EXT_vertex_input_dynamic_state" -EXT_physical_device_drm :: 1 -EXT_PHYSICAL_DEVICE_DRM_SPEC_VERSION :: 1 -EXT_PHYSICAL_DEVICE_DRM_EXTENSION_NAME :: "VK_EXT_physical_device_drm" -EXT_device_address_binding_report :: 1 -EXT_DEVICE_ADDRESS_BINDING_REPORT_SPEC_VERSION :: 1 -EXT_DEVICE_ADDRESS_BINDING_REPORT_EXTENSION_NAME :: "VK_EXT_device_address_binding_report" -EXT_depth_clip_control :: 1 -EXT_DEPTH_CLIP_CONTROL_SPEC_VERSION :: 1 -EXT_DEPTH_CLIP_CONTROL_EXTENSION_NAME :: "VK_EXT_depth_clip_control" -EXT_primitive_topology_list_restart :: 1 -EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_SPEC_VERSION :: 1 -EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_EXTENSION_NAME :: "VK_EXT_primitive_topology_list_restart" -EXT_present_mode_fifo_latest_ready :: 1 -EXT_PRESENT_MODE_FIFO_LATEST_READY_SPEC_VERSION :: 1 -EXT_PRESENT_MODE_FIFO_LATEST_READY_EXTENSION_NAME :: "VK_EXT_present_mode_fifo_latest_ready" -NV_external_memory_rdma :: 1 -NV_EXTERNAL_MEMORY_RDMA_SPEC_VERSION :: 1 -NV_EXTERNAL_MEMORY_RDMA_EXTENSION_NAME :: "VK_NV_external_memory_rdma" -EXT_pipeline_properties :: 1 -EXT_PIPELINE_PROPERTIES_SPEC_VERSION :: 1 -EXT_PIPELINE_PROPERTIES_EXTENSION_NAME :: "VK_EXT_pipeline_properties" -EXT_frame_boundary :: 1 -EXT_FRAME_BOUNDARY_SPEC_VERSION :: 1 -EXT_FRAME_BOUNDARY_EXTENSION_NAME :: "VK_EXT_frame_boundary" -EXT_multisampled_render_to_single_sampled :: 1 -EXT_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_SPEC_VERSION :: 1 -EXT_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_EXTENSION_NAME :: "VK_EXT_multisampled_render_to_single_sampled" -EXT_extended_dynamic_state2 :: 1 -EXT_EXTENDED_DYNAMIC_STATE_2_SPEC_VERSION :: 1 -EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME :: "VK_EXT_extended_dynamic_state2" -EXT_color_write_enable :: 1 -EXT_COLOR_WRITE_ENABLE_SPEC_VERSION :: 1 -EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME :: "VK_EXT_color_write_enable" -EXT_primitives_generated_query :: 1 -EXT_PRIMITIVES_GENERATED_QUERY_SPEC_VERSION :: 1 -EXT_PRIMITIVES_GENERATED_QUERY_EXTENSION_NAME :: "VK_EXT_primitives_generated_query" -EXT_global_priority_query :: 1 -EXT_GLOBAL_PRIORITY_QUERY_SPEC_VERSION :: 1 -EXT_GLOBAL_PRIORITY_QUERY_EXTENSION_NAME :: "VK_EXT_global_priority_query" -EXT_image_view_min_lod :: 1 -EXT_IMAGE_VIEW_MIN_LOD_SPEC_VERSION :: 1 -EXT_IMAGE_VIEW_MIN_LOD_EXTENSION_NAME :: "VK_EXT_image_view_min_lod" -EXT_multi_draw :: 1 -EXT_MULTI_DRAW_SPEC_VERSION :: 1 -EXT_MULTI_DRAW_EXTENSION_NAME :: "VK_EXT_multi_draw" -EXT_image_2d_view_of_3d :: 1 -EXT_IMAGE_2D_VIEW_OF_3D_SPEC_VERSION :: 1 -EXT_IMAGE_2D_VIEW_OF_3D_EXTENSION_NAME :: "VK_EXT_image_2d_view_of_3d" -EXT_shader_tile_image :: 1 -EXT_SHADER_TILE_IMAGE_SPEC_VERSION :: 1 -EXT_SHADER_TILE_IMAGE_EXTENSION_NAME :: "VK_EXT_shader_tile_image" -EXT_opacity_micromap :: 1 -EXT_OPACITY_MICROMAP_SPEC_VERSION :: 2 -EXT_OPACITY_MICROMAP_EXTENSION_NAME :: "VK_EXT_opacity_micromap" -EXT_load_store_op_none :: 1 -EXT_LOAD_STORE_OP_NONE_SPEC_VERSION :: 1 -EXT_LOAD_STORE_OP_NONE_EXTENSION_NAME :: "VK_EXT_load_store_op_none" -EXT_border_color_swizzle :: 1 -EXT_BORDER_COLOR_SWIZZLE_SPEC_VERSION :: 1 -EXT_BORDER_COLOR_SWIZZLE_EXTENSION_NAME :: "VK_EXT_border_color_swizzle" -EXT_pageable_device_local_memory :: 1 -EXT_PAGEABLE_DEVICE_LOCAL_MEMORY_SPEC_VERSION :: 1 -EXT_PAGEABLE_DEVICE_LOCAL_MEMORY_EXTENSION_NAME :: "VK_EXT_pageable_device_local_memory" -EXT_image_sliced_view_of_3d :: 1 -EXT_IMAGE_SLICED_VIEW_OF_3D_SPEC_VERSION :: 1 -EXT_IMAGE_SLICED_VIEW_OF_3D_EXTENSION_NAME :: "VK_EXT_image_sliced_view_of_3d" -EXT_depth_clamp_zero_one :: 1 -EXT_DEPTH_CLAMP_ZERO_ONE_SPEC_VERSION :: 1 -EXT_DEPTH_CLAMP_ZERO_ONE_EXTENSION_NAME :: "VK_EXT_depth_clamp_zero_one" -EXT_non_seamless_cube_map :: 1 -EXT_NON_SEAMLESS_CUBE_MAP_SPEC_VERSION :: 1 -EXT_NON_SEAMLESS_CUBE_MAP_EXTENSION_NAME :: "VK_EXT_non_seamless_cube_map" -NV_copy_memory_indirect :: 1 -NV_COPY_MEMORY_INDIRECT_SPEC_VERSION :: 1 -NV_COPY_MEMORY_INDIRECT_EXTENSION_NAME :: "VK_NV_copy_memory_indirect" -NV_memory_decompression :: 1 -NV_MEMORY_DECOMPRESSION_SPEC_VERSION :: 1 -NV_MEMORY_DECOMPRESSION_EXTENSION_NAME :: "VK_NV_memory_decompression" -NV_device_generated_commands_compute :: 1 -NV_DEVICE_GENERATED_COMMANDS_COMPUTE_SPEC_VERSION :: 2 -NV_DEVICE_GENERATED_COMMANDS_COMPUTE_EXTENSION_NAME :: "VK_NV_device_generated_commands_compute" -NV_ray_tracing_linear_swept_spheres :: 1 -NV_RAY_TRACING_LINEAR_SWEPT_SPHERES_SPEC_VERSION :: 1 -NV_RAY_TRACING_LINEAR_SWEPT_SPHERES_EXTENSION_NAME :: "VK_NV_ray_tracing_linear_swept_spheres" -NV_linear_color_attachment :: 1 -NV_LINEAR_COLOR_ATTACHMENT_SPEC_VERSION :: 1 -NV_LINEAR_COLOR_ATTACHMENT_EXTENSION_NAME :: "VK_NV_linear_color_attachment" -GOOGLE_surfaceless_query :: 1 -GOOGLE_SURFACELESS_QUERY_SPEC_VERSION :: 2 -GOOGLE_SURFACELESS_QUERY_EXTENSION_NAME :: "VK_GOOGLE_surfaceless_query" -EXT_image_compression_control_swapchain :: 1 -EXT_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_SPEC_VERSION :: 1 -EXT_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_EXTENSION_NAME :: "VK_EXT_image_compression_control_swapchain" -EXT_nested_command_buffer :: 1 -EXT_NESTED_COMMAND_BUFFER_SPEC_VERSION :: 1 -EXT_NESTED_COMMAND_BUFFER_EXTENSION_NAME :: "VK_EXT_nested_command_buffer" -EXT_external_memory_acquire_unmodified :: 1 -EXT_EXTERNAL_MEMORY_ACQUIRE_UNMODIFIED_SPEC_VERSION :: 1 -EXT_EXTERNAL_MEMORY_ACQUIRE_UNMODIFIED_EXTENSION_NAME :: "VK_EXT_external_memory_acquire_unmodified" -EXT_extended_dynamic_state3 :: 1 -EXT_EXTENDED_DYNAMIC_STATE_3_SPEC_VERSION :: 2 -EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME :: "VK_EXT_extended_dynamic_state3" -EXT_subpass_merge_feedback :: 1 -EXT_SUBPASS_MERGE_FEEDBACK_SPEC_VERSION :: 2 -EXT_SUBPASS_MERGE_FEEDBACK_EXTENSION_NAME :: "VK_EXT_subpass_merge_feedback" -EXT_shader_module_identifier :: 1 -EXT_SHADER_MODULE_IDENTIFIER_SPEC_VERSION :: 1 -EXT_SHADER_MODULE_IDENTIFIER_EXTENSION_NAME :: "VK_EXT_shader_module_identifier" -EXT_rasterization_order_attachment_access :: 1 -EXT_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_SPEC_VERSION :: 1 -EXT_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_EXTENSION_NAME :: "VK_EXT_rasterization_order_attachment_access" -NV_optical_flow :: 1 -NV_OPTICAL_FLOW_SPEC_VERSION :: 1 -NV_OPTICAL_FLOW_EXTENSION_NAME :: "VK_NV_optical_flow" -EXT_legacy_dithering :: 1 -EXT_LEGACY_DITHERING_SPEC_VERSION :: 2 -EXT_LEGACY_DITHERING_EXTENSION_NAME :: "VK_EXT_legacy_dithering" -EXT_pipeline_protected_access :: 1 -EXT_PIPELINE_PROTECTED_ACCESS_SPEC_VERSION :: 1 -EXT_PIPELINE_PROTECTED_ACCESS_EXTENSION_NAME :: "VK_EXT_pipeline_protected_access" -AMD_anti_lag :: 1 -AMD_ANTI_LAG_SPEC_VERSION :: 1 -AMD_ANTI_LAG_EXTENSION_NAME :: "VK_AMD_anti_lag" -EXT_shader_object :: 1 -EXT_SHADER_OBJECT_SPEC_VERSION :: 1 -EXT_SHADER_OBJECT_EXTENSION_NAME :: "VK_EXT_shader_object" -NV_ray_tracing_invocation_reorder :: 1 -NV_RAY_TRACING_INVOCATION_REORDER_SPEC_VERSION :: 1 -NV_RAY_TRACING_INVOCATION_REORDER_EXTENSION_NAME :: "VK_NV_ray_tracing_invocation_reorder" -NV_cooperative_vector :: 1 -NV_COOPERATIVE_VECTOR_SPEC_VERSION :: 4 -NV_COOPERATIVE_VECTOR_EXTENSION_NAME :: "VK_NV_cooperative_vector" -NV_extended_sparse_address_space :: 1 -NV_EXTENDED_SPARSE_ADDRESS_SPACE_SPEC_VERSION :: 1 -NV_EXTENDED_SPARSE_ADDRESS_SPACE_EXTENSION_NAME :: "VK_NV_extended_sparse_address_space" -EXT_mutable_descriptor_type :: 1 -EXT_MUTABLE_DESCRIPTOR_TYPE_SPEC_VERSION :: 1 -EXT_MUTABLE_DESCRIPTOR_TYPE_EXTENSION_NAME :: "VK_EXT_mutable_descriptor_type" -EXT_legacy_vertex_attributes :: 1 -EXT_LEGACY_VERTEX_ATTRIBUTES_SPEC_VERSION :: 1 -EXT_LEGACY_VERTEX_ATTRIBUTES_EXTENSION_NAME :: "VK_EXT_legacy_vertex_attributes" -EXT_layer_settings :: 1 -EXT_LAYER_SETTINGS_SPEC_VERSION :: 2 -EXT_LAYER_SETTINGS_EXTENSION_NAME :: "VK_EXT_layer_settings" -EXT_pipeline_library_group_handles :: 1 -EXT_PIPELINE_LIBRARY_GROUP_HANDLES_SPEC_VERSION :: 1 -EXT_PIPELINE_LIBRARY_GROUP_HANDLES_EXTENSION_NAME :: "VK_EXT_pipeline_library_group_handles" -EXT_dynamic_rendering_unused_attachments :: 1 -EXT_DYNAMIC_RENDERING_UNUSED_ATTACHMENTS_SPEC_VERSION :: 1 -EXT_DYNAMIC_RENDERING_UNUSED_ATTACHMENTS_EXTENSION_NAME :: "VK_EXT_dynamic_rendering_unused_attachments" -NV_low_latency2 :: 1 -NV_LOW_LATENCY_2_SPEC_VERSION :: 2 -NV_LOW_LATENCY_2_EXTENSION_NAME :: "VK_NV_low_latency2" -NV_per_stage_descriptor_set :: 1 -NV_PER_STAGE_DESCRIPTOR_SET_SPEC_VERSION :: 1 -NV_PER_STAGE_DESCRIPTOR_SET_EXTENSION_NAME :: "VK_NV_per_stage_descriptor_set" -EXT_attachment_feedback_loop_dynamic_state :: 1 -EXT_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_SPEC_VERSION :: 1 -EXT_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_EXTENSION_NAME :: "VK_EXT_attachment_feedback_loop_dynamic_state" -NV_descriptor_pool_overallocation :: 1 -NV_DESCRIPTOR_POOL_OVERALLOCATION_SPEC_VERSION :: 1 -NV_DESCRIPTOR_POOL_OVERALLOCATION_EXTENSION_NAME :: "VK_NV_descriptor_pool_overallocation" -NV_display_stereo :: 1 -NV_DISPLAY_STEREO_SPEC_VERSION :: 1 -NV_DISPLAY_STEREO_EXTENSION_NAME :: "VK_NV_display_stereo" -NV_raw_access_chains :: 1 -NV_RAW_ACCESS_CHAINS_SPEC_VERSION :: 1 -NV_RAW_ACCESS_CHAINS_EXTENSION_NAME :: "VK_NV_raw_access_chains" -NV_command_buffer_inheritance :: 1 -NV_COMMAND_BUFFER_INHERITANCE_SPEC_VERSION :: 1 -NV_COMMAND_BUFFER_INHERITANCE_EXTENSION_NAME :: "VK_NV_command_buffer_inheritance" -NV_shader_atomic_float16_vector :: 1 -NV_SHADER_ATOMIC_FLOAT16_VECTOR_SPEC_VERSION :: 1 -NV_SHADER_ATOMIC_FLOAT16_VECTOR_EXTENSION_NAME :: "VK_NV_shader_atomic_float16_vector" -EXT_shader_replicated_composites :: 1 -EXT_SHADER_REPLICATED_COMPOSITES_SPEC_VERSION :: 1 -EXT_SHADER_REPLICATED_COMPOSITES_EXTENSION_NAME :: "VK_EXT_shader_replicated_composites" -NV_ray_tracing_validation :: 1 -NV_RAY_TRACING_VALIDATION_SPEC_VERSION :: 1 -NV_RAY_TRACING_VALIDATION_EXTENSION_NAME :: "VK_NV_ray_tracing_validation" -NV_cluster_acceleration_structure :: 1 -NV_CLUSTER_ACCELERATION_STRUCTURE_SPEC_VERSION :: 2 -NV_CLUSTER_ACCELERATION_STRUCTURE_EXTENSION_NAME :: "VK_NV_cluster_acceleration_structure" -NV_partitioned_acceleration_structure :: 1 -NV_PARTITIONED_ACCELERATION_STRUCTURE_SPEC_VERSION :: 1 -NV_PARTITIONED_ACCELERATION_STRUCTURE_EXTENSION_NAME :: "VK_NV_partitioned_acceleration_structure" -EXT_device_generated_commands :: 1 -EXT_DEVICE_GENERATED_COMMANDS_SPEC_VERSION :: 1 -EXT_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME :: "VK_EXT_device_generated_commands" -EXT_depth_clamp_control :: 1 -EXT_DEPTH_CLAMP_CONTROL_SPEC_VERSION :: 1 -EXT_DEPTH_CLAMP_CONTROL_EXTENSION_NAME :: "VK_EXT_depth_clamp_control" -NV_cooperative_matrix2 :: 1 -NV_COOPERATIVE_MATRIX_2_SPEC_VERSION :: 1 -NV_COOPERATIVE_MATRIX_2_EXTENSION_NAME :: "VK_NV_cooperative_matrix2" -EXT_vertex_attribute_robustness :: 1 -EXT_VERTEX_ATTRIBUTE_ROBUSTNESS_SPEC_VERSION :: 1 -EXT_VERTEX_ATTRIBUTE_ROBUSTNESS_EXTENSION_NAME :: "VK_EXT_vertex_attribute_robustness" -NV_present_metering :: 1 -NV_PRESENT_METERING_SPEC_VERSION :: 1 -NV_PRESENT_METERING_EXTENSION_NAME :: "VK_NV_present_metering" -KHR_acceleration_structure :: 1 -KHR_ACCELERATION_STRUCTURE_SPEC_VERSION :: 13 -KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME :: "VK_KHR_acceleration_structure" -KHR_ray_tracing_pipeline :: 1 -KHR_RAY_TRACING_PIPELINE_SPEC_VERSION :: 1 -KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME :: "VK_KHR_ray_tracing_pipeline" -KHR_ray_query :: 1 -KHR_RAY_QUERY_SPEC_VERSION :: 1 -KHR_RAY_QUERY_EXTENSION_NAME :: "VK_KHR_ray_query" -EXT_mesh_shader :: 1 -EXT_MESH_SHADER_SPEC_VERSION :: 1 -EXT_MESH_SHADER_EXTENSION_NAME :: "VK_EXT_mesh_shader" -KHR_win32_surface :: 1 -KHR_WIN32_SURFACE_SPEC_VERSION :: 6 -KHR_WIN32_SURFACE_EXTENSION_NAME :: "VK_KHR_win32_surface" -KHR_external_memory_win32 :: 1 -KHR_EXTERNAL_MEMORY_WIN32_SPEC_VERSION :: 1 -KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME :: "VK_KHR_external_memory_win32" -KHR_win32_keyed_mutex :: 1 -KHR_WIN32_KEYED_MUTEX_SPEC_VERSION :: 1 -KHR_WIN32_KEYED_MUTEX_EXTENSION_NAME :: "VK_KHR_win32_keyed_mutex" -KHR_external_semaphore_win32 :: 1 -KHR_EXTERNAL_SEMAPHORE_WIN32_SPEC_VERSION :: 1 -KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME :: "VK_KHR_external_semaphore_win32" -KHR_external_fence_win32 :: 1 -KHR_EXTERNAL_FENCE_WIN32_SPEC_VERSION :: 1 -KHR_EXTERNAL_FENCE_WIN32_EXTENSION_NAME :: "VK_KHR_external_fence_win32" -NV_external_memory_win32 :: 1 -NV_EXTERNAL_MEMORY_WIN32_SPEC_VERSION :: 1 -NV_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME :: "VK_NV_external_memory_win32" -NV_win32_keyed_mutex :: 1 -NV_WIN32_KEYED_MUTEX_SPEC_VERSION :: 2 -NV_WIN32_KEYED_MUTEX_EXTENSION_NAME :: "VK_NV_win32_keyed_mutex" -EXT_full_screen_exclusive :: 1 -EXT_FULL_SCREEN_EXCLUSIVE_SPEC_VERSION :: 4 -EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME :: "VK_EXT_full_screen_exclusive" -NV_acquire_winrt_display :: 1 -NV_ACQUIRE_WINRT_DISPLAY_SPEC_VERSION :: 1 -NV_ACQUIRE_WINRT_DISPLAY_EXTENSION_NAME :: "VK_NV_acquire_winrt_display" -EXT_metal_surface :: 1 -EXT_METAL_SURFACE_SPEC_VERSION :: 1 -EXT_METAL_SURFACE_EXTENSION_NAME :: "VK_EXT_metal_surface" -EXT_metal_objects :: 1 -EXT_METAL_OBJECTS_SPEC_VERSION :: 2 -EXT_METAL_OBJECTS_EXTENSION_NAME :: "VK_EXT_metal_objects" -EXT_external_memory_metal :: 1 -EXT_EXTERNAL_MEMORY_METAL_SPEC_VERSION :: 1 -EXT_EXTERNAL_MEMORY_METAL_EXTENSION_NAME :: "VK_EXT_external_memory_metal" -KHR_wayland_surface :: 1 -KHR_WAYLAND_SURFACE_SPEC_VERSION :: 6 -KHR_WAYLAND_SURFACE_EXTENSION_NAME :: "VK_KHR_wayland_surface" -KHR_xlib_surface :: 1 -KHR_XLIB_SURFACE_SPEC_VERSION :: 6 -KHR_XLIB_SURFACE_EXTENSION_NAME :: "VK_KHR_xlib_surface" -KHR_xcb_surface :: 1 -KHR_XCB_SURFACE_SPEC_VERSION :: 6 -KHR_XCB_SURFACE_EXTENSION_NAME :: "VK_KHR_xcb_surface" -KHR_portability_subset :: 1 -KHR_PORTABILITY_SUBSET_SPEC_VERSION :: 1 -KHR_PORTABILITY_SUBSET_EXTENSION_NAME :: "VK_KHR_portability_subset" -AMDX_shader_enqueue :: 1 -AMDX_SHADER_ENQUEUE_SPEC_VERSION :: 2 -AMDX_SHADER_ENQUEUE_EXTENSION_NAME :: "VK_AMDX_shader_enqueue" -NV_displacement_micromap :: 1 -NV_DISPLACEMENT_MICROMAP_SPEC_VERSION :: 2 -NV_DISPLACEMENT_MICROMAP_EXTENSION_NAME :: "VK_NV_displacement_micromap" +KHR_surface :: 1 +KHR_SURFACE_SPEC_VERSION :: 25 +KHR_SURFACE_EXTENSION_NAME :: "VK_KHR_surface" +KHR_swapchain :: 1 +KHR_SWAPCHAIN_SPEC_VERSION :: 70 +KHR_SWAPCHAIN_EXTENSION_NAME :: "VK_KHR_swapchain" +KHR_display :: 1 +KHR_DISPLAY_SPEC_VERSION :: 23 +KHR_DISPLAY_EXTENSION_NAME :: "VK_KHR_display" +KHR_display_swapchain :: 1 +KHR_DISPLAY_SWAPCHAIN_SPEC_VERSION :: 10 +KHR_DISPLAY_SWAPCHAIN_EXTENSION_NAME :: "VK_KHR_display_swapchain" +KHR_sampler_mirror_clamp_to_edge :: 1 +KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_SPEC_VERSION :: 3 +KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME :: "VK_KHR_sampler_mirror_clamp_to_edge" +KHR_video_queue :: 1 +KHR_VIDEO_QUEUE_SPEC_VERSION :: 8 +KHR_VIDEO_QUEUE_EXTENSION_NAME :: "VK_KHR_video_queue" +KHR_video_decode_queue :: 1 +KHR_VIDEO_DECODE_QUEUE_SPEC_VERSION :: 8 +KHR_VIDEO_DECODE_QUEUE_EXTENSION_NAME :: "VK_KHR_video_decode_queue" +KHR_video_encode_h264 :: 1 +KHR_VIDEO_ENCODE_H264_SPEC_VERSION :: 14 +KHR_VIDEO_ENCODE_H264_EXTENSION_NAME :: "VK_KHR_video_encode_h264" +KHR_video_encode_h265 :: 1 +KHR_VIDEO_ENCODE_H265_SPEC_VERSION :: 14 +KHR_VIDEO_ENCODE_H265_EXTENSION_NAME :: "VK_KHR_video_encode_h265" +KHR_video_decode_h264 :: 1 +KHR_VIDEO_DECODE_H264_SPEC_VERSION :: 9 +KHR_VIDEO_DECODE_H264_EXTENSION_NAME :: "VK_KHR_video_decode_h264" +KHR_dynamic_rendering :: 1 +KHR_DYNAMIC_RENDERING_SPEC_VERSION :: 1 +KHR_DYNAMIC_RENDERING_EXTENSION_NAME :: "VK_KHR_dynamic_rendering" +KHR_multiview :: 1 +KHR_MULTIVIEW_SPEC_VERSION :: 1 +KHR_MULTIVIEW_EXTENSION_NAME :: "VK_KHR_multiview" +KHR_get_physical_device_properties2 :: 1 +KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_SPEC_VERSION :: 2 +KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME :: "VK_KHR_get_physical_device_properties2" +KHR_device_group :: 1 +KHR_DEVICE_GROUP_SPEC_VERSION :: 4 +KHR_DEVICE_GROUP_EXTENSION_NAME :: "VK_KHR_device_group" +KHR_shader_draw_parameters :: 1 +KHR_SHADER_DRAW_PARAMETERS_SPEC_VERSION :: 1 +KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME :: "VK_KHR_shader_draw_parameters" +KHR_maintenance1 :: 1 +KHR_MAINTENANCE_1_SPEC_VERSION :: 2 +KHR_MAINTENANCE_1_EXTENSION_NAME :: "VK_KHR_maintenance1" +KHR_MAINTENANCE1_SPEC_VERSION :: KHR_MAINTENANCE_1_SPEC_VERSION +KHR_MAINTENANCE1_EXTENSION_NAME :: KHR_MAINTENANCE_1_EXTENSION_NAME +KHR_device_group_creation :: 1 +KHR_DEVICE_GROUP_CREATION_SPEC_VERSION :: 1 +KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME :: "VK_KHR_device_group_creation" +MAX_DEVICE_GROUP_SIZE_KHR :: MAX_DEVICE_GROUP_SIZE +KHR_external_memory_capabilities :: 1 +KHR_EXTERNAL_MEMORY_CAPABILITIES_SPEC_VERSION :: 1 +KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME :: "VK_KHR_external_memory_capabilities" +LUID_SIZE_KHR :: LUID_SIZE +KHR_external_memory :: 1 +KHR_EXTERNAL_MEMORY_SPEC_VERSION :: 1 +KHR_EXTERNAL_MEMORY_EXTENSION_NAME :: "VK_KHR_external_memory" +QUEUE_FAMILY_EXTERNAL_KHR :: QUEUE_FAMILY_EXTERNAL +KHR_external_memory_fd :: 1 +KHR_EXTERNAL_MEMORY_FD_SPEC_VERSION :: 1 +KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME :: "VK_KHR_external_memory_fd" +KHR_external_semaphore_capabilities :: 1 +KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_SPEC_VERSION :: 1 +KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME :: "VK_KHR_external_semaphore_capabilities" +KHR_external_semaphore :: 1 +KHR_EXTERNAL_SEMAPHORE_SPEC_VERSION :: 1 +KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME :: "VK_KHR_external_semaphore" +KHR_external_semaphore_fd :: 1 +KHR_EXTERNAL_SEMAPHORE_FD_SPEC_VERSION :: 1 +KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME :: "VK_KHR_external_semaphore_fd" +KHR_push_descriptor :: 1 +KHR_PUSH_DESCRIPTOR_SPEC_VERSION :: 2 +KHR_PUSH_DESCRIPTOR_EXTENSION_NAME :: "VK_KHR_push_descriptor" +KHR_shader_float16_int8 :: 1 +KHR_SHADER_FLOAT16_INT8_SPEC_VERSION :: 1 +KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME :: "VK_KHR_shader_float16_int8" +KHR_16bit_storage :: 1 +KHR_16BIT_STORAGE_SPEC_VERSION :: 1 +KHR_16BIT_STORAGE_EXTENSION_NAME :: "VK_KHR_16bit_storage" +KHR_incremental_present :: 1 +KHR_INCREMENTAL_PRESENT_SPEC_VERSION :: 2 +KHR_INCREMENTAL_PRESENT_EXTENSION_NAME :: "VK_KHR_incremental_present" +KHR_descriptor_update_template :: 1 +KHR_DESCRIPTOR_UPDATE_TEMPLATE_SPEC_VERSION :: 1 +KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME :: "VK_KHR_descriptor_update_template" +KHR_imageless_framebuffer :: 1 +KHR_IMAGELESS_FRAMEBUFFER_SPEC_VERSION :: 1 +KHR_IMAGELESS_FRAMEBUFFER_EXTENSION_NAME :: "VK_KHR_imageless_framebuffer" +KHR_create_renderpass2 :: 1 +KHR_CREATE_RENDERPASS_2_SPEC_VERSION :: 1 +KHR_CREATE_RENDERPASS_2_EXTENSION_NAME :: "VK_KHR_create_renderpass2" +KHR_shared_presentable_image :: 1 +KHR_SHARED_PRESENTABLE_IMAGE_SPEC_VERSION :: 1 +KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME :: "VK_KHR_shared_presentable_image" +KHR_external_fence_capabilities :: 1 +KHR_EXTERNAL_FENCE_CAPABILITIES_SPEC_VERSION :: 1 +KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME :: "VK_KHR_external_fence_capabilities" +KHR_external_fence :: 1 +KHR_EXTERNAL_FENCE_SPEC_VERSION :: 1 +KHR_EXTERNAL_FENCE_EXTENSION_NAME :: "VK_KHR_external_fence" +KHR_external_fence_fd :: 1 +KHR_EXTERNAL_FENCE_FD_SPEC_VERSION :: 1 +KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME :: "VK_KHR_external_fence_fd" +KHR_performance_query :: 1 +KHR_PERFORMANCE_QUERY_SPEC_VERSION :: 1 +KHR_PERFORMANCE_QUERY_EXTENSION_NAME :: "VK_KHR_performance_query" +KHR_maintenance2 :: 1 +KHR_MAINTENANCE_2_SPEC_VERSION :: 1 +KHR_MAINTENANCE_2_EXTENSION_NAME :: "VK_KHR_maintenance2" +KHR_MAINTENANCE2_SPEC_VERSION :: KHR_MAINTENANCE_2_SPEC_VERSION +KHR_MAINTENANCE2_EXTENSION_NAME :: KHR_MAINTENANCE_2_EXTENSION_NAME +KHR_get_surface_capabilities2 :: 1 +KHR_GET_SURFACE_CAPABILITIES_2_SPEC_VERSION :: 1 +KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME :: "VK_KHR_get_surface_capabilities2" +KHR_variable_pointers :: 1 +KHR_VARIABLE_POINTERS_SPEC_VERSION :: 1 +KHR_VARIABLE_POINTERS_EXTENSION_NAME :: "VK_KHR_variable_pointers" +KHR_get_display_properties2 :: 1 +KHR_GET_DISPLAY_PROPERTIES_2_SPEC_VERSION :: 1 +KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME :: "VK_KHR_get_display_properties2" +KHR_dedicated_allocation :: 1 +KHR_DEDICATED_ALLOCATION_SPEC_VERSION :: 3 +KHR_DEDICATED_ALLOCATION_EXTENSION_NAME :: "VK_KHR_dedicated_allocation" +KHR_storage_buffer_storage_class :: 1 +KHR_STORAGE_BUFFER_STORAGE_CLASS_SPEC_VERSION :: 1 +KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME :: "VK_KHR_storage_buffer_storage_class" +KHR_relaxed_block_layout :: 1 +KHR_RELAXED_BLOCK_LAYOUT_SPEC_VERSION :: 1 +KHR_RELAXED_BLOCK_LAYOUT_EXTENSION_NAME :: "VK_KHR_relaxed_block_layout" +KHR_get_memory_requirements2 :: 1 +KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION :: 1 +KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME :: "VK_KHR_get_memory_requirements2" +KHR_image_format_list :: 1 +KHR_IMAGE_FORMAT_LIST_SPEC_VERSION :: 1 +KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME :: "VK_KHR_image_format_list" +KHR_sampler_ycbcr_conversion :: 1 +KHR_SAMPLER_YCBCR_CONVERSION_SPEC_VERSION :: 14 +KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME :: "VK_KHR_sampler_ycbcr_conversion" +KHR_bind_memory2 :: 1 +KHR_BIND_MEMORY_2_SPEC_VERSION :: 1 +KHR_BIND_MEMORY_2_EXTENSION_NAME :: "VK_KHR_bind_memory2" +KHR_maintenance3 :: 1 +KHR_MAINTENANCE_3_SPEC_VERSION :: 1 +KHR_MAINTENANCE_3_EXTENSION_NAME :: "VK_KHR_maintenance3" +KHR_MAINTENANCE3_SPEC_VERSION :: KHR_MAINTENANCE_3_SPEC_VERSION +KHR_MAINTENANCE3_EXTENSION_NAME :: KHR_MAINTENANCE_3_EXTENSION_NAME +KHR_draw_indirect_count :: 1 +KHR_DRAW_INDIRECT_COUNT_SPEC_VERSION :: 1 +KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME :: "VK_KHR_draw_indirect_count" +KHR_shader_subgroup_extended_types :: 1 +KHR_SHADER_SUBGROUP_EXTENDED_TYPES_SPEC_VERSION :: 1 +KHR_SHADER_SUBGROUP_EXTENDED_TYPES_EXTENSION_NAME :: "VK_KHR_shader_subgroup_extended_types" +KHR_8bit_storage :: 1 +KHR_8BIT_STORAGE_SPEC_VERSION :: 1 +KHR_8BIT_STORAGE_EXTENSION_NAME :: "VK_KHR_8bit_storage" +KHR_shader_atomic_int64 :: 1 +KHR_SHADER_ATOMIC_INT64_SPEC_VERSION :: 1 +KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME :: "VK_KHR_shader_atomic_int64" +KHR_shader_clock :: 1 +KHR_SHADER_CLOCK_SPEC_VERSION :: 1 +KHR_SHADER_CLOCK_EXTENSION_NAME :: "VK_KHR_shader_clock" +KHR_video_decode_h265 :: 1 +KHR_VIDEO_DECODE_H265_SPEC_VERSION :: 8 +KHR_VIDEO_DECODE_H265_EXTENSION_NAME :: "VK_KHR_video_decode_h265" +KHR_global_priority :: 1 +KHR_GLOBAL_PRIORITY_SPEC_VERSION :: 1 +KHR_GLOBAL_PRIORITY_EXTENSION_NAME :: "VK_KHR_global_priority" +MAX_GLOBAL_PRIORITY_SIZE_KHR :: MAX_GLOBAL_PRIORITY_SIZE +KHR_driver_properties :: 1 +KHR_DRIVER_PROPERTIES_SPEC_VERSION :: 1 +KHR_DRIVER_PROPERTIES_EXTENSION_NAME :: "VK_KHR_driver_properties" +MAX_DRIVER_NAME_SIZE_KHR :: MAX_DRIVER_NAME_SIZE +MAX_DRIVER_INFO_SIZE_KHR :: MAX_DRIVER_INFO_SIZE +KHR_shader_float_controls :: 1 +KHR_SHADER_FLOAT_CONTROLS_SPEC_VERSION :: 4 +KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME :: "VK_KHR_shader_float_controls" +KHR_depth_stencil_resolve :: 1 +KHR_DEPTH_STENCIL_RESOLVE_SPEC_VERSION :: 1 +KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME :: "VK_KHR_depth_stencil_resolve" +KHR_swapchain_mutable_format :: 1 +KHR_SWAPCHAIN_MUTABLE_FORMAT_SPEC_VERSION :: 1 +KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME :: "VK_KHR_swapchain_mutable_format" +KHR_timeline_semaphore :: 1 +KHR_TIMELINE_SEMAPHORE_SPEC_VERSION :: 2 +KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME :: "VK_KHR_timeline_semaphore" +KHR_vulkan_memory_model :: 1 +KHR_VULKAN_MEMORY_MODEL_SPEC_VERSION :: 3 +KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME :: "VK_KHR_vulkan_memory_model" +KHR_shader_terminate_invocation :: 1 +KHR_SHADER_TERMINATE_INVOCATION_SPEC_VERSION :: 1 +KHR_SHADER_TERMINATE_INVOCATION_EXTENSION_NAME :: "VK_KHR_shader_terminate_invocation" +KHR_fragment_shading_rate :: 1 +KHR_FRAGMENT_SHADING_RATE_SPEC_VERSION :: 2 +KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME :: "VK_KHR_fragment_shading_rate" +KHR_dynamic_rendering_local_read :: 1 +KHR_DYNAMIC_RENDERING_LOCAL_READ_SPEC_VERSION :: 1 +KHR_DYNAMIC_RENDERING_LOCAL_READ_EXTENSION_NAME :: "VK_KHR_dynamic_rendering_local_read" +KHR_shader_quad_control :: 1 +KHR_SHADER_QUAD_CONTROL_SPEC_VERSION :: 1 +KHR_SHADER_QUAD_CONTROL_EXTENSION_NAME :: "VK_KHR_shader_quad_control" +KHR_spirv_1_4 :: 1 +KHR_SPIRV_1_4_SPEC_VERSION :: 1 +KHR_SPIRV_1_4_EXTENSION_NAME :: "VK_KHR_spirv_1_4" +KHR_surface_protected_capabilities :: 1 +KHR_SURFACE_PROTECTED_CAPABILITIES_SPEC_VERSION :: 1 +KHR_SURFACE_PROTECTED_CAPABILITIES_EXTENSION_NAME :: "VK_KHR_surface_protected_capabilities" +KHR_separate_depth_stencil_layouts :: 1 +KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_SPEC_VERSION :: 1 +KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_EXTENSION_NAME :: "VK_KHR_separate_depth_stencil_layouts" +KHR_present_wait :: 1 +KHR_PRESENT_WAIT_SPEC_VERSION :: 1 +KHR_PRESENT_WAIT_EXTENSION_NAME :: "VK_KHR_present_wait" +KHR_uniform_buffer_standard_layout :: 1 +KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_SPEC_VERSION :: 1 +KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME :: "VK_KHR_uniform_buffer_standard_layout" +KHR_buffer_device_address :: 1 +KHR_BUFFER_DEVICE_ADDRESS_SPEC_VERSION :: 1 +KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME :: "VK_KHR_buffer_device_address" +KHR_deferred_host_operations :: 1 +KHR_DEFERRED_HOST_OPERATIONS_SPEC_VERSION :: 4 +KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME :: "VK_KHR_deferred_host_operations" +KHR_pipeline_executable_properties :: 1 +KHR_PIPELINE_EXECUTABLE_PROPERTIES_SPEC_VERSION :: 1 +KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME :: "VK_KHR_pipeline_executable_properties" +KHR_map_memory2 :: 1 +KHR_MAP_MEMORY_2_SPEC_VERSION :: 1 +KHR_MAP_MEMORY_2_EXTENSION_NAME :: "VK_KHR_map_memory2" +KHR_shader_integer_dot_product :: 1 +KHR_SHADER_INTEGER_DOT_PRODUCT_SPEC_VERSION :: 1 +KHR_SHADER_INTEGER_DOT_PRODUCT_EXTENSION_NAME :: "VK_KHR_shader_integer_dot_product" +KHR_pipeline_library :: 1 +KHR_PIPELINE_LIBRARY_SPEC_VERSION :: 1 +KHR_PIPELINE_LIBRARY_EXTENSION_NAME :: "VK_KHR_pipeline_library" +KHR_shader_non_semantic_info :: 1 +KHR_SHADER_NON_SEMANTIC_INFO_SPEC_VERSION :: 1 +KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME :: "VK_KHR_shader_non_semantic_info" +KHR_present_id :: 1 +KHR_PRESENT_ID_SPEC_VERSION :: 1 +KHR_PRESENT_ID_EXTENSION_NAME :: "VK_KHR_present_id" +KHR_video_encode_queue :: 1 +KHR_VIDEO_ENCODE_QUEUE_SPEC_VERSION :: 12 +KHR_VIDEO_ENCODE_QUEUE_EXTENSION_NAME :: "VK_KHR_video_encode_queue" +KHR_synchronization2 :: 1 +KHR_SYNCHRONIZATION_2_SPEC_VERSION :: 1 +KHR_SYNCHRONIZATION_2_EXTENSION_NAME :: "VK_KHR_synchronization2" +KHR_fragment_shader_barycentric :: 1 +KHR_FRAGMENT_SHADER_BARYCENTRIC_SPEC_VERSION :: 1 +KHR_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME :: "VK_KHR_fragment_shader_barycentric" +KHR_shader_subgroup_uniform_control_flow :: 1 +KHR_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_SPEC_VERSION :: 1 +KHR_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_EXTENSION_NAME :: "VK_KHR_shader_subgroup_uniform_control_flow" +KHR_zero_initialize_workgroup_memory :: 1 +KHR_ZERO_INITIALIZE_WORKGROUP_MEMORY_SPEC_VERSION :: 1 +KHR_ZERO_INITIALIZE_WORKGROUP_MEMORY_EXTENSION_NAME :: "VK_KHR_zero_initialize_workgroup_memory" +KHR_workgroup_memory_explicit_layout :: 1 +KHR_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_SPEC_VERSION :: 1 +KHR_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_EXTENSION_NAME :: "VK_KHR_workgroup_memory_explicit_layout" +KHR_copy_commands2 :: 1 +KHR_COPY_COMMANDS_2_SPEC_VERSION :: 1 +KHR_COPY_COMMANDS_2_EXTENSION_NAME :: "VK_KHR_copy_commands2" +KHR_format_feature_flags2 :: 1 +KHR_FORMAT_FEATURE_FLAGS_2_SPEC_VERSION :: 2 +KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME :: "VK_KHR_format_feature_flags2" +KHR_ray_tracing_maintenance1 :: 1 +KHR_RAY_TRACING_MAINTENANCE_1_SPEC_VERSION :: 1 +KHR_RAY_TRACING_MAINTENANCE_1_EXTENSION_NAME :: "VK_KHR_ray_tracing_maintenance1" +KHR_portability_enumeration :: 1 +KHR_PORTABILITY_ENUMERATION_SPEC_VERSION :: 1 +KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME :: "VK_KHR_portability_enumeration" +KHR_maintenance4 :: 1 +KHR_MAINTENANCE_4_SPEC_VERSION :: 2 +KHR_MAINTENANCE_4_EXTENSION_NAME :: "VK_KHR_maintenance4" +KHR_shader_subgroup_rotate :: 1 +KHR_SHADER_SUBGROUP_ROTATE_SPEC_VERSION :: 2 +KHR_SHADER_SUBGROUP_ROTATE_EXTENSION_NAME :: "VK_KHR_shader_subgroup_rotate" +KHR_shader_maximal_reconvergence :: 1 +KHR_SHADER_MAXIMAL_RECONVERGENCE_SPEC_VERSION :: 1 +KHR_SHADER_MAXIMAL_RECONVERGENCE_EXTENSION_NAME :: "VK_KHR_shader_maximal_reconvergence" +KHR_maintenance5 :: 1 +KHR_MAINTENANCE_5_SPEC_VERSION :: 1 +KHR_MAINTENANCE_5_EXTENSION_NAME :: "VK_KHR_maintenance5" +KHR_ray_tracing_position_fetch :: 1 +KHR_RAY_TRACING_POSITION_FETCH_SPEC_VERSION :: 1 +KHR_RAY_TRACING_POSITION_FETCH_EXTENSION_NAME :: "VK_KHR_ray_tracing_position_fetch" +KHR_pipeline_binary :: 1 +MAX_PIPELINE_BINARY_KEY_SIZE_KHR :: 32 +KHR_PIPELINE_BINARY_SPEC_VERSION :: 1 +KHR_PIPELINE_BINARY_EXTENSION_NAME :: "VK_KHR_pipeline_binary" +KHR_cooperative_matrix :: 1 +KHR_COOPERATIVE_MATRIX_SPEC_VERSION :: 2 +KHR_COOPERATIVE_MATRIX_EXTENSION_NAME :: "VK_KHR_cooperative_matrix" +KHR_compute_shader_derivatives :: 1 +KHR_COMPUTE_SHADER_DERIVATIVES_SPEC_VERSION :: 1 +KHR_COMPUTE_SHADER_DERIVATIVES_EXTENSION_NAME :: "VK_KHR_compute_shader_derivatives" +KHR_video_decode_av1 :: 1 +MAX_VIDEO_AV1_REFERENCES_PER_FRAME_KHR :: 7 +KHR_VIDEO_DECODE_AV1_SPEC_VERSION :: 1 +KHR_VIDEO_DECODE_AV1_EXTENSION_NAME :: "VK_KHR_video_decode_av1" +KHR_video_encode_av1 :: 1 +KHR_VIDEO_ENCODE_AV1_SPEC_VERSION :: 1 +KHR_VIDEO_ENCODE_AV1_EXTENSION_NAME :: "VK_KHR_video_encode_av1" +KHR_video_maintenance1 :: 1 +KHR_VIDEO_MAINTENANCE_1_SPEC_VERSION :: 1 +KHR_VIDEO_MAINTENANCE_1_EXTENSION_NAME :: "VK_KHR_video_maintenance1" +KHR_vertex_attribute_divisor :: 1 +KHR_VERTEX_ATTRIBUTE_DIVISOR_SPEC_VERSION :: 1 +KHR_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME :: "VK_KHR_vertex_attribute_divisor" +KHR_load_store_op_none :: 1 +KHR_LOAD_STORE_OP_NONE_SPEC_VERSION :: 1 +KHR_LOAD_STORE_OP_NONE_EXTENSION_NAME :: "VK_KHR_load_store_op_none" +KHR_shader_float_controls2 :: 1 +KHR_SHADER_FLOAT_CONTROLS_2_SPEC_VERSION :: 1 +KHR_SHADER_FLOAT_CONTROLS_2_EXTENSION_NAME :: "VK_KHR_shader_float_controls2" +KHR_index_type_uint8 :: 1 +KHR_INDEX_TYPE_UINT8_SPEC_VERSION :: 1 +KHR_INDEX_TYPE_UINT8_EXTENSION_NAME :: "VK_KHR_index_type_uint8" +KHR_line_rasterization :: 1 +KHR_LINE_RASTERIZATION_SPEC_VERSION :: 1 +KHR_LINE_RASTERIZATION_EXTENSION_NAME :: "VK_KHR_line_rasterization" +KHR_calibrated_timestamps :: 1 +KHR_CALIBRATED_TIMESTAMPS_SPEC_VERSION :: 1 +KHR_CALIBRATED_TIMESTAMPS_EXTENSION_NAME :: "VK_KHR_calibrated_timestamps" +KHR_shader_expect_assume :: 1 +KHR_SHADER_EXPECT_ASSUME_SPEC_VERSION :: 1 +KHR_SHADER_EXPECT_ASSUME_EXTENSION_NAME :: "VK_KHR_shader_expect_assume" +KHR_maintenance6 :: 1 +KHR_MAINTENANCE_6_SPEC_VERSION :: 1 +KHR_MAINTENANCE_6_EXTENSION_NAME :: "VK_KHR_maintenance6" +KHR_video_encode_quantization_map :: 1 +KHR_VIDEO_ENCODE_QUANTIZATION_MAP_SPEC_VERSION :: 2 +KHR_VIDEO_ENCODE_QUANTIZATION_MAP_EXTENSION_NAME :: "VK_KHR_video_encode_quantization_map" +KHR_shader_relaxed_extended_instruction :: 1 +KHR_SHADER_RELAXED_EXTENDED_INSTRUCTION_SPEC_VERSION :: 1 +KHR_SHADER_RELAXED_EXTENDED_INSTRUCTION_EXTENSION_NAME :: "VK_KHR_shader_relaxed_extended_instruction" +KHR_maintenance7 :: 1 +KHR_MAINTENANCE_7_SPEC_VERSION :: 1 +KHR_MAINTENANCE_7_EXTENSION_NAME :: "VK_KHR_maintenance7" +KHR_maintenance8 :: 1 +KHR_MAINTENANCE_8_SPEC_VERSION :: 1 +KHR_MAINTENANCE_8_EXTENSION_NAME :: "VK_KHR_maintenance8" +KHR_video_maintenance2 :: 1 +KHR_VIDEO_MAINTENANCE_2_SPEC_VERSION :: 1 +KHR_VIDEO_MAINTENANCE_2_EXTENSION_NAME :: "VK_KHR_video_maintenance2" +KHR_depth_clamp_zero_one :: 1 +KHR_DEPTH_CLAMP_ZERO_ONE_SPEC_VERSION :: 1 +KHR_DEPTH_CLAMP_ZERO_ONE_EXTENSION_NAME :: "VK_KHR_depth_clamp_zero_one" +EXT_debug_report :: 1 +EXT_DEBUG_REPORT_SPEC_VERSION :: 10 +EXT_DEBUG_REPORT_EXTENSION_NAME :: "VK_EXT_debug_report" +NV_glsl_shader :: 1 +NV_GLSL_SHADER_SPEC_VERSION :: 1 +NV_GLSL_SHADER_EXTENSION_NAME :: "VK_NV_glsl_shader" +EXT_depth_range_unrestricted :: 1 +EXT_DEPTH_RANGE_UNRESTRICTED_SPEC_VERSION :: 1 +EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME :: "VK_EXT_depth_range_unrestricted" +AMD_rasterization_order :: 1 +AMD_RASTERIZATION_ORDER_SPEC_VERSION :: 1 +AMD_RASTERIZATION_ORDER_EXTENSION_NAME :: "VK_AMD_rasterization_order" +AMD_shader_trinary_minmax :: 1 +AMD_SHADER_TRINARY_MINMAX_SPEC_VERSION :: 1 +AMD_SHADER_TRINARY_MINMAX_EXTENSION_NAME :: "VK_AMD_shader_trinary_minmax" +AMD_shader_explicit_vertex_parameter :: 1 +AMD_SHADER_EXPLICIT_VERTEX_PARAMETER_SPEC_VERSION :: 1 +AMD_SHADER_EXPLICIT_VERTEX_PARAMETER_EXTENSION_NAME :: "VK_AMD_shader_explicit_vertex_parameter" +EXT_debug_marker :: 1 +EXT_DEBUG_MARKER_SPEC_VERSION :: 4 +EXT_DEBUG_MARKER_EXTENSION_NAME :: "VK_EXT_debug_marker" +AMD_gcn_shader :: 1 +AMD_GCN_SHADER_SPEC_VERSION :: 1 +AMD_GCN_SHADER_EXTENSION_NAME :: "VK_AMD_gcn_shader" +NV_dedicated_allocation :: 1 +NV_DEDICATED_ALLOCATION_SPEC_VERSION :: 1 +NV_DEDICATED_ALLOCATION_EXTENSION_NAME :: "VK_NV_dedicated_allocation" +EXT_transform_feedback :: 1 +EXT_TRANSFORM_FEEDBACK_SPEC_VERSION :: 1 +EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME :: "VK_EXT_transform_feedback" +NVX_binary_import :: 1 +NVX_BINARY_IMPORT_SPEC_VERSION :: 2 +NVX_BINARY_IMPORT_EXTENSION_NAME :: "VK_NVX_binary_import" +NVX_image_view_handle :: 1 +NVX_IMAGE_VIEW_HANDLE_SPEC_VERSION :: 3 +NVX_IMAGE_VIEW_HANDLE_EXTENSION_NAME :: "VK_NVX_image_view_handle" +AMD_draw_indirect_count :: 1 +AMD_DRAW_INDIRECT_COUNT_SPEC_VERSION :: 2 +AMD_DRAW_INDIRECT_COUNT_EXTENSION_NAME :: "VK_AMD_draw_indirect_count" +AMD_negative_viewport_height :: 1 +AMD_NEGATIVE_VIEWPORT_HEIGHT_SPEC_VERSION :: 1 +AMD_NEGATIVE_VIEWPORT_HEIGHT_EXTENSION_NAME :: "VK_AMD_negative_viewport_height" +AMD_gpu_shader_half_float :: 1 +AMD_GPU_SHADER_HALF_FLOAT_SPEC_VERSION :: 2 +AMD_GPU_SHADER_HALF_FLOAT_EXTENSION_NAME :: "VK_AMD_gpu_shader_half_float" +AMD_shader_ballot :: 1 +AMD_SHADER_BALLOT_SPEC_VERSION :: 1 +AMD_SHADER_BALLOT_EXTENSION_NAME :: "VK_AMD_shader_ballot" +AMD_texture_gather_bias_lod :: 1 +AMD_TEXTURE_GATHER_BIAS_LOD_SPEC_VERSION :: 1 +AMD_TEXTURE_GATHER_BIAS_LOD_EXTENSION_NAME :: "VK_AMD_texture_gather_bias_lod" +AMD_shader_info :: 1 +AMD_SHADER_INFO_SPEC_VERSION :: 1 +AMD_SHADER_INFO_EXTENSION_NAME :: "VK_AMD_shader_info" +AMD_shader_image_load_store_lod :: 1 +AMD_SHADER_IMAGE_LOAD_STORE_LOD_SPEC_VERSION :: 1 +AMD_SHADER_IMAGE_LOAD_STORE_LOD_EXTENSION_NAME :: "VK_AMD_shader_image_load_store_lod" +NV_corner_sampled_image :: 1 +NV_CORNER_SAMPLED_IMAGE_SPEC_VERSION :: 2 +NV_CORNER_SAMPLED_IMAGE_EXTENSION_NAME :: "VK_NV_corner_sampled_image" +NV_external_memory_capabilities :: 1 +NV_EXTERNAL_MEMORY_CAPABILITIES_SPEC_VERSION :: 1 +NV_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME :: "VK_NV_external_memory_capabilities" +NV_external_memory :: 1 +NV_EXTERNAL_MEMORY_SPEC_VERSION :: 1 +NV_EXTERNAL_MEMORY_EXTENSION_NAME :: "VK_NV_external_memory" +EXT_validation_flags :: 1 +EXT_VALIDATION_FLAGS_SPEC_VERSION :: 3 +EXT_VALIDATION_FLAGS_EXTENSION_NAME :: "VK_EXT_validation_flags" +EXT_shader_subgroup_ballot :: 1 +EXT_SHADER_SUBGROUP_BALLOT_SPEC_VERSION :: 1 +EXT_SHADER_SUBGROUP_BALLOT_EXTENSION_NAME :: "VK_EXT_shader_subgroup_ballot" +EXT_shader_subgroup_vote :: 1 +EXT_SHADER_SUBGROUP_VOTE_SPEC_VERSION :: 1 +EXT_SHADER_SUBGROUP_VOTE_EXTENSION_NAME :: "VK_EXT_shader_subgroup_vote" +EXT_texture_compression_astc_hdr :: 1 +EXT_TEXTURE_COMPRESSION_ASTC_HDR_SPEC_VERSION :: 1 +EXT_TEXTURE_COMPRESSION_ASTC_HDR_EXTENSION_NAME :: "VK_EXT_texture_compression_astc_hdr" +EXT_astc_decode_mode :: 1 +EXT_ASTC_DECODE_MODE_SPEC_VERSION :: 1 +EXT_ASTC_DECODE_MODE_EXTENSION_NAME :: "VK_EXT_astc_decode_mode" +EXT_pipeline_robustness :: 1 +EXT_PIPELINE_ROBUSTNESS_SPEC_VERSION :: 1 +EXT_PIPELINE_ROBUSTNESS_EXTENSION_NAME :: "VK_EXT_pipeline_robustness" +EXT_conditional_rendering :: 1 +EXT_CONDITIONAL_RENDERING_SPEC_VERSION :: 2 +EXT_CONDITIONAL_RENDERING_EXTENSION_NAME :: "VK_EXT_conditional_rendering" +NV_clip_space_w_scaling :: 1 +NV_CLIP_SPACE_W_SCALING_SPEC_VERSION :: 1 +NV_CLIP_SPACE_W_SCALING_EXTENSION_NAME :: "VK_NV_clip_space_w_scaling" +EXT_direct_mode_display :: 1 +EXT_DIRECT_MODE_DISPLAY_SPEC_VERSION :: 1 +EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME :: "VK_EXT_direct_mode_display" +EXT_display_surface_counter :: 1 +EXT_DISPLAY_SURFACE_COUNTER_SPEC_VERSION :: 1 +EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME :: "VK_EXT_display_surface_counter" +EXT_display_control :: 1 +EXT_DISPLAY_CONTROL_SPEC_VERSION :: 1 +EXT_DISPLAY_CONTROL_EXTENSION_NAME :: "VK_EXT_display_control" +GOOGLE_display_timing :: 1 +GOOGLE_DISPLAY_TIMING_SPEC_VERSION :: 1 +GOOGLE_DISPLAY_TIMING_EXTENSION_NAME :: "VK_GOOGLE_display_timing" +NV_sample_mask_override_coverage :: 1 +NV_SAMPLE_MASK_OVERRIDE_COVERAGE_SPEC_VERSION :: 1 +NV_SAMPLE_MASK_OVERRIDE_COVERAGE_EXTENSION_NAME :: "VK_NV_sample_mask_override_coverage" +NV_geometry_shader_passthrough :: 1 +NV_GEOMETRY_SHADER_PASSTHROUGH_SPEC_VERSION :: 1 +NV_GEOMETRY_SHADER_PASSTHROUGH_EXTENSION_NAME :: "VK_NV_geometry_shader_passthrough" +NV_viewport_array2 :: 1 +NV_VIEWPORT_ARRAY_2_SPEC_VERSION :: 1 +NV_VIEWPORT_ARRAY_2_EXTENSION_NAME :: "VK_NV_viewport_array2" +NV_VIEWPORT_ARRAY2_SPEC_VERSION :: NV_VIEWPORT_ARRAY_2_SPEC_VERSION +NV_VIEWPORT_ARRAY2_EXTENSION_NAME :: NV_VIEWPORT_ARRAY_2_EXTENSION_NAME +NVX_multiview_per_view_attributes :: 1 +NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES_SPEC_VERSION :: 1 +NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES_EXTENSION_NAME :: "VK_NVX_multiview_per_view_attributes" +NV_viewport_swizzle :: 1 +NV_VIEWPORT_SWIZZLE_SPEC_VERSION :: 1 +NV_VIEWPORT_SWIZZLE_EXTENSION_NAME :: "VK_NV_viewport_swizzle" +EXT_discard_rectangles :: 1 +EXT_DISCARD_RECTANGLES_SPEC_VERSION :: 2 +EXT_DISCARD_RECTANGLES_EXTENSION_NAME :: "VK_EXT_discard_rectangles" +EXT_conservative_rasterization :: 1 +EXT_CONSERVATIVE_RASTERIZATION_SPEC_VERSION :: 1 +EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME :: "VK_EXT_conservative_rasterization" +EXT_depth_clip_enable :: 1 +EXT_DEPTH_CLIP_ENABLE_SPEC_VERSION :: 1 +EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME :: "VK_EXT_depth_clip_enable" +EXT_swapchain_colorspace :: 1 +EXT_SWAPCHAIN_COLOR_SPACE_SPEC_VERSION :: 5 +EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME :: "VK_EXT_swapchain_colorspace" +EXT_hdr_metadata :: 1 +EXT_HDR_METADATA_SPEC_VERSION :: 3 +EXT_HDR_METADATA_EXTENSION_NAME :: "VK_EXT_hdr_metadata" +EXT_external_memory_dma_buf :: 1 +EXT_EXTERNAL_MEMORY_DMA_BUF_SPEC_VERSION :: 1 +EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME :: "VK_EXT_external_memory_dma_buf" +EXT_queue_family_foreign :: 1 +EXT_QUEUE_FAMILY_FOREIGN_SPEC_VERSION :: 1 +EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME :: "VK_EXT_queue_family_foreign" +QUEUE_FAMILY_FOREIGN_EXT :: 2 +EXT_debug_utils :: 1 +EXT_DEBUG_UTILS_SPEC_VERSION :: 2 +EXT_DEBUG_UTILS_EXTENSION_NAME :: "VK_EXT_debug_utils" +EXT_sampler_filter_minmax :: 1 +EXT_SAMPLER_FILTER_MINMAX_SPEC_VERSION :: 2 +EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME :: "VK_EXT_sampler_filter_minmax" +AMD_gpu_shader_int16 :: 1 +AMD_GPU_SHADER_INT16_SPEC_VERSION :: 2 +AMD_GPU_SHADER_INT16_EXTENSION_NAME :: "VK_AMD_gpu_shader_int16" +AMD_mixed_attachment_samples :: 1 +AMD_MIXED_ATTACHMENT_SAMPLES_SPEC_VERSION :: 1 +AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME :: "VK_AMD_mixed_attachment_samples" +AMD_shader_fragment_mask :: 1 +AMD_SHADER_FRAGMENT_MASK_SPEC_VERSION :: 1 +AMD_SHADER_FRAGMENT_MASK_EXTENSION_NAME :: "VK_AMD_shader_fragment_mask" +EXT_inline_uniform_block :: 1 +EXT_INLINE_UNIFORM_BLOCK_SPEC_VERSION :: 1 +EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME :: "VK_EXT_inline_uniform_block" +EXT_shader_stencil_export :: 1 +EXT_SHADER_STENCIL_EXPORT_SPEC_VERSION :: 1 +EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME :: "VK_EXT_shader_stencil_export" +EXT_sample_locations :: 1 +EXT_SAMPLE_LOCATIONS_SPEC_VERSION :: 1 +EXT_SAMPLE_LOCATIONS_EXTENSION_NAME :: "VK_EXT_sample_locations" +EXT_blend_operation_advanced :: 1 +EXT_BLEND_OPERATION_ADVANCED_SPEC_VERSION :: 2 +EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME :: "VK_EXT_blend_operation_advanced" +NV_fragment_coverage_to_color :: 1 +NV_FRAGMENT_COVERAGE_TO_COLOR_SPEC_VERSION :: 1 +NV_FRAGMENT_COVERAGE_TO_COLOR_EXTENSION_NAME :: "VK_NV_fragment_coverage_to_color" +NV_framebuffer_mixed_samples :: 1 +NV_FRAMEBUFFER_MIXED_SAMPLES_SPEC_VERSION :: 1 +NV_FRAMEBUFFER_MIXED_SAMPLES_EXTENSION_NAME :: "VK_NV_framebuffer_mixed_samples" +NV_fill_rectangle :: 1 +NV_FILL_RECTANGLE_SPEC_VERSION :: 1 +NV_FILL_RECTANGLE_EXTENSION_NAME :: "VK_NV_fill_rectangle" +NV_shader_sm_builtins :: 1 +NV_SHADER_SM_BUILTINS_SPEC_VERSION :: 1 +NV_SHADER_SM_BUILTINS_EXTENSION_NAME :: "VK_NV_shader_sm_builtins" +EXT_post_depth_coverage :: 1 +EXT_POST_DEPTH_COVERAGE_SPEC_VERSION :: 1 +EXT_POST_DEPTH_COVERAGE_EXTENSION_NAME :: "VK_EXT_post_depth_coverage" +EXT_image_drm_format_modifier :: 1 +EXT_IMAGE_DRM_FORMAT_MODIFIER_SPEC_VERSION :: 2 +EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME :: "VK_EXT_image_drm_format_modifier" +EXT_validation_cache :: 1 +EXT_VALIDATION_CACHE_SPEC_VERSION :: 1 +EXT_VALIDATION_CACHE_EXTENSION_NAME :: "VK_EXT_validation_cache" +EXT_descriptor_indexing :: 1 +EXT_DESCRIPTOR_INDEXING_SPEC_VERSION :: 2 +EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME :: "VK_EXT_descriptor_indexing" +EXT_shader_viewport_index_layer :: 1 +EXT_SHADER_VIEWPORT_INDEX_LAYER_SPEC_VERSION :: 1 +EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME :: "VK_EXT_shader_viewport_index_layer" +NV_shading_rate_image :: 1 +NV_SHADING_RATE_IMAGE_SPEC_VERSION :: 3 +NV_SHADING_RATE_IMAGE_EXTENSION_NAME :: "VK_NV_shading_rate_image" +NV_ray_tracing :: 1 +NV_RAY_TRACING_SPEC_VERSION :: 3 +NV_RAY_TRACING_EXTENSION_NAME :: "VK_NV_ray_tracing" +SHADER_UNUSED_KHR :: ~u32(0) +SHADER_UNUSED_NV :: SHADER_UNUSED_KHR +NV_representative_fragment_test :: 1 +NV_REPRESENTATIVE_FRAGMENT_TEST_SPEC_VERSION :: 2 +NV_REPRESENTATIVE_FRAGMENT_TEST_EXTENSION_NAME :: "VK_NV_representative_fragment_test" +EXT_filter_cubic :: 1 +EXT_FILTER_CUBIC_SPEC_VERSION :: 3 +EXT_FILTER_CUBIC_EXTENSION_NAME :: "VK_EXT_filter_cubic" +EXT_global_priority :: 1 +EXT_GLOBAL_PRIORITY_SPEC_VERSION :: 2 +EXT_GLOBAL_PRIORITY_EXTENSION_NAME :: "VK_EXT_global_priority" +EXT_external_memory_host :: 1 +EXT_EXTERNAL_MEMORY_HOST_SPEC_VERSION :: 1 +EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME :: "VK_EXT_external_memory_host" +AMD_buffer_marker :: 1 +AMD_BUFFER_MARKER_SPEC_VERSION :: 1 +AMD_BUFFER_MARKER_EXTENSION_NAME :: "VK_AMD_buffer_marker" +AMD_pipeline_compiler_control :: 1 +AMD_PIPELINE_COMPILER_CONTROL_SPEC_VERSION :: 1 +AMD_PIPELINE_COMPILER_CONTROL_EXTENSION_NAME :: "VK_AMD_pipeline_compiler_control" +EXT_calibrated_timestamps :: 1 +EXT_CALIBRATED_TIMESTAMPS_SPEC_VERSION :: 2 +EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME :: "VK_EXT_calibrated_timestamps" +AMD_shader_core_properties :: 1 +AMD_SHADER_CORE_PROPERTIES_SPEC_VERSION :: 2 +AMD_SHADER_CORE_PROPERTIES_EXTENSION_NAME :: "VK_AMD_shader_core_properties" +AMD_memory_overallocation_behavior :: 1 +AMD_MEMORY_OVERALLOCATION_BEHAVIOR_SPEC_VERSION :: 1 +AMD_MEMORY_OVERALLOCATION_BEHAVIOR_EXTENSION_NAME :: "VK_AMD_memory_overallocation_behavior" +EXT_vertex_attribute_divisor :: 1 +EXT_VERTEX_ATTRIBUTE_DIVISOR_SPEC_VERSION :: 3 +EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME :: "VK_EXT_vertex_attribute_divisor" +EXT_pipeline_creation_feedback :: 1 +EXT_PIPELINE_CREATION_FEEDBACK_SPEC_VERSION :: 1 +EXT_PIPELINE_CREATION_FEEDBACK_EXTENSION_NAME :: "VK_EXT_pipeline_creation_feedback" +NV_shader_subgroup_partitioned :: 1 +NV_SHADER_SUBGROUP_PARTITIONED_SPEC_VERSION :: 1 +NV_SHADER_SUBGROUP_PARTITIONED_EXTENSION_NAME :: "VK_NV_shader_subgroup_partitioned" +NV_compute_shader_derivatives :: 1 +NV_COMPUTE_SHADER_DERIVATIVES_SPEC_VERSION :: 1 +NV_COMPUTE_SHADER_DERIVATIVES_EXTENSION_NAME :: "VK_NV_compute_shader_derivatives" +NV_mesh_shader :: 1 +NV_MESH_SHADER_SPEC_VERSION :: 1 +NV_MESH_SHADER_EXTENSION_NAME :: "VK_NV_mesh_shader" +NV_fragment_shader_barycentric :: 1 +NV_FRAGMENT_SHADER_BARYCENTRIC_SPEC_VERSION :: 1 +NV_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME :: "VK_NV_fragment_shader_barycentric" +NV_shader_image_footprint :: 1 +NV_SHADER_IMAGE_FOOTPRINT_SPEC_VERSION :: 2 +NV_SHADER_IMAGE_FOOTPRINT_EXTENSION_NAME :: "VK_NV_shader_image_footprint" +NV_scissor_exclusive :: 1 +NV_SCISSOR_EXCLUSIVE_SPEC_VERSION :: 2 +NV_SCISSOR_EXCLUSIVE_EXTENSION_NAME :: "VK_NV_scissor_exclusive" +NV_device_diagnostic_checkpoints :: 1 +NV_DEVICE_DIAGNOSTIC_CHECKPOINTS_SPEC_VERSION :: 2 +NV_DEVICE_DIAGNOSTIC_CHECKPOINTS_EXTENSION_NAME :: "VK_NV_device_diagnostic_checkpoints" +EXT_pci_bus_info :: 1 +EXT_PCI_BUS_INFO_SPEC_VERSION :: 2 +EXT_PCI_BUS_INFO_EXTENSION_NAME :: "VK_EXT_pci_bus_info" +AMD_display_native_hdr :: 1 +AMD_DISPLAY_NATIVE_HDR_SPEC_VERSION :: 1 +AMD_DISPLAY_NATIVE_HDR_EXTENSION_NAME :: "VK_AMD_display_native_hdr" +EXT_fragment_density_map :: 1 +EXT_FRAGMENT_DENSITY_MAP_SPEC_VERSION :: 2 +EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME :: "VK_EXT_fragment_density_map" +EXT_scalar_block_layout :: 1 +EXT_SCALAR_BLOCK_LAYOUT_SPEC_VERSION :: 1 +EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME :: "VK_EXT_scalar_block_layout" +GOOGLE_hlsl_functionality1 :: 1 +GOOGLE_HLSL_FUNCTIONALITY_1_SPEC_VERSION :: 1 +GOOGLE_HLSL_FUNCTIONALITY_1_EXTENSION_NAME :: "VK_GOOGLE_hlsl_functionality1" +GOOGLE_HLSL_FUNCTIONALITY1_SPEC_VERSION :: GOOGLE_HLSL_FUNCTIONALITY_1_SPEC_VERSION +GOOGLE_HLSL_FUNCTIONALITY1_EXTENSION_NAME :: GOOGLE_HLSL_FUNCTIONALITY_1_EXTENSION_NAME +GOOGLE_decorate_string :: 1 +GOOGLE_DECORATE_STRING_SPEC_VERSION :: 1 +GOOGLE_DECORATE_STRING_EXTENSION_NAME :: "VK_GOOGLE_decorate_string" +EXT_subgroup_size_control :: 1 +EXT_SUBGROUP_SIZE_CONTROL_SPEC_VERSION :: 2 +EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME :: "VK_EXT_subgroup_size_control" +AMD_shader_core_properties2 :: 1 +AMD_SHADER_CORE_PROPERTIES_2_SPEC_VERSION :: 1 +AMD_SHADER_CORE_PROPERTIES_2_EXTENSION_NAME :: "VK_AMD_shader_core_properties2" +AMD_device_coherent_memory :: 1 +AMD_DEVICE_COHERENT_MEMORY_SPEC_VERSION :: 1 +AMD_DEVICE_COHERENT_MEMORY_EXTENSION_NAME :: "VK_AMD_device_coherent_memory" +EXT_shader_image_atomic_int64 :: 1 +EXT_SHADER_IMAGE_ATOMIC_INT64_SPEC_VERSION :: 1 +EXT_SHADER_IMAGE_ATOMIC_INT64_EXTENSION_NAME :: "VK_EXT_shader_image_atomic_int64" +EXT_memory_budget :: 1 +EXT_MEMORY_BUDGET_SPEC_VERSION :: 1 +EXT_MEMORY_BUDGET_EXTENSION_NAME :: "VK_EXT_memory_budget" +EXT_memory_priority :: 1 +EXT_MEMORY_PRIORITY_SPEC_VERSION :: 1 +EXT_MEMORY_PRIORITY_EXTENSION_NAME :: "VK_EXT_memory_priority" +NV_dedicated_allocation_image_aliasing :: 1 +NV_DEDICATED_ALLOCATION_IMAGE_ALIASING_SPEC_VERSION :: 1 +NV_DEDICATED_ALLOCATION_IMAGE_ALIASING_EXTENSION_NAME :: "VK_NV_dedicated_allocation_image_aliasing" +EXT_buffer_device_address :: 1 +EXT_BUFFER_DEVICE_ADDRESS_SPEC_VERSION :: 2 +EXT_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME :: "VK_EXT_buffer_device_address" +EXT_tooling_info :: 1 +EXT_TOOLING_INFO_SPEC_VERSION :: 1 +EXT_TOOLING_INFO_EXTENSION_NAME :: "VK_EXT_tooling_info" +EXT_separate_stencil_usage :: 1 +EXT_SEPARATE_STENCIL_USAGE_SPEC_VERSION :: 1 +EXT_SEPARATE_STENCIL_USAGE_EXTENSION_NAME :: "VK_EXT_separate_stencil_usage" +EXT_validation_features :: 1 +EXT_VALIDATION_FEATURES_SPEC_VERSION :: 6 +EXT_VALIDATION_FEATURES_EXTENSION_NAME :: "VK_EXT_validation_features" +NV_cooperative_matrix :: 1 +NV_COOPERATIVE_MATRIX_SPEC_VERSION :: 1 +NV_COOPERATIVE_MATRIX_EXTENSION_NAME :: "VK_NV_cooperative_matrix" +NV_coverage_reduction_mode :: 1 +NV_COVERAGE_REDUCTION_MODE_SPEC_VERSION :: 1 +NV_COVERAGE_REDUCTION_MODE_EXTENSION_NAME :: "VK_NV_coverage_reduction_mode" +EXT_fragment_shader_interlock :: 1 +EXT_FRAGMENT_SHADER_INTERLOCK_SPEC_VERSION :: 1 +EXT_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME :: "VK_EXT_fragment_shader_interlock" +EXT_ycbcr_image_arrays :: 1 +EXT_YCBCR_IMAGE_ARRAYS_SPEC_VERSION :: 1 +EXT_YCBCR_IMAGE_ARRAYS_EXTENSION_NAME :: "VK_EXT_ycbcr_image_arrays" +EXT_provoking_vertex :: 1 +EXT_PROVOKING_VERTEX_SPEC_VERSION :: 1 +EXT_PROVOKING_VERTEX_EXTENSION_NAME :: "VK_EXT_provoking_vertex" +EXT_headless_surface :: 1 +EXT_HEADLESS_SURFACE_SPEC_VERSION :: 1 +EXT_HEADLESS_SURFACE_EXTENSION_NAME :: "VK_EXT_headless_surface" +EXT_line_rasterization :: 1 +EXT_LINE_RASTERIZATION_SPEC_VERSION :: 1 +EXT_LINE_RASTERIZATION_EXTENSION_NAME :: "VK_EXT_line_rasterization" +EXT_shader_atomic_float :: 1 +EXT_SHADER_ATOMIC_FLOAT_SPEC_VERSION :: 1 +EXT_SHADER_ATOMIC_FLOAT_EXTENSION_NAME :: "VK_EXT_shader_atomic_float" +EXT_host_query_reset :: 1 +EXT_HOST_QUERY_RESET_SPEC_VERSION :: 1 +EXT_HOST_QUERY_RESET_EXTENSION_NAME :: "VK_EXT_host_query_reset" +EXT_index_type_uint8 :: 1 +EXT_INDEX_TYPE_UINT8_SPEC_VERSION :: 1 +EXT_INDEX_TYPE_UINT8_EXTENSION_NAME :: "VK_EXT_index_type_uint8" +EXT_extended_dynamic_state :: 1 +EXT_EXTENDED_DYNAMIC_STATE_SPEC_VERSION :: 1 +EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME :: "VK_EXT_extended_dynamic_state" +EXT_host_image_copy :: 1 +EXT_HOST_IMAGE_COPY_SPEC_VERSION :: 1 +EXT_HOST_IMAGE_COPY_EXTENSION_NAME :: "VK_EXT_host_image_copy" +EXT_map_memory_placed :: 1 +EXT_MAP_MEMORY_PLACED_SPEC_VERSION :: 1 +EXT_MAP_MEMORY_PLACED_EXTENSION_NAME :: "VK_EXT_map_memory_placed" +EXT_shader_atomic_float2 :: 1 +EXT_SHADER_ATOMIC_FLOAT_2_SPEC_VERSION :: 1 +EXT_SHADER_ATOMIC_FLOAT_2_EXTENSION_NAME :: "VK_EXT_shader_atomic_float2" +EXT_surface_maintenance1 :: 1 +EXT_SURFACE_MAINTENANCE_1_SPEC_VERSION :: 1 +EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME :: "VK_EXT_surface_maintenance1" +EXT_swapchain_maintenance1 :: 1 +EXT_SWAPCHAIN_MAINTENANCE_1_SPEC_VERSION :: 1 +EXT_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME :: "VK_EXT_swapchain_maintenance1" +EXT_shader_demote_to_helper_invocation :: 1 +EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_SPEC_VERSION :: 1 +EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME :: "VK_EXT_shader_demote_to_helper_invocation" +NV_device_generated_commands :: 1 +NV_DEVICE_GENERATED_COMMANDS_SPEC_VERSION :: 3 +NV_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME :: "VK_NV_device_generated_commands" +NV_inherited_viewport_scissor :: 1 +NV_INHERITED_VIEWPORT_SCISSOR_SPEC_VERSION :: 1 +NV_INHERITED_VIEWPORT_SCISSOR_EXTENSION_NAME :: "VK_NV_inherited_viewport_scissor" +EXT_texel_buffer_alignment :: 1 +EXT_TEXEL_BUFFER_ALIGNMENT_SPEC_VERSION :: 1 +EXT_TEXEL_BUFFER_ALIGNMENT_EXTENSION_NAME :: "VK_EXT_texel_buffer_alignment" +EXT_depth_bias_control :: 1 +EXT_DEPTH_BIAS_CONTROL_SPEC_VERSION :: 1 +EXT_DEPTH_BIAS_CONTROL_EXTENSION_NAME :: "VK_EXT_depth_bias_control" +EXT_device_memory_report :: 1 +EXT_DEVICE_MEMORY_REPORT_SPEC_VERSION :: 2 +EXT_DEVICE_MEMORY_REPORT_EXTENSION_NAME :: "VK_EXT_device_memory_report" +EXT_acquire_drm_display :: 1 +EXT_ACQUIRE_DRM_DISPLAY_SPEC_VERSION :: 1 +EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME :: "VK_EXT_acquire_drm_display" +EXT_robustness2 :: 1 +EXT_ROBUSTNESS_2_SPEC_VERSION :: 1 +EXT_ROBUSTNESS_2_EXTENSION_NAME :: "VK_EXT_robustness2" +EXT_custom_border_color :: 1 +EXT_CUSTOM_BORDER_COLOR_SPEC_VERSION :: 12 +EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME :: "VK_EXT_custom_border_color" +GOOGLE_user_type :: 1 +GOOGLE_USER_TYPE_SPEC_VERSION :: 1 +GOOGLE_USER_TYPE_EXTENSION_NAME :: "VK_GOOGLE_user_type" +NV_present_barrier :: 1 +NV_PRESENT_BARRIER_SPEC_VERSION :: 1 +NV_PRESENT_BARRIER_EXTENSION_NAME :: "VK_NV_present_barrier" +EXT_private_data :: 1 +EXT_PRIVATE_DATA_SPEC_VERSION :: 1 +EXT_PRIVATE_DATA_EXTENSION_NAME :: "VK_EXT_private_data" +EXT_pipeline_creation_cache_control :: 1 +EXT_PIPELINE_CREATION_CACHE_CONTROL_SPEC_VERSION :: 3 +EXT_PIPELINE_CREATION_CACHE_CONTROL_EXTENSION_NAME :: "VK_EXT_pipeline_creation_cache_control" +NV_device_diagnostics_config :: 1 +NV_DEVICE_DIAGNOSTICS_CONFIG_SPEC_VERSION :: 2 +NV_DEVICE_DIAGNOSTICS_CONFIG_EXTENSION_NAME :: "VK_NV_device_diagnostics_config" +NV_cuda_kernel_launch :: 1 +NV_CUDA_KERNEL_LAUNCH_SPEC_VERSION :: 2 +NV_CUDA_KERNEL_LAUNCH_EXTENSION_NAME :: "VK_NV_cuda_kernel_launch" +NV_low_latency :: 1 +NV_LOW_LATENCY_SPEC_VERSION :: 1 +NV_LOW_LATENCY_EXTENSION_NAME :: "VK_NV_low_latency" +EXT_descriptor_buffer :: 1 +EXT_DESCRIPTOR_BUFFER_SPEC_VERSION :: 1 +EXT_DESCRIPTOR_BUFFER_EXTENSION_NAME :: "VK_EXT_descriptor_buffer" +EXT_graphics_pipeline_library :: 1 +EXT_GRAPHICS_PIPELINE_LIBRARY_SPEC_VERSION :: 1 +EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME :: "VK_EXT_graphics_pipeline_library" +AMD_shader_early_and_late_fragment_tests :: 1 +AMD_SHADER_EARLY_AND_LATE_FRAGMENT_TESTS_SPEC_VERSION :: 1 +AMD_SHADER_EARLY_AND_LATE_FRAGMENT_TESTS_EXTENSION_NAME :: "VK_AMD_shader_early_and_late_fragment_tests" +NV_fragment_shading_rate_enums :: 1 +NV_FRAGMENT_SHADING_RATE_ENUMS_SPEC_VERSION :: 1 +NV_FRAGMENT_SHADING_RATE_ENUMS_EXTENSION_NAME :: "VK_NV_fragment_shading_rate_enums" +NV_ray_tracing_motion_blur :: 1 +NV_RAY_TRACING_MOTION_BLUR_SPEC_VERSION :: 1 +NV_RAY_TRACING_MOTION_BLUR_EXTENSION_NAME :: "VK_NV_ray_tracing_motion_blur" +EXT_ycbcr_2plane_444_formats :: 1 +EXT_YCBCR_2PLANE_444_FORMATS_SPEC_VERSION :: 1 +EXT_YCBCR_2PLANE_444_FORMATS_EXTENSION_NAME :: "VK_EXT_ycbcr_2plane_444_formats" +EXT_fragment_density_map2 :: 1 +EXT_FRAGMENT_DENSITY_MAP_2_SPEC_VERSION :: 1 +EXT_FRAGMENT_DENSITY_MAP_2_EXTENSION_NAME :: "VK_EXT_fragment_density_map2" +EXT_image_robustness :: 1 +EXT_IMAGE_ROBUSTNESS_SPEC_VERSION :: 1 +EXT_IMAGE_ROBUSTNESS_EXTENSION_NAME :: "VK_EXT_image_robustness" +EXT_image_compression_control :: 1 +EXT_IMAGE_COMPRESSION_CONTROL_SPEC_VERSION :: 1 +EXT_IMAGE_COMPRESSION_CONTROL_EXTENSION_NAME :: "VK_EXT_image_compression_control" +EXT_attachment_feedback_loop_layout :: 1 +EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_SPEC_VERSION :: 2 +EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_EXTENSION_NAME :: "VK_EXT_attachment_feedback_loop_layout" +EXT_4444_formats :: 1 +EXT_4444_FORMATS_SPEC_VERSION :: 1 +EXT_4444_FORMATS_EXTENSION_NAME :: "VK_EXT_4444_formats" +EXT_device_fault :: 1 +EXT_DEVICE_FAULT_SPEC_VERSION :: 2 +EXT_DEVICE_FAULT_EXTENSION_NAME :: "VK_EXT_device_fault" +EXT_rgba10x6_formats :: 1 +EXT_RGBA10X6_FORMATS_SPEC_VERSION :: 1 +EXT_RGBA10X6_FORMATS_EXTENSION_NAME :: "VK_EXT_rgba10x6_formats" +EXT_vertex_input_dynamic_state :: 1 +EXT_VERTEX_INPUT_DYNAMIC_STATE_SPEC_VERSION :: 2 +EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME :: "VK_EXT_vertex_input_dynamic_state" +EXT_physical_device_drm :: 1 +EXT_PHYSICAL_DEVICE_DRM_SPEC_VERSION :: 1 +EXT_PHYSICAL_DEVICE_DRM_EXTENSION_NAME :: "VK_EXT_physical_device_drm" +EXT_device_address_binding_report :: 1 +EXT_DEVICE_ADDRESS_BINDING_REPORT_SPEC_VERSION :: 1 +EXT_DEVICE_ADDRESS_BINDING_REPORT_EXTENSION_NAME :: "VK_EXT_device_address_binding_report" +EXT_depth_clip_control :: 1 +EXT_DEPTH_CLIP_CONTROL_SPEC_VERSION :: 1 +EXT_DEPTH_CLIP_CONTROL_EXTENSION_NAME :: "VK_EXT_depth_clip_control" +EXT_primitive_topology_list_restart :: 1 +EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_SPEC_VERSION :: 1 +EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_EXTENSION_NAME :: "VK_EXT_primitive_topology_list_restart" +EXT_present_mode_fifo_latest_ready :: 1 +EXT_PRESENT_MODE_FIFO_LATEST_READY_SPEC_VERSION :: 1 +EXT_PRESENT_MODE_FIFO_LATEST_READY_EXTENSION_NAME :: "VK_EXT_present_mode_fifo_latest_ready" +NV_external_memory_rdma :: 1 +NV_EXTERNAL_MEMORY_RDMA_SPEC_VERSION :: 1 +NV_EXTERNAL_MEMORY_RDMA_EXTENSION_NAME :: "VK_NV_external_memory_rdma" +EXT_pipeline_properties :: 1 +EXT_PIPELINE_PROPERTIES_SPEC_VERSION :: 1 +EXT_PIPELINE_PROPERTIES_EXTENSION_NAME :: "VK_EXT_pipeline_properties" +EXT_frame_boundary :: 1 +EXT_FRAME_BOUNDARY_SPEC_VERSION :: 1 +EXT_FRAME_BOUNDARY_EXTENSION_NAME :: "VK_EXT_frame_boundary" +EXT_multisampled_render_to_single_sampled :: 1 +EXT_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_SPEC_VERSION :: 1 +EXT_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_EXTENSION_NAME :: "VK_EXT_multisampled_render_to_single_sampled" +EXT_extended_dynamic_state2 :: 1 +EXT_EXTENDED_DYNAMIC_STATE_2_SPEC_VERSION :: 1 +EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME :: "VK_EXT_extended_dynamic_state2" +EXT_color_write_enable :: 1 +EXT_COLOR_WRITE_ENABLE_SPEC_VERSION :: 1 +EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME :: "VK_EXT_color_write_enable" +EXT_primitives_generated_query :: 1 +EXT_PRIMITIVES_GENERATED_QUERY_SPEC_VERSION :: 1 +EXT_PRIMITIVES_GENERATED_QUERY_EXTENSION_NAME :: "VK_EXT_primitives_generated_query" +EXT_global_priority_query :: 1 +EXT_GLOBAL_PRIORITY_QUERY_SPEC_VERSION :: 1 +EXT_GLOBAL_PRIORITY_QUERY_EXTENSION_NAME :: "VK_EXT_global_priority_query" +MAX_GLOBAL_PRIORITY_SIZE_EXT :: MAX_GLOBAL_PRIORITY_SIZE +EXT_image_view_min_lod :: 1 +EXT_IMAGE_VIEW_MIN_LOD_SPEC_VERSION :: 1 +EXT_IMAGE_VIEW_MIN_LOD_EXTENSION_NAME :: "VK_EXT_image_view_min_lod" +EXT_multi_draw :: 1 +EXT_MULTI_DRAW_SPEC_VERSION :: 1 +EXT_MULTI_DRAW_EXTENSION_NAME :: "VK_EXT_multi_draw" +EXT_image_2d_view_of_3d :: 1 +EXT_IMAGE_2D_VIEW_OF_3D_SPEC_VERSION :: 1 +EXT_IMAGE_2D_VIEW_OF_3D_EXTENSION_NAME :: "VK_EXT_image_2d_view_of_3d" +EXT_shader_tile_image :: 1 +EXT_SHADER_TILE_IMAGE_SPEC_VERSION :: 1 +EXT_SHADER_TILE_IMAGE_EXTENSION_NAME :: "VK_EXT_shader_tile_image" +EXT_opacity_micromap :: 1 +EXT_OPACITY_MICROMAP_SPEC_VERSION :: 2 +EXT_OPACITY_MICROMAP_EXTENSION_NAME :: "VK_EXT_opacity_micromap" +EXT_load_store_op_none :: 1 +EXT_LOAD_STORE_OP_NONE_SPEC_VERSION :: 1 +EXT_LOAD_STORE_OP_NONE_EXTENSION_NAME :: "VK_EXT_load_store_op_none" +EXT_border_color_swizzle :: 1 +EXT_BORDER_COLOR_SWIZZLE_SPEC_VERSION :: 1 +EXT_BORDER_COLOR_SWIZZLE_EXTENSION_NAME :: "VK_EXT_border_color_swizzle" +EXT_pageable_device_local_memory :: 1 +EXT_PAGEABLE_DEVICE_LOCAL_MEMORY_SPEC_VERSION :: 1 +EXT_PAGEABLE_DEVICE_LOCAL_MEMORY_EXTENSION_NAME :: "VK_EXT_pageable_device_local_memory" +EXT_image_sliced_view_of_3d :: 1 +EXT_IMAGE_SLICED_VIEW_OF_3D_SPEC_VERSION :: 1 +EXT_IMAGE_SLICED_VIEW_OF_3D_EXTENSION_NAME :: "VK_EXT_image_sliced_view_of_3d" +REMAINING_3D_SLICES_EXT :: ~u32(0) +EXT_depth_clamp_zero_one :: 1 +EXT_DEPTH_CLAMP_ZERO_ONE_SPEC_VERSION :: 1 +EXT_DEPTH_CLAMP_ZERO_ONE_EXTENSION_NAME :: "VK_EXT_depth_clamp_zero_one" +EXT_non_seamless_cube_map :: 1 +EXT_NON_SEAMLESS_CUBE_MAP_SPEC_VERSION :: 1 +EXT_NON_SEAMLESS_CUBE_MAP_EXTENSION_NAME :: "VK_EXT_non_seamless_cube_map" +NV_copy_memory_indirect :: 1 +NV_COPY_MEMORY_INDIRECT_SPEC_VERSION :: 1 +NV_COPY_MEMORY_INDIRECT_EXTENSION_NAME :: "VK_NV_copy_memory_indirect" +NV_memory_decompression :: 1 +NV_MEMORY_DECOMPRESSION_SPEC_VERSION :: 1 +NV_MEMORY_DECOMPRESSION_EXTENSION_NAME :: "VK_NV_memory_decompression" +NV_device_generated_commands_compute :: 1 +NV_DEVICE_GENERATED_COMMANDS_COMPUTE_SPEC_VERSION :: 2 +NV_DEVICE_GENERATED_COMMANDS_COMPUTE_EXTENSION_NAME :: "VK_NV_device_generated_commands_compute" +NV_ray_tracing_linear_swept_spheres :: 1 +NV_RAY_TRACING_LINEAR_SWEPT_SPHERES_SPEC_VERSION :: 1 +NV_RAY_TRACING_LINEAR_SWEPT_SPHERES_EXTENSION_NAME :: "VK_NV_ray_tracing_linear_swept_spheres" +NV_linear_color_attachment :: 1 +NV_LINEAR_COLOR_ATTACHMENT_SPEC_VERSION :: 1 +NV_LINEAR_COLOR_ATTACHMENT_EXTENSION_NAME :: "VK_NV_linear_color_attachment" +GOOGLE_surfaceless_query :: 1 +GOOGLE_SURFACELESS_QUERY_SPEC_VERSION :: 2 +GOOGLE_SURFACELESS_QUERY_EXTENSION_NAME :: "VK_GOOGLE_surfaceless_query" +EXT_image_compression_control_swapchain :: 1 +EXT_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_SPEC_VERSION :: 1 +EXT_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_EXTENSION_NAME :: "VK_EXT_image_compression_control_swapchain" +EXT_nested_command_buffer :: 1 +EXT_NESTED_COMMAND_BUFFER_SPEC_VERSION :: 1 +EXT_NESTED_COMMAND_BUFFER_EXTENSION_NAME :: "VK_EXT_nested_command_buffer" +EXT_external_memory_acquire_unmodified :: 1 +EXT_EXTERNAL_MEMORY_ACQUIRE_UNMODIFIED_SPEC_VERSION :: 1 +EXT_EXTERNAL_MEMORY_ACQUIRE_UNMODIFIED_EXTENSION_NAME :: "VK_EXT_external_memory_acquire_unmodified" +EXT_extended_dynamic_state3 :: 1 +EXT_EXTENDED_DYNAMIC_STATE_3_SPEC_VERSION :: 2 +EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME :: "VK_EXT_extended_dynamic_state3" +EXT_subpass_merge_feedback :: 1 +EXT_SUBPASS_MERGE_FEEDBACK_SPEC_VERSION :: 2 +EXT_SUBPASS_MERGE_FEEDBACK_EXTENSION_NAME :: "VK_EXT_subpass_merge_feedback" +EXT_shader_module_identifier :: 1 +MAX_SHADER_MODULE_IDENTIFIER_SIZE_EXT :: 32 +EXT_SHADER_MODULE_IDENTIFIER_SPEC_VERSION :: 1 +EXT_SHADER_MODULE_IDENTIFIER_EXTENSION_NAME :: "VK_EXT_shader_module_identifier" +EXT_rasterization_order_attachment_access :: 1 +EXT_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_SPEC_VERSION :: 1 +EXT_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_EXTENSION_NAME :: "VK_EXT_rasterization_order_attachment_access" +NV_optical_flow :: 1 +NV_OPTICAL_FLOW_SPEC_VERSION :: 1 +NV_OPTICAL_FLOW_EXTENSION_NAME :: "VK_NV_optical_flow" +EXT_legacy_dithering :: 1 +EXT_LEGACY_DITHERING_SPEC_VERSION :: 2 +EXT_LEGACY_DITHERING_EXTENSION_NAME :: "VK_EXT_legacy_dithering" +EXT_pipeline_protected_access :: 1 +EXT_PIPELINE_PROTECTED_ACCESS_SPEC_VERSION :: 1 +EXT_PIPELINE_PROTECTED_ACCESS_EXTENSION_NAME :: "VK_EXT_pipeline_protected_access" +AMD_anti_lag :: 1 +AMD_ANTI_LAG_SPEC_VERSION :: 1 +AMD_ANTI_LAG_EXTENSION_NAME :: "VK_AMD_anti_lag" +EXT_shader_object :: 1 +EXT_SHADER_OBJECT_SPEC_VERSION :: 1 +EXT_SHADER_OBJECT_EXTENSION_NAME :: "VK_EXT_shader_object" +NV_ray_tracing_invocation_reorder :: 1 +NV_RAY_TRACING_INVOCATION_REORDER_SPEC_VERSION :: 1 +NV_RAY_TRACING_INVOCATION_REORDER_EXTENSION_NAME :: "VK_NV_ray_tracing_invocation_reorder" +NV_cooperative_vector :: 1 +NV_COOPERATIVE_VECTOR_SPEC_VERSION :: 4 +NV_COOPERATIVE_VECTOR_EXTENSION_NAME :: "VK_NV_cooperative_vector" +NV_extended_sparse_address_space :: 1 +NV_EXTENDED_SPARSE_ADDRESS_SPACE_SPEC_VERSION :: 1 +NV_EXTENDED_SPARSE_ADDRESS_SPACE_EXTENSION_NAME :: "VK_NV_extended_sparse_address_space" +EXT_mutable_descriptor_type :: 1 +EXT_MUTABLE_DESCRIPTOR_TYPE_SPEC_VERSION :: 1 +EXT_MUTABLE_DESCRIPTOR_TYPE_EXTENSION_NAME :: "VK_EXT_mutable_descriptor_type" +EXT_legacy_vertex_attributes :: 1 +EXT_LEGACY_VERTEX_ATTRIBUTES_SPEC_VERSION :: 1 +EXT_LEGACY_VERTEX_ATTRIBUTES_EXTENSION_NAME :: "VK_EXT_legacy_vertex_attributes" +EXT_layer_settings :: 1 +EXT_LAYER_SETTINGS_SPEC_VERSION :: 2 +EXT_LAYER_SETTINGS_EXTENSION_NAME :: "VK_EXT_layer_settings" +EXT_pipeline_library_group_handles :: 1 +EXT_PIPELINE_LIBRARY_GROUP_HANDLES_SPEC_VERSION :: 1 +EXT_PIPELINE_LIBRARY_GROUP_HANDLES_EXTENSION_NAME :: "VK_EXT_pipeline_library_group_handles" +EXT_dynamic_rendering_unused_attachments :: 1 +EXT_DYNAMIC_RENDERING_UNUSED_ATTACHMENTS_SPEC_VERSION :: 1 +EXT_DYNAMIC_RENDERING_UNUSED_ATTACHMENTS_EXTENSION_NAME :: "VK_EXT_dynamic_rendering_unused_attachments" +NV_low_latency2 :: 1 +NV_LOW_LATENCY_2_SPEC_VERSION :: 2 +NV_LOW_LATENCY_2_EXTENSION_NAME :: "VK_NV_low_latency2" +NV_per_stage_descriptor_set :: 1 +NV_PER_STAGE_DESCRIPTOR_SET_SPEC_VERSION :: 1 +NV_PER_STAGE_DESCRIPTOR_SET_EXTENSION_NAME :: "VK_NV_per_stage_descriptor_set" +EXT_attachment_feedback_loop_dynamic_state :: 1 +EXT_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_SPEC_VERSION :: 1 +EXT_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_EXTENSION_NAME :: "VK_EXT_attachment_feedback_loop_dynamic_state" +NV_descriptor_pool_overallocation :: 1 +NV_DESCRIPTOR_POOL_OVERALLOCATION_SPEC_VERSION :: 1 +NV_DESCRIPTOR_POOL_OVERALLOCATION_EXTENSION_NAME :: "VK_NV_descriptor_pool_overallocation" +NV_display_stereo :: 1 +NV_DISPLAY_STEREO_SPEC_VERSION :: 1 +NV_DISPLAY_STEREO_EXTENSION_NAME :: "VK_NV_display_stereo" +NV_raw_access_chains :: 1 +NV_RAW_ACCESS_CHAINS_SPEC_VERSION :: 1 +NV_RAW_ACCESS_CHAINS_EXTENSION_NAME :: "VK_NV_raw_access_chains" +NV_command_buffer_inheritance :: 1 +NV_COMMAND_BUFFER_INHERITANCE_SPEC_VERSION :: 1 +NV_COMMAND_BUFFER_INHERITANCE_EXTENSION_NAME :: "VK_NV_command_buffer_inheritance" +NV_shader_atomic_float16_vector :: 1 +NV_SHADER_ATOMIC_FLOAT16_VECTOR_SPEC_VERSION :: 1 +NV_SHADER_ATOMIC_FLOAT16_VECTOR_EXTENSION_NAME :: "VK_NV_shader_atomic_float16_vector" +EXT_shader_replicated_composites :: 1 +EXT_SHADER_REPLICATED_COMPOSITES_SPEC_VERSION :: 1 +EXT_SHADER_REPLICATED_COMPOSITES_EXTENSION_NAME :: "VK_EXT_shader_replicated_composites" +NV_ray_tracing_validation :: 1 +NV_RAY_TRACING_VALIDATION_SPEC_VERSION :: 1 +NV_RAY_TRACING_VALIDATION_EXTENSION_NAME :: "VK_NV_ray_tracing_validation" +NV_cluster_acceleration_structure :: 1 +NV_CLUSTER_ACCELERATION_STRUCTURE_SPEC_VERSION :: 2 +NV_CLUSTER_ACCELERATION_STRUCTURE_EXTENSION_NAME :: "VK_NV_cluster_acceleration_structure" +NV_partitioned_acceleration_structure :: 1 +NV_PARTITIONED_ACCELERATION_STRUCTURE_SPEC_VERSION :: 1 +NV_PARTITIONED_ACCELERATION_STRUCTURE_EXTENSION_NAME :: "VK_NV_partitioned_acceleration_structure" +PARTITIONED_ACCELERATION_STRUCTURE_PARTITION_INDEX_GLOBAL_NV :: ~u32(0) +EXT_device_generated_commands :: 1 +EXT_DEVICE_GENERATED_COMMANDS_SPEC_VERSION :: 1 +EXT_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME :: "VK_EXT_device_generated_commands" +EXT_depth_clamp_control :: 1 +EXT_DEPTH_CLAMP_CONTROL_SPEC_VERSION :: 1 +EXT_DEPTH_CLAMP_CONTROL_EXTENSION_NAME :: "VK_EXT_depth_clamp_control" +NV_cooperative_matrix2 :: 1 +NV_COOPERATIVE_MATRIX_2_SPEC_VERSION :: 1 +NV_COOPERATIVE_MATRIX_2_EXTENSION_NAME :: "VK_NV_cooperative_matrix2" +EXT_vertex_attribute_robustness :: 1 +EXT_VERTEX_ATTRIBUTE_ROBUSTNESS_SPEC_VERSION :: 1 +EXT_VERTEX_ATTRIBUTE_ROBUSTNESS_EXTENSION_NAME :: "VK_EXT_vertex_attribute_robustness" +NV_present_metering :: 1 +NV_PRESENT_METERING_SPEC_VERSION :: 1 +NV_PRESENT_METERING_EXTENSION_NAME :: "VK_NV_present_metering" +KHR_acceleration_structure :: 1 +KHR_ACCELERATION_STRUCTURE_SPEC_VERSION :: 13 +KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME :: "VK_KHR_acceleration_structure" +KHR_ray_tracing_pipeline :: 1 +KHR_RAY_TRACING_PIPELINE_SPEC_VERSION :: 1 +KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME :: "VK_KHR_ray_tracing_pipeline" +KHR_ray_query :: 1 +KHR_RAY_QUERY_SPEC_VERSION :: 1 +KHR_RAY_QUERY_EXTENSION_NAME :: "VK_KHR_ray_query" +EXT_mesh_shader :: 1 +EXT_MESH_SHADER_SPEC_VERSION :: 1 +EXT_MESH_SHADER_EXTENSION_NAME :: "VK_EXT_mesh_shader" +KHR_win32_surface :: 1 +KHR_WIN32_SURFACE_SPEC_VERSION :: 6 +KHR_WIN32_SURFACE_EXTENSION_NAME :: "VK_KHR_win32_surface" +KHR_external_memory_win32 :: 1 +KHR_EXTERNAL_MEMORY_WIN32_SPEC_VERSION :: 1 +KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME :: "VK_KHR_external_memory_win32" +KHR_win32_keyed_mutex :: 1 +KHR_WIN32_KEYED_MUTEX_SPEC_VERSION :: 1 +KHR_WIN32_KEYED_MUTEX_EXTENSION_NAME :: "VK_KHR_win32_keyed_mutex" +KHR_external_semaphore_win32 :: 1 +KHR_EXTERNAL_SEMAPHORE_WIN32_SPEC_VERSION :: 1 +KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME :: "VK_KHR_external_semaphore_win32" +KHR_external_fence_win32 :: 1 +KHR_EXTERNAL_FENCE_WIN32_SPEC_VERSION :: 1 +KHR_EXTERNAL_FENCE_WIN32_EXTENSION_NAME :: "VK_KHR_external_fence_win32" +NV_external_memory_win32 :: 1 +NV_EXTERNAL_MEMORY_WIN32_SPEC_VERSION :: 1 +NV_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME :: "VK_NV_external_memory_win32" +NV_win32_keyed_mutex :: 1 +NV_WIN32_KEYED_MUTEX_SPEC_VERSION :: 2 +NV_WIN32_KEYED_MUTEX_EXTENSION_NAME :: "VK_NV_win32_keyed_mutex" +EXT_full_screen_exclusive :: 1 +EXT_FULL_SCREEN_EXCLUSIVE_SPEC_VERSION :: 4 +EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME :: "VK_EXT_full_screen_exclusive" +NV_acquire_winrt_display :: 1 +NV_ACQUIRE_WINRT_DISPLAY_SPEC_VERSION :: 1 +NV_ACQUIRE_WINRT_DISPLAY_EXTENSION_NAME :: "VK_NV_acquire_winrt_display" +EXT_metal_surface :: 1 +EXT_METAL_SURFACE_SPEC_VERSION :: 1 +EXT_METAL_SURFACE_EXTENSION_NAME :: "VK_EXT_metal_surface" +EXT_metal_objects :: 1 +EXT_METAL_OBJECTS_SPEC_VERSION :: 2 +EXT_METAL_OBJECTS_EXTENSION_NAME :: "VK_EXT_metal_objects" +EXT_external_memory_metal :: 1 +EXT_EXTERNAL_MEMORY_METAL_SPEC_VERSION :: 1 +EXT_EXTERNAL_MEMORY_METAL_EXTENSION_NAME :: "VK_EXT_external_memory_metal" +KHR_wayland_surface :: 1 +KHR_WAYLAND_SURFACE_SPEC_VERSION :: 6 +KHR_WAYLAND_SURFACE_EXTENSION_NAME :: "VK_KHR_wayland_surface" +KHR_xlib_surface :: 1 +KHR_XLIB_SURFACE_SPEC_VERSION :: 6 +KHR_XLIB_SURFACE_EXTENSION_NAME :: "VK_KHR_xlib_surface" +KHR_xcb_surface :: 1 +KHR_XCB_SURFACE_SPEC_VERSION :: 6 +KHR_XCB_SURFACE_EXTENSION_NAME :: "VK_KHR_xcb_surface" +KHR_portability_subset :: 1 +KHR_PORTABILITY_SUBSET_SPEC_VERSION :: 1 +KHR_PORTABILITY_SUBSET_EXTENSION_NAME :: "VK_KHR_portability_subset" +AMDX_shader_enqueue :: 1 +AMDX_SHADER_ENQUEUE_SPEC_VERSION :: 2 +AMDX_SHADER_ENQUEUE_EXTENSION_NAME :: "VK_AMDX_shader_enqueue" +NV_displacement_micromap :: 1 +NV_DISPLACEMENT_MICROMAP_SPEC_VERSION :: 2 +NV_DISPLACEMENT_MICROMAP_EXTENSION_NAME :: "VK_NV_displacement_micromap" // Handles types Instance :: distinct Handle diff --git a/vendor/vulkan/enums.odin b/vendor/vulkan/enums.odin index 418c7c8b1..3b9a1dc34 100644 --- a/vendor/vulkan/enums.odin +++ b/vendor/vulkan/enums.odin @@ -1,6 +1,3 @@ -// -// Vulkan wrapper generated from "https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/master/include/vulkan/vulkan_core.h" -// package vulkan import "core:c" diff --git a/vendor/vulkan/procedures.odin b/vendor/vulkan/procedures.odin index 6a63c83d0..12eedbcfe 100644 --- a/vendor/vulkan/procedures.odin +++ b/vendor/vulkan/procedures.odin @@ -1,6 +1,3 @@ -// -// Vulkan wrapper generated from "https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/master/include/vulkan/vulkan_core.h" -// package vulkan import "core:c" diff --git a/vendor/vulkan/structs.odin b/vendor/vulkan/structs.odin index 7ceac8c82..5391b3319 100644 --- a/vendor/vulkan/structs.odin +++ b/vendor/vulkan/structs.odin @@ -1,6 +1,3 @@ -// -// Vulkan wrapper generated from "https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/master/include/vulkan/vulkan_core.h" -// package vulkan import "core:c" diff --git a/vendor/wgpu/glfwglue/doc.odin b/vendor/wgpu/glfwglue/doc.odin new file mode 100644 index 000000000..65716dd91 --- /dev/null +++ b/vendor/wgpu/glfwglue/doc.odin @@ -0,0 +1,2 @@ +// WGPU glue for GLFW. +package wgpu_glfw_glue \ No newline at end of file diff --git a/vendor/wgpu/sdl2glue/doc.odin b/vendor/wgpu/sdl2glue/doc.odin new file mode 100644 index 000000000..13d7eb103 --- /dev/null +++ b/vendor/wgpu/sdl2glue/doc.odin @@ -0,0 +1,2 @@ +// WGPU glue for SDL2. +package wgpu_sdl2_glue diff --git a/vendor/wgpu/sdl3glue/doc.odin b/vendor/wgpu/sdl3glue/doc.odin new file mode 100644 index 000000000..e95ed5c47 --- /dev/null +++ b/vendor/wgpu/sdl3glue/doc.odin @@ -0,0 +1,2 @@ +// WGPU glue for SDL3. +package wgpu_sdl3_glue \ No newline at end of file diff --git a/vendor/windows/GameInput/doc.odin b/vendor/windows/GameInput/doc.odin new file mode 100644 index 000000000..873062edf --- /dev/null +++ b/vendor/windows/GameInput/doc.odin @@ -0,0 +1,6 @@ +/* + Bindings for [[ Windows Game Input GDK ; https://learn.microsoft.com/en-us/gaming/gdk/_content/gc/input/overviews/input-overview ]]. + + Windows SDK 10.0.26100.0 is at least required to link with. +*/ +package windows_game_input \ No newline at end of file diff --git a/vendor/windows/XAudio2/doc.odin b/vendor/windows/XAudio2/doc.odin new file mode 100644 index 000000000..84ab08c39 --- /dev/null +++ b/vendor/windows/XAudio2/doc.odin @@ -0,0 +1,6 @@ +/* + Bindings for [[ Windows XAudio2 ; https://learn.microsoft.com/en-us/windows/win32/xaudio2/xaudio2-introduction ]]. + + Compiling for Windows 10 RS5 (1809) and later +*/ +package windows_xaudio2 \ No newline at end of file diff --git a/vendor/x11/xlib/xlib.odin b/vendor/x11/xlib/xlib.odin index bd9ba3b59..a2d51c401 100644 --- a/vendor/x11/xlib/xlib.odin +++ b/vendor/x11/xlib/xlib.odin @@ -1,3 +1,4 @@ +// Bindings for [[ X11's Xlib (PDF) ; https://www.x.org/docs/X11/xlib.pdf ]]. package xlib // Value, specifying whether `vendor:x11/xlib` is available on the current platform. diff --git a/vendor/zlib/zlib.odin b/vendor/zlib/zlib.odin index 021449813..4c2ce712a 100644 --- a/vendor/zlib/zlib.odin +++ b/vendor/zlib/zlib.odin @@ -1,3 +1,4 @@ +// Bindings for [[ libz ; https://zlib.net ]] ZLIB compression library. package vendor_zlib import "core:c"