rune/shared/
caller.rs
1use core::marker::PhantomData;
2
3use rust_alloc::sync::Arc;
4
5use crate::runtime::{FixedArgs, FunctionHandler, InstAddress, Output, VmResult};
6use crate::FromValue;
7
8#[derive(Clone)]
13pub(crate) struct Caller<A, const N: usize, T> {
14 handler: Arc<FunctionHandler>,
15 _marker: PhantomData<(A, T)>,
16}
17
18impl<A, const N: usize, T> Caller<A, N, T>
19where
20 A: FixedArgs<N>,
21 T: FromValue,
22{
23 pub(crate) fn new(handler: Arc<FunctionHandler>) -> Self {
25 Self {
26 handler,
27 _marker: PhantomData,
28 }
29 }
30
31 pub(crate) fn with_return<U>(&self) -> Caller<A, N, U>
33 where
34 U: FromValue,
35 {
36 Caller {
37 handler: self.handler.clone(),
38 _marker: PhantomData,
39 }
40 }
41
42 pub(crate) fn call(&self, args: A) -> VmResult<T> {
44 const {
45 assert!(N > 0, "Must be used with non-zero arguments");
46 }
47
48 let mut args = vm_try!(args.into_array());
49
50 vm_try!((self.handler)(
51 &mut args,
52 InstAddress::ZERO,
53 N,
54 Output::keep(0)
55 ));
56
57 let Some(value) = args.into_iter().next() else {
58 unreachable!();
59 };
60
61 VmResult::Ok(vm_try!(T::from_value(value)))
62 }
63}
64
65unsafe impl<A, const N: usize, T> Send for Caller<A, N, T> {}
67unsafe impl<A, const N: usize, T> Sync for Caller<A, N, T> {}