Merge branch 'odin-lang:master' into master

This commit is contained in:
marcs feh
2024-02-02 21:56:40 -03:00
committed by GitHub
265 changed files with 2046 additions and 1581 deletions
+1 -1
View File
@@ -4,7 +4,7 @@ import "core:bytes"
import "core:io"
import "core:mem"
import "core:unicode/utf8"
import "core:intrinsics"
import "base:intrinsics"
// Extra errors returns by scanning procedures
Scanner_Extra_Error :: enum i32 {
-128
View File
@@ -1,128 +0,0 @@
// This is purely for documentation
package builtin
nil :: nil
false :: 0!=0
true :: 0==0
ODIN_OS :: ODIN_OS
ODIN_ARCH :: ODIN_ARCH
ODIN_ENDIAN :: ODIN_ENDIAN
ODIN_VENDOR :: ODIN_VENDOR
ODIN_VERSION :: ODIN_VERSION
ODIN_ROOT :: ODIN_ROOT
ODIN_DEBUG :: ODIN_DEBUG
byte :: u8 // alias
bool :: bool
b8 :: b8
b16 :: b16
b32 :: b32
b64 :: b64
i8 :: i8
u8 :: u8
i16 :: i16
u16 :: u16
i32 :: i32
u32 :: u32
i64 :: i64
u64 :: u64
i128 :: i128
u128 :: u128
rune :: rune
f16 :: f16
f32 :: f32
f64 :: f64
complex32 :: complex32
complex64 :: complex64
complex128 :: complex128
quaternion64 :: quaternion64
quaternion128 :: quaternion128
quaternion256 :: quaternion256
int :: int
uint :: uint
uintptr :: uintptr
rawptr :: rawptr
string :: string
cstring :: cstring
any :: any
typeid :: typeid
// Endian Specific Types
i16le :: i16le
u16le :: u16le
i32le :: i32le
u32le :: u32le
i64le :: i64le
u64le :: u64le
i128le :: i128le
u128le :: u128le
i16be :: i16be
u16be :: u16be
i32be :: i32be
u32be :: u32be
i64be :: i64be
u64be :: u64be
i128be :: i128be
u128be :: u128be
f16le :: f16le
f32le :: f32le
f64le :: f64le
f16be :: f16be
f32be :: f32be
f64be :: f64be
// Procedures
len :: proc(array: Array_Type) -> int ---
cap :: proc(array: Array_Type) -> int ---
size_of :: proc($T: typeid) -> int ---
align_of :: proc($T: typeid) -> int ---
// e.g. offset_of(t.f), where t is an instance of the type T
offset_of_selector :: proc(selector: $T) -> uintptr ---
// e.g. offset_of(T, f), where T can be the type instead of a variable
offset_of_member :: proc($T: typeid, member: $M) -> uintptr ---
offset_of :: proc{offset_of_selector, offset_of_member}
// e.g. offset_of(T, "f"), where T can be the type instead of a variable
offset_of_by_string :: proc($T: typeid, member: string) -> uintptr ---
type_of :: proc(x: expr) -> type ---
type_info_of :: proc($T: typeid) -> ^runtime.Type_Info ---
typeid_of :: proc($T: typeid) -> typeid ---
swizzle :: proc(x: [N]T, indices: ..int) -> [len(indices)]T ---
complex :: proc(real, imag: Float) -> Complex_Type ---
quaternion :: proc(imag, jmag, kmag, real: Float) -> Quaternion_Type --- // fields must be named
real :: proc(value: Complex_Or_Quaternion) -> Float ---
imag :: proc(value: Complex_Or_Quaternion) -> Float ---
jmag :: proc(value: Quaternion) -> Float ---
kmag :: proc(value: Quaternion) -> Float ---
conj :: proc(value: Complex_Or_Quaternion) -> Complex_Or_Quaternion ---
expand_values :: proc(value: Struct_Or_Array) -> (A, B, C, ...) ---
min :: proc(values: ..T) -> T ---
max :: proc(values: ..T) -> T ---
abs :: proc(value: T) -> T ---
clamp :: proc(value, minimum, maximum: T) -> T ---
soa_zip :: proc(slices: ...) -> #soa[]Struct ---
soa_unzip :: proc(value: $S/#soa[]$E) -> (slices: ...) ---
+1 -1
View File
@@ -1,6 +1,6 @@
package c
import builtin "core:builtin"
import builtin "base:builtin"
char :: builtin.u8 // assuming -funsigned-char
+1 -1
View File
@@ -67,7 +67,7 @@ foreign libc {
crealf :: proc(z: complex_float) -> float ---
}
import builtin "core:builtin"
import builtin "base:builtin"
complex_float :: distinct builtin.complex64
complex_double :: distinct builtin.complex128
+1 -1
View File
@@ -2,7 +2,7 @@ package libc
// 7.12 Mathematics
import "core:intrinsics"
import "base:intrinsics"
when ODIN_OS == .Windows {
foreign import libc "system:libucrt.lib"
+1 -1
View File
@@ -2,7 +2,7 @@ package libc
// 7.16 Variable arguments
import "core:intrinsics"
import "base:intrinsics"
@(private="file")
@(default_calling_convention="none")
+1 -1
View File
@@ -2,7 +2,7 @@ package libc
// 7.17 Atomics
import "core:intrinsics"
import "base:intrinsics"
ATOMIC_BOOL_LOCK_FREE :: true
ATOMIC_CHAR_LOCK_FREE :: true
+1 -1
View File
@@ -1,6 +1,6 @@
package libc
import "core:runtime"
import "base:runtime"
// 7.24 String handling
+1 -1
View File
@@ -12,7 +12,7 @@ package compress
import "core:io"
import "core:bytes"
import "core:runtime"
import "base:runtime"
/*
These settings bound how much compression algorithms will allocate for their output buffer.
+1 -1
View File
@@ -11,7 +11,7 @@
// package shoco is an implementation of the shoco short string compressor
package shoco
import "core:intrinsics"
import "base:intrinsics"
import "core:compress"
Shoco_Pack :: struct {
+1 -1
View File
@@ -1,6 +1,6 @@
package dynamic_bit_array
import "core:intrinsics"
import "base:intrinsics"
import "core:mem"
/*
@@ -1,6 +1,6 @@
package container_intrusive_list
import "core:intrinsics"
import "base:intrinsics"
// An intrusive doubly-linked list
//
+2 -2
View File
@@ -1,7 +1,7 @@
package container_lru
import "core:runtime"
import "core:intrinsics"
import "base:runtime"
import "base:intrinsics"
_ :: runtime
_ :: intrinsics
@@ -1,6 +1,6 @@
package container_priority_queue
import "core:builtin"
import "base:builtin"
Priority_Queue :: struct($T: typeid) {
queue: [dynamic]T,
+2 -2
View File
@@ -1,7 +1,7 @@
package container_queue
import "core:builtin"
import "core:runtime"
import "base:builtin"
import "base:runtime"
_ :: runtime
// Dynamically resizable double-ended queue/ring-buffer
+2 -2
View File
@@ -1,7 +1,7 @@
package container_small_array
import "core:builtin"
import "core:runtime"
import "base:builtin"
import "base:runtime"
_ :: runtime
Small_Array :: struct($N: int, $T: typeid) where N >= 0 {
@@ -3,8 +3,8 @@
// map type is being used to accelerate lookups.
package container_topological_sort
import "core:intrinsics"
import "core:runtime"
import "base:intrinsics"
import "base:runtime"
_ :: intrinsics
_ :: runtime
+2 -2
View File
@@ -1,8 +1,8 @@
package dynlib
import "core:intrinsics"
import "base:intrinsics"
import "core:reflect"
import "core:runtime"
import "base:runtime"
_ :: intrinsics
_ :: reflect
_ :: runtime
+1 -1
View File
@@ -4,7 +4,7 @@ package dynlib
import win32 "core:sys/windows"
import "core:strings"
import "core:runtime"
import "base:runtime"
import "core:reflect"
_load_library :: proc(path: string, global_symbols := false) -> (Library, bool) {
+1 -1
View File
@@ -1,6 +1,6 @@
package encoding_endian
import "core:intrinsics"
import "base:intrinsics"
import "core:math/bits"
Byte_Order :: enum u8 {
+1 -1
View File
@@ -2,7 +2,7 @@ package json
import "core:mem"
import "core:math/bits"
import "core:runtime"
import "base:runtime"
import "core:strconv"
import "core:strings"
import "core:reflect"
+1 -1
View File
@@ -5,7 +5,7 @@ import "core:math"
import "core:reflect"
import "core:strconv"
import "core:strings"
import "core:runtime"
import "base:runtime"
Unmarshal_Data_Error :: enum {
Invalid_Data,
+2 -2
View File
@@ -29,11 +29,11 @@ package xml
import "core:bytes"
import "core:encoding/entity"
import "core:intrinsics"
import "base:intrinsics"
import "core:mem"
import "core:os"
import "core:strings"
import "core:runtime"
import "base:runtime"
likely :: intrinsics.expect
+4 -18
View File
@@ -1,15 +1,15 @@
package fmt
import "base:intrinsics"
import "base:runtime"
import "core:math/bits"
import "core:mem"
import "core:io"
import "core:reflect"
import "core:runtime"
import "core:strconv"
import "core:strings"
import "core:time"
import "core:unicode/utf8"
import "core:intrinsics"
// Internal data structure that stores the required information for formatted printing
Info :: struct {
@@ -954,24 +954,10 @@ _fmt_int :: proc(fi: ^Info, u: u64, base: int, is_signed: bool, bit_size: int, d
start := 0
flags: strconv.Int_Flags
if fi.hash && !fi.zero { flags |= {.Prefix} }
if fi.plus { flags |= {.Plus} }
if fi.hash { flags |= {.Prefix} }
if fi.plus { flags |= {.Plus} }
s := strconv.append_bits(buf[start:], u, base, is_signed, bit_size, digits, flags)
if fi.hash && fi.zero && fi.indent == 0 {
c: byte = 0
switch base {
case 2: c = 'b'
case 8: c = 'o'
case 12: c = 'z'
case 16: c = 'x'
}
if c != 0 {
io.write_byte(fi.writer, '0', &fi.n)
io.write_byte(fi.writer, c, &fi.n)
}
}
prev_zero := fi.zero
defer fi.zero = prev_zero
fi.zero = false
+1 -1
View File
@@ -2,7 +2,7 @@
//+build !js
package fmt
import "core:runtime"
import "base:runtime"
import "core:os"
import "core:io"
import "core:bufio"
+1 -1
View File
@@ -1,6 +1,6 @@
package hash
import "core:intrinsics"
import "base:intrinsics"
@(optimization_mode="speed")
crc32 :: proc(data: []byte, seed := u32(0)) -> u32 #no_bounds_check {
+1 -1
View File
@@ -1,7 +1,7 @@
package hash
import "core:mem"
import "core:intrinsics"
import "base:intrinsics"
@(optimization_mode="speed")
adler32 :: proc(data: []byte, seed := u32(1)) -> u32 #no_bounds_check {
+2 -2
View File
@@ -9,8 +9,8 @@
*/
package xxhash
import "core:intrinsics"
import "core:runtime"
import "base:intrinsics"
import "base:runtime"
mem_copy :: runtime.mem_copy
byte_swap :: intrinsics.byte_swap
+1 -1
View File
@@ -10,7 +10,7 @@
package xxhash
import "core:mem"
import "core:intrinsics"
import "base:intrinsics"
/*
=== XXH3 128-bit streaming ===
+1 -1
View File
@@ -9,7 +9,7 @@
*/
package xxhash
import "core:intrinsics"
import "base:intrinsics"
/*
*************************************************************************
+1 -1
View File
@@ -9,7 +9,7 @@
*/
package xxhash
import "core:intrinsics"
import "base:intrinsics"
/*
32-bit hash functions
+1 -1
View File
@@ -9,7 +9,7 @@
*/
package xxhash
import "core:intrinsics"
import "base:intrinsics"
/*
64-bit hash functions
+1 -1
View File
@@ -13,7 +13,7 @@ package image
import "core:bytes"
import "core:mem"
import "core:compress"
import "core:runtime"
import "base:runtime"
/*
67_108_864 pixels max by default.
+1 -1
View File
@@ -8,7 +8,7 @@ import "core:mem"
import "core:strconv"
import "core:strings"
import "core:unicode"
import "core:runtime"
import "base:runtime"
Image :: image.Image
Format :: image.Netpbm_Format
+1 -1
View File
@@ -16,7 +16,7 @@ import coretime "core:time"
import "core:strings"
import "core:bytes"
import "core:mem"
import "core:runtime"
import "base:runtime"
/*
Cleanup of image-specific data.
+2 -2
View File
@@ -22,8 +22,8 @@ import "core:hash"
import "core:bytes"
import "core:io"
import "core:mem"
import "core:intrinsics"
import "core:runtime"
import "base:intrinsics"
import "base:runtime"
// Limit chunk sizes.
// By default: IDAT = 8k x 8k x 16-bits + 8k filter bytes.
-316
View File
@@ -1,316 +0,0 @@
// This is purely for documentation
//+build ignore
package intrinsics
// Package-Related
is_package_imported :: proc(package_name: string) -> bool ---
// Types
soa_struct :: proc($N: int, $T: typeid) -> type/#soa[N]T
// Volatile
volatile_load :: proc(dst: ^$T) -> T ---
volatile_store :: proc(dst: ^$T, val: T) ---
non_temporal_load :: proc(dst: ^$T) -> T ---
non_temporal_store :: proc(dst: ^$T, val: T) ---
// Trapping
debug_trap :: proc() ---
trap :: proc() -> ! ---
// Instructions
alloca :: proc(size, align: int) -> [^]u8 ---
cpu_relax :: proc() ---
read_cycle_counter :: proc() -> i64 ---
count_ones :: proc(x: $T) -> T where type_is_integer(T) || type_is_simd_vector(T) ---
count_zeros :: proc(x: $T) -> T where type_is_integer(T) || type_is_simd_vector(T) ---
count_trailing_zeros :: proc(x: $T) -> T where type_is_integer(T) || type_is_simd_vector(T) ---
count_leading_zeros :: proc(x: $T) -> T where type_is_integer(T) || type_is_simd_vector(T) ---
reverse_bits :: proc(x: $T) -> T where type_is_integer(T) || type_is_simd_vector(T) ---
byte_swap :: proc(x: $T) -> T where type_is_integer(T) || type_is_float(T) ---
overflow_add :: proc(lhs, rhs: $T) -> (T, bool) #optional_ok ---
overflow_sub :: proc(lhs, rhs: $T) -> (T, bool) #optional_ok ---
overflow_mul :: proc(lhs, rhs: $T) -> (T, bool) #optional_ok ---
sqrt :: proc(x: $T) -> T where type_is_float(T) || (type_is_simd_vector(T) && type_is_float(type_elem_type(T))) ---
fused_mul_add :: proc(a, b, c: $T) -> T where type_is_float(T) || (type_is_simd_vector(T) && type_is_float(type_elem_type(T))) ---
mem_copy :: proc(dst, src: rawptr, len: int) ---
mem_copy_non_overlapping :: proc(dst, src: rawptr, len: int) ---
mem_zero :: proc(ptr: rawptr, len: int) ---
mem_zero_volatile :: proc(ptr: rawptr, len: int) ---
// prefer [^]T operations if possible
ptr_offset :: proc(ptr: ^$T, offset: int) -> ^T ---
ptr_sub :: proc(a, b: ^$T) -> int ---
unaligned_load :: proc(src: ^$T) -> T ---
unaligned_store :: proc(dst: ^$T, val: T) -> T ---
fixed_point_mul :: proc(lhs, rhs: $T, #const scale: uint) -> T where type_is_integer(T) ---
fixed_point_div :: proc(lhs, rhs: $T, #const scale: uint) -> T where type_is_integer(T) ---
fixed_point_mul_sat :: proc(lhs, rhs: $T, #const scale: uint) -> T where type_is_integer(T) ---
fixed_point_div_sat :: proc(lhs, rhs: $T, #const scale: uint) -> T where type_is_integer(T) ---
prefetch_read_instruction :: proc(address: rawptr, #const locality: i32 /* 0..=3 */) ---
prefetch_read_data :: proc(address: rawptr, #const locality: i32 /* 0..=3 */) ---
prefetch_write_instruction :: proc(address: rawptr, #const locality: i32 /* 0..=3 */) ---
prefetch_write_data :: proc(address: rawptr, #const locality: i32 /* 0..=3 */) ---
// Compiler Hints
expect :: proc(val, expected_val: T) -> T ---
// Linux and Darwin Only
syscall :: proc(id: uintptr, args: ..uintptr) -> uintptr ---
// Atomics
Atomic_Memory_Order :: enum {
Relaxed = 0, // Unordered
Consume = 1, // Monotonic
Acquire = 2,
Release = 3,
Acq_Rel = 4,
Seq_Cst = 5,
}
atomic_type_is_lock_free :: proc($T: typeid) -> bool ---
atomic_thread_fence :: proc(order: Atomic_Memory_Order) ---
atomic_signal_fence :: proc(order: Atomic_Memory_Order) ---
atomic_store :: proc(dst: ^$T, val: T) ---
atomic_store_explicit :: proc(dst: ^$T, val: T, order: Atomic_Memory_Order) ---
atomic_load :: proc(dst: ^$T) -> T ---
atomic_load_explicit :: proc(dst: ^$T, order: Atomic_Memory_Order) -> T ---
// fetch then operator
atomic_add :: proc(dst: ^$T, val: T) -> T ---
atomic_add_explicit :: proc(dst: ^$T, val: T, order: Atomic_Memory_Order) -> T ---
atomic_sub :: proc(dst: ^$T, val: T) -> T ---
atomic_sub_explicit :: proc(dst: ^$T, val: T, order: Atomic_Memory_Order) -> T ---
atomic_and :: proc(dst: ^$T, val: T) -> T ---
atomic_and_explicit :: proc(dst: ^$T, val: T, order: Atomic_Memory_Order) -> T ---
atomic_nand :: proc(dst: ^$T, val: T) -> T ---
atomic_nand_explicit :: proc(dst: ^$T, val: T, order: Atomic_Memory_Order) -> T ---
atomic_or :: proc(dst: ^$T, val: T) -> T ---
atomic_or_explicit :: proc(dst: ^$T, val: T, order: Atomic_Memory_Order) -> T ---
atomic_xor :: proc(dst: ^$T, val: T) -> T ---
atomic_xor_explicit :: proc(dst: ^$T, val: T, order: Atomic_Memory_Order) -> T ---
atomic_exchange :: proc(dst: ^$T, val: T) -> T ---
atomic_exchange_explicit :: proc(dst: ^$T, val: T, order: Atomic_Memory_Order) -> T ---
atomic_compare_exchange_strong :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok ---
atomic_compare_exchange_strong_explicit :: proc(dst: ^$T, old, new: T, success, failure: Atomic_Memory_Order) -> (T, bool) #optional_ok ---
atomic_compare_exchange_weak :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok ---
atomic_compare_exchange_weak_explicit :: proc(dst: ^$T, old, new: T, success, failure: Atomic_Memory_Order) -> (T, bool) #optional_ok ---
// Constant type tests
type_base_type :: proc($T: typeid) -> type ---
type_core_type :: proc($T: typeid) -> type ---
type_elem_type :: proc($T: typeid) -> type ---
type_is_boolean :: proc($T: typeid) -> bool ---
type_is_integer :: proc($T: typeid) -> bool ---
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_endian_platform :: proc($T: typeid) -> bool ---
type_is_endian_little :: proc($T: typeid) -> bool ---
type_is_endian_big :: proc($T: typeid) -> bool ---
type_is_unsigned :: proc($T: typeid) -> bool ---
type_is_numeric :: proc($T: typeid) -> bool ---
type_is_ordered :: proc($T: typeid) -> bool ---
type_is_ordered_numeric :: proc($T: typeid) -> bool ---
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_dereferenceable :: proc($T: typeid) -> bool ---
type_is_valid_map_key :: proc($T: typeid) -> bool ---
type_is_valid_matrix_elements :: proc($T: typeid) -> bool ---
type_is_named :: proc($T: typeid) -> bool ---
type_is_pointer :: proc($T: typeid) -> bool ---
type_is_multi_pointer :: proc($T: typeid) -> bool ---
type_is_array :: proc($T: typeid) -> bool ---
type_is_enumerated_array :: proc($T: typeid) -> bool ---
type_is_slice :: proc($T: typeid) -> bool ---
type_is_dynamic_array :: proc($T: typeid) -> bool ---
type_is_map :: proc($T: typeid) -> bool ---
type_is_struct :: proc($T: typeid) -> bool ---
type_is_union :: proc($T: typeid) -> bool ---
type_is_enum :: proc($T: typeid) -> bool ---
type_is_proc :: proc($T: typeid) -> bool ---
type_is_bit_set :: proc($T: typeid) -> bool ---
type_is_simd_vector :: proc($T: typeid) -> bool ---
type_is_matrix :: proc($T: typeid) -> bool ---
type_has_nil :: proc($T: typeid) -> bool ---
type_is_specialization_of :: proc($T, $S: typeid) -> bool ---
type_is_variant_of :: proc($U, $V: typeid) -> bool where type_is_union(U) ---
type_union_tag_type :: proc($T: typeid) -> typeid where type_is_union(T) ---
type_union_tag_offset :: proc($T: typeid) -> uintptr where type_is_union(T) ---
type_union_base_tag_value :: proc($T: typeid) -> int where type_is_union(U) ---
type_union_variant_count :: proc($T: typeid) -> int where type_is_union(T) ---
type_variant_type_of :: proc($T: typeid, $index: int) -> typeid where type_is_union(T) ---
type_variant_index_of :: proc($U, $V: typeid) -> int where type_is_union(U) ---
type_has_field :: proc($T: typeid, $name: string) -> bool ---
type_field_type :: proc($T: typeid, $name: string) -> typeid ---
type_proc_parameter_count :: proc($T: typeid) -> int where type_is_proc(T) ---
type_proc_return_count :: proc($T: typeid) -> int where type_is_proc(T) ---
type_proc_parameter_type :: proc($T: typeid, index: int) -> typeid where type_is_proc(T) ---
type_proc_return_type :: proc($T: typeid, index: int) -> typeid where type_is_proc(T) ---
type_struct_field_count :: proc($T: typeid) -> int where type_is_struct(T) ---
type_polymorphic_record_parameter_count :: proc($T: typeid) -> typeid ---
type_polymorphic_record_parameter_value :: proc($T: typeid, index: int) -> $V ---
type_is_specialized_polymorphic_record :: proc($T: typeid) -> bool ---
type_is_unspecialized_polymorphic_record :: proc($T: typeid) -> bool ---
type_is_subtype_of :: proc($T, $U: typeid) -> bool ---
type_field_index_of :: proc($T: typeid, $name: string) -> uintptr ---
type_equal_proc :: proc($T: typeid) -> (equal: proc "contextless" (rawptr, rawptr) -> bool) where type_is_comparable(T) ---
type_hasher_proc :: proc($T: typeid) -> (hasher: proc "contextless" (data: rawptr, seed: uintptr) -> uintptr) where type_is_comparable(T) ---
type_map_info :: proc($T: typeid/map[$K]$V) -> ^runtime.Map_Info ---
type_map_cell_info :: proc($T: typeid) -> ^runtime.Map_Cell_Info ---
type_convert_variants_to_pointers :: proc($T: typeid) -> typeid where type_is_union(T) ---
type_merge :: proc($U, $V: typeid) -> typeid where type_is_union(U), type_is_union(V) ---
constant_utf16_cstring :: proc($literal: string) -> [^]u16 ---
// SIMD related
simd_add :: proc(a, b: #simd[N]T) -> #simd[N]T ---
simd_sub :: proc(a, b: #simd[N]T) -> #simd[N]T ---
simd_mul :: proc(a, b: #simd[N]T) -> #simd[N]T ---
simd_div :: proc(a, b: #simd[N]T) -> #simd[N]T where type_is_float(T) ---
// Keeps Odin's Behaviour
// (x << y) if y <= mask else 0
simd_shl :: proc(a: #simd[N]T, b: #simd[N]Unsigned_Integer) -> #simd[N]T ---
simd_shr :: proc(a: #simd[N]T, b: #simd[N]Unsigned_Integer) -> #simd[N]T ---
// Similar to C's Behaviour
// x << (y & mask)
simd_shl_masked :: proc(a: #simd[N]T, b: #simd[N]Unsigned_Integer) -> #simd[N]T ---
simd_shr_masked :: proc(a: #simd[N]T, b: #simd[N]Unsigned_Integer) -> #simd[N]T ---
simd_add_sat :: proc(a, b: #simd[N]T) -> #simd[N]T ---
simd_sub_sat :: proc(a, b: #simd[N]T) -> #simd[N]T ---
simd_bit_and :: proc(a, b: #simd[N]T) -> #simd[N]T ---
simd_bit_or :: proc(a, b: #simd[N]T) -> #simd[N]T ---
simd_bit_xor :: proc(a, b: #simd[N]T) -> #simd[N]T ---
simd_bit_and_not :: proc(a, b: #simd[N]T) -> #simd[N]T ---
simd_neg :: proc(a: #simd[N]T) -> #simd[N]T ---
simd_abs :: proc(a: #simd[N]T) -> #simd[N]T ---
simd_min :: proc(a, b: #simd[N]T) -> #simd[N]T ---
simd_max :: proc(a, b: #simd[N]T) -> #simd[N]T ---
simd_clamp :: proc(v, min, max: #simd[N]T) -> #simd[N]T ---
// Return an unsigned integer of the same size as the input type
// NOT A BOOLEAN
// element-wise:
// false => 0x00...00
// true => 0xff...ff
simd_lanes_eq :: proc(a, b: #simd[N]T) -> #simd[N]Integer ---
simd_lanes_ne :: proc(a, b: #simd[N]T) -> #simd[N]Integer ---
simd_lanes_lt :: proc(a, b: #simd[N]T) -> #simd[N]Integer ---
simd_lanes_le :: proc(a, b: #simd[N]T) -> #simd[N]Integer ---
simd_lanes_gt :: proc(a, b: #simd[N]T) -> #simd[N]Integer ---
simd_lanes_ge :: proc(a, b: #simd[N]T) -> #simd[N]Integer ---
simd_extract :: proc(a: #simd[N]T, idx: uint) -> T ---
simd_replace :: proc(a: #simd[N]T, idx: uint, elem: T) -> #simd[N]T ---
simd_reduce_add_ordered :: proc(a: #simd[N]T) -> T ---
simd_reduce_mul_ordered :: proc(a: #simd[N]T) -> T ---
simd_reduce_min :: proc(a: #simd[N]T) -> T ---
simd_reduce_max :: proc(a: #simd[N]T) -> T ---
simd_reduce_and :: proc(a: #simd[N]T) -> T ---
simd_reduce_or :: proc(a: #simd[N]T) -> T ---
simd_reduce_xor :: proc(a: #simd[N]T) -> T ---
simd_shuffle :: proc(a, b: #simd[N]T, indices: ..int) -> #simd[len(indices)]T ---
simd_select :: proc(cond: #simd[N]boolean_or_integer, true, false: #simd[N]T) -> #simd[N]T ---
// Lane-wise operations
simd_ceil :: proc(a: #simd[N]any_float) -> #simd[N]any_float ---
simd_floor :: proc(a: #simd[N]any_float) -> #simd[N]any_float ---
simd_trunc :: proc(a: #simd[N]any_float) -> #simd[N]any_float ---
// rounding to the nearest integral value; if two values are equally near, rounds to the even one
simd_nearest :: proc(a: #simd[N]any_float) -> #simd[N]any_float ---
simd_to_bits :: proc(v: #simd[N]T) -> #simd[N]Integer where size_of(T) == size_of(Integer), type_is_unsigned(Integer) ---
// equivalent a swizzle with descending indices, e.g. reserve(a, 3, 2, 1, 0)
simd_reverse :: proc(a: #simd[N]T) -> #simd[N]T ---
simd_rotate_left :: proc(a: #simd[N]T, $offset: int) -> #simd[N]T ---
simd_rotate_right :: proc(a: #simd[N]T, $offset: int) -> #simd[N]T ---
// WASM targets only
wasm_memory_grow :: proc(index, delta: uintptr) -> int ---
wasm_memory_size :: proc(index: uintptr) -> int ---
// `timeout_ns` is maximum number of nanoseconds the calling thread will be blocked for
// A negative value will be blocked forever
// Return value:
// 0 - indicates that the thread blocked and then was woken up
// 1 - the loaded value from `ptr` did not match `expected`, the thread did not block
// 2 - the thread blocked, but the timeout
wasm_memory_atomic_wait32 :: proc(ptr: ^u32, expected: u32, timeout_ns: i64) -> u32 ---
wasm_memory_atomic_notify32 :: proc(ptr: ^u32, waiters: u32) -> (waiters_woken_up: u32) ---
// x86 Targets (i386, amd64)
x86_cpuid :: proc(ax, cx: u32) -> (eax, ebx, ecx, edx: u32) ---
x86_xgetbv :: proc(cx: u32) -> (eax, edx: u32) ---
// Darwin targets only
objc_object :: struct{}
objc_selector :: struct{}
objc_class :: struct{}
objc_id :: ^objc_object
objc_SEL :: ^objc_selector
objc_Class :: ^objc_class
objc_find_selector :: proc($name: string) -> objc_SEL ---
objc_register_selector :: proc($name: string) -> objc_SEL ---
objc_find_class :: proc($name: string) -> objc_Class ---
objc_register_class :: proc($name: string) -> objc_Class ---
valgrind_client_request :: proc(default: uintptr, request: uintptr, a0, a1, a2, a3, a4: uintptr) -> uintptr ---
// Internal compiler use only
__entry_point :: proc() ---
+1 -1
View File
@@ -3,7 +3,7 @@
// operations into an abstracted stream interface.
package io
import "core:intrinsics"
import "base:intrinsics"
import "core:unicode/utf8"
// Seek whence values
+1
View File
@@ -1,3 +1,4 @@
//+build !freestanding
package log
import "core:fmt"
+1 -1
View File
@@ -1,6 +1,6 @@
package log
import "core:runtime"
import "base:runtime"
import "core:fmt"
+1 -1
View File
@@ -1,6 +1,6 @@
package log
import "core:runtime"
import "base:runtime"
import "core:fmt"
Log_Allocator_Format :: enum {
+1 -1
View File
@@ -6,7 +6,7 @@
package math_big
import "core:intrinsics"
import "base:intrinsics"
/*
TODO: Make the tunables runtime adjustable where practical.
+1 -1
View File
@@ -6,7 +6,7 @@
package math_big
import "core:intrinsics"
import "base:intrinsics"
import rnd "core:math/rand"
/*
+2 -2
View File
@@ -28,9 +28,9 @@
package math_big
import "core:mem"
import "core:intrinsics"
import "base:intrinsics"
import rnd "core:math/rand"
import "core:builtin"
import "base:builtin"
/*
Low-level addition, unsigned. Handbook of Applied Cryptography, algorithm 14.7.
+1 -1
View File
@@ -19,7 +19,7 @@
package math_big
import "core:intrinsics"
import "base:intrinsics"
import "core:mem"
/*
+1 -1
View File
@@ -12,7 +12,7 @@
package math_big
import "core:intrinsics"
import "base:intrinsics"
/*
===========================
+1 -1
View File
@@ -16,7 +16,7 @@
package math_big
import "core:intrinsics"
import "base:intrinsics"
import "core:mem"
import "core:os"
+2 -2
View File
@@ -1,7 +1,7 @@
package math_big
import "core:builtin"
import "core:intrinsics"
import "base:builtin"
import "base:intrinsics"
import "core:math"
Rat :: struct {
+1 -1
View File
@@ -11,7 +11,7 @@
package math_big
import "core:time"
import "core:runtime"
import "base:runtime"
print_value :: proc(name: string, value: i64) {
runtime.print_string("\t")
+1 -1
View File
@@ -1,6 +1,6 @@
package math_bits
import "core:intrinsics"
import "base:intrinsics"
U8_MIN :: 0
U16_MIN :: 0
+1 -1
View File
@@ -1,6 +1,6 @@
package math_cmplx
import "core:builtin"
import "base:builtin"
import "core:math"
// The original C code, the long comment, and the constants
+1 -1
View File
@@ -1,6 +1,6 @@
package math_cmplx
import "core:builtin"
import "base:builtin"
import "core:math"
// The original C code, the long comment, and the constants
+1 -1
View File
@@ -2,7 +2,7 @@
package ease
import "core:math"
import "core:intrinsics"
import "base:intrinsics"
import "core:time"
@(private) PI_2 :: math.PI / 2
+1 -1
View File
@@ -2,7 +2,7 @@ package math_fixed
import "core:math"
import "core:strconv"
import "core:intrinsics"
import "base:intrinsics"
_, _, _ :: intrinsics, strconv, math
Fixed :: struct($Backing: typeid, $Fraction_Width: uint)
+1 -1
View File
@@ -1,6 +1,6 @@
package linalg
import "core:builtin"
import "base:builtin"
import "core:math"
@(require_results)
+274 -5
View File
@@ -1,8 +1,8 @@
package linalg
import "core:math"
import "core:builtin"
import "core:intrinsics"
import "base:builtin"
import "base:intrinsics"
// Generic
@@ -66,7 +66,7 @@ quaternion256_dot :: proc "contextless" (a, b: $T/quaternion256) -> (c: f64) {
dot :: proc{scalar_dot, vector_dot, quaternion64_dot, quaternion128_dot, quaternion256_dot}
inner_product :: dot
outer_product :: builtin.outer_product
outer_product :: intrinsics.outer_product
@(require_results)
quaternion_inverse :: proc "contextless" (q: $Q) -> Q where IS_QUATERNION(Q) {
@@ -179,8 +179,7 @@ identity :: proc "contextless" ($T: typeid/[$N][N]$E) -> (m: T) #no_bounds_check
return m
}
trace :: builtin.matrix_trace
transpose :: builtin.transpose
transpose :: intrinsics.transpose
@(require_results)
matrix_mul :: proc "contextless" (a, b: $M/matrix[$N, N]$E) -> (c: M)
@@ -355,3 +354,273 @@ matrix_cast :: proc "contextless" (v: $A/matrix[$M, $N]$T, $Elem_Type: typeid) -
@(require_results) to_quaternion64 :: #force_inline proc(v: $A/[$N]$T) -> [N]quaternion64 { return array_cast(v, quaternion64) }
@(require_results) to_quaternion128 :: #force_inline proc(v: $A/[$N]$T) -> [N]quaternion128 { return array_cast(v, quaternion128) }
@(require_results) to_quaternion256 :: #force_inline proc(v: $A/[$N]$T) -> [N]quaternion256 { return array_cast(v, quaternion256) }
hadamard_product :: intrinsics.hadamard_product
matrix_flatten :: intrinsics.matrix_flatten
determinant :: proc{
matrix1x1_determinant,
matrix2x2_determinant,
matrix3x3_determinant,
matrix4x4_determinant,
}
adjugate :: proc{
matrix1x1_adjugate,
matrix2x2_adjugate,
matrix3x3_adjugate,
matrix4x4_adjugate,
}
inverse_transpose :: proc{
matrix1x1_inverse_transpose,
matrix2x2_inverse_transpose,
matrix3x3_inverse_transpose,
matrix4x4_inverse_transpose,
}
inverse :: proc{
matrix1x1_inverse,
matrix2x2_inverse,
matrix3x3_inverse,
matrix4x4_inverse,
}
@(require_results)
hermitian_adjoint :: proc "contextless" (m: $M/matrix[$N, N]$T) -> M where intrinsics.type_is_complex(T), N >= 1 {
return conj(transpose(m))
}
@(require_results)
trace :: proc "contextless" (m: $M/matrix[$N, N]$T) -> (trace: T) {
for i in 0..<N {
trace += m[i, i]
}
return
}
@(require_results)
matrix_minor :: proc "contextless" (m: $M/matrix[$N, N]$T, #any_int row, column: int) -> (minor: T) where N > 1 {
K :: int(N-1)
cut_down: matrix[K, K]T
for col_idx in 0..<K {
j := col_idx + int(col_idx >= column)
for row_idx in 0..<K {
i := row_idx + int(row_idx >= row)
cut_down[row_idx, col_idx] = m[i, j]
}
}
return determinant(cut_down)
}
@(require_results)
matrix1x1_determinant :: proc "contextless" (m: $M/matrix[1, 1]$T) -> (det: T) {
return m[0, 0]
}
@(require_results)
matrix2x2_determinant :: proc "contextless" (m: $M/matrix[2, 2]$T) -> (det: T) {
return m[0, 0]*m[1, 1] - m[0, 1]*m[1, 0]
}
@(require_results)
matrix3x3_determinant :: proc "contextless" (m: $M/matrix[3, 3]$T) -> (det: T) {
a := +m[0, 0] * (m[1, 1] * m[2, 2] - m[1, 2] * m[2, 1])
b := -m[0, 1] * (m[1, 0] * m[2, 2] - m[1, 2] * m[2, 0])
c := +m[0, 2] * (m[1, 0] * m[2, 1] - m[1, 1] * m[2, 0])
return a + b + c
}
@(require_results)
matrix4x4_determinant :: proc "contextless" (m: $M/matrix[4, 4]$T) -> (det: T) {
a := adjugate(m)
#no_bounds_check for i in 0..<4 {
det += m[0, i] * a[0, i]
}
return
}
@(require_results)
matrix1x1_adjugate :: proc "contextless" (x: $M/matrix[1, 1]$T) -> (y: M) {
y = x
return
}
@(require_results)
matrix2x2_adjugate :: proc "contextless" (x: $M/matrix[2, 2]$T) -> (y: M) {
y[0, 0] = +x[1, 1]
y[0, 1] = -x[1, 0]
y[1, 0] = -x[0, 1]
y[1, 1] = +x[0, 0]
return
}
@(require_results)
matrix3x3_adjugate :: proc "contextless" (m: $M/matrix[3, 3]$T) -> (y: M) {
y[0, 0] = +(m[1, 1] * m[2, 2] - m[2, 1] * m[1, 2])
y[0, 1] = -(m[1, 0] * m[2, 2] - m[2, 0] * m[1, 2])
y[0, 2] = +(m[1, 0] * m[2, 1] - m[2, 0] * m[1, 1])
y[1, 0] = -(m[0, 1] * m[2, 2] - m[2, 1] * m[0, 2])
y[1, 1] = +(m[0, 0] * m[2, 2] - m[2, 0] * m[0, 2])
y[1, 2] = -(m[0, 0] * m[2, 1] - m[2, 0] * m[0, 1])
y[2, 0] = +(m[0, 1] * m[1, 2] - m[1, 1] * m[0, 2])
y[2, 1] = -(m[0, 0] * m[1, 2] - m[1, 0] * m[0, 2])
y[2, 2] = +(m[0, 0] * m[1, 1] - m[1, 0] * m[0, 1])
return
}
@(require_results)
matrix4x4_adjugate :: proc "contextless" (x: $M/matrix[4, 4]$T) -> (y: M) {
for i in 0..<4 {
for j in 0..<4 {
sign: T = 1 if (i + j) % 2 == 0 else -1
y[i, j] = sign * matrix_minor(x, i, j)
}
}
return
}
@(require_results)
matrix1x1_inverse_transpose :: proc "contextless" (x: $M/matrix[1, 1]$T) -> (y: M) {
y[0, 0] = 1/x[0, 0]
return
}
@(require_results)
matrix2x2_inverse_transpose :: proc "contextless" (x: $M/matrix[2, 2]$T) -> (y: M) {
d := x[0, 0]*x[1, 1] - x[0, 1]*x[1, 0]
when intrinsics.type_is_integer(T) {
y[0, 0] = +x[1, 1] / d
y[1, 0] = -x[0, 1] / d
y[0, 1] = -x[1, 0] / d
y[1, 1] = +x[0, 0] / d
} else {
id := 1 / d
y[0, 0] = +x[1, 1] * id
y[1, 0] = -x[0, 1] * id
y[0, 1] = -x[1, 0] * id
y[1, 1] = +x[0, 0] * id
}
return
}
@(require_results)
matrix3x3_inverse_transpose :: proc "contextless" (x: $M/matrix[3, 3]$T) -> (y: M) #no_bounds_check {
a := adjugate(x)
d := determinant(x)
when intrinsics.type_is_integer(T) {
for i in 0..<3 {
for j in 0..<3 {
y[i, j] = a[i, j] / d
}
}
} else {
id := 1/d
for i in 0..<3 {
for j in 0..<3 {
y[i, j] = a[i, j] * id
}
}
}
return
}
@(require_results)
matrix4x4_inverse_transpose :: proc "contextless" (x: $M/matrix[4, 4]$T) -> (y: M) #no_bounds_check {
a := adjugate(x)
d: T
for i in 0..<4 {
d += x[0, i] * a[0, i]
}
when intrinsics.type_is_integer(T) {
for i in 0..<4 {
for j in 0..<4 {
y[i, j] = a[i, j] / d
}
}
} else {
id := 1/d
for i in 0..<4 {
for j in 0..<4 {
y[i, j] = a[i, j] * id
}
}
}
return
}
@(require_results)
matrix1x1_inverse :: proc "contextless" (x: $M/matrix[1, 1]$T) -> (y: M) {
y[0, 0] = 1/x[0, 0]
return
}
@(require_results)
matrix2x2_inverse :: proc "contextless" (x: $M/matrix[2, 2]$T) -> (y: M) {
d := x[0, 0]*x[1, 1] - x[0, 1]*x[1, 0]
when intrinsics.type_is_integer(T) {
y[0, 0] = +x[1, 1] / d
y[0, 1] = -x[0, 1] / d
y[1, 0] = -x[1, 0] / d
y[1, 1] = +x[0, 0] / d
} else {
id := 1 / d
y[0, 0] = +x[1, 1] * id
y[0, 1] = -x[0, 1] * id
y[1, 0] = -x[1, 0] * id
y[1, 1] = +x[0, 0] * id
}
return
}
@(require_results)
matrix3x3_inverse :: proc "contextless" (x: $M/matrix[3, 3]$T) -> (y: M) #no_bounds_check {
a := adjugate(x)
d := determinant(x)
when intrinsics.type_is_integer(T) {
for i in 0..<3 {
for j in 0..<3 {
y[i, j] = a[j, i] / d
}
}
} else {
id := 1/d
for i in 0..<3 {
for j in 0..<3 {
y[i, j] = a[j, i] * id
}
}
}
return
}
@(require_results)
matrix4x4_inverse :: proc "contextless" (x: $M/matrix[4, 4]$T) -> (y: M) #no_bounds_check {
a := adjugate(x)
d: T
for i in 0..<4 {
d += x[0, i] * a[0, i]
}
when intrinsics.type_is_integer(T) {
for i in 0..<4 {
for j in 0..<4 {
y[i, j] = a[j, i] / d
}
}
} else {
id := 1/d
for i in 0..<4 {
for j in 0..<4 {
y[i, j] = a[j, i] * id
}
}
}
return
}
+274 -22
View File
@@ -1,7 +1,8 @@
// core:math/linalg/glsl implements a GLSL-like mathematics library plus numerous other utility procedures
package math_linalg_glsl
import "core:builtin"
import "base:builtin"
import "base:intrinsics"
TAU :: 6.28318530717958647692528676655900576
PI :: 3.14159265358979323846264338327950288
@@ -1838,30 +1839,281 @@ dquatMulDvec3 :: proc "c" (q: dquat, v: dvec3) -> dvec3 {
@(require_results) inverse_mat2 :: proc "c" (m: mat2) -> mat2 { return builtin.inverse(m) }
@(require_results) inverse_mat3 :: proc "c" (m: mat3) -> mat3 { return builtin.inverse(m) }
@(require_results) inverse_mat4 :: proc "c" (m: mat4) -> mat4 { return builtin.inverse(m) }
@(require_results) inverse_dmat2 :: proc "c" (m: dmat2) -> dmat2 { return builtin.inverse(m) }
@(require_results) inverse_dmat3 :: proc "c" (m: dmat3) -> dmat3 { return builtin.inverse(m) }
@(require_results) inverse_dmat4 :: proc "c" (m: dmat4) -> dmat4 { return builtin.inverse(m) }
@(require_results) inverse_mat2 :: proc "c" (m: mat2) -> mat2 { return inverse_matrix2x2(m) }
@(require_results) inverse_mat3 :: proc "c" (m: mat3) -> mat3 { return inverse_matrix3x3(m) }
@(require_results) inverse_mat4 :: proc "c" (m: mat4) -> mat4 { return inverse_matrix4x4(m) }
@(require_results) inverse_dmat2 :: proc "c" (m: dmat2) -> dmat2 { return inverse_matrix2x2(m) }
@(require_results) inverse_dmat3 :: proc "c" (m: dmat3) -> dmat3 { return inverse_matrix3x3(m) }
@(require_results) inverse_dmat4 :: proc "c" (m: dmat4) -> dmat4 { return inverse_matrix4x4(m) }
@(require_results) inverse_quat :: proc "c" (q: quat) -> quat { return 1/q }
@(require_results) inverse_dquat :: proc "c" (q: dquat) -> dquat { return 1/q }
transpose :: intrinsics.transpose
determinant :: proc{
determinant_matrix1x1,
determinant_matrix2x2,
determinant_matrix3x3,
determinant_matrix4x4,
}
adjugate :: proc{
adjugate_matrix1x1,
adjugate_matrix2x2,
adjugate_matrix3x3,
adjugate_matrix4x4,
}
inverse_transpose :: proc{
inverse_transpose_matrix1x1,
inverse_transpose_matrix2x2,
inverse_transpose_matrix3x3,
inverse_transpose_matrix4x4,
}
inverse :: proc{
inverse_mat2,
inverse_mat3,
inverse_mat4,
inverse_dmat2,
inverse_dmat3,
inverse_dmat4,
inverse_quat,
inverse_dquat,
inverse_matrix1x1,
inverse_matrix2x2,
inverse_matrix3x3,
inverse_matrix4x4,
}
@(require_results)
hermitian_adjoint :: proc "contextless" (m: $M/matrix[$N, N]$T) -> M where intrinsics.type_is_complex(T), N >= 1 {
return conj(transpose(m))
}
@(require_results)
trace :: proc "contextless" (m: $M/matrix[$N, N]$T) -> (trace: T) {
for i in 0..<N {
trace += m[i, i]
}
return
}
@(require_results)
matrix_minor :: proc "contextless" (m: $M/matrix[$N, N]$T, #any_int row, column: int) -> (minor: T) where N > 1 {
K :: int(N-1)
cut_down: matrix[K, K]T
for col_idx in 0..<K {
j := col_idx + int(col_idx >= column)
for row_idx in 0..<K {
i := row_idx + int(row_idx >= row)
cut_down[row_idx, col_idx] = m[i, j]
}
}
return determinant(cut_down)
}
@(require_results)
determinant_matrix1x1 :: proc "contextless" (m: $M/matrix[1, 1]$T) -> (det: T) {
return m[0, 0]
}
@(require_results)
determinant_matrix2x2 :: proc "contextless" (m: $M/matrix[2, 2]$T) -> (det: T) {
return m[0, 0]*m[1, 1] - m[0, 1]*m[1, 0]
}
@(require_results)
determinant_matrix3x3 :: proc "contextless" (m: $M/matrix[3, 3]$T) -> (det: T) {
a := +m[0, 0] * (m[1, 1] * m[2, 2] - m[1, 2] * m[2, 1])
b := -m[0, 1] * (m[1, 0] * m[2, 2] - m[1, 2] * m[2, 0])
c := +m[0, 2] * (m[1, 0] * m[2, 1] - m[1, 1] * m[2, 0])
return a + b + c
}
@(require_results)
determinant_matrix4x4 :: proc "contextless" (m: $M/matrix[4, 4]$T) -> (det: T) {
a := adjugate(m)
#no_bounds_check for i in 0..<4 {
det += m[0, i] * a[0, i]
}
return
}
@(require_results)
adjugate_matrix1x1 :: proc "contextless" (x: $M/matrix[1, 1]$T) -> (y: M) {
y = x
return
}
@(require_results)
adjugate_matrix2x2 :: proc "contextless" (x: $M/matrix[2, 2]$T) -> (y: M) {
y[0, 0] = +x[1, 1]
y[0, 1] = -x[1, 0]
y[1, 0] = -x[0, 1]
y[1, 1] = +x[0, 0]
return
}
@(require_results)
adjugate_matrix3x3 :: proc "contextless" (m: $M/matrix[3, 3]$T) -> (y: M) {
y[0, 0] = +(m[1, 1] * m[2, 2] - m[2, 1] * m[1, 2])
y[0, 1] = -(m[1, 0] * m[2, 2] - m[2, 0] * m[1, 2])
y[0, 2] = +(m[1, 0] * m[2, 1] - m[2, 0] * m[1, 1])
y[1, 0] = -(m[0, 1] * m[2, 2] - m[2, 1] * m[0, 2])
y[1, 1] = +(m[0, 0] * m[2, 2] - m[2, 0] * m[0, 2])
y[1, 2] = -(m[0, 0] * m[2, 1] - m[2, 0] * m[0, 1])
y[2, 0] = +(m[0, 1] * m[1, 2] - m[1, 1] * m[0, 2])
y[2, 1] = -(m[0, 0] * m[1, 2] - m[1, 0] * m[0, 2])
y[2, 2] = +(m[0, 0] * m[1, 1] - m[1, 0] * m[0, 1])
return
}
@(require_results)
adjugate_matrix4x4 :: proc "contextless" (x: $M/matrix[4, 4]$T) -> (y: M) {
for i in 0..<4 {
for j in 0..<4 {
sign: T = 1 if (i + j) % 2 == 0 else -1
y[i, j] = sign * matrix_minor(x, i, j)
}
}
return
}
@(require_results)
inverse_transpose_matrix1x1 :: proc "contextless" (x: $M/matrix[1, 1]$T) -> (y: M) {
y[0, 0] = 1/x[0, 0]
return
}
@(require_results)
inverse_transpose_matrix2x2 :: proc "contextless" (x: $M/matrix[2, 2]$T) -> (y: M) {
d := x[0, 0]*x[1, 1] - x[0, 1]*x[1, 0]
when intrinsics.type_is_integer(T) {
y[0, 0] = +x[1, 1] / d
y[1, 0] = -x[0, 1] / d
y[0, 1] = -x[1, 0] / d
y[1, 1] = +x[0, 0] / d
} else {
id := 1 / d
y[0, 0] = +x[1, 1] * id
y[1, 0] = -x[0, 1] * id
y[0, 1] = -x[1, 0] * id
y[1, 1] = +x[0, 0] * id
}
return
}
@(require_results)
inverse_transpose_matrix3x3 :: proc "contextless" (x: $M/matrix[3, 3]$T) -> (y: M) #no_bounds_check {
a := adjugate(x)
d := determinant(x)
when intrinsics.type_is_integer(T) {
for i in 0..<3 {
for j in 0..<3 {
y[i, j] = a[i, j] / d
}
}
} else {
id := 1/d
for i in 0..<3 {
for j in 0..<3 {
y[i, j] = a[i, j] * id
}
}
}
return
}
@(require_results)
inverse_transpose_matrix4x4 :: proc "contextless" (x: $M/matrix[4, 4]$T) -> (y: M) #no_bounds_check {
a := adjugate(x)
d: T
for i in 0..<4 {
d += x[0, i] * a[0, i]
}
when intrinsics.type_is_integer(T) {
for i in 0..<4 {
for j in 0..<4 {
y[i, j] = a[i, j] / d
}
}
} else {
id := 1/d
for i in 0..<4 {
for j in 0..<4 {
y[i, j] = a[i, j] * id
}
}
}
return
}
@(require_results)
inverse_matrix1x1 :: proc "contextless" (x: $M/matrix[1, 1]$T) -> (y: M) {
y[0, 0] = 1/x[0, 0]
return
}
@(require_results)
inverse_matrix2x2 :: proc "contextless" (x: $M/matrix[2, 2]$T) -> (y: M) {
d := x[0, 0]*x[1, 1] - x[0, 1]*x[1, 0]
when intrinsics.type_is_integer(T) {
y[0, 0] = +x[1, 1] / d
y[0, 1] = -x[0, 1] / d
y[1, 0] = -x[1, 0] / d
y[1, 1] = +x[0, 0] / d
} else {
id := 1 / d
y[0, 0] = +x[1, 1] * id
y[0, 1] = -x[0, 1] * id
y[1, 0] = -x[1, 0] * id
y[1, 1] = +x[0, 0] * id
}
return
}
@(require_results)
inverse_matrix3x3 :: proc "contextless" (x: $M/matrix[3, 3]$T) -> (y: M) #no_bounds_check {
a := adjugate(x)
d := determinant(x)
when intrinsics.type_is_integer(T) {
for i in 0..<3 {
for j in 0..<3 {
y[i, j] = a[j, i] / d
}
}
} else {
id := 1/d
for i in 0..<3 {
for j in 0..<3 {
y[i, j] = a[j, i] * id
}
}
}
return
}
@(require_results)
inverse_matrix4x4 :: proc "contextless" (x: $M/matrix[4, 4]$T) -> (y: M) #no_bounds_check {
a := adjugate(x)
d: T
for i in 0..<4 {
d += x[0, i] * a[0, i]
}
when intrinsics.type_is_integer(T) {
for i in 0..<4 {
for j in 0..<4 {
y[i, j] = a[j, i] / d
}
}
} else {
id := 1/d
for i in 0..<4 {
for j in 0..<4 {
y[i, j] = a[j, i] * id
}
}
}
return
}
transpose :: builtin.transpose
inverse_transpose :: builtin.inverse_transpose
adjugate :: builtin.adjugate
hermitian_adjoint :: builtin.hermitian_adjoint
minor :: builtin.matrix_minor
determinant :: builtin.determinant
trace :: builtin.matrix_trace
+277 -16
View File
@@ -1,7 +1,8 @@
// core:math/linalg/hlsl implements a HLSL-like mathematics library plus numerous other utility procedures
package math_linalg_hlsl
import "core:builtin"
import "base:builtin"
import "base:intrinsics"
TAU :: 6.28318530717958647692528676655900576
PI :: 3.14159265358979323846264338327950288
@@ -1471,14 +1472,14 @@ not :: proc{
@(require_results) inverse_float1x1 :: proc "c" (m: float1x1) -> float1x1 { return builtin.inverse(m) }
@(require_results) inverse_float2x2 :: proc "c" (m: float2x2) -> float2x2 { return builtin.inverse(m) }
@(require_results) inverse_float3x3 :: proc "c" (m: float3x3) -> float3x3 { return builtin.inverse(m) }
@(require_results) inverse_float4x4 :: proc "c" (m: float4x4) -> float4x4 { return builtin.inverse(m) }
@(require_results) inverse_double1x1 :: proc "c" (m: double1x1) -> double1x1 { return builtin.inverse(m) }
@(require_results) inverse_double2x2 :: proc "c" (m: double2x2) -> double2x2 { return builtin.inverse(m) }
@(require_results) inverse_double3x3 :: proc "c" (m: double3x3) -> double3x3 { return builtin.inverse(m) }
@(require_results) inverse_double4x4 :: proc "c" (m: double4x4) -> double4x4 { return builtin.inverse(m) }
@(require_results) inverse_float1x1 :: proc "c" (m: float1x1) -> float1x1 { return inverse_matrix1x1(m) }
@(require_results) inverse_float2x2 :: proc "c" (m: float2x2) -> float2x2 { return inverse_matrix2x2(m) }
@(require_results) inverse_float3x3 :: proc "c" (m: float3x3) -> float3x3 { return inverse_matrix3x3(m) }
@(require_results) inverse_float4x4 :: proc "c" (m: float4x4) -> float4x4 { return inverse_matrix4x4(m) }
@(require_results) inverse_double1x1 :: proc "c" (m: double1x1) -> double1x1 { return inverse_matrix1x1(m) }
@(require_results) inverse_double2x2 :: proc "c" (m: double2x2) -> double2x2 { return inverse_matrix2x2(m) }
@(require_results) inverse_double3x3 :: proc "c" (m: double3x3) -> double3x3 { return inverse_matrix3x3(m) }
@(require_results) inverse_double4x4 :: proc "c" (m: double4x4) -> double4x4 { return inverse_matrix4x4(m) }
inverse :: proc{
inverse_float1x1,
@@ -1489,15 +1490,275 @@ inverse :: proc{
inverse_double2x2,
inverse_double3x3,
inverse_double4x4,
inverse_matrix1x1,
inverse_matrix2x2,
inverse_matrix3x3,
inverse_matrix4x4,
}
transpose :: builtin.transpose
inverse_transpose :: builtin.inverse_transpose
adjugate :: builtin.adjugate
hermitian_adjoint :: builtin.hermitian_adjoint
minor :: builtin.matrix_minor
determinant :: builtin.determinant
trace :: builtin.matrix_trace
transpose :: intrinsics.transpose
determinant :: proc{
determinant_matrix1x1,
determinant_matrix2x2,
determinant_matrix3x3,
determinant_matrix4x4,
}
adjugate :: proc{
adjugate_matrix1x1,
adjugate_matrix2x2,
adjugate_matrix3x3,
adjugate_matrix4x4,
}
inverse_transpose :: proc{
inverse_transpose_matrix1x1,
inverse_transpose_matrix2x2,
inverse_transpose_matrix3x3,
inverse_transpose_matrix4x4,
}
@(require_results)
hermitian_adjoint :: proc "contextless" (m: $M/matrix[$N, N]$T) -> M where intrinsics.type_is_complex(T), N >= 1 {
return conj(transpose(m))
}
@(require_results)
trace :: proc "contextless" (m: $M/matrix[$N, N]$T) -> (trace: T) {
for i in 0..<N {
trace += m[i, i]
}
return
}
@(require_results)
matrix_minor :: proc "contextless" (m: $M/matrix[$N, N]$T, #any_int row, column: int) -> (minor: T) where N > 1 {
K :: int(N-1)
cut_down: matrix[K, K]T
for col_idx in 0..<K {
j := col_idx + int(col_idx >= column)
for row_idx in 0..<K {
i := row_idx + int(row_idx >= row)
cut_down[row_idx, col_idx] = m[i, j]
}
}
return determinant(cut_down)
}
@(require_results)
determinant_matrix1x1 :: proc "contextless" (m: $M/matrix[1, 1]$T) -> (det: T) {
return m[0, 0]
}
@(require_results)
determinant_matrix2x2 :: proc "contextless" (m: $M/matrix[2, 2]$T) -> (det: T) {
return m[0, 0]*m[1, 1] - m[0, 1]*m[1, 0]
}
@(require_results)
determinant_matrix3x3 :: proc "contextless" (m: $M/matrix[3, 3]$T) -> (det: T) {
a := +m[0, 0] * (m[1, 1] * m[2, 2] - m[1, 2] * m[2, 1])
b := -m[0, 1] * (m[1, 0] * m[2, 2] - m[1, 2] * m[2, 0])
c := +m[0, 2] * (m[1, 0] * m[2, 1] - m[1, 1] * m[2, 0])
return a + b + c
}
@(require_results)
determinant_matrix4x4 :: proc "contextless" (m: $M/matrix[4, 4]$T) -> (det: T) {
a := adjugate(m)
#no_bounds_check for i in 0..<4 {
det += m[0, i] * a[0, i]
}
return
}
@(require_results)
adjugate_matrix1x1 :: proc "contextless" (x: $M/matrix[1, 1]$T) -> (y: M) {
y = x
return
}
@(require_results)
adjugate_matrix2x2 :: proc "contextless" (x: $M/matrix[2, 2]$T) -> (y: M) {
y[0, 0] = +x[1, 1]
y[0, 1] = -x[1, 0]
y[1, 0] = -x[0, 1]
y[1, 1] = +x[0, 0]
return
}
@(require_results)
adjugate_matrix3x3 :: proc "contextless" (m: $M/matrix[3, 3]$T) -> (y: M) {
y[0, 0] = +(m[1, 1] * m[2, 2] - m[2, 1] * m[1, 2])
y[0, 1] = -(m[1, 0] * m[2, 2] - m[2, 0] * m[1, 2])
y[0, 2] = +(m[1, 0] * m[2, 1] - m[2, 0] * m[1, 1])
y[1, 0] = -(m[0, 1] * m[2, 2] - m[2, 1] * m[0, 2])
y[1, 1] = +(m[0, 0] * m[2, 2] - m[2, 0] * m[0, 2])
y[1, 2] = -(m[0, 0] * m[2, 1] - m[2, 0] * m[0, 1])
y[2, 0] = +(m[0, 1] * m[1, 2] - m[1, 1] * m[0, 2])
y[2, 1] = -(m[0, 0] * m[1, 2] - m[1, 0] * m[0, 2])
y[2, 2] = +(m[0, 0] * m[1, 1] - m[1, 0] * m[0, 1])
return
}
@(require_results)
adjugate_matrix4x4 :: proc "contextless" (x: $M/matrix[4, 4]$T) -> (y: M) {
for i in 0..<4 {
for j in 0..<4 {
sign: T = 1 if (i + j) % 2 == 0 else -1
y[i, j] = sign * matrix_minor(x, i, j)
}
}
return
}
@(require_results)
inverse_transpose_matrix1x1 :: proc "contextless" (x: $M/matrix[1, 1]$T) -> (y: M) {
y[0, 0] = 1/x[0, 0]
return
}
@(require_results)
inverse_transpose_matrix2x2 :: proc "contextless" (x: $M/matrix[2, 2]$T) -> (y: M) {
d := x[0, 0]*x[1, 1] - x[0, 1]*x[1, 0]
when intrinsics.type_is_integer(T) {
y[0, 0] = +x[1, 1] / d
y[1, 0] = -x[0, 1] / d
y[0, 1] = -x[1, 0] / d
y[1, 1] = +x[0, 0] / d
} else {
id := 1 / d
y[0, 0] = +x[1, 1] * id
y[1, 0] = -x[0, 1] * id
y[0, 1] = -x[1, 0] * id
y[1, 1] = +x[0, 0] * id
}
return
}
@(require_results)
inverse_transpose_matrix3x3 :: proc "contextless" (x: $M/matrix[3, 3]$T) -> (y: M) #no_bounds_check {
a := adjugate(x)
d := determinant(x)
when intrinsics.type_is_integer(T) {
for i in 0..<3 {
for j in 0..<3 {
y[i, j] = a[i, j] / d
}
}
} else {
id := 1/d
for i in 0..<3 {
for j in 0..<3 {
y[i, j] = a[i, j] * id
}
}
}
return
}
@(require_results)
inverse_transpose_matrix4x4 :: proc "contextless" (x: $M/matrix[4, 4]$T) -> (y: M) #no_bounds_check {
a := adjugate(x)
d: T
for i in 0..<4 {
d += x[0, i] * a[0, i]
}
when intrinsics.type_is_integer(T) {
for i in 0..<4 {
for j in 0..<4 {
y[i, j] = a[i, j] / d
}
}
} else {
id := 1/d
for i in 0..<4 {
for j in 0..<4 {
y[i, j] = a[i, j] * id
}
}
}
return
}
@(require_results)
inverse_matrix1x1 :: proc "contextless" (x: $M/matrix[1, 1]$T) -> (y: M) {
y[0, 0] = 1/x[0, 0]
return
}
@(require_results)
inverse_matrix2x2 :: proc "contextless" (x: $M/matrix[2, 2]$T) -> (y: M) {
d := x[0, 0]*x[1, 1] - x[0, 1]*x[1, 0]
when intrinsics.type_is_integer(T) {
y[0, 0] = +x[1, 1] / d
y[0, 1] = -x[0, 1] / d
y[1, 0] = -x[1, 0] / d
y[1, 1] = +x[0, 0] / d
} else {
id := 1 / d
y[0, 0] = +x[1, 1] * id
y[0, 1] = -x[0, 1] * id
y[1, 0] = -x[1, 0] * id
y[1, 1] = +x[0, 0] * id
}
return
}
@(require_results)
inverse_matrix3x3 :: proc "contextless" (x: $M/matrix[3, 3]$T) -> (y: M) #no_bounds_check {
a := adjugate(x)
d := determinant(x)
when intrinsics.type_is_integer(T) {
for i in 0..<3 {
for j in 0..<3 {
y[i, j] = a[j, i] / d
}
}
} else {
id := 1/d
for i in 0..<3 {
for j in 0..<3 {
y[i, j] = a[j, i] * id
}
}
}
return
}
@(require_results)
inverse_matrix4x4 :: proc "contextless" (x: $M/matrix[4, 4]$T) -> (y: M) #no_bounds_check {
a := adjugate(x)
d: T
for i in 0..<4 {
d += x[0, i] * a[0, i]
}
when intrinsics.type_is_integer(T) {
for i in 0..<4 {
for j in 0..<4 {
y[i, j] = a[j, i] / d
}
}
} else {
id := 1/d
for i in 0..<4 {
for j in 0..<4 {
y[i, j] = a[j, i] * id
}
}
}
return
}
asfloat :: proc{
asfloat_float,
+7 -7
View File
@@ -1,6 +1,6 @@
package linalg
import "core:builtin"
import "base:builtin"
import "core:math"
F16_EPSILON :: 1e-3
@@ -1447,16 +1447,16 @@ matrix3_adjoint :: proc{
@(require_results)
matrix3_inverse_transpose_f16 :: proc "contextless" (m: Matrix3f16) -> (inverse_transpose: Matrix3f16) {
return builtin.inverse_transpose(m)
matrix3_inverse_transpose_f16 :: proc "contextless" (m: Matrix3f16) -> (p: Matrix3f16) {
return inverse_transpose(m)
}
@(require_results)
matrix3_inverse_transpose_f32 :: proc "contextless" (m: Matrix3f32) -> (inverse_transpose: Matrix3f32) {
return builtin.inverse_transpose(m)
matrix3_inverse_transpose_f32 :: proc "contextless" (m: Matrix3f32) -> (p: Matrix3f32) {
return inverse_transpose(m)
}
@(require_results)
matrix3_inverse_transpose_f64 :: proc "contextless" (m: Matrix3f64) -> (inverse_transpose: Matrix3f64) {
return builtin.inverse_transpose(m)
matrix3_inverse_transpose_f64 :: proc "contextless" (m: Matrix3f64) -> (p: Matrix3f64) {
return inverse_transpose(m)
}
matrix3_inverse_transpose :: proc{
matrix3_inverse_transpose_f16,
+2 -2
View File
@@ -1,7 +1,7 @@
package math
import "core:intrinsics"
import "core:builtin"
import "base:intrinsics"
import "base:builtin"
_ :: intrinsics
Float_Class :: enum {
+1 -1
View File
@@ -1,7 +1,7 @@
//+build !js
package math
import "core:intrinsics"
import "base:intrinsics"
@(default_calling_convention="none", private="file")
foreign _ {
+1 -1
View File
@@ -1,7 +1,7 @@
//+build js
package math
import "core:intrinsics"
import "base:intrinsics"
foreign import "odin_env"
+1 -1
View File
@@ -4,7 +4,7 @@ Package core:math/rand implements various random number generators
*/
package rand
import "core:intrinsics"
import "base:intrinsics"
import "core:math"
import "core:mem"
+1 -1
View File
@@ -1,6 +1,6 @@
package mem
import "core:runtime"
import "base:runtime"
// NOTE(bill, 2019-12-31): These are defined in `package runtime` as they are used in the `context`. This is to prevent an import definition cycle.
Allocator_Mode :: runtime.Allocator_Mode
+2 -134
View File
@@ -1,8 +1,7 @@
package mem
import "core:intrinsics"
import "core:runtime"
import "core:sync"
import "base:intrinsics"
import "base:runtime"
nil_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
size, alignment: int,
@@ -861,134 +860,3 @@ panic_allocator :: proc() -> Allocator {
data = nil,
}
}
Tracking_Allocator_Entry :: struct {
memory: rawptr,
size: int,
alignment: int,
mode: Allocator_Mode,
err: Allocator_Error,
location: runtime.Source_Code_Location,
}
Tracking_Allocator_Bad_Free_Entry :: struct {
memory: rawptr,
location: runtime.Source_Code_Location,
}
Tracking_Allocator :: struct {
backing: Allocator,
allocation_map: map[rawptr]Tracking_Allocator_Entry,
bad_free_array: [dynamic]Tracking_Allocator_Bad_Free_Entry,
mutex: sync.Mutex,
clear_on_free_all: bool,
}
tracking_allocator_init :: proc(t: ^Tracking_Allocator, backing_allocator: Allocator, internals_allocator := context.allocator) {
t.backing = backing_allocator
t.allocation_map.allocator = internals_allocator
t.bad_free_array.allocator = internals_allocator
if .Free_All in query_features(t.backing) {
t.clear_on_free_all = true
}
}
tracking_allocator_destroy :: proc(t: ^Tracking_Allocator) {
delete(t.allocation_map)
delete(t.bad_free_array)
}
tracking_allocator_clear :: proc(t: ^Tracking_Allocator) {
sync.mutex_lock(&t.mutex)
clear(&t.allocation_map)
clear(&t.bad_free_array)
sync.mutex_unlock(&t.mutex)
}
@(require_results)
tracking_allocator :: proc(data: ^Tracking_Allocator) -> Allocator {
return Allocator{
data = data,
procedure = tracking_allocator_proc,
}
}
tracking_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
size, alignment: int,
old_memory: rawptr, old_size: int, loc := #caller_location) -> (result: []byte, err: Allocator_Error) {
data := (^Tracking_Allocator)(allocator_data)
sync.mutex_guard(&data.mutex)
if mode == .Query_Info {
info := (^Allocator_Query_Info)(old_memory)
if info != nil && info.pointer != nil {
if entry, ok := data.allocation_map[info.pointer]; ok {
info.size = entry.size
info.alignment = entry.alignment
}
info.pointer = nil
}
return
}
if mode == .Free && old_memory != nil && old_memory not_in data.allocation_map {
append(&data.bad_free_array, Tracking_Allocator_Bad_Free_Entry{
memory = old_memory,
location = loc,
})
} else {
result = data.backing.procedure(data.backing.data, mode, size, alignment, old_memory, old_size, loc) or_return
}
result_ptr := raw_data(result)
if data.allocation_map.allocator.procedure == nil {
data.allocation_map.allocator = context.allocator
}
switch mode {
case .Alloc, .Alloc_Non_Zeroed:
data.allocation_map[result_ptr] = Tracking_Allocator_Entry{
memory = result_ptr,
size = size,
mode = mode,
alignment = alignment,
err = err,
location = loc,
}
case .Free:
delete_key(&data.allocation_map, old_memory)
case .Free_All:
if data.clear_on_free_all {
clear_map(&data.allocation_map)
}
case .Resize, .Resize_Non_Zeroed:
if old_memory != result_ptr {
delete_key(&data.allocation_map, old_memory)
}
data.allocation_map[result_ptr] = Tracking_Allocator_Entry{
memory = result_ptr,
size = size,
mode = mode,
alignment = alignment,
err = err,
location = loc,
}
case .Query_Features:
set := (^Allocator_Mode_Set)(old_memory)
if set != nil {
set^ = {.Alloc, .Alloc_Non_Zeroed, .Free, .Free_All, .Resize, .Query_Features, .Query_Info}
}
return nil, nil
case .Query_Info:
unreachable()
}
return
}
+2 -2
View File
@@ -1,7 +1,7 @@
package mem
import "core:runtime"
import "core:intrinsics"
import "base:runtime"
import "base:intrinsics"
Byte :: runtime.Byte
Kilobyte :: runtime.Kilobyte
+2 -2
View File
@@ -1,7 +1,7 @@
package mem
import "core:builtin"
import "core:runtime"
import "base:builtin"
import "base:runtime"
Raw_Any :: runtime.Raw_Any
Raw_String :: runtime.Raw_String
+135
View File
@@ -0,0 +1,135 @@
//+build !freestanding
package mem
import "base:runtime"
import "core:sync"
Tracking_Allocator_Entry :: struct {
memory: rawptr,
size: int,
alignment: int,
mode: Allocator_Mode,
err: Allocator_Error,
location: runtime.Source_Code_Location,
}
Tracking_Allocator_Bad_Free_Entry :: struct {
memory: rawptr,
location: runtime.Source_Code_Location,
}
Tracking_Allocator :: struct {
backing: Allocator,
allocation_map: map[rawptr]Tracking_Allocator_Entry,
bad_free_array: [dynamic]Tracking_Allocator_Bad_Free_Entry,
mutex: sync.Mutex,
clear_on_free_all: bool,
}
tracking_allocator_init :: proc(t: ^Tracking_Allocator, backing_allocator: Allocator, internals_allocator := context.allocator) {
t.backing = backing_allocator
t.allocation_map.allocator = internals_allocator
t.bad_free_array.allocator = internals_allocator
if .Free_All in query_features(t.backing) {
t.clear_on_free_all = true
}
}
tracking_allocator_destroy :: proc(t: ^Tracking_Allocator) {
delete(t.allocation_map)
delete(t.bad_free_array)
}
tracking_allocator_clear :: proc(t: ^Tracking_Allocator) {
sync.mutex_lock(&t.mutex)
clear(&t.allocation_map)
clear(&t.bad_free_array)
sync.mutex_unlock(&t.mutex)
}
@(require_results)
tracking_allocator :: proc(data: ^Tracking_Allocator) -> Allocator {
return Allocator{
data = data,
procedure = tracking_allocator_proc,
}
}
tracking_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
size, alignment: int,
old_memory: rawptr, old_size: int, loc := #caller_location) -> (result: []byte, err: Allocator_Error) {
data := (^Tracking_Allocator)(allocator_data)
sync.mutex_guard(&data.mutex)
if mode == .Query_Info {
info := (^Allocator_Query_Info)(old_memory)
if info != nil && info.pointer != nil {
if entry, ok := data.allocation_map[info.pointer]; ok {
info.size = entry.size
info.alignment = entry.alignment
}
info.pointer = nil
}
return
}
if mode == .Free && old_memory != nil && old_memory not_in data.allocation_map {
append(&data.bad_free_array, Tracking_Allocator_Bad_Free_Entry{
memory = old_memory,
location = loc,
})
} else {
result = data.backing.procedure(data.backing.data, mode, size, alignment, old_memory, old_size, loc) or_return
}
result_ptr := raw_data(result)
if data.allocation_map.allocator.procedure == nil {
data.allocation_map.allocator = context.allocator
}
switch mode {
case .Alloc, .Alloc_Non_Zeroed:
data.allocation_map[result_ptr] = Tracking_Allocator_Entry{
memory = result_ptr,
size = size,
mode = mode,
alignment = alignment,
err = err,
location = loc,
}
case .Free:
delete_key(&data.allocation_map, old_memory)
case .Free_All:
if data.clear_on_free_all {
clear_map(&data.allocation_map)
}
case .Resize, .Resize_Non_Zeroed:
if old_memory != result_ptr {
delete_key(&data.allocation_map, old_memory)
}
data.allocation_map[result_ptr] = Tracking_Allocator_Entry{
memory = result_ptr,
size = size,
mode = mode,
alignment = alignment,
err = err,
location = loc,
}
case .Query_Features:
set := (^Allocator_Mode_Set)(old_memory)
if set != nil {
set^ = {.Alloc, .Alloc_Non_Zeroed, .Free, .Free_All, .Resize, .Query_Features, .Query_Info}
}
return nil, nil
case .Query_Info:
unreachable()
}
return
}
+2 -2
View File
@@ -1,8 +1,8 @@
package mem_virtual
import "core:mem"
import "core:intrinsics"
import "core:runtime"
import "base:intrinsics"
import "base:runtime"
_ :: runtime
DEFAULT_PAGE_SIZE := uint(4096)
+1 -1
View File
@@ -2,7 +2,7 @@
//+private
package mem_virtual
foreign import libc "System.framework"
foreign import libc "system:System.framework"
import "core:c"
PROT_NONE :: 0x0 /* [MC2] no permissions */
+1 -1
View File
@@ -21,7 +21,7 @@ package net
Jeroen van Rijn: Cross platform unification, code style, documentation
*/
import "core:runtime"
import "base:runtime"
/*
TUNEABLES - See also top of `dns.odin` for DNS configuration.
+1
View File
@@ -768,6 +768,7 @@ Struct_Type :: struct {
tok_pos: tokenizer.Pos,
poly_params: ^Field_List,
align: ^Expr,
field_align: ^Expr,
where_token: tokenizer.Token,
where_clauses: []^Expr,
is_packed: bool,
+2 -1
View File
@@ -1,6 +1,6 @@
package odin_ast
import "core:intrinsics"
import "base:intrinsics"
import "core:mem"
import "core:fmt"
import "core:reflect"
@@ -314,6 +314,7 @@ clone_node :: proc(node: ^Node) -> ^Node {
case ^Struct_Type:
r.poly_params = auto_cast clone(r.poly_params)
r.align = clone(r.align)
r.field_align = clone(r.field_align)
r.fields = auto_cast clone(r.fields)
case ^Union_Type:
r.poly_params = auto_cast clone(r.poly_params)
+7
View File
@@ -2547,6 +2547,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
poly_params: ^ast.Field_List
align: ^ast.Expr
field_align: ^ast.Expr
is_packed: bool
is_raw_union: bool
is_no_copy: bool
@@ -2578,6 +2579,11 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
error(p, tag.pos, "duplicate struct tag '#%s'", tag.text)
}
align = parse_expr(p, true)
case "field_align":
if field_align != nil {
error(p, tag.pos, "duplicate struct tag '#%s'", tag.text)
}
field_align = parse_expr(p, true)
case "raw_union":
if is_raw_union {
error(p, tag.pos, "duplicate struct tag '#%s'", tag.text)
@@ -2620,6 +2626,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
st := ast.new(ast.Struct_Type, tok.pos, end_pos(close))
st.poly_params = poly_params
st.align = align
st.field_align = field_align
st.is_packed = is_packed
st.is_raw_union = is_raw_union
st.is_no_copy = is_no_copy
+1 -1
View File
@@ -2,7 +2,7 @@ package os
import "core:strings"
import "core:mem"
import "core:runtime"
import "base:runtime"
read_dir :: proc(fd: Handle, n: int, allocator := context.allocator) -> (fi: []File_Info, err: Errno) {
dirp: Dir
+1 -1
View File
@@ -2,7 +2,7 @@ package os
import win32 "core:sys/windows"
import "core:strings"
import "core:runtime"
import "base:runtime"
read_dir :: proc(fd: Handle, n: int, allocator := context.allocator) -> (fi: []File_Info, err: Errno) {
find_data_to_file_info :: proc(base_path: string, d: ^win32.WIN32_FIND_DATAW) -> (fi: File_Info) {
+1 -1
View File
@@ -1,7 +1,7 @@
package os
import win32 "core:sys/windows"
import "core:runtime"
import "base:runtime"
// lookup_env gets the value of the environment variable named by the key
// If the variable is found in the environment the value (which can be empty) is returned and the boolean is true
+5 -5
View File
@@ -1,8 +1,8 @@
package os
import win32 "core:sys/windows"
import "core:intrinsics"
import "core:runtime"
import "base:intrinsics"
import "base:runtime"
import "core:unicode/utf16"
is_path_separator :: proc(c: byte) -> bool {
@@ -349,7 +349,7 @@ exists :: proc(path: string) -> bool {
wpath := win32.utf8_to_wstring(path, context.temp_allocator)
attribs := win32.GetFileAttributesW(wpath)
return i32(attribs) != win32.INVALID_FILE_ATTRIBUTES
return attribs != win32.INVALID_FILE_ATTRIBUTES
}
is_file :: proc(path: string) -> bool {
@@ -357,7 +357,7 @@ is_file :: proc(path: string) -> bool {
wpath := win32.utf8_to_wstring(path, context.temp_allocator)
attribs := win32.GetFileAttributesW(wpath)
if i32(attribs) != win32.INVALID_FILE_ATTRIBUTES {
if attribs != win32.INVALID_FILE_ATTRIBUTES {
return attribs & win32.FILE_ATTRIBUTE_DIRECTORY == 0
}
return false
@@ -368,7 +368,7 @@ is_dir :: proc(path: string) -> bool {
wpath := win32.utf8_to_wstring(path, context.temp_allocator)
attribs := win32.GetFileAttributesW(wpath)
if i32(attribs) != win32.INVALID_FILE_ATTRIBUTES {
if attribs != win32.INVALID_FILE_ATTRIBUTES {
return attribs & win32.FILE_ATTRIBUTE_DIRECTORY != 0
}
return false
+6 -92
View File
@@ -1,5 +1,6 @@
package os
import "base:runtime"
import "core:mem"
import "core:strconv"
import "core:unicode/utf8"
@@ -168,99 +169,12 @@ read_ptr :: proc(fd: Handle, data: rawptr, len: int) -> (int, Errno) {
return read(fd, s)
}
heap_allocator_proc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode,
size, alignment: int,
old_memory: rawptr, old_size: int, loc := #caller_location) -> ([]byte, mem.Allocator_Error) {
//
// NOTE(tetra, 2020-01-14): The heap doesn't respect alignment.
// Instead, we overallocate by `alignment + size_of(rawptr) - 1`, and insert
// padding. We also store the original pointer returned by heap_alloc right before
// the pointer we return to the user.
//
heap_allocator_proc :: runtime.heap_allocator_proc
heap_allocator :: runtime.heap_allocator
aligned_alloc :: proc(size, alignment: int, old_ptr: rawptr = nil, zero_memory := true) -> ([]byte, mem.Allocator_Error) {
a := max(alignment, align_of(rawptr))
space := size + a - 1
allocated_mem: rawptr
if old_ptr != nil {
original_old_ptr := mem.ptr_offset((^rawptr)(old_ptr), -1)^
allocated_mem = heap_resize(original_old_ptr, space+size_of(rawptr))
} else {
allocated_mem = heap_alloc(space+size_of(rawptr), zero_memory)
}
aligned_mem := rawptr(mem.ptr_offset((^u8)(allocated_mem), size_of(rawptr)))
ptr := uintptr(aligned_mem)
aligned_ptr := (ptr - 1 + uintptr(a)) & -uintptr(a)
diff := int(aligned_ptr - ptr)
if (size + diff) > space || allocated_mem == nil {
return nil, .Out_Of_Memory
}
aligned_mem = rawptr(aligned_ptr)
mem.ptr_offset((^rawptr)(aligned_mem), -1)^ = allocated_mem
return mem.byte_slice(aligned_mem, size), nil
}
aligned_free :: proc(p: rawptr) {
if p != nil {
heap_free(mem.ptr_offset((^rawptr)(p), -1)^)
}
}
aligned_resize :: proc(p: rawptr, old_size: int, new_size: int, new_alignment: int, zero_memory := true) -> (new_memory: []byte, err: mem.Allocator_Error) {
if p == nil {
return nil, nil
}
new_memory = aligned_alloc(new_size, new_alignment, p, zero_memory) or_return
// NOTE: heap_resize does not zero the new memory, so we do it
if zero_memory && new_size > old_size {
new_region := mem.raw_data(new_memory[old_size:])
mem.zero(new_region, new_size - old_size)
}
return
}
switch mode {
case .Alloc, .Alloc_Non_Zeroed:
return aligned_alloc(size, alignment, nil, mode == .Alloc)
case .Free:
aligned_free(old_memory)
case .Free_All:
return nil, .Mode_Not_Implemented
case .Resize, .Resize_Non_Zeroed:
if old_memory == nil {
return aligned_alloc(size, alignment, nil, mode == .Resize)
}
return aligned_resize(old_memory, old_size, size, alignment, mode == .Resize)
case .Query_Features:
set := (^mem.Allocator_Mode_Set)(old_memory)
if set != nil {
set^ = {.Alloc, .Alloc_Non_Zeroed, .Free, .Resize, .Resize_Non_Zeroed, .Query_Features}
}
return nil, nil
case .Query_Info:
return nil, .Mode_Not_Implemented
}
return nil, nil
}
heap_allocator :: proc() -> mem.Allocator {
return mem.Allocator{
procedure = heap_allocator_proc,
data = nil,
}
}
heap_alloc :: runtime.heap_alloc
heap_resize :: runtime.heap_resize
heap_free :: runtime.heap_free
processor_core_count :: proc() -> int {
return _processor_core_count()
+1 -1
View File
@@ -1,6 +1,6 @@
package os2
import "core:runtime"
import "base:runtime"
// get_env retrieves the value of the environment variable named by the key
// It returns the value, which will be empty if the variable is not present
+1 -1
View File
@@ -1,7 +1,7 @@
//+private
package os2
import "core:runtime"
import "base:runtime"
_lookup_env :: proc(key: string, allocator: runtime.Allocator) -> (value: string, found: bool) {
//TODO
+1 -1
View File
@@ -2,7 +2,7 @@
package os2
import win32 "core:sys/windows"
import "core:runtime"
import "base:runtime"
_lookup_env :: proc(key: string, allocator: runtime.Allocator) -> (value: string, found: bool) {
if key == "" {
+1 -1
View File
@@ -1,7 +1,7 @@
package os2
import "core:io"
import "core:runtime"
import "base:runtime"
General_Error :: enum u32 {
None,
+22 -16
View File
@@ -2,7 +2,7 @@ package os2
import "core:io"
import "core:time"
import "core:runtime"
import "base:runtime"
File :: struct {
impl: _File,
@@ -156,41 +156,46 @@ read_link :: proc(name: string, allocator: runtime.Allocator) -> (string, Error)
}
chdir :: proc(name: string) -> Error {
chdir :: change_directory
change_directory :: proc(name: string) -> Error {
return _chdir(name)
}
chmod :: proc(name: string, mode: File_Mode) -> Error {
chmod :: change_mode
change_mode :: proc(name: string, mode: File_Mode) -> Error {
return _chmod(name, mode)
}
chown :: proc(name: string, uid, gid: int) -> Error {
chown :: change_owner
change_owner :: proc(name: string, uid, gid: int) -> Error {
return _chown(name, uid, gid)
}
fchdir :: proc(f: ^File) -> Error {
fchdir :: fchange_directory
fchange_directory :: proc(f: ^File) -> Error {
return _fchdir(f)
}
fchmod :: proc(f: ^File, mode: File_Mode) -> Error {
fchmod :: fchange_mode
fchange_mode :: proc(f: ^File, mode: File_Mode) -> Error {
return _fchmod(f, mode)
}
fchown :: proc(f: ^File, uid, gid: int) -> Error {
fchown :: fchange_owner
fchange_owner :: proc(f: ^File, uid, gid: int) -> Error {
return _fchown(f, uid, gid)
}
lchown :: proc(name: string, uid, gid: int) -> Error {
lchown :: change_owner_do_not_follow_links
change_owner_do_not_follow_links :: proc(name: string, uid, gid: int) -> Error {
return _lchown(name, uid, gid)
}
chtimes :: proc(name: string, atime, mtime: time.Time) -> Error {
chtimes :: change_times
change_times :: proc(name: string, atime, mtime: time.Time) -> Error {
return _chtimes(name, atime, mtime)
}
fchtimes :: proc(f: ^File, atime, mtime: time.Time) -> Error {
fchtimes :: fchange_times
fchange_times :: proc(f: ^File, atime, mtime: time.Time) -> Error {
return _fchtimes(f, atime, mtime)
}
@@ -202,7 +207,8 @@ is_file :: proc(path: string) -> bool {
return _is_file(path)
}
is_dir :: proc(path: string) -> bool {
is_dir :: is_directory
is_directory :: proc(path: string) -> bool {
return _is_dir(path)
}
@@ -213,7 +219,7 @@ copy_file :: proc(dst_path, src_path: string) -> Error {
info := fstat(src, _file_allocator()) or_return
defer file_info_delete(info, _file_allocator())
if info.is_dir {
if info.is_directory {
return .Invalid_File
}
+1 -1
View File
@@ -4,7 +4,7 @@ package os2
import "core:io"
import "core:time"
import "core:strings"
import "core:runtime"
import "base:runtime"
import "core:sys/unix"
INVALID_HANDLE :: -1
+9 -2
View File
@@ -1,7 +1,7 @@
package os2
import "core:mem"
import "core:runtime"
import "base:runtime"
import "core:strconv"
import "core:unicode/utf8"
@@ -74,14 +74,21 @@ read_ptr :: proc(f: ^File, data: rawptr, len: int) -> (n: int, err: Error) {
}
read_entire_file :: proc{
read_entire_file_from_path,
read_entire_file_from_file,
}
read_entire_file :: proc(name: string, allocator: runtime.Allocator) -> (data: []byte, err: Error) {
read_entire_file_from_path :: proc(name: string, allocator: runtime.Allocator) -> (data: []byte, err: Error) {
f, ferr := open(name)
if ferr != nil {
return nil, ferr
}
defer close(f)
return read_entire_file_from_file(f, allocator)
}
read_entire_file_from_file :: proc(f: ^File, allocator: runtime.Allocator) -> (data: []byte, err: Error) {
size: int
if size64, err := file_size(f); err == nil {
if i64(int(size64)) != size64 {
+5 -5
View File
@@ -4,7 +4,7 @@ package os2
import "core:io"
import "core:mem"
import "core:sync"
import "core:runtime"
import "base:runtime"
import "core:strings"
import "core:time"
import "core:unicode/utf16"
@@ -454,7 +454,7 @@ _remove :: proc(name: string) -> Error {
if err != err1 {
a := win32.GetFileAttributesW(p)
if a == ~u32(0) {
if a == win32.INVALID_FILE_ATTRIBUTES {
err = _get_platform_error()
} else {
if a & win32.FILE_ATTRIBUTE_DIRECTORY != 0 {
@@ -704,13 +704,13 @@ _fchtimes :: proc(f: ^File, atime, mtime: time.Time) -> Error {
_exists :: proc(path: string) -> bool {
wpath := _fix_long_path(path)
attribs := win32.GetFileAttributesW(wpath)
return i32(attribs) != win32.INVALID_FILE_ATTRIBUTES
return attribs != win32.INVALID_FILE_ATTRIBUTES
}
_is_file :: proc(path: string) -> bool {
wpath := _fix_long_path(path)
attribs := win32.GetFileAttributesW(wpath)
if i32(attribs) != win32.INVALID_FILE_ATTRIBUTES {
if attribs != win32.INVALID_FILE_ATTRIBUTES {
return attribs & win32.FILE_ATTRIBUTE_DIRECTORY == 0
}
return false
@@ -719,7 +719,7 @@ _is_file :: proc(path: string) -> bool {
_is_dir :: proc(path: string) -> bool {
wpath := _fix_long_path(path)
attribs := win32.GetFileAttributesW(wpath)
if i32(attribs) != win32.INVALID_FILE_ATTRIBUTES {
if attribs != win32.INVALID_FILE_ATTRIBUTES {
return attribs & win32.FILE_ATTRIBUTE_DIRECTORY != 0
}
return false
+1 -1
View File
@@ -1,6 +1,6 @@
package os2
import "core:runtime"
import "base:runtime"
heap_allocator :: proc() -> runtime.Allocator {
return runtime.Allocator{
+1 -1
View File
@@ -200,7 +200,7 @@ _heap_allocator_proc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode,
case .Free_All:
return nil, .Mode_Not_Implemented
case .Resize:
case .Resize, .Resize_Non_Zeroed:
if old_memory == nil {
return aligned_alloc(size, alignment)
}
+10 -6
View File
@@ -1,6 +1,6 @@
package os2
import "core:runtime"
import "base:runtime"
Path_Separator :: _Path_Separator // OS-Specific
Path_List_Separator :: _Path_List_Separator // OS-Specific
@@ -9,11 +9,13 @@ is_path_separator :: proc(c: byte) -> bool {
return _is_path_separator(c)
}
mkdir :: proc(name: string, perm: File_Mode) -> Error {
mkdir :: make_directory
make_directory :: proc(name: string, perm: File_Mode) -> Error {
return _mkdir(name, perm)
}
mkdir_all :: proc(path: string, perm: File_Mode) -> Error {
mkdir_all :: make_directory_all
make_directory_all :: proc(path: string, perm: File_Mode) -> Error {
return _mkdir_all(path, perm)
}
@@ -22,10 +24,12 @@ remove_all :: proc(path: string) -> Error {
}
getwd :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) {
getwd :: get_working_directory
get_working_directory :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) {
return _getwd(allocator)
}
setwd :: proc(dir: string) -> (err: Error) {
setwd :: set_working_directory
set_working_directory :: proc(dir: string) -> (err: Error) {
return _setwd(dir)
}
+1 -1
View File
@@ -3,7 +3,7 @@ package os2
import "core:strings"
import "core:strconv"
import "core:runtime"
import "base:runtime"
import "core:sys/unix"
_Path_Separator :: '/'
+3 -3
View File
@@ -2,7 +2,7 @@
package os2
import win32 "core:sys/windows"
import "core:runtime"
import "base:runtime"
import "core:strings"
_Path_Separator :: '\\'
@@ -33,7 +33,7 @@ _mkdir_all :: proc(path: string, perm: File_Mode) -> Error {
dir, err := stat(path, _temp_allocator())
if err == nil {
if dir.is_dir {
if dir.is_directory {
return nil
}
return .Exist
@@ -60,7 +60,7 @@ _mkdir_all :: proc(path: string, perm: File_Mode) -> Error {
err = mkdir(path, perm)
if err != nil {
dir1, err1 := lstat(path, _temp_allocator())
if err1 == nil && dir1.is_dir {
if err1 == nil && dir1.is_directory {
return nil
}
return err
+1 -1
View File
@@ -2,7 +2,7 @@ package os2
import "core:sync"
import "core:time"
import "core:runtime"
import "base:runtime"
args: []string
+8 -7
View File
@@ -1,14 +1,14 @@
package os2
import "core:time"
import "core:runtime"
import "base:runtime"
File_Info :: struct {
fullpath: string,
name: string,
size: i64,
mode: File_Mode,
is_dir: bool,
fullpath: string,
name: string,
size: i64,
mode: File_Mode,
is_directory: bool,
creation_time: time.Time,
modification_time: time.Time,
access_time: time.Time,
@@ -33,7 +33,8 @@ stat :: proc(name: string, allocator: runtime.Allocator) -> (File_Info, Error) {
return _stat(name, allocator)
}
lstat :: proc(name: string, allocator: runtime.Allocator) -> (File_Info, Error) {
lstat :: stat_do_not_follow_links
stat_do_not_follow_links :: proc(name: string, allocator: runtime.Allocator) -> (File_Info, Error) {
return _lstat(name, allocator)
}
+2 -2
View File
@@ -2,7 +2,7 @@
package os2
import "core:time"
import "core:runtime"
import "base:runtime"
import "core:strings"
import "core:sys/unix"
import "core:path/filepath"
@@ -101,7 +101,7 @@ _fstat_internal :: proc(fd: int, allocator: runtime.Allocator) -> (File_Info, Er
name = "",
size = s.size,
mode = 0,
is_dir = S_ISDIR(s.mode),
is_directory = S_ISDIR(s.mode),
modification_time = time.Time {s.modified.seconds},
access_time = time.Time {s.last_access.seconds},
creation_time = time.Time{0}, // regular stat does not provide this
+4 -4
View File
@@ -1,7 +1,7 @@
//+private
package os2
import "core:runtime"
import "base:runtime"
import "core:time"
import "core:strings"
import win32 "core:sys/windows"
@@ -228,7 +228,7 @@ _file_info_from_win32_file_attribute_data :: proc(d: ^win32.WIN32_FILE_ATTRIBUTE
fi.size = i64(d.nFileSizeHigh)<<32 + i64(d.nFileSizeLow)
fi.mode |= _file_mode_from_file_attributes(d.dwFileAttributes, nil, 0)
fi.is_dir = fi.mode & File_Mode_Dir != 0
fi.is_directory = fi.mode & File_Mode_Dir != 0
fi.creation_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftCreationTime))
fi.modification_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastWriteTime))
@@ -245,7 +245,7 @@ _file_info_from_win32_find_data :: proc(d: ^win32.WIN32_FIND_DATAW, name: string
fi.size = i64(d.nFileSizeHigh)<<32 + i64(d.nFileSizeLow)
fi.mode |= _file_mode_from_file_attributes(d.dwFileAttributes, nil, 0)
fi.is_dir = fi.mode & File_Mode_Dir != 0
fi.is_directory = fi.mode & File_Mode_Dir != 0
fi.creation_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftCreationTime))
fi.modification_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastWriteTime))
@@ -282,7 +282,7 @@ _file_info_from_get_file_information_by_handle :: proc(path: string, h: win32.HA
fi.size = i64(d.nFileSizeHigh)<<32 + i64(d.nFileSizeLow)
fi.mode |= _file_mode_from_file_attributes(ti.FileAttributes, h, ti.ReparseTag)
fi.is_dir = fi.mode & File_Mode_Dir != 0
fi.is_directory = fi.mode & File_Mode_Dir != 0
fi.creation_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftCreationTime))
fi.modification_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastWriteTime))
+6 -4
View File
@@ -1,15 +1,17 @@
package os2
import "core:runtime"
import "base:runtime"
create_temp :: proc(dir, pattern: string) -> (^File, Error) {
create_temp_file :: proc(dir, pattern: string) -> (^File, Error) {
return _create_temp(dir, pattern)
}
mkdir_temp :: proc(dir, pattern: string, allocator: runtime.Allocator) -> (string, Error) {
mkdir_temp :: make_directory_temp
make_directory_temp :: proc(dir, pattern: string, allocator: runtime.Allocator) -> (string, Error) {
return _mkdir_temp(dir, pattern, allocator)
}
temp_dir :: proc(allocator: runtime.Allocator) -> (string, Error) {
temp_dir :: temp_directory
temp_directory :: proc(allocator: runtime.Allocator) -> (string, Error) {
return _temp_dir(allocator)
}
+1 -1
View File
@@ -1,7 +1,7 @@
//+private
package os2
import "core:runtime"
import "base:runtime"
_create_temp :: proc(dir, pattern: string) -> (^File, Error) {
+1 -1
View File
@@ -1,7 +1,7 @@
//+private
package os2
import "core:runtime"
import "base:runtime"
import win32 "core:sys/windows"
_create_temp :: proc(dir, pattern: string) -> (^File, Error) {
+1 -1
View File
@@ -1,7 +1,7 @@
package os2
import "core:strings"
import "core:runtime"
import "base:runtime"
user_cache_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) {
#partial switch ODIN_OS {

Some files were not shown because too many files have changed in this diff Show More