@@ -7,7 +7,6 @@ pub use crate::instance::execution::{KillError, KillState, KillSuccess, KillSwit
77pub use crate :: instance:: signals:: { signal_handler_none, SignalBehavior , SignalHandler } ;
88pub use crate :: instance:: state:: State ;
99
10- use crate :: alloc:: Alloc ;
1110use crate :: context:: Context ;
1211use crate :: embed_ctx:: CtxMap ;
1312use crate :: error:: Error ;
@@ -18,13 +17,13 @@ use crate::region::RegionInternal;
1817use crate :: sysdeps:: HOST_PAGE_SIZE_EXPECTED ;
1918use crate :: val:: { UntypedRetVal , Val } ;
2019use crate :: WASM_PAGE_SIZE ;
20+ use crate :: { alloc:: Alloc , future:: AsyncContext } ;
2121use libc:: { c_void, pthread_self, siginfo_t, uintptr_t} ;
2222use lucet_module:: InstanceRuntimeData ;
2323use memoffset:: offset_of;
2424use std:: any:: Any ;
2525use std:: cell:: { BorrowError , BorrowMutError , Ref , RefCell , RefMut , UnsafeCell } ;
2626use std:: convert:: TryFrom ;
27- use std:: marker:: PhantomData ;
2827use std:: mem;
2928use std:: ops:: { Deref , DerefMut } ;
3029use std:: ptr:: { self , NonNull } ;
@@ -228,6 +227,10 @@ pub struct Instance {
228227 /// Small mutexed state used for remote kill switch functionality
229228 pub ( crate ) kill_state : Arc < KillState > ,
230229
230+ /// Indicates whether the instance is running in an async context (`Instance::run_async`)
231+ /// or not. Needed by `Vmctx::block_on`.
232+ pub ( crate ) async_ctx : Option < std:: sync:: Arc < AsyncContext > > ,
233+
231234 #[ cfg( feature = "concurrent_testpoints" ) ]
232235 /// Conditionally-present helpers to force permutations of possible races in testing.
233236 pub lock_testpoints : Arc < LockTestpoints > ,
@@ -515,7 +518,7 @@ impl Instance {
515518 /// in the future.
516519 pub fn run ( & mut self , entrypoint : & str , args : & [ Val ] ) -> Result < RunResult , Error > {
517520 let func = self . module . get_export_func ( entrypoint) ?;
518- Ok ( self . run_func ( func, & args, false , None ) ?. unwrap ( ) )
521+ Ok ( self . run_func ( func, & args, None , None ) ?. unwrap ( ) )
519522 }
520523
521524 /// Run a function with arguments in the guest context from the [WebAssembly function
@@ -531,7 +534,7 @@ impl Instance {
531534 args : & [ Val ] ,
532535 ) -> Result < RunResult , Error > {
533536 let func = self . module . get_func_from_idx ( table_idx, func_idx) ?;
534- Ok ( self . run_func ( func, & args, false , None ) ?. unwrap ( ) )
537+ Ok ( self . run_func ( func, & args, None , None ) ?. unwrap ( ) )
535538 }
536539
537540 /// Resume execution of an instance that has yielded without providing a value to the guest.
@@ -562,19 +565,21 @@ impl Instance {
562565 /// The foreign code safety caveat of [`Instance::run()`](struct.Instance.html#method.run)
563566 /// applies.
564567 pub fn resume_with_val < A : Any + ' static > ( & mut self , val : A ) -> Result < RunResult , Error > {
565- Ok ( self . resume_with_val_impl ( val, false , None ) ?. unwrap ( ) )
568+ Ok ( self
569+ . resume_with_val_impl ( Box :: new ( val) , None , None ) ?
570+ . unwrap ( ) )
566571 }
567572
568- pub ( crate ) fn resume_with_val_impl < A : Any + ' static > (
573+ pub ( crate ) fn resume_with_val_impl (
569574 & mut self ,
570- val : A ,
571- async_context : bool ,
575+ val : Box < dyn Any + ' static > ,
576+ async_context : Option < AsyncContext > ,
572577 max_insn_count : Option < u64 > ,
573578 ) -> Result < InternalRunResult , Error > {
574579 match & self . state {
575580 State :: Yielded { expecting, .. } => {
576581 // make sure the resumed value is of the right type
577- if !expecting . is :: < PhantomData < A > > ( ) {
582+ if & ( * val ) . type_id ( ) != expecting {
578583 return Err ( Error :: InvalidArgument (
579584 "type mismatch between yielded instance expected value and resumed value" ,
580585 ) ) ;
@@ -583,7 +588,7 @@ impl Instance {
583588 _ => return Err ( Error :: InvalidArgument ( "can only resume a yielded instance" ) ) ,
584589 }
585590
586- self . resumed_val = Some ( Box :: new ( val) as Box < dyn Any + ' static > ) ;
591+ self . resumed_val = Some ( val) ;
587592
588593 self . set_instruction_bound_delta ( max_insn_count) ;
589594 self . swap_and_return ( async_context)
@@ -602,6 +607,7 @@ impl Instance {
602607 /// applies.
603608 pub ( crate ) fn resume_bounded (
604609 & mut self ,
610+ async_context : AsyncContext ,
605611 max_insn_count : u64 ,
606612 ) -> Result < InternalRunResult , Error > {
607613 if !self . state . is_bound_expired ( ) {
@@ -610,7 +616,7 @@ impl Instance {
610616 ) ) ;
611617 }
612618 self . set_instruction_bound_delta ( Some ( max_insn_count) ) ;
613- self . swap_and_return ( true )
619+ self . swap_and_return ( Some ( async_context ) )
614620 }
615621
616622 /// Run the module's [start function][start], if one exists.
@@ -648,7 +654,7 @@ impl Instance {
648654 if !self . is_not_started ( ) {
649655 return Err ( Error :: StartAlreadyRun ) ;
650656 }
651- self . run_func ( start, & [ ] , false , None ) ?;
657+ self . run_func ( start, & [ ] , None , None ) ?;
652658 }
653659 Ok ( ( ) )
654660 }
@@ -1021,6 +1027,7 @@ impl Instance {
10211027 entrypoint : None ,
10221028 resumed_val : None ,
10231029 terminate_on_heap_oom : false ,
1030+ async_ctx : None ,
10241031 _padding : ( ) ,
10251032 } ;
10261033 inst. set_globals_ptr ( globals_ptr) ;
@@ -1090,7 +1097,7 @@ impl Instance {
10901097 & mut self ,
10911098 func : FunctionHandle ,
10921099 args : & [ Val ] ,
1093- async_context : bool ,
1100+ async_context : Option < AsyncContext > ,
10941101 inst_count_bound : Option < u64 > ,
10951102 ) -> Result < InternalRunResult , Error > {
10961103 let needs_start = self . state . is_not_started ( ) && !func. is_start_func ;
@@ -1191,7 +1198,10 @@ impl Instance {
11911198 /// This must only be called for an instance in a ready, non-fatally faulted, or yielded state,
11921199 /// or in the not-started state on the start function. The public wrappers around this function
11931200 /// should make sure the state is appropriate.
1194- fn swap_and_return ( & mut self , async_context : bool ) -> Result < InternalRunResult , Error > {
1201+ fn swap_and_return < ' a > (
1202+ & mut self ,
1203+ async_context : Option < AsyncContext > ,
1204+ ) -> Result < InternalRunResult , Error > {
11951205 let is_start_func = self
11961206 . entrypoint
11971207 . expect ( "we always have an entrypoint by now" )
@@ -1203,7 +1213,10 @@ impl Instance {
12031213 || self . state. is_yielded( )
12041214 || self . state. is_bound_expired( )
12051215 ) ;
1206- self . state = State :: Running { async_context } ;
1216+
1217+ self . async_ctx = async_context. map ( |cx| Arc :: new ( cx) ) ;
1218+
1219+ self . state = State :: Running ;
12071220
12081221 let res = self . with_current_instance ( |i| {
12091222 i. with_signals_on ( |i| {
@@ -1217,6 +1230,9 @@ impl Instance {
12171230 } )
12181231 } ) ;
12191232
1233+ // remove async ctx
1234+ self . async_ctx . take ( ) ;
1235+
12201236 #[ cfg( feature = "concurrent_testpoints" ) ]
12211237 self . lock_testpoints
12221238 . instance_after_clearing_current_instance
0 commit comments