[][src]Struct wasmtime::Linker

pub struct Linker { /* fields omitted */ }

Structure used to link wasm modules/instances together.

This structure is used to assist in instantiating a Module. A Linker is a way of performing name resolution to make instantiating a module easier (as opposed to calling Instance::new). Linker is a name-based resolver where names are dynamically defined and then used to instantiate a Module. The goal of a Linker is to have a one-argument method, Linker::instantiate, which takes a Module and produces an Instance. This method will automatically select all the right imports for the Module to be instantiated, and will otherwise return an error if an import isn't satisfied.

Name Resolution

As mentioned previously, Linker is a form of name resolver. It will be using the string-based names of imports on a module to attempt to select a matching item to hook up to it. This name resolution has two-levels of namespaces, a module level and a name level. Each item is defined within a module and then has its own name. This basically follows the wasm standard for modularization.

Names in a Linker can be defined twice, but only for different signatures of items. This means that every item defined in a Linker has a unique name/type pair. For example you can define two functions with the module name foo and item name bar, so long as they have different function signatures. Currently duplicate memories and tables are not allowed, only one-per-name is allowed.

Note that allowing duplicates by shadowing the previous definition can be controlled with the Linker::allow_shadowing method as well.

Implementations

impl Linker[src]

pub fn new(store: &Store) -> Linker[src]

Creates a new Linker.

This function will create a new Linker which is ready to start linking modules. All items defined in this linker and produced by this linker will be connected with store and must come from the same store.

Examples

use wasmtime::{Linker, Store};

let store = Store::default();
let mut linker = Linker::new(&store);
// ...

pub fn allow_shadowing(&mut self, allow: bool) -> &mut Linker[src]

Configures whether this Linker will shadow previous duplicate definitions of the same signature.

By default a Linker will disallow duplicate definitions of the same signature. This method, however, can be used to instead allow duplicates and have the latest definition take precedence when linking modules.

Examples

let mut linker = Linker::new(&store);
linker.func("", "", || {})?;

// by default, duplicates are disallowed
assert!(linker.func("", "", || {}).is_err());

// but shadowing can be configured to be allowed as well
linker.allow_shadowing(true);
linker.func("", "", || {})?;

pub fn define(
    &mut self,
    module: &str,
    name: &str,
    item: impl Into<Extern>
) -> Result<&mut Self>
[src]

Defines a new item in this Linker.

This method will add a new definition, by name, to this instance of Linker. The module and name provided are what to name the item.

Errors

Returns an error if the module and name already identify an item of the same type as the item provided and if shadowing is disallowed. For more information see the documentation on Linker.

Also returns an error if item comes from a different store than this Linker was created with.

Examples

let mut linker = Linker::new(&store);
let ty = GlobalType::new(ValType::I32, Mutability::Const);
let global = Global::new(&store, ty, Val::I32(0x1234))?;
linker.define("host", "offset", global)?;

let wat = r#"
    (module
        (import "host" "offset" (global i32))
        (memory 1)
        (data (global.get 0) "foo")
    )
"#;
let module = Module::new(store.engine(), wat)?;
linker.instantiate(&module)?;

pub fn func<Params, Args>(
    &mut self,
    module: &str,
    name: &str,
    func: impl IntoFunc<Params, Args>
) -> Result<&mut Self>
[src]

Convenience wrapper to define a function import.

This method is a convenience wrapper around Linker::define which internally delegates to Func::wrap.

Errors

Returns an error if the module and name already identify an item of the same type as the item provided and if shadowing is disallowed. For more information see the documentation on Linker.

Examples

let mut linker = Linker::new(&store);
linker.func("host", "double", |x: i32| x * 2)?;
linker.func("host", "log_i32", |x: i32| println!("{}", x))?;
linker.func("host", "log_str", |caller: Caller, ptr: i32, len: i32| {
    // ...
})?;

let wat = r#"
    (module
        (import "host" "double" (func (param i32) (result i32)))
        (import "host" "log_i32" (func (param i32)))
        (import "host" "log_str" (func (param i32 i32)))
    )
"#;
let module = Module::new(store.engine(), wat)?;
linker.instantiate(&module)?;

pub fn instance(
    &mut self,
    module_name: &str,
    instance: &Instance
) -> Result<&mut Self>
[src]

Convenience wrapper to define an entire Instance in this linker.

This function is a convenience wrapper around Linker::define which will define all exports on instance into this linker. The module name for each export is module_name, and the name for each export is the name in the instance itself.

Errors

Returns an error if the any item is redefined twice in this linker (for example the same module_name was already defined) and shadowing is disallowed, or if instance comes from a different Store than this Linker originally was created with.

Examples

let mut linker = Linker::new(&store);

// Instantiate a small instance...
let wat = r#"(module (func (export "run") ))"#;
let module = Module::new(store.engine(), wat)?;
let instance = linker.instantiate(&module)?;

// ... and inform the linker that the name of this instance is
// `instance1`. This defines the `instance1::run` name for our next
// module to use.
linker.instance("instance1", &instance)?;

let wat = r#"
    (module
        (import "instance1" "run" (func $instance1_run))
        (func (export "run")
            call $instance1_run
        )
    )
"#;
let module = Module::new(store.engine(), wat)?;
let instance = linker.instantiate(&module)?;

pub fn module(
    &mut self,
    module_name: &str,
    module: &Module
) -> Result<&mut Self>
[src]

