Skip to content

Commit

Permalink
add hooks for entering and exiting native code to Store
Browse files Browse the repository at this point in the history
  • Loading branch information
pchickey committed Jun 3, 2021
1 parent cbdde2a commit f9e8c8e
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 4 deletions.
15 changes: 12 additions & 3 deletions crates/wasmtime/src/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,7 @@ impl Func {
values_vec: *mut u128,
func: &dyn Fn(Caller<'_, T>, &[Val], &mut [Val]) -> Result<(), Trap>,
) -> Result<(), Trap> {
caller.store.0.entering_native_hook()?;
// We have a dynamic guarantee that `values_vec` has the right
// number of arguments and the right types of arguments. As a result
// we should be able to safely run through them all and read them.
Expand Down Expand Up @@ -883,6 +884,7 @@ impl Func {
}
}

caller.store.0.exiting_native_hook()?;
Ok(())
}

Expand Down Expand Up @@ -1173,7 +1175,7 @@ pub unsafe trait WasmRet {
// explicitly, used when wrapping async functions which always bottom-out
// in a function that returns a trap because futures can be cancelled.
#[doc(hidden)]
type Fallible: WasmRet;
type Fallible: WasmRet<Abi = Self::Abi, Retptr = Self::Retptr>;
#[doc(hidden)]
fn into_fallible(self) -> Self::Fallible;
#[doc(hidden)]
Expand Down Expand Up @@ -1689,12 +1691,19 @@ macro_rules! impl_into_func {

let ret = {
panic::catch_unwind(AssertUnwindSafe(|| {
if let Err(trap) = caller.store.0.entering_native_hook() {
return R::fallible_from_trap(trap);
}
let mut _store = caller.sub_caller().store.opaque();
$(let $args = $args::from_abi($args, &mut _store);)*
func(
let r = func(
caller.sub_caller(),
$( $args, )*
)
);
if let Err(trap) = caller.store.0.exiting_native_hook() {
return R::fallible_from_trap(trap);
}
r.into_fallible()
}))
};

Expand Down
43 changes: 42 additions & 1 deletion crates/wasmtime/src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ pub struct StoreInner<T> {
_marker: marker::PhantomPinned,
inner: StoreInnermost,
limiter: Option<Box<dyn FnMut(&mut T) -> &mut (dyn crate::ResourceLimiter) + Send + Sync>>,
entering_native_hook: Option<Box<dyn FnMut(&mut T) -> Result<(), crate::Trap> + Send + Sync>>,
exiting_native_hook: Option<Box<dyn FnMut(&mut T) -> Result<(), crate::Trap> + Send + Sync>>,
// for comments about `ManuallyDrop`, see `Store::into_data`
data: ManuallyDrop<T>,
}
Expand Down Expand Up @@ -239,7 +241,8 @@ impl<T> Store<T> {
default_callee,
},
limiter: None,
default_callee,
entering_native_hook: None,
exiting_native_hook: None,
data: ManuallyDrop::new(data),
});

Expand Down Expand Up @@ -322,6 +325,28 @@ impl<T> Store<T> {
inner.limiter = Some(Box::new(limiter));
}

/// Configure a function that runs each time WebAssembly code running on this [`Store`] calls
/// into native code.
///
/// This function may return a [`Trap`], which terminates execution.
pub fn entering_native_code_hook(
&mut self,
hook: impl FnMut(&mut T) -> Result<(), Trap> + Send + Sync + 'static,
) {
self.inner.entering_native_hook = Some(Box::new(hook));
}

/// Configure a function that runs before native code running on this [`Store`] returns to
/// WebAssembly code.
///
/// This function may return a [`Trap`], which terminates execution.
pub fn exiting_native_code_hook(
&mut self,
hook: impl FnMut(&mut T) -> Result<(), Trap> + Send + Sync + 'static,
) {
self.inner.exiting_native_hook = Some(Box::new(hook));
}

/// Returns the [`Engine`] that this store is associated with.
pub fn engine(&self) -> &Engine {
self.inner.engine()
Expand Down Expand Up @@ -621,6 +646,22 @@ impl<T> StoreInner<T> {
let accessor = self.limiter.as_mut()?;
Some(accessor(&mut self.data))
}

pub fn entering_native_hook(&mut self) -> Result<(), Trap> {
if let Some(hook) = &mut self.entering_native_hook {
hook(&mut self.data)
} else {
Ok(())
}
}

pub fn exiting_native_hook(&mut self) -> Result<(), Trap> {
if let Some(hook) = &mut self.exiting_native_hook {
hook(&mut self.data)
} else {
Ok(())
}
}
}

impl StoreInnermost {
Expand Down

0 comments on commit f9e8c8e

Please sign in to comment.