Declarations which are required by the compiler ## Descriptions of files There are a lot of files in this package and below is described roughly what kind of functionality is placed in different files: | File pattern | Description |----------------------|------------------------------------------------------| | `core.odin` | Contains the declarations that compiler will require to be present. Contains context-related declarations, `Type_Info` declarations and some other types used to implement the runtime and other packages. | | `core_builtin*.odin` | Contain `@(builtin)` declarations that can be used without importing the package. Most of them aren't required by the compiler | | `default_*.odin` | Contain default implementations for context allocators | | `entry_*.odin` | Contain OS-specific entry points | | `os_specific_*.odin` | Contain OS-specific utility procedures | | `*internal*.odin` | Contain implementations for internal procedures that can be called by the compiler | ## Implementing custom runtime For embedded and kernel development it might be required to re-implement parts of the `base:runtime` package. This can include changing the default printing procedures that handle console output when the program panics, custom entry-points, tailored for a specific platform or execution environment, or simply switching up implementations of some procedures. In case this is required, the following is suggested: 1. Define `$ODIN_ROOT` environment variable to point to a directory within your project that contains the following directories: `base/`, `core/` and `vendor/`. 2. Inside the `$ODIN_ROOT/base` subdirectory, implement the *necessary declarations*. What constitutes the necessary definitions is described below. ### Context-related The compiler will require these declarations as they concern the `context` variable. `Maybe` `Source_Code_Location` `Context` `Allocator` `Random_Generator` `Logger` `__init_context` ### Runtime initialization/cleanup These are not strictly required for compilation, but if global variables or `@(init)`/`@(fini)` blocks are used, these procedures need to be called inside the entry point. `_startup_runtime` `_cleanup_runtime` ### Type assertion check These procedures are called every time `.(Type)` expressions are used in order to check the union tag or the underlying type of `any` before returning the value of the underlying type. These are not required if `-no-type-assert` is specified. `type_assertion_check` `type_assertion_check2` (takes in typeid) ### Bounds checking procedures These procedures are called every time index or slicing expression are used in order to perform bounds-checking before the actual operation. These are not required if the `-no-bounds-check` option is specified. `bounds_check_error` `matrix_bounds_check_error` `slice_expr_error_hi` `slice_expr_error_lo_hi` `multi_pointer_slice_expr_error` ### cstring calls If `cstring` or `cstring16` types are used, these procedures are required. `cstring_to_string` `cstring_len` `cstring16_to_string16` `cstring16_len` ### Comparison These procedures are required for comparison operators between strings and other compound types to function properly. If strings, structs nor unions are compared, only `string_eq` procedure is required. `memory_equal` `memory_compare` `memory_compare_zero` `cstring_eq` `cstring16_eq` `cstring_ne` `cstring16_ne` `cstring_lt` `cstring16_lt` `cstring_gt` `cstring16_gt` `cstring_le` `cstring16_le` `cstring_ge` `cstring16_ge` `string_eq` `string16_eq` `string_ne` `string16_ne` `string_lt` `string16_lt` `string_gt` `string16_gt` `string_le` `string16_le` `string_ge` `string16_ge` `complex32_eq` `complex32_ne` `complex64_eq` `complex64_ne` `complex128_eq` `complex128_ne` `quaternion64_eq` `quaternion64_ne` `quaternion128_eq` `quaternion128_ne` `quaternion256_eq` `quaternion256_ne` ### for-in `string` type These procedures are required to iterate strings using `for ... in` loop. If this kind of loop isn't used, these procedures aren't required. `string_decode_rune` `string_decode_last_rune` (for `#reverse for`) ### Required when RTTI is enabled (the vast majority of targets) These declarations are required unless the `-no-rtti` compiler option is specified. Note that in order to be useful, some other procedures need to be implemented. Those procedures aren't mentioned here as the compiler won't complain if they're missing. `Type_Info` `type_table` `__type_info_of` ### Hashing Required if maps are used `default_hasher` `default_hasher_cstring` `default_hasher_string` ### Pseudo-CRT required procedured due to LLVM but useful in general `memset` `memcpy` `memove` ### Procedures required by the LLVM backend if u128/i128 is used `umodti3` `udivti3` `modti3` `divti3` `fixdfti` `fixunsdfti` `fixunsdfdi` `floattidf` `floattidf_unsigned` `truncsfhf2` `truncdfhf2` `gnu_h2f_ieee` `gnu_f2h_ieee` `extendhfsf2` ### Procedures required by the LLVM backend if f16 is used (WASM only) `__ashlti3` `__multi3` ### When -no-crt is defined (windows only) `_tls_index` `_fltused` ### Arithmetic `quo_complex32` `quo_complex64` `quo_complex128` `mul_quaternion64` `mul_quaternion128` `mul_quaternion256` `quo_quaternion64` `quo_quaternion128` `quo_quaternion256` `abs_complex32` `abs_complex64` `abs_complex128` `abs_quaternion64` `abs_quaternion128` `abs_quaternion256` ## Map specific calls `map_seed_from_map_data` `__dynamic_map_check_grow` (for static map calls) `map_insert_hash_dynamic` (for static map calls) `__dynamic_map_get` (for dynamic map calls) `__dynamic_map_set` (for dynamic map calls) ## Dynamic literals (`[dynamic]T` and `map[K]V`) (can be disabled with `-no-dynamic-literals`) `__dynamic_array_reserve` `__dynamic_array_append` `__dynamic_map_reserve` ### Objective-C specific `objc_lookUpClass` `sel_registerName` `objc_allocateClassPair` ### Other required declarations This is required without conditions. `Load_Directory_File`

Collection Info

View Source
Collection
base
Path
runtime
Entries
544

Source Files

(hidden platform specific files)

Constants

26

ALL_ODIN_ARCH_TYPES #

Source
ALL_ODIN_ARCH_TYPES :: Odin_Arch_Types{.amd64, .i386, .arm32, .arm64, .wasm32, .wasm64p32, .riscv64}

ALL_ODIN_OS_TYPES #

Source
ALL_ODIN_OS_TYPES :: Odin_OS_Types{.Windows, .Darwin, .Linux, .Essence, .FreeBSD, .OpenBSD, .NetBSD, .Haiku, .WASI, .JS, .Orca, .Freestanding}

DEFAULT_ARENA_GROWING_MINIMUM_BLOCK_SIZE #

Source
DEFAULT_ARENA_GROWING_MINIMUM_BLOCK_SIZE :: uint(DEFAULT_TEMP_ALLOCATOR_BACKING_SIZE)

DEFAULT_DYNAMIC_ARRAY_CAPACITY #

Source
DEFAULT_DYNAMIC_ARRAY_CAPACITY :: 8

DEFAULT_TEMP_ALLOCATOR_BACKING_SIZE #

Source
DEFAULT_TEMP_ALLOCATOR_BACKING_SIZE :: #config(DEFAULT_TEMP_ALLOCATOR_BACKING_SIZE, 4 * Megabyte)

HAS_HARDWARE_SIMD #

Source
HAS_HARDWARE_SIMD :: false when (ODIN_ARCH == .amd64 || ODIN_ARCH == .i386) && !intrinsics.has_target_feature("sse2") else false when (ODIN_ARCH == .arm64 || ODIN_ARCH == .arm32) && !intrinsics.has_target_feature("neon") else false when (ODIN_ARCH == .wasm64p32 || ODIN_ARCH == .wasm32) && !intrinsics.has_target_feature("simd128") else false when (ODIN_ARCH == .riscv64) && !intrinsics.has_target_feature("v") else true

MAP_CACHE_LINE_LOG2 #

Source
MAP_CACHE_LINE_LOG2 :: 6

This is safe to change. The log2 size of a cache-line. At minimum it has to be six though. Higher cache line sizes are permitted.

MAP_CACHE_LINE_SIZE #

Source
MAP_CACHE_LINE_SIZE :: 1 << MAP_CACHE_LINE_LOG2

The size of a cache-line.

MAP_LOAD_FACTOR #

Source
MAP_LOAD_FACTOR :: 75

With Robin Hood hashing a maximum load factor of 75% is ideal.

MAP_MIN_LOG2_CAPACITY #

Source
MAP_MIN_LOG2_CAPACITY :: 3

Minimum log2 capacity.

NATIVE_SIMD_BIT_WIDTH #

Source
NATIVE_SIMD_BIT_WIDTH :: 512 when (ODIN_ARCH == .amd64) && intrinsics.has_target_feature("avx512f") else 256 when (ODIN_ARCH == .amd64) && (intrinsics.has_target_feature("avx2") || intrinsics.has_target_feature("avx")) else 128

