linera_witty/runtime/wasmtime/
mod.rs

1// Copyright (c) Zefchain Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4//! Support for the [Wasmtime](https://wasmtime.dev) runtime.
5
6mod export_function;
7mod function;
8mod memory;
9mod parameters;
10mod results;
11
12pub use anyhow;
13use wasmtime::{AsContext, AsContextMut, Extern, Memory, Store, StoreContext, StoreContextMut};
14pub use wasmtime::{Caller, Linker};
15
16pub use self::{parameters::WasmtimeParameters, results::WasmtimeResults};
17use super::traits::{Instance, Runtime};
18
19/// Representation of the [Wasmtime](https://wasmtime.dev) runtime.
20pub struct Wasmtime;
21
22impl Runtime for Wasmtime {
23    type Export = Extern;
24    type Memory = Memory;
25}
26
27/// Necessary data for implementing an entrypoint [`Instance`].
28pub struct EntrypointInstance<UserData> {
29    instance: wasmtime::Instance,
30    store: Store<UserData>,
31}
32
33impl<UserData> EntrypointInstance<UserData> {
34    /// Creates a new [`EntrypointInstance`] with the guest module
35    /// [`Instance`][`wasmtime::Instance`] and [`Store`].
36    pub fn new(instance: wasmtime::Instance, store: Store<UserData>) -> Self {
37        EntrypointInstance { instance, store }
38    }
39}
40
41impl<UserData> AsContext for EntrypointInstance<UserData> {
42    type Data = UserData;
43
44    fn as_context(&self) -> StoreContext<UserData> {
45        self.store.as_context()
46    }
47}
48
49impl<UserData> AsContextMut for EntrypointInstance<UserData> {
50    fn as_context_mut(&mut self) -> StoreContextMut<UserData> {
51        self.store.as_context_mut()
52    }
53}
54
55impl<UserData> Instance for EntrypointInstance<UserData> {
56    type Runtime = Wasmtime;
57    type UserData = UserData;
58    type UserDataReference<'a>
59        = &'a UserData
60    where
61        Self: 'a,
62        UserData: 'a;
63    type UserDataMutReference<'a>
64        = &'a mut UserData
65    where
66        Self: 'a,
67        UserData: 'a;
68
69    fn load_export(&mut self, name: &str) -> Option<Extern> {
70        self.instance.get_export(&mut self.store, name)
71    }
72
73    fn user_data(&self) -> Self::UserDataReference<'_> {
74        self.store.data()
75    }
76
77    fn user_data_mut(&mut self) -> Self::UserDataMutReference<'_> {
78        self.store.data_mut()
79    }
80}
81
82/// Alias for the [`Instance`] implementation made available inside host functions called by the
83/// guest.
84pub type ReentrantInstance<'a, UserData> = Caller<'a, UserData>;
85
86impl<UserData> Instance for Caller<'_, UserData> {
87    type Runtime = Wasmtime;
88    type UserData = UserData;
89    type UserDataReference<'a>
90        = &'a UserData
91    where
92        Self: 'a,
93        UserData: 'a;
94    type UserDataMutReference<'a>
95        = &'a mut UserData
96    where
97        Self: 'a,
98        UserData: 'a;
99
100    fn load_export(&mut self, name: &str) -> Option<Extern> {
101        Caller::get_export(self, name)
102    }
103
104    fn user_data(&self) -> Self::UserDataReference<'_> {
105        Caller::data(self)
106    }
107
108    fn user_data_mut(&mut self) -> Self::UserDataMutReference<'_> {
109        Caller::data_mut(self)
110    }
111}