Skip to content

Commit a6925c2

Browse files
authored
wasmtime: Make StoreContextMut accessible in epoch deadline callback (#6075)
This commit changes the signature of the `Store::epoch_deadline_callback` to take in `StoreContextMut` instead of a mutable reference to the store's data. This is useful in cases in which the callback definition needs access to the Store to be able to use other methods that take in `AsContext`/`AsContextMut`, like for example `WasmtimeBacktrace::capture`
1 parent 2fde253 commit a6925c2

2 files changed

Lines changed: 17 additions & 7 deletions

File tree

crates/wasmtime/src/store.rs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -425,11 +425,13 @@ enum OutOfGas {
425425

426426
/// What to do when the engine epoch reaches the deadline for a Store
427427
/// during execution of a function using that store.
428+
#[derive(Default)]
428429
enum EpochDeadline<T> {
429430
/// Return early with a trap.
431+
#[default]
430432
Trap,
431433
/// Call a custom deadline handler.
432-
Callback(Box<dyn FnMut(&mut T) -> Result<u64> + Send + Sync>),
434+
Callback(Box<dyn FnMut(StoreContextMut<T>) -> Result<u64> + Send + Sync>),
433435
/// Extend the deadline by the specified number of ticks after
434436
/// yielding to the async executor loop.
435437
#[cfg(feature = "async")]
@@ -932,7 +934,7 @@ impl<T> Store<T> {
932934
/// for an introduction to epoch-based interruption.
933935
pub fn epoch_deadline_callback(
934936
&mut self,
935-
callback: impl FnMut(&mut T) -> Result<u64> + Send + Sync + 'static,
937+
callback: impl FnMut(StoreContextMut<T>) -> Result<u64> + Send + Sync + 'static,
936938
) {
937939
self.inner.epoch_deadline_callback(Box::new(callback));
938940
}
@@ -1975,10 +1977,13 @@ unsafe impl<T> wasmtime_runtime::Store for StoreInner<T> {
19751977
}
19761978

19771979
fn new_epoch(&mut self) -> Result<u64, anyhow::Error> {
1978-
return match &mut self.epoch_deadline_behavior {
1980+
// Temporarily take the configured behavior to avoid mutably borrowing
1981+
// multiple times.
1982+
let mut behavior = std::mem::take(&mut self.epoch_deadline_behavior);
1983+
let delta_result = match &mut behavior {
19791984
EpochDeadline::Trap => Err(Trap::Interrupt.into()),
19801985
EpochDeadline::Callback(callback) => {
1981-
let delta = callback(&mut self.data)?;
1986+
let delta = callback((&mut *self).as_context_mut())?;
19821987
// Set a new deadline and return the new epoch deadline so
19831988
// the Wasm code doesn't have to reload it.
19841989
self.set_epoch_deadline(delta);
@@ -1998,6 +2003,10 @@ unsafe impl<T> wasmtime_runtime::Store for StoreInner<T> {
19982003
Ok(self.get_epoch_deadline())
19992004
}
20002005
};
2006+
2007+
// Put back the original behavior which was replaced by `take`.
2008+
self.epoch_deadline_behavior = behavior;
2009+
delta_result
20012010
}
20022011
}
20032012

@@ -2022,7 +2031,7 @@ impl<T> StoreInner<T> {
20222031

20232032
fn epoch_deadline_callback(
20242033
&mut self,
2025-
callback: Box<dyn FnMut(&mut T) -> Result<u64> + Send + Sync>,
2034+
callback: Box<dyn FnMut(StoreContextMut<T>) -> Result<u64> + Send + Sync>,
20262035
) {
20272036
self.epoch_deadline_behavior = EpochDeadline::Callback(callback);
20282037
}

tests/all/epoch_interruption.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ fn make_env<T>(engine: &Engine) -> Linker<T> {
3232

3333
enum InterruptMode {
3434
Trap,
35-
Callback(fn(&mut usize) -> Result<u64>),
35+
Callback(fn(StoreContextMut<usize>) -> Result<u64>),
3636
Yield(u64),
3737
}
3838

@@ -334,7 +334,8 @@ async fn epoch_callback_continue() {
334334
(func $subfunc))
335335
",
336336
1,
337-
InterruptMode::Callback(|s| {
337+
InterruptMode::Callback(|mut cx| {
338+
let s = cx.data_mut();
338339
*s += 1;
339340
Ok(1)
340341
}),

0 commit comments

Comments
 (0)