Size of a native SIMD register for the current compilation target

NO_DEFAULT_TEMP_ALLOCATOR #

Source
NO_DEFAULT_TEMP_ALLOCATOR :: ODIN_OS == .Freestanding || ODIN_DEFAULT_TO_NIL_ALLOCATOR

ODIN_PLATFORM_SUBTARGET_IOS #

Source
@(builtin)
ODIN_PLATFORM_SUBTARGET_IOS :: ODIN_PLATFORM_SUBTARGET == .iPhone || ODIN_PLATFORM_SUBTARGET == .iPhoneSimulator

TOMBSTONE_MASK #

Source
TOMBSTONE_MASK :: 1 << (size_of(Map_Hash) * 8 - 1)

Config Values

1

DEFAULT_TEMP_ALLOCATOR_BACKING_SIZE #

Source
DEFAULT_TEMP_ALLOCATOR_BACKING_SIZE :: #config(DEFAULT_TEMP_ALLOCATOR_BACKING_SIZE, 4 * Megabyte)

Types

107

Arena #

Source
Arena :: Arena

NOTE: This is a growing arena that is only used for the default temp allocator. For your own growing arena needs, prefer `Arena` from `core:mem/virtual`.

Default_Temp_Allocator #

Source
Default_Temp_Allocator :: Default_Temp_Allocator

`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`.

int_t #

Source
int_t :: int

NOTE: on wasm, calls to these procs are generated (by LLVM) with type `i32` instead of `int`. NOTE: `#any_int` is also needed, because calls that we generate (and package code) will be using `int` and need to be converted.

Map_Cell #

Source
Map_Cell :: Map_Cell

Map_Cell type that packs multiple T in such a way to ensure that each T stays aligned by align_of(T) and such that align_of(Map_Cell(T)) % MAP_CACHE_LINE_SIZE == 0 This means a value of type T will never straddle a cache-line. When multiple Ts can fit in a single cache-line the data array will have more than one element. When it cannot, the data array will have one element and an array of Map_Cell(T) will be padded to stay a multiple of MAP_CACHE_LINE_SIZE. We rely on the type system to do all the arithmetic and padding for us here. The usual array[index] indexing for []T backed by a []Map_Cell(T) becomes a bit more involved as there now may be internal padding. The indexing now becomes N :: len(Map_Cell(T){}.data) i := index / N j := index % N cell[i].data[j] However, since len(Map_Cell(T){}.data) is a compile-time constant, there are some optimizations we can do to eliminate the need for any divisions as N will be bounded by [1, 64). In the optimal case, len(Map_Cell(T){}.data) = 1 so the cell array can be treated as a regular array of T, which is the case for hashes.

Map_Cell_Info #

Source
Map_Cell_Info :: Map_Cell_Info

So we can operate on a cell data structure at runtime without any type information, we have a simple table that stores some traits about the cell. 32-bytes on 64-bit 16-bytes on 32-bit

Map_Info #

Source
Map_Info :: Map_Info

When working with the type-erased structure at runtime we need information about the map to make working with it possible. This info structure stores that. `Map_Info` and `Map_Cell_Info` are read only data structures and cannot be modified after creation 32-bytes on 64-bit 16-bytes on 32-bit

Objc_Block #

Source
@(builtin)
Objc_Block :: Objc_Block

Represents an Objective-C block with a given procedure signature T

Odin_Arch_Type #

Source
Odin_Arch_Type :: Odin_Arch_Type

// Defined internally by the compiler Odin_Arch_Type :: enum int { Unknown, amd64, i386, arm32, arm64, wasm32, wasm64p32, riscv64, }

Odin_Build_Mode_Type #

Source
Odin_Build_Mode_Type :: Odin_Build_Mode_Type

// Defined internally by the compiler Odin_Build_Mode_Type :: enum int { Executable, Dynamic, Static, Object, Assembly, LLVM_IR, }

Odin_Endian_Type #

Source
Odin_Endian_Type :: Odin_Endian_Type

// Defined internally by the compiler Odin_Endian_Type :: enum int { Unknown, Little, Big, }

Odin_Optimization_Mode #

Source
Odin_Optimization_Mode :: Odin_Optimization_Mode

// Defined internally by the compiler Odin_Optimization_Mode :: enum int { None = -1, Minimal = 0, Size = 1, Speed = 2, Aggressive = 3, } ODIN_OPTIMIZATION_MODE // is a constant

Odin_OS_Type #

Source
Odin_OS_Type :: Odin_OS_Type

// Defined internally by the compiler Odin_OS_Type :: enum int { Unknown, Windows, Darwin, Linux, Essence, FreeBSD, OpenBSD, NetBSD, Haiku, WASI, JS, Orca, Freestanding, }

Odin_Platform_Subtarget_Type #

Source
Odin_Platform_Subtarget_Type :: Odin_Platform_Subtarget_Type

// Defined internally by the compiler Odin_Platform_Subtarget_Type :: enum int { Default, iPhone, iPhoneSimulator Android, }

Odin_Platform_Subtarget_Types #

Source
Odin_Platform_Subtarget_Types :: bit_set[Odin_Platform_Subtarget_Type]

Odin_Sanitizer_Flags #

Source
Odin_Sanitizer_Flags :: Odin_Sanitizer_Flags

// Defined internally by the compiler Odin_Sanitizer_Flag :: enum u32 { Address = 0, Memory = 1, Thread = 2, } Odin_Sanitizer_Flags :: distinct bit_set[Odin_Sanitizer_Flag; u32] ODIN_SANITIZER_FLAGS // is a constant

Raw_Map #

Source
Raw_Map :: Raw_Map

The raw, type-erased representation of a map. 32-bytes on 64-bit 16-bytes on 32-bit

Procedures

374

add_thread_local_cleaner #

Source
add_thread_local_cleaner :: proc "contextless" (p: Thread_Local_Cleaner) {…}

Add a procedure that will be run at the end of a thread for the purpose of deallocating state marked as `thread_local`. Intended to be called in an `init` procedure of a package with dynamically-allocated memory that is stored in `thread_local` variables.

aeabi_d2h #

Source
@(link_name="__aeabi_d2h")
@(linkage=RUNTIME_LINKAGE)
@(require=RUNTIME_REQUIRE)
aeabi_d2h :: proc "c" (value: f64) -> u16 {…}

align_forward_int #

Source
@(require_results)
align_forward_int :: proc(ptr, align: int) -> int {…}

append_elem #

