Skip to content

Commit

Permalink
Soup up documentation for errors and traps
Browse files Browse the repository at this point in the history
  • Loading branch information
alexcrichton committed Nov 1, 2022
1 parent 9b0275e commit a651f23
Show file tree
Hide file tree
Showing 5 changed files with 231 additions and 33 deletions.
40 changes: 29 additions & 11 deletions crates/wasmtime/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,15 +381,30 @@ impl Config {
self
}

/// Configures whether backtraces exist in a `Trap`.
///
/// Enabled by default, this feature builds in support to
/// generate backtraces at runtime for WebAssembly modules. This means that
/// unwinding information is compiled into wasm modules and necessary runtime
/// dependencies are enabled as well.
///
/// When disabled, wasm backtrace details are ignored, and [`crate::Trap::trace()`]
/// will always return `None`.
/// Configures whether [`WasmBacktrace`] will be present in the context of
/// errors returned from Wasmtime.
///
/// A backtrace may be collected whenever an error is returned from a host
/// function call through to WebAssembly or when WebAssembly itself hits a
/// trap condition, such as an out-of-bounds memory access. This flag
/// indicates, in these conditions, whether the backtrace is collected or
/// not.
///
/// Currently wasm backtraces are implemented through frame pointer walking.
/// This means that collecting a backtrace is expected to be a fast and
/// relatively cheap operation. Additionally backtrace collection is
/// suitable in concurrent environments since one thread capturing a
/// backtrace won't block other threads.
///
/// Collected backtraces are attached via [`anyhow::Error::context`] to
/// errors returned from host functions. The [`WasmBacktrace`] type can be
/// acquired via [`anyhow::Error::downcast_ref`] to inspect the backtrace.
/// When this option is disabled then this context is never applied to
/// errors coming out of wasm.
///
/// This option is `true` by default.
///
/// [`WasmBacktrace`]: crate::WasmBacktrace
#[deprecated = "Backtraces will always be enabled in future Wasmtime releases; if this \
causes problems for you, please file an issue."]
pub fn wasm_backtrace(&mut self, enable: bool) -> &mut Self {
Expand Down Expand Up @@ -429,13 +444,16 @@ impl Config {
/// This configuration option only exists to help third-party stack
/// capturing mechanisms, such as the system's unwinder or the `backtrace`
/// crate, determine how to unwind through Wasm frames. It does not affect
/// whether Wasmtime can capture Wasm backtraces or not, or whether
/// [`Trap::trace`][crate::Trap::trace] returns `Some` or `None`.
/// whether Wasmtime can capture Wasm backtraces or not. The presence of
/// [`WasmBacktrace`] is controlled by the [`Config::wasm_backtrace`]
/// option.
///
/// Note that native unwind information is always generated when targeting
/// Windows, since the Windows ABI requires it.
///
/// This option defaults to `true`.
///
/// [`WasmBacktrace`]: crate::WasmBacktrace
pub fn native_unwind_info(&mut self, enable: bool) -> &mut Self {
self.native_unwind_info = enable;
self
Expand Down
79 changes: 75 additions & 4 deletions crates/wasmtime/src/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,22 @@ impl Func {
///
/// For more information about `Send + Sync + 'static` requirements on the
/// `func`, see [`Func::wrap`](#why-send--sync--static).
///
/// # Errors
///
/// The host-provided function here returns a
/// [`Result<()>`](anyhow::Result). If the function returns `Ok(())` then
/// that indicates that the host function completed successfully and wrote
/// the result into the `&mut [Val]` argument.
///
/// If the function returns `Err(e)`, however, then this is equivalent to
/// the host function triggering a trap for wasm. WebAssembly execution is
/// immediately halted and the original caller of [`Func::call`], for
/// example, will receive the error returned here (possibly with
/// [`WasmBacktrace`](crate::WasmBacktrace) context information attached).
///
/// For more information about errors in Wasmtime see the [`Trap`]
/// documentation.
#[cfg(compiler)]
#[cfg_attr(nightlydoc, doc(cfg(feature = "cranelift")))] // see build.rs
pub fn new<T>(
Expand Down Expand Up @@ -355,6 +371,11 @@ impl Func {
/// [`Func::new`] or [`Func::wrap`]. The [`Func::wrap`] API, in particular,
/// is both safer and faster than this API.
///
/// # Errors
///
/// See [`Func::new`] for the behavior of returning an error from the host
/// function provided here.
///
/// # Unsafety
///
/// This function is not safe because it's not known at compile time that
Expand Down Expand Up @@ -392,6 +413,11 @@ impl Func {
/// This function will panic if `store` is not associated with an [async
/// config](crate::Config::async_support).
///
/// # Errors
///
/// See [`Func::new`] for the behavior of returning an error from the host
/// function provided here.
///
/// # Examples
///
/// ```
Expand Down Expand Up @@ -543,6 +569,18 @@ impl Func {
/// actually closing over any values. These zero-sized types will use the
/// context from [`Caller`] for host-defined information.
///
/// # Errors
///
/// The closure provided here to `wrap` can optionally return a
/// [`Result<T>`](anyhow::Result). Returning `Ok(t)` represents the host
/// function successfully completing with the `t` result. Returning
/// `Err(e)`, however, is equivalent to raising a custom wasm trap.
/// Execution of WebAssembly does not resume and the stack is unwound to the
/// original caller of the function where the error is returned.
///
/// For more information about errors in Wasmtime see the [`Trap`]
/// documentation.
///
/// # Examples
///
/// First up we can see how simple wasm imports can be implemented, such
Expand Down Expand Up @@ -750,16 +788,41 @@ impl Func {
/// Invokes this function with the `params` given and writes returned values
/// to `results`.
///
/// The `params` here must match the type signature of this `Func`, or a
/// trap will occur. If a trap occurs while executing this function, then a
/// trap will also be returned. Additionally `results` must have the same
/// length as the number of results for this function.
/// The `params` here must match the type signature of this `Func`, or an
/// error will occur. Additionally `results` must have the same
/// length as the number of results for this function. Calling this function
/// will synchronously execute the WebAssembly function referenced to get
/// the results.
///
/// This function will return `Ok(())` if execution completed without a trap
/// or error of any kind. In this situation the results will be written to
/// the provided `results` array.
///
/// # Errors
///
/// Any error which occurs throughout the execution of the function will be
/// returned as `Err(e)`. The [`Error`](anyhow::Error) type can be inspected
/// for the precise error cause such as:
///
/// * [`Trap`] - indicates that a wasm trap happened and execution was
/// halted.
/// * [`WasmBacktrace`] - optionally included on errors for backtrace
/// information of the trap/error.
/// * Other string-based errors to indicate issues such as type errors with
/// `params`.
/// * Any host-originating error originally returned from a function defined
/// via [`Func::new`], for example.
///
/// Errors typically indicate that execution of WebAssembly was halted
/// mid-way and did not complete after the error condition happened.
///
/// # Panics
///
/// This function will panic if called on a function belonging to an async
/// store. Asynchronous stores must always use `call_async`.
/// initiates a panic. Also panics if `store` does not own this function.
///
/// [`WasmBacktrace`]: crate::WasmBacktrace
pub fn call(
&self,
mut store: impl AsContextMut,
Expand Down Expand Up @@ -788,6 +851,10 @@ impl Func {
/// invoked many times with new `ExternRef` values and no other GC happens
/// via any other means then no values will get collected.
///
/// # Errors
///
/// For more information about errors see the [`Func::call`] documentation.
///
/// # Unsafety
///
/// This function is unsafe because the `params_and_returns` argument is not
Expand Down Expand Up @@ -878,6 +945,10 @@ impl Func {
/// For more information see the documentation on [asynchronous
/// configs](crate::Config::async_support).
///
/// # Errors
///
/// For more information on errors see the [`Func::call`] documentation.
///
/// # Panics
///
/// Panics if this is called on a function in a synchronous store. This
Expand Down
8 changes: 8 additions & 0 deletions crates/wasmtime/src/func/typed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ where
/// For more information, see the [`Func::typed`] and [`Func::call`]
/// documentation.
///
/// # Errors
///
/// For more information on errors see the documentation on [`Func::call`].
///
/// # Panics
///
/// This function will panic if it is called when the underlying [`Func`] is
Expand All @@ -91,6 +95,10 @@ where
/// For more information, see the [`Func::typed`] and [`Func::call_async`]
/// documentation.
///
/// # Errors
///
/// For more information on errors see the documentation on [`Func::call`].
///
/// # Panics
///
/// This function will panic if it is called when the underlying [`Func`] is
Expand Down
7 changes: 4 additions & 3 deletions crates/wasmtime/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ impl Instance {
///
/// When instantiation fails it's recommended to inspect the return value to
/// see why it failed, or bubble it upwards. If you'd like to specifically
/// check for trap errors, you can use `error.downcast::<Trap>()`.
/// check for trap errors, you can use `error.downcast::<Trap>()`. For more
/// about error handling see the [`Trap`] documentation.
///
/// # Panics
///
Expand All @@ -102,7 +103,7 @@ impl Instance {
mut store: impl AsContextMut,
module: &Module,
imports: &[Extern],
) -> Result<Instance, Error> {
) -> Result<Instance> {
let mut store = store.as_context_mut();
let imports = Instance::typecheck_externs(store.0, module, imports)?;
// Note that the unsafety here should be satisfied by the call to
Expand Down Expand Up @@ -134,7 +135,7 @@ impl Instance {
mut store: impl AsContextMut<Data = T>,
module: &Module,
imports: &[Extern],
) -> Result<Instance, Error>
) -> Result<Instance>
where
T: Send,
{
Expand Down
Loading

0 comments on commit a651f23

Please sign in to comment.