Skip to main content

wasm_split

Attribute Macro wasm_split 

Source
#[wasm_split]
Expand description

Indicate a function as a split point.

The macro emits a function with the same signature, except that it is async. Calls to this function will first load the module into which the annotated function was split into before forwarding the arguments and the result. On non-wasm targets, the function will be called directly.

The annotated function must fulfill the requirements a typical extern declared function must fufill:

  • It can not be async. If you want to support this, you must Box or otherwise wrap the Future into a dyn object. Also see the return_wrapper option for some further hints.
  • It can not be const.
  • It can not make use of a receiver argument, generics or an impl return type.
  • The only extern linkage on wasm is #[wasm_import_module] which implies extern "C", see this blog post. The macro allows you to specify a different linkage but that is only used for the generated wrapper function. The forward call will happen with "C" ABI. This means in particular that panicking is forbidden across the call. As of now, a panic on wasm leads to an abort, and this doc serves only as a warning.

ยงSyntax

wasm_split($module:ident (, $option ),* ) => { ... };

All functions with the same specified $module end up in one split off WASM chunk.

The following options are supported:

  • wasm_split_path = $this:path changes the path at which the runtime support crate is expected. As a framework, you might want to reexport this from some hidden module path. Default: ::wasm_split_helpers.

  • return_wrapper( let $bindings:pat = _ ; $compute:block -> $ret:ty ). A rather low-level option to support rewriting the result of the wrapped function. The generated wrapper will, rather than directly return the result from the user-given function, bind this to $bindings and emit the statements in $compute to generate the return value of the wrapper with the return type indicated by $ret.

    Example use case: return_wrapper( let future = _ ; { future.await } -> Output) to await a future directly in the wrapper.

  • preload( $( #[$attr] )* $preload_name:ident ) generates an additional preload function $preload_name that fetches the module in which the wrapped function is contained without calling it. Its signature is async fn() and a hard load failure panics, matching the wrapper; with the fallible option it instead returns Result<(), $wasm_split_path::SplitLoaderError>. See also SplitLoaderError.

  • fallible surfaces a load failure as Err instead of panicking (a panic aborts the whole wasm module). The annotated function must return Result<_, E> where E: From<$wasm_split_path::SplitLoaderError>; the macro leaves that signature untouched and converts a load failure into your E via ?, so a use-site can fold it straight into a framework-specific error. The generated preload function (if any) returns Result<(), $wasm_split_path::SplitLoaderError>. Without this option both keep their infallible signatures and a hard load failure panics. The failure is not cached, so a later call retries from scratch. See also SplitLoaderError.