[][src]Struct wasmtime::Func

pub struct Func { /* fields omitted */ }

A WebAssembly function which can be called.

This type can represent a number of callable items, such as:

These types of callable items are all wrapped up in this Func and can be used to both instantiate an Instance as well as be extracted from an Instance.

Func and Clone

Functions are internally reference counted so you can clone a Func. The cloning process only performs a shallow clone, so two cloned Func instances are equivalent in their functionality.

Examples

One way to get a Func is from an Instance after you've instantiated it:

let engine = Engine::default();
let store = Store::new(&engine);
let module = Module::new(&engine, r#"(module (func (export "foo")))"#)?;
let instance = Instance::new(&store, &module, &[])?;
let foo = instance.get_func("foo").expect("export wasn't a function");

// Work with `foo` as a `Func` at this point, such as calling it
// dynamically...
match foo.call(&[]) {
    Ok(result) => { /* ... */ }
    Err(trap) => {
        panic!("execution of `foo` resulted in a wasm trap: {}", trap);
    }
}
foo.call(&[])?;

// ... or we can make a static assertion about its signature and call it.
// Our first call here can fail if the signatures don't match, and then the
// second call can fail if the function traps (like the `match` above).
let foo = foo.get0::<()>()?;
foo()?;

You can also use the wrap function to create a Func

let store = Store::default();

// Create a custom `Func` which can execute arbitrary code inside of the
// closure.
let add = Func::wrap(&store, |a: i32, b: i32| -> i32 { a + b });

// Next we can hook that up to a wasm module which uses it.
let module = Module::new(
    store.engine(),
    r#"
        (module
            (import "" "" (func $add (param i32 i32) (result i32)))
            (func (export "call_add_twice") (result i32)
                i32.const 1
                i32.const 2
                call $add
                i32.const 3
                i32.const 4
                call $add
                i32.add))
    "#,
)?;
let instance = Instance::new(&store, &module, &[add.into()])?;
let call_add_twice = instance.get_func("call_add_twice").expect("export wasn't a function");
let call_add_twice = call_add_twice.get0::<i32>()?;

assert_eq!(call_add_twice()?, 10);

Or you could also create an entirely dynamic Func!

let store = Store::default();

// Here we need to define the type signature of our `Double` function and
// then wrap it up in a `Func`
let double_type = wasmtime::FuncType::new(
    [wasmtime::ValType::I32].iter().cloned(),
    [wasmtime::ValType::I32].iter().cloned(),
);
let double = Func::new(&store, double_type, |_, params, results| {
    let mut value = params[0].unwrap_i32();
    value *= 2;
    results[0] = value.into();
    Ok(())
});

let module = Module::new(
    store.engine(),
    r#"
        (module
            (import "" "" (func $double (param i32) (result i32)))
            (func $start
                i32.const 1
                call $double
                drop)
            (start $start))
    "#,
)?;
let instance = Instance::new(&store, &module, &[double.into()])?;
// .. work with `instance` if necessary

Implementations

impl Func[src]

pub fn new(
    store: &Store,
    ty: FuncType,
    func: impl Fn(Caller<'_>, &[Val], &mut [Val]) -> Result<(), Trap> + 'static
) -> Self
[src]

Creates a new Func with the given arguments, typically to create a user-defined function to pass as an import to a module.

  • store - a cache of data where information is stored, typically shared with a Module.

  • ty - the signature of this function, used to indicate what the inputs and outputs are, which must be WebAssembly types.

  • func - the native code invoked whenever this Func will be called. This closure is provided a Caller as its first argument to learn information about the caller, and then it's passed a list of parameters as a slice along with a mutable slice of where to write results.

Note that the implementation of func must adhere to the ty signature given, error or traps may occur if it does not respect the ty signature.

Additionally note that this is quite a dynamic function since signatures are not statically known. For a more performant Func it's recommended to use Func::wrap if you can because with statically known signatures the engine can optimize the implementation much more.

pub fn wrap<Params, Results>(
    store: &Store,
    func: impl IntoFunc<Params, Results>
) -> Func
[src]

Creates a new Func from the given Rust closure.

This function will create a new Func which, when called, will execute the given Rust closure. Unlike Func::new the target function being called is known statically so the type signature can be inferred. Rust types will map to WebAssembly types as follows:

Rust Argument TypeWebAssembly Type
i32i32
u32i32
i64i64
u64i64
f32f32
f64f64
(not supported)v128
Option<Func>funcref
Option<ExternRef>externref

Any of the Rust types can be returned from the closure as well, in addition to some extra types

Rust Return TypeWebAssembly Return TypeMeaning
()nothingno return value
Result<T, Trap>Tfunction may trap

At this time multi-value returns are not supported, and supporting this is the subject of #1178.

Finally you can also optionally take Caller as the first argument of your closure. If inserted then you're able to inspect the caller's state, for example the Memory it has exported so you can read what pointers point to.

Note that when using this API, the intention is to create as thin of a layer as possible for when WebAssembly calls the function provided. With sufficient inlining and optimization the WebAssembly will call straight into func provided, with no extra fluff entailed.

Examples

First up we can see how simple wasm imports can be implemented, such as a function that adds its two arguments and returns the result.

let add = Func::wrap(&store, |a: i32, b: i32| a + b);
let module = Module::new(
    store.engine(),
    r#"
        (module
            (import "" "" (func $add (param i32 i32) (result i32)))
            (func (export "foo") (param i32 i32) (result i32)
                local.get 0
                local.get 1
                call $add))
    "#,
)?;
let instance = Instance::new(&store, &module, &[add.into()])?;
let foo = instance.get_func("foo").unwrap().get2::<i32, i32, i32>()?;
assert_eq!(foo(1, 2)?, 3);

We can also do the same thing, but generate a trap if the addition overflows:

let add = Func::wrap(&store, |a: i32, b: i32| {
    match a.checked_add(b) {
        Some(i) => Ok(i),
        None => Err(Trap::new("overflow")),
    }
});
let module = Module::new(
    store.engine(),
    r#"
        (module
            (import "" "" (func $add (param i32 i32) (result i32)))
            (func (export "foo") (param i32 i32) (result i32)
                local.get 0
                local.get 1
                call $add))
    "#,
)?;
let instance = Instance::new(&store, &module, &[add.into()])?;
let foo = instance.get_func("foo").unwrap().get2::<i32, i32, i32>()?;
assert_eq!(foo(1, 2)?, 3);
assert!(foo(i32::max_value(), 1).is_err());

And don't forget all the wasm types are supported!

let debug = Func::wrap(&store, |a: i32, b: u32, c: f32, d: i64, e: u64, f: f64| {

    println!("a={}", a);
    println!("b={}", b);
    println!("c={}", c);
    println!("d={}", d);
    println!("e={}", e);
    println!("f={}", f);
});
let module = Module::new(
    store.engine(),
    r#"
        (module
            (import "" "" (func $debug (param i32 i32 f32 i64 i64 f64)))
            (func (export "foo")
                i32.const -1
                i32.const 1
                f32.const 2
                i64.const -3
                i64.const 3
                f64.const 4
                call $debug))
    "#,
)?;
let instance = Instance::new(&store, &module, &[debug.into()])?;
let foo = instance.get_func("foo").unwrap().get0::<()>()?;
foo()?;

Finally if you want to get really fancy you can also implement imports that read/write wasm module's memory

use std::str;

let log_str = Func::wrap(&store, |caller: Caller<'_>, ptr: i32, len: i32| {
    let mem = match caller.get_export("memory") {
        Some(Extern::Memory(mem)) => mem,
        _ => return Err(Trap::new("failed to find host memory")),
    };

    // We're reading raw wasm memory here so we need `unsafe`. Note
    // though that this should be safe because we don't reenter wasm
    // while we're reading wasm memory, nor should we clash with
    // any other memory accessors (assuming they're well-behaved
    // too).
    unsafe {
        let data = mem.data_unchecked()
            .get(ptr as u32 as usize..)
            .and_then(|arr| arr.get(..len as u32 as usize));
        let string = match data {
            Some(data) => match str::from_utf8(data) {
                Ok(s) => s,
                Err(_) => return Err(Trap::new("invalid utf-8")),
            },
            None => return Err(Trap::new("pointer/length out of bounds")),
        };
        assert_eq!(string, "Hello, world!");
        println!("{}", string);
    }
    Ok(())
});
let module = Module::new(
    store.engine(),
    r#"
        (module
            (import "" "" (func $log_str (param i32 i32)))
            (func (export "foo")
                i32.const 4   ;; ptr
                i32.const 13  ;; len
                call $log_str)
            (memory (export "memory") 1)
            (data (i32.const 4) "Hello, world!"))
    "#,
)?;
let instance = Instance::new(&store, &module, &[log_str.into()])?;
let foo = instance.get_func("foo").unwrap().get0::<()>()?;
foo()?;

pub fn ty(&self) -> FuncType[src]

Returns the underlying wasm type that this Func has.

pub fn param_arity(&self) -> usize[src]

Returns the number of parameters that this function takes.

pub fn result_arity(&self) -> usize[src]

Returns the number of results this function produces.

pub fn call(&self, params: &[Val]) -> Result<Box<[Val]>>[src]

Invokes this function with the params given, returning the results and any trap, if one occurs.

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.

This function should not panic unless the underlying function itself initiates a panic.

pub fn get0<R>(&self) -> Result<impl Fn() -> Result<R, Trap>> where
    R: WasmTy
[src]

Extracts a natively-callable object from this Func, if the signature matches.

See the Func::get1 method for more documentation.

pub fn get1<A1, R>(&self) -> Result<impl Fn(A1) -> Result<R, Trap>> where
    A1: WasmTy,
    R: WasmTy
[src]

Extracts a natively-callable object from this Func, if the signature matches.

This function serves as an optimized version of the Func::call method if the type signature of a function is statically known to the program. This method is faster than call on a few metrics:

  • Runtime type-checking only happens once, when this method is called.
  • The result values, if any, aren't boxed into a vector.
  • Arguments and return values don't go through boxing and unboxing.
  • No trampolines are used to transfer control flow to/from JIT code, instead this function jumps directly into JIT code.

For more information about which Rust types match up to which wasm types, see the documentation on Func::wrap.

Return

This function will return None if the type signature asserted statically does not match the runtime type signature. Some, however, will be returned if the underlying function takes one parameter of type A and returns the parameter R. Currently R can either be () (no return values) or one wasm type. At this time a multi-value return isn't supported.

The returned closure will always return a Result<R, Trap> and an Err is returned if a trap happens while the wasm is executing.

pub fn get2<A1, A2, R>(&self) -> Result<impl Fn(A1, A2) -> Result<R, Trap>> where
    A1: WasmTy,
    A2: WasmTy,
    R: WasmTy
[src]

Extracts a natively-callable object from this Func, if the signature matches.

See the Func::get1 method for more documentation.

pub fn get3<A1, A2, A3, R>(
    &self
) -> Result<impl Fn(A1, A2, A3) -> Result<R, Trap>> where
    A1: WasmTy,
    A2: WasmTy,
    A3: WasmTy,
    R: WasmTy
[src]

Extracts a natively-callable object from this Func, if the signature matches.

See the Func::get1 method for more documentation.

pub fn get4<A1, A2, A3, A4, R>(
    &self
) -> Result<impl Fn(A1, A2, A3, A4) -> Result<R, Trap>> where
    A1: WasmTy,
    A2: WasmTy,
    A3: WasmTy,
    A4: WasmTy,
    R: WasmTy
[src]

Extracts a natively-callable object from this Func, if the signature matches.

See the Func::get1 method for more documentation.

pub fn get5<A1, A2, A3, A4, A5, R>(
    &self
) -> Result<impl Fn(A1, A2, A3, A4, A5) -> Result<R, Trap>> where
    A1: WasmTy,
    A2: WasmTy,
    A3: WasmTy,
    A4: WasmTy,
    A5: WasmTy,
    R: WasmTy
[src]

Extracts a natively-callable object from this Func, if the signature matches.

See the Func::get1 method for more documentation.

pub fn get6<A1, A2, A3, A4, A5, A6, R>(
    &self
) -> Result<impl Fn(A1, A2, A3, A4, A5, A6) -> Result<R, Trap>> where
    A1: WasmTy,
    A2: WasmTy,
    A3: WasmTy,
    A4: WasmTy,
    A5: WasmTy,
    A6: WasmTy,
    R: WasmTy
[src]

Extracts a natively-callable object from this Func, if the signature matches.

See the Func::get1 method for more documentation.

pub fn get7<A1, A2, A3, A4, A5, A6, A7, R>(
    &self
) -> Result<impl Fn(A1, A2, A3, A4, A5, A6, A7) -> Result<R, Trap>> where
    A1: WasmTy,
    A2: WasmTy,
    A3: WasmTy,
    A4: WasmTy,
    A5: WasmTy,
    A6: WasmTy,
    A7: WasmTy,
    R: WasmTy
[src]

Extracts a natively-callable object from this Func, if the signature matches.

See the Func::get1 method for more documentation.

pub fn get8<A1, A2, A3, A4, A5, A6, A7, A8, R>(
    &self
) -> Result<impl Fn(A1, A2, A3, A4, A5, A6, A7, A8) -> Result<R, Trap>> where
    A1: WasmTy,
    A2: WasmTy,
    A3: WasmTy,
    A4: WasmTy,
    A5: WasmTy,
    A6: WasmTy,
    A7: WasmTy,
    A8: WasmTy,
    R: WasmTy
[src]

Extracts a natively-callable object from this Func, if the signature matches.

See the Func::get1 method for more documentation.

pub fn get9<A1, A2, A3, A4, A5, A6, A7, A8, A9, R>(
    &self
) -> Result<impl Fn(A1, A2, A3, A4, A5, A6, A7, A8, A9) -> Result<R, Trap>> where
    A1: WasmTy,
    A2: WasmTy,
    A3: WasmTy,
    A4: WasmTy,
    A5: WasmTy,
    A6: WasmTy,
    A7: WasmTy,
    A8: WasmTy,
    A9: WasmTy,
    R: WasmTy
[src]

Extracts a natively-callable object from this Func, if the signature matches.

See the Func::get1 method for more documentation.

pub fn get10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, R>(
    &self
) -> Result<impl Fn(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) -> Result<R, Trap>> where
    A1: WasmTy,
    A2: WasmTy,
    A3: WasmTy,
    A4: WasmTy,
    A5: WasmTy,
    A6: WasmTy,
    A7: WasmTy,
    A8: WasmTy,
    A9: WasmTy,
    A10: WasmTy,
    R: WasmTy
[src]

Extracts a natively-callable object from this Func, if the signature matches.

See the Func::get1 method for more documentation.

pub fn get11<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, R>(
    &self
) -> Result<impl Fn(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11) -> Result<R, Trap>> where
    A1: WasmTy,
    A2: WasmTy,
    A3: WasmTy,
    A4: WasmTy,
    A5: WasmTy,
    A6: WasmTy,
    A7: WasmTy,
    A8: WasmTy,
    A9: WasmTy,
    A10: WasmTy,
    A11: WasmTy,
    R: WasmTy
[src]

Extracts a natively-callable object from this Func, if the signature matches.

See the Func::get1 method for more documentation.

pub fn get12<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, R>(
    &self
) -> Result<impl Fn(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12) -> Result<R, Trap>> where
    A1: WasmTy,
    A2: WasmTy,
    A3: WasmTy,
    A4: WasmTy,
    A5: WasmTy,
    A6: WasmTy,
    A7: WasmTy,
    A8: WasmTy,
    A9: WasmTy,
    A10: WasmTy,
    A11: WasmTy,
    A12: WasmTy,
    R: WasmTy
[src]

Extracts a natively-callable object from this Func, if the signature matches.

See the Func::get1 method for more documentation.

pub fn get13<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, R>(
    &self
) -> Result<impl Fn(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13) -> Result<R, Trap>> where
    A1: WasmTy,
    A2: WasmTy,
    A3: WasmTy,
    A4: WasmTy,
    A5: WasmTy,
    A6: WasmTy,
    A7: WasmTy,
    A8: WasmTy,
    A9: WasmTy,
    A10: WasmTy,
    A11: WasmTy,
    A12: WasmTy,
    A13: WasmTy,
    R: WasmTy
[src]

Extracts a natively-callable object from this Func, if the signature matches.

See the Func::get1 method for more documentation.

pub fn get14<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, R>(
    &self
) -> Result<impl Fn(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14) -> Result<R, Trap>> where
    A1: WasmTy,
    A2: WasmTy,
    A3: WasmTy,
    A4: WasmTy,
    A5: WasmTy,
    A6: WasmTy,
    A7: WasmTy,
    A8: WasmTy,
    A9: WasmTy,
    A10: WasmTy,
    A11: WasmTy,
    A12: WasmTy,
    A13: WasmTy,
    A14: WasmTy,
    R: WasmTy
[src]

Extracts a natively-callable object from this Func, if the signature matches.

See the Func::get1 method for more documentation.

pub fn get15<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, R>(
    &self
) -> Result<impl Fn(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15) -> Result<R, Trap>> where
    A1: WasmTy,
    A2: WasmTy,
    A3: WasmTy,
    A4: WasmTy,
    A5: WasmTy,
    A6: WasmTy,
    A7: WasmTy,
    A8: WasmTy,
    A9: WasmTy,
    A10: WasmTy,
    A11: WasmTy,
    A12: WasmTy,
    A13: WasmTy,
    A14: WasmTy,
    A15: WasmTy,
    R: WasmTy
[src]

Extracts a natively-callable object from this Func, if the signature matches.

See the Func::get1 method for more documentation.

pub fn store(&self) -> &Store[src]

Get a reference to this function's store.

Trait Implementations

impl Clone for Func[src]

impl Debug for Func[src]

impl From<Func> for Extern[src]

impl From<Func> for Val[src]

Auto Trait Implementations

impl !RefUnwindSafe for Func

impl !Send for Func

impl !Sync for Func

impl Unpin for Func

impl !UnwindSafe for Func

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Pointable for T

type Init = T

The type for initializers.

impl<T> Same<T> for T

type Output = T

Should always be Self

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.