Struct wasmer_interface_types_fl::interpreter::Interpreter[][src]

pub struct Interpreter<Instance, Export, LocalImport, Memory, MemoryView> where
    Export: Export,
    LocalImport: LocalImport,
    Memory: Memory<MemoryView>,
    MemoryView: MemoryView,
    Instance: Instance<Export, LocalImport, Memory, MemoryView>, 
{ /* fields omitted */ }
Expand description

An interpreter is the central piece of this crate. It is a set of executable instructions. Each instruction takes the runtime as argument. The runtime holds the invocation inputs, the stack, and the WebAssembly instance.

When the interpreter executes the instructions, each of them can query the WebAssembly instance, operates on the stack, or reads the invocation inputs. At the end of the execution, the stack supposedly contains a result. Since an interpreter is used by a WIT adapter to execute its instructions, the result on the stack is the result of the adapter.

Example

use std::{cell::Cell, collections::HashMap, convert::TryInto};
use wasmer_interface_types::{
    interpreter::{
        instructions::tests::{Export, Instance, LocalImport, Memory, MemoryView},
//      ^^^^^^^^^^^^ This is private and for testing purposes only.
//                   It is basically a fake WebAssembly runtime.
        stack::Stackable,
        Instruction, Interpreter,
    },
    types::IType,
    values::IValue,
};

// 1. Creates an interpreter from a set of instructions. They will
//    be transformed into executable instructions.
let interpreter: Interpreter<Instance, Export, LocalImport, Memory, MemoryView> = (&vec![
    Instruction::ArgumentGet { index: 1 },
    Instruction::ArgumentGet { index: 0 },
    Instruction::CallCore { function_index: 42 },
])
    .try_into()
    .unwrap();

// 2. Defines the arguments of the adapter.
let invocation_inputs = vec![IValue::I32(3), IValue::I32(4)];

// 3. Creates a WebAssembly instance.
let mut instance = Instance {
    // 3.1. Defines one function: `fn sum(a: i32, b: i32) -> i32 { a + b }`.
    locals_or_imports: {
        let mut hashmap = HashMap::new();
        hashmap.insert(
            42,
            LocalImport {
                // Defines the argument types of the function.
                inputs: vec![IType::I32, IType::I32],

                // Defines the result types.
                outputs: vec![IType::I32],

                // Defines the function implementation.
                function: |arguments: &[IValue]| {
                    let a: i32 = (&arguments[0]).try_into().unwrap();
                    let b: i32 = (&arguments[1]).try_into().unwrap();

                    Ok(vec![IValue::I32(a + b)])
                },
            },
        );
    },
    ..Default::default()
};

// 4. Executes the instructions.
let run = interpreter.run(&invocation_inputs, &mut instance);

assert!(run.is_ok());

let stack = run.unwrap();

// 5. Read the stack to get the result.
assert_eq!(stack.as_slice(), &[IValue::I32(7)]);

Implementations

Runs the interpreter, such as:

  1. Create a fresh stack,
  2. Create a fresh stack,
  3. Execute the instructions one after the other, and returns the stack.

Trait Implementations

Transforms a Vec<Instruction> into an Interpreter.

The type returned in the event of a conversion error.

Performs the conversion.

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Performs the conversion.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.