wasmer_interface_types/interpreter/
mod.rs1mod instructions;
4pub mod stack;
5pub mod wasm;
6
7use crate::{
8 errors::{InstructionResult, InterpreterResult},
9 values::InterfaceValue,
10};
11pub use instructions::Instruction;
12use stack::Stack;
13use std::{convert::TryFrom, marker::PhantomData};
14
15pub(crate) struct Runtime<'invocation, 'instance, Instance, Export, LocalImport, Memory, MemoryView>
18where
19 Export: wasm::structures::Export + 'instance,
20 LocalImport: wasm::structures::LocalImport + 'instance,
21 Memory: wasm::structures::Memory<MemoryView> + 'instance,
22 MemoryView: wasm::structures::MemoryView,
23 Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView> + 'instance,
24{
25 invocation_inputs: &'invocation [InterfaceValue],
28
29 stack: Stack<InterfaceValue>,
31
32 wasm_instance: &'instance mut Instance,
35
36 _phantom: PhantomData<(Export, LocalImport, Memory, MemoryView)>,
38}
39
40pub(crate) type ExecutableInstruction<Instance, Export, LocalImport, Memory, MemoryView> = Box<
43 dyn Fn(
44 &mut Runtime<Instance, Export, LocalImport, Memory, MemoryView>,
45 ) -> InstructionResult<()>,
46>;
47
48pub struct Interpreter<Instance, Export, LocalImport, Memory, MemoryView>
127where
128 Export: wasm::structures::Export,
129 LocalImport: wasm::structures::LocalImport,
130 Memory: wasm::structures::Memory<MemoryView>,
131 MemoryView: wasm::structures::MemoryView,
132 Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView>,
133{
134 executable_instructions:
135 Vec<ExecutableInstruction<Instance, Export, LocalImport, Memory, MemoryView>>,
136}
137
138impl<Instance, Export, LocalImport, Memory, MemoryView>
139 Interpreter<Instance, Export, LocalImport, Memory, MemoryView>
140where
141 Export: wasm::structures::Export,
142 LocalImport: wasm::structures::LocalImport,
143 Memory: wasm::structures::Memory<MemoryView>,
144 MemoryView: wasm::structures::MemoryView,
145 Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView>,
146{
147 fn iter(
148 &self,
149 ) -> impl Iterator<
150 Item = &ExecutableInstruction<Instance, Export, LocalImport, Memory, MemoryView>,
151 > + '_ {
152 self.executable_instructions.iter()
153 }
154
155 pub fn run(
161 &self,
162 invocation_inputs: &[InterfaceValue],
163 wasm_instance: &mut Instance,
164 ) -> InterpreterResult<Stack<InterfaceValue>> {
165 let mut runtime = Runtime {
166 invocation_inputs,
167 stack: Stack::new(),
168 wasm_instance,
169 _phantom: PhantomData,
170 };
171
172 for executable_instruction in self.iter() {
173 executable_instruction(&mut runtime)?;
174 }
175
176 Ok(runtime.stack)
177 }
178}
179
180impl<Instance, Export, LocalImport, Memory, MemoryView> TryFrom<&Vec<Instruction>>
182 for Interpreter<Instance, Export, LocalImport, Memory, MemoryView>
183where
184 Export: wasm::structures::Export,
185 LocalImport: wasm::structures::LocalImport,
186 Memory: wasm::structures::Memory<MemoryView>,
187 MemoryView: wasm::structures::MemoryView,
188 Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView>,
189{
190 type Error = ();
191
192 fn try_from(instructions: &Vec<Instruction>) -> Result<Self, Self::Error> {
193 let executable_instructions = instructions
194 .iter()
195 .map(|instruction| match instruction {
196 Instruction::ArgumentGet { index } => {
197 instructions::argument_get(*index, *instruction)
198 }
199
200 Instruction::CallCore { function_index } => {
201 instructions::call_core(*function_index, *instruction)
202 }
203
204 Instruction::S8FromI32 => instructions::s8_from_i32(*instruction),
205 Instruction::S8FromI64 => instructions::s8_from_i64(*instruction),
206 Instruction::S16FromI32 => instructions::s16_from_i32(*instruction),
207 Instruction::S16FromI64 => instructions::s16_from_i64(*instruction),
208 Instruction::S32FromI32 => instructions::s32_from_i32(*instruction),
209 Instruction::S32FromI64 => instructions::s32_from_i64(*instruction),
210 Instruction::S64FromI32 => instructions::s64_from_i32(*instruction),
211 Instruction::S64FromI64 => instructions::s64_from_i64(*instruction),
212 Instruction::I32FromS8 => instructions::i32_from_s8(*instruction),
213 Instruction::I32FromS16 => instructions::i32_from_s16(*instruction),
214 Instruction::I32FromS32 => instructions::i32_from_s32(*instruction),
215 Instruction::I32FromS64 => instructions::i32_from_s64(*instruction),
216 Instruction::I64FromS8 => instructions::i64_from_s8(*instruction),
217 Instruction::I64FromS16 => instructions::i64_from_s16(*instruction),
218 Instruction::I64FromS32 => instructions::i64_from_s32(*instruction),
219 Instruction::I64FromS64 => instructions::i64_from_s64(*instruction),
220 Instruction::U8FromI32 => instructions::u8_from_i32(*instruction),
221 Instruction::U8FromI64 => instructions::u8_from_i64(*instruction),
222 Instruction::U16FromI32 => instructions::u16_from_i32(*instruction),
223 Instruction::U16FromI64 => instructions::u16_from_i64(*instruction),
224 Instruction::U32FromI32 => instructions::u32_from_i32(*instruction),
225 Instruction::U32FromI64 => instructions::u32_from_i64(*instruction),
226 Instruction::U64FromI32 => instructions::u64_from_i32(*instruction),
227 Instruction::U64FromI64 => instructions::u64_from_i64(*instruction),
228 Instruction::I32FromU8 => instructions::i32_from_u8(*instruction),
229 Instruction::I32FromU16 => instructions::i32_from_u16(*instruction),
230 Instruction::I32FromU32 => instructions::i32_from_u32(*instruction),
231 Instruction::I32FromU64 => instructions::i32_from_u64(*instruction),
232 Instruction::I64FromU8 => instructions::i64_from_u8(*instruction),
233 Instruction::I64FromU16 => instructions::i64_from_u16(*instruction),
234 Instruction::I64FromU32 => instructions::i64_from_u32(*instruction),
235 Instruction::I64FromU64 => instructions::i64_from_u64(*instruction),
236
237 Instruction::StringLiftMemory => instructions::string_lift_memory(*instruction),
238 Instruction::StringLowerMemory => instructions::string_lower_memory(*instruction),
239 Instruction::StringSize => instructions::string_size(*instruction),
240
241 Instruction::RecordLift { type_index } => {
242 instructions::record_lift(*type_index, *instruction)
243 }
244 Instruction::RecordLower { type_index } => {
245 instructions::record_lower(*type_index, *instruction)
246 }
247 })
248 .collect();
249
250 Ok(Interpreter {
251 executable_instructions,
252 })
253 }
254}