Memory::new_async, grow_async now work!

This commit is contained in:
Pat Hickey
2021-10-20 18:34:26 -07:00
parent adf7521e30
commit 2225722373
3 changed files with 53 additions and 17 deletions

View File

@@ -503,19 +503,19 @@ impl<'a> Instantiator<'a> {
// NB: this is the same code as `run`. It's intentionally // NB: this is the same code as `run`. It's intentionally
// small but should be kept in sync (modulo the async bits). // small but should be kept in sync (modulo the async bits).
loop { store
.on_fiber(|store| loop {
let step = self.step(store.0)?; let step = self.step(store.0)?;
if let Some((instance, start, toplevel)) = step { if let Some((instance, start, toplevel)) = step {
if let Some(start) = start { if let Some(start) = start {
store Instantiator::start_raw(store, instance, start)?
.on_fiber(|store| Instantiator::start_raw(store, instance, start))
.await??;
} }
if toplevel { if toplevel {
break Ok(instance); break Ok(instance);
} }
} }
} })
.await?
} }
/// Processes the next initializer for the next instance being created /// Processes the next initializer for the next instance being created

View File

@@ -223,6 +223,24 @@ impl Memory {
Memory::_new(store.as_context_mut().0, ty) Memory::_new(store.as_context_mut().0, ty)
} }
/// Async variant of [`Memory::new`]. You must use this variant with Stores which have a
/// [`ResourceLimiterAsync`].
#[cfg(feature = "async")]
pub async fn new_async<T>(
mut store: impl AsContextMut<Data = T>,
ty: MemoryType,
) -> Result<Memory>
where
T: Send,
{
let mut store = store.as_context_mut();
assert!(
store.0.async_support(),
"cannot use `new_async` without enabling async support on the config"
);
store.on_fiber(|store| Memory::_new(store.0, ty)).await?
}
fn _new(store: &mut StoreOpaque, ty: MemoryType) -> Result<Memory> { fn _new(store: &mut StoreOpaque, ty: MemoryType) -> Result<Memory> {
unsafe { unsafe {
let export = generate_memory_export(store, &ty)?; let export = generate_memory_export(store, &ty)?;
@@ -472,6 +490,23 @@ impl Memory {
} }
} }
/// Async variant of [`Memory::grow`]. Required when using a [`ResourceLimiterAsync`].
#[cfg(feature = "async")]
pub async fn grow_async<T>(
&self,
mut store: impl AsContextMut<Data = T>,
delta: u64,
) -> Result<u64>
where
T: Send,
{
let mut store = store.as_context_mut();
assert!(
store.0.async_support(),
"cannot use `grow_async` without enabling async support on the config"
);
store.on_fiber(|store| self.grow(store, delta)).await?
}
fn wasmtime_memory(&self, store: &mut StoreOpaque) -> *mut wasmtime_runtime::Memory { fn wasmtime_memory(&self, store: &mut StoreOpaque) -> *mut wasmtime_runtime::Memory {
unsafe { unsafe {
let export = &store[self.0]; let export = &store[self.0];

View File

@@ -115,15 +115,16 @@ async fn test_limits_async() -> Result<()> {
// Test instance exports and host objects hitting the limit // Test instance exports and host objects hitting the limit
for memory in std::array::IntoIter::new([ for memory in std::array::IntoIter::new([
instance.get_memory(&mut store, "m").unwrap(), instance.get_memory(&mut store, "m").unwrap(),
Memory::new(&mut store, MemoryType::new(0, None))?, Memory::new_async(&mut store, MemoryType::new(0, None)).await?,
]) { ]) {
memory.grow(&mut store, 3)?; memory.grow_async(&mut store, 3).await?;
memory.grow(&mut store, 5)?; memory.grow_async(&mut store, 5).await?;
memory.grow(&mut store, 2)?; memory.grow_async(&mut store, 2).await?;
assert_eq!( assert_eq!(
memory memory
.grow(&mut store, 1) .grow_async(&mut store, 1)
.await
.map_err(|e| e.to_string()) .map_err(|e| e.to_string())
.unwrap_err(), .unwrap_err(),
"failed to grow memory by `1`" "failed to grow memory by `1`"