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