diff options
| author | korvahkh <92224397+korvahkh@users.noreply.github.com> | 2024-06-13 01:27:44 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-06-13 01:27:44 +0000 |
| commit | 104ca2ce22c269b71df08edb00cb26bee4daf59d (patch) | |
| tree | ee0a3275d3b42ae9aa85d09bf01f278d3965cc31 /base | |
| parent | a7a6ff8c693be92929327660fd446dfc0af62e01 (diff) | |
| parent | a67df0739245d85e7aa773e7271a64121ca534c5 (diff) | |
Merge branch 'odin-lang:master' into fix-omitempty-comma
Diffstat (limited to 'base')
| -rw-r--r-- | base/builtin/builtin.odin | 2 | ||||
| -rw-r--r-- | base/intrinsics/intrinsics.odin | 4 | ||||
| -rw-r--r-- | base/runtime/core.odin | 40 | ||||
| -rw-r--r-- | base/runtime/core_builtin.odin | 10 | ||||
| -rw-r--r-- | base/runtime/default_allocators_general.odin | 2 | ||||
| -rw-r--r-- | base/runtime/docs.odin | 2 | ||||
| -rw-r--r-- | base/runtime/entry_wasm.odin | 36 | ||||
| -rw-r--r-- | base/runtime/error_checks.odin | 4 | ||||
| -rw-r--r-- | base/runtime/heap_allocator_orca.odin | 29 | ||||
| -rw-r--r-- | base/runtime/heap_allocator_other.odin | 2 | ||||
| -rw-r--r-- | base/runtime/internal.odin | 4 | ||||
| -rw-r--r-- | base/runtime/os_specific_orca.odin | 43 | ||||
| -rw-r--r-- | base/runtime/procs.odin | 26 | ||||
| -rw-r--r-- | base/runtime/wasm_allocator.odin | 28 |
14 files changed, 185 insertions, 47 deletions
diff --git a/base/builtin/builtin.odin b/base/builtin/builtin.odin index 5cba3c8ea..c4a9b141f 100644 --- a/base/builtin/builtin.odin +++ b/base/builtin/builtin.odin @@ -126,3 +126,5 @@ clamp :: proc(value, minimum, maximum: T) -> T --- soa_zip :: proc(slices: ...) -> #soa[]Struct --- soa_unzip :: proc(value: $S/#soa[]$E) -> (slices: ...) --- + +unreachable :: proc() -> ! --- diff --git a/base/intrinsics/intrinsics.odin b/base/intrinsics/intrinsics.odin index 8873f3bbc..4f6fa2713 100644 --- a/base/intrinsics/intrinsics.odin +++ b/base/intrinsics/intrinsics.odin @@ -295,6 +295,10 @@ simd_rotate_right :: proc(a: #simd[N]T, $offset: int) -> #simd[N]T --- // if all listed features are supported. has_target_feature :: proc($test: $T) -> bool where type_is_string(T) || type_is_proc(T) --- + +// Returns the value of the procedure where `x` must be a call expression +procedure_of :: proc(x: $T) -> T where type_is_proc(T) --- + // WASM targets only wasm_memory_grow :: proc(index, delta: uintptr) -> int --- wasm_memory_size :: proc(index: uintptr) -> int --- diff --git a/base/runtime/core.odin b/base/runtime/core.odin index 66099e787..8671920f5 100644 --- a/base/runtime/core.odin +++ b/base/runtime/core.odin @@ -470,6 +470,15 @@ Raw_Soa_Pointer :: struct { index: int, } +Raw_Complex32 :: struct {real, imag: f16} +Raw_Complex64 :: struct {real, imag: f32} +Raw_Complex128 :: struct {real, imag: f64} +Raw_Quaternion64 :: struct {imag, jmag, kmag: f16, real: f16} +Raw_Quaternion128 :: struct {imag, jmag, kmag: f32, real: f32} +Raw_Quaternion256 :: struct {imag, jmag, kmag: f64, real: f64} +Raw_Quaternion64_Vector_Scalar :: struct {vector: [3]f16, scalar: f16} +Raw_Quaternion128_Vector_Scalar :: struct {vector: [3]f32, scalar: f32} +Raw_Quaternion256_Vector_Scalar :: struct {vector: [3]f64, scalar: f64} /* @@ -481,7 +490,9 @@ Raw_Soa_Pointer :: struct { Linux, Essence, FreeBSD, + Haiku, OpenBSD, + NetBSD, WASI, JS, Freestanding, @@ -508,6 +519,7 @@ Odin_Arch_Type :: type_of(ODIN_ARCH) Odin_Build_Mode_Type :: enum int { Executable, Dynamic, + Static, Object, Assembly, LLVM_IR, @@ -548,6 +560,19 @@ Odin_Platform_Subtarget_Type :: type_of(ODIN_PLATFORM_SUBTARGET) */ Odin_Sanitizer_Flags :: type_of(ODIN_SANITIZER_FLAGS) +/* + // Defined internally by the compiler + Odin_Optimization_Mode :: enum int { + None = -1, + Minimal = 0, + Size = 1, + Speed = 2, + Aggressive = 3, + } + + ODIN_OPTIMIZATION_MODE // is a constant +*/ +Odin_Optimization_Mode :: type_of(ODIN_OPTIMIZATION_MODE) ///////////////////////////// // Init Startup Procedures // @@ -689,7 +714,7 @@ default_assertion_failure_proc :: proc(prefix, message: string, loc: Source_Code when ODIN_OS == .Freestanding { // Do nothing } else { - when !ODIN_DISABLE_ASSERT { + when ODIN_OS != .Orca && !ODIN_DISABLE_ASSERT { print_caller_location(loc) print_string(" ") } @@ -698,7 +723,18 @@ default_assertion_failure_proc :: proc(prefix, message: string, loc: Source_Code print_string(": ") print_string(message) } - print_byte('\n') + + when ODIN_OS == .Orca { + assert_fail( + cstring(raw_data(loc.file_path)), + cstring(raw_data(loc.procedure)), + loc.line, + "", + cstring(raw_data(orca_stderr_buffer[:orca_stderr_buffer_idx])), + ) + } else { + print_byte('\n') + } } trap() } diff --git a/base/runtime/core_builtin.odin b/base/runtime/core_builtin.odin index 00c30d3fd..a9566c831 100644 --- a/base/runtime/core_builtin.odin +++ b/base/runtime/core_builtin.odin @@ -383,7 +383,7 @@ clear_map :: proc "contextless" (m: ^$T/map[$K]$V) { // // Note: Prefer the procedure group `reserve` @builtin -reserve_map :: proc(m: ^$T/map[$K]$V, capacity: int, loc := #caller_location) -> Allocator_Error { +reserve_map :: proc(m: ^$T/map[$K]$V, #any_int capacity: int, loc := #caller_location) -> Allocator_Error { return __dynamic_map_reserve((^Raw_Map)(m), map_info(T), uint(capacity), loc) if m != nil else nil } @@ -721,12 +721,12 @@ _reserve_dynamic_array :: #force_inline proc(array: ^$T/[dynamic]$E, capacity: i } @builtin -reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, capacity: int, loc := #caller_location) -> Allocator_Error { +reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, #any_int 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 { +non_zero_reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, #any_int capacity: int, loc := #caller_location) -> Allocator_Error { return _reserve_dynamic_array(array, capacity, false, loc) } @@ -773,12 +773,12 @@ _resize_dynamic_array :: #force_inline proc(array: ^$T/[dynamic]$E, length: int, } @builtin -resize_dynamic_array :: proc(array: ^$T/[dynamic]$E, length: int, loc := #caller_location) -> Allocator_Error { +resize_dynamic_array :: proc(array: ^$T/[dynamic]$E, #any_int 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 { +non_zero_resize_dynamic_array :: proc(array: ^$T/[dynamic]$E, #any_int length: int, loc := #caller_location) -> Allocator_Error { return _resize_dynamic_array(array, length, false, loc=loc) } diff --git a/base/runtime/default_allocators_general.odin b/base/runtime/default_allocators_general.odin index ab4dd1db8..64af6c904 100644 --- a/base/runtime/default_allocators_general.odin +++ b/base/runtime/default_allocators_general.odin @@ -6,7 +6,7 @@ when ODIN_DEFAULT_TO_NIL_ALLOCATOR { } else when ODIN_DEFAULT_TO_PANIC_ALLOCATOR { default_allocator_proc :: panic_allocator_proc default_allocator :: panic_allocator -} else when ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32 { +} else when ODIN_OS != .Orca && (ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32) { default_allocator :: default_wasm_allocator default_allocator_proc :: wasm_allocator_proc } else { diff --git a/base/runtime/docs.odin b/base/runtime/docs.odin index 865eeb9ef..f6b439aa0 100644 --- a/base/runtime/docs.odin +++ b/base/runtime/docs.odin @@ -157,7 +157,7 @@ __dynamic_map_get // dynamic map calls __dynamic_map_set // dynamic map calls -## Dynamic literals ([dymamic]T and map[K]V) (can be disabled with -no-dynamic-literals) +## Dynamic literals ([dynamic]T and map[K]V) (can be disabled with -no-dynamic-literals) __dynamic_array_reserve __dynamic_array_append diff --git a/base/runtime/entry_wasm.odin b/base/runtime/entry_wasm.odin index c608942ba..a24c6f4b7 100644 --- a/base/runtime/entry_wasm.odin +++ b/base/runtime/entry_wasm.odin @@ -6,15 +6,29 @@ package runtime import "base:intrinsics" when !ODIN_TEST && !ODIN_NO_ENTRY_POINT { - @(link_name="_start", linkage="strong", require, export) - _start :: proc "c" () { - context = default_context() - #force_no_inline _startup_runtime() - intrinsics.__entry_point() + when ODIN_OS == .Orca { + @(linkage="strong", require, export) + oc_on_init :: proc "c" () { + context = default_context() + #force_no_inline _startup_runtime() + intrinsics.__entry_point() + } + @(linkage="strong", require, export) + oc_on_terminate :: proc "c" () { + context = default_context() + #force_no_inline _cleanup_runtime() + } + } else { + @(link_name="_start", linkage="strong", require, export) + _start :: proc "c" () { + context = default_context() + #force_no_inline _startup_runtime() + intrinsics.__entry_point() + } + @(link_name="_end", linkage="strong", require, export) + _end :: proc "c" () { + context = default_context() + #force_no_inline _cleanup_runtime() + } } - @(link_name="_end", linkage="strong", require, export) - _end :: proc "c" () { - context = default_context() - #force_no_inline _cleanup_runtime() - } -}
\ No newline at end of file +} diff --git a/base/runtime/error_checks.odin b/base/runtime/error_checks.odin index 742e06a71..32a895c3f 100644 --- a/base/runtime/error_checks.odin +++ b/base/runtime/error_checks.odin @@ -4,6 +4,8 @@ package runtime bounds_trap :: proc "contextless" () -> ! { when ODIN_OS == .Windows { windows_trap_array_bounds() + } else when ODIN_OS == .Orca { + abort_ext("", "", 0, "bounds trap") } else { trap() } @@ -13,6 +15,8 @@ bounds_trap :: proc "contextless" () -> ! { type_assertion_trap :: proc "contextless" () -> ! { when ODIN_OS == .Windows { windows_trap_type_assertion() + } else when ODIN_OS == .Orca { + abort_ext("", "", 0, "type assertion trap") } else { trap() } diff --git a/base/runtime/heap_allocator_orca.odin b/base/runtime/heap_allocator_orca.odin new file mode 100644 index 000000000..c22a67ca1 --- /dev/null +++ b/base/runtime/heap_allocator_orca.odin @@ -0,0 +1,29 @@ +//+build orca +//+private +package runtime + +foreign { + @(link_name="malloc") _orca_malloc :: proc "c" (size: int) -> rawptr --- + @(link_name="calloc") _orca_calloc :: proc "c" (num, size: int) -> rawptr --- + @(link_name="free") _orca_free :: proc "c" (ptr: rawptr) --- + @(link_name="realloc") _orca_realloc :: proc "c" (ptr: rawptr, size: int) -> rawptr --- +} + +_heap_alloc :: proc(size: int, zero_memory := true) -> rawptr { + if size <= 0 { + return nil + } + if zero_memory { + return _orca_calloc(1, size) + } else { + return _orca_malloc(size) + } +} + +_heap_resize :: proc(ptr: rawptr, new_size: int) -> rawptr { + return _orca_realloc(ptr, new_size) +} + +_heap_free :: proc(ptr: rawptr) { + _orca_free(ptr) +} diff --git a/base/runtime/heap_allocator_other.odin b/base/runtime/heap_allocator_other.odin index 45049c7e9..74536ada9 100644 --- a/base/runtime/heap_allocator_other.odin +++ b/base/runtime/heap_allocator_other.odin @@ -12,4 +12,4 @@ _heap_resize :: proc(ptr: rawptr, new_size: int) -> rawptr { _heap_free :: proc(ptr: rawptr) { unimplemented("base:runtime 'heap_free' procedure is not supported on this platform") -}
\ No newline at end of file +} diff --git a/base/runtime/internal.odin b/base/runtime/internal.odin index 8e1b3d633..378eea256 100644 --- a/base/runtime/internal.odin +++ b/base/runtime/internal.odin @@ -483,7 +483,7 @@ quaternion256_ne :: #force_inline proc "contextless" (a, b: quaternion256) -> bo string_decode_rune :: #force_inline proc "contextless" (s: string) -> (rune, int) { // NOTE(bill): Duplicated here to remove dependency on package unicode/utf8 - @static accept_sizes := [256]u8{ + @(static, rodata) accept_sizes := [256]u8{ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x00-0x0f 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x10-0x1f 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x20-0x2f @@ -504,7 +504,7 @@ string_decode_rune :: #force_inline proc "contextless" (s: string) -> (rune, int } Accept_Range :: struct {lo, hi: u8} - @static accept_ranges := [5]Accept_Range{ + @(static, rodata) accept_ranges := [5]Accept_Range{ {0x80, 0xbf}, {0xa0, 0xbf}, {0x80, 0x9f}, diff --git a/base/runtime/os_specific_orca.odin b/base/runtime/os_specific_orca.odin new file mode 100644 index 000000000..b6f5930ab --- /dev/null +++ b/base/runtime/os_specific_orca.odin @@ -0,0 +1,43 @@ +//+build orca +//+private +package runtime + +import "base:intrinsics" + +// Constants allowing to specify the level of logging verbosity. +log_level :: enum u32 { + // Only errors are logged. + ERROR = 0, + // Only warnings and errors are logged. + WARNING = 1, + // All messages are logged. + INFO = 2, + COUNT = 3, +} + +@(default_calling_convention="c", link_prefix="oc_") +foreign { + abort_ext :: proc(file: cstring, function: cstring, line: i32, fmt: cstring, #c_vararg args: ..any) -> ! --- + assert_fail :: proc(file: cstring, function: cstring, line: i32, src: cstring, fmt: cstring, #c_vararg args: ..any) -> ! --- + log_ext :: proc(level: log_level, function: cstring, file: cstring, line: i32, fmt: cstring, #c_vararg args: ..any) --- +} + +// NOTE: This is all pretty gross, don't look. + +// WASM is single threaded so this should be fine. +orca_stderr_buffer: [4096]byte +orca_stderr_buffer_idx: int + +_stderr_write :: proc "contextless" (data: []byte) -> (int, _OS_Errno) { + for b in data { + orca_stderr_buffer[orca_stderr_buffer_idx] = b + orca_stderr_buffer_idx += 1 + + if b == '\n' || orca_stderr_buffer_idx == len(orca_stderr_buffer)-1 { + log_ext(.ERROR, "", "", 0, cstring(raw_data(orca_stderr_buffer[:orca_stderr_buffer_idx]))) + orca_stderr_buffer_idx = 0 + } + } + + return len(data), 0 +} diff --git a/base/runtime/procs.odin b/base/runtime/procs.odin index 454574c35..002a6501f 100644 --- a/base/runtime/procs.odin +++ b/base/runtime/procs.odin @@ -25,13 +25,19 @@ when ODIN_NO_CRT && ODIN_OS == .Windows { RtlMoveMemory(dst, src, len) return dst } -} else when ODIN_NO_CRT || (ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32) { +} else when ODIN_NO_CRT || (ODIN_OS != .Orca && (ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32)) { + // NOTE: on wasm, calls to these procs are generated (by LLVM) with type `i32` instead of `int`. + // + // NOTE: `#any_int` is also needed, because calls that we generate (and package code) + // will be using `int` and need to be converted. + int_t :: i32 when ODIN_ARCH == .wasm64p32 else int + @(link_name="memset", linkage="strong", require) - memset :: proc "c" (ptr: rawptr, val: i32, len: int) -> rawptr { + memset :: proc "c" (ptr: rawptr, val: i32, #any_int len: int_t) -> rawptr { if ptr != nil && len != 0 { b := byte(val) p := ([^]byte)(ptr) - for i := 0; i < len; i += 1 { + for i := int_t(0); i < len; i += 1 { p[i] = b } } @@ -39,10 +45,10 @@ when ODIN_NO_CRT && ODIN_OS == .Windows { } @(link_name="bzero", linkage="strong", require) - bzero :: proc "c" (ptr: rawptr, len: int) -> rawptr { + bzero :: proc "c" (ptr: rawptr, #any_int len: int_t) -> rawptr { if ptr != nil && len != 0 { p := ([^]byte)(ptr) - for i := 0; i < len; i += 1 { + for i := int_t(0); i < len; i += 1 { p[i] = 0 } } @@ -50,7 +56,7 @@ when ODIN_NO_CRT && ODIN_OS == .Windows { } @(link_name="memmove", linkage="strong", require) - memmove :: proc "c" (dst, src: rawptr, len: int) -> rawptr { + memmove :: proc "c" (dst, src: rawptr, #any_int len: int_t) -> rawptr { d, s := ([^]byte)(dst), ([^]byte)(src) if d == s || len == 0 { return dst @@ -63,7 +69,7 @@ when ODIN_NO_CRT && ODIN_OS == .Windows { } if s > d && uintptr(s)-uintptr(d) < uintptr(len) { - for i := 0; i < len; i += 1 { + for i := int_t(0); i < len; i += 1 { d[i] = s[i] } return dst @@ -71,10 +77,10 @@ when ODIN_NO_CRT && ODIN_OS == .Windows { return memcpy(dst, src, len) } @(link_name="memcpy", linkage="strong", require) - memcpy :: proc "c" (dst, src: rawptr, len: int) -> rawptr { + memcpy :: proc "c" (dst, src: rawptr, #any_int len: int_t) -> rawptr { d, s := ([^]byte)(dst), ([^]byte)(src) if d != s { - for i := 0; i < len; i += 1 { + for i := int_t(0); i < len; i += 1 { d[i] = s[i] } } @@ -92,4 +98,4 @@ when ODIN_NO_CRT && ODIN_OS == .Windows { } return ptr } -}
\ No newline at end of file +} diff --git a/base/runtime/wasm_allocator.odin b/base/runtime/wasm_allocator.odin index acfc80b0a..6bca0b3d6 100644 --- a/base/runtime/wasm_allocator.odin +++ b/base/runtime/wasm_allocator.odin @@ -7,20 +7,20 @@ import "base:intrinsics" Port of emmalloc, modified for use in Odin. Invariants: - - Per-allocation header overhead is 8 bytes, smallest allocated payload - amount is 8 bytes, and a multiple of 4 bytes. - - Acquired memory blocks are subdivided into disjoint regions that lie - next to each other. - - A region is either in used or free. - Used regions may be adjacent, and a used and unused region - may be adjacent, but not two unused ones - they would be - merged. - - Memory allocation takes constant time, unless the alloc needs to wasm_memory_grow() - or memory is very close to being exhausted. - - Free and used regions are managed inside "root regions", which are slabs - of memory acquired via wasm_memory_grow(). - - Memory retrieved using wasm_memory_grow() can not be given back to the OS. - Therefore, frees are internal to the allocator. + - Per-allocation header overhead is 8 bytes, smallest allocated payload + amount is 8 bytes, and a multiple of 4 bytes. + - Acquired memory blocks are subdivided into disjoint regions that lie + next to each other. + - A region is either in used or free. + Used regions may be adjacent, and a used and unused region + may be adjacent, but not two unused ones - they would be + merged. + - Memory allocation takes constant time, unless the alloc needs to wasm_memory_grow() + or memory is very close to being exhausted. + - Free and used regions are managed inside "root regions", which are slabs + of memory acquired via wasm_memory_grow(). + - Memory retrieved using wasm_memory_grow() can not be given back to the OS. + Therefore, frees are internal to the allocator. Copyright (c) 2010-2014 Emscripten authors, see AUTHORS file. |