diff --git a/RELEASES.md b/RELEASES.md index 2a3900575d2e..031f32fbcea0 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -74,6 +74,7 @@ Unreleased. enabled, ensuring that spans aren't present in traces from unrelated async tasks. [#9217](https://github.com/bytecodealliance/wasmtime/pull/9217) + [#9263](https://github.com/bytecodealliance/wasmtime/pull/9263) * Completed support for the `CallHook` API when using the component model. [#9196](https://github.com/bytecodealliance/wasmtime/pull/9196) diff --git a/crates/component-macro/tests/expanded.rs b/crates/component-macro/tests/expanded.rs index 89da10fbb21b..29e338bc02f0 100644 --- a/crates/component-macro/tests/expanded.rs +++ b/crates/component-macro/tests/expanded.rs @@ -14,6 +14,13 @@ macro_rules! genexpand { async: true, stringify: true, }))?; + + process_expanded($path, "_tracing_async", wasmtime::component::bindgen!({ + path: $path, + async: true, + tracing: true, + stringify: true, + }))?; }; } diff --git a/crates/component-macro/tests/expanded/char_tracing_async.rs b/crates/component-macro/tests/expanded/char_tracing_async.rs new file mode 100644 index 000000000000..dc7caf15fc8d --- /dev/null +++ b/crates/component-macro/tests/expanded/char_tracing_async.rs @@ -0,0 +1,461 @@ +/// Auto-generated bindings for a pre-instantiated version of a +/// component which implements the world `the-world`. +/// +/// This structure is created through [`TheWorldPre::new`] which +/// takes a [`InstancePre`](wasmtime::component::InstancePre) that +/// has been created through a [`Linker`](wasmtime::component::Linker). +/// +/// For more information see [`TheWorld`] as well. +pub struct TheWorldPre { + instance_pre: wasmtime::component::InstancePre, + indices: TheWorldIndices, +} +impl Clone for TheWorldPre { + fn clone(&self) -> Self { + Self { + instance_pre: self.instance_pre.clone(), + indices: self.indices.clone(), + } + } +} +impl<_T> TheWorldPre<_T> { + /// Creates a new copy of `TheWorldPre` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component behind `instance_pre` + /// does not have the required exports. + pub fn new( + instance_pre: wasmtime::component::InstancePre<_T>, + ) -> wasmtime::Result { + let indices = TheWorldIndices::new(instance_pre.component())?; + Ok(Self { instance_pre, indices }) + } + pub fn engine(&self) -> &wasmtime::Engine { + self.instance_pre.engine() + } + pub fn instance_pre(&self) -> &wasmtime::component::InstancePre<_T> { + &self.instance_pre + } + /// Instantiates a new instance of [`TheWorld`] within the + /// `store` provided. + /// + /// This function will use `self` as the pre-instantiated + /// instance to perform instantiation. Afterwards the preloaded + /// indices in `self` are used to lookup all exports on the + /// resulting instance. + pub async fn instantiate_async( + &self, + mut store: impl wasmtime::AsContextMut, + ) -> wasmtime::Result + where + _T: Send, + { + let mut store = store.as_context_mut(); + let instance = self.instance_pre.instantiate_async(&mut store).await?; + self.indices.load(&mut store, &instance) + } +} +/// Auto-generated bindings for index of the exports of +/// `the-world`. +/// +/// This is an implementation detail of [`TheWorldPre`] and can +/// be constructed if needed as well. +/// +/// For more information see [`TheWorld`] as well. +#[derive(Clone)] +pub struct TheWorldIndices { + interface0: exports::foo::foo::chars::GuestIndices, +} +/// Auto-generated bindings for an instance a component which +/// implements the world `the-world`. +/// +/// This structure can be created through a number of means +/// depending on your requirements and what you have on hand: +/// +/// * The most convenient way is to use +/// [`TheWorld::instantiate_async`] which only needs a +/// [`Store`], [`Component`], and [`Linker`]. +/// +/// * Alternatively you can create a [`TheWorldPre`] ahead of +/// time with a [`Component`] to front-load string lookups +/// of exports once instead of per-instantiation. This +/// method then uses [`TheWorldPre::instantiate_async`] to +/// create a [`TheWorld`]. +/// +/// * If you've instantiated the instance yourself already +/// then you can use [`TheWorld::new`]. +/// +/// * You can also access the guts of instantiation through +/// [`TheWorldIndices::new_instance`] followed +/// by [`TheWorldIndices::load`] to crate an instance of this +/// type. +/// +/// These methods are all equivalent to one another and move +/// around the tradeoff of what work is performed when. +/// +/// [`Store`]: wasmtime::Store +/// [`Component`]: wasmtime::component::Component +/// [`Linker`]: wasmtime::component::Linker +pub struct TheWorld { + interface0: exports::foo::foo::chars::Guest, +} +const _: () = { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + impl TheWorldIndices { + /// Creates a new copy of `TheWorldIndices` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component does not have the + /// required exports. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let _component = component; + let interface0 = exports::foo::foo::chars::GuestIndices::new(_component)?; + Ok(TheWorldIndices { interface0 }) + } + /// Creates a new instance of [`TheWorldIndices`] from an + /// instantiated component. + /// + /// This method of creating a [`TheWorld`] will perform string + /// lookups for all exports when this method is called. This + /// will only succeed if the provided instance matches the + /// requirements of [`TheWorld`]. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = exports::foo::foo::chars::GuestIndices::new_instance( + &mut store, + _instance, + )?; + Ok(TheWorldIndices { interface0 }) + } + /// Uses the indices stored in `self` to load an instance + /// of [`TheWorld`] from the instance provided. + /// + /// Note that at this time this method will additionally + /// perform type-checks of all exports. + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = self.interface0.load(&mut store, &_instance)?; + Ok(TheWorld { interface0 }) + } + } + impl TheWorld { + /// Convenience wrapper around [`TheWorldPre::new`] and + /// [`TheWorldPre::instantiate_async`]. + pub async fn instantiate_async<_T>( + mut store: impl wasmtime::AsContextMut, + component: &wasmtime::component::Component, + linker: &wasmtime::component::Linker<_T>, + ) -> wasmtime::Result + where + _T: Send, + { + let pre = linker.instantiate_pre(component)?; + TheWorldPre::new(pre)?.instantiate_async(store).await + } + /// Convenience wrapper around [`TheWorldIndices::new_instance`] and + /// [`TheWorldIndices::load`]. + pub fn new( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let indices = TheWorldIndices::new_instance(&mut store, instance)?; + indices.load(store, instance) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + T: Send, + U: foo::foo::chars::Host + Send, + { + foo::foo::chars::add_to_linker(linker, get)?; + Ok(()) + } + pub fn foo_foo_chars(&self) -> &exports::foo::foo::chars::Guest { + &self.interface0 + } + } +}; +pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod chars { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send { + /// A function that accepts a character + async fn take_char(&mut self, x: char) -> (); + /// A function that returns a character + async fn return_char(&mut self) -> char; + } + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("foo:foo/chars")?; + inst.func_wrap_async( + "take-char", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (char,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "chars", function = "take-char", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::take_char(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "return-char", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "chars", function = "return-char", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::return_char(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + /// A function that accepts a character + async fn take_char(&mut self, x: char) -> () { + Host::take_char(*self, x).await + } + /// A function that returns a character + async fn return_char(&mut self) -> char { + Host::return_char(*self).await + } + } + } + } +} +pub mod exports { + pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod chars { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + pub struct Guest { + take_char: wasmtime::component::Func, + return_char: wasmtime::component::Func, + } + #[derive(Clone)] + pub struct GuestIndices { + take_char: wasmtime::component::ComponentExportIndex, + return_char: wasmtime::component::ComponentExportIndex, + } + impl GuestIndices { + /// Constructor for [`GuestIndices`] which takes a + /// [`Component`](wasmtime::component::Component) as input and can be executed + /// before instantiation. + /// + /// This constructor can be used to front-load string lookups to find exports + /// within a component. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let (_, instance) = component + .export_index(None, "foo:foo/chars") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/chars`" + ) + })?; + Self::_new(|name| { + component.export_index(Some(&instance), name).map(|p| p.1) + }) + } + /// This constructor is similar to [`GuestIndices::new`] except that it + /// performs string lookups after instantiation time. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let instance_export = instance + .get_export(&mut store, None, "foo:foo/chars") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/chars`" + ) + })?; + Self::_new(|name| { + instance.get_export(&mut store, Some(&instance_export), name) + }) + } + fn _new( + mut lookup: impl FnMut( + &str, + ) -> Option, + ) -> wasmtime::Result { + let mut lookup = move |name| { + lookup(name) + .ok_or_else(|| { + anyhow::anyhow!( + "instance export `foo:foo/chars` does \ + not have export `{name}`" + ) + }) + }; + let _ = &mut lookup; + let take_char = lookup("take-char")?; + let return_char = lookup("return-char")?; + Ok(GuestIndices { + take_char, + return_char, + }) + } + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let mut store = store.as_context_mut(); + let _ = &mut store; + let _instance = instance; + let take_char = *_instance + .get_typed_func::<(char,), ()>(&mut store, &self.take_char)? + .func(); + let return_char = *_instance + .get_typed_func::< + (), + (char,), + >(&mut store, &self.return_char)? + .func(); + Ok(Guest { take_char, return_char }) + } + } + impl Guest { + /// A function that accepts a character + pub async fn call_take_char( + &self, + mut store: S, + arg0: char, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/chars", function = "take-char", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (char,), + (), + >::new_unchecked(self.take_char) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + /// A function that returns a character + pub async fn call_return_char( + &self, + mut store: S, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/chars", function = "return-char", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (char,), + >::new_unchecked(self.return_char) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + } + } + } + } +} diff --git a/crates/component-macro/tests/expanded/conventions_tracing_async.rs b/crates/component-macro/tests/expanded/conventions_tracing_async.rs new file mode 100644 index 000000000000..ac89ef41c553 --- /dev/null +++ b/crates/component-macro/tests/expanded/conventions_tracing_async.rs @@ -0,0 +1,1190 @@ +/// Auto-generated bindings for a pre-instantiated version of a +/// component which implements the world `the-world`. +/// +/// This structure is created through [`TheWorldPre::new`] which +/// takes a [`InstancePre`](wasmtime::component::InstancePre) that +/// has been created through a [`Linker`](wasmtime::component::Linker). +/// +/// For more information see [`TheWorld`] as well. +pub struct TheWorldPre { + instance_pre: wasmtime::component::InstancePre, + indices: TheWorldIndices, +} +impl Clone for TheWorldPre { + fn clone(&self) -> Self { + Self { + instance_pre: self.instance_pre.clone(), + indices: self.indices.clone(), + } + } +} +impl<_T> TheWorldPre<_T> { + /// Creates a new copy of `TheWorldPre` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component behind `instance_pre` + /// does not have the required exports. + pub fn new( + instance_pre: wasmtime::component::InstancePre<_T>, + ) -> wasmtime::Result { + let indices = TheWorldIndices::new(instance_pre.component())?; + Ok(Self { instance_pre, indices }) + } + pub fn engine(&self) -> &wasmtime::Engine { + self.instance_pre.engine() + } + pub fn instance_pre(&self) -> &wasmtime::component::InstancePre<_T> { + &self.instance_pre + } + /// Instantiates a new instance of [`TheWorld`] within the + /// `store` provided. + /// + /// This function will use `self` as the pre-instantiated + /// instance to perform instantiation. Afterwards the preloaded + /// indices in `self` are used to lookup all exports on the + /// resulting instance. + pub async fn instantiate_async( + &self, + mut store: impl wasmtime::AsContextMut, + ) -> wasmtime::Result + where + _T: Send, + { + let mut store = store.as_context_mut(); + let instance = self.instance_pre.instantiate_async(&mut store).await?; + self.indices.load(&mut store, &instance) + } +} +/// Auto-generated bindings for index of the exports of +/// `the-world`. +/// +/// This is an implementation detail of [`TheWorldPre`] and can +/// be constructed if needed as well. +/// +/// For more information see [`TheWorld`] as well. +#[derive(Clone)] +pub struct TheWorldIndices { + interface0: exports::foo::foo::conventions::GuestIndices, +} +/// Auto-generated bindings for an instance a component which +/// implements the world `the-world`. +/// +/// This structure can be created through a number of means +/// depending on your requirements and what you have on hand: +/// +/// * The most convenient way is to use +/// [`TheWorld::instantiate_async`] which only needs a +/// [`Store`], [`Component`], and [`Linker`]. +/// +/// * Alternatively you can create a [`TheWorldPre`] ahead of +/// time with a [`Component`] to front-load string lookups +/// of exports once instead of per-instantiation. This +/// method then uses [`TheWorldPre::instantiate_async`] to +/// create a [`TheWorld`]. +/// +/// * If you've instantiated the instance yourself already +/// then you can use [`TheWorld::new`]. +/// +/// * You can also access the guts of instantiation through +/// [`TheWorldIndices::new_instance`] followed +/// by [`TheWorldIndices::load`] to crate an instance of this +/// type. +/// +/// These methods are all equivalent to one another and move +/// around the tradeoff of what work is performed when. +/// +/// [`Store`]: wasmtime::Store +/// [`Component`]: wasmtime::component::Component +/// [`Linker`]: wasmtime::component::Linker +pub struct TheWorld { + interface0: exports::foo::foo::conventions::Guest, +} +const _: () = { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + impl TheWorldIndices { + /// Creates a new copy of `TheWorldIndices` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component does not have the + /// required exports. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let _component = component; + let interface0 = exports::foo::foo::conventions::GuestIndices::new( + _component, + )?; + Ok(TheWorldIndices { interface0 }) + } + /// Creates a new instance of [`TheWorldIndices`] from an + /// instantiated component. + /// + /// This method of creating a [`TheWorld`] will perform string + /// lookups for all exports when this method is called. This + /// will only succeed if the provided instance matches the + /// requirements of [`TheWorld`]. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = exports::foo::foo::conventions::GuestIndices::new_instance( + &mut store, + _instance, + )?; + Ok(TheWorldIndices { interface0 }) + } + /// Uses the indices stored in `self` to load an instance + /// of [`TheWorld`] from the instance provided. + /// + /// Note that at this time this method will additionally + /// perform type-checks of all exports. + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = self.interface0.load(&mut store, &_instance)?; + Ok(TheWorld { interface0 }) + } + } + impl TheWorld { + /// Convenience wrapper around [`TheWorldPre::new`] and + /// [`TheWorldPre::instantiate_async`]. + pub async fn instantiate_async<_T>( + mut store: impl wasmtime::AsContextMut, + component: &wasmtime::component::Component, + linker: &wasmtime::component::Linker<_T>, + ) -> wasmtime::Result + where + _T: Send, + { + let pre = linker.instantiate_pre(component)?; + TheWorldPre::new(pre)?.instantiate_async(store).await + } + /// Convenience wrapper around [`TheWorldIndices::new_instance`] and + /// [`TheWorldIndices::load`]. + pub fn new( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let indices = TheWorldIndices::new_instance(&mut store, instance)?; + indices.load(store, instance) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + T: Send, + U: foo::foo::conventions::Host + Send, + { + foo::foo::conventions::add_to_linker(linker, get)?; + Ok(()) + } + pub fn foo_foo_conventions(&self) -> &exports::foo::foo::conventions::Guest { + &self.interface0 + } + } +}; +pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod conventions { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(record)] + #[derive(Clone, Copy)] + pub struct LudicrousSpeed { + #[component(name = "how-fast-are-you-going")] + pub how_fast_are_you_going: u32, + #[component(name = "i-am-going-extremely-slow")] + pub i_am_going_extremely_slow: u64, + } + impl core::fmt::Debug for LudicrousSpeed { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("LudicrousSpeed") + .field("how-fast-are-you-going", &self.how_fast_are_you_going) + .field( + "i-am-going-extremely-slow", + &self.i_am_going_extremely_slow, + ) + .finish() + } + } + const _: () = { + assert!( + 16 == < LudicrousSpeed as wasmtime::component::ComponentType + >::SIZE32 + ); + assert!( + 8 == < LudicrousSpeed as wasmtime::component::ComponentType + >::ALIGN32 + ); + }; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send { + async fn kebab_case(&mut self) -> (); + async fn foo(&mut self, x: LudicrousSpeed) -> (); + async fn function_with_dashes(&mut self) -> (); + async fn function_with_no_weird_characters(&mut self) -> (); + async fn apple(&mut self) -> (); + async fn apple_pear(&mut self) -> (); + async fn apple_pear_grape(&mut self) -> (); + async fn a0(&mut self) -> (); + /// Comment out identifiers that collide when mapped to snake_case, for now; see + /// https://github.com/WebAssembly/component-model/issues/118 + /// APPLE: func() + /// APPLE-pear-GRAPE: func() + /// apple-PEAR-grape: func() + async fn is_xml(&mut self) -> (); + async fn explicit(&mut self) -> (); + async fn explicit_kebab(&mut self) -> (); + /// Identifiers with the same name as keywords are quoted. + async fn bool(&mut self) -> (); + } + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("foo:foo/conventions")?; + inst.func_wrap_async( + "kebab-case", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "conventions", function = "kebab-case", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::kebab_case(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "foo", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (LudicrousSpeed,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "conventions", function = "foo", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::foo(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "function-with-dashes", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "conventions", function = "function-with-dashes", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::function_with_dashes(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "function-with-no-weird-characters", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "conventions", function = + "function-with-no-weird-characters", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::function_with_no_weird_characters(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "apple", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "conventions", function = "apple", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::apple(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "apple-pear", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "conventions", function = "apple-pear", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::apple_pear(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "apple-pear-grape", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "conventions", function = "apple-pear-grape", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::apple_pear_grape(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "a0", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "conventions", function = "a0", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::a0(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "is-XML", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "conventions", function = "is-XML", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::is_xml(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "explicit", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "conventions", function = "explicit", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::explicit(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "explicit-kebab", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "conventions", function = "explicit-kebab", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::explicit_kebab(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "bool", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "conventions", function = "bool", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::bool(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn kebab_case(&mut self) -> () { + Host::kebab_case(*self).await + } + async fn foo(&mut self, x: LudicrousSpeed) -> () { + Host::foo(*self, x).await + } + async fn function_with_dashes(&mut self) -> () { + Host::function_with_dashes(*self).await + } + async fn function_with_no_weird_characters(&mut self) -> () { + Host::function_with_no_weird_characters(*self).await + } + async fn apple(&mut self) -> () { + Host::apple(*self).await + } + async fn apple_pear(&mut self) -> () { + Host::apple_pear(*self).await + } + async fn apple_pear_grape(&mut self) -> () { + Host::apple_pear_grape(*self).await + } + async fn a0(&mut self) -> () { + Host::a0(*self).await + } + /// Comment out identifiers that collide when mapped to snake_case, for now; see + /// https://github.com/WebAssembly/component-model/issues/118 + /// APPLE: func() + /// APPLE-pear-GRAPE: func() + /// apple-PEAR-grape: func() + async fn is_xml(&mut self) -> () { + Host::is_xml(*self).await + } + async fn explicit(&mut self) -> () { + Host::explicit(*self).await + } + async fn explicit_kebab(&mut self) -> () { + Host::explicit_kebab(*self).await + } + /// Identifiers with the same name as keywords are quoted. + async fn bool(&mut self) -> () { + Host::bool(*self).await + } + } + } + } +} +pub mod exports { + pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod conventions { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(record)] + #[derive(Clone, Copy)] + pub struct LudicrousSpeed { + #[component(name = "how-fast-are-you-going")] + pub how_fast_are_you_going: u32, + #[component(name = "i-am-going-extremely-slow")] + pub i_am_going_extremely_slow: u64, + } + impl core::fmt::Debug for LudicrousSpeed { + fn fmt( + &self, + f: &mut core::fmt::Formatter<'_>, + ) -> core::fmt::Result { + f.debug_struct("LudicrousSpeed") + .field( + "how-fast-are-you-going", + &self.how_fast_are_you_going, + ) + .field( + "i-am-going-extremely-slow", + &self.i_am_going_extremely_slow, + ) + .finish() + } + } + const _: () = { + assert!( + 16 == < LudicrousSpeed as wasmtime::component::ComponentType + >::SIZE32 + ); + assert!( + 8 == < LudicrousSpeed as wasmtime::component::ComponentType + >::ALIGN32 + ); + }; + pub struct Guest { + kebab_case: wasmtime::component::Func, + foo: wasmtime::component::Func, + function_with_dashes: wasmtime::component::Func, + function_with_no_weird_characters: wasmtime::component::Func, + apple: wasmtime::component::Func, + apple_pear: wasmtime::component::Func, + apple_pear_grape: wasmtime::component::Func, + a0: wasmtime::component::Func, + is_xml: wasmtime::component::Func, + explicit: wasmtime::component::Func, + explicit_kebab: wasmtime::component::Func, + bool: wasmtime::component::Func, + } + #[derive(Clone)] + pub struct GuestIndices { + kebab_case: wasmtime::component::ComponentExportIndex, + foo: wasmtime::component::ComponentExportIndex, + function_with_dashes: wasmtime::component::ComponentExportIndex, + function_with_no_weird_characters: wasmtime::component::ComponentExportIndex, + apple: wasmtime::component::ComponentExportIndex, + apple_pear: wasmtime::component::ComponentExportIndex, + apple_pear_grape: wasmtime::component::ComponentExportIndex, + a0: wasmtime::component::ComponentExportIndex, + is_xml: wasmtime::component::ComponentExportIndex, + explicit: wasmtime::component::ComponentExportIndex, + explicit_kebab: wasmtime::component::ComponentExportIndex, + bool: wasmtime::component::ComponentExportIndex, + } + impl GuestIndices { + /// Constructor for [`GuestIndices`] which takes a + /// [`Component`](wasmtime::component::Component) as input and can be executed + /// before instantiation. + /// + /// This constructor can be used to front-load string lookups to find exports + /// within a component. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let (_, instance) = component + .export_index(None, "foo:foo/conventions") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/conventions`" + ) + })?; + Self::_new(|name| { + component.export_index(Some(&instance), name).map(|p| p.1) + }) + } + /// This constructor is similar to [`GuestIndices::new`] except that it + /// performs string lookups after instantiation time. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let instance_export = instance + .get_export(&mut store, None, "foo:foo/conventions") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/conventions`" + ) + })?; + Self::_new(|name| { + instance.get_export(&mut store, Some(&instance_export), name) + }) + } + fn _new( + mut lookup: impl FnMut( + &str, + ) -> Option, + ) -> wasmtime::Result { + let mut lookup = move |name| { + lookup(name) + .ok_or_else(|| { + anyhow::anyhow!( + "instance export `foo:foo/conventions` does \ + not have export `{name}`" + ) + }) + }; + let _ = &mut lookup; + let kebab_case = lookup("kebab-case")?; + let foo = lookup("foo")?; + let function_with_dashes = lookup("function-with-dashes")?; + let function_with_no_weird_characters = lookup( + "function-with-no-weird-characters", + )?; + let apple = lookup("apple")?; + let apple_pear = lookup("apple-pear")?; + let apple_pear_grape = lookup("apple-pear-grape")?; + let a0 = lookup("a0")?; + let is_xml = lookup("is-XML")?; + let explicit = lookup("explicit")?; + let explicit_kebab = lookup("explicit-kebab")?; + let bool = lookup("bool")?; + Ok(GuestIndices { + kebab_case, + foo, + function_with_dashes, + function_with_no_weird_characters, + apple, + apple_pear, + apple_pear_grape, + a0, + is_xml, + explicit, + explicit_kebab, + bool, + }) + } + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let mut store = store.as_context_mut(); + let _ = &mut store; + let _instance = instance; + let kebab_case = *_instance + .get_typed_func::<(), ()>(&mut store, &self.kebab_case)? + .func(); + let foo = *_instance + .get_typed_func::< + (LudicrousSpeed,), + (), + >(&mut store, &self.foo)? + .func(); + let function_with_dashes = *_instance + .get_typed_func::< + (), + (), + >(&mut store, &self.function_with_dashes)? + .func(); + let function_with_no_weird_characters = *_instance + .get_typed_func::< + (), + (), + >(&mut store, &self.function_with_no_weird_characters)? + .func(); + let apple = *_instance + .get_typed_func::<(), ()>(&mut store, &self.apple)? + .func(); + let apple_pear = *_instance + .get_typed_func::<(), ()>(&mut store, &self.apple_pear)? + .func(); + let apple_pear_grape = *_instance + .get_typed_func::< + (), + (), + >(&mut store, &self.apple_pear_grape)? + .func(); + let a0 = *_instance + .get_typed_func::<(), ()>(&mut store, &self.a0)? + .func(); + let is_xml = *_instance + .get_typed_func::<(), ()>(&mut store, &self.is_xml)? + .func(); + let explicit = *_instance + .get_typed_func::<(), ()>(&mut store, &self.explicit)? + .func(); + let explicit_kebab = *_instance + .get_typed_func::<(), ()>(&mut store, &self.explicit_kebab)? + .func(); + let bool = *_instance + .get_typed_func::<(), ()>(&mut store, &self.bool)? + .func(); + Ok(Guest { + kebab_case, + foo, + function_with_dashes, + function_with_no_weird_characters, + apple, + apple_pear, + apple_pear_grape, + a0, + is_xml, + explicit, + explicit_kebab, + bool, + }) + } + } + impl Guest { + pub async fn call_kebab_case( + &self, + mut store: S, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/conventions", function = "kebab-case", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (), + >::new_unchecked(self.kebab_case) + }; + let () = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_foo( + &self, + mut store: S, + arg0: LudicrousSpeed, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/conventions", function = "foo", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (LudicrousSpeed,), + (), + >::new_unchecked(self.foo) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_function_with_dashes( + &self, + mut store: S, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/conventions", function = "function-with-dashes", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (), + >::new_unchecked(self.function_with_dashes) + }; + let () = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_function_with_no_weird_characters< + S: wasmtime::AsContextMut, + >(&self, mut store: S) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/conventions", function = + "function-with-no-weird-characters", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (), + >::new_unchecked(self.function_with_no_weird_characters) + }; + let () = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_apple( + &self, + mut store: S, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/conventions", function = "apple", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (), + >::new_unchecked(self.apple) + }; + let () = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_apple_pear( + &self, + mut store: S, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/conventions", function = "apple-pear", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (), + >::new_unchecked(self.apple_pear) + }; + let () = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_apple_pear_grape( + &self, + mut store: S, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/conventions", function = "apple-pear-grape", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (), + >::new_unchecked(self.apple_pear_grape) + }; + let () = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_a0( + &self, + mut store: S, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/conventions", function = "a0", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (), + >::new_unchecked(self.a0) + }; + let () = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + /// Comment out identifiers that collide when mapped to snake_case, for now; see + /// https://github.com/WebAssembly/component-model/issues/118 + /// APPLE: func() + /// APPLE-pear-GRAPE: func() + /// apple-PEAR-grape: func() + pub async fn call_is_xml( + &self, + mut store: S, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/conventions", function = "is-XML", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (), + >::new_unchecked(self.is_xml) + }; + let () = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_explicit( + &self, + mut store: S, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/conventions", function = "explicit", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (), + >::new_unchecked(self.explicit) + }; + let () = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_explicit_kebab( + &self, + mut store: S, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/conventions", function = "explicit-kebab", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (), + >::new_unchecked(self.explicit_kebab) + }; + let () = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + /// Identifiers with the same name as keywords are quoted. + pub async fn call_bool( + &self, + mut store: S, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/conventions", function = "bool", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (), + >::new_unchecked(self.bool) + }; + let () = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + } + } + } + } +} diff --git a/crates/component-macro/tests/expanded/dead-code_tracing_async.rs b/crates/component-macro/tests/expanded/dead-code_tracing_async.rs new file mode 100644 index 000000000000..fc670a943af6 --- /dev/null +++ b/crates/component-macro/tests/expanded/dead-code_tracing_async.rs @@ -0,0 +1,313 @@ +/// Auto-generated bindings for a pre-instantiated version of a +/// component which implements the world `imports`. +/// +/// This structure is created through [`ImportsPre::new`] which +/// takes a [`InstancePre`](wasmtime::component::InstancePre) that +/// has been created through a [`Linker`](wasmtime::component::Linker). +/// +/// For more information see [`Imports`] as well. +pub struct ImportsPre { + instance_pre: wasmtime::component::InstancePre, + indices: ImportsIndices, +} +impl Clone for ImportsPre { + fn clone(&self) -> Self { + Self { + instance_pre: self.instance_pre.clone(), + indices: self.indices.clone(), + } + } +} +impl<_T> ImportsPre<_T> { + /// Creates a new copy of `ImportsPre` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component behind `instance_pre` + /// does not have the required exports. + pub fn new( + instance_pre: wasmtime::component::InstancePre<_T>, + ) -> wasmtime::Result { + let indices = ImportsIndices::new(instance_pre.component())?; + Ok(Self { instance_pre, indices }) + } + pub fn engine(&self) -> &wasmtime::Engine { + self.instance_pre.engine() + } + pub fn instance_pre(&self) -> &wasmtime::component::InstancePre<_T> { + &self.instance_pre + } + /// Instantiates a new instance of [`Imports`] within the + /// `store` provided. + /// + /// This function will use `self` as the pre-instantiated + /// instance to perform instantiation. Afterwards the preloaded + /// indices in `self` are used to lookup all exports on the + /// resulting instance. + pub async fn instantiate_async( + &self, + mut store: impl wasmtime::AsContextMut, + ) -> wasmtime::Result + where + _T: Send, + { + let mut store = store.as_context_mut(); + let instance = self.instance_pre.instantiate_async(&mut store).await?; + self.indices.load(&mut store, &instance) + } +} +/// Auto-generated bindings for index of the exports of +/// `imports`. +/// +/// This is an implementation detail of [`ImportsPre`] and can +/// be constructed if needed as well. +/// +/// For more information see [`Imports`] as well. +#[derive(Clone)] +pub struct ImportsIndices {} +/// Auto-generated bindings for an instance a component which +/// implements the world `imports`. +/// +/// This structure can be created through a number of means +/// depending on your requirements and what you have on hand: +/// +/// * The most convenient way is to use +/// [`Imports::instantiate_async`] which only needs a +/// [`Store`], [`Component`], and [`Linker`]. +/// +/// * Alternatively you can create a [`ImportsPre`] ahead of +/// time with a [`Component`] to front-load string lookups +/// of exports once instead of per-instantiation. This +/// method then uses [`ImportsPre::instantiate_async`] to +/// create a [`Imports`]. +/// +/// * If you've instantiated the instance yourself already +/// then you can use [`Imports::new`]. +/// +/// * You can also access the guts of instantiation through +/// [`ImportsIndices::new_instance`] followed +/// by [`ImportsIndices::load`] to crate an instance of this +/// type. +/// +/// These methods are all equivalent to one another and move +/// around the tradeoff of what work is performed when. +/// +/// [`Store`]: wasmtime::Store +/// [`Component`]: wasmtime::component::Component +/// [`Linker`]: wasmtime::component::Linker +pub struct Imports {} +const _: () = { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + impl ImportsIndices { + /// Creates a new copy of `ImportsIndices` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component does not have the + /// required exports. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let _component = component; + Ok(ImportsIndices {}) + } + /// Creates a new instance of [`ImportsIndices`] from an + /// instantiated component. + /// + /// This method of creating a [`Imports`] will perform string + /// lookups for all exports when this method is called. This + /// will only succeed if the provided instance matches the + /// requirements of [`Imports`]. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + Ok(ImportsIndices {}) + } + /// Uses the indices stored in `self` to load an instance + /// of [`Imports`] from the instance provided. + /// + /// Note that at this time this method will additionally + /// perform type-checks of all exports. + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + Ok(Imports {}) + } + } + impl Imports { + /// Convenience wrapper around [`ImportsPre::new`] and + /// [`ImportsPre::instantiate_async`]. + pub async fn instantiate_async<_T>( + mut store: impl wasmtime::AsContextMut, + component: &wasmtime::component::Component, + linker: &wasmtime::component::Linker<_T>, + ) -> wasmtime::Result + where + _T: Send, + { + let pre = linker.instantiate_pre(component)?; + ImportsPre::new(pre)?.instantiate_async(store).await + } + /// Convenience wrapper around [`ImportsIndices::new_instance`] and + /// [`ImportsIndices::load`]. + pub fn new( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let indices = ImportsIndices::new_instance(&mut store, instance)?; + indices.load(store, instance) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + T: Send, + U: a::b::interface_with_live_type::Host + + a::b::interface_with_dead_type::Host + Send, + { + a::b::interface_with_live_type::add_to_linker(linker, get)?; + a::b::interface_with_dead_type::add_to_linker(linker, get)?; + Ok(()) + } + } +}; +pub mod a { + pub mod b { + #[allow(clippy::all)] + pub mod interface_with_live_type { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(record)] + #[derive(Clone, Copy)] + pub struct LiveType { + #[component(name = "a")] + pub a: u32, + } + impl core::fmt::Debug for LiveType { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("LiveType").field("a", &self.a).finish() + } + } + const _: () = { + assert!(4 == < LiveType as wasmtime::component::ComponentType >::SIZE32); + assert!( + 4 == < LiveType as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send { + async fn f(&mut self) -> LiveType; + } + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("a:b/interface-with-live-type")?; + inst.func_wrap_async( + "f", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "interface-with-live-type", function = "f", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::f(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn f(&mut self) -> LiveType { + Host::f(*self).await + } + } + } + #[allow(clippy::all)] + pub mod interface_with_dead_type { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send {} + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("a:b/interface-with-dead-type")?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T {} + } + } +} diff --git a/crates/component-macro/tests/expanded/direct-import_tracing_async.rs b/crates/component-macro/tests/expanded/direct-import_tracing_async.rs new file mode 100644 index 000000000000..464deae28bf9 --- /dev/null +++ b/crates/component-macro/tests/expanded/direct-import_tracing_async.rs @@ -0,0 +1,232 @@ +/// Auto-generated bindings for a pre-instantiated version of a +/// component which implements the world `foo`. +/// +/// This structure is created through [`FooPre::new`] which +/// takes a [`InstancePre`](wasmtime::component::InstancePre) that +/// has been created through a [`Linker`](wasmtime::component::Linker). +/// +/// For more information see [`Foo`] as well. +pub struct FooPre { + instance_pre: wasmtime::component::InstancePre, + indices: FooIndices, +} +impl Clone for FooPre { + fn clone(&self) -> Self { + Self { + instance_pre: self.instance_pre.clone(), + indices: self.indices.clone(), + } + } +} +impl<_T> FooPre<_T> { + /// Creates a new copy of `FooPre` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component behind `instance_pre` + /// does not have the required exports. + pub fn new( + instance_pre: wasmtime::component::InstancePre<_T>, + ) -> wasmtime::Result { + let indices = FooIndices::new(instance_pre.component())?; + Ok(Self { instance_pre, indices }) + } + pub fn engine(&self) -> &wasmtime::Engine { + self.instance_pre.engine() + } + pub fn instance_pre(&self) -> &wasmtime::component::InstancePre<_T> { + &self.instance_pre + } + /// Instantiates a new instance of [`Foo`] within the + /// `store` provided. + /// + /// This function will use `self` as the pre-instantiated + /// instance to perform instantiation. Afterwards the preloaded + /// indices in `self` are used to lookup all exports on the + /// resulting instance. + pub async fn instantiate_async( + &self, + mut store: impl wasmtime::AsContextMut, + ) -> wasmtime::Result + where + _T: Send, + { + let mut store = store.as_context_mut(); + let instance = self.instance_pre.instantiate_async(&mut store).await?; + self.indices.load(&mut store, &instance) + } +} +/// Auto-generated bindings for index of the exports of +/// `foo`. +/// +/// This is an implementation detail of [`FooPre`] and can +/// be constructed if needed as well. +/// +/// For more information see [`Foo`] as well. +#[derive(Clone)] +pub struct FooIndices {} +/// Auto-generated bindings for an instance a component which +/// implements the world `foo`. +/// +/// This structure can be created through a number of means +/// depending on your requirements and what you have on hand: +/// +/// * The most convenient way is to use +/// [`Foo::instantiate_async`] which only needs a +/// [`Store`], [`Component`], and [`Linker`]. +/// +/// * Alternatively you can create a [`FooPre`] ahead of +/// time with a [`Component`] to front-load string lookups +/// of exports once instead of per-instantiation. This +/// method then uses [`FooPre::instantiate_async`] to +/// create a [`Foo`]. +/// +/// * If you've instantiated the instance yourself already +/// then you can use [`Foo::new`]. +/// +/// * You can also access the guts of instantiation through +/// [`FooIndices::new_instance`] followed +/// by [`FooIndices::load`] to crate an instance of this +/// type. +/// +/// These methods are all equivalent to one another and move +/// around the tradeoff of what work is performed when. +/// +/// [`Store`]: wasmtime::Store +/// [`Component`]: wasmtime::component::Component +/// [`Linker`]: wasmtime::component::Linker +pub struct Foo {} +#[wasmtime::component::__internal::async_trait] +pub trait FooImports: Send { + async fn foo(&mut self) -> (); +} +pub trait FooImportsGetHost< + T, +>: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: FooImports; +} +impl FooImportsGetHost for F +where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: FooImports, +{ + type Host = O; +} +#[wasmtime::component::__internal::async_trait] +impl<_T: FooImports + ?Sized + Send> FooImports for &mut _T { + async fn foo(&mut self) -> () { + FooImports::foo(*self).await + } +} +const _: () = { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + impl FooIndices { + /// Creates a new copy of `FooIndices` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component does not have the + /// required exports. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let _component = component; + Ok(FooIndices {}) + } + /// Creates a new instance of [`FooIndices`] from an + /// instantiated component. + /// + /// This method of creating a [`Foo`] will perform string + /// lookups for all exports when this method is called. This + /// will only succeed if the provided instance matches the + /// requirements of [`Foo`]. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + Ok(FooIndices {}) + } + /// Uses the indices stored in `self` to load an instance + /// of [`Foo`] from the instance provided. + /// + /// Note that at this time this method will additionally + /// perform type-checks of all exports. + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + Ok(Foo {}) + } + } + impl Foo { + /// Convenience wrapper around [`FooPre::new`] and + /// [`FooPre::instantiate_async`]. + pub async fn instantiate_async<_T>( + mut store: impl wasmtime::AsContextMut, + component: &wasmtime::component::Component, + linker: &wasmtime::component::Linker<_T>, + ) -> wasmtime::Result + where + _T: Send, + { + let pre = linker.instantiate_pre(component)?; + FooPre::new(pre)?.instantiate_async(store).await + } + /// Convenience wrapper around [`FooIndices::new_instance`] and + /// [`FooIndices::load`]. + pub fn new( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let indices = FooIndices::new_instance(&mut store, instance)?; + indices.load(store, instance) + } + pub fn add_to_linker_imports_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> FooImportsGetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut linker = linker.root(); + linker + .func_wrap_async( + "foo", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = "foo", + function = "foo", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = FooImports::foo(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + T: Send, + U: FooImports + Send, + { + Self::add_to_linker_imports_get_host(linker, get)?; + Ok(()) + } + } +}; diff --git a/crates/component-macro/tests/expanded/empty_tracing_async.rs b/crates/component-macro/tests/expanded/empty_tracing_async.rs new file mode 100644 index 000000000000..d2eea87b72a0 --- /dev/null +++ b/crates/component-macro/tests/expanded/empty_tracing_async.rs @@ -0,0 +1,165 @@ +/// Auto-generated bindings for a pre-instantiated version of a +/// component which implements the world `empty`. +/// +/// This structure is created through [`EmptyPre::new`] which +/// takes a [`InstancePre`](wasmtime::component::InstancePre) that +/// has been created through a [`Linker`](wasmtime::component::Linker). +/// +/// For more information see [`Empty`] as well. +pub struct EmptyPre { + instance_pre: wasmtime::component::InstancePre, + indices: EmptyIndices, +} +impl Clone for EmptyPre { + fn clone(&self) -> Self { + Self { + instance_pre: self.instance_pre.clone(), + indices: self.indices.clone(), + } + } +} +impl<_T> EmptyPre<_T> { + /// Creates a new copy of `EmptyPre` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component behind `instance_pre` + /// does not have the required exports. + pub fn new( + instance_pre: wasmtime::component::InstancePre<_T>, + ) -> wasmtime::Result { + let indices = EmptyIndices::new(instance_pre.component())?; + Ok(Self { instance_pre, indices }) + } + pub fn engine(&self) -> &wasmtime::Engine { + self.instance_pre.engine() + } + pub fn instance_pre(&self) -> &wasmtime::component::InstancePre<_T> { + &self.instance_pre + } + /// Instantiates a new instance of [`Empty`] within the + /// `store` provided. + /// + /// This function will use `self` as the pre-instantiated + /// instance to perform instantiation. Afterwards the preloaded + /// indices in `self` are used to lookup all exports on the + /// resulting instance. + pub async fn instantiate_async( + &self, + mut store: impl wasmtime::AsContextMut, + ) -> wasmtime::Result + where + _T: Send, + { + let mut store = store.as_context_mut(); + let instance = self.instance_pre.instantiate_async(&mut store).await?; + self.indices.load(&mut store, &instance) + } +} +/// Auto-generated bindings for index of the exports of +/// `empty`. +/// +/// This is an implementation detail of [`EmptyPre`] and can +/// be constructed if needed as well. +/// +/// For more information see [`Empty`] as well. +#[derive(Clone)] +pub struct EmptyIndices {} +/// Auto-generated bindings for an instance a component which +/// implements the world `empty`. +/// +/// This structure can be created through a number of means +/// depending on your requirements and what you have on hand: +/// +/// * The most convenient way is to use +/// [`Empty::instantiate_async`] which only needs a +/// [`Store`], [`Component`], and [`Linker`]. +/// +/// * Alternatively you can create a [`EmptyPre`] ahead of +/// time with a [`Component`] to front-load string lookups +/// of exports once instead of per-instantiation. This +/// method then uses [`EmptyPre::instantiate_async`] to +/// create a [`Empty`]. +/// +/// * If you've instantiated the instance yourself already +/// then you can use [`Empty::new`]. +/// +/// * You can also access the guts of instantiation through +/// [`EmptyIndices::new_instance`] followed +/// by [`EmptyIndices::load`] to crate an instance of this +/// type. +/// +/// These methods are all equivalent to one another and move +/// around the tradeoff of what work is performed when. +/// +/// [`Store`]: wasmtime::Store +/// [`Component`]: wasmtime::component::Component +/// [`Linker`]: wasmtime::component::Linker +pub struct Empty {} +const _: () = { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + impl EmptyIndices { + /// Creates a new copy of `EmptyIndices` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component does not have the + /// required exports. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let _component = component; + Ok(EmptyIndices {}) + } + /// Creates a new instance of [`EmptyIndices`] from an + /// instantiated component. + /// + /// This method of creating a [`Empty`] will perform string + /// lookups for all exports when this method is called. This + /// will only succeed if the provided instance matches the + /// requirements of [`Empty`]. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + Ok(EmptyIndices {}) + } + /// Uses the indices stored in `self` to load an instance + /// of [`Empty`] from the instance provided. + /// + /// Note that at this time this method will additionally + /// perform type-checks of all exports. + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + Ok(Empty {}) + } + } + impl Empty { + /// Convenience wrapper around [`EmptyPre::new`] and + /// [`EmptyPre::instantiate_async`]. + pub async fn instantiate_async<_T>( + mut store: impl wasmtime::AsContextMut, + component: &wasmtime::component::Component, + linker: &wasmtime::component::Linker<_T>, + ) -> wasmtime::Result + where + _T: Send, + { + let pre = linker.instantiate_pre(component)?; + EmptyPre::new(pre)?.instantiate_async(store).await + } + /// Convenience wrapper around [`EmptyIndices::new_instance`] and + /// [`EmptyIndices::load`]. + pub fn new( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let indices = EmptyIndices::new_instance(&mut store, instance)?; + indices.load(store, instance) + } + } +}; diff --git a/crates/component-macro/tests/expanded/flags_tracing_async.rs b/crates/component-macro/tests/expanded/flags_tracing_async.rs new file mode 100644 index 000000000000..8bec37487115 --- /dev/null +++ b/crates/component-macro/tests/expanded/flags_tracing_async.rs @@ -0,0 +1,1096 @@ +/// Auto-generated bindings for a pre-instantiated version of a +/// component which implements the world `the-flags`. +/// +/// This structure is created through [`TheFlagsPre::new`] which +/// takes a [`InstancePre`](wasmtime::component::InstancePre) that +/// has been created through a [`Linker`](wasmtime::component::Linker). +/// +/// For more information see [`TheFlags`] as well. +pub struct TheFlagsPre { + instance_pre: wasmtime::component::InstancePre, + indices: TheFlagsIndices, +} +impl Clone for TheFlagsPre { + fn clone(&self) -> Self { + Self { + instance_pre: self.instance_pre.clone(), + indices: self.indices.clone(), + } + } +} +impl<_T> TheFlagsPre<_T> { + /// Creates a new copy of `TheFlagsPre` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component behind `instance_pre` + /// does not have the required exports. + pub fn new( + instance_pre: wasmtime::component::InstancePre<_T>, + ) -> wasmtime::Result { + let indices = TheFlagsIndices::new(instance_pre.component())?; + Ok(Self { instance_pre, indices }) + } + pub fn engine(&self) -> &wasmtime::Engine { + self.instance_pre.engine() + } + pub fn instance_pre(&self) -> &wasmtime::component::InstancePre<_T> { + &self.instance_pre + } + /// Instantiates a new instance of [`TheFlags`] within the + /// `store` provided. + /// + /// This function will use `self` as the pre-instantiated + /// instance to perform instantiation. Afterwards the preloaded + /// indices in `self` are used to lookup all exports on the + /// resulting instance. + pub async fn instantiate_async( + &self, + mut store: impl wasmtime::AsContextMut, + ) -> wasmtime::Result + where + _T: Send, + { + let mut store = store.as_context_mut(); + let instance = self.instance_pre.instantiate_async(&mut store).await?; + self.indices.load(&mut store, &instance) + } +} +/// Auto-generated bindings for index of the exports of +/// `the-flags`. +/// +/// This is an implementation detail of [`TheFlagsPre`] and can +/// be constructed if needed as well. +/// +/// For more information see [`TheFlags`] as well. +#[derive(Clone)] +pub struct TheFlagsIndices { + interface0: exports::foo::foo::flegs::GuestIndices, +} +/// Auto-generated bindings for an instance a component which +/// implements the world `the-flags`. +/// +/// This structure can be created through a number of means +/// depending on your requirements and what you have on hand: +/// +/// * The most convenient way is to use +/// [`TheFlags::instantiate_async`] which only needs a +/// [`Store`], [`Component`], and [`Linker`]. +/// +/// * Alternatively you can create a [`TheFlagsPre`] ahead of +/// time with a [`Component`] to front-load string lookups +/// of exports once instead of per-instantiation. This +/// method then uses [`TheFlagsPre::instantiate_async`] to +/// create a [`TheFlags`]. +/// +/// * If you've instantiated the instance yourself already +/// then you can use [`TheFlags::new`]. +/// +/// * You can also access the guts of instantiation through +/// [`TheFlagsIndices::new_instance`] followed +/// by [`TheFlagsIndices::load`] to crate an instance of this +/// type. +/// +/// These methods are all equivalent to one another and move +/// around the tradeoff of what work is performed when. +/// +/// [`Store`]: wasmtime::Store +/// [`Component`]: wasmtime::component::Component +/// [`Linker`]: wasmtime::component::Linker +pub struct TheFlags { + interface0: exports::foo::foo::flegs::Guest, +} +const _: () = { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + impl TheFlagsIndices { + /// Creates a new copy of `TheFlagsIndices` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component does not have the + /// required exports. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let _component = component; + let interface0 = exports::foo::foo::flegs::GuestIndices::new(_component)?; + Ok(TheFlagsIndices { interface0 }) + } + /// Creates a new instance of [`TheFlagsIndices`] from an + /// instantiated component. + /// + /// This method of creating a [`TheFlags`] will perform string + /// lookups for all exports when this method is called. This + /// will only succeed if the provided instance matches the + /// requirements of [`TheFlags`]. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = exports::foo::foo::flegs::GuestIndices::new_instance( + &mut store, + _instance, + )?; + Ok(TheFlagsIndices { interface0 }) + } + /// Uses the indices stored in `self` to load an instance + /// of [`TheFlags`] from the instance provided. + /// + /// Note that at this time this method will additionally + /// perform type-checks of all exports. + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = self.interface0.load(&mut store, &_instance)?; + Ok(TheFlags { interface0 }) + } + } + impl TheFlags { + /// Convenience wrapper around [`TheFlagsPre::new`] and + /// [`TheFlagsPre::instantiate_async`]. + pub async fn instantiate_async<_T>( + mut store: impl wasmtime::AsContextMut, + component: &wasmtime::component::Component, + linker: &wasmtime::component::Linker<_T>, + ) -> wasmtime::Result + where + _T: Send, + { + let pre = linker.instantiate_pre(component)?; + TheFlagsPre::new(pre)?.instantiate_async(store).await + } + /// Convenience wrapper around [`TheFlagsIndices::new_instance`] and + /// [`TheFlagsIndices::load`]. + pub fn new( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let indices = TheFlagsIndices::new_instance(&mut store, instance)?; + indices.load(store, instance) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + T: Send, + U: foo::foo::flegs::Host + Send, + { + foo::foo::flegs::add_to_linker(linker, get)?; + Ok(()) + } + pub fn foo_foo_flegs(&self) -> &exports::foo::foo::flegs::Guest { + &self.interface0 + } + } +}; +pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod flegs { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + wasmtime::component::flags!(Flag1 { #[component(name = "b0")] const B0; }); + const _: () = { + assert!(1 == < Flag1 as wasmtime::component::ComponentType >::SIZE32); + assert!(1 == < Flag1 as wasmtime::component::ComponentType >::ALIGN32); + }; + wasmtime::component::flags!( + Flag2 { #[component(name = "b0")] const B0; #[component(name = "b1")] + const B1; } + ); + const _: () = { + assert!(1 == < Flag2 as wasmtime::component::ComponentType >::SIZE32); + assert!(1 == < Flag2 as wasmtime::component::ComponentType >::ALIGN32); + }; + wasmtime::component::flags!( + Flag4 { #[component(name = "b0")] const B0; #[component(name = "b1")] + const B1; #[component(name = "b2")] const B2; #[component(name = "b3")] + const B3; } + ); + const _: () = { + assert!(1 == < Flag4 as wasmtime::component::ComponentType >::SIZE32); + assert!(1 == < Flag4 as wasmtime::component::ComponentType >::ALIGN32); + }; + wasmtime::component::flags!( + Flag8 { #[component(name = "b0")] const B0; #[component(name = "b1")] + const B1; #[component(name = "b2")] const B2; #[component(name = "b3")] + const B3; #[component(name = "b4")] const B4; #[component(name = "b5")] + const B5; #[component(name = "b6")] const B6; #[component(name = "b7")] + const B7; } + ); + const _: () = { + assert!(1 == < Flag8 as wasmtime::component::ComponentType >::SIZE32); + assert!(1 == < Flag8 as wasmtime::component::ComponentType >::ALIGN32); + }; + wasmtime::component::flags!( + Flag16 { #[component(name = "b0")] const B0; #[component(name = "b1")] + const B1; #[component(name = "b2")] const B2; #[component(name = "b3")] + const B3; #[component(name = "b4")] const B4; #[component(name = "b5")] + const B5; #[component(name = "b6")] const B6; #[component(name = "b7")] + const B7; #[component(name = "b8")] const B8; #[component(name = "b9")] + const B9; #[component(name = "b10")] const B10; #[component(name = + "b11")] const B11; #[component(name = "b12")] const B12; #[component(name + = "b13")] const B13; #[component(name = "b14")] const B14; + #[component(name = "b15")] const B15; } + ); + const _: () = { + assert!(2 == < Flag16 as wasmtime::component::ComponentType >::SIZE32); + assert!(2 == < Flag16 as wasmtime::component::ComponentType >::ALIGN32); + }; + wasmtime::component::flags!( + Flag32 { #[component(name = "b0")] const B0; #[component(name = "b1")] + const B1; #[component(name = "b2")] const B2; #[component(name = "b3")] + const B3; #[component(name = "b4")] const B4; #[component(name = "b5")] + const B5; #[component(name = "b6")] const B6; #[component(name = "b7")] + const B7; #[component(name = "b8")] const B8; #[component(name = "b9")] + const B9; #[component(name = "b10")] const B10; #[component(name = + "b11")] const B11; #[component(name = "b12")] const B12; #[component(name + = "b13")] const B13; #[component(name = "b14")] const B14; + #[component(name = "b15")] const B15; #[component(name = "b16")] const + B16; #[component(name = "b17")] const B17; #[component(name = "b18")] + const B18; #[component(name = "b19")] const B19; #[component(name = + "b20")] const B20; #[component(name = "b21")] const B21; #[component(name + = "b22")] const B22; #[component(name = "b23")] const B23; + #[component(name = "b24")] const B24; #[component(name = "b25")] const + B25; #[component(name = "b26")] const B26; #[component(name = "b27")] + const B27; #[component(name = "b28")] const B28; #[component(name = + "b29")] const B29; #[component(name = "b30")] const B30; #[component(name + = "b31")] const B31; } + ); + const _: () = { + assert!(4 == < Flag32 as wasmtime::component::ComponentType >::SIZE32); + assert!(4 == < Flag32 as wasmtime::component::ComponentType >::ALIGN32); + }; + wasmtime::component::flags!( + Flag64 { #[component(name = "b0")] const B0; #[component(name = "b1")] + const B1; #[component(name = "b2")] const B2; #[component(name = "b3")] + const B3; #[component(name = "b4")] const B4; #[component(name = "b5")] + const B5; #[component(name = "b6")] const B6; #[component(name = "b7")] + const B7; #[component(name = "b8")] const B8; #[component(name = "b9")] + const B9; #[component(name = "b10")] const B10; #[component(name = + "b11")] const B11; #[component(name = "b12")] const B12; #[component(name + = "b13")] const B13; #[component(name = "b14")] const B14; + #[component(name = "b15")] const B15; #[component(name = "b16")] const + B16; #[component(name = "b17")] const B17; #[component(name = "b18")] + const B18; #[component(name = "b19")] const B19; #[component(name = + "b20")] const B20; #[component(name = "b21")] const B21; #[component(name + = "b22")] const B22; #[component(name = "b23")] const B23; + #[component(name = "b24")] const B24; #[component(name = "b25")] const + B25; #[component(name = "b26")] const B26; #[component(name = "b27")] + const B27; #[component(name = "b28")] const B28; #[component(name = + "b29")] const B29; #[component(name = "b30")] const B30; #[component(name + = "b31")] const B31; #[component(name = "b32")] const B32; + #[component(name = "b33")] const B33; #[component(name = "b34")] const + B34; #[component(name = "b35")] const B35; #[component(name = "b36")] + const B36; #[component(name = "b37")] const B37; #[component(name = + "b38")] const B38; #[component(name = "b39")] const B39; #[component(name + = "b40")] const B40; #[component(name = "b41")] const B41; + #[component(name = "b42")] const B42; #[component(name = "b43")] const + B43; #[component(name = "b44")] const B44; #[component(name = "b45")] + const B45; #[component(name = "b46")] const B46; #[component(name = + "b47")] const B47; #[component(name = "b48")] const B48; #[component(name + = "b49")] const B49; #[component(name = "b50")] const B50; + #[component(name = "b51")] const B51; #[component(name = "b52")] const + B52; #[component(name = "b53")] const B53; #[component(name = "b54")] + const B54; #[component(name = "b55")] const B55; #[component(name = + "b56")] const B56; #[component(name = "b57")] const B57; #[component(name + = "b58")] const B58; #[component(name = "b59")] const B59; + #[component(name = "b60")] const B60; #[component(name = "b61")] const + B61; #[component(name = "b62")] const B62; #[component(name = "b63")] + const B63; } + ); + const _: () = { + assert!(8 == < Flag64 as wasmtime::component::ComponentType >::SIZE32); + assert!(4 == < Flag64 as wasmtime::component::ComponentType >::ALIGN32); + }; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send { + async fn roundtrip_flag1(&mut self, x: Flag1) -> Flag1; + async fn roundtrip_flag2(&mut self, x: Flag2) -> Flag2; + async fn roundtrip_flag4(&mut self, x: Flag4) -> Flag4; + async fn roundtrip_flag8(&mut self, x: Flag8) -> Flag8; + async fn roundtrip_flag16(&mut self, x: Flag16) -> Flag16; + async fn roundtrip_flag32(&mut self, x: Flag32) -> Flag32; + async fn roundtrip_flag64(&mut self, x: Flag64) -> Flag64; + } + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("foo:foo/flegs")?; + inst.func_wrap_async( + "roundtrip-flag1", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (Flag1,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "flegs", function = "roundtrip-flag1", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::roundtrip_flag1(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "roundtrip-flag2", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (Flag2,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "flegs", function = "roundtrip-flag2", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::roundtrip_flag2(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "roundtrip-flag4", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (Flag4,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "flegs", function = "roundtrip-flag4", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::roundtrip_flag4(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "roundtrip-flag8", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (Flag8,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "flegs", function = "roundtrip-flag8", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::roundtrip_flag8(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "roundtrip-flag16", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (Flag16,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "flegs", function = "roundtrip-flag16", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::roundtrip_flag16(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "roundtrip-flag32", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (Flag32,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "flegs", function = "roundtrip-flag32", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::roundtrip_flag32(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "roundtrip-flag64", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (Flag64,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "flegs", function = "roundtrip-flag64", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::roundtrip_flag64(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn roundtrip_flag1(&mut self, x: Flag1) -> Flag1 { + Host::roundtrip_flag1(*self, x).await + } + async fn roundtrip_flag2(&mut self, x: Flag2) -> Flag2 { + Host::roundtrip_flag2(*self, x).await + } + async fn roundtrip_flag4(&mut self, x: Flag4) -> Flag4 { + Host::roundtrip_flag4(*self, x).await + } + async fn roundtrip_flag8(&mut self, x: Flag8) -> Flag8 { + Host::roundtrip_flag8(*self, x).await + } + async fn roundtrip_flag16(&mut self, x: Flag16) -> Flag16 { + Host::roundtrip_flag16(*self, x).await + } + async fn roundtrip_flag32(&mut self, x: Flag32) -> Flag32 { + Host::roundtrip_flag32(*self, x).await + } + async fn roundtrip_flag64(&mut self, x: Flag64) -> Flag64 { + Host::roundtrip_flag64(*self, x).await + } + } + } + } +} +pub mod exports { + pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod flegs { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + wasmtime::component::flags!( + Flag1 { #[component(name = "b0")] const B0; } + ); + const _: () = { + assert!( + 1 == < Flag1 as wasmtime::component::ComponentType >::SIZE32 + ); + assert!( + 1 == < Flag1 as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + wasmtime::component::flags!( + Flag2 { #[component(name = "b0")] const B0; #[component(name = "b1")] + const B1; } + ); + const _: () = { + assert!( + 1 == < Flag2 as wasmtime::component::ComponentType >::SIZE32 + ); + assert!( + 1 == < Flag2 as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + wasmtime::component::flags!( + Flag4 { #[component(name = "b0")] const B0; #[component(name = "b1")] + const B1; #[component(name = "b2")] const B2; #[component(name = + "b3")] const B3; } + ); + const _: () = { + assert!( + 1 == < Flag4 as wasmtime::component::ComponentType >::SIZE32 + ); + assert!( + 1 == < Flag4 as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + wasmtime::component::flags!( + Flag8 { #[component(name = "b0")] const B0; #[component(name = "b1")] + const B1; #[component(name = "b2")] const B2; #[component(name = + "b3")] const B3; #[component(name = "b4")] const B4; #[component(name + = "b5")] const B5; #[component(name = "b6")] const B6; + #[component(name = "b7")] const B7; } + ); + const _: () = { + assert!( + 1 == < Flag8 as wasmtime::component::ComponentType >::SIZE32 + ); + assert!( + 1 == < Flag8 as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + wasmtime::component::flags!( + Flag16 { #[component(name = "b0")] const B0; #[component(name = + "b1")] const B1; #[component(name = "b2")] const B2; #[component(name + = "b3")] const B3; #[component(name = "b4")] const B4; + #[component(name = "b5")] const B5; #[component(name = "b6")] const + B6; #[component(name = "b7")] const B7; #[component(name = "b8")] + const B8; #[component(name = "b9")] const B9; #[component(name = + "b10")] const B10; #[component(name = "b11")] const B11; + #[component(name = "b12")] const B12; #[component(name = "b13")] + const B13; #[component(name = "b14")] const B14; #[component(name = + "b15")] const B15; } + ); + const _: () = { + assert!( + 2 == < Flag16 as wasmtime::component::ComponentType >::SIZE32 + ); + assert!( + 2 == < Flag16 as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + wasmtime::component::flags!( + Flag32 { #[component(name = "b0")] const B0; #[component(name = + "b1")] const B1; #[component(name = "b2")] const B2; #[component(name + = "b3")] const B3; #[component(name = "b4")] const B4; + #[component(name = "b5")] const B5; #[component(name = "b6")] const + B6; #[component(name = "b7")] const B7; #[component(name = "b8")] + const B8; #[component(name = "b9")] const B9; #[component(name = + "b10")] const B10; #[component(name = "b11")] const B11; + #[component(name = "b12")] const B12; #[component(name = "b13")] + const B13; #[component(name = "b14")] const B14; #[component(name = + "b15")] const B15; #[component(name = "b16")] const B16; + #[component(name = "b17")] const B17; #[component(name = "b18")] + const B18; #[component(name = "b19")] const B19; #[component(name = + "b20")] const B20; #[component(name = "b21")] const B21; + #[component(name = "b22")] const B22; #[component(name = "b23")] + const B23; #[component(name = "b24")] const B24; #[component(name = + "b25")] const B25; #[component(name = "b26")] const B26; + #[component(name = "b27")] const B27; #[component(name = "b28")] + const B28; #[component(name = "b29")] const B29; #[component(name = + "b30")] const B30; #[component(name = "b31")] const B31; } + ); + const _: () = { + assert!( + 4 == < Flag32 as wasmtime::component::ComponentType >::SIZE32 + ); + assert!( + 4 == < Flag32 as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + wasmtime::component::flags!( + Flag64 { #[component(name = "b0")] const B0; #[component(name = + "b1")] const B1; #[component(name = "b2")] const B2; #[component(name + = "b3")] const B3; #[component(name = "b4")] const B4; + #[component(name = "b5")] const B5; #[component(name = "b6")] const + B6; #[component(name = "b7")] const B7; #[component(name = "b8")] + const B8; #[component(name = "b9")] const B9; #[component(name = + "b10")] const B10; #[component(name = "b11")] const B11; + #[component(name = "b12")] const B12; #[component(name = "b13")] + const B13; #[component(name = "b14")] const B14; #[component(name = + "b15")] const B15; #[component(name = "b16")] const B16; + #[component(name = "b17")] const B17; #[component(name = "b18")] + const B18; #[component(name = "b19")] const B19; #[component(name = + "b20")] const B20; #[component(name = "b21")] const B21; + #[component(name = "b22")] const B22; #[component(name = "b23")] + const B23; #[component(name = "b24")] const B24; #[component(name = + "b25")] const B25; #[component(name = "b26")] const B26; + #[component(name = "b27")] const B27; #[component(name = "b28")] + const B28; #[component(name = "b29")] const B29; #[component(name = + "b30")] const B30; #[component(name = "b31")] const B31; + #[component(name = "b32")] const B32; #[component(name = "b33")] + const B33; #[component(name = "b34")] const B34; #[component(name = + "b35")] const B35; #[component(name = "b36")] const B36; + #[component(name = "b37")] const B37; #[component(name = "b38")] + const B38; #[component(name = "b39")] const B39; #[component(name = + "b40")] const B40; #[component(name = "b41")] const B41; + #[component(name = "b42")] const B42; #[component(name = "b43")] + const B43; #[component(name = "b44")] const B44; #[component(name = + "b45")] const B45; #[component(name = "b46")] const B46; + #[component(name = "b47")] const B47; #[component(name = "b48")] + const B48; #[component(name = "b49")] const B49; #[component(name = + "b50")] const B50; #[component(name = "b51")] const B51; + #[component(name = "b52")] const B52; #[component(name = "b53")] + const B53; #[component(name = "b54")] const B54; #[component(name = + "b55")] const B55; #[component(name = "b56")] const B56; + #[component(name = "b57")] const B57; #[component(name = "b58")] + const B58; #[component(name = "b59")] const B59; #[component(name = + "b60")] const B60; #[component(name = "b61")] const B61; + #[component(name = "b62")] const B62; #[component(name = "b63")] + const B63; } + ); + const _: () = { + assert!( + 8 == < Flag64 as wasmtime::component::ComponentType >::SIZE32 + ); + assert!( + 4 == < Flag64 as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + pub struct Guest { + roundtrip_flag1: wasmtime::component::Func, + roundtrip_flag2: wasmtime::component::Func, + roundtrip_flag4: wasmtime::component::Func, + roundtrip_flag8: wasmtime::component::Func, + roundtrip_flag16: wasmtime::component::Func, + roundtrip_flag32: wasmtime::component::Func, + roundtrip_flag64: wasmtime::component::Func, + } + #[derive(Clone)] + pub struct GuestIndices { + roundtrip_flag1: wasmtime::component::ComponentExportIndex, + roundtrip_flag2: wasmtime::component::ComponentExportIndex, + roundtrip_flag4: wasmtime::component::ComponentExportIndex, + roundtrip_flag8: wasmtime::component::ComponentExportIndex, + roundtrip_flag16: wasmtime::component::ComponentExportIndex, + roundtrip_flag32: wasmtime::component::ComponentExportIndex, + roundtrip_flag64: wasmtime::component::ComponentExportIndex, + } + impl GuestIndices { + /// Constructor for [`GuestIndices`] which takes a + /// [`Component`](wasmtime::component::Component) as input and can be executed + /// before instantiation. + /// + /// This constructor can be used to front-load string lookups to find exports + /// within a component. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let (_, instance) = component + .export_index(None, "foo:foo/flegs") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/flegs`" + ) + })?; + Self::_new(|name| { + component.export_index(Some(&instance), name).map(|p| p.1) + }) + } + /// This constructor is similar to [`GuestIndices::new`] except that it + /// performs string lookups after instantiation time. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let instance_export = instance + .get_export(&mut store, None, "foo:foo/flegs") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/flegs`" + ) + })?; + Self::_new(|name| { + instance.get_export(&mut store, Some(&instance_export), name) + }) + } + fn _new( + mut lookup: impl FnMut( + &str, + ) -> Option, + ) -> wasmtime::Result { + let mut lookup = move |name| { + lookup(name) + .ok_or_else(|| { + anyhow::anyhow!( + "instance export `foo:foo/flegs` does \ + not have export `{name}`" + ) + }) + }; + let _ = &mut lookup; + let roundtrip_flag1 = lookup("roundtrip-flag1")?; + let roundtrip_flag2 = lookup("roundtrip-flag2")?; + let roundtrip_flag4 = lookup("roundtrip-flag4")?; + let roundtrip_flag8 = lookup("roundtrip-flag8")?; + let roundtrip_flag16 = lookup("roundtrip-flag16")?; + let roundtrip_flag32 = lookup("roundtrip-flag32")?; + let roundtrip_flag64 = lookup("roundtrip-flag64")?; + Ok(GuestIndices { + roundtrip_flag1, + roundtrip_flag2, + roundtrip_flag4, + roundtrip_flag8, + roundtrip_flag16, + roundtrip_flag32, + roundtrip_flag64, + }) + } + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let mut store = store.as_context_mut(); + let _ = &mut store; + let _instance = instance; + let roundtrip_flag1 = *_instance + .get_typed_func::< + (Flag1,), + (Flag1,), + >(&mut store, &self.roundtrip_flag1)? + .func(); + let roundtrip_flag2 = *_instance + .get_typed_func::< + (Flag2,), + (Flag2,), + >(&mut store, &self.roundtrip_flag2)? + .func(); + let roundtrip_flag4 = *_instance + .get_typed_func::< + (Flag4,), + (Flag4,), + >(&mut store, &self.roundtrip_flag4)? + .func(); + let roundtrip_flag8 = *_instance + .get_typed_func::< + (Flag8,), + (Flag8,), + >(&mut store, &self.roundtrip_flag8)? + .func(); + let roundtrip_flag16 = *_instance + .get_typed_func::< + (Flag16,), + (Flag16,), + >(&mut store, &self.roundtrip_flag16)? + .func(); + let roundtrip_flag32 = *_instance + .get_typed_func::< + (Flag32,), + (Flag32,), + >(&mut store, &self.roundtrip_flag32)? + .func(); + let roundtrip_flag64 = *_instance + .get_typed_func::< + (Flag64,), + (Flag64,), + >(&mut store, &self.roundtrip_flag64)? + .func(); + Ok(Guest { + roundtrip_flag1, + roundtrip_flag2, + roundtrip_flag4, + roundtrip_flag8, + roundtrip_flag16, + roundtrip_flag32, + roundtrip_flag64, + }) + } + } + impl Guest { + pub async fn call_roundtrip_flag1( + &self, + mut store: S, + arg0: Flag1, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/flegs", function = "roundtrip-flag1", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (Flag1,), + (Flag1,), + >::new_unchecked(self.roundtrip_flag1) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_roundtrip_flag2( + &self, + mut store: S, + arg0: Flag2, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/flegs", function = "roundtrip-flag2", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (Flag2,), + (Flag2,), + >::new_unchecked(self.roundtrip_flag2) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_roundtrip_flag4( + &self, + mut store: S, + arg0: Flag4, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/flegs", function = "roundtrip-flag4", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (Flag4,), + (Flag4,), + >::new_unchecked(self.roundtrip_flag4) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_roundtrip_flag8( + &self, + mut store: S, + arg0: Flag8, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/flegs", function = "roundtrip-flag8", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (Flag8,), + (Flag8,), + >::new_unchecked(self.roundtrip_flag8) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_roundtrip_flag16( + &self, + mut store: S, + arg0: Flag16, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/flegs", function = "roundtrip-flag16", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (Flag16,), + (Flag16,), + >::new_unchecked(self.roundtrip_flag16) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_roundtrip_flag32( + &self, + mut store: S, + arg0: Flag32, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/flegs", function = "roundtrip-flag32", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (Flag32,), + (Flag32,), + >::new_unchecked(self.roundtrip_flag32) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_roundtrip_flag64( + &self, + mut store: S, + arg0: Flag64, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/flegs", function = "roundtrip-flag64", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (Flag64,), + (Flag64,), + >::new_unchecked(self.roundtrip_flag64) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + } + } + } + } +} diff --git a/crates/component-macro/tests/expanded/floats_tracing_async.rs b/crates/component-macro/tests/expanded/floats_tracing_async.rs new file mode 100644 index 000000000000..6717ef2f583d --- /dev/null +++ b/crates/component-macro/tests/expanded/floats_tracing_async.rs @@ -0,0 +1,594 @@ +/// Auto-generated bindings for a pre-instantiated version of a +/// component which implements the world `the-world`. +/// +/// This structure is created through [`TheWorldPre::new`] which +/// takes a [`InstancePre`](wasmtime::component::InstancePre) that +/// has been created through a [`Linker`](wasmtime::component::Linker). +/// +/// For more information see [`TheWorld`] as well. +pub struct TheWorldPre { + instance_pre: wasmtime::component::InstancePre, + indices: TheWorldIndices, +} +impl Clone for TheWorldPre { + fn clone(&self) -> Self { + Self { + instance_pre: self.instance_pre.clone(), + indices: self.indices.clone(), + } + } +} +impl<_T> TheWorldPre<_T> { + /// Creates a new copy of `TheWorldPre` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component behind `instance_pre` + /// does not have the required exports. + pub fn new( + instance_pre: wasmtime::component::InstancePre<_T>, + ) -> wasmtime::Result { + let indices = TheWorldIndices::new(instance_pre.component())?; + Ok(Self { instance_pre, indices }) + } + pub fn engine(&self) -> &wasmtime::Engine { + self.instance_pre.engine() + } + pub fn instance_pre(&self) -> &wasmtime::component::InstancePre<_T> { + &self.instance_pre + } + /// Instantiates a new instance of [`TheWorld`] within the + /// `store` provided. + /// + /// This function will use `self` as the pre-instantiated + /// instance to perform instantiation. Afterwards the preloaded + /// indices in `self` are used to lookup all exports on the + /// resulting instance. + pub async fn instantiate_async( + &self, + mut store: impl wasmtime::AsContextMut, + ) -> wasmtime::Result + where + _T: Send, + { + let mut store = store.as_context_mut(); + let instance = self.instance_pre.instantiate_async(&mut store).await?; + self.indices.load(&mut store, &instance) + } +} +/// Auto-generated bindings for index of the exports of +/// `the-world`. +/// +/// This is an implementation detail of [`TheWorldPre`] and can +/// be constructed if needed as well. +/// +/// For more information see [`TheWorld`] as well. +#[derive(Clone)] +pub struct TheWorldIndices { + interface0: exports::foo::foo::floats::GuestIndices, +} +/// Auto-generated bindings for an instance a component which +/// implements the world `the-world`. +/// +/// This structure can be created through a number of means +/// depending on your requirements and what you have on hand: +/// +/// * The most convenient way is to use +/// [`TheWorld::instantiate_async`] which only needs a +/// [`Store`], [`Component`], and [`Linker`]. +/// +/// * Alternatively you can create a [`TheWorldPre`] ahead of +/// time with a [`Component`] to front-load string lookups +/// of exports once instead of per-instantiation. This +/// method then uses [`TheWorldPre::instantiate_async`] to +/// create a [`TheWorld`]. +/// +/// * If you've instantiated the instance yourself already +/// then you can use [`TheWorld::new`]. +/// +/// * You can also access the guts of instantiation through +/// [`TheWorldIndices::new_instance`] followed +/// by [`TheWorldIndices::load`] to crate an instance of this +/// type. +/// +/// These methods are all equivalent to one another and move +/// around the tradeoff of what work is performed when. +/// +/// [`Store`]: wasmtime::Store +/// [`Component`]: wasmtime::component::Component +/// [`Linker`]: wasmtime::component::Linker +pub struct TheWorld { + interface0: exports::foo::foo::floats::Guest, +} +const _: () = { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + impl TheWorldIndices { + /// Creates a new copy of `TheWorldIndices` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component does not have the + /// required exports. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let _component = component; + let interface0 = exports::foo::foo::floats::GuestIndices::new(_component)?; + Ok(TheWorldIndices { interface0 }) + } + /// Creates a new instance of [`TheWorldIndices`] from an + /// instantiated component. + /// + /// This method of creating a [`TheWorld`] will perform string + /// lookups for all exports when this method is called. This + /// will only succeed if the provided instance matches the + /// requirements of [`TheWorld`]. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = exports::foo::foo::floats::GuestIndices::new_instance( + &mut store, + _instance, + )?; + Ok(TheWorldIndices { interface0 }) + } + /// Uses the indices stored in `self` to load an instance + /// of [`TheWorld`] from the instance provided. + /// + /// Note that at this time this method will additionally + /// perform type-checks of all exports. + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = self.interface0.load(&mut store, &_instance)?; + Ok(TheWorld { interface0 }) + } + } + impl TheWorld { + /// Convenience wrapper around [`TheWorldPre::new`] and + /// [`TheWorldPre::instantiate_async`]. + pub async fn instantiate_async<_T>( + mut store: impl wasmtime::AsContextMut, + component: &wasmtime::component::Component, + linker: &wasmtime::component::Linker<_T>, + ) -> wasmtime::Result + where + _T: Send, + { + let pre = linker.instantiate_pre(component)?; + TheWorldPre::new(pre)?.instantiate_async(store).await + } + /// Convenience wrapper around [`TheWorldIndices::new_instance`] and + /// [`TheWorldIndices::load`]. + pub fn new( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let indices = TheWorldIndices::new_instance(&mut store, instance)?; + indices.load(store, instance) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + T: Send, + U: foo::foo::floats::Host + Send, + { + foo::foo::floats::add_to_linker(linker, get)?; + Ok(()) + } + pub fn foo_foo_floats(&self) -> &exports::foo::foo::floats::Guest { + &self.interface0 + } + } +}; +pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod floats { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send { + async fn float32_param(&mut self, x: f32) -> (); + async fn float64_param(&mut self, x: f64) -> (); + async fn float32_result(&mut self) -> f32; + async fn float64_result(&mut self) -> f64; + } + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("foo:foo/floats")?; + inst.func_wrap_async( + "float32-param", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (f32,)| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "floats", function = "float32-param", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::float32_param(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "float64-param", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (f64,)| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "floats", function = "float64-param", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::float64_param(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "float32-result", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "floats", function = "float32-result", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::float32_result(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "float64-result", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "floats", function = "float64-result", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::float64_result(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn float32_param(&mut self, x: f32) -> () { + Host::float32_param(*self, x).await + } + async fn float64_param(&mut self, x: f64) -> () { + Host::float64_param(*self, x).await + } + async fn float32_result(&mut self) -> f32 { + Host::float32_result(*self).await + } + async fn float64_result(&mut self) -> f64 { + Host::float64_result(*self).await + } + } + } + } +} +pub mod exports { + pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod floats { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + pub struct Guest { + float32_param: wasmtime::component::Func, + float64_param: wasmtime::component::Func, + float32_result: wasmtime::component::Func, + float64_result: wasmtime::component::Func, + } + #[derive(Clone)] + pub struct GuestIndices { + float32_param: wasmtime::component::ComponentExportIndex, + float64_param: wasmtime::component::ComponentExportIndex, + float32_result: wasmtime::component::ComponentExportIndex, + float64_result: wasmtime::component::ComponentExportIndex, + } + impl GuestIndices { + /// Constructor for [`GuestIndices`] which takes a + /// [`Component`](wasmtime::component::Component) as input and can be executed + /// before instantiation. + /// + /// This constructor can be used to front-load string lookups to find exports + /// within a component. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let (_, instance) = component + .export_index(None, "foo:foo/floats") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/floats`" + ) + })?; + Self::_new(|name| { + component.export_index(Some(&instance), name).map(|p| p.1) + }) + } + /// This constructor is similar to [`GuestIndices::new`] except that it + /// performs string lookups after instantiation time. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let instance_export = instance + .get_export(&mut store, None, "foo:foo/floats") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/floats`" + ) + })?; + Self::_new(|name| { + instance.get_export(&mut store, Some(&instance_export), name) + }) + } + fn _new( + mut lookup: impl FnMut( + &str, + ) -> Option, + ) -> wasmtime::Result { + let mut lookup = move |name| { + lookup(name) + .ok_or_else(|| { + anyhow::anyhow!( + "instance export `foo:foo/floats` does \ + not have export `{name}`" + ) + }) + }; + let _ = &mut lookup; + let float32_param = lookup("float32-param")?; + let float64_param = lookup("float64-param")?; + let float32_result = lookup("float32-result")?; + let float64_result = lookup("float64-result")?; + Ok(GuestIndices { + float32_param, + float64_param, + float32_result, + float64_result, + }) + } + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let mut store = store.as_context_mut(); + let _ = &mut store; + let _instance = instance; + let float32_param = *_instance + .get_typed_func::< + (f32,), + (), + >(&mut store, &self.float32_param)? + .func(); + let float64_param = *_instance + .get_typed_func::< + (f64,), + (), + >(&mut store, &self.float64_param)? + .func(); + let float32_result = *_instance + .get_typed_func::< + (), + (f32,), + >(&mut store, &self.float32_result)? + .func(); + let float64_result = *_instance + .get_typed_func::< + (), + (f64,), + >(&mut store, &self.float64_result)? + .func(); + Ok(Guest { + float32_param, + float64_param, + float32_result, + float64_result, + }) + } + } + impl Guest { + pub async fn call_float32_param( + &self, + mut store: S, + arg0: f32, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/floats", function = "float32-param", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (f32,), + (), + >::new_unchecked(self.float32_param) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_float64_param( + &self, + mut store: S, + arg0: f64, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/floats", function = "float64-param", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (f64,), + (), + >::new_unchecked(self.float64_param) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_float32_result( + &self, + mut store: S, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/floats", function = "float32-result", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (f32,), + >::new_unchecked(self.float32_result) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_float64_result( + &self, + mut store: S, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/floats", function = "float64-result", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (f64,), + >::new_unchecked(self.float64_result) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + } + } + } + } +} diff --git a/crates/component-macro/tests/expanded/function-new_tracing_async.rs b/crates/component-macro/tests/expanded/function-new_tracing_async.rs new file mode 100644 index 000000000000..da3f9d8c9596 --- /dev/null +++ b/crates/component-macro/tests/expanded/function-new_tracing_async.rs @@ -0,0 +1,199 @@ +/// Auto-generated bindings for a pre-instantiated version of a +/// component which implements the world `foo`. +/// +/// This structure is created through [`FooPre::new`] which +/// takes a [`InstancePre`](wasmtime::component::InstancePre) that +/// has been created through a [`Linker`](wasmtime::component::Linker). +/// +/// For more information see [`Foo`] as well. +pub struct FooPre { + instance_pre: wasmtime::component::InstancePre, + indices: FooIndices, +} +impl Clone for FooPre { + fn clone(&self) -> Self { + Self { + instance_pre: self.instance_pre.clone(), + indices: self.indices.clone(), + } + } +} +impl<_T> FooPre<_T> { + /// Creates a new copy of `FooPre` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component behind `instance_pre` + /// does not have the required exports. + pub fn new( + instance_pre: wasmtime::component::InstancePre<_T>, + ) -> wasmtime::Result { + let indices = FooIndices::new(instance_pre.component())?; + Ok(Self { instance_pre, indices }) + } + pub fn engine(&self) -> &wasmtime::Engine { + self.instance_pre.engine() + } + pub fn instance_pre(&self) -> &wasmtime::component::InstancePre<_T> { + &self.instance_pre + } + /// Instantiates a new instance of [`Foo`] within the + /// `store` provided. + /// + /// This function will use `self` as the pre-instantiated + /// instance to perform instantiation. Afterwards the preloaded + /// indices in `self` are used to lookup all exports on the + /// resulting instance. + pub async fn instantiate_async( + &self, + mut store: impl wasmtime::AsContextMut, + ) -> wasmtime::Result + where + _T: Send, + { + let mut store = store.as_context_mut(); + let instance = self.instance_pre.instantiate_async(&mut store).await?; + self.indices.load(&mut store, &instance) + } +} +/// Auto-generated bindings for index of the exports of +/// `foo`. +/// +/// This is an implementation detail of [`FooPre`] and can +/// be constructed if needed as well. +/// +/// For more information see [`Foo`] as well. +#[derive(Clone)] +pub struct FooIndices { + new: wasmtime::component::ComponentExportIndex, +} +/// Auto-generated bindings for an instance a component which +/// implements the world `foo`. +/// +/// This structure can be created through a number of means +/// depending on your requirements and what you have on hand: +/// +/// * The most convenient way is to use +/// [`Foo::instantiate_async`] which only needs a +/// [`Store`], [`Component`], and [`Linker`]. +/// +/// * Alternatively you can create a [`FooPre`] ahead of +/// time with a [`Component`] to front-load string lookups +/// of exports once instead of per-instantiation. This +/// method then uses [`FooPre::instantiate_async`] to +/// create a [`Foo`]. +/// +/// * If you've instantiated the instance yourself already +/// then you can use [`Foo::new`]. +/// +/// * You can also access the guts of instantiation through +/// [`FooIndices::new_instance`] followed +/// by [`FooIndices::load`] to crate an instance of this +/// type. +/// +/// These methods are all equivalent to one another and move +/// around the tradeoff of what work is performed when. +/// +/// [`Store`]: wasmtime::Store +/// [`Component`]: wasmtime::component::Component +/// [`Linker`]: wasmtime::component::Linker +pub struct Foo { + new: wasmtime::component::Func, +} +const _: () = { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + impl FooIndices { + /// Creates a new copy of `FooIndices` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component does not have the + /// required exports. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let _component = component; + let new = _component + .export_index(None, "new") + .ok_or_else(|| anyhow::anyhow!("no function export `new` found"))? + .1; + Ok(FooIndices { new }) + } + /// Creates a new instance of [`FooIndices`] from an + /// instantiated component. + /// + /// This method of creating a [`Foo`] will perform string + /// lookups for all exports when this method is called. This + /// will only succeed if the provided instance matches the + /// requirements of [`Foo`]. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let new = _instance + .get_export(&mut store, None, "new") + .ok_or_else(|| anyhow::anyhow!("no function export `new` found"))?; + Ok(FooIndices { new }) + } + /// Uses the indices stored in `self` to load an instance + /// of [`Foo`] from the instance provided. + /// + /// Note that at this time this method will additionally + /// perform type-checks of all exports. + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let new = *_instance.get_typed_func::<(), ()>(&mut store, &self.new)?.func(); + Ok(Foo { new }) + } + } + impl Foo { + /// Convenience wrapper around [`FooPre::new`] and + /// [`FooPre::instantiate_async`]. + pub async fn instantiate_async<_T>( + mut store: impl wasmtime::AsContextMut, + component: &wasmtime::component::Component, + linker: &wasmtime::component::Linker<_T>, + ) -> wasmtime::Result + where + _T: Send, + { + let pre = linker.instantiate_pre(component)?; + FooPre::new(pre)?.instantiate_async(store).await + } + /// Convenience wrapper around [`FooIndices::new_instance`] and + /// [`FooIndices::load`]. + pub fn new( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let indices = FooIndices::new_instance(&mut store, instance)?; + indices.load(store, instance) + } + pub async fn call_new( + &self, + mut store: S, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = "default", function + = "new", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::<(), ()>::new_unchecked(self.new) + }; + let () = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee.post_return_async(store.as_context_mut()).instrument(span).await?; + Ok(()) + } + } +}; diff --git a/crates/component-macro/tests/expanded/integers_tracing_async.rs b/crates/component-macro/tests/expanded/integers_tracing_async.rs new file mode 100644 index 000000000000..b14b6f2d962c --- /dev/null +++ b/crates/component-macro/tests/expanded/integers_tracing_async.rs @@ -0,0 +1,1555 @@ +/// Auto-generated bindings for a pre-instantiated version of a +/// component which implements the world `the-world`. +/// +/// This structure is created through [`TheWorldPre::new`] which +/// takes a [`InstancePre`](wasmtime::component::InstancePre) that +/// has been created through a [`Linker`](wasmtime::component::Linker). +/// +/// For more information see [`TheWorld`] as well. +pub struct TheWorldPre { + instance_pre: wasmtime::component::InstancePre, + indices: TheWorldIndices, +} +impl Clone for TheWorldPre { + fn clone(&self) -> Self { + Self { + instance_pre: self.instance_pre.clone(), + indices: self.indices.clone(), + } + } +} +impl<_T> TheWorldPre<_T> { + /// Creates a new copy of `TheWorldPre` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component behind `instance_pre` + /// does not have the required exports. + pub fn new( + instance_pre: wasmtime::component::InstancePre<_T>, + ) -> wasmtime::Result { + let indices = TheWorldIndices::new(instance_pre.component())?; + Ok(Self { instance_pre, indices }) + } + pub fn engine(&self) -> &wasmtime::Engine { + self.instance_pre.engine() + } + pub fn instance_pre(&self) -> &wasmtime::component::InstancePre<_T> { + &self.instance_pre + } + /// Instantiates a new instance of [`TheWorld`] within the + /// `store` provided. + /// + /// This function will use `self` as the pre-instantiated + /// instance to perform instantiation. Afterwards the preloaded + /// indices in `self` are used to lookup all exports on the + /// resulting instance. + pub async fn instantiate_async( + &self, + mut store: impl wasmtime::AsContextMut, + ) -> wasmtime::Result + where + _T: Send, + { + let mut store = store.as_context_mut(); + let instance = self.instance_pre.instantiate_async(&mut store).await?; + self.indices.load(&mut store, &instance) + } +} +/// Auto-generated bindings for index of the exports of +/// `the-world`. +/// +/// This is an implementation detail of [`TheWorldPre`] and can +/// be constructed if needed as well. +/// +/// For more information see [`TheWorld`] as well. +#[derive(Clone)] +pub struct TheWorldIndices { + interface0: exports::foo::foo::integers::GuestIndices, +} +/// Auto-generated bindings for an instance a component which +/// implements the world `the-world`. +/// +/// This structure can be created through a number of means +/// depending on your requirements and what you have on hand: +/// +/// * The most convenient way is to use +/// [`TheWorld::instantiate_async`] which only needs a +/// [`Store`], [`Component`], and [`Linker`]. +/// +/// * Alternatively you can create a [`TheWorldPre`] ahead of +/// time with a [`Component`] to front-load string lookups +/// of exports once instead of per-instantiation. This +/// method then uses [`TheWorldPre::instantiate_async`] to +/// create a [`TheWorld`]. +/// +/// * If you've instantiated the instance yourself already +/// then you can use [`TheWorld::new`]. +/// +/// * You can also access the guts of instantiation through +/// [`TheWorldIndices::new_instance`] followed +/// by [`TheWorldIndices::load`] to crate an instance of this +/// type. +/// +/// These methods are all equivalent to one another and move +/// around the tradeoff of what work is performed when. +/// +/// [`Store`]: wasmtime::Store +/// [`Component`]: wasmtime::component::Component +/// [`Linker`]: wasmtime::component::Linker +pub struct TheWorld { + interface0: exports::foo::foo::integers::Guest, +} +const _: () = { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + impl TheWorldIndices { + /// Creates a new copy of `TheWorldIndices` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component does not have the + /// required exports. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let _component = component; + let interface0 = exports::foo::foo::integers::GuestIndices::new(_component)?; + Ok(TheWorldIndices { interface0 }) + } + /// Creates a new instance of [`TheWorldIndices`] from an + /// instantiated component. + /// + /// This method of creating a [`TheWorld`] will perform string + /// lookups for all exports when this method is called. This + /// will only succeed if the provided instance matches the + /// requirements of [`TheWorld`]. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = exports::foo::foo::integers::GuestIndices::new_instance( + &mut store, + _instance, + )?; + Ok(TheWorldIndices { interface0 }) + } + /// Uses the indices stored in `self` to load an instance + /// of [`TheWorld`] from the instance provided. + /// + /// Note that at this time this method will additionally + /// perform type-checks of all exports. + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = self.interface0.load(&mut store, &_instance)?; + Ok(TheWorld { interface0 }) + } + } + impl TheWorld { + /// Convenience wrapper around [`TheWorldPre::new`] and + /// [`TheWorldPre::instantiate_async`]. + pub async fn instantiate_async<_T>( + mut store: impl wasmtime::AsContextMut, + component: &wasmtime::component::Component, + linker: &wasmtime::component::Linker<_T>, + ) -> wasmtime::Result + where + _T: Send, + { + let pre = linker.instantiate_pre(component)?; + TheWorldPre::new(pre)?.instantiate_async(store).await + } + /// Convenience wrapper around [`TheWorldIndices::new_instance`] and + /// [`TheWorldIndices::load`]. + pub fn new( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let indices = TheWorldIndices::new_instance(&mut store, instance)?; + indices.load(store, instance) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + T: Send, + U: foo::foo::integers::Host + Send, + { + foo::foo::integers::add_to_linker(linker, get)?; + Ok(()) + } + pub fn foo_foo_integers(&self) -> &exports::foo::foo::integers::Guest { + &self.interface0 + } + } +}; +pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod integers { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send { + async fn a1(&mut self, x: u8) -> (); + async fn a2(&mut self, x: i8) -> (); + async fn a3(&mut self, x: u16) -> (); + async fn a4(&mut self, x: i16) -> (); + async fn a5(&mut self, x: u32) -> (); + async fn a6(&mut self, x: i32) -> (); + async fn a7(&mut self, x: u64) -> (); + async fn a8(&mut self, x: i64) -> (); + async fn a9( + &mut self, + p1: u8, + p2: i8, + p3: u16, + p4: i16, + p5: u32, + p6: i32, + p7: u64, + p8: i64, + ) -> (); + async fn r1(&mut self) -> u8; + async fn r2(&mut self) -> i8; + async fn r3(&mut self) -> u16; + async fn r4(&mut self) -> i16; + async fn r5(&mut self) -> u32; + async fn r6(&mut self) -> i32; + async fn r7(&mut self) -> u64; + async fn r8(&mut self) -> i64; + async fn pair_ret(&mut self) -> (i64, u8); + } + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("foo:foo/integers")?; + inst.func_wrap_async( + "a1", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (u8,)| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "integers", function = "a1", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::a1(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "a2", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (i8,)| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "integers", function = "a2", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::a2(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "a3", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (u16,)| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "integers", function = "a3", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::a3(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "a4", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (i16,)| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "integers", function = "a4", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::a4(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "a5", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (u32,)| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "integers", function = "a5", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::a5(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "a6", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (i32,)| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "integers", function = "a6", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::a6(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "a7", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (u64,)| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "integers", function = "a7", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::a7(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "a8", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (i64,)| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "integers", function = "a8", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::a8(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "a9", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + ( + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + arg7, + ): (u8, i8, u16, i16, u32, i32, u64, i64)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "integers", function = "a9", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, p1 = tracing::field::debug(& arg0), + p2 = tracing::field::debug(& arg1), p3 = + tracing::field::debug(& arg2), p4 = tracing::field::debug(& + arg3), p5 = tracing::field::debug(& arg4), p6 = + tracing::field::debug(& arg5), p7 = tracing::field::debug(& + arg6), p8 = tracing::field::debug(& arg7), "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::a9( + host, + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + arg7, + ) + .await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "r1", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "integers", function = "r1", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::r1(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "r2", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "integers", function = "r2", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::r2(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "r3", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "integers", function = "r3", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::r3(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "r4", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "integers", function = "r4", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::r4(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "r5", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "integers", function = "r5", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::r5(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "r6", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "integers", function = "r6", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::r6(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "r7", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "integers", function = "r7", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::r7(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "r8", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "integers", function = "r8", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::r8(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "pair-ret", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "integers", function = "pair-ret", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::pair_ret(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn a1(&mut self, x: u8) -> () { + Host::a1(*self, x).await + } + async fn a2(&mut self, x: i8) -> () { + Host::a2(*self, x).await + } + async fn a3(&mut self, x: u16) -> () { + Host::a3(*self, x).await + } + async fn a4(&mut self, x: i16) -> () { + Host::a4(*self, x).await + } + async fn a5(&mut self, x: u32) -> () { + Host::a5(*self, x).await + } + async fn a6(&mut self, x: i32) -> () { + Host::a6(*self, x).await + } + async fn a7(&mut self, x: u64) -> () { + Host::a7(*self, x).await + } + async fn a8(&mut self, x: i64) -> () { + Host::a8(*self, x).await + } + async fn a9( + &mut self, + p1: u8, + p2: i8, + p3: u16, + p4: i16, + p5: u32, + p6: i32, + p7: u64, + p8: i64, + ) -> () { + Host::a9(*self, p1, p2, p3, p4, p5, p6, p7, p8).await + } + async fn r1(&mut self) -> u8 { + Host::r1(*self).await + } + async fn r2(&mut self) -> i8 { + Host::r2(*self).await + } + async fn r3(&mut self) -> u16 { + Host::r3(*self).await + } + async fn r4(&mut self) -> i16 { + Host::r4(*self).await + } + async fn r5(&mut self) -> u32 { + Host::r5(*self).await + } + async fn r6(&mut self) -> i32 { + Host::r6(*self).await + } + async fn r7(&mut self) -> u64 { + Host::r7(*self).await + } + async fn r8(&mut self) -> i64 { + Host::r8(*self).await + } + async fn pair_ret(&mut self) -> (i64, u8) { + Host::pair_ret(*self).await + } + } + } + } +} +pub mod exports { + pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod integers { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + pub struct Guest { + a1: wasmtime::component::Func, + a2: wasmtime::component::Func, + a3: wasmtime::component::Func, + a4: wasmtime::component::Func, + a5: wasmtime::component::Func, + a6: wasmtime::component::Func, + a7: wasmtime::component::Func, + a8: wasmtime::component::Func, + a9: wasmtime::component::Func, + r1: wasmtime::component::Func, + r2: wasmtime::component::Func, + r3: wasmtime::component::Func, + r4: wasmtime::component::Func, + r5: wasmtime::component::Func, + r6: wasmtime::component::Func, + r7: wasmtime::component::Func, + r8: wasmtime::component::Func, + pair_ret: wasmtime::component::Func, + } + #[derive(Clone)] + pub struct GuestIndices { + a1: wasmtime::component::ComponentExportIndex, + a2: wasmtime::component::ComponentExportIndex, + a3: wasmtime::component::ComponentExportIndex, + a4: wasmtime::component::ComponentExportIndex, + a5: wasmtime::component::ComponentExportIndex, + a6: wasmtime::component::ComponentExportIndex, + a7: wasmtime::component::ComponentExportIndex, + a8: wasmtime::component::ComponentExportIndex, + a9: wasmtime::component::ComponentExportIndex, + r1: wasmtime::component::ComponentExportIndex, + r2: wasmtime::component::ComponentExportIndex, + r3: wasmtime::component::ComponentExportIndex, + r4: wasmtime::component::ComponentExportIndex, + r5: wasmtime::component::ComponentExportIndex, + r6: wasmtime::component::ComponentExportIndex, + r7: wasmtime::component::ComponentExportIndex, + r8: wasmtime::component::ComponentExportIndex, + pair_ret: wasmtime::component::ComponentExportIndex, + } + impl GuestIndices { + /// Constructor for [`GuestIndices`] which takes a + /// [`Component`](wasmtime::component::Component) as input and can be executed + /// before instantiation. + /// + /// This constructor can be used to front-load string lookups to find exports + /// within a component. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let (_, instance) = component + .export_index(None, "foo:foo/integers") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/integers`" + ) + })?; + Self::_new(|name| { + component.export_index(Some(&instance), name).map(|p| p.1) + }) + } + /// This constructor is similar to [`GuestIndices::new`] except that it + /// performs string lookups after instantiation time. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let instance_export = instance + .get_export(&mut store, None, "foo:foo/integers") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/integers`" + ) + })?; + Self::_new(|name| { + instance.get_export(&mut store, Some(&instance_export), name) + }) + } + fn _new( + mut lookup: impl FnMut( + &str, + ) -> Option, + ) -> wasmtime::Result { + let mut lookup = move |name| { + lookup(name) + .ok_or_else(|| { + anyhow::anyhow!( + "instance export `foo:foo/integers` does \ + not have export `{name}`" + ) + }) + }; + let _ = &mut lookup; + let a1 = lookup("a1")?; + let a2 = lookup("a2")?; + let a3 = lookup("a3")?; + let a4 = lookup("a4")?; + let a5 = lookup("a5")?; + let a6 = lookup("a6")?; + let a7 = lookup("a7")?; + let a8 = lookup("a8")?; + let a9 = lookup("a9")?; + let r1 = lookup("r1")?; + let r2 = lookup("r2")?; + let r3 = lookup("r3")?; + let r4 = lookup("r4")?; + let r5 = lookup("r5")?; + let r6 = lookup("r6")?; + let r7 = lookup("r7")?; + let r8 = lookup("r8")?; + let pair_ret = lookup("pair-ret")?; + Ok(GuestIndices { + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + r1, + r2, + r3, + r4, + r5, + r6, + r7, + r8, + pair_ret, + }) + } + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let mut store = store.as_context_mut(); + let _ = &mut store; + let _instance = instance; + let a1 = *_instance + .get_typed_func::<(u8,), ()>(&mut store, &self.a1)? + .func(); + let a2 = *_instance + .get_typed_func::<(i8,), ()>(&mut store, &self.a2)? + .func(); + let a3 = *_instance + .get_typed_func::<(u16,), ()>(&mut store, &self.a3)? + .func(); + let a4 = *_instance + .get_typed_func::<(i16,), ()>(&mut store, &self.a4)? + .func(); + let a5 = *_instance + .get_typed_func::<(u32,), ()>(&mut store, &self.a5)? + .func(); + let a6 = *_instance + .get_typed_func::<(i32,), ()>(&mut store, &self.a6)? + .func(); + let a7 = *_instance + .get_typed_func::<(u64,), ()>(&mut store, &self.a7)? + .func(); + let a8 = *_instance + .get_typed_func::<(i64,), ()>(&mut store, &self.a8)? + .func(); + let a9 = *_instance + .get_typed_func::< + (u8, i8, u16, i16, u32, i32, u64, i64), + (), + >(&mut store, &self.a9)? + .func(); + let r1 = *_instance + .get_typed_func::<(), (u8,)>(&mut store, &self.r1)? + .func(); + let r2 = *_instance + .get_typed_func::<(), (i8,)>(&mut store, &self.r2)? + .func(); + let r3 = *_instance + .get_typed_func::<(), (u16,)>(&mut store, &self.r3)? + .func(); + let r4 = *_instance + .get_typed_func::<(), (i16,)>(&mut store, &self.r4)? + .func(); + let r5 = *_instance + .get_typed_func::<(), (u32,)>(&mut store, &self.r5)? + .func(); + let r6 = *_instance + .get_typed_func::<(), (i32,)>(&mut store, &self.r6)? + .func(); + let r7 = *_instance + .get_typed_func::<(), (u64,)>(&mut store, &self.r7)? + .func(); + let r8 = *_instance + .get_typed_func::<(), (i64,)>(&mut store, &self.r8)? + .func(); + let pair_ret = *_instance + .get_typed_func::< + (), + ((i64, u8),), + >(&mut store, &self.pair_ret)? + .func(); + Ok(Guest { + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + r1, + r2, + r3, + r4, + r5, + r6, + r7, + r8, + pair_ret, + }) + } + } + impl Guest { + pub async fn call_a1( + &self, + mut store: S, + arg0: u8, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/integers", function = "a1", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (u8,), + (), + >::new_unchecked(self.a1) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_a2( + &self, + mut store: S, + arg0: i8, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/integers", function = "a2", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (i8,), + (), + >::new_unchecked(self.a2) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_a3( + &self, + mut store: S, + arg0: u16, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/integers", function = "a3", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (u16,), + (), + >::new_unchecked(self.a3) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_a4( + &self, + mut store: S, + arg0: i16, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/integers", function = "a4", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (i16,), + (), + >::new_unchecked(self.a4) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_a5( + &self, + mut store: S, + arg0: u32, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/integers", function = "a5", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (u32,), + (), + >::new_unchecked(self.a5) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_a6( + &self, + mut store: S, + arg0: i32, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/integers", function = "a6", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (i32,), + (), + >::new_unchecked(self.a6) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_a7( + &self, + mut store: S, + arg0: u64, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/integers", function = "a7", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (u64,), + (), + >::new_unchecked(self.a7) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_a8( + &self, + mut store: S, + arg0: i64, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/integers", function = "a8", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (i64,), + (), + >::new_unchecked(self.a8) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_a9( + &self, + mut store: S, + arg0: u8, + arg1: i8, + arg2: u16, + arg3: i16, + arg4: u32, + arg5: i32, + arg6: u64, + arg7: i64, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/integers", function = "a9", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (u8, i8, u16, i16, u32, i32, u64, i64), + (), + >::new_unchecked(self.a9) + }; + let () = callee + .call_async( + store.as_context_mut(), + (arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7), + ) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_r1( + &self, + mut store: S, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/integers", function = "r1", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (u8,), + >::new_unchecked(self.r1) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_r2( + &self, + mut store: S, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/integers", function = "r2", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (i8,), + >::new_unchecked(self.r2) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_r3( + &self, + mut store: S, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/integers", function = "r3", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (u16,), + >::new_unchecked(self.r3) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_r4( + &self, + mut store: S, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/integers", function = "r4", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (i16,), + >::new_unchecked(self.r4) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_r5( + &self, + mut store: S, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/integers", function = "r5", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (u32,), + >::new_unchecked(self.r5) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_r6( + &self, + mut store: S, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/integers", function = "r6", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (i32,), + >::new_unchecked(self.r6) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_r7( + &self, + mut store: S, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/integers", function = "r7", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (u64,), + >::new_unchecked(self.r7) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_r8( + &self, + mut store: S, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/integers", function = "r8", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (i64,), + >::new_unchecked(self.r8) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_pair_ret( + &self, + mut store: S, + ) -> wasmtime::Result<(i64, u8)> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/integers", function = "pair-ret", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + ((i64, u8),), + >::new_unchecked(self.pair_ret) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + } + } + } + } +} diff --git a/crates/component-macro/tests/expanded/lists_tracing_async.rs b/crates/component-macro/tests/expanded/lists_tracing_async.rs new file mode 100644 index 000000000000..4e69ec9d48bd --- /dev/null +++ b/crates/component-macro/tests/expanded/lists_tracing_async.rs @@ -0,0 +1,2980 @@ +/// Auto-generated bindings for a pre-instantiated version of a +/// component which implements the world `the-lists`. +/// +/// This structure is created through [`TheListsPre::new`] which +/// takes a [`InstancePre`](wasmtime::component::InstancePre) that +/// has been created through a [`Linker`](wasmtime::component::Linker). +/// +/// For more information see [`TheLists`] as well. +pub struct TheListsPre { + instance_pre: wasmtime::component::InstancePre, + indices: TheListsIndices, +} +impl Clone for TheListsPre { + fn clone(&self) -> Self { + Self { + instance_pre: self.instance_pre.clone(), + indices: self.indices.clone(), + } + } +} +impl<_T> TheListsPre<_T> { + /// Creates a new copy of `TheListsPre` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component behind `instance_pre` + /// does not have the required exports. + pub fn new( + instance_pre: wasmtime::component::InstancePre<_T>, + ) -> wasmtime::Result { + let indices = TheListsIndices::new(instance_pre.component())?; + Ok(Self { instance_pre, indices }) + } + pub fn engine(&self) -> &wasmtime::Engine { + self.instance_pre.engine() + } + pub fn instance_pre(&self) -> &wasmtime::component::InstancePre<_T> { + &self.instance_pre + } + /// Instantiates a new instance of [`TheLists`] within the + /// `store` provided. + /// + /// This function will use `self` as the pre-instantiated + /// instance to perform instantiation. Afterwards the preloaded + /// indices in `self` are used to lookup all exports on the + /// resulting instance. + pub async fn instantiate_async( + &self, + mut store: impl wasmtime::AsContextMut, + ) -> wasmtime::Result + where + _T: Send, + { + let mut store = store.as_context_mut(); + let instance = self.instance_pre.instantiate_async(&mut store).await?; + self.indices.load(&mut store, &instance) + } +} +/// Auto-generated bindings for index of the exports of +/// `the-lists`. +/// +/// This is an implementation detail of [`TheListsPre`] and can +/// be constructed if needed as well. +/// +/// For more information see [`TheLists`] as well. +#[derive(Clone)] +pub struct TheListsIndices { + interface0: exports::foo::foo::lists::GuestIndices, +} +/// Auto-generated bindings for an instance a component which +/// implements the world `the-lists`. +/// +/// This structure can be created through a number of means +/// depending on your requirements and what you have on hand: +/// +/// * The most convenient way is to use +/// [`TheLists::instantiate_async`] which only needs a +/// [`Store`], [`Component`], and [`Linker`]. +/// +/// * Alternatively you can create a [`TheListsPre`] ahead of +/// time with a [`Component`] to front-load string lookups +/// of exports once instead of per-instantiation. This +/// method then uses [`TheListsPre::instantiate_async`] to +/// create a [`TheLists`]. +/// +/// * If you've instantiated the instance yourself already +/// then you can use [`TheLists::new`]. +/// +/// * You can also access the guts of instantiation through +/// [`TheListsIndices::new_instance`] followed +/// by [`TheListsIndices::load`] to crate an instance of this +/// type. +/// +/// These methods are all equivalent to one another and move +/// around the tradeoff of what work is performed when. +/// +/// [`Store`]: wasmtime::Store +/// [`Component`]: wasmtime::component::Component +/// [`Linker`]: wasmtime::component::Linker +pub struct TheLists { + interface0: exports::foo::foo::lists::Guest, +} +const _: () = { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + impl TheListsIndices { + /// Creates a new copy of `TheListsIndices` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component does not have the + /// required exports. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let _component = component; + let interface0 = exports::foo::foo::lists::GuestIndices::new(_component)?; + Ok(TheListsIndices { interface0 }) + } + /// Creates a new instance of [`TheListsIndices`] from an + /// instantiated component. + /// + /// This method of creating a [`TheLists`] will perform string + /// lookups for all exports when this method is called. This + /// will only succeed if the provided instance matches the + /// requirements of [`TheLists`]. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = exports::foo::foo::lists::GuestIndices::new_instance( + &mut store, + _instance, + )?; + Ok(TheListsIndices { interface0 }) + } + /// Uses the indices stored in `self` to load an instance + /// of [`TheLists`] from the instance provided. + /// + /// Note that at this time this method will additionally + /// perform type-checks of all exports. + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = self.interface0.load(&mut store, &_instance)?; + Ok(TheLists { interface0 }) + } + } + impl TheLists { + /// Convenience wrapper around [`TheListsPre::new`] and + /// [`TheListsPre::instantiate_async`]. + pub async fn instantiate_async<_T>( + mut store: impl wasmtime::AsContextMut, + component: &wasmtime::component::Component, + linker: &wasmtime::component::Linker<_T>, + ) -> wasmtime::Result + where + _T: Send, + { + let pre = linker.instantiate_pre(component)?; + TheListsPre::new(pre)?.instantiate_async(store).await + } + /// Convenience wrapper around [`TheListsIndices::new_instance`] and + /// [`TheListsIndices::load`]. + pub fn new( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let indices = TheListsIndices::new_instance(&mut store, instance)?; + indices.load(store, instance) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + T: Send, + U: foo::foo::lists::Host + Send, + { + foo::foo::lists::add_to_linker(linker, get)?; + Ok(()) + } + pub fn foo_foo_lists(&self) -> &exports::foo::foo::lists::Guest { + &self.interface0 + } + } +}; +pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod lists { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(record)] + #[derive(Clone)] + pub struct OtherRecord { + #[component(name = "a1")] + pub a1: u32, + #[component(name = "a2")] + pub a2: u64, + #[component(name = "a3")] + pub a3: i32, + #[component(name = "a4")] + pub a4: i64, + #[component(name = "b")] + pub b: wasmtime::component::__internal::String, + #[component(name = "c")] + pub c: wasmtime::component::__internal::Vec, + } + impl core::fmt::Debug for OtherRecord { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("OtherRecord") + .field("a1", &self.a1) + .field("a2", &self.a2) + .field("a3", &self.a3) + .field("a4", &self.a4) + .field("b", &self.b) + .field("c", &self.c) + .finish() + } + } + const _: () = { + assert!( + 48 == < OtherRecord as wasmtime::component::ComponentType >::SIZE32 + ); + assert!( + 8 == < OtherRecord as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(record)] + #[derive(Clone)] + pub struct SomeRecord { + #[component(name = "x")] + pub x: wasmtime::component::__internal::String, + #[component(name = "y")] + pub y: OtherRecord, + #[component(name = "z")] + pub z: wasmtime::component::__internal::Vec, + #[component(name = "c1")] + pub c1: u32, + #[component(name = "c2")] + pub c2: u64, + #[component(name = "c3")] + pub c3: i32, + #[component(name = "c4")] + pub c4: i64, + } + impl core::fmt::Debug for SomeRecord { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("SomeRecord") + .field("x", &self.x) + .field("y", &self.y) + .field("z", &self.z) + .field("c1", &self.c1) + .field("c2", &self.c2) + .field("c3", &self.c3) + .field("c4", &self.c4) + .finish() + } + } + const _: () = { + assert!( + 96 == < SomeRecord as wasmtime::component::ComponentType >::SIZE32 + ); + assert!( + 8 == < SomeRecord as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(variant)] + #[derive(Clone)] + pub enum OtherVariant { + #[component(name = "a")] + A, + #[component(name = "b")] + B(u32), + #[component(name = "c")] + C(wasmtime::component::__internal::String), + } + impl core::fmt::Debug for OtherVariant { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + OtherVariant::A => f.debug_tuple("OtherVariant::A").finish(), + OtherVariant::B(e) => { + f.debug_tuple("OtherVariant::B").field(e).finish() + } + OtherVariant::C(e) => { + f.debug_tuple("OtherVariant::C").field(e).finish() + } + } + } + } + const _: () = { + assert!( + 12 == < OtherVariant as wasmtime::component::ComponentType >::SIZE32 + ); + assert!( + 4 == < OtherVariant as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(variant)] + #[derive(Clone)] + pub enum SomeVariant { + #[component(name = "a")] + A(wasmtime::component::__internal::String), + #[component(name = "b")] + B, + #[component(name = "c")] + C(u32), + #[component(name = "d")] + D(wasmtime::component::__internal::Vec), + } + impl core::fmt::Debug for SomeVariant { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + SomeVariant::A(e) => { + f.debug_tuple("SomeVariant::A").field(e).finish() + } + SomeVariant::B => f.debug_tuple("SomeVariant::B").finish(), + SomeVariant::C(e) => { + f.debug_tuple("SomeVariant::C").field(e).finish() + } + SomeVariant::D(e) => { + f.debug_tuple("SomeVariant::D").field(e).finish() + } + } + } + } + const _: () = { + assert!( + 12 == < SomeVariant as wasmtime::component::ComponentType >::SIZE32 + ); + assert!( + 4 == < SomeVariant as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + pub type LoadStoreAllSizes = wasmtime::component::__internal::Vec< + ( + wasmtime::component::__internal::String, + u8, + i8, + u16, + i16, + u32, + i32, + u64, + i64, + f32, + f64, + char, + ), + >; + const _: () = { + assert!( + 8 == < LoadStoreAllSizes as wasmtime::component::ComponentType + >::SIZE32 + ); + assert!( + 4 == < LoadStoreAllSizes as wasmtime::component::ComponentType + >::ALIGN32 + ); + }; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send { + async fn list_u8_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> (); + async fn list_u16_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> (); + async fn list_u32_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> (); + async fn list_u64_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> (); + async fn list_s8_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> (); + async fn list_s16_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> (); + async fn list_s32_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> (); + async fn list_s64_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> (); + async fn list_float32_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> (); + async fn list_float64_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> (); + async fn list_u8_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec; + async fn list_u16_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec; + async fn list_u32_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec; + async fn list_u64_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec; + async fn list_s8_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec; + async fn list_s16_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec; + async fn list_s32_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec; + async fn list_s64_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec; + async fn list_float32_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec; + async fn list_float64_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec; + async fn tuple_list( + &mut self, + x: wasmtime::component::__internal::Vec<(u8, i8)>, + ) -> wasmtime::component::__internal::Vec<(i64, u32)>; + async fn string_list_arg( + &mut self, + a: wasmtime::component::__internal::Vec< + wasmtime::component::__internal::String, + >, + ) -> (); + async fn string_list_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec< + wasmtime::component::__internal::String, + >; + async fn tuple_string_list( + &mut self, + x: wasmtime::component::__internal::Vec< + (u8, wasmtime::component::__internal::String), + >, + ) -> wasmtime::component::__internal::Vec< + (wasmtime::component::__internal::String, u8), + >; + async fn string_list( + &mut self, + x: wasmtime::component::__internal::Vec< + wasmtime::component::__internal::String, + >, + ) -> wasmtime::component::__internal::Vec< + wasmtime::component::__internal::String, + >; + async fn record_list( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> wasmtime::component::__internal::Vec; + async fn record_list_reverse( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> wasmtime::component::__internal::Vec; + async fn variant_list( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> wasmtime::component::__internal::Vec; + async fn load_store_everything( + &mut self, + a: LoadStoreAllSizes, + ) -> LoadStoreAllSizes; + } + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("foo:foo/lists")?; + inst.func_wrap_async( + "list-u8-param", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (wasmtime::component::__internal::Vec,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "lists", function = "list-u8-param", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::list_u8_param(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "list-u16-param", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (wasmtime::component::__internal::Vec,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "lists", function = "list-u16-param", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::list_u16_param(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "list-u32-param", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (wasmtime::component::__internal::Vec,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "lists", function = "list-u32-param", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::list_u32_param(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "list-u64-param", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (wasmtime::component::__internal::Vec,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "lists", function = "list-u64-param", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::list_u64_param(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "list-s8-param", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (wasmtime::component::__internal::Vec,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "lists", function = "list-s8-param", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::list_s8_param(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "list-s16-param", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (wasmtime::component::__internal::Vec,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "lists", function = "list-s16-param", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::list_s16_param(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "list-s32-param", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (wasmtime::component::__internal::Vec,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "lists", function = "list-s32-param", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::list_s32_param(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "list-s64-param", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (wasmtime::component::__internal::Vec,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "lists", function = "list-s64-param", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::list_s64_param(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "list-float32-param", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (wasmtime::component::__internal::Vec,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "lists", function = "list-float32-param", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::list_float32_param(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "list-float64-param", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (wasmtime::component::__internal::Vec,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "lists", function = "list-float64-param", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::list_float64_param(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "list-u8-ret", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "lists", function = "list-u8-ret", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::list_u8_ret(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "list-u16-ret", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "lists", function = "list-u16-ret", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::list_u16_ret(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "list-u32-ret", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "lists", function = "list-u32-ret", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::list_u32_ret(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "list-u64-ret", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "lists", function = "list-u64-ret", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::list_u64_ret(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "list-s8-ret", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "lists", function = "list-s8-ret", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::list_s8_ret(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "list-s16-ret", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "lists", function = "list-s16-ret", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::list_s16_ret(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "list-s32-ret", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "lists", function = "list-s32-ret", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::list_s32_ret(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "list-s64-ret", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "lists", function = "list-s64-ret", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::list_s64_ret(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "list-float32-ret", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "lists", function = "list-float32-ret", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::list_float32_ret(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "list-float64-ret", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "lists", function = "list-float64-ret", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::list_float64_ret(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "tuple-list", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (wasmtime::component::__internal::Vec<(u8, i8)>,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "lists", function = "tuple-list", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::tuple_list(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "string-list-arg", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + ( + arg0, + ): ( + wasmtime::component::__internal::Vec< + wasmtime::component::__internal::String, + >, + )| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "lists", function = "string-list-arg", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, a = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::string_list_arg(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "string-list-ret", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "lists", function = "string-list-ret", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::string_list_ret(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "tuple-string-list", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + ( + arg0, + ): ( + wasmtime::component::__internal::Vec< + (u8, wasmtime::component::__internal::String), + >, + )| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "lists", function = "tuple-string-list", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::tuple_string_list(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "string-list", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + ( + arg0, + ): ( + wasmtime::component::__internal::Vec< + wasmtime::component::__internal::String, + >, + )| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "lists", function = "string-list", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::string_list(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "record-list", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (wasmtime::component::__internal::Vec,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "lists", function = "record-list", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::record_list(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "record-list-reverse", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (wasmtime::component::__internal::Vec,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "lists", function = "record-list-reverse", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::record_list_reverse(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "variant-list", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (wasmtime::component::__internal::Vec,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "lists", function = "variant-list", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::variant_list(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "load-store-everything", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (LoadStoreAllSizes,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "lists", function = "load-store-everything", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, a = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::load_store_everything(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn list_u8_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> () { + Host::list_u8_param(*self, x).await + } + async fn list_u16_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> () { + Host::list_u16_param(*self, x).await + } + async fn list_u32_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> () { + Host::list_u32_param(*self, x).await + } + async fn list_u64_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> () { + Host::list_u64_param(*self, x).await + } + async fn list_s8_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> () { + Host::list_s8_param(*self, x).await + } + async fn list_s16_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> () { + Host::list_s16_param(*self, x).await + } + async fn list_s32_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> () { + Host::list_s32_param(*self, x).await + } + async fn list_s64_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> () { + Host::list_s64_param(*self, x).await + } + async fn list_float32_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> () { + Host::list_float32_param(*self, x).await + } + async fn list_float64_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> () { + Host::list_float64_param(*self, x).await + } + async fn list_u8_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec { + Host::list_u8_ret(*self).await + } + async fn list_u16_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec { + Host::list_u16_ret(*self).await + } + async fn list_u32_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec { + Host::list_u32_ret(*self).await + } + async fn list_u64_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec { + Host::list_u64_ret(*self).await + } + async fn list_s8_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec { + Host::list_s8_ret(*self).await + } + async fn list_s16_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec { + Host::list_s16_ret(*self).await + } + async fn list_s32_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec { + Host::list_s32_ret(*self).await + } + async fn list_s64_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec { + Host::list_s64_ret(*self).await + } + async fn list_float32_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec { + Host::list_float32_ret(*self).await + } + async fn list_float64_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec { + Host::list_float64_ret(*self).await + } + async fn tuple_list( + &mut self, + x: wasmtime::component::__internal::Vec<(u8, i8)>, + ) -> wasmtime::component::__internal::Vec<(i64, u32)> { + Host::tuple_list(*self, x).await + } + async fn string_list_arg( + &mut self, + a: wasmtime::component::__internal::Vec< + wasmtime::component::__internal::String, + >, + ) -> () { + Host::string_list_arg(*self, a).await + } + async fn string_list_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec< + wasmtime::component::__internal::String, + > { + Host::string_list_ret(*self).await + } + async fn tuple_string_list( + &mut self, + x: wasmtime::component::__internal::Vec< + (u8, wasmtime::component::__internal::String), + >, + ) -> wasmtime::component::__internal::Vec< + (wasmtime::component::__internal::String, u8), + > { + Host::tuple_string_list(*self, x).await + } + async fn string_list( + &mut self, + x: wasmtime::component::__internal::Vec< + wasmtime::component::__internal::String, + >, + ) -> wasmtime::component::__internal::Vec< + wasmtime::component::__internal::String, + > { + Host::string_list(*self, x).await + } + async fn record_list( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> wasmtime::component::__internal::Vec { + Host::record_list(*self, x).await + } + async fn record_list_reverse( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> wasmtime::component::__internal::Vec { + Host::record_list_reverse(*self, x).await + } + async fn variant_list( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> wasmtime::component::__internal::Vec { + Host::variant_list(*self, x).await + } + async fn load_store_everything( + &mut self, + a: LoadStoreAllSizes, + ) -> LoadStoreAllSizes { + Host::load_store_everything(*self, a).await + } + } + } + } +} +pub mod exports { + pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod lists { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(record)] + #[derive(Clone)] + pub struct OtherRecord { + #[component(name = "a1")] + pub a1: u32, + #[component(name = "a2")] + pub a2: u64, + #[component(name = "a3")] + pub a3: i32, + #[component(name = "a4")] + pub a4: i64, + #[component(name = "b")] + pub b: wasmtime::component::__internal::String, + #[component(name = "c")] + pub c: wasmtime::component::__internal::Vec, + } + impl core::fmt::Debug for OtherRecord { + fn fmt( + &self, + f: &mut core::fmt::Formatter<'_>, + ) -> core::fmt::Result { + f.debug_struct("OtherRecord") + .field("a1", &self.a1) + .field("a2", &self.a2) + .field("a3", &self.a3) + .field("a4", &self.a4) + .field("b", &self.b) + .field("c", &self.c) + .finish() + } + } + const _: () = { + assert!( + 48 == < OtherRecord as wasmtime::component::ComponentType + >::SIZE32 + ); + assert!( + 8 == < OtherRecord as wasmtime::component::ComponentType + >::ALIGN32 + ); + }; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(record)] + #[derive(Clone)] + pub struct SomeRecord { + #[component(name = "x")] + pub x: wasmtime::component::__internal::String, + #[component(name = "y")] + pub y: OtherRecord, + #[component(name = "z")] + pub z: wasmtime::component::__internal::Vec, + #[component(name = "c1")] + pub c1: u32, + #[component(name = "c2")] + pub c2: u64, + #[component(name = "c3")] + pub c3: i32, + #[component(name = "c4")] + pub c4: i64, + } + impl core::fmt::Debug for SomeRecord { + fn fmt( + &self, + f: &mut core::fmt::Formatter<'_>, + ) -> core::fmt::Result { + f.debug_struct("SomeRecord") + .field("x", &self.x) + .field("y", &self.y) + .field("z", &self.z) + .field("c1", &self.c1) + .field("c2", &self.c2) + .field("c3", &self.c3) + .field("c4", &self.c4) + .finish() + } + } + const _: () = { + assert!( + 96 == < SomeRecord as wasmtime::component::ComponentType + >::SIZE32 + ); + assert!( + 8 == < SomeRecord as wasmtime::component::ComponentType + >::ALIGN32 + ); + }; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(variant)] + #[derive(Clone)] + pub enum OtherVariant { + #[component(name = "a")] + A, + #[component(name = "b")] + B(u32), + #[component(name = "c")] + C(wasmtime::component::__internal::String), + } + impl core::fmt::Debug for OtherVariant { + fn fmt( + &self, + f: &mut core::fmt::Formatter<'_>, + ) -> core::fmt::Result { + match self { + OtherVariant::A => f.debug_tuple("OtherVariant::A").finish(), + OtherVariant::B(e) => { + f.debug_tuple("OtherVariant::B").field(e).finish() + } + OtherVariant::C(e) => { + f.debug_tuple("OtherVariant::C").field(e).finish() + } + } + } + } + const _: () = { + assert!( + 12 == < OtherVariant as wasmtime::component::ComponentType + >::SIZE32 + ); + assert!( + 4 == < OtherVariant as wasmtime::component::ComponentType + >::ALIGN32 + ); + }; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(variant)] + #[derive(Clone)] + pub enum SomeVariant { + #[component(name = "a")] + A(wasmtime::component::__internal::String), + #[component(name = "b")] + B, + #[component(name = "c")] + C(u32), + #[component(name = "d")] + D(wasmtime::component::__internal::Vec), + } + impl core::fmt::Debug for SomeVariant { + fn fmt( + &self, + f: &mut core::fmt::Formatter<'_>, + ) -> core::fmt::Result { + match self { + SomeVariant::A(e) => { + f.debug_tuple("SomeVariant::A").field(e).finish() + } + SomeVariant::B => f.debug_tuple("SomeVariant::B").finish(), + SomeVariant::C(e) => { + f.debug_tuple("SomeVariant::C").field(e).finish() + } + SomeVariant::D(e) => { + f.debug_tuple("SomeVariant::D").field(e).finish() + } + } + } + } + const _: () = { + assert!( + 12 == < SomeVariant as wasmtime::component::ComponentType + >::SIZE32 + ); + assert!( + 4 == < SomeVariant as wasmtime::component::ComponentType + >::ALIGN32 + ); + }; + pub type LoadStoreAllSizes = wasmtime::component::__internal::Vec< + ( + wasmtime::component::__internal::String, + u8, + i8, + u16, + i16, + u32, + i32, + u64, + i64, + f32, + f64, + char, + ), + >; + const _: () = { + assert!( + 8 == < LoadStoreAllSizes as wasmtime::component::ComponentType + >::SIZE32 + ); + assert!( + 4 == < LoadStoreAllSizes as wasmtime::component::ComponentType + >::ALIGN32 + ); + }; + pub struct Guest { + list_u8_param: wasmtime::component::Func, + list_u16_param: wasmtime::component::Func, + list_u32_param: wasmtime::component::Func, + list_u64_param: wasmtime::component::Func, + list_s8_param: wasmtime::component::Func, + list_s16_param: wasmtime::component::Func, + list_s32_param: wasmtime::component::Func, + list_s64_param: wasmtime::component::Func, + list_float32_param: wasmtime::component::Func, + list_float64_param: wasmtime::component::Func, + list_u8_ret: wasmtime::component::Func, + list_u16_ret: wasmtime::component::Func, + list_u32_ret: wasmtime::component::Func, + list_u64_ret: wasmtime::component::Func, + list_s8_ret: wasmtime::component::Func, + list_s16_ret: wasmtime::component::Func, + list_s32_ret: wasmtime::component::Func, + list_s64_ret: wasmtime::component::Func, + list_float32_ret: wasmtime::component::Func, + list_float64_ret: wasmtime::component::Func, + tuple_list: wasmtime::component::Func, + string_list_arg: wasmtime::component::Func, + string_list_ret: wasmtime::component::Func, + tuple_string_list: wasmtime::component::Func, + string_list: wasmtime::component::Func, + record_list: wasmtime::component::Func, + record_list_reverse: wasmtime::component::Func, + variant_list: wasmtime::component::Func, + load_store_everything: wasmtime::component::Func, + } + #[derive(Clone)] + pub struct GuestIndices { + list_u8_param: wasmtime::component::ComponentExportIndex, + list_u16_param: wasmtime::component::ComponentExportIndex, + list_u32_param: wasmtime::component::ComponentExportIndex, + list_u64_param: wasmtime::component::ComponentExportIndex, + list_s8_param: wasmtime::component::ComponentExportIndex, + list_s16_param: wasmtime::component::ComponentExportIndex, + list_s32_param: wasmtime::component::ComponentExportIndex, + list_s64_param: wasmtime::component::ComponentExportIndex, + list_float32_param: wasmtime::component::ComponentExportIndex, + list_float64_param: wasmtime::component::ComponentExportIndex, + list_u8_ret: wasmtime::component::ComponentExportIndex, + list_u16_ret: wasmtime::component::ComponentExportIndex, + list_u32_ret: wasmtime::component::ComponentExportIndex, + list_u64_ret: wasmtime::component::ComponentExportIndex, + list_s8_ret: wasmtime::component::ComponentExportIndex, + list_s16_ret: wasmtime::component::ComponentExportIndex, + list_s32_ret: wasmtime::component::ComponentExportIndex, + list_s64_ret: wasmtime::component::ComponentExportIndex, + list_float32_ret: wasmtime::component::ComponentExportIndex, + list_float64_ret: wasmtime::component::ComponentExportIndex, + tuple_list: wasmtime::component::ComponentExportIndex, + string_list_arg: wasmtime::component::ComponentExportIndex, + string_list_ret: wasmtime::component::ComponentExportIndex, + tuple_string_list: wasmtime::component::ComponentExportIndex, + string_list: wasmtime::component::ComponentExportIndex, + record_list: wasmtime::component::ComponentExportIndex, + record_list_reverse: wasmtime::component::ComponentExportIndex, + variant_list: wasmtime::component::ComponentExportIndex, + load_store_everything: wasmtime::component::ComponentExportIndex, + } + impl GuestIndices { + /// Constructor for [`GuestIndices`] which takes a + /// [`Component`](wasmtime::component::Component) as input and can be executed + /// before instantiation. + /// + /// This constructor can be used to front-load string lookups to find exports + /// within a component. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let (_, instance) = component + .export_index(None, "foo:foo/lists") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/lists`" + ) + })?; + Self::_new(|name| { + component.export_index(Some(&instance), name).map(|p| p.1) + }) + } + /// This constructor is similar to [`GuestIndices::new`] except that it + /// performs string lookups after instantiation time. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let instance_export = instance + .get_export(&mut store, None, "foo:foo/lists") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/lists`" + ) + })?; + Self::_new(|name| { + instance.get_export(&mut store, Some(&instance_export), name) + }) + } + fn _new( + mut lookup: impl FnMut( + &str, + ) -> Option, + ) -> wasmtime::Result { + let mut lookup = move |name| { + lookup(name) + .ok_or_else(|| { + anyhow::anyhow!( + "instance export `foo:foo/lists` does \ + not have export `{name}`" + ) + }) + }; + let _ = &mut lookup; + let list_u8_param = lookup("list-u8-param")?; + let list_u16_param = lookup("list-u16-param")?; + let list_u32_param = lookup("list-u32-param")?; + let list_u64_param = lookup("list-u64-param")?; + let list_s8_param = lookup("list-s8-param")?; + let list_s16_param = lookup("list-s16-param")?; + let list_s32_param = lookup("list-s32-param")?; + let list_s64_param = lookup("list-s64-param")?; + let list_float32_param = lookup("list-float32-param")?; + let list_float64_param = lookup("list-float64-param")?; + let list_u8_ret = lookup("list-u8-ret")?; + let list_u16_ret = lookup("list-u16-ret")?; + let list_u32_ret = lookup("list-u32-ret")?; + let list_u64_ret = lookup("list-u64-ret")?; + let list_s8_ret = lookup("list-s8-ret")?; + let list_s16_ret = lookup("list-s16-ret")?; + let list_s32_ret = lookup("list-s32-ret")?; + let list_s64_ret = lookup("list-s64-ret")?; + let list_float32_ret = lookup("list-float32-ret")?; + let list_float64_ret = lookup("list-float64-ret")?; + let tuple_list = lookup("tuple-list")?; + let string_list_arg = lookup("string-list-arg")?; + let string_list_ret = lookup("string-list-ret")?; + let tuple_string_list = lookup("tuple-string-list")?; + let string_list = lookup("string-list")?; + let record_list = lookup("record-list")?; + let record_list_reverse = lookup("record-list-reverse")?; + let variant_list = lookup("variant-list")?; + let load_store_everything = lookup("load-store-everything")?; + Ok(GuestIndices { + list_u8_param, + list_u16_param, + list_u32_param, + list_u64_param, + list_s8_param, + list_s16_param, + list_s32_param, + list_s64_param, + list_float32_param, + list_float64_param, + list_u8_ret, + list_u16_ret, + list_u32_ret, + list_u64_ret, + list_s8_ret, + list_s16_ret, + list_s32_ret, + list_s64_ret, + list_float32_ret, + list_float64_ret, + tuple_list, + string_list_arg, + string_list_ret, + tuple_string_list, + string_list, + record_list, + record_list_reverse, + variant_list, + load_store_everything, + }) + } + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let mut store = store.as_context_mut(); + let _ = &mut store; + let _instance = instance; + let list_u8_param = *_instance + .get_typed_func::< + (&[u8],), + (), + >(&mut store, &self.list_u8_param)? + .func(); + let list_u16_param = *_instance + .get_typed_func::< + (&[u16],), + (), + >(&mut store, &self.list_u16_param)? + .func(); + let list_u32_param = *_instance + .get_typed_func::< + (&[u32],), + (), + >(&mut store, &self.list_u32_param)? + .func(); + let list_u64_param = *_instance + .get_typed_func::< + (&[u64],), + (), + >(&mut store, &self.list_u64_param)? + .func(); + let list_s8_param = *_instance + .get_typed_func::< + (&[i8],), + (), + >(&mut store, &self.list_s8_param)? + .func(); + let list_s16_param = *_instance + .get_typed_func::< + (&[i16],), + (), + >(&mut store, &self.list_s16_param)? + .func(); + let list_s32_param = *_instance + .get_typed_func::< + (&[i32],), + (), + >(&mut store, &self.list_s32_param)? + .func(); + let list_s64_param = *_instance + .get_typed_func::< + (&[i64],), + (), + >(&mut store, &self.list_s64_param)? + .func(); + let list_float32_param = *_instance + .get_typed_func::< + (&[f32],), + (), + >(&mut store, &self.list_float32_param)? + .func(); + let list_float64_param = *_instance + .get_typed_func::< + (&[f64],), + (), + >(&mut store, &self.list_float64_param)? + .func(); + let list_u8_ret = *_instance + .get_typed_func::< + (), + (wasmtime::component::__internal::Vec,), + >(&mut store, &self.list_u8_ret)? + .func(); + let list_u16_ret = *_instance + .get_typed_func::< + (), + (wasmtime::component::__internal::Vec,), + >(&mut store, &self.list_u16_ret)? + .func(); + let list_u32_ret = *_instance + .get_typed_func::< + (), + (wasmtime::component::__internal::Vec,), + >(&mut store, &self.list_u32_ret)? + .func(); + let list_u64_ret = *_instance + .get_typed_func::< + (), + (wasmtime::component::__internal::Vec,), + >(&mut store, &self.list_u64_ret)? + .func(); + let list_s8_ret = *_instance + .get_typed_func::< + (), + (wasmtime::component::__internal::Vec,), + >(&mut store, &self.list_s8_ret)? + .func(); + let list_s16_ret = *_instance + .get_typed_func::< + (), + (wasmtime::component::__internal::Vec,), + >(&mut store, &self.list_s16_ret)? + .func(); + let list_s32_ret = *_instance + .get_typed_func::< + (), + (wasmtime::component::__internal::Vec,), + >(&mut store, &self.list_s32_ret)? + .func(); + let list_s64_ret = *_instance + .get_typed_func::< + (), + (wasmtime::component::__internal::Vec,), + >(&mut store, &self.list_s64_ret)? + .func(); + let list_float32_ret = *_instance + .get_typed_func::< + (), + (wasmtime::component::__internal::Vec,), + >(&mut store, &self.list_float32_ret)? + .func(); + let list_float64_ret = *_instance + .get_typed_func::< + (), + (wasmtime::component::__internal::Vec,), + >(&mut store, &self.list_float64_ret)? + .func(); + let tuple_list = *_instance + .get_typed_func::< + (&[(u8, i8)],), + (wasmtime::component::__internal::Vec<(i64, u32)>,), + >(&mut store, &self.tuple_list)? + .func(); + let string_list_arg = *_instance + .get_typed_func::< + (&[wasmtime::component::__internal::String],), + (), + >(&mut store, &self.string_list_arg)? + .func(); + let string_list_ret = *_instance + .get_typed_func::< + (), + ( + wasmtime::component::__internal::Vec< + wasmtime::component::__internal::String, + >, + ), + >(&mut store, &self.string_list_ret)? + .func(); + let tuple_string_list = *_instance + .get_typed_func::< + (&[(u8, wasmtime::component::__internal::String)],), + ( + wasmtime::component::__internal::Vec< + (wasmtime::component::__internal::String, u8), + >, + ), + >(&mut store, &self.tuple_string_list)? + .func(); + let string_list = *_instance + .get_typed_func::< + (&[wasmtime::component::__internal::String],), + ( + wasmtime::component::__internal::Vec< + wasmtime::component::__internal::String, + >, + ), + >(&mut store, &self.string_list)? + .func(); + let record_list = *_instance + .get_typed_func::< + (&[SomeRecord],), + (wasmtime::component::__internal::Vec,), + >(&mut store, &self.record_list)? + .func(); + let record_list_reverse = *_instance + .get_typed_func::< + (&[OtherRecord],), + (wasmtime::component::__internal::Vec,), + >(&mut store, &self.record_list_reverse)? + .func(); + let variant_list = *_instance + .get_typed_func::< + (&[SomeVariant],), + (wasmtime::component::__internal::Vec,), + >(&mut store, &self.variant_list)? + .func(); + let load_store_everything = *_instance + .get_typed_func::< + (&LoadStoreAllSizes,), + (LoadStoreAllSizes,), + >(&mut store, &self.load_store_everything)? + .func(); + Ok(Guest { + list_u8_param, + list_u16_param, + list_u32_param, + list_u64_param, + list_s8_param, + list_s16_param, + list_s32_param, + list_s64_param, + list_float32_param, + list_float64_param, + list_u8_ret, + list_u16_ret, + list_u32_ret, + list_u64_ret, + list_s8_ret, + list_s16_ret, + list_s32_ret, + list_s64_ret, + list_float32_ret, + list_float64_ret, + tuple_list, + string_list_arg, + string_list_ret, + tuple_string_list, + string_list, + record_list, + record_list_reverse, + variant_list, + load_store_everything, + }) + } + } + impl Guest { + pub async fn call_list_u8_param( + &self, + mut store: S, + arg0: &[u8], + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/lists", function = "list-u8-param", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (&[u8],), + (), + >::new_unchecked(self.list_u8_param) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_list_u16_param( + &self, + mut store: S, + arg0: &[u16], + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/lists", function = "list-u16-param", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (&[u16],), + (), + >::new_unchecked(self.list_u16_param) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_list_u32_param( + &self, + mut store: S, + arg0: &[u32], + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/lists", function = "list-u32-param", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (&[u32],), + (), + >::new_unchecked(self.list_u32_param) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_list_u64_param( + &self, + mut store: S, + arg0: &[u64], + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/lists", function = "list-u64-param", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (&[u64],), + (), + >::new_unchecked(self.list_u64_param) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_list_s8_param( + &self, + mut store: S, + arg0: &[i8], + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/lists", function = "list-s8-param", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (&[i8],), + (), + >::new_unchecked(self.list_s8_param) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_list_s16_param( + &self, + mut store: S, + arg0: &[i16], + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/lists", function = "list-s16-param", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (&[i16],), + (), + >::new_unchecked(self.list_s16_param) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_list_s32_param( + &self, + mut store: S, + arg0: &[i32], + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/lists", function = "list-s32-param", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (&[i32],), + (), + >::new_unchecked(self.list_s32_param) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_list_s64_param( + &self, + mut store: S, + arg0: &[i64], + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/lists", function = "list-s64-param", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (&[i64],), + (), + >::new_unchecked(self.list_s64_param) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_list_float32_param( + &self, + mut store: S, + arg0: &[f32], + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/lists", function = "list-float32-param", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (&[f32],), + (), + >::new_unchecked(self.list_float32_param) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_list_float64_param( + &self, + mut store: S, + arg0: &[f64], + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/lists", function = "list-float64-param", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (&[f64],), + (), + >::new_unchecked(self.list_float64_param) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_list_u8_ret( + &self, + mut store: S, + ) -> wasmtime::Result> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/lists", function = "list-u8-ret", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (wasmtime::component::__internal::Vec,), + >::new_unchecked(self.list_u8_ret) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_list_u16_ret( + &self, + mut store: S, + ) -> wasmtime::Result> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/lists", function = "list-u16-ret", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (wasmtime::component::__internal::Vec,), + >::new_unchecked(self.list_u16_ret) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_list_u32_ret( + &self, + mut store: S, + ) -> wasmtime::Result> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/lists", function = "list-u32-ret", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (wasmtime::component::__internal::Vec,), + >::new_unchecked(self.list_u32_ret) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_list_u64_ret( + &self, + mut store: S, + ) -> wasmtime::Result> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/lists", function = "list-u64-ret", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (wasmtime::component::__internal::Vec,), + >::new_unchecked(self.list_u64_ret) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_list_s8_ret( + &self, + mut store: S, + ) -> wasmtime::Result> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/lists", function = "list-s8-ret", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (wasmtime::component::__internal::Vec,), + >::new_unchecked(self.list_s8_ret) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_list_s16_ret( + &self, + mut store: S, + ) -> wasmtime::Result> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/lists", function = "list-s16-ret", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (wasmtime::component::__internal::Vec,), + >::new_unchecked(self.list_s16_ret) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_list_s32_ret( + &self, + mut store: S, + ) -> wasmtime::Result> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/lists", function = "list-s32-ret", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (wasmtime::component::__internal::Vec,), + >::new_unchecked(self.list_s32_ret) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_list_s64_ret( + &self, + mut store: S, + ) -> wasmtime::Result> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/lists", function = "list-s64-ret", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (wasmtime::component::__internal::Vec,), + >::new_unchecked(self.list_s64_ret) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_list_float32_ret( + &self, + mut store: S, + ) -> wasmtime::Result> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/lists", function = "list-float32-ret", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (wasmtime::component::__internal::Vec,), + >::new_unchecked(self.list_float32_ret) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_list_float64_ret( + &self, + mut store: S, + ) -> wasmtime::Result> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/lists", function = "list-float64-ret", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (wasmtime::component::__internal::Vec,), + >::new_unchecked(self.list_float64_ret) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_tuple_list( + &self, + mut store: S, + arg0: &[(u8, i8)], + ) -> wasmtime::Result< + wasmtime::component::__internal::Vec<(i64, u32)>, + > + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/lists", function = "tuple-list", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (&[(u8, i8)],), + (wasmtime::component::__internal::Vec<(i64, u32)>,), + >::new_unchecked(self.tuple_list) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_string_list_arg( + &self, + mut store: S, + arg0: &[wasmtime::component::__internal::String], + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/lists", function = "string-list-arg", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (&[wasmtime::component::__internal::String],), + (), + >::new_unchecked(self.string_list_arg) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_string_list_ret( + &self, + mut store: S, + ) -> wasmtime::Result< + wasmtime::component::__internal::Vec< + wasmtime::component::__internal::String, + >, + > + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/lists", function = "string-list-ret", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + ( + wasmtime::component::__internal::Vec< + wasmtime::component::__internal::String, + >, + ), + >::new_unchecked(self.string_list_ret) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_tuple_string_list( + &self, + mut store: S, + arg0: &[(u8, wasmtime::component::__internal::String)], + ) -> wasmtime::Result< + wasmtime::component::__internal::Vec< + (wasmtime::component::__internal::String, u8), + >, + > + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/lists", function = "tuple-string-list", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (&[(u8, wasmtime::component::__internal::String)],), + ( + wasmtime::component::__internal::Vec< + (wasmtime::component::__internal::String, u8), + >, + ), + >::new_unchecked(self.tuple_string_list) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_string_list( + &self, + mut store: S, + arg0: &[wasmtime::component::__internal::String], + ) -> wasmtime::Result< + wasmtime::component::__internal::Vec< + wasmtime::component::__internal::String, + >, + > + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/lists", function = "string-list", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (&[wasmtime::component::__internal::String],), + ( + wasmtime::component::__internal::Vec< + wasmtime::component::__internal::String, + >, + ), + >::new_unchecked(self.string_list) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_record_list( + &self, + mut store: S, + arg0: &[SomeRecord], + ) -> wasmtime::Result< + wasmtime::component::__internal::Vec, + > + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/lists", function = "record-list", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (&[SomeRecord],), + (wasmtime::component::__internal::Vec,), + >::new_unchecked(self.record_list) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_record_list_reverse( + &self, + mut store: S, + arg0: &[OtherRecord], + ) -> wasmtime::Result< + wasmtime::component::__internal::Vec, + > + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/lists", function = "record-list-reverse", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (&[OtherRecord],), + (wasmtime::component::__internal::Vec,), + >::new_unchecked(self.record_list_reverse) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_variant_list( + &self, + mut store: S, + arg0: &[SomeVariant], + ) -> wasmtime::Result< + wasmtime::component::__internal::Vec, + > + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/lists", function = "variant-list", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (&[SomeVariant],), + (wasmtime::component::__internal::Vec,), + >::new_unchecked(self.variant_list) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_load_store_everything( + &self, + mut store: S, + arg0: &LoadStoreAllSizes, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/lists", function = "load-store-everything", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (&LoadStoreAllSizes,), + (LoadStoreAllSizes,), + >::new_unchecked(self.load_store_everything) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + } + } + } + } +} diff --git a/crates/component-macro/tests/expanded/many-arguments_tracing_async.rs b/crates/component-macro/tests/expanded/many-arguments_tracing_async.rs new file mode 100644 index 000000000000..ed87748a3f17 --- /dev/null +++ b/crates/component-macro/tests/expanded/many-arguments_tracing_async.rs @@ -0,0 +1,819 @@ +/// Auto-generated bindings for a pre-instantiated version of a +/// component which implements the world `the-world`. +/// +/// This structure is created through [`TheWorldPre::new`] which +/// takes a [`InstancePre`](wasmtime::component::InstancePre) that +/// has been created through a [`Linker`](wasmtime::component::Linker). +/// +/// For more information see [`TheWorld`] as well. +pub struct TheWorldPre { + instance_pre: wasmtime::component::InstancePre, + indices: TheWorldIndices, +} +impl Clone for TheWorldPre { + fn clone(&self) -> Self { + Self { + instance_pre: self.instance_pre.clone(), + indices: self.indices.clone(), + } + } +} +impl<_T> TheWorldPre<_T> { + /// Creates a new copy of `TheWorldPre` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component behind `instance_pre` + /// does not have the required exports. + pub fn new( + instance_pre: wasmtime::component::InstancePre<_T>, + ) -> wasmtime::Result { + let indices = TheWorldIndices::new(instance_pre.component())?; + Ok(Self { instance_pre, indices }) + } + pub fn engine(&self) -> &wasmtime::Engine { + self.instance_pre.engine() + } + pub fn instance_pre(&self) -> &wasmtime::component::InstancePre<_T> { + &self.instance_pre + } + /// Instantiates a new instance of [`TheWorld`] within the + /// `store` provided. + /// + /// This function will use `self` as the pre-instantiated + /// instance to perform instantiation. Afterwards the preloaded + /// indices in `self` are used to lookup all exports on the + /// resulting instance. + pub async fn instantiate_async( + &self, + mut store: impl wasmtime::AsContextMut, + ) -> wasmtime::Result + where + _T: Send, + { + let mut store = store.as_context_mut(); + let instance = self.instance_pre.instantiate_async(&mut store).await?; + self.indices.load(&mut store, &instance) + } +} +/// Auto-generated bindings for index of the exports of +/// `the-world`. +/// +/// This is an implementation detail of [`TheWorldPre`] and can +/// be constructed if needed as well. +/// +/// For more information see [`TheWorld`] as well. +#[derive(Clone)] +pub struct TheWorldIndices { + interface0: exports::foo::foo::manyarg::GuestIndices, +} +/// Auto-generated bindings for an instance a component which +/// implements the world `the-world`. +/// +/// This structure can be created through a number of means +/// depending on your requirements and what you have on hand: +/// +/// * The most convenient way is to use +/// [`TheWorld::instantiate_async`] which only needs a +/// [`Store`], [`Component`], and [`Linker`]. +/// +/// * Alternatively you can create a [`TheWorldPre`] ahead of +/// time with a [`Component`] to front-load string lookups +/// of exports once instead of per-instantiation. This +/// method then uses [`TheWorldPre::instantiate_async`] to +/// create a [`TheWorld`]. +/// +/// * If you've instantiated the instance yourself already +/// then you can use [`TheWorld::new`]. +/// +/// * You can also access the guts of instantiation through +/// [`TheWorldIndices::new_instance`] followed +/// by [`TheWorldIndices::load`] to crate an instance of this +/// type. +/// +/// These methods are all equivalent to one another and move +/// around the tradeoff of what work is performed when. +/// +/// [`Store`]: wasmtime::Store +/// [`Component`]: wasmtime::component::Component +/// [`Linker`]: wasmtime::component::Linker +pub struct TheWorld { + interface0: exports::foo::foo::manyarg::Guest, +} +const _: () = { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + impl TheWorldIndices { + /// Creates a new copy of `TheWorldIndices` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component does not have the + /// required exports. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let _component = component; + let interface0 = exports::foo::foo::manyarg::GuestIndices::new(_component)?; + Ok(TheWorldIndices { interface0 }) + } + /// Creates a new instance of [`TheWorldIndices`] from an + /// instantiated component. + /// + /// This method of creating a [`TheWorld`] will perform string + /// lookups for all exports when this method is called. This + /// will only succeed if the provided instance matches the + /// requirements of [`TheWorld`]. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = exports::foo::foo::manyarg::GuestIndices::new_instance( + &mut store, + _instance, + )?; + Ok(TheWorldIndices { interface0 }) + } + /// Uses the indices stored in `self` to load an instance + /// of [`TheWorld`] from the instance provided. + /// + /// Note that at this time this method will additionally + /// perform type-checks of all exports. + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = self.interface0.load(&mut store, &_instance)?; + Ok(TheWorld { interface0 }) + } + } + impl TheWorld { + /// Convenience wrapper around [`TheWorldPre::new`] and + /// [`TheWorldPre::instantiate_async`]. + pub async fn instantiate_async<_T>( + mut store: impl wasmtime::AsContextMut, + component: &wasmtime::component::Component, + linker: &wasmtime::component::Linker<_T>, + ) -> wasmtime::Result + where + _T: Send, + { + let pre = linker.instantiate_pre(component)?; + TheWorldPre::new(pre)?.instantiate_async(store).await + } + /// Convenience wrapper around [`TheWorldIndices::new_instance`] and + /// [`TheWorldIndices::load`]. + pub fn new( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let indices = TheWorldIndices::new_instance(&mut store, instance)?; + indices.load(store, instance) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + T: Send, + U: foo::foo::manyarg::Host + Send, + { + foo::foo::manyarg::add_to_linker(linker, get)?; + Ok(()) + } + pub fn foo_foo_manyarg(&self) -> &exports::foo::foo::manyarg::Guest { + &self.interface0 + } + } +}; +pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod manyarg { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(record)] + #[derive(Clone)] + pub struct BigStruct { + #[component(name = "a1")] + pub a1: wasmtime::component::__internal::String, + #[component(name = "a2")] + pub a2: wasmtime::component::__internal::String, + #[component(name = "a3")] + pub a3: wasmtime::component::__internal::String, + #[component(name = "a4")] + pub a4: wasmtime::component::__internal::String, + #[component(name = "a5")] + pub a5: wasmtime::component::__internal::String, + #[component(name = "a6")] + pub a6: wasmtime::component::__internal::String, + #[component(name = "a7")] + pub a7: wasmtime::component::__internal::String, + #[component(name = "a8")] + pub a8: wasmtime::component::__internal::String, + #[component(name = "a9")] + pub a9: wasmtime::component::__internal::String, + #[component(name = "a10")] + pub a10: wasmtime::component::__internal::String, + #[component(name = "a11")] + pub a11: wasmtime::component::__internal::String, + #[component(name = "a12")] + pub a12: wasmtime::component::__internal::String, + #[component(name = "a13")] + pub a13: wasmtime::component::__internal::String, + #[component(name = "a14")] + pub a14: wasmtime::component::__internal::String, + #[component(name = "a15")] + pub a15: wasmtime::component::__internal::String, + #[component(name = "a16")] + pub a16: wasmtime::component::__internal::String, + #[component(name = "a17")] + pub a17: wasmtime::component::__internal::String, + #[component(name = "a18")] + pub a18: wasmtime::component::__internal::String, + #[component(name = "a19")] + pub a19: wasmtime::component::__internal::String, + #[component(name = "a20")] + pub a20: wasmtime::component::__internal::String, + } + impl core::fmt::Debug for BigStruct { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("BigStruct") + .field("a1", &self.a1) + .field("a2", &self.a2) + .field("a3", &self.a3) + .field("a4", &self.a4) + .field("a5", &self.a5) + .field("a6", &self.a6) + .field("a7", &self.a7) + .field("a8", &self.a8) + .field("a9", &self.a9) + .field("a10", &self.a10) + .field("a11", &self.a11) + .field("a12", &self.a12) + .field("a13", &self.a13) + .field("a14", &self.a14) + .field("a15", &self.a15) + .field("a16", &self.a16) + .field("a17", &self.a17) + .field("a18", &self.a18) + .field("a19", &self.a19) + .field("a20", &self.a20) + .finish() + } + } + const _: () = { + assert!( + 160 == < BigStruct as wasmtime::component::ComponentType >::SIZE32 + ); + assert!( + 4 == < BigStruct as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send { + async fn many_args( + &mut self, + a1: u64, + a2: u64, + a3: u64, + a4: u64, + a5: u64, + a6: u64, + a7: u64, + a8: u64, + a9: u64, + a10: u64, + a11: u64, + a12: u64, + a13: u64, + a14: u64, + a15: u64, + a16: u64, + ) -> (); + async fn big_argument(&mut self, x: BigStruct) -> (); + } + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("foo:foo/manyarg")?; + inst.func_wrap_async( + "many-args", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + ( + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + arg7, + arg8, + arg9, + arg10, + arg11, + arg12, + arg13, + arg14, + arg15, + ): ( + u64, + u64, + u64, + u64, + u64, + u64, + u64, + u64, + u64, + u64, + u64, + u64, + u64, + u64, + u64, + u64, + )| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "manyarg", function = "many-args", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, a1 = tracing::field::debug(& arg0), + a2 = tracing::field::debug(& arg1), a3 = + tracing::field::debug(& arg2), a4 = tracing::field::debug(& + arg3), a5 = tracing::field::debug(& arg4), a6 = + tracing::field::debug(& arg5), a7 = tracing::field::debug(& + arg6), a8 = tracing::field::debug(& arg7), a9 = + tracing::field::debug(& arg8), a10 = tracing::field::debug(& + arg9), a11 = tracing::field::debug(& arg10), a12 = + tracing::field::debug(& arg11), a13 = + tracing::field::debug(& arg12), a14 = + tracing::field::debug(& arg13), a15 = + tracing::field::debug(& arg14), a16 = + tracing::field::debug(& arg15), "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::many_args( + host, + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + arg7, + arg8, + arg9, + arg10, + arg11, + arg12, + arg13, + arg14, + arg15, + ) + .await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "big-argument", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (BigStruct,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "manyarg", function = "big-argument", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::big_argument(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn many_args( + &mut self, + a1: u64, + a2: u64, + a3: u64, + a4: u64, + a5: u64, + a6: u64, + a7: u64, + a8: u64, + a9: u64, + a10: u64, + a11: u64, + a12: u64, + a13: u64, + a14: u64, + a15: u64, + a16: u64, + ) -> () { + Host::many_args( + *self, + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + a10, + a11, + a12, + a13, + a14, + a15, + a16, + ) + .await + } + async fn big_argument(&mut self, x: BigStruct) -> () { + Host::big_argument(*self, x).await + } + } + } + } +} +pub mod exports { + pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod manyarg { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(record)] + #[derive(Clone)] + pub struct BigStruct { + #[component(name = "a1")] + pub a1: wasmtime::component::__internal::String, + #[component(name = "a2")] + pub a2: wasmtime::component::__internal::String, + #[component(name = "a3")] + pub a3: wasmtime::component::__internal::String, + #[component(name = "a4")] + pub a4: wasmtime::component::__internal::String, + #[component(name = "a5")] + pub a5: wasmtime::component::__internal::String, + #[component(name = "a6")] + pub a6: wasmtime::component::__internal::String, + #[component(name = "a7")] + pub a7: wasmtime::component::__internal::String, + #[component(name = "a8")] + pub a8: wasmtime::component::__internal::String, + #[component(name = "a9")] + pub a9: wasmtime::component::__internal::String, + #[component(name = "a10")] + pub a10: wasmtime::component::__internal::String, + #[component(name = "a11")] + pub a11: wasmtime::component::__internal::String, + #[component(name = "a12")] + pub a12: wasmtime::component::__internal::String, + #[component(name = "a13")] + pub a13: wasmtime::component::__internal::String, + #[component(name = "a14")] + pub a14: wasmtime::component::__internal::String, + #[component(name = "a15")] + pub a15: wasmtime::component::__internal::String, + #[component(name = "a16")] + pub a16: wasmtime::component::__internal::String, + #[component(name = "a17")] + pub a17: wasmtime::component::__internal::String, + #[component(name = "a18")] + pub a18: wasmtime::component::__internal::String, + #[component(name = "a19")] + pub a19: wasmtime::component::__internal::String, + #[component(name = "a20")] + pub a20: wasmtime::component::__internal::String, + } + impl core::fmt::Debug for BigStruct { + fn fmt( + &self, + f: &mut core::fmt::Formatter<'_>, + ) -> core::fmt::Result { + f.debug_struct("BigStruct") + .field("a1", &self.a1) + .field("a2", &self.a2) + .field("a3", &self.a3) + .field("a4", &self.a4) + .field("a5", &self.a5) + .field("a6", &self.a6) + .field("a7", &self.a7) + .field("a8", &self.a8) + .field("a9", &self.a9) + .field("a10", &self.a10) + .field("a11", &self.a11) + .field("a12", &self.a12) + .field("a13", &self.a13) + .field("a14", &self.a14) + .field("a15", &self.a15) + .field("a16", &self.a16) + .field("a17", &self.a17) + .field("a18", &self.a18) + .field("a19", &self.a19) + .field("a20", &self.a20) + .finish() + } + } + const _: () = { + assert!( + 160 == < BigStruct as wasmtime::component::ComponentType + >::SIZE32 + ); + assert!( + 4 == < BigStruct as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + pub struct Guest { + many_args: wasmtime::component::Func, + big_argument: wasmtime::component::Func, + } + #[derive(Clone)] + pub struct GuestIndices { + many_args: wasmtime::component::ComponentExportIndex, + big_argument: wasmtime::component::ComponentExportIndex, + } + impl GuestIndices { + /// Constructor for [`GuestIndices`] which takes a + /// [`Component`](wasmtime::component::Component) as input and can be executed + /// before instantiation. + /// + /// This constructor can be used to front-load string lookups to find exports + /// within a component. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let (_, instance) = component + .export_index(None, "foo:foo/manyarg") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/manyarg`" + ) + })?; + Self::_new(|name| { + component.export_index(Some(&instance), name).map(|p| p.1) + }) + } + /// This constructor is similar to [`GuestIndices::new`] except that it + /// performs string lookups after instantiation time. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let instance_export = instance + .get_export(&mut store, None, "foo:foo/manyarg") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/manyarg`" + ) + })?; + Self::_new(|name| { + instance.get_export(&mut store, Some(&instance_export), name) + }) + } + fn _new( + mut lookup: impl FnMut( + &str, + ) -> Option, + ) -> wasmtime::Result { + let mut lookup = move |name| { + lookup(name) + .ok_or_else(|| { + anyhow::anyhow!( + "instance export `foo:foo/manyarg` does \ + not have export `{name}`" + ) + }) + }; + let _ = &mut lookup; + let many_args = lookup("many-args")?; + let big_argument = lookup("big-argument")?; + Ok(GuestIndices { + many_args, + big_argument, + }) + } + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let mut store = store.as_context_mut(); + let _ = &mut store; + let _instance = instance; + let many_args = *_instance + .get_typed_func::< + ( + u64, + u64, + u64, + u64, + u64, + u64, + u64, + u64, + u64, + u64, + u64, + u64, + u64, + u64, + u64, + u64, + ), + (), + >(&mut store, &self.many_args)? + .func(); + let big_argument = *_instance + .get_typed_func::< + (&BigStruct,), + (), + >(&mut store, &self.big_argument)? + .func(); + Ok(Guest { many_args, big_argument }) + } + } + impl Guest { + pub async fn call_many_args( + &self, + mut store: S, + arg0: u64, + arg1: u64, + arg2: u64, + arg3: u64, + arg4: u64, + arg5: u64, + arg6: u64, + arg7: u64, + arg8: u64, + arg9: u64, + arg10: u64, + arg11: u64, + arg12: u64, + arg13: u64, + arg14: u64, + arg15: u64, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/manyarg", function = "many-args", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + ( + u64, + u64, + u64, + u64, + u64, + u64, + u64, + u64, + u64, + u64, + u64, + u64, + u64, + u64, + u64, + u64, + ), + (), + >::new_unchecked(self.many_args) + }; + let () = callee + .call_async( + store.as_context_mut(), + ( + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + arg7, + arg8, + arg9, + arg10, + arg11, + arg12, + arg13, + arg14, + arg15, + ), + ) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_big_argument( + &self, + mut store: S, + arg0: &BigStruct, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/manyarg", function = "big-argument", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (&BigStruct,), + (), + >::new_unchecked(self.big_argument) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + } + } + } + } +} diff --git a/crates/component-macro/tests/expanded/multi-return_tracing_async.rs b/crates/component-macro/tests/expanded/multi-return_tracing_async.rs new file mode 100644 index 000000000000..f24b6a347d29 --- /dev/null +++ b/crates/component-macro/tests/expanded/multi-return_tracing_async.rs @@ -0,0 +1,633 @@ +/// Auto-generated bindings for a pre-instantiated version of a +/// component which implements the world `the-world`. +/// +/// This structure is created through [`TheWorldPre::new`] which +/// takes a [`InstancePre`](wasmtime::component::InstancePre) that +/// has been created through a [`Linker`](wasmtime::component::Linker). +/// +/// For more information see [`TheWorld`] as well. +pub struct TheWorldPre { + instance_pre: wasmtime::component::InstancePre, + indices: TheWorldIndices, +} +impl Clone for TheWorldPre { + fn clone(&self) -> Self { + Self { + instance_pre: self.instance_pre.clone(), + indices: self.indices.clone(), + } + } +} +impl<_T> TheWorldPre<_T> { + /// Creates a new copy of `TheWorldPre` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component behind `instance_pre` + /// does not have the required exports. + pub fn new( + instance_pre: wasmtime::component::InstancePre<_T>, + ) -> wasmtime::Result { + let indices = TheWorldIndices::new(instance_pre.component())?; + Ok(Self { instance_pre, indices }) + } + pub fn engine(&self) -> &wasmtime::Engine { + self.instance_pre.engine() + } + pub fn instance_pre(&self) -> &wasmtime::component::InstancePre<_T> { + &self.instance_pre + } + /// Instantiates a new instance of [`TheWorld`] within the + /// `store` provided. + /// + /// This function will use `self` as the pre-instantiated + /// instance to perform instantiation. Afterwards the preloaded + /// indices in `self` are used to lookup all exports on the + /// resulting instance. + pub async fn instantiate_async( + &self, + mut store: impl wasmtime::AsContextMut, + ) -> wasmtime::Result + where + _T: Send, + { + let mut store = store.as_context_mut(); + let instance = self.instance_pre.instantiate_async(&mut store).await?; + self.indices.load(&mut store, &instance) + } +} +/// Auto-generated bindings for index of the exports of +/// `the-world`. +/// +/// This is an implementation detail of [`TheWorldPre`] and can +/// be constructed if needed as well. +/// +/// For more information see [`TheWorld`] as well. +#[derive(Clone)] +pub struct TheWorldIndices { + interface0: exports::foo::foo::multi_return::GuestIndices, +} +/// Auto-generated bindings for an instance a component which +/// implements the world `the-world`. +/// +/// This structure can be created through a number of means +/// depending on your requirements and what you have on hand: +/// +/// * The most convenient way is to use +/// [`TheWorld::instantiate_async`] which only needs a +/// [`Store`], [`Component`], and [`Linker`]. +/// +/// * Alternatively you can create a [`TheWorldPre`] ahead of +/// time with a [`Component`] to front-load string lookups +/// of exports once instead of per-instantiation. This +/// method then uses [`TheWorldPre::instantiate_async`] to +/// create a [`TheWorld`]. +/// +/// * If you've instantiated the instance yourself already +/// then you can use [`TheWorld::new`]. +/// +/// * You can also access the guts of instantiation through +/// [`TheWorldIndices::new_instance`] followed +/// by [`TheWorldIndices::load`] to crate an instance of this +/// type. +/// +/// These methods are all equivalent to one another and move +/// around the tradeoff of what work is performed when. +/// +/// [`Store`]: wasmtime::Store +/// [`Component`]: wasmtime::component::Component +/// [`Linker`]: wasmtime::component::Linker +pub struct TheWorld { + interface0: exports::foo::foo::multi_return::Guest, +} +const _: () = { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + impl TheWorldIndices { + /// Creates a new copy of `TheWorldIndices` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component does not have the + /// required exports. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let _component = component; + let interface0 = exports::foo::foo::multi_return::GuestIndices::new( + _component, + )?; + Ok(TheWorldIndices { interface0 }) + } + /// Creates a new instance of [`TheWorldIndices`] from an + /// instantiated component. + /// + /// This method of creating a [`TheWorld`] will perform string + /// lookups for all exports when this method is called. This + /// will only succeed if the provided instance matches the + /// requirements of [`TheWorld`]. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = exports::foo::foo::multi_return::GuestIndices::new_instance( + &mut store, + _instance, + )?; + Ok(TheWorldIndices { interface0 }) + } + /// Uses the indices stored in `self` to load an instance + /// of [`TheWorld`] from the instance provided. + /// + /// Note that at this time this method will additionally + /// perform type-checks of all exports. + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = self.interface0.load(&mut store, &_instance)?; + Ok(TheWorld { interface0 }) + } + } + impl TheWorld { + /// Convenience wrapper around [`TheWorldPre::new`] and + /// [`TheWorldPre::instantiate_async`]. + pub async fn instantiate_async<_T>( + mut store: impl wasmtime::AsContextMut, + component: &wasmtime::component::Component, + linker: &wasmtime::component::Linker<_T>, + ) -> wasmtime::Result + where + _T: Send, + { + let pre = linker.instantiate_pre(component)?; + TheWorldPre::new(pre)?.instantiate_async(store).await + } + /// Convenience wrapper around [`TheWorldIndices::new_instance`] and + /// [`TheWorldIndices::load`]. + pub fn new( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let indices = TheWorldIndices::new_instance(&mut store, instance)?; + indices.load(store, instance) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + T: Send, + U: foo::foo::multi_return::Host + Send, + { + foo::foo::multi_return::add_to_linker(linker, get)?; + Ok(()) + } + pub fn foo_foo_multi_return(&self) -> &exports::foo::foo::multi_return::Guest { + &self.interface0 + } + } +}; +pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod multi_return { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send { + async fn mra(&mut self) -> (); + async fn mrb(&mut self) -> (); + async fn mrc(&mut self) -> u32; + async fn mrd(&mut self) -> u32; + async fn mre(&mut self) -> (u32, f32); + } + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("foo:foo/multi-return")?; + inst.func_wrap_async( + "mra", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "multi-return", function = "mra", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::mra(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "mrb", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "multi-return", function = "mrb", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::mrb(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "mrc", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "multi-return", function = "mrc", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::mrc(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "mrd", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "multi-return", function = "mrd", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::mrd(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "mre", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "multi-return", function = "mre", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::mre(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn mra(&mut self) -> () { + Host::mra(*self).await + } + async fn mrb(&mut self) -> () { + Host::mrb(*self).await + } + async fn mrc(&mut self) -> u32 { + Host::mrc(*self).await + } + async fn mrd(&mut self) -> u32 { + Host::mrd(*self).await + } + async fn mre(&mut self) -> (u32, f32) { + Host::mre(*self).await + } + } + } + } +} +pub mod exports { + pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod multi_return { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + pub struct Guest { + mra: wasmtime::component::Func, + mrb: wasmtime::component::Func, + mrc: wasmtime::component::Func, + mrd: wasmtime::component::Func, + mre: wasmtime::component::Func, + } + #[derive(Clone)] + pub struct GuestIndices { + mra: wasmtime::component::ComponentExportIndex, + mrb: wasmtime::component::ComponentExportIndex, + mrc: wasmtime::component::ComponentExportIndex, + mrd: wasmtime::component::ComponentExportIndex, + mre: wasmtime::component::ComponentExportIndex, + } + impl GuestIndices { + /// Constructor for [`GuestIndices`] which takes a + /// [`Component`](wasmtime::component::Component) as input and can be executed + /// before instantiation. + /// + /// This constructor can be used to front-load string lookups to find exports + /// within a component. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let (_, instance) = component + .export_index(None, "foo:foo/multi-return") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/multi-return`" + ) + })?; + Self::_new(|name| { + component.export_index(Some(&instance), name).map(|p| p.1) + }) + } + /// This constructor is similar to [`GuestIndices::new`] except that it + /// performs string lookups after instantiation time. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let instance_export = instance + .get_export(&mut store, None, "foo:foo/multi-return") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/multi-return`" + ) + })?; + Self::_new(|name| { + instance.get_export(&mut store, Some(&instance_export), name) + }) + } + fn _new( + mut lookup: impl FnMut( + &str, + ) -> Option, + ) -> wasmtime::Result { + let mut lookup = move |name| { + lookup(name) + .ok_or_else(|| { + anyhow::anyhow!( + "instance export `foo:foo/multi-return` does \ + not have export `{name}`" + ) + }) + }; + let _ = &mut lookup; + let mra = lookup("mra")?; + let mrb = lookup("mrb")?; + let mrc = lookup("mrc")?; + let mrd = lookup("mrd")?; + let mre = lookup("mre")?; + Ok(GuestIndices { + mra, + mrb, + mrc, + mrd, + mre, + }) + } + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let mut store = store.as_context_mut(); + let _ = &mut store; + let _instance = instance; + let mra = *_instance + .get_typed_func::<(), ()>(&mut store, &self.mra)? + .func(); + let mrb = *_instance + .get_typed_func::<(), ()>(&mut store, &self.mrb)? + .func(); + let mrc = *_instance + .get_typed_func::<(), (u32,)>(&mut store, &self.mrc)? + .func(); + let mrd = *_instance + .get_typed_func::<(), (u32,)>(&mut store, &self.mrd)? + .func(); + let mre = *_instance + .get_typed_func::<(), (u32, f32)>(&mut store, &self.mre)? + .func(); + Ok(Guest { mra, mrb, mrc, mrd, mre }) + } + } + impl Guest { + pub async fn call_mra( + &self, + mut store: S, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/multi-return", function = "mra", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (), + >::new_unchecked(self.mra) + }; + let () = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_mrb( + &self, + mut store: S, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/multi-return", function = "mrb", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (), + >::new_unchecked(self.mrb) + }; + let () = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_mrc( + &self, + mut store: S, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/multi-return", function = "mrc", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (u32,), + >::new_unchecked(self.mrc) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_mrd( + &self, + mut store: S, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/multi-return", function = "mrd", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (u32,), + >::new_unchecked(self.mrd) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_mre( + &self, + mut store: S, + ) -> wasmtime::Result<(u32, f32)> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/multi-return", function = "mre", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (u32, f32), + >::new_unchecked(self.mre) + }; + let (ret0, ret1) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok((ret0, ret1)) + } + } + } + } + } +} diff --git a/crates/component-macro/tests/expanded/multiversion_tracing_async.rs b/crates/component-macro/tests/expanded/multiversion_tracing_async.rs new file mode 100644 index 000000000000..11fa4d6cbbcc --- /dev/null +++ b/crates/component-macro/tests/expanded/multiversion_tracing_async.rs @@ -0,0 +1,585 @@ +/// Auto-generated bindings for a pre-instantiated version of a +/// component which implements the world `foo`. +/// +/// This structure is created through [`FooPre::new`] which +/// takes a [`InstancePre`](wasmtime::component::InstancePre) that +/// has been created through a [`Linker`](wasmtime::component::Linker). +/// +/// For more information see [`Foo`] as well. +pub struct FooPre { + instance_pre: wasmtime::component::InstancePre, + indices: FooIndices, +} +impl Clone for FooPre { + fn clone(&self) -> Self { + Self { + instance_pre: self.instance_pre.clone(), + indices: self.indices.clone(), + } + } +} +impl<_T> FooPre<_T> { + /// Creates a new copy of `FooPre` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component behind `instance_pre` + /// does not have the required exports. + pub fn new( + instance_pre: wasmtime::component::InstancePre<_T>, + ) -> wasmtime::Result { + let indices = FooIndices::new(instance_pre.component())?; + Ok(Self { instance_pre, indices }) + } + pub fn engine(&self) -> &wasmtime::Engine { + self.instance_pre.engine() + } + pub fn instance_pre(&self) -> &wasmtime::component::InstancePre<_T> { + &self.instance_pre + } + /// Instantiates a new instance of [`Foo`] within the + /// `store` provided. + /// + /// This function will use `self` as the pre-instantiated + /// instance to perform instantiation. Afterwards the preloaded + /// indices in `self` are used to lookup all exports on the + /// resulting instance. + pub async fn instantiate_async( + &self, + mut store: impl wasmtime::AsContextMut, + ) -> wasmtime::Result + where + _T: Send, + { + let mut store = store.as_context_mut(); + let instance = self.instance_pre.instantiate_async(&mut store).await?; + self.indices.load(&mut store, &instance) + } +} +/// Auto-generated bindings for index of the exports of +/// `foo`. +/// +/// This is an implementation detail of [`FooPre`] and can +/// be constructed if needed as well. +/// +/// For more information see [`Foo`] as well. +#[derive(Clone)] +pub struct FooIndices { + interface0: exports::my::dep0_1_0::a::GuestIndices, + interface1: exports::my::dep0_2_0::a::GuestIndices, +} +/// Auto-generated bindings for an instance a component which +/// implements the world `foo`. +/// +/// This structure can be created through a number of means +/// depending on your requirements and what you have on hand: +/// +/// * The most convenient way is to use +/// [`Foo::instantiate_async`] which only needs a +/// [`Store`], [`Component`], and [`Linker`]. +/// +/// * Alternatively you can create a [`FooPre`] ahead of +/// time with a [`Component`] to front-load string lookups +/// of exports once instead of per-instantiation. This +/// method then uses [`FooPre::instantiate_async`] to +/// create a [`Foo`]. +/// +/// * If you've instantiated the instance yourself already +/// then you can use [`Foo::new`]. +/// +/// * You can also access the guts of instantiation through +/// [`FooIndices::new_instance`] followed +/// by [`FooIndices::load`] to crate an instance of this +/// type. +/// +/// These methods are all equivalent to one another and move +/// around the tradeoff of what work is performed when. +/// +/// [`Store`]: wasmtime::Store +/// [`Component`]: wasmtime::component::Component +/// [`Linker`]: wasmtime::component::Linker +pub struct Foo { + interface0: exports::my::dep0_1_0::a::Guest, + interface1: exports::my::dep0_2_0::a::Guest, +} +const _: () = { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + impl FooIndices { + /// Creates a new copy of `FooIndices` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component does not have the + /// required exports. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let _component = component; + let interface0 = exports::my::dep0_1_0::a::GuestIndices::new(_component)?; + let interface1 = exports::my::dep0_2_0::a::GuestIndices::new(_component)?; + Ok(FooIndices { + interface0, + interface1, + }) + } + /// Creates a new instance of [`FooIndices`] from an + /// instantiated component. + /// + /// This method of creating a [`Foo`] will perform string + /// lookups for all exports when this method is called. This + /// will only succeed if the provided instance matches the + /// requirements of [`Foo`]. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = exports::my::dep0_1_0::a::GuestIndices::new_instance( + &mut store, + _instance, + )?; + let interface1 = exports::my::dep0_2_0::a::GuestIndices::new_instance( + &mut store, + _instance, + )?; + Ok(FooIndices { + interface0, + interface1, + }) + } + /// Uses the indices stored in `self` to load an instance + /// of [`Foo`] from the instance provided. + /// + /// Note that at this time this method will additionally + /// perform type-checks of all exports. + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = self.interface0.load(&mut store, &_instance)?; + let interface1 = self.interface1.load(&mut store, &_instance)?; + Ok(Foo { interface0, interface1 }) + } + } + impl Foo { + /// Convenience wrapper around [`FooPre::new`] and + /// [`FooPre::instantiate_async`]. + pub async fn instantiate_async<_T>( + mut store: impl wasmtime::AsContextMut, + component: &wasmtime::component::Component, + linker: &wasmtime::component::Linker<_T>, + ) -> wasmtime::Result + where + _T: Send, + { + let pre = linker.instantiate_pre(component)?; + FooPre::new(pre)?.instantiate_async(store).await + } + /// Convenience wrapper around [`FooIndices::new_instance`] and + /// [`FooIndices::load`]. + pub fn new( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let indices = FooIndices::new_instance(&mut store, instance)?; + indices.load(store, instance) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + T: Send, + U: my::dep0_1_0::a::Host + my::dep0_2_0::a::Host + Send, + { + my::dep0_1_0::a::add_to_linker(linker, get)?; + my::dep0_2_0::a::add_to_linker(linker, get)?; + Ok(()) + } + pub fn my_dep0_1_0_a(&self) -> &exports::my::dep0_1_0::a::Guest { + &self.interface0 + } + pub fn my_dep0_2_0_a(&self) -> &exports::my::dep0_2_0::a::Guest { + &self.interface1 + } + } +}; +pub mod my { + pub mod dep0_1_0 { + #[allow(clippy::all)] + pub mod a { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send { + async fn x(&mut self) -> (); + } + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("my:dep/a@0.1.0")?; + inst.func_wrap_async( + "x", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = "a", + function = "x", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::x(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn x(&mut self) -> () { + Host::x(*self).await + } + } + } + } + pub mod dep0_2_0 { + #[allow(clippy::all)] + pub mod a { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send { + async fn x(&mut self) -> (); + } + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("my:dep/a@0.2.0")?; + inst.func_wrap_async( + "x", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = "a", + function = "x", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::x(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn x(&mut self) -> () { + Host::x(*self).await + } + } + } + } +} +pub mod exports { + pub mod my { + pub mod dep0_1_0 { + #[allow(clippy::all)] + pub mod a { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + pub struct Guest { + x: wasmtime::component::Func, + } + #[derive(Clone)] + pub struct GuestIndices { + x: wasmtime::component::ComponentExportIndex, + } + impl GuestIndices { + /// Constructor for [`GuestIndices`] which takes a + /// [`Component`](wasmtime::component::Component) as input and can be executed + /// before instantiation. + /// + /// This constructor can be used to front-load string lookups to find exports + /// within a component. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let (_, instance) = component + .export_index(None, "my:dep/a@0.1.0") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `my:dep/a@0.1.0`" + ) + })?; + Self::_new(|name| { + component.export_index(Some(&instance), name).map(|p| p.1) + }) + } + /// This constructor is similar to [`GuestIndices::new`] except that it + /// performs string lookups after instantiation time. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let instance_export = instance + .get_export(&mut store, None, "my:dep/a@0.1.0") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `my:dep/a@0.1.0`" + ) + })?; + Self::_new(|name| { + instance.get_export(&mut store, Some(&instance_export), name) + }) + } + fn _new( + mut lookup: impl FnMut( + &str, + ) -> Option, + ) -> wasmtime::Result { + let mut lookup = move |name| { + lookup(name) + .ok_or_else(|| { + anyhow::anyhow!( + "instance export `my:dep/a@0.1.0` does \ + not have export `{name}`" + ) + }) + }; + let _ = &mut lookup; + let x = lookup("x")?; + Ok(GuestIndices { x }) + } + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let mut store = store.as_context_mut(); + let _ = &mut store; + let _instance = instance; + let x = *_instance + .get_typed_func::<(), ()>(&mut store, &self.x)? + .func(); + Ok(Guest { x }) + } + } + impl Guest { + pub async fn call_x( + &self, + mut store: S, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "my:dep/a@0.1.0", function = "x", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (), + >::new_unchecked(self.x) + }; + let () = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + } + } + } + pub mod dep0_2_0 { + #[allow(clippy::all)] + pub mod a { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + pub struct Guest { + x: wasmtime::component::Func, + } + #[derive(Clone)] + pub struct GuestIndices { + x: wasmtime::component::ComponentExportIndex, + } + impl GuestIndices { + /// Constructor for [`GuestIndices`] which takes a + /// [`Component`](wasmtime::component::Component) as input and can be executed + /// before instantiation. + /// + /// This constructor can be used to front-load string lookups to find exports + /// within a component. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let (_, instance) = component + .export_index(None, "my:dep/a@0.2.0") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `my:dep/a@0.2.0`" + ) + })?; + Self::_new(|name| { + component.export_index(Some(&instance), name).map(|p| p.1) + }) + } + /// This constructor is similar to [`GuestIndices::new`] except that it + /// performs string lookups after instantiation time. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let instance_export = instance + .get_export(&mut store, None, "my:dep/a@0.2.0") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `my:dep/a@0.2.0`" + ) + })?; + Self::_new(|name| { + instance.get_export(&mut store, Some(&instance_export), name) + }) + } + fn _new( + mut lookup: impl FnMut( + &str, + ) -> Option, + ) -> wasmtime::Result { + let mut lookup = move |name| { + lookup(name) + .ok_or_else(|| { + anyhow::anyhow!( + "instance export `my:dep/a@0.2.0` does \ + not have export `{name}`" + ) + }) + }; + let _ = &mut lookup; + let x = lookup("x")?; + Ok(GuestIndices { x }) + } + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let mut store = store.as_context_mut(); + let _ = &mut store; + let _instance = instance; + let x = *_instance + .get_typed_func::<(), ()>(&mut store, &self.x)? + .func(); + Ok(Guest { x }) + } + } + impl Guest { + pub async fn call_x( + &self, + mut store: S, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "my:dep/a@0.2.0", function = "x", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (), + >::new_unchecked(self.x) + }; + let () = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + } + } + } + } +} diff --git a/crates/component-macro/tests/expanded/records_tracing_async.rs b/crates/component-macro/tests/expanded/records_tracing_async.rs new file mode 100644 index 000000000000..8bcfaffa0ea7 --- /dev/null +++ b/crates/component-macro/tests/expanded/records_tracing_async.rs @@ -0,0 +1,1406 @@ +/// Auto-generated bindings for a pre-instantiated version of a +/// component which implements the world `the-world`. +/// +/// This structure is created through [`TheWorldPre::new`] which +/// takes a [`InstancePre`](wasmtime::component::InstancePre) that +/// has been created through a [`Linker`](wasmtime::component::Linker). +/// +/// For more information see [`TheWorld`] as well. +pub struct TheWorldPre { + instance_pre: wasmtime::component::InstancePre, + indices: TheWorldIndices, +} +impl Clone for TheWorldPre { + fn clone(&self) -> Self { + Self { + instance_pre: self.instance_pre.clone(), + indices: self.indices.clone(), + } + } +} +impl<_T> TheWorldPre<_T> { + /// Creates a new copy of `TheWorldPre` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component behind `instance_pre` + /// does not have the required exports. + pub fn new( + instance_pre: wasmtime::component::InstancePre<_T>, + ) -> wasmtime::Result { + let indices = TheWorldIndices::new(instance_pre.component())?; + Ok(Self { instance_pre, indices }) + } + pub fn engine(&self) -> &wasmtime::Engine { + self.instance_pre.engine() + } + pub fn instance_pre(&self) -> &wasmtime::component::InstancePre<_T> { + &self.instance_pre + } + /// Instantiates a new instance of [`TheWorld`] within the + /// `store` provided. + /// + /// This function will use `self` as the pre-instantiated + /// instance to perform instantiation. Afterwards the preloaded + /// indices in `self` are used to lookup all exports on the + /// resulting instance. + pub async fn instantiate_async( + &self, + mut store: impl wasmtime::AsContextMut, + ) -> wasmtime::Result + where + _T: Send, + { + let mut store = store.as_context_mut(); + let instance = self.instance_pre.instantiate_async(&mut store).await?; + self.indices.load(&mut store, &instance) + } +} +/// Auto-generated bindings for index of the exports of +/// `the-world`. +/// +/// This is an implementation detail of [`TheWorldPre`] and can +/// be constructed if needed as well. +/// +/// For more information see [`TheWorld`] as well. +#[derive(Clone)] +pub struct TheWorldIndices { + interface0: exports::foo::foo::records::GuestIndices, +} +/// Auto-generated bindings for an instance a component which +/// implements the world `the-world`. +/// +/// This structure can be created through a number of means +/// depending on your requirements and what you have on hand: +/// +/// * The most convenient way is to use +/// [`TheWorld::instantiate_async`] which only needs a +/// [`Store`], [`Component`], and [`Linker`]. +/// +/// * Alternatively you can create a [`TheWorldPre`] ahead of +/// time with a [`Component`] to front-load string lookups +/// of exports once instead of per-instantiation. This +/// method then uses [`TheWorldPre::instantiate_async`] to +/// create a [`TheWorld`]. +/// +/// * If you've instantiated the instance yourself already +/// then you can use [`TheWorld::new`]. +/// +/// * You can also access the guts of instantiation through +/// [`TheWorldIndices::new_instance`] followed +/// by [`TheWorldIndices::load`] to crate an instance of this +/// type. +/// +/// These methods are all equivalent to one another and move +/// around the tradeoff of what work is performed when. +/// +/// [`Store`]: wasmtime::Store +/// [`Component`]: wasmtime::component::Component +/// [`Linker`]: wasmtime::component::Linker +pub struct TheWorld { + interface0: exports::foo::foo::records::Guest, +} +const _: () = { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + impl TheWorldIndices { + /// Creates a new copy of `TheWorldIndices` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component does not have the + /// required exports. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let _component = component; + let interface0 = exports::foo::foo::records::GuestIndices::new(_component)?; + Ok(TheWorldIndices { interface0 }) + } + /// Creates a new instance of [`TheWorldIndices`] from an + /// instantiated component. + /// + /// This method of creating a [`TheWorld`] will perform string + /// lookups for all exports when this method is called. This + /// will only succeed if the provided instance matches the + /// requirements of [`TheWorld`]. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = exports::foo::foo::records::GuestIndices::new_instance( + &mut store, + _instance, + )?; + Ok(TheWorldIndices { interface0 }) + } + /// Uses the indices stored in `self` to load an instance + /// of [`TheWorld`] from the instance provided. + /// + /// Note that at this time this method will additionally + /// perform type-checks of all exports. + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = self.interface0.load(&mut store, &_instance)?; + Ok(TheWorld { interface0 }) + } + } + impl TheWorld { + /// Convenience wrapper around [`TheWorldPre::new`] and + /// [`TheWorldPre::instantiate_async`]. + pub async fn instantiate_async<_T>( + mut store: impl wasmtime::AsContextMut, + component: &wasmtime::component::Component, + linker: &wasmtime::component::Linker<_T>, + ) -> wasmtime::Result + where + _T: Send, + { + let pre = linker.instantiate_pre(component)?; + TheWorldPre::new(pre)?.instantiate_async(store).await + } + /// Convenience wrapper around [`TheWorldIndices::new_instance`] and + /// [`TheWorldIndices::load`]. + pub fn new( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let indices = TheWorldIndices::new_instance(&mut store, instance)?; + indices.load(store, instance) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + T: Send, + U: foo::foo::records::Host + Send, + { + foo::foo::records::add_to_linker(linker, get)?; + Ok(()) + } + pub fn foo_foo_records(&self) -> &exports::foo::foo::records::Guest { + &self.interface0 + } + } +}; +pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod records { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(record)] + #[derive(Clone, Copy)] + pub struct Empty {} + impl core::fmt::Debug for Empty { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("Empty").finish() + } + } + const _: () = { + assert!(0 == < Empty as wasmtime::component::ComponentType >::SIZE32); + assert!(1 == < Empty as wasmtime::component::ComponentType >::ALIGN32); + }; + /// A record containing two scalar fields + /// that both have the same type + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(record)] + #[derive(Clone, Copy)] + pub struct Scalars { + /// The first field, named a + #[component(name = "a")] + pub a: u32, + /// The second field, named b + #[component(name = "b")] + pub b: u32, + } + impl core::fmt::Debug for Scalars { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("Scalars") + .field("a", &self.a) + .field("b", &self.b) + .finish() + } + } + const _: () = { + assert!(8 == < Scalars as wasmtime::component::ComponentType >::SIZE32); + assert!(4 == < Scalars as wasmtime::component::ComponentType >::ALIGN32); + }; + /// A record that is really just flags + /// All of the fields are bool + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(record)] + #[derive(Clone, Copy)] + pub struct ReallyFlags { + #[component(name = "a")] + pub a: bool, + #[component(name = "b")] + pub b: bool, + #[component(name = "c")] + pub c: bool, + #[component(name = "d")] + pub d: bool, + #[component(name = "e")] + pub e: bool, + #[component(name = "f")] + pub f: bool, + #[component(name = "g")] + pub g: bool, + #[component(name = "h")] + pub h: bool, + #[component(name = "i")] + pub i: bool, + } + impl core::fmt::Debug for ReallyFlags { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("ReallyFlags") + .field("a", &self.a) + .field("b", &self.b) + .field("c", &self.c) + .field("d", &self.d) + .field("e", &self.e) + .field("f", &self.f) + .field("g", &self.g) + .field("h", &self.h) + .field("i", &self.i) + .finish() + } + } + const _: () = { + assert!( + 9 == < ReallyFlags as wasmtime::component::ComponentType >::SIZE32 + ); + assert!( + 1 == < ReallyFlags as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(record)] + #[derive(Clone)] + pub struct Aggregates { + #[component(name = "a")] + pub a: Scalars, + #[component(name = "b")] + pub b: u32, + #[component(name = "c")] + pub c: Empty, + #[component(name = "d")] + pub d: wasmtime::component::__internal::String, + #[component(name = "e")] + pub e: ReallyFlags, + } + impl core::fmt::Debug for Aggregates { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("Aggregates") + .field("a", &self.a) + .field("b", &self.b) + .field("c", &self.c) + .field("d", &self.d) + .field("e", &self.e) + .finish() + } + } + const _: () = { + assert!( + 32 == < Aggregates as wasmtime::component::ComponentType >::SIZE32 + ); + assert!( + 4 == < Aggregates as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + pub type IntTypedef = i32; + const _: () = { + assert!( + 4 == < IntTypedef as wasmtime::component::ComponentType >::SIZE32 + ); + assert!( + 4 == < IntTypedef as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + pub type TupleTypedef2 = (IntTypedef,); + const _: () = { + assert!( + 4 == < TupleTypedef2 as wasmtime::component::ComponentType >::SIZE32 + ); + assert!( + 4 == < TupleTypedef2 as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send { + async fn tuple_arg(&mut self, x: (char, u32)) -> (); + async fn tuple_result(&mut self) -> (char, u32); + async fn empty_arg(&mut self, x: Empty) -> (); + async fn empty_result(&mut self) -> Empty; + async fn scalar_arg(&mut self, x: Scalars) -> (); + async fn scalar_result(&mut self) -> Scalars; + async fn flags_arg(&mut self, x: ReallyFlags) -> (); + async fn flags_result(&mut self) -> ReallyFlags; + async fn aggregate_arg(&mut self, x: Aggregates) -> (); + async fn aggregate_result(&mut self) -> Aggregates; + async fn typedef_inout(&mut self, e: TupleTypedef2) -> i32; + } + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("foo:foo/records")?; + inst.func_wrap_async( + "tuple-arg", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): ((char, u32),)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "records", function = "tuple-arg", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::tuple_arg(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "tuple-result", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "records", function = "tuple-result", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::tuple_result(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "empty-arg", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (Empty,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "records", function = "empty-arg", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::empty_arg(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "empty-result", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "records", function = "empty-result", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::empty_result(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "scalar-arg", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (Scalars,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "records", function = "scalar-arg", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::scalar_arg(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "scalar-result", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "records", function = "scalar-result", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::scalar_result(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "flags-arg", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (ReallyFlags,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "records", function = "flags-arg", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::flags_arg(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "flags-result", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "records", function = "flags-result", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::flags_result(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "aggregate-arg", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (Aggregates,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "records", function = "aggregate-arg", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::aggregate_arg(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "aggregate-result", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "records", function = "aggregate-result", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::aggregate_result(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "typedef-inout", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (TupleTypedef2,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "records", function = "typedef-inout", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, e = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::typedef_inout(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn tuple_arg(&mut self, x: (char, u32)) -> () { + Host::tuple_arg(*self, x).await + } + async fn tuple_result(&mut self) -> (char, u32) { + Host::tuple_result(*self).await + } + async fn empty_arg(&mut self, x: Empty) -> () { + Host::empty_arg(*self, x).await + } + async fn empty_result(&mut self) -> Empty { + Host::empty_result(*self).await + } + async fn scalar_arg(&mut self, x: Scalars) -> () { + Host::scalar_arg(*self, x).await + } + async fn scalar_result(&mut self) -> Scalars { + Host::scalar_result(*self).await + } + async fn flags_arg(&mut self, x: ReallyFlags) -> () { + Host::flags_arg(*self, x).await + } + async fn flags_result(&mut self) -> ReallyFlags { + Host::flags_result(*self).await + } + async fn aggregate_arg(&mut self, x: Aggregates) -> () { + Host::aggregate_arg(*self, x).await + } + async fn aggregate_result(&mut self) -> Aggregates { + Host::aggregate_result(*self).await + } + async fn typedef_inout(&mut self, e: TupleTypedef2) -> i32 { + Host::typedef_inout(*self, e).await + } + } + } + } +} +pub mod exports { + pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod records { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(record)] + #[derive(Clone, Copy)] + pub struct Empty {} + impl core::fmt::Debug for Empty { + fn fmt( + &self, + f: &mut core::fmt::Formatter<'_>, + ) -> core::fmt::Result { + f.debug_struct("Empty").finish() + } + } + const _: () = { + assert!( + 0 == < Empty as wasmtime::component::ComponentType >::SIZE32 + ); + assert!( + 1 == < Empty as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + /// A record containing two scalar fields + /// that both have the same type + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(record)] + #[derive(Clone, Copy)] + pub struct Scalars { + /// The first field, named a + #[component(name = "a")] + pub a: u32, + /// The second field, named b + #[component(name = "b")] + pub b: u32, + } + impl core::fmt::Debug for Scalars { + fn fmt( + &self, + f: &mut core::fmt::Formatter<'_>, + ) -> core::fmt::Result { + f.debug_struct("Scalars") + .field("a", &self.a) + .field("b", &self.b) + .finish() + } + } + const _: () = { + assert!( + 8 == < Scalars as wasmtime::component::ComponentType >::SIZE32 + ); + assert!( + 4 == < Scalars as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + /// A record that is really just flags + /// All of the fields are bool + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(record)] + #[derive(Clone, Copy)] + pub struct ReallyFlags { + #[component(name = "a")] + pub a: bool, + #[component(name = "b")] + pub b: bool, + #[component(name = "c")] + pub c: bool, + #[component(name = "d")] + pub d: bool, + #[component(name = "e")] + pub e: bool, + #[component(name = "f")] + pub f: bool, + #[component(name = "g")] + pub g: bool, + #[component(name = "h")] + pub h: bool, + #[component(name = "i")] + pub i: bool, + } + impl core::fmt::Debug for ReallyFlags { + fn fmt( + &self, + f: &mut core::fmt::Formatter<'_>, + ) -> core::fmt::Result { + f.debug_struct("ReallyFlags") + .field("a", &self.a) + .field("b", &self.b) + .field("c", &self.c) + .field("d", &self.d) + .field("e", &self.e) + .field("f", &self.f) + .field("g", &self.g) + .field("h", &self.h) + .field("i", &self.i) + .finish() + } + } + const _: () = { + assert!( + 9 == < ReallyFlags as wasmtime::component::ComponentType + >::SIZE32 + ); + assert!( + 1 == < ReallyFlags as wasmtime::component::ComponentType + >::ALIGN32 + ); + }; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(record)] + #[derive(Clone)] + pub struct Aggregates { + #[component(name = "a")] + pub a: Scalars, + #[component(name = "b")] + pub b: u32, + #[component(name = "c")] + pub c: Empty, + #[component(name = "d")] + pub d: wasmtime::component::__internal::String, + #[component(name = "e")] + pub e: ReallyFlags, + } + impl core::fmt::Debug for Aggregates { + fn fmt( + &self, + f: &mut core::fmt::Formatter<'_>, + ) -> core::fmt::Result { + f.debug_struct("Aggregates") + .field("a", &self.a) + .field("b", &self.b) + .field("c", &self.c) + .field("d", &self.d) + .field("e", &self.e) + .finish() + } + } + const _: () = { + assert!( + 32 == < Aggregates as wasmtime::component::ComponentType + >::SIZE32 + ); + assert!( + 4 == < Aggregates as wasmtime::component::ComponentType + >::ALIGN32 + ); + }; + pub type IntTypedef = i32; + const _: () = { + assert!( + 4 == < IntTypedef as wasmtime::component::ComponentType >::SIZE32 + ); + assert!( + 4 == < IntTypedef as wasmtime::component::ComponentType + >::ALIGN32 + ); + }; + pub type TupleTypedef2 = (IntTypedef,); + const _: () = { + assert!( + 4 == < TupleTypedef2 as wasmtime::component::ComponentType + >::SIZE32 + ); + assert!( + 4 == < TupleTypedef2 as wasmtime::component::ComponentType + >::ALIGN32 + ); + }; + pub struct Guest { + tuple_arg: wasmtime::component::Func, + tuple_result: wasmtime::component::Func, + empty_arg: wasmtime::component::Func, + empty_result: wasmtime::component::Func, + scalar_arg: wasmtime::component::Func, + scalar_result: wasmtime::component::Func, + flags_arg: wasmtime::component::Func, + flags_result: wasmtime::component::Func, + aggregate_arg: wasmtime::component::Func, + aggregate_result: wasmtime::component::Func, + typedef_inout: wasmtime::component::Func, + } + #[derive(Clone)] + pub struct GuestIndices { + tuple_arg: wasmtime::component::ComponentExportIndex, + tuple_result: wasmtime::component::ComponentExportIndex, + empty_arg: wasmtime::component::ComponentExportIndex, + empty_result: wasmtime::component::ComponentExportIndex, + scalar_arg: wasmtime::component::ComponentExportIndex, + scalar_result: wasmtime::component::ComponentExportIndex, + flags_arg: wasmtime::component::ComponentExportIndex, + flags_result: wasmtime::component::ComponentExportIndex, + aggregate_arg: wasmtime::component::ComponentExportIndex, + aggregate_result: wasmtime::component::ComponentExportIndex, + typedef_inout: wasmtime::component::ComponentExportIndex, + } + impl GuestIndices { + /// Constructor for [`GuestIndices`] which takes a + /// [`Component`](wasmtime::component::Component) as input and can be executed + /// before instantiation. + /// + /// This constructor can be used to front-load string lookups to find exports + /// within a component. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let (_, instance) = component + .export_index(None, "foo:foo/records") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/records`" + ) + })?; + Self::_new(|name| { + component.export_index(Some(&instance), name).map(|p| p.1) + }) + } + /// This constructor is similar to [`GuestIndices::new`] except that it + /// performs string lookups after instantiation time. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let instance_export = instance + .get_export(&mut store, None, "foo:foo/records") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/records`" + ) + })?; + Self::_new(|name| { + instance.get_export(&mut store, Some(&instance_export), name) + }) + } + fn _new( + mut lookup: impl FnMut( + &str, + ) -> Option, + ) -> wasmtime::Result { + let mut lookup = move |name| { + lookup(name) + .ok_or_else(|| { + anyhow::anyhow!( + "instance export `foo:foo/records` does \ + not have export `{name}`" + ) + }) + }; + let _ = &mut lookup; + let tuple_arg = lookup("tuple-arg")?; + let tuple_result = lookup("tuple-result")?; + let empty_arg = lookup("empty-arg")?; + let empty_result = lookup("empty-result")?; + let scalar_arg = lookup("scalar-arg")?; + let scalar_result = lookup("scalar-result")?; + let flags_arg = lookup("flags-arg")?; + let flags_result = lookup("flags-result")?; + let aggregate_arg = lookup("aggregate-arg")?; + let aggregate_result = lookup("aggregate-result")?; + let typedef_inout = lookup("typedef-inout")?; + Ok(GuestIndices { + tuple_arg, + tuple_result, + empty_arg, + empty_result, + scalar_arg, + scalar_result, + flags_arg, + flags_result, + aggregate_arg, + aggregate_result, + typedef_inout, + }) + } + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let mut store = store.as_context_mut(); + let _ = &mut store; + let _instance = instance; + let tuple_arg = *_instance + .get_typed_func::< + ((char, u32),), + (), + >(&mut store, &self.tuple_arg)? + .func(); + let tuple_result = *_instance + .get_typed_func::< + (), + ((char, u32),), + >(&mut store, &self.tuple_result)? + .func(); + let empty_arg = *_instance + .get_typed_func::<(Empty,), ()>(&mut store, &self.empty_arg)? + .func(); + let empty_result = *_instance + .get_typed_func::< + (), + (Empty,), + >(&mut store, &self.empty_result)? + .func(); + let scalar_arg = *_instance + .get_typed_func::< + (Scalars,), + (), + >(&mut store, &self.scalar_arg)? + .func(); + let scalar_result = *_instance + .get_typed_func::< + (), + (Scalars,), + >(&mut store, &self.scalar_result)? + .func(); + let flags_arg = *_instance + .get_typed_func::< + (ReallyFlags,), + (), + >(&mut store, &self.flags_arg)? + .func(); + let flags_result = *_instance + .get_typed_func::< + (), + (ReallyFlags,), + >(&mut store, &self.flags_result)? + .func(); + let aggregate_arg = *_instance + .get_typed_func::< + (&Aggregates,), + (), + >(&mut store, &self.aggregate_arg)? + .func(); + let aggregate_result = *_instance + .get_typed_func::< + (), + (Aggregates,), + >(&mut store, &self.aggregate_result)? + .func(); + let typedef_inout = *_instance + .get_typed_func::< + (TupleTypedef2,), + (i32,), + >(&mut store, &self.typedef_inout)? + .func(); + Ok(Guest { + tuple_arg, + tuple_result, + empty_arg, + empty_result, + scalar_arg, + scalar_result, + flags_arg, + flags_result, + aggregate_arg, + aggregate_result, + typedef_inout, + }) + } + } + impl Guest { + pub async fn call_tuple_arg( + &self, + mut store: S, + arg0: (char, u32), + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/records", function = "tuple-arg", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + ((char, u32),), + (), + >::new_unchecked(self.tuple_arg) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_tuple_result( + &self, + mut store: S, + ) -> wasmtime::Result<(char, u32)> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/records", function = "tuple-result", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + ((char, u32),), + >::new_unchecked(self.tuple_result) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_empty_arg( + &self, + mut store: S, + arg0: Empty, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/records", function = "empty-arg", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (Empty,), + (), + >::new_unchecked(self.empty_arg) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_empty_result( + &self, + mut store: S, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/records", function = "empty-result", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (Empty,), + >::new_unchecked(self.empty_result) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_scalar_arg( + &self, + mut store: S, + arg0: Scalars, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/records", function = "scalar-arg", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (Scalars,), + (), + >::new_unchecked(self.scalar_arg) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_scalar_result( + &self, + mut store: S, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/records", function = "scalar-result", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (Scalars,), + >::new_unchecked(self.scalar_result) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_flags_arg( + &self, + mut store: S, + arg0: ReallyFlags, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/records", function = "flags-arg", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (ReallyFlags,), + (), + >::new_unchecked(self.flags_arg) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_flags_result( + &self, + mut store: S, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/records", function = "flags-result", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (ReallyFlags,), + >::new_unchecked(self.flags_result) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_aggregate_arg( + &self, + mut store: S, + arg0: &Aggregates, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/records", function = "aggregate-arg", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (&Aggregates,), + (), + >::new_unchecked(self.aggregate_arg) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_aggregate_result( + &self, + mut store: S, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/records", function = "aggregate-result", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (Aggregates,), + >::new_unchecked(self.aggregate_result) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_typedef_inout( + &self, + mut store: S, + arg0: TupleTypedef2, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/records", function = "typedef-inout", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (TupleTypedef2,), + (i32,), + >::new_unchecked(self.typedef_inout) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + } + } + } + } +} diff --git a/crates/component-macro/tests/expanded/rename_tracing_async.rs b/crates/component-macro/tests/expanded/rename_tracing_async.rs new file mode 100644 index 000000000000..f8bc4e5e606c --- /dev/null +++ b/crates/component-macro/tests/expanded/rename_tracing_async.rs @@ -0,0 +1,302 @@ +/// Auto-generated bindings for a pre-instantiated version of a +/// component which implements the world `neptune`. +/// +/// This structure is created through [`NeptunePre::new`] which +/// takes a [`InstancePre`](wasmtime::component::InstancePre) that +/// has been created through a [`Linker`](wasmtime::component::Linker). +/// +/// For more information see [`Neptune`] as well. +pub struct NeptunePre { + instance_pre: wasmtime::component::InstancePre, + indices: NeptuneIndices, +} +impl Clone for NeptunePre { + fn clone(&self) -> Self { + Self { + instance_pre: self.instance_pre.clone(), + indices: self.indices.clone(), + } + } +} +impl<_T> NeptunePre<_T> { + /// Creates a new copy of `NeptunePre` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component behind `instance_pre` + /// does not have the required exports. + pub fn new( + instance_pre: wasmtime::component::InstancePre<_T>, + ) -> wasmtime::Result { + let indices = NeptuneIndices::new(instance_pre.component())?; + Ok(Self { instance_pre, indices }) + } + pub fn engine(&self) -> &wasmtime::Engine { + self.instance_pre.engine() + } + pub fn instance_pre(&self) -> &wasmtime::component::InstancePre<_T> { + &self.instance_pre + } + /// Instantiates a new instance of [`Neptune`] within the + /// `store` provided. + /// + /// This function will use `self` as the pre-instantiated + /// instance to perform instantiation. Afterwards the preloaded + /// indices in `self` are used to lookup all exports on the + /// resulting instance. + pub async fn instantiate_async( + &self, + mut store: impl wasmtime::AsContextMut, + ) -> wasmtime::Result + where + _T: Send, + { + let mut store = store.as_context_mut(); + let instance = self.instance_pre.instantiate_async(&mut store).await?; + self.indices.load(&mut store, &instance) + } +} +/// Auto-generated bindings for index of the exports of +/// `neptune`. +/// +/// This is an implementation detail of [`NeptunePre`] and can +/// be constructed if needed as well. +/// +/// For more information see [`Neptune`] as well. +#[derive(Clone)] +pub struct NeptuneIndices {} +/// Auto-generated bindings for an instance a component which +/// implements the world `neptune`. +/// +/// This structure can be created through a number of means +/// depending on your requirements and what you have on hand: +/// +/// * The most convenient way is to use +/// [`Neptune::instantiate_async`] which only needs a +/// [`Store`], [`Component`], and [`Linker`]. +/// +/// * Alternatively you can create a [`NeptunePre`] ahead of +/// time with a [`Component`] to front-load string lookups +/// of exports once instead of per-instantiation. This +/// method then uses [`NeptunePre::instantiate_async`] to +/// create a [`Neptune`]. +/// +/// * If you've instantiated the instance yourself already +/// then you can use [`Neptune::new`]. +/// +/// * You can also access the guts of instantiation through +/// [`NeptuneIndices::new_instance`] followed +/// by [`NeptuneIndices::load`] to crate an instance of this +/// type. +/// +/// These methods are all equivalent to one another and move +/// around the tradeoff of what work is performed when. +/// +/// [`Store`]: wasmtime::Store +/// [`Component`]: wasmtime::component::Component +/// [`Linker`]: wasmtime::component::Linker +pub struct Neptune {} +const _: () = { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + impl NeptuneIndices { + /// Creates a new copy of `NeptuneIndices` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component does not have the + /// required exports. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let _component = component; + Ok(NeptuneIndices {}) + } + /// Creates a new instance of [`NeptuneIndices`] from an + /// instantiated component. + /// + /// This method of creating a [`Neptune`] will perform string + /// lookups for all exports when this method is called. This + /// will only succeed if the provided instance matches the + /// requirements of [`Neptune`]. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + Ok(NeptuneIndices {}) + } + /// Uses the indices stored in `self` to load an instance + /// of [`Neptune`] from the instance provided. + /// + /// Note that at this time this method will additionally + /// perform type-checks of all exports. + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + Ok(Neptune {}) + } + } + impl Neptune { + /// Convenience wrapper around [`NeptunePre::new`] and + /// [`NeptunePre::instantiate_async`]. + pub async fn instantiate_async<_T>( + mut store: impl wasmtime::AsContextMut, + component: &wasmtime::component::Component, + linker: &wasmtime::component::Linker<_T>, + ) -> wasmtime::Result + where + _T: Send, + { + let pre = linker.instantiate_pre(component)?; + NeptunePre::new(pre)?.instantiate_async(store).await + } + /// Convenience wrapper around [`NeptuneIndices::new_instance`] and + /// [`NeptuneIndices::load`]. + pub fn new( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let indices = NeptuneIndices::new_instance(&mut store, instance)?; + indices.load(store, instance) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + T: Send, + U: foo::foo::green::Host + foo::foo::red::Host + Send, + { + foo::foo::green::add_to_linker(linker, get)?; + foo::foo::red::add_to_linker(linker, get)?; + Ok(()) + } + } +}; +pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod green { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + pub type Thing = i32; + const _: () = { + assert!(4 == < Thing as wasmtime::component::ComponentType >::SIZE32); + assert!(4 == < Thing as wasmtime::component::ComponentType >::ALIGN32); + }; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send {} + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("foo:foo/green")?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T {} + } + #[allow(clippy::all)] + pub mod red { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + pub type Thing = super::super::super::foo::foo::green::Thing; + const _: () = { + assert!(4 == < Thing as wasmtime::component::ComponentType >::SIZE32); + assert!(4 == < Thing as wasmtime::component::ComponentType >::ALIGN32); + }; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send { + async fn foo(&mut self) -> Thing; + } + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("foo:foo/red")?; + inst.func_wrap_async( + "foo", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = "red", + function = "foo", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::foo(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn foo(&mut self) -> Thing { + Host::foo(*self).await + } + } + } + } +} diff --git a/crates/component-macro/tests/expanded/resources-export_tracing_async.rs b/crates/component-macro/tests/expanded/resources-export_tracing_async.rs new file mode 100644 index 000000000000..e25bebe52015 --- /dev/null +++ b/crates/component-macro/tests/expanded/resources-export_tracing_async.rs @@ -0,0 +1,1011 @@ +/// Auto-generated bindings for a pre-instantiated version of a +/// component which implements the world `w`. +/// +/// This structure is created through [`WPre::new`] which +/// takes a [`InstancePre`](wasmtime::component::InstancePre) that +/// has been created through a [`Linker`](wasmtime::component::Linker). +/// +/// For more information see [`W`] as well. +pub struct WPre { + instance_pre: wasmtime::component::InstancePre, + indices: WIndices, +} +impl Clone for WPre { + fn clone(&self) -> Self { + Self { + instance_pre: self.instance_pre.clone(), + indices: self.indices.clone(), + } + } +} +impl<_T> WPre<_T> { + /// Creates a new copy of `WPre` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component behind `instance_pre` + /// does not have the required exports. + pub fn new( + instance_pre: wasmtime::component::InstancePre<_T>, + ) -> wasmtime::Result { + let indices = WIndices::new(instance_pre.component())?; + Ok(Self { instance_pre, indices }) + } + pub fn engine(&self) -> &wasmtime::Engine { + self.instance_pre.engine() + } + pub fn instance_pre(&self) -> &wasmtime::component::InstancePre<_T> { + &self.instance_pre + } + /// Instantiates a new instance of [`W`] within the + /// `store` provided. + /// + /// This function will use `self` as the pre-instantiated + /// instance to perform instantiation. Afterwards the preloaded + /// indices in `self` are used to lookup all exports on the + /// resulting instance. + pub async fn instantiate_async( + &self, + mut store: impl wasmtime::AsContextMut, + ) -> wasmtime::Result + where + _T: Send, + { + let mut store = store.as_context_mut(); + let instance = self.instance_pre.instantiate_async(&mut store).await?; + self.indices.load(&mut store, &instance) + } +} +/// Auto-generated bindings for index of the exports of +/// `w`. +/// +/// This is an implementation detail of [`WPre`] and can +/// be constructed if needed as well. +/// +/// For more information see [`W`] as well. +#[derive(Clone)] +pub struct WIndices { + interface0: exports::foo::foo::simple_export::GuestIndices, + interface1: exports::foo::foo::export_using_import::GuestIndices, + interface2: exports::foo::foo::export_using_export1::GuestIndices, + interface3: exports::foo::foo::export_using_export2::GuestIndices, +} +/// Auto-generated bindings for an instance a component which +/// implements the world `w`. +/// +/// This structure can be created through a number of means +/// depending on your requirements and what you have on hand: +/// +/// * The most convenient way is to use +/// [`W::instantiate_async`] which only needs a +/// [`Store`], [`Component`], and [`Linker`]. +/// +/// * Alternatively you can create a [`WPre`] ahead of +/// time with a [`Component`] to front-load string lookups +/// of exports once instead of per-instantiation. This +/// method then uses [`WPre::instantiate_async`] to +/// create a [`W`]. +/// +/// * If you've instantiated the instance yourself already +/// then you can use [`W::new`]. +/// +/// * You can also access the guts of instantiation through +/// [`WIndices::new_instance`] followed +/// by [`WIndices::load`] to crate an instance of this +/// type. +/// +/// These methods are all equivalent to one another and move +/// around the tradeoff of what work is performed when. +/// +/// [`Store`]: wasmtime::Store +/// [`Component`]: wasmtime::component::Component +/// [`Linker`]: wasmtime::component::Linker +pub struct W { + interface0: exports::foo::foo::simple_export::Guest, + interface1: exports::foo::foo::export_using_import::Guest, + interface2: exports::foo::foo::export_using_export1::Guest, + interface3: exports::foo::foo::export_using_export2::Guest, +} +const _: () = { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + impl WIndices { + /// Creates a new copy of `WIndices` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component does not have the + /// required exports. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let _component = component; + let interface0 = exports::foo::foo::simple_export::GuestIndices::new( + _component, + )?; + let interface1 = exports::foo::foo::export_using_import::GuestIndices::new( + _component, + )?; + let interface2 = exports::foo::foo::export_using_export1::GuestIndices::new( + _component, + )?; + let interface3 = exports::foo::foo::export_using_export2::GuestIndices::new( + _component, + )?; + Ok(WIndices { + interface0, + interface1, + interface2, + interface3, + }) + } + /// Creates a new instance of [`WIndices`] from an + /// instantiated component. + /// + /// This method of creating a [`W`] will perform string + /// lookups for all exports when this method is called. This + /// will only succeed if the provided instance matches the + /// requirements of [`W`]. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = exports::foo::foo::simple_export::GuestIndices::new_instance( + &mut store, + _instance, + )?; + let interface1 = exports::foo::foo::export_using_import::GuestIndices::new_instance( + &mut store, + _instance, + )?; + let interface2 = exports::foo::foo::export_using_export1::GuestIndices::new_instance( + &mut store, + _instance, + )?; + let interface3 = exports::foo::foo::export_using_export2::GuestIndices::new_instance( + &mut store, + _instance, + )?; + Ok(WIndices { + interface0, + interface1, + interface2, + interface3, + }) + } + /// Uses the indices stored in `self` to load an instance + /// of [`W`] from the instance provided. + /// + /// Note that at this time this method will additionally + /// perform type-checks of all exports. + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = self.interface0.load(&mut store, &_instance)?; + let interface1 = self.interface1.load(&mut store, &_instance)?; + let interface2 = self.interface2.load(&mut store, &_instance)?; + let interface3 = self.interface3.load(&mut store, &_instance)?; + Ok(W { + interface0, + interface1, + interface2, + interface3, + }) + } + } + impl W { + /// Convenience wrapper around [`WPre::new`] and + /// [`WPre::instantiate_async`]. + pub async fn instantiate_async<_T>( + mut store: impl wasmtime::AsContextMut, + component: &wasmtime::component::Component, + linker: &wasmtime::component::Linker<_T>, + ) -> wasmtime::Result + where + _T: Send, + { + let pre = linker.instantiate_pre(component)?; + WPre::new(pre)?.instantiate_async(store).await + } + /// Convenience wrapper around [`WIndices::new_instance`] and + /// [`WIndices::load`]. + pub fn new( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let indices = WIndices::new_instance(&mut store, instance)?; + indices.load(store, instance) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + T: Send, + U: foo::foo::transitive_import::Host + Send, + { + foo::foo::transitive_import::add_to_linker(linker, get)?; + Ok(()) + } + pub fn foo_foo_simple_export(&self) -> &exports::foo::foo::simple_export::Guest { + &self.interface0 + } + pub fn foo_foo_export_using_import( + &self, + ) -> &exports::foo::foo::export_using_import::Guest { + &self.interface1 + } + pub fn foo_foo_export_using_export1( + &self, + ) -> &exports::foo::foo::export_using_export1::Guest { + &self.interface2 + } + pub fn foo_foo_export_using_export2( + &self, + ) -> &exports::foo::foo::export_using_export2::Guest { + &self.interface3 + } + } +}; +pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod transitive_import { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + pub enum Y {} + #[wasmtime::component::__internal::async_trait] + pub trait HostY { + async fn drop( + &mut self, + rep: wasmtime::component::Resource, + ) -> wasmtime::Result<()>; + } + #[wasmtime::component::__internal::async_trait] + impl<_T: HostY + ?Sized + Send> HostY for &mut _T { + async fn drop( + &mut self, + rep: wasmtime::component::Resource, + ) -> wasmtime::Result<()> { + HostY::drop(*self, rep).await + } + } + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send + HostY {} + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("foo:foo/transitive-import")?; + inst.resource_async( + "y", + wasmtime::component::ResourceType::host::(), + move |mut store, rep| { + std::boxed::Box::new(async move { + HostY::drop( + &mut host_getter(store.data_mut()), + wasmtime::component::Resource::new_own(rep), + ) + .await + }) + }, + )?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T {} + } + } +} +pub mod exports { + pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod simple_export { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + pub type A = wasmtime::component::ResourceAny; + pub struct GuestA<'a> { + funcs: &'a Guest, + } + pub struct Guest { + constructor_a_constructor: wasmtime::component::Func, + static_a_static_a: wasmtime::component::Func, + method_a_method_a: wasmtime::component::Func, + } + #[derive(Clone)] + pub struct GuestIndices { + constructor_a_constructor: wasmtime::component::ComponentExportIndex, + static_a_static_a: wasmtime::component::ComponentExportIndex, + method_a_method_a: wasmtime::component::ComponentExportIndex, + } + impl GuestIndices { + /// Constructor for [`GuestIndices`] which takes a + /// [`Component`](wasmtime::component::Component) as input and can be executed + /// before instantiation. + /// + /// This constructor can be used to front-load string lookups to find exports + /// within a component. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let (_, instance) = component + .export_index(None, "foo:foo/simple-export") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/simple-export`" + ) + })?; + Self::_new(|name| { + component.export_index(Some(&instance), name).map(|p| p.1) + }) + } + /// This constructor is similar to [`GuestIndices::new`] except that it + /// performs string lookups after instantiation time. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let instance_export = instance + .get_export(&mut store, None, "foo:foo/simple-export") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/simple-export`" + ) + })?; + Self::_new(|name| { + instance.get_export(&mut store, Some(&instance_export), name) + }) + } + fn _new( + mut lookup: impl FnMut( + &str, + ) -> Option, + ) -> wasmtime::Result { + let mut lookup = move |name| { + lookup(name) + .ok_or_else(|| { + anyhow::anyhow!( + "instance export `foo:foo/simple-export` does \ + not have export `{name}`" + ) + }) + }; + let _ = &mut lookup; + let constructor_a_constructor = lookup("[constructor]a")?; + let static_a_static_a = lookup("[static]a.static-a")?; + let method_a_method_a = lookup("[method]a.method-a")?; + Ok(GuestIndices { + constructor_a_constructor, + static_a_static_a, + method_a_method_a, + }) + } + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let mut store = store.as_context_mut(); + let _ = &mut store; + let _instance = instance; + let constructor_a_constructor = *_instance + .get_typed_func::< + (), + (wasmtime::component::ResourceAny,), + >(&mut store, &self.constructor_a_constructor)? + .func(); + let static_a_static_a = *_instance + .get_typed_func::< + (), + (u32,), + >(&mut store, &self.static_a_static_a)? + .func(); + let method_a_method_a = *_instance + .get_typed_func::< + (wasmtime::component::ResourceAny,), + (u32,), + >(&mut store, &self.method_a_method_a)? + .func(); + Ok(Guest { + constructor_a_constructor, + static_a_static_a, + method_a_method_a, + }) + } + } + impl Guest { + pub fn a(&self) -> GuestA<'_> { + GuestA { funcs: self } + } + } + impl GuestA<'_> { + pub async fn call_constructor( + &self, + mut store: S, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/simple-export", function = "[constructor]a", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (wasmtime::component::ResourceAny,), + >::new_unchecked(self.funcs.constructor_a_constructor) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_static_a( + &self, + mut store: S, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/simple-export", function = "[static]a.static-a", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (u32,), + >::new_unchecked(self.funcs.static_a_static_a) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_method_a( + &self, + mut store: S, + arg0: wasmtime::component::ResourceAny, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/simple-export", function = "[method]a.method-a", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (wasmtime::component::ResourceAny,), + (u32,), + >::new_unchecked(self.funcs.method_a_method_a) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + } + } + #[allow(clippy::all)] + pub mod export_using_import { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + pub type Y = super::super::super::super::foo::foo::transitive_import::Y; + pub type A = wasmtime::component::ResourceAny; + pub struct GuestA<'a> { + funcs: &'a Guest, + } + pub struct Guest { + constructor_a_constructor: wasmtime::component::Func, + static_a_static_a: wasmtime::component::Func, + method_a_method_a: wasmtime::component::Func, + } + #[derive(Clone)] + pub struct GuestIndices { + constructor_a_constructor: wasmtime::component::ComponentExportIndex, + static_a_static_a: wasmtime::component::ComponentExportIndex, + method_a_method_a: wasmtime::component::ComponentExportIndex, + } + impl GuestIndices { + /// Constructor for [`GuestIndices`] which takes a + /// [`Component`](wasmtime::component::Component) as input and can be executed + /// before instantiation. + /// + /// This constructor can be used to front-load string lookups to find exports + /// within a component. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let (_, instance) = component + .export_index(None, "foo:foo/export-using-import") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/export-using-import`" + ) + })?; + Self::_new(|name| { + component.export_index(Some(&instance), name).map(|p| p.1) + }) + } + /// This constructor is similar to [`GuestIndices::new`] except that it + /// performs string lookups after instantiation time. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let instance_export = instance + .get_export(&mut store, None, "foo:foo/export-using-import") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/export-using-import`" + ) + })?; + Self::_new(|name| { + instance.get_export(&mut store, Some(&instance_export), name) + }) + } + fn _new( + mut lookup: impl FnMut( + &str, + ) -> Option, + ) -> wasmtime::Result { + let mut lookup = move |name| { + lookup(name) + .ok_or_else(|| { + anyhow::anyhow!( + "instance export `foo:foo/export-using-import` does \ + not have export `{name}`" + ) + }) + }; + let _ = &mut lookup; + let constructor_a_constructor = lookup("[constructor]a")?; + let static_a_static_a = lookup("[static]a.static-a")?; + let method_a_method_a = lookup("[method]a.method-a")?; + Ok(GuestIndices { + constructor_a_constructor, + static_a_static_a, + method_a_method_a, + }) + } + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let mut store = store.as_context_mut(); + let _ = &mut store; + let _instance = instance; + let constructor_a_constructor = *_instance + .get_typed_func::< + (wasmtime::component::Resource,), + (wasmtime::component::ResourceAny,), + >(&mut store, &self.constructor_a_constructor)? + .func(); + let static_a_static_a = *_instance + .get_typed_func::< + (), + (wasmtime::component::Resource,), + >(&mut store, &self.static_a_static_a)? + .func(); + let method_a_method_a = *_instance + .get_typed_func::< + ( + wasmtime::component::ResourceAny, + wasmtime::component::Resource, + ), + (wasmtime::component::Resource,), + >(&mut store, &self.method_a_method_a)? + .func(); + Ok(Guest { + constructor_a_constructor, + static_a_static_a, + method_a_method_a, + }) + } + } + impl Guest { + pub fn a(&self) -> GuestA<'_> { + GuestA { funcs: self } + } + } + impl GuestA<'_> { + pub async fn call_constructor( + &self, + mut store: S, + arg0: wasmtime::component::Resource, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/export-using-import", function = "[constructor]a", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (wasmtime::component::Resource,), + (wasmtime::component::ResourceAny,), + >::new_unchecked(self.funcs.constructor_a_constructor) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_static_a( + &self, + mut store: S, + ) -> wasmtime::Result> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/export-using-import", function = + "[static]a.static-a", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (wasmtime::component::Resource,), + >::new_unchecked(self.funcs.static_a_static_a) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_method_a( + &self, + mut store: S, + arg0: wasmtime::component::ResourceAny, + arg1: wasmtime::component::Resource, + ) -> wasmtime::Result> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/export-using-import", function = + "[method]a.method-a", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + ( + wasmtime::component::ResourceAny, + wasmtime::component::Resource, + ), + (wasmtime::component::Resource,), + >::new_unchecked(self.funcs.method_a_method_a) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), (arg0, arg1)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + } + } + #[allow(clippy::all)] + pub mod export_using_export1 { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + pub type A = wasmtime::component::ResourceAny; + pub struct GuestA<'a> { + funcs: &'a Guest, + } + pub struct Guest { + constructor_a_constructor: wasmtime::component::Func, + } + #[derive(Clone)] + pub struct GuestIndices { + constructor_a_constructor: wasmtime::component::ComponentExportIndex, + } + impl GuestIndices { + /// Constructor for [`GuestIndices`] which takes a + /// [`Component`](wasmtime::component::Component) as input and can be executed + /// before instantiation. + /// + /// This constructor can be used to front-load string lookups to find exports + /// within a component. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let (_, instance) = component + .export_index(None, "foo:foo/export-using-export1") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/export-using-export1`" + ) + })?; + Self::_new(|name| { + component.export_index(Some(&instance), name).map(|p| p.1) + }) + } + /// This constructor is similar to [`GuestIndices::new`] except that it + /// performs string lookups after instantiation time. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let instance_export = instance + .get_export(&mut store, None, "foo:foo/export-using-export1") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/export-using-export1`" + ) + })?; + Self::_new(|name| { + instance.get_export(&mut store, Some(&instance_export), name) + }) + } + fn _new( + mut lookup: impl FnMut( + &str, + ) -> Option, + ) -> wasmtime::Result { + let mut lookup = move |name| { + lookup(name) + .ok_or_else(|| { + anyhow::anyhow!( + "instance export `foo:foo/export-using-export1` does \ + not have export `{name}`" + ) + }) + }; + let _ = &mut lookup; + let constructor_a_constructor = lookup("[constructor]a")?; + Ok(GuestIndices { + constructor_a_constructor, + }) + } + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let mut store = store.as_context_mut(); + let _ = &mut store; + let _instance = instance; + let constructor_a_constructor = *_instance + .get_typed_func::< + (), + (wasmtime::component::ResourceAny,), + >(&mut store, &self.constructor_a_constructor)? + .func(); + Ok(Guest { constructor_a_constructor }) + } + } + impl Guest { + pub fn a(&self) -> GuestA<'_> { + GuestA { funcs: self } + } + } + impl GuestA<'_> { + pub async fn call_constructor( + &self, + mut store: S, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/export-using-export1", function = "[constructor]a", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (wasmtime::component::ResourceAny,), + >::new_unchecked(self.funcs.constructor_a_constructor) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + } + } + #[allow(clippy::all)] + pub mod export_using_export2 { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + pub type A = super::super::super::super::exports::foo::foo::export_using_export1::A; + pub type B = wasmtime::component::ResourceAny; + pub struct GuestB<'a> { + funcs: &'a Guest, + } + pub struct Guest { + constructor_b_constructor: wasmtime::component::Func, + } + #[derive(Clone)] + pub struct GuestIndices { + constructor_b_constructor: wasmtime::component::ComponentExportIndex, + } + impl GuestIndices { + /// Constructor for [`GuestIndices`] which takes a + /// [`Component`](wasmtime::component::Component) as input and can be executed + /// before instantiation. + /// + /// This constructor can be used to front-load string lookups to find exports + /// within a component. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let (_, instance) = component + .export_index(None, "foo:foo/export-using-export2") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/export-using-export2`" + ) + })?; + Self::_new(|name| { + component.export_index(Some(&instance), name).map(|p| p.1) + }) + } + /// This constructor is similar to [`GuestIndices::new`] except that it + /// performs string lookups after instantiation time. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let instance_export = instance + .get_export(&mut store, None, "foo:foo/export-using-export2") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/export-using-export2`" + ) + })?; + Self::_new(|name| { + instance.get_export(&mut store, Some(&instance_export), name) + }) + } + fn _new( + mut lookup: impl FnMut( + &str, + ) -> Option, + ) -> wasmtime::Result { + let mut lookup = move |name| { + lookup(name) + .ok_or_else(|| { + anyhow::anyhow!( + "instance export `foo:foo/export-using-export2` does \ + not have export `{name}`" + ) + }) + }; + let _ = &mut lookup; + let constructor_b_constructor = lookup("[constructor]b")?; + Ok(GuestIndices { + constructor_b_constructor, + }) + } + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let mut store = store.as_context_mut(); + let _ = &mut store; + let _instance = instance; + let constructor_b_constructor = *_instance + .get_typed_func::< + (wasmtime::component::ResourceAny,), + (wasmtime::component::ResourceAny,), + >(&mut store, &self.constructor_b_constructor)? + .func(); + Ok(Guest { constructor_b_constructor }) + } + } + impl Guest { + pub fn b(&self) -> GuestB<'_> { + GuestB { funcs: self } + } + } + impl GuestB<'_> { + pub async fn call_constructor( + &self, + mut store: S, + arg0: wasmtime::component::ResourceAny, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/export-using-export2", function = "[constructor]b", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (wasmtime::component::ResourceAny,), + (wasmtime::component::ResourceAny,), + >::new_unchecked(self.funcs.constructor_b_constructor) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + } + } + } + } +} diff --git a/crates/component-macro/tests/expanded/resources-import_tracing_async.rs b/crates/component-macro/tests/expanded/resources-import_tracing_async.rs new file mode 100644 index 000000000000..33d35ed86a2e --- /dev/null +++ b/crates/component-macro/tests/expanded/resources-import_tracing_async.rs @@ -0,0 +1,1774 @@ +pub enum WorldResource {} +#[wasmtime::component::__internal::async_trait] +pub trait HostWorldResource { + async fn new(&mut self) -> wasmtime::component::Resource; + async fn foo(&mut self, self_: wasmtime::component::Resource) -> (); + async fn static_foo(&mut self) -> (); + async fn drop( + &mut self, + rep: wasmtime::component::Resource, + ) -> wasmtime::Result<()>; +} +#[wasmtime::component::__internal::async_trait] +impl<_T: HostWorldResource + ?Sized + Send> HostWorldResource for &mut _T { + async fn new(&mut self) -> wasmtime::component::Resource { + HostWorldResource::new(*self).await + } + async fn foo(&mut self, self_: wasmtime::component::Resource) -> () { + HostWorldResource::foo(*self, self_).await + } + async fn static_foo(&mut self) -> () { + HostWorldResource::static_foo(*self).await + } + async fn drop( + &mut self, + rep: wasmtime::component::Resource, + ) -> wasmtime::Result<()> { + HostWorldResource::drop(*self, rep).await + } +} +/// Auto-generated bindings for a pre-instantiated version of a +/// component which implements the world `the-world`. +/// +/// This structure is created through [`TheWorldPre::new`] which +/// takes a [`InstancePre`](wasmtime::component::InstancePre) that +/// has been created through a [`Linker`](wasmtime::component::Linker). +/// +/// For more information see [`TheWorld`] as well. +pub struct TheWorldPre { + instance_pre: wasmtime::component::InstancePre, + indices: TheWorldIndices, +} +impl Clone for TheWorldPre { + fn clone(&self) -> Self { + Self { + instance_pre: self.instance_pre.clone(), + indices: self.indices.clone(), + } + } +} +impl<_T> TheWorldPre<_T> { + /// Creates a new copy of `TheWorldPre` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component behind `instance_pre` + /// does not have the required exports. + pub fn new( + instance_pre: wasmtime::component::InstancePre<_T>, + ) -> wasmtime::Result { + let indices = TheWorldIndices::new(instance_pre.component())?; + Ok(Self { instance_pre, indices }) + } + pub fn engine(&self) -> &wasmtime::Engine { + self.instance_pre.engine() + } + pub fn instance_pre(&self) -> &wasmtime::component::InstancePre<_T> { + &self.instance_pre + } + /// Instantiates a new instance of [`TheWorld`] within the + /// `store` provided. + /// + /// This function will use `self` as the pre-instantiated + /// instance to perform instantiation. Afterwards the preloaded + /// indices in `self` are used to lookup all exports on the + /// resulting instance. + pub async fn instantiate_async( + &self, + mut store: impl wasmtime::AsContextMut, + ) -> wasmtime::Result + where + _T: Send, + { + let mut store = store.as_context_mut(); + let instance = self.instance_pre.instantiate_async(&mut store).await?; + self.indices.load(&mut store, &instance) + } +} +/// Auto-generated bindings for index of the exports of +/// `the-world`. +/// +/// This is an implementation detail of [`TheWorldPre`] and can +/// be constructed if needed as well. +/// +/// For more information see [`TheWorld`] as well. +#[derive(Clone)] +pub struct TheWorldIndices { + interface1: exports::foo::foo::uses_resource_transitively::GuestIndices, + some_world_func2: wasmtime::component::ComponentExportIndex, +} +/// Auto-generated bindings for an instance a component which +/// implements the world `the-world`. +/// +/// This structure can be created through a number of means +/// depending on your requirements and what you have on hand: +/// +/// * The most convenient way is to use +/// [`TheWorld::instantiate_async`] which only needs a +/// [`Store`], [`Component`], and [`Linker`]. +/// +/// * Alternatively you can create a [`TheWorldPre`] ahead of +/// time with a [`Component`] to front-load string lookups +/// of exports once instead of per-instantiation. This +/// method then uses [`TheWorldPre::instantiate_async`] to +/// create a [`TheWorld`]. +/// +/// * If you've instantiated the instance yourself already +/// then you can use [`TheWorld::new`]. +/// +/// * You can also access the guts of instantiation through +/// [`TheWorldIndices::new_instance`] followed +/// by [`TheWorldIndices::load`] to crate an instance of this +/// type. +/// +/// These methods are all equivalent to one another and move +/// around the tradeoff of what work is performed when. +/// +/// [`Store`]: wasmtime::Store +/// [`Component`]: wasmtime::component::Component +/// [`Linker`]: wasmtime::component::Linker +pub struct TheWorld { + interface1: exports::foo::foo::uses_resource_transitively::Guest, + some_world_func2: wasmtime::component::Func, +} +#[wasmtime::component::__internal::async_trait] +pub trait TheWorldImports: Send + HostWorldResource { + async fn some_world_func(&mut self) -> wasmtime::component::Resource; +} +pub trait TheWorldImportsGetHost< + T, +>: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: TheWorldImports; +} +impl TheWorldImportsGetHost for F +where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: TheWorldImports, +{ + type Host = O; +} +#[wasmtime::component::__internal::async_trait] +impl<_T: TheWorldImports + ?Sized + Send> TheWorldImports for &mut _T { + async fn some_world_func(&mut self) -> wasmtime::component::Resource { + TheWorldImports::some_world_func(*self).await + } +} +const _: () = { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + impl TheWorldIndices { + /// Creates a new copy of `TheWorldIndices` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component does not have the + /// required exports. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let _component = component; + let interface1 = exports::foo::foo::uses_resource_transitively::GuestIndices::new( + _component, + )?; + let some_world_func2 = _component + .export_index(None, "some-world-func2") + .ok_or_else(|| { + anyhow::anyhow!("no function export `some-world-func2` found") + })? + .1; + Ok(TheWorldIndices { + interface1, + some_world_func2, + }) + } + /// Creates a new instance of [`TheWorldIndices`] from an + /// instantiated component. + /// + /// This method of creating a [`TheWorld`] will perform string + /// lookups for all exports when this method is called. This + /// will only succeed if the provided instance matches the + /// requirements of [`TheWorld`]. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface1 = exports::foo::foo::uses_resource_transitively::GuestIndices::new_instance( + &mut store, + _instance, + )?; + let some_world_func2 = _instance + .get_export(&mut store, None, "some-world-func2") + .ok_or_else(|| { + anyhow::anyhow!("no function export `some-world-func2` found") + })?; + Ok(TheWorldIndices { + interface1, + some_world_func2, + }) + } + /// Uses the indices stored in `self` to load an instance + /// of [`TheWorld`] from the instance provided. + /// + /// Note that at this time this method will additionally + /// perform type-checks of all exports. + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface1 = self.interface1.load(&mut store, &_instance)?; + let some_world_func2 = *_instance + .get_typed_func::< + (), + (wasmtime::component::Resource,), + >(&mut store, &self.some_world_func2)? + .func(); + Ok(TheWorld { + interface1, + some_world_func2, + }) + } + } + impl TheWorld { + /// Convenience wrapper around [`TheWorldPre::new`] and + /// [`TheWorldPre::instantiate_async`]. + pub async fn instantiate_async<_T>( + mut store: impl wasmtime::AsContextMut, + component: &wasmtime::component::Component, + linker: &wasmtime::component::Linker<_T>, + ) -> wasmtime::Result + where + _T: Send, + { + let pre = linker.instantiate_pre(component)?; + TheWorldPre::new(pre)?.instantiate_async(store).await + } + /// Convenience wrapper around [`TheWorldIndices::new_instance`] and + /// [`TheWorldIndices::load`]. + pub fn new( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let indices = TheWorldIndices::new_instance(&mut store, instance)?; + indices.load(store, instance) + } + pub fn add_to_linker_imports_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> TheWorldImportsGetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut linker = linker.root(); + linker + .resource_async( + "world-resource", + wasmtime::component::ResourceType::host::(), + move |mut store, rep| { + std::boxed::Box::new(async move { + HostWorldResource::drop( + &mut host_getter(store.data_mut()), + wasmtime::component::Resource::new_own(rep), + ) + .await + }) + }, + )?; + linker + .func_wrap_async( + "[constructor]world-resource", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "the-world", function = "[constructor]world-resource", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = HostWorldResource::new(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + linker + .func_wrap_async( + "[method]world-resource.foo", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (wasmtime::component::Resource,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "the-world", function = "[method]world-resource.foo", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, self_ = tracing::field::debug(& + arg0), "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = HostWorldResource::foo(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + linker + .func_wrap_async( + "[static]world-resource.static-foo", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "the-world", function = "[static]world-resource.static-foo", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = HostWorldResource::static_foo(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + linker + .func_wrap_async( + "some-world-func", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "the-world", function = "some-world-func", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = TheWorldImports::some_world_func(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + T: Send, + U: foo::foo::resources::Host + foo::foo::long_use_chain1::Host + + foo::foo::long_use_chain2::Host + foo::foo::long_use_chain3::Host + + foo::foo::long_use_chain4::Host + + foo::foo::transitive_interface_with_resource::Host + TheWorldImports + + Send, + { + Self::add_to_linker_imports_get_host(linker, get)?; + foo::foo::resources::add_to_linker(linker, get)?; + foo::foo::long_use_chain1::add_to_linker(linker, get)?; + foo::foo::long_use_chain2::add_to_linker(linker, get)?; + foo::foo::long_use_chain3::add_to_linker(linker, get)?; + foo::foo::long_use_chain4::add_to_linker(linker, get)?; + foo::foo::transitive_interface_with_resource::add_to_linker(linker, get)?; + Ok(()) + } + pub async fn call_some_world_func2( + &self, + mut store: S, + ) -> wasmtime::Result> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = "default", function + = "some-world-func2", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (wasmtime::component::Resource,), + >::new_unchecked(self.some_world_func2) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee.post_return_async(store.as_context_mut()).instrument(span).await?; + Ok(ret0) + } + pub fn foo_foo_uses_resource_transitively( + &self, + ) -> &exports::foo::foo::uses_resource_transitively::Guest { + &self.interface1 + } + } +}; +pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod resources { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + pub enum Bar {} + #[wasmtime::component::__internal::async_trait] + pub trait HostBar { + async fn new(&mut self) -> wasmtime::component::Resource; + async fn static_a(&mut self) -> u32; + async fn method_a( + &mut self, + self_: wasmtime::component::Resource, + ) -> u32; + async fn drop( + &mut self, + rep: wasmtime::component::Resource, + ) -> wasmtime::Result<()>; + } + #[wasmtime::component::__internal::async_trait] + impl<_T: HostBar + ?Sized + Send> HostBar for &mut _T { + async fn new(&mut self) -> wasmtime::component::Resource { + HostBar::new(*self).await + } + async fn static_a(&mut self) -> u32 { + HostBar::static_a(*self).await + } + async fn method_a( + &mut self, + self_: wasmtime::component::Resource, + ) -> u32 { + HostBar::method_a(*self, self_).await + } + async fn drop( + &mut self, + rep: wasmtime::component::Resource, + ) -> wasmtime::Result<()> { + HostBar::drop(*self, rep).await + } + } + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(record)] + pub struct NestedOwn { + #[component(name = "nested-bar")] + pub nested_bar: wasmtime::component::Resource, + } + impl core::fmt::Debug for NestedOwn { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("NestedOwn") + .field("nested-bar", &self.nested_bar) + .finish() + } + } + const _: () = { + assert!( + 4 == < NestedOwn as wasmtime::component::ComponentType >::SIZE32 + ); + assert!( + 4 == < NestedOwn as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(record)] + pub struct NestedBorrow { + #[component(name = "nested-bar")] + pub nested_bar: wasmtime::component::Resource, + } + impl core::fmt::Debug for NestedBorrow { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("NestedBorrow") + .field("nested-bar", &self.nested_bar) + .finish() + } + } + const _: () = { + assert!( + 4 == < NestedBorrow as wasmtime::component::ComponentType >::SIZE32 + ); + assert!( + 4 == < NestedBorrow as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + pub type SomeHandle = wasmtime::component::Resource; + const _: () = { + assert!( + 4 == < SomeHandle as wasmtime::component::ComponentType >::SIZE32 + ); + assert!( + 4 == < SomeHandle as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send + HostBar { + async fn bar_own_arg( + &mut self, + x: wasmtime::component::Resource, + ) -> (); + async fn bar_borrow_arg( + &mut self, + x: wasmtime::component::Resource, + ) -> (); + async fn bar_result(&mut self) -> wasmtime::component::Resource; + async fn tuple_own_arg( + &mut self, + x: (wasmtime::component::Resource, u32), + ) -> (); + async fn tuple_borrow_arg( + &mut self, + x: (wasmtime::component::Resource, u32), + ) -> (); + async fn tuple_result( + &mut self, + ) -> (wasmtime::component::Resource, u32); + async fn option_own_arg( + &mut self, + x: Option>, + ) -> (); + async fn option_borrow_arg( + &mut self, + x: Option>, + ) -> (); + async fn option_result( + &mut self, + ) -> Option>; + async fn result_own_arg( + &mut self, + x: Result, ()>, + ) -> (); + async fn result_borrow_arg( + &mut self, + x: Result, ()>, + ) -> (); + async fn result_result( + &mut self, + ) -> Result, ()>; + async fn list_own_arg( + &mut self, + x: wasmtime::component::__internal::Vec< + wasmtime::component::Resource, + >, + ) -> (); + async fn list_borrow_arg( + &mut self, + x: wasmtime::component::__internal::Vec< + wasmtime::component::Resource, + >, + ) -> (); + async fn list_result( + &mut self, + ) -> wasmtime::component::__internal::Vec< + wasmtime::component::Resource, + >; + async fn record_own_arg(&mut self, x: NestedOwn) -> (); + async fn record_borrow_arg(&mut self, x: NestedBorrow) -> (); + async fn record_result(&mut self) -> NestedOwn; + async fn func_with_handle_typedef(&mut self, x: SomeHandle) -> (); + } + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("foo:foo/resources")?; + inst.resource_async( + "bar", + wasmtime::component::ResourceType::host::(), + move |mut store, rep| { + std::boxed::Box::new(async move { + HostBar::drop( + &mut host_getter(store.data_mut()), + wasmtime::component::Resource::new_own(rep), + ) + .await + }) + }, + )?; + inst.func_wrap_async( + "[constructor]bar", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "resources", function = "[constructor]bar", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = HostBar::new(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "[static]bar.static-a", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "resources", function = "[static]bar.static-a", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = HostBar::static_a(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "[method]bar.method-a", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (wasmtime::component::Resource,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "resources", function = "[method]bar.method-a", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, self_ = tracing::field::debug(& + arg0), "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = HostBar::method_a(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "bar-own-arg", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (wasmtime::component::Resource,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "resources", function = "bar-own-arg", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::bar_own_arg(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "bar-borrow-arg", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (wasmtime::component::Resource,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "resources", function = "bar-borrow-arg", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::bar_borrow_arg(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "bar-result", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "resources", function = "bar-result", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::bar_result(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "tuple-own-arg", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): ((wasmtime::component::Resource, u32),)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "resources", function = "tuple-own-arg", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::tuple_own_arg(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "tuple-borrow-arg", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): ((wasmtime::component::Resource, u32),)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "resources", function = "tuple-borrow-arg", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::tuple_borrow_arg(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "tuple-result", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "resources", function = "tuple-result", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::tuple_result(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "option-own-arg", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (Option>,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "resources", function = "option-own-arg", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::option_own_arg(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "option-borrow-arg", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (Option>,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "resources", function = "option-borrow-arg", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::option_borrow_arg(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "option-result", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "resources", function = "option-result", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::option_result(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "result-own-arg", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (Result, ()>,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "resources", function = "result-own-arg", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::result_own_arg(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "result-borrow-arg", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (Result, ()>,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "resources", function = "result-borrow-arg", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::result_borrow_arg(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "result-result", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "resources", function = "result-result", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::result_result(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "list-own-arg", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + ( + arg0, + ): ( + wasmtime::component::__internal::Vec< + wasmtime::component::Resource, + >, + )| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "resources", function = "list-own-arg", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::list_own_arg(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "list-borrow-arg", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + ( + arg0, + ): ( + wasmtime::component::__internal::Vec< + wasmtime::component::Resource, + >, + )| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "resources", function = "list-borrow-arg", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::list_borrow_arg(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "list-result", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "resources", function = "list-result", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::list_result(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "record-own-arg", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (NestedOwn,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "resources", function = "record-own-arg", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::record_own_arg(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "record-borrow-arg", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (NestedBorrow,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "resources", function = "record-borrow-arg", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::record_borrow_arg(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "record-result", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "resources", function = "record-result", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::record_result(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "func-with-handle-typedef", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (SomeHandle,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "resources", function = "func-with-handle-typedef", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::func_with_handle_typedef(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn bar_own_arg( + &mut self, + x: wasmtime::component::Resource, + ) -> () { + Host::bar_own_arg(*self, x).await + } + async fn bar_borrow_arg( + &mut self, + x: wasmtime::component::Resource, + ) -> () { + Host::bar_borrow_arg(*self, x).await + } + async fn bar_result(&mut self) -> wasmtime::component::Resource { + Host::bar_result(*self).await + } + async fn tuple_own_arg( + &mut self, + x: (wasmtime::component::Resource, u32), + ) -> () { + Host::tuple_own_arg(*self, x).await + } + async fn tuple_borrow_arg( + &mut self, + x: (wasmtime::component::Resource, u32), + ) -> () { + Host::tuple_borrow_arg(*self, x).await + } + async fn tuple_result( + &mut self, + ) -> (wasmtime::component::Resource, u32) { + Host::tuple_result(*self).await + } + async fn option_own_arg( + &mut self, + x: Option>, + ) -> () { + Host::option_own_arg(*self, x).await + } + async fn option_borrow_arg( + &mut self, + x: Option>, + ) -> () { + Host::option_borrow_arg(*self, x).await + } + async fn option_result( + &mut self, + ) -> Option> { + Host::option_result(*self).await + } + async fn result_own_arg( + &mut self, + x: Result, ()>, + ) -> () { + Host::result_own_arg(*self, x).await + } + async fn result_borrow_arg( + &mut self, + x: Result, ()>, + ) -> () { + Host::result_borrow_arg(*self, x).await + } + async fn result_result( + &mut self, + ) -> Result, ()> { + Host::result_result(*self).await + } + async fn list_own_arg( + &mut self, + x: wasmtime::component::__internal::Vec< + wasmtime::component::Resource, + >, + ) -> () { + Host::list_own_arg(*self, x).await + } + async fn list_borrow_arg( + &mut self, + x: wasmtime::component::__internal::Vec< + wasmtime::component::Resource, + >, + ) -> () { + Host::list_borrow_arg(*self, x).await + } + async fn list_result( + &mut self, + ) -> wasmtime::component::__internal::Vec< + wasmtime::component::Resource, + > { + Host::list_result(*self).await + } + async fn record_own_arg(&mut self, x: NestedOwn) -> () { + Host::record_own_arg(*self, x).await + } + async fn record_borrow_arg(&mut self, x: NestedBorrow) -> () { + Host::record_borrow_arg(*self, x).await + } + async fn record_result(&mut self) -> NestedOwn { + Host::record_result(*self).await + } + async fn func_with_handle_typedef(&mut self, x: SomeHandle) -> () { + Host::func_with_handle_typedef(*self, x).await + } + } + } + #[allow(clippy::all)] + pub mod long_use_chain1 { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + pub enum A {} + #[wasmtime::component::__internal::async_trait] + pub trait HostA { + async fn drop( + &mut self, + rep: wasmtime::component::Resource, + ) -> wasmtime::Result<()>; + } + #[wasmtime::component::__internal::async_trait] + impl<_T: HostA + ?Sized + Send> HostA for &mut _T { + async fn drop( + &mut self, + rep: wasmtime::component::Resource, + ) -> wasmtime::Result<()> { + HostA::drop(*self, rep).await + } + } + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send + HostA {} + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("foo:foo/long-use-chain1")?; + inst.resource_async( + "a", + wasmtime::component::ResourceType::host::(), + move |mut store, rep| { + std::boxed::Box::new(async move { + HostA::drop( + &mut host_getter(store.data_mut()), + wasmtime::component::Resource::new_own(rep), + ) + .await + }) + }, + )?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T {} + } + #[allow(clippy::all)] + pub mod long_use_chain2 { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + pub type A = super::super::super::foo::foo::long_use_chain1::A; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send {} + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("foo:foo/long-use-chain2")?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T {} + } + #[allow(clippy::all)] + pub mod long_use_chain3 { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + pub type A = super::super::super::foo::foo::long_use_chain2::A; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send {} + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("foo:foo/long-use-chain3")?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T {} + } + #[allow(clippy::all)] + pub mod long_use_chain4 { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + pub type A = super::super::super::foo::foo::long_use_chain3::A; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send { + async fn foo(&mut self) -> wasmtime::component::Resource; + } + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("foo:foo/long-use-chain4")?; + inst.func_wrap_async( + "foo", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "long-use-chain4", function = "foo", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::foo(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn foo(&mut self) -> wasmtime::component::Resource { + Host::foo(*self).await + } + } + } + #[allow(clippy::all)] + pub mod transitive_interface_with_resource { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + pub enum Foo {} + #[wasmtime::component::__internal::async_trait] + pub trait HostFoo { + async fn drop( + &mut self, + rep: wasmtime::component::Resource, + ) -> wasmtime::Result<()>; + } + #[wasmtime::component::__internal::async_trait] + impl<_T: HostFoo + ?Sized + Send> HostFoo for &mut _T { + async fn drop( + &mut self, + rep: wasmtime::component::Resource, + ) -> wasmtime::Result<()> { + HostFoo::drop(*self, rep).await + } + } + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send + HostFoo {} + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker + .instance("foo:foo/transitive-interface-with-resource")?; + inst.resource_async( + "foo", + wasmtime::component::ResourceType::host::(), + move |mut store, rep| { + std::boxed::Box::new(async move { + HostFoo::drop( + &mut host_getter(store.data_mut()), + wasmtime::component::Resource::new_own(rep), + ) + .await + }) + }, + )?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T {} + } + } +} +pub mod exports { + pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod uses_resource_transitively { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + pub type Foo = super::super::super::super::foo::foo::transitive_interface_with_resource::Foo; + pub struct Guest { + handle: wasmtime::component::Func, + } + #[derive(Clone)] + pub struct GuestIndices { + handle: wasmtime::component::ComponentExportIndex, + } + impl GuestIndices { + /// Constructor for [`GuestIndices`] which takes a + /// [`Component`](wasmtime::component::Component) as input and can be executed + /// before instantiation. + /// + /// This constructor can be used to front-load string lookups to find exports + /// within a component. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let (_, instance) = component + .export_index(None, "foo:foo/uses-resource-transitively") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/uses-resource-transitively`" + ) + })?; + Self::_new(|name| { + component.export_index(Some(&instance), name).map(|p| p.1) + }) + } + /// This constructor is similar to [`GuestIndices::new`] except that it + /// performs string lookups after instantiation time. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let instance_export = instance + .get_export( + &mut store, + None, + "foo:foo/uses-resource-transitively", + ) + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/uses-resource-transitively`" + ) + })?; + Self::_new(|name| { + instance.get_export(&mut store, Some(&instance_export), name) + }) + } + fn _new( + mut lookup: impl FnMut( + &str, + ) -> Option, + ) -> wasmtime::Result { + let mut lookup = move |name| { + lookup(name) + .ok_or_else(|| { + anyhow::anyhow!( + "instance export `foo:foo/uses-resource-transitively` does \ + not have export `{name}`" + ) + }) + }; + let _ = &mut lookup; + let handle = lookup("handle")?; + Ok(GuestIndices { handle }) + } + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let mut store = store.as_context_mut(); + let _ = &mut store; + let _instance = instance; + let handle = *_instance + .get_typed_func::< + (wasmtime::component::Resource,), + (), + >(&mut store, &self.handle)? + .func(); + Ok(Guest { handle }) + } + } + impl Guest { + pub async fn call_handle( + &self, + mut store: S, + arg0: wasmtime::component::Resource, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/uses-resource-transitively", function = "handle", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (wasmtime::component::Resource,), + (), + >::new_unchecked(self.handle) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + } + } + } + } +} diff --git a/crates/component-macro/tests/expanded/share-types_tracing_async.rs b/crates/component-macro/tests/expanded/share-types_tracing_async.rs new file mode 100644 index 000000000000..67c7eaf1646d --- /dev/null +++ b/crates/component-macro/tests/expanded/share-types_tracing_async.rs @@ -0,0 +1,477 @@ +/// Auto-generated bindings for a pre-instantiated version of a +/// component which implements the world `http-interface`. +/// +/// This structure is created through [`HttpInterfacePre::new`] which +/// takes a [`InstancePre`](wasmtime::component::InstancePre) that +/// has been created through a [`Linker`](wasmtime::component::Linker). +/// +/// For more information see [`HttpInterface`] as well. +pub struct HttpInterfacePre { + instance_pre: wasmtime::component::InstancePre, + indices: HttpInterfaceIndices, +} +impl Clone for HttpInterfacePre { + fn clone(&self) -> Self { + Self { + instance_pre: self.instance_pre.clone(), + indices: self.indices.clone(), + } + } +} +impl<_T> HttpInterfacePre<_T> { + /// Creates a new copy of `HttpInterfacePre` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component behind `instance_pre` + /// does not have the required exports. + pub fn new( + instance_pre: wasmtime::component::InstancePre<_T>, + ) -> wasmtime::Result { + let indices = HttpInterfaceIndices::new(instance_pre.component())?; + Ok(Self { instance_pre, indices }) + } + pub fn engine(&self) -> &wasmtime::Engine { + self.instance_pre.engine() + } + pub fn instance_pre(&self) -> &wasmtime::component::InstancePre<_T> { + &self.instance_pre + } + /// Instantiates a new instance of [`HttpInterface`] within the + /// `store` provided. + /// + /// This function will use `self` as the pre-instantiated + /// instance to perform instantiation. Afterwards the preloaded + /// indices in `self` are used to lookup all exports on the + /// resulting instance. + pub async fn instantiate_async( + &self, + mut store: impl wasmtime::AsContextMut, + ) -> wasmtime::Result + where + _T: Send, + { + let mut store = store.as_context_mut(); + let instance = self.instance_pre.instantiate_async(&mut store).await?; + self.indices.load(&mut store, &instance) + } +} +/// Auto-generated bindings for index of the exports of +/// `http-interface`. +/// +/// This is an implementation detail of [`HttpInterfacePre`] and can +/// be constructed if needed as well. +/// +/// For more information see [`HttpInterface`] as well. +#[derive(Clone)] +pub struct HttpInterfaceIndices { + interface0: exports::http_handler::GuestIndices, +} +/// Auto-generated bindings for an instance a component which +/// implements the world `http-interface`. +/// +/// This structure can be created through a number of means +/// depending on your requirements and what you have on hand: +/// +/// * The most convenient way is to use +/// [`HttpInterface::instantiate_async`] which only needs a +/// [`Store`], [`Component`], and [`Linker`]. +/// +/// * Alternatively you can create a [`HttpInterfacePre`] ahead of +/// time with a [`Component`] to front-load string lookups +/// of exports once instead of per-instantiation. This +/// method then uses [`HttpInterfacePre::instantiate_async`] to +/// create a [`HttpInterface`]. +/// +/// * If you've instantiated the instance yourself already +/// then you can use [`HttpInterface::new`]. +/// +/// * You can also access the guts of instantiation through +/// [`HttpInterfaceIndices::new_instance`] followed +/// by [`HttpInterfaceIndices::load`] to crate an instance of this +/// type. +/// +/// These methods are all equivalent to one another and move +/// around the tradeoff of what work is performed when. +/// +/// [`Store`]: wasmtime::Store +/// [`Component`]: wasmtime::component::Component +/// [`Linker`]: wasmtime::component::Linker +pub struct HttpInterface { + interface0: exports::http_handler::Guest, +} +const _: () = { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + impl HttpInterfaceIndices { + /// Creates a new copy of `HttpInterfaceIndices` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component does not have the + /// required exports. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let _component = component; + let interface0 = exports::http_handler::GuestIndices::new(_component)?; + Ok(HttpInterfaceIndices { interface0 }) + } + /// Creates a new instance of [`HttpInterfaceIndices`] from an + /// instantiated component. + /// + /// This method of creating a [`HttpInterface`] will perform string + /// lookups for all exports when this method is called. This + /// will only succeed if the provided instance matches the + /// requirements of [`HttpInterface`]. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = exports::http_handler::GuestIndices::new_instance( + &mut store, + _instance, + )?; + Ok(HttpInterfaceIndices { interface0 }) + } + /// Uses the indices stored in `self` to load an instance + /// of [`HttpInterface`] from the instance provided. + /// + /// Note that at this time this method will additionally + /// perform type-checks of all exports. + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = self.interface0.load(&mut store, &_instance)?; + Ok(HttpInterface { interface0 }) + } + } + impl HttpInterface { + /// Convenience wrapper around [`HttpInterfacePre::new`] and + /// [`HttpInterfacePre::instantiate_async`]. + pub async fn instantiate_async<_T>( + mut store: impl wasmtime::AsContextMut, + component: &wasmtime::component::Component, + linker: &wasmtime::component::Linker<_T>, + ) -> wasmtime::Result + where + _T: Send, + { + let pre = linker.instantiate_pre(component)?; + HttpInterfacePre::new(pre)?.instantiate_async(store).await + } + /// Convenience wrapper around [`HttpInterfaceIndices::new_instance`] and + /// [`HttpInterfaceIndices::load`]. + pub fn new( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let indices = HttpInterfaceIndices::new_instance(&mut store, instance)?; + indices.load(store, instance) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + T: Send, + U: foo::foo::http_types::Host + http_fetch::Host + Send, + { + foo::foo::http_types::add_to_linker(linker, get)?; + http_fetch::add_to_linker(linker, get)?; + Ok(()) + } + pub fn http_handler(&self) -> &exports::http_handler::Guest { + &self.interface0 + } + } +}; +pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod http_types { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(record)] + #[derive(Clone)] + pub struct Request { + #[component(name = "method")] + pub method: wasmtime::component::__internal::String, + } + impl core::fmt::Debug for Request { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("Request").field("method", &self.method).finish() + } + } + const _: () = { + assert!(8 == < Request as wasmtime::component::ComponentType >::SIZE32); + assert!(4 == < Request as wasmtime::component::ComponentType >::ALIGN32); + }; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(record)] + #[derive(Clone)] + pub struct Response { + #[component(name = "body")] + pub body: wasmtime::component::__internal::String, + } + impl core::fmt::Debug for Response { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("Response").field("body", &self.body).finish() + } + } + const _: () = { + assert!(8 == < Response as wasmtime::component::ComponentType >::SIZE32); + assert!( + 4 == < Response as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send {} + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("foo:foo/http-types")?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T {} + } + } +} +#[allow(clippy::all)] +pub mod http_fetch { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + pub type Request = super::foo::foo::http_types::Request; + const _: () = { + assert!(8 == < Request as wasmtime::component::ComponentType >::SIZE32); + assert!(4 == < Request as wasmtime::component::ComponentType >::ALIGN32); + }; + pub type Response = super::foo::foo::http_types::Response; + const _: () = { + assert!(8 == < Response as wasmtime::component::ComponentType >::SIZE32); + assert!(4 == < Response as wasmtime::component::ComponentType >::ALIGN32); + }; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send { + async fn fetch_request(&mut self, request: Request) -> Response; + } + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("http-fetch")?; + inst.func_wrap_async( + "fetch-request", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (Request,)| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = "", + function = "fetch-request", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, request = tracing::field::debug(& + arg0), "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::fetch_request(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn fetch_request(&mut self, request: Request) -> Response { + Host::fetch_request(*self, request).await + } + } +} +pub mod exports { + #[allow(clippy::all)] + pub mod http_handler { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + pub type Request = super::super::foo::foo::http_types::Request; + const _: () = { + assert!(8 == < Request as wasmtime::component::ComponentType >::SIZE32); + assert!(4 == < Request as wasmtime::component::ComponentType >::ALIGN32); + }; + pub type Response = super::super::foo::foo::http_types::Response; + const _: () = { + assert!(8 == < Response as wasmtime::component::ComponentType >::SIZE32); + assert!(4 == < Response as wasmtime::component::ComponentType >::ALIGN32); + }; + pub struct Guest { + handle_request: wasmtime::component::Func, + } + #[derive(Clone)] + pub struct GuestIndices { + handle_request: wasmtime::component::ComponentExportIndex, + } + impl GuestIndices { + /// Constructor for [`GuestIndices`] which takes a + /// [`Component`](wasmtime::component::Component) as input and can be executed + /// before instantiation. + /// + /// This constructor can be used to front-load string lookups to find exports + /// within a component. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let (_, instance) = component + .export_index(None, "http-handler") + .ok_or_else(|| { + anyhow::anyhow!("no exported instance named `http-handler`") + })?; + Self::_new(|name| { + component.export_index(Some(&instance), name).map(|p| p.1) + }) + } + /// This constructor is similar to [`GuestIndices::new`] except that it + /// performs string lookups after instantiation time. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let instance_export = instance + .get_export(&mut store, None, "http-handler") + .ok_or_else(|| { + anyhow::anyhow!("no exported instance named `http-handler`") + })?; + Self::_new(|name| { + instance.get_export(&mut store, Some(&instance_export), name) + }) + } + fn _new( + mut lookup: impl FnMut( + &str, + ) -> Option, + ) -> wasmtime::Result { + let mut lookup = move |name| { + lookup(name) + .ok_or_else(|| { + anyhow::anyhow!( + "instance export `http-handler` does \ + not have export `{name}`" + ) + }) + }; + let _ = &mut lookup; + let handle_request = lookup("handle-request")?; + Ok(GuestIndices { handle_request }) + } + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let mut store = store.as_context_mut(); + let _ = &mut store; + let _instance = instance; + let handle_request = *_instance + .get_typed_func::< + (&Request,), + (Response,), + >(&mut store, &self.handle_request)? + .func(); + Ok(Guest { handle_request }) + } + } + impl Guest { + pub async fn call_handle_request( + &self, + mut store: S, + arg0: &Request, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = "http-handler", + function = "handle-request", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (&Request,), + (Response,), + >::new_unchecked(self.handle_request) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee.post_return_async(store.as_context_mut()).instrument(span).await?; + Ok(ret0) + } + } + } +} diff --git a/crates/component-macro/tests/expanded/simple-functions_tracing_async.rs b/crates/component-macro/tests/expanded/simple-functions_tracing_async.rs new file mode 100644 index 000000000000..16d28903eab0 --- /dev/null +++ b/crates/component-macro/tests/expanded/simple-functions_tracing_async.rs @@ -0,0 +1,718 @@ +/// Auto-generated bindings for a pre-instantiated version of a +/// component which implements the world `the-world`. +/// +/// This structure is created through [`TheWorldPre::new`] which +/// takes a [`InstancePre`](wasmtime::component::InstancePre) that +/// has been created through a [`Linker`](wasmtime::component::Linker). +/// +/// For more information see [`TheWorld`] as well. +pub struct TheWorldPre { + instance_pre: wasmtime::component::InstancePre, + indices: TheWorldIndices, +} +impl Clone for TheWorldPre { + fn clone(&self) -> Self { + Self { + instance_pre: self.instance_pre.clone(), + indices: self.indices.clone(), + } + } +} +impl<_T> TheWorldPre<_T> { + /// Creates a new copy of `TheWorldPre` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component behind `instance_pre` + /// does not have the required exports. + pub fn new( + instance_pre: wasmtime::component::InstancePre<_T>, + ) -> wasmtime::Result { + let indices = TheWorldIndices::new(instance_pre.component())?; + Ok(Self { instance_pre, indices }) + } + pub fn engine(&self) -> &wasmtime::Engine { + self.instance_pre.engine() + } + pub fn instance_pre(&self) -> &wasmtime::component::InstancePre<_T> { + &self.instance_pre + } + /// Instantiates a new instance of [`TheWorld`] within the + /// `store` provided. + /// + /// This function will use `self` as the pre-instantiated + /// instance to perform instantiation. Afterwards the preloaded + /// indices in `self` are used to lookup all exports on the + /// resulting instance. + pub async fn instantiate_async( + &self, + mut store: impl wasmtime::AsContextMut, + ) -> wasmtime::Result + where + _T: Send, + { + let mut store = store.as_context_mut(); + let instance = self.instance_pre.instantiate_async(&mut store).await?; + self.indices.load(&mut store, &instance) + } +} +/// Auto-generated bindings for index of the exports of +/// `the-world`. +/// +/// This is an implementation detail of [`TheWorldPre`] and can +/// be constructed if needed as well. +/// +/// For more information see [`TheWorld`] as well. +#[derive(Clone)] +pub struct TheWorldIndices { + interface0: exports::foo::foo::simple::GuestIndices, +} +/// Auto-generated bindings for an instance a component which +/// implements the world `the-world`. +/// +/// This structure can be created through a number of means +/// depending on your requirements and what you have on hand: +/// +/// * The most convenient way is to use +/// [`TheWorld::instantiate_async`] which only needs a +/// [`Store`], [`Component`], and [`Linker`]. +/// +/// * Alternatively you can create a [`TheWorldPre`] ahead of +/// time with a [`Component`] to front-load string lookups +/// of exports once instead of per-instantiation. This +/// method then uses [`TheWorldPre::instantiate_async`] to +/// create a [`TheWorld`]. +/// +/// * If you've instantiated the instance yourself already +/// then you can use [`TheWorld::new`]. +/// +/// * You can also access the guts of instantiation through +/// [`TheWorldIndices::new_instance`] followed +/// by [`TheWorldIndices::load`] to crate an instance of this +/// type. +/// +/// These methods are all equivalent to one another and move +/// around the tradeoff of what work is performed when. +/// +/// [`Store`]: wasmtime::Store +/// [`Component`]: wasmtime::component::Component +/// [`Linker`]: wasmtime::component::Linker +pub struct TheWorld { + interface0: exports::foo::foo::simple::Guest, +} +const _: () = { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + impl TheWorldIndices { + /// Creates a new copy of `TheWorldIndices` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component does not have the + /// required exports. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let _component = component; + let interface0 = exports::foo::foo::simple::GuestIndices::new(_component)?; + Ok(TheWorldIndices { interface0 }) + } + /// Creates a new instance of [`TheWorldIndices`] from an + /// instantiated component. + /// + /// This method of creating a [`TheWorld`] will perform string + /// lookups for all exports when this method is called. This + /// will only succeed if the provided instance matches the + /// requirements of [`TheWorld`]. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = exports::foo::foo::simple::GuestIndices::new_instance( + &mut store, + _instance, + )?; + Ok(TheWorldIndices { interface0 }) + } + /// Uses the indices stored in `self` to load an instance + /// of [`TheWorld`] from the instance provided. + /// + /// Note that at this time this method will additionally + /// perform type-checks of all exports. + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = self.interface0.load(&mut store, &_instance)?; + Ok(TheWorld { interface0 }) + } + } + impl TheWorld { + /// Convenience wrapper around [`TheWorldPre::new`] and + /// [`TheWorldPre::instantiate_async`]. + pub async fn instantiate_async<_T>( + mut store: impl wasmtime::AsContextMut, + component: &wasmtime::component::Component, + linker: &wasmtime::component::Linker<_T>, + ) -> wasmtime::Result + where + _T: Send, + { + let pre = linker.instantiate_pre(component)?; + TheWorldPre::new(pre)?.instantiate_async(store).await + } + /// Convenience wrapper around [`TheWorldIndices::new_instance`] and + /// [`TheWorldIndices::load`]. + pub fn new( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let indices = TheWorldIndices::new_instance(&mut store, instance)?; + indices.load(store, instance) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + T: Send, + U: foo::foo::simple::Host + Send, + { + foo::foo::simple::add_to_linker(linker, get)?; + Ok(()) + } + pub fn foo_foo_simple(&self) -> &exports::foo::foo::simple::Guest { + &self.interface0 + } + } +}; +pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod simple { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send { + async fn f1(&mut self) -> (); + async fn f2(&mut self, a: u32) -> (); + async fn f3(&mut self, a: u32, b: u32) -> (); + async fn f4(&mut self) -> u32; + async fn f5(&mut self) -> (u32, u32); + async fn f6(&mut self, a: u32, b: u32, c: u32) -> (u32, u32, u32); + } + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("foo:foo/simple")?; + inst.func_wrap_async( + "f1", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "simple", function = "f1", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::f1(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "f2", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (u32,)| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "simple", function = "f2", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, a = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::f2(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "f3", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0, arg1): (u32, u32)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "simple", function = "f3", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, a = tracing::field::debug(& arg0), b + = tracing::field::debug(& arg1), "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::f3(host, arg0, arg1).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "f4", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "simple", function = "f4", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::f4(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "f5", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "simple", function = "f5", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::f5(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "f6", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0, arg1, arg2): (u32, u32, u32)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "simple", function = "f6", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, a = tracing::field::debug(& arg0), b + = tracing::field::debug(& arg1), c = tracing::field::debug(& + arg2), "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::f6(host, arg0, arg1, arg2).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn f1(&mut self) -> () { + Host::f1(*self).await + } + async fn f2(&mut self, a: u32) -> () { + Host::f2(*self, a).await + } + async fn f3(&mut self, a: u32, b: u32) -> () { + Host::f3(*self, a, b).await + } + async fn f4(&mut self) -> u32 { + Host::f4(*self).await + } + async fn f5(&mut self) -> (u32, u32) { + Host::f5(*self).await + } + async fn f6(&mut self, a: u32, b: u32, c: u32) -> (u32, u32, u32) { + Host::f6(*self, a, b, c).await + } + } + } + } +} +pub mod exports { + pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod simple { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + pub struct Guest { + f1: wasmtime::component::Func, + f2: wasmtime::component::Func, + f3: wasmtime::component::Func, + f4: wasmtime::component::Func, + f5: wasmtime::component::Func, + f6: wasmtime::component::Func, + } + #[derive(Clone)] + pub struct GuestIndices { + f1: wasmtime::component::ComponentExportIndex, + f2: wasmtime::component::ComponentExportIndex, + f3: wasmtime::component::ComponentExportIndex, + f4: wasmtime::component::ComponentExportIndex, + f5: wasmtime::component::ComponentExportIndex, + f6: wasmtime::component::ComponentExportIndex, + } + impl GuestIndices { + /// Constructor for [`GuestIndices`] which takes a + /// [`Component`](wasmtime::component::Component) as input and can be executed + /// before instantiation. + /// + /// This constructor can be used to front-load string lookups to find exports + /// within a component. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let (_, instance) = component + .export_index(None, "foo:foo/simple") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/simple`" + ) + })?; + Self::_new(|name| { + component.export_index(Some(&instance), name).map(|p| p.1) + }) + } + /// This constructor is similar to [`GuestIndices::new`] except that it + /// performs string lookups after instantiation time. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let instance_export = instance + .get_export(&mut store, None, "foo:foo/simple") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/simple`" + ) + })?; + Self::_new(|name| { + instance.get_export(&mut store, Some(&instance_export), name) + }) + } + fn _new( + mut lookup: impl FnMut( + &str, + ) -> Option, + ) -> wasmtime::Result { + let mut lookup = move |name| { + lookup(name) + .ok_or_else(|| { + anyhow::anyhow!( + "instance export `foo:foo/simple` does \ + not have export `{name}`" + ) + }) + }; + let _ = &mut lookup; + let f1 = lookup("f1")?; + let f2 = lookup("f2")?; + let f3 = lookup("f3")?; + let f4 = lookup("f4")?; + let f5 = lookup("f5")?; + let f6 = lookup("f6")?; + Ok(GuestIndices { + f1, + f2, + f3, + f4, + f5, + f6, + }) + } + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let mut store = store.as_context_mut(); + let _ = &mut store; + let _instance = instance; + let f1 = *_instance + .get_typed_func::<(), ()>(&mut store, &self.f1)? + .func(); + let f2 = *_instance + .get_typed_func::<(u32,), ()>(&mut store, &self.f2)? + .func(); + let f3 = *_instance + .get_typed_func::<(u32, u32), ()>(&mut store, &self.f3)? + .func(); + let f4 = *_instance + .get_typed_func::<(), (u32,)>(&mut store, &self.f4)? + .func(); + let f5 = *_instance + .get_typed_func::<(), ((u32, u32),)>(&mut store, &self.f5)? + .func(); + let f6 = *_instance + .get_typed_func::< + (u32, u32, u32), + ((u32, u32, u32),), + >(&mut store, &self.f6)? + .func(); + Ok(Guest { f1, f2, f3, f4, f5, f6 }) + } + } + impl Guest { + pub async fn call_f1( + &self, + mut store: S, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/simple", function = "f1", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (), + >::new_unchecked(self.f1) + }; + let () = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_f2( + &self, + mut store: S, + arg0: u32, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/simple", function = "f2", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (u32,), + (), + >::new_unchecked(self.f2) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_f3( + &self, + mut store: S, + arg0: u32, + arg1: u32, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/simple", function = "f3", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (u32, u32), + (), + >::new_unchecked(self.f3) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0, arg1)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_f4( + &self, + mut store: S, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/simple", function = "f4", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (u32,), + >::new_unchecked(self.f4) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_f5( + &self, + mut store: S, + ) -> wasmtime::Result<(u32, u32)> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/simple", function = "f5", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + ((u32, u32),), + >::new_unchecked(self.f5) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_f6( + &self, + mut store: S, + arg0: u32, + arg1: u32, + arg2: u32, + ) -> wasmtime::Result<(u32, u32, u32)> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/simple", function = "f6", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (u32, u32, u32), + ((u32, u32, u32),), + >::new_unchecked(self.f6) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), (arg0, arg1, arg2)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + } + } + } + } +} diff --git a/crates/component-macro/tests/expanded/simple-lists_tracing_async.rs b/crates/component-macro/tests/expanded/simple-lists_tracing_async.rs new file mode 100644 index 000000000000..32cad358dded --- /dev/null +++ b/crates/component-macro/tests/expanded/simple-lists_tracing_async.rs @@ -0,0 +1,687 @@ +/// Auto-generated bindings for a pre-instantiated version of a +/// component which implements the world `my-world`. +/// +/// This structure is created through [`MyWorldPre::new`] which +/// takes a [`InstancePre`](wasmtime::component::InstancePre) that +/// has been created through a [`Linker`](wasmtime::component::Linker). +/// +/// For more information see [`MyWorld`] as well. +pub struct MyWorldPre { + instance_pre: wasmtime::component::InstancePre, + indices: MyWorldIndices, +} +impl Clone for MyWorldPre { + fn clone(&self) -> Self { + Self { + instance_pre: self.instance_pre.clone(), + indices: self.indices.clone(), + } + } +} +impl<_T> MyWorldPre<_T> { + /// Creates a new copy of `MyWorldPre` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component behind `instance_pre` + /// does not have the required exports. + pub fn new( + instance_pre: wasmtime::component::InstancePre<_T>, + ) -> wasmtime::Result { + let indices = MyWorldIndices::new(instance_pre.component())?; + Ok(Self { instance_pre, indices }) + } + pub fn engine(&self) -> &wasmtime::Engine { + self.instance_pre.engine() + } + pub fn instance_pre(&self) -> &wasmtime::component::InstancePre<_T> { + &self.instance_pre + } + /// Instantiates a new instance of [`MyWorld`] within the + /// `store` provided. + /// + /// This function will use `self` as the pre-instantiated + /// instance to perform instantiation. Afterwards the preloaded + /// indices in `self` are used to lookup all exports on the + /// resulting instance. + pub async fn instantiate_async( + &self, + mut store: impl wasmtime::AsContextMut, + ) -> wasmtime::Result + where + _T: Send, + { + let mut store = store.as_context_mut(); + let instance = self.instance_pre.instantiate_async(&mut store).await?; + self.indices.load(&mut store, &instance) + } +} +/// Auto-generated bindings for index of the exports of +/// `my-world`. +/// +/// This is an implementation detail of [`MyWorldPre`] and can +/// be constructed if needed as well. +/// +/// For more information see [`MyWorld`] as well. +#[derive(Clone)] +pub struct MyWorldIndices { + interface0: exports::foo::foo::simple_lists::GuestIndices, +} +/// Auto-generated bindings for an instance a component which +/// implements the world `my-world`. +/// +/// This structure can be created through a number of means +/// depending on your requirements and what you have on hand: +/// +/// * The most convenient way is to use +/// [`MyWorld::instantiate_async`] which only needs a +/// [`Store`], [`Component`], and [`Linker`]. +/// +/// * Alternatively you can create a [`MyWorldPre`] ahead of +/// time with a [`Component`] to front-load string lookups +/// of exports once instead of per-instantiation. This +/// method then uses [`MyWorldPre::instantiate_async`] to +/// create a [`MyWorld`]. +/// +/// * If you've instantiated the instance yourself already +/// then you can use [`MyWorld::new`]. +/// +/// * You can also access the guts of instantiation through +/// [`MyWorldIndices::new_instance`] followed +/// by [`MyWorldIndices::load`] to crate an instance of this +/// type. +/// +/// These methods are all equivalent to one another and move +/// around the tradeoff of what work is performed when. +/// +/// [`Store`]: wasmtime::Store +/// [`Component`]: wasmtime::component::Component +/// [`Linker`]: wasmtime::component::Linker +pub struct MyWorld { + interface0: exports::foo::foo::simple_lists::Guest, +} +const _: () = { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + impl MyWorldIndices { + /// Creates a new copy of `MyWorldIndices` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component does not have the + /// required exports. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let _component = component; + let interface0 = exports::foo::foo::simple_lists::GuestIndices::new( + _component, + )?; + Ok(MyWorldIndices { interface0 }) + } + /// Creates a new instance of [`MyWorldIndices`] from an + /// instantiated component. + /// + /// This method of creating a [`MyWorld`] will perform string + /// lookups for all exports when this method is called. This + /// will only succeed if the provided instance matches the + /// requirements of [`MyWorld`]. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = exports::foo::foo::simple_lists::GuestIndices::new_instance( + &mut store, + _instance, + )?; + Ok(MyWorldIndices { interface0 }) + } + /// Uses the indices stored in `self` to load an instance + /// of [`MyWorld`] from the instance provided. + /// + /// Note that at this time this method will additionally + /// perform type-checks of all exports. + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = self.interface0.load(&mut store, &_instance)?; + Ok(MyWorld { interface0 }) + } + } + impl MyWorld { + /// Convenience wrapper around [`MyWorldPre::new`] and + /// [`MyWorldPre::instantiate_async`]. + pub async fn instantiate_async<_T>( + mut store: impl wasmtime::AsContextMut, + component: &wasmtime::component::Component, + linker: &wasmtime::component::Linker<_T>, + ) -> wasmtime::Result + where + _T: Send, + { + let pre = linker.instantiate_pre(component)?; + MyWorldPre::new(pre)?.instantiate_async(store).await + } + /// Convenience wrapper around [`MyWorldIndices::new_instance`] and + /// [`MyWorldIndices::load`]. + pub fn new( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let indices = MyWorldIndices::new_instance(&mut store, instance)?; + indices.load(store, instance) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + T: Send, + U: foo::foo::simple_lists::Host + Send, + { + foo::foo::simple_lists::add_to_linker(linker, get)?; + Ok(()) + } + pub fn foo_foo_simple_lists(&self) -> &exports::foo::foo::simple_lists::Guest { + &self.interface0 + } + } +}; +pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod simple_lists { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send { + async fn simple_list1( + &mut self, + l: wasmtime::component::__internal::Vec, + ) -> (); + async fn simple_list2( + &mut self, + ) -> wasmtime::component::__internal::Vec; + async fn simple_list3( + &mut self, + a: wasmtime::component::__internal::Vec, + b: wasmtime::component::__internal::Vec, + ) -> ( + wasmtime::component::__internal::Vec, + wasmtime::component::__internal::Vec, + ); + async fn simple_list4( + &mut self, + l: wasmtime::component::__internal::Vec< + wasmtime::component::__internal::Vec, + >, + ) -> wasmtime::component::__internal::Vec< + wasmtime::component::__internal::Vec, + >; + } + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("foo:foo/simple-lists")?; + inst.func_wrap_async( + "simple-list1", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (wasmtime::component::__internal::Vec,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "simple-lists", function = "simple-list1", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, l = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::simple_list1(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "simple-list2", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "simple-lists", function = "simple-list2", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::simple_list2(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "simple-list3", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + ( + arg0, + arg1, + ): ( + wasmtime::component::__internal::Vec, + wasmtime::component::__internal::Vec, + )| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "simple-lists", function = "simple-list3", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, a = tracing::field::debug(& arg0), b + = tracing::field::debug(& arg1), "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::simple_list3(host, arg0, arg1).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "simple-list4", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + ( + arg0, + ): ( + wasmtime::component::__internal::Vec< + wasmtime::component::__internal::Vec, + >, + )| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "simple-lists", function = "simple-list4", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, l = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::simple_list4(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn simple_list1( + &mut self, + l: wasmtime::component::__internal::Vec, + ) -> () { + Host::simple_list1(*self, l).await + } + async fn simple_list2( + &mut self, + ) -> wasmtime::component::__internal::Vec { + Host::simple_list2(*self).await + } + async fn simple_list3( + &mut self, + a: wasmtime::component::__internal::Vec, + b: wasmtime::component::__internal::Vec, + ) -> ( + wasmtime::component::__internal::Vec, + wasmtime::component::__internal::Vec, + ) { + Host::simple_list3(*self, a, b).await + } + async fn simple_list4( + &mut self, + l: wasmtime::component::__internal::Vec< + wasmtime::component::__internal::Vec, + >, + ) -> wasmtime::component::__internal::Vec< + wasmtime::component::__internal::Vec, + > { + Host::simple_list4(*self, l).await + } + } + } + } +} +pub mod exports { + pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod simple_lists { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + pub struct Guest { + simple_list1: wasmtime::component::Func, + simple_list2: wasmtime::component::Func, + simple_list3: wasmtime::component::Func, + simple_list4: wasmtime::component::Func, + } + #[derive(Clone)] + pub struct GuestIndices { + simple_list1: wasmtime::component::ComponentExportIndex, + simple_list2: wasmtime::component::ComponentExportIndex, + simple_list3: wasmtime::component::ComponentExportIndex, + simple_list4: wasmtime::component::ComponentExportIndex, + } + impl GuestIndices { + /// Constructor for [`GuestIndices`] which takes a + /// [`Component`](wasmtime::component::Component) as input and can be executed + /// before instantiation. + /// + /// This constructor can be used to front-load string lookups to find exports + /// within a component. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let (_, instance) = component + .export_index(None, "foo:foo/simple-lists") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/simple-lists`" + ) + })?; + Self::_new(|name| { + component.export_index(Some(&instance), name).map(|p| p.1) + }) + } + /// This constructor is similar to [`GuestIndices::new`] except that it + /// performs string lookups after instantiation time. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let instance_export = instance + .get_export(&mut store, None, "foo:foo/simple-lists") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/simple-lists`" + ) + })?; + Self::_new(|name| { + instance.get_export(&mut store, Some(&instance_export), name) + }) + } + fn _new( + mut lookup: impl FnMut( + &str, + ) -> Option, + ) -> wasmtime::Result { + let mut lookup = move |name| { + lookup(name) + .ok_or_else(|| { + anyhow::anyhow!( + "instance export `foo:foo/simple-lists` does \ + not have export `{name}`" + ) + }) + }; + let _ = &mut lookup; + let simple_list1 = lookup("simple-list1")?; + let simple_list2 = lookup("simple-list2")?; + let simple_list3 = lookup("simple-list3")?; + let simple_list4 = lookup("simple-list4")?; + Ok(GuestIndices { + simple_list1, + simple_list2, + simple_list3, + simple_list4, + }) + } + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let mut store = store.as_context_mut(); + let _ = &mut store; + let _instance = instance; + let simple_list1 = *_instance + .get_typed_func::< + (&[u32],), + (), + >(&mut store, &self.simple_list1)? + .func(); + let simple_list2 = *_instance + .get_typed_func::< + (), + (wasmtime::component::__internal::Vec,), + >(&mut store, &self.simple_list2)? + .func(); + let simple_list3 = *_instance + .get_typed_func::< + (&[u32], &[u32]), + ( + ( + wasmtime::component::__internal::Vec, + wasmtime::component::__internal::Vec, + ), + ), + >(&mut store, &self.simple_list3)? + .func(); + let simple_list4 = *_instance + .get_typed_func::< + (&[wasmtime::component::__internal::Vec],), + ( + wasmtime::component::__internal::Vec< + wasmtime::component::__internal::Vec, + >, + ), + >(&mut store, &self.simple_list4)? + .func(); + Ok(Guest { + simple_list1, + simple_list2, + simple_list3, + simple_list4, + }) + } + } + impl Guest { + pub async fn call_simple_list1( + &self, + mut store: S, + arg0: &[u32], + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/simple-lists", function = "simple-list1", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (&[u32],), + (), + >::new_unchecked(self.simple_list1) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_simple_list2( + &self, + mut store: S, + ) -> wasmtime::Result> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/simple-lists", function = "simple-list2", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (wasmtime::component::__internal::Vec,), + >::new_unchecked(self.simple_list2) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_simple_list3( + &self, + mut store: S, + arg0: &[u32], + arg1: &[u32], + ) -> wasmtime::Result< + ( + wasmtime::component::__internal::Vec, + wasmtime::component::__internal::Vec, + ), + > + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/simple-lists", function = "simple-list3", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (&[u32], &[u32]), + ( + ( + wasmtime::component::__internal::Vec, + wasmtime::component::__internal::Vec, + ), + ), + >::new_unchecked(self.simple_list3) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), (arg0, arg1)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_simple_list4( + &self, + mut store: S, + arg0: &[wasmtime::component::__internal::Vec], + ) -> wasmtime::Result< + wasmtime::component::__internal::Vec< + wasmtime::component::__internal::Vec, + >, + > + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/simple-lists", function = "simple-list4", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (&[wasmtime::component::__internal::Vec],), + ( + wasmtime::component::__internal::Vec< + wasmtime::component::__internal::Vec, + >, + ), + >::new_unchecked(self.simple_list4) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + } + } + } + } +} diff --git a/crates/component-macro/tests/expanded/simple-wasi_tracing_async.rs b/crates/component-macro/tests/expanded/simple-wasi_tracing_async.rs new file mode 100644 index 000000000000..6c6a92ca2eb4 --- /dev/null +++ b/crates/component-macro/tests/expanded/simple-wasi_tracing_async.rs @@ -0,0 +1,380 @@ +/// Auto-generated bindings for a pre-instantiated version of a +/// component which implements the world `wasi`. +/// +/// This structure is created through [`WasiPre::new`] which +/// takes a [`InstancePre`](wasmtime::component::InstancePre) that +/// has been created through a [`Linker`](wasmtime::component::Linker). +/// +/// For more information see [`Wasi`] as well. +pub struct WasiPre { + instance_pre: wasmtime::component::InstancePre, + indices: WasiIndices, +} +impl Clone for WasiPre { + fn clone(&self) -> Self { + Self { + instance_pre: self.instance_pre.clone(), + indices: self.indices.clone(), + } + } +} +impl<_T> WasiPre<_T> { + /// Creates a new copy of `WasiPre` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component behind `instance_pre` + /// does not have the required exports. + pub fn new( + instance_pre: wasmtime::component::InstancePre<_T>, + ) -> wasmtime::Result { + let indices = WasiIndices::new(instance_pre.component())?; + Ok(Self { instance_pre, indices }) + } + pub fn engine(&self) -> &wasmtime::Engine { + self.instance_pre.engine() + } + pub fn instance_pre(&self) -> &wasmtime::component::InstancePre<_T> { + &self.instance_pre + } + /// Instantiates a new instance of [`Wasi`] within the + /// `store` provided. + /// + /// This function will use `self` as the pre-instantiated + /// instance to perform instantiation. Afterwards the preloaded + /// indices in `self` are used to lookup all exports on the + /// resulting instance. + pub async fn instantiate_async( + &self, + mut store: impl wasmtime::AsContextMut, + ) -> wasmtime::Result + where + _T: Send, + { + let mut store = store.as_context_mut(); + let instance = self.instance_pre.instantiate_async(&mut store).await?; + self.indices.load(&mut store, &instance) + } +} +/// Auto-generated bindings for index of the exports of +/// `wasi`. +/// +/// This is an implementation detail of [`WasiPre`] and can +/// be constructed if needed as well. +/// +/// For more information see [`Wasi`] as well. +#[derive(Clone)] +pub struct WasiIndices {} +/// Auto-generated bindings for an instance a component which +/// implements the world `wasi`. +/// +/// This structure can be created through a number of means +/// depending on your requirements and what you have on hand: +/// +/// * The most convenient way is to use +/// [`Wasi::instantiate_async`] which only needs a +/// [`Store`], [`Component`], and [`Linker`]. +/// +/// * Alternatively you can create a [`WasiPre`] ahead of +/// time with a [`Component`] to front-load string lookups +/// of exports once instead of per-instantiation. This +/// method then uses [`WasiPre::instantiate_async`] to +/// create a [`Wasi`]. +/// +/// * If you've instantiated the instance yourself already +/// then you can use [`Wasi::new`]. +/// +/// * You can also access the guts of instantiation through +/// [`WasiIndices::new_instance`] followed +/// by [`WasiIndices::load`] to crate an instance of this +/// type. +/// +/// These methods are all equivalent to one another and move +/// around the tradeoff of what work is performed when. +/// +/// [`Store`]: wasmtime::Store +/// [`Component`]: wasmtime::component::Component +/// [`Linker`]: wasmtime::component::Linker +pub struct Wasi {} +const _: () = { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + impl WasiIndices { + /// Creates a new copy of `WasiIndices` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component does not have the + /// required exports. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let _component = component; + Ok(WasiIndices {}) + } + /// Creates a new instance of [`WasiIndices`] from an + /// instantiated component. + /// + /// This method of creating a [`Wasi`] will perform string + /// lookups for all exports when this method is called. This + /// will only succeed if the provided instance matches the + /// requirements of [`Wasi`]. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + Ok(WasiIndices {}) + } + /// Uses the indices stored in `self` to load an instance + /// of [`Wasi`] from the instance provided. + /// + /// Note that at this time this method will additionally + /// perform type-checks of all exports. + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + Ok(Wasi {}) + } + } + impl Wasi { + /// Convenience wrapper around [`WasiPre::new`] and + /// [`WasiPre::instantiate_async`]. + pub async fn instantiate_async<_T>( + mut store: impl wasmtime::AsContextMut, + component: &wasmtime::component::Component, + linker: &wasmtime::component::Linker<_T>, + ) -> wasmtime::Result + where + _T: Send, + { + let pre = linker.instantiate_pre(component)?; + WasiPre::new(pre)?.instantiate_async(store).await + } + /// Convenience wrapper around [`WasiIndices::new_instance`] and + /// [`WasiIndices::load`]. + pub fn new( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let indices = WasiIndices::new_instance(&mut store, instance)?; + indices.load(store, instance) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + T: Send, + U: foo::foo::wasi_filesystem::Host + foo::foo::wall_clock::Host + Send, + { + foo::foo::wasi_filesystem::add_to_linker(linker, get)?; + foo::foo::wall_clock::add_to_linker(linker, get)?; + Ok(()) + } + } +}; +pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod wasi_filesystem { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(record)] + #[derive(Clone, Copy)] + pub struct DescriptorStat {} + impl core::fmt::Debug for DescriptorStat { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("DescriptorStat").finish() + } + } + const _: () = { + assert!( + 0 == < DescriptorStat as wasmtime::component::ComponentType >::SIZE32 + ); + assert!( + 1 == < DescriptorStat as wasmtime::component::ComponentType + >::ALIGN32 + ); + }; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(enum)] + #[derive(Clone, Copy, Eq, PartialEq)] + #[repr(u8)] + pub enum Errno { + #[component(name = "e")] + E, + } + impl Errno { + pub fn name(&self) -> &'static str { + match self { + Errno::E => "e", + } + } + pub fn message(&self) -> &'static str { + match self { + Errno::E => "", + } + } + } + impl core::fmt::Debug for Errno { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("Errno") + .field("code", &(*self as i32)) + .field("name", &self.name()) + .field("message", &self.message()) + .finish() + } + } + impl core::fmt::Display for Errno { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "{} (error {})", self.name(), * self as i32) + } + } + impl std::error::Error for Errno {} + const _: () = { + assert!(1 == < Errno as wasmtime::component::ComponentType >::SIZE32); + assert!(1 == < Errno as wasmtime::component::ComponentType >::ALIGN32); + }; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send { + async fn create_directory_at(&mut self) -> Result<(), Errno>; + async fn stat(&mut self) -> Result; + } + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("foo:foo/wasi-filesystem")?; + inst.func_wrap_async( + "create-directory-at", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "wasi-filesystem", function = "create-directory-at", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::create_directory_at(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "stat", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "wasi-filesystem", function = "stat", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::stat(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn create_directory_at(&mut self) -> Result<(), Errno> { + Host::create_directory_at(*self).await + } + async fn stat(&mut self) -> Result { + Host::stat(*self).await + } + } + } + #[allow(clippy::all)] + pub mod wall_clock { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send {} + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("foo:foo/wall-clock")?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T {} + } + } +} diff --git a/crates/component-macro/tests/expanded/small-anonymous_tracing_async.rs b/crates/component-macro/tests/expanded/small-anonymous_tracing_async.rs new file mode 100644 index 000000000000..113ccf2700ae --- /dev/null +++ b/crates/component-macro/tests/expanded/small-anonymous_tracing_async.rs @@ -0,0 +1,496 @@ +/// Auto-generated bindings for a pre-instantiated version of a +/// component which implements the world `the-world`. +/// +/// This structure is created through [`TheWorldPre::new`] which +/// takes a [`InstancePre`](wasmtime::component::InstancePre) that +/// has been created through a [`Linker`](wasmtime::component::Linker). +/// +/// For more information see [`TheWorld`] as well. +pub struct TheWorldPre { + instance_pre: wasmtime::component::InstancePre, + indices: TheWorldIndices, +} +impl Clone for TheWorldPre { + fn clone(&self) -> Self { + Self { + instance_pre: self.instance_pre.clone(), + indices: self.indices.clone(), + } + } +} +impl<_T> TheWorldPre<_T> { + /// Creates a new copy of `TheWorldPre` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component behind `instance_pre` + /// does not have the required exports. + pub fn new( + instance_pre: wasmtime::component::InstancePre<_T>, + ) -> wasmtime::Result { + let indices = TheWorldIndices::new(instance_pre.component())?; + Ok(Self { instance_pre, indices }) + } + pub fn engine(&self) -> &wasmtime::Engine { + self.instance_pre.engine() + } + pub fn instance_pre(&self) -> &wasmtime::component::InstancePre<_T> { + &self.instance_pre + } + /// Instantiates a new instance of [`TheWorld`] within the + /// `store` provided. + /// + /// This function will use `self` as the pre-instantiated + /// instance to perform instantiation. Afterwards the preloaded + /// indices in `self` are used to lookup all exports on the + /// resulting instance. + pub async fn instantiate_async( + &self, + mut store: impl wasmtime::AsContextMut, + ) -> wasmtime::Result + where + _T: Send, + { + let mut store = store.as_context_mut(); + let instance = self.instance_pre.instantiate_async(&mut store).await?; + self.indices.load(&mut store, &instance) + } +} +/// Auto-generated bindings for index of the exports of +/// `the-world`. +/// +/// This is an implementation detail of [`TheWorldPre`] and can +/// be constructed if needed as well. +/// +/// For more information see [`TheWorld`] as well. +#[derive(Clone)] +pub struct TheWorldIndices { + interface0: exports::foo::foo::anon::GuestIndices, +} +/// Auto-generated bindings for an instance a component which +/// implements the world `the-world`. +/// +/// This structure can be created through a number of means +/// depending on your requirements and what you have on hand: +/// +/// * The most convenient way is to use +/// [`TheWorld::instantiate_async`] which only needs a +/// [`Store`], [`Component`], and [`Linker`]. +/// +/// * Alternatively you can create a [`TheWorldPre`] ahead of +/// time with a [`Component`] to front-load string lookups +/// of exports once instead of per-instantiation. This +/// method then uses [`TheWorldPre::instantiate_async`] to +/// create a [`TheWorld`]. +/// +/// * If you've instantiated the instance yourself already +/// then you can use [`TheWorld::new`]. +/// +/// * You can also access the guts of instantiation through +/// [`TheWorldIndices::new_instance`] followed +/// by [`TheWorldIndices::load`] to crate an instance of this +/// type. +/// +/// These methods are all equivalent to one another and move +/// around the tradeoff of what work is performed when. +/// +/// [`Store`]: wasmtime::Store +/// [`Component`]: wasmtime::component::Component +/// [`Linker`]: wasmtime::component::Linker +pub struct TheWorld { + interface0: exports::foo::foo::anon::Guest, +} +const _: () = { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + impl TheWorldIndices { + /// Creates a new copy of `TheWorldIndices` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component does not have the + /// required exports. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let _component = component; + let interface0 = exports::foo::foo::anon::GuestIndices::new(_component)?; + Ok(TheWorldIndices { interface0 }) + } + /// Creates a new instance of [`TheWorldIndices`] from an + /// instantiated component. + /// + /// This method of creating a [`TheWorld`] will perform string + /// lookups for all exports when this method is called. This + /// will only succeed if the provided instance matches the + /// requirements of [`TheWorld`]. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = exports::foo::foo::anon::GuestIndices::new_instance( + &mut store, + _instance, + )?; + Ok(TheWorldIndices { interface0 }) + } + /// Uses the indices stored in `self` to load an instance + /// of [`TheWorld`] from the instance provided. + /// + /// Note that at this time this method will additionally + /// perform type-checks of all exports. + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = self.interface0.load(&mut store, &_instance)?; + Ok(TheWorld { interface0 }) + } + } + impl TheWorld { + /// Convenience wrapper around [`TheWorldPre::new`] and + /// [`TheWorldPre::instantiate_async`]. + pub async fn instantiate_async<_T>( + mut store: impl wasmtime::AsContextMut, + component: &wasmtime::component::Component, + linker: &wasmtime::component::Linker<_T>, + ) -> wasmtime::Result + where + _T: Send, + { + let pre = linker.instantiate_pre(component)?; + TheWorldPre::new(pre)?.instantiate_async(store).await + } + /// Convenience wrapper around [`TheWorldIndices::new_instance`] and + /// [`TheWorldIndices::load`]. + pub fn new( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let indices = TheWorldIndices::new_instance(&mut store, instance)?; + indices.load(store, instance) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + T: Send, + U: foo::foo::anon::Host + Send, + { + foo::foo::anon::add_to_linker(linker, get)?; + Ok(()) + } + pub fn foo_foo_anon(&self) -> &exports::foo::foo::anon::Guest { + &self.interface0 + } + } +}; +pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod anon { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(enum)] + #[derive(Clone, Copy, Eq, PartialEq)] + #[repr(u8)] + pub enum Error { + #[component(name = "success")] + Success, + #[component(name = "failure")] + Failure, + } + impl Error { + pub fn name(&self) -> &'static str { + match self { + Error::Success => "success", + Error::Failure => "failure", + } + } + pub fn message(&self) -> &'static str { + match self { + Error::Success => "", + Error::Failure => "", + } + } + } + impl core::fmt::Debug for Error { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("Error") + .field("code", &(*self as i32)) + .field("name", &self.name()) + .field("message", &self.message()) + .finish() + } + } + impl core::fmt::Display for Error { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "{} (error {})", self.name(), * self as i32) + } + } + impl std::error::Error for Error {} + const _: () = { + assert!(1 == < Error as wasmtime::component::ComponentType >::SIZE32); + assert!(1 == < Error as wasmtime::component::ComponentType >::ALIGN32); + }; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send { + async fn option_test( + &mut self, + ) -> Result, Error>; + } + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("foo:foo/anon")?; + inst.func_wrap_async( + "option-test", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = "anon", + function = "option-test", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::option_test(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn option_test( + &mut self, + ) -> Result, Error> { + Host::option_test(*self).await + } + } + } + } +} +pub mod exports { + pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod anon { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(enum)] + #[derive(Clone, Copy, Eq, PartialEq)] + #[repr(u8)] + pub enum Error { + #[component(name = "success")] + Success, + #[component(name = "failure")] + Failure, + } + impl Error { + pub fn name(&self) -> &'static str { + match self { + Error::Success => "success", + Error::Failure => "failure", + } + } + pub fn message(&self) -> &'static str { + match self { + Error::Success => "", + Error::Failure => "", + } + } + } + impl core::fmt::Debug for Error { + fn fmt( + &self, + f: &mut core::fmt::Formatter<'_>, + ) -> core::fmt::Result { + f.debug_struct("Error") + .field("code", &(*self as i32)) + .field("name", &self.name()) + .field("message", &self.message()) + .finish() + } + } + impl core::fmt::Display for Error { + fn fmt( + &self, + f: &mut core::fmt::Formatter<'_>, + ) -> core::fmt::Result { + write!(f, "{} (error {})", self.name(), * self as i32) + } + } + impl std::error::Error for Error {} + const _: () = { + assert!( + 1 == < Error as wasmtime::component::ComponentType >::SIZE32 + ); + assert!( + 1 == < Error as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + pub struct Guest { + option_test: wasmtime::component::Func, + } + #[derive(Clone)] + pub struct GuestIndices { + option_test: wasmtime::component::ComponentExportIndex, + } + impl GuestIndices { + /// Constructor for [`GuestIndices`] which takes a + /// [`Component`](wasmtime::component::Component) as input and can be executed + /// before instantiation. + /// + /// This constructor can be used to front-load string lookups to find exports + /// within a component. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let (_, instance) = component + .export_index(None, "foo:foo/anon") + .ok_or_else(|| { + anyhow::anyhow!("no exported instance named `foo:foo/anon`") + })?; + Self::_new(|name| { + component.export_index(Some(&instance), name).map(|p| p.1) + }) + } + /// This constructor is similar to [`GuestIndices::new`] except that it + /// performs string lookups after instantiation time. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let instance_export = instance + .get_export(&mut store, None, "foo:foo/anon") + .ok_or_else(|| { + anyhow::anyhow!("no exported instance named `foo:foo/anon`") + })?; + Self::_new(|name| { + instance.get_export(&mut store, Some(&instance_export), name) + }) + } + fn _new( + mut lookup: impl FnMut( + &str, + ) -> Option, + ) -> wasmtime::Result { + let mut lookup = move |name| { + lookup(name) + .ok_or_else(|| { + anyhow::anyhow!( + "instance export `foo:foo/anon` does \ + not have export `{name}`" + ) + }) + }; + let _ = &mut lookup; + let option_test = lookup("option-test")?; + Ok(GuestIndices { option_test }) + } + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let mut store = store.as_context_mut(); + let _ = &mut store; + let _instance = instance; + let option_test = *_instance + .get_typed_func::< + (), + ( + Result< + Option, + Error, + >, + ), + >(&mut store, &self.option_test)? + .func(); + Ok(Guest { option_test }) + } + } + impl Guest { + pub async fn call_option_test( + &self, + mut store: S, + ) -> wasmtime::Result< + Result, Error>, + > + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/anon", function = "option-test", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + ( + Result< + Option, + Error, + >, + ), + >::new_unchecked(self.option_test) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + } + } + } + } +} diff --git a/crates/component-macro/tests/expanded/smoke-default_tracing_async.rs b/crates/component-macro/tests/expanded/smoke-default_tracing_async.rs new file mode 100644 index 000000000000..96f7792ceb76 --- /dev/null +++ b/crates/component-macro/tests/expanded/smoke-default_tracing_async.rs @@ -0,0 +1,199 @@ +/// Auto-generated bindings for a pre-instantiated version of a +/// component which implements the world `the-world`. +/// +/// This structure is created through [`TheWorldPre::new`] which +/// takes a [`InstancePre`](wasmtime::component::InstancePre) that +/// has been created through a [`Linker`](wasmtime::component::Linker). +/// +/// For more information see [`TheWorld`] as well. +pub struct TheWorldPre { + instance_pre: wasmtime::component::InstancePre, + indices: TheWorldIndices, +} +impl Clone for TheWorldPre { + fn clone(&self) -> Self { + Self { + instance_pre: self.instance_pre.clone(), + indices: self.indices.clone(), + } + } +} +impl<_T> TheWorldPre<_T> { + /// Creates a new copy of `TheWorldPre` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component behind `instance_pre` + /// does not have the required exports. + pub fn new( + instance_pre: wasmtime::component::InstancePre<_T>, + ) -> wasmtime::Result { + let indices = TheWorldIndices::new(instance_pre.component())?; + Ok(Self { instance_pre, indices }) + } + pub fn engine(&self) -> &wasmtime::Engine { + self.instance_pre.engine() + } + pub fn instance_pre(&self) -> &wasmtime::component::InstancePre<_T> { + &self.instance_pre + } + /// Instantiates a new instance of [`TheWorld`] within the + /// `store` provided. + /// + /// This function will use `self` as the pre-instantiated + /// instance to perform instantiation. Afterwards the preloaded + /// indices in `self` are used to lookup all exports on the + /// resulting instance. + pub async fn instantiate_async( + &self, + mut store: impl wasmtime::AsContextMut, + ) -> wasmtime::Result + where + _T: Send, + { + let mut store = store.as_context_mut(); + let instance = self.instance_pre.instantiate_async(&mut store).await?; + self.indices.load(&mut store, &instance) + } +} +/// Auto-generated bindings for index of the exports of +/// `the-world`. +/// +/// This is an implementation detail of [`TheWorldPre`] and can +/// be constructed if needed as well. +/// +/// For more information see [`TheWorld`] as well. +#[derive(Clone)] +pub struct TheWorldIndices { + y: wasmtime::component::ComponentExportIndex, +} +/// Auto-generated bindings for an instance a component which +/// implements the world `the-world`. +/// +/// This structure can be created through a number of means +/// depending on your requirements and what you have on hand: +/// +/// * The most convenient way is to use +/// [`TheWorld::instantiate_async`] which only needs a +/// [`Store`], [`Component`], and [`Linker`]. +/// +/// * Alternatively you can create a [`TheWorldPre`] ahead of +/// time with a [`Component`] to front-load string lookups +/// of exports once instead of per-instantiation. This +/// method then uses [`TheWorldPre::instantiate_async`] to +/// create a [`TheWorld`]. +/// +/// * If you've instantiated the instance yourself already +/// then you can use [`TheWorld::new`]. +/// +/// * You can also access the guts of instantiation through +/// [`TheWorldIndices::new_instance`] followed +/// by [`TheWorldIndices::load`] to crate an instance of this +/// type. +/// +/// These methods are all equivalent to one another and move +/// around the tradeoff of what work is performed when. +/// +/// [`Store`]: wasmtime::Store +/// [`Component`]: wasmtime::component::Component +/// [`Linker`]: wasmtime::component::Linker +pub struct TheWorld { + y: wasmtime::component::Func, +} +const _: () = { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + impl TheWorldIndices { + /// Creates a new copy of `TheWorldIndices` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component does not have the + /// required exports. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let _component = component; + let y = _component + .export_index(None, "y") + .ok_or_else(|| anyhow::anyhow!("no function export `y` found"))? + .1; + Ok(TheWorldIndices { y }) + } + /// Creates a new instance of [`TheWorldIndices`] from an + /// instantiated component. + /// + /// This method of creating a [`TheWorld`] will perform string + /// lookups for all exports when this method is called. This + /// will only succeed if the provided instance matches the + /// requirements of [`TheWorld`]. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let y = _instance + .get_export(&mut store, None, "y") + .ok_or_else(|| anyhow::anyhow!("no function export `y` found"))?; + Ok(TheWorldIndices { y }) + } + /// Uses the indices stored in `self` to load an instance + /// of [`TheWorld`] from the instance provided. + /// + /// Note that at this time this method will additionally + /// perform type-checks of all exports. + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let y = *_instance.get_typed_func::<(), ()>(&mut store, &self.y)?.func(); + Ok(TheWorld { y }) + } + } + impl TheWorld { + /// Convenience wrapper around [`TheWorldPre::new`] and + /// [`TheWorldPre::instantiate_async`]. + pub async fn instantiate_async<_T>( + mut store: impl wasmtime::AsContextMut, + component: &wasmtime::component::Component, + linker: &wasmtime::component::Linker<_T>, + ) -> wasmtime::Result + where + _T: Send, + { + let pre = linker.instantiate_pre(component)?; + TheWorldPre::new(pre)?.instantiate_async(store).await + } + /// Convenience wrapper around [`TheWorldIndices::new_instance`] and + /// [`TheWorldIndices::load`]. + pub fn new( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let indices = TheWorldIndices::new_instance(&mut store, instance)?; + indices.load(store, instance) + } + pub async fn call_y( + &self, + mut store: S, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = "default", function + = "y", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::<(), ()>::new_unchecked(self.y) + }; + let () = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee.post_return_async(store.as_context_mut()).instrument(span).await?; + Ok(()) + } + } +}; diff --git a/crates/component-macro/tests/expanded/smoke-export_tracing_async.rs b/crates/component-macro/tests/expanded/smoke-export_tracing_async.rs new file mode 100644 index 000000000000..9427cbcaa928 --- /dev/null +++ b/crates/component-macro/tests/expanded/smoke-export_tracing_async.rs @@ -0,0 +1,280 @@ +/// Auto-generated bindings for a pre-instantiated version of a +/// component which implements the world `the-world`. +/// +/// This structure is created through [`TheWorldPre::new`] which +/// takes a [`InstancePre`](wasmtime::component::InstancePre) that +/// has been created through a [`Linker`](wasmtime::component::Linker). +/// +/// For more information see [`TheWorld`] as well. +pub struct TheWorldPre { + instance_pre: wasmtime::component::InstancePre, + indices: TheWorldIndices, +} +impl Clone for TheWorldPre { + fn clone(&self) -> Self { + Self { + instance_pre: self.instance_pre.clone(), + indices: self.indices.clone(), + } + } +} +impl<_T> TheWorldPre<_T> { + /// Creates a new copy of `TheWorldPre` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component behind `instance_pre` + /// does not have the required exports. + pub fn new( + instance_pre: wasmtime::component::InstancePre<_T>, + ) -> wasmtime::Result { + let indices = TheWorldIndices::new(instance_pre.component())?; + Ok(Self { instance_pre, indices }) + } + pub fn engine(&self) -> &wasmtime::Engine { + self.instance_pre.engine() + } + pub fn instance_pre(&self) -> &wasmtime::component::InstancePre<_T> { + &self.instance_pre + } + /// Instantiates a new instance of [`TheWorld`] within the + /// `store` provided. + /// + /// This function will use `self` as the pre-instantiated + /// instance to perform instantiation. Afterwards the preloaded + /// indices in `self` are used to lookup all exports on the + /// resulting instance. + pub async fn instantiate_async( + &self, + mut store: impl wasmtime::AsContextMut, + ) -> wasmtime::Result + where + _T: Send, + { + let mut store = store.as_context_mut(); + let instance = self.instance_pre.instantiate_async(&mut store).await?; + self.indices.load(&mut store, &instance) + } +} +/// Auto-generated bindings for index of the exports of +/// `the-world`. +/// +/// This is an implementation detail of [`TheWorldPre`] and can +/// be constructed if needed as well. +/// +/// For more information see [`TheWorld`] as well. +#[derive(Clone)] +pub struct TheWorldIndices { + interface0: exports::the_name::GuestIndices, +} +/// Auto-generated bindings for an instance a component which +/// implements the world `the-world`. +/// +/// This structure can be created through a number of means +/// depending on your requirements and what you have on hand: +/// +/// * The most convenient way is to use +/// [`TheWorld::instantiate_async`] which only needs a +/// [`Store`], [`Component`], and [`Linker`]. +/// +/// * Alternatively you can create a [`TheWorldPre`] ahead of +/// time with a [`Component`] to front-load string lookups +/// of exports once instead of per-instantiation. This +/// method then uses [`TheWorldPre::instantiate_async`] to +/// create a [`TheWorld`]. +/// +/// * If you've instantiated the instance yourself already +/// then you can use [`TheWorld::new`]. +/// +/// * You can also access the guts of instantiation through +/// [`TheWorldIndices::new_instance`] followed +/// by [`TheWorldIndices::load`] to crate an instance of this +/// type. +/// +/// These methods are all equivalent to one another and move +/// around the tradeoff of what work is performed when. +/// +/// [`Store`]: wasmtime::Store +/// [`Component`]: wasmtime::component::Component +/// [`Linker`]: wasmtime::component::Linker +pub struct TheWorld { + interface0: exports::the_name::Guest, +} +const _: () = { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + impl TheWorldIndices { + /// Creates a new copy of `TheWorldIndices` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component does not have the + /// required exports. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let _component = component; + let interface0 = exports::the_name::GuestIndices::new(_component)?; + Ok(TheWorldIndices { interface0 }) + } + /// Creates a new instance of [`TheWorldIndices`] from an + /// instantiated component. + /// + /// This method of creating a [`TheWorld`] will perform string + /// lookups for all exports when this method is called. This + /// will only succeed if the provided instance matches the + /// requirements of [`TheWorld`]. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = exports::the_name::GuestIndices::new_instance( + &mut store, + _instance, + )?; + Ok(TheWorldIndices { interface0 }) + } + /// Uses the indices stored in `self` to load an instance + /// of [`TheWorld`] from the instance provided. + /// + /// Note that at this time this method will additionally + /// perform type-checks of all exports. + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = self.interface0.load(&mut store, &_instance)?; + Ok(TheWorld { interface0 }) + } + } + impl TheWorld { + /// Convenience wrapper around [`TheWorldPre::new`] and + /// [`TheWorldPre::instantiate_async`]. + pub async fn instantiate_async<_T>( + mut store: impl wasmtime::AsContextMut, + component: &wasmtime::component::Component, + linker: &wasmtime::component::Linker<_T>, + ) -> wasmtime::Result + where + _T: Send, + { + let pre = linker.instantiate_pre(component)?; + TheWorldPre::new(pre)?.instantiate_async(store).await + } + /// Convenience wrapper around [`TheWorldIndices::new_instance`] and + /// [`TheWorldIndices::load`]. + pub fn new( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let indices = TheWorldIndices::new_instance(&mut store, instance)?; + indices.load(store, instance) + } + pub fn the_name(&self) -> &exports::the_name::Guest { + &self.interface0 + } + } +}; +pub mod exports { + #[allow(clippy::all)] + pub mod the_name { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + pub struct Guest { + y: wasmtime::component::Func, + } + #[derive(Clone)] + pub struct GuestIndices { + y: wasmtime::component::ComponentExportIndex, + } + impl GuestIndices { + /// Constructor for [`GuestIndices`] which takes a + /// [`Component`](wasmtime::component::Component) as input and can be executed + /// before instantiation. + /// + /// This constructor can be used to front-load string lookups to find exports + /// within a component. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let (_, instance) = component + .export_index(None, "the-name") + .ok_or_else(|| { + anyhow::anyhow!("no exported instance named `the-name`") + })?; + Self::_new(|name| { + component.export_index(Some(&instance), name).map(|p| p.1) + }) + } + /// This constructor is similar to [`GuestIndices::new`] except that it + /// performs string lookups after instantiation time. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let instance_export = instance + .get_export(&mut store, None, "the-name") + .ok_or_else(|| { + anyhow::anyhow!("no exported instance named `the-name`") + })?; + Self::_new(|name| { + instance.get_export(&mut store, Some(&instance_export), name) + }) + } + fn _new( + mut lookup: impl FnMut( + &str, + ) -> Option, + ) -> wasmtime::Result { + let mut lookup = move |name| { + lookup(name) + .ok_or_else(|| { + anyhow::anyhow!( + "instance export `the-name` does \ + not have export `{name}`" + ) + }) + }; + let _ = &mut lookup; + let y = lookup("y")?; + Ok(GuestIndices { y }) + } + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let mut store = store.as_context_mut(); + let _ = &mut store; + let _instance = instance; + let y = *_instance.get_typed_func::<(), ()>(&mut store, &self.y)?.func(); + Ok(Guest { y }) + } + } + impl Guest { + pub async fn call_y( + &self, + mut store: S, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = "the-name", + function = "y", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::<(), ()>::new_unchecked(self.y) + }; + let () = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee.post_return_async(store.as_context_mut()).instrument(span).await?; + Ok(()) + } + } + } +} diff --git a/crates/component-macro/tests/expanded/smoke_tracing_async.rs b/crates/component-macro/tests/expanded/smoke_tracing_async.rs new file mode 100644 index 000000000000..a3cd2582d13a --- /dev/null +++ b/crates/component-macro/tests/expanded/smoke_tracing_async.rs @@ -0,0 +1,246 @@ +/// Auto-generated bindings for a pre-instantiated version of a +/// component which implements the world `the-world`. +/// +/// This structure is created through [`TheWorldPre::new`] which +/// takes a [`InstancePre`](wasmtime::component::InstancePre) that +/// has been created through a [`Linker`](wasmtime::component::Linker). +/// +/// For more information see [`TheWorld`] as well. +pub struct TheWorldPre { + instance_pre: wasmtime::component::InstancePre, + indices: TheWorldIndices, +} +impl Clone for TheWorldPre { + fn clone(&self) -> Self { + Self { + instance_pre: self.instance_pre.clone(), + indices: self.indices.clone(), + } + } +} +impl<_T> TheWorldPre<_T> { + /// Creates a new copy of `TheWorldPre` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component behind `instance_pre` + /// does not have the required exports. + pub fn new( + instance_pre: wasmtime::component::InstancePre<_T>, + ) -> wasmtime::Result { + let indices = TheWorldIndices::new(instance_pre.component())?; + Ok(Self { instance_pre, indices }) + } + pub fn engine(&self) -> &wasmtime::Engine { + self.instance_pre.engine() + } + pub fn instance_pre(&self) -> &wasmtime::component::InstancePre<_T> { + &self.instance_pre + } + /// Instantiates a new instance of [`TheWorld`] within the + /// `store` provided. + /// + /// This function will use `self` as the pre-instantiated + /// instance to perform instantiation. Afterwards the preloaded + /// indices in `self` are used to lookup all exports on the + /// resulting instance. + pub async fn instantiate_async( + &self, + mut store: impl wasmtime::AsContextMut, + ) -> wasmtime::Result + where + _T: Send, + { + let mut store = store.as_context_mut(); + let instance = self.instance_pre.instantiate_async(&mut store).await?; + self.indices.load(&mut store, &instance) + } +} +/// Auto-generated bindings for index of the exports of +/// `the-world`. +/// +/// This is an implementation detail of [`TheWorldPre`] and can +/// be constructed if needed as well. +/// +/// For more information see [`TheWorld`] as well. +#[derive(Clone)] +pub struct TheWorldIndices {} +/// Auto-generated bindings for an instance a component which +/// implements the world `the-world`. +/// +/// This structure can be created through a number of means +/// depending on your requirements and what you have on hand: +/// +/// * The most convenient way is to use +/// [`TheWorld::instantiate_async`] which only needs a +/// [`Store`], [`Component`], and [`Linker`]. +/// +/// * Alternatively you can create a [`TheWorldPre`] ahead of +/// time with a [`Component`] to front-load string lookups +/// of exports once instead of per-instantiation. This +/// method then uses [`TheWorldPre::instantiate_async`] to +/// create a [`TheWorld`]. +/// +/// * If you've instantiated the instance yourself already +/// then you can use [`TheWorld::new`]. +/// +/// * You can also access the guts of instantiation through +/// [`TheWorldIndices::new_instance`] followed +/// by [`TheWorldIndices::load`] to crate an instance of this +/// type. +/// +/// These methods are all equivalent to one another and move +/// around the tradeoff of what work is performed when. +/// +/// [`Store`]: wasmtime::Store +/// [`Component`]: wasmtime::component::Component +/// [`Linker`]: wasmtime::component::Linker +pub struct TheWorld {} +const _: () = { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + impl TheWorldIndices { + /// Creates a new copy of `TheWorldIndices` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component does not have the + /// required exports. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let _component = component; + Ok(TheWorldIndices {}) + } + /// Creates a new instance of [`TheWorldIndices`] from an + /// instantiated component. + /// + /// This method of creating a [`TheWorld`] will perform string + /// lookups for all exports when this method is called. This + /// will only succeed if the provided instance matches the + /// requirements of [`TheWorld`]. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + Ok(TheWorldIndices {}) + } + /// Uses the indices stored in `self` to load an instance + /// of [`TheWorld`] from the instance provided. + /// + /// Note that at this time this method will additionally + /// perform type-checks of all exports. + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + Ok(TheWorld {}) + } + } + impl TheWorld { + /// Convenience wrapper around [`TheWorldPre::new`] and + /// [`TheWorldPre::instantiate_async`]. + pub async fn instantiate_async<_T>( + mut store: impl wasmtime::AsContextMut, + component: &wasmtime::component::Component, + linker: &wasmtime::component::Linker<_T>, + ) -> wasmtime::Result + where + _T: Send, + { + let pre = linker.instantiate_pre(component)?; + TheWorldPre::new(pre)?.instantiate_async(store).await + } + /// Convenience wrapper around [`TheWorldIndices::new_instance`] and + /// [`TheWorldIndices::load`]. + pub fn new( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let indices = TheWorldIndices::new_instance(&mut store, instance)?; + indices.load(store, instance) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + T: Send, + U: imports::Host + Send, + { + imports::add_to_linker(linker, get)?; + Ok(()) + } + } +}; +#[allow(clippy::all)] +pub mod imports { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send { + async fn y(&mut self) -> (); + } + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("imports")?; + inst.func_wrap_async( + "y", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = "", + function = "y", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::y(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn y(&mut self) -> () { + Host::y(*self).await + } + } +} diff --git a/crates/component-macro/tests/expanded/strings_tracing_async.rs b/crates/component-macro/tests/expanded/strings_tracing_async.rs new file mode 100644 index 000000000000..c7d2ae7f767f --- /dev/null +++ b/crates/component-macro/tests/expanded/strings_tracing_async.rs @@ -0,0 +1,538 @@ +/// Auto-generated bindings for a pre-instantiated version of a +/// component which implements the world `the-world`. +/// +/// This structure is created through [`TheWorldPre::new`] which +/// takes a [`InstancePre`](wasmtime::component::InstancePre) that +/// has been created through a [`Linker`](wasmtime::component::Linker). +/// +/// For more information see [`TheWorld`] as well. +pub struct TheWorldPre { + instance_pre: wasmtime::component::InstancePre, + indices: TheWorldIndices, +} +impl Clone for TheWorldPre { + fn clone(&self) -> Self { + Self { + instance_pre: self.instance_pre.clone(), + indices: self.indices.clone(), + } + } +} +impl<_T> TheWorldPre<_T> { + /// Creates a new copy of `TheWorldPre` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component behind `instance_pre` + /// does not have the required exports. + pub fn new( + instance_pre: wasmtime::component::InstancePre<_T>, + ) -> wasmtime::Result { + let indices = TheWorldIndices::new(instance_pre.component())?; + Ok(Self { instance_pre, indices }) + } + pub fn engine(&self) -> &wasmtime::Engine { + self.instance_pre.engine() + } + pub fn instance_pre(&self) -> &wasmtime::component::InstancePre<_T> { + &self.instance_pre + } + /// Instantiates a new instance of [`TheWorld`] within the + /// `store` provided. + /// + /// This function will use `self` as the pre-instantiated + /// instance to perform instantiation. Afterwards the preloaded + /// indices in `self` are used to lookup all exports on the + /// resulting instance. + pub async fn instantiate_async( + &self, + mut store: impl wasmtime::AsContextMut, + ) -> wasmtime::Result + where + _T: Send, + { + let mut store = store.as_context_mut(); + let instance = self.instance_pre.instantiate_async(&mut store).await?; + self.indices.load(&mut store, &instance) + } +} +/// Auto-generated bindings for index of the exports of +/// `the-world`. +/// +/// This is an implementation detail of [`TheWorldPre`] and can +/// be constructed if needed as well. +/// +/// For more information see [`TheWorld`] as well. +#[derive(Clone)] +pub struct TheWorldIndices { + interface0: exports::foo::foo::strings::GuestIndices, +} +/// Auto-generated bindings for an instance a component which +/// implements the world `the-world`. +/// +/// This structure can be created through a number of means +/// depending on your requirements and what you have on hand: +/// +/// * The most convenient way is to use +/// [`TheWorld::instantiate_async`] which only needs a +/// [`Store`], [`Component`], and [`Linker`]. +/// +/// * Alternatively you can create a [`TheWorldPre`] ahead of +/// time with a [`Component`] to front-load string lookups +/// of exports once instead of per-instantiation. This +/// method then uses [`TheWorldPre::instantiate_async`] to +/// create a [`TheWorld`]. +/// +/// * If you've instantiated the instance yourself already +/// then you can use [`TheWorld::new`]. +/// +/// * You can also access the guts of instantiation through +/// [`TheWorldIndices::new_instance`] followed +/// by [`TheWorldIndices::load`] to crate an instance of this +/// type. +/// +/// These methods are all equivalent to one another and move +/// around the tradeoff of what work is performed when. +/// +/// [`Store`]: wasmtime::Store +/// [`Component`]: wasmtime::component::Component +/// [`Linker`]: wasmtime::component::Linker +pub struct TheWorld { + interface0: exports::foo::foo::strings::Guest, +} +const _: () = { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + impl TheWorldIndices { + /// Creates a new copy of `TheWorldIndices` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component does not have the + /// required exports. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let _component = component; + let interface0 = exports::foo::foo::strings::GuestIndices::new(_component)?; + Ok(TheWorldIndices { interface0 }) + } + /// Creates a new instance of [`TheWorldIndices`] from an + /// instantiated component. + /// + /// This method of creating a [`TheWorld`] will perform string + /// lookups for all exports when this method is called. This + /// will only succeed if the provided instance matches the + /// requirements of [`TheWorld`]. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = exports::foo::foo::strings::GuestIndices::new_instance( + &mut store, + _instance, + )?; + Ok(TheWorldIndices { interface0 }) + } + /// Uses the indices stored in `self` to load an instance + /// of [`TheWorld`] from the instance provided. + /// + /// Note that at this time this method will additionally + /// perform type-checks of all exports. + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = self.interface0.load(&mut store, &_instance)?; + Ok(TheWorld { interface0 }) + } + } + impl TheWorld { + /// Convenience wrapper around [`TheWorldPre::new`] and + /// [`TheWorldPre::instantiate_async`]. + pub async fn instantiate_async<_T>( + mut store: impl wasmtime::AsContextMut, + component: &wasmtime::component::Component, + linker: &wasmtime::component::Linker<_T>, + ) -> wasmtime::Result + where + _T: Send, + { + let pre = linker.instantiate_pre(component)?; + TheWorldPre::new(pre)?.instantiate_async(store).await + } + /// Convenience wrapper around [`TheWorldIndices::new_instance`] and + /// [`TheWorldIndices::load`]. + pub fn new( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let indices = TheWorldIndices::new_instance(&mut store, instance)?; + indices.load(store, instance) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + T: Send, + U: foo::foo::strings::Host + Send, + { + foo::foo::strings::add_to_linker(linker, get)?; + Ok(()) + } + pub fn foo_foo_strings(&self) -> &exports::foo::foo::strings::Guest { + &self.interface0 + } + } +}; +pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod strings { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send { + async fn a(&mut self, x: wasmtime::component::__internal::String) -> (); + async fn b(&mut self) -> wasmtime::component::__internal::String; + async fn c( + &mut self, + a: wasmtime::component::__internal::String, + b: wasmtime::component::__internal::String, + ) -> wasmtime::component::__internal::String; + } + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("foo:foo/strings")?; + inst.func_wrap_async( + "a", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (wasmtime::component::__internal::String,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "strings", function = "a", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::a(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "b", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "strings", function = "b", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::b(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "c", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + ( + arg0, + arg1, + ): ( + wasmtime::component::__internal::String, + wasmtime::component::__internal::String, + )| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "strings", function = "c", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, a = tracing::field::debug(& arg0), b + = tracing::field::debug(& arg1), "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::c(host, arg0, arg1).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn a(&mut self, x: wasmtime::component::__internal::String) -> () { + Host::a(*self, x).await + } + async fn b(&mut self) -> wasmtime::component::__internal::String { + Host::b(*self).await + } + async fn c( + &mut self, + a: wasmtime::component::__internal::String, + b: wasmtime::component::__internal::String, + ) -> wasmtime::component::__internal::String { + Host::c(*self, a, b).await + } + } + } + } +} +pub mod exports { + pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod strings { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + pub struct Guest { + a: wasmtime::component::Func, + b: wasmtime::component::Func, + c: wasmtime::component::Func, + } + #[derive(Clone)] + pub struct GuestIndices { + a: wasmtime::component::ComponentExportIndex, + b: wasmtime::component::ComponentExportIndex, + c: wasmtime::component::ComponentExportIndex, + } + impl GuestIndices { + /// Constructor for [`GuestIndices`] which takes a + /// [`Component`](wasmtime::component::Component) as input and can be executed + /// before instantiation. + /// + /// This constructor can be used to front-load string lookups to find exports + /// within a component. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let (_, instance) = component + .export_index(None, "foo:foo/strings") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/strings`" + ) + })?; + Self::_new(|name| { + component.export_index(Some(&instance), name).map(|p| p.1) + }) + } + /// This constructor is similar to [`GuestIndices::new`] except that it + /// performs string lookups after instantiation time. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let instance_export = instance + .get_export(&mut store, None, "foo:foo/strings") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/strings`" + ) + })?; + Self::_new(|name| { + instance.get_export(&mut store, Some(&instance_export), name) + }) + } + fn _new( + mut lookup: impl FnMut( + &str, + ) -> Option, + ) -> wasmtime::Result { + let mut lookup = move |name| { + lookup(name) + .ok_or_else(|| { + anyhow::anyhow!( + "instance export `foo:foo/strings` does \ + not have export `{name}`" + ) + }) + }; + let _ = &mut lookup; + let a = lookup("a")?; + let b = lookup("b")?; + let c = lookup("c")?; + Ok(GuestIndices { a, b, c }) + } + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let mut store = store.as_context_mut(); + let _ = &mut store; + let _instance = instance; + let a = *_instance + .get_typed_func::<(&str,), ()>(&mut store, &self.a)? + .func(); + let b = *_instance + .get_typed_func::< + (), + (wasmtime::component::__internal::String,), + >(&mut store, &self.b)? + .func(); + let c = *_instance + .get_typed_func::< + (&str, &str), + (wasmtime::component::__internal::String,), + >(&mut store, &self.c)? + .func(); + Ok(Guest { a, b, c }) + } + } + impl Guest { + pub async fn call_a( + &self, + mut store: S, + arg0: &str, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/strings", function = "a", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (&str,), + (), + >::new_unchecked(self.a) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_b( + &self, + mut store: S, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/strings", function = "b", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (wasmtime::component::__internal::String,), + >::new_unchecked(self.b) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_c( + &self, + mut store: S, + arg0: &str, + arg1: &str, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/strings", function = "c", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (&str, &str), + (wasmtime::component::__internal::String,), + >::new_unchecked(self.c) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), (arg0, arg1)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + } + } + } + } +} diff --git a/crates/component-macro/tests/expanded/unversioned-foo_tracing_async.rs b/crates/component-macro/tests/expanded/unversioned-foo_tracing_async.rs new file mode 100644 index 000000000000..062ca5b258f7 --- /dev/null +++ b/crates/component-macro/tests/expanded/unversioned-foo_tracing_async.rs @@ -0,0 +1,278 @@ +/// Auto-generated bindings for a pre-instantiated version of a +/// component which implements the world `nope`. +/// +/// This structure is created through [`NopePre::new`] which +/// takes a [`InstancePre`](wasmtime::component::InstancePre) that +/// has been created through a [`Linker`](wasmtime::component::Linker). +/// +/// For more information see [`Nope`] as well. +pub struct NopePre { + instance_pre: wasmtime::component::InstancePre, + indices: NopeIndices, +} +impl Clone for NopePre { + fn clone(&self) -> Self { + Self { + instance_pre: self.instance_pre.clone(), + indices: self.indices.clone(), + } + } +} +impl<_T> NopePre<_T> { + /// Creates a new copy of `NopePre` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component behind `instance_pre` + /// does not have the required exports. + pub fn new( + instance_pre: wasmtime::component::InstancePre<_T>, + ) -> wasmtime::Result { + let indices = NopeIndices::new(instance_pre.component())?; + Ok(Self { instance_pre, indices }) + } + pub fn engine(&self) -> &wasmtime::Engine { + self.instance_pre.engine() + } + pub fn instance_pre(&self) -> &wasmtime::component::InstancePre<_T> { + &self.instance_pre + } + /// Instantiates a new instance of [`Nope`] within the + /// `store` provided. + /// + /// This function will use `self` as the pre-instantiated + /// instance to perform instantiation. Afterwards the preloaded + /// indices in `self` are used to lookup all exports on the + /// resulting instance. + pub async fn instantiate_async( + &self, + mut store: impl wasmtime::AsContextMut, + ) -> wasmtime::Result + where + _T: Send, + { + let mut store = store.as_context_mut(); + let instance = self.instance_pre.instantiate_async(&mut store).await?; + self.indices.load(&mut store, &instance) + } +} +/// Auto-generated bindings for index of the exports of +/// `nope`. +/// +/// This is an implementation detail of [`NopePre`] and can +/// be constructed if needed as well. +/// +/// For more information see [`Nope`] as well. +#[derive(Clone)] +pub struct NopeIndices {} +/// Auto-generated bindings for an instance a component which +/// implements the world `nope`. +/// +/// This structure can be created through a number of means +/// depending on your requirements and what you have on hand: +/// +/// * The most convenient way is to use +/// [`Nope::instantiate_async`] which only needs a +/// [`Store`], [`Component`], and [`Linker`]. +/// +/// * Alternatively you can create a [`NopePre`] ahead of +/// time with a [`Component`] to front-load string lookups +/// of exports once instead of per-instantiation. This +/// method then uses [`NopePre::instantiate_async`] to +/// create a [`Nope`]. +/// +/// * If you've instantiated the instance yourself already +/// then you can use [`Nope::new`]. +/// +/// * You can also access the guts of instantiation through +/// [`NopeIndices::new_instance`] followed +/// by [`NopeIndices::load`] to crate an instance of this +/// type. +/// +/// These methods are all equivalent to one another and move +/// around the tradeoff of what work is performed when. +/// +/// [`Store`]: wasmtime::Store +/// [`Component`]: wasmtime::component::Component +/// [`Linker`]: wasmtime::component::Linker +pub struct Nope {} +const _: () = { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + impl NopeIndices { + /// Creates a new copy of `NopeIndices` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component does not have the + /// required exports. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let _component = component; + Ok(NopeIndices {}) + } + /// Creates a new instance of [`NopeIndices`] from an + /// instantiated component. + /// + /// This method of creating a [`Nope`] will perform string + /// lookups for all exports when this method is called. This + /// will only succeed if the provided instance matches the + /// requirements of [`Nope`]. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + Ok(NopeIndices {}) + } + /// Uses the indices stored in `self` to load an instance + /// of [`Nope`] from the instance provided. + /// + /// Note that at this time this method will additionally + /// perform type-checks of all exports. + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + Ok(Nope {}) + } + } + impl Nope { + /// Convenience wrapper around [`NopePre::new`] and + /// [`NopePre::instantiate_async`]. + pub async fn instantiate_async<_T>( + mut store: impl wasmtime::AsContextMut, + component: &wasmtime::component::Component, + linker: &wasmtime::component::Linker<_T>, + ) -> wasmtime::Result + where + _T: Send, + { + let pre = linker.instantiate_pre(component)?; + NopePre::new(pre)?.instantiate_async(store).await + } + /// Convenience wrapper around [`NopeIndices::new_instance`] and + /// [`NopeIndices::load`]. + pub fn new( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let indices = NopeIndices::new_instance(&mut store, instance)?; + indices.load(store, instance) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + T: Send, + U: foo::foo::a::Host + Send, + { + foo::foo::a::add_to_linker(linker, get)?; + Ok(()) + } + } +}; +pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod a { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(variant)] + #[derive(Clone)] + pub enum Error { + #[component(name = "other")] + Other(wasmtime::component::__internal::String), + } + impl core::fmt::Debug for Error { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Error::Other(e) => { + f.debug_tuple("Error::Other").field(e).finish() + } + } + } + } + impl core::fmt::Display for Error { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "{:?}", self) + } + } + impl std::error::Error for Error {} + const _: () = { + assert!(12 == < Error as wasmtime::component::ComponentType >::SIZE32); + assert!(4 == < Error as wasmtime::component::ComponentType >::ALIGN32); + }; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send { + async fn g(&mut self) -> Result<(), Error>; + } + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("foo:foo/a")?; + inst.func_wrap_async( + "g", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = "a", + function = "g", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::g(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn g(&mut self) -> Result<(), Error> { + Host::g(*self).await + } + } + } + } +} diff --git a/crates/component-macro/tests/expanded/use-paths_tracing_async.rs b/crates/component-macro/tests/expanded/use-paths_tracing_async.rs new file mode 100644 index 000000000000..3affa9c4cbf7 --- /dev/null +++ b/crates/component-macro/tests/expanded/use-paths_tracing_async.rs @@ -0,0 +1,494 @@ +/// Auto-generated bindings for a pre-instantiated version of a +/// component which implements the world `d`. +/// +/// This structure is created through [`DPre::new`] which +/// takes a [`InstancePre`](wasmtime::component::InstancePre) that +/// has been created through a [`Linker`](wasmtime::component::Linker). +/// +/// For more information see [`D`] as well. +pub struct DPre { + instance_pre: wasmtime::component::InstancePre, + indices: DIndices, +} +impl Clone for DPre { + fn clone(&self) -> Self { + Self { + instance_pre: self.instance_pre.clone(), + indices: self.indices.clone(), + } + } +} +impl<_T> DPre<_T> { + /// Creates a new copy of `DPre` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component behind `instance_pre` + /// does not have the required exports. + pub fn new( + instance_pre: wasmtime::component::InstancePre<_T>, + ) -> wasmtime::Result { + let indices = DIndices::new(instance_pre.component())?; + Ok(Self { instance_pre, indices }) + } + pub fn engine(&self) -> &wasmtime::Engine { + self.instance_pre.engine() + } + pub fn instance_pre(&self) -> &wasmtime::component::InstancePre<_T> { + &self.instance_pre + } + /// Instantiates a new instance of [`D`] within the + /// `store` provided. + /// + /// This function will use `self` as the pre-instantiated + /// instance to perform instantiation. Afterwards the preloaded + /// indices in `self` are used to lookup all exports on the + /// resulting instance. + pub async fn instantiate_async( + &self, + mut store: impl wasmtime::AsContextMut, + ) -> wasmtime::Result + where + _T: Send, + { + let mut store = store.as_context_mut(); + let instance = self.instance_pre.instantiate_async(&mut store).await?; + self.indices.load(&mut store, &instance) + } +} +/// Auto-generated bindings for index of the exports of +/// `d`. +/// +/// This is an implementation detail of [`DPre`] and can +/// be constructed if needed as well. +/// +/// For more information see [`D`] as well. +#[derive(Clone)] +pub struct DIndices {} +/// Auto-generated bindings for an instance a component which +/// implements the world `d`. +/// +/// This structure can be created through a number of means +/// depending on your requirements and what you have on hand: +/// +/// * The most convenient way is to use +/// [`D::instantiate_async`] which only needs a +/// [`Store`], [`Component`], and [`Linker`]. +/// +/// * Alternatively you can create a [`DPre`] ahead of +/// time with a [`Component`] to front-load string lookups +/// of exports once instead of per-instantiation. This +/// method then uses [`DPre::instantiate_async`] to +/// create a [`D`]. +/// +/// * If you've instantiated the instance yourself already +/// then you can use [`D::new`]. +/// +/// * You can also access the guts of instantiation through +/// [`DIndices::new_instance`] followed +/// by [`DIndices::load`] to crate an instance of this +/// type. +/// +/// These methods are all equivalent to one another and move +/// around the tradeoff of what work is performed when. +/// +/// [`Store`]: wasmtime::Store +/// [`Component`]: wasmtime::component::Component +/// [`Linker`]: wasmtime::component::Linker +pub struct D {} +const _: () = { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + impl DIndices { + /// Creates a new copy of `DIndices` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component does not have the + /// required exports. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let _component = component; + Ok(DIndices {}) + } + /// Creates a new instance of [`DIndices`] from an + /// instantiated component. + /// + /// This method of creating a [`D`] will perform string + /// lookups for all exports when this method is called. This + /// will only succeed if the provided instance matches the + /// requirements of [`D`]. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + Ok(DIndices {}) + } + /// Uses the indices stored in `self` to load an instance + /// of [`D`] from the instance provided. + /// + /// Note that at this time this method will additionally + /// perform type-checks of all exports. + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + Ok(D {}) + } + } + impl D { + /// Convenience wrapper around [`DPre::new`] and + /// [`DPre::instantiate_async`]. + pub async fn instantiate_async<_T>( + mut store: impl wasmtime::AsContextMut, + component: &wasmtime::component::Component, + linker: &wasmtime::component::Linker<_T>, + ) -> wasmtime::Result + where + _T: Send, + { + let pre = linker.instantiate_pre(component)?; + DPre::new(pre)?.instantiate_async(store).await + } + /// Convenience wrapper around [`DIndices::new_instance`] and + /// [`DIndices::load`]. + pub fn new( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let indices = DIndices::new_instance(&mut store, instance)?; + indices.load(store, instance) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + T: Send, + U: foo::foo::a::Host + foo::foo::b::Host + foo::foo::c::Host + d::Host + + Send, + { + foo::foo::a::add_to_linker(linker, get)?; + foo::foo::b::add_to_linker(linker, get)?; + foo::foo::c::add_to_linker(linker, get)?; + d::add_to_linker(linker, get)?; + Ok(()) + } + } +}; +pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod a { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(record)] + #[derive(Clone, Copy)] + pub struct Foo {} + impl core::fmt::Debug for Foo { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("Foo").finish() + } + } + const _: () = { + assert!(0 == < Foo as wasmtime::component::ComponentType >::SIZE32); + assert!(1 == < Foo as wasmtime::component::ComponentType >::ALIGN32); + }; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send { + async fn a(&mut self) -> Foo; + } + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("foo:foo/a")?; + inst.func_wrap_async( + "a", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = "a", + function = "a", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::a(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn a(&mut self) -> Foo { + Host::a(*self).await + } + } + } + #[allow(clippy::all)] + pub mod b { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + pub type Foo = super::super::super::foo::foo::a::Foo; + const _: () = { + assert!(0 == < Foo as wasmtime::component::ComponentType >::SIZE32); + assert!(1 == < Foo as wasmtime::component::ComponentType >::ALIGN32); + }; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send { + async fn a(&mut self) -> Foo; + } + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("foo:foo/b")?; + inst.func_wrap_async( + "a", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = "b", + function = "a", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::a(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn a(&mut self) -> Foo { + Host::a(*self).await + } + } + } + #[allow(clippy::all)] + pub mod c { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + pub type Foo = super::super::super::foo::foo::b::Foo; + const _: () = { + assert!(0 == < Foo as wasmtime::component::ComponentType >::SIZE32); + assert!(1 == < Foo as wasmtime::component::ComponentType >::ALIGN32); + }; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send { + async fn a(&mut self) -> Foo; + } + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("foo:foo/c")?; + inst.func_wrap_async( + "a", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = "c", + function = "a", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::a(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn a(&mut self) -> Foo { + Host::a(*self).await + } + } + } + } +} +#[allow(clippy::all)] +pub mod d { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + pub type Foo = super::foo::foo::c::Foo; + const _: () = { + assert!(0 == < Foo as wasmtime::component::ComponentType >::SIZE32); + assert!(1 == < Foo as wasmtime::component::ComponentType >::ALIGN32); + }; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send { + async fn b(&mut self) -> Foo; + } + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("d")?; + inst.func_wrap_async( + "b", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = "", + function = "b", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::b(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn b(&mut self) -> Foo { + Host::b(*self).await + } + } +} diff --git a/crates/component-macro/tests/expanded/variants_tracing_async.rs b/crates/component-macro/tests/expanded/variants_tracing_async.rs new file mode 100644 index 000000000000..94001b2536ca --- /dev/null +++ b/crates/component-macro/tests/expanded/variants_tracing_async.rs @@ -0,0 +1,2705 @@ +/// Auto-generated bindings for a pre-instantiated version of a +/// component which implements the world `my-world`. +/// +/// This structure is created through [`MyWorldPre::new`] which +/// takes a [`InstancePre`](wasmtime::component::InstancePre) that +/// has been created through a [`Linker`](wasmtime::component::Linker). +/// +/// For more information see [`MyWorld`] as well. +pub struct MyWorldPre { + instance_pre: wasmtime::component::InstancePre, + indices: MyWorldIndices, +} +impl Clone for MyWorldPre { + fn clone(&self) -> Self { + Self { + instance_pre: self.instance_pre.clone(), + indices: self.indices.clone(), + } + } +} +impl<_T> MyWorldPre<_T> { + /// Creates a new copy of `MyWorldPre` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component behind `instance_pre` + /// does not have the required exports. + pub fn new( + instance_pre: wasmtime::component::InstancePre<_T>, + ) -> wasmtime::Result { + let indices = MyWorldIndices::new(instance_pre.component())?; + Ok(Self { instance_pre, indices }) + } + pub fn engine(&self) -> &wasmtime::Engine { + self.instance_pre.engine() + } + pub fn instance_pre(&self) -> &wasmtime::component::InstancePre<_T> { + &self.instance_pre + } + /// Instantiates a new instance of [`MyWorld`] within the + /// `store` provided. + /// + /// This function will use `self` as the pre-instantiated + /// instance to perform instantiation. Afterwards the preloaded + /// indices in `self` are used to lookup all exports on the + /// resulting instance. + pub async fn instantiate_async( + &self, + mut store: impl wasmtime::AsContextMut, + ) -> wasmtime::Result + where + _T: Send, + { + let mut store = store.as_context_mut(); + let instance = self.instance_pre.instantiate_async(&mut store).await?; + self.indices.load(&mut store, &instance) + } +} +/// Auto-generated bindings for index of the exports of +/// `my-world`. +/// +/// This is an implementation detail of [`MyWorldPre`] and can +/// be constructed if needed as well. +/// +/// For more information see [`MyWorld`] as well. +#[derive(Clone)] +pub struct MyWorldIndices { + interface0: exports::foo::foo::variants::GuestIndices, +} +/// Auto-generated bindings for an instance a component which +/// implements the world `my-world`. +/// +/// This structure can be created through a number of means +/// depending on your requirements and what you have on hand: +/// +/// * The most convenient way is to use +/// [`MyWorld::instantiate_async`] which only needs a +/// [`Store`], [`Component`], and [`Linker`]. +/// +/// * Alternatively you can create a [`MyWorldPre`] ahead of +/// time with a [`Component`] to front-load string lookups +/// of exports once instead of per-instantiation. This +/// method then uses [`MyWorldPre::instantiate_async`] to +/// create a [`MyWorld`]. +/// +/// * If you've instantiated the instance yourself already +/// then you can use [`MyWorld::new`]. +/// +/// * You can also access the guts of instantiation through +/// [`MyWorldIndices::new_instance`] followed +/// by [`MyWorldIndices::load`] to crate an instance of this +/// type. +/// +/// These methods are all equivalent to one another and move +/// around the tradeoff of what work is performed when. +/// +/// [`Store`]: wasmtime::Store +/// [`Component`]: wasmtime::component::Component +/// [`Linker`]: wasmtime::component::Linker +pub struct MyWorld { + interface0: exports::foo::foo::variants::Guest, +} +const _: () = { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + impl MyWorldIndices { + /// Creates a new copy of `MyWorldIndices` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component does not have the + /// required exports. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let _component = component; + let interface0 = exports::foo::foo::variants::GuestIndices::new(_component)?; + Ok(MyWorldIndices { interface0 }) + } + /// Creates a new instance of [`MyWorldIndices`] from an + /// instantiated component. + /// + /// This method of creating a [`MyWorld`] will perform string + /// lookups for all exports when this method is called. This + /// will only succeed if the provided instance matches the + /// requirements of [`MyWorld`]. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = exports::foo::foo::variants::GuestIndices::new_instance( + &mut store, + _instance, + )?; + Ok(MyWorldIndices { interface0 }) + } + /// Uses the indices stored in `self` to load an instance + /// of [`MyWorld`] from the instance provided. + /// + /// Note that at this time this method will additionally + /// perform type-checks of all exports. + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = self.interface0.load(&mut store, &_instance)?; + Ok(MyWorld { interface0 }) + } + } + impl MyWorld { + /// Convenience wrapper around [`MyWorldPre::new`] and + /// [`MyWorldPre::instantiate_async`]. + pub async fn instantiate_async<_T>( + mut store: impl wasmtime::AsContextMut, + component: &wasmtime::component::Component, + linker: &wasmtime::component::Linker<_T>, + ) -> wasmtime::Result + where + _T: Send, + { + let pre = linker.instantiate_pre(component)?; + MyWorldPre::new(pre)?.instantiate_async(store).await + } + /// Convenience wrapper around [`MyWorldIndices::new_instance`] and + /// [`MyWorldIndices::load`]. + pub fn new( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let indices = MyWorldIndices::new_instance(&mut store, instance)?; + indices.load(store, instance) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + T: Send, + U: foo::foo::variants::Host + Send, + { + foo::foo::variants::add_to_linker(linker, get)?; + Ok(()) + } + pub fn foo_foo_variants(&self) -> &exports::foo::foo::variants::Guest { + &self.interface0 + } + } +}; +pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod variants { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(enum)] + #[derive(Clone, Copy, Eq, PartialEq)] + #[repr(u8)] + pub enum E1 { + #[component(name = "a")] + A, + } + impl core::fmt::Debug for E1 { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + E1::A => f.debug_tuple("E1::A").finish(), + } + } + } + const _: () = { + assert!(1 == < E1 as wasmtime::component::ComponentType >::SIZE32); + assert!(1 == < E1 as wasmtime::component::ComponentType >::ALIGN32); + }; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(record)] + #[derive(Clone, Copy)] + pub struct Empty {} + impl core::fmt::Debug for Empty { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("Empty").finish() + } + } + const _: () = { + assert!(0 == < Empty as wasmtime::component::ComponentType >::SIZE32); + assert!(1 == < Empty as wasmtime::component::ComponentType >::ALIGN32); + }; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(variant)] + #[derive(Clone)] + pub enum V1 { + #[component(name = "a")] + A, + #[component(name = "c")] + C(E1), + #[component(name = "d")] + D(wasmtime::component::__internal::String), + #[component(name = "e")] + E(Empty), + #[component(name = "f")] + F, + #[component(name = "g")] + G(u32), + } + impl core::fmt::Debug for V1 { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + V1::A => f.debug_tuple("V1::A").finish(), + V1::C(e) => f.debug_tuple("V1::C").field(e).finish(), + V1::D(e) => f.debug_tuple("V1::D").field(e).finish(), + V1::E(e) => f.debug_tuple("V1::E").field(e).finish(), + V1::F => f.debug_tuple("V1::F").finish(), + V1::G(e) => f.debug_tuple("V1::G").field(e).finish(), + } + } + } + const _: () = { + assert!(12 == < V1 as wasmtime::component::ComponentType >::SIZE32); + assert!(4 == < V1 as wasmtime::component::ComponentType >::ALIGN32); + }; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(variant)] + #[derive(Clone, Copy)] + pub enum Casts1 { + #[component(name = "a")] + A(i32), + #[component(name = "b")] + B(f32), + } + impl core::fmt::Debug for Casts1 { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Casts1::A(e) => f.debug_tuple("Casts1::A").field(e).finish(), + Casts1::B(e) => f.debug_tuple("Casts1::B").field(e).finish(), + } + } + } + const _: () = { + assert!(8 == < Casts1 as wasmtime::component::ComponentType >::SIZE32); + assert!(4 == < Casts1 as wasmtime::component::ComponentType >::ALIGN32); + }; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(variant)] + #[derive(Clone, Copy)] + pub enum Casts2 { + #[component(name = "a")] + A(f64), + #[component(name = "b")] + B(f32), + } + impl core::fmt::Debug for Casts2 { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Casts2::A(e) => f.debug_tuple("Casts2::A").field(e).finish(), + Casts2::B(e) => f.debug_tuple("Casts2::B").field(e).finish(), + } + } + } + const _: () = { + assert!(16 == < Casts2 as wasmtime::component::ComponentType >::SIZE32); + assert!(8 == < Casts2 as wasmtime::component::ComponentType >::ALIGN32); + }; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(variant)] + #[derive(Clone, Copy)] + pub enum Casts3 { + #[component(name = "a")] + A(f64), + #[component(name = "b")] + B(u64), + } + impl core::fmt::Debug for Casts3 { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Casts3::A(e) => f.debug_tuple("Casts3::A").field(e).finish(), + Casts3::B(e) => f.debug_tuple("Casts3::B").field(e).finish(), + } + } + } + const _: () = { + assert!(16 == < Casts3 as wasmtime::component::ComponentType >::SIZE32); + assert!(8 == < Casts3 as wasmtime::component::ComponentType >::ALIGN32); + }; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(variant)] + #[derive(Clone, Copy)] + pub enum Casts4 { + #[component(name = "a")] + A(u32), + #[component(name = "b")] + B(i64), + } + impl core::fmt::Debug for Casts4 { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Casts4::A(e) => f.debug_tuple("Casts4::A").field(e).finish(), + Casts4::B(e) => f.debug_tuple("Casts4::B").field(e).finish(), + } + } + } + const _: () = { + assert!(16 == < Casts4 as wasmtime::component::ComponentType >::SIZE32); + assert!(8 == < Casts4 as wasmtime::component::ComponentType >::ALIGN32); + }; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(variant)] + #[derive(Clone, Copy)] + pub enum Casts5 { + #[component(name = "a")] + A(f32), + #[component(name = "b")] + B(i64), + } + impl core::fmt::Debug for Casts5 { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Casts5::A(e) => f.debug_tuple("Casts5::A").field(e).finish(), + Casts5::B(e) => f.debug_tuple("Casts5::B").field(e).finish(), + } + } + } + const _: () = { + assert!(16 == < Casts5 as wasmtime::component::ComponentType >::SIZE32); + assert!(8 == < Casts5 as wasmtime::component::ComponentType >::ALIGN32); + }; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(variant)] + #[derive(Clone, Copy)] + pub enum Casts6 { + #[component(name = "a")] + A((f32, u32)), + #[component(name = "b")] + B((u32, u32)), + } + impl core::fmt::Debug for Casts6 { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Casts6::A(e) => f.debug_tuple("Casts6::A").field(e).finish(), + Casts6::B(e) => f.debug_tuple("Casts6::B").field(e).finish(), + } + } + } + const _: () = { + assert!(12 == < Casts6 as wasmtime::component::ComponentType >::SIZE32); + assert!(4 == < Casts6 as wasmtime::component::ComponentType >::ALIGN32); + }; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(enum)] + #[derive(Clone, Copy, Eq, PartialEq)] + #[repr(u8)] + pub enum MyErrno { + #[component(name = "bad1")] + Bad1, + #[component(name = "bad2")] + Bad2, + } + impl MyErrno { + pub fn name(&self) -> &'static str { + match self { + MyErrno::Bad1 => "bad1", + MyErrno::Bad2 => "bad2", + } + } + pub fn message(&self) -> &'static str { + match self { + MyErrno::Bad1 => "", + MyErrno::Bad2 => "", + } + } + } + impl core::fmt::Debug for MyErrno { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("MyErrno") + .field("code", &(*self as i32)) + .field("name", &self.name()) + .field("message", &self.message()) + .finish() + } + } + impl core::fmt::Display for MyErrno { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "{} (error {})", self.name(), * self as i32) + } + } + impl std::error::Error for MyErrno {} + const _: () = { + assert!(1 == < MyErrno as wasmtime::component::ComponentType >::SIZE32); + assert!(1 == < MyErrno as wasmtime::component::ComponentType >::ALIGN32); + }; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(record)] + #[derive(Clone)] + pub struct IsClone { + #[component(name = "v1")] + pub v1: V1, + } + impl core::fmt::Debug for IsClone { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("IsClone").field("v1", &self.v1).finish() + } + } + const _: () = { + assert!(12 == < IsClone as wasmtime::component::ComponentType >::SIZE32); + assert!(4 == < IsClone as wasmtime::component::ComponentType >::ALIGN32); + }; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send { + async fn e1_arg(&mut self, x: E1) -> (); + async fn e1_result(&mut self) -> E1; + async fn v1_arg(&mut self, x: V1) -> (); + async fn v1_result(&mut self) -> V1; + async fn bool_arg(&mut self, x: bool) -> (); + async fn bool_result(&mut self) -> bool; + async fn option_arg( + &mut self, + a: Option, + b: Option<()>, + c: Option, + d: Option, + e: Option, + g: Option>, + ) -> (); + async fn option_result( + &mut self, + ) -> ( + Option, + Option<()>, + Option, + Option, + Option, + Option>, + ); + async fn casts( + &mut self, + a: Casts1, + b: Casts2, + c: Casts3, + d: Casts4, + e: Casts5, + f: Casts6, + ) -> (Casts1, Casts2, Casts3, Casts4, Casts5, Casts6); + async fn result_arg( + &mut self, + a: Result<(), ()>, + b: Result<(), E1>, + c: Result, + d: Result<(), ()>, + e: Result, + f: Result< + wasmtime::component::__internal::String, + wasmtime::component::__internal::Vec, + >, + ) -> (); + async fn result_result( + &mut self, + ) -> ( + Result<(), ()>, + Result<(), E1>, + Result, + Result<(), ()>, + Result, + Result< + wasmtime::component::__internal::String, + wasmtime::component::__internal::Vec, + >, + ); + async fn return_result_sugar(&mut self) -> Result; + async fn return_result_sugar2(&mut self) -> Result<(), MyErrno>; + async fn return_result_sugar3(&mut self) -> Result; + async fn return_result_sugar4(&mut self) -> Result<(i32, u32), MyErrno>; + async fn return_option_sugar(&mut self) -> Option; + async fn return_option_sugar2(&mut self) -> Option; + async fn result_simple(&mut self) -> Result; + async fn is_clone_arg(&mut self, a: IsClone) -> (); + async fn is_clone_return(&mut self) -> IsClone; + async fn return_named_option(&mut self) -> Option; + async fn return_named_result(&mut self) -> Result; + } + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("foo:foo/variants")?; + inst.func_wrap_async( + "e1-arg", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (E1,)| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "variants", function = "e1-arg", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::e1_arg(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "e1-result", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "variants", function = "e1-result", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::e1_result(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "v1-arg", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (V1,)| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "variants", function = "v1-arg", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::v1_arg(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "v1-result", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "variants", function = "v1-result", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::v1_result(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "bool-arg", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (bool,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "variants", function = "bool-arg", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, x = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::bool_arg(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "bool-result", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "variants", function = "bool-result", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::bool_result(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "option-arg", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + ( + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + ): ( + Option, + Option<()>, + Option, + Option, + Option, + Option>, + )| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "variants", function = "option-arg", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, a = tracing::field::debug(& arg0), b + = tracing::field::debug(& arg1), c = tracing::field::debug(& + arg2), d = tracing::field::debug(& arg3), e = + tracing::field::debug(& arg4), g = tracing::field::debug(& + arg5), "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::option_arg( + host, + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + ) + .await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "option-result", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "variants", function = "option-result", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::option_result(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "casts", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + ( + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + ): (Casts1, Casts2, Casts3, Casts4, Casts5, Casts6)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "variants", function = "casts", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, a = tracing::field::debug(& arg0), b + = tracing::field::debug(& arg1), c = tracing::field::debug(& + arg2), d = tracing::field::debug(& arg3), e = + tracing::field::debug(& arg4), f = tracing::field::debug(& + arg5), "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::casts( + host, + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + ) + .await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "result-arg", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + ( + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + ): ( + Result<(), ()>, + Result<(), E1>, + Result, + Result<(), ()>, + Result, + Result< + wasmtime::component::__internal::String, + wasmtime::component::__internal::Vec, + >, + )| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "variants", function = "result-arg", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, a = tracing::field::debug(& arg0), b + = tracing::field::debug(& arg1), c = tracing::field::debug(& + arg2), d = tracing::field::debug(& arg3), e = + tracing::field::debug(& arg4), f = tracing::field::debug(& + arg5), "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::result_arg( + host, + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + ) + .await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "result-result", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "variants", function = "result-result", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::result_result(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "return-result-sugar", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "variants", function = "return-result-sugar", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::return_result_sugar(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "return-result-sugar2", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "variants", function = "return-result-sugar2", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::return_result_sugar2(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "return-result-sugar3", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "variants", function = "return-result-sugar3", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::return_result_sugar3(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "return-result-sugar4", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "variants", function = "return-result-sugar4", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::return_result_sugar4(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "return-option-sugar", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "variants", function = "return-option-sugar", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::return_option_sugar(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "return-option-sugar2", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "variants", function = "return-option-sugar2", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::return_option_sugar2(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "result-simple", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "variants", function = "result-simple", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::result_simple(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "is-clone-arg", + move | + mut caller: wasmtime::StoreContextMut<'_, T>, + (arg0,): (IsClone,)| + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "variants", function = "is-clone-arg", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!( + tracing::Level::TRACE, a = tracing::field::debug(& arg0), + "call" + ); + let host = &mut host_getter(caller.data_mut()); + let r = Host::is_clone_arg(host, arg0).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok(r) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "is-clone-return", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "variants", function = "is-clone-return", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::is_clone_return(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "return-named-option", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "variants", function = "return-named-option", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::return_named_option(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + inst.func_wrap_async( + "return-named-result", + move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen import", module = + "variants", function = "return-named-result", + ); + wasmtime::component::__internal::Box::new( + async move { + tracing::event!(tracing::Level::TRACE, "call"); + let host = &mut host_getter(caller.data_mut()); + let r = Host::return_named_result(host).await; + tracing::event!( + tracing::Level::TRACE, result = tracing::field::debug(& r), + "return" + ); + Ok((r,)) + } + .instrument(span), + ) + }, + )?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn e1_arg(&mut self, x: E1) -> () { + Host::e1_arg(*self, x).await + } + async fn e1_result(&mut self) -> E1 { + Host::e1_result(*self).await + } + async fn v1_arg(&mut self, x: V1) -> () { + Host::v1_arg(*self, x).await + } + async fn v1_result(&mut self) -> V1 { + Host::v1_result(*self).await + } + async fn bool_arg(&mut self, x: bool) -> () { + Host::bool_arg(*self, x).await + } + async fn bool_result(&mut self) -> bool { + Host::bool_result(*self).await + } + async fn option_arg( + &mut self, + a: Option, + b: Option<()>, + c: Option, + d: Option, + e: Option, + g: Option>, + ) -> () { + Host::option_arg(*self, a, b, c, d, e, g).await + } + async fn option_result( + &mut self, + ) -> ( + Option, + Option<()>, + Option, + Option, + Option, + Option>, + ) { + Host::option_result(*self).await + } + async fn casts( + &mut self, + a: Casts1, + b: Casts2, + c: Casts3, + d: Casts4, + e: Casts5, + f: Casts6, + ) -> (Casts1, Casts2, Casts3, Casts4, Casts5, Casts6) { + Host::casts(*self, a, b, c, d, e, f).await + } + async fn result_arg( + &mut self, + a: Result<(), ()>, + b: Result<(), E1>, + c: Result, + d: Result<(), ()>, + e: Result, + f: Result< + wasmtime::component::__internal::String, + wasmtime::component::__internal::Vec, + >, + ) -> () { + Host::result_arg(*self, a, b, c, d, e, f).await + } + async fn result_result( + &mut self, + ) -> ( + Result<(), ()>, + Result<(), E1>, + Result, + Result<(), ()>, + Result, + Result< + wasmtime::component::__internal::String, + wasmtime::component::__internal::Vec, + >, + ) { + Host::result_result(*self).await + } + async fn return_result_sugar(&mut self) -> Result { + Host::return_result_sugar(*self).await + } + async fn return_result_sugar2(&mut self) -> Result<(), MyErrno> { + Host::return_result_sugar2(*self).await + } + async fn return_result_sugar3(&mut self) -> Result { + Host::return_result_sugar3(*self).await + } + async fn return_result_sugar4(&mut self) -> Result<(i32, u32), MyErrno> { + Host::return_result_sugar4(*self).await + } + async fn return_option_sugar(&mut self) -> Option { + Host::return_option_sugar(*self).await + } + async fn return_option_sugar2(&mut self) -> Option { + Host::return_option_sugar2(*self).await + } + async fn result_simple(&mut self) -> Result { + Host::result_simple(*self).await + } + async fn is_clone_arg(&mut self, a: IsClone) -> () { + Host::is_clone_arg(*self, a).await + } + async fn is_clone_return(&mut self) -> IsClone { + Host::is_clone_return(*self).await + } + async fn return_named_option(&mut self) -> Option { + Host::return_named_option(*self).await + } + async fn return_named_result(&mut self) -> Result { + Host::return_named_result(*self).await + } + } + } + } +} +pub mod exports { + pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod variants { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(enum)] + #[derive(Clone, Copy, Eq, PartialEq)] + #[repr(u8)] + pub enum E1 { + #[component(name = "a")] + A, + } + impl core::fmt::Debug for E1 { + fn fmt( + &self, + f: &mut core::fmt::Formatter<'_>, + ) -> core::fmt::Result { + match self { + E1::A => f.debug_tuple("E1::A").finish(), + } + } + } + const _: () = { + assert!(1 == < E1 as wasmtime::component::ComponentType >::SIZE32); + assert!(1 == < E1 as wasmtime::component::ComponentType >::ALIGN32); + }; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(record)] + #[derive(Clone, Copy)] + pub struct Empty {} + impl core::fmt::Debug for Empty { + fn fmt( + &self, + f: &mut core::fmt::Formatter<'_>, + ) -> core::fmt::Result { + f.debug_struct("Empty").finish() + } + } + const _: () = { + assert!( + 0 == < Empty as wasmtime::component::ComponentType >::SIZE32 + ); + assert!( + 1 == < Empty as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(variant)] + #[derive(Clone)] + pub enum V1 { + #[component(name = "a")] + A, + #[component(name = "c")] + C(E1), + #[component(name = "d")] + D(wasmtime::component::__internal::String), + #[component(name = "e")] + E(Empty), + #[component(name = "f")] + F, + #[component(name = "g")] + G(u32), + } + impl core::fmt::Debug for V1 { + fn fmt( + &self, + f: &mut core::fmt::Formatter<'_>, + ) -> core::fmt::Result { + match self { + V1::A => f.debug_tuple("V1::A").finish(), + V1::C(e) => f.debug_tuple("V1::C").field(e).finish(), + V1::D(e) => f.debug_tuple("V1::D").field(e).finish(), + V1::E(e) => f.debug_tuple("V1::E").field(e).finish(), + V1::F => f.debug_tuple("V1::F").finish(), + V1::G(e) => f.debug_tuple("V1::G").field(e).finish(), + } + } + } + const _: () = { + assert!(12 == < V1 as wasmtime::component::ComponentType >::SIZE32); + assert!(4 == < V1 as wasmtime::component::ComponentType >::ALIGN32); + }; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(variant)] + #[derive(Clone, Copy)] + pub enum Casts1 { + #[component(name = "a")] + A(i32), + #[component(name = "b")] + B(f32), + } + impl core::fmt::Debug for Casts1 { + fn fmt( + &self, + f: &mut core::fmt::Formatter<'_>, + ) -> core::fmt::Result { + match self { + Casts1::A(e) => f.debug_tuple("Casts1::A").field(e).finish(), + Casts1::B(e) => f.debug_tuple("Casts1::B").field(e).finish(), + } + } + } + const _: () = { + assert!( + 8 == < Casts1 as wasmtime::component::ComponentType >::SIZE32 + ); + assert!( + 4 == < Casts1 as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(variant)] + #[derive(Clone, Copy)] + pub enum Casts2 { + #[component(name = "a")] + A(f64), + #[component(name = "b")] + B(f32), + } + impl core::fmt::Debug for Casts2 { + fn fmt( + &self, + f: &mut core::fmt::Formatter<'_>, + ) -> core::fmt::Result { + match self { + Casts2::A(e) => f.debug_tuple("Casts2::A").field(e).finish(), + Casts2::B(e) => f.debug_tuple("Casts2::B").field(e).finish(), + } + } + } + const _: () = { + assert!( + 16 == < Casts2 as wasmtime::component::ComponentType >::SIZE32 + ); + assert!( + 8 == < Casts2 as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(variant)] + #[derive(Clone, Copy)] + pub enum Casts3 { + #[component(name = "a")] + A(f64), + #[component(name = "b")] + B(u64), + } + impl core::fmt::Debug for Casts3 { + fn fmt( + &self, + f: &mut core::fmt::Formatter<'_>, + ) -> core::fmt::Result { + match self { + Casts3::A(e) => f.debug_tuple("Casts3::A").field(e).finish(), + Casts3::B(e) => f.debug_tuple("Casts3::B").field(e).finish(), + } + } + } + const _: () = { + assert!( + 16 == < Casts3 as wasmtime::component::ComponentType >::SIZE32 + ); + assert!( + 8 == < Casts3 as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(variant)] + #[derive(Clone, Copy)] + pub enum Casts4 { + #[component(name = "a")] + A(u32), + #[component(name = "b")] + B(i64), + } + impl core::fmt::Debug for Casts4 { + fn fmt( + &self, + f: &mut core::fmt::Formatter<'_>, + ) -> core::fmt::Result { + match self { + Casts4::A(e) => f.debug_tuple("Casts4::A").field(e).finish(), + Casts4::B(e) => f.debug_tuple("Casts4::B").field(e).finish(), + } + } + } + const _: () = { + assert!( + 16 == < Casts4 as wasmtime::component::ComponentType >::SIZE32 + ); + assert!( + 8 == < Casts4 as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(variant)] + #[derive(Clone, Copy)] + pub enum Casts5 { + #[component(name = "a")] + A(f32), + #[component(name = "b")] + B(i64), + } + impl core::fmt::Debug for Casts5 { + fn fmt( + &self, + f: &mut core::fmt::Formatter<'_>, + ) -> core::fmt::Result { + match self { + Casts5::A(e) => f.debug_tuple("Casts5::A").field(e).finish(), + Casts5::B(e) => f.debug_tuple("Casts5::B").field(e).finish(), + } + } + } + const _: () = { + assert!( + 16 == < Casts5 as wasmtime::component::ComponentType >::SIZE32 + ); + assert!( + 8 == < Casts5 as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(variant)] + #[derive(Clone, Copy)] + pub enum Casts6 { + #[component(name = "a")] + A((f32, u32)), + #[component(name = "b")] + B((u32, u32)), + } + impl core::fmt::Debug for Casts6 { + fn fmt( + &self, + f: &mut core::fmt::Formatter<'_>, + ) -> core::fmt::Result { + match self { + Casts6::A(e) => f.debug_tuple("Casts6::A").field(e).finish(), + Casts6::B(e) => f.debug_tuple("Casts6::B").field(e).finish(), + } + } + } + const _: () = { + assert!( + 12 == < Casts6 as wasmtime::component::ComponentType >::SIZE32 + ); + assert!( + 4 == < Casts6 as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(enum)] + #[derive(Clone, Copy, Eq, PartialEq)] + #[repr(u8)] + pub enum MyErrno { + #[component(name = "bad1")] + Bad1, + #[component(name = "bad2")] + Bad2, + } + impl MyErrno { + pub fn name(&self) -> &'static str { + match self { + MyErrno::Bad1 => "bad1", + MyErrno::Bad2 => "bad2", + } + } + pub fn message(&self) -> &'static str { + match self { + MyErrno::Bad1 => "", + MyErrno::Bad2 => "", + } + } + } + impl core::fmt::Debug for MyErrno { + fn fmt( + &self, + f: &mut core::fmt::Formatter<'_>, + ) -> core::fmt::Result { + f.debug_struct("MyErrno") + .field("code", &(*self as i32)) + .field("name", &self.name()) + .field("message", &self.message()) + .finish() + } + } + impl core::fmt::Display for MyErrno { + fn fmt( + &self, + f: &mut core::fmt::Formatter<'_>, + ) -> core::fmt::Result { + write!(f, "{} (error {})", self.name(), * self as i32) + } + } + impl std::error::Error for MyErrno {} + const _: () = { + assert!( + 1 == < MyErrno as wasmtime::component::ComponentType >::SIZE32 + ); + assert!( + 1 == < MyErrno as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + #[derive(wasmtime::component::ComponentType)] + #[derive(wasmtime::component::Lift)] + #[derive(wasmtime::component::Lower)] + #[component(record)] + #[derive(Clone)] + pub struct IsClone { + #[component(name = "v1")] + pub v1: V1, + } + impl core::fmt::Debug for IsClone { + fn fmt( + &self, + f: &mut core::fmt::Formatter<'_>, + ) -> core::fmt::Result { + f.debug_struct("IsClone").field("v1", &self.v1).finish() + } + } + const _: () = { + assert!( + 12 == < IsClone as wasmtime::component::ComponentType >::SIZE32 + ); + assert!( + 4 == < IsClone as wasmtime::component::ComponentType >::ALIGN32 + ); + }; + pub struct Guest { + e1_arg: wasmtime::component::Func, + e1_result: wasmtime::component::Func, + v1_arg: wasmtime::component::Func, + v1_result: wasmtime::component::Func, + bool_arg: wasmtime::component::Func, + bool_result: wasmtime::component::Func, + option_arg: wasmtime::component::Func, + option_result: wasmtime::component::Func, + casts: wasmtime::component::Func, + result_arg: wasmtime::component::Func, + result_result: wasmtime::component::Func, + return_result_sugar: wasmtime::component::Func, + return_result_sugar2: wasmtime::component::Func, + return_result_sugar3: wasmtime::component::Func, + return_result_sugar4: wasmtime::component::Func, + return_option_sugar: wasmtime::component::Func, + return_option_sugar2: wasmtime::component::Func, + result_simple: wasmtime::component::Func, + is_clone_arg: wasmtime::component::Func, + is_clone_return: wasmtime::component::Func, + return_named_option: wasmtime::component::Func, + return_named_result: wasmtime::component::Func, + } + #[derive(Clone)] + pub struct GuestIndices { + e1_arg: wasmtime::component::ComponentExportIndex, + e1_result: wasmtime::component::ComponentExportIndex, + v1_arg: wasmtime::component::ComponentExportIndex, + v1_result: wasmtime::component::ComponentExportIndex, + bool_arg: wasmtime::component::ComponentExportIndex, + bool_result: wasmtime::component::ComponentExportIndex, + option_arg: wasmtime::component::ComponentExportIndex, + option_result: wasmtime::component::ComponentExportIndex, + casts: wasmtime::component::ComponentExportIndex, + result_arg: wasmtime::component::ComponentExportIndex, + result_result: wasmtime::component::ComponentExportIndex, + return_result_sugar: wasmtime::component::ComponentExportIndex, + return_result_sugar2: wasmtime::component::ComponentExportIndex, + return_result_sugar3: wasmtime::component::ComponentExportIndex, + return_result_sugar4: wasmtime::component::ComponentExportIndex, + return_option_sugar: wasmtime::component::ComponentExportIndex, + return_option_sugar2: wasmtime::component::ComponentExportIndex, + result_simple: wasmtime::component::ComponentExportIndex, + is_clone_arg: wasmtime::component::ComponentExportIndex, + is_clone_return: wasmtime::component::ComponentExportIndex, + return_named_option: wasmtime::component::ComponentExportIndex, + return_named_result: wasmtime::component::ComponentExportIndex, + } + impl GuestIndices { + /// Constructor for [`GuestIndices`] which takes a + /// [`Component`](wasmtime::component::Component) as input and can be executed + /// before instantiation. + /// + /// This constructor can be used to front-load string lookups to find exports + /// within a component. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let (_, instance) = component + .export_index(None, "foo:foo/variants") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/variants`" + ) + })?; + Self::_new(|name| { + component.export_index(Some(&instance), name).map(|p| p.1) + }) + } + /// This constructor is similar to [`GuestIndices::new`] except that it + /// performs string lookups after instantiation time. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let instance_export = instance + .get_export(&mut store, None, "foo:foo/variants") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `foo:foo/variants`" + ) + })?; + Self::_new(|name| { + instance.get_export(&mut store, Some(&instance_export), name) + }) + } + fn _new( + mut lookup: impl FnMut( + &str, + ) -> Option, + ) -> wasmtime::Result { + let mut lookup = move |name| { + lookup(name) + .ok_or_else(|| { + anyhow::anyhow!( + "instance export `foo:foo/variants` does \ + not have export `{name}`" + ) + }) + }; + let _ = &mut lookup; + let e1_arg = lookup("e1-arg")?; + let e1_result = lookup("e1-result")?; + let v1_arg = lookup("v1-arg")?; + let v1_result = lookup("v1-result")?; + let bool_arg = lookup("bool-arg")?; + let bool_result = lookup("bool-result")?; + let option_arg = lookup("option-arg")?; + let option_result = lookup("option-result")?; + let casts = lookup("casts")?; + let result_arg = lookup("result-arg")?; + let result_result = lookup("result-result")?; + let return_result_sugar = lookup("return-result-sugar")?; + let return_result_sugar2 = lookup("return-result-sugar2")?; + let return_result_sugar3 = lookup("return-result-sugar3")?; + let return_result_sugar4 = lookup("return-result-sugar4")?; + let return_option_sugar = lookup("return-option-sugar")?; + let return_option_sugar2 = lookup("return-option-sugar2")?; + let result_simple = lookup("result-simple")?; + let is_clone_arg = lookup("is-clone-arg")?; + let is_clone_return = lookup("is-clone-return")?; + let return_named_option = lookup("return-named-option")?; + let return_named_result = lookup("return-named-result")?; + Ok(GuestIndices { + e1_arg, + e1_result, + v1_arg, + v1_result, + bool_arg, + bool_result, + option_arg, + option_result, + casts, + result_arg, + result_result, + return_result_sugar, + return_result_sugar2, + return_result_sugar3, + return_result_sugar4, + return_option_sugar, + return_option_sugar2, + result_simple, + is_clone_arg, + is_clone_return, + return_named_option, + return_named_result, + }) + } + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let mut store = store.as_context_mut(); + let _ = &mut store; + let _instance = instance; + let e1_arg = *_instance + .get_typed_func::<(E1,), ()>(&mut store, &self.e1_arg)? + .func(); + let e1_result = *_instance + .get_typed_func::<(), (E1,)>(&mut store, &self.e1_result)? + .func(); + let v1_arg = *_instance + .get_typed_func::<(&V1,), ()>(&mut store, &self.v1_arg)? + .func(); + let v1_result = *_instance + .get_typed_func::<(), (V1,)>(&mut store, &self.v1_result)? + .func(); + let bool_arg = *_instance + .get_typed_func::<(bool,), ()>(&mut store, &self.bool_arg)? + .func(); + let bool_result = *_instance + .get_typed_func::< + (), + (bool,), + >(&mut store, &self.bool_result)? + .func(); + let option_arg = *_instance + .get_typed_func::< + ( + Option, + Option<()>, + Option, + Option, + Option, + Option>, + ), + (), + >(&mut store, &self.option_arg)? + .func(); + let option_result = *_instance + .get_typed_func::< + (), + ( + ( + Option, + Option<()>, + Option, + Option, + Option, + Option>, + ), + ), + >(&mut store, &self.option_result)? + .func(); + let casts = *_instance + .get_typed_func::< + (Casts1, Casts2, Casts3, Casts4, Casts5, Casts6), + ((Casts1, Casts2, Casts3, Casts4, Casts5, Casts6),), + >(&mut store, &self.casts)? + .func(); + let result_arg = *_instance + .get_typed_func::< + ( + Result<(), ()>, + Result<(), E1>, + Result, + Result<(), ()>, + Result, + Result<&str, &[u8]>, + ), + (), + >(&mut store, &self.result_arg)? + .func(); + let result_result = *_instance + .get_typed_func::< + (), + ( + ( + Result<(), ()>, + Result<(), E1>, + Result, + Result<(), ()>, + Result, + Result< + wasmtime::component::__internal::String, + wasmtime::component::__internal::Vec, + >, + ), + ), + >(&mut store, &self.result_result)? + .func(); + let return_result_sugar = *_instance + .get_typed_func::< + (), + (Result,), + >(&mut store, &self.return_result_sugar)? + .func(); + let return_result_sugar2 = *_instance + .get_typed_func::< + (), + (Result<(), MyErrno>,), + >(&mut store, &self.return_result_sugar2)? + .func(); + let return_result_sugar3 = *_instance + .get_typed_func::< + (), + (Result,), + >(&mut store, &self.return_result_sugar3)? + .func(); + let return_result_sugar4 = *_instance + .get_typed_func::< + (), + (Result<(i32, u32), MyErrno>,), + >(&mut store, &self.return_result_sugar4)? + .func(); + let return_option_sugar = *_instance + .get_typed_func::< + (), + (Option,), + >(&mut store, &self.return_option_sugar)? + .func(); + let return_option_sugar2 = *_instance + .get_typed_func::< + (), + (Option,), + >(&mut store, &self.return_option_sugar2)? + .func(); + let result_simple = *_instance + .get_typed_func::< + (), + (Result,), + >(&mut store, &self.result_simple)? + .func(); + let is_clone_arg = *_instance + .get_typed_func::< + (&IsClone,), + (), + >(&mut store, &self.is_clone_arg)? + .func(); + let is_clone_return = *_instance + .get_typed_func::< + (), + (IsClone,), + >(&mut store, &self.is_clone_return)? + .func(); + let return_named_option = *_instance + .get_typed_func::< + (), + (Option,), + >(&mut store, &self.return_named_option)? + .func(); + let return_named_result = *_instance + .get_typed_func::< + (), + (Result,), + >(&mut store, &self.return_named_result)? + .func(); + Ok(Guest { + e1_arg, + e1_result, + v1_arg, + v1_result, + bool_arg, + bool_result, + option_arg, + option_result, + casts, + result_arg, + result_result, + return_result_sugar, + return_result_sugar2, + return_result_sugar3, + return_result_sugar4, + return_option_sugar, + return_option_sugar2, + result_simple, + is_clone_arg, + is_clone_return, + return_named_option, + return_named_result, + }) + } + } + impl Guest { + pub async fn call_e1_arg( + &self, + mut store: S, + arg0: E1, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/variants", function = "e1-arg", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (E1,), + (), + >::new_unchecked(self.e1_arg) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_e1_result( + &self, + mut store: S, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/variants", function = "e1-result", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (E1,), + >::new_unchecked(self.e1_result) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_v1_arg( + &self, + mut store: S, + arg0: &V1, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/variants", function = "v1-arg", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (&V1,), + (), + >::new_unchecked(self.v1_arg) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_v1_result( + &self, + mut store: S, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/variants", function = "v1-result", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (V1,), + >::new_unchecked(self.v1_result) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_bool_arg( + &self, + mut store: S, + arg0: bool, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/variants", function = "bool-arg", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (bool,), + (), + >::new_unchecked(self.bool_arg) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_bool_result( + &self, + mut store: S, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/variants", function = "bool-result", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (bool,), + >::new_unchecked(self.bool_result) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_option_arg( + &self, + mut store: S, + arg0: Option, + arg1: Option<()>, + arg2: Option, + arg3: Option, + arg4: Option, + arg5: Option>, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/variants", function = "option-arg", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + ( + Option, + Option<()>, + Option, + Option, + Option, + Option>, + ), + (), + >::new_unchecked(self.option_arg) + }; + let () = callee + .call_async( + store.as_context_mut(), + (arg0, arg1, arg2, arg3, arg4, arg5), + ) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_option_result( + &self, + mut store: S, + ) -> wasmtime::Result< + ( + Option, + Option<()>, + Option, + Option, + Option, + Option>, + ), + > + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/variants", function = "option-result", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + ( + ( + Option, + Option<()>, + Option, + Option, + Option, + Option>, + ), + ), + >::new_unchecked(self.option_result) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_casts( + &self, + mut store: S, + arg0: Casts1, + arg1: Casts2, + arg2: Casts3, + arg3: Casts4, + arg4: Casts5, + arg5: Casts6, + ) -> wasmtime::Result< + (Casts1, Casts2, Casts3, Casts4, Casts5, Casts6), + > + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/variants", function = "casts", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (Casts1, Casts2, Casts3, Casts4, Casts5, Casts6), + ((Casts1, Casts2, Casts3, Casts4, Casts5, Casts6),), + >::new_unchecked(self.casts) + }; + let (ret0,) = callee + .call_async( + store.as_context_mut(), + (arg0, arg1, arg2, arg3, arg4, arg5), + ) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_result_arg( + &self, + mut store: S, + arg0: Result<(), ()>, + arg1: Result<(), E1>, + arg2: Result, + arg3: Result<(), ()>, + arg4: Result, + arg5: Result<&str, &[u8]>, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/variants", function = "result-arg", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + ( + Result<(), ()>, + Result<(), E1>, + Result, + Result<(), ()>, + Result, + Result<&str, &[u8]>, + ), + (), + >::new_unchecked(self.result_arg) + }; + let () = callee + .call_async( + store.as_context_mut(), + (arg0, arg1, arg2, arg3, arg4, arg5), + ) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_result_result( + &self, + mut store: S, + ) -> wasmtime::Result< + ( + Result<(), ()>, + Result<(), E1>, + Result, + Result<(), ()>, + Result, + Result< + wasmtime::component::__internal::String, + wasmtime::component::__internal::Vec, + >, + ), + > + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/variants", function = "result-result", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + ( + ( + Result<(), ()>, + Result<(), E1>, + Result, + Result<(), ()>, + Result, + Result< + wasmtime::component::__internal::String, + wasmtime::component::__internal::Vec, + >, + ), + ), + >::new_unchecked(self.result_result) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_return_result_sugar( + &self, + mut store: S, + ) -> wasmtime::Result> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/variants", function = "return-result-sugar", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (Result,), + >::new_unchecked(self.return_result_sugar) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_return_result_sugar2( + &self, + mut store: S, + ) -> wasmtime::Result> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/variants", function = "return-result-sugar2", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (Result<(), MyErrno>,), + >::new_unchecked(self.return_result_sugar2) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_return_result_sugar3( + &self, + mut store: S, + ) -> wasmtime::Result> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/variants", function = "return-result-sugar3", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (Result,), + >::new_unchecked(self.return_result_sugar3) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_return_result_sugar4( + &self, + mut store: S, + ) -> wasmtime::Result> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/variants", function = "return-result-sugar4", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (Result<(i32, u32), MyErrno>,), + >::new_unchecked(self.return_result_sugar4) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_return_option_sugar( + &self, + mut store: S, + ) -> wasmtime::Result> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/variants", function = "return-option-sugar", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (Option,), + >::new_unchecked(self.return_option_sugar) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_return_option_sugar2( + &self, + mut store: S, + ) -> wasmtime::Result> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/variants", function = "return-option-sugar2", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (Option,), + >::new_unchecked(self.return_option_sugar2) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_result_simple( + &self, + mut store: S, + ) -> wasmtime::Result> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/variants", function = "result-simple", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (Result,), + >::new_unchecked(self.result_simple) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_is_clone_arg( + &self, + mut store: S, + arg0: &IsClone, + ) -> wasmtime::Result<()> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/variants", function = "is-clone-arg", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (&IsClone,), + (), + >::new_unchecked(self.is_clone_arg) + }; + let () = callee + .call_async(store.as_context_mut(), (arg0,)) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(()) + } + pub async fn call_is_clone_return( + &self, + mut store: S, + ) -> wasmtime::Result + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/variants", function = "is-clone-return", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (IsClone,), + >::new_unchecked(self.is_clone_return) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_return_named_option( + &self, + mut store: S, + ) -> wasmtime::Result> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/variants", function = "return-named-option", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (Option,), + >::new_unchecked(self.return_named_option) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + pub async fn call_return_named_result( + &self, + mut store: S, + ) -> wasmtime::Result> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = + "foo:foo/variants", function = "return-named-result", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::< + (), + (Result,), + >::new_unchecked(self.return_named_result) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee + .post_return_async(store.as_context_mut()) + .instrument(span) + .await?; + Ok(ret0) + } + } + } + } + } +} diff --git a/crates/component-macro/tests/expanded/wat_tracing_async.rs b/crates/component-macro/tests/expanded/wat_tracing_async.rs new file mode 100644 index 000000000000..cad73611fe21 --- /dev/null +++ b/crates/component-macro/tests/expanded/wat_tracing_async.rs @@ -0,0 +1,271 @@ +/// Auto-generated bindings for a pre-instantiated version of a +/// component which implements the world `example`. +/// +/// This structure is created through [`ExamplePre::new`] which +/// takes a [`InstancePre`](wasmtime::component::InstancePre) that +/// has been created through a [`Linker`](wasmtime::component::Linker). +/// +/// For more information see [`Example`] as well. +pub struct ExamplePre { + instance_pre: wasmtime::component::InstancePre, + indices: ExampleIndices, +} +impl Clone for ExamplePre { + fn clone(&self) -> Self { + Self { + instance_pre: self.instance_pre.clone(), + indices: self.indices.clone(), + } + } +} +impl<_T> ExamplePre<_T> { + /// Creates a new copy of `ExamplePre` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component behind `instance_pre` + /// does not have the required exports. + pub fn new( + instance_pre: wasmtime::component::InstancePre<_T>, + ) -> wasmtime::Result { + let indices = ExampleIndices::new(instance_pre.component())?; + Ok(Self { instance_pre, indices }) + } + pub fn engine(&self) -> &wasmtime::Engine { + self.instance_pre.engine() + } + pub fn instance_pre(&self) -> &wasmtime::component::InstancePre<_T> { + &self.instance_pre + } + /// Instantiates a new instance of [`Example`] within the + /// `store` provided. + /// + /// This function will use `self` as the pre-instantiated + /// instance to perform instantiation. Afterwards the preloaded + /// indices in `self` are used to lookup all exports on the + /// resulting instance. + pub async fn instantiate_async( + &self, + mut store: impl wasmtime::AsContextMut, + ) -> wasmtime::Result + where + _T: Send, + { + let mut store = store.as_context_mut(); + let instance = self.instance_pre.instantiate_async(&mut store).await?; + self.indices.load(&mut store, &instance) + } +} +/// Auto-generated bindings for index of the exports of +/// `example`. +/// +/// This is an implementation detail of [`ExamplePre`] and can +/// be constructed if needed as well. +/// +/// For more information see [`Example`] as well. +#[derive(Clone)] +pub struct ExampleIndices { + interface0: exports::same::name::this_name_is_duplicated::GuestIndices, +} +/// Auto-generated bindings for an instance a component which +/// implements the world `example`. +/// +/// This structure can be created through a number of means +/// depending on your requirements and what you have on hand: +/// +/// * The most convenient way is to use +/// [`Example::instantiate_async`] which only needs a +/// [`Store`], [`Component`], and [`Linker`]. +/// +/// * Alternatively you can create a [`ExamplePre`] ahead of +/// time with a [`Component`] to front-load string lookups +/// of exports once instead of per-instantiation. This +/// method then uses [`ExamplePre::instantiate_async`] to +/// create a [`Example`]. +/// +/// * If you've instantiated the instance yourself already +/// then you can use [`Example::new`]. +/// +/// * You can also access the guts of instantiation through +/// [`ExampleIndices::new_instance`] followed +/// by [`ExampleIndices::load`] to crate an instance of this +/// type. +/// +/// These methods are all equivalent to one another and move +/// around the tradeoff of what work is performed when. +/// +/// [`Store`]: wasmtime::Store +/// [`Component`]: wasmtime::component::Component +/// [`Linker`]: wasmtime::component::Linker +pub struct Example { + interface0: exports::same::name::this_name_is_duplicated::Guest, +} +const _: () = { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + impl ExampleIndices { + /// Creates a new copy of `ExampleIndices` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component does not have the + /// required exports. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let _component = component; + let interface0 = exports::same::name::this_name_is_duplicated::GuestIndices::new( + _component, + )?; + Ok(ExampleIndices { interface0 }) + } + /// Creates a new instance of [`ExampleIndices`] from an + /// instantiated component. + /// + /// This method of creating a [`Example`] will perform string + /// lookups for all exports when this method is called. This + /// will only succeed if the provided instance matches the + /// requirements of [`Example`]. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = exports::same::name::this_name_is_duplicated::GuestIndices::new_instance( + &mut store, + _instance, + )?; + Ok(ExampleIndices { interface0 }) + } + /// Uses the indices stored in `self` to load an instance + /// of [`Example`] from the instance provided. + /// + /// Note that at this time this method will additionally + /// perform type-checks of all exports. + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let interface0 = self.interface0.load(&mut store, &_instance)?; + Ok(Example { interface0 }) + } + } + impl Example { + /// Convenience wrapper around [`ExamplePre::new`] and + /// [`ExamplePre::instantiate_async`]. + pub async fn instantiate_async<_T>( + mut store: impl wasmtime::AsContextMut, + component: &wasmtime::component::Component, + linker: &wasmtime::component::Linker<_T>, + ) -> wasmtime::Result + where + _T: Send, + { + let pre = linker.instantiate_pre(component)?; + ExamplePre::new(pre)?.instantiate_async(store).await + } + /// Convenience wrapper around [`ExampleIndices::new_instance`] and + /// [`ExampleIndices::load`]. + pub fn new( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let indices = ExampleIndices::new_instance(&mut store, instance)?; + indices.load(store, instance) + } + pub fn same_name_this_name_is_duplicated( + &self, + ) -> &exports::same::name::this_name_is_duplicated::Guest { + &self.interface0 + } + } +}; +pub mod exports { + pub mod same { + pub mod name { + #[allow(clippy::all)] + pub mod this_name_is_duplicated { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + pub type ThisNameIsDuplicated = wasmtime::component::ResourceAny; + pub struct GuestThisNameIsDuplicated<'a> { + funcs: &'a Guest, + } + pub struct Guest {} + #[derive(Clone)] + pub struct GuestIndices {} + impl GuestIndices { + /// Constructor for [`GuestIndices`] which takes a + /// [`Component`](wasmtime::component::Component) as input and can be executed + /// before instantiation. + /// + /// This constructor can be used to front-load string lookups to find exports + /// within a component. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let (_, instance) = component + .export_index(None, "same:name/this-name-is-duplicated") + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `same:name/this-name-is-duplicated`" + ) + })?; + Self::_new(|name| { + component.export_index(Some(&instance), name).map(|p| p.1) + }) + } + /// This constructor is similar to [`GuestIndices::new`] except that it + /// performs string lookups after instantiation time. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let instance_export = instance + .get_export( + &mut store, + None, + "same:name/this-name-is-duplicated", + ) + .ok_or_else(|| { + anyhow::anyhow!( + "no exported instance named `same:name/this-name-is-duplicated`" + ) + })?; + Self::_new(|name| { + instance.get_export(&mut store, Some(&instance_export), name) + }) + } + fn _new( + mut lookup: impl FnMut( + &str, + ) -> Option, + ) -> wasmtime::Result { + let mut lookup = move |name| { + lookup(name) + .ok_or_else(|| { + anyhow::anyhow!( + "instance export `same:name/this-name-is-duplicated` does \ + not have export `{name}`" + ) + }) + }; + let _ = &mut lookup; + Ok(GuestIndices {}) + } + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let mut store = store.as_context_mut(); + let _ = &mut store; + let _instance = instance; + Ok(Guest {}) + } + } + impl Guest {} + } + } + } +} diff --git a/crates/component-macro/tests/expanded/worlds-with-types_tracing_async.rs b/crates/component-macro/tests/expanded/worlds-with-types_tracing_async.rs new file mode 100644 index 000000000000..63ed3ffff6e4 --- /dev/null +++ b/crates/component-macro/tests/expanded/worlds-with-types_tracing_async.rs @@ -0,0 +1,287 @@ +pub type U = foo::foo::i::T; +const _: () = { + assert!(2 == < U as wasmtime::component::ComponentType >::SIZE32); + assert!(2 == < U as wasmtime::component::ComponentType >::ALIGN32); +}; +pub type T = u32; +const _: () = { + assert!(4 == < T as wasmtime::component::ComponentType >::SIZE32); + assert!(4 == < T as wasmtime::component::ComponentType >::ALIGN32); +}; +#[derive(wasmtime::component::ComponentType)] +#[derive(wasmtime::component::Lift)] +#[derive(wasmtime::component::Lower)] +#[component(record)] +#[derive(Clone, Copy)] +pub struct R {} +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("R").finish() + } +} +const _: () = { + assert!(0 == < R as wasmtime::component::ComponentType >::SIZE32); + assert!(1 == < R as wasmtime::component::ComponentType >::ALIGN32); +}; +/// Auto-generated bindings for a pre-instantiated version of a +/// component which implements the world `foo`. +/// +/// This structure is created through [`FooPre::new`] which +/// takes a [`InstancePre`](wasmtime::component::InstancePre) that +/// has been created through a [`Linker`](wasmtime::component::Linker). +/// +/// For more information see [`Foo`] as well. +pub struct FooPre { + instance_pre: wasmtime::component::InstancePre, + indices: FooIndices, +} +impl Clone for FooPre { + fn clone(&self) -> Self { + Self { + instance_pre: self.instance_pre.clone(), + indices: self.indices.clone(), + } + } +} +impl<_T> FooPre<_T> { + /// Creates a new copy of `FooPre` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component behind `instance_pre` + /// does not have the required exports. + pub fn new( + instance_pre: wasmtime::component::InstancePre<_T>, + ) -> wasmtime::Result { + let indices = FooIndices::new(instance_pre.component())?; + Ok(Self { instance_pre, indices }) + } + pub fn engine(&self) -> &wasmtime::Engine { + self.instance_pre.engine() + } + pub fn instance_pre(&self) -> &wasmtime::component::InstancePre<_T> { + &self.instance_pre + } + /// Instantiates a new instance of [`Foo`] within the + /// `store` provided. + /// + /// This function will use `self` as the pre-instantiated + /// instance to perform instantiation. Afterwards the preloaded + /// indices in `self` are used to lookup all exports on the + /// resulting instance. + pub async fn instantiate_async( + &self, + mut store: impl wasmtime::AsContextMut, + ) -> wasmtime::Result + where + _T: Send, + { + let mut store = store.as_context_mut(); + let instance = self.instance_pre.instantiate_async(&mut store).await?; + self.indices.load(&mut store, &instance) + } +} +/// Auto-generated bindings for index of the exports of +/// `foo`. +/// +/// This is an implementation detail of [`FooPre`] and can +/// be constructed if needed as well. +/// +/// For more information see [`Foo`] as well. +#[derive(Clone)] +pub struct FooIndices { + f: wasmtime::component::ComponentExportIndex, +} +/// Auto-generated bindings for an instance a component which +/// implements the world `foo`. +/// +/// This structure can be created through a number of means +/// depending on your requirements and what you have on hand: +/// +/// * The most convenient way is to use +/// [`Foo::instantiate_async`] which only needs a +/// [`Store`], [`Component`], and [`Linker`]. +/// +/// * Alternatively you can create a [`FooPre`] ahead of +/// time with a [`Component`] to front-load string lookups +/// of exports once instead of per-instantiation. This +/// method then uses [`FooPre::instantiate_async`] to +/// create a [`Foo`]. +/// +/// * If you've instantiated the instance yourself already +/// then you can use [`Foo::new`]. +/// +/// * You can also access the guts of instantiation through +/// [`FooIndices::new_instance`] followed +/// by [`FooIndices::load`] to crate an instance of this +/// type. +/// +/// These methods are all equivalent to one another and move +/// around the tradeoff of what work is performed when. +/// +/// [`Store`]: wasmtime::Store +/// [`Component`]: wasmtime::component::Component +/// [`Linker`]: wasmtime::component::Linker +pub struct Foo { + f: wasmtime::component::Func, +} +const _: () = { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + impl FooIndices { + /// Creates a new copy of `FooIndices` bindings which can then + /// be used to instantiate into a particular store. + /// + /// This method may fail if the component does not have the + /// required exports. + pub fn new( + component: &wasmtime::component::Component, + ) -> wasmtime::Result { + let _component = component; + let f = _component + .export_index(None, "f") + .ok_or_else(|| anyhow::anyhow!("no function export `f` found"))? + .1; + Ok(FooIndices { f }) + } + /// Creates a new instance of [`FooIndices`] from an + /// instantiated component. + /// + /// This method of creating a [`Foo`] will perform string + /// lookups for all exports when this method is called. This + /// will only succeed if the provided instance matches the + /// requirements of [`Foo`]. + pub fn new_instance( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let f = _instance + .get_export(&mut store, None, "f") + .ok_or_else(|| anyhow::anyhow!("no function export `f` found"))?; + Ok(FooIndices { f }) + } + /// Uses the indices stored in `self` to load an instance + /// of [`Foo`] from the instance provided. + /// + /// Note that at this time this method will additionally + /// perform type-checks of all exports. + pub fn load( + &self, + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let _instance = instance; + let f = *_instance + .get_typed_func::<(), ((T, U, R),)>(&mut store, &self.f)? + .func(); + Ok(Foo { f }) + } + } + impl Foo { + /// Convenience wrapper around [`FooPre::new`] and + /// [`FooPre::instantiate_async`]. + pub async fn instantiate_async<_T>( + mut store: impl wasmtime::AsContextMut, + component: &wasmtime::component::Component, + linker: &wasmtime::component::Linker<_T>, + ) -> wasmtime::Result + where + _T: Send, + { + let pre = linker.instantiate_pre(component)?; + FooPre::new(pre)?.instantiate_async(store).await + } + /// Convenience wrapper around [`FooIndices::new_instance`] and + /// [`FooIndices::load`]. + pub fn new( + mut store: impl wasmtime::AsContextMut, + instance: &wasmtime::component::Instance, + ) -> wasmtime::Result { + let indices = FooIndices::new_instance(&mut store, instance)?; + indices.load(store, instance) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + T: Send, + U: foo::foo::i::Host + Send, + { + foo::foo::i::add_to_linker(linker, get)?; + Ok(()) + } + pub async fn call_f( + &self, + mut store: S, + ) -> wasmtime::Result<(T, U, R)> + where + ::Data: Send, + { + use tracing::Instrument; + let span = tracing::span!( + tracing::Level::TRACE, "wit-bindgen export", module = "default", function + = "f", + ); + let callee = unsafe { + wasmtime::component::TypedFunc::<(), ((T, U, R),)>::new_unchecked(self.f) + }; + let (ret0,) = callee + .call_async(store.as_context_mut(), ()) + .instrument(span.clone()) + .await?; + callee.post_return_async(store.as_context_mut()).instrument(span).await?; + Ok(ret0) + } + } +}; +pub mod foo { + pub mod foo { + #[allow(clippy::all)] + pub mod i { + #[allow(unused_imports)] + use wasmtime::component::__internal::anyhow; + pub type T = u16; + const _: () = { + assert!(2 == < T as wasmtime::component::ComponentType >::SIZE32); + assert!(2 == < T as wasmtime::component::ComponentType >::ALIGN32); + }; + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send {} + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where + T: Send, + { + let mut inst = linker.instance("foo:foo/i")?; + Ok(()) + } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T {} + } + } +} diff --git a/crates/wit-bindgen/src/lib.rs b/crates/wit-bindgen/src/lib.rs index aa630827e5a2..338567ccdc94 100644 --- a/crates/wit-bindgen/src/lib.rs +++ b/crates/wit-bindgen/src/lib.rs @@ -2782,6 +2782,10 @@ impl<'a> InterfaceGenerator<'a> { } if self.gen.opts.tracing { + if is_async { + self.src.push_str("use tracing::Instrument;\n"); + } + let ns = match ns { Some(key) => resolve.name_world_key(key), None => "default".to_string(), @@ -2794,10 +2798,17 @@ impl<'a> InterfaceGenerator<'a> { module = \"{ns}\", function = \"{}\", ); - let _enter = span.enter(); ", func.name, )); + + if !is_async { + self.src.push_str( + " + let _enter = span.enter(); + ", + ); + } } self.src.push_str("let callee = unsafe {\n"); @@ -2832,11 +2843,22 @@ impl<'a> InterfaceGenerator<'a> { for (i, _) in func.params.iter().enumerate() { uwrite!(self.src, "arg{}, ", i); } - uwriteln!(self.src, ")){await_}?;"); + let instrument = if is_async && self.gen.opts.tracing { + ".instrument(span.clone())" + } else { + "" + }; + uwriteln!(self.src, ")){instrument}{await_}?;"); + + let instrument = if is_async && self.gen.opts.tracing { + ".instrument(span)" + } else { + "" + }; uwriteln!( self.src, - "callee.post_return{async__}(store.as_context_mut()){await_}?;" + "callee.post_return{async__}(store.as_context_mut()){instrument}{await_}?;" ); self.src.push_str("Ok(");