diff --git a/core/runtime/core_builtin.odin b/core/runtime/core_builtin.odin index bd919247e..82b28ae6d 100644 --- a/core/runtime/core_builtin.odin +++ b/core/runtime/core_builtin.odin @@ -6,7 +6,7 @@ import "core:intrinsics" Maybe :: union($T: typeid) {T} -@builtin +@(builtin, require_results) container_of :: #force_inline proc "contextless" (ptr: $P/^$Field_Type, $T: typeid, $field_name: string) -> ^T where intrinsics.type_has_field(T, field_name), intrinsics.type_field_type(T, field_name) == Field_Type { @@ -179,17 +179,18 @@ delete :: proc{ // 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 -@builtin +@(builtin, require_results) new :: proc($T: typeid, allocator := context.allocator, loc := #caller_location) -> (^T, Allocator_Error) #optional_allocator_error { return new_aligned(T, align_of(T), allocator, loc) } +@(require_results) new_aligned :: proc($T: typeid, alignment: int, allocator := context.allocator, loc := #caller_location) -> (t: ^T, err: Allocator_Error) { data := mem_alloc_bytes(size_of(T), alignment, allocator, loc) or_return t = (^T)(raw_data(data)) return } -@builtin +@(builtin, require_results) new_clone :: proc(data: $T, allocator := context.allocator, loc := #caller_location) -> (t: ^T, err: Allocator_Error) #optional_allocator_error { t_data := mem_alloc_bytes(size_of(T), align_of(T), allocator, loc) or_return t = (^T)(raw_data(t_data)) @@ -201,6 +202,7 @@ new_clone :: proc(data: $T, allocator := context.allocator, loc := #caller_locat DEFAULT_RESERVE_CAPACITY :: 16 +@(require_results) make_aligned :: proc($T: typeid/[]$E, #any_int len: int, alignment: int, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) #optional_allocator_error { make_slice_error_loc(loc, len) data, err := mem_alloc_bytes(size_of(E)*len, alignment, allocator, loc) @@ -211,19 +213,19 @@ make_aligned :: proc($T: typeid/[]$E, #any_int len: int, alignment: int, allocat return transmute(T)s, err } -@(builtin) +@(builtin, require_results) make_slice :: proc($T: typeid/[]$E, #any_int len: int, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) #optional_allocator_error { return make_aligned(T, len, align_of(E), allocator, loc) } -@(builtin) +@(builtin, require_results) make_dynamic_array :: proc($T: typeid/[dynamic]$E, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) #optional_allocator_error { return make_dynamic_array_len_cap(T, 0, DEFAULT_RESERVE_CAPACITY, allocator, loc) } -@(builtin) +@(builtin, require_results) make_dynamic_array_len :: proc($T: typeid/[dynamic]$E, #any_int len: int, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) #optional_allocator_error { return make_dynamic_array_len_cap(T, len, len, allocator, loc) } -@(builtin) +@(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: T, err: Allocator_Error) #optional_allocator_error { make_dynamic_array_error_loc(loc, len, cap) data := mem_alloc_bytes(size_of(E)*cap, align_of(E), allocator, loc) or_return @@ -234,7 +236,7 @@ make_dynamic_array_len_cap :: proc($T: typeid/[dynamic]$E, #any_int len: int, #a array = transmute(T)s return } -@(builtin) +@(builtin, require_results) make_map :: proc($T: typeid/map[$K]$E, #any_int capacity: int = 1< (m: T, err: Allocator_Error) #optional_allocator_error { make_map_expr_error_loc(loc, capacity) context.allocator = allocator @@ -242,7 +244,7 @@ make_map :: proc($T: typeid/map[$K]$E, #any_int capacity: int = 1< (mp: T, err: Allocator_Error) #optional_allocator_error { make_slice_error_loc(loc, len) data := mem_alloc_bytes(size_of(E)*len, align_of(E), allocator, loc) or_return diff --git a/core/runtime/core_builtin_matrix.odin b/core/runtime/core_builtin_matrix.odin index 53589587c..7d60d625c 100644 --- a/core/runtime/core_builtin_matrix.odin +++ b/core/runtime/core_builtin_matrix.odin @@ -37,12 +37,12 @@ inverse :: proc{ matrix4x4_inverse, } -@(builtin) +@(builtin, 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)) } -@(builtin) +@(builtin, require_results) matrix_trace :: proc "contextless" (m: $M/matrix[$N, N]$T) -> (trace: T) { for i in 0.. (trace: T) { return } -@(builtin) +@(builtin, require_results) matrix_minor :: proc "contextless" (m: $M/matrix[$N, N]$T, row, column: int) -> (minor: T) where N > 1 { K :: N-1 cut_down: matrix[K, K]T @@ -66,23 +66,23 @@ matrix_minor :: proc "contextless" (m: $M/matrix[$N, N]$T, row, column: int) -> -@(builtin) +@(builtin, require_results) matrix1x1_determinant :: proc "contextless" (m: $M/matrix[1, 1]$T) -> (det: T) { return m[0, 0] } -@(builtin) +@(builtin, 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] } -@(builtin) +@(builtin, 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 } -@(builtin) +@(builtin, 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 { @@ -94,13 +94,13 @@ matrix4x4_determinant :: proc "contextless" (m: $M/matrix[4, 4]$T) -> (det: T) { -@(builtin) +@(builtin, require_results) matrix1x1_adjugate :: proc "contextless" (x: $M/matrix[1, 1]$T) -> (y: M) { y = x return } -@(builtin) +@(builtin, 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] @@ -109,7 +109,7 @@ matrix2x2_adjugate :: proc "contextless" (x: $M/matrix[2, 2]$T) -> (y: M) { return } -@(builtin) +@(builtin, 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]) @@ -124,7 +124,7 @@ matrix3x3_adjugate :: proc "contextless" (m: $M/matrix[3, 3]$T) -> (y: M) { } -@(builtin) +@(builtin, require_results) matrix4x4_adjugate :: proc "contextless" (x: $M/matrix[4, 4]$T) -> (y: M) { for i in 0..<4 { for j in 0..<4 { @@ -135,13 +135,13 @@ matrix4x4_adjugate :: proc "contextless" (x: $M/matrix[4, 4]$T) -> (y: M) { return } -@(builtin) +@(builtin, require_results) matrix1x1_inverse_transpose :: proc "contextless" (x: $M/matrix[1, 1]$T) -> (y: M) { y[0, 0] = 1/x[0, 0] return } -@(builtin) +@(builtin, 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) { @@ -159,7 +159,7 @@ matrix2x2_inverse_transpose :: proc "contextless" (x: $M/matrix[2, 2]$T) -> (y: return } -@(builtin) +@(builtin, require_results) matrix3x3_inverse_transpose :: proc "contextless" (x: $M/matrix[3, 3]$T) -> (y: M) #no_bounds_check { a := adjugate(x) d := determinant(x) @@ -180,7 +180,7 @@ matrix3x3_inverse_transpose :: proc "contextless" (x: $M/matrix[3, 3]$T) -> (y: return } -@(builtin) +@(builtin, require_results) matrix4x4_inverse_transpose :: proc "contextless" (x: $M/matrix[4, 4]$T) -> (y: M) #no_bounds_check { a := adjugate(x) d: T @@ -204,13 +204,13 @@ matrix4x4_inverse_transpose :: proc "contextless" (x: $M/matrix[4, 4]$T) -> (y: return } -@(builtin) +@(builtin, require_results) matrix1x1_inverse :: proc "contextless" (x: $M/matrix[1, 1]$T) -> (y: M) { y[0, 0] = 1/x[0, 0] return } -@(builtin) +@(builtin, 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) { @@ -228,7 +228,7 @@ matrix2x2_inverse :: proc "contextless" (x: $M/matrix[2, 2]$T) -> (y: M) { return } -@(builtin) +@(builtin, require_results) matrix3x3_inverse :: proc "contextless" (x: $M/matrix[3, 3]$T) -> (y: M) #no_bounds_check { a := adjugate(x) d := determinant(x) @@ -249,7 +249,7 @@ matrix3x3_inverse :: proc "contextless" (x: $M/matrix[3, 3]$T) -> (y: M) #no_bou return } -@(builtin) +@(builtin, require_results) matrix4x4_inverse :: proc "contextless" (x: $M/matrix[4, 4]$T) -> (y: M) #no_bounds_check { a := adjugate(x) d: T diff --git a/core/runtime/core_builtin_soa.odin b/core/runtime/core_builtin_soa.odin index 2b7fd3681..10f9846a2 100644 --- a/core/runtime/core_builtin_soa.odin +++ b/core/runtime/core_builtin_soa.odin @@ -50,6 +50,7 @@ Raw_SOA_Footer_Dynamic_Array :: struct { allocator: Allocator, } +@(builtin, require_results) raw_soa_footer_slice :: proc(array: ^$T/#soa[]$E) -> (footer: ^Raw_SOA_Footer_Slice) { if array == nil { return nil @@ -58,6 +59,7 @@ raw_soa_footer_slice :: proc(array: ^$T/#soa[]$E) -> (footer: ^Raw_SOA_Footer_Sl footer = (^Raw_SOA_Footer_Slice)(uintptr(array) + field_count*size_of(rawptr)) return } +@(builtin, require_results) raw_soa_footer_dynamic_array :: proc(array: ^$T/#soa[dynamic]$E) -> (footer: ^Raw_SOA_Footer_Dynamic_Array) { if array == nil { return nil @@ -78,7 +80,7 @@ raw_soa_footer :: proc{ -@builtin +@(builtin, require_results) make_soa_aligned :: proc($T: typeid/#soa[]$E, length: int, alignment: int, allocator := context.allocator, loc := #caller_location) -> (array: T, err: Allocator_Error) #optional_allocator_error { if length <= 0 { return @@ -137,26 +139,26 @@ make_soa_aligned :: proc($T: typeid/#soa[]$E, length: int, alignment: int, alloc return } -@builtin +@(builtin, require_results) make_soa_slice :: proc($T: typeid/#soa[]$E, length: int, allocator := context.allocator, loc := #caller_location) -> (array: T, err: Allocator_Error) #optional_allocator_error { return make_soa_aligned(T, length, align_of(E), allocator, loc) } -@builtin +@(builtin, require_results) make_soa_dynamic_array :: proc($T: typeid/#soa[dynamic]$E, allocator := context.allocator, loc := #caller_location) -> (array: T) { context.allocator = allocator reserve_soa(&array, DEFAULT_RESERVE_CAPACITY, loc) return } -@builtin +@(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: T) { context.allocator = allocator resize_soa(&array, length, loc) return } -@builtin +@(builtin, require_results) make_soa_dynamic_array_len_cap :: proc($T: typeid/#soa[dynamic]$E, #any_int length, capacity: int, allocator := context.allocator, loc := #caller_location) -> (array: T) { context.allocator = allocator if reserve_soa(&array, capacity, loc) {