philpax opened issue #6124:
Feature
wit-bindgen
recently updated its code generation to generate owned-only types by default:https://github.com/bytecodealliance/wit-bindgen/pull/547
https://github.com/bytecodealliance/wit-bindgen/pull/552I would like
wasmtime
to match this.Benefit
As mentioned in https://github.com/bytecodealliance/wit-bindgen/issues/535, binding generation of borrowed types can be tedious with nested types. Owned types simplify this.
Implementation
Porting over the changes from
wit-bindgen
should be sufficient.
alexcrichton commented on issue #6124:
I think that this is already done, but have you found differently when using the
wasmtime::component::bindgen!
macro?
philpax commented on issue #6124:
We've actually refactored our code to make it less necessary now, but
[package] name = "wit-bindgen-borrow-bug-repro" version = "0.1.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] wasmtime = { git = "https://github.com/bytecodealliance/wasmtime.git", rev = "51e8eafff2b0bb2a10efb1452a23c4c9feff4261", features = ["component-model"] }
default world bindings { export exp: self.exp import imp: self.imp } interface common { type value = list<tuple<>> type entity = list<tuple<u32, value>> } interface exp { use self.common.{entity} exp: func(a: entity) -> entity } interface imp { use self.common.{entity} imp: func(a: entity) -> entity }
wasmtime::component::bindgen!("main.bindings"); fn main() { println!("Hello, world!"); }
The bindgen generates
Param
andResult
types:#[allow(clippy::all)] pub mod common { #[allow(unused_imports)] use wasmtime::component::__internal::anyhow; pub type ValueParam<'a> = &'a [()]; const _: () = { { if !(8 == <ValueParam as wasmtime::component::ComponentType>::SIZE32) { $crate::panicking::panic("explicit panic"); } }; { if !(4 == <ValueParam as wasmtime::component::ComponentType>::ALIGN32) { $crate::panicking::panic("explicit panic"); } }; }; pub type ValueResult = Vec<()>; const _: () = { { if !(8 == <ValueResult as wasmtime::component::ComponentType>::SIZE32) { $crate::panicking::panic("explicit panic"); } }; { if !(4 == <ValueResult as wasmtime::component::ComponentType>::ALIGN32) { $crate::panicking::panic("explicit panic"); } }; }; pub type EntityParam<'a> = &'a [(u32, ValueParam<'a>)]; const _: () = { { if !(8 == <EntityParam as wasmtime::component::ComponentType>::SIZE32) { $crate::panicking::panic("explicit panic"); } }; { if !(4 == <EntityParam as wasmtime::component::ComponentType>::ALIGN32) { $crate::panicking::panic("explicit panic"); } }; }; pub type EntityResult = Vec<(u32, ValueResult)>; const _: () = { { if !(8 == <EntityResult as wasmtime::component::ComponentType>::SIZE32) { $crate::panicking::panic("explicit panic"); } }; { if !(4 == <EntityResult as wasmtime::component::ComponentType>::ALIGN32) { $crate::panicking::panic("explicit panic"); } }; }; pub trait Host {} pub fn add_to_linker<T, U>( linker: &mut wasmtime::component::Linker<T>, get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, ) -> wasmtime::Result<()> where U: Host, { let mut inst = linker.instance("common")?; Ok(()) } } #[allow(clippy::all)] pub mod imp { #[allow(unused_imports)] use wasmtime::component::__internal::anyhow; pub type Entity = super::common::EntityResult; const _: () = { { if !(8 == <Entity as wasmtime::component::ComponentType>::SIZE32) { $crate::panicking::panic("explicit panic"); } }; { if !(4 == <Entity as wasmtime::component::ComponentType>::ALIGN32) { $crate::panicking::panic("explicit panic"); } }; }; pub trait Host { fn imp(&mut self, a: Entity) -> wasmtime::Result<Entity>; } pub fn add_to_linker<T, U>( linker: &mut wasmtime::component::Linker<T>, get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, ) -> wasmtime::Result<()> where U: Host, { let mut inst = linker.instance("imp")?; inst.func_wrap( "imp", move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (Entity,)| { let host = get(caller.data_mut()); let r = host.imp(arg0); Ok((r?,)) }, )?; Ok(()) } } #[allow(clippy::all)] pub mod exp { #[allow(unused_imports)] use wasmtime::component::__internal::anyhow; pub type EntityParam<'a> = super::common::EntityParam<'a>; const _: () = { { if !(8 == <EntityParam as wasmtime::component::ComponentType>::SIZE32) { $crate::panicking::panic("explicit panic"); } }; { if !(4 == <EntityParam as wasmtime::component::ComponentType>::ALIGN32) { $crate::panicking::panic("explicit panic"); } }; }; pub type EntityResult = super::common::EntityResult; const _: () = { { if !(8 == <EntityResult as wasmtime::component::ComponentType>::SIZE32) { $crate::panicking::panic("explicit panic"); } }; { if !(4 == <EntityResult as wasmtime::component::ComponentType>::ALIGN32) { $crate::panicking::panic("explicit panic"); } }; }; pub struct Exp { exp: wasmtime::component::Func, } impl Exp { pub fn new( __exports: &mut wasmtime::component::ExportInstance<'_, '_>, ) -> wasmtime::Result<Exp> { let exp = *__exports .typed_func::<(EntityParam<'_>,), (EntityResult,)>("exp")? .func(); Ok(Exp { exp }) } pub fn call_exp<S: wasmtime::AsContextMut>( &self, mut store: S, arg0: EntityParam<'_>, ) -> wasmtime::Result<EntityResult> { let callee = unsafe { wasmtime::component::TypedFunc::<(EntityParam<'_>,), (EntityResult,)>::new_unchecked( self.exp, ) }; let (ret0,) = callee.call(store.as_context_mut(), (arg0,))?; callee.post_return(store.as_context_mut())?; Ok(ret0) } } }
alexcrichton commented on issue #6124:
Ah ok, thanks for the example!
cfallin closed issue #6124:
Feature
wit-bindgen
recently updated its code generation to generate owned-only types by default:https://github.com/bytecodealliance/wit-bindgen/pull/547
https://github.com/bytecodealliance/wit-bindgen/pull/552I would like
wasmtime
to match this.Benefit
As mentioned in https://github.com/bytecodealliance/wit-bindgen/issues/535, binding generation of borrowed types can be tedious with nested types. Owned types simplify this.
Implementation
Porting over the changes from
wit-bindgen
should be sufficient.
Last updated: Dec 23 2024 at 12:05 UTC