Fix bad merge.
Fix a bad merge with the `async` feature that accidentally removed the allocation of fiber stacks via the instance allocator.
This commit is contained in:
@@ -754,12 +754,14 @@ impl Store {
|
|||||||
/// that the various comments are illuminating as to what's going on here.
|
/// that the various comments are illuminating as to what's going on here.
|
||||||
#[cfg(feature = "async")]
|
#[cfg(feature = "async")]
|
||||||
pub(crate) async fn on_fiber<R>(&self, func: impl FnOnce() -> R) -> Result<R, Trap> {
|
pub(crate) async fn on_fiber<R>(&self, func: impl FnOnce() -> R) -> Result<R, Trap> {
|
||||||
debug_assert!(self.is_async());
|
let config = self.inner.engine.config();
|
||||||
|
|
||||||
// TODO: allocation of a fiber should be much more abstract where we
|
debug_assert!(self.is_async());
|
||||||
// shouldn't be allocating huge stacks on every async wasm function call.
|
debug_assert!(config.async_stack_size > 0);
|
||||||
|
|
||||||
|
type SuspendType = wasmtime_fiber::Suspend<Result<(), Trap>, (), Result<(), Trap>>;
|
||||||
let mut slot = None;
|
let mut slot = None;
|
||||||
let fiber = wasmtime_fiber::Fiber::new(10 * 1024 * 1024, |keep_going, suspend| {
|
let func = |keep_going, suspend: &SuspendType| {
|
||||||
// First check and see if we were interrupted/dropped, and only
|
// First check and see if we were interrupted/dropped, and only
|
||||||
// continue if we haven't been.
|
// continue if we haven't been.
|
||||||
keep_going?;
|
keep_going?;
|
||||||
@@ -777,18 +779,46 @@ impl Store {
|
|||||||
|
|
||||||
slot = Some(func());
|
slot = Some(func());
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
};
|
||||||
.map_err(|e| Trap::from(anyhow::Error::from(e)))?;
|
|
||||||
|
let (fiber, stack) = match config.instance_allocator().allocate_fiber_stack() {
|
||||||
|
Ok(stack) => {
|
||||||
|
// Use the returned stack and deallocate it when finished
|
||||||
|
(
|
||||||
|
unsafe {
|
||||||
|
wasmtime_fiber::Fiber::new_with_stack(stack, func)
|
||||||
|
.map_err(|e| Trap::from(anyhow::Error::from(e)))?
|
||||||
|
},
|
||||||
|
stack,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Err(wasmtime_runtime::FiberStackError::NotSupported) => {
|
||||||
|
// The allocator doesn't support custom fiber stacks for the current platform
|
||||||
|
// Request that the fiber itself allocate the stack
|
||||||
|
(
|
||||||
|
wasmtime_fiber::Fiber::new(config.async_stack_size, func)
|
||||||
|
.map_err(|e| Trap::from(anyhow::Error::from(e)))?,
|
||||||
|
std::ptr::null_mut(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Err(e) => return Err(Trap::from(anyhow::Error::from(e))),
|
||||||
|
};
|
||||||
|
|
||||||
// Once we have the fiber representing our synchronous computation, we
|
// Once we have the fiber representing our synchronous computation, we
|
||||||
// wrap that in a custom future implementation which does the
|
// wrap that in a custom future implementation which does the
|
||||||
// translation from the future protocol to our fiber API.
|
// translation from the future protocol to our fiber API.
|
||||||
FiberFuture { fiber, store: self }.await?;
|
FiberFuture {
|
||||||
|
fiber,
|
||||||
|
store: self,
|
||||||
|
stack,
|
||||||
|
}
|
||||||
|
.await?;
|
||||||
return Ok(slot.unwrap());
|
return Ok(slot.unwrap());
|
||||||
|
|
||||||
struct FiberFuture<'a> {
|
struct FiberFuture<'a> {
|
||||||
fiber: wasmtime_fiber::Fiber<'a, Result<(), Trap>, (), Result<(), Trap>>,
|
fiber: wasmtime_fiber::Fiber<'a, Result<(), Trap>, (), Result<(), Trap>>,
|
||||||
store: &'a Store,
|
store: &'a Store,
|
||||||
|
stack: *mut u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Future for FiberFuture<'_> {
|
impl Future for FiberFuture<'_> {
|
||||||
@@ -845,9 +875,7 @@ impl Store {
|
|||||||
// completion.
|
// completion.
|
||||||
impl Drop for FiberFuture<'_> {
|
impl Drop for FiberFuture<'_> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
if self.fiber.done() {
|
if !self.fiber.done() {
|
||||||
return;
|
|
||||||
}
|
|
||||||
let result = self.fiber.resume(Err(Trap::new("future dropped")));
|
let result = self.fiber.resume(Err(Trap::new("future dropped")));
|
||||||
// This resumption with an error should always complete the
|
// This resumption with an error should always complete the
|
||||||
// fiber. While it's technically possible for host code to catch
|
// fiber. While it's technically possible for host code to catch
|
||||||
@@ -855,6 +883,16 @@ impl Store {
|
|||||||
// callers that they shouldn't be doing that.
|
// callers that they shouldn't be doing that.
|
||||||
debug_assert!(result.is_ok());
|
debug_assert!(result.is_ok());
|
||||||
}
|
}
|
||||||
|
if !self.stack.is_null() {
|
||||||
|
unsafe {
|
||||||
|
self.store
|
||||||
|
.engine()
|
||||||
|
.config()
|
||||||
|
.instance_allocator()
|
||||||
|
.deallocate_fiber_stack(self.stack)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user