From 2f7f809fd6f943b31d0db9c82186ed23edcb5e20 Mon Sep 17 00:00:00 2001 From: Andrew Dirksen Date: Mon, 19 Nov 2018 15:59:23 -0800 Subject: [PATCH] make interpreter reusable --- src/func.rs | 12 ++++-------- src/lib.rs | 1 + src/runner.rs | 27 ++++++++++++++++++++++++--- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/func.rs b/src/func.rs index 8a274c1..bf36b49 100644 --- a/src/func.rs +++ b/src/func.rs @@ -7,10 +7,7 @@ use host::Externals; use isa; use module::ModuleInstance; use parity_wasm::elements::Local; -use runner::{ - check_function_args, FunctionContext, Interpreter, InterpreterState, RuntimeValueInternal, - DEFAULT_CALL_STACK_LIMIT, DEFAULT_VALUE_STACK_LIMIT, -}; +use runner::{check_function_args, Interpreter, InterpreterState, DEFAULT_CALL_STACK_LIMIT, DEFAULT_VALUE_STACK_LIMIT}; use types::ValueType; use value::RuntimeValue; use {Signature, Trap}; @@ -136,13 +133,11 @@ impl FuncInstance { func: &FuncRef, args: &[RuntimeValue], externals: &mut E, - value_stack: StackWithLimit, - call_stack: StackWithLimit, + interpreter: &mut Interpreter, ) -> Result, Trap> { check_function_args(func.signature(), &args)?; match *func.as_internal() { FuncInstanceInternal::Internal { .. } => { - let mut interpreter = Interpreter::new(value_stack, call_stack); interpreter.start_execution(externals, func, args, func.signature().return_type()) } FuncInstanceInternal::Host { @@ -167,7 +162,8 @@ impl FuncInstance { ) -> Result, Trap> { let value_stack = StackWithLimit::with_size(StackSize::from_element_count(DEFAULT_VALUE_STACK_LIMIT)); let call_stack = StackWithLimit::with_size(StackSize::from_element_count(DEFAULT_CALL_STACK_LIMIT)); - Self::invoke_configurable(func, args, externals, value_stack, call_stack) + let mut interpreter = Interpreter::new(value_stack, call_stack); + Self::invoke_configurable(func, args, externals, &mut interpreter) } /// Invoke the function, get a resumable handle. This handle can then be used to [`start_execution`]. If a diff --git a/src/lib.rs b/src/lib.rs index cad8752..c6b75dc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -405,6 +405,7 @@ pub use self::global::{GlobalInstance, GlobalRef}; pub use self::func::{FuncInstance, FuncRef, FuncInvocation, ResumableError}; pub use self::types::{Signature, ValueType, GlobalDescriptor, TableDescriptor, MemoryDescriptor}; pub use self::common::stack::{StackWithLimit, StackSize, StackSizeLimit, StackSizeInitial}; +pub use self::runner::Interpreter; /// WebAssembly-specific sizes and units. pub mod memory_units { diff --git a/src/runner.rs b/src/runner.rs index 57f0a89..c578821 100644 --- a/src/runner.rs +++ b/src/runner.rs @@ -172,6 +172,9 @@ pub struct Interpreter { } impl Interpreter { + /// Initialize an interpreter that will use `value_stack` and `call_stack`. + /// + /// `value_stack` `call_stack` determine the allowed stack size during later executions. pub fn new( value_stack: StackWithLimit, call_stack: StackWithLimit, @@ -183,11 +186,20 @@ impl Interpreter { } } - pub fn state(&self) -> &InterpreterState { + // Todo, use types to prevent user from calling start_execution on an inretpreter not in Initialized + // state. + /// Wipe all data in this interpreter, so it can be safely reused. + pub fn reset(&mut self) { + self.value_stack.truncate(0); + self.call_stack.truncate(0); + self.state = InterpreterState::Initialized; + } + + pub(crate) fn state(&self) -> &InterpreterState { &self.state } - pub fn start_execution( + pub(crate) fn start_execution( &mut self, externals: &mut E, func: &FuncRef, @@ -220,7 +232,7 @@ impl Interpreter { Ok(opt_return_value) } - pub fn resume_execution<'a, E: Externals + 'a>( + pub(crate) fn resume_execution<'a, E: Externals + 'a>( &mut self, return_val: Option, externals: &'a mut E, @@ -1321,6 +1333,15 @@ impl ValueStack { fn len(&self) -> usize { self.0.len() } + + /// Shortens the stack, keeping the first `len` elements and dropping + /// the rest. + /// + /// If `len` is greater than the stack's current length, this has no + /// effect. + fn truncate(&mut self, new_len: usize) { + self.0.truncate(new_len) + } } impl From for TrapKind {