diff --git a/compiler/gen/src/llvm/build.rs b/compiler/gen/src/llvm/build.rs index 8d6fb22760..f16e36e758 100644 --- a/compiler/gen/src/llvm/build.rs +++ b/compiler/gen/src/llvm/build.rs @@ -1960,9 +1960,15 @@ fn make_exception_catching_wrapper<'a, 'ctx, 'env>( let result_alloca = builder.build_alloca(wrapper_return_type, "result"); // invoke instead of call, so that we can catch any exeptions thrown in Roc code + let arguments = wrapper_function.get_params(); let call_result = { - let call = - builder.build_invoke(roc_function, &[], then_block, catch_block, "call_roc_main"); + let call = builder.build_invoke( + roc_function, + &arguments, + then_block, + catch_block, + "call_roc_function", + ); call.set_call_convention(FAST_CALL_CONV); call.try_as_basic_value().left().unwrap() }; diff --git a/examples/closure/Closure.roc b/examples/closure/Closure.roc index 253ca727ba..d22e8cd4e5 100644 --- a/examples/closure/Closure.roc +++ b/examples/closure/Closure.roc @@ -4,5 +4,5 @@ closure : {} -> Int closure = x = 42 - \{} -> x + \{} -> x + 9223372036854775807 diff --git a/examples/hello-world/platform/src/lib.rs b/examples/hello-world/platform/src/lib.rs index 07375c7b46..81b2e49170 100644 --- a/examples/hello-world/platform/src/lib.rs +++ b/examples/hello-world/platform/src/lib.rs @@ -2,7 +2,7 @@ use roc_std::RocStr; use std::str; extern "C" { - #[link_name = "main_1"] + #[link_name = "main_1_exposed"] fn main() -> RocStr; } diff --git a/examples/multi-module/platform/src/lib.rs b/examples/multi-module/platform/src/lib.rs index a7b310f7ef..5a9aba13c7 100644 --- a/examples/multi-module/platform/src/lib.rs +++ b/examples/multi-module/platform/src/lib.rs @@ -1,9 +1,10 @@ +use roc_std::RocCallResult; use roc_std::RocList; use std::time::SystemTime; extern "C" { - #[link_name = "quicksort_1"] - fn quicksort(list: RocList) -> RocList; + #[link_name = "quicksort_1_exposed"] + fn quicksort(list: RocList, output: &mut RocCallResult>) -> (); } const NUM_NUMS: usize = 100; @@ -24,7 +25,17 @@ pub fn rust_main() -> isize { println!("Running Roc quicksort on {} numbers...", nums.len()); let start_time = SystemTime::now(); - let answer = unsafe { quicksort(nums) }; + let answer = unsafe { + use std::mem::MaybeUninit; + let mut output = MaybeUninit::uninit(); + + quicksort(nums, &mut *output.as_mut_ptr()); + + match output.assume_init().into() { + Ok(value) => value, + Err(msg) => panic!("roc failed with message: {}", msg), + } + }; let end_time = SystemTime::now(); let duration = end_time.duration_since(start_time).unwrap(); diff --git a/examples/quicksort/platform/src/lib.rs b/examples/quicksort/platform/src/lib.rs index a7b310f7ef..3b4a2969f1 100644 --- a/examples/quicksort/platform/src/lib.rs +++ b/examples/quicksort/platform/src/lib.rs @@ -2,7 +2,7 @@ use roc_std::RocList; use std::time::SystemTime; extern "C" { - #[link_name = "quicksort_1"] + #[link_name = "quicksort_1_exposed"] fn quicksort(list: RocList) -> RocList; } diff --git a/roc_std/src/lib.rs b/roc_std/src/lib.rs index 746348a5bd..177ba87e99 100644 --- a/roc_std/src/lib.rs +++ b/roc_std/src/lib.rs @@ -426,3 +426,39 @@ impl Drop for RocStr { } } } + +#[allow(non_camel_case_types)] +type c_char = u8; + +#[repr(u64)] +pub enum RocCallResult { + Success(T), + Failure(*mut c_char), +} + +impl Into> for RocCallResult { + fn into(self) -> Result { + use RocCallResult::*; + + match self { + Success(value) => Ok(value), + Failure(failure) => Err({ + let msg = unsafe { + let mut null_byte_index = 0; + loop { + if *failure.offset(null_byte_index) == 0 { + break; + } + null_byte_index += 1; + } + + let bytes = core::slice::from_raw_parts(failure, null_byte_index as usize); + + core::str::from_utf8_unchecked(bytes) + }; + + msg + }), + } + } +}