@@ -96,7 +96,7 @@ use crate::runtime::vm::{
9696 SignalHandler , StoreBox , Unwind , VMContext , VMFuncRef , VMGcRef , VMStore , VMStoreContext ,
9797} ;
9898use crate :: trampoline:: VMHostGlobalContext ;
99- use crate :: { Engine , Module , Trap , Val , ValRaw , module:: ModuleRegistry } ;
99+ use crate :: { Engine , Module , Val , ValRaw , module:: ModuleRegistry } ;
100100use crate :: { Global , Instance , Memory , Table , Uninhabited } ;
101101use alloc:: sync:: Arc ;
102102use core:: fmt;
@@ -324,6 +324,9 @@ enum CallHookInner<T: 'static> {
324324/// the deadline for a Store during execution of a function using that store.
325325#[ non_exhaustive]
326326pub enum UpdateDeadline {
327+ /// Halt execution of WebAssembly, don't update the epoch deadline, and
328+ /// raise a trap.
329+ Interrupt ,
327330 /// Extend the deadline by the specified number of ticks.
328331 Continue ( u64 ) ,
329332 /// Extend the deadline by the specified number of ticks after yielding to
@@ -429,7 +432,7 @@ pub struct StoreOpaque {
429432 // together. Then when we run out of gas, we inject the yield amount from the reserve
430433 // until the reserve is empty.
431434 fuel_reserve : u64 ,
432- fuel_yield_interval : Option < NonZeroU64 > ,
435+ pub ( crate ) fuel_yield_interval : Option < NonZeroU64 > ,
433436 /// Indexed data within this `Store`, used to store information about
434437 /// globals, functions, memories, etc.
435438 store_data : StoreData ,
@@ -1893,7 +1896,7 @@ impl StoreOpaque {
18931896 Ok ( get_fuel ( injected_fuel, self . fuel_reserve ) )
18941897 }
18951898
1896- fn refuel ( & mut self ) -> bool {
1899+ pub ( crate ) fn refuel ( & mut self ) -> bool {
18971900 let injected_fuel = unsafe { & mut * self . vm_store_context . fuel_consumed . get ( ) } ;
18981901 refuel (
18991902 injected_fuel,
@@ -2277,6 +2280,22 @@ at https://bytecodealliance.org/security.
22772280
22782281 Ok ( id)
22792282 }
2283+
2284+ #[ cfg( target_has_atomic = "64" ) ]
2285+ pub ( crate ) fn set_epoch_deadline ( & mut self , delta : u64 ) {
2286+ // Set a new deadline based on the "epoch deadline delta".
2287+ //
2288+ // Also, note that when this update is performed while Wasm is
2289+ // on the stack, the Wasm will reload the new value once we
2290+ // return into it.
2291+ let current_epoch = self . engine ( ) . current_epoch ( ) ;
2292+ let epoch_deadline = self . vm_store_context . epoch_deadline . get_mut ( ) ;
2293+ * epoch_deadline = current_epoch + delta;
2294+ }
2295+
2296+ pub ( crate ) fn get_epoch_deadline ( & mut self ) -> u64 {
2297+ * self . vm_store_context . epoch_deadline . get_mut ( )
2298+ }
22802299}
22812300
22822301/// Helper parameter to [`StoreOpaque::allocate_instance`].
@@ -2327,67 +2346,19 @@ unsafe impl<T> VMStore for StoreInner<T> {
23272346 )
23282347 }
23292348
2330- fn out_of_gas ( & mut self ) -> Result < ( ) > {
2331- if !self . refuel ( ) {
2332- return Err ( Trap :: OutOfFuel . into ( ) ) ;
2333- }
2334- #[ cfg( feature = "async" ) ]
2335- if self . fuel_yield_interval . is_some ( ) {
2336- self . async_yield_impl ( ) ?;
2337- }
2338- Ok ( ( ) )
2339- }
2340-
23412349 #[ cfg( target_has_atomic = "64" ) ]
2342- fn new_epoch ( & mut self ) -> Result < u64 , anyhow :: Error > {
2350+ fn new_epoch_updated_deadline ( & mut self ) -> Result < UpdateDeadline > {
23432351 // Temporarily take the configured behavior to avoid mutably borrowing
23442352 // multiple times.
23452353 let mut behavior = self . epoch_deadline_behavior . take ( ) ;
2346- let delta_result = match & mut behavior {
2347- None => Err ( Trap :: Interrupt . into ( ) ) ,
2348- Some ( callback) => callback ( ( & mut * self ) . as_context_mut ( ) ) . and_then ( |update| {
2349- let delta = match update {
2350- UpdateDeadline :: Continue ( delta) => delta,
2351- #[ cfg( feature = "async" ) ]
2352- UpdateDeadline :: Yield ( delta) => {
2353- assert ! (
2354- self . async_support( ) ,
2355- "cannot use `UpdateDeadline::Yield` without enabling async support in the config"
2356- ) ;
2357- // Do the async yield. May return a trap if future was
2358- // canceled while we're yielded.
2359- self . async_yield_impl ( ) ?;
2360- delta
2361- }
2362- #[ cfg( feature = "async" ) ]
2363- UpdateDeadline :: YieldCustom ( delta, future) => {
2364- assert ! (
2365- self . async_support( ) ,
2366- "cannot use `UpdateDeadline::YieldCustom` without enabling async support in the config"
2367- ) ;
2368-
2369- // When control returns, we have a `Result<()>` passed
2370- // in from the host fiber. If this finished successfully then
2371- // we were resumed normally via a `poll`, so keep going. If
2372- // the future was dropped while we were yielded, then we need
2373- // to clean up this fiber. Do so by raising a trap which will
2374- // abort all wasm and get caught on the other side to clean
2375- // things up.
2376- self . block_on ( |_| future) ?;
2377- delta
2378- }
2379- } ;
2380-
2381- // Set a new deadline and return the new epoch deadline so
2382- // the Wasm code doesn't have to reload it.
2383- self . set_epoch_deadline ( delta) ;
2384- Ok ( self . get_epoch_deadline ( ) )
2385- } )
2354+ let update = match & mut behavior {
2355+ Some ( callback) => callback ( ( & mut * self ) . as_context_mut ( ) ) ,
2356+ None => Ok ( UpdateDeadline :: Interrupt ) ,
23862357 } ;
23872358
23882359 // Put back the original behavior which was replaced by `take`.
23892360 self . epoch_deadline_behavior = behavior;
2390- delta_result
2361+ update
23912362 }
23922363
23932364 #[ cfg( feature = "component-model" ) ]
@@ -2397,18 +2368,6 @@ unsafe impl<T> VMStore for StoreInner<T> {
23972368}
23982369
23992370impl < T > StoreInner < T > {
2400- #[ cfg( target_has_atomic = "64" ) ]
2401- pub ( crate ) fn set_epoch_deadline ( & mut self , delta : u64 ) {
2402- // Set a new deadline based on the "epoch deadline delta".
2403- //
2404- // Also, note that when this update is performed while Wasm is
2405- // on the stack, the Wasm will reload the new value once we
2406- // return into it.
2407- let current_epoch = self . engine ( ) . current_epoch ( ) ;
2408- let epoch_deadline = self . vm_store_context . epoch_deadline . get_mut ( ) ;
2409- * epoch_deadline = current_epoch + delta;
2410- }
2411-
24122371 #[ cfg( target_has_atomic = "64" ) ]
24132372 fn epoch_deadline_trap ( & mut self ) {
24142373 self . epoch_deadline_behavior = None ;
@@ -2421,10 +2380,6 @@ impl<T> StoreInner<T> {
24212380 ) {
24222381 self . epoch_deadline_behavior = Some ( callback) ;
24232382 }
2424-
2425- fn get_epoch_deadline ( & mut self ) -> u64 {
2426- * self . vm_store_context . epoch_deadline . get_mut ( )
2427- }
24282383}
24292384
24302385impl < T : Default > Default for Store < T > {
0 commit comments