@@ -14,15 +14,15 @@ use futures::TryStreamExt as _;
1414use tokio:: io:: { AsyncRead , AsyncReadExt as _, AsyncWrite , AsyncWriteExt as _} ;
1515use tokio:: try_join;
1616use tokio_util:: codec:: Encoder ;
17- use tracing:: { instrument, warn} ;
17+ use tracing:: { debug , instrument, trace , warn} ;
1818use wasm_tokio:: cm:: AsyncReadValue as _;
1919use wasm_tokio:: {
2020 AsyncReadCore as _, AsyncReadLeb128 as _, AsyncReadUtf8 as _, CoreStringEncoder , Leb128Encoder ,
2121 Utf8Encoder ,
2222} ;
2323use wasmtime:: component:: types:: { self , Case , Field } ;
2424use wasmtime:: component:: { LinkerInstance , Type , Val } ;
25- use wasmtime:: { AsContextMut , StoreContextMut } ;
25+ use wasmtime:: { AsContextMut , Engine , StoreContextMut } ;
2626use wasmtime_wasi:: WasiView ;
2727use wrpc_transport:: { Index as _, Invocation , Invoke , Session } ;
2828
@@ -44,6 +44,7 @@ impl<T, W> ValEncoder<'_, T, W> {
4444 }
4545 }
4646
47+ #[ must_use]
4748 pub fn with_type < ' a > ( & ' a mut self , ty : & ' a Type ) -> ValEncoder < ' a , T , W > {
4849 ValEncoder {
4950 store : self . store . as_context_mut ( ) ,
@@ -446,7 +447,9 @@ async fn read_flags(n: usize, r: &mut (impl AsyncRead + Unpin)) -> std::io::Resu
446447 Ok ( u128:: from_le_bytes ( buf) )
447448}
448449
449- pub async fn read_value < T , R > (
450+ /// Read encoded value of type [`Type`] from an [`AsyncRead`] into a [`Val`]
451+ #[ instrument( level = "trace" , skip_all, fields( ty, path) ) ]
452+ async fn read_value < T , R > (
450453 store : & mut impl AsContextMut < Data = T > ,
451454 r : & mut Pin < & mut R > ,
452455 val : & mut Val ,
@@ -534,6 +537,7 @@ where
534537 for i in 0 ..n {
535538 let mut v = Val :: Bool ( false ) ;
536539 path. push ( i) ;
540+ trace ! ( i, "reading list element value" ) ;
537541 Box :: pin ( read_value ( store, r, & mut v, & ty, & path) ) . await ?;
538542 path. pop ( ) ;
539543 vs. push ( v) ;
@@ -548,6 +552,7 @@ where
548552 for ( i, Field { name, ty } ) in fields. enumerate ( ) {
549553 let mut v = Val :: Bool ( false ) ;
550554 path. push ( i) ;
555+ trace ! ( i, "reading struct field value" ) ;
551556 Box :: pin ( read_value ( store, r, & mut v, & ty, & path) ) . await ?;
552557 path. pop ( ) ;
553558 vs. push ( ( name. to_string ( ) , v) ) ;
@@ -562,6 +567,7 @@ where
562567 for ( i, ty) in types. enumerate ( ) {
563568 let mut v = Val :: Bool ( false ) ;
564569 path. push ( i) ;
570+ trace ! ( i, "reading tuple element value" ) ;
565571 Box :: pin ( read_value ( store, r, & mut v, & ty, & path) ) . await ?;
566572 path. pop ( ) ;
567573 vs. push ( v) ;
@@ -583,6 +589,7 @@ where
583589 let name = name. to_string ( ) ;
584590 if let Some ( ty) = ty {
585591 let mut v = Val :: Bool ( false ) ;
592+ trace ! ( variant = name, "reading nested variant value" ) ;
586593 Box :: pin ( read_value ( store, r, & mut v, & ty, path) ) . await ?;
587594 * val = Val :: Variant ( name, Some ( Box :: new ( v) ) ) ;
588595 } else {
@@ -608,6 +615,7 @@ where
608615 let ok = r. read_option_status ( ) . await ?;
609616 if ok {
610617 let mut v = Val :: Bool ( false ) ;
618+ trace ! ( "reading nested `option::some` value" ) ;
611619 Box :: pin ( read_value ( store, r, & mut v, & ty. ty ( ) , path) ) . await ?;
612620 * val = Val :: Option ( Some ( Box :: new ( v) ) ) ;
613621 } else {
@@ -620,13 +628,15 @@ where
620628 if ok {
621629 if let Some ( ty) = ty. ok ( ) {
622630 let mut v = Val :: Bool ( false ) ;
631+ trace ! ( "reading nested `result::ok` value" ) ;
623632 Box :: pin ( read_value ( store, r, & mut v, & ty, path) ) . await ?;
624633 * val = Val :: Result ( Ok ( Some ( Box :: new ( v) ) ) ) ;
625634 } else {
626635 * val = Val :: Result ( Ok ( None ) ) ;
627636 }
628637 } else if let Some ( ty) = ty. err ( ) {
629638 let mut v = Val :: Bool ( false ) ;
639+ trace ! ( "reading nested `result::err` value" ) ;
630640 Box :: pin ( read_value ( store, r, & mut v, & ty, path) ) . await ?;
631641 * val = Val :: Result ( Err ( Some ( Box :: new ( v) ) ) ) ;
632642 } else {
@@ -696,6 +706,90 @@ pub trait WrpcView<C: Invoke>: Send {
696706 fn client ( & self ) -> & C ;
697707}
698708
709+ /// Polyfill [`types::ComponentItem`] in a [`LinkerInstance`] using [`wrpc_transport::Invoke`]
710+ #[ instrument( level = "trace" , skip_all) ]
711+ pub fn link_item < ' a , C , V > (
712+ engine : & Engine ,
713+ linker : & mut LinkerInstance < V > ,
714+ ty : types:: ComponentItem ,
715+ instance : impl Into < Arc < str > > ,
716+ name : impl Into < Arc < str > > ,
717+ cx : C :: Context ,
718+ ) -> wasmtime:: Result < ( ) >
719+ where
720+ V : WrpcView < C > + WasiView ,
721+ C : Invoke ,
722+ C :: Error : Into < wasmtime:: Error > ,
723+ C :: Context : Clone + ' static ,
724+ <C :: Session as Session >:: TransportError : Into < wasmtime:: Error > ,
725+ <C :: Outgoing as wrpc_transport:: Index < C :: NestedOutgoing > >:: Error : Into < wasmtime:: Error > ,
726+ C :: NestedOutgoing : ' static ,
727+ <C :: NestedOutgoing as wrpc_transport:: Index < C :: NestedOutgoing > >:: Error : Into < wasmtime:: Error > ,
728+ C :: Incoming : Unpin + Sized + ' static ,
729+ <C :: Incoming as wrpc_transport:: Index < C :: Incoming > >:: Error :
730+ Into < Box < dyn std:: error:: Error + Send + Sync > > ,
731+ {
732+ let instance = instance. into ( ) ;
733+ match ty {
734+ types:: ComponentItem :: ComponentFunc ( ty) => {
735+ let name = name. into ( ) ;
736+ debug ! ( ?instance, ?name, "linking function" ) ;
737+ link_function ( linker, ty, instance, name, cx) ?
738+ }
739+ types:: ComponentItem :: CoreFunc ( _) => {
740+ bail ! ( "polyfilling core functions not supported yet" )
741+ }
742+ types:: ComponentItem :: Module ( _) => bail ! ( "polyfilling modules not supported yet" ) ,
743+ types:: ComponentItem :: Component ( ty) => {
744+ for ( name, ty) in ty. imports ( & engine) {
745+ debug ! ( ?instance, name, "linking component item" ) ;
746+ link_item ( engine, linker, ty, "" , name, cx. clone ( ) ) ?;
747+ }
748+ }
749+ types:: ComponentItem :: ComponentInstance ( ty) => {
750+ let name = name. into ( ) ;
751+ let mut linker = linker
752+ . instance ( & name)
753+ . with_context ( || format ! ( "failed to instantiate `{name}` in the linker" ) ) ?;
754+ debug ! ( ?instance, ?name, "linking instance" ) ;
755+ link_instance ( engine, & mut linker, ty, name, cx) ?
756+ }
757+ types:: ComponentItem :: Type ( _) => { }
758+ types:: ComponentItem :: Resource ( _) => bail ! ( "polyfilling resources not supported yet" ) ,
759+ }
760+ Ok ( ( ) )
761+ }
762+
763+ /// Polyfill [`types::ComponentInstance`] in a [`LinkerInstance`] using [`wrpc_transport::Invoke`]
764+ #[ instrument( level = "trace" , skip_all) ]
765+ pub fn link_instance < ' a , C , V > (
766+ engine : & Engine ,
767+ linker : & mut LinkerInstance < V > ,
768+ ty : types:: ComponentInstance ,
769+ name : impl Into < Arc < str > > ,
770+ cx : C :: Context ,
771+ ) -> wasmtime:: Result < ( ) >
772+ where
773+ V : WrpcView < C > + WasiView ,
774+ C : Invoke ,
775+ C :: Error : Into < wasmtime:: Error > ,
776+ C :: Context : Clone + ' static ,
777+ <C :: Session as Session >:: TransportError : Into < wasmtime:: Error > ,
778+ <C :: Outgoing as wrpc_transport:: Index < C :: NestedOutgoing > >:: Error : Into < wasmtime:: Error > ,
779+ C :: NestedOutgoing : ' static ,
780+ <C :: NestedOutgoing as wrpc_transport:: Index < C :: NestedOutgoing > >:: Error : Into < wasmtime:: Error > ,
781+ C :: Incoming : Unpin + Sized + ' static ,
782+ <C :: Incoming as wrpc_transport:: Index < C :: Incoming > >:: Error :
783+ Into < Box < dyn std:: error:: Error + Send + Sync > > ,
784+ {
785+ let instance = name. into ( ) ;
786+ for ( name, ty) in ty. exports ( & engine) {
787+ debug ! ( name, "linking instance item" ) ;
788+ link_item ( engine, linker, ty, Arc :: clone ( & instance) , name, cx. clone ( ) ) ?
789+ }
790+ Ok ( ( ) )
791+ }
792+
699793/// Polyfill [`types::ComponentFunc`] in a [`LinkerInstance`] using [`wrpc_transport::Invoke`]
700794#[ instrument( level = "trace" , skip_all) ]
701795pub fn link_function < ' a , C , V > (
@@ -769,7 +863,7 @@ where
769863 for ( i, ( v, ref ty) ) in zip( results, ty. results( ) ) . enumerate( ) {
770864 read_value( & mut store, & mut incoming, v, ty, & [ i] )
771865 . await
772- . context ( "failed to decode result value" ) ?;
866+ . with_context ( || format! ( "failed to decode return value {i}" ) ) ?;
773867 }
774868 Ok ( ( ) )
775869 } ,
0 commit comments