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}