From 3e1791aa5c178cdae3f45bced10775a82abc361a Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Mon, 13 Nov 2023 20:54:19 +0100 Subject: Fix typos --- core/runtime/core_builtin.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'core/runtime') diff --git a/core/runtime/core_builtin.odin b/core/runtime/core_builtin.odin index a73a3d712..0348a93df 100644 --- a/core/runtime/core_builtin.odin +++ b/core/runtime/core_builtin.odin @@ -109,7 +109,7 @@ remove_range :: proc(array: ^$D/[dynamic]$T, lo, hi: int, loc := #caller_locatio // `pop` will remove and return the end 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. +// Note: If the dynamic array has no elements (`len(array) == 0`), this procedure will panic. @builtin pop :: proc(array: ^$T/[dynamic]$E, loc := #caller_location) -> (res: E) #no_bounds_check { assert(len(array) > 0, loc=loc) -- cgit v1.2.3 From 6b9202dfbf25a022287583197e57dbcd9159ea63 Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Sun, 12 Nov 2023 02:02:30 +0100 Subject: -no-crt and assembly compilation on darwin --- core/runtime/entry_unix.odin | 11 ++++--- core/runtime/entry_unix_no_crt_darwin_arm64.asm | 20 ++++++++++++ core/runtime/os_specific_any.odin | 2 +- core/runtime/os_specific_darwin.odin | 12 +++++++ src/checker.cpp | 2 +- src/linker.cpp | 42 ++++++++++++++++--------- 6 files changed, 68 insertions(+), 21 deletions(-) create mode 100644 core/runtime/entry_unix_no_crt_darwin_arm64.asm create mode 100644 core/runtime/os_specific_darwin.odin (limited to 'core/runtime') diff --git a/core/runtime/entry_unix.odin b/core/runtime/entry_unix.odin index 0c718445a..78e545c22 100644 --- a/core/runtime/entry_unix.odin +++ b/core/runtime/entry_unix.odin @@ -26,8 +26,13 @@ when ODIN_BUILD_MODE == .Dynamic { // to retrieve argc and argv from the stack when ODIN_ARCH == .amd64 { @require foreign import entry "entry_unix_no_crt_amd64.asm" + SYS_exit :: 60 } else when ODIN_ARCH == .i386 { @require foreign import entry "entry_unix_no_crt_i386.asm" + SYS_exit :: 1 + } else when ODIN_OS == .Darwin && ODIN_ARCH == .arm64 { + @require foreign import entry "entry_unix_no_crt_darwin_arm64.asm" + SYS_exit :: 1 } @(link_name="_start_odin", linkage="strong", require) _start_odin :: proc "c" (argc: i32, argv: [^]cstring) -> ! { @@ -36,11 +41,7 @@ when ODIN_BUILD_MODE == .Dynamic { #force_no_inline _startup_runtime() intrinsics.__entry_point() #force_no_inline _cleanup_runtime() - when ODIN_ARCH == .amd64 { - intrinsics.syscall(/*SYS_exit = */60) - } else when ODIN_ARCH == .i386 { - intrinsics.syscall(/*SYS_exit = */1) - } + intrinsics.syscall(SYS_exit, 0) unreachable() } } else { diff --git a/core/runtime/entry_unix_no_crt_darwin_arm64.asm b/core/runtime/entry_unix_no_crt_darwin_arm64.asm new file mode 100644 index 000000000..0f71fbdf8 --- /dev/null +++ b/core/runtime/entry_unix_no_crt_darwin_arm64.asm @@ -0,0 +1,20 @@ + .section __TEXT,__text + + ; NOTE(laytan): this should ideally be the -minimum-os-version flag but there is no nice way of preprocessing assembly in Odin. + ; 10 seems to be the lowest it goes and I don't see it mess with any targeted os version so this seems fine. + .build_version macos, 10, 0 + + .extern __start_odin + + .global _main + .align 2 +_main: + mov x5, sp ; use x5 as the stack pointer + + str x0, [x5] ; get argc into x0 (kernel passes 32-bit int argc as 64-bits on stack to keep alignment) + str x1, [x5, #8] ; get argv into x1 + + and sp, x5, #~15 ; force 16-byte alignment of the stack + + bl __start_odin ; call into Odin entry point + ret ; should never get here diff --git a/core/runtime/os_specific_any.odin b/core/runtime/os_specific_any.odin index afa106138..5fffceeeb 100644 --- a/core/runtime/os_specific_any.odin +++ b/core/runtime/os_specific_any.odin @@ -1,4 +1,4 @@ -//+build !freestanding !wasi !windows !js +//+build !freestanding !wasi !windows !js !darwin package runtime import "core:os" diff --git a/core/runtime/os_specific_darwin.odin b/core/runtime/os_specific_darwin.odin new file mode 100644 index 000000000..33136c92f --- /dev/null +++ b/core/runtime/os_specific_darwin.odin @@ -0,0 +1,12 @@ +//+build darwin +package runtime + +import "core:intrinsics" + +_os_write :: proc "contextless" (data: []byte) -> (int, _OS_Errno) { + ret := intrinsics.syscall(4, 1, uintptr(raw_data(data)), uintptr(len(data))) + if ret < 0 { + return 0, _OS_Errno(-ret) + } + return int(ret), 0 +} diff --git a/src/checker.cpp b/src/checker.cpp index 29f22bd9c..0366cf05d 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -4733,7 +4733,7 @@ gb_internal void check_add_foreign_import_decl(CheckerContext *ctx, Ast *decl) { } if (has_asm_extension(fullpath)) { - if (build_context.metrics.arch != TargetArch_amd64) { + if (build_context.metrics.arch != TargetArch_amd64 && build_context.metrics.os != TargetOs_darwin) { error(decl, "Assembly files are not yet supported on this platform: %.*s_%.*s", LIT(target_os_names[build_context.metrics.os]), LIT(target_arch_names[build_context.metrics.arch])); } diff --git a/src/linker.cpp b/src/linker.cpp index eb3687ae2..c3ede0f55 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -337,20 +337,34 @@ gb_internal i32 linker_stage(LinkerData *gen) { obj_format = str_lit("elf32"); } #endif // GB_ARCH_*_BIT - // Note(bumbread): I'm assuming nasm is installed on the host machine. - // Shipping binaries on unix-likes gets into the weird territorry of - // "which version of glibc" is it linked with. - result = system_exec_command_line_app("nasm", - "nasm \"%.*s\" " - "-f \"%.*s\" " - "-o \"%.*s\" " - "%.*s " - "", - LIT(asm_file), - LIT(obj_format), - LIT(obj_file), - LIT(build_context.extra_assembler_flags) - ); + + if (is_osx) { + // `as` comes with MacOS. + result = system_exec_command_line_app("as", + "as \"%.*s\" " + "-o \"%.*s\" " + "%.*s " + "", + LIT(asm_file), + LIT(obj_file), + LIT(build_context.extra_assembler_flags) + ); + } else { + // Note(bumbread): I'm assuming nasm is installed on the host machine. + // Shipping binaries on unix-likes gets into the weird territorry of + // "which version of glibc" is it linked with. + result = system_exec_command_line_app("nasm", + "nasm \"%.*s\" " + "-f \"%.*s\" " + "-o \"%.*s\" " + "%.*s " + "", + LIT(asm_file), + LIT(obj_format), + LIT(obj_file), + LIT(build_context.extra_assembler_flags) + ); + } array_add(&gen->output_object_paths, obj_file); } else { if (string_set_update(&libs, lib)) { -- cgit v1.2.3 From 4af77aeff684cf9a4a764a9e18d942f232cd7caf Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 22 Nov 2023 15:04:41 +0000 Subject: Lower `MAP_MIN_LOG2_CAPACITY` from `6` to `3` (64->8) --- core/runtime/dynamic_map_internal.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'core/runtime') diff --git a/core/runtime/dynamic_map_internal.odin b/core/runtime/dynamic_map_internal.odin index bdf0979cb..491a7974d 100644 --- a/core/runtime/dynamic_map_internal.odin +++ b/core/runtime/dynamic_map_internal.odin @@ -44,7 +44,7 @@ _ :: intrinsics MAP_LOAD_FACTOR :: 75 // Minimum log2 capacity. -MAP_MIN_LOG2_CAPACITY :: 6 // 64 elements +MAP_MIN_LOG2_CAPACITY :: 3 // 8 elements // Has to be less than 100% though. #assert(MAP_LOAD_FACTOR < 100) -- cgit v1.2.3 From 0888c69b57604b674b6c220c6f60297d98bae58c Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 23 Nov 2023 17:16:21 +0000 Subject: Remove unneeded `typeid_of` --- core/runtime/core_builtin_soa.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'core/runtime') diff --git a/core/runtime/core_builtin_soa.odin b/core/runtime/core_builtin_soa.odin index f3882a9a8..6313a28f5 100644 --- a/core/runtime/core_builtin_soa.odin +++ b/core/runtime/core_builtin_soa.odin @@ -287,7 +287,7 @@ append_soa_elem :: proc(array: ^$T/#soa[dynamic]$E, arg: E, loc := #caller_locat footer := raw_soa_footer(array) if size_of(E) > 0 && cap(array)-len(array) > 0 { - ti := type_info_of(typeid_of(T)) + ti := type_info_of(T) ti = type_info_base(ti) si := &ti.variant.(Type_Info_Struct) field_count: uintptr -- cgit v1.2.3 From e23eba09147c20b95728919f0f86b1ab267f416a Mon Sep 17 00:00:00 2001 From: flga Date: Fri, 1 Dec 2023 19:21:58 +0000 Subject: runtime: panic_allocator should use panic_allocator_proc --- core/runtime/default_allocators_nil.odin | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'core/runtime') diff --git a/core/runtime/default_allocators_nil.odin b/core/runtime/default_allocators_nil.odin index a340050eb..eee6a7998 100644 --- a/core/runtime/default_allocators_nil.odin +++ b/core/runtime/default_allocators_nil.odin @@ -35,7 +35,7 @@ nil_allocator :: proc() -> Allocator { when ODIN_OS == .Freestanding { default_allocator_proc :: nil_allocator_proc default_allocator :: nil_allocator -} +} @@ -78,9 +78,7 @@ panic_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, panic_allocator :: proc() -> Allocator { return Allocator{ - procedure = nil_allocator_proc, + procedure = panic_allocator_proc, data = nil, } } - - -- cgit v1.2.3 From 58e4a011c72d268ca35d46d2288d5858677e9cac Mon Sep 17 00:00:00 2001 From: Colin Davidson Date: Mon, 4 Dec 2023 00:08:13 -0800 Subject: add non-zeroing append and resize --- core/mem/alloc.odin | 2 + core/mem/allocators.odin | 32 +++++---- core/os/os.odin | 14 ++-- core/runtime/core.odin | 1 + core/runtime/core_builtin.odin | 105 ++++++++++++++++++++++++----- core/runtime/default_allocators_arena.odin | 2 +- core/runtime/default_allocators_nil.odin | 6 +- core/runtime/internal.odin | 27 ++++++-- 8 files changed, 147 insertions(+), 42 deletions(-) (limited to 'core/runtime') diff --git a/core/mem/alloc.odin b/core/mem/alloc.odin index 57e82a5f8..507b13d6f 100644 --- a/core/mem/alloc.odin +++ b/core/mem/alloc.odin @@ -11,6 +11,8 @@ Allocator_Mode :: enum byte { Free_All, Resize, Query_Features, + Alloc_Non_Zeroed, + Resize_Non_Zeroed, } */ diff --git a/core/mem/allocators.odin b/core/mem/allocators.odin index 4f5dd8eef..362b897b4 100644 --- a/core/mem/allocators.odin +++ b/core/mem/allocators.odin @@ -85,7 +85,7 @@ arena_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, case .Free_All: arena.offset = 0 - case .Resize: + case .Resize, .Resize_Non_Zeroed: return default_resize_bytes_align(byte_slice(old_memory, old_size), size, alignment, arena_allocator(arena)) case .Query_Features: @@ -259,7 +259,7 @@ scratch_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, } clear(&s.leaked_allocations) - case .Resize: + case .Resize, .Resize_Non_Zeroed: begin := uintptr(raw_data(s.data)) end := begin + uintptr(len(s.data)) old_ptr := uintptr(old_memory) @@ -278,7 +278,7 @@ scratch_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, case .Query_Features: set := (^Allocator_Mode_Set)(old_memory) if set != nil { - set^ = {.Alloc, .Alloc_Non_Zeroed, .Free, .Free_All, .Resize, .Query_Features} + set^ = {.Alloc, .Alloc_Non_Zeroed, .Free, .Free_All, .Resize, .Resize_Non_Zeroed, .Query_Features} } return nil, nil @@ -406,9 +406,9 @@ stack_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, s.prev_offset = 0 s.curr_offset = 0 - case .Resize: + case .Resize, .Resize_Non_Zeroed: if old_memory == nil { - return raw_alloc(s, size, alignment, true) + return raw_alloc(s, size, alignment, mode == .Resize) } if size == 0 { return nil, nil @@ -434,7 +434,7 @@ stack_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, old_offset := int(curr_addr - uintptr(header.padding) - uintptr(raw_data(s.data))) if old_offset != header.prev_offset { - data, err := raw_alloc(s, size, alignment, true) + data, err := raw_alloc(s, size, alignment, mode == .Resize) if err == nil { runtime.copy(data, byte_slice(old_memory, old_size)) } @@ -455,7 +455,7 @@ stack_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, case .Query_Features: set := (^Allocator_Mode_Set)(old_memory) if set != nil { - set^ = {.Alloc, .Alloc_Non_Zeroed, .Free, .Free_All, .Resize, .Query_Features} + set^ = {.Alloc, .Alloc_Non_Zeroed, .Free, .Free_All, .Resize, .Resize_Non_Zeroed, .Query_Features} } return nil, nil case .Query_Info: @@ -565,9 +565,9 @@ small_stack_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, case .Free_All: s.offset = 0 - case .Resize: + case .Resize, .Resize_Non_Zeroed: if old_memory == nil { - return raw_alloc(s, size, align, true) + return raw_alloc(s, size, align, mode == .Resize) } if size == 0 { return nil, nil @@ -590,7 +590,7 @@ small_stack_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, return byte_slice(old_memory, size), nil } - data, err := raw_alloc(s, size, align, true) + data, err := raw_alloc(s, size, align, mode == .Resize) if err == nil { runtime.copy(data, byte_slice(old_memory, old_size)) } @@ -599,7 +599,7 @@ small_stack_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, case .Query_Features: set := (^Allocator_Mode_Set)(old_memory) if set != nil { - set^ = {.Alloc, .Alloc_Non_Zeroed, .Free, .Free_All, .Resize, .Query_Features} + set^ = {.Alloc, .Alloc_Non_Zeroed, .Free, .Free_All, .Resize, .Resize_Non_Zeroed, .Query_Features} } return nil, nil @@ -649,7 +649,7 @@ dynamic_pool_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode case .Free_All: dynamic_pool_free_all(pool) return nil, nil - case .Resize: + case .Resize, .Resize_Non_Zeroed: if old_size >= size { return byte_slice(old_memory, size), nil } @@ -662,7 +662,7 @@ dynamic_pool_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode case .Query_Features: set := (^Allocator_Mode_Set)(old_memory) if set != nil { - set^ = {.Alloc, .Alloc_Non_Zeroed, .Free_All, .Resize, .Query_Features, .Query_Info} + set^ = {.Alloc, .Alloc_Non_Zeroed, .Free_All, .Resize, .Resize_Non_Zeroed, .Query_Features, .Query_Info} } return nil, nil @@ -826,6 +826,10 @@ panic_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, if size > 0 { panic("mem: panic allocator, .Resize called", loc=loc) } + case .Resize_Non_Zeroed: + if size > 0 { + panic("mem: panic allocator, .Resize_Non_Zeroed called", loc=loc) + } case .Free: if old_memory != nil { panic("mem: panic allocator, .Free called", loc=loc) @@ -958,7 +962,7 @@ tracking_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, if data.clear_on_free_all { clear_map(&data.allocation_map) } - case .Resize: + case .Resize, .Resize_Non_Zeroed: if old_memory != result_ptr { delete_key(&data.allocation_map, old_memory) } diff --git a/core/os/os.odin b/core/os/os.odin index 15864e47e..3210a39d0 100644 --- a/core/os/os.odin +++ b/core/os/os.odin @@ -210,15 +210,15 @@ heap_allocator_proc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode, } } - aligned_resize :: proc(p: rawptr, old_size: int, new_size: int, new_alignment: int) -> (new_memory: []byte, err: mem.Allocator_Error) { + 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) or_return + 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 new_size > old_size { + if zero_memory && new_size > old_size { new_region := mem.raw_data(new_memory[old_size:]) mem.zero(new_region, new_size - old_size) } @@ -235,16 +235,16 @@ 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) + return aligned_alloc(size, alignment, nil, mode == .Resize) } - return aligned_resize(old_memory, old_size, size, alignment) + 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, .Query_Features} + set^ = {.Alloc, .Alloc_Non_Zeroed, .Free, .Resize, .Resize_Non_Zeroed, .Query_Features} } return nil, nil diff --git a/core/runtime/core.odin b/core/runtime/core.odin index 2d176f909..0832ddd13 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -306,6 +306,7 @@ Allocator_Mode :: enum byte { Query_Features, Query_Info, Alloc_Non_Zeroed, + Resize_Non_Zeroed, } Allocator_Mode_Set :: distinct bit_set[Allocator_Mode] diff --git a/core/runtime/core_builtin.odin b/core/runtime/core_builtin.odin index 0348a93df..b597c2486 100644 --- a/core/runtime/core_builtin.odin +++ b/core/runtime/core_builtin.odin @@ -169,10 +169,16 @@ clear :: proc{clear_dynamic_array, clear_map} @builtin reserve :: proc{reserve_dynamic_array, reserve_map} +@builtin +non_zero_reserve :: proc{non_zero_reserve_dynamic_array} + // `resize` will try to resize memory of a passed dynamic array or map to the requested element count (setting the `len`, and possibly `cap`). @builtin resize :: proc{resize_dynamic_array} +@builtin +non_zero_resize :: proc{non_zero_resize_dynamic_array} + // Shrinks the capacity of a dynamic array or map down to the current length, or the given capacity. @builtin shrink :: proc{shrink_dynamic_array, shrink_map} @@ -404,10 +410,7 @@ delete_key :: proc(m: ^$T/map[$K]$V, key: K) -> (deleted_key: K, deleted_value: return } - - -@builtin -append_elem :: proc(array: ^$T/[dynamic]$E, arg: E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { +_append_elem :: #force_inline proc(array: ^$T/[dynamic]$E, arg: E, should_zero: bool, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { if array == nil { return 0, nil } @@ -418,7 +421,13 @@ append_elem :: proc(array: ^$T/[dynamic]$E, arg: E, loc := #caller_location) -> } else { if cap(array) < len(array)+1 { cap := 2 * cap(array) + max(8, 1) - err = reserve(array, cap, loc) // do not 'or_return' here as it could be a partial success + + // do not 'or_return' here as it could be a partial success + if should_zero { + err = reserve(array, cap, loc) + } else { + err = non_zero_reserve(array, cap, loc) + } } if cap(array)-len(array) > 0 { a := (^Raw_Dynamic_Array)(array) @@ -435,7 +444,16 @@ append_elem :: proc(array: ^$T/[dynamic]$E, arg: E, loc := #caller_location) -> } @builtin -append_elems :: proc(array: ^$T/[dynamic]$E, args: ..E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { +append_elem :: proc(array: ^$T/[dynamic]$E, arg: E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { + return _append_elem(array, arg, true, loc=loc) +} + +@builtin +non_zero_append_elem :: proc(array: ^$T/[dynamic]$E, arg: E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { + return _append_elem(array, arg, false, loc=loc) +} + +_append_elems :: #force_inline proc(array: ^$T/[dynamic]$E, should_zero: bool, loc := #caller_location, args: ..E) -> (n: int, err: Allocator_Error) #optional_allocator_error { if array == nil { return 0, nil } @@ -452,7 +470,13 @@ append_elems :: proc(array: ^$T/[dynamic]$E, args: ..E, loc := #caller_location) } else { if cap(array) < len(array)+arg_len { cap := 2 * cap(array) + max(8, arg_len) - err = reserve(array, cap, loc) // do not 'or_return' here as it could be a partial success + + // do not 'or_return' here as it could be a partial success + if should_zero { + err = reserve(array, cap, loc) + } else { + err = non_zero_reserve(array, cap, loc) + } } arg_len = min(cap(array)-len(array), arg_len) if arg_len > 0 { @@ -468,11 +492,33 @@ append_elems :: proc(array: ^$T/[dynamic]$E, args: ..E, loc := #caller_location) } } +@builtin +append_elems :: proc(array: ^$T/[dynamic]$E, args: ..E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { + return _append_elems(array, true, loc, ..args) +} + +@builtin +non_zero_append_elems :: proc(array: ^$T/[dynamic]$E, args: ..E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { + return _append_elems(array, false, loc, ..args) +} + // The append_string built-in procedure appends a string to the end of a [dynamic]u8 like type +_append_elem_string :: proc(array: ^$T/[dynamic]$E/u8, arg: $A/string, should_zero: bool, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { + args := transmute([]E)arg + if should_zero { + return append_elems(array, ..args, loc=loc) + } else { + return non_zero_append_elems(array, ..args, loc=loc) + } +} + @builtin append_elem_string :: proc(array: ^$T/[dynamic]$E/u8, arg: $A/string, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { - args := transmute([]E)arg - return append_elems(array, ..args, loc=loc) + return _append_elem_string(array, arg, true, loc) +} +@builtin +non_zero_append_elem_string :: proc(array: ^$T/[dynamic]$E/u8, arg: $A/string, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { + return _append_elem_string(array, arg, false, loc) } @@ -492,6 +538,7 @@ append_string :: proc(array: ^$T/[dynamic]$E/u8, args: ..string, loc := #caller_ // The append built-in procedure appends elements to the end of a dynamic array @builtin append :: proc{append_elem, append_elems, append_elem_string} +@builtin non_zero_append :: proc{non_zero_append_elem, non_zero_append_elems, non_zero_append_elem_string} @builtin @@ -633,8 +680,7 @@ clear_dynamic_array :: proc "contextless" (array: ^$T/[dynamic]$E) { // `reserve_dynamic_array` will try to reserve memory of a passed dynamic array or map to the requested element count (setting the `cap`). // // Note: Prefer the procedure group `reserve`. -@builtin -reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, capacity: int, loc := #caller_location) -> Allocator_Error { +_reserve_dynamic_array :: #force_inline proc(array: ^$T/[dynamic]$E, capacity: int, should_zero: bool, loc := #caller_location) -> Allocator_Error { if array == nil { return nil } @@ -653,7 +699,12 @@ reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, capacity: int, loc := #cal new_size := capacity * size_of(E) allocator := a.allocator - new_data := mem_resize(a.data, old_size, new_size, align_of(E), allocator, loc) or_return + new_data: []byte + if should_zero { + new_data = mem_resize(a.data, old_size, new_size, align_of(E), allocator, loc) or_return + } else { + new_data = non_zero_mem_resize(a.data, old_size, new_size, align_of(E), allocator, loc) or_return + } if new_data == nil && new_size > 0 { return .Out_Of_Memory } @@ -663,11 +714,20 @@ reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, capacity: int, loc := #cal return nil } +@builtin +reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, capacity: int, loc := #caller_location) -> Allocator_Error { + return _reserve_dynamic_array(array, capacity, true, loc) +} + +@builtin +non_zero_reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, capacity: int, loc := #caller_location) -> Allocator_Error { + return _reserve_dynamic_array(array, capacity, false, loc) +} + // `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`). // // Note: Prefer the procedure group `resize` -@builtin -resize_dynamic_array :: proc(array: ^$T/[dynamic]$E, length: int, loc := #caller_location) -> Allocator_Error { +_resize_dynamic_array :: #force_inline proc(array: ^$T/[dynamic]$E, length: int, should_zero: bool, loc := #caller_location) -> Allocator_Error { if array == nil { return nil } @@ -687,7 +747,12 @@ resize_dynamic_array :: proc(array: ^$T/[dynamic]$E, length: int, loc := #caller new_size := length * size_of(E) allocator := a.allocator - new_data := mem_resize(a.data, old_size, new_size, align_of(E), allocator, loc) or_return + new_data : []byte + if should_zero { + new_data = mem_resize(a.data, old_size, new_size, align_of(E), allocator, loc) or_return + } else { + new_data = non_zero_mem_resize(a.data, old_size, new_size, align_of(E), allocator, loc) or_return + } if new_data == nil && new_size > 0 { return .Out_Of_Memory } @@ -698,6 +763,16 @@ resize_dynamic_array :: proc(array: ^$T/[dynamic]$E, length: int, loc := #caller return nil } +@builtin +resize_dynamic_array :: proc(array: ^$T/[dynamic]$E, length: int, loc := #caller_location) -> Allocator_Error { + return _resize_dynamic_array(array, length, true, loc=loc) +} + +@builtin +non_zero_resize_dynamic_array :: proc(array: ^$T/[dynamic]$E, length: int, loc := #caller_location) -> Allocator_Error { + return _resize_dynamic_array(array, length, false, loc=loc) +} + /* Shrinks the capacity of a dynamic array down to the current length, or the given capacity. diff --git a/core/runtime/default_allocators_arena.odin b/core/runtime/default_allocators_arena.odin index 1c36c4f7c..3d62ba4eb 100644 --- a/core/runtime/default_allocators_arena.odin +++ b/core/runtime/default_allocators_arena.odin @@ -195,7 +195,7 @@ arena_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, err = .Mode_Not_Implemented case .Free_All: arena_free_all(arena, location) - case .Resize: + case .Resize, .Resize_Non_Zeroed: old_data := ([^]byte)(old_memory) switch { diff --git a/core/runtime/default_allocators_nil.odin b/core/runtime/default_allocators_nil.odin index eee6a7998..c882f5196 100644 --- a/core/runtime/default_allocators_nil.odin +++ b/core/runtime/default_allocators_nil.odin @@ -10,7 +10,7 @@ nil_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, return nil, .None case .Free_All: return nil, .Mode_Not_Implemented - case .Resize: + case .Resize, .Resize_Non_Zeroed: if size == 0 { return nil, .None } @@ -55,6 +55,10 @@ panic_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, if size > 0 { panic("panic allocator, .Resize called", loc=loc) } + case .Resize_Non_Zeroed: + if size > 0 { + panic("panic allocator, .Alloc_Non_Zeroed called", loc=loc) + } case .Free: if old_memory != nil { panic("panic allocator, .Free called", loc=loc) diff --git a/core/runtime/internal.odin b/core/runtime/internal.odin index d0e550743..7c91a5ce6 100644 --- a/core/runtime/internal.odin +++ b/core/runtime/internal.odin @@ -187,7 +187,7 @@ mem_free_all :: #force_inline proc(allocator := context.allocator, loc := #calle return } -mem_resize :: proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> (data: []byte, err: Allocator_Error) { +_mem_resize :: #force_inline proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, should_zero: bool, loc := #caller_location) -> (data: []byte, err: Allocator_Error) { if allocator.procedure == nil { return nil, nil } @@ -198,15 +198,27 @@ mem_resize :: proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAUL } return } else if ptr == nil { - return allocator.procedure(allocator.data, .Alloc, new_size, alignment, nil, 0, loc) + if should_zero { + return allocator.procedure(allocator.data, .Alloc, new_size, alignment, nil, 0, loc) + } else { + return allocator.procedure(allocator.data, .Alloc_Non_Zeroed, new_size, alignment, nil, 0, loc) + } } else if old_size == new_size && uintptr(ptr) % uintptr(alignment) == 0 { data = ([^]byte)(ptr)[:old_size] return } - data, err = allocator.procedure(allocator.data, .Resize, new_size, alignment, ptr, old_size, loc) + if should_zero { + data, err = allocator.procedure(allocator.data, .Resize, new_size, alignment, ptr, old_size, loc) + } else { + data, err = allocator.procedure(allocator.data, .Resize_Non_Zeroed, new_size, alignment, ptr, old_size, loc) + } if err == .Mode_Not_Implemented { - data, err = allocator.procedure(allocator.data, .Alloc, new_size, alignment, nil, 0, loc) + if should_zero { + data, err = allocator.procedure(allocator.data, .Alloc, new_size, alignment, nil, 0, loc) + } else { + data, err = allocator.procedure(allocator.data, .Alloc_Non_Zeroed, new_size, alignment, nil, 0, loc) + } if err != nil { return } @@ -216,6 +228,13 @@ mem_resize :: proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAUL return } +mem_resize :: proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> (data: []byte, err: Allocator_Error) { + return _mem_resize(ptr, old_size, new_size, alignment, allocator, true, loc) +} +non_zero_mem_resize :: proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> (data: []byte, err: Allocator_Error) { + return _mem_resize(ptr, old_size, new_size, alignment, allocator, false, loc) +} + memory_equal :: proc "contextless" (x, y: rawptr, n: int) -> bool { switch { case n == 0: return true -- cgit v1.2.3 From bfbeb23f5479af375ceea6d97d2add64a6bc6519 Mon Sep 17 00:00:00 2001 From: Colin Davidson Date: Mon, 4 Dec 2023 03:09:13 -0800 Subject: add resize non zeroed in more places --- core/log/log_allocator.odin | 9 ++++++++- core/mem/virtual/arena.odin | 2 +- core/runtime/default_allocators_windows.odin | 4 ++-- vendor/commonmark/cmark.odin | 4 ++-- vendor/raylib/raylib.odin | 2 +- 5 files changed, 14 insertions(+), 7 deletions(-) (limited to 'core/runtime') diff --git a/core/log/log_allocator.odin b/core/log/log_allocator.odin index 934f0d643..846a84a62 100644 --- a/core/log/log_allocator.odin +++ b/core/log/log_allocator.odin @@ -80,6 +80,13 @@ log_allocator_proc :: proc(allocator_data: rawptr, mode: runtime.Allocator_Mode, la.prefix, padding, old_memory, old_size, size, alignment, location = location, ) + case .Resize_Non_Zeroed: + logf( + la.level, + "%s%s>>> ALLOCATOR(mode=.Resize_Non_Zeroed, ptr=%p, old_size=%d, size=%d, alignment=%d)", + la.prefix, padding, old_memory, old_size, size, alignment, + location = location, + ) case .Query_Features: logf( la.level, @@ -111,4 +118,4 @@ log_allocator_proc :: proc(allocator_data: rawptr, mode: runtime.Allocator_Mode, } } return data, err -} \ No newline at end of file +} diff --git a/core/mem/virtual/arena.odin b/core/mem/virtual/arena.odin index d15df46ad..f6fbe237f 100644 --- a/core/mem/virtual/arena.odin +++ b/core/mem/virtual/arena.odin @@ -288,7 +288,7 @@ arena_allocator_proc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode, err = .Mode_Not_Implemented case .Free_All: arena_free_all(arena, location) - case .Resize: + case .Resize, .Resize_Non_Zeroed: old_data := ([^]byte)(old_memory) switch { diff --git a/core/runtime/default_allocators_windows.odin b/core/runtime/default_allocators_windows.odin index a78a4d04e..1b0f78428 100644 --- a/core/runtime/default_allocators_windows.odin +++ b/core/runtime/default_allocators_windows.odin @@ -19,7 +19,7 @@ when ODIN_DEFAULT_TO_NIL_ALLOCATOR { case .Free_All: return nil, .Mode_Not_Implemented - case .Resize: + case .Resize, .Resize_Non_Zeroed: data, err = _windows_default_resize(old_memory, old_size, size, alignment) case .Query_Features: @@ -41,4 +41,4 @@ when ODIN_DEFAULT_TO_NIL_ALLOCATOR { data = nil, } } -} \ No newline at end of file +} diff --git a/vendor/commonmark/cmark.odin b/vendor/commonmark/cmark.odin index 80e33cec4..05f639371 100644 --- a/vendor/commonmark/cmark.odin +++ b/vendor/commonmark/cmark.odin @@ -507,7 +507,7 @@ cmark_allocator_proc :: proc(allocator_data: rawptr, mode: runtime.Allocator_Mod case .Free_All: return nil, .Mode_Not_Implemented - case .Resize: + case .Resize, .Resize_Non_Zeroed: new_ptr := cmark_alloc.realloc(old_memory, c.size_t(size)) res = transmute([]byte)runtime.Raw_Slice{new_ptr, size} if size > old_size { @@ -529,4 +529,4 @@ get_default_mem_allocator_as_odin :: proc() -> runtime.Allocator { procedure = cmark_allocator_proc, data = rawptr(get_default_mem_allocator()), } -} \ No newline at end of file +} diff --git a/vendor/raylib/raylib.odin b/vendor/raylib/raylib.odin index 21d044145..63c663228 100644 --- a/vendor/raylib/raylib.odin +++ b/vendor/raylib/raylib.odin @@ -1683,7 +1683,7 @@ MemAllocatorProc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode, MemFree(old_memory) return nil, nil - case .Resize: + case .Resize, .Resize_Non_Zeroed: ptr := MemRealloc(old_memory, c.uint(size)) if ptr == nil { err = .Out_Of_Memory -- cgit v1.2.3 From 291a064725c85e7d6a68d0e830a6c967372eae38 Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Mon, 4 Dec 2023 14:57:02 +0100 Subject: fix write on x86_64 Darwin --- core/runtime/os_specific_darwin.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'core/runtime') diff --git a/core/runtime/os_specific_darwin.odin b/core/runtime/os_specific_darwin.odin index 33136c92f..5de9a7d57 100644 --- a/core/runtime/os_specific_darwin.odin +++ b/core/runtime/os_specific_darwin.odin @@ -4,7 +4,7 @@ package runtime import "core:intrinsics" _os_write :: proc "contextless" (data: []byte) -> (int, _OS_Errno) { - ret := intrinsics.syscall(4, 1, uintptr(raw_data(data)), uintptr(len(data))) + ret := intrinsics.syscall(0x2000004, 1, uintptr(raw_data(data)), uintptr(len(data))) if ret < 0 { return 0, _OS_Errno(-ret) } -- cgit v1.2.3 From 29c80c238d7ec2a571fe8e6ac2171235d1b83fd9 Mon Sep 17 00:00:00 2001 From: Yawning Angel Date: Sun, 17 Dec 2023 22:58:44 +0900 Subject: core: Fixed build constraints Multiple constraints on the same line are combined with logical OR, while combining multiple negated constraints needs to be done with logical AND (each constraint on a separate line). --- core/fmt/fmt_os.odin | 3 ++- core/runtime/os_specific_any.odin | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'core/runtime') diff --git a/core/fmt/fmt_os.odin b/core/fmt/fmt_os.odin index 1f0ccf412..3d1b0847b 100644 --- a/core/fmt/fmt_os.odin +++ b/core/fmt/fmt_os.odin @@ -1,4 +1,5 @@ -//+build !freestanding !js +//+build !freestanding +//+build !js package fmt import "core:runtime" diff --git a/core/runtime/os_specific_any.odin b/core/runtime/os_specific_any.odin index 5fffceeeb..6a96655c4 100644 --- a/core/runtime/os_specific_any.odin +++ b/core/runtime/os_specific_any.odin @@ -1,4 +1,8 @@ -//+build !freestanding !wasi !windows !js !darwin +//+build !darwin +//+build !freestanding +//+build !js +//+build !wasi +//+build !windows package runtime import "core:os" -- cgit v1.2.3 From 4ae021cd4cc8fb8a1cf27c0b7c2272ddd025dde0 Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Mon, 18 Dec 2023 15:17:27 +0100 Subject: add other failing test and fix them --- core/runtime/default_allocators_arena.odin | 8 ++++---- tests/core/runtime/test_core_runtime.odin | 13 ++++++++++++- 2 files changed, 16 insertions(+), 5 deletions(-) (limited to 'core/runtime') diff --git a/core/runtime/default_allocators_arena.odin b/core/runtime/default_allocators_arena.odin index 1c36c4f7c..3e78e7f20 100644 --- a/core/runtime/default_allocators_arena.odin +++ b/core/runtime/default_allocators_arena.odin @@ -102,14 +102,14 @@ arena_alloc :: proc(arena: ^Arena, size, alignment: uint, loc := #caller_locatio if size == 0 { return } - - if arena.curr_block == nil || (safe_add(arena.curr_block.used, size) or_else 0) > arena.curr_block.capacity { - size = align_forward_uint(size, alignment) + + needed := align_forward_uint(size, alignment) + if arena.curr_block == nil || (safe_add(arena.curr_block.used, needed) or_else 0) > arena.curr_block.capacity { if arena.minimum_block_size == 0 { arena.minimum_block_size = DEFAULT_ARENA_GROWING_MINIMUM_BLOCK_SIZE } - block_size := max(size, arena.minimum_block_size) + block_size := max(needed, arena.minimum_block_size) if arena.backing_allocator.procedure == nil { arena.backing_allocator = default_allocator() diff --git a/tests/core/runtime/test_core_runtime.odin b/tests/core/runtime/test_core_runtime.odin index 6ec1e78d9..5ae07ffe2 100644 --- a/tests/core/runtime/test_core_runtime.odin +++ b/tests/core/runtime/test_core_runtime.odin @@ -30,6 +30,7 @@ main :: proc() { test_temp_allocator_big_alloc_and_alignment(&t) test_temp_allocator_alignment_boundary(&t) + test_temp_allocator_returns_correct_size(&t) fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) if TEST_fail > 0 { @@ -56,6 +57,16 @@ test_temp_allocator_big_alloc_and_alignment :: proc(t: ^testing.T) { context.allocator = runtime.arena_allocator(&arena) mappy: map[[8]int]int - err := reserve(&mappy, 50000) + err := reserve(&mappy, 50000) expect_value(t, err, nil) } + +@(test) +test_temp_allocator_returns_correct_size :: proc(t: ^testing.T) { + arena: runtime.Arena + context.allocator = runtime.arena_allocator(&arena) + + bytes, err := mem.alloc_bytes(10, 16) + expect_value(t, err, nil) + expect_value(t, len(bytes), 10) +} -- cgit v1.2.3 From 9a490e4e0d6c50b0f27f7844437115a92cb8f2c1 Mon Sep 17 00:00:00 2001 From: Laytan Date: Mon, 18 Dec 2023 16:38:51 +0100 Subject: fix big alignment --- core/mem/virtual/arena.odin | 2 +- core/mem/virtual/virtual.odin | 8 ++++---- core/runtime/default_allocators_arena.odin | 12 ++++++------ 3 files changed, 11 insertions(+), 11 deletions(-) (limited to 'core/runtime') diff --git a/core/mem/virtual/arena.odin b/core/mem/virtual/arena.odin index bc685f0b8..90379e5e6 100644 --- a/core/mem/virtual/arena.odin +++ b/core/mem/virtual/arena.odin @@ -106,7 +106,7 @@ arena_alloc :: proc(arena: ^Arena, size: uint, alignment: uint, loc := #caller_l block_size := max(needed, arena.minimum_block_size) - new_block := memory_block_alloc(needed, block_size, {}) or_return + new_block := memory_block_alloc(needed, block_size, alignment, {}) or_return new_block.prev = arena.curr_block arena.curr_block = new_block arena.total_reserved += new_block.reserved diff --git a/core/mem/virtual/virtual.odin b/core/mem/virtual/virtual.odin index 1624fae9d..89f0d9c58 100644 --- a/core/mem/virtual/virtual.odin +++ b/core/mem/virtual/virtual.odin @@ -68,7 +68,7 @@ align_formula :: #force_inline proc "contextless" (size, align: uint) -> uint { } @(require_results) -memory_block_alloc :: proc(committed, reserved: uint, flags: Memory_Block_Flags) -> (block: ^Memory_Block, err: Allocator_Error) { +memory_block_alloc :: proc(committed, reserved: uint, alignment: uint, flags: Memory_Block_Flags) -> (block: ^Memory_Block, err: Allocator_Error) { page_size := DEFAULT_PAGE_SIZE assert(mem.is_power_of_two(uintptr(page_size))) @@ -79,8 +79,8 @@ memory_block_alloc :: proc(committed, reserved: uint, flags: Memory_Block_Flags) reserved = align_formula(reserved, page_size) committed = clamp(committed, 0, reserved) - total_size := uint(reserved + size_of(Platform_Memory_Block)) - base_offset := uintptr(size_of(Platform_Memory_Block)) + total_size := uint(reserved + max(alignment, size_of(Platform_Memory_Block))) + base_offset := uintptr(max(alignment, size_of(Platform_Memory_Block))) protect_offset := uintptr(0) do_protection := false @@ -183,4 +183,4 @@ memory_block_dealloc :: proc(block_to_free: ^Memory_Block) { safe_add :: #force_inline proc "contextless" (x, y: uint) -> (uint, bool) { z, did_overflow := intrinsics.overflow_add(x, y) return z, !did_overflow -} \ No newline at end of file +} diff --git a/core/runtime/default_allocators_arena.odin b/core/runtime/default_allocators_arena.odin index 3e78e7f20..4506acb56 100644 --- a/core/runtime/default_allocators_arena.odin +++ b/core/runtime/default_allocators_arena.odin @@ -28,11 +28,11 @@ safe_add :: #force_inline proc "contextless" (x, y: uint) -> (uint, bool) { } @(require_results) -memory_block_alloc :: proc(allocator: Allocator, capacity: uint, loc := #caller_location) -> (block: ^Memory_Block, err: Allocator_Error) { - total_size := uint(capacity + size_of(Memory_Block)) - base_offset := uintptr(size_of(Memory_Block)) +memory_block_alloc :: proc(allocator: Allocator, capacity: uint, alignment: uint, loc := #caller_location) -> (block: ^Memory_Block, err: Allocator_Error) { + total_size := uint(capacity + max(alignment, size_of(Memory_Block))) + base_offset := uintptr(max(alignment, size_of(Memory_Block))) - min_alignment: int = max(16, align_of(Memory_Block)) + min_alignment: int = max(16, align_of(Memory_Block), int(alignment)) data := mem_alloc(int(total_size), min_alignment, allocator, loc) or_return block = (^Memory_Block)(raw_data(data)) end := uintptr(raw_data(data)[len(data):]) @@ -115,7 +115,7 @@ arena_alloc :: proc(arena: ^Arena, size, alignment: uint, loc := #caller_locatio arena.backing_allocator = default_allocator() } - new_block := memory_block_alloc(arena.backing_allocator, block_size, loc) or_return + new_block := memory_block_alloc(arena.backing_allocator, block_size, alignment, loc) or_return new_block.prev = arena.curr_block arena.curr_block = new_block arena.total_capacity += new_block.capacity @@ -134,7 +134,7 @@ arena_init :: proc(arena: ^Arena, size: uint, backing_allocator: Allocator, loc arena^ = {} arena.backing_allocator = backing_allocator arena.minimum_block_size = max(size, 1<<12) // minimum block size of 4 KiB - new_block := memory_block_alloc(arena.backing_allocator, arena.minimum_block_size, loc) or_return + new_block := memory_block_alloc(arena.backing_allocator, arena.minimum_block_size, 0, loc) or_return arena.curr_block = new_block arena.total_capacity += new_block.capacity return nil -- cgit v1.2.3 From 829e4cc67e4adb8283813f08f091b71fb94d975d Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 18 Dec 2023 22:22:08 +0000 Subject: Fix `assign_at_elems` to match the same logic as `assign_at_elem_string` --- core/runtime/core_builtin.odin | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'core/runtime') diff --git a/core/runtime/core_builtin.odin b/core/runtime/core_builtin.odin index 0348a93df..eb9315fab 100644 --- a/core/runtime/core_builtin.odin +++ b/core/runtime/core_builtin.odin @@ -234,6 +234,8 @@ delete :: proc{ delete_dynamic_array, delete_slice, delete_map, + delete_soa_slice, + delete_soa_dynamic_array, } @@ -587,11 +589,14 @@ assign_at_elem :: proc(array: ^$T/[dynamic]$E, index: int, arg: E, loc := #calle @builtin assign_at_elems :: proc(array: ^$T/[dynamic]$E, index: int, args: ..E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error { - if index+len(args) < len(array) { + new_size := index + len(arg) + if len(args) == 0 { + ok = true + } else if new_size < len(array) { copy(array[index:], args) ok = true } else { - resize(array, index+1+len(args), loc) or_return + resize(array, new_size, loc) or_return copy(array[index:], args) ok = true } -- cgit v1.2.3 From 1fa2af213debd4a04be1d88105fdddbcaf5fc14a Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Thu, 28 Dec 2023 17:10:08 +0100 Subject: fix typo in assign_at_elems --- core/runtime/core_builtin.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'core/runtime') diff --git a/core/runtime/core_builtin.odin b/core/runtime/core_builtin.odin index eb9315fab..d3ca42454 100644 --- a/core/runtime/core_builtin.odin +++ b/core/runtime/core_builtin.odin @@ -589,7 +589,7 @@ assign_at_elem :: proc(array: ^$T/[dynamic]$E, index: int, arg: E, loc := #calle @builtin assign_at_elems :: proc(array: ^$T/[dynamic]$E, index: int, args: ..E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error { - new_size := index + len(arg) + new_size := index + len(args) if len(args) == 0 { ok = true } else if new_size < len(array) { -- cgit v1.2.3 From b47736260af5316c4d0581464e4c48960a5b7648 Mon Sep 17 00:00:00 2001 From: Alex Ragalie <2127095+aragalie@users.noreply.github.com> Date: Sun, 31 Dec 2023 21:57:39 +0100 Subject: remove duplication --- core/runtime/core_builtin.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'core/runtime') diff --git a/core/runtime/core_builtin.odin b/core/runtime/core_builtin.odin index d3ca42454..c3c5fd5d0 100644 --- a/core/runtime/core_builtin.odin +++ b/core/runtime/core_builtin.odin @@ -348,7 +348,7 @@ make_multi_pointer :: proc($T: typeid/[^]$E, #any_int len: int, allocator := con // // 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, default is context.allocator +// Make uses the specified allocator, default is context.allocator. @builtin make :: proc{ make_slice, -- cgit v1.2.3 From 8a7c2ea9d0e6b55bcfc5068ff2bf7c2a14ccfebf Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Tue, 2 Jan 2024 18:50:00 +0100 Subject: darwin: actually honor no-crt by not linking with `-lSystem -lm` --- core/runtime/procs.odin | 13 ++++++++++++- src/linker.cpp | 9 ++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) (limited to 'core/runtime') diff --git a/core/runtime/procs.odin b/core/runtime/procs.odin index 1592c608b..1b8a54c6d 100644 --- a/core/runtime/procs.odin +++ b/core/runtime/procs.odin @@ -37,7 +37,18 @@ when ODIN_NO_CRT && ODIN_OS == .Windows { } return ptr } - + + @(link_name="bzero", linkage="strong", require) + bzero :: proc "c" (ptr: rawptr, len: int) -> rawptr { + if ptr != nil && len != 0 { + p := ([^]byte)(ptr) + for i := 0; i < len; i += 1 { + p[i] = 0 + } + } + return ptr + } + @(link_name="memmove", linkage="strong", require) memmove :: proc "c" (dst, src: rawptr, len: int) -> rawptr { d, s := ([^]byte)(dst), ([^]byte)(src) diff --git a/src/linker.cpp b/src/linker.cpp index ef9fa8e59..4ab4b2cd1 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -483,10 +483,13 @@ gb_internal i32 linker_stage(LinkerData *gen) { gbString platform_lib_str = gb_string_make(heap_allocator(), ""); defer (gb_string_free(platform_lib_str)); if (build_context.metrics.os == TargetOs_darwin) { - platform_lib_str = gb_string_appendc(platform_lib_str, "-lm -Wl,-syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -L/usr/local/lib"); + platform_lib_str = gb_string_appendc(platform_lib_str, "-Wl,-syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -L/usr/local/lib"); #if defined(GB_SYSTEM_OSX) - if(gen->needs_system_library_linked == 1) { - platform_lib_str = gb_string_appendc(platform_lib_str, " -lSystem "); + if(!build_context.no_crt) { + platform_lib_str = gb_string_appendc(platform_lib_str, " -lm "); + if(gen->needs_system_library_linked == 1) { + platform_lib_str = gb_string_appendc(platform_lib_str, " -lSystem "); + } } #endif } else { -- cgit v1.2.3 From 0b83e3dae5c96550f1500612aa7073ee8f6ae5b6 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 5 Jan 2024 14:29:14 +0000 Subject: Enforce naming the parameters with `builtin.quaternion` to reduce confusion --- core/encoding/json/unmarshal.odin | 6 +- core/math/linalg/general.odin | 2 +- core/runtime/internal.odin | 12 ++-- core/sys/windows/advapi32.odin | 5 ++ examples/demo/demo.odin | 8 ++- src/check_builtin.cpp | 139 ++++++++++++++++++++++++++++++++++---- src/llvm_backend_proc.cpp | 43 ++++++++---- 7 files changed, 174 insertions(+), 41 deletions(-) (limited to 'core/runtime') diff --git a/core/encoding/json/unmarshal.odin b/core/encoding/json/unmarshal.odin index afcc43c0c..c1905f6b0 100644 --- a/core/encoding/json/unmarshal.odin +++ b/core/encoding/json/unmarshal.odin @@ -137,9 +137,9 @@ assign_float :: proc(val: any, f: $T) -> bool { case complex64: dst = complex(f32(f), 0) case complex128: dst = complex(f64(f), 0) - case quaternion64: dst = quaternion(f16(f), 0, 0, 0) - case quaternion128: dst = quaternion(f32(f), 0, 0, 0) - case quaternion256: dst = quaternion(f64(f), 0, 0, 0) + case quaternion64: dst = quaternion(w=f16(f), x=0, y=0, z=0) + case quaternion128: dst = quaternion(w=f32(f), x=0, y=0, z=0) + case quaternion256: dst = quaternion(w=f64(f), x=0, y=0, z=0) case: return false } diff --git a/core/math/linalg/general.odin b/core/math/linalg/general.odin index b58305c63..a61fe9189 100644 --- a/core/math/linalg/general.odin +++ b/core/math/linalg/general.odin @@ -70,7 +70,7 @@ outer_product :: builtin.outer_product @(require_results) quaternion_inverse :: proc "contextless" (q: $Q) -> Q where IS_QUATERNION(Q) { - return conj(q) * quaternion(1.0/dot(q, q), 0, 0, 0) + return conj(q) * quaternion(w=1.0/dot(q, q), x=0, y=0, z=0) } diff --git a/core/runtime/internal.odin b/core/runtime/internal.odin index d0e550743..0d7bdee8b 100644 --- a/core/runtime/internal.odin +++ b/core/runtime/internal.odin @@ -730,7 +730,7 @@ mul_quaternion64 :: proc "contextless" (q, r: quaternion64) -> quaternion64 { t2 := r0*q2 + r1*q3 + r2*q0 - r3*q1 t3 := r0*q3 - r1*q2 + r2*q1 + r3*q0 - return quaternion(t0, t1, t2, t3) + return quaternion(w=t0, x=t1, y=t2, z=t3) } mul_quaternion128 :: proc "contextless" (q, r: quaternion128) -> quaternion128 { @@ -742,7 +742,7 @@ mul_quaternion128 :: proc "contextless" (q, r: quaternion128) -> quaternion128 { t2 := r0*q2 + r1*q3 + r2*q0 - r3*q1 t3 := r0*q3 - r1*q2 + r2*q1 + r3*q0 - return quaternion(t0, t1, t2, t3) + return quaternion(w=t0, x=t1, y=t2, z=t3) } mul_quaternion256 :: proc "contextless" (q, r: quaternion256) -> quaternion256 { @@ -754,7 +754,7 @@ mul_quaternion256 :: proc "contextless" (q, r: quaternion256) -> quaternion256 { t2 := r0*q2 + r1*q3 + r2*q0 - r3*q1 t3 := r0*q3 - r1*q2 + r2*q1 + r3*q0 - return quaternion(t0, t1, t2, t3) + return quaternion(w=t0, x=t1, y=t2, z=t3) } quo_quaternion64 :: proc "contextless" (q, r: quaternion64) -> quaternion64 { @@ -768,7 +768,7 @@ quo_quaternion64 :: proc "contextless" (q, r: quaternion64) -> quaternion64 { t2 := (r0*q2 - r1*q3 - r2*q0 + r3*q1) * invmag2 t3 := (r0*q3 + r1*q2 + r2*q1 - r3*q0) * invmag2 - return quaternion(t0, t1, t2, t3) + return quaternion(w=t0, x=t1, y=t2, z=t3) } quo_quaternion128 :: proc "contextless" (q, r: quaternion128) -> quaternion128 { @@ -782,7 +782,7 @@ quo_quaternion128 :: proc "contextless" (q, r: quaternion128) -> quaternion128 { t2 := (r0*q2 - r1*q3 - r2*q0 + r3*q1) * invmag2 t3 := (r0*q3 + r1*q2 + r2*q1 - r3*q0) * invmag2 - return quaternion(t0, t1, t2, t3) + return quaternion(w=t0, x=t1, y=t2, z=t3) } quo_quaternion256 :: proc "contextless" (q, r: quaternion256) -> quaternion256 { @@ -796,7 +796,7 @@ quo_quaternion256 :: proc "contextless" (q, r: quaternion256) -> quaternion256 { t2 := (r0*q2 - r1*q3 - r2*q0 + r3*q1) * invmag2 t3 := (r0*q3 + r1*q2 + r2*q1 - r3*q0) * invmag2 - return quaternion(t0, t1, t2, t3) + return quaternion(w=t0, x=t1, y=t2, z=t3) } @(link_name="__truncsfhf2", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE) diff --git a/core/sys/windows/advapi32.odin b/core/sys/windows/advapi32.odin index dc7ec1e08..86e173211 100644 --- a/core/sys/windows/advapi32.odin +++ b/core/sys/windows/advapi32.odin @@ -13,6 +13,11 @@ foreign advapi32 { DesiredAccess: DWORD, TokenHandle: ^HANDLE) -> BOOL --- + OpenThreadToken :: proc(ThreadHandle: HANDLE, + DesiredAccess: DWORD, + OpenAsSelf: BOOL, + TokenHandle: ^HANDLE) -> BOOL --- + CryptAcquireContextW :: proc(hProv: ^HCRYPTPROV, szContainer, szProvider: wstring, dwProvType, dwFlags: DWORD) -> DWORD --- CryptGenRandom :: proc(hProv: HCRYPTPROV, dwLen: DWORD, buf: LPVOID) -> DWORD --- CryptReleaseContext :: proc(hProv: HCRYPTPROV, dwFlags: DWORD) -> DWORD --- diff --git a/examples/demo/demo.odin b/examples/demo/demo.odin index b890d5778..bc6a4d9ea 100644 --- a/examples/demo/demo.odin +++ b/examples/demo/demo.odin @@ -1514,7 +1514,7 @@ quaternions :: proc() { { // Quaternion operations q := 1 + 2i + 3j + 4k - r := quaternion(5, 6, 7, 8) + r := quaternion(real=5, imag=6, jmag=7, kmag=8) t := q * r fmt.printf("(%v) * (%v) = %v\n", q, r, t) v := q / r @@ -1527,8 +1527,10 @@ quaternions :: proc() { { // The quaternion types q128: quaternion128 // 4xf32 q256: quaternion256 // 4xf64 - q128 = quaternion(1, 0, 0, 0) - q256 = 1 // quaternion(1, 0, 0, 0) + q128 = quaternion(w=1, x=0, y=0, z=0) + q256 = 1 // quaternion(x=0, y=0, z=0, w=1) + + // NOTE: The internal memory layout of a quaternion is xyzw } { // Built-in procedures q := 1 + 2i + 3j + 4k diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index b3aaab754..55962f89f 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -1666,7 +1666,12 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As if (ce->args.count > 0) { if (ce->args[0]->kind == Ast_FieldValue) { - if (id != BuiltinProc_soa_zip) { + switch (id) { + case BuiltinProc_soa_zip: + case BuiltinProc_quaternion: + // okay + break; + default: error(call, "'field = value' calling is not allowed on built-in procedures"); return false; } @@ -2299,8 +2304,32 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As } case BuiltinProc_quaternion: { + bool first_is_field_value = (ce->args[0]->kind == Ast_FieldValue); + + bool fail = false; + for (Ast *arg : ce->args) { + bool mix = false; + if (first_is_field_value) { + mix = arg->kind != Ast_FieldValue; + } else { + mix = arg->kind == Ast_FieldValue; + } + if (mix) { + error(arg, "Mixture of 'field = value' and value elements in the procedure call '%.*s' is not allowed", LIT(builtin_name)); + fail = true; + break; + } + } + + if (fail) { + operand->type = t_untyped_quaternion; + operand->mode = Addressing_Constant; + operand->value = exact_value_quaternion(0.0, 0.0, 0.0, 0.0); + break; + } + // quaternion :: proc(real, imag, jmag, kmag: float_type) -> complex_type - Operand x = *operand; + Operand x = {}; Operand y = {}; Operand z = {}; Operand w = {}; @@ -2309,23 +2338,103 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As operand->type = t_invalid; operand->mode = Addressing_Invalid; - check_expr(c, &y, ce->args[1]); - if (y.mode == Addressing_Invalid) { - return false; - } - check_expr(c, &z, ce->args[2]); - if (y.mode == Addressing_Invalid) { - return false; - } - check_expr(c, &w, ce->args[3]); - if (y.mode == Addressing_Invalid) { - return false; - } + if (first_is_field_value) { + u32 fields_set[4] = {}; // 0 unset, 1 xyzw, 2 real/etc + + auto const check_field = [&fields_set, &builtin_name](CheckerContext *c, Operand *o, Ast *arg, i32 *index) -> bool { + *index = -1; + + ast_node(field, FieldValue, arg); + String name = {}; + if (field->field->kind == Ast_Ident) { + name = field->field->Ident.token.string; + } else { + error(field->field, "Expected an identifier for field argument"); + return false; + } + + u32 style = 0; + + if (name == "x") { + *index = 1; style = 1; + } else if (name == "y") { + *index = 2; style = 1; + } else if (name == "z") { + *index = 3; style = 1; + } else if (name == "w") { + *index = 0; style = 1; + } else if (name == "imag") { + *index = 1; style = 2; + } else if (name == "jmag") { + *index = 2; style = 2; + } else if (name == "kmag") { + *index = 3; style = 2; + } else if (name == "real") { + *index = 0; style = 2; + } else { + error(field->field, "Unknown name for '%.*s', expected (w, x, y, z; or real, imag, jmag, kmag), got '%.*s'", LIT(builtin_name), LIT(name)); + return false; + } + + if (fields_set[*index]) { + error(field->field, "Previously assigned field: '%.*s'", LIT(name)); + } + fields_set[*index] = style; + + check_expr(c, o, field->value); + return o->mode != Addressing_Invalid; + }; + + // TODO(bill): disallow style mixing + Operand *refs[4] = {&x, &y, &z, &w}; + + for (i32 i = 0; i < 4; i++) { + i32 index = -1; + Operand o = {}; + bool ok = check_field(c, &o, ce->args[i], &index); + if (!ok) { + return false; + } + + *refs[index] = o; + } + + for (i32 i = 0; i < 4; i++) { + GB_ASSERT(fields_set[i]); + } + for (i32 i = 1; i < 4; i++) { + if (fields_set[i] != fields_set[i-1]) { + error(call, "Mixture of xyzw and real/etc is not allowed with '%.*s'", LIT(builtin_name)); + break; + } + } + } else { + error(call, "'%.*s' requires that all arguments are named (w, x, y, z; or real, imag, jmag, kmag)", LIT(builtin_name)); + + check_expr(c, &x, ce->args[0]); + if (x.mode == Addressing_Invalid) { + return false; + } + + check_expr(c, &y, ce->args[1]); + if (y.mode == Addressing_Invalid) { + return false; + } + check_expr(c, &z, ce->args[2]); + if (z.mode == Addressing_Invalid) { + return false; + } + check_expr(c, &w, ce->args[3]); + if (w.mode == Addressing_Invalid) { + return false; + } + } convert_to_typed(c, &x, y.type); if (x.mode == Addressing_Invalid) return false; convert_to_typed(c, &y, x.type); if (y.mode == Addressing_Invalid) return false; convert_to_typed(c, &z, x.type); if (z.mode == Addressing_Invalid) return false; convert_to_typed(c, &w, x.type); if (w.mode == Addressing_Invalid) return false; + if (x.mode == Addressing_Constant && y.mode == Addressing_Constant && z.mode == Addressing_Constant && @@ -3092,7 +3201,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As mix = arg->kind == Ast_FieldValue; } if (mix) { - error(arg, "Mixture of 'field = value' and value elements in the procedure call 'soa_zip' is not allowed"); + error(arg, "Mixture of 'field = value' and value elements in the procedure call '%.*s' is not allowed", LIT(builtin_name)); fail = true; break; } diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 1244bd377..3f16d07a5 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -1826,24 +1826,41 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu } case BuiltinProc_quaternion: { - lbValue real = lb_build_expr(p, ce->args[0]); - lbValue imag = lb_build_expr(p, ce->args[1]); - lbValue jmag = lb_build_expr(p, ce->args[2]); - lbValue kmag = lb_build_expr(p, ce->args[3]); + lbValue xyzw[4] = {}; + for (i32 i = 0; i < 4; i++) { + ast_node(f, FieldValue, ce->args[i]); + GB_ASSERT(f->field->kind == Ast_Ident); + String name = f->field->Ident.token.string; + i32 index = -1; + + // @QuaternionLayout + if (name == "x" || name == "imag") { + index = 0; + } else if (name == "y" || name == "jmag") { + index = 1; + } else if (name == "z" || name == "kmag") { + index = 2; + } else if (name == "w" || name == "real") { + index = 3; + } + GB_ASSERT(index >= 0); + + xyzw[index] = lb_build_expr(p, ce->args[i]); + } + - // @QuaternionLayout lbAddr dst_addr = lb_add_local_generated(p, tv.type, false); lbValue dst = lb_addr_get_ptr(p, dst_addr); Type *ft = base_complex_elem_type(tv.type); - real = lb_emit_conv(p, real, ft); - imag = lb_emit_conv(p, imag, ft); - jmag = lb_emit_conv(p, jmag, ft); - kmag = lb_emit_conv(p, kmag, ft); - lb_emit_store(p, lb_emit_struct_ep(p, dst, 3), real); - lb_emit_store(p, lb_emit_struct_ep(p, dst, 0), imag); - lb_emit_store(p, lb_emit_struct_ep(p, dst, 1), jmag); - lb_emit_store(p, lb_emit_struct_ep(p, dst, 2), kmag); + xyzw[0] = lb_emit_conv(p, xyzw[0], ft); + xyzw[1] = lb_emit_conv(p, xyzw[1], ft); + xyzw[2] = lb_emit_conv(p, xyzw[2], ft); + xyzw[3] = lb_emit_conv(p, xyzw[3], ft); + lb_emit_store(p, lb_emit_struct_ep(p, dst, 0), xyzw[0]); + lb_emit_store(p, lb_emit_struct_ep(p, dst, 1), xyzw[1]); + lb_emit_store(p, lb_emit_struct_ep(p, dst, 2), xyzw[2]); + lb_emit_store(p, lb_emit_struct_ep(p, dst, 3), xyzw[3]); return lb_emit_load(p, dst); } -- cgit v1.2.3 From f4782157d3b586a88983d3b770c2c0eeb17946d1 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 7 Jan 2024 21:34:44 +0000 Subject: Implement instrumentation pass --- core/runtime/core.odin | 1 + core/runtime/entry_unix.odin | 1 + core/runtime/entry_wasm.odin | 1 + core/runtime/entry_windows.odin | 1 + core/runtime/error_checks.odin | 24 ++++++----- core/runtime/procs_windows_amd64.odin | 1 + core/runtime/procs_windows_i386.odin | 1 + src/check_decl.cpp | 26 ++++++++---- src/entity.cpp | 2 +- src/llvm_backend.cpp | 2 - src/llvm_backend.hpp | 2 +- src/llvm_backend_general.cpp | 13 ++++++ src/llvm_backend_opt.cpp | 77 +++++++++++++++++++++++++++++++++++ src/llvm_backend_proc.cpp | 12 ++++++ 14 files changed, 143 insertions(+), 21 deletions(-) (limited to 'core/runtime') diff --git a/core/runtime/core.odin b/core/runtime/core.odin index 2d176f909..e12d9a43d 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -18,6 +18,7 @@ // This could change at a later date if the all these data structures are // implemented within the compiler rather than in this "preload" file // +//+no-instrumentation package runtime import "core:intrinsics" diff --git a/core/runtime/entry_unix.odin b/core/runtime/entry_unix.odin index 78e545c22..f494a509e 100644 --- a/core/runtime/entry_unix.odin +++ b/core/runtime/entry_unix.odin @@ -1,5 +1,6 @@ //+private //+build linux, darwin, freebsd, openbsd +//+no-instrumentation package runtime import "core:intrinsics" diff --git a/core/runtime/entry_wasm.odin b/core/runtime/entry_wasm.odin index 235d5611b..e7f3f156f 100644 --- a/core/runtime/entry_wasm.odin +++ b/core/runtime/entry_wasm.odin @@ -1,5 +1,6 @@ //+private //+build wasm32, wasm64p32 +//+no-instrumentation package runtime import "core:intrinsics" diff --git a/core/runtime/entry_windows.odin b/core/runtime/entry_windows.odin index a315c1209..277daecca 100644 --- a/core/runtime/entry_windows.odin +++ b/core/runtime/entry_windows.odin @@ -1,5 +1,6 @@ //+private //+build windows +//+no-instrumentation package runtime import "core:intrinsics" diff --git a/core/runtime/error_checks.odin b/core/runtime/error_checks.odin index 9d484979a..ea6333c29 100644 --- a/core/runtime/error_checks.odin +++ b/core/runtime/error_checks.odin @@ -1,5 +1,6 @@ package runtime +@(no_instrumentation) bounds_trap :: proc "contextless" () -> ! { when ODIN_OS == .Windows { windows_trap_array_bounds() @@ -8,6 +9,7 @@ bounds_trap :: proc "contextless" () -> ! { } } +@(no_instrumentation) type_assertion_trap :: proc "contextless" () -> ! { when ODIN_OS == .Windows { windows_trap_type_assertion() @@ -21,7 +23,7 @@ bounds_check_error :: proc "contextless" (file: string, line, column: i32, index if uint(index) < uint(count) { return } - @(cold) + @(cold, no_instrumentation) handle_error :: proc "contextless" (file: string, line, column: i32, index, count: int) -> ! { print_caller_location(Source_Code_Location{file, line, column, ""}) print_string(" Index ") @@ -34,6 +36,7 @@ bounds_check_error :: proc "contextless" (file: string, line, column: i32, index handle_error(file, line, column, index, count) } +@(no_instrumentation) slice_handle_error :: proc "contextless" (file: string, line, column: i32, lo, hi: int, len: int) -> ! { print_caller_location(Source_Code_Location{file, line, column, ""}) print_string(" Invalid slice indices ") @@ -46,6 +49,7 @@ slice_handle_error :: proc "contextless" (file: string, line, column: i32, lo, h bounds_trap() } +@(no_instrumentation) multi_pointer_slice_handle_error :: proc "contextless" (file: string, line, column: i32, lo, hi: int) -> ! { print_caller_location(Source_Code_Location{file, line, column, ""}) print_string(" Invalid slice indices ") @@ -82,7 +86,7 @@ dynamic_array_expr_error :: proc "contextless" (file: string, line, column: i32, if 0 <= low && low <= high && high <= max { return } - @(cold) + @(cold, no_instrumentation) handle_error :: proc "contextless" (file: string, line, column: i32, low, high, max: int) -> ! { print_caller_location(Source_Code_Location{file, line, column, ""}) print_string(" Invalid dynamic array indices ") @@ -103,7 +107,7 @@ matrix_bounds_check_error :: proc "contextless" (file: string, line, column: i32 uint(column_index) < uint(column_count) { return } - @(cold) + @(cold, no_instrumentation) handle_error :: proc "contextless" (file: string, line, column: i32, row_index, column_index, row_count, column_count: int) -> ! { print_caller_location(Source_Code_Location{file, line, column, ""}) print_string(" Matrix indices [") @@ -127,7 +131,7 @@ when ODIN_NO_RTTI { if ok { return } - @(cold) + @(cold, no_instrumentation) handle_error :: proc "contextless" (file: string, line, column: i32) -> ! { print_caller_location(Source_Code_Location{file, line, column, ""}) print_string(" Invalid type assertion\n") @@ -140,7 +144,7 @@ when ODIN_NO_RTTI { if ok { return } - @(cold) + @(cold, no_instrumentation) handle_error :: proc "contextless" (file: string, line, column: i32) -> ! { print_caller_location(Source_Code_Location{file, line, column, ""}) print_string(" Invalid type assertion\n") @@ -153,7 +157,7 @@ when ODIN_NO_RTTI { if ok { return } - @(cold) + @(cold, no_instrumentation) handle_error :: proc "contextless" (file: string, line, column: i32, from, to: typeid) -> ! { print_caller_location(Source_Code_Location{file, line, column, ""}) print_string(" Invalid type assertion from ") @@ -198,7 +202,7 @@ when ODIN_NO_RTTI { return id } - @(cold) + @(cold, no_instrumentation) handle_error :: proc "contextless" (file: string, line, column: i32, from, to: typeid, from_data: rawptr) -> ! { actual := variant_type(from, from_data) @@ -224,7 +228,7 @@ make_slice_error_loc :: #force_inline proc "contextless" (loc := #caller_locatio if 0 <= len { return } - @(cold) + @(cold, no_instrumentation) handle_error :: proc "contextless" (loc: Source_Code_Location, len: int) -> ! { print_caller_location(loc) print_string(" Invalid slice length for make: ") @@ -239,7 +243,7 @@ make_dynamic_array_error_loc :: #force_inline proc "contextless" (loc := #caller if 0 <= len && len <= cap { return } - @(cold) + @(cold, no_instrumentation) handle_error :: proc "contextless" (loc: Source_Code_Location, len, cap: int) -> ! { print_caller_location(loc) print_string(" Invalid dynamic array parameters for make: ") @@ -256,7 +260,7 @@ make_map_expr_error_loc :: #force_inline proc "contextless" (loc := #caller_loca if 0 <= cap { return } - @(cold) + @(cold, no_instrumentation) handle_error :: proc "contextless" (loc: Source_Code_Location, cap: int) -> ! { print_caller_location(loc) print_string(" Invalid map capacity for make: ") diff --git a/core/runtime/procs_windows_amd64.odin b/core/runtime/procs_windows_amd64.odin index e430357be..a30985d5c 100644 --- a/core/runtime/procs_windows_amd64.odin +++ b/core/runtime/procs_windows_amd64.odin @@ -1,4 +1,5 @@ //+private +//+no-instrumentation package runtime foreign import kernel32 "system:Kernel32.lib" diff --git a/core/runtime/procs_windows_i386.odin b/core/runtime/procs_windows_i386.odin index f810197f1..4f606da8f 100644 --- a/core/runtime/procs_windows_i386.odin +++ b/core/runtime/procs_windows_i386.odin @@ -1,4 +1,5 @@ //+private +//+no-instrumentation package runtime @require foreign import "system:int64.lib" diff --git a/src/check_decl.cpp b/src/check_decl.cpp index c69d8185e..a530945f9 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -910,24 +910,24 @@ gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { e->Procedure.entry_point_only = ac.entry_point_only; e->Procedure.is_export = ac.is_export; - bool no_instrumentation = false; + bool has_instrumentation = false; if (pl->body == nullptr) { - no_instrumentation = true; + has_instrumentation = false; if (ac.no_instrumentation != Instrumentation_Default) { error(e->token, "@(no_instrumentation) is not allowed on foreign procedures"); } } else { - if (e->file) { - no_instrumentation = (e->file->flags & AstFile_NoInstrumentation) != 0; + AstFile *file = e->token.pos.file_id ? global_files[e->token.pos.file_id] : nullptr; + if (file) { + has_instrumentation = (file->flags & AstFile_NoInstrumentation) == 0; } switch (ac.no_instrumentation) { - case Instrumentation_Enabled: no_instrumentation = false; break; + case Instrumentation_Enabled: has_instrumentation = true; break; case Instrumentation_Default: break; - case Instrumentation_Disabled: no_instrumentation = true; break; + case Instrumentation_Disabled: has_instrumentation = false; break; } } - e->Procedure.no_instrumentation = no_instrumentation; auto const is_valid_instrumentation_call = [](Type *type) -> bool { if (type == nullptr || type->kind != Type_Proc) { @@ -949,6 +949,9 @@ gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { if (ac.instrumentation_enter && ac.instrumentation_exit) { error(e->token, "A procedure cannot be marked with both @(instrumentation_enter) and @(instrumentation_exit)"); + + has_instrumentation = false; + e->flags |= EntityFlag_Require; } else if (ac.instrumentation_enter) { if (!is_valid_instrumentation_call(e->type)) { gbString s = type_to_string(e->type); @@ -961,6 +964,9 @@ gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { } else { ctx->info->instrumentation_enter_entity = e; } + + has_instrumentation = false; + e->flags |= EntityFlag_Require; } else if (ac.instrumentation_exit) { if (!is_valid_instrumentation_call(e->type)) { gbString s = type_to_string(e->type); @@ -973,8 +979,14 @@ gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { } else { ctx->info->instrumentation_exit_entity = e; } + + has_instrumentation = false; + e->flags |= EntityFlag_Require; } + e->Procedure.has_instrumentation = has_instrumentation; + + e->deprecated_message = ac.deprecated_message; e->warning_message = ac.warning_message; ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix); diff --git a/src/entity.cpp b/src/entity.cpp index 0539386d0..e6c46d37e 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -251,7 +251,7 @@ struct Entity { bool generated_from_polymorphic : 1; bool target_feature_disabled : 1; bool entry_point_only : 1; - bool no_instrumentation : 1; + bool has_instrumentation : 1; String target_feature; } Procedure; struct { diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index b90fd8495..0175d039e 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -1497,8 +1497,6 @@ gb_internal WORKER_TASK_PROC(lb_llvm_module_pass_worker_proc) { auto passes = array_make(heap_allocator(), 0, 64); defer (array_free(&passes)); - - LLVMPassBuilderOptionsRef pb_options = LLVMCreatePassBuilderOptions(); defer (LLVMDisposePassBuilderOptions(pb_options)); diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index 4e193bcea..b645d66d6 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -563,7 +563,7 @@ gb_internal LLVMTypeRef OdinLLVMGetVectorElementType(LLVMTypeRef type); gb_internal String lb_filepath_ll_for_module(lbModule *m); - +gb_internal LLVMTypeRef lb_type_internal_for_procedures_raw(lbModule *m, Type *type); gb_internal LLVMTypeRef llvm_array_type(LLVMTypeRef ElementType, uint64_t ElementCount) { #if LB_USE_NEW_PASS_SYSTEM diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 54327cc54..f0f5327c6 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -2348,6 +2348,15 @@ gb_internal LLVMAttributeRef lb_create_enum_attribute(LLVMContextRef ctx, char c return LLVMCreateEnumAttribute(ctx, kind, value); } +gb_internal LLVMAttributeRef lb_create_string_attribute(LLVMContextRef ctx, String const &key, String const &value) { + LLVMAttributeRef attr = LLVMCreateStringAttribute( + ctx, + cast(char const *)key.text, cast(unsigned)key.len, + cast(char const *)value.text, cast(unsigned)value.len); + return attr; +} + + gb_internal void lb_add_proc_attribute_at_index(lbProcedure *p, isize index, char const *name, u64 value) { LLVMAttributeRef attr = lb_create_enum_attribute(p->module->ctx, name, value); GB_ASSERT(attr != nullptr); @@ -2361,6 +2370,10 @@ gb_internal void lb_add_proc_attribute_at_index(lbProcedure *p, isize index, cha gb_internal void lb_add_attribute_to_proc(lbModule *m, LLVMValueRef proc_value, char const *name, u64 value=0) { LLVMAddAttributeAtIndex(proc_value, LLVMAttributeIndex_FunctionIndex, lb_create_enum_attribute(m->ctx, name, value)); } +gb_internal void lb_add_attribute_to_proc_with_string(lbModule *m, LLVMValueRef proc_value, String const &name, String const &value) { + LLVMAttributeRef attr = lb_create_string_attribute(m->ctx, name, value); + LLVMAddAttributeAtIndex(proc_value, LLVMAttributeIndex_FunctionIndex, attr); +} diff --git a/src/llvm_backend_opt.cpp b/src/llvm_backend_opt.cpp index 2e03b7974..d5487d259 100644 --- a/src/llvm_backend_opt.cpp +++ b/src/llvm_backend_opt.cpp @@ -380,6 +380,80 @@ gb_internal void lb_run_remove_dead_instruction_pass(lbProcedure *p) { } } +gb_internal LLVMValueRef lb_run_instrumentation_pass_insert_call(lbProcedure *p, Entity *entity, LLVMBuilderRef dummy_builder) { + lbModule *m = p->module; + + lbValue cc = lb_find_procedure_value_from_entity(m, entity); + + LLVMValueRef args[2] = {}; + args[0] = p->value; + + LLVMValueRef returnaddress_args[1] = {}; + + returnaddress_args[0] = LLVMConstInt(LLVMInt32TypeInContext(m->ctx), 0, false); + + char const *instrinsic_name = "llvm.returnaddress"; + unsigned id = LLVMLookupIntrinsicID(instrinsic_name, gb_strlen(instrinsic_name)); + GB_ASSERT_MSG(id != 0, "Unable to find %s", instrinsic_name); + LLVMValueRef ip = LLVMGetIntrinsicDeclaration(m->mod, id, nullptr, 0); + LLVMTypeRef call_type = LLVMIntrinsicGetType(m->ctx, id, nullptr, 0); + args[1] = LLVMBuildCall2(dummy_builder, call_type, ip, returnaddress_args, gb_count_of(returnaddress_args), ""); + + LLVMTypeRef fnp = lb_type_internal_for_procedures_raw(p->module, entity->type); + return LLVMBuildCall2(dummy_builder, fnp, cc.value, args, 2, ""); +} + + +gb_internal void lb_run_instrumentation_pass(lbProcedure *p) { + lbModule *m = p->module; + Entity *enter = m->info->instrumentation_enter_entity; + Entity *exit = m->info->instrumentation_exit_entity; + if (enter == nullptr || exit == nullptr) { + return; + } + if (!(p->entity && + p->entity->kind == Entity_Procedure && + p->entity->Procedure.has_instrumentation)) { + return; + } + +#define LLVM_V_NAME(x) x, cast(unsigned)(gb_count_of(x)-1) + + LLVMBuilderRef dummy_builder = LLVMCreateBuilderInContext(m->ctx); + defer (LLVMDisposeBuilder(dummy_builder)); + + LLVMBasicBlockRef entry_bb = p->entry_block->block; + LLVMPositionBuilder(dummy_builder, entry_bb, LLVMGetFirstInstruction(entry_bb)); + lb_run_instrumentation_pass_insert_call(p, enter, dummy_builder); + LLVMRemoveStringAttributeAtIndex(p->value, LLVMAttributeIndex_FunctionIndex, LLVM_V_NAME("instrument-function-entry")); + + unsigned bb_count = LLVMCountBasicBlocks(p->value); + LLVMBasicBlockRef *bbs = gb_alloc_array(temporary_allocator(), LLVMBasicBlockRef, bb_count); + LLVMGetBasicBlocks(p->value, bbs); + for (unsigned i = 0; i < bb_count; i++) { + LLVMBasicBlockRef bb = bbs[i]; + LLVMValueRef terminator = LLVMGetBasicBlockTerminator(bb); + if (terminator == nullptr || + !LLVMIsAReturnInst(terminator)) { + continue; + } + + // TODO(bill): getTerminatingMustTailCall() + // If T is preceded by a musttail call, that's the real terminator. + // if (CallInst *CI = BB.getTerminatingMustTailCall()) + // T = CI; + + + LLVMPositionBuilderBefore(dummy_builder, terminator); + lb_run_instrumentation_pass_insert_call(p, exit, dummy_builder); + } + + LLVMRemoveStringAttributeAtIndex(p->value, LLVMAttributeIndex_FunctionIndex, LLVM_V_NAME("instrument-function-exit")); + +#undef LLVM_V_NAME +} + + gb_internal void lb_run_function_pass_manager(LLVMPassManagerRef fpm, lbProcedure *p, lbFunctionPassManagerKind pass_manager_kind) { if (p == nullptr) { @@ -401,6 +475,7 @@ gb_internal void lb_run_function_pass_manager(LLVMPassManagerRef fpm, lbProcedur } break; } + lb_run_instrumentation_pass(p); LLVMRunFunctionPassManager(fpm, p->value); } @@ -552,3 +627,5 @@ gb_internal void lb_run_remove_unused_globals_pass(lbModule *m) { } } } + + diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index d4eae84bc..09bebd0cf 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -329,6 +329,18 @@ gb_internal lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool i } } + if (p->body && entity->Procedure.has_instrumentation) { + Entity *instrumentation_enter = m->info->instrumentation_enter_entity; + Entity *instrumentation_exit = m->info->instrumentation_exit_entity; + if (instrumentation_enter && instrumentation_exit) { + String enter = lb_get_entity_name(m, instrumentation_enter); + String exit = lb_get_entity_name(m, instrumentation_exit); + + lb_add_attribute_to_proc_with_string(m, p->value, make_string_c("instrument-function-entry"), enter); + lb_add_attribute_to_proc_with_string(m, p->value, make_string_c("instrument-function-exit"), exit); + } + } + lbValue proc_value = {p->value, p->type}; lb_add_entity(m, entity, proc_value); lb_add_member(m, p->name, proc_value); -- cgit v1.2.3 From 90ac400ec5a60a99fe16f2669edd22e4be14cf83 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 17 Jan 2024 17:25:23 +0000 Subject: stdcall -> system --- core/mem/virtual/virtual_windows.odin | 2 +- core/runtime/entry_windows.odin | 4 ++-- core/runtime/os_specific_windows.odin | 2 +- core/runtime/procs.odin | 2 +- core/runtime/procs_windows_amd64.odin | 2 +- core/runtime/procs_windows_i386.odin | 2 +- core/sync/futex_windows.odin | 6 +++--- core/sys/windows/dnsapi.odin | 2 +- core/sys/windows/ip_helper.odin | 2 +- core/testing/runner_windows.odin | 4 ++-- core/thread/thread_windows.odin | 2 +- 11 files changed, 15 insertions(+), 15 deletions(-) (limited to 'core/runtime') diff --git a/core/mem/virtual/virtual_windows.odin b/core/mem/virtual/virtual_windows.odin index bbd74a925..5e97296af 100644 --- a/core/mem/virtual/virtual_windows.odin +++ b/core/mem/virtual/virtual_windows.odin @@ -53,7 +53,7 @@ PAGE_TARGETS_NO_UPDATE :: 0x40000000 ERROR_INVALID_ADDRESS :: 487 ERROR_COMMITMENT_LIMIT :: 1455 -@(default_calling_convention="stdcall") +@(default_calling_convention="system") foreign Kernel32 { GetSystemInfo :: proc(lpSystemInfo: LPSYSTEM_INFO) --- VirtualAlloc :: proc(lpAddress: rawptr, dwSize: uint, flAllocationType: u32, flProtect: u32) -> rawptr --- diff --git a/core/runtime/entry_windows.odin b/core/runtime/entry_windows.odin index 277daecca..b6fbe1dcc 100644 --- a/core/runtime/entry_windows.odin +++ b/core/runtime/entry_windows.odin @@ -7,7 +7,7 @@ import "core:intrinsics" when ODIN_BUILD_MODE == .Dynamic { @(link_name="DllMain", linkage="strong", require) - DllMain :: proc "stdcall" (hinstDLL: rawptr, fdwReason: u32, lpReserved: rawptr) -> b32 { + DllMain :: proc "system" (hinstDLL: rawptr, fdwReason: u32, lpReserved: rawptr) -> b32 { context = default_context() // Populate Windows DLL-specific global @@ -29,7 +29,7 @@ when ODIN_BUILD_MODE == .Dynamic { } else when !ODIN_TEST && !ODIN_NO_ENTRY_POINT { when ODIN_ARCH == .i386 || ODIN_NO_CRT { @(link_name="mainCRTStartup", linkage="strong", require) - mainCRTStartup :: proc "stdcall" () -> i32 { + mainCRTStartup :: proc "system" () -> i32 { context = default_context() #force_no_inline _startup_runtime() intrinsics.__entry_point() diff --git a/core/runtime/os_specific_windows.odin b/core/runtime/os_specific_windows.odin index 9f001fa5a..4a5907466 100644 --- a/core/runtime/os_specific_windows.odin +++ b/core/runtime/os_specific_windows.odin @@ -4,7 +4,7 @@ package runtime foreign import kernel32 "system:Kernel32.lib" @(private="file") -@(default_calling_convention="stdcall") +@(default_calling_convention="system") foreign kernel32 { // NOTE(bill): The types are not using the standard names (e.g. DWORD and LPVOID) to just minimizing the dependency diff --git a/core/runtime/procs.odin b/core/runtime/procs.odin index 1b8a54c6d..454574c35 100644 --- a/core/runtime/procs.odin +++ b/core/runtime/procs.odin @@ -4,7 +4,7 @@ when ODIN_NO_CRT && ODIN_OS == .Windows { foreign import lib "system:NtDll.lib" @(private="file") - @(default_calling_convention="stdcall") + @(default_calling_convention="system") foreign lib { RtlMoveMemory :: proc(dst, s: rawptr, length: int) --- RtlFillMemory :: proc(dst: rawptr, length: int, fill: i32) --- diff --git a/core/runtime/procs_windows_amd64.odin b/core/runtime/procs_windows_amd64.odin index a30985d5c..ea495f5fa 100644 --- a/core/runtime/procs_windows_amd64.odin +++ b/core/runtime/procs_windows_amd64.odin @@ -6,7 +6,7 @@ foreign import kernel32 "system:Kernel32.lib" @(private) foreign kernel32 { - RaiseException :: proc "stdcall" (dwExceptionCode, dwExceptionFlags, nNumberOfArguments: u32, lpArguments: ^uint) -> ! --- + RaiseException :: proc "system" (dwExceptionCode, dwExceptionFlags, nNumberOfArguments: u32, lpArguments: ^uint) -> ! --- } windows_trap_array_bounds :: proc "contextless" () -> ! { diff --git a/core/runtime/procs_windows_i386.odin b/core/runtime/procs_windows_i386.odin index 4f606da8f..10422cf07 100644 --- a/core/runtime/procs_windows_i386.odin +++ b/core/runtime/procs_windows_i386.odin @@ -13,7 +13,7 @@ windows_trap_array_bounds :: proc "contextless" () -> ! { EXCEPTION_ARRAY_BOUNDS_EXCEEDED :: 0xC000008C foreign kernel32 { - RaiseException :: proc "stdcall" (dwExceptionCode, dwExceptionFlags, nNumberOfArguments: DWORD, lpArguments: ^ULONG_PTR) -> ! --- + RaiseException :: proc "system" (dwExceptionCode, dwExceptionFlags, nNumberOfArguments: DWORD, lpArguments: ^ULONG_PTR) -> ! --- } RaiseException(EXCEPTION_ARRAY_BOUNDS_EXCEEDED, 0, 0, nil) diff --git a/core/sync/futex_windows.odin b/core/sync/futex_windows.odin index 8ddbef3ed..6a26baf5b 100644 --- a/core/sync/futex_windows.odin +++ b/core/sync/futex_windows.odin @@ -5,14 +5,14 @@ package sync import "core:time" foreign import Synchronization "system:Synchronization.lib" -@(default_calling_convention="stdcall") +@(default_calling_convention="system") foreign Synchronization { WakeByAddressSingle :: proc(Address: rawptr) --- WakeByAddressAll :: proc(Address: rawptr) --- } foreign import Ntdll "system:Ntdll.lib" -@(default_calling_convention="stdcall") +@(default_calling_convention="system") foreign Ntdll { RtlWaitOnAddress :: proc(Address: rawptr, CompareAddress: rawptr, AddressSize: uint, Timeout: ^i64) -> i32 --- RtlNtStatusToDosError :: proc(status: i32) -> u32 --- @@ -30,7 +30,7 @@ foreign Ntdll { GODDAMN MICROSOFT! */ -CustomWaitOnAddress :: proc "stdcall" (Address: rawptr, CompareAddress: rawptr, AddressSize: uint, Timeout: ^i64) -> bool { +CustomWaitOnAddress :: proc "system" (Address: rawptr, CompareAddress: rawptr, AddressSize: uint, Timeout: ^i64) -> bool { status := RtlWaitOnAddress(Address, CompareAddress, AddressSize, Timeout) if status != 0 { SetLastError(RtlNtStatusToDosError(status)) diff --git a/core/sys/windows/dnsapi.odin b/core/sys/windows/dnsapi.odin index 623fa2889..dd2d1acee 100644 --- a/core/sys/windows/dnsapi.odin +++ b/core/sys/windows/dnsapi.odin @@ -3,7 +3,7 @@ package sys_windows foreign import "system:Dnsapi.lib" -@(default_calling_convention="std") +@(default_calling_convention="system") foreign Dnsapi { DnsQuery_UTF8 :: proc(name: cstring, type: u16, options: DWORD, extra: PVOID, results: ^^DNS_RECORD, reserved: PVOID) -> DNS_STATUS --- DnsRecordListFree :: proc(list: ^DNS_RECORD, options: DWORD) --- diff --git a/core/sys/windows/ip_helper.odin b/core/sys/windows/ip_helper.odin index d8f93f533..4c2534c10 100644 --- a/core/sys/windows/ip_helper.odin +++ b/core/sys/windows/ip_helper.odin @@ -217,7 +217,7 @@ NL_DAD_STATE :: enum i32 { IpDadStatePreferred = 4, } -@(default_calling_convention = "std") +@(default_calling_convention = "system") foreign iphlpapi { /* The GetAdaptersAddresses function retrieves the addresses associated with the adapters on the local computer. diff --git a/core/testing/runner_windows.odin b/core/testing/runner_windows.odin index 17bcfce26..dbb9ed1c0 100644 --- a/core/testing/runner_windows.odin +++ b/core/testing/runner_windows.odin @@ -90,7 +90,7 @@ Thread_Os_Specific :: struct { } thread_create :: proc(procedure: Thread_Proc) -> ^Thread { - __windows_thread_entry_proc :: proc "stdcall" (t_: rawptr) -> win32.DWORD { + __windows_thread_entry_proc :: proc "system" (t_: rawptr) -> win32.DWORD { t := (^Thread)(t_) context = t.init_context.? or_else runtime.default_context() @@ -172,7 +172,7 @@ global_current_t: ^T run_internal_test :: proc(t: ^T, it: Internal_Test) { thread := thread_create(proc(thread: ^Thread) { - exception_handler_proc :: proc "stdcall" (ExceptionInfo: ^win32.EXCEPTION_POINTERS) -> win32.LONG { + exception_handler_proc :: proc "system" (ExceptionInfo: ^win32.EXCEPTION_POINTERS) -> win32.LONG { switch ExceptionInfo.ExceptionRecord.ExceptionCode { case win32.EXCEPTION_DATATYPE_MISALIGNMENT, diff --git a/core/thread/thread_windows.odin b/core/thread/thread_windows.odin index 2d6cad1ad..28b2294d1 100644 --- a/core/thread/thread_windows.odin +++ b/core/thread/thread_windows.odin @@ -21,7 +21,7 @@ _thread_priority_map := [Thread_Priority]i32{ _create :: proc(procedure: Thread_Proc, priority: Thread_Priority) -> ^Thread { win32_thread_id: win32.DWORD - __windows_thread_entry_proc :: proc "stdcall" (t_: rawptr) -> win32.DWORD { + __windows_thread_entry_proc :: proc "system" (t_: rawptr) -> win32.DWORD { t := (^Thread)(t_) t.id = sync.current_thread_id() -- cgit v1.2.3 From 14e2cc17d6420e4c25a8d4fa815fffde87fd7239 Mon Sep 17 00:00:00 2001 From: Kyle Burke Date: Wed, 24 Jan 2024 09:39:47 -0600 Subject: Remove mention of `map` in builtin resize proc group --- core/runtime/core_builtin.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'core/runtime') diff --git a/core/runtime/core_builtin.odin b/core/runtime/core_builtin.odin index bc85cd7f2..3f4ebbc74 100644 --- a/core/runtime/core_builtin.odin +++ b/core/runtime/core_builtin.odin @@ -172,7 +172,7 @@ reserve :: proc{reserve_dynamic_array, reserve_map} @builtin non_zero_reserve :: proc{non_zero_reserve_dynamic_array} -// `resize` will try to resize memory of a passed dynamic array or map to the requested element count (setting the `len`, and possibly `cap`). +// `resize` will try to resize memory of a passed dynamic array to the requested element count (setting the `len`, and possibly `cap`). @builtin resize :: proc{resize_dynamic_array} -- cgit v1.2.3