@@ -70,12 +70,26 @@ mod ready_chunks;
7070mod states;
7171mod table;
7272
73+ /// Corresponds to `CallState` in the upstream spec.
7374#[ derive( Clone , Copy , Eq , PartialEq , Debug ) ]
74- #[ repr( u32 ) ]
75- enum Status {
75+ pub enum Status {
7676 Starting = 1 ,
77- Started ,
78- Returned ,
77+ Started = 2 ,
78+ Returned = 3 ,
79+ }
80+
81+ impl Status {
82+ /// Packs this status and the optional `waitable` provided into a 32-bit
83+ /// result that the canonical ABI requires.
84+ ///
85+ /// The low 4 bits are reserved for the status while the upper 28 bits are
86+ /// the waitable, if present.
87+ pub fn pack ( self , waitable : Option < u32 > ) -> u32 {
88+ assert ! ( matches!( self , Status :: Returned ) == waitable. is_none( ) ) ;
89+ let waitable = waitable. unwrap_or ( 0 ) ;
90+ assert ! ( waitable < ( 1 << 28 ) ) ;
91+ ( waitable << 4 ) | ( self as u32 )
92+ }
7993}
8094
8195#[ derive( Clone , Copy , Debug ) ]
@@ -1602,12 +1616,14 @@ impl ComponentInstance {
16021616
16031617 log:: trace!( "status {status:?} for {}" , guest_task. rep( ) ) ;
16041618
1605- let call = if status != Status :: Returned {
1619+ let waitable = if status != Status :: Returned {
16061620 if async_caller {
16071621 self . get_mut ( guest_task) ?. has_suspended = true ;
16081622
1609- self . waitable_tables ( ) [ caller_instance]
1610- . insert ( guest_task. rep ( ) , WaitableState :: GuestTask ) ?
1623+ Some (
1624+ self . waitable_tables ( ) [ caller_instance]
1625+ . insert ( guest_task. rep ( ) , WaitableState :: GuestTask ) ?,
1626+ )
16111627 } else {
16121628 let caller = if let Caller :: Guest { task, .. } = & self . get ( guest_task) ?. caller {
16131629 * task
@@ -1621,10 +1637,10 @@ impl ComponentInstance {
16211637
16221638 self . poll_for_result ( guest_task) ?;
16231639 status = Status :: Returned ;
1624- 0
1640+ None
16251641 }
16261642 } else {
1627- 0
1643+ None
16281644 } ;
16291645
16301646 if let Some ( storage) = storage {
@@ -1635,10 +1651,8 @@ impl ComponentInstance {
16351651 } else {
16361652 return Err ( anyhow ! ( crate :: Trap :: NoAsyncResult ) ) ;
16371653 }
1638- Ok ( 0 )
1639- } else {
1640- Ok ( ( ( status as u32 ) << 30 ) | call)
16411654 }
1655+ Ok ( status. pack ( waitable) )
16421656 }
16431657
16441658 pub ( crate ) fn wrap_call < T , F , P , R > (
0 commit comments