mirror of
https://github.com/odin-lang/Odin.git
synced 2026-06-04 01:34:39 +00:00
@@ -701,7 +701,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(" ")
|
||||
}
|
||||
@@ -710,7 +710,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()
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
29
base/runtime/heap_allocator_orca.odin
Normal file
29
base/runtime/heap_allocator_orca.odin
Normal file
@@ -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)
|
||||
}
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
43
base/runtime/os_specific_orca.odin
Normal file
43
base/runtime/os_specific_orca.odin
Normal file
@@ -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
|
||||
}
|
||||
@@ -25,7 +25,7 @@ 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)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
//+build !freestanding
|
||||
//+build !js
|
||||
//+build !orca
|
||||
package fmt
|
||||
|
||||
import "base:runtime"
|
||||
|
||||
24
core/time/time_orca.odin
Normal file
24
core/time/time_orca.odin
Normal file
@@ -0,0 +1,24 @@
|
||||
//+private
|
||||
//+build orca
|
||||
package time
|
||||
|
||||
_IS_SUPPORTED :: false
|
||||
|
||||
_now :: proc "contextless" () -> Time {
|
||||
return {}
|
||||
}
|
||||
|
||||
_sleep :: proc "contextless" (d: Duration) {
|
||||
}
|
||||
|
||||
_tick_now :: proc "contextless" () -> Tick {
|
||||
// mul_div_u64 :: proc "contextless" (val, num, den: i64) -> i64 {
|
||||
// q := val / den
|
||||
// r := val % den
|
||||
// return q * num + r * num / den
|
||||
// }
|
||||
return {}
|
||||
}
|
||||
|
||||
_yield :: proc "contextless" () {
|
||||
}
|
||||
@@ -1088,7 +1088,6 @@ gb_global TargetMetrics target_orca_wasm32 = {
|
||||
TargetArch_wasm32,
|
||||
4, 4, 8, 16,
|
||||
str_lit("wasm32-wasi-js"),
|
||||
// str_lit("e-m:e-p:32:32-i64:64-n32:64-S128"),
|
||||
};
|
||||
|
||||
|
||||
@@ -1170,6 +1169,7 @@ gb_global NamedTargetMetrics named_targets[] = {
|
||||
{ str_lit("freestanding_wasm32"), &target_freestanding_wasm32 },
|
||||
{ str_lit("wasi_wasm32"), &target_wasi_wasm32 },
|
||||
{ str_lit("js_wasm32"), &target_js_wasm32 },
|
||||
{ str_lit("orca_wasm32"), &target_orca_wasm32 },
|
||||
|
||||
{ str_lit("freestanding_wasm64p32"), &target_freestanding_wasm64p32 },
|
||||
{ str_lit("js_wasm64p32"), &target_js_wasm64p32 },
|
||||
@@ -2045,11 +2045,10 @@ gb_internal void init_build_context(TargetMetrics *cross_target, Subtarget subta
|
||||
// }
|
||||
if (bc->no_entry_point || bc->metrics.os == TargetOs_orca) {
|
||||
link_flags = gb_string_appendc(link_flags, "--no-entry ");
|
||||
bc->no_entry_point = true; // just in case for the "orca" target
|
||||
}
|
||||
|
||||
|
||||
bc->link_flags = make_string_c(link_flags);
|
||||
|
||||
|
||||
// Disallow on wasm
|
||||
bc->use_separate_modules = false;
|
||||
} else {
|
||||
|
||||
@@ -13,6 +13,7 @@ struct LinkerData {
|
||||
};
|
||||
|
||||
gb_internal i32 system_exec_command_line_app(char const *name, char const *fmt, ...);
|
||||
gb_internal bool system_exec_command_line_app_output(char const *command, gbString *output);
|
||||
|
||||
#if defined(GB_SYSTEM_OSX)
|
||||
gb_internal void linker_enable_system_library_linking(LinkerData *ld) {
|
||||
@@ -69,27 +70,40 @@ gb_internal i32 linker_stage(LinkerData *gen) {
|
||||
if (is_arch_wasm()) {
|
||||
timings_start_section(timings, str_lit("wasm-ld"));
|
||||
|
||||
String extra_orca_flags = {};
|
||||
gbString extra_orca_flags = gb_string_make(temporary_allocator(), "");
|
||||
|
||||
gbString inputs = gb_string_make(temporary_allocator(), "");
|
||||
inputs = gb_string_append_fmt(inputs, "\"%.*s.o\"", LIT(output_filename));
|
||||
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
if (build_context.metrics.os == TargetOs_orca) {
|
||||
extra_orca_flags = str_lit(" W:/orca/installation/dev-afb9591/bin/liborca_wasm.a --export-dynamic");
|
||||
gbString orca_sdk_path = gb_string_make(temporary_allocator(), "");
|
||||
if (!system_exec_command_line_app_output("orca sdk-path", &orca_sdk_path)) {
|
||||
gb_printf_err("executing `orca sdk-path` failed, make sure Orca is installed and added to your path\n");
|
||||
return 1;
|
||||
}
|
||||
if (gb_string_length(orca_sdk_path) == 0) {
|
||||
gb_printf_err("executing `orca sdk-path` did not produce output\n");
|
||||
return 1;
|
||||
}
|
||||
inputs = gb_string_append_fmt(inputs, " \"%s/orca-libc/lib/crt1.o\" \"%s/orca-libc/lib/libc.o\"", orca_sdk_path, orca_sdk_path);
|
||||
|
||||
extra_orca_flags = gb_string_append_fmt(extra_orca_flags, " -L \"%s/bin\" -lorca_wasm --export-dynamic", orca_sdk_path);
|
||||
}
|
||||
|
||||
result = system_exec_command_line_app("wasm-ld",
|
||||
"\"%.*s\\bin\\wasm-ld\" \"%.*s.o\" -o \"%.*s\" %.*s %.*s %.*s",
|
||||
LIT(build_context.ODIN_ROOT),
|
||||
LIT(output_filename), LIT(output_filename), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags),
|
||||
LIT(extra_orca_flags));
|
||||
#else
|
||||
if (build_context.metrics.os == TargetOs_orca) {
|
||||
extra_orca_flags = str_lit(" -L . -lorca --export-dynamic");
|
||||
}
|
||||
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
result = system_exec_command_line_app("wasm-ld",
|
||||
"wasm-ld \"%.*s.o\" -o \"%.*s\" %.*s %.*s %.*s",
|
||||
LIT(output_filename), LIT(output_filename), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags),
|
||||
LIT(extra_orca_flags));
|
||||
"\"%.*s\\bin\\wasm-ld\" %s -o \"%.*s\" %.*s %.*s %s",
|
||||
LIT(build_context.ODIN_ROOT),
|
||||
inputs, LIT(output_filename), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags),
|
||||
extra_orca_flags);
|
||||
#else
|
||||
result = system_exec_command_line_app("wasm-ld",
|
||||
"wasm-ld %s -o \"%.*s\" %.*s %.*s %s",
|
||||
inputs, LIT(output_filename),
|
||||
LIT(build_context.link_flags),
|
||||
LIT(build_context.extra_linker_flags),
|
||||
extra_orca_flags);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
32
src/main.cpp
32
src/main.cpp
@@ -155,6 +155,38 @@ gb_internal i32 system_exec_command_line_app(char const *name, char const *fmt,
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
#define popen _popen
|
||||
#define pclose _pclose
|
||||
#endif
|
||||
|
||||
gb_internal bool system_exec_command_line_app_output(char const *command, gbString *output) {
|
||||
GB_ASSERT(output);
|
||||
|
||||
u8 buffer[256];
|
||||
FILE *stream;
|
||||
stream = popen(command, "r");
|
||||
if (!stream) {
|
||||
return false;
|
||||
}
|
||||
defer (pclose(stream));
|
||||
|
||||
while (!feof(stream)) {
|
||||
size_t n = fread(buffer, 1, 255, stream);
|
||||
*output = gb_string_append_length(*output, buffer, n);
|
||||
|
||||
if (ferror(stream)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (build_context.show_system_calls) {
|
||||
gb_printf_err("[SYSTEM CALL OUTPUT] %s -> %s\n", command, *output);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
gb_internal Array<String> setup_args(int argc, char const **argv) {
|
||||
gbAllocator a = heap_allocator();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user