rune/runtime/
guarded_args.rsuse crate::alloc::Vec;
use crate::runtime::Args;
use crate::runtime::{Stack, UnsafeToValue, Value, VmResult};
pub trait GuardedArgs {
type Guard;
unsafe fn guarded_into_stack(self, stack: &mut Stack) -> VmResult<Self::Guard>;
unsafe fn guarded_into_vec(self) -> VmResult<(Vec<Value>, Self::Guard)>;
fn count(&self) -> usize;
}
macro_rules! impl_into_args {
($count:expr $(, $ty:ident $value:ident $_:expr)*) => {
impl<$($ty,)*> GuardedArgs for ($($ty,)*)
where
$($ty: UnsafeToValue,)*
{
type Guard = ($($ty::Guard,)*);
#[allow(unused)]
#[inline]
unsafe fn guarded_into_stack(self, stack: &mut Stack) -> VmResult<Self::Guard> {
let ($($value,)*) = self;
$(let $value = vm_try!($value.unsafe_to_value());)*
$(vm_try!(stack.push($value.0));)*
VmResult::Ok(($($value.1,)*))
}
#[allow(unused)]
#[inline]
unsafe fn guarded_into_vec(self) -> VmResult<(Vec<Value>, Self::Guard)> {
let ($($value,)*) = self;
$(let $value = vm_try!($value.unsafe_to_value());)*
let mut out = vm_try!(Vec::try_with_capacity($count));
$(vm_try!(out.try_push($value.0));)*
VmResult::Ok((out, ($($value.1,)*)))
}
#[inline]
fn count(&self) -> usize {
$count
}
}
};
}
repeat_macro!(impl_into_args);
impl GuardedArgs for Vec<Value> {
type Guard = ();
#[inline]
unsafe fn guarded_into_stack(self, stack: &mut Stack) -> VmResult<Self::Guard> {
self.into_stack(stack)
}
#[inline]
unsafe fn guarded_into_vec(self) -> VmResult<(Vec<Value>, Self::Guard)> {
VmResult::Ok((self, ()))
}
#[inline]
fn count(&self) -> usize {
(self as &dyn Args).count()
}
}
#[cfg(feature = "alloc")]
impl GuardedArgs for ::rust_alloc::vec::Vec<Value> {
type Guard = ();
#[inline]
unsafe fn guarded_into_stack(self, stack: &mut Stack) -> VmResult<Self::Guard> {
self.into_stack(stack)
}
#[inline]
unsafe fn guarded_into_vec(self) -> VmResult<(Vec<Value>, Self::Guard)> {
VmResult::Ok((vm_try!(Vec::try_from(self)), ()))
}
#[inline]
fn count(&self) -> usize {
self.len()
}
}