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
impl<Instance, Export, LocalImport, Memory, MemoryView> Interpreter<Instance, Export, LocalImport, Memory, MemoryView> where
Export: Export,
LocalImport: LocalImport,
Memory: Memory<MemoryView>,
MemoryView: MemoryView,
Instance: Instance<Export, LocalImport, Memory, MemoryView>,
impl<Instance, Export, LocalImport, Memory, MemoryView> Interpreter<Instance, Export, LocalImport, Memory, MemoryView> where
Export: Export,
LocalImport: LocalImport,
Memory: Memory<MemoryView>,
MemoryView: MemoryView,
Instance: Instance<Export, LocalImport, Memory, MemoryView>,
Trait Implementations
impl<Instance, Export, LocalImport, Memory, MemoryView> TryFrom<Vec<Instruction, Global>> for Interpreter<Instance, Export, LocalImport, Memory, MemoryView> where
Export: Export,
LocalImport: LocalImport,
Memory: Memory<MemoryView>,
MemoryView: MemoryView,
Instance: Instance<Export, LocalImport, Memory, MemoryView>,
impl<Instance, Export, LocalImport, Memory, MemoryView> TryFrom<Vec<Instruction, Global>> for Interpreter<Instance, Export, LocalImport, Memory, MemoryView> where
Export: Export,
LocalImport: LocalImport,
Memory: Memory<MemoryView>,
MemoryView: MemoryView,
Instance: Instance<Export, LocalImport, Memory, MemoryView>,
Transforms a Vec<Instruction>
into an Interpreter
.