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}