diff --git a/base/runtime/default_allocators_nil.odin b/base/runtime/default_allocators_nil.odin index e7a1b1a74..14edd11dd 100644 --- a/base/runtime/default_allocators_nil.odin +++ b/base/runtime/default_allocators_nil.odin @@ -23,7 +23,7 @@ nil_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, return nil, .None } -nil_allocator :: proc() -> Allocator { +nil_allocator :: proc "contextless" () -> Allocator { return Allocator{ procedure = nil_allocator_proc, data = nil, diff --git a/base/runtime/default_temp_allocator_arena.odin b/base/runtime/default_temp_allocator_arena.odin index ca144b66f..525f81825 100644 --- a/base/runtime/default_temp_allocator_arena.odin +++ b/base/runtime/default_temp_allocator_arena.odin @@ -52,10 +52,13 @@ memory_block_alloc :: proc(allocator: Allocator, capacity: uint, alignment: uint return } -memory_block_dealloc :: proc(block_to_free: ^Memory_Block, loc := #caller_location) { +memory_block_dealloc :: proc "contextless" (block_to_free: ^Memory_Block, loc := #caller_location) { if block_to_free != nil { + allocator := block_to_free.allocator // sanitizer.address_unpoison(block_to_free.base, block_to_free.capacity) + context = default_context() + context.allocator = allocator mem_free(block_to_free, allocator, loc) } } @@ -172,7 +175,7 @@ arena_free_all :: proc(arena: ^Arena, loc := #caller_location) { arena.total_used = 0 } -arena_destroy :: proc(arena: ^Arena, loc := #caller_location) { +arena_destroy :: proc "contextless" (arena: ^Arena, loc := #caller_location) { for arena.curr_block != nil { free_block := arena.curr_block arena.curr_block = free_block.prev diff --git a/base/runtime/default_temporary_allocator.odin b/base/runtime/default_temporary_allocator.odin index b355ded70..671728be8 100644 --- a/base/runtime/default_temporary_allocator.odin +++ b/base/runtime/default_temporary_allocator.odin @@ -8,7 +8,7 @@ when NO_DEFAULT_TEMP_ALLOCATOR { default_temp_allocator_init :: proc(s: ^Default_Temp_Allocator, size: int, backing_allocator := context.allocator) {} - default_temp_allocator_destroy :: proc(s: ^Default_Temp_Allocator) {} + default_temp_allocator_destroy :: proc "contextless" (s: ^Default_Temp_Allocator) {} default_temp_allocator_proc :: nil_allocator_proc @@ -28,7 +28,7 @@ when NO_DEFAULT_TEMP_ALLOCATOR { _ = arena_init(&s.arena, uint(size), backing_allocator) } - default_temp_allocator_destroy :: proc(s: ^Default_Temp_Allocator) { + default_temp_allocator_destroy :: proc "contextless" (s: ^Default_Temp_Allocator) { if s != nil { arena_destroy(&s.arena) s^ = {} @@ -56,7 +56,7 @@ when NO_DEFAULT_TEMP_ALLOCATOR { } @(fini, private) - _destroy_temp_allocator_fini :: proc() { + _destroy_temp_allocator_fini :: proc "contextless" () { default_temp_allocator_destroy(&global_default_temp_allocator_data) } } diff --git a/base/runtime/procs_js.odin b/base/runtime/procs_js.odin index 58bed808d..3690f9436 100644 --- a/base/runtime/procs_js.odin +++ b/base/runtime/procs_js.odin @@ -3,8 +3,8 @@ package runtime init_default_context_for_js: Context @(init, private="file") -init_default_context :: proc() { - init_default_context_for_js = context +init_default_context :: proc "contextless" () { + __init_context(&init_default_context_for_js) } @(export) diff --git a/base/runtime/thread_management.odin b/base/runtime/thread_management.odin index cabd4691c..97dcbc8f5 100644 --- a/base/runtime/thread_management.odin +++ b/base/runtime/thread_management.odin @@ -1,10 +1,14 @@ package runtime -Thread_Local_Cleaner :: #type proc "odin" () +Thread_Local_Cleaner_Odin :: #type proc "odin" () +Thread_Local_Cleaner_Contextless :: #type proc "contextless" () + +Thread_Local_Cleaner :: union #shared_nil {Thread_Local_Cleaner_Odin, Thread_Local_Cleaner_Contextless} @(private="file") thread_local_cleaners: [8]Thread_Local_Cleaner + // Add a procedure that will be run at the end of a thread for the purpose of // deallocating state marked as `thread_local`. // @@ -29,6 +33,9 @@ run_thread_local_cleaners :: proc "odin" () { if p == nil { break } - p() + switch v in p { + case Thread_Local_Cleaner_Odin: v() + case Thread_Local_Cleaner_Contextless: v() + } } } diff --git a/core/encoding/cbor/tags.odin b/core/encoding/cbor/tags.odin index ae1664dfc..be07b926a 100644 --- a/core/encoding/cbor/tags.odin +++ b/core/encoding/cbor/tags.odin @@ -82,14 +82,16 @@ _tag_implementations_id: map[string]Tag_Implementation _tag_implementations_type: map[typeid]Tag_Implementation // Register a custom tag implementation to be used when marshalling that type and unmarshalling that tag number. -tag_register_type :: proc(impl: Tag_Implementation, nr: Tag_Number, type: typeid) { +tag_register_type :: proc "contextless" (impl: Tag_Implementation, nr: Tag_Number, type: typeid) { + context = runtime.default_context() _tag_implementations_nr[nr] = impl _tag_implementations_type[type] = impl } // Register a custom tag implementation to be used when marshalling that tag number or marshalling // a field with the struct tag `cbor_tag:"nr"`. -tag_register_number :: proc(impl: Tag_Implementation, nr: Tag_Number, id: string) { +tag_register_number :: proc "contextless" (impl: Tag_Implementation, nr: Tag_Number, id: string) { + context = runtime.default_context() _tag_implementations_nr[nr] = impl _tag_implementations_id[id] = impl } @@ -98,13 +100,13 @@ tag_register_number :: proc(impl: Tag_Implementation, nr: Tag_Number, id: string INITIALIZE_DEFAULT_TAGS :: #config(CBOR_INITIALIZE_DEFAULT_TAGS, !ODIN_DEFAULT_TO_PANIC_ALLOCATOR && !ODIN_DEFAULT_TO_NIL_ALLOCATOR) @(private, init, disabled=!INITIALIZE_DEFAULT_TAGS) -tags_initialize_defaults :: proc() { +tags_initialize_defaults :: proc "contextless" () { tags_register_defaults() } // Registers tags that have implementations provided by this package. // This is done by default and can be controlled with the `CBOR_INITIALIZE_DEFAULT_TAGS` define. -tags_register_defaults :: proc() { +tags_register_defaults :: proc "contextless" () { tag_register_number({nil, tag_time_unmarshal, tag_time_marshal}, TAG_EPOCH_TIME_NR, TAG_EPOCH_TIME_ID) tag_register_number({nil, tag_base64_unmarshal, tag_base64_marshal}, TAG_BASE64_NR, TAG_BASE64_ID) tag_register_number({nil, tag_cbor_unmarshal, tag_cbor_marshal}, TAG_CBOR_NR, TAG_CBOR_ID) diff --git a/core/flags/rtti.odin b/core/flags/rtti.odin index ce7a23773..058292698 100644 --- a/core/flags/rtti.odin +++ b/core/flags/rtti.odin @@ -38,6 +38,6 @@ Note that only one can be active at a time. Inputs: - setter: The type setter. Pass `nil` to disable any previously set setter. */ -register_type_setter :: proc(setter: Custom_Type_Setter) { +register_type_setter :: proc "contextless" (setter: Custom_Type_Setter) { global_custom_type_setter = setter } diff --git a/core/image/bmp/bmp.odin b/core/image/bmp/bmp.odin index 057c2ffa0..d5a094e83 100644 --- a/core/image/bmp/bmp.odin +++ b/core/image/bmp/bmp.odin @@ -741,6 +741,6 @@ destroy :: proc(img: ^Image) { } @(init, private) -_register :: proc() { +_register :: proc "contextless" () { image.register(.BMP, load_from_bytes, destroy) } diff --git a/core/image/general.odin b/core/image/general.odin index e92b54f18..336b41d25 100644 --- a/core/image/general.odin +++ b/core/image/general.odin @@ -10,13 +10,13 @@ Destroy_Proc :: #type proc(img: ^Image) _internal_loaders: [Which_File_Type]Loader_Proc _internal_destroyers: [Which_File_Type]Destroy_Proc -register :: proc(kind: Which_File_Type, loader: Loader_Proc, destroyer: Destroy_Proc) { - assert(loader != nil) - assert(destroyer != nil) - assert(_internal_loaders[kind] == nil) +register :: proc "contextless" (kind: Which_File_Type, loader: Loader_Proc, destroyer: Destroy_Proc) { + assert_contextless(loader != nil) + assert_contextless(destroyer != nil) + assert_contextless(_internal_loaders[kind] == nil) _internal_loaders[kind] = loader - assert(_internal_destroyers[kind] == nil) + assert_contextless(_internal_destroyers[kind] == nil) _internal_destroyers[kind] = destroyer } diff --git a/core/image/netpbm/netpbm.odin b/core/image/netpbm/netpbm.odin index a9dc6599a..25e0228b5 100644 --- a/core/image/netpbm/netpbm.odin +++ b/core/image/netpbm/netpbm.odin @@ -720,7 +720,7 @@ autoselect_pbm_format_from_image :: proc(img: ^Image, prefer_binary := true, for } @(init, private) -_register :: proc() { +_register :: proc "contextless" () { loader :: proc(data: []byte, options: image.Options, allocator: mem.Allocator) -> (img: ^Image, err: Error) { return load_from_bytes(data, allocator) } diff --git a/core/image/png/png.odin b/core/image/png/png.odin index 3eb56c245..87efcf9b5 100644 --- a/core/image/png/png.odin +++ b/core/image/png/png.odin @@ -1611,6 +1611,6 @@ defilter :: proc(img: ^Image, filter_bytes: ^bytes.Buffer, header: ^image.PNG_IH } @(init, private) -_register :: proc() { +_register :: proc "contextless" () { image.register(.PNG, load_from_bytes, destroy) } diff --git a/core/image/qoi/qoi.odin b/core/image/qoi/qoi.odin index 6b6149e60..ded8d7971 100644 --- a/core/image/qoi/qoi.odin +++ b/core/image/qoi/qoi.odin @@ -371,6 +371,6 @@ qoi_hash :: #force_inline proc(pixel: RGBA_Pixel) -> (index: u8) { } @(init, private) -_register :: proc() { +_register :: proc "contextless" () { image.register(.QOI, load_from_bytes, destroy) } diff --git a/core/image/tga/tga.odin b/core/image/tga/tga.odin index 46e37a0cf..5fda803c5 100644 --- a/core/image/tga/tga.odin +++ b/core/image/tga/tga.odin @@ -406,6 +406,6 @@ IMAGE_DESCRIPTOR_RIGHT_MASK :: 1<<4 IMAGE_DESCRIPTOR_TOP_MASK :: 1<<5 @(init, private) -_register :: proc() { +_register :: proc "contextless" () { image.register(.TGA, load_from_bytes, destroy) } \ No newline at end of file diff --git a/core/log/file_console_logger.odin b/core/log/file_console_logger.odin index 0fe5c3477..f0acc8a22 100644 --- a/core/log/file_console_logger.odin +++ b/core/log/file_console_logger.odin @@ -43,12 +43,14 @@ File_Console_Logger_Data :: struct { @(private) global_subtract_stderr_options: Options @(init, private) -init_standard_stream_status :: proc() { +init_standard_stream_status :: proc "contextless" () { // NOTE(Feoramund): While it is technically possible for these streams to // be redirected during the runtime of the program, the cost of checking on // every single log message is not worth it to support such an // uncommonly-used feature. if terminal.color_enabled { + context = runtime.default_context() + // This is done this way because it's possible that only one of these // streams could be redirected to a file. if !terminal.is_terminal(os.stdout) { diff --git a/core/math/big/helpers.odin b/core/math/big/helpers.odin index ee09bb2c7..569f0b810 100644 --- a/core/math/big/helpers.odin +++ b/core/math/big/helpers.odin @@ -7,6 +7,7 @@ package math_big import "base:intrinsics" +import "base:runtime" import rnd "core:math/rand" /* @@ -778,22 +779,23 @@ int_from_bytes_little_python :: proc(a: ^Int, buf: []u8, signed := false, alloca INT_ONE, INT_ZERO, INT_MINUS_ONE, INT_INF, INT_MINUS_INF, INT_NAN := &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{} @(init, private) -_init_constants :: proc() { +_init_constants :: proc "contextless" () { initialize_constants() } -initialize_constants :: proc() -> (res: int) { - internal_set( INT_ZERO, 0); INT_ZERO.flags = {.Immutable} - internal_set( INT_ONE, 1); INT_ONE.flags = {.Immutable} - internal_set(INT_MINUS_ONE, -1); INT_MINUS_ONE.flags = {.Immutable} +initialize_constants :: proc "contextless" () -> (res: int) { + context = runtime.default_context() + internal_int_set_from_integer( INT_ZERO, 0); INT_ZERO.flags = {.Immutable} + internal_int_set_from_integer( INT_ONE, 1); INT_ONE.flags = {.Immutable} + internal_int_set_from_integer(INT_MINUS_ONE, -1); INT_MINUS_ONE.flags = {.Immutable} /* We set these special values to -1 or 1 so they don't get mistake for zero accidentally. This allows for shortcut tests of is_zero as .used == 0. */ - internal_set( INT_NAN, 1); INT_NAN.flags = {.Immutable, .NaN} - internal_set( INT_INF, 1); INT_INF.flags = {.Immutable, .Inf} - internal_set(INT_MINUS_INF, -1); INT_MINUS_INF.flags = {.Immutable, .Inf} + internal_int_set_from_integer( INT_NAN, 1); INT_NAN.flags = {.Immutable, .NaN} + internal_int_set_from_integer( INT_INF, 1); INT_INF.flags = {.Immutable, .Inf} + internal_int_set_from_integer(INT_MINUS_INF, -1); INT_MINUS_INF.flags = {.Immutable, .Inf} return _DEFAULT_MUL_KARATSUBA_CUTOFF } diff --git a/core/math/big/internal.odin b/core/math/big/internal.odin index 4707177c4..e0bc1ae06 100644 --- a/core/math/big/internal.odin +++ b/core/math/big/internal.odin @@ -27,10 +27,10 @@ package math_big -import "core:mem" -import "base:intrinsics" -import rnd "core:math/rand" import "base:builtin" +import "base:intrinsics" +import "core:mem" +import rnd "core:math/rand" /* Low-level addition, unsigned. Handbook of Applied Cryptography, algorithm 14.7. @@ -2885,12 +2885,12 @@ internal_clear_if_uninitialized_multi :: proc(args: ..^Int, allocator := context } internal_clear_if_uninitialized :: proc {internal_clear_if_uninitialized_single, internal_clear_if_uninitialized_multi, } -internal_error_if_immutable_single :: proc(arg: ^Int) -> (err: Error) { +internal_error_if_immutable_single :: proc "contextless" (arg: ^Int) -> (err: Error) { if arg != nil && .Immutable in arg.flags { return .Assignment_To_Immutable } return nil } -internal_error_if_immutable_multi :: proc(args: ..^Int) -> (err: Error) { +internal_error_if_immutable_multi :: proc "contextless" (args: ..^Int) -> (err: Error) { for i in args { if i != nil && .Immutable in i.flags { return .Assignment_To_Immutable } } diff --git a/core/mem/virtual/virtual.odin b/core/mem/virtual/virtual.odin index 3027e5848..3f388acf3 100644 --- a/core/mem/virtual/virtual.odin +++ b/core/mem/virtual/virtual.odin @@ -9,7 +9,7 @@ _ :: runtime DEFAULT_PAGE_SIZE := uint(4096) @(init, private) -platform_memory_init :: proc() { +platform_memory_init :: proc "contextless" () { _platform_memory_init() } diff --git a/core/mem/virtual/virtual_linux.odin b/core/mem/virtual/virtual_linux.odin index 3e0d7668b..f819fbf86 100644 --- a/core/mem/virtual/virtual_linux.odin +++ b/core/mem/virtual/virtual_linux.odin @@ -43,10 +43,10 @@ _protect :: proc "contextless" (data: rawptr, size: uint, flags: Protect_Flags) return errno == .NONE } -_platform_memory_init :: proc() { +_platform_memory_init :: proc "contextless" () { DEFAULT_PAGE_SIZE = 4096 // is power of two - assert(DEFAULT_PAGE_SIZE != 0 && (DEFAULT_PAGE_SIZE & (DEFAULT_PAGE_SIZE-1)) == 0) + assert_contextless(DEFAULT_PAGE_SIZE != 0 && (DEFAULT_PAGE_SIZE & (DEFAULT_PAGE_SIZE-1)) == 0) } diff --git a/core/mem/virtual/virtual_other.odin b/core/mem/virtual/virtual_other.odin index a57856975..c6386e842 100644 --- a/core/mem/virtual/virtual_other.odin +++ b/core/mem/virtual/virtual_other.odin @@ -25,7 +25,7 @@ _protect :: proc "contextless" (data: rawptr, size: uint, flags: Protect_Flags) return false } -_platform_memory_init :: proc() { +_platform_memory_init :: proc "contextless" () { } _map_file :: proc "contextless" (fd: uintptr, size: i64, flags: Map_File_Flags) -> (data: []byte, error: Map_File_Error) { diff --git a/core/mem/virtual/virtual_posix.odin b/core/mem/virtual/virtual_posix.odin index 0b304a5e7..4bb161770 100644 --- a/core/mem/virtual/virtual_posix.odin +++ b/core/mem/virtual/virtual_posix.odin @@ -28,13 +28,13 @@ _protect :: proc "contextless" (data: rawptr, size: uint, flags: Protect_Flags) return posix.mprotect(data, size, transmute(posix.Prot_Flags)flags) == .OK } -_platform_memory_init :: proc() { +_platform_memory_init :: proc "contextless" () { // NOTE: `posix.PAGESIZE` due to legacy reasons could be wrong so we use `sysconf`. size := posix.sysconf(._PAGESIZE) DEFAULT_PAGE_SIZE = uint(max(size, posix.PAGESIZE)) // is power of two - assert(DEFAULT_PAGE_SIZE != 0 && (DEFAULT_PAGE_SIZE & (DEFAULT_PAGE_SIZE-1)) == 0) + assert_contextless(DEFAULT_PAGE_SIZE != 0 && (DEFAULT_PAGE_SIZE & (DEFAULT_PAGE_SIZE-1)) == 0) } _map_file :: proc "contextless" (fd: uintptr, size: i64, flags: Map_File_Flags) -> (data: []byte, error: Map_File_Error) { diff --git a/core/mem/virtual/virtual_windows.odin b/core/mem/virtual/virtual_windows.odin index 3fd4eeb68..1d777af17 100644 --- a/core/mem/virtual/virtual_windows.odin +++ b/core/mem/virtual/virtual_windows.odin @@ -146,13 +146,13 @@ _protect :: proc "contextless" (data: rawptr, size: uint, flags: Protect_Flags) @(no_sanitize_address) -_platform_memory_init :: proc() { +_platform_memory_init :: proc "contextless" () { sys_info: SYSTEM_INFO GetSystemInfo(&sys_info) DEFAULT_PAGE_SIZE = max(DEFAULT_PAGE_SIZE, uint(sys_info.dwPageSize)) // is power of two - assert(DEFAULT_PAGE_SIZE != 0 && (DEFAULT_PAGE_SIZE & (DEFAULT_PAGE_SIZE-1)) == 0) + assert_contextless(DEFAULT_PAGE_SIZE != 0 && (DEFAULT_PAGE_SIZE & (DEFAULT_PAGE_SIZE-1)) == 0) } diff --git a/core/net/socket_windows.odin b/core/net/socket_windows.odin index cab820ed5..9127874de 100644 --- a/core/net/socket_windows.odin +++ b/core/net/socket_windows.odin @@ -79,7 +79,7 @@ Shutdown_Manner :: enum c.int { } @(init, private) -ensure_winsock_initialized :: proc() { +ensure_winsock_initialized :: proc "contextless" () { win.ensure_winsock_initialized() } diff --git a/core/os/os2/allocators.odin b/core/os/os2/allocators.odin index cedfbdee1..36a7d72be 100644 --- a/core/os/os2/allocators.odin +++ b/core/os/os2/allocators.odin @@ -16,7 +16,7 @@ MAX_TEMP_ARENA_COLLISIONS :: MAX_TEMP_ARENA_COUNT - 1 global_default_temp_allocator_arenas: [MAX_TEMP_ARENA_COUNT]runtime.Arena @(fini, private) -temp_allocator_fini :: proc() { +temp_allocator_fini :: proc "contextless" () { for &arena in global_default_temp_allocator_arenas { runtime.arena_destroy(&arena) } @@ -69,6 +69,6 @@ _temp_allocator_end :: proc(tmp: runtime.Arena_Temp) { } @(init, private) -init_thread_local_cleaner :: proc() { +init_thread_local_cleaner :: proc "contextless" () { runtime.add_thread_local_cleaner(temp_allocator_fini) } diff --git a/core/os/os2/file_linux.odin b/core/os/os2/file_linux.odin index b1d11b425..92f0c1541 100644 --- a/core/os/os2/file_linux.odin +++ b/core/os/os2/file_linux.odin @@ -45,8 +45,8 @@ _stderr := File{ } @init -_standard_stream_init :: proc() { - new_std :: proc(impl: ^File_Impl, fd: linux.Fd, name: string) -> ^File { +_standard_stream_init :: proc "contextless" () { + new_std :: proc "contextless" (impl: ^File_Impl, fd: linux.Fd, name: string) -> ^File { impl.file.impl = impl impl.fd = linux.Fd(fd) impl.allocator = runtime.nil_allocator() diff --git a/core/os/os2/file_posix.odin b/core/os/os2/file_posix.odin index 2d74618ee..fed8d766c 100644 --- a/core/os/os2/file_posix.odin +++ b/core/os/os2/file_posix.odin @@ -25,8 +25,8 @@ File_Impl :: struct { } @(init) -init_std_files :: proc() { - new_std :: proc(impl: ^File_Impl, fd: posix.FD, name: cstring) -> ^File { +init_std_files :: proc "contextless" () { + new_std :: proc "contextless" (impl: ^File_Impl, fd: posix.FD, name: cstring) -> ^File { impl.file.impl = impl impl.fd = fd impl.allocator = runtime.nil_allocator() diff --git a/core/os/os2/file_wasi.odin b/core/os/os2/file_wasi.odin index 0245841e3..1d417ffb1 100644 --- a/core/os/os2/file_wasi.odin +++ b/core/os/os2/file_wasi.odin @@ -30,8 +30,8 @@ Preopen :: struct { preopens: []Preopen @(init) -init_std_files :: proc() { - new_std :: proc(impl: ^File_Impl, fd: wasi.fd_t, name: string) -> ^File { +init_std_files :: proc "contextless" () { + new_std :: proc "contextless" (impl: ^File_Impl, fd: wasi.fd_t, name: string) -> ^File { impl.file.impl = impl impl.allocator = runtime.nil_allocator() impl.fd = fd diff --git a/core/os/os2/file_windows.odin b/core/os/os2/file_windows.odin index 25e9cb4b0..b39e65fe2 100644 --- a/core/os/os2/file_windows.odin +++ b/core/os/os2/file_windows.odin @@ -43,8 +43,8 @@ File_Impl :: struct { } @(init) -init_std_files :: proc() { - new_std :: proc(impl: ^File_Impl, code: u32, name: string) -> ^File { +init_std_files :: proc "contextless" () { + new_std :: proc "contextless" (impl: ^File_Impl, code: u32, name: string) -> ^File { impl.file.impl = impl impl.allocator = runtime.nil_allocator() @@ -77,7 +77,7 @@ init_std_files :: proc() { stderr = new_std(&files[2], win32.STD_ERROR_HANDLE, "") } -_handle :: proc(f: ^File) -> win32.HANDLE { +_handle :: proc "contextless" (f: ^File) -> win32.HANDLE { return win32.HANDLE(_fd(f)) } @@ -234,7 +234,7 @@ _clone :: proc(f: ^File) -> (clone: ^File, err: Error) { return _new_file(uintptr(clonefd), name(f), file_allocator()) } -_fd :: proc(f: ^File) -> uintptr { +_fd :: proc "contextless" (f: ^File) -> uintptr { if f == nil || f.impl == nil { return INVALID_HANDLE } diff --git a/core/os/os2/path_windows.odin b/core/os/os2/path_windows.odin index e0a00b07a..e5a1545ec 100644 --- a/core/os/os2/path_windows.odin +++ b/core/os/os2/path_windows.odin @@ -160,7 +160,7 @@ _get_executable_path :: proc(allocator: runtime.Allocator) -> (path: string, err can_use_long_paths: bool @(init) -init_long_path_support :: proc() { +init_long_path_support :: proc "contextless" () { can_use_long_paths = false key: win32.HKEY diff --git a/core/os/os2/process.odin b/core/os/os2/process.odin index 3c84f3539..635befc64 100644 --- a/core/os/os2/process.odin +++ b/core/os/os2/process.odin @@ -16,7 +16,8 @@ Arguments to the current process. args := get_args() @(private="file") -get_args :: proc() -> []string { +get_args :: proc "contextless" () -> []string { + context = runtime.default_context() result := make([]string, len(runtime.args__), heap_allocator()) for rt_arg, i in runtime.args__ { result[i] = string(rt_arg) @@ -24,6 +25,12 @@ get_args :: proc() -> []string { return result } +@(fini, private="file") +delete_args :: proc "contextless" () { + context = runtime.default_context() + delete(args, heap_allocator()) +} + /* Exit the current process. */ diff --git a/core/os/os2/process_posix_darwin.odin b/core/os/os2/process_posix_darwin.odin index 7625e513a..f655d42a9 100644 --- a/core/os/os2/process_posix_darwin.odin +++ b/core/os/os2/process_posix_darwin.odin @@ -13,7 +13,7 @@ import "core:time" foreign import lib "system:System" foreign lib { - sysctl :: proc( + sysctl :: proc "c" ( name: [^]i32, namelen: u32, oldp: rawptr, oldlenp: ^uint, newp: rawptr, newlen: uint, diff --git a/core/os/os_darwin.odin b/core/os/os_darwin.odin index 1010d27a8..77b5825dd 100644 --- a/core/os/os_darwin.odin +++ b/core/os/os_darwin.odin @@ -1226,7 +1226,8 @@ _processor_core_count :: proc() -> int { } @(private, require_results) -_alloc_command_line_arguments :: proc() -> []string { +_alloc_command_line_arguments :: proc "contextless" () -> []string { + context = runtime.default_context() res := make([]string, len(runtime.args__)) for _, i in res { res[i] = string(runtime.args__[i]) @@ -1235,7 +1236,8 @@ _alloc_command_line_arguments :: proc() -> []string { } @(private, fini) -_delete_command_line_arguments :: proc() { +_delete_command_line_arguments :: proc "contextless" () { + context = runtime.default_context() delete(args) } diff --git a/core/os/os_freebsd.odin b/core/os/os_freebsd.odin index aeffdcb87..0542e10dc 100644 --- a/core/os/os_freebsd.odin +++ b/core/os/os_freebsd.odin @@ -965,7 +965,8 @@ _processor_core_count :: proc() -> int { @(private, require_results) -_alloc_command_line_arguments :: proc() -> []string { +_alloc_command_line_arguments :: proc "contextless" () -> []string { + context = runtime.default_context() res := make([]string, len(runtime.args__)) for _, i in res { res[i] = string(runtime.args__[i]) @@ -974,6 +975,7 @@ _alloc_command_line_arguments :: proc() -> []string { } @(private, fini) -_delete_command_line_arguments :: proc() { +_delete_command_line_arguments :: proc "contextless" () { + context = runtime.default_context() delete(args) } diff --git a/core/os/os_haiku.odin b/core/os/os_haiku.odin index b56d516a4..e7c71338b 100644 --- a/core/os/os_haiku.odin +++ b/core/os/os_haiku.odin @@ -317,7 +317,8 @@ file_size :: proc(fd: Handle) -> (i64, Error) { args := _alloc_command_line_arguments() @(private, require_results) -_alloc_command_line_arguments :: proc() -> []string { +_alloc_command_line_arguments :: proc "contextless" () -> []string { + context = runtime.default_context() res := make([]string, len(runtime.args__)) for arg, i in runtime.args__ { res[i] = string(arg) @@ -326,7 +327,8 @@ _alloc_command_line_arguments :: proc() -> []string { } @(private, fini) -_delete_command_line_arguments :: proc() { +_delete_command_line_arguments :: proc "contextless" () { + context = runtime.default_context() delete(args) } diff --git a/core/os/os_linux.odin b/core/os/os_linux.odin index 66c30711d..15d230820 100644 --- a/core/os/os_linux.odin +++ b/core/os/os_linux.odin @@ -1098,7 +1098,8 @@ _processor_core_count :: proc() -> int { } @(private, require_results) -_alloc_command_line_arguments :: proc() -> []string { +_alloc_command_line_arguments :: proc "contextless" () -> []string { + context = runtime.default_context() res := make([]string, len(runtime.args__)) for _, i in res { res[i] = string(runtime.args__[i]) @@ -1107,7 +1108,8 @@ _alloc_command_line_arguments :: proc() -> []string { } @(private, fini) -_delete_command_line_arguments :: proc() { +_delete_command_line_arguments :: proc "contextless" () { + context = runtime.default_context() delete(args) } diff --git a/core/os/os_netbsd.odin b/core/os/os_netbsd.odin index accc5abcd..30511012f 100644 --- a/core/os/os_netbsd.odin +++ b/core/os/os_netbsd.odin @@ -1015,7 +1015,8 @@ _processor_core_count :: proc() -> int { } @(private, require_results) -_alloc_command_line_arguments :: proc() -> []string { +_alloc_command_line_arguments :: proc "contextless" () -> []string { + context = runtime.default_context() res := make([]string, len(runtime.args__)) for _, i in res { res[i] = string(runtime.args__[i]) @@ -1024,6 +1025,7 @@ _alloc_command_line_arguments :: proc() -> []string { } @(private, fini) -_delete_command_line_arguments :: proc() { +_delete_command_line_arguments :: proc "contextless" () { + context = runtime.default_context() delete(args) } diff --git a/core/os/os_openbsd.odin b/core/os/os_openbsd.odin index ec9181ba6..50ee37dff 100644 --- a/core/os/os_openbsd.odin +++ b/core/os/os_openbsd.odin @@ -915,7 +915,8 @@ _processor_core_count :: proc() -> int { } @(private, require_results) -_alloc_command_line_arguments :: proc() -> []string { +_alloc_command_line_arguments :: proc "contextless" () -> []string { + context = runtime.default_context() res := make([]string, len(runtime.args__)) for _, i in res { res[i] = string(runtime.args__[i]) @@ -924,6 +925,7 @@ _alloc_command_line_arguments :: proc() -> []string { } @(private, fini) -_delete_command_line_arguments :: proc() { +_delete_command_line_arguments :: proc "contextless" () { + context = runtime.default_context() delete(args) } diff --git a/core/os/os_wasi.odin b/core/os/os_wasi.odin index f135e4d42..fe0a1fb3e 100644 --- a/core/os/os_wasi.odin +++ b/core/os/os_wasi.odin @@ -28,16 +28,18 @@ stderr: Handle = 2 args := _alloc_command_line_arguments() @(private, require_results) -_alloc_command_line_arguments :: proc() -> (args: []string) { - args = make([]string, len(runtime.args__)) - for &arg, i in args { +_alloc_command_line_arguments :: proc "contextless" () -> []string { + context = runtime.default_context() + cmd_args := make([]string, len(runtime.args__)) + for &arg, i in cmd_args { arg = string(runtime.args__[i]) } - return + return cmd_args } @(private, fini) -_delete_command_line_arguments :: proc() { +_delete_command_line_arguments :: proc "contextless" () { + context = runtime.default_context() delete(args) } @@ -57,9 +59,8 @@ Preopen :: struct { preopens: []Preopen @(init, private) -init_preopens :: proc() { - - strip_prefixes :: proc(path: string) -> string { +init_preopens :: proc "contextless" () { + strip_prefixes :: proc "contextless"(path: string) -> string { path := path loop: for len(path) > 0 { switch { @@ -76,6 +77,8 @@ init_preopens :: proc() { return path } + context = runtime.default_context() + dyn_preopens: [dynamic]Preopen loop: for fd := wasi.fd_t(3); ; fd += 1 { desc, err := wasi.fd_prestat_get(fd) diff --git a/core/os/os_windows.odin b/core/os/os_windows.odin index 3c1725cc5..03c194596 100644 --- a/core/os/os_windows.odin +++ b/core/os/os_windows.odin @@ -194,7 +194,8 @@ current_thread_id :: proc "contextless" () -> int { @(private, require_results) -_alloc_command_line_arguments :: proc() -> []string { +_alloc_command_line_arguments :: proc "contextless" () -> []string { + context = runtime.default_context() arg_count: i32 arg_list_ptr := win32.CommandLineToArgvW(win32.GetCommandLineW(), &arg_count) arg_list := make([]string, int(arg_count)) @@ -216,7 +217,8 @@ _alloc_command_line_arguments :: proc() -> []string { } @(private, fini) -_delete_command_line_arguments :: proc() { +_delete_command_line_arguments :: proc "contextless" () { + context = runtime.default_context() for s in args { delete(s) } diff --git a/core/sys/info/cpu_intel.odin b/core/sys/info/cpu_intel.odin index 7c5b38ca4..e8f07c732 100644 --- a/core/sys/info/cpu_intel.odin +++ b/core/sys/info/cpu_intel.odin @@ -52,7 +52,7 @@ CPU :: struct { cpu: CPU @(init, private) -init_cpu_features :: proc "c" () { +init_cpu_features :: proc "contextless" () { is_set :: #force_inline proc "c" (bit: u32, value: u32) -> bool { return (value>>bit) & 0x1 != 0 } @@ -156,7 +156,7 @@ init_cpu_features :: proc "c" () { _cpu_name_buf: [72]u8 @(init, private) -init_cpu_name :: proc "c" () { +init_cpu_name :: proc "contextless" () { number_of_extended_ids, _, _, _ := cpuid(0x8000_0000, 0) if number_of_extended_ids < 0x8000_0004 { return diff --git a/core/sys/info/cpu_linux_arm.odin b/core/sys/info/cpu_linux_arm.odin index cde76a83d..6e8b1a634 100644 --- a/core/sys/info/cpu_linux_arm.odin +++ b/core/sys/info/cpu_linux_arm.odin @@ -2,11 +2,13 @@ #+build linux package sysinfo +import "base:runtime" import "core:sys/linux" import "core:strings" @(init, private) -init_cpu_features :: proc() { +init_cpu_features :: proc "contextless" () { + context = runtime.default_context() fd, err := linux.open("/proc/cpuinfo", {}) if err != .NONE { return } defer linux.close(fd) diff --git a/core/sys/info/cpu_linux_intel.odin b/core/sys/info/cpu_linux_intel.odin index e43737475..af76a75e4 100644 --- a/core/sys/info/cpu_linux_intel.odin +++ b/core/sys/info/cpu_linux_intel.odin @@ -2,12 +2,15 @@ #+build linux package sysinfo +import "base:runtime" import "core:sys/linux" import "core:strings" import "core:strconv" @(init, private) -init_cpu_core_count :: proc() { +init_cpu_core_count :: proc "contextless" () { + context = runtime.default_context() + fd, err := linux.open("/proc/cpuinfo", {}) if err != .NONE { return } defer linux.close(fd) diff --git a/core/sys/info/cpu_linux_riscv64.odin b/core/sys/info/cpu_linux_riscv64.odin index 3d36d126d..e65e8a3d2 100644 --- a/core/sys/info/cpu_linux_riscv64.odin +++ b/core/sys/info/cpu_linux_riscv64.odin @@ -7,7 +7,7 @@ import "base:intrinsics" import "core:sys/linux" @(init, private) -init_cpu_features :: proc() { +init_cpu_features :: proc "contextless" () { _features: CPU_Features defer cpu.features = _features @@ -81,11 +81,11 @@ init_cpu_features :: proc() { } err := linux.riscv_hwprobe(raw_data(pairs), len(pairs), 0, nil, {}) if err != nil { - assert(err == .ENOSYS, "unexpected error from riscv_hwprobe()") + assert_contextless(err == .ENOSYS, "unexpected error from riscv_hwprobe()") return } - assert(pairs[0].key == .IMA_EXT_0) + assert_contextless(pairs[0].key == .IMA_EXT_0) exts := pairs[0].value.ima_ext_0 exts -= { .FD, .C, .V } _features += transmute(CPU_Features)exts @@ -97,7 +97,7 @@ init_cpu_features :: proc() { _features += { .Misaligned_Supported } } } else { - assert(pairs[1].key == .CPUPERF_0) + assert_contextless(pairs[1].key == .CPUPERF_0) if .FAST in pairs[1].value.cpu_perf_0 { _features += { .Misaligned_Supported, .Misaligned_Fast } } else if .UNSUPPORTED not_in pairs[1].value.cpu_perf_0 { @@ -108,6 +108,6 @@ init_cpu_features :: proc() { } @(init, private) -init_cpu_name :: proc() { +init_cpu_name :: proc "contextless" () { cpu.name = "RISCV64" } diff --git a/core/sys/info/cpu_windows.odin b/core/sys/info/cpu_windows.odin index 7dd2d2a8c..72d79f9a7 100644 --- a/core/sys/info/cpu_windows.odin +++ b/core/sys/info/cpu_windows.odin @@ -2,9 +2,12 @@ package sysinfo import sys "core:sys/windows" import "base:intrinsics" +import "base:runtime" @(init, private) -init_cpu_core_count :: proc() { +init_cpu_core_count :: proc "contextless" () { + context = runtime.default_context() + infos: []sys.SYSTEM_LOGICAL_PROCESSOR_INFORMATION defer delete(infos) diff --git a/core/sys/info/platform_bsd.odin b/core/sys/info/platform_bsd.odin index 6bb32cd3d..2f8d7f5bb 100644 --- a/core/sys/info/platform_bsd.odin +++ b/core/sys/info/platform_bsd.odin @@ -10,7 +10,9 @@ import "base:runtime" version_string_buf: [1024]u8 @(init, private) -init_os_version :: proc () { +init_os_version :: proc "contextless" () { + context = runtime.default_context() + when ODIN_OS == .NetBSD { os_version.platform = .NetBSD } else { @@ -66,7 +68,7 @@ init_os_version :: proc () { } @(init, private) -init_ram :: proc() { +init_ram :: proc "contextless" () { // Retrieve RAM info using `sysctl` mib := []i32{sys.CTL_HW, sys.HW_PHYSMEM64} mem_size: u64 diff --git a/core/sys/info/platform_darwin.odin b/core/sys/info/platform_darwin.odin index 3fc8064ec..07c26ec28 100644 --- a/core/sys/info/platform_darwin.odin +++ b/core/sys/info/platform_darwin.odin @@ -1,5 +1,7 @@ package sysinfo +import "base:runtime" + import "core:strconv" import "core:strings" import "core:sys/unix" @@ -9,7 +11,8 @@ import NS "core:sys/darwin/Foundation" version_string_buf: [1024]u8 @(init, private) -init_platform :: proc() { +init_platform :: proc "contextless" () { + context = runtime.default_context() ws :: strings.write_string wi :: strings.write_int diff --git a/core/sys/info/platform_freebsd.odin b/core/sys/info/platform_freebsd.odin index b26fb7875..eb39769de 100644 --- a/core/sys/info/platform_freebsd.odin +++ b/core/sys/info/platform_freebsd.odin @@ -9,7 +9,9 @@ import "base:runtime" version_string_buf: [1024]u8 @(init, private) -init_os_version :: proc () { +init_os_version :: proc "contextless" () { + context = runtime.default_context() + os_version.platform = .FreeBSD kernel_version_buf: [1024]u8 @@ -68,7 +70,7 @@ init_os_version :: proc () { } @(init, private) -init_ram :: proc() { +init_ram :: proc "contextless" () { // Retrieve RAM info using `sysctl` mib := []i32{sys.CTL_HW, sys.HW_PHYSMEM} mem_size: u64 diff --git a/core/sys/info/platform_linux.odin b/core/sys/info/platform_linux.odin index 9c342e567..43cd580c1 100644 --- a/core/sys/info/platform_linux.odin +++ b/core/sys/info/platform_linux.odin @@ -1,6 +1,7 @@ package sysinfo import "base:intrinsics" +import "base:runtime" import "core:strconv" import "core:strings" @@ -10,7 +11,9 @@ import "core:sys/linux" version_string_buf: [1024]u8 @(init, private) -init_os_version :: proc () { +init_os_version :: proc "contextless" () { + context = runtime.default_context() + os_version.platform = .Linux b := strings.builder_from_bytes(version_string_buf[:]) @@ -91,11 +94,11 @@ init_os_version :: proc () { } @(init, private) -init_ram :: proc() { +init_ram :: proc "contextless" () { // Retrieve RAM info using `sysinfo` sys_info: linux.Sys_Info errno := linux.sysinfo(&sys_info) - assert(errno == .NONE, "Good luck to whoever's debugging this, something's seriously cucked up!") + assert_contextless(errno == .NONE, "Good luck to whoever's debugging this, something's seriously cucked up!") ram = RAM{ total_ram = int(sys_info.totalram) * int(sys_info.mem_unit), free_ram = int(sys_info.freeram) * int(sys_info.mem_unit), diff --git a/core/sys/info/platform_windows.odin b/core/sys/info/platform_windows.odin index dd1441d30..ff8ebe2ee 100644 --- a/core/sys/info/platform_windows.odin +++ b/core/sys/info/platform_windows.odin @@ -12,7 +12,9 @@ import "base:runtime" version_string_buf: [1024]u8 @(init, private) -init_os_version :: proc () { +init_os_version :: proc "contextless" () { + context = runtime.default_context() + /* NOTE(Jeroen): `GetVersionEx` will return 6.2 for Windows 10 unless the program is manifested for Windows 10. @@ -43,6 +45,7 @@ init_os_version :: proc () { os_version.minor = int(osvi.dwMinorVersion) os_version.build[0] = int(osvi.dwBuildNumber) + b := strings.builder_from_bytes(version_string_buf[:]) strings.write_string(&b, "Windows ") @@ -259,7 +262,7 @@ init_os_version :: proc () { } @(init, private) -init_ram :: proc() { +init_ram :: proc "contextless" () { state: sys.MEMORYSTATUSEX state.dwLength = size_of(state) @@ -276,10 +279,11 @@ init_ram :: proc() { } @(init, private) -init_gpu_info :: proc() { - +init_gpu_info :: proc "contextless" () { GPU_INFO_BASE :: "SYSTEM\\ControlSet001\\Control\\Class\\{4d36e968-e325-11ce-bfc1-08002be10318}\\" + context = runtime.default_context() + gpu_list: [dynamic]GPU gpu_index: int diff --git a/core/sys/posix/stdlib_libc.odin b/core/sys/posix/stdlib_libc.odin index e31c51704..966dc1d32 100644 --- a/core/sys/posix/stdlib_libc.odin +++ b/core/sys/posix/stdlib_libc.odin @@ -60,7 +60,7 @@ wctomb :: libc.wctomb mbstowcs :: libc.mbstowcs wcstombs :: libc.wcstombs -free :: #force_inline proc(ptr: $T) where intrinsics.type_is_pointer(T) || intrinsics.type_is_multi_pointer(T) || T == cstring { +free :: #force_inline proc "c" (ptr: $T) where intrinsics.type_is_pointer(T) || intrinsics.type_is_multi_pointer(T) || T == cstring { libc.free(rawptr(ptr)) } diff --git a/core/sys/unix/sysctl_freebsd.odin b/core/sys/unix/sysctl_freebsd.odin index f5fee6c6c..cdd591a5b 100644 --- a/core/sys/unix/sysctl_freebsd.odin +++ b/core/sys/unix/sysctl_freebsd.odin @@ -3,7 +3,7 @@ package unix import "base:intrinsics" -sysctl :: proc(mib: []i32, val: ^$T) -> (ok: bool) { +sysctl :: proc "contextless" (mib: []i32, val: ^$T) -> (ok: bool) { mib := mib result_size := u64(size_of(T)) diff --git a/core/sys/unix/sysctl_netbsd.odin b/core/sys/unix/sysctl_netbsd.odin index ad89b9ad4..b70740721 100644 --- a/core/sys/unix/sysctl_netbsd.odin +++ b/core/sys/unix/sysctl_netbsd.odin @@ -8,7 +8,7 @@ foreign libc { @(link_name="sysctl") _unix_sysctl :: proc(name: [^]i32, namelen: u32, oldp: rawptr, oldlenp: ^c.size_t, newp: rawptr, newlen: c.size_t) -> i32 --- } -sysctl :: proc(mib: []i32, val: ^$T) -> (ok: bool) { +sysctl :: proc "contextless" (mib: []i32, val: ^$T) -> (ok: bool) { mib := mib result_size := c.size_t(size_of(T)) res := _unix_sysctl(raw_data(mib), u32(len(mib)), val, &result_size, nil, 0) diff --git a/core/sys/unix/sysctl_openbsd.odin b/core/sys/unix/sysctl_openbsd.odin index 49c9b6336..e71b743f8 100644 --- a/core/sys/unix/sysctl_openbsd.odin +++ b/core/sys/unix/sysctl_openbsd.odin @@ -9,7 +9,7 @@ foreign libc { @(link_name="sysctl") _unix_sysctl :: proc(name: [^]i32, namelen: u32, oldp: rawptr, oldlenp: ^c.size_t, newp: rawptr, newlen: c.size_t) -> i32 --- } -sysctl :: proc(mib: []i32, val: ^$T) -> (ok: bool) { +sysctl :: proc "contextless" (mib: []i32, val: ^$T) -> (ok: bool) { mib := mib result_size := c.size_t(size_of(T)) res := _unix_sysctl(raw_data(mib), u32(len(mib)), val, &result_size, nil, 0) diff --git a/core/sys/windows/util.odin b/core/sys/windows/util.odin index 10dc907e7..125038ac4 100644 --- a/core/sys/windows/util.odin +++ b/core/sys/windows/util.odin @@ -628,7 +628,7 @@ run_as_user :: proc(username, password, application, commandline: string, pi: ^P } } -ensure_winsock_initialized :: proc() { +ensure_winsock_initialized :: proc "contextless" () { @static gate := false @static initted := false @@ -644,7 +644,7 @@ ensure_winsock_initialized :: proc() { unused_info: WSADATA version_requested := WORD(2) << 8 | 2 res := WSAStartup(version_requested, &unused_info) - assert(res == 0, "unable to initialized Winsock2") + assert_contextless(res == 0, "unable to initialized Winsock2") initted = true } diff --git a/core/terminal/internal.odin b/core/terminal/internal.odin index 44007e14f..9404ff833 100644 --- a/core/terminal/internal.odin +++ b/core/terminal/internal.odin @@ -1,6 +1,7 @@ #+private package terminal +import "base:runtime" import "core:os" import "core:strings" @@ -68,9 +69,11 @@ get_environment_color :: proc() -> Color_Depth { } @(init) -init_terminal :: proc() { +init_terminal :: proc "contextless" () { _init_terminal() + context = runtime.default_context() + // We respect `NO_COLOR` specifically as a color-disabler but not as a // blanket ban on any terminal manipulation codes, hence why this comes // after `_init_terminal` which will allow Windows to enable Virtual @@ -81,6 +84,6 @@ init_terminal :: proc() { } @(fini) -fini_terminal :: proc() { +fini_terminal :: proc "contextless" () { _fini_terminal() } diff --git a/core/terminal/terminal_js.odin b/core/terminal/terminal_js.odin index 2d880420b..4dcd4465e 100644 --- a/core/terminal/terminal_js.odin +++ b/core/terminal/terminal_js.odin @@ -4,12 +4,12 @@ package terminal import "core:os" -_is_terminal :: proc(handle: os.Handle) -> bool { +_is_terminal :: proc "contextless" (handle: os.Handle) -> bool { return true } -_init_terminal :: proc() { +_init_terminal :: proc "contextless" () { color_depth = .None } -_fini_terminal :: proc() { } \ No newline at end of file +_fini_terminal :: proc "contextless" () { } \ No newline at end of file diff --git a/core/terminal/terminal_posix.odin b/core/terminal/terminal_posix.odin index f578e12c6..8d96dd256 100644 --- a/core/terminal/terminal_posix.odin +++ b/core/terminal/terminal_posix.odin @@ -2,15 +2,17 @@ #+build linux, darwin, netbsd, openbsd, freebsd, haiku package terminal +import "base:runtime" import "core:os" import "core:sys/posix" -_is_terminal :: proc(handle: os.Handle) -> bool { +_is_terminal :: proc "contextless" (handle: os.Handle) -> bool { return bool(posix.isatty(posix.FD(handle))) } -_init_terminal :: proc() { +_init_terminal :: proc "contextless" () { + context = runtime.default_context() color_depth = get_environment_color() } -_fini_terminal :: proc() { } +_fini_terminal :: proc "contextless" () { } diff --git a/core/terminal/terminal_windows.odin b/core/terminal/terminal_windows.odin index 18ec98332..6d5f98a1f 100644 --- a/core/terminal/terminal_windows.odin +++ b/core/terminal/terminal_windows.odin @@ -1,10 +1,11 @@ #+private package terminal +import "base:runtime" import "core:os" import "core:sys/windows" -_is_terminal :: proc(handle: os.Handle) -> bool { +_is_terminal :: proc "contextless" (handle: os.Handle) -> bool { is_tty := windows.GetFileType(windows.HANDLE(handle)) == windows.FILE_TYPE_CHAR return is_tty } @@ -18,7 +19,7 @@ old_modes: [2]struct{ } @(init) -_init_terminal :: proc() { +_init_terminal :: proc "contextless" () { vtp_enabled: bool for &v in old_modes { @@ -42,13 +43,15 @@ _init_terminal :: proc() { // This color depth is available on Windows 10 since build 10586. color_depth = .Four_Bit } else { + context = runtime.default_context() + // The user may be on a non-default terminal emulator. color_depth = get_environment_color() } } @(fini) -_fini_terminal :: proc() { +_fini_terminal :: proc "contextless" () { for v in old_modes { handle := windows.GetStdHandle(v.handle) if handle == windows.INVALID_HANDLE || handle == nil { diff --git a/src/check_decl.cpp b/src/check_decl.cpp index af46ee40e..ee7906e5e 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1851,6 +1851,12 @@ gb_internal void check_entity_decl(CheckerContext *ctx, Entity *e, DeclInfo *d, c.scope = d->scope; c.decl = d; c.type_level = 0; + c.curr_proc_calling_convention = ProcCC_Contextless; + + auto prev_flags = c.scope->flags; + defer (c.scope->flags = prev_flags); + c.scope->flags &= ~ScopeFlag_ContextDefined; + e->parent_proc_decl = c.curr_proc_decl; e->state = EntityState_InProgress; diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 6a50b553e..db82a60ce 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -8169,8 +8169,12 @@ gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *c if (pt->kind == Type_Proc && pt->Proc.calling_convention == ProcCC_Odin) { if ((c->scope->flags & ScopeFlag_ContextDefined) == 0) { ERROR_BLOCK(); - error(call, "'context' has not been defined within this scope, but is required for this procedure call"); - error_line("\tSuggestion: 'context = runtime.default_context()'"); + if (c->scope->flags & ScopeFlag_File) { + error(call, "Procedures requiring a 'context' cannot be called at the global scope"); + } else { + error(call, "'context' has not been defined within this scope, but is required for this procedure call"); + error_line("\tSuggestion: 'context = runtime.default_context()'"); + } } } diff --git a/src/checker.cpp b/src/checker.cpp index a13290750..f631a1412 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -2675,6 +2675,10 @@ gb_internal void generate_minimum_dependency_set_internal(Checker *c, Entity *st is_init = false; } + if (t->Proc.calling_convention != ProcCC_Contextless) { + error(e->token, "@(init) procedures must be declared as \"contextless\""); + } + if ((e->scope->flags & (ScopeFlag_File|ScopeFlag_Pkg)) == 0) { error(e->token, "@(init) procedures must be declared at the file scope"); is_init = false; @@ -2689,6 +2693,7 @@ gb_internal void generate_minimum_dependency_set_internal(Checker *c, Entity *st error(e->token, "An @(init) procedure must not use a blank identifier as its name"); } + if (is_init) { add_dependency_to_set(c, e); array_add(&c->info.init_procedures, e); @@ -2706,6 +2711,10 @@ gb_internal void generate_minimum_dependency_set_internal(Checker *c, Entity *st is_fini = false; } + if (t->Proc.calling_convention != ProcCC_Contextless) { + error(e->token, "@(fini) procedures must be declared as \"contextless\""); + } + if ((e->scope->flags & (ScopeFlag_File|ScopeFlag_Pkg)) == 0) { error(e->token, "@(fini) procedures must be declared at the file scope"); is_fini = false; diff --git a/tests/core/flags/test_core_flags.odin b/tests/core/flags/test_core_flags.odin index 0527d85c5..0cfcf8e75 100644 --- a/tests/core/flags/test_core_flags.odin +++ b/tests/core/flags/test_core_flags.odin @@ -17,7 +17,7 @@ Custom_Data :: struct { } @(init) -init_custom_type_setter :: proc() { +init_custom_type_setter :: proc "contextless" () { // NOTE: This is done here so it can be out of the flow of the // multi-threaded test runner, to prevent any data races that could be // reported by using `-sanitize:thread`. diff --git a/tests/core/normal.odin b/tests/core/normal.odin index 5bc73bd24..fe69acf64 100644 --- a/tests/core/normal.odin +++ b/tests/core/normal.odin @@ -3,9 +3,9 @@ package tests_core import rlibc "core:c/libc" @(init) -download_assets :: proc() { +download_assets :: proc "contextless" () { if rlibc.system("python3 " + ODIN_ROOT + "tests/core/download_assets.py " + ODIN_ROOT + "tests/core/assets") != 0 { - panic("downloading test assets failed!") + panic_contextless("downloading test assets failed!") } } diff --git a/tests/internal/test_global_any.odin b/tests/internal/test_global_any.odin index 73b70e0a4..850884912 100644 --- a/tests/internal/test_global_any.odin +++ b/tests/internal/test_global_any.odin @@ -3,7 +3,7 @@ package test_internal @(private="file") global_any_from_proc: any = from_proc() -from_proc :: proc() -> f32 { +from_proc :: proc "contextless" () -> f32 { return 1.1 } diff --git a/vendor/libc/libc.odin b/vendor/libc/libc.odin index 00d687109..a5508e14f 100644 --- a/vendor/libc/libc.odin +++ b/vendor/libc/libc.odin @@ -10,8 +10,9 @@ g_ctx: runtime.Context g_allocator: mem.Compat_Allocator @(init) -init_context :: proc() { - g_ctx = context +init_context :: proc "contextless" () { + g_ctx = runtime.default_context() + context = g_ctx // Wrapping the allocator with the mem.Compat_Allocator so we can // mimic the realloc semantics. diff --git a/vendor/libc/stdlib.odin b/vendor/libc/stdlib.odin index 9f578a436..bb9233a28 100644 --- a/vendor/libc/stdlib.odin +++ b/vendor/libc/stdlib.odin @@ -169,7 +169,7 @@ exit :: proc "c" (exit_code: c.int) -> ! { } @(private, fini) -finish_atexit :: proc "c" () { +finish_atexit :: proc "contextless" () { n := intrinsics.atomic_exchange(&atexit_functions_count, 0) for function in atexit_functions[:n] { function() diff --git a/vendor/miniaudio/common.odin b/vendor/miniaudio/common.odin index 0263278bc..e675cb7f6 100644 --- a/vendor/miniaudio/common.odin +++ b/vendor/miniaudio/common.odin @@ -25,7 +25,7 @@ BINDINGS_VERSION :: [3]u32{BINDINGS_VERSION_MAJOR, BINDINGS_VERSION_MIN BINDINGS_VERSION_STRING :: "0.11.22" @(init) -version_check :: proc() { +version_check :: proc "contextless" () { v: [3]u32 version(&v.x, &v.y, &v.z) if v != BINDINGS_VERSION { @@ -43,7 +43,7 @@ version_check :: proc() { n += copy(buf[n:], "and executing `make`") } - panic(string(buf[:n])) + panic_contextless(string(buf[:n])) } } diff --git a/vendor/wgpu/wgpu_js.odin b/vendor/wgpu/wgpu_js.odin index 3c8375adb..3217a97dc 100644 --- a/vendor/wgpu/wgpu_js.odin +++ b/vendor/wgpu/wgpu_js.odin @@ -5,7 +5,7 @@ import "base:runtime" g_context: runtime.Context @(private="file", init) -wgpu_init_allocator :: proc() { +wgpu_init_allocator :: proc "contextless" () { if g_context.allocator.procedure == nil { g_context = runtime.default_context() }