1+ #[ cfg( feature = "rr" ) ]
2+ use super :: { replay_data_from_store, replay_data_from_store_mut} ;
13use crate :: rr:: FlatBytes ;
24#[ cfg( feature = "rr" ) ]
35use crate :: rr:: {
4- RREvent , RRFuncArgVals , ReplayError , ReplayHostContext , Replayer , ResultEvent ,
6+ RREvent , RRFuncArgVals , ReplayError , Replayer , ResultEvent , Validate ,
57 common_events:: HostFuncEntryEvent , common_events:: HostFuncReturnEvent ,
6- common_events:: WasmFuncReturnEvent , core_events:: WasmFuncEntryEvent ,
8+ common_events:: WasmFuncReturnEvent , core_events:: InstantiationEvent ,
9+ core_events:: WasmFuncEntryEvent ,
710} ;
8- use crate :: store:: StoreOpaque ;
9- use crate :: { Caller , FuncType , StoreContextMut , ValRaw , WasmFuncOrigin , prelude:: * } ;
11+ use crate :: store:: { InstanceId , StoreOpaque } ;
12+ use crate :: { Caller , FuncType , Module , StoreContextMut , ValRaw , WasmFuncOrigin , prelude:: * } ;
1013#[ cfg( feature = "rr" ) ]
1114use wasmtime_environ:: EntityIndex ;
15+ use wasmtime_environ:: WasmChecksum ;
1216
1317/// Record and replay hook operation for core wasm function entry events
1418///
@@ -121,7 +125,7 @@ where
121125 Ok ( ( ) )
122126}
123127
124- /// Replay hook operation for host function return events
128+ /// Replay hook operation for host function return events.
125129#[ inline]
126130pub fn replay_host_func_return < T , U : ' static > (
127131 args : & mut [ T ] ,
@@ -146,14 +150,9 @@ where
146150 RREvent :: CoreWasmFuncEntry ( event) => {
147151 let entity = EntityIndex :: from ( event. origin . index ) ;
148152
149- // SAFETY: The store's data is always of type `ReplayHostContext<T>` when created by
150- // the replay driver. As an additional guarantee, we assert that replay is indeed
151- // truly enabled.
152- assert ! ( caller. store. 0 . replay_enabled( ) ) ;
153- let replay_data = unsafe {
154- let raw_ptr: * const U = caller. store . data ( ) ;
155- & * ( raw_ptr as * const ReplayHostContext )
156- } ;
153+ // Unwrapping the `replay_buffer_mut()` above ensures that we are in replay mode
154+ // passing the safety contract for `replay_data_from_store`
155+ let replay_data = unsafe { replay_data_from_store ( & caller. store ) } ;
157156
158157 // Grab the correct module instance
159158 let instance = replay_data. get_module_instance ( event. origin . instance ) ?;
@@ -194,3 +193,48 @@ where
194193 let _ = ( args, caller) ;
195194 Ok ( ( ) )
196195}
196+
197+ /// Hook for recording a module instantiation event and validating the
198+ /// instantiation during replay.
199+ pub fn record_and_replay_validate_instantiation < T : ' static > (
200+ store : & mut StoreContextMut < ' _ , T > ,
201+ module : WasmChecksum ,
202+ instance : InstanceId ,
203+ ) -> Result < ( ) > {
204+ #[ cfg( feature = "rr" ) ]
205+ {
206+ store
207+ . 0
208+ . record_event ( || InstantiationEvent { module, instance } ) ?;
209+ if store. 0 . replay_enabled ( ) {
210+ let replay_data = unsafe { replay_data_from_store_mut ( store) } ;
211+ replay_data. take_current_module_instantiation ( ) . expect (
212+ "replay driver should have set module instantiate data before trying to validate it" ,
213+ ) . validate ( & InstantiationEvent { module, instance } ) ?;
214+ }
215+ }
216+ let _ = ( store, module, instance) ;
217+ Ok ( ( ) )
218+ }
219+
220+ /// Ensure that memories are not exported memories in Core wasm modules when
221+ /// recording is enabled.
222+ pub fn rr_validate_module_unexported_memory ( module : & Module ) -> Result < ( ) > {
223+ // Check for exported memories when recording is enabled.
224+ #[ cfg( feature = "rr" ) ]
225+ {
226+ if module. engine ( ) . is_recording ( )
227+ && module. exports ( ) . any ( |export| {
228+ if let crate :: ExternType :: Memory ( _) = export. ty ( ) {
229+ true
230+ } else {
231+ false
232+ }
233+ } )
234+ {
235+ bail ! ( "Cannot support recording for core wasm modules when a memory is exported" ) ;
236+ }
237+ }
238+ let _ = module;
239+ Ok ( ( ) )
240+ }
0 commit comments