From dbbe96ae5c343f0e803de6ee508207a62571534f Mon Sep 17 00:00:00 2001 From: Courtney Strachan Date: Sun, 2 Mar 2025 07:57:23 -0800 Subject: [PATCH 001/113] Fixed json null value parsing --- core/encoding/json/marshal.odin | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin index 020facd14..ed6de2f52 100644 --- a/core/encoding/json/marshal.odin +++ b/core/encoding/json/marshal.odin @@ -176,7 +176,13 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: return .Unsupported_Type case runtime.Type_Info_Pointer: - return .Unsupported_Type + ptr := a.(rawptr) + + if ptr == nil { + io.write_string(w, "null") or_return + } else { + return .Unsupported_Type + } case runtime.Type_Info_Multi_Pointer: return .Unsupported_Type From 30021e8dac0ff6a9a8ddc023f5a4c3924ebfd7c3 Mon Sep 17 00:00:00 2001 From: Sam Mercer <130914459+smercer10@users.noreply.github.com> Date: Fri, 29 Aug 2025 11:02:30 +0100 Subject: [PATCH 002/113] Fix rbtree.find_or_insert Update the existing node's value if the key is already present and align documentation with behavior. --- core/container/rbtree/rbtree.odin | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/core/container/rbtree/rbtree.odin b/core/container/rbtree/rbtree.odin index 090551367..e9d0d08f4 100644 --- a/core/container/rbtree/rbtree.odin +++ b/core/container/rbtree/rbtree.odin @@ -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 } } From cef381261af9653c61102bf4ebafbcb690b21841 Mon Sep 17 00:00:00 2001 From: Username-Leon Date: Mon, 29 Sep 2025 18:44:07 +0200 Subject: [PATCH 003/113] Fixed vulkan bindings. In vendor/vulkan, vendor constants ending with EXT/AMD/NV/NVX/GOOGLE/KHX (all except KHR) are now present. VK_SHADER_UNUSED_KHR (as well as others previously absent) was improperly translated from (~0U) to 0. Explicit checks for "(~0U)", "(~0UL)" and "(~0ULL)" have been added to produce ~u32(0) and ~u64(0). Hardcoded constants in the bindings generator ending with EXT have been removed as they are now properly caught by the regex. --- .../vulkan/_gen/create_vulkan_odin_wrapper.py | 10 +- vendor/vulkan/core.odin | 2134 +++++++++-------- 2 files changed, 1075 insertions(+), 1069 deletions(-) diff --git a/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py b/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py index 2d78179e7..f06370d12 100644 --- a/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py +++ b/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py @@ -301,7 +301,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 +311,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)" or value == "(~0UL)": + 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") @@ -935,7 +939,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 +949,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 diff --git a/vendor/vulkan/core.odin b/vendor/vulkan/core.odin index a80bdc73b..ad33df148 100644 --- a/vendor/vulkan/core.odin +++ b/vendor/vulkan/core.odin @@ -39,7 +39,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 +49,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 +138,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 From d203dff09f147ffd30a3627de1a31408b6f28688 Mon Sep 17 00:00:00 2001 From: Username-Leon Date: Mon, 29 Sep 2025 19:09:11 +0200 Subject: [PATCH 004/113] Removed 0UL check. Thought unsigned long was consistent across platforms --- vendor/vulkan/_gen/create_vulkan_odin_wrapper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py b/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py index f06370d12..79a022243 100644 --- a/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py +++ b/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py @@ -311,7 +311,7 @@ def parse_constants(f): for name, value in data: value = remove_prefix(value, 'VK_') v = number_suffix_re.findall(value) - if value == "(~0U)" or value == "(~0UL)": + if value == "(~0U)": value = "~u32(0)" elif value == "(~0ULL)": value = "~u64(0)" From 5af13f5d53b4e5f5d472cd8a8bc4444f05ea36d6 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Tue, 16 Sep 2025 00:49:31 -0400 Subject: [PATCH 005/113] Automatically emit objc_msgSend calls when calling imported or implemented Objective-C methods - Add intrinsics.objc_super() - Emit objc_msgSendSuper2 calls when an objc method call is combined with objc_super(self) - Fix objc_block return value ABI for large struct returns - Fix objc_implement method wrappers bad ABI for large struct returns and indirect args - Simplify parameter forwarding for objc_imlpement methods - Add intrinsics.objc_instancetype to mimi Objective-C instancetype* returns This facilitates returning the correct type on subclasses when calling mehtods such as `alloc`, `init`, `retain`, etc. - Refactor Objective-C class implementations generation so that hierarchies are properly initialized - Better codegen for context passing with ivar-based autocontext - Allow @superclass on imported objc-c objects - Better codegen for block forwarding invoker, arguments are forwarded directly --- base/intrinsics/intrinsics.odin | 10 +- base/runtime/procs_darwin.odin | 16 ++- src/check_builtin.cpp | 59 ++++++++- src/check_decl.cpp | 128 ++++++++++++------- src/check_expr.cpp | 73 +++++++++++ src/checker.cpp | 8 ++ src/checker_builtin_procs.hpp | 4 +- src/entity.cpp | 4 + src/llvm_backend.cpp | 170 +++++++++++++++++-------- src/llvm_backend_proc.cpp | 22 +++- src/llvm_backend_utility.cpp | 218 +++++++++++++++++++++++++++----- src/parser.hpp | 3 +- src/types.cpp | 11 ++ 13 files changed, 575 insertions(+), 151 deletions(-) diff --git a/base/intrinsics/intrinsics.odin b/base/intrinsics/intrinsics.odin index 2d940cf67..dd508180d 100644 --- a/base/intrinsics/intrinsics.odin +++ b/base/intrinsics/intrinsics.odin @@ -374,10 +374,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 +386,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/procs_darwin.odin b/base/runtime/procs_darwin.odin index d176f0f63..cc3dabc9b 100644 --- a/base/runtime/procs_darwin.odin +++ b/base/runtime/procs_darwin.odin @@ -15,16 +15,23 @@ 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) --- + objc_msgSendSuper2 :: proc "c" (super: ^objc_super, op: objc_SEL, #c_vararg args: ..any) --- + 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 +40,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/src/check_builtin.cpp b/src/check_builtin.cpp index 7e1567750..f142f04b7 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -210,7 +210,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 +248,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 +472,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 +686,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; } } @@ -2515,6 +2567,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: diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 842f8653c..113c1e171 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -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"); @@ -1040,61 +1038,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)); @@ -1479,7 +1516,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 { @@ -1527,6 +1564,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 2a22e5c48..5f36bf3a1 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -8151,6 +8151,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 && @@ -8414,6 +8481,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..d3c111de4 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); } } @@ -3386,12 +3388,18 @@ 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) { + 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) { diff --git a/src/checker_builtin_procs.hpp b/src/checker_builtin_procs.hpp index c6071bf98..c2255a6ba 100644 --- a/src/checker_builtin_procs.hpp +++ b/src/checker_builtin_procs.hpp @@ -354,6 +354,7 @@ BuiltinProc__type_end, BuiltinProc_objc_register_class, BuiltinProc_objc_ivar_get, BuiltinProc_objc_block, + BuiltinProc_objc_super, BuiltinProc_constant_utf16_cstring, @@ -715,7 +716,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/llvm_backend.cpp b/src/llvm_backend.cpp index b47e2788f..86c83b91f 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; @@ -2192,6 +2251,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_proc.cpp b/src/llvm_backend_proc.cpp index 7680c5e76..3bd5f4ef2 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -3753,6 +3753,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: @@ -4122,21 +4123,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->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); @@ -4170,11 +4173,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; @@ -4402,6 +4407,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 7fe6b1458..d124f164e 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -2373,7 +2373,7 @@ 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 - + // TODO(harold): Ensure we don't have any issues with large struct arguments or returns in block wrappers. ast_node(ce, CallExpr, expr); GB_ASSERT(ce->args.count > 0); @@ -2452,7 +2452,9 @@ 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_"); @@ -2531,45 +2533,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); @@ -2587,8 +2610,8 @@ 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); - 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 +2619,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 +2634,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 +2674,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 +2803,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.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..372c2e991 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -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 @@ -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); From 6d9ace4a2cd4a05af5ce46d6975108a0cc5c0086 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Mon, 29 Sep 2025 15:58:30 -0400 Subject: [PATCH 006/113] Remove outdated todo --- src/llvm_backend_utility.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index d124f164e..10a258ab1 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -2373,7 +2373,6 @@ 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 - // TODO(harold): Ensure we don't have any issues with large struct arguments or returns in block wrappers. ast_node(ce, CallExpr, expr); GB_ASSERT(ce->args.count > 0); From 9425954861b028d289c03a06ca7cd8f3be4c1fdb Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Mon, 29 Sep 2025 16:04:30 -0400 Subject: [PATCH 007/113] Ignore patterns for local development in CMake --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index be3e78954..7057aea2c 100644 --- a/.gitignore +++ b/.gitignore @@ -302,3 +302,8 @@ misc/featuregen/featuregen .cache/ .clangd compile_commands.json + +# Dev cmake helpers +build/ +cmake-build*/ +CMakeLists.txt From 481deee4ae409b495fff089c08b6acd9f552a7b3 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Mon, 29 Sep 2025 20:15:46 -0400 Subject: [PATCH 008/113] Fix entity nullptr check --- .gitignore | 1 + src/llvm_backend_proc.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 7057aea2c..4efb5d73e 100644 --- a/.gitignore +++ b/.gitignore @@ -307,3 +307,4 @@ compile_commands.json build/ cmake-build*/ CMakeLists.txt +sandbox/ diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 3bd5f4ef2..08ef42f01 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -4135,7 +4135,7 @@ gb_internal lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr) { return lb_build_builtin_proc(p, expr, tv, id); } - bool is_objc_call = proc_entity->Procedure.is_objc_impl_or_import; + bool is_objc_call = proc_entity && proc_entity->Procedure.is_objc_impl_or_import; // NOTE(bill): Regular call lbValue value = {}; From fc44b104315ddac114ae756f5d3f1ed236636782 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Mon, 29 Sep 2025 20:20:54 -0400 Subject: [PATCH 009/113] Include objc runtime type dependencies only on darwin --- src/checker.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/checker.cpp b/src/checker.cpp index d3c111de4..0a8590570 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -3389,8 +3389,10 @@ gb_internal void init_core_map_type(Checker *c) { } gb_internal void init_core_objc_c(Checker *c) { - t_objc_super = find_core_type(c, str_lit("objc_super")); - t_objc_super_ptr = alloc_type_pointer(t_objc_super); + 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) { From 8908e82258fff7df9dfea6a65e3d622deb6e19cc Mon Sep 17 00:00:00 2001 From: 149-code Date: Mon, 29 Sep 2025 23:36:14 -0500 Subject: [PATCH 010/113] Removed unused pBufferOut parameters --- vendor/miniaudio/data_conversion.odin | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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. */ From 2daaf57ad1f0b0cd166704f808736ddf7f603e23 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Tue, 30 Sep 2025 14:15:14 -0400 Subject: [PATCH 011/113] Correct signature (missing return value) for `objc_msgSendSuper2` --- base/runtime/procs_darwin.odin | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/base/runtime/procs_darwin.odin b/base/runtime/procs_darwin.odin index cc3dabc9b..0ffe68e49 100644 --- a/base/runtime/procs_darwin.odin +++ b/base/runtime/procs_darwin.odin @@ -29,7 +29,9 @@ foreign ObjC { 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_msgSendSuper2 :: proc "c" (super: ^objc_super, 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) --- From 588513a510f5906d214633bfcdce6b4441e900bb Mon Sep 17 00:00:00 2001 From: Jakub Tomsu Date: Wed, 1 Oct 2025 15:54:32 +0200 Subject: [PATCH 012/113] bitcast only non-pointer-like-element simd vectors, handle others like other aggregate types --- src/llvm_backend_utility.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index 155c55675..1abbf60bc 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))) { From 0158e4009b7bbb68a378037ecb33bd2a836cae2f Mon Sep 17 00:00:00 2001 From: xenobas Date: Wed, 1 Oct 2025 18:01:10 +0100 Subject: [PATCH 013/113] Fix proc group named operands issue #4971 --- src/check_expr.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/check_expr.cpp b/src/check_expr.cpp index c1861652a..fa9de90bb 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -7488,8 +7488,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, From a39697d84c47dfbb9179bcaacdced447b686adf2 Mon Sep 17 00:00:00 2001 From: Franz Hoeltermann Date: Thu, 2 Oct 2025 17:31:59 +0200 Subject: [PATCH 014/113] Fix srgb <-> linear rgb conversion functions in `core:math/linalg` and add implementations for vector3 --- core/math/linalg/specific.odin | 135 ++++++++++++++++++--------------- 1 file changed, 75 insertions(+), 60 deletions(-) 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 { From 01bbd981adccc63e9934a2ad7760985d029d6807 Mon Sep 17 00:00:00 2001 From: samwega Date: Fri, 3 Oct 2025 20:54:18 +0300 Subject: [PATCH 015/113] short C names deprecated (itoa, ftoa), C reimplementations of atoi and atof deprecated as parse_int() and parse_f64() are preferable --- core/strconv/deprecated.odin | 24 +++++++++++++++ core/strconv/strconv.odin | 60 ++++-------------------------------- 2 files changed, 30 insertions(+), 54 deletions(-) diff --git a/core/strconv/deprecated.odin b/core/strconv/deprecated.odin index 883822e4b..20cd2642e 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 int_to_string 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 parse_f64() instead") +atof :: proc(s: string) -> f64 { + v, _ := parse_f64(s) + return v +} + +@(deprecated="Use 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..e7de67c42 100644 --- a/core/strconv/strconv.odin +++ b/core/strconv/strconv.odin @@ -1547,6 +1547,8 @@ write_u128 :: proc(buf: []byte, u: u128, base: int) -> string { } /* +`itoa` C name deprecated, use `int_to_string` instead (same procedure) + Converts an integer value to a string and stores it in the given buffer **Inputs** @@ -1557,9 +1559,9 @@ Example: import "core:fmt" import "core:strconv" - itoa_example :: proc() { + int_to_string_example :: proc() { buf: [4]byte - result := strconv.itoa(buf[:], 42) + result := strconv.int_to_string(buf[:], 42) fmt.println(result, buf) // "42" } @@ -1570,62 +1572,12 @@ Output: **Returns** - The resulting string after converting the integer value */ -itoa :: proc(buf: []byte, i: int) -> string { +int_to_string :: proc(buf: []byte, i: int) -> string { return write_int(buf, i64(i), 10) } /* -Converts a string to an integer value +`ftoa` C name deprecated, use `int_to_string` instead (same procedure) -**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** From 2af3f280bf232274d8f5aa32b7f3ded53e0b5061 Mon Sep 17 00:00:00 2001 From: samwega Date: Fri, 3 Oct 2025 21:14:00 +0300 Subject: [PATCH 016/113] Tetralux asked for int_tostring() to also be deprecated, use write_int() instead. --- core/strconv/deprecated.odin | 6 +++--- core/strconv/strconv.odin | 29 ----------------------------- 2 files changed, 3 insertions(+), 32 deletions(-) diff --git a/core/strconv/deprecated.odin b/core/strconv/deprecated.odin index 20cd2642e..c644d331e 100644 --- a/core/strconv/deprecated.odin +++ b/core/strconv/deprecated.odin @@ -39,7 +39,7 @@ append_float :: proc(buf: []byte, f: f64, fmt: byte, prec, bit_size: int) -> str // 2025-10-03 Deprecated C short names and implementations -@(deprecated="Use int_to_string instead") +@(deprecated="Use strconv.write_int() instead") itoa :: proc(buf: []byte, i: int) -> string { return write_int(buf, i64(i), 10) } @@ -50,13 +50,13 @@ atoi :: proc(s: string) -> int { return v } -@(deprecated="Use parse_f64() instead") +@(deprecated="Use strconv.parse_f64() instead") atof :: proc(s: string) -> f64 { v, _ := parse_f64(s) return v } -@(deprecated="Use write_float instead") +@(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 e7de67c42..8680542ee 100644 --- a/core/strconv/strconv.odin +++ b/core/strconv/strconv.odin @@ -1546,35 +1546,6 @@ write_u128 :: proc(buf: []byte, u: u128, base: int) -> string { return write_bits_128(buf, u, base, false, 8*size_of(uint), digits, nil) } -/* -`itoa` C name deprecated, use `int_to_string` instead (same procedure) - -Converts an integer value to a string and stores it in the given buffer - -**Inputs** -- buf: The buffer to store the resulting string -- i: The integer value to be converted - -Example: - - import "core:fmt" - import "core:strconv" - int_to_string_example :: proc() { - buf: [4]byte - result := strconv.int_to_string(buf[:], 42) - fmt.println(result, buf) // "42" - } - -Output: - - 42 [52, 50, 0, 0] - -**Returns** -- The resulting string after converting the integer value -*/ -int_to_string :: proc(buf: []byte, i: int) -> string { - return write_int(buf, i64(i), 10) -} /* `ftoa` C name deprecated, use `int_to_string` instead (same procedure) From bbf297f2653cc565da932277b99c929e1e399faf Mon Sep 17 00:00:00 2001 From: samwega Date: Fri, 3 Oct 2025 21:18:38 +0300 Subject: [PATCH 017/113] fix: copy/paste error --- core/strconv/strconv.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/strconv/strconv.odin b/core/strconv/strconv.odin index 8680542ee..7fcb578f7 100644 --- a/core/strconv/strconv.odin +++ b/core/strconv/strconv.odin @@ -1547,7 +1547,7 @@ write_u128 :: proc(buf: []byte, u: u128, base: int) -> string { } /* -`ftoa` C name deprecated, use `int_to_string` instead (same procedure) +`ftoa` C name deprecated, use `write_float` instead (same procedure) Writes a float64 value as a string to the given buffer with the specified format and precision From 83d36451a334f500a15eb6e8b55a810fbd5681d3 Mon Sep 17 00:00:00 2001 From: samwega Date: Fri, 3 Oct 2025 22:13:03 +0300 Subject: [PATCH 018/113] os_linux.odin was using itoa, changed to use write_int() --- core/os/os_linux.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/os/os_linux.odin b/core/os/os_linux.odin index 15d230820..1b53183c2 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(int)fd, 10 ) procfs_path := strings.concatenate( []string{ "/proc/self/fd/", fd_str } ) defer delete(procfs_path) From 9e9d41ddfd30257006f66709f2ba0222381c615d Mon Sep 17 00:00:00 2001 From: samwega Date: Fri, 3 Oct 2025 22:17:25 +0300 Subject: [PATCH 019/113] fix: cars i64 instead of int --- core/os/os_linux.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/os/os_linux.odin b/core/os/os_linux.odin index 1b53183c2..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.write_int( buf[:], cast(int)fd, 10 ) + fd_str := strconv.write_int( buf[:], cast(i64)fd, 10 ) procfs_path := strings.concatenate( []string{ "/proc/self/fd/", fd_str } ) defer delete(procfs_path) From 9da10dece2da04ab47771fa66e2f4e355573d891 Mon Sep 17 00:00:00 2001 From: samwega Date: Fri, 3 Oct 2025 22:26:24 +0300 Subject: [PATCH 020/113] fix: another itoa() used in path_linux.odin had to be replaced with write_int() --- core/os/os2/path_linux.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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) From 7237747ee7f8c53285dc8138cfad9402be1bf77d Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Sun, 5 Oct 2025 15:19:58 +0200 Subject: [PATCH 021/113] Try fix macOS Intel nightlies. --- .github/workflows/nightly.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 From 61db9c71f697233773764e51830e413b6bb487f4 Mon Sep 17 00:00:00 2001 From: xenobas Date: Sun, 5 Oct 2025 15:46:02 +0100 Subject: [PATCH 022/113] Fix non infix params with default value exclusion counting --- src/check_expr.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/check_expr.cpp b/src/check_expr.cpp index c6f7e022e..fbd2a815c 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -6211,7 +6211,6 @@ gb_internal isize get_procedure_param_count_excluding_defaults(Type *pt, isize * continue; } } - break; } } From 3edf964b55f3402670de9337dd83cf374932c2bd Mon Sep 17 00:00:00 2001 From: xenobas Date: Sun, 5 Oct 2025 20:18:41 +0100 Subject: [PATCH 023/113] Fix #5225 wasm odin.js undefined this.mem --- core/sys/wasm/js/odin.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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; } } From 86f9c920dafc40c6bb1eb5cc5461b20ca954459c Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Sun, 5 Oct 2025 15:50:01 -0400 Subject: [PATCH 024/113] Fix Objective-C block symbols naming conflict across modules. Fix assert triggered when there's checker errors and Objective-C method implementations. --- src/checker.cpp | 5 ++++- src/llvm_backend.hpp | 2 +- src/llvm_backend_utility.cpp | 21 +++++++++++---------- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/checker.cpp b/src/checker.cpp index 0a8590570..2a82203ef 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1501,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); diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index 6870f6259..6a4616694 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 + std::atomic objc_next_block_id; // Used to name objective-c blocks. IMPORTANT: Tracked on the main 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_utility.cpp b/src/llvm_backend_utility.cpp index ca7bf34e3..60dcf0992 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -2271,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(), ""), "__$objc_block_copy_helper_%lld", block_id); + gbString dispose_helper_name = gb_string_append_fmt(gb_string_make(temporary_allocator(), ""), "__$objc_block_dispose_helper_%lld", block_id); // copy: Block_Literal *dst, Block_Literal *src, i32 field_apropos // dispose: Block_Literal *src, i32 field_apropos @@ -2385,7 +2385,8 @@ gb_internal lbValue lb_handle_objc_block(lbProcedure *p, Ast *expr) { lbModule *m = p->module; - m->objc_next_block_id += 1; + lbModule *default_module = &m->gen->default_module; + const isize block_id = default_module->objc_next_block_id++; const isize capture_arg_count = ce->args.count - 1; @@ -2431,7 +2432,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(), ""), "__$objc_block_invoker_%lld", 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); @@ -2464,10 +2465,10 @@ gb_internal lbValue lb_handle_objc_block(lbProcedure *p, Ast *expr) { // 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); + block_lit_type_name = gb_string_append_fmt(block_lit_type_name, "%lld", 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); + block_desc_type_name = gb_string_append_fmt(block_desc_type_name, "%lld", block_id); LLVMTypeRef block_lit_type = {}; LLVMTypeRef block_desc_type = {}; @@ -2511,7 +2512,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); @@ -2530,7 +2531,7 @@ 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); + desc_global_name = gb_string_append_fmt(desc_global_name, "%lld", block_id); LLVMValueRef p_descriptor = LLVMAddGlobal(m->mod, block_desc_type, desc_global_name); LLVMSetInitializer(p_descriptor, block_desc_initializer); @@ -2614,7 +2615,7 @@ 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 block_result = {}; block_result.type = block_result_type; From e79e53dbbd4cd3298dab3ec05ca70abfc998d377 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Sun, 5 Oct 2025 16:14:32 -0400 Subject: [PATCH 025/113] Use module-prefixed naming scheme for tracking objc block instead of shared id counter. --- src/llvm_backend.hpp | 2 +- src/llvm_backend_utility.cpp | 22 ++++++++++------------ 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index 6a4616694..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; - std::atomic objc_next_block_id; // Used to name objective-c blocks. IMPORTANT: Tracked on the main 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_utility.cpp b/src/llvm_backend_utility.cpp index 60dcf0992..2cddd23d9 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -2275,8 +2275,8 @@ gb_internal void lb_create_objc_block_helper_procs( 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", block_id); - gbString dispose_helper_name = gb_string_append_fmt(gb_string_make(temporary_allocator(), ""), "__$objc_block_dispose_helper_%lld", 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 @@ -2385,9 +2385,7 @@ gb_internal lbValue lb_handle_objc_block(lbProcedure *p, Ast *expr) { lbModule *m = p->module; - lbModule *default_module = &m->gen->default_module; - const isize block_id = default_module->objc_next_block_id++; - + 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); @@ -2432,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", 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); @@ -2464,11 +2462,11 @@ gb_internal lbValue lb_handle_objc_block(lbProcedure *p, Ast *expr) { 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", 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", 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 = {}; @@ -2530,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", 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); From 69ad94d8a8c6b96952224faa259a4edbce8eabb0 Mon Sep 17 00:00:00 2001 From: Courtney Strachan Date: Sun, 5 Oct 2025 19:22:04 -0700 Subject: [PATCH 026/113] Followup fix to #4895 --- core/encoding/json/marshal.odin | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin index 2fb507edf..e563c326a 100644 --- a/core/encoding/json/marshal.odin +++ b/core/encoding/json/marshal.odin @@ -176,9 +176,7 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: return .Unsupported_Type case runtime.Type_Info_Pointer: - ptr := a.(rawptr) - - if ptr == nil { + if v.id == typeid_of(Null) { io.write_string(w, "null") or_return } else { return .Unsupported_Type From 866486fa1cfac6ea55b78531703214cae3e4ed4a Mon Sep 17 00:00:00 2001 From: A1029384756 Date: Mon, 6 Oct 2025 00:12:31 -0400 Subject: [PATCH 027/113] [llvm-14-entry-fix] bitcast context pointer to match types for llvm 14 --- src/llvm_backend.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index ab0811085..1e8280a2e 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -2041,7 +2041,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); } From 1708cb556a673b237facb86328819849dfb35007 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 7 Oct 2025 09:10:34 +0100 Subject: [PATCH 028/113] Improve docs for `core:bufio`; Rename `scanner_scan` -> `scan` (keep alias of old name) --- core/bufio/reader.odin | 4 ++++ core/bufio/scanner.odin | 28 +++++++++++++++++++++------- core/bufio/writer.odin | 2 ++ 3 files changed, 27 insertions(+), 7 deletions(-) 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 = {} From 5a12ccef44972c5172bdd6e886e5bf7d69a892f1 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 7 Oct 2025 09:37:52 +0100 Subject: [PATCH 029/113] Add `unicode.simple_fold`; Finish `(strings|bytes).equal_fold` --- core/unicode/fold.odin | 79 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 core/unicode/fold.odin diff --git a/core/unicode/fold.odin b/core/unicode/fold.odin new file mode 100644 index 000000000..edd8a3156 --- /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 { + 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) +} From fb93713f249c56258f67b7c22f0c207e4e11e246 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 7 Oct 2025 09:45:54 +0100 Subject: [PATCH 030/113] Add `@(rodata)` and `@(require_results)` to `core:text/match` --- core/text/match/strlib.odin | 76 +++++++++++++++++++++++++------------ 1 file changed, 51 insertions(+), 25 deletions(-) diff --git a/core/text/match/strlib.odin b/core/text/match/strlib.odin index 819f464c5..bfb66ca5d 100644 --- a/core/text/match/strlib.odin +++ b/core/text/match/strlib.odin @@ -9,11 +9,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 { @@ -33,12 +34,13 @@ CAP_UNFINISHED :: -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 +67,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 +96,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 +110,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 +126,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 +138,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 +149,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 +164,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 +176,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 +211,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 +254,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 @@ -261,6 +276,7 @@ single_match :: proc(ms: ^Match_State, s, p, ep: int) -> (matched: bool, schar_s 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,6 +316,7 @@ 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 @@ -331,6 +348,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 @@ -352,6 +370,7 @@ min_expand :: proc(ms: ^Match_State, s, p, ep: int) -> (res: int, err: Error) { } } +@(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 @@ -486,6 +508,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 @@ -521,6 +544,7 @@ match_default :: proc(ms: ^Match_State, s, p: int) -> (unused: int, err: Error) 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 { @@ -542,6 +566,7 @@ push_onecapture :: proc(ms: ^Match_State, i: int, s: int, e: int, matches: []M return } +@(require_results) push_captures :: proc( ms: ^Match_State, s: int, @@ -559,6 +584,7 @@ push_captures :: proc( // SPECIALS := "^$*+?.([%-" // all special characters inside a small ascii array +@(rodata) SPECIALS_TABLE := [256]bool { '^' = true, '$' = true, @@ -573,6 +599,7 @@ SPECIALS_TABLE := [256]bool { } // helper call to quick search for special characters +@(require_results) index_special :: proc(text: string) -> int { for i in 0.. int { return -1 } +@(require_results) lmem_find :: proc(s1, s2: string) -> int { l1 := len(s1) l2 := len(s2) @@ -618,6 +646,7 @@ lmem_find :: proc(s1, s2: string) -> int { // find a pattern with in a haystack with an offset // allow_memfind will speed up simple searches +@(require_results) find_aux :: proc( haystack: string, pattern: string, @@ -684,6 +713,7 @@ find_aux :: proc( // rest has to be used from captures // assumes captures is zeroed on first iteration // resets captures to zero on last iteration +@(require_results) gmatch :: proc( haystack: ^string, pattern: string, @@ -707,6 +737,7 @@ gmatch :: proc( } // gsub with builder, replace patterns found with the replace content +@(require_results) gsub_builder :: proc( builder: ^strings.Builder, haystack: string, @@ -746,6 +777,7 @@ gsub_builder :: proc( } // uses temp builder to build initial string - then allocates the result +@(require_results) gsub_allocator :: proc( haystack: string, pattern: string, @@ -768,12 +800,7 @@ 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 @@ -800,11 +827,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 +846,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 +871,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 +896,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,6 +906,7 @@ 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, @@ -902,6 +923,7 @@ 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, @@ -917,6 +939,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 +947,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 +957,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 +987,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] } From 787c3a7298b5df1482ab1e916f8a5f11283e7fd4 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 7 Oct 2025 09:50:05 +0100 Subject: [PATCH 031/113] Remove `@(require_results)` on `find_aux` --- core/text/match/strlib.odin | 1 - 1 file changed, 1 deletion(-) diff --git a/core/text/match/strlib.odin b/core/text/match/strlib.odin index bfb66ca5d..a711dc60c 100644 --- a/core/text/match/strlib.odin +++ b/core/text/match/strlib.odin @@ -646,7 +646,6 @@ lmem_find :: proc(s1, s2: string) -> int { // find a pattern with in a haystack with an offset // allow_memfind will speed up simple searches -@(require_results) find_aux :: proc( haystack: string, pattern: string, From 66401b2e7379e71e146f687f151dc13366933711 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 7 Oct 2025 10:16:13 +0100 Subject: [PATCH 032/113] Minor formatting changes --- core/text/match/strlib.odin | 159 +++++++++++++++--------------------- 1 file changed, 65 insertions(+), 94 deletions(-) diff --git a/core/text/match/strlib.odin b/core/text/match/strlib.odin index a711dc60c..05f907bb6 100644 --- a/core/text/match/strlib.odin +++ b/core/text/match/strlib.odin @@ -28,10 +28,10 @@ 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, @@ -269,8 +269,10 @@ 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 @@ -323,7 +325,6 @@ max_expand :: proc(ms: ^Match_State, s, p, ep: int) -> (res: int, err: Error) { // count up matches for { matched, size := single_match(ms, m, p, ep) or_return - if !matched { break } @@ -333,7 +334,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 } @@ -357,15 +357,14 @@ 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 } } } @@ -453,7 +452,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) @@ -482,7 +480,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) @@ -518,8 +516,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 @@ -528,16 +528,16 @@ 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) } } @@ -557,9 +557,12 @@ 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 } } } @@ -567,13 +570,8 @@ push_onecapture :: proc(ms: ^Match_State, i: int, s: int, e: int, matches: []M } @(require_results) -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 +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 { 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 @@ -646,36 +643,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, } @@ -713,11 +702,7 @@ find_aux :: proc( // assumes captures is zeroed on first iteration // resets captures to zero on last iteration @(require_results) -gmatch :: proc( - haystack: ^string, - pattern: string, - captures: ^[MAX_CAPTURES]Match, -) -> (res: string, ok: bool) { +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) @@ -737,24 +722,16 @@ gmatch :: proc( // gsub with builder, replace patterns found with the replace content @(require_results) -gsub_builder :: proc( - builder: ^strings.Builder, - haystack: string, - pattern: string, - replace: string, -) -> string { +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 {} } @@ -777,21 +754,16 @@ gsub_builder :: proc( // uses temp builder to build initial string - then allocates the result @(require_results) -gsub_allocator :: proc( - haystack: string, - pattern: string, - replace: string, - allocator := context.allocator, -) -> string { +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 @@ -806,8 +778,7 @@ gsub_with :: proc(haystack, pattern: string, data: rawptr, call: Gsub_Proc) { for { length := find_aux(haystack, pattern, 0, false, &captures) or_break - // done - if length == 0 { + if length == 0 { // done break } @@ -911,8 +882,8 @@ matcher_find :: proc(matcher: ^Matcher) -> (start, end: int, ok: bool) #no_bound 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] @@ -928,8 +899,8 @@ matcher_match :: proc(matcher: ^Matcher) -> (word: string, ok: bool) #no_bounds_ 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] From d343afbad536da0bdbe6799003df1255dc53a963 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 7 Oct 2025 10:34:48 +0100 Subject: [PATCH 033/113] Improve core_builtin.odin docs --- base/runtime/core_builtin.odin | 113 +++++++++++++++++++++++++++------ 1 file changed, 94 insertions(+), 19 deletions(-) diff --git a/base/runtime/core_builtin.odin b/base/runtime/core_builtin.odin index d63d9e72a..9f3fcbf9a 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 { @@ -564,6 +566,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 { @@ -575,6 +578,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 { @@ -613,6 +619,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 { @@ -624,6 +633,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 { @@ -640,10 +652,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) @@ -651,6 +669,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 @@ -665,7 +685,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, @@ -674,7 +695,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, @@ -684,6 +706,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 { @@ -695,6 +719,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 { @@ -716,6 +741,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 { @@ -742,6 +768,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 { @@ -766,10 +793,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) { @@ -784,6 +814,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) @@ -800,7 +832,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) @@ -817,7 +850,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, +} @@ -834,6 +874,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 { @@ -868,11 +910,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) @@ -921,28 +973,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) } @@ -1023,6 +1080,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)) @@ -1030,6 +1088,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) { @@ -1050,9 +1112,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 { @@ -1068,6 +1130,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 @@ -1077,6 +1141,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 @@ -1086,7 +1152,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) { @@ -1103,6 +1172,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 { @@ -1114,11 +1185,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) From 47cfee1f6247abe4eb904cb128d0c907b5958a8b Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 7 Oct 2025 10:38:50 +0100 Subject: [PATCH 034/113] Add docs to `nil_allocator` and `panic_allocator` --- base/runtime/default_allocators_nil.odin | 11 +++++++++++ 1 file changed, 11 insertions(+) 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{ From a4a74442cec9cd8c8956032d0e910862e944f9bf Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 7 Oct 2025 10:41:52 +0100 Subject: [PATCH 035/113] Add some basic docs to `Default_Temp_Allocator` --- base/runtime/default_temporary_allocator.odin | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/base/runtime/default_temporary_allocator.odin b/base/runtime/default_temporary_allocator.odin index ec3c6ad8c..2017570bb 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, } From 1a90b06fac6a2e8370b8d74c8f0dfb34e445a436 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 7 Oct 2025 11:49:56 +0100 Subject: [PATCH 036/113] Improve documentation for `core:reflect` --- core/reflect/doc.odin | 52 +++++++++ core/reflect/iterator.odin | 8 ++ core/reflect/reflect.odin | 234 ++++++++++++++++++++++++++++++++----- core/reflect/types.odin | 65 +++++++++++ 4 files changed, 330 insertions(+), 29 deletions(-) create mode 100644 core/reflect/doc.odin diff --git a/core/reflect/doc.odin b/core/reflect/doc.odin new file mode 100644 index 000000000..2006f3d3f --- /dev/null +++ b/core/reflect/doc.odin @@ -0,0 +1,52 @@ +// Package reflect provides 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)) +// +// Example: +// a: any = 123 +// // equivalent to +// a: any +// tmp: int = 123 +// a.data = &tmp +// a.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..86fa9d4b5 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` whether 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` whether 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 possbiel. 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 { @@ -381,14 +461,16 @@ deref :: proc(val: any) -> any { // 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: +// v := struct_field_value_by_name(the_struct, field) +// nested_value_through_using := struct_field_value_by_name(the_struct, field, allow_using=true) @(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_Type` 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 return. Otherwise an empty string is returned. +// This is just a wrapper around `struct_tag_lookup` with the `ok` value being ignored. +// +// The convention for 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) } +// 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 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 "" } @@ -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]) } +// 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") } +// Checks to see if the data stored is a bit_set and is big_ending. 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 } @@ -1543,6 +1698,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 +1708,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 +1725,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 +1737,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 +1765,12 @@ 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 +1865,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..fc983df3b 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 == .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 From 56f275bc7109b5102e4fc2394584827bdb8fbc59 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 7 Oct 2025 11:52:49 +0100 Subject: [PATCH 037/113] Fix typo --- core/reflect/types.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/reflect/types.odin b/core/reflect/types.odin index fc983df3b..2e82e29b1 100644 --- a/core/reflect/types.odin +++ b/core/reflect/types.odin @@ -293,7 +293,7 @@ is_string16 :: proc(info: ^Type_Info) -> bool { 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 == .UTF_16 + return ok && v.is_cstring && v.encoding == .UTF_16 } // Returns true the base-type is a boolean of any kind, false otherwise. From d14576e8437ea08d43e0fb378391f34de6e591a8 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 7 Oct 2025 12:00:59 +0100 Subject: [PATCH 038/113] Space to tabs --- core/reflect/doc.odin | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/core/reflect/doc.odin b/core/reflect/doc.odin index 2006f3d3f..92fa9ff52 100644 --- a/core/reflect/doc.odin +++ b/core/reflect/doc.odin @@ -29,20 +29,20 @@ // 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)) +// x: int = 123 +// a: any = x +// // equivalent to +// a: any +// a.data = &x +// a.id = typeid_of(type_of(x)) // // Example: -// a: any = 123 -// // equivalent to -// a: any -// tmp: int = 123 -// a.data = &tmp -// a.id = typeid_of(type_of(tmp)) +// a: any = 123 +// // equivalent to +// a: any +// tmp: int = 123 +// a.data = &tmp +// a.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 From 1400952530a24f5c2926de7a7ac414bd4a947e7a Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 7 Oct 2025 12:07:40 +0100 Subject: [PATCH 039/113] Merge examples --- core/reflect/doc.odin | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/core/reflect/doc.odin b/core/reflect/doc.odin index 92fa9ff52..1c94f3dbc 100644 --- a/core/reflect/doc.odin +++ b/core/reflect/doc.odin @@ -35,14 +35,13 @@ // a: any // a.data = &x // a.id = typeid_of(type_of(x)) -// -// Example: -// a: any = 123 +// // With literals +// v: any = 123 // // equivalent to -// a: any -// tmp: int = 123 -// a.data = &tmp -// a.id = typeid_of(type_of(tmp)) +// 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 From f40fc2792f01b1fa265f62fb2aa4ef39e7529903 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 7 Oct 2025 12:38:01 +0100 Subject: [PATCH 040/113] Replace normal sort procedure with a simpler unified type-erased one --- core/slice/sort.odin | 149 ++++++++++- core/slice/sort_private.odin | 494 ++++++++++++----------------------- 2 files changed, 309 insertions(+), 334 deletions(-) diff --git a/core/slice/sort.odin b/core/slice/sort.odin index 3b4119afa..b613ff1ed 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) } } } @@ -79,7 +90,18 @@ 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)^ + x, y := data[xi], data[yi] + if x < y { + return .Less + } else if x > y { + return .Greater + } + return .Equal + }, raw_data(data)) } return indices } @@ -91,7 +113,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 +159,55 @@ 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) + } + } + 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) } } return indices @@ -115,11 +216,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 { 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 From b90c8063867574982c139341679e86fcc0075aee Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 7 Oct 2025 12:42:50 +0100 Subject: [PATCH 041/113] Remove `context._internal` usage --- core/slice/sort.odin | 65 +++++++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/core/slice/sort.odin b/core/slice/sort.odin index b613ff1ed..7485679c8 100644 --- a/core/slice/sort.odin +++ b/core/slice/sort.odin @@ -325,36 +325,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 { + x, y := (^E)(lhs)^, (^E)(rhs)^ + + ctx := (^Context)(user_data) + a := k(i) + b := k(j) + switch { + case a < b: return .Less + case a > b: return .Greater + } + return .Equal }) } 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 { + x, y := (^E)(lhs)^, (^E)(rhs)^ + + ctx := (^Context)(user_data) + a := k(i) + b := k(j) + switch { + case a < b: return .Greater + case a > b: return .Less + } + return .Equal }) } @@ -366,12 +389,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 From 1aa3283d1b23ece8ad43b1d8ed8ed0ecf7842c35 Mon Sep 17 00:00:00 2001 From: Hector Date: Tue, 7 Oct 2025 12:58:08 +0100 Subject: [PATCH 042/113] Added PointInRectFloat to SDL3 --- vendor/sdl3/sdl3_rect.odin | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/vendor/sdl3/sdl3_rect.odin b/vendor/sdl3/sdl3_rect.odin index 53470dec4..10e741de1 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 From 85e37f2f7e202ce5c5aaf751ed6d43eb0d66e849 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 7 Oct 2025 13:18:30 +0100 Subject: [PATCH 043/113] Add missing `nil` --- core/slice/sort.odin | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/slice/sort.odin b/core/slice/sort.odin index 7485679c8..3d5bad34e 100644 --- a/core/slice/sort.odin +++ b/core/slice/sort.odin @@ -358,7 +358,7 @@ sort_by_key :: proc(data: $T/[]$E, key: proc(E) -> $K) where ORD(K) { case a > b: return .Greater } return .Equal - }) + }, nil) } reverse_sort_by_key :: proc(data: $T/[]$E, key: proc(E) -> $K) where ORD(K) { @@ -378,7 +378,7 @@ reverse_sort_by_key :: proc(data: $T/[]$E, key: proc(E) -> $K) where ORD(K) { case a > b: return .Less } return .Equal - }) + }, nil) } @(require_results) From 9e068c254b32767ea5b03af6b9955b34d0e4685d Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 7 Oct 2025 13:22:15 +0100 Subject: [PATCH 044/113] Fix typos --- core/slice/sort.odin | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/core/slice/sort.odin b/core/slice/sort.odin index 3d5bad34e..75c341d7c 100644 --- a/core/slice/sort.odin +++ b/core/slice/sort.odin @@ -348,11 +348,11 @@ sort_by_key :: proc(data: $T/[]$E, key: proc(E) -> $K) where ORD(K) { ctx := &Context{key} sort_by_generic_cmp(data, proc(lhs, rhs: rawptr, user_data: rawptr) -> Ordering { - x, y := (^E)(lhs)^, (^E)(rhs)^ + i, j := (^E)(lhs)^, (^E)(rhs)^ ctx := (^Context)(user_data) - a := k(i) - b := k(j) + a := ctx.key(i) + b := ctx.key(j) switch { case a < b: return .Less case a > b: return .Greater @@ -368,11 +368,11 @@ reverse_sort_by_key :: proc(data: $T/[]$E, key: proc(E) -> $K) where ORD(K) { ctx := &Context{key} sort_by_generic_cmp(data, proc(lhs, rhs: rawptr, user_data: rawptr) -> Ordering { - x, y := (^E)(lhs)^, (^E)(rhs)^ + i, j := (^E)(lhs)^, (^E)(rhs)^ ctx := (^Context)(user_data) - a := k(i) - b := k(j) + a := ctx.key(i) + b := ctx.key(j) switch { case a < b: return .Greater case a > b: return .Less From af8c698b97a8577a2f05a191c8e6492a650f6f83 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 7 Oct 2025 13:24:13 +0100 Subject: [PATCH 045/113] use `ctx` --- core/slice/sort.odin | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/slice/sort.odin b/core/slice/sort.odin index 75c341d7c..7e2415249 100644 --- a/core/slice/sort.odin +++ b/core/slice/sort.odin @@ -358,7 +358,7 @@ sort_by_key :: proc(data: $T/[]$E, key: proc(E) -> $K) where ORD(K) { case a > b: return .Greater } return .Equal - }, nil) + }, ctx) } reverse_sort_by_key :: proc(data: $T/[]$E, key: proc(E) -> $K) where ORD(K) { @@ -378,7 +378,7 @@ reverse_sort_by_key :: proc(data: $T/[]$E, key: proc(E) -> $K) where ORD(K) { case a > b: return .Less } return .Equal - }, nil) + }, ctx) } @(require_results) From 13b8607cc392bfa925c9dc65589ea93b67f2df83 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 7 Oct 2025 14:15:40 +0100 Subject: [PATCH 046/113] Add `_internal_sort_from_indices_permuation` --- core/slice/ptr.odin | 10 +++++----- core/slice/sort.odin | 29 ++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 6 deletions(-) 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/sort.odin b/core/slice/sort.odin index 7e2415249..dde5592e8 100644 --- a/core/slice/sort.odin +++ b/core/slice/sort.odin @@ -81,6 +81,25 @@ sort_by_indices_overwrite :: proc(data: $T/[]$E, indices: []int) { swap_with_slice(data, temp) } +@(private) +_internal_sort_from_indices_permuation :: proc(data: $T/[]$E, indices: []int) { + assert(len(data) == len(indices)) + if len(indices) <= 1 { + return + } + + // TODO(bill): This is not O(N) + for i in 0.. (indices: []int) where ORD(E) { @@ -90,11 +109,13 @@ sort_with_indices :: proc(data: $T/[]$E, allocator := context.allocator) -> (ind for _, idx in indices { indices[idx] = idx } + 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)^ - x, y := data[xi], data[yi] + #no_bounds_check x, y := data[xi], data[yi] if x < y { return .Less } else if x > y { @@ -102,6 +123,8 @@ sort_with_indices :: proc(data: $T/[]$E, allocator := context.allocator) -> (ind } return .Equal }, raw_data(data)) + + _internal_sort_from_indices_permuation(data, indices) } return indices } @@ -177,6 +200,8 @@ sort_by_with_indices :: proc(data: $T/[]$E, less: proc(i, j: E) -> bool, allocat } return .Equal }, ctx) + + _internal_sort_from_indices_permuation(data, indices) } } return indices @@ -208,6 +233,8 @@ sort_by_with_indices_with_data :: proc(data: $T/[]$E, less: proc(i, j: E, user_d } return .Equal }, ctx) + + _internal_sort_from_indices_permuation(data, indices) } } return indices From 20e67f2ad9a5aaf4b3d01e3e717b70785357979f Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 7 Oct 2025 14:27:19 +0100 Subject: [PATCH 047/113] Add some more docs --- base/runtime/core.odin | 22 ++++++++++++++++++++++ core/bytes/bytes.odin | 9 +++++++-- core/strings/strings.odin | 9 +++++++-- 3 files changed, 36 insertions(+), 4 deletions(-) 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/core/bytes/bytes.odin b/core/bytes/bytes.odin index 71b6ef70c..6e872e757 100644 --- a/core/bytes/bytes.odin +++ b/core/bytes/bytes.odin @@ -134,8 +134,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/strings/strings.odin b/core/strings/strings.odin index ffa11f219..79a8cec29 100644 --- a/core/strings/strings.odin +++ b/core/strings/strings.odin @@ -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 } From d17ee79470e16327049350d462056292348cf6a0 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 7 Oct 2025 14:30:13 +0100 Subject: [PATCH 048/113] Fix #5764 --- core/math/math.odin | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/core/math/math.odin b/core/math/math.odin index b99a97bc1..b399b4dac 100644 --- a/core/math/math.odin +++ b/core/math/math.odin @@ -402,7 +402,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) From 5320feb6737c4d89ce54fda463ea8ff8b8200dba Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Tue, 7 Oct 2025 22:54:35 +0200 Subject: [PATCH 049/113] Add reflect.as_string16 and fix typos --- core/reflect/reflect.odin | 70 +++++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 24 deletions(-) diff --git a/core/reflect/reflect.odin b/core/reflect/reflect.odin index 86fa9d4b5..5fbff08c2 100644 --- a/core/reflect/reflect.odin +++ b/core/reflect/reflect.odin @@ -153,7 +153,7 @@ when !ODIN_NO_RTTI { } -// any_base returns an `any` whether the `typeid` has been replaced with the `base-type` equivalent +// 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 @@ -163,7 +163,7 @@ any_base :: proc(v: any) -> any { return v } -// any_core returns an `any` whether the `typeid` has been replaced with the `core-type` equivalent +// 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 @@ -368,7 +368,7 @@ capacity :: proc(val: any) -> int { } -// Dynamically indexes `any` as an indexable-type if possbiel. Returns `nil` if not possible +// 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 } @@ -455,13 +455,13 @@ 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` represents a information of a field of a struct Struct_Field :: struct { name: string, type: ^Type_Info, @@ -541,8 +541,8 @@ struct_field_value_by_name :: proc(a: any, field: string, allow_using := false) // Returns an `any` of a struct field specified by a `Struct_Field` // Example: -// v := struct_field_value_by_name(the_struct, field) -// nested_value_through_using := struct_field_value_by_name(the_struct, field, allow_using=true) +// 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 } @@ -573,7 +573,7 @@ struct_field_types :: proc(T: typeid) -> []^Type_Info { } -// Returns a `[]Struct_Type` of the tags of the struct fields of type `T` +// 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)) @@ -673,23 +673,23 @@ 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 return. Otherwise an empty string is returned. +// 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 is usually of the form: +// 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 is usually of the form: +// The convention for struct tags is usually of the form: // // `key:"value" another:"set" and:"whatever"` @(require_results) @@ -770,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)) @@ -917,7 +917,7 @@ type_info_union_is_pure_maybe :: proc(info: runtime.Type_Info_Union) -> bool { return len(info.variants) == 1 && is_pointer_internally(info.variants[0]) } -// Returns `typeid` of a any-encoded union type. Panics if a union was not passed. +// 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 } @@ -1003,7 +1003,7 @@ 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 +// 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} @@ -1114,7 +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. +// 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 } @@ -1153,7 +1153,7 @@ set_union_value :: proc(dst: any, value: any) -> bool { panic("expected a union to reflect.set_union_variant_typeid") } -// Checks to see if the data stored is a bit_set and is big_ending. Panics if a bit_set was not passed. +// 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 } @@ -1185,7 +1185,7 @@ Bit_Field :: struct { tag: Struct_Tag, } -// Returns the fields of a bit_field type `T` as an `#soa` slice. +// 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) { ... } @@ -1204,7 +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` +// 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)) @@ -1214,7 +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 +// 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)) @@ -1224,7 +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` +// 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)) @@ -1234,7 +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` +// 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)) @@ -1244,7 +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` +// 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)) @@ -1655,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) { @@ -1770,6 +1791,7 @@ DEFAULT_EQUAL_MAX_RECURSION_LEVEL :: 32 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 { From b55cf5f8f4510e09f090c9bf7e47e3b66b139de5 Mon Sep 17 00:00:00 2001 From: A1029384756 Date: Tue, 7 Oct 2025 22:58:50 -0400 Subject: [PATCH 050/113] llvm 14 fixed --- src/llvm_backend.cpp | 3 +- src/llvm_backend_const.cpp | 130 ++++++++++++++++++++++++++++++----- src/llvm_backend_general.cpp | 25 +++++++ 3 files changed, 139 insertions(+), 19 deletions(-) diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index ab0811085..1e8280a2e 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -2041,7 +2041,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); } diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index 193bffe08..7700df5e7 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,84 @@ gb_internal bool lb_is_nested_possibly_constant(Type *ft, Selection const &sel, return lb_is_elem_const(elem, ft); } +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 = LLVMSizeOfTypeInBits(td, src_ty); + unsigned dst_bits = 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 = 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 = llvm_const_shl(m, llvm_const_zext(m, elem_int, src_int_ty), + LLVMConstInt(src_int_ty, i * elem_bits, false)); + as_int = llvm_const_or(m, 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 = llvm_const_zext(m, 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 = 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 = llvm_const_lshr(m, 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; +} + 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; @@ -634,14 +731,11 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, lb lbValue cv = lb_const_value(m, value_type, value, cc, value_type); Type *variant_type = cv.type; - LLVMValueRef values[4] = {}; + LLVMValueRef values[3] = {}; unsigned value_count = 0; - 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); - } + LLVMTypeRef block_type = lb_type_internal_union_block_type(m, bt); + values[value_count++] = llvm_const_pad_to_size(m, cv.value, block_type); Type *tag_type = union_tag_type(bt); LLVMTypeRef llvm_tag_type = lb_type(m, tag_type); @@ -870,7 +964,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 +986,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 +1566,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_general.cpp b/src/llvm_backend_general.cpp index 39cf70a6a..9e3042d5a 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -449,6 +449,31 @@ gb_internal LLVMValueRef llvm_const_insert_value(lbModule *m, LLVMValueRef agg, } +gb_internal LLVMValueRef llvm_const_shl(lbModule *m, LLVMValueRef a, LLVMValueRef b) { + LLVMValueRef res = LLVMBuildShl(m->const_dummy_builder, a, b, ""); + GB_ASSERT(LLVMIsConstant(res)); + return res; +} + +gb_internal LLVMValueRef llvm_const_lshr(lbModule *m, LLVMValueRef a, LLVMValueRef b) { + LLVMValueRef res = LLVMBuildLShr(m->const_dummy_builder, a, b, ""); + GB_ASSERT(LLVMIsConstant(res)); + return res; +} + +gb_internal LLVMValueRef llvm_const_or(lbModule *m, LLVMValueRef a, LLVMValueRef b) { + LLVMValueRef res = LLVMBuildOr(m->const_dummy_builder, a, b, ""); + GB_ASSERT(LLVMIsConstant(res)); + return res; +} + +gb_internal LLVMValueRef llvm_const_zext(lbModule *m, LLVMValueRef a, LLVMTypeRef b) { + LLVMValueRef res = LLVMBuildZExt(m->const_dummy_builder, a, b, ""); + GB_ASSERT(LLVMIsConstant(res)); + return res; +} + + gb_internal LLVMValueRef llvm_cstring(lbModule *m, String const &str) { From 7179987ac9d87b69657cfa81f49e78fcc7e99e44 Mon Sep 17 00:00:00 2001 From: A1029384756 Date: Tue, 7 Oct 2025 23:15:12 -0400 Subject: [PATCH 051/113] casting --- src/llvm_backend_const.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index 7700df5e7..f1e497b5f 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -572,8 +572,8 @@ LLVMValueRef llvm_const_pad_to_size(lbModule *m, LLVMValueRef val, LLVMTypeRef d LLVMContextRef ctx = m->ctx; LLVMTargetDataRef td = LLVMGetModuleDataLayout(m->mod); LLVMTypeRef src_ty = LLVMTypeOf(val); - unsigned src_bits = LLVMSizeOfTypeInBits(td, src_ty); - unsigned dst_bits = LLVMSizeOfTypeInBits(td, dst_ty); + 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); @@ -589,7 +589,7 @@ LLVMValueRef llvm_const_pad_to_size(lbModule *m, LLVMValueRef val, LLVMTypeRef d } else if (src_kind == LLVMArrayTypeKind) { unsigned elem_count = LLVMGetArrayLength(src_ty); LLVMTypeRef elem_ty = LLVMGetElementType(src_ty); - unsigned elem_bits = LLVMSizeOfTypeInBits(td, elem_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); @@ -627,7 +627,7 @@ LLVMValueRef llvm_const_pad_to_size(lbModule *m, LLVMValueRef val, LLVMTypeRef d } else if (dst_kind == LLVMArrayTypeKind) { unsigned elem_count = LLVMGetArrayLength(dst_ty); LLVMTypeRef elem_ty = LLVMGetElementType(dst_ty); - unsigned elem_bits = LLVMSizeOfTypeInBits(td, elem_ty); + unsigned elem_bits = (unsigned)LLVMSizeOfTypeInBits(td, elem_ty); LLVMValueRef *elems = temporary_alloc_array(elem_count); LLVMTypeRef as_int_ty = LLVMTypeOf(as_int); From cfe651e8d23cb85097db32662acefd27b4350be9 Mon Sep 17 00:00:00 2001 From: A1029384756 Date: Tue, 7 Oct 2025 23:26:29 -0400 Subject: [PATCH 052/113] formatting --- src/llvm_backend_const.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index f1e497b5f..37dccf571 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -597,8 +597,7 @@ LLVMValueRef llvm_const_pad_to_size(lbModule *m, LLVMValueRef val, LLVMTypeRef d 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 = llvm_const_shl(m, llvm_const_zext(m, elem_int, src_int_ty), - LLVMConstInt(src_int_ty, i * elem_bits, false)); + LLVMValueRef shifted = llvm_const_shl(m, llvm_const_zext(m, elem_int, src_int_ty), LLVMConstInt(src_int_ty, i * elem_bits, false)); as_int = llvm_const_or(m, as_int, shifted); } } else { From 10259ee665db0d6c2fe335c304e1a4d1b4188e06 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 8 Oct 2025 12:35:14 +0100 Subject: [PATCH 053/113] Minor rename of a procedure --- core/slice/sort.odin | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/core/slice/sort.odin b/core/slice/sort.odin index dde5592e8..42112c613 100644 --- a/core/slice/sort.odin +++ b/core/slice/sort.odin @@ -81,14 +81,12 @@ sort_by_indices_overwrite :: proc(data: $T/[]$E, indices: []int) { swap_with_slice(data, temp) } -@(private) -_internal_sort_from_indices_permuation :: proc(data: $T/[]$E, indices: []int) { +sort_from_permutation_indices :: proc(data: $T/[]$E, indices: []int) { assert(len(data) == len(indices)) if len(indices) <= 1 { return } - // TODO(bill): This is not O(N) for i in 0.. (ind return .Equal }, raw_data(data)) - _internal_sort_from_indices_permuation(data, indices) + sort_from_permutation_indices(data, indices) } return indices } @@ -201,7 +199,7 @@ sort_by_with_indices :: proc(data: $T/[]$E, less: proc(i, j: E) -> bool, allocat return .Equal }, ctx) - _internal_sort_from_indices_permuation(data, indices) + sort_from_permutation_indices(data, indices) } } return indices @@ -234,7 +232,7 @@ sort_by_with_indices_with_data :: proc(data: $T/[]$E, less: proc(i, j: E, user_d return .Equal }, ctx) - _internal_sort_from_indices_permuation(data, indices) + sort_from_permutation_indices(data, indices) } } return indices From 9f5bde4a6f2975f5b783a3e0f7d04f5ecd74b63d Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Wed, 8 Oct 2025 11:38:20 -0400 Subject: [PATCH 054/113] Perform type kind check before making use relevant fields in objc_superclass check --- src/check_decl.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/check_decl.cpp b/src/check_decl.cpp index fa4eade0f..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); From 3317a1f0e924e60a85ae947506da8652e7ae69cf Mon Sep 17 00:00:00 2001 From: thetarnav Date: Wed, 8 Oct 2025 22:00:44 +0200 Subject: [PATCH 055/113] Add #no_bounds_check to procedures in core:unicode --- core/unicode/fold.odin | 2 +- core/unicode/letter.odin | 47 +++++++++++++++++++++------------------- 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/core/unicode/fold.odin b/core/unicode/fold.odin index edd8a3156..2e0d7225c 100644 --- a/core/unicode/fold.odin +++ b/core/unicode/fold.odin @@ -14,7 +14,7 @@ package unicode // simple_fold('\u212a') == 'k' // simple_fold(-3) == -3 @(require_results) -simple_fold :: proc(r: rune) -> rune { +simple_fold :: proc(r: rune) -> rune #no_bounds_check { Fold_Pair :: struct { from: u16, to: u16, 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' From 79912b3a98f8efd46ab83b75d147709748800249 Mon Sep 17 00:00:00 2001 From: Karl Zylinski Date: Thu, 9 Oct 2025 00:32:16 +0200 Subject: [PATCH 056/113] Fix for fontstash crash because it didn't fetch the offset of the first font correctly. The old setup didn't work with TTC files that contain multiple fonts. --- vendor/fontstash/fontstash.odin | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/vendor/fontstash/fontstash.odin b/vendor/fontstash/fontstash.odin index 8563277b1..b3000de70 100644 --- a/vendor/fontstash/fontstash.odin +++ b/vendor/fontstash/fontstash.odin @@ -335,7 +335,10 @@ AddFontMem :: proc( res.freeLoadedData = freeLoadedData res.name = strings.clone(name) - stbtt.InitFont(&res.info, &res.loadedData[0], 0) + // Get offset of first font (if the font is a TTC then it can contain multiple fonts) + // Note: There is currently no support for specifying any other font than first one. + font_offset := stbtt.GetFontOffsetForIndex(raw_data(res.loadedData), 0) + stbtt.InitFont(&res.info, raw_data(res.loadedData), font_offset) ascent, descent, line_gap: i32 stbtt.GetFontVMetrics(&res.info, &ascent, &descent, &line_gap) From e001e402c29d6ef712dc2fc7efe2135b575a9df1 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 9 Oct 2025 09:55:14 +0100 Subject: [PATCH 057/113] Add `intrinsics.type_is_cstring` and `intrinsics.type_is_cstring16` --- src/check_builtin.cpp | 4 ++++ src/checker_builtin_procs.hpp | 2 ++ 2 files changed, 6 insertions(+) diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index f142f04b7..b95b46450 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, @@ -6424,6 +6426,8 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As case BuiltinProc_type_is_quaternion: case BuiltinProc_type_is_string: case BuiltinProc_type_is_string16: + case BuiltinProc_type_is_cstring: + case BuiltinProc_type_is_cstring16: case BuiltinProc_type_is_typeid: case BuiltinProc_type_is_any: case BuiltinProc_type_is_endian_platform: diff --git a/src/checker_builtin_procs.hpp b/src/checker_builtin_procs.hpp index c2255a6ba..80e503c70 100644 --- a/src/checker_builtin_procs.hpp +++ b/src/checker_builtin_procs.hpp @@ -251,6 +251,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, From 7870e6d68b400cb40dca7d7ac8843bb731ea666a Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 9 Oct 2025 09:56:30 +0100 Subject: [PATCH 058/113] Update `intrinsics.odin` --- base/intrinsics/intrinsics.odin | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/base/intrinsics/intrinsics.odin b/base/intrinsics/intrinsics.odin index dd508180d..d2af85619 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 --- From 0b2c0f785cf21c6f8e8bc9d90f23201a7ae71f47 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 9 Oct 2025 10:06:39 +0100 Subject: [PATCH 059/113] Add `type_is_nearly_simple_compare` to `intrinsics.odin` --- base/intrinsics/intrinsics.odin | 1 + 1 file changed, 1 insertion(+) diff --git a/base/intrinsics/intrinsics.odin b/base/intrinsics/intrinsics.odin index d2af85619..805d78594 100644 --- a/base/intrinsics/intrinsics.odin +++ b/base/intrinsics/intrinsics.odin @@ -157,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 --- From 41c523faa5a66232239e1f0ea262a6721eefc3b9 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 9 Oct 2025 10:10:49 +0100 Subject: [PATCH 060/113] Add `intrinsics.type_is_raw_union` --- src/check_builtin.cpp | 6 ++++-- src/checker_builtin_procs.hpp | 9 +++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index b95b46450..0f8944cb9 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -57,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, @@ -6424,12 +6425,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_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_typeid: - case BuiltinProc_type_is_any: case BuiltinProc_type_is_endian_platform: case BuiltinProc_type_is_endian_little: case BuiltinProc_type_is_endian_big: @@ -6461,6 +6462,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: diff --git a/src/checker_builtin_procs.hpp b/src/checker_builtin_procs.hpp index 80e503c70..addaeaf23 100644 --- a/src/checker_builtin_procs.hpp +++ b/src/checker_builtin_procs.hpp @@ -287,6 +287,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, @@ -614,10 +616,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}, @@ -651,6 +655,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}, From a60058259d9ae6bbff37fff49e53d542354c90c1 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 9 Oct 2025 10:25:48 +0100 Subject: [PATCH 061/113] Allow `intrinsics.type_union_tag_offset` with maybe-like unions --- src/check_builtin.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 0f8944cb9..5d1016bba 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -6742,9 +6742,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; From adc44312bf78b1842f568d0bac3170898688007b Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 9 Oct 2025 10:36:50 +0100 Subject: [PATCH 062/113] `const string` -> `constant string` --- src/check_builtin.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 5d1016bba..a19fb15ec 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -6525,7 +6525,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; } @@ -6605,7 +6605,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; } @@ -7242,7 +7242,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; } From a7b6ab92c118c617223751dd9ca0c38cdd72447b Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 9 Oct 2025 11:32:25 +0100 Subject: [PATCH 063/113] Remove unused store --- core/slice/sort.odin | 1 - 1 file changed, 1 deletion(-) diff --git a/core/slice/sort.odin b/core/slice/sort.odin index 42112c613..1e2a8ff59 100644 --- a/core/slice/sort.odin +++ b/core/slice/sort.odin @@ -357,7 +357,6 @@ reverse_sort_by :: proc(data: $T/[]$E, less: proc(i, j: E) -> bool) { } reverse_sort_by_cmp :: proc(data: $T/[]$E, cmp: proc(i, j: E) -> Ordering) { - context._internal = rawptr(cmp) 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) From ee063e708a119012653bf22db5111537d2d53cb6 Mon Sep 17 00:00:00 2001 From: connnnal <216976529+connnnal@users.noreply.github.com> Date: Thu, 9 Oct 2025 11:38:22 +0100 Subject: [PATCH 064/113] Disable bounds check for the first utf8 byte Known safe from prior `n < 1` check --- core/unicode/utf8/utf8.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/unicode/utf8/utf8.odin b/core/unicode/utf8/utf8.odin index 67f8a8be9..91ec44886 100644 --- a/core/unicode/utf8/utf8.odin +++ b/core/unicode/utf8/utf8.odin @@ -108,7 +108,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. From c73bd6f51d6f0932206d030baab0c3825971263a Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 9 Oct 2025 11:42:09 +0100 Subject: [PATCH 065/113] Make `Operation:` comments unformatted --- core/simd/simd.odin | 108 ++++++++++++++++++++++---------------------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/core/simd/simd.odin b/core/simd/simd.odin index 303eceb97..da76ed49b 100644 --- a/core/simd/simd.odin +++ b/core/simd/simd.odin @@ -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 } From 87716da363ac414f203b6029d472d2218d2be684 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 9 Oct 2025 12:23:59 +0100 Subject: [PATCH 066/113] Add package line docs to c and libc --- core/c/c.odin | 1 + core/c/libc/doc.odin | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 core/c/libc/doc.odin diff --git a/core/c/c.odin b/core/c/c.odin index 73727d8d5..907b2f80f 100644 --- a/core/c/c.odin +++ b/core/c/c.odin @@ -1,3 +1,4 @@ +// package c just defines the basic types used by C programs 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..883a3dda5 --- /dev/null +++ b/core/c/libc/doc.odin @@ -0,0 +1,2 @@ +// package libc declares the commonly used things in "libc" (C standard library) +package libc From 3e8f4e080ce35de3c8adeed08778ed220b8680be Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 9 Oct 2025 12:26:35 +0100 Subject: [PATCH 067/113] Add more doc lines --- core/bufio/doc.odin | 2 ++ core/bytes/bytes.odin | 1 + 2 files changed, 3 insertions(+) create mode 100644 core/bufio/doc.odin diff --git a/core/bufio/doc.odin b/core/bufio/doc.odin new file mode 100644 index 000000000..f725e83dc --- /dev/null +++ b/core/bufio/doc.odin @@ -0,0 +1,2 @@ +// package bufio implements buffered I/O. It wraps an `io.Stream` interface to provide buffering. +package bufio \ No newline at end of file diff --git a/core/bytes/bytes.odin b/core/bytes/bytes.odin index 6e872e757..859f90318 100644 --- a/core/bytes/bytes.odin +++ b/core/bytes/bytes.odin @@ -1,3 +1,4 @@ +// package bytes implements procedures for manipulation of byte slices package bytes import "base:intrinsics" From 63ac9c73829b9e9a318c1258285e17a920acac91 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 9 Oct 2025 12:27:22 +0100 Subject: [PATCH 068/113] Add doc line to spall --- core/prof/spall/doc.odin | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/prof/spall/doc.odin b/core/prof/spall/doc.odin index b007ad4cb..be84cac2d 100644 --- a/core/prof/spall/doc.odin +++ b/core/prof/spall/doc.odin @@ -1,4 +1,6 @@ /* +package spall is a package that is used for profiling using the "spall" format + Example: package main From 8019bd360abf3de6287eed206a649fe56fd43563 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 9 Oct 2025 12:28:16 +0100 Subject: [PATCH 069/113] Add doc line to `strconv` --- core/strconv/strconv.odin | 1 + 1 file changed, 1 insertion(+) diff --git a/core/strconv/strconv.odin b/core/strconv/strconv.odin index 7fcb578f7..5634f1712 100644 --- a/core/strconv/strconv.odin +++ b/core/strconv/strconv.odin @@ -1,3 +1,4 @@ +// package strconv implements conversions to and from string represnetations of other data types package strconv import "core:unicode/utf8" From 9ddb93bd01fbbd57267260dd7c1e894bc4e82cbb Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 9 Oct 2025 12:29:18 +0100 Subject: [PATCH 070/113] Add doc line to `core:thread` --- core/thread/thread.odin | 1 + 1 file changed, 1 insertion(+) diff --git a/core/thread/thread.odin b/core/thread/thread.odin index 194c7bfef..c5018a5fe 100644 --- a/core/thread/thread.odin +++ b/core/thread/thread.odin @@ -1,3 +1,4 @@ +// package thread implements multi-threading operations so spawn threads and thread pools package thread import "base:runtime" From 857c78c22bf97417b74b60cf08eb24ece546e26c Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 9 Oct 2025 12:37:18 +0100 Subject: [PATCH 071/113] Add doc lins to unicode packages --- core/unicode/doc.odin | 2 ++ core/unicode/utf16/utf16.odin | 1 + core/unicode/utf8/utf8.odin | 1 + 3 files changed, 4 insertions(+) create mode 100644 core/unicode/doc.odin diff --git a/core/unicode/doc.odin b/core/unicode/doc.odin new file mode 100644 index 000000000..4d9ff78f5 --- /dev/null +++ b/core/unicode/doc.odin @@ -0,0 +1,2 @@ +// package unicode provides data and procedures to test properties of Unicode code points +package unicode \ No newline at end of file diff --git a/core/unicode/utf16/utf16.odin b/core/unicode/utf16/utf16.odin index d3f98584b..75c553f62 100644 --- a/core/unicode/utf16/utf16.odin +++ b/core/unicode/utf16/utf16.odin @@ -1,3 +1,4 @@ +// package utf16 implements 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..31bdb3491 100644 --- a/core/unicode/utf8/utf8.odin +++ b/core/unicode/utf8/utf8.odin @@ -1,3 +1,4 @@ +// package utf8 implements procedures and constants to support text-encoding in the UTF-8 character encoding package utf8 RUNE_ERROR :: '\ufffd' From c3d4b1f0b5b0c0fb765b425d19033195ce4588a8 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 9 Oct 2025 13:37:22 +0100 Subject: [PATCH 072/113] Add doc line to `core:unicode/utf8/utf8string` --- core/unicode/utf8/utf8string/string.odin | 1 + 1 file changed, 1 insertion(+) diff --git a/core/unicode/utf8/utf8string/string.odin b/core/unicode/utf8/utf8string/string.odin index 4b0fe7241..7d067a9bf 100644 --- a/core/unicode/utf8/utf8string/string.odin +++ b/core/unicode/utf8/utf8string/string.odin @@ -1,3 +1,4 @@ +// package utf8string provides a convenient and efficient way to index strings by Unicode code point (rune) rather than byte package utf8string import "core:unicode/utf8" From 5a154a1775449a839d713e9adba8ebea4d6e06de Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Thu, 9 Oct 2025 14:41:22 +0200 Subject: [PATCH 073/113] Add more package lines for the docs --- core/compress/gzip/doc.odin | 5 +++-- core/compress/shoco/doc.odin | 2 ++ core/compress/shoco/model.odin | 4 ++-- core/compress/shoco/shoco.odin | 6 +++--- core/compress/zlib/doc.odin | 5 +++-- core/container/bit_array/doc.odin | 6 ++++-- 6 files changed, 17 insertions(+), 11 deletions(-) create mode 100644 core/compress/shoco/doc.odin diff --git a/core/compress/gzip/doc.odin b/core/compress/gzip/doc.odin index fd7ef5a19..745d020c5 100644 --- a/core/compress/gzip/doc.odin +++ b/core/compress/gzip/doc.odin @@ -1,3 +1,5 @@ +// package gzip implements a small GZIP implementation as an example. +package compress_gzip /* Copyright 2021 Jeroen van Rijn . Made available under Odin's BSD-3 license. @@ -86,5 +88,4 @@ Example: } bytes.buffer_destroy(&buf) } -*/ -package compress_gzip +*/ \ No newline at end of file diff --git a/core/compress/shoco/doc.odin b/core/compress/shoco/doc.odin new file mode 100644 index 000000000..78ab01776 --- /dev/null +++ b/core/compress/shoco/doc.odin @@ -0,0 +1,2 @@ +// package shoco is an implementation of the shoco short string compressor. +package compress_shoco \ 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..d8810e532 100644 --- a/core/compress/shoco/shoco.odin +++ b/core/compress/shoco/shoco.odin @@ -1,3 +1,6 @@ +// package shoco is an implementation of the shoco short string compressor. +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..19ef1c045 100644 --- a/core/compress/zlib/doc.odin +++ b/core/compress/zlib/doc.odin @@ -1,3 +1,5 @@ +// package zlib implements Deflate decompression +package compress_zlib /* Copyright 2021 Jeroen van Rijn . Made available under Odin's BSD-3 license. @@ -47,5 +49,4 @@ Example: fmt.printf("Input: %v bytes, output (%v bytes):\n%v\n", len(ODIN_DEMO), len(s), s) assert(len(s) == OUTPUT_SIZE) } -*/ -package compress_zlib +*/ \ No newline at end of file diff --git a/core/container/bit_array/doc.odin b/core/container/bit_array/doc.odin index 36bf90002..6d35d48d1 100644 --- a/core/container/bit_array/doc.odin +++ b/core/container/bit_array/doc.odin @@ -1,3 +1,6 @@ +// package bit_array implements a dynamically-sized array of bits +package container_dynamic_bit_array + /* The Bit Array can be used in several ways: @@ -48,5 +51,4 @@ Example: fmt.printf("Get(Negative_Test): %v, %v\n", get(bits, Foo.Negative_Test)) fmt.printf("Freed.\n") } -*/ -package container_dynamic_bit_array +*/ \ No newline at end of file From 9c7fe1d8a7b26ecd0d4de2a1d6241f453deca6cc Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Thu, 9 Oct 2025 14:58:50 +0200 Subject: [PATCH 074/113] Package lines for core:container. --- core/container/intrusive/list/doc.odin | 6 ++++-- core/container/lru/doc.odin | 2 ++ core/container/priority_queue/doc.odin | 2 ++ core/container/queue/doc.odin | 2 ++ core/container/rbtree/doc.odin | 2 ++ core/container/rbtree/rbtree.odin | 1 - core/container/small_array/doc.odin | 9 ++++----- core/container/topological_sort/doc.odin | 2 ++ core/container/topological_sort/topological_sort.odin | 9 ++++++--- 9 files changed, 24 insertions(+), 11 deletions(-) create mode 100644 core/container/lru/doc.odin create mode 100644 core/container/priority_queue/doc.odin create mode 100644 core/container/queue/doc.odin create mode 100644 core/container/rbtree/doc.odin create mode 100644 core/container/topological_sort/doc.odin diff --git a/core/container/intrusive/list/doc.odin b/core/container/intrusive/list/doc.odin index 155f1dfe2..78502e35d 100644 --- a/core/container/intrusive/list/doc.odin +++ b/core/container/intrusive/list/doc.odin @@ -1,3 +1,6 @@ +// package list implements an intrusive doubly-linked list. +package container_intrusive_list + /* Package list implements an intrusive doubly-linked list. @@ -45,5 +48,4 @@ Example: Output: Hello World -*/ -package container_intrusive_list +*/ \ No newline at end of file diff --git a/core/container/lru/doc.odin b/core/container/lru/doc.odin new file mode 100644 index 000000000..540487bc6 --- /dev/null +++ b/core/container/lru/doc.odin @@ -0,0 +1,2 @@ +// package lru implements an LRU cache. It automatically removes older entries if its capacity is reached. +package container_lru \ No newline at end of file diff --git a/core/container/priority_queue/doc.odin b/core/container/priority_queue/doc.odin new file mode 100644 index 000000000..a71a9dd28 --- /dev/null +++ b/core/container/priority_queue/doc.odin @@ -0,0 +1,2 @@ +// package priority_queue implements a Priority Queue data structure +package container_priority_queue \ No newline at end of file diff --git a/core/container/queue/doc.odin b/core/container/queue/doc.odin new file mode 100644 index 000000000..efb29fc2a --- /dev/null +++ b/core/container/queue/doc.odin @@ -0,0 +1,2 @@ +// package queue implements a dynamically resizable double-ended queue/ring-buffer. +package container_queue \ No newline at end of file diff --git a/core/container/rbtree/doc.odin b/core/container/rbtree/doc.odin new file mode 100644 index 000000000..691442e8e --- /dev/null +++ b/core/container/rbtree/doc.odin @@ -0,0 +1,2 @@ +// package rbtree implements a red-black tree +package container_rbtree \ No newline at end of file diff --git a/core/container/rbtree/rbtree.odin b/core/container/rbtree/rbtree.odin index e9d0d08f4..6a3b9c9ea 100644 --- a/core/container/rbtree/rbtree.odin +++ b/core/container/rbtree/rbtree.odin @@ -1,4 +1,3 @@ -// This package implements a red-black tree package container_rbtree @(require) import "base:intrinsics" diff --git a/core/container/small_array/doc.odin b/core/container/small_array/doc.odin index f3e9acd57..a57caf798 100644 --- a/core/container/small_array/doc.odin +++ b/core/container/small_array/doc.odin @@ -1,7 +1,7 @@ -/* -Package small_array implements a dynamic array like -interface on a stack-allocated, fixed-size array. +// package small_array implements a dynamic array-like interface on a stack-allocated, fixed-size array. +package container_small_array +/* 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 @@ -51,5 +51,4 @@ Output: Hellope -*/ -package container_small_array +*/ \ No newline at end of file diff --git a/core/container/topological_sort/doc.odin b/core/container/topological_sort/doc.odin new file mode 100644 index 000000000..cd79e0e54 --- /dev/null +++ b/core/container/topological_sort/doc.odin @@ -0,0 +1,2 @@ +// package topological_sort implements a generic O(V+E) topological sorter. +package container_topological_sort \ 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..6afe9c453 100644 --- a/core/container/topological_sort/topological_sort.odin +++ b/core/container/topological_sort/topological_sort.odin @@ -1,8 +1,11 @@ -// 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. package container_topological_sort +/* + 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. +*/ + import "base:intrinsics" import "base:runtime" _ :: intrinsics From 153b0de4206773956d0402c880de2ff5254947e4 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Thu, 9 Oct 2025 15:18:23 +0200 Subject: [PATCH 075/113] Package lines for core:debug --- core/debug/trace/doc.odin | 7 +++---- core/dynlib/doc.odin | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/core/debug/trace/doc.odin b/core/debug/trace/doc.odin index e65548769..40f055161 100644 --- a/core/debug/trace/doc.odin +++ b/core/debug/trace/doc.odin @@ -1,6 +1,6 @@ +// package debug implements a stack trace library. Only works when debug symbols are enabled `-debug`. +package debug_trace /* -A debug stack trace library. Only works when debug symbols are enabled `-debug`. - Example: import "base:runtime" import "core:debug/trace" @@ -47,5 +47,4 @@ Example: ... } -*/ -package debug_trace \ No newline at end of file +*/ \ No newline at end of file diff --git a/core/dynlib/doc.odin b/core/dynlib/doc.odin index 487fcb715..6cb443092 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. +package dynlib implements 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. From 8e410f82045eaabd24fd45f15df25ef2e56248b4 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 9 Oct 2025 14:22:56 +0100 Subject: [PATCH 076/113] Add "possibly nil" comments to ast.odin --- core/odin/ast/ast.odin | 120 ++++++++++++++++++++--------------------- 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/core/odin/ast/ast.odin b/core/odin/ast/ast.odin index 3b8998b31..dbb7f5e52 100644 --- a/core/odin/ast/ast.odin +++ b/core/odin/ast/ast.odin @@ -70,7 +70,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 +137,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 +170,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 +224,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 +291,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 +384,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 +398,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 +413,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 +436,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 +460,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 +470,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 +481,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 +498,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 +689,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 +710,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 +729,7 @@ Poly_Type :: struct { using node: Expr, dollar: tokenizer.Pos, type: ^Ident, - specialization: ^Expr, + specialization: ^Expr, // possibly nil } Proc_Type :: struct { @@ -746,7 +746,7 @@ Proc_Type :: struct { Pointer_Type :: struct { using node: Expr, - tag: ^Expr, + tag: ^Expr, // possibly nil pointer: tokenizer.Pos, elem: ^Expr, } @@ -762,7 +762,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 +770,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 +780,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 +803,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 +814,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 +827,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 +864,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 { From aec7d6480be79bb32c9937ff06ec38baff89e344 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Thu, 9 Oct 2025 15:27:53 +0200 Subject: [PATCH 077/113] Package lines for base32, move its tests to tests" --- core/debug/pe/doc.odin | 2 + core/encoding/base32/base32.odin | 4 +- core/encoding/base32/doc.odin | 2 + .../core/encoding/base32/base32.odin | 37 ++++++++++--------- tests/core/normal.odin | 1 + 5 files changed, 28 insertions(+), 18 deletions(-) create mode 100644 core/debug/pe/doc.odin create mode 100644 core/encoding/base32/doc.odin rename core/encoding/base32/base32_test.odin => tests/core/encoding/base32/base32.odin (87%) diff --git a/core/debug/pe/doc.odin b/core/debug/pe/doc.odin new file mode 100644 index 000000000..7fc32b030 --- /dev/null +++ b/core/debug/pe/doc.odin @@ -0,0 +1,2 @@ +// package pe implements a reader for the PE executable format for debug purposes +package debug_pe \ No newline at end of file diff --git a/core/encoding/base32/base32.odin b/core/encoding/base32/base32.odin index 2267a872b..6c3abf29c 100644 --- a/core/encoding/base32/base32.odin +++ b/core/encoding/base32/base32.odin @@ -1,6 +1,8 @@ +package encoding_base32 + // Base32 encoding/decoding implementation as specified in RFC 4648. // [[ More; https://www.rfc-editor.org/rfc/rfc4648.html ]] -package encoding_base32 + // @note(zh): Encoding utility for Base32 // A secondary param can be used to supply a custom alphabet to diff --git a/core/encoding/base32/doc.odin b/core/encoding/base32/doc.odin new file mode 100644 index 000000000..8d6f57c88 --- /dev/null +++ b/core/encoding/base32/doc.odin @@ -0,0 +1,2 @@ +// package base32 implements Base32 encoding/decoding, as specified in RFC 4648. +package encoding_base32 \ No newline at end of file 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" From 940b0c54bcbdabbc38d562fc7da7c21099ac392b Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 9 Oct 2025 15:01:57 +0100 Subject: [PATCH 078/113] Add doc line to `core:mem/virtual` --- core/mem/virtual/doc.odin | 62 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 core/mem/virtual/doc.odin diff --git a/core/mem/virtual/doc.odin b/core/mem/virtual/doc.odin new file mode 100644 index 000000000..143bb228f --- /dev/null +++ b/core/mem/virtual/doc.odin @@ -0,0 +1,62 @@ +/* +package mem/virtual implements 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 virtual + From 025cb03242fea23bf632967291419dcd1f881e28 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 9 Oct 2025 15:02:16 +0100 Subject: [PATCH 079/113] Add `all-bits` to feature tag --- src/parser.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/parser.cpp b/src/parser.cpp index 363eb0c55..94c6083f7 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -6424,6 +6424,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; } @@ -6436,6 +6437,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; } } From af189b45f37dcb01ba37230f6a04bcf5260b2a48 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 9 Oct 2025 15:04:28 +0100 Subject: [PATCH 080/113] Fix typo --- core/mem/virtual/doc.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/mem/virtual/doc.odin b/core/mem/virtual/doc.odin index 143bb228f..b4235b356 100644 --- a/core/mem/virtual/doc.odin +++ b/core/mem/virtual/doc.odin @@ -58,5 +58,5 @@ Example: */ -package virtual +package mem_virtual From 248b0fe9e155e1a00a04cb7b1fc687601d401d7c Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Thu, 9 Oct 2025 16:11:33 +0200 Subject: [PATCH 081/113] More package lines --- core/bytes/bytes.odin | 2 +- core/c/c.odin | 2 +- core/c/libc/doc.odin | 2 +- core/compress/common.odin | 7 +++---- core/compress/gzip/doc.odin | 2 +- core/compress/zlib/doc.odin | 2 +- core/container/bit_array/doc.odin | 2 +- core/container/priority_queue/doc.odin | 2 +- core/container/rbtree/doc.odin | 2 +- core/crypto/aead/doc.odin | 6 +++--- core/crypto/aegis/aegis.odin | 5 +++-- core/crypto/chacha20poly1305/chacha20poly1305.odin | 6 +++--- core/crypto/crypto.odin | 5 +---- core/crypto/deoxysii/deoxysii.odin | 3 +-- core/encoding/base32/doc.odin | 2 +- core/encoding/base64/doc.odin | 2 ++ core/encoding/cbor/doc.odin | 6 +++--- 17 files changed, 28 insertions(+), 30 deletions(-) create mode 100644 core/encoding/base64/doc.odin diff --git a/core/bytes/bytes.odin b/core/bytes/bytes.odin index 859f90318..d4a0804b5 100644 --- a/core/bytes/bytes.odin +++ b/core/bytes/bytes.odin @@ -1,4 +1,4 @@ -// package bytes implements procedures for manipulation of byte slices +// package bytes implements procedures for manipulation of byte slices. package bytes import "base:intrinsics" diff --git a/core/c/c.odin b/core/c/c.odin index 907b2f80f..c609cefd1 100644 --- a/core/c/c.odin +++ b/core/c/c.odin @@ -1,4 +1,4 @@ -// package c just defines the basic types used by C programs +// package c just defines the basic types used by C programs. package c import builtin "base:builtin" diff --git a/core/c/libc/doc.odin b/core/c/libc/doc.odin index 883a3dda5..29fb40a30 100644 --- a/core/c/libc/doc.odin +++ b/core/c/libc/doc.odin @@ -1,2 +1,2 @@ -// package libc declares the commonly used things in "libc" (C standard library) +// package libc 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..917dcfba5 100644 --- a/core/compress/common.odin +++ b/core/compress/common.odin @@ -1,3 +1,6 @@ +// package compress is a collection of utilities to aid with other compression 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 745d020c5..c35f205e5 100644 --- a/core/compress/gzip/doc.odin +++ b/core/compress/gzip/doc.odin @@ -1,4 +1,4 @@ -// package gzip implements a small GZIP implementation as an example. +// package gzip implements a small GZIP unpacker as an example. package compress_gzip /* Copyright 2021 Jeroen van Rijn . diff --git a/core/compress/zlib/doc.odin b/core/compress/zlib/doc.odin index 19ef1c045..f143073a3 100644 --- a/core/compress/zlib/doc.odin +++ b/core/compress/zlib/doc.odin @@ -1,4 +1,4 @@ -// package zlib implements Deflate decompression +// package zlib implements Deflate decompression. package compress_zlib /* Copyright 2021 Jeroen van Rijn . diff --git a/core/container/bit_array/doc.odin b/core/container/bit_array/doc.odin index 6d35d48d1..3ff6f5765 100644 --- a/core/container/bit_array/doc.odin +++ b/core/container/bit_array/doc.odin @@ -1,4 +1,4 @@ -// package bit_array implements a dynamically-sized array of bits +// package bit_array implements a dynamically-sized array of bits. package container_dynamic_bit_array /* diff --git a/core/container/priority_queue/doc.odin b/core/container/priority_queue/doc.odin index a71a9dd28..7cba4af8d 100644 --- a/core/container/priority_queue/doc.odin +++ b/core/container/priority_queue/doc.odin @@ -1,2 +1,2 @@ -// package priority_queue implements a Priority Queue data structure +// package priority_queue implements a Priority Queue data structure. package container_priority_queue \ No newline at end of file diff --git a/core/container/rbtree/doc.odin b/core/container/rbtree/doc.odin index 691442e8e..3ff154d18 100644 --- a/core/container/rbtree/doc.odin +++ b/core/container/rbtree/doc.odin @@ -1,2 +1,2 @@ -// package rbtree implements a red-black tree +// package rbtree implements a red-black tree. package container_rbtree \ No newline at end of file diff --git a/core/crypto/aead/doc.odin b/core/crypto/aead/doc.odin index 93be674a0..687b4deae 100644 --- a/core/crypto/aead/doc.odin +++ b/core/crypto/aead/doc.odin @@ -1,6 +1,6 @@ + /* -package aead provides a generic interface to the supported Authenticated -Encryption with Associated Data algorithms. +package aead implements a generic interface to Authenticated Encryption with Associated Data 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 +54,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..c0d8bf4ee 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. +package aegis implements the 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/chacha20poly1305/chacha20poly1305.odin b/core/crypto/chacha20poly1305/chacha20poly1305.odin index 6706b3820..f6f375a84 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. +package chacha20poly1305 implements the CHACHA20_POLY1305 and XChaCha20_Poly1305 AEAD 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..52ccb00de 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. -*/ +// package crypto implements 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..db72ff194 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. +package deoxysii implements the Deoxys-II-256 Authenticated Encryption with Additional Data algorithm. - [[ https://sites.google.com/view/deoxyscipher ]] - [[ https://thomaspeyrin.github.io/web/assets/docs/papers/Jean-etal-JoC2021.pdf ]] diff --git a/core/encoding/base32/doc.odin b/core/encoding/base32/doc.odin index 8d6f57c88..34d12e657 100644 --- a/core/encoding/base32/doc.odin +++ b/core/encoding/base32/doc.odin @@ -1,2 +1,2 @@ -// package base32 implements Base32 encoding/decoding, as specified in RFC 4648. +// package base32 implements Base32 encoding and decoding, as specified in RFC 4648. package encoding_base32 \ No newline at end of file diff --git a/core/encoding/base64/doc.odin b/core/encoding/base64/doc.odin new file mode 100644 index 000000000..902cf660e --- /dev/null +++ b/core/encoding/base64/doc.odin @@ -0,0 +1,2 @@ +// package base64 implements Base64 encoding and decoding +package encoding_base64 \ No newline at end of file diff --git a/core/encoding/cbor/doc.odin b/core/encoding/cbor/doc.odin index b3fa36130..92f0fa02d 100644 --- a/core/encoding/cbor/doc.odin +++ b/core/encoding/cbor/doc.odin @@ -1,3 +1,5 @@ +// package cbor implements encoding, decoding, marshaling and unmarshaling types from/into RCF 8949 compatible CBOR binary. +package encoding_cbor /* Package cbor encodes, decodes, marshals and unmarshals types from/into RCF 8949 compatible CBOR binary. Also provided are conversion to and from JSON and the CBOR diagnostic format. @@ -164,6 +166,4 @@ Output: "renamed :)": 123123.12500000, "str": "Hello, World!" } -*/ -package encoding_cbor - +*/ \ No newline at end of file From 288b45f50cd6691f19066a775b5e065cf89dc2bd Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Thu, 9 Oct 2025 16:34:18 +0200 Subject: [PATCH 082/113] package lines for encoding --- core/crypto/hkdf/hkdf.odin | 3 +-- core/crypto/x25519/x25519.odin | 3 +-- core/crypto/x448/x448.odin | 3 +-- core/debug/pe/doc.odin | 2 +- core/encoding/base64/doc.odin | 2 +- core/encoding/cbor/doc.odin | 2 +- core/encoding/endian/doc.odin | 3 +-- core/encoding/entity/entity.odin | 18 +++++++++--------- core/encoding/hex/hex.odin | 1 + core/encoding/hxa/doc.odin | 3 ++- core/encoding/ini/ini.odin | 1 + core/encoding/json/doc.odin | 2 ++ core/encoding/uuid/doc.odin | 3 +-- core/encoding/varint/doc.odin | 2 +- core/encoding/xml/doc.odin | 2 +- 15 files changed, 25 insertions(+), 25 deletions(-) create mode 100644 core/encoding/json/doc.odin diff --git a/core/crypto/hkdf/hkdf.odin b/core/crypto/hkdf/hkdf.odin index bffe09eff..9d9497668 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. +package hkdf implements the HKDF HMAC-based Extract-and-Expand Key Derivation Function. See: [[ https://www.rfc-editor.org/rfc/rfc5869 ]] */ diff --git a/core/crypto/x25519/x25519.odin b/core/crypto/x25519/x25519.odin index 6805c3ff8..8c0c6570d 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. +package x25519 implements the 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..727bacf27 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. +package x448 implements the X448 (aka curve448) Elliptic-Curve Diffie-Hellman key exchange protocol. See: - [[ https://www.rfc-editor.org/rfc/rfc7748 ]] diff --git a/core/debug/pe/doc.odin b/core/debug/pe/doc.odin index 7fc32b030..5de03446b 100644 --- a/core/debug/pe/doc.odin +++ b/core/debug/pe/doc.odin @@ -1,2 +1,2 @@ -// package pe implements a reader for the PE executable format for debug purposes +// package pe implements a reader for the PE executable format for debug purposes. package debug_pe \ No newline at end of file diff --git a/core/encoding/base64/doc.odin b/core/encoding/base64/doc.odin index 902cf660e..0eab8ae09 100644 --- a/core/encoding/base64/doc.odin +++ b/core/encoding/base64/doc.odin @@ -1,2 +1,2 @@ -// package base64 implements Base64 encoding and decoding +// package base64 implements Base64 encoding and decoding. package encoding_base64 \ No newline at end of file diff --git a/core/encoding/cbor/doc.odin b/core/encoding/cbor/doc.odin index 92f0fa02d..f0388daa9 100644 --- a/core/encoding/cbor/doc.odin +++ b/core/encoding/cbor/doc.odin @@ -1,4 +1,4 @@ -// package cbor implements encoding, decoding, marshaling and unmarshaling types from/into RCF 8949 compatible CBOR binary. +// package cbor implements encoding and decoding types from/into RCF 8949 compatible CBOR binary. package encoding_cbor /* Package cbor encodes, decodes, marshals and unmarshals types from/into RCF 8949 compatible CBOR binary. diff --git a/core/encoding/endian/doc.odin b/core/encoding/endian/doc.odin index 0b43e3097..0c397b29f 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. + Package endian implements 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..45841d125 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. + package entity implements a unicode `&entity;` encoder and decoder. 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..9e0837450 100644 --- a/core/encoding/hex/hex.odin +++ b/core/encoding/hex/hex.odin @@ -1,3 +1,4 @@ +// package hex implements 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..bfca89d3c 100644 --- a/core/encoding/hxa/doc.odin +++ b/core/encoding/hxa/doc.odin @@ -1,5 +1,6 @@ /* -Implementation of the HxA 3D asset format +package hxa implements 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..f58aaed4d 100644 --- a/core/encoding/ini/ini.odin +++ b/core/encoding/ini/ini.odin @@ -1,3 +1,4 @@ +// package ini implements 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/doc.odin b/core/encoding/json/doc.odin new file mode 100644 index 000000000..04c38d142 --- /dev/null +++ b/core/encoding/json/doc.odin @@ -0,0 +1,2 @@ +// package json implements encoding and decoding JSON in strict JSON, JSON5 and BitSquid variants. +package encoding_json \ No newline at end of file diff --git a/core/encoding/uuid/doc.odin b/core/encoding/uuid/doc.odin index f910c33d8..373740a8e 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. +package uuid implements Universally Unique Identifiers according to RFC 4122, with additions from RFC 9562. The UUIDs are textually represented and read in the following string format: `00000000-0000-v000-V000-000000000000` diff --git a/core/encoding/varint/doc.odin b/core/encoding/varint/doc.odin index a00cfed15..ccc9493cd 100644 --- a/core/encoding/varint/doc.odin +++ b/core/encoding/varint/doc.odin @@ -1,5 +1,5 @@ /* -Implementation of the LEB128 variable integer encoding as used by DWARF encoding and DEX files, among others. +package varint implements LEB128 variable integer encoding and decoding, as used by DWARF & DEX files. Author of this Odin package: Jeroen van Rijn diff --git a/core/encoding/xml/doc.odin b/core/encoding/xml/doc.odin index 10d9f78be..8746fae02 100644 --- a/core/encoding/xml/doc.odin +++ b/core/encoding/xml/doc.odin @@ -1,5 +1,5 @@ /* -XML 1.0 / 1.1 parser +package xml implements 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 ]]. From 51cd08296f618a8c2b25aa4f31f584d98024896a Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Thu, 9 Oct 2025 16:58:41 +0200 Subject: [PATCH 083/113] package lines for core:hash --- core/hash/xxhash/common.odin | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/core/hash/xxhash/common.odin b/core/hash/xxhash/common.odin index 636393b52..a0f26fe4e 100644 --- a/core/hash/xxhash/common.odin +++ b/core/hash/xxhash/common.odin @@ -1,3 +1,8 @@ +// package xxhash implements 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" From 673358f8b9e2b8daf95790e75b17204eeeb7dd82 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Thu, 9 Oct 2025 17:18:51 +0200 Subject: [PATCH 084/113] Package lines for `core:image`. --- core/image/bmp/bmp.odin | 2 +- core/image/common.odin | 5 ++--- core/image/jpeg/jpeg.odin | 1 + core/image/netpbm/doc.odin | 2 ++ core/image/png/doc.odin | 2 +- core/image/qoi/qoi.odin | 11 +++++------ core/image/tga/tga.odin | 7 +++---- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/core/image/bmp/bmp.odin b/core/image/bmp/bmp.odin index d5a094e83..189e371de 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 +// package bmp implements a Microsoft BMP image reader and writer. 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/jpeg/jpeg.odin b/core/image/jpeg/jpeg.odin index 818bd13d5..b95f6ef99 100644 --- a/core/image/jpeg/jpeg.odin +++ b/core/image/jpeg/jpeg.odin @@ -1,3 +1,4 @@ +// package jpeg implements a 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..720a7dc2a 100644 --- a/core/image/netpbm/doc.odin +++ b/core/image/netpbm/doc.odin @@ -1,4 +1,6 @@ /* +package netpbm implements 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..6b402dcb2 100644 --- a/core/image/png/doc.odin +++ b/core/image/png/doc.odin @@ -1,5 +1,5 @@ /* -package png implements a PNG image reader +package png implements a PNG image reader. The PNG specification is at [[ https://www.w3.org/TR/PNG/ ]]. diff --git a/core/image/qoi/qoi.odin b/core/image/qoi/qoi.odin index ded8d7971..8e4ff03e0 100644 --- a/core/image/qoi/qoi.odin +++ b/core/image/qoi/qoi.odin @@ -1,3 +1,8 @@ +// package qoi implements a QOI image reader. +// +// 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..f2e34484b 100644 --- a/core/image/tga/tga.odin +++ b/core/image/tga/tga.odin @@ -1,3 +1,6 @@ +// package tga implements a TGA image reader and writer for 8-bit RGB and RGBA 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" From be9384fc8d869e6dcf111ce29481dc6daaf42d38 Mon Sep 17 00:00:00 2001 From: A1029384756 Date: Thu, 9 Oct 2025 12:03:25 -0400 Subject: [PATCH 085/113] [llvm-14-fixes] use specific `LLVMConst*` codepaths for LLVM 14 --- src/llvm_backend_const.cpp | 41 ++++++++++++++++++++++++++++++------ src/llvm_backend_general.cpp | 25 ---------------------- 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index 37dccf571..4c154c85a 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -114,7 +114,7 @@ gb_internal LLVMValueRef llvm_const_cast(lbModule *m, LLVMValueRef val, LLVMType if (!LLVMIsLiteralStruct(dst)) { return LLVMConstNamedStruct(dst, field_vals, dst_n); } else { - return LLVMConstStructInContext(m->ctx, field_vals, dst_n, LLVMIsPackedStruct(dst)); + return LLVMConstStructInContext(m->ctx, field_vals, dst_n, LLVMIsPackedStruct(dst)); } } } @@ -568,6 +568,7 @@ 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); @@ -597,8 +598,27 @@ LLVMValueRef llvm_const_pad_to_size(lbModule *m, LLVMValueRef val, LLVMTypeRef d 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 = llvm_const_shl(m, llvm_const_zext(m, elem_int, src_int_ty), LLVMConstInt(src_int_ty, i * elem_bits, false)); - as_int = llvm_const_or(m, as_int, shifted); + 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)); @@ -608,7 +628,7 @@ LLVMValueRef llvm_const_pad_to_size(lbModule *m, LLVMValueRef val, LLVMTypeRef d if (src_bits != dst_bits) { LLVMTypeRef dst_int_ty = LLVMIntTypeInContext(ctx, dst_bits); if (src_bits < dst_bits) { - as_int = llvm_const_zext(m, as_int, dst_int_ty); + as_int = LLVMConstZExt(as_int, dst_int_ty); } else { as_int = LLVMConstTrunc(as_int, dst_int_ty); } @@ -632,7 +652,7 @@ LLVMValueRef llvm_const_pad_to_size(lbModule *m, LLVMValueRef val, LLVMTypeRef d LLVMTypeRef as_int_ty = LLVMTypeOf(as_int); for (unsigned i = 0; i < elem_count; i++) { - LLVMValueRef shifted = llvm_const_lshr(m, as_int, LLVMConstInt(as_int_ty, i * elem_bits, false)); + 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); @@ -644,6 +664,7 @@ LLVMValueRef llvm_const_pad_to_size(lbModule *m, LLVMValueRef val, LLVMTypeRef d 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) { @@ -730,11 +751,19 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, lb lbValue cv = lb_const_value(m, value_type, value, cc, value_type); Type *variant_type = cv.type; - LLVMValueRef values[3] = {}; + 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); diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 9e3042d5a..39cf70a6a 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -449,31 +449,6 @@ gb_internal LLVMValueRef llvm_const_insert_value(lbModule *m, LLVMValueRef agg, } -gb_internal LLVMValueRef llvm_const_shl(lbModule *m, LLVMValueRef a, LLVMValueRef b) { - LLVMValueRef res = LLVMBuildShl(m->const_dummy_builder, a, b, ""); - GB_ASSERT(LLVMIsConstant(res)); - return res; -} - -gb_internal LLVMValueRef llvm_const_lshr(lbModule *m, LLVMValueRef a, LLVMValueRef b) { - LLVMValueRef res = LLVMBuildLShr(m->const_dummy_builder, a, b, ""); - GB_ASSERT(LLVMIsConstant(res)); - return res; -} - -gb_internal LLVMValueRef llvm_const_or(lbModule *m, LLVMValueRef a, LLVMValueRef b) { - LLVMValueRef res = LLVMBuildOr(m->const_dummy_builder, a, b, ""); - GB_ASSERT(LLVMIsConstant(res)); - return res; -} - -gb_internal LLVMValueRef llvm_const_zext(lbModule *m, LLVMValueRef a, LLVMTypeRef b) { - LLVMValueRef res = LLVMBuildZExt(m->const_dummy_builder, a, b, ""); - GB_ASSERT(LLVMIsConstant(res)); - return res; -} - - gb_internal LLVMValueRef llvm_cstring(lbModule *m, String const &str) { From c4c2431997d1854fe9d746e04a240239a88aab6d Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Thu, 9 Oct 2025 19:56:21 +0200 Subject: [PATCH 086/113] Package lines for `core:math` and more. --- core/log/log.odin | 1 + core/math/big/api.odin | 4 ++-- core/math/big/common.odin | 5 ++--- core/math/big/doc.odin | 7 ++++--- core/math/big/helpers.odin | 5 ++--- core/math/big/internal.odin | 4 ++-- core/math/big/logical.odin | 5 ++--- core/math/big/prime.odin | 5 ++--- core/math/big/private.odin | 5 ++--- core/math/big/public.odin | 5 ++--- core/math/big/radix.odin | 5 ++--- core/math/big/tune.odin | 6 +++--- core/math/bits/bits.odin | 1 + core/math/cmplx/cmplx.odin | 1 + core/math/ease/ease.odin | 2 +- core/math/fixed/fixed.odin | 1 + core/math/linalg/doc.odin | 2 +- core/math/linalg/glsl/linalg_glsl.odin | 2 +- core/math/linalg/hlsl/linalg_hlsl.odin | 2 +- core/math/math.odin | 1 + core/math/noise/internal.odin | 5 +++-- core/math/noise/opensimplex2.odin | 2 +- core/math/rand/rand.odin | 5 +---- 23 files changed, 39 insertions(+), 42 deletions(-) diff --git a/core/log/log.odin b/core/log/log.odin index b2efe8beb..892132255 100644 --- a/core/log/log.odin +++ b/core/log/log.odin @@ -1,3 +1,4 @@ +// package log implements the context.Logger interface. package log import "base:runtime" 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 index 0f9b88d01..04650d6dc 100644 --- a/core/math/big/doc.odin +++ b/core/math/big/doc.odin @@ -1,6 +1,7 @@ +// package big implements arbitrary precision integers and rationals. +package math_big + /* -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 +*/ \ No newline at end of file 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..ed929a09d 100644 --- a/core/math/big/public.odin +++ b/core/math/big/public.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 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..f9059f7d8 100644 --- a/core/math/bits/bits.odin +++ b/core/math/bits/bits.odin @@ -1,3 +1,4 @@ +// package bits implements 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..3249cc4b4 100644 --- a/core/math/cmplx/cmplx.odin +++ b/core/math/cmplx/cmplx.odin @@ -1,3 +1,4 @@ +// package cmplx implements 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..2d6a7c924 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 +// package ease implements 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..0f0555e4e 100644 --- a/core/math/fixed/fixed.odin +++ b/core/math/fixed/fixed.odin @@ -1,3 +1,4 @@ +// package fixed implements 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..be1686bb8 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 +// package linalg implements 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..c24908b0f 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 +// package glsl implements a 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..3993f7055 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 +// package hlsl implements a HLSL-like mathematics library plus numerous other utility procedures. package math_linalg_hlsl import "base:builtin" diff --git a/core/math/math.odin b/core/math/math.odin index b399b4dac..39f2be42c 100644 --- a/core/math/math.odin +++ b/core/math/math.odin @@ -1,3 +1,4 @@ +// package math implements typical trignometric and other basic math routines. package math import "base:intrinsics" 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..08ff3c938 100644 --- a/core/math/noise/opensimplex2.odin +++ b/core/math/noise/opensimplex2.odin @@ -1,5 +1,5 @@ /* - OpenSimplex2 noise implementation. + package noise implements the OpenSimplex2 noise algorithm. Ported from [[ https://github.com/KdotJPG/OpenSimplex2 }]. Copyright 2022 Yuki2 [[ https://github.com/NoahR02 ]] diff --git a/core/math/rand/rand.odin b/core/math/rand/rand.odin index 6b9a73395..4feecc8bb 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 -*/ +// package rand implements various random number generators. package rand import "base:intrinsics" From 8a35acd50609e3ac1463bffebc79955b7ea619b8 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Thu, 9 Oct 2025 20:11:06 +0200 Subject: [PATCH 087/113] More package lines. --- core/hash/doc.odin | 2 ++ core/image/doc.odin | 2 ++ core/mem/doc.odin | 3 +-- core/mem/tlsf/tlsf.odin | 6 +++--- core/mem/virtual/doc.odin | 2 +- core/net/doc.odin | 31 ++++++++++++++-------------- core/odin/ast/ast.odin | 1 + core/odin/doc-format/doc_format.odin | 1 + core/odin/doc.odin | 2 ++ core/odin/parser/parser.odin | 1 + core/odin/tokenizer/tokenizer.odin | 1 + core/os/os.odin | 1 + 12 files changed, 31 insertions(+), 22 deletions(-) create mode 100644 core/hash/doc.odin create mode 100644 core/image/doc.odin create mode 100644 core/odin/doc.odin diff --git a/core/hash/doc.odin b/core/hash/doc.odin new file mode 100644 index 000000000..5fdc79cb7 --- /dev/null +++ b/core/hash/doc.odin @@ -0,0 +1,2 @@ +// package hash implements crc32, crc64, adler32, djb, fnv, jenkins, murmur and other hashes. +package hash \ No newline at end of file diff --git a/core/image/doc.odin b/core/image/doc.odin new file mode 100644 index 000000000..cb6bc4d96 --- /dev/null +++ b/core/image/doc.odin @@ -0,0 +1,2 @@ +// package image implements a general 2D image library to be used with other image related packages. +package image \ No newline at end of file diff --git a/core/mem/doc.odin b/core/mem/doc.odin index 580b08c96..8b4a77b6c 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. +package mem implements 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/tlsf/tlsf.odin b/core/mem/tlsf/tlsf.odin index 0ae8c28e0..792abb08e 100644 --- a/core/mem/tlsf/tlsf.odin +++ b/core/mem/tlsf/tlsf.odin @@ -1,3 +1,6 @@ +// package tlsf implements a 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 index b4235b356..b423afde6 100644 --- a/core/mem/virtual/doc.odin +++ b/core/mem/virtual/doc.odin @@ -1,5 +1,5 @@ /* -package mem/virtual implements a platform agnostic way to reserve/commit/decommit virtual memory +package virtual implements a platform agnostic way to reserve/commit/decommit virtual memory. virtual.Arena usage diff --git a/core/net/doc.odin b/core/net/doc.odin index ed720c0ae..1d6ad776a 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. +package net implements 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 dbb7f5e52..d69a51f92 100644 --- a/core/odin/ast/ast.odin +++ b/core/odin/ast/ast.odin @@ -1,3 +1,4 @@ +// package ast implements the Abstract Syntax Tree for the Odin parser packages. package odin_ast import "core:odin/tokenizer" diff --git a/core/odin/doc-format/doc_format.odin b/core/odin/doc-format/doc_format.odin index e6804c981..b9a9cc2d3 100644 --- a/core/odin/doc-format/doc_format.odin +++ b/core/odin/doc-format/doc_format.odin @@ -1,3 +1,4 @@ +// package doc-format implements 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..69c40ccaf --- /dev/null +++ b/core/odin/doc.odin @@ -0,0 +1,2 @@ +// package odin implements 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..e898b030f 100644 --- a/core/odin/parser/parser.odin +++ b/core/odin/parser/parser.odin @@ -1,3 +1,4 @@ +// package parser implements 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..6f4d4eb16 100644 --- a/core/odin/tokenizer/tokenizer.odin +++ b/core/odin/tokenizer/tokenizer.odin @@ -1,3 +1,4 @@ +// package tokenizer implements 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..0c437c5ff 100644 --- a/core/os/os.odin +++ b/core/os/os.odin @@ -1,3 +1,4 @@ +// package os implements cross-platform OS interactions like file I/O. package os import "base:intrinsics" From 2bc409eab53bb7208ec59d431112489eb9d226db Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Thu, 9 Oct 2025 20:40:13 +0200 Subject: [PATCH 088/113] More package lines. --- core/path/filepath/path.odin | 4 ++-- core/path/slashpath/path.odin | 3 +-- core/prof/spall/doc.odin | 2 +- core/reflect/doc.odin | 2 +- core/relative/relative.odin | 1 + core/simd/simd.odin | 2 +- core/simd/x86/doc.odin | 2 ++ core/slice/heap/heap.odin | 6 +++--- core/slice/slice.odin | 1 + 9 files changed, 13 insertions(+), 10 deletions(-) create mode 100644 core/simd/x86/doc.odin diff --git a/core/path/filepath/path.odin b/core/path/filepath/path.odin index e23183b02..d23fa1ff1 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 +// package 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 slashpath package. package filepath import "base:runtime" diff --git a/core/path/slashpath/path.odin b/core/path/slashpath/path.odin index 52b4878bc..5067fa147 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 +// package slashpath is only to be used for paths separated by forward slashes, e.g. paths in URLs. // // 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 be84cac2d..597527b84 100644 --- a/core/prof/spall/doc.odin +++ b/core/prof/spall/doc.odin @@ -1,5 +1,5 @@ /* -package spall is a package that is used for profiling using the "spall" format +package spall is a package that is used for profiling using the "spall" format. Example: package main diff --git a/core/reflect/doc.odin b/core/reflect/doc.odin index 1c94f3dbc..eb8bd7030 100644 --- a/core/reflect/doc.odin +++ b/core/reflect/doc.odin @@ -1,4 +1,4 @@ -// Package reflect provides utility procedures and types to perform runtime type introspection/reflection (RTTI). +// package reflect provides 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! // diff --git a/core/relative/relative.odin b/core/relative/relative.odin index 30a7b86ae..c3e55971b 100644 --- a/core/relative/relative.odin +++ b/core/relative/relative.odin @@ -1,3 +1,4 @@ +// package relative implements relative pointers and slices. package relative_types import "base:intrinsics" diff --git a/core/simd/simd.odin b/core/simd/simd.odin index da76ed49b..3aee09944 100644 --- a/core/simd/simd.odin +++ b/core/simd/simd.odin @@ -1,5 +1,5 @@ /* -The SIMD support package. +package simd implements 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 diff --git a/core/simd/x86/doc.odin b/core/simd/x86/doc.odin new file mode 100644 index 000000000..1a43fa3aa --- /dev/null +++ b/core/simd/x86/doc.odin @@ -0,0 +1,2 @@ +// package x86 implements 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..f3c016656 100644 --- a/core/slice/heap/heap.odin +++ b/core/slice/heap/heap.odin @@ -1,3 +1,6 @@ +// package heap implements 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/slice.odin b/core/slice/slice.odin index 8337a9728..b103473b7 100644 --- a/core/slice/slice.odin +++ b/core/slice/slice.odin @@ -1,3 +1,4 @@ +// package slice implements utility procedures for working with slices, including sorting and searching them. package slice import "base:intrinsics" From 7a9ea3ee6d02d8eade6d7988498bd69716391563 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Thu, 9 Oct 2025 23:05:29 +0200 Subject: [PATCH 089/113] Further overhaul of package line comments. --- core/bufio/doc.odin | 2 +- core/bytes/bytes.odin | 2 +- core/c/c.odin | 2 +- core/c/libc/doc.odin | 2 +- core/compress/common.odin | 2 +- core/compress/gzip/doc.odin | 2 +- core/compress/shoco/doc.odin | 2 -- core/compress/shoco/shoco.odin | 2 +- core/compress/zlib/doc.odin | 2 +- core/container/avl/avl.odin | 6 +----- core/container/bit_array/doc.odin | 2 +- core/container/intrusive/list/doc.odin | 2 +- core/container/lru/doc.odin | 2 -- core/container/lru/lru_cache.odin | 1 + core/container/priority_queue/doc.odin | 2 -- .../priority_queue/priority_queue.odin | 1 + core/container/queue/doc.odin | 2 -- core/container/queue/queue.odin | 1 + core/container/rbtree/doc.odin | 2 -- core/container/rbtree/rbtree.odin | 1 + core/container/small_array/doc.odin | 2 +- core/container/topological_sort/doc.odin | 2 -- .../topological_sort/topological_sort.odin | 8 ++----- core/crypto/aead/doc.odin | 3 +-- core/crypto/aegis/aegis.odin | 2 +- core/crypto/aes/aes.odin | 2 +- core/crypto/blake2b/blake2b.odin | 2 +- core/crypto/blake2s/blake2s.odin | 2 +- core/crypto/chacha20/chacha20.odin | 2 +- .../chacha20poly1305/chacha20poly1305.odin | 2 +- core/crypto/crypto.odin | 2 +- core/crypto/deoxysii/deoxysii.odin | 2 +- core/crypto/ed25519/ed25519.odin | 2 +- core/crypto/hash/doc.odin | 2 +- core/crypto/hkdf/hkdf.odin | 2 +- core/crypto/hmac/hmac.odin | 2 +- core/crypto/kmac/kmac.odin | 2 +- core/crypto/legacy/keccak/keccak.odin | 2 +- core/crypto/legacy/md5/md5.odin | 2 +- core/crypto/legacy/sha1/sha1.odin | 2 +- core/crypto/pbkdf2/pbkdf2.odin | 2 +- core/crypto/poly1305/poly1305.odin | 2 +- core/crypto/ristretto255/ristretto255.odin | 2 +- core/crypto/sha2/sha2.odin | 2 +- core/crypto/sha3/sha3.odin | 2 +- core/crypto/shake/shake.odin | 2 +- core/crypto/siphash/siphash.odin | 2 +- core/crypto/sm3/sm3.odin | 2 +- core/crypto/tuplehash/tuplehash.odin | 2 +- core/crypto/x25519/x25519.odin | 2 +- core/crypto/x448/x448.odin | 2 +- core/debug/pe/doc.odin | 2 +- core/debug/trace/doc.odin | 2 +- core/dynlib/doc.odin | 2 +- core/encoding/base32/base32.odin | 1 + core/encoding/base32/doc.odin | 2 -- core/encoding/base64/base64.odin | 1 + core/encoding/base64/doc.odin | 2 -- core/encoding/cbor/doc.odin | 2 +- core/encoding/csv/doc.odin | 2 +- core/encoding/endian/doc.odin | 2 +- core/encoding/entity/entity.odin | 2 +- core/encoding/hex/hex.odin | 2 +- core/encoding/hxa/doc.odin | 2 +- core/encoding/ini/ini.odin | 2 +- core/encoding/json/doc.odin | 2 -- core/encoding/json/types.odin | 1 + core/encoding/uuid/doc.odin | 2 +- core/encoding/uuid/legacy/legacy.odin | 5 ++--- core/encoding/varint/doc.odin | 2 +- core/encoding/xml/doc.odin | 2 +- core/flags/doc.odin | 2 +- core/fmt/doc.odin | 2 +- core/hash/doc.odin | 2 +- core/hash/xxhash/common.odin | 2 +- core/image/bmp/bmp.odin | 2 +- core/image/doc.odin | 2 +- core/image/jpeg/jpeg.odin | 2 +- core/image/netpbm/doc.odin | 2 +- core/image/png/doc.odin | 2 +- core/image/qoi/qoi.odin | 2 +- core/image/tga/tga.odin | 2 +- core/io/io.odin | 2 +- core/log/log.odin | 2 +- core/math/big/doc.odin | 7 ------- core/math/big/public.odin | 1 + core/math/bits/bits.odin | 2 +- core/math/cmplx/cmplx.odin | 2 +- core/math/ease/ease.odin | 2 +- core/math/fixed/fixed.odin | 2 +- core/math/linalg/doc.odin | 2 +- core/math/linalg/glsl/linalg_glsl.odin | 2 +- core/math/linalg/hlsl/linalg_hlsl.odin | 2 +- core/math/math.odin | 2 +- core/math/noise/opensimplex2.odin | 2 +- core/math/rand/rand.odin | 2 +- core/mem/doc.odin | 2 +- core/mem/tlsf/tlsf.odin | 2 +- core/mem/virtual/doc.odin | 2 +- core/net/doc.odin | 2 +- core/odin/ast/ast.odin | 2 +- core/odin/doc-format/doc_format.odin | 2 +- core/odin/doc.odin | 2 +- core/odin/parser/parser.odin | 2 +- core/odin/tokenizer/tokenizer.odin | 2 +- core/os/os.odin | 2 +- core/path/filepath/path.odin | 2 +- core/path/slashpath/path.odin | 2 +- core/prof/spall/doc.odin | 2 +- core/reflect/doc.odin | 2 +- core/relative/relative.odin | 2 +- core/simd/simd.odin | 2 +- core/simd/x86/doc.odin | 2 +- core/slice/heap/heap.odin | 2 +- core/slice/slice.odin | 2 +- core/sort/sort.odin | 1 + core/strconv/decimal/decimal.odin | 5 +++-- core/strconv/strconv.odin | 2 +- core/strings/strings.odin | 2 +- core/sync/chan/doc.odin | 3 +-- core/sync/doc.odin | 8 ++----- core/sys/info/doc.odin | 21 +++++++++---------- core/sys/orca/macros.odin | 2 +- core/sys/posix/posix.odin | 2 +- core/terminal/ansi/doc.odin | 5 ++--- core/terminal/doc.odin | 4 ---- core/terminal/terminal.odin | 1 + core/testing/testing.odin | 1 + core/text/edit/text_edit.odin | 2 ++ core/text/i18n/doc.odin | 2 +- core/text/match/strlib.odin | 1 + core/text/regex/common/common.odin | 2 +- core/text/regex/compiler/doc.odin | 3 +-- core/text/regex/doc.odin | 3 +-- core/text/regex/optimizer/doc.odin | 5 +++-- core/text/regex/parser/doc.odin | 3 +-- core/text/regex/tokenizer/tokenizer.odin | 1 + core/text/regex/virtual_machine/doc.odin | 5 ++--- core/text/scanner/scanner.odin | 2 +- core/text/table/doc.odin | 2 +- core/thread/thread.odin | 2 +- core/time/time.odin | 1 + core/time/timezone/tzdate.odin | 1 + core/unicode/doc.odin | 2 +- core/unicode/utf16/utf16.odin | 2 +- core/unicode/utf8/utf8.odin | 2 +- core/unicode/utf8/utf8string/string.odin | 2 +- 147 files changed, 155 insertions(+), 186 deletions(-) delete mode 100644 core/compress/shoco/doc.odin delete mode 100644 core/container/lru/doc.odin delete mode 100644 core/container/priority_queue/doc.odin delete mode 100644 core/container/queue/doc.odin delete mode 100644 core/container/rbtree/doc.odin delete mode 100644 core/container/topological_sort/doc.odin delete mode 100644 core/encoding/base32/doc.odin delete mode 100644 core/encoding/base64/doc.odin delete mode 100644 core/encoding/json/doc.odin delete mode 100644 core/math/big/doc.odin delete mode 100644 core/terminal/doc.odin diff --git a/core/bufio/doc.odin b/core/bufio/doc.odin index f725e83dc..683f68f07 100644 --- a/core/bufio/doc.odin +++ b/core/bufio/doc.odin @@ -1,2 +1,2 @@ -// package bufio implements buffered I/O. It wraps an `io.Stream` interface to provide buffering. +// Wraps an `io.Stream` interface to provide buffered I/O. package bufio \ No newline at end of file diff --git a/core/bytes/bytes.odin b/core/bytes/bytes.odin index d4a0804b5..79de89d2f 100644 --- a/core/bytes/bytes.odin +++ b/core/bytes/bytes.odin @@ -1,4 +1,4 @@ -// package bytes implements procedures for manipulation of byte slices. +// Procedures for manipulation of `[]byte` slices. package bytes import "base:intrinsics" diff --git a/core/c/c.odin b/core/c/c.odin index c609cefd1..8266bf38a 100644 --- a/core/c/c.odin +++ b/core/c/c.odin @@ -1,4 +1,4 @@ -// package c just defines the basic types used by C programs. +// 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 index 29fb40a30..856ee41c6 100644 --- a/core/c/libc/doc.odin +++ b/core/c/libc/doc.odin @@ -1,2 +1,2 @@ -// package libc declares the commonly used things in "libc" (C standard library). +// 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 917dcfba5..796a60071 100644 --- a/core/compress/common.odin +++ b/core/compress/common.odin @@ -1,4 +1,4 @@ -// package compress is a collection of utilities to aid with other compression packages. +// A collection of utilities to aid with other `compress`ion packages. package compress /* diff --git a/core/compress/gzip/doc.odin b/core/compress/gzip/doc.odin index c35f205e5..8a04c41bd 100644 --- a/core/compress/gzip/doc.odin +++ b/core/compress/gzip/doc.odin @@ -1,4 +1,4 @@ -// package gzip implements a small GZIP unpacker as an example. +// A small `GZIP` unpacker. package compress_gzip /* Copyright 2021 Jeroen van Rijn . diff --git a/core/compress/shoco/doc.odin b/core/compress/shoco/doc.odin deleted file mode 100644 index 78ab01776..000000000 --- a/core/compress/shoco/doc.odin +++ /dev/null @@ -1,2 +0,0 @@ -// package shoco is an implementation of the shoco short string compressor. -package compress_shoco \ No newline at end of file diff --git a/core/compress/shoco/shoco.odin b/core/compress/shoco/shoco.odin index d8810e532..be079df19 100644 --- a/core/compress/shoco/shoco.odin +++ b/core/compress/shoco/shoco.odin @@ -1,4 +1,4 @@ -// package shoco is an implementation of the shoco short string compressor. +// `Shoco` short string compression and decompression. package compress_shoco /* diff --git a/core/compress/zlib/doc.odin b/core/compress/zlib/doc.odin index f143073a3..9c3893e2f 100644 --- a/core/compress/zlib/doc.odin +++ b/core/compress/zlib/doc.odin @@ -1,4 +1,4 @@ -// package zlib implements Deflate decompression. +// `Deflate` decompression of raw and `ZLIB`-type streams. package compress_zlib /* Copyright 2021 Jeroen van Rijn . 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 3ff6f5765..aa27817e8 100644 --- a/core/container/bit_array/doc.odin +++ b/core/container/bit_array/doc.odin @@ -1,4 +1,4 @@ -// package bit_array implements a dynamically-sized array of bits. +// A dynamically-sized array of bits. package container_dynamic_bit_array /* diff --git a/core/container/intrusive/list/doc.odin b/core/container/intrusive/list/doc.odin index 78502e35d..b84e32bd9 100644 --- a/core/container/intrusive/list/doc.odin +++ b/core/container/intrusive/list/doc.odin @@ -1,4 +1,4 @@ -// package list implements an intrusive doubly-linked list. +// An intrusive doubly-linked list. package container_intrusive_list /* diff --git a/core/container/lru/doc.odin b/core/container/lru/doc.odin deleted file mode 100644 index 540487bc6..000000000 --- a/core/container/lru/doc.odin +++ /dev/null @@ -1,2 +0,0 @@ -// package lru implements an LRU cache. It automatically removes older entries if its capacity is reached. -package container_lru \ 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/doc.odin b/core/container/priority_queue/doc.odin deleted file mode 100644 index 7cba4af8d..000000000 --- a/core/container/priority_queue/doc.odin +++ /dev/null @@ -1,2 +0,0 @@ -// package priority_queue implements a Priority Queue data structure. -package container_priority_queue \ No newline at end of file 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/doc.odin b/core/container/queue/doc.odin deleted file mode 100644 index efb29fc2a..000000000 --- a/core/container/queue/doc.odin +++ /dev/null @@ -1,2 +0,0 @@ -// package queue implements a dynamically resizable double-ended queue/ring-buffer. -package container_queue \ No newline at end of file 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/doc.odin b/core/container/rbtree/doc.odin deleted file mode 100644 index 3ff154d18..000000000 --- a/core/container/rbtree/doc.odin +++ /dev/null @@ -1,2 +0,0 @@ -// package rbtree implements a red-black tree. -package container_rbtree \ No newline at end of file diff --git a/core/container/rbtree/rbtree.odin b/core/container/rbtree/rbtree.odin index 6a3b9c9ea..35ce21413 100644 --- a/core/container/rbtree/rbtree.odin +++ b/core/container/rbtree/rbtree.odin @@ -1,3 +1,4 @@ +// A red-black tree with the same API as our AVL tree. package container_rbtree @(require) import "base:intrinsics" diff --git a/core/container/small_array/doc.odin b/core/container/small_array/doc.odin index a57caf798..12ad6b134 100644 --- a/core/container/small_array/doc.odin +++ b/core/container/small_array/doc.odin @@ -1,4 +1,4 @@ -// 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. package container_small_array /* diff --git a/core/container/topological_sort/doc.odin b/core/container/topological_sort/doc.odin deleted file mode 100644 index cd79e0e54..000000000 --- a/core/container/topological_sort/doc.odin +++ /dev/null @@ -1,2 +0,0 @@ -// package topological_sort implements a generic O(V+E) topological sorter. -package container_topological_sort \ 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 6afe9c453..a49d04b49 100644 --- a/core/container/topological_sort/topological_sort.odin +++ b/core/container/topological_sort/topological_sort.odin @@ -1,11 +1,7 @@ +// 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 -/* - 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. -*/ - import "base:intrinsics" import "base:runtime" _ :: intrinsics diff --git a/core/crypto/aead/doc.odin b/core/crypto/aead/doc.odin index 687b4deae..811dd564d 100644 --- a/core/crypto/aead/doc.odin +++ b/core/crypto/aead/doc.odin @@ -1,6 +1,5 @@ - /* -package aead implements a generic interface to 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, diff --git a/core/crypto/aegis/aegis.odin b/core/crypto/aegis/aegis.odin index c0d8bf4ee..41b7ad5be 100644 --- a/core/crypto/aegis/aegis.odin +++ b/core/crypto/aegis/aegis.odin @@ -1,5 +1,5 @@ /* -package aegis implements the AEGIS-128L and AEGIS-256 AEAD algorithms. +`AEGIS-128L` and `AEGIS-256` AEAD algorithms. Where AEAD stands for Authenticated Encryption with Additional Data. 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 f6f375a84..9840d357e 100644 --- a/core/crypto/chacha20poly1305/chacha20poly1305.odin +++ b/core/crypto/chacha20poly1305/chacha20poly1305.odin @@ -1,5 +1,5 @@ /* -package chacha20poly1305 implements the CHACHA20_POLY1305 and XChaCha20_Poly1305 AEAD algorithms. +`AEAD_CHACHA20_POLY1305` and `AEAD_XChaCha20_Poly1305` algorithms. Where AEAD stands for Authenticated Encryption with Additional Data. diff --git a/core/crypto/crypto.odin b/core/crypto/crypto.odin index 52ccb00de..89e92e35f 100644 --- a/core/crypto/crypto.odin +++ b/core/crypto/crypto.odin @@ -1,4 +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 db72ff194..3ebcfea30 100644 --- a/core/crypto/deoxysii/deoxysii.odin +++ b/core/crypto/deoxysii/deoxysii.odin @@ -1,5 +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 9d9497668..b3a6bf303 100644 --- a/core/crypto/hkdf/hkdf.odin +++ b/core/crypto/hkdf/hkdf.odin @@ -1,5 +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 8c0c6570d..e25d1831f 100644 --- a/core/crypto/x25519/x25519.odin +++ b/core/crypto/x25519/x25519.odin @@ -1,5 +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 727bacf27..75693e055 100644 --- a/core/crypto/x448/x448.odin +++ b/core/crypto/x448/x448.odin @@ -1,5 +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/doc.odin b/core/debug/pe/doc.odin index 5de03446b..7590d328f 100644 --- a/core/debug/pe/doc.odin +++ b/core/debug/pe/doc.odin @@ -1,2 +1,2 @@ -// package pe implements a reader for the PE executable format for debug purposes. +// A reader for the Windows `PE` executable format for debug purposes. package debug_pe \ No newline at end of file diff --git a/core/debug/trace/doc.odin b/core/debug/trace/doc.odin index 40f055161..c9b715653 100644 --- a/core/debug/trace/doc.odin +++ b/core/debug/trace/doc.odin @@ -1,4 +1,4 @@ -// package debug implements a stack trace library. Only works when debug symbols are enabled `-debug`. +// Stack trace library. Only works when debug symbols are enabled using `-debug`. package debug_trace /* Example: diff --git a/core/dynlib/doc.odin b/core/dynlib/doc.odin index 6cb443092..f727a299c 100644 --- a/core/dynlib/doc.odin +++ b/core/dynlib/doc.odin @@ -1,5 +1,5 @@ /* -package 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/encoding/base32/base32.odin b/core/encoding/base32/base32.odin index 6c3abf29c..d49d62f77 100644 --- a/core/encoding/base32/base32.odin +++ b/core/encoding/base32/base32.odin @@ -1,3 +1,4 @@ +// `Base32` encoding and decoding, as specified in `RFC 4648`. package encoding_base32 // Base32 encoding/decoding implementation as specified in RFC 4648. diff --git a/core/encoding/base32/doc.odin b/core/encoding/base32/doc.odin deleted file mode 100644 index 34d12e657..000000000 --- a/core/encoding/base32/doc.odin +++ /dev/null @@ -1,2 +0,0 @@ -// package base32 implements Base32 encoding and decoding, as specified in RFC 4648. -package encoding_base32 \ No newline at end of file diff --git a/core/encoding/base64/base64.odin b/core/encoding/base64/base64.odin index 1013a7d0b..1960b4b55 100644 --- a/core/encoding/base64/base64.odin +++ b/core/encoding/base64/base64.odin @@ -1,3 +1,4 @@ +// `Base64` encoding and decoding. package encoding_base64 import "core:io" diff --git a/core/encoding/base64/doc.odin b/core/encoding/base64/doc.odin deleted file mode 100644 index 0eab8ae09..000000000 --- a/core/encoding/base64/doc.odin +++ /dev/null @@ -1,2 +0,0 @@ -// package base64 implements Base64 encoding and decoding. -package encoding_base64 \ No newline at end of file diff --git a/core/encoding/cbor/doc.odin b/core/encoding/cbor/doc.odin index f0388daa9..4acc63139 100644 --- a/core/encoding/cbor/doc.odin +++ b/core/encoding/cbor/doc.odin @@ -1,4 +1,4 @@ -// package cbor implements encoding and decoding types from/into RCF 8949 compatible CBOR binary. +// Encoding and decoding types from/into `RCF 8949` compatible `CBOR` binary. package encoding_cbor /* Package cbor encodes, decodes, marshals and unmarshals types from/into RCF 8949 compatible CBOR binary. diff --git a/core/encoding/csv/doc.odin b/core/encoding/csv/doc.odin index 7abe2be49..2b9fdd849 100644 --- a/core/encoding/csv/doc.odin +++ b/core/encoding/csv/doc.odin @@ -1,5 +1,5 @@ /* -package csv reads and writes comma-separated values (CSV) files. +Reader and writer for comma-separated values (`CSV`) files, per `RFC 4180`. This package supports the format described in [[ RFC 4180; https://tools.ietf.org/html/rfc4180.html ]] Example: diff --git a/core/encoding/endian/doc.odin b/core/encoding/endian/doc.odin index 0c397b29f..7cc9da1b7 100644 --- a/core/encoding/endian/doc.odin +++ b/core/encoding/endian/doc.odin @@ -1,5 +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 45841d125..28ff58170 100644 --- a/core/encoding/entity/entity.odin +++ b/core/encoding/entity/entity.odin @@ -1,5 +1,5 @@ /* - package entity implements a unicode `&entity;` encoder and 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 diff --git a/core/encoding/hex/hex.odin b/core/encoding/hex/hex.odin index 9e0837450..318e52ace 100644 --- a/core/encoding/hex/hex.odin +++ b/core/encoding/hex/hex.odin @@ -1,4 +1,4 @@ -// package hex implements encoding and decoding of hex-encoded binary, e.g. `0x23` -> `#`. +// 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 bfca89d3c..902428668 100644 --- a/core/encoding/hxa/doc.odin +++ b/core/encoding/hxa/doc.odin @@ -1,5 +1,5 @@ /* -package hxa implements Eskil Steenberg's HxA 3D asset interchange 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 f58aaed4d..a119b0f2e 100644 --- a/core/encoding/ini/ini.odin +++ b/core/encoding/ini/ini.odin @@ -1,4 +1,4 @@ -// package ini implements a variant of the `.ini` file format with `key = value` entries in `[sections]`. +// 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/doc.odin b/core/encoding/json/doc.odin deleted file mode 100644 index 04c38d142..000000000 --- a/core/encoding/json/doc.odin +++ /dev/null @@ -1,2 +0,0 @@ -// package json implements encoding and decoding JSON in strict JSON, JSON5 and BitSquid variants. -package encoding_json \ No newline at end of file diff --git a/core/encoding/json/types.odin b/core/encoding/json/types.odin index 41eb21377..a5f9daa02 100644 --- a/core/encoding/json/types.odin +++ b/core/encoding/json/types.odin @@ -1,3 +1,4 @@ +// Encoding and decoding JSON in strict `JSON`, `JSON5` and `BitSquid` variants. package encoding_json import "core:strings" diff --git a/core/encoding/uuid/doc.odin b/core/encoding/uuid/doc.odin index 373740a8e..c2622c56b 100644 --- a/core/encoding/uuid/doc.odin +++ b/core/encoding/uuid/doc.odin @@ -1,5 +1,5 @@ /* -package uuid implements Universally Unique Identifiers according to RFC 4122, with additions from RFC 9562. +Universally Unique Identifiers (`UUID`) according to `RFC 4122`, with additions from `RFC 9562`. 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 ccc9493cd..23a28f913 100644 --- a/core/encoding/varint/doc.odin +++ b/core/encoding/varint/doc.odin @@ -1,5 +1,5 @@ /* -package varint implements LEB128 variable integer encoding and decoding, as used by DWARF & DEX files. +`LEB128` variable integer encoding and decoding, as used by `DWARF` & `DEX` files. Author of this Odin package: Jeroen van Rijn diff --git a/core/encoding/xml/doc.odin b/core/encoding/xml/doc.odin index 8746fae02..79d960847 100644 --- a/core/encoding/xml/doc.odin +++ b/core/encoding/xml/doc.odin @@ -1,5 +1,5 @@ /* -package xml implements a parser for a useful subset of the XML specification. +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 ]]. 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 index 5fdc79cb7..d7531a4c2 100644 --- a/core/hash/doc.odin +++ b/core/hash/doc.odin @@ -1,2 +1,2 @@ -// package hash implements crc32, crc64, adler32, djb, fnv, jenkins, murmur and other hashes. +// `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 a0f26fe4e..ce98f21f9 100644 --- a/core/hash/xxhash/common.odin +++ b/core/hash/xxhash/common.odin @@ -1,4 +1,4 @@ -// package xxhash implements Yann Collet's xxhash. +// Yann Collet's `xxhash`. // // [[ xxhash Fast Hash Algorithm; https://cyan4973.github.io/xxHash/ ]] package xxhash diff --git a/core/image/bmp/bmp.odin b/core/image/bmp/bmp.odin index 189e371de..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 and writer. +// Reader and writer for Microsoft `BMP` images. package core_image_bmp import "core:image" diff --git a/core/image/doc.odin b/core/image/doc.odin index cb6bc4d96..1e44cca59 100644 --- a/core/image/doc.odin +++ b/core/image/doc.odin @@ -1,2 +1,2 @@ -// package image implements a general 2D image library to be used with other image related packages. +// 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 b95f6ef99..241066273 100644 --- a/core/image/jpeg/jpeg.odin +++ b/core/image/jpeg/jpeg.odin @@ -1,4 +1,4 @@ -// package jpeg implements a reader for baseline JPEG images. +// 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 720a7dc2a..bac893b0f 100644 --- a/core/image/netpbm/doc.odin +++ b/core/image/netpbm/doc.odin @@ -1,5 +1,5 @@ /* -package netpbm implements readers and writers for PBM, PGM, PPM, PAM and PFM images. +Readers and writers for `PBM`, `PGM`, `PPM`, `PAM` and `PFM` images. Formats: diff --git a/core/image/png/doc.odin b/core/image/png/doc.odin index 6b402dcb2..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/qoi/qoi.odin b/core/image/qoi/qoi.odin index 8e4ff03e0..a2b38a7a6 100644 --- a/core/image/qoi/qoi.odin +++ b/core/image/qoi/qoi.odin @@ -1,4 +1,4 @@ -// package qoi implements a QOI image reader. +// Reader and writer for `QOI` images. // // The QOI specification is at [[ https://qoiformat.org ]]. package qoi diff --git a/core/image/tga/tga.odin b/core/image/tga/tga.odin index f2e34484b..ad939e7ff 100644 --- a/core/image/tga/tga.odin +++ b/core/image/tga/tga.odin @@ -1,4 +1,4 @@ -// package tga implements a TGA image reader and writer for 8-bit RGB and RGBA images. +// Reader and writer for 8-bit RGB and RGBA `TGA` images. package tga /* 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 892132255..4209a2850 100644 --- a/core/log/log.odin +++ b/core/log/log.odin @@ -1,4 +1,4 @@ -// package log implements the context.Logger interface. +// Implementations of the `context.Logger` interface. package log import "base:runtime" diff --git a/core/math/big/doc.odin b/core/math/big/doc.odin deleted file mode 100644 index 04650d6dc..000000000 --- a/core/math/big/doc.odin +++ /dev/null @@ -1,7 +0,0 @@ -// package big implements arbitrary precision integers and rationals. -package math_big - -/* -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. -*/ \ No newline at end of file diff --git a/core/math/big/public.odin b/core/math/big/public.odin index ed929a09d..dfefbc91a 100644 --- a/core/math/big/public.odin +++ b/core/math/big/public.odin @@ -1,3 +1,4 @@ +// Arbitrary precision integers and rationals. package math_big /* diff --git a/core/math/bits/bits.odin b/core/math/bits/bits.odin index f9059f7d8..effcf4985 100644 --- a/core/math/bits/bits.odin +++ b/core/math/bits/bits.odin @@ -1,4 +1,4 @@ -// package bits implements bit-level operations, including the ability to set or toggle individual bits in an integer. +// 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 3249cc4b4..f5c572cc6 100644 --- a/core/math/cmplx/cmplx.odin +++ b/core/math/cmplx/cmplx.odin @@ -1,4 +1,4 @@ -// package cmplx implements trigonometric and other mathematic operations on complex numbers. +// 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 2d6a7c924..c6dd56dbc 100644 --- a/core/math/ease/ease.odin +++ b/core/math/ease/ease.odin @@ -1,4 +1,4 @@ -// package ease implements 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 0f0555e4e..28f87b6d2 100644 --- a/core/math/fixed/fixed.odin +++ b/core/math/fixed/fixed.odin @@ -1,4 +1,4 @@ -// package fixed implements fixed-point rational numbers and conversion to/from `f64`. +// 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 be1686bb8..38a894148 100644 --- a/core/math/linalg/doc.odin +++ b/core/math/linalg/doc.odin @@ -1,2 +1,2 @@ -// package 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 c24908b0f..46ee7a6f7 100644 --- a/core/math/linalg/glsl/linalg_glsl.odin +++ b/core/math/linalg/glsl/linalg_glsl.odin @@ -1,4 +1,4 @@ -// package 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 3993f7055..5c78bd8b1 100644 --- a/core/math/linalg/hlsl/linalg_hlsl.odin +++ b/core/math/linalg/hlsl/linalg_hlsl.odin @@ -1,4 +1,4 @@ -// package 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/math.odin b/core/math/math.odin index 39f2be42c..34642049c 100644 --- a/core/math/math.odin +++ b/core/math/math.odin @@ -1,4 +1,4 @@ -// package math implements typical trignometric and other basic math routines. +// Typical trignometric and other basic math routines. package math import "base:intrinsics" diff --git a/core/math/noise/opensimplex2.odin b/core/math/noise/opensimplex2.odin index 08ff3c938..ef12a26fa 100644 --- a/core/math/noise/opensimplex2.odin +++ b/core/math/noise/opensimplex2.odin @@ -1,5 +1,5 @@ /* - package noise implements the OpenSimplex2 noise algorithm. + `OpenSimplex2` noise algorithm. Ported from [[ https://github.com/KdotJPG/OpenSimplex2 }]. Copyright 2022 Yuki2 [[ https://github.com/NoahR02 ]] diff --git a/core/math/rand/rand.odin b/core/math/rand/rand.odin index 4feecc8bb..8e270b7df 100644 --- a/core/math/rand/rand.odin +++ b/core/math/rand/rand.odin @@ -1,4 +1,4 @@ -// package 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 8b4a77b6c..657251902 100644 --- a/core/mem/doc.odin +++ b/core/mem/doc.odin @@ -1,5 +1,5 @@ /* -package mem implements various allocators and provides helpers 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/tlsf/tlsf.odin b/core/mem/tlsf/tlsf.odin index 792abb08e..37c6858ec 100644 --- a/core/mem/tlsf/tlsf.odin +++ b/core/mem/tlsf/tlsf.odin @@ -1,4 +1,4 @@ -// package tlsf implements a Two Level Segregated Fit memory allocator. +// Two Level Segregated Fit memory allocator. package mem_tlsf /* diff --git a/core/mem/virtual/doc.odin b/core/mem/virtual/doc.odin index b423afde6..614e290c3 100644 --- a/core/mem/virtual/doc.odin +++ b/core/mem/virtual/doc.odin @@ -1,5 +1,5 @@ /* -package virtual implements a platform agnostic way to reserve/commit/decommit virtual memory. +A platform agnostic way to reserve/commit/decommit virtual memory. virtual.Arena usage diff --git a/core/net/doc.odin b/core/net/doc.odin index 1d6ad776a..082a1497a 100644 --- a/core/net/doc.odin +++ b/core/net/doc.odin @@ -1,5 +1,5 @@ /* -package net implements cross-platform Berkeley Sockets, DNS resolution and associated procedures. +Cross-platform Berkeley Sockets, `DNS` resolution and associated procedures. Features: - Supports Windows, Linux and OSX. diff --git a/core/odin/ast/ast.odin b/core/odin/ast/ast.odin index d69a51f92..4dcc1f215 100644 --- a/core/odin/ast/ast.odin +++ b/core/odin/ast/ast.odin @@ -1,4 +1,4 @@ -// package ast implements the Abstract Syntax Tree for the Odin parser packages. +// Abstract Syntax Tree for the `Odin` parser packages. package odin_ast import "core:odin/tokenizer" diff --git a/core/odin/doc-format/doc_format.odin b/core/odin/doc-format/doc_format.odin index b9a9cc2d3..e37092948 100644 --- a/core/odin/doc-format/doc_format.odin +++ b/core/odin/doc-format/doc_format.odin @@ -1,4 +1,4 @@ -// package doc-format implements the .odin-doc file format, as used by these package docs at pkg.odin-lang.org. +// 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 index 69c40ccaf..40aeaea7f 100644 --- a/core/odin/doc.odin +++ b/core/odin/doc.odin @@ -1,2 +1,2 @@ -// package odin implements a lexer and parser for the Odin language for the purposes of writing tooling. +// 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 e898b030f..94ea649f9 100644 --- a/core/odin/parser/parser.odin +++ b/core/odin/parser/parser.odin @@ -1,4 +1,4 @@ -// package parser implements the *.odin file parser to be used in tooling. +// 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 6f4d4eb16..9f46f2ed6 100644 --- a/core/odin/tokenizer/tokenizer.odin +++ b/core/odin/tokenizer/tokenizer.odin @@ -1,4 +1,4 @@ -// package tokenizer implements the tokenizer (lexer) for *.odin files, used to create tooling. +// 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 0c437c5ff..da7b0c151 100644 --- a/core/os/os.odin +++ b/core/os/os.odin @@ -1,4 +1,4 @@ -// package os implements cross-platform OS interactions like file I/O. +// Cross-platform `OS` interactions like file `I/O`. package os import "base:intrinsics" diff --git a/core/path/filepath/path.odin b/core/path/filepath/path.odin index d23fa1ff1..14a9181c3 100644 --- a/core/path/filepath/path.odin +++ b/core/path/filepath/path.odin @@ -1,4 +1,4 @@ -// package filepath package uses either forward slashes or backslashes depending on the operating system. +// 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 diff --git a/core/path/slashpath/path.odin b/core/path/slashpath/path.odin index 5067fa147..1d2a24453 100644 --- a/core/path/slashpath/path.odin +++ b/core/path/slashpath/path.odin @@ -1,4 +1,4 @@ -// package slashpath 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 597527b84..2098a12d6 100644 --- a/core/prof/spall/doc.odin +++ b/core/prof/spall/doc.odin @@ -1,5 +1,5 @@ /* -package spall is a package that is used for profiling using the "spall" format. +Profiling using the "`spall`" format. Example: package main diff --git a/core/reflect/doc.odin b/core/reflect/doc.odin index eb8bd7030..5ec5e7070 100644 --- a/core/reflect/doc.odin +++ b/core/reflect/doc.odin @@ -1,4 +1,4 @@ -// package reflect provides utility procedures and types to perform runtime type introspection/reflection (RTTI). +// 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! // diff --git a/core/relative/relative.odin b/core/relative/relative.odin index c3e55971b..791ac6f7d 100644 --- a/core/relative/relative.odin +++ b/core/relative/relative.odin @@ -1,4 +1,4 @@ -// package relative implements relative pointers and slices. +// Relative pointers and slices. package relative_types import "base:intrinsics" diff --git a/core/simd/simd.odin b/core/simd/simd.odin index 3aee09944..bca661757 100644 --- a/core/simd/simd.odin +++ b/core/simd/simd.odin @@ -1,5 +1,5 @@ /* -package simd implements cross-platform SIMD support types and procedures. +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 diff --git a/core/simd/x86/doc.odin b/core/simd/x86/doc.odin index 1a43fa3aa..dcdc30abd 100644 --- a/core/simd/x86/doc.odin +++ b/core/simd/x86/doc.odin @@ -1,2 +1,2 @@ -// package x86 implements SIMD intrinsics specific to the Intel x86 and AMD64 architectures. +// `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 f3c016656..dd088f250 100644 --- a/core/slice/heap/heap.odin +++ b/core/slice/heap/heap.odin @@ -1,4 +1,4 @@ -// package heap implements a generic in-place max heap on a slice for any type. +// A generic in-place max heap on a slice for any type. package heap /* diff --git a/core/slice/slice.odin b/core/slice/slice.odin index b103473b7..0d0cadefa 100644 --- a/core/slice/slice.odin +++ b/core/slice/slice.odin @@ -1,4 +1,4 @@ -// package slice implements utility procedures for working with slices, including sorting and searching them. +// Utility procedures for working with slices, including sorting and searching them. package slice import "base:intrinsics" 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/strconv.odin b/core/strconv/strconv.odin index 5634f1712..48a75d972 100644 --- a/core/strconv/strconv.odin +++ b/core/strconv/strconv.odin @@ -1,4 +1,4 @@ -// package strconv implements conversions to and from string represnetations of other data types +// Conversions to and from `string` representations of other data types like integers and booleans. package strconv import "core:unicode/utf8" diff --git a/core/strings/strings.odin b/core/strings/strings.odin index 79a8cec29..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" 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..d19bb13a0 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. @@ -87,3 +77,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/orca/macros.odin b/core/sys/orca/macros.odin index 12adfdb91..60dbdae99 100644 --- a/core/sys/orca/macros.odin +++ b/core/sys/orca/macros.odin @@ -1,4 +1,4 @@ -// File contains implementations of the Orca API that are defined as macros in Orca. +// Implementations of the `Orca` API that are defined as macros in Orca. package orca 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/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 05f907bb6..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" 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 c5018a5fe..26c1a3e27 100644 --- a/core/thread/thread.odin +++ b/core/thread/thread.odin @@ -1,4 +1,4 @@ -// package thread implements multi-threading operations so spawn threads and thread pools +// 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 index 4d9ff78f5..302fd59e1 100644 --- a/core/unicode/doc.odin +++ b/core/unicode/doc.odin @@ -1,2 +1,2 @@ -// package unicode provides data and procedures to test properties of Unicode code points +// Data and procedures to test properties of `Unicode` code points. package unicode \ No newline at end of file diff --git a/core/unicode/utf16/utf16.odin b/core/unicode/utf16/utf16.odin index 75c553f62..990d5bafa 100644 --- a/core/unicode/utf16/utf16.odin +++ b/core/unicode/utf16/utf16.odin @@ -1,4 +1,4 @@ -// package utf16 implements procedures and constants to support text-encoding in the UTF-16 character encoding +// 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 5740ae71e..281e36f43 100644 --- a/core/unicode/utf8/utf8.odin +++ b/core/unicode/utf8/utf8.odin @@ -1,4 +1,4 @@ -// package utf8 implements procedures and constants to support text-encoding in the UTF-8 character encoding +// Procedures and constants to support text-encoding in the `UTF-8` character encoding. package utf8 RUNE_ERROR :: '\ufffd' diff --git a/core/unicode/utf8/utf8string/string.odin b/core/unicode/utf8/utf8string/string.odin index 7d067a9bf..7ece469a4 100644 --- a/core/unicode/utf8/utf8string/string.odin +++ b/core/unicode/utf8/utf8string/string.odin @@ -1,4 +1,4 @@ -// package utf8string provides a convenient and efficient way to index strings by Unicode code point (rune) rather than byte +// A convenient and efficient way to index strings by `Unicode` code point (`rune`) rather than byte. package utf8string import "core:unicode/utf8" From 4723ec75adfc8bcea4477d46838f3b966c7ecea5 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 10 Oct 2025 09:47:31 +0100 Subject: [PATCH 090/113] Use `sync.Mutex` instead of a boolean-check for `log.Log_Allocator` --- core/log/log_allocator.odin | 141 ++++++++++++++++++------------------ 1 file changed, 70 insertions(+), 71 deletions(-) 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 } From 4068eeb5fae3981b34a5e5ae96e7c1b0c0eedc85 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 10 Oct 2025 09:57:53 +0100 Subject: [PATCH 091/113] Add `Raw_String16`/`Raw_Cstring16` to `core:mem` --- core/mem/raw.odin | 11 +++++++++++ 1 file changed, 11 insertions(+) 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. */ From ece213afca742bb91e9328230fd21b6b94c85662 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Fri, 10 Oct 2025 12:24:28 +0200 Subject: [PATCH 092/113] Render examples. --- core/compress/gzip/doc.odin | 25 +++++++++--------- core/compress/zlib/doc.odin | 23 +++++++++-------- core/container/bit_array/doc.odin | 14 +++++------ core/container/intrusive/list/doc.odin | 10 +++----- core/container/small_array/doc.odin | 12 ++++----- core/debug/pe/doc.odin | 2 -- core/debug/pe/pe.odin | 1 + core/debug/trace/doc.odin | 7 +++--- core/dynlib/example/example.odin | 2 +- core/encoding/base32/base32.odin | 34 ++++++++++++------------- core/encoding/base64/base64.odin | 17 +++++++------ core/encoding/cbor/doc.odin | 8 +++--- core/encoding/json/types.odin | 22 ++++++++-------- core/encoding/varint/doc.odin | 4 +-- core/encoding/varint/leb128.odin | 4 +-- core/encoding/xml/doc.odin | 6 ++--- core/encoding/xml/xml_reader.odin | 6 ++--- core/hash/xxhash/streaming.odin | 4 +-- core/hash/xxhash/xxhash_3.odin | 4 +-- core/hash/xxhash/xxhash_32.odin | 4 +-- core/hash/xxhash/xxhash_64.odin | 4 +-- core/image/png/helpers.odin | 4 +-- core/image/png/png.odin | 7 +++--- core/prof/spall/doc.odin | 2 ++ core/sys/info/doc.odin | 35 +++++++++++++------------- core/sys/info/platform_windows.odin | 13 +++++----- core/sys/orca/macros.odin | 4 +-- core/sys/orca/odin.odin | 4 +-- core/sys/orca/orca.odin | 3 +++ 29 files changed, 146 insertions(+), 139 deletions(-) delete mode 100644 core/debug/pe/doc.odin diff --git a/core/compress/gzip/doc.odin b/core/compress/gzip/doc.odin index 8a04c41bd..18f2259cb 100644 --- a/core/compress/gzip/doc.odin +++ b/core/compress/gzip/doc.odin @@ -1,17 +1,6 @@ -// A small `GZIP` unpacker. -package compress_gzip /* - 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,4 +77,16 @@ Example: } bytes.buffer_destroy(&buf) } +*/ +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/zlib/doc.odin b/core/compress/zlib/doc.odin index 9c3893e2f..6923c2a60 100644 --- a/core/compress/zlib/doc.odin +++ b/core/compress/zlib/doc.odin @@ -1,16 +1,6 @@ -// `Deflate` decompression of raw and `ZLIB`-type streams. -package compress_zlib /* - 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,4 +39,15 @@ Example: fmt.printf("Input: %v bytes, output (%v bytes):\n%v\n", len(ODIN_DEMO), len(s), s) assert(len(s) == OUTPUT_SIZE) } +*/ +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/bit_array/doc.odin b/core/container/bit_array/doc.odin index aa27817e8..e86059ecd 100644 --- a/core/container/bit_array/doc.odin +++ b/core/container/bit_array/doc.odin @@ -1,10 +1,9 @@ -// A dynamically-sized array of bits. -package container_dynamic_bit_array - /* +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 @@ -21,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 @@ -51,4 +50,5 @@ Example: fmt.printf("Get(Negative_Test): %v, %v\n", get(bits, Foo.Negative_Test)) fmt.printf("Freed.\n") } -*/ \ No newline at end of file +*/ +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 b84e32bd9..a50c27216 100644 --- a/core/container/intrusive/list/doc.odin +++ b/core/container/intrusive/list/doc.odin @@ -1,10 +1,7 @@ -// An intrusive doubly-linked list. -package container_intrusive_list - /* -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, @@ -48,4 +45,5 @@ Example: Output: Hello World -*/ \ No newline at end of file +*/ +package container_intrusive_list \ No newline at end of file diff --git a/core/container/small_array/doc.odin b/core/container/small_array/doc.odin index 12ad6b134..21d000a10 100644 --- a/core/container/small_array/doc.odin +++ b/core/container/small_array/doc.odin @@ -1,8 +1,7 @@ -// A dynamic array-like interface on a stack-allocated, fixed-size array. -package container_small_array - /* -The Small_Array type is optimal for scenarios where you need +A dynamic array-like interface on a stack-allocated, fixed-size array. + +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) { @@ -51,4 +50,5 @@ Output: Hellope -*/ \ No newline at end of file +*/ +package container_small_array \ No newline at end of file diff --git a/core/debug/pe/doc.odin b/core/debug/pe/doc.odin deleted file mode 100644 index 7590d328f..000000000 --- a/core/debug/pe/doc.odin +++ /dev/null @@ -1,2 +0,0 @@ -// A reader for the Windows `PE` executable format for debug purposes. -package debug_pe \ No newline at end of file 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 c9b715653..e5fd3f7c2 100644 --- a/core/debug/trace/doc.odin +++ b/core/debug/trace/doc.odin @@ -1,6 +1,6 @@ -// Stack trace library. Only works when debug symbols are enabled using `-debug`. -package debug_trace /* +Stack trace library. Only works when debug symbols are enabled using `-debug`. + Example: import "base:runtime" import "core:debug/trace" @@ -47,4 +47,5 @@ Example: ... } -*/ \ No newline at end of file +*/ +package debug_trace \ No newline at end of file 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 d49d62f77..f50db12b3 100644 --- a/core/encoding/base32/base32.odin +++ b/core/encoding/base32/base32.odin @@ -1,22 +1,22 @@ -// `Base32` encoding and decoding, as specified in `RFC 4648`. +/* +`Base32` encoding and decoding, as specified in `RFC 4648`. + +[[ 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 -// Base32 encoding/decoding implementation as specified in RFC 4648. -// [[ More; https://www.rfc-editor.org/rfc/rfc4648.html ]] - - -// @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 1960b4b55..2cd7227b5 100644 --- a/core/encoding/base64/base64.odin +++ b/core/encoding/base64/base64.odin @@ -1,17 +1,18 @@ -// `Base64` encoding and decoding. +/* +`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 4acc63139..4967a079a 100644 --- a/core/encoding/cbor/doc.odin +++ b/core/encoding/cbor/doc.odin @@ -1,7 +1,6 @@ -// Encoding and decoding types from/into `RCF 8949` compatible `CBOR` binary. -package encoding_cbor /* -Package cbor encodes, decodes, marshals and unmarshals types from/into RCF 8949 compatible CBOR binary. +Encodes and decodes types from/into `RCF 8949` compatible `CBOR` binary. + Also provided are conversion to and from JSON and the CBOR diagnostic format. **Allocations:** @@ -166,4 +165,5 @@ Output: "renamed :)": 123123.12500000, "str": "Hello, World!" } -*/ \ No newline at end of file +*/ +package encoding_cbor \ No newline at end of file diff --git a/core/encoding/json/types.odin b/core/encoding/json/types.odin index a5f9daa02..75a66f646 100644 --- a/core/encoding/json/types.odin +++ b/core/encoding/json/types.odin @@ -1,15 +1,13 @@ -// Encoding and decoding JSON in strict `JSON`, `JSON5` and `BitSquid` variants. -package encoding_json - -import "core:strings" - /* - JSON +Encoding and decoding JSON in strict `JSON`, `JSON5` and `BitSquid` 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. @@ -22,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/varint/doc.odin b/core/encoding/varint/doc.odin index 23a28f913..e17faec49 100644 --- a/core/encoding/varint/doc.odin +++ b/core/encoding/varint/doc.odin @@ -1,8 +1,6 @@ /* `LEB128` variable integer encoding and decoding, as used by `DWARF` & `DEX` files. -Author of this Odin package: Jeroen van Rijn - 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 79d960847..9030cd400 100644 --- a/core/encoding/xml/doc.odin +++ b/core/encoding/xml/doc.odin @@ -1,7 +1,7 @@ /* 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/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/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/prof/spall/doc.odin b/core/prof/spall/doc.odin index 2098a12d6..e07a00a26 100644 --- a/core/prof/spall/doc.odin +++ b/core/prof/spall/doc.odin @@ -1,6 +1,8 @@ /* Profiling using the "`spall`" format. +See: [[ https://gravitymoth.com/spall/ ]] + Example: package main diff --git a/core/sys/info/doc.odin b/core/sys/info/doc.odin index d19bb13a0..7859b4e60 100644 --- a/core/sys/info/doc.odin +++ b/core/sys/info/doc.odin @@ -23,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) @@ -37,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: diff --git a/core/sys/info/platform_windows.odin b/core/sys/info/platform_windows.odin index ff8ebe2ee..7713e7bda 100644 --- a/core/sys/info/platform_windows.odin +++ b/core/sys/info/platform_windows.odin @@ -285,25 +285,26 @@ init_gpu_info :: proc "contextless" () { context = runtime.default_context() gpu_list: [dynamic]GPU - gpu_index: int - for { + // TODO: Use registry APIs to iterate over entries instead of trying 0000..0009. + for gpu_index in 0..<10 { key := fmt.tprintf("%v\\%04d", GPU_INFO_BASE, gpu_index) + gpu: ^GPU if vendor, ok := read_reg_string(sys.HKEY_LOCAL_MACHINE, key, "ProviderName"); ok { append(&gpu_list, GPU{vendor_name = vendor}) + gpu = &gpu_list[len(gpu_list) - 1] } else { - break + 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 60dbdae99..14b270bef 100644 --- a/core/sys/orca/macros.odin +++ b/core/sys/orca/macros.odin @@ -1,7 +1,7 @@ -// 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" From 1572ed57b669ed06d4ad7513bc51f70ba0952c16 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 10 Oct 2025 11:40:36 +0100 Subject: [PATCH 093/113] Add `intrinsics.concatenate` --- src/check_builtin.cpp | 86 +++++++++++++++++++++++++++++++++++ src/checker_builtin_procs.hpp | 4 ++ 2 files changed, 90 insertions(+) diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index a19fb15ec..13a1c4e69 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -4885,6 +4885,92 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As break; } + case BuiltinProc_concatenate: { + Operand lhs = {}; + Operand rhs = {}; + + check_expr(c, &lhs, ce->args[0]); + if (lhs.mode == Addressing_Invalid) { + return false; + } + check_expr(c, &rhs, ce->args[1]); + if (rhs.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; + } + if (rhs.mode != Addressing_Constant) { + error(rhs.expr, "'%*.s' expects a constant array or slice", LIT(builtin_name)); + return false; + } + + if (!are_types_identical(lhs.type, rhs.type)) { + gbString a = type_to_string(lhs.type); + gbString b = type_to_string(rhs.type); + error(rhs.expr, "'%*.s' expects a two constant values of the same type, got '%s' vs '%s'", LIT(builtin_name), a, b); + gb_string_free(b); + gb_string_free(a); + return false; + } + + 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; + } + if (rhs.value.kind != ExactValue_Compound) { + gbString a = exact_value_to_string(rhs.value); + error(rhs.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); + ast_node(rhs_cl, CompoundLit, rhs.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; + } + } + for (Ast *elem : rhs_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; + } + } + + Ast *type_ast = lhs_cl->type; + if (type_ast == nullptr) { + type_ast = rhs_cl->type; + } + + + Array new_elems = {}; + array_init(&new_elems, heap_allocator()); + + array_add_elems(&new_elems, lhs_cl->elems.data, lhs_cl->elems.count); + array_add_elems(&new_elems, rhs_cl->elems.data, rhs_cl->elems.count); + + Ast *new_compound_lit = ast_compound_lit(lhs.expr->file(), type_ast, new_elems, ast_token(lhs.expr), ast_end_token(rhs.expr)); + + operand->mode = Addressing_Constant; + operand->value = exact_value_compound(new_compound_lit); + operand->type = lhs.type; + break; + } + case BuiltinProc_alloca: { Operand sz = {}; diff --git a/src/checker_builtin_procs.hpp b/src/checker_builtin_procs.hpp index addaeaf23..8de6a4f5e 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, @@ -427,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, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("alloca"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("cpu_relax"), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, From 061b14e1649ea5829e2612dc905cdc9af863a071 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 10 Oct 2025 11:48:18 +0100 Subject: [PATCH 094/113] Allow `intrinsics.concatenate` to be variadic --- src/check_builtin.cpp | 87 +++++++++++++++++++---------------- src/checker_builtin_procs.hpp | 2 +- 2 files changed, 48 insertions(+), 41 deletions(-) diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 13a1c4e69..c337802c9 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -4887,56 +4887,32 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As case BuiltinProc_concatenate: { Operand lhs = {}; - Operand rhs = {}; check_expr(c, &lhs, ce->args[0]); if (lhs.mode == Addressing_Invalid) { return false; } - check_expr(c, &rhs, ce->args[1]); - if (rhs.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; - } - if (rhs.mode != Addressing_Constant) { - error(rhs.expr, "'%*.s' expects a constant array or slice", LIT(builtin_name)); - return false; - } - - if (!are_types_identical(lhs.type, rhs.type)) { - gbString a = type_to_string(lhs.type); - gbString b = type_to_string(rhs.type); - error(rhs.expr, "'%*.s' expects a two constant values of the same type, got '%s' vs '%s'", LIT(builtin_name), a, b); - gb_string_free(b); - gb_string_free(a); + 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); + 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; } - if (rhs.value.kind != ExactValue_Compound) { - gbString a = exact_value_to_string(rhs.value); - error(rhs.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); - ast_node(rhs_cl, CompoundLit, rhs.value.value_compound); for (Ast *elem : lhs_cl->elems) { if (elem->kind == Ast_FieldValue) { @@ -4944,26 +4920,57 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As return false; } } - for (Ast *elem : rhs_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; - } - } Ast *type_ast = lhs_cl->type; - if (type_ast == nullptr) { - type_ast = rhs_cl->type; - } - Array new_elems = {}; array_init(&new_elems, heap_allocator()); array_add_elems(&new_elems, lhs_cl->elems.data, lhs_cl->elems.count); - array_add_elems(&new_elems, rhs_cl->elems.data, rhs_cl->elems.count); - Ast *new_compound_lit = ast_compound_lit(lhs.expr->file(), type_ast, new_elems, ast_token(lhs.expr), ast_end_token(rhs.expr)); + for (isize i = 1; i < ce->args.count; i++) { + Operand extra = {}; + 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 (!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 type, got '%s' vs '%s'", LIT(builtin_name), a, b); + gb_string_free(b); + gb_string_free(a); + return false; + } + + 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; + } + } + + if (type_ast == nullptr) { + type_ast = extra_cl->type; + } + array_add_elems(&new_elems, extra_cl->elems.data, extra_cl->elems.count); + } + + Ast *new_compound_lit = ast_compound_lit(lhs.expr->file(), type_ast, 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); diff --git a/src/checker_builtin_procs.hpp b/src/checker_builtin_procs.hpp index 8de6a4f5e..01502128a 100644 --- a/src/checker_builtin_procs.hpp +++ b/src/checker_builtin_procs.hpp @@ -429,7 +429,7 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { {STR_LIT("soa_struct"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, // Type - {STR_LIT("concatenate"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {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}, From 5e12532ebad58215cc6039dc77211652961dc1a9 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 10 Oct 2025 11:49:09 +0100 Subject: [PATCH 095/113] Add basic type inference to the arguments --- src/check_builtin.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index c337802c9..a4109601e 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -4888,7 +4888,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As case BuiltinProc_concatenate: { Operand lhs = {}; - check_expr(c, &lhs, ce->args[0]); + check_expr_with_type_hint(c, &lhs, ce->args[0], type_hint); if (lhs.mode == Addressing_Invalid) { return false; } @@ -4930,7 +4930,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As for (isize i = 1; i < ce->args.count; i++) { Operand extra = {}; - check_expr(c, &extra, ce->args[i]); + check_expr_with_type_hint(c, &extra, ce->args[i], lhs.type); if (extra.mode == Addressing_Invalid) { return false; } From 24bc044d78c5d02e174b15490a0f8f5289b0cb03 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 10 Oct 2025 12:00:44 +0100 Subject: [PATCH 096/113] Support fixed-length arrays for `intrinsics.concatenate` --- src/check_builtin.cpp | 50 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index a4109601e..fb7b29edd 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -4921,6 +4921,8 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As } } + Type *elem_type = base_any_array_type(lhs.type); + Ast *type_ast = lhs_cl->type; Array new_elems = {}; @@ -4930,7 +4932,11 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As for (isize i = 1; i < ce->args.count; i++) { Operand extra = {}; - check_expr_with_type_hint(c, &extra, ce->args[i], lhs.type); + 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; } @@ -4938,13 +4944,34 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As error(extra.expr, "'%.*s' expects a constant array or slice", LIT(builtin_name)); return false; } - 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 type, got '%s' vs '%s'", LIT(builtin_name), a, b); - gb_string_free(b); - gb_string_free(a); - 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) { @@ -4974,7 +5001,12 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As operand->mode = Addressing_Constant; operand->value = exact_value_compound(new_compound_lit); - operand->type = lhs.type; + + if (is_type_slice(lhs.type)) { + operand->type = lhs.type; + } else { + operand->type = alloc_type_array(elem_type, new_elems.count); + } break; } From 1387c3d311db07edb36d8db5d0a2befb8417b771 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 10 Oct 2025 12:04:22 +0100 Subject: [PATCH 097/113] Remove unneeded type expression --- src/check_builtin.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index fb7b29edd..fcd2200dc 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -4923,8 +4923,6 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As Type *elem_type = base_any_array_type(lhs.type); - Ast *type_ast = lhs_cl->type; - Array new_elems = {}; array_init(&new_elems, heap_allocator()); @@ -4991,13 +4989,10 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As } } - if (type_ast == nullptr) { - type_ast = extra_cl->type; - } array_add_elems(&new_elems, extra_cl->elems.data, extra_cl->elems.count); } - Ast *new_compound_lit = ast_compound_lit(lhs.expr->file(), type_ast, new_elems, ast_token(lhs.expr), ast_end_token(ce->args[ce->args.count-1])); + 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); From 26b3a4d182788a08ea1d9eb8d7c3b49235065cb6 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 10 Oct 2025 12:09:41 +0100 Subject: [PATCH 098/113] Handle concatenation at the end --- src/check_builtin.cpp | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index fcd2200dc..530efb3c8 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -4923,11 +4923,6 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As Type *elem_type = base_any_array_type(lhs.type); - Array new_elems = {}; - array_init(&new_elems, heap_allocator()); - - array_add_elems(&new_elems, lhs_cl->elems.data, lhs_cl->elems.count); - for (isize i = 1; i < ce->args.count; i++) { Operand extra = {}; if (is_type_slice(lhs.type)) { @@ -4988,8 +4983,25 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As return false; } } + } - array_add_elems(&new_elems, extra_cl->elems.data, extra_cl->elems.count); + 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])); From 98dac324e92d950ab9374de9c56169f7396246a4 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 10 Oct 2025 12:13:49 +0100 Subject: [PATCH 099/113] Add to `intrinsics.odin` --- base/intrinsics/intrinsics.odin | 3 +++ 1 file changed, 3 insertions(+) diff --git a/base/intrinsics/intrinsics.odin b/base/intrinsics/intrinsics.odin index 805d78594..952f927bd 100644 --- a/base/intrinsics/intrinsics.odin +++ b/base/intrinsics/intrinsics.odin @@ -348,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) --- From ad1cf253521e3107ee1590ad5acf9da343edb93d Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Fri, 10 Oct 2025 13:35:32 +0200 Subject: [PATCH 100/113] Increase timeout for `posix.test_pthreads`. --- tests/core/sys/posix/posix.odin | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 From e1d8ece408a23a43e3257610e89e5065972de6bc Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Fri, 10 Oct 2025 14:12:59 +0200 Subject: [PATCH 101/113] core:sys/info: iterate over registry nodes to enumerate GPUs --- core/sys/info/platform_windows.odin | 53 ++++++++++++++++++++++++----- core/sys/windows/advapi32.odin | 7 ++++ 2 files changed, 52 insertions(+), 8 deletions(-) diff --git a/core/sys/info/platform_windows.odin b/core/sys/info/platform_windows.odin index 7713e7bda..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,20 +281,56 @@ 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: ^GPU - // TODO: Use registry APIs to iterate over entries instead of trying 0000..0009. - for gpu_index in 0..<10 { - key := fmt.tprintf("%v\\%04d", GPU_INFO_BASE, gpu_index) + index := sys.DWORD(0) + for { + defer index += 1 + + 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) - gpu: ^GPU if vendor, ok := read_reg_string(sys.HKEY_LOCAL_MACHINE, key, "ProviderName"); ok { - append(&gpu_list, GPU{vendor_name = vendor}) - gpu = &gpu_list[len(gpu_list) - 1] + idx := append(&gpu_list, GPU{vendor_name = vendor}) + gpu = &gpu_list[idx - 1] } else { continue } 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, From a42f81edeb748e99adcb38d7641822bb22c36fce Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Fri, 10 Oct 2025 15:31:33 +0200 Subject: [PATCH 102/113] Start adding pkg lines for vendor. --- examples/all/all_vendor.odin | 1 + examples/all/all_vendor_windows.odin | 1 + vendor/box2d/box2d.odin | 1 + vendor/cgltf/cgltf.odin | 1 + vendor/commonmark/cmark.odin | 2 +- vendor/commonmark/doc.odin | 2 +- vendor/compress/lz4/lz4.odin | 1 + vendor/darwin/CoreVideo/CVDisplayLink.odin | 1 + vendor/darwin/Metal/MetalClasses.odin | 1 + vendor/darwin/MetalKit/MetalKit.odin | 1 + vendor/darwin/QuartzCore/QuartzCore.odin | 1 + 11 files changed, 11 insertions(+), 2 deletions(-) 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/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..9d2a975f3 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..e63db9b15 100644 --- a/vendor/commonmark/cmark.odin +++ b/vendor/commonmark/cmark.odin @@ -1,5 +1,5 @@ /* - 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. diff --git a/vendor/commonmark/doc.odin b/vendor/commonmark/doc.odin index ef788fb8f..3b96594d9 100644 --- a/vendor/commonmark/doc.odin +++ b/vendor/commonmark/doc.odin @@ -1,6 +1,6 @@ #+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. 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" From 7e64dedb7738cdfb6cddd9eb391629b3ad69dc8b Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 10 Oct 2025 14:31:41 +0100 Subject: [PATCH 103/113] Fix #5778 --- src/check_expr.cpp | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 8834091d1..d638cf97e 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -3523,20 +3523,27 @@ 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)) { return true; - } else if (check_is_castable_to(c, x, type)) { - if (is_type_pointer(type)) { - return true; - } } - } else if (check_is_castable_to(c, x, type)) { - x->value = {}; - x->mode = Addressing_Value; - 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, bt, &x->value)) { + return true; + } + goto check_castable; } - } 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)) { From 7e7b6ac0de9f34dd8efd08a9c6f303bcd25ed1cc Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 10 Oct 2025 14:37:18 +0100 Subject: [PATCH 104/113] Add short-circuit for `check_cast_internal` --- src/check_expr.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/check_expr.cpp b/src/check_expr.cpp index d638cf97e..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; } @@ -3526,17 +3529,21 @@ gb_internal bool check_cast_internal(CheckerContext *c, Operand *x, Type *type) 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; } 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, bt, &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; } return false; From 65acbe1788bb101ea700f1ccd68f94d2f6ff4926 Mon Sep 17 00:00:00 2001 From: Hector Date: Fri, 10 Oct 2025 15:26:50 +0100 Subject: [PATCH 105/113] Changed indentation to tabs --- vendor/sdl3/sdl3_rect.odin | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vendor/sdl3/sdl3_rect.odin b/vendor/sdl3/sdl3_rect.odin index 10e741de1..6af9dc937 100644 --- a/vendor/sdl3/sdl3_rect.odin +++ b/vendor/sdl3/sdl3_rect.odin @@ -31,8 +31,8 @@ PointInRect :: proc "c" (p: Point, r: Rect) -> bool { @(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)) ) + return ( (p.x >= r.x) && (p.x <= (r.x + r.w)) && + (p.y >= r.y) && (p.y <= (r.y + r.h)) ) } @(require_results) From 998fbdc5c028f57619e58bda69819d131692b800 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Fri, 10 Oct 2025 17:51:28 +0200 Subject: [PATCH 106/113] Doc lines for vendor:* --- vendor/ENet/enet.odin | 1 + vendor/OpenEXRCore/exr_base.odin | 1 + vendor/OpenGL/helpers.odin | 1 + vendor/cgltf/cgltf.odin | 2 +- vendor/commonmark/cmark.odin | 6 -- vendor/commonmark/doc.odin | 77 ++++++++----------- vendor/directx/d3d11/d3d11.odin | 1 + vendor/directx/d3d12/d3d12.odin | 1 + vendor/directx/d3d_compiler/d3d_compiler.odin | 1 + vendor/directx/dxc/dxcapi.odin | 1 + vendor/directx/dxgi/dxgi.odin | 1 + vendor/egl/egl.odin | 1 + vendor/fontstash/fontstash.odin | 1 + vendor/ggpo/ggpo.odin | 2 + vendor/glfw/types.odin | 1 + vendor/kb_text_shape/kb_text_shape_procs.odin | 1 + vendor/libc/stdlib.odin | 1 + vendor/lua/5.1/lua.odin | 1 + vendor/lua/5.2/lua.odin | 1 + vendor/lua/5.3/lua.odin | 1 + vendor/lua/5.4/lua.odin | 1 + vendor/microui/microui.odin | 3 +- vendor/miniaudio/doc.odin | 9 +-- vendor/nanovg/gl/gl.odin | 1 + vendor/nanovg/nanovg.odin | 1 + vendor/portmidi/doc.odin | 1 + vendor/raylib/raylib.odin | 2 +- vendor/sdl2/image/sdl_image.odin | 1 + vendor/sdl2/mixer/sdl_mixer.odin | 1 + vendor/sdl2/net/sdl_net.odin | 1 + vendor/sdl2/sdl2.odin | 1 + vendor/sdl2/ttf/sdl_ttf.odin | 1 + vendor/sdl3/image/sdl_image.odin | 1 + vendor/sdl3/sdl3_main.odin | 1 + vendor/sdl3/ttf/sdl3_ttf.odin | 1 + vendor/stb/easy_font/stb_easy_font.odin | 40 +++++----- vendor/stb/image/stb_image.odin | 1 + vendor/stb/rect_pack/stb_rect_pack.odin | 1 + vendor/stb/truetype/stb_truetype.odin | 1 + vendor/stb/vorbis/stb_vorbis.odin | 1 + .../vulkan/_gen/create_vulkan_odin_wrapper.py | 24 +++--- vendor/vulkan/core.odin | 4 +- vendor/vulkan/enums.odin | 3 - vendor/vulkan/procedures.odin | 3 - vendor/vulkan/structs.odin | 3 - vendor/wgpu/glfwglue/doc.odin | 2 + vendor/wgpu/sdl2glue/doc.odin | 2 + vendor/wgpu/sdl3glue/doc.odin | 2 + vendor/windows/GameInput/doc.odin | 6 ++ vendor/windows/XAudio2/doc.odin | 6 ++ vendor/x11/xlib/xlib.odin | 1 + vendor/zlib/zlib.odin | 1 + 52 files changed, 125 insertions(+), 105 deletions(-) create mode 100644 vendor/wgpu/glfwglue/doc.odin create mode 100644 vendor/wgpu/sdl2glue/doc.odin create mode 100644 vendor/wgpu/sdl3glue/doc.odin create mode 100644 vendor/windows/GameInput/doc.odin create mode 100644 vendor/windows/XAudio2/doc.odin 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/cgltf/cgltf.odin b/vendor/cgltf/cgltf.odin index 9d2a975f3..aeceb14c5 100644 --- a/vendor/cgltf/cgltf.odin +++ b/vendor/cgltf/cgltf.odin @@ -1,4 +1,4 @@ -// Bindings for [[ cgtlf ; https://github.com/jkuhlmann/cgltf ]]. +// Bindings for [[ Cgtlf ; https://github.com/jkuhlmann/cgltf ]]. package cgltf @(private) diff --git a/vendor/commonmark/cmark.odin b/vendor/commonmark/cmark.odin index e63db9b15..fd1be45fd 100644 --- a/vendor/commonmark/cmark.odin +++ b/vendor/commonmark/cmark.odin @@ -1,9 +1,3 @@ -/* - 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 import "core:c" diff --git a/vendor/commonmark/doc.odin b/vendor/commonmark/doc.odin index 3b96594d9..648226234 100644 --- a/vendor/commonmark/doc.odin +++ b/vendor/commonmark/doc.odin @@ -1,18 +1,13 @@ -#+build ignore /* - Bindings for [[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/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..0ab97e8cb 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 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/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/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 f1dcdf2a2..d88fafda1 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 79a022243..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), @@ -889,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) @@ -974,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" @@ -1041,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 ad33df148..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) 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" From 236111864ec8147acf73ce4db1ef3310205cac7a Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Fri, 10 Oct 2025 18:29:52 +0200 Subject: [PATCH 107/113] Link doc lines to source specifications. --- core/encoding/base32/base32.odin | 4 +--- core/encoding/cbor/doc.odin | 2 +- core/encoding/csv/doc.odin | 3 +-- core/encoding/json/types.odin | 2 +- core/encoding/uuid/doc.odin | 2 +- core/math/noise/opensimplex2.odin | 4 ++-- 6 files changed, 7 insertions(+), 10 deletions(-) diff --git a/core/encoding/base32/base32.odin b/core/encoding/base32/base32.odin index f50db12b3..34de2ff53 100644 --- a/core/encoding/base32/base32.odin +++ b/core/encoding/base32/base32.odin @@ -1,7 +1,5 @@ /* -`Base32` encoding and decoding, as specified in `RFC 4648`. - -[[ RFC 4648; 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`. diff --git a/core/encoding/cbor/doc.odin b/core/encoding/cbor/doc.odin index 4967a079a..370c5aaa9 100644 --- a/core/encoding/cbor/doc.odin +++ b/core/encoding/cbor/doc.odin @@ -1,5 +1,5 @@ /* -Encodes and decodes 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. diff --git a/core/encoding/csv/doc.odin b/core/encoding/csv/doc.odin index 2b9fdd849..50b8e3d1a 100644 --- a/core/encoding/csv/doc.odin +++ b/core/encoding/csv/doc.odin @@ -1,6 +1,5 @@ /* -Reader and writer for comma-separated values (`CSV`) files, per `RFC 4180`. -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/json/types.odin b/core/encoding/json/types.odin index 75a66f646..1da17a0db 100644 --- a/core/encoding/json/types.odin +++ b/core/encoding/json/types.odin @@ -1,5 +1,5 @@ /* -Encoding and decoding JSON in strict `JSON`, `JSON5` and `BitSquid` variants. +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 diff --git a/core/encoding/uuid/doc.odin b/core/encoding/uuid/doc.odin index c2622c56b..a5f01ca7c 100644 --- a/core/encoding/uuid/doc.odin +++ b/core/encoding/uuid/doc.odin @@ -1,5 +1,5 @@ /* -Universally Unique Identifiers (`UUID`) according to `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/math/noise/opensimplex2.odin b/core/math/noise/opensimplex2.odin index ef12a26fa..0fabdf3cf 100644 --- a/core/math/noise/opensimplex2.odin +++ b/core/math/noise/opensimplex2.odin @@ -1,7 +1,7 @@ /* - `OpenSimplex2` noise algorithm. + [[ 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 From a4350b41ae8922d7d4f09c84511ab2043b6a7d7c Mon Sep 17 00:00:00 2001 From: Karl Zylinski Date: Fri, 10 Oct 2025 23:40:29 +0200 Subject: [PATCH 108/113] Add fontIndex parameter to fontstash that controls which font in a TTC to load --- vendor/fontstash/fontstash.odin | 12 ++++++++---- vendor/fontstash/fontstash_os.odin | 5 ++++- vendor/fontstash/fontstash_other.odin | 1 + 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/vendor/fontstash/fontstash.odin b/vendor/fontstash/fontstash.odin index b3000de70..30e42be86 100644 --- a/vendor/fontstash/fontstash.odin +++ b/vendor/fontstash/fontstash.odin @@ -323,11 +323,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,10 +339,10 @@ AddFontMem :: proc( res.freeLoadedData = freeLoadedData res.name = strings.clone(name) - // Get offset of first font (if the font is a TTC then it can contain multiple fonts) - // Note: There is currently no support for specifying any other font than first one. - font_offset := stbtt.GetFontOffsetForIndex(raw_data(res.loadedData), 0) - stbtt.InitFont(&res.info, raw_data(res.loadedData), font_offset) + 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") } From 48a79a6f8c4470f3958c0e3405da2de77e0825fb Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Sat, 11 Oct 2025 14:55:48 +0200 Subject: [PATCH 109/113] Fix #5789 --- src/exact_value.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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)); From b3dfd34f2d3ca1431e3e5d8f8157b545afa45b3e Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Sat, 11 Oct 2025 14:57:45 +0200 Subject: [PATCH 110/113] #5788 --- src/types.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/types.cpp b/src/types.cpp index 372c2e991..b4cc67d83 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -1725,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; } @@ -1766,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; } From e6754547aba1df61af2fc302a100762c09fe215f Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Sat, 11 Oct 2025 15:17:23 +0200 Subject: [PATCH 111/113] Fix #5786 --- src/types.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types.cpp b/src/types.cpp index b4cc67d83..66c87a25d 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_Simple_Compare; } return flags; } From 5dbade87e9cc806d581a563b9b587eaf7314fafd Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Sat, 11 Oct 2025 15:43:30 +0200 Subject: [PATCH 112/113] Simple compare is also comparable --- src/types.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types.cpp b/src/types.cpp index 66c87a25d..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_Simple_Compare; + flags |= TypeInfoFlag_Comparable|TypeInfoFlag_Simple_Compare; } return flags; } From e4db455458cc4b376f9983fc9968f6e82fc5ba17 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Sat, 11 Oct 2025 20:32:09 +0200 Subject: [PATCH 113/113] Fix #5785 --- src/checker.cpp | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/checker.cpp b/src/checker.cpp index 2a82203ef..8b3638c9d 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -5093,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);