1use std::fmt;
2
3use paste::paste;
4
5use crate::{FuncItemRef, ImportResolver, MirContext, ffi};
6
7#[derive(Clone, Copy)]
9#[repr(transparent)]
10pub struct Val(pub(crate) ffi::MIR_val_t);
11
12impl Default for Val {
13 fn default() -> Self {
14 Self(unsafe { std::mem::zeroed::<ffi::MIR_val_t>() })
15 }
16}
17
18impl fmt::Debug for Val {
19 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20 f.debug_struct("Val")
21 .field("i64", &self.as_i64())
22 .field("u64", &self.as_u64())
23 .field("f32", &self.as_f32())
24 .field("f64", &self.as_f64())
25 .finish()
26 }
27}
28
29macro_rules! impl_val_variant {
30 ($($name:ident: $ty:ident;)*) => {
31 $(
32 impl From<$ty> for Val {
33 #[inline]
34 fn from(v: $ty) -> Self {
35 let mut ret = Self::default();
37 ret.0.$name = v;
38 ret
39 }
40 }
41 )*
42 impl Val {
43 paste! {
44 $(
45 #[doc = concat!("`", stringify!($ty), "`.")]
47 #[must_use]
48 #[inline]
49 pub fn [<as_ $ty>](self) -> $ty {
50 unsafe { self.0.$name }
51 }
52 )*
53 }
54 }
55 };
56}
57
58impl_val_variant! {
59 i: i64;
60 u: u64;
61 f: f32;
62 d: f64;
63}
64
65impl MirContext {
66 pub fn link_modules_for_interpret(&self) {
72 unsafe { self.link_modules_raw(Some(ffi::MIR_set_interp_interface), None) }
73 }
74
75 pub unsafe fn link_modules_for_interpret_with_resolver(&self, resolver: &ImportResolver) {
86 unsafe { self.link_modules_raw(Some(ffi::MIR_set_interp_interface), Some(resolver)) }
87 }
88
89 pub unsafe fn interpret_unchecked(
99 &self,
100 func: FuncItemRef<'_>,
101 results: &mut [Val],
102 args: &[Val],
103 ) {
104 let data = unsafe { func.data() };
105 debug_assert_eq!(data.nres as usize, results.len());
106 debug_assert_eq!(data.nargs as usize, args.len());
107 unsafe {
108 ffi::MIR_interp_arr(
109 self.as_raw(),
110 func.as_raw(),
111 results.as_mut_ptr().cast::<ffi::MIR_val_t>(),
112 args.len(),
113 args.as_ptr().cast::<ffi::MIR_val_t>().cast_mut(),
114 );
115 }
116 }
117}