rune/runtime/
guarded_args.rs1use crate::alloc::Vec;
2use crate::runtime::Args;
3use crate::runtime::{Stack, UnsafeToValue, Value, VmResult};
4
5pub trait GuardedArgs {
11 type Guard;
13
14 unsafe fn guarded_into_stack(self, stack: &mut Stack) -> VmResult<Self::Guard>;
22
23 unsafe fn guarded_into_vec(self) -> VmResult<(Vec<Value>, Self::Guard)>;
31
32 fn count(&self) -> usize;
34}
35
36macro_rules! impl_into_args {
37 ($count:expr $(, $ty:ident $value:ident $_:expr)*) => {
38 impl<$($ty,)*> GuardedArgs for ($($ty,)*)
39 where
40 $($ty: UnsafeToValue,)*
41 {
42 type Guard = ($($ty::Guard,)*);
43
44 #[allow(unused)]
45 #[inline]
46 unsafe fn guarded_into_stack(self, stack: &mut Stack) -> VmResult<Self::Guard> {
47 let ($($value,)*) = self;
48 $(let $value = vm_try!($value.unsafe_to_value());)*
49 $(vm_try!(stack.push($value.0));)*
50 VmResult::Ok(($($value.1,)*))
51 }
52
53 #[allow(unused)]
54 #[inline]
55 unsafe fn guarded_into_vec(self) -> VmResult<(Vec<Value>, Self::Guard)> {
56 let ($($value,)*) = self;
57 $(let $value = vm_try!($value.unsafe_to_value());)*
58 let mut out = vm_try!(Vec::try_with_capacity($count));
59 $(vm_try!(out.try_push($value.0));)*
60 VmResult::Ok((out, ($($value.1,)*)))
61 }
62
63 #[inline]
64 fn count(&self) -> usize {
65 $count
66 }
67 }
68 };
69}
70
71repeat_macro!(impl_into_args);
72
73impl GuardedArgs for Vec<Value> {
74 type Guard = ();
75
76 #[inline]
77 unsafe fn guarded_into_stack(self, stack: &mut Stack) -> VmResult<Self::Guard> {
78 self.into_stack(stack)
79 }
80
81 #[inline]
82 unsafe fn guarded_into_vec(self) -> VmResult<(Vec<Value>, Self::Guard)> {
83 VmResult::Ok((self, ()))
84 }
85
86 #[inline]
87 fn count(&self) -> usize {
88 (self as &dyn Args).count()
89 }
90}
91
92#[cfg(feature = "alloc")]
93impl GuardedArgs for ::rust_alloc::vec::Vec<Value> {
94 type Guard = ();
95
96 #[inline]
97 unsafe fn guarded_into_stack(self, stack: &mut Stack) -> VmResult<Self::Guard> {
98 self.into_stack(stack)
99 }
100
101 #[inline]
102 unsafe fn guarded_into_vec(self) -> VmResult<(Vec<Value>, Self::Guard)> {
103 VmResult::Ok((vm_try!(Vec::try_from(self)), ()))
104 }
105
106 #[inline]
107 fn count(&self) -> usize {
108 self.len()
109 }
110}