aboutsummaryrefslogtreecommitdiff
path: root/core/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'core/runtime')
-rw-r--r--core/runtime/core.odin2
-rw-r--r--core/runtime/core_builtin.odin120
-rw-r--r--core/runtime/core_builtin_soa.odin2
-rw-r--r--core/runtime/default_allocators_arena.odin22
-rw-r--r--core/runtime/default_allocators_nil.odin12
-rw-r--r--core/runtime/default_allocators_windows.odin4
-rw-r--r--core/runtime/dynamic_map_internal.odin2
-rw-r--r--core/runtime/entry_unix.odin12
-rw-r--r--core/runtime/entry_unix_no_crt_darwin_arm64.asm20
-rw-r--r--core/runtime/entry_wasm.odin1
-rw-r--r--core/runtime/entry_windows.odin5
-rw-r--r--core/runtime/error_checks.odin24
-rw-r--r--core/runtime/internal.odin39
-rw-r--r--core/runtime/os_specific_any.odin6
-rw-r--r--core/runtime/os_specific_darwin.odin12
-rw-r--r--core/runtime/os_specific_windows.odin2
-rw-r--r--core/runtime/procs.odin15
-rw-r--r--core/runtime/procs_windows_amd64.odin3
-rw-r--r--core/runtime/procs_windows_i386.odin3
19 files changed, 233 insertions, 73 deletions
diff --git a/core/runtime/core.odin b/core/runtime/core.odin
index 2d176f909..740482493 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"
@@ -306,6 +307,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 a73a3d712..3f4ebbc74 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)
@@ -169,10 +169,16 @@ clear :: proc{clear_dynamic_array, clear_map}
@builtin
reserve :: proc{reserve_dynamic_array, reserve_map}
-// `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
+non_zero_reserve :: proc{non_zero_reserve_dynamic_array}
+
+// `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}
+@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}
@@ -234,6 +240,8 @@ delete :: proc{
delete_dynamic_array,
delete_slice,
delete_map,
+ delete_soa_slice,
+ delete_soa_dynamic_array,
}
@@ -346,7 +354,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,
@@ -404,10 +412,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 +423,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 +446,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 +472,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 +494,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 +540,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
@@ -587,11 +636,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(args)
+ 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
}
@@ -633,8 +685,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 +704,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 +719,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 +752,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 +768,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/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
diff --git a/core/runtime/default_allocators_arena.odin b/core/runtime/default_allocators_arena.odin
index 1c36c4f7c..1fe3c6cfc 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):])
@@ -102,20 +102,20 @@ 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()
}
- 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
@@ -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 a340050eb..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
}
@@ -35,7 +35,7 @@ nil_allocator :: proc() -> Allocator {
when ODIN_OS == .Freestanding {
default_allocator_proc :: nil_allocator_proc
default_allocator :: nil_allocator
-}
+}
@@ -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)
@@ -78,9 +82,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,
}
}
-
-
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/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)
diff --git a/core/runtime/entry_unix.odin b/core/runtime/entry_unix.odin
index 0c718445a..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"
@@ -26,8 +27,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 +42,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/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..b6fbe1dcc 100644
--- a/core/runtime/entry_windows.odin
+++ b/core/runtime/entry_windows.odin
@@ -1,12 +1,13 @@
//+private
//+build windows
+//+no-instrumentation
package runtime
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
@@ -28,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/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/internal.odin b/core/runtime/internal.odin
index d0e550743..d4c43ed7e 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
@@ -730,7 +749,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 +761,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 +773,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 +787,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 +801,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 +815,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/runtime/os_specific_any.odin b/core/runtime/os_specific_any.odin
index afa106138..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
+//+build !darwin
+//+build !freestanding
+//+build !js
+//+build !wasi
+//+build !windows
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..5de9a7d57
--- /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(0x2000004, 1, uintptr(raw_data(data)), uintptr(len(data)))
+ if ret < 0 {
+ return 0, _OS_Errno(-ret)
+ }
+ return int(ret), 0
+}
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 1592c608b..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) ---
@@ -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/core/runtime/procs_windows_amd64.odin b/core/runtime/procs_windows_amd64.odin
index e430357be..ea495f5fa 100644
--- a/core/runtime/procs_windows_amd64.odin
+++ b/core/runtime/procs_windows_amd64.odin
@@ -1,11 +1,12 @@
//+private
+//+no-instrumentation
package runtime
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 f810197f1..10422cf07 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"
@@ -12,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)