make interpreter reusable
This commit is contained in:
parent
9dd258c2bb
commit
2f7f809fd6
12
src/func.rs
12
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<RuntimeValueInternal>,
|
||||
call_stack: StackWithLimit<FunctionContext>,
|
||||
interpreter: &mut Interpreter,
|
||||
) -> Result<Option<RuntimeValue>, 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<Option<RuntimeValue>, 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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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<RuntimeValueInternal>,
|
||||
call_stack: StackWithLimit<FunctionContext>,
|
||||
|
@ -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<E: Externals>(
|
||||
pub(crate) fn start_execution<E: Externals>(
|
||||
&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<RuntimeValue>,
|
||||
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<StackOverflow> for TrapKind {
|
||||
|
|
Loading…
Reference in New Issue