Pass state in ExecutionParams

This commit is contained in:
Sergey Pepyakin
2017-12-11 16:38:52 +01:00
parent 5920cd93d5
commit 8588899f82
4 changed files with 29 additions and 19 deletions

View File

@ -20,9 +20,12 @@ const DEFAULT_FRAME_STACK_LIMIT: usize = 1024;
/// Execution context. /// Execution context.
#[derive(Clone)] #[derive(Clone)]
pub struct ExecutionParams { pub struct ExecutionParams<St: 'static> {
/// Arguments. /// Arguments.
pub args: Vec<RuntimeValue>, pub args: Vec<RuntimeValue>,
/// State that can be used by host functions,
pub state: St,
} }
/// Export type. /// Export type.
@ -76,7 +79,7 @@ pub struct InternalFunction<'a> {
pub labels: &'a HashMap<usize, usize>, pub labels: &'a HashMap<usize, usize>,
} }
impl ExecutionParams { impl<St> ExecutionParams<St> {
/// Add argument. /// Add argument.
pub fn add_argument(mut self, arg: RuntimeValue) -> Self { pub fn add_argument(mut self, arg: RuntimeValue) -> Self {
self.args.push(arg); self.args.push(arg);
@ -84,18 +87,20 @@ impl ExecutionParams {
} }
} }
impl Default for ExecutionParams { impl<St: Default> Default for ExecutionParams<St> {
fn default() -> Self { fn default() -> Self {
ExecutionParams { ExecutionParams {
args: Vec::default(), args: Vec::default(),
state: St::default(),
} }
} }
} }
impl<'a> From<Vec<RuntimeValue>> for ExecutionParams { impl<'a, St: Default> From<Vec<RuntimeValue>> for ExecutionParams<St> {
fn from(args: Vec<RuntimeValue>) -> ExecutionParams { fn from(args: Vec<RuntimeValue>) -> ExecutionParams<St> {
ExecutionParams { ExecutionParams {
args: args args: args,
state: St::default(),
} }
} }
} }

View File

@ -22,11 +22,11 @@ impl ProgramInstance {
} }
/// Instantiate module with validation. /// Instantiate module with validation.
pub fn add_module<'a>( pub fn add_module<'a, St: 'static>(
&mut self, &mut self,
name: &str, name: &str,
module: Module, module: Module,
start_exec_params: ExecutionParams, start_exec_params: ExecutionParams<St>,
) -> Result<ModuleId, Error> { ) -> Result<ModuleId, Error> {
let mut extern_vals = Vec::new(); let mut extern_vals = Vec::new();
for import_entry in module.import_section().map(|s| s.entries()).unwrap_or(&[]) { for import_entry in module.import_section().map(|s| s.entries()).unwrap_or(&[]) {

View File

@ -18,8 +18,9 @@ use common::{DEFAULT_MEMORY_INDEX, DEFAULT_TABLE_INDEX, BlockFrame, BlockFrameTy
use common::stack::StackWithLimit; use common::stack::StackWithLimit;
/// Function interpreter. /// Function interpreter.
pub struct Interpreter<'store> { pub struct Interpreter<'store, St: 'static> {
store: &'store mut Store, store: &'store mut Store,
state: &'store mut St,
} }
/// Function execution context. /// Function execution context.
@ -64,10 +65,11 @@ enum RunResult {
NestedCall(FunctionContext), NestedCall(FunctionContext),
} }
impl<'store> Interpreter<'store> { impl<'store, St: 'static> Interpreter<'store, St> {
pub fn new(store: &mut Store) -> Interpreter { pub fn new(store: &'store mut Store, state: &'store mut St) -> Interpreter<'store, St> {
Interpreter { Interpreter {
store store,
state
} }
} }
@ -95,7 +97,7 @@ impl<'store> Interpreter<'store> {
}, },
FuncInstance::Host { host_func, .. } => { FuncInstance::Host { host_func, .. } => {
let args: Vec<_> = function_context.locals.drain(..).collect(); let args: Vec<_> = function_context.locals.drain(..).collect();
let result = self.store.invoke_host(host_func, args)?; let result = self.store.invoke_host(self.state, host_func, args)?;
RunResult::Return(result) RunResult::Return(result)
}, },
} }

View File

@ -2,6 +2,7 @@
#![allow(unused)] #![allow(unused)]
use std::sync::Arc; use std::sync::Arc;
use std::any::Any;
use std::collections::HashMap; use std::collections::HashMap;
use elements::{FunctionType, GlobalEntry, GlobalType, InitExpr, MemoryType, Module, use elements::{FunctionType, GlobalEntry, GlobalType, InitExpr, MemoryType, Module,
Opcode, Opcodes, Local, TableType, Type, Internal}; Opcode, Opcodes, Local, TableType, Type, Internal};
@ -371,11 +372,11 @@ impl Store {
Ok(()) Ok(())
} }
pub fn instantiate_module( pub fn instantiate_module<St: 'static>(
&mut self, &mut self,
module: &Module, module: &Module,
extern_vals: &[ExternVal], extern_vals: &[ExternVal],
start_exec_params: ExecutionParams, start_exec_params: ExecutionParams<St>,
) -> Result<ModuleId, Error> { ) -> Result<ModuleId, Error> {
let mut instance = ModuleInstance::new(); let mut instance = ModuleInstance::new();
// Reserve the index of the module, but not yet push the module. // Reserve the index of the module, but not yet push the module.
@ -447,8 +448,8 @@ impl Store {
Ok(module_id) Ok(module_id)
} }
fn invoke(&mut self, func: FuncId, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error> { fn invoke<St>(&mut self, func: FuncId, params: ExecutionParams<St>) -> Result<Option<RuntimeValue>, Error> {
let ExecutionParams { args } = params; let ExecutionParams { args, mut state } = params;
let mut args = StackWithLimit::with_data(args, DEFAULT_VALUE_STACK_LIMIT); let mut args = StackWithLimit::with_data(args, DEFAULT_VALUE_STACK_LIMIT);
let outer = CallerContext::topmost(&mut args); let outer = CallerContext::topmost(&mut args);
let inner = { let inner = {
@ -457,11 +458,13 @@ impl Store {
let args = prepare_function_args(&func_signature, outer.value_stack)?; let args = prepare_function_args(&func_signature, outer.value_stack)?;
FunctionContext::new(self, func, outer.value_stack_limit, outer.frame_stack_limit, &func_signature, args) FunctionContext::new(self, func, outer.value_stack_limit, outer.frame_stack_limit, &func_signature, args)
}; };
let mut interpreter = Interpreter::new(self); let mut interpreter = Interpreter::new(self, &mut state);
interpreter.run_function(inner) interpreter.run_function(inner)
} }
pub fn invoke_host(&mut self, host_func: HostFuncId, args: Vec<RuntimeValue>) -> Result<Option<RuntimeValue>, Error> { pub fn invoke_host<St: 'static>(&mut self, state: &mut St, host_func: HostFuncId, args: Vec<RuntimeValue>) -> Result<Option<RuntimeValue>, Error> {
let host_func_instance = self.host_funcs.get(host_func.0 as usize).expect("ID should be always valid");
host_func_instance.call_as_any(state as &mut Any, &args);
panic!() panic!()
} }