Skip to main content

wasmtime_wasi/
view.rs

1use crate::WasiCtx;
2use wasmtime::component::ResourceTable;
3
4/// A trait which provides access to the [`WasiCtx`] inside the embedder's `T`
5/// of [`Store<T>`][`Store`].
6///
7/// This crate's WASI Host implementations depend on the contents of
8/// [`WasiCtx`]. The `T` type [`Store<T>`][`Store`] is defined in each
9/// embedding of Wasmtime. These implementations are connected to the
10/// [`Linker<T>`][`Linker`] by [`add_to_linker_async`](crate::p2::add_to_linker_async)
11/// functions.
12///
13/// # Example
14///
15/// ```
16/// use wasmtime_wasi::{WasiCtx, WasiCtxView, WasiView};
17/// use wasmtime::component::ResourceTable;
18///
19/// struct MyState {
20///     ctx: WasiCtx,
21///     table: ResourceTable,
22/// }
23///
24/// impl WasiView for MyState {
25///     fn ctx(&mut self) -> WasiCtxView<'_> {
26///         WasiCtxView{
27///             ctx: &mut self.ctx,
28///             table: &mut self.table,
29///         }
30///     }
31/// }
32/// ```
33/// [`Store`]: wasmtime::Store
34/// [`Linker`]: wasmtime::component::Linker
35///
36pub trait WasiView: Send {
37    /// Yields mutable access to the [`WasiCtx`] configuration used for this
38    /// context.
39    fn ctx(&mut self) -> WasiCtxView<'_>;
40}
41
42/// Structure returned from [`WasiView::ctx`] which provides access to WASI
43/// state for host functions to be implemented with.
44pub struct WasiCtxView<'a> {
45    /// The [`WasiCtx`], or configuration, of the guest.
46    pub ctx: &'a mut WasiCtx,
47    /// Resources, such as files/streams, that the guest is using.
48    pub table: &'a mut ResourceTable,
49}
50
51impl<T: WasiView> crate::cli::WasiCliView for T {
52    fn cli(&mut self) -> crate::cli::WasiCliCtxView<'_> {
53        let WasiCtxView { ctx, table } = self.ctx();
54        crate::cli::WasiCliCtxView {
55            ctx: &mut ctx.cli,
56            table,
57        }
58    }
59}
60
61impl<T: WasiView> crate::clocks::WasiClocksView for T {
62    fn clocks(&mut self) -> crate::clocks::WasiClocksCtxView<'_> {
63        let WasiCtxView { ctx, table } = self.ctx();
64        crate::clocks::WasiClocksCtxView {
65            ctx: &mut ctx.clocks,
66            table,
67        }
68    }
69}
70
71impl<T: WasiView> crate::filesystem::WasiFilesystemView for T {
72    fn filesystem(&mut self) -> crate::filesystem::WasiFilesystemCtxView<'_> {
73        let WasiCtxView { ctx, table } = self.ctx();
74        crate::filesystem::WasiFilesystemCtxView {
75            ctx: &mut ctx.filesystem,
76            table,
77        }
78    }
79}
80
81impl<T: WasiView> crate::random::WasiRandomView for T {
82    fn random(&mut self) -> &mut crate::random::WasiRandomCtx {
83        &mut self.ctx().ctx.random
84    }
85}
86
87impl<T: WasiView> crate::sockets::WasiSocketsView for T {
88    fn sockets(&mut self) -> crate::sockets::WasiSocketsCtxView<'_> {
89        let WasiCtxView { ctx, table } = self.ctx();
90        crate::sockets::WasiSocketsCtxView {
91            ctx: &mut ctx.sockets,
92            table,
93        }
94    }
95}
96
97/// Identifier used to correlate a named import to a host-defined value.
98///
99/// This type is a small newtype wrapper around a `usize`, its only field which
100/// is also public. Embeders define the meaning of this value and are in control
101/// of both creating this an interpreting it. Creation of [`NamedId`] happens in
102/// functions like [`wasmtime_wasi::p3::add_named_to_linker`] where embedders
103/// will allocate a [`NamedId`] for all recognized named imports. Interpreting
104/// a [`NamedId`] happens later in traits such as [`WasiNamedView`] where the id
105/// is passed back to the embedder and a corresponding context must be returned.
106///
107/// Internally the `wasmtime-wasi` crate does not inspect the internal field
108/// here nor ever create one. Embedders are solely responsible for managing this
109/// id and its conetnts.
110///
111/// [`wasmtime_wasi::p3::add_named_to_linker`]: crate::p3::add_named_to_linker
112#[derive(Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, Debug)]
113pub struct NamedId(pub usize);
114
115/// A helper structure by which to implement generated-`Host` traits for
116/// bindings corresponding to named imports.
117///
118/// This is an implementation detail of how named imports are organized.
119/// Embedders invoking generated `add_to_linker` functions directly will be
120/// required to create this structure directly. Otherwise you probably won't
121/// need to interact with this.
122pub struct WasiCtxNamedView<'a, T>(pub &'a mut T);
123
124/// A trait which provides access to a specific [`WasiCtx`] as scoped by a
125/// [`NamedId`] parameter.
126///
127/// This trait is used as part of convenience
128/// [`wasmtime_wasi::p3::add_named_to_linker`] functions for example. This is
129/// used to scope access of a WASI context within a specific `id` or named
130/// import.
131///
132/// [`wasmtime_wasi::p3::add_named_to_linker`]: crate::p3::add_named_to_linker
133pub trait WasiNamedView: Send + 'static {
134    /// Yields mutable access to the [`WasiCtx`] configuration used for this
135    /// context.
136    fn ctx(&mut self, id: NamedId) -> WasiCtxView<'_>;
137}
138
139impl<T: WasiNamedView> crate::cli::WasiCliNamedView for T {
140    fn cli(&mut self, id: NamedId) -> crate::cli::WasiCliCtxView<'_> {
141        let WasiCtxView { ctx, table } = self.ctx(id);
142        crate::cli::WasiCliCtxView {
143            ctx: &mut ctx.cli,
144            table,
145        }
146    }
147}
148
149impl<T: WasiNamedView> crate::clocks::WasiClocksNamedView for T {
150    fn clocks(&mut self, id: NamedId) -> crate::clocks::WasiClocksCtxView<'_> {
151        let WasiCtxView { ctx, table } = self.ctx(id);
152        crate::clocks::WasiClocksCtxView {
153            ctx: &mut ctx.clocks,
154            table,
155        }
156    }
157}
158
159impl<T: WasiNamedView> crate::filesystem::WasiFilesystemNamedView for T {
160    fn filesystem(&mut self, id: NamedId) -> crate::filesystem::WasiFilesystemCtxView<'_> {
161        let WasiCtxView { ctx, table } = self.ctx(id);
162        crate::filesystem::WasiFilesystemCtxView {
163            ctx: &mut ctx.filesystem,
164            table,
165        }
166    }
167}
168
169impl<T: WasiNamedView> crate::random::WasiRandomNamedView for T {
170    fn random(&mut self, id: NamedId) -> &mut crate::random::WasiRandomCtx {
171        self.ctx(id).ctx.random()
172    }
173}
174
175impl<T: WasiNamedView> crate::sockets::WasiSocketsNamedView for T {
176    fn sockets(&mut self, id: NamedId) -> crate::sockets::WasiSocketsCtxView<'_> {
177        let WasiCtxView { ctx, table } = self.ctx(id);
178        crate::sockets::WasiSocketsCtxView {
179            ctx: &mut ctx.sockets,
180            table,
181        }
182    }
183}