aboutsummaryrefslogtreecommitdiff
path: root/base/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'base/runtime')
-rw-r--r--base/runtime/core.odin40
-rw-r--r--base/runtime/core_builtin.odin10
-rw-r--r--base/runtime/default_allocators_general.odin2
-rw-r--r--base/runtime/docs.odin2
-rw-r--r--base/runtime/entry_wasm.odin36
-rw-r--r--base/runtime/error_checks.odin4
-rw-r--r--base/runtime/heap_allocator_orca.odin29
-rw-r--r--base/runtime/heap_allocator_other.odin2
-rw-r--r--base/runtime/internal.odin4
-rw-r--r--base/runtime/os_specific_orca.odin43
-rw-r--r--base/runtime/procs.odin26
-rw-r--r--base/runtime/wasm_allocator.odin28
12 files changed, 179 insertions, 47 deletions
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.