wasmi/func/
caller.rs

1use super::super::{AsContext, AsContextMut, StoreContext, StoreContextMut};
2use crate::{Engine, Error, Extern, Instance};
3
4/// Represents the caller’s context when creating a host function via [`Func::wrap`].
5///
6/// [`Func::wrap`]: struct.Func.html#method.wrap
7pub struct Caller<'a, T> {
8    ctx: StoreContextMut<'a, T>,
9    /// The module instance associated to the call.
10    /// This is `Some` if the host function was called from a Wasm function
11    /// since all Wasm function are associated to a module instance.
12    /// This usually is `None` if the host function was called from the host side.
13    instance: Option<Instance>,
14}
15
16impl<'a, T> Caller<'a, T> {
17    /// Creates a new [`Caller`] from the given store context and [`Instance`] handle.
18    pub(crate) fn new<C>(ctx: &'a mut C, instance: Option<&Instance>) -> Self
19    where
20        C: AsContextMut<Data = T>,
21    {
22        Self {
23            ctx: ctx.as_context_mut(),
24            instance: instance.copied(),
25        }
26    }
27
28    /// Queries the caller for an exported definition identifier by `name`.
29    ///
30    /// Returns `None` if there is no associated [`Instance`] of the caller
31    /// or if the caller does not provide an export under the name `name`.
32    pub fn get_export(&self, name: &str) -> Option<Extern> {
33        self.instance
34            .and_then(|instance| instance.get_export(self, name))
35    }
36
37    /// Returns a shared reference to the user provided host data.
38    pub fn data(&self) -> &T {
39        self.ctx.store.data()
40    }
41
42    /// Returns an exclusive reference to the user provided host data.
43    pub fn data_mut(&mut self) -> &mut T {
44        self.ctx.store.data_mut()
45    }
46
47    /// Returns a shared reference to the used [`Engine`].
48    pub fn engine(&self) -> &Engine {
49        self.ctx.store.engine()
50    }
51
52    /// Returns the remaining fuel of the [`Store`](crate::Store) if fuel metering is enabled.
53    ///
54    /// For more information see [`Store::get_fuel`](crate::Store::get_fuel).
55    ///
56    /// # Errors
57    ///
58    /// If fuel metering is disabled.
59    pub fn get_fuel(&self) -> Result<u64, Error> {
60        self.ctx.store.get_fuel()
61    }
62
63    /// Sets the remaining fuel of the [`Store`](crate::Store) to `value` if fuel metering is enabled.
64    ///
65    /// For more information see [`Store::get_fuel`](crate::Store::set_fuel).
66    ///
67    /// # Errors
68    ///
69    /// If fuel metering is disabled.
70    pub fn set_fuel(&mut self, fuel: u64) -> Result<(), Error> {
71        self.ctx.store.set_fuel(fuel)
72    }
73}
74
75impl<T> AsContext for Caller<'_, T> {
76    type Data = T;
77
78    #[inline]
79    fn as_context(&self) -> StoreContext<'_, Self::Data> {
80        self.ctx.as_context()
81    }
82}
83
84impl<T> AsContextMut for Caller<'_, T> {
85    #[inline]
86    fn as_context_mut(&mut self) -> StoreContextMut<'_, Self::Data> {
87        self.ctx.as_context_mut()
88    }
89}
90
91impl<'a, T: AsContextMut> From<&'a mut T> for Caller<'a, T::Data> {
92    #[inline]
93    fn from(ctx: &'a mut T) -> Self {
94        Self {
95            ctx: ctx.as_context_mut(),
96            instance: None,
97        }
98    }
99}