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 isa;
|
||||||
use module::ModuleInstance;
|
use module::ModuleInstance;
|
||||||
use parity_wasm::elements::Local;
|
use parity_wasm::elements::Local;
|
||||||
use runner::{
|
use runner::{check_function_args, Interpreter, InterpreterState, DEFAULT_CALL_STACK_LIMIT, DEFAULT_VALUE_STACK_LIMIT};
|
||||||
check_function_args, FunctionContext, Interpreter, InterpreterState, RuntimeValueInternal,
|
|
||||||
DEFAULT_CALL_STACK_LIMIT, DEFAULT_VALUE_STACK_LIMIT,
|
|
||||||
};
|
|
||||||
use types::ValueType;
|
use types::ValueType;
|
||||||
use value::RuntimeValue;
|
use value::RuntimeValue;
|
||||||
use {Signature, Trap};
|
use {Signature, Trap};
|
||||||
|
@ -136,13 +133,11 @@ impl FuncInstance {
|
||||||
func: &FuncRef,
|
func: &FuncRef,
|
||||||
args: &[RuntimeValue],
|
args: &[RuntimeValue],
|
||||||
externals: &mut E,
|
externals: &mut E,
|
||||||
value_stack: StackWithLimit<RuntimeValueInternal>,
|
interpreter: &mut Interpreter,
|
||||||
call_stack: StackWithLimit<FunctionContext>,
|
|
||||||
) -> Result<Option<RuntimeValue>, Trap> {
|
) -> Result<Option<RuntimeValue>, Trap> {
|
||||||
check_function_args(func.signature(), &args)?;
|
check_function_args(func.signature(), &args)?;
|
||||||
match *func.as_internal() {
|
match *func.as_internal() {
|
||||||
FuncInstanceInternal::Internal { .. } => {
|
FuncInstanceInternal::Internal { .. } => {
|
||||||
let mut interpreter = Interpreter::new(value_stack, call_stack);
|
|
||||||
interpreter.start_execution(externals, func, args, func.signature().return_type())
|
interpreter.start_execution(externals, func, args, func.signature().return_type())
|
||||||
}
|
}
|
||||||
FuncInstanceInternal::Host {
|
FuncInstanceInternal::Host {
|
||||||
|
@ -167,7 +162,8 @@ impl FuncInstance {
|
||||||
) -> Result<Option<RuntimeValue>, Trap> {
|
) -> Result<Option<RuntimeValue>, Trap> {
|
||||||
let value_stack = StackWithLimit::with_size(StackSize::from_element_count(DEFAULT_VALUE_STACK_LIMIT));
|
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));
|
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
|
/// 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::func::{FuncInstance, FuncRef, FuncInvocation, ResumableError};
|
||||||
pub use self::types::{Signature, ValueType, GlobalDescriptor, TableDescriptor, MemoryDescriptor};
|
pub use self::types::{Signature, ValueType, GlobalDescriptor, TableDescriptor, MemoryDescriptor};
|
||||||
pub use self::common::stack::{StackWithLimit, StackSize, StackSizeLimit, StackSizeInitial};
|
pub use self::common::stack::{StackWithLimit, StackSize, StackSizeLimit, StackSizeInitial};
|
||||||
|
pub use self::runner::Interpreter;
|
||||||
|
|
||||||
/// WebAssembly-specific sizes and units.
|
/// WebAssembly-specific sizes and units.
|
||||||
pub mod memory_units {
|
pub mod memory_units {
|
||||||
|
|
|
@ -172,6 +172,9 @@ pub struct Interpreter {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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(
|
pub fn new(
|
||||||
value_stack: StackWithLimit<RuntimeValueInternal>,
|
value_stack: StackWithLimit<RuntimeValueInternal>,
|
||||||
call_stack: StackWithLimit<FunctionContext>,
|
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
|
&self.state
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start_execution<E: Externals>(
|
pub(crate) fn start_execution<E: Externals>(
|
||||||
&mut self,
|
&mut self,
|
||||||
externals: &mut E,
|
externals: &mut E,
|
||||||
func: &FuncRef,
|
func: &FuncRef,
|
||||||
|
@ -220,7 +232,7 @@ impl Interpreter {
|
||||||
Ok(opt_return_value)
|
Ok(opt_return_value)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resume_execution<'a, E: Externals + 'a>(
|
pub(crate) fn resume_execution<'a, E: Externals + 'a>(
|
||||||
&mut self,
|
&mut self,
|
||||||
return_val: Option<RuntimeValue>,
|
return_val: Option<RuntimeValue>,
|
||||||
externals: &'a mut E,
|
externals: &'a mut E,
|
||||||
|
@ -1321,6 +1333,15 @@ impl ValueStack {
|
||||||
fn len(&self) -> usize {
|
fn len(&self) -> usize {
|
||||||
self.0.len()
|
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 {
|
impl From<StackOverflow> for TrapKind {
|
||||||
|
|
Loading…
Reference in New Issue