Browse Source

improve orca target

Laytan Laats 1 year ago
parent
commit
8455e159f5

+ 13 - 2
base/runtime/core.odin

@@ -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()
 }

+ 1 - 1
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 {

+ 25 - 11
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()
-	}
-}
+}

+ 4 - 0
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()
 	}

+ 29 - 0
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)
+}

+ 1 - 1
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")
-}
+}

+ 43 - 0
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
+}

+ 1 - 1
base/runtime/procs.odin

@@ -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 - 0
core/fmt/fmt_os.odin

@@ -1,5 +1,6 @@
 //+build !freestanding
 //+build !js
+//+build !orca
 package fmt
 
 import "base:runtime"

+ 24 - 0
core/time/time_orca.odin

@@ -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" () {
+}

+ 4 - 5
src/build_settings.cpp

@@ -1080,8 +1080,7 @@ gb_global TargetMetrics target_orca_wasm32 = {
 	TargetOs_orca,
 	TargetArch_wasm32,
 	4, 4, 8, 16,
-	str_lit("wasm32-wasi-js"),
-	// str_lit("e-m:e-p:32:32-i64:64-n32:64-S128"),
+	str_lit("wasm32-freestanding-js"),
 };
 
 
@@ -1161,6 +1160,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 },
@@ -2032,11 +2032,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 {

+ 26 - 10
src/linker.cpp

@@ -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,42 @@ 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");
+			// TODO: Orca windows.
+
+			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);
 		}
 
+
+	#if defined(GB_SYSTEM_WINDOWS)
 		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");
-				}
-
 		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));
+			"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;
 	}

+ 28 - 0
src/main.cpp

@@ -155,6 +155,34 @@ gb_internal i32 system_exec_command_line_app(char const *name, char const *fmt,
 	return exit_code;
 }
 
+// TODO: windows.
+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();