use RocCallResult and pass-by-reference in all examples

This commit is contained in:
Folkert 2020-11-01 15:00:11 +01:00
parent 89e9549d85
commit 5897a07962
6 changed files with 61 additions and 8 deletions

View file

@ -1960,9 +1960,15 @@ fn make_exception_catching_wrapper<'a, 'ctx, 'env>(
let result_alloca = builder.build_alloca(wrapper_return_type, "result"); 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 // 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_result = {
let call = let call = builder.build_invoke(
builder.build_invoke(roc_function, &[], then_block, catch_block, "call_roc_main"); roc_function,
&arguments,
then_block,
catch_block,
"call_roc_function",
);
call.set_call_convention(FAST_CALL_CONV); call.set_call_convention(FAST_CALL_CONV);
call.try_as_basic_value().left().unwrap() call.try_as_basic_value().left().unwrap()
}; };

View file

@ -4,5 +4,5 @@ closure : {} -> Int
closure = closure =
x = 42 x = 42
\{} -> x \{} -> x + 9223372036854775807

View file

@ -2,7 +2,7 @@ use roc_std::RocStr;
use std::str; use std::str;
extern "C" { extern "C" {
#[link_name = "main_1"] #[link_name = "main_1_exposed"]
fn main() -> RocStr; fn main() -> RocStr;
} }

View file

@ -1,9 +1,10 @@
use roc_std::RocCallResult;
use roc_std::RocList; use roc_std::RocList;
use std::time::SystemTime; use std::time::SystemTime;
extern "C" { extern "C" {
#[link_name = "quicksort_1"] #[link_name = "quicksort_1_exposed"]
fn quicksort(list: RocList<i64>) -> RocList<i64>; fn quicksort(list: RocList<i64>, output: &mut RocCallResult<RocList<i64>>) -> ();
} }
const NUM_NUMS: usize = 100; const NUM_NUMS: usize = 100;
@ -24,7 +25,17 @@ pub fn rust_main() -> isize {
println!("Running Roc quicksort on {} numbers...", nums.len()); println!("Running Roc quicksort on {} numbers...", nums.len());
let start_time = SystemTime::now(); 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 end_time = SystemTime::now();
let duration = end_time.duration_since(start_time).unwrap(); let duration = end_time.duration_since(start_time).unwrap();

View file

@ -2,7 +2,7 @@ use roc_std::RocList;
use std::time::SystemTime; use std::time::SystemTime;
extern "C" { extern "C" {
#[link_name = "quicksort_1"] #[link_name = "quicksort_1_exposed"]
fn quicksort(list: RocList<i64>) -> RocList<i64>; fn quicksort(list: RocList<i64>) -> RocList<i64>;
} }

View file

@ -426,3 +426,39 @@ impl Drop for RocStr {
} }
} }
} }
#[allow(non_camel_case_types)]
type c_char = u8;
#[repr(u64)]
pub enum RocCallResult<T> {
Success(T),
Failure(*mut c_char),
}
impl<T: Sized> Into<Result<T, &'static str>> for RocCallResult<T> {
fn into(self) -> Result<T, &'static str> {
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
}),
}
}
}