4949
5050use {
5151 crate :: {
52- AsContext , AsContextMut , Engine , StoreContext , StoreContextMut , ValRaw ,
5352 component:: {
54- HasData , HasSelf , Instance ,
5553 func:: { self , Func , Options } ,
54+ HasData , HasSelf , Instance ,
5655 } ,
5756 store:: { StoreInner , StoreOpaque , StoreToken } ,
5857 vm:: {
59- AsyncWasmCallState , PreviousAsyncWasmCallState , SendSyncPtr , VMFuncRef ,
60- VMMemoryDefinition , VMStore , VMStoreRawPtr ,
6158 component:: { CallContext , ComponentInstance , InstanceFlags , ResourceTables } ,
6259 mpk:: { self , ProtectionMask } ,
60+ AsyncWasmCallState , PreviousAsyncWasmCallState , SendSyncPtr , VMFuncRef ,
61+ VMMemoryDefinition , VMStore , VMStoreRawPtr ,
6362 } ,
63+ AsContext , AsContextMut , Engine , StoreContext , StoreContextMut , ValRaw ,
6464 } ,
65- anyhow:: { Context as _, Result , anyhow , bail } ,
65+ anyhow:: { anyhow , bail , Context as _, Result } ,
6666 error_contexts:: { GlobalErrorContextRefCount , LocalErrorContextRefCount } ,
6767 futures:: {
6868 channel:: oneshot,
@@ -83,36 +83,35 @@ use {
8383 marker:: PhantomData ,
8484 mem:: { self , MaybeUninit } ,
8585 ops:: Range ,
86- pin:: { Pin , pin } ,
86+ pin:: { pin , Pin } ,
8787 ptr:: { self , NonNull } ,
8888 sync:: {
89- Arc , Mutex ,
9089 atomic:: { AtomicPtr , Ordering :: Relaxed } ,
90+ Arc , Mutex ,
9191 } ,
9292 task:: { Context , Poll , Wake , Waker } ,
9393 vec:: Vec ,
9494 } ,
9595 table:: { Table , TableDebug , TableError , TableId } ,
9696 wasmtime_environ:: {
97- PrimaryMap ,
9897 component:: {
99- MAX_FLAT_PARAMS , MAX_FLAT_RESULTS , PREPARE_ASYNC_NO_RESULT , PREPARE_ASYNC_WITH_RESULT ,
10098 RuntimeComponentInstanceIndex , StringEncoding ,
10199 TypeComponentGlobalErrorContextTableIndex , TypeComponentLocalErrorContextTableIndex ,
102- TypeFutureTableIndex , TypeStreamTableIndex , TypeTupleIndex ,
100+ TypeFutureTableIndex , TypeStreamTableIndex , TypeTupleIndex , MAX_FLAT_PARAMS ,
101+ MAX_FLAT_RESULTS , PREPARE_ASYNC_NO_RESULT , PREPARE_ASYNC_WITH_RESULT ,
103102 } ,
104- fact,
103+ fact, PrimaryMap ,
105104 } ,
106105 wasmtime_fiber:: { Fiber , Suspend } ,
107106} ;
108107
108+ pub ( crate ) use futures_and_streams:: {
109+ lower_error_context_to_index, lower_future_to_index, lower_stream_to_index, ResourcePair ,
110+ } ;
109111pub use futures_and_streams:: {
110112 ErrorContext , FutureReader , FutureWriter , HostFuture , HostStream , ReadBuffer , StreamReader ,
111113 StreamWriter , VecBuffer , Watch , WriteBuffer ,
112114} ;
113- pub ( crate ) use futures_and_streams:: {
114- ResourcePair , lower_error_context_to_index, lower_future_to_index, lower_stream_to_index,
115- } ;
116115
117116mod error_contexts;
118117mod futures_and_streams;
@@ -288,7 +287,7 @@ where
288287 token : StoreToken < T > ,
289288 get : fn ( ) -> * mut dyn VMStore ,
290289 get_data : fn ( & mut T ) -> D :: Data < ' _ > ,
291- instance : Option < Instance > ,
290+ instance : Instance ,
292291}
293292
294293impl < T > Accessor < T > {
@@ -309,7 +308,7 @@ impl<T> Accessor<T> {
309308 /// intended scope. If it returns, the caller must be granted exclusive
310309 /// access to that store until the call to `Future::poll` for the current
311310 /// host task returns.
312- unsafe fn new ( token : StoreToken < T > , instance : Option < Instance > ) -> Self {
311+ unsafe fn new ( token : StoreToken < T > , instance : Instance ) -> Self {
313312 Self {
314313 token,
315314 get : get_store,
@@ -377,7 +376,7 @@ where
377376 where
378377 T : ' static ,
379378 {
380- let instance = self . instance . unwrap ( ) ;
379+ let instance = self . instance ;
381380 let accessor = Self {
382381 token : self . token ,
383382 get : self . get ,
@@ -391,11 +390,6 @@ where
391390
392391 /// Retrieve the component instance of the caller.
393392 pub fn instance ( & self ) -> Instance {
394- self . instance . unwrap ( )
395- }
396-
397- #[ doc( hidden) ]
398- pub fn maybe_instance ( & self ) -> Option < Instance > {
399393 self . instance
400394 }
401395}
@@ -515,16 +509,15 @@ enum InstanceThreadLocalState {
515509 /// they can be mutably referenced without either one aliasing the other.
516510 Detached {
517511 instance : SendSyncPtr < ComponentInstance > ,
512+ handle : Instance ,
518513 store : VMStoreRawPtr ,
519514 } ,
520515 /// The specified instance's event loop is currently polling a future, and
521- /// the instance handle is available via the `instance ` field.
516+ /// the instance handle is available via the `handle ` field.
522517 ///
523518 /// In this case, the store and instance are in an "attached" state, meaning
524519 /// care must be taken to avoid creating mutable reference aliases.
525- Attached {
526- instance : SendSyncPtr < ComponentInstance > ,
527- } ,
520+ Attached { handle : Instance } ,
528521}
529522
530523impl fmt:: Debug for InstanceThreadLocalState {
@@ -560,7 +553,10 @@ fn with_local_instance<R>(fun: impl FnOnce(&mut dyn VMStore, &mut ComponentInsta
560553 INSTANCE_STATE . with ( |v| v. replace ( InstanceThreadLocalState :: Polling ) ) ,
561554 ) ;
562555
563- let InstanceThreadLocalState :: Detached { instance, store } = state. 0 else {
556+ let InstanceThreadLocalState :: Detached {
557+ instance, store, ..
558+ } = state. 0
559+ else {
564560 unreachable ! ( "expected `Detached`; got `{:?}`" , state. 0 )
565561 } ;
566562 let ( store, instance) = unsafe { ( & mut * store. 0 . as_ptr ( ) , & mut * instance. as_ptr ( ) ) } ;
@@ -581,6 +577,7 @@ fn poll_with_local_instance<F: Future + Send + ?Sized>(
581577 let state = ResetInstanceThreadLocalState ( INSTANCE_STATE . with ( |v| {
582578 v. replace ( InstanceThreadLocalState :: Detached {
583579 instance : SendSyncPtr :: new ( instance. into ( ) ) ,
580+ handle : instance. instance ,
584581 store : VMStoreRawPtr ( store. into ( ) ) ,
585582 } )
586583 } ) ) ;
@@ -819,24 +816,7 @@ impl fmt::Debug for WorkItem {
819816}
820817
821818impl < T > StoreContextMut < ' _ , T > {
822- /// Temporarily split the specified store and instance into a "detached"
823- /// state (i.e. clearing the pointers they have to each other) so that they
824- /// can both safely be exclusively referenced without accidentally aliasing
825- /// one via the other.
826- ///
827- /// This will take the specified instance out of the store, null out the
828- /// pointer in the instance which points back to the store, call the
829- /// specified function with exclusive references to both, and then reset
830- /// everything back to the way it was before returning a result.
831- ///
832- /// This is appropriate for use in code which needs safe, exclusive access
833- /// to both the store and the instance simultaneously. Note that you'll
834- /// need to temporarily re-attach the instance to the store using
835- /// `with_attached_instance` when calling guest code or calling
836- /// application-defined host functions, since they both expect the instance
837- /// to be in an "attached" state.
838- ///
839- /// See also `with_detached_instance_async` for async closures.
819+ /// Temporary code which will go away soon. Nothing to see here, folks.
840820 fn with_detached_instance < R > (
841821 & mut self ,
842822 instance : & Instance ,
@@ -849,18 +829,22 @@ impl<T> StoreContextMut<'_, T> {
849829 }
850830 _ => unreachable ! ( ) ,
851831 } ) ) ;
852- let ptr = self . 0 . hide_instance ( * instance) ;
853- // SAFETY: We've taken the instance out of the store, so now we own
854- // it and can take an exclusive reference to it.
855- let reference = unsafe { & mut * ptr } ;
856- reference. set_store ( None ) ;
857- let result = fun ( self . as_context_mut ( ) , reference) ;
858- reference. set_store ( Some ( VMStoreRawPtr ( self . traitobj ( ) ) ) ) ;
859- self . 0 . unhide_instance ( * instance) ;
860- result
832+ // SAFETY: This isn't safe at all, since `fun` will easily be able to
833+ // create aliases of `instance` using
834+ // e.g. `StoreOpaque::component_instance_mut`. As of this writing,
835+ // we're relying on `fun` never doing that except within a
836+ // `with_attached_instance` closure where it's sound.
837+ //
838+ // We're planning to remove `with_{a,de}tached_instance[_async]` soon
839+ // anyway and migrate the code which uses it to deal in `Instance`
840+ // parameters rather than `&mut ComponentInstance` parameters,
841+ // retrieving the latter only as necessary, with soundness enforced by
842+ // the borrow checker, at which point this will go away.
843+ let instance = unsafe { & mut * self . 0 [ instance. 0 ] . as_mut ( ) . unwrap ( ) . instance_ptr ( ) } ;
844+ fun ( self . as_context_mut ( ) , instance)
861845 }
862846
863- /// Same as `with_detached_instance`, but for async closures .
847+ /// Temporary code which will go away soon. Nothing to see here, folks .
864848 async fn with_detached_instance_async < R > (
865849 & mut self ,
866850 instance : & Instance ,
@@ -873,55 +857,47 @@ impl<T> StoreContextMut<'_, T> {
873857 }
874858 _ => unreachable ! ( ) ,
875859 } ) ) ;
876- let ptr = self . 0 . hide_instance ( * instance) ;
877- // SAFETY: We've taken the instance out of the store, so now we own
878- // it and can take an exclusive reference to it.
879- let reference = unsafe { & mut * ptr } ;
880- reference. set_store ( None ) ;
881- let result = fun ( self . as_context_mut ( ) , reference) . await ;
882- reference. set_store ( Some ( VMStoreRawPtr ( self . traitobj ( ) ) ) ) ;
883- self . 0 . unhide_instance ( * instance) ;
884- result
860+ // SAFETY: See corresponding comment in `with_detached_instance`
861+ let instance = unsafe { & mut * self . 0 [ instance. 0 ] . as_mut ( ) . unwrap ( ) . instance_ptr ( ) } ;
862+ fun ( self . as_context_mut ( ) , instance) . await
885863 }
886864
887- /// Temporarily the operation performed by `with_detached_instance{_async}`.
888- /// See the docs for those functions for details.
865+ /// Temporary code which will go away soon. Nothing to see here, folks.
889866 pub ( crate ) fn with_attached_instance < R > (
890867 & mut self ,
891868 instance : & mut ComponentInstance ,
892- fun : impl FnOnce ( StoreContextMut < ' _ , T > , Option < Instance > ) -> R ,
869+ fun : impl FnOnce ( StoreContextMut < ' _ , T > , Instance ) -> R ,
893870 ) -> R {
894871 let _state = ResetInstanceThreadLocalState ( INSTANCE_STATE . with ( |v| match v. get ( ) {
895872 state @ InstanceThreadLocalState :: None => state,
896- state @ InstanceThreadLocalState :: Polling => {
897- if instance. instance . is_some ( ) {
898- v. replace ( InstanceThreadLocalState :: Attached {
899- instance : SendSyncPtr :: new ( instance. into ( ) ) ,
900- } )
901- } else {
902- state
903- }
904- }
873+ InstanceThreadLocalState :: Polling => v. replace ( InstanceThreadLocalState :: Attached {
874+ handle : instance. instance ,
875+ } ) ,
905876 _ => unreachable ! ( ) ,
906877 } ) ) ;
907- if let Some ( handle) = instance. instance {
908- self . 0 . unhide_instance ( handle) ;
909- }
910- instance. set_store ( Some ( VMStoreRawPtr ( self . traitobj ( ) ) ) ) ;
911- let result = fun ( self . as_context_mut ( ) , instance. instance ) ;
912- instance. set_store ( None ) ;
913- if let Some ( handle) = instance. instance {
914- self . 0 . hide_instance ( handle) ;
915- }
916- result
878+ fun ( self . as_context_mut ( ) , instance. instance )
917879 }
918880}
919881
920- impl ComponentInstance {
921- pub ( crate ) fn instance ( & self ) -> Option < Instance > {
922- self . instance
882+ impl StoreOpaque {
883+ /// Temporary code which will go away soon. Nothing to see here, folks.
884+ pub ( crate ) fn with_attached_instance < R > (
885+ & mut self ,
886+ instance : & mut ComponentInstance ,
887+ fun : impl FnOnce ( & mut StoreOpaque , Instance ) -> R ,
888+ ) -> R {
889+ let _state = ResetInstanceThreadLocalState ( INSTANCE_STATE . with ( |v| match v. get ( ) {
890+ state @ InstanceThreadLocalState :: None => state,
891+ InstanceThreadLocalState :: Polling => v. replace ( InstanceThreadLocalState :: Attached {
892+ handle : instance. instance ,
893+ } ) ,
894+ _ => unreachable ! ( ) ,
895+ } ) ) ;
896+ fun ( self , instance. instance )
923897 }
898+ }
924899
900+ impl ComponentInstance {
925901 fn instance_state ( & mut self , instance : RuntimeComponentInstanceIndex ) -> & mut InstanceState {
926902 self . concurrent_state
927903 . instance_states
@@ -1283,10 +1259,10 @@ impl ComponentInstance {
12831259 & mut dyn VMStore ,
12841260 & mut ComponentInstance ,
12851261 ) -> Result < [ MaybeUninit < ValRaw > ; MAX_FLAT_PARAMS ] >
1286- + Send
1287- + Sync
1288- + ' static
1289- + use < T > {
1262+ + Send
1263+ + Sync
1264+ + ' static
1265+ + use < T > {
12901266 let token = StoreToken :: new ( store) ;
12911267 move |store : & mut dyn VMStore , instance : & mut ComponentInstance | {
12921268 let mut storage = [ MaybeUninit :: uninit ( ) ; MAX_FLAT_PARAMS ] ;
@@ -1887,7 +1863,7 @@ impl ComponentInstance {
18871863 // thread-local variable which `poll_with_state` will populate and reset
18881864 // with valid pointers to the store data and the store itself each time
18891865 // the returned future is polled, respectively.
1890- let mut accessor = unsafe { Accessor :: new ( token, self . instance ( ) ) } ;
1866+ let mut accessor = unsafe { Accessor :: new ( token, self . instance ) } ;
18911867 let mut future = Box :: pin ( async move { closure ( & mut accessor, params) . await } ) ;
18921868 Box :: pin ( future:: poll_fn ( move |cx| {
18931869 poll_with_state ( token, cx, future. as_mut ( ) )
@@ -3358,7 +3334,7 @@ impl Instance {
33583334 . with_detached_instance ( self , |store, instance| {
33593335 let token = StoreToken :: new ( store) ;
33603336 // SAFETY: See corresponding comment in `ComponentInstance::wrap_call`.
3361- let mut accessor = unsafe { Accessor :: new ( token, instance. instance ( ) ) } ;
3337+ let mut accessor = unsafe { Accessor :: new ( token, instance. instance ) } ;
33623338 let mut future = Box :: pin ( async move { fun ( & mut accessor) . await } ) ;
33633339 Box :: pin ( future:: poll_fn ( move |cx| {
33643340 poll_with_state ( token, cx, future. as_mut ( ) )
@@ -3382,8 +3358,7 @@ impl Instance {
33823358 ) -> AbortHandle {
33833359 let mut store = store. as_context_mut ( ) ;
33843360 // SAFETY: TODO
3385- let accessor =
3386- unsafe { Accessor :: new ( StoreToken :: new ( store. as_context_mut ( ) ) , Some ( * self ) ) } ;
3361+ let accessor = unsafe { Accessor :: new ( StoreToken :: new ( store. as_context_mut ( ) ) , * self ) } ;
33873362 self . spawn_with_accessor ( store, accessor, task)
33883363 }
33893364
@@ -4751,7 +4726,7 @@ fn for_any_lift<
47514726///
47524727/// See `Instance::run` for details.
47534728fn checked < F : Future + Send + ' static > (
4754- instance : SendSyncPtr < ComponentInstance > ,
4729+ instance : Instance ,
47554730 fut : F ,
47564731) -> impl Future < Output = F :: Output > + Send + ' static {
47574732 let mut fut = Box :: pin ( fut) ;
@@ -4764,12 +4739,8 @@ fn checked<F: Future + Send + 'static>(
47644739 ";
47654740 INSTANCE_STATE . with ( |v| {
47664741 let matched = match v. get ( ) {
4767- InstanceThreadLocalState :: Detached {
4768- instance : local, ..
4769- }
4770- | InstanceThreadLocalState :: Attached { instance : local } => {
4771- local. as_ptr ( ) == instance. as_ptr ( )
4772- }
4742+ InstanceThreadLocalState :: Detached { handle, .. }
4743+ | InstanceThreadLocalState :: Attached { handle } => handle. 0 == instance. 0 ,
47734744 InstanceThreadLocalState :: None => false ,
47744745 InstanceThreadLocalState :: Polling => unreachable ! ( ) ,
47754746 } ;
@@ -5299,12 +5270,8 @@ pub(crate) fn queue_call<T: 'static, R: Send + 'static>(
52995270
53005271 queue_call0 ( store. as_context_mut ( ) , handle, task, param_count) ?;
53015272
5302- let func_data = & store[ handle. 0 ] ;
5303- let instance = func_data. instance ;
5304- let instance_ptr = store. 0 [ instance. 0 ] . as_ref ( ) . unwrap ( ) . instance_ptr ( ) ;
5305-
53065273 Ok ( checked (
5307- SendSyncPtr :: new ( NonNull :: new ( instance_ptr ) . unwrap ( ) ) ,
5274+ store [ handle . 0 ] . instance ,
53085275 rx. map ( |result| {
53095276 result
53105277 . map ( |v| * v. downcast ( ) . unwrap ( ) )
0 commit comments