Define automatic instantiations of a Module in this linker.

This automatically handles Commands and Reactors instantiation and initialization.

Exported functions of a Command module may be called directly, however instead of having a single instance which is reused for each call, each call creates a new instance, which lives for the duration of the call. The imports of the Command are resolved once, and reused for each instantiation, so all dependencies need to be present at the time when Linker::module is called.

For Reactors, a single instance is created, and an initialization function is called, and then its exports may be called.

Ordinary modules which don't declare themselves to be either Commands or Reactors are treated as Reactors without any initialization calls.

Errors

Returns an error if the any item is redefined twice in this linker (for example the same module_name was already defined) and shadowing is disallowed, if instance comes from a different Store than this Linker originally was created with, or if a Reactor initialization function traps.

Examples

let mut linker = Linker::new(&store);

// Instantiate a small instance and inform the linker that the name of
// this instance is `instance1`. This defines the `instance1::run` name
// for our next module to use.
let wat = r#"(module (func (export "run") ))"#;
let module = Module::new(store.engine(), wat)?;
linker.module("instance1", &module)?;

let wat = r#"
    (module
        (import "instance1" "run" (func $instance1_run))
        (func (export "run")
            call $instance1_run
        )
    )
"#;
let module = Module::new(store.engine(), wat)?;
let instance = linker.instantiate(&module)?;

For a Command, a new instance is created for each call.

let mut linker = Linker::new(&store);

// Create a Command that attempts to count the number of times it is run, but is
// foiled by each call getting a new instance.
let wat = r#"
    (module
        (global $counter (mut i32) (i32.const 0))
        (func (export "_start")
            (global.set $counter (i32.add (global.get $counter) (i32.const 1)))
        )
        (func (export "read_counter") (result i32)
            (global.get $counter)
        )
    )
"#;
let module = Module::new(store.engine(), wat)?;
linker.module("commander", &module)?;
let run = linker.get_default("")?.get0::<()>()?;
run()?;
run()?;
run()?;

let wat = r#"
    (module
        (import "commander" "_start" (func $commander_start))
        (import "commander" "read_counter" (func $commander_read_counter (result i32)))
        (func (export "run") (result i32)
            call $commander_start
            call $commander_start
            call $commander_start
            call $commander_read_counter
        )
    )
"#;
let module = Module::new(store.engine(), wat)?;
linker.module("", &module)?;
let count = linker.get_one_by_name("", "run")?.into_func().unwrap().get0::<i32>()?()?;
assert_eq!(count, 0, "a Command should get a fresh instance on each invocation");

pub fn alias(&mut self, module: &str, as_module: &str) -> Result<()>[src]

Aliases one module's name as another.

This method will alias all currently defined under module to also be defined under the name as_module too.

Errors

Returns an error if any shadowing violations happen while defining new items.

pub fn instantiate(&self, module: &Module) -> Result<Instance>[src]

Attempts to instantiate the module provided.

This method will attempt to assemble a list of imports that correspond to the imports required by the Module provided. This list of imports is then passed to Instance::new to continue the instantiation process.

Each import of module will be looked up in this Linker and must have previously been defined. If it was previously defined with an incorrect signature or if it was not previously defined then an error will be returned because the import can not be satisfied.

Per the WebAssembly spec, instantiation includes running the module's start function, if it has one (not to be confused with the _start function, which is not run).

Errors

This method can fail because an import may not be found, or because instantiation itself may fail. For information on instantiation failures see Instance::new.

Examples

let mut linker = Linker::new(&store);
linker.func("host", "double", |x: i32| x * 2)?;

let wat = r#"
    (module
        (import "host" "double" (func (param i32) (result i32)))
    )
"#;
let module = Module::new(store.engine(), wat)?;
linker.instantiate(&module)?;

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

Returns the Store that this linker is connected to.

pub fn iter(&self) -> impl Iterator<Item = (&str, &str, Extern)>[src]

Returns an iterator over all items defined in this Linker, in arbitrary order.

The iterator returned will yield 3-tuples where the first two elements are the module name and item name for the external item, and the third item is the item itself that is defined.

Note that multiple Extern items may be defined for the same module/name pair.

pub fn get(&self, import: &ImportType<'_>) -> Option<Extern>[src]

Looks up a value in this Linker which matches the import type provided.

Returns None if no match was found.

pub fn get_by_name<'a: 'p, 'p>(
    &'a self,
    module: &'p str,
    name: &'p str
) -> impl Iterator<Item = &'a Extern> + 'p
[src]

Returns all items defined for the module and name pair.

This may return an empty iterator, but it may also return multiple items if the module/name have been defined twice.

pub fn get_one_by_name(&self, module: &str, name: &str) -> Result<Extern>[src]

Returns the single item defined for the module and name pair.

Unlike the similar Linker::get_by_name method this function returns a single Extern item. If the module and name pair isn't defined in this linker then an error is returned. If more than one value exists for the module and name pairs, then an error is returned as well.

pub fn get_default(&self, module: &str) -> Result<Func>[src]

Returns the "default export" of a module.

An export with an empty string is considered to be a "default export". "_start" is also recognized for compatibility.

Auto Trait Implementations

impl !RefUnwindSafe for Linker

impl !Send for Linker

impl !Sync for Linker

impl Unpin for Linker

impl !UnwindSafe for Linker

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> Same<T> for T

type Output = T

Should always be Self

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.