mirror of
https://github.com/fluencelabs/parity-wasm
synced 2025-06-19 01:41:45 +00:00
Pass state in ExecutionParams
This commit is contained in:
@ -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(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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(&[]) {
|
||||||
|
@ -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)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -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!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user