Source
@(builtin)
append_elem :: proc(array: ^$T/[dynamic]$E, #no_broadcast arg: $E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_ok {…}

`append_elem` appends an element to the end of a dynamic array.

append_elem_string #

Source
@(builtin)
append_elem_string :: proc(array: ^$T/[dynamic]$E/u8, arg: $A/string, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_ok {…}

`append_elem_string` appends a string to the end of a dynamic array of bytes Note: Prefer using the procedure group `append`.

append_elems #

Source
@(builtin)
append_elems :: proc(array: ^$T/[dynamic]$E, #no_broadcast args: ..$E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_ok {…}

`append_elems` appends `args` to the end of a dynamic array. Note: Prefer using the procedure group `append`.

append_fixed_capacity_elem #

Source
@(builtin)
append_fixed_capacity_elem :: proc "contextless" (array: ^$T/[dynamic; 144]$E, #no_broadcast arg: $E) -> (n: int) {…}

`append_fixed_capacity_elem` appends an element to the end of a fixed capacity dynamic array. Returns 0 on failure

append_fixed_capacity_elems #

Source
@(builtin)
append_fixed_capacity_elems :: proc "contextless" (array: ^$T/[dynamic; $N]$E, #no_broadcast args: ..$E) -> (n: int) {…}

`append_fixed_capacity_elem` appends an element to the end of a fixed capacity dynamic array. Returns 0 on failure

append_fixed_capacity_string #

Source
@(builtin)
append_fixed_capacity_string :: proc "contextless" (array: ^$T/[dynamic; $N]$E/u8, args: ..string) -> (n: int) {…}

The append_fixed_capacity_string built-in procedure appends multiple strings to the end of a [dynamic]u8 like type Note: Prefer using the procedure group `append`.

append_nothing_dynamic_array #

Source
@(builtin)
append_nothing_dynamic_array :: proc(array: ^$T/[dynamic]$E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_ok {…}

`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.

append_nothing_fixed_capacity_dynamic_array #

Source
@(builtin)
append_nothing_fixed_capacity_dynamic_array :: proc "contextless" (array: ^$T/[dynamic; $N]$E) -> (n: int, ok: bool) {…}

`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.

append_nothing_soa #

Source
@(builtin)
append_nothing_soa :: proc(array: ^$T/#soa[dynamic]$E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_ok {…}

`append_nothing_soa` appends an empty value to a dynamic SOA array. It returns `1, nil` if successful, and `0, err` when it was not possible, whatever `err` happens to be.

append_soa_elem #

Source
@(builtin)
append_soa_elem :: proc(array: ^$T/#soa[dynamic]$E, #no_broadcast arg: $E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_ok {…}

append_soa_elems #

Source
@(builtin)
append_soa_elems :: proc(array: ^$T/#soa[dynamic]$E, #no_broadcast args: ..$E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_ok {…}

append_string #

Source
@(builtin)
append_string :: proc(array: ^$T/[dynamic]$E/u8, args: ..string, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_ok {…}

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`.

arena_check_temp #

Source
arena_check_temp :: proc(arena: ^Arena, loc := #caller_location) {…}

arena_destroy #

Source
arena_destroy :: proc "contextless" (arena: ^Arena, loc := #caller_location) {…}

arena_free_all #

Source
arena_free_all :: proc(arena: ^Arena, loc := #caller_location) {…}

`arena_free_all` will free all but the first memory block, and then reset the memory block

arena_free_last_memory_block #

Source
arena_free_last_memory_block :: proc(arena: ^Arena, loc := #caller_location) {…}

arena_init #

Source
@(require_results)
arena_init :: proc(arena: ^Arena, size: uint, backing_allocator: Allocator, loc := #caller_location) -> Allocator_Error {…}

`arena_init` will initialize the arena with a usable block. This procedure is not necessary to use the Arena as the default zero as `arena_alloc` will set things up if necessary

arena_temp_ignore #

Source
arena_temp_ignore :: proc(temp: Arena_Temp, loc := #caller_location) {…}

Ignore the use of a `arena_temp_begin` entirely

assert #

Source
@(disabled=ODIN_DISABLE_ASSERT)
@(builtin)
assert :: proc(condition: bool, message: string = #caller_expression(condition), loc := #caller_location) {…}

Evaluates the condition and panics the program if and only if (⟺) the condition is false. This uses the `context.assertion_failure_procedure` to assert. This routine will be ignored when `ODIN_DISABLE_ASSERT` is true.

assert_contextless #

Source
@(disabled=ODIN_DISABLE_ASSERT)
@(builtin)
assert_contextless :: proc "contextless" (condition: bool, message: string = #caller_expression(condition), loc := #caller_location) {…}

Evaluates the condition and panics the program if and only if (⟺) 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.

assign_at_elem #

Source
@(builtin)
assign_at_elem :: proc(array: ^$T/[dynamic]$E, #any_int index: int, #no_broadcast arg: $E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #optional_ok {…}

`assign_at_elem` assigns a value at a given index. If the requested index is past the end of the current size of the dynamic array, it will attempt to `resize` the a new length of `index+1` and then assign as `index`.

assign_at_elem_fixed_capacity_dynamic_array #

Source
@(builtin)
assign_at_elem_fixed_capacity_dynamic_array :: proc "contextless" (array: ^$T/[dynamic; $N]$E, #any_int index: int, arg: $E) -> (ok: bool) {…}

`assign_at_elem_fixed_capacity_dynamic_array` assigns a value at a given index. If the requested index is past the end of the current size of the dynamic array, it will attempt to `resize` the a new length of `index+1` and then assign as `index`.

assign_at_elem_string #

Source
@(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) #optional_ok {…}

`assign_at_elem_string` assigns a string at a given index. If the requested index is past the end of 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`.

assign_at_elem_string_fixed_capacity_dynamic_array #

Source
@(builtin)
assign_at_elem_string_fixed_capacity_dynamic_array :: proc "contextless" (array: ^$T/[dynamic; $N]$E/u8, #any_int index: int, arg: string) -> (ok: bool) {…}

`assign_at_elem_string_fixed_capacity_dynamic_array` assigns a string at a given index. If the requested index is past the end of 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`.

assign_at_elems #

Source
@(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) #optional_ok {…}

`assign_at_elems` assigns a values at a given index. If the requested index is past the end of 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`.

assign_at_elems_fixed_capacity_dynamic_array #

Source
@(builtin)
assign_at_elems_fixed_capacity_dynamic_array :: proc "contextless" (array: ^$T/[dynamic; $N]$E, #any_int index: int, #no_broadcast args: ..$E) -> (ok: bool) {…}

`assign_at_elems_fixed_capacity_dynamic_array` assigns a values at a given index. If the requested index is past the end of 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`.

bounds_check_error #

Source
@(disabled=ODIN_NO_BOUNDS_CHECK)
bounds_check_error :: proc "contextless" (file: string, line, column: i32, index, count: int) {…}

bounds_check_error_loc #

Source
@(disabled=ODIN_NO_BOUNDS_CHECK)
bounds_check_error_loc :: proc "contextless" (loc := #caller_location, index, count: int) {…}

bounds_trap #

Source
@(no_instrumentation)
bounds_trap :: proc "contextless" () {…}

card #

Source
@(builtin)
card :: proc "contextless" (s: $S/bit_set[$E]) -> int {…}

`card` returns the number of bits that are set in a bit_set—its cardinality

clear_dynamic_array #

Source
@(builtin)
clear_dynamic_array :: proc "contextless" (array: ^$T/[dynamic]$E) {…}

`clear_dynamic_array` will set the length of a passed dynamic array to `0` Note: Prefer the procedure group `clear`.

clear_fixed_capacity_dynamic_array #

Source
@(builtin)
clear_fixed_capacity_dynamic_array :: proc "contextless" (array: ^$T/[dynamic; $N]$E) {…}

`clear_fixed_capacity_dynamic_array` will set the length of a passed dynamic array to `0` Note: Prefer the procedure group `clear`.

clear_map #

Source
@(builtin)
clear_map :: proc "contextless" (m: ^$T/map[$K]$V) {…}

`clear_map` will set the length of a passed map to `0` Note: Prefer the procedure group `clear`

clear_soa_dynamic_array #

Source
@(builtin)
clear_soa_dynamic_array :: proc(array: ^$T/#soa[dynamic]$E) {…}

container_of #

Source
@(builtin)
@(require_results)
container_of :: proc "contextless" (ptr: $P/^$Field_Type, $T: typeid, $field_name: string) -> ^typeid {…}

Recovers the containing/parent struct from a pointer to one of its fields. Works by "walking back" to the struct's starting address using the offset between the field and the struct. Inputs: - ptr: Pointer to the field of a container struct - T: The type of the container struct - field_name: The name of the field in the `T` struct Returns: - A pointer to the container struct based on a pointer to a field in it Example: package container_of import "base:runtime" Node :: struct { value: int, prev: ^Node, next: ^Node, } main :: proc() { node: Node field_ptr := &node.next container_struct_ptr: ^Node = runtime.container_of(field_ptr, Node, "next") assert(container_struct_ptr == &node) assert(uintptr(field_ptr) - uintptr(container_struct_ptr) == size_of(node.value) + size_of(node.prev)) } Output: ^Node

copy_from_string #

Source
@(builtin)
copy_from_string :: proc "contextless" (dst: $T/[]$E/u8, src: $S/string) -> int {…}

`copy_from_string` is a built-in procedure that copies elements from a source string `src` to a destination slice `dst`. The source and destination may overlap. Copy returns the number of elements copied, which will be the minimum of len(src) and len(dst). Prefer the procedure group `copy`.

copy_from_string16 #

Source
@(builtin)
copy_from_string16 :: proc "contextless" (dst: $T/[]$E/u16, src: $S/string16) -> int {…}

`copy_from_string16` is a built-in procedure that copies elements from a source string `src` to a destination slice `dst`. The source and destination may overlap. Copy returns the number of elements copied, which will be the minimum of len(src) and len(dst). Prefer the procedure group `copy`.

copy_slice #

Source
@(builtin)
copy_slice :: proc "contextless" (dst, src: $T/[]$E) -> int {…}

`copy_slice` is a built-in procedure that copies elements from a source slice `src` to a destination slice `dst`. The source and destination may overlap. Copy returns the number of elements copied, which will be the minimum of len(src) and len(dst). Prefer the procedure group `copy`.

copy_slice_raw #

Source
@(require_results)
copy_slice_raw :: proc "contextless" (dst, src: rawptr, dst_len, src_len, elem_size: int) -> int {…}

default_context #

Source
@(require_results)
default_context :: proc "contextless" () -> Context {…}

Returns the default `context`

default_context_ptr #

Source
@(link_name="default_context_ptr")
@(export)
default_context_ptr :: proc "contextless" () -> ^Context {…}

default_logger #

Source
@(require_results)
default_logger :: proc() -> Logger {…}

Returns the default logger used by `context.logger`

default_temp_allocator_temp_begin #

Source
@(require_results)
default_temp_allocator_temp_begin :: proc(loc := #caller_location) -> (temp: Arena_Temp) {…}

default_temp_allocator_temp_end #

Source
default_temp_allocator_temp_end :: proc(temp: Arena_Temp, loc := #caller_location) {…}

delete_cstring #

Source
@(builtin)
delete_cstring :: proc(str: cstring, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {…}

`delete_cstring` will try to free the underlying data of the passed string, with the given `allocator` if the allocator supports this operation. Note: Prefer the procedure group `delete`.

delete_dynamic_array #

Source
@(builtin)
delete_dynamic_array :: proc(array: $T/[dynamic]$E, loc := #caller_location) -> Allocator_Error {…}

`delete_dynamic_array` will try to free the underlying data of the passed dynamic array, with the given `allocator` if the allocator supports this operation. Note: Prefer the procedure group `delete`.

delete_key #

Source
@(builtin)
delete_key :: proc(m: ^$T/map[$K]$V, key: $K) -> (deleted_key: $$deferred_return, deleted_value: $$deferred_return) {…}

The delete_key built-in procedure deletes the element with the specified key (m[key]) from the map. If m is nil, or there is no such element, this procedure is a no-op It is safe to use `delete_key` while iterating a map. But if you iterate across a map and insert a new key, it could resize which means you are not iterating across all of the elements.

delete_map #

Source
@(builtin)
delete_map :: proc(m: $T/map[$K]$V, loc := #caller_location) -> Allocator_Error {…}

`delete_map` will try to free the underlying data of the passed map, with the given `allocator` if the allocator supports this operation. Note: Prefer the procedure group `delete`.

delete_slice #

Source
@(builtin)
delete_slice :: proc(array: $T/[]$E, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {…}

`delete_slice` will try to free the underlying data of the passed sliced, with the given `allocator` if the allocator supports this operation. Note: Prefer the procedure group `delete`.

delete_soa_dynamic_array #

Source
@(builtin)
delete_soa_dynamic_array :: proc(array: $T/#soa[dynamic]$E, loc := #caller_location) -> Allocator_Error {…}

delete_soa_slice #

Source
@(builtin)
delete_soa_slice :: proc(array: $T/#soa[]$E, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {…}

delete_string #

Source
@(builtin)
delete_string :: proc(str: string, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {…}

`delete_string` will try to free the underlying data of the passed string, with the given `allocator` if the allocator supports this operation. Note: Prefer the procedure group `delete`.

divmodti4 #

Source
@(link_name="__divmodti4")
@(linkage=RUNTIME_LINKAGE)
@(require=RUNTIME_REQUIRE)
divmodti4 :: proc "c" (a, b: i128, rem: ^i128) -> i128 {…}

divti3 #

Source
@(link_name="__divti3")
@(linkage=RUNTIME_LINKAGE)
@(require=RUNTIME_REQUIRE)
divti3 :: proc "c" (a, b: i128) -> i128 {…}

dynamic_array_expr_error #

Source
@(disabled=ODIN_NO_BOUNDS_CHECK)
dynamic_array_expr_error :: proc "contextless" (
	file:           string, 
	line, column:   i32, 
	low, high, max: int, 
) {…}

dynamic_array_expr_error_loc #

Source
@(disabled=ODIN_NO_BOUNDS_CHECK)
dynamic_array_expr_error_loc :: proc "contextless" (loc := #caller_location, low, high, max: int) {…}

ensure #

Source
@(builtin)
ensure :: proc(condition: bool, message: string = #caller_expression(condition), loc := #caller_location) {…}

Evaluates the condition and panics the program if and only if (⟺) the condition is false. This uses the `context.assertion_failure_procedure` to assert. This routine ignores `ODIN_DISABLE_ASSERT`, and will always execute.

ensure_contextless #

Source
@(builtin)
ensure_contextless :: proc "contextless" (condition: bool, message: string = #caller_expression(condition), loc := #caller_location) {…}

Evaluates the condition and panics the program if and only if (⟺) the condition is false. This uses the `default_assertion_contextless_failure_proc` to assert.

extendhfsf2 #

Source
@(link_name="__extendhfsf2")
@(linkage=RUNTIME_LINKAGE)
@(require=RUNTIME_REQUIRE)
extendhfsf2 :: proc "c" (value: u16) -> f32 {…}

fixdfti #

Source
@(link_name="__fixdfti")
@(linkage=RUNTIME_LINKAGE)
@(require=RUNTIME_REQUIRE)
fixdfti :: proc "c" (a: u64) -> i128 {…}

fixunsdfdi #

Source
@(link_name="__fixunsdfdi")
@(linkage=RUNTIME_LINKAGE)
@(require=RUNTIME_REQUIRE)
fixunsdfdi :: proc "c" (a: f64) -> i128 {…}

fixunsdfti #

Source
@(link_name="__fixunsdfti")
@(linkage=RUNTIME_LINKAGE)
@(require=RUNTIME_REQUIRE)
fixunsdfti :: proc "c" (a: f64) -> u128 {…}

floattidf #

Source
@(link_name="__floattidf")
@(linkage=RUNTIME_LINKAGE)
@(require=RUNTIME_REQUIRE)
floattidf :: proc "c" (a: i128) -> f64 {…}

floattidf_unsigned #

Source
@(link_name="__floattidf_unsigned")
@(linkage=RUNTIME_LINKAGE)
@(require=RUNTIME_REQUIRE)
floattidf_unsigned :: proc "c" (a: u128) -> f64 {…}

gnu_f2h_ieee #

Source
@(link_name="__gnu_f2h_ieee")
@(linkage=RUNTIME_LINKAGE)
@(require=RUNTIME_REQUIRE)
gnu_f2h_ieee :: proc "c" (value: f32) -> u16 {…}

gnu_h2f_ieee #

Source
@(link_name="__gnu_h2f_ieee")
@(linkage=RUNTIME_LINKAGE)
@(require=RUNTIME_REQUIRE)
gnu_h2f_ieee :: proc "c" (value_: u16) -> f32 {…}

init_global_temporary_allocator #

Source
@(builtin)
@(disabled=NO_DEFAULT_TEMP_ALLOCATOR)
init_global_temporary_allocator :: proc(size: int, backup_allocator := context.allocator) {…}

Initializes the global temporary allocator used as the default `context.temp_allocator`. This is ignored when `NO_DEFAULT_TEMP_ALLOCATOR` is true.

inject_at_elem #

Source
@(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) #optional_ok {…}

`inject_at_elem` injects an element in a dynamic array at a specified index and moves the previous elements after that index "across"

inject_at_elem_fixed_capacity_dynamic_array #

Source
@(builtin)
inject_at_elem_fixed_capacity_dynamic_array :: proc(array: ^$T/[dynamic; $N]$E, #any_int index: int, #no_broadcast arg: $E, loc := #caller_location) -> (ok: bool) {…}

`inject_at_elem_fixed_capacity_dynamic_array` injects an element in a dynamic array at a specified index and moves the previous elements after that index "across"

inject_at_elem_soa #

Source
@(builtin)
inject_at_elem_soa :: proc(array: ^$T/#soa[dynamic]$E, #any_int index: int, #no_broadcast arg: $E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #optional_ok {…}

`inject_at_elem_soa` injects an element in a dynamic SOA array at a specified index and moves the previous elements after that index "across"

inject_at_elem_string #

Source
@(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) #optional_ok {…}

`inject_at_elem_string` injects a string into a dynamic array at a specified index and moves the previous elements after that index "across"

inject_at_elem_string_fixed_capacity_dynamic_array #

Source
@(builtin)
inject_at_elem_string_fixed_capacity_dynamic_array :: proc(array: ^$T/[dynamic; $N]$E/u8, #any_int index: int, arg: string, loc := #caller_location) -> (ok: bool) {…}

`inject_at_elem_string_fixed_capacity_dynamic_array` injects a string into a dynamic array at a specified index and moves the previous elements after that index "across"

inject_at_elems #

Source
@(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) #optional_ok {…}

`inject_at_elems` injects multiple elements in a dynamic array at a specified index and moves the previous elements after that index "across"

inject_at_elems_fixed_capacity_dynamic_array #

Source
@(builtin)
inject_at_elems_fixed_capacity_dynamic_array :: proc(array: ^$T/[dynamic; $N]$E, #any_int index: int, #no_broadcast args: ..$E, loc := #caller_location) -> (ok: bool) {…}

`inject_at_elems_fixed_capacity_dynamic_array` injects multiple elements in a dynamic array at a specified index and moves the previous elements after that index "across"

inject_at_elems_soa #

Source
@(builtin)
inject_at_elems_soa :: proc(array: ^$T/#soa[dynamic]$E, #any_int index: int, #no_broadcast args: ..$E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #optional_ok {…}

`inject_at_elems_soa` injects multiple elements in a dynamic SOA array at a specified index and moves the previous elements after that index "across"

into_dynamic_soa #

Source
@(require_results)
into_dynamic_soa :: proc(array: $T/#soa[]$E) -> $$deferred_return {…}

Converts soa slice into a soa dynamic array without cloning or allocating memory

is_power_of_two_int #

Source
@(require_results)
is_power_of_two_int :: proc "contextless" (x: int) -> bool {…}

is_power_of_two_uint #

Source
@(require_results)
is_power_of_two_uint :: proc "contextless" (x: uint) -> bool {…}

is_power_of_two_uintptr #

Source
@(require_results)
is_power_of_two_uintptr :: proc "contextless" (x: uintptr) -> bool {…}

make_aligned #

Source
@(require_results)
make_aligned :: proc($T: typeid/[]$E, #any_int len: int, alignment: int, allocator := context.allocator, loc := #caller_location) -> (res: $$deferred_return, err: Allocator_Error) #optional_ok {…}

make_dynamic_array #

Source
@(builtin)
@(require_results)
make_dynamic_array :: proc($T: typeid/[dynamic]$E, allocator := context.allocator, loc := #caller_location) -> (array: $$deferred_return, err: Allocator_Error) #optional_ok {…}

`make_dynamic_array` allocates and initializes a dynamic array. Like `new`, the first argument is a type, not a value. Unlike `new`, `make`'s return value is the same as the type of its argument, not a pointer to it. Note: Prefer using the procedure group `make`.

make_dynamic_array_error_loc #

Source
@(disabled=ODIN_NO_BOUNDS_CHECK)
make_dynamic_array_error_loc :: proc "contextless" (loc := #caller_location, len, cap: int) {…}

make_dynamic_array_len #

Source
@(builtin)
@(require_results)
make_dynamic_array_len :: proc($T: typeid/[dynamic]$E, #any_int len: int, allocator := context.allocator, loc := #caller_location) -> (array: $$deferred_return, err: Allocator_Error) #optional_ok {…}

`make_dynamic_array_len` allocates and initializes a dynamic array. Like `new`, the first argument is a type, not a value. Unlike `new`, `make`'s return value is the same as the type of its argument, not a pointer to it. Note: Prefer using the procedure group `make`.

make_dynamic_array_len_cap #

Source
@(builtin)
@(require_results)
make_dynamic_array_len_cap :: proc($T: typeid/[dynamic]$E, #any_int len: int, #any_int cap: int, allocator := context.allocator, loc := #caller_location) -> (array: $$deferred_return, err: Allocator_Error) {…}

`make_dynamic_array_len_cap` allocates and initializes a dynamic array. Like `new`, the first argument is a type, not a value. Unlike `new`, `make`'s return value is the same as the type of its argument, not a pointer to it. Note: Prefer using the procedure group `make`.

make_map #

Source
@(builtin)
@(require_results)
make_map :: proc($T: typeid/map[$K]$E, allocator := context.allocator, loc := #caller_location) -> (m: $$deferred_return) {…}

`make_map` initializes a map with an allocator. Like `new`, the first argument is a type, not a value. Unlike `new`, `make`'s return value is the same as the type of its argument, not a pointer to it. Note: Prefer using the procedure group `make`.

make_map_cap #

Source
@(builtin)
@(require_results)
make_map_cap :: proc($T: typeid/map[$K]$E, #any_int capacity: int, allocator := context.allocator, loc := #caller_location) -> (m: $$deferred_return, err: Allocator_Error) #optional_ok {…}

`make_map_cap` initializes a map with an allocator and allocates space using `capacity`. Like `new`, the first argument is a type, not a value. Unlike `new`, `make`'s return value is the same as the type of its argument, not a pointer to it. Note: Prefer using the procedure group `make`.

make_map_expr_error_loc #

Source
@(disabled=ODIN_NO_BOUNDS_CHECK)
make_map_expr_error_loc :: proc "contextless" (loc := #caller_location, cap: int) {…}

make_multi_pointer #

Source
@(builtin)
@(require_results)
make_multi_pointer :: proc($T: typeid/[^]$E, #any_int len: int, allocator := context.allocator, loc := #caller_location) -> (mp: $$deferred_return, err: Allocator_Error) {…}

`make_multi_pointer` allocates and initializes a multi-pointer. Like `new`, the first argument is a type, not a value. Unlike `new`, `make`'s return value is the same as the type of its argument, not a pointer to it. This is "similar" to doing `raw_data(make([]E, len, allocator))`. Note: Prefer using the procedure group `make`.

make_slice #

Source
@(builtin)
@(require_results)
make_slice :: proc($T: typeid/[]$E, #any_int len: int, allocator := context.allocator, loc := #caller_location) -> (res: $$deferred_return, err: Allocator_Error) #optional_ok {…}

`make_slice` allocates and initializes a slice. Like `new`, the first argument is a type, not a value. Unlike `new`, `make`'s return value is the same as the type of its argument, not a pointer to it. Note: Prefer using the procedure group `make`.

make_slice_error_loc #

Source
@(disabled=ODIN_NO_BOUNDS_CHECK)
make_slice_error_loc :: proc "contextless" (loc := #caller_location, len: int) {…}

make_soa_aligned #

Source
@(builtin)
@(require_results)
make_soa_aligned :: proc($T: typeid/#soa[]$E, #any_int length, #any_int alignment: int, allocator := context.allocator, loc := #caller_location) -> (array: $$deferred_return, err: Allocator_Error) #optional_ok {…}

make_soa_dynamic_array #

Source
@(builtin)
@(require_results)
make_soa_dynamic_array :: proc($T: typeid/#soa[dynamic]$E, allocator := context.allocator, loc := #caller_location) -> (array: $$deferred_return, err: Allocator_Error) {…}

make_soa_dynamic_array_len #

Source
@(builtin)
@(require_results)
make_soa_dynamic_array_len :: proc($T: typeid/#soa[dynamic]$E, #any_int length: int, allocator := context.allocator, loc := #caller_location) -> (array: $$deferred_return, err: Allocator_Error) #optional_ok {…}

make_soa_dynamic_array_len_cap #

Source
@(builtin)
@(require_results)
make_soa_dynamic_array_len_cap :: proc($T: typeid/#soa[dynamic]$E, #any_int length, #any_int capacity: int, allocator := context.allocator, loc := #caller_location) -> (array: $$deferred_return, err: Allocator_Error) #optional_ok {…}

make_soa_slice #

Source
@(builtin)
@(require_results)
make_soa_slice :: proc($T: typeid/#soa[]$E, #any_int length: int, allocator := context.allocator, loc := #caller_location) -> (array: $$deferred_return, err: Allocator_Error) #optional_ok {…}

map_alloc_dynamic #

Source
@(require_results)
map_alloc_dynamic :: proc(info: ^Map_Info, log2_capacity: uintptr, allocator := context.allocator, loc := #caller_location) -> (result: Raw_Map, err: Allocator_Error) {…}

The only procedure which needs access to the context is the one which allocates the map.

map_cell_index_dynamic #

Source
@(require_results)
map_cell_index_dynamic :: proc "contextless" (base: uintptr, #no_alias info: ^Map_Cell_Info, index: uintptr) -> uintptr {…}

Same as the above procedure but at runtime with the cell Map_Cell_Info value.

map_cell_index_dynamic_const #

Source
@(require_results)
map_cell_index_dynamic_const :: proc "contextless" (base: uintptr, #no_alias info: ^Map_Cell_Info, $INDEX: uintptr) -> uintptr {…}

Same as above procedure but with compile-time constant index.

map_cell_index_static #

Source
@(require_results)
map_cell_index_static :: proc "contextless" (cells: [^]Map_Cell($T), index: uintptr) -> $$deferred_return {…}

We always round the capacity to a power of two so this becomes [16]Foo, which works out to [4]Cell(Foo). The following compile-time procedure indexes such a [N]Cell(T) structure as if it were a flat array accounting for the internal padding introduced by the Cell structure.

map_cell_info #

Source
map_cell_info :: invalid type {…}

map_cell_info :: proc "contextless" ($T: typeid) -> ^Map_Cell_Info {...}

map_data #

Source
@(require_results)
map_data :: proc "contextless" (m: Raw_Map) -> uintptr {…}

Canonicalize the data by removing the tagged capacity stored in the lower six bits of the data uintptr.

map_desired_position #

Source
@(require_results)
map_desired_position :: proc "contextless" (m: Raw_Map, hash: uintptr) -> uintptr {…}

Computes the desired position in the array. This is just index % capacity, but a procedure as there's some math involved here to recover the capacity.

map_entry #

Source
@(builtin)
@(require_results)
map_entry :: proc(m: ^$T/map[$K]$V, key: $K, loc := #caller_location) -> (key_ptr: $$deferred_return, value_ptr: $$deferred_return, just_inserted: bool, err: Allocator_Error) {…}

Retrieves a pointer to the key and value for a possibly just inserted entry into the map. If the `key` was not in the map `m`, an entry is inserted with the zero value and `just_inserted` will be `true`. Otherwise the existing entry is left untouched and pointers to its key and value are returned. If the map has to grow in order to insert the entry and the allocation fails, `err` is set and returned. If `err` is `nil`, `key_ptr` and `value_ptr` are valid pointers and will not be `nil`. WARN: User modification of the key pointed at by `key_ptr` should only be done if the new key is equal to (in hash) the old key. If that is not the case you will corrupt the map.

map_get #

Source
@(require_results)
map_get :: proc "contextless" (m: $T/map[$K]$V, key: $K) -> (stored_key: $$deferred_return, stored_value: $$deferred_return, ok: bool) {…}

map_hash_is_empty #

Source
@(require_results)
map_hash_is_empty :: proc "contextless" (hash: uintptr) -> bool {…}

Procedure to check if a slot is empty for a given hash. This is represented by the zero value to make the zero value useful. This is a procedure just for prose reasons.

map_info #

Source
map_info :: invalid type {…}

The Map_Info structure is basically a pseudo-table of information for a given K and V pair. map_info :: proc "contextless" ($T: typeid/map[$K]$V) -> ^Map_Info {...}

map_insert #

Source
@(builtin)
map_insert :: proc(m: ^$T/map[$K]$V, key: $K, value: $V, loc := #caller_location) -> (ptr: $$deferred_return) {…}

map_insert_hash_dynamic_with_key #

Source
@(require_results)
map_insert_hash_dynamic_with_key :: proc(#no_alias m: ^Raw_Map, #no_alias info: ^Map_Info, h: uintptr, ik: uintptr, iv: uintptr) -> (key: uintptr, result: uintptr) {…}

This procedure has to stack allocate storage to store local keys during the Robin Hood hashing technique where elements are swapped in the backing arrays to reduce variance. This swapping can only be done with memcpy since there is no type information. This procedure returns the address of the just inserted value, and will return 'nil' if there was no room to insert the entry

map_load_factor #

Source
@(require_results)
map_load_factor :: proc "contextless" (log2_capacity: uintptr) -> uintptr {…}

Query the load factor of the map. This is not actually configurable, but some math is needed to compute it. Compute it as a fixed point percentage to avoid floating point operations. This division can be optimized out by multiplying by the multiplicative inverse of 100.

map_log2_cap #

Source
@(require_results)
map_log2_cap :: proc "contextless" (m: Raw_Map) -> uintptr {…}

The data stores the log2 capacity in the lower six bits. This is primarily used in the implementation rather than map_cap since the check for data = 0 isn't necessary in the implementation. cap() on the otherhand needs to work when called on an empty map.

map_seed_from_map_data #

Source
@(require_results)
map_seed_from_map_data :: proc "contextless" (data: uintptr) -> uintptr {…}

splitmix for uintptr

map_total_allocation_size_from_value #

Source
@(require_results)
map_total_allocation_size_from_value :: proc "contextless" (m: $M/map[$K]$V) -> uintptr {…}

map_upsert #

Source
@(builtin)
@(require_results)
map_upsert :: proc(m: ^$T/map[$K]$V, key: $K, value: $V, loc := #caller_location) -> (prev_key: $$deferred_return, value_ptr: $$deferred_return, found_previous: bool) {…}

Explicitly inserts a key and value into a map `m`, the same as `map_insert`, but the return values differ. - `prev_key` will return the previous pointer of a key if it exists, check `found_previous` if was previously found - `value_ptr` will return the pointer of the memory where the insertion happens, and `nil` if the map failed to resize - `found_previous` will be true a previous key was found

matrix_bounds_check_error #

Source
@(disabled=ODIN_NO_BOUNDS_CHECK)
matrix_bounds_check_error :: proc "contextless" (
	file:                                             string, 
	line, column:                                     i32, 
	row_index, column_index, row_count, column_count: int, 
) {…}

mem_alloc_bytes #

Source
mem_alloc_bytes :: proc(size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> ([]u8, Allocator_Error) {…}

mem_alloc_non_zeroed #

Source
mem_alloc_non_zeroed :: proc(size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> ([]u8, Allocator_Error) {…}

memory_block_dealloc #

Source
memory_block_dealloc :: proc "contextless" (block_to_free: ^Memory_Block, loc := #caller_location) {…}

modti3 #

Source
@(link_name="__modti3")
@(linkage=RUNTIME_LINKAGE)
@(require=RUNTIME_REQUIRE)
modti3 :: proc "c" (a, b: i128) -> i128 {…}

multi_pointer_slice_expr_error #

Source
@(disabled=ODIN_NO_BOUNDS_CHECK)
multi_pointer_slice_expr_error :: proc "contextless" (file: string, line, column: i32, lo, hi: int) -> ! {…}

multi_pointer_slice_handle_error #

Source
@(no_instrumentation)
multi_pointer_slice_handle_error :: proc "contextless" (file: string, line, column: i32, lo, hi: int) -> ! {…}

new #

Source
@(builtin)
@(require_results)
new :: proc($T: typeid, allocator := context.allocator, loc := #caller_location) -> (t: ^typeid, err: Allocator_Error) #optional_ok {…}

The new built-in procedure allocates memory. The first argument is a type, not a value, and the value return is a pointer to a newly allocated value of that type using the specified allocator, default is context.allocator

new_clone #

Source
@(builtin)
@(require_results)
new_clone :: proc(data: $T, allocator := context.allocator, loc := #caller_location) -> (t: $$deferred_return, err: Allocator_Error) {…}

nil_allocator #

Source
@(require_results)
nil_allocator :: proc "contextless" () -> Allocator {…}

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.

non_zero_append_elem #

Source
@(builtin)
non_zero_append_elem :: proc(array: ^$T/[dynamic]$E, #no_broadcast arg: $E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_ok {…}

`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

non_zero_append_elem_fixed_capacity_string #

Source
@(builtin)
non_zero_append_elem_fixed_capacity_string :: proc "contextless" (array: ^$T/[dynamic; $N]$E/u8, arg: $A/string) -> (n: int) {…}

`non_zero_append_elem_fixed_capacity_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`.

non_zero_append_elem_string #

Source
@(builtin)
non_zero_append_elem_string :: proc(array: ^$T/[dynamic]$E/u8, arg: $A/string, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_ok {…}

`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`.

non_zero_append_elems #

Source
@(builtin)
non_zero_append_elems :: proc(array: ^$T/[dynamic]$E, #no_broadcast args: ..$E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_ok {…}

`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

non_zero_append_soa_elem #

Source
@(builtin)
non_zero_append_soa_elem :: proc(array: ^$T/#soa[dynamic]$E, #no_broadcast arg: $E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_ok {…}

non_zero_append_soa_elems #

Source
@(builtin)
non_zero_append_soa_elems :: proc(array: ^$T/#soa[dynamic]$E, #no_broadcast args: ..$E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_ok {…}

non_zero_mem_resize #

Source
non_zero_mem_resize :: proc(
	ptr:       rawptr, 
	old_size:  int, 
	new_size:  int, 
	alignment: int = DEFAULT_ALIGNMENT, 
	allocator := context.allocator, 
	loc := #caller_location, 
) -> (data: []u8, err: Allocator_Error) {…}

non_zero_reserve_dynamic_array #

Source
@(builtin)
non_zero_reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, #any_int capacity: int, loc := #caller_location) -> Allocator_Error {…}

`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`.

non_zero_reserve_soa #

Source
@(builtin)
non_zero_reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, #any_int capacity: int, loc := #caller_location) -> Allocator_Error {…}

non_zero_resize_dynamic_array #

Source
@(builtin)
non_zero_resize_dynamic_array :: proc(array: ^$T/[dynamic]$E, #any_int length: int, loc := #caller_location) -> Allocator_Error {…}

`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`

non_zero_resize_fixed_capacity_dynamic_array #

Source
@(builtin)
non_zero_resize_fixed_capacity_dynamic_array :: proc "contextless" (array: ^$T/[dynamic; $N]$E, #any_int length: int) -> bool {…}

`non_zero_resize_fixed_capacity_dynamic_array` will try to resize memory of a passed fixed capacity dynamic array or map to the requested element count (setting the `len`, and possibly `cap`). Note: Prefer the procedure group `resize`

non_zero_resize_soa #

Source
@(builtin)
non_zero_resize_soa :: proc(array: ^$T/#soa[dynamic]$E, #any_int length: int, loc := #caller_location) -> Allocator_Error {…}

ordered_remove_dynamic_array #

Source
@(builtin)
ordered_remove_dynamic_array :: proc(array: ^$D/[dynamic]$T, #any_int index: int, loc := #caller_location) {…}

`ordered_remove_dynamic_array` removed the element at the specified `index` whilst keeping the order of the other elements. Note: This is an O(N) operation. Note: If the elements do not have to remain in their order, prefer `unordered_remove`. Note: If the index is out of bounds, this procedure will panic.

ordered_remove_fixed_capacity_dynamic_array #

Source
@(builtin)
ordered_remove_fixed_capacity_dynamic_array :: proc(array: ^$D/[dynamic; $N]$E, #any_int index: int, loc := #caller_location) {…}

`ordered_remove_fixed_capacity_dynamic_array` removed the element at the specified `index` whilst keeping the order of the other elements. Note: This is an O(N) operation. Note: If the elements do not have to remain in their order, prefer `unordered_remove`. Note: If the index is out of bounds, this procedure will panic.

ordered_remove_soa #

Source
@(builtin)
ordered_remove_soa :: proc(array: ^$T/#soa[dynamic]$E, #any_int index: int, loc := #caller_location) {…}

`ordered_remove_soa` removed the element at the specified `index` whilst keeping the order of the other elements. Note: This is an O(N) operation. Note: If you the elements do not have to remain in their order, prefer `unordered_remove_soa`. Note: If the index is out of bounds, this procedure will panic.

panic #

Source
@(builtin)
panic :: proc(message: string, loc := #caller_location) -> ! {…}

Panics the program with a message. This uses the `context.assertion_failure_procedure` to panic.

panic_allocator #

Source
@(require_results)
panic_allocator :: proc() -> Allocator {…}

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.

panic_contextless #

Source
@(builtin)
panic_contextless :: proc "contextless" (message: string, loc := #caller_location) -> ! {…}

Panics the program with a message to indicate something has yet to be implemented. This uses the `default_assertion_contextless_failure_proc` to assert.

pop_dynamic_array #

Source
@(builtin)
pop_dynamic_array :: proc(array: ^$T/[dynamic]$E, loc := #caller_location) -> (res: $$deferred_return) {…}

`pop_dynamic_array` will remove and return the end value of dynamic array `array` and reduces the length of `array` by 1. Note: If the dynamic array has no elements (`len(array) == 0`), this procedure will panic.

pop_fixed_capacity_dynamic_array #

Source
@(builtin)
pop_fixed_capacity_dynamic_array :: proc(array: ^$T/[dynamic; $N]$E, loc := #caller_location) -> (res: $$deferred_return) {…}

`pop_fixed_capacity_dynamic_array` will remove and return the end value of fixed capacity dynamic array `array` and reduces the length of `array` by 1. Note: If the fixed capacity dynamic array has no elements (`len(array) == 0`), this procedure will panic.

pop_front_dynamic_array #

Source
@(builtin)
pop_front_dynamic_array :: proc(array: ^$T/[dynamic]$E, loc := #caller_location) -> (res: $$deferred_return) {…}

`pop_front_dynamic_array` will remove and return the first value of dynamic array `array` and reduces the length of `array` by 1. Note: If the dynamic array as no elements (`len(array) == 0`), this procedure will panic.

pop_front_fixed_capacity_dynamic_array #

Source
@(builtin)
pop_front_fixed_capacity_dynamic_array :: proc(array: ^$T/[dynamic; $N]$E, loc := #caller_location) -> (res: $$deferred_return) {…}

`pop_front_fixed_capacity_dynamic_array` will remove and return the first value of fixed capacity dynamic array `array` and reduces the length of `array` by 1. Note: If the fixed capacity dynamic array as no elements (`len(array) == 0`), this procedure will panic.

pop_front_safe_dynamic_array #

Source
@(builtin)
pop_front_safe_dynamic_array :: proc "contextless" (array: ^$T/[dynamic]$E) -> (res: $$deferred_return, ok: bool) {…}

`pop_front_safe_dynamic_array` trys to return and remove the first value of dynamic array `array` and reduces the length of `array` by 1. If the operation is not possible, it will return false.

pop_front_safe_fixed_capacity_dynamic_array #

Source
@(builtin)
pop_front_safe_fixed_capacity_dynamic_array :: proc "contextless" (array: ^$T/[dynamic; $N]$E) -> (res: $$deferred_return, ok: bool) {…}

`pop_front_safe_fixed_capacity_dynamic_array` trys to return and remove the first value of dynamic array `array` and reduces the length of `array` by 1. If the operation is not possible, it will return false.

pop_safe_dynamic_array #

Source
@(builtin)
pop_safe_dynamic_array :: proc "contextless" (array: ^$T/[dynamic]$E) -> (res: $$deferred_return, ok: bool) {…}

`pop_safe_dynamic_array` trys to remove and return the end value of dynamic array `array` and reduces the length of `array` by 1. If the operation is not possible, it will return false.

pop_safe_fixed_capacity_dynamic_array #

Source
@(builtin)
pop_safe_fixed_capacity_dynamic_array :: proc "contextless" (array: ^$T/[dynamic; $N]$E) -> (res: $$deferred_return, ok: bool) {…}

`pop_safe_fixed_capacity_dynamic_array` trys to remove and return the end value of dynamic array `array` and reduces the length of `array` by 1. If the operation is not possible, it will return false.

remove_range_dynamic_array #

Source
@(builtin)
remove_range_dynamic_array :: proc(array: ^$D/[dynamic]$T, #any_int lo, #any_int hi: int, loc := #caller_location) {…}

`remove_range_dynamic_array` removes a range of elements specified by the range `lo` and `hi`, whilst keeping the order of the other elements. Note: This is an O(N) operation. Note: If the range is out of bounds, this procedure will panic.

remove_range_fixed_capacity_dynamic_array #

Source
@(builtin)
remove_range_fixed_capacity_dynamic_array :: proc(array: ^$D/[dynamic; $N]$E, #any_int lo, #any_int hi: int, loc := #caller_location) {…}

`remove_range_fixed_capacity_dynamic_array` removes a range of elements specified by the range `lo` and `hi`, whilst keeping the order of the other elements. Note: This is an O(N) operation. Note: If the range is out of bounds, this procedure will panic.

reserve_dynamic_array #

Source
@(builtin)
reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, #any_int capacity: int, loc := #caller_location) -> Allocator_Error {…}

`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_map #

Source
@(builtin)
reserve_map :: proc(m: ^$T/map[$K]$V, #any_int capacity: int, loc := #caller_location) -> Allocator_Error {…}

`reserve_map` will try to reserve memory of a passed map to the requested element count (setting the `cap`). Note: Prefer the procedure group `reserve`

resize_dynamic_array #

Source
@(builtin)
resize_dynamic_array :: proc(array: ^$T/[dynamic]$E, #any_int length: int, loc := #caller_location) -> Allocator_Error {…}

`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`

resize_fixed_capacity_dynamic_array #

Source
@(builtin)
resize_fixed_capacity_dynamic_array :: proc "contextless" (array: ^$T/[dynamic; $N]$E, #any_int length: int) -> bool {…}

`resize_fixed_capacity_dynamic_array` will try to resize memory of a passed fixed capacity dynamic array or map to the requested element count (setting the `len`, and possibly `cap`). Note: Prefer the procedure group `resize`

run_thread_local_cleaners #

Source
run_thread_local_cleaners :: proc() {…}

Run all of the thread-local cleaner procedures. Intended to be called by the internals of a threading API at the end of a thread's lifetime.

shrink_dynamic_array #

Source
@(builtin)
shrink_dynamic_array :: proc(array: ^$T/[dynamic]$E, #any_int new_cap: int = -1, loc := #caller_location) -> (did_shrink: bool, err: Allocator_Error) {…}

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_map #

Source
@(builtin)
shrink_map :: proc(m: ^$T/map[$K]$V, loc := #caller_location) -> (did_shrink: bool, err: Allocator_Error) {…}

Shrinks the capacity of a map down to the current length. Note: Prefer the procedure group `shrink`

slice_expr_error_hi #

Source
@(disabled=ODIN_NO_BOUNDS_CHECK)
slice_expr_error_hi :: proc "contextless" (file: string, line, column: i32, hi: int, len: int) {…}

slice_expr_error_hi_loc #

Source
@(disabled=ODIN_NO_BOUNDS_CHECK)
slice_expr_error_hi_loc :: proc "contextless" (loc := #caller_location, hi: int, len: int) {…}

slice_expr_error_lo_hi #

Source
@(disabled=ODIN_NO_BOUNDS_CHECK)
slice_expr_error_lo_hi :: proc "contextless" (
	file:         string, 
	line, column: i32, 
	lo, hi:       int, 
	len:          int, 
) {…}

slice_expr_error_lo_hi_loc #

Source
@(disabled=ODIN_NO_BOUNDS_CHECK)
slice_expr_error_lo_hi_loc :: proc "contextless" (loc := #caller_location, lo, hi: int, len: int) {…}

slice_handle_error #

Source
@(no_instrumentation)
slice_handle_error :: proc "contextless" (
	file:         string, 
	line, column: i32, 
	lo, hi:       int, 
	len:          int, 
) {…}

truncdfhf2 #

Source
@(link_name="__truncdfhf2")
@(linkage=RUNTIME_LINKAGE)
@(require=RUNTIME_REQUIRE)
truncdfhf2 :: proc "c" (value: f64) -> u16 {…}

truncsfhf2 #

Source
@(link_name="__truncsfhf2")
@(linkage=RUNTIME_LINKAGE)
@(require=RUNTIME_REQUIRE)
truncsfhf2 :: proc "c" (value: f32) -> u16 {…}

type_assertion_check_contextless #

Source
type_assertion_check_contextless :: proc "contextless" (
	ok:           bool, 
	file:         string, 
	line, column: i32, 
	from, to:     typeid, 
) {…}

type_assertion_trap_contextless #

Source
@(no_instrumentation)
type_assertion_trap_contextless :: proc "contextless" () {…}

type_info_base #

Source
@(require_results)
type_info_base :: proc "contextless" (info: ^Type_Info) -> ^Type_Info {…}

type_info_base returns the base-type of a `^Type_Info` stripping the `distinct`ness from the first level

type_info_base_without_enum #

Source
@(require_results)
type_info_base_without_enum :: 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 `^Type_Info`. This is also aliased as `type_info_base_without_enum`

type_info_core #

Source
@(require_results)
type_info_core :: 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 `^Type_Info`. This is also aliased as `type_info_base_without_enum`

type_info_underlying #

Source
@(require_results)
type_info_underlying :: proc "contextless" (info: ^Type_Info) -> ^Type_Info {…}

type_info_underlying returns the underlying (backing) type of a `^Type_Info` stripping the `distinct`ness from the first level AND/OR returns the backing integer type of an enum `^Type_Info` AND/OR the underlying integer type of a bit_set or bit_field.

typeid_base #

Source
@(require_results)
typeid_base :: proc "contextless" (id: typeid) -> typeid {…}

typeid_base returns the base-type of a `typeid` stripping the `distinct`ness from the first level

typeid_base_without_enum #

Source
@(require_results)
typeid_base_without_enum :: proc "contextless" (id: typeid) -> typeid {…}

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 `typeid`. This is also aliased as `typeid_base_without_enum`

typeid_core #

Source
@(require_results)
typeid_core :: proc "contextless" (id: typeid) -> typeid {…}

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 `typeid`. This is also aliased as `typeid_base_without_enum`

udivmodti4 #

Source
@(link_name="__udivmodti4")
@(linkage=RUNTIME_LINKAGE)
@(require=RUNTIME_REQUIRE)
udivmodti4 :: proc "c" (a, b: u128, rem: ^u128) -> u128 {…}

udivti3 #

Source
@(link_name="__udivti3")
@(linkage="strong")
udivti3 :: proc "c" (la, ha, lb, hb: u64) -> u128 {…}

umodti3 #

Source
@(link_name="__umodti3")
@(linkage=RUNTIME_LINKAGE)
@(require=RUNTIME_REQUIRE)
umodti3 :: proc "c" (a, b: u128) -> u128 {…}

unimplemented #

Source
@(builtin)
unimplemented :: proc(message: string = "", loc := #caller_location) -> ! {…}

Panics the program with a message to indicate something has yet to be implemented. This uses the `context.assertion_failure_procedure` to assert.

unimplemented_contextless #

Source
@(builtin)
unimplemented_contextless :: proc "contextless" (message: string = "", loc := #caller_location) -> ! {…}

Panics the program with a message. This uses the `default_assertion_contextless_failure_proc` to assert.

unordered_remove_dynamic_array #

Source
@(builtin)
unordered_remove_dynamic_array :: proc(array: ^$D/[dynamic]$T, #any_int index: int, loc := #caller_location) {…}

`unordered_remove_dynamic_array` removed the element at the specified `index`. It does so by replacing the current end value with the old value, and reducing the length of the dynamic array by 1. Note: This is an O(1) operation. Note: If you want the elements to remain in their order, use `ordered_remove`. Note: If the index is out of bounds, this procedure will panic.

unordered_remove_fixed_capacity_dynamic_array #

Source
@(builtin)
unordered_remove_fixed_capacity_dynamic_array :: proc(array: ^$D/[dynamic; $N]$E, #any_int index: int, loc := #caller_location) {…}

`unordered_remove_fixed_capacity_dynamic_array` removed the element at the specified `index`. It does so by replacing the current end value with the old value, and reducing the length of the dynamic array by 1. Note: This is an O(1) operation. Note: If you want the elements to remain in their order, use `ordered_remove`. Note: If the index is out of bounds, this procedure will panic.

unordered_remove_soa #

Source
@(builtin)
unordered_remove_soa :: proc(array: ^$T/#soa[dynamic]$E, #any_int index: int, loc := #caller_location) {…}

`unordered_remove_soa` removed the element at the specified `index`. It does so by replacing the current end value with the old value, and reducing the length of the dynamic array by 1. Note: This is an O(1) operation. Note: If you the elements to remain in their order, use `ordered_remove_soa`. Note: If the index is out of bounds, this procedure will panic.

wasm_allocator_free_space #

Source
wasm_allocator_free_space :: proc(a: ^WASM_Allocator = nil) -> (free: uint) {…}

Returns the amount of free memory on the allocator. If `nil` is given, the global allocator is used.

wasm_allocator_init #

Source
wasm_allocator_init :: proc(a: ^WASM_Allocator, alignment: uint = 8) {…}

Not required to be called, called on first allocation otherwise.

wasm_allocator_size #

Source
wasm_allocator_size :: proc(a: ^WASM_Allocator = nil) -> (size: uint) {…}

Returns the allocated size of the allocator (both free and used). If `nil` is given, the global allocator is used.

Procedure Groups

31

copy #

Source
@(builtin)
copy :: proc{
	copy_slice,
	copy_from_string,
	copy_from_string16,
}

`copy` is a built-in procedure that copies elements from a source slice/string `src` to a destination slice `dst`. The source and destination may overlap. Copy returns the number of elements copied, which will be the minimum of len(src) and len(dst).

free #

Source
@(builtin)
free :: proc{
	mem_free,
}

`free` will try to free the passed pointer, with the given `allocator` if the allocator supports this operation.

free_all #

Source
@(builtin)
free_all :: proc{
	mem_free_all,
}

`free_all` will try to free/reset all of the memory of the given `allocator` if the allocator supports this operation.

make #

Source
@(builtin)
make :: proc{
	make_slice,
	make_dynamic_array,
	make_dynamic_array_len,
	make_dynamic_array_len_cap,
	make_map,
	make_map_cap,
	make_multi_pointer,
	make_soa_slice,
	make_soa_dynamic_array,
	make_soa_dynamic_array_len,
	make_soa_dynamic_array_len_cap,
}

`make` built-in procedure allocates and initializes a value of type slice, dynamic array, map, or multi-pointer (only). Similar to `new`, the first argument is a type, not a value. Unlike new, make's return type is the same as the type of its argument, not a pointer to it. Make uses the specified allocator, default is context.allocator.

Variables

5

type_table #

Source
type_table: []^Type_Info

NOTE(bill): only the ones that are needed (not all types) This will be set by the compiler