@@ -14,15 +14,15 @@ use futures::TryStreamExt as _;
14
14
use tokio:: io:: { AsyncRead , AsyncReadExt as _, AsyncWrite , AsyncWriteExt as _} ;
15
15
use tokio:: try_join;
16
16
use tokio_util:: codec:: Encoder ;
17
- use tracing:: { instrument, warn} ;
17
+ use tracing:: { debug , instrument, trace , warn} ;
18
18
use wasm_tokio:: cm:: AsyncReadValue as _;
19
19
use wasm_tokio:: {
20
20
AsyncReadCore as _, AsyncReadLeb128 as _, AsyncReadUtf8 as _, CoreStringEncoder , Leb128Encoder ,
21
21
Utf8Encoder ,
22
22
} ;
23
23
use wasmtime:: component:: types:: { self , Case , Field } ;
24
24
use wasmtime:: component:: { LinkerInstance , Type , Val } ;
25
- use wasmtime:: { AsContextMut , StoreContextMut } ;
25
+ use wasmtime:: { AsContextMut , Engine , StoreContextMut } ;
26
26
use wasmtime_wasi:: WasiView ;
27
27
use wrpc_transport:: { Index as _, Invocation , Invoke , Session } ;
28
28
@@ -44,6 +44,7 @@ impl<T, W> ValEncoder<'_, T, W> {
44
44
}
45
45
}
46
46
47
+ #[ must_use]
47
48
pub fn with_type < ' a > ( & ' a mut self , ty : & ' a Type ) -> ValEncoder < ' a , T , W > {
48
49
ValEncoder {
49
50
store : self . store . as_context_mut ( ) ,
@@ -446,7 +447,9 @@ async fn read_flags(n: usize, r: &mut (impl AsyncRead + Unpin)) -> std::io::Resu
446
447
Ok ( u128:: from_le_bytes ( buf) )
447
448
}
448
449
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 > (
450
453
store : & mut impl AsContextMut < Data = T > ,
451
454
r : & mut Pin < & mut R > ,
452
455
val : & mut Val ,
@@ -534,6 +537,7 @@ where
534
537
for i in 0 ..n {
535
538
let mut v = Val :: Bool ( false ) ;
536
539
path. push ( i) ;
540
+ trace ! ( i, "reading list element value" ) ;
537
541
Box :: pin ( read_value ( store, r, & mut v, & ty, & path) ) . await ?;
538
542
path. pop ( ) ;
539
543
vs. push ( v) ;
@@ -548,6 +552,7 @@ where
548
552
for ( i, Field { name, ty } ) in fields. enumerate ( ) {
549
553
let mut v = Val :: Bool ( false ) ;
550
554
path. push ( i) ;
555
+ trace ! ( i, "reading struct field value" ) ;
551
556
Box :: pin ( read_value ( store, r, & mut v, & ty, & path) ) . await ?;
552
557
path. pop ( ) ;
553
558
vs. push ( ( name. to_string ( ) , v) ) ;
@@ -562,6 +567,7 @@ where
562
567
for ( i, ty) in types. enumerate ( ) {
563
568
let mut v = Val :: Bool ( false ) ;
564
569
path. push ( i) ;
570
+ trace ! ( i, "reading tuple element value" ) ;
565
571
Box :: pin ( read_value ( store, r, & mut v, & ty, & path) ) . await ?;
566
572
path. pop ( ) ;
567
573
vs. push ( v) ;
@@ -583,6 +589,7 @@ where
583
589
let name = name. to_string ( ) ;
584
590
if let Some ( ty) = ty {
585
591
let mut v = Val :: Bool ( false ) ;
592
+ trace ! ( variant = name, "reading nested variant value" ) ;
586
593
Box :: pin ( read_value ( store, r, & mut v, & ty, path) ) . await ?;
587
594
* val = Val :: Variant ( name, Some ( Box :: new ( v) ) ) ;
588
595
} else {
@@ -608,6 +615,7 @@ where
608
615
let ok = r. read_option_status ( ) . await ?;
609
616
if ok {
610
617
let mut v = Val :: Bool ( false ) ;
618
+ trace ! ( "reading nested `option::some` value" ) ;
611
619
Box :: pin ( read_value ( store, r, & mut v, & ty. ty ( ) , path) ) . await ?;
612
620
* val = Val :: Option ( Some ( Box :: new ( v) ) ) ;
613
621
} else {
@@ -620,13 +628,15 @@ where
620
628
if ok {
621
629
if let Some ( ty) = ty. ok ( ) {
622
630
let mut v = Val :: Bool ( false ) ;
631
+ trace ! ( "reading nested `result::ok` value" ) ;
623
632
Box :: pin ( read_value ( store, r, & mut v, & ty, path) ) . await ?;
624
633
* val = Val :: Result ( Ok ( Some ( Box :: new ( v) ) ) ) ;
625
634
} else {
626
635
* val = Val :: Result ( Ok ( None ) ) ;
627
636
}
628
637
} else if let Some ( ty) = ty. err ( ) {
629
638
let mut v = Val :: Bool ( false ) ;
639
+ trace ! ( "reading nested `result::err` value" ) ;
630
640
Box :: pin ( read_value ( store, r, & mut v, & ty, path) ) . await ?;
631
641
* val = Val :: Result ( Err ( Some ( Box :: new ( v) ) ) ) ;
632
642
} else {
@@ -696,6 +706,90 @@ pub trait WrpcView<C: Invoke>: Send {
696
706
fn client ( & self ) -> & C ;
697
707
}
698
708
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
+
699
793
/// Polyfill [`types::ComponentFunc`] in a [`LinkerInstance`] using [`wrpc_transport::Invoke`]
700
794
#[ instrument( level = "trace" , skip_all) ]
701
795
pub fn link_function < ' a , C , V > (
@@ -769,7 +863,7 @@ where
769
863
for ( i, ( v, ref ty) ) in zip( results, ty. results( ) ) . enumerate( ) {
770
864
read_value( & mut store, & mut incoming, v, ty, & [ i] )
771
865
. await
772
- . context ( "failed to decode result value" ) ?;
866
+ . with_context ( || format! ( "failed to decode return value {i}" ) ) ?;
773
867
}
774
868
Ok ( ( ) )
775
869
} ,
0 commit comments