1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
/// A trait used as part of [`bindgen!`] to indicate a `Data<'_>` payload that
/// implements some host bindings traits.
///
/// The purpose of the [`bindgen!`] macro is to define Rust traits that the host
/// can implement to fulfill WIT functions imported from the host into a
/// component. The [`bindgen!`] macro then additionally generates a function
/// which takes a [`Linker`] and an implementation of the traits and fills out
/// the [`Linker`]. This trait, [`HasData`], is used in this process of filling
/// out the [`Linker`] for some WIT interfaces.
///
/// Wasmtime's [`Store<T>`] type is the home for all per-instance state.
/// Notably the `T` here is generic (the Wasmtime library allows any type to be
/// placed here) and it's also instance-specific as a [`Store<T>`] is typically
/// allocated one-per-instance. Implementations of host APIs, however, often
/// want to live in a library and not be tied to any particular `T`. For example
/// Wasmtime provides the `wasmtime-wasi` crates as an implementation of
/// standard WASI APIs as a library, but they don't want to fix a particular `T`
/// in [`Store<T>`] as embedders should be able to fill out their own `T` for
/// their needs. The purpose of this trait is to enable this situation.
///
/// This trait is used in `add_to_linker` functions generated by [`bindgen!`] in
/// conjunction with a function pointer. It looks something along the lines of:
///
/// ```
/// use wasmtime::component::{Linker, HasData};
///
/// // generated by bindgen!
/// trait Host {
/// // ..
/// }
///
/// fn add_to_linker<T, D>(linker: &mut Linker<T>, getter: fn(&mut T) -> D::Data<'_>)
/// where D: HasData,
/// for<'a> D::Data<'a>: Host,
/// {
/// // ...
/// # let _ = (linker, getter);
/// }
/// ```
///
/// Here the `D` type parameter, bounded by [`HasData`], is used to specify
/// the return type of the `getter` function provided here. The `getter`
/// "projects" from `&mut T` to `D::Data<'_>`, notably enabling it to capture
/// the lifetime of the `&mut T` passed in as well.
///
/// The `Data` associated type here is further bounded in `add_to_linker` above
/// as it must implement the traits generated by [`bindgen!`]. This means that
/// `linker` is filled out with functions that, when called, first `getter` is
/// invoked and then the actual function delegates to the `Host` trait
/// implementation in this case.
///
/// The `D` type parameter here isn't actually a runtime value, nor is it stored
/// anywhere. It's purely used as a means of projecting a "generic associated
/// type", here where `<'a>` is the generic argument, a lifetime. This means
/// that the choice of `D` is disconnected from both `T` and `D::Data<'_>` and
/// can be whatever you like. Sometimes you might need to define an empty struct
/// in your project to use this, but Wasmtime also provides a convenience
/// [`HasSelf`] type to avoid the need for this in some common use cases.
///
/// # Example: `Host for T` using `Store<T>`
///
/// Let's say you wanted to invoke the above `add_to_linker` function where the
/// `T` in [`Store<T>`] directly implements the `Host` trait itself:
///
/// ```
/// use wasmtime::component::{Linker, HasSelf};
/// # use wasmtime::component::HasData;
/// #
/// # trait Host { }
/// # impl<T: Host + ?Sized> Host for &mut T {}
/// #
/// # fn add_to_linker<T, D>(linker: &mut Linker<T>, getter: fn(&mut T) -> D::Data<'_>)
/// # where D: HasData,
/// # for<'a> D::Data<'a>: Host,
/// # {
/// # let _ = (linker, getter);
/// # }
///
/// struct MyStoreState { /* ... */ }
///
/// impl Host for MyStoreState {
/// // ..
/// }
///
/// fn fill_out_my_linker(linker: &mut Linker<MyStoreState>) {
/// add_to_linker::<_, HasSelf<_>>(linker, |x| x)
/// }
/// ```
///
/// Here the `add_to_linker` invocation is annotated with `<_, HasSelf<_>>`. The
/// first argument gets inferred to `MyStoreState`, and the second argument gets
/// inferred to `HasSelf<MyStoreState>` This means that the projection function
/// in this case, here the identity `|x| x`, is typed as
/// `fn(&mut MyStoreState) -> &mut MyStoreState`. This is because the `HasData`
/// implementation for `HasSelf<T>` means that we have
/// `type Data<'a> = &'a mut T`.
///
/// # Example: `Host for MyLibraryState` using `Store<T>`
///
/// Let's say though that you instead are writing a library like WASI where you
/// don't know the `T` of [`Store<T>`] ahead of time. In such a case you might
/// hand-write your own `add_to_linker` wrapper that looks like this:
///
/// ```
/// use wasmtime::component::{Linker, HasData};
/// #
/// # trait Host { }
/// # impl<T: Host + ?Sized> Host for &mut T {}
/// #
/// # fn add_to_linker<T, D>(linker: &mut Linker<T>, getter: fn(&mut T) -> D::Data<'_>)
/// # where D: HasData,
/// # for<'a> D::Data<'a>: Host,
/// # {
/// # let _ = (linker, getter);
/// # }
///
/// // publicly exposed per-instance state for your library, users will
/// // construct this and store it within the `T` in `Store<T>`
/// pub struct MyLibraryState { /* ... */ }
///
/// impl Host for MyLibraryState {
/// // ..
/// }
///
/// // hand-written publicly exposed convenience function to add this crate's
/// // component functionality to the provided linker.
/// pub fn add_my_library_to_linker<T>(
/// linker: &mut Linker<T>,
/// f: fn(&mut T) -> &mut MyLibraryState,
/// ) {
/// // invoke the bindgen!-generated `add_to_linker`
/// add_to_linker::<_, MyLibrary>(linker, f);
/// }
///
/// // Note this need not be publicly exposed, it's just a private internal
/// // detail.
/// struct MyLibrary;
///
/// impl HasData for MyLibrary {
/// type Data<'a> = &'a mut MyLibraryState;
/// }
/// ```
///
/// Here the `MyLibrary` type, private to this crate, has a `HasData`
/// implementation which indicates that implementations of the
/// `bindgen!`-generated APIs are done in terms of `MyLibraryState`
/// specifically. The `add_my_library_to_linker` takes an externally-provided
/// `f` closure which projects from `&mut T`, whatever data the store is using,
/// to `MyLibraryState` which must be stored within the store itself.
///
/// # Example: `Host for MyLibraryState<'_>` using `Store<T>`
///
/// Let's say you're like the above scenario where you're writing a library but
/// instead of being able to wrap up all your state for each trait
/// implementation in a structure it's spread across a few structures. These
/// structures may be stored in different locations inside of `Store<T>` which
/// makes it difficult to wrap up in a single type and return that. Here you can
/// make use of "view" types to collect a number of disjoint borrows into one
/// structure:
///
/// ```
/// use wasmtime::component::{Linker, HasData};
/// #
/// # trait Host { }
/// # impl<T: Host + ?Sized> Host for &mut T {}
/// #
/// # fn add_to_linker<T, D>(linker: &mut Linker<T>, getter: fn(&mut T) -> D::Data<'_>)
/// # where D: HasData,
/// # for<'a> D::Data<'a>: Host,
/// # {
/// # let _ = (linker, getter);
/// # }
/// # struct StateA;
/// # struct StateB;
///
/// // Like before, this is publicly exposed, and this is a "bag of pointers" to
/// // all the pieces of state necessary to implement `Host` below.
/// pub struct MyLibraryState<'a> {
/// pub state_a: &'a mut StateA,
/// pub state_b: &'a mut StateB,
/// }
///
/// impl Host for MyLibraryState<'_> {
/// // ..
/// }
///
/// pub fn add_my_library_to_linker<T>(
/// linker: &mut Linker<T>,
/// f: fn(&mut T) -> MyLibraryState<'_>,
/// ) {
/// // invoke the bindgen!-generated `add_to_linker`
/// add_to_linker::<_, MyLibrary>(linker, f);
/// }
///
/// struct MyLibrary;
///
/// impl HasData for MyLibrary {
/// type Data<'a> = MyLibraryState<'a>;
/// }
/// ```
///
/// This is similar to the above example but shows using a lifetime parameter on
/// a structure instead of using a pointer-with-a-lifetime only. Otherwise
/// though this'll end up working out the same way.
///
/// # Example: `Host for U: MyLibrary` using `Store<T>`
///
/// Let's say you're in a situation where you're a library which wants to create
/// a "simpler" trait than the `Host`-generated traits from [`bindgen!`] and
/// then you want to implement `Host` in terms of this trait. This requires a
/// bit more boilerplate as well as a new custom structure, but doing so looks
/// like this:
///
/// ```
/// use wasmtime::component::{Linker, HasData};
/// #
/// # trait Host { }
/// # impl<T: Host + ?Sized> Host for &mut T {}
/// #
/// # fn add_to_linker<T, D>(linker: &mut Linker<T>, getter: fn(&mut T) -> D::Data<'_>)
/// # where D: HasData,
/// # for<'a> D::Data<'a>: Host,
/// # {
/// # let _ = (linker, getter);
/// # }
///
/// // This is your public trait which external users need to implement. This
/// // can encapsulate any "core" functionality needed to implement
/// // bindgen!-generated traits such as `Host` below.
/// pub trait MyLibraryTrait {
/// // ...
/// }
///
/// // You'll need to provide a "forwarding" implementation of this trait from
/// // `&mut T` to `T` to get the below implementation to compile.
/// impl<T: MyLibraryTrait + ?Sized> MyLibraryTrait for &mut T {
/// // ...
/// }
///
/// // This is a bit of a "hack" and an unfortunate workaround, but is currently
/// // used to work within the confines of orphan rules and such. This is
/// // publicly exposed as the function provided below must provide access to
/// // this.
/// pub struct MyLibraryImpl<T>(pub T);
///
/// // Here you'd implement all of `Host` in terms of `MyLibraryTrait`.
/// // Functions with `&mut self` would use `self.0` to access the functionality
/// // in `MyLibraryTrait`.
/// impl<T: MyLibraryTrait> Host for MyLibraryImpl<T> {
/// // ..
/// }
///
/// // optional: this avoids the need for `self.0` accessors in `Host` above,
/// // but this otherwise isn't required.
/// impl<T: MyLibraryTrait> MyLibraryTrait for MyLibraryImpl<T> {
/// // ..
/// }
///
/// // Note the second type parameter on this method, `U`, which is the user's
/// // implementation of `MyLibraryTrait`. Note that this additionally must
/// // be bounded with `'static` here.
/// pub fn add_my_library_to_linker<T, U>(
/// linker: &mut Linker<T>,
/// f: fn(&mut T) -> MyLibraryImpl<&mut U>,
/// )
/// where U: MyLibraryTrait + 'static,
/// {
/// add_to_linker::<_, MyLibrary<U>>(linker, f);
/// }
///
/// // An adjusted definition of `MyLibrary` relative to the previous example,
/// // still private, which hooks up all the types used here.
/// struct MyLibrary<U>(U);
///
/// impl<U: 'static> HasData for MyLibrary<U> {
/// type Data<'a> = MyLibraryImpl<&'a mut U>;
/// }
/// ```
///
/// This iteration of implementing component-interfaces-as-a-library is
/// unfortunately relatively verbose and unintuitive at this time. We're always
/// keen on improving this though, so if you've got ideas of how to improve this
/// please let us know!
///
/// [`bindgen!`]: super::bindgen
/// [`Linker`]: super::Linker
/// [`Store<T>`]: crate::Store
/// A convenience implementation of the [`HasData`] trait when the data
/// associated with an implementation is `&mut T`.
///
/// For more examples on using this see the [`HasData`] trait.
;