Clean externals

This commit is contained in:
Sergey Pepyakin
2017-12-11 15:01:38 +01:00
parent 929d62b286
commit 339b909f86
3 changed files with 18 additions and 31 deletions

View File

@ -117,8 +117,6 @@ pub struct CallerContext<'a> {
pub frame_stack_limit: usize, pub frame_stack_limit: usize,
/// Stack of the input parameters /// Stack of the input parameters
pub value_stack: &'a mut StackWithLimit<RuntimeValue>, pub value_stack: &'a mut StackWithLimit<RuntimeValue>,
/// Execution-local external modules.
pub externals: &'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>,
} }
/// Internal function ready for interpretation. /// Internal function ready for interpretation.
@ -458,7 +456,7 @@ impl ModuleInstanceInterface for ModuleInstance {
let ExecutionParams { args, externals } = params; let ExecutionParams { args, externals } = params;
let mut args = StackWithLimit::with_data(args, DEFAULT_VALUE_STACK_LIMIT); let mut args = StackWithLimit::with_data(args, DEFAULT_VALUE_STACK_LIMIT);
let function_reference = self.function_reference(ItemIndex::IndexSpace(index), Some(&externals))?; let function_reference = self.function_reference(ItemIndex::IndexSpace(index), Some(&externals))?;
let function_context = CallerContext::topmost(&mut args, &externals); let function_context = CallerContext::topmost(&mut args);
function_reference.module.call_internal_function(function_context, function_reference.internal_index) function_reference.module.call_internal_function(function_context, function_reference.internal_index)
} }
@ -638,12 +636,11 @@ impl ModuleInstanceInterface for ModuleInstance {
impl<'a> CallerContext<'a> { impl<'a> CallerContext<'a> {
/// Top most args /// Top most args
pub fn topmost(args: &'a mut StackWithLimit<RuntimeValue>, externals: &'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>) -> Self { pub fn topmost(args: &'a mut StackWithLimit<RuntimeValue>) -> Self {
CallerContext { CallerContext {
value_stack_limit: DEFAULT_VALUE_STACK_LIMIT, value_stack_limit: DEFAULT_VALUE_STACK_LIMIT,
frame_stack_limit: DEFAULT_FRAME_STACK_LIMIT, frame_stack_limit: DEFAULT_FRAME_STACK_LIMIT,
value_stack: args, value_stack: args,
externals: externals,
} }
} }
@ -653,7 +650,6 @@ impl<'a> CallerContext<'a> {
value_stack_limit: outer.value_stack().limit() - outer.value_stack().len(), value_stack_limit: outer.value_stack().limit() - outer.value_stack().len(),
frame_stack_limit: outer.frame_stack().limit() - outer.frame_stack().len(), frame_stack_limit: outer.frame_stack().limit() - outer.frame_stack().len(),
value_stack: &mut outer.value_stack, value_stack: &mut outer.value_stack,
externals: &outer.externals,
} }
} }
} }

View File

@ -1,14 +1,13 @@
use std::mem; use std::mem;
use std::ops; use std::ops;
use std::{u32, usize}; use std::{u32, usize};
use std::sync::Arc;
use std::fmt::{self, Display}; use std::fmt::{self, Display};
use std::iter::repeat; use std::iter::repeat;
use std::collections::{HashMap, VecDeque}; use std::collections::{HashMap, VecDeque};
use elements::{Opcode, BlockType, Local}; use elements::{Opcode, BlockType, Local};
use interpreter::Error; use interpreter::Error;
use interpreter::store::{Store, FuncId, ModuleId, FuncInstance}; use interpreter::store::{Store, FuncId, ModuleId, FuncInstance};
use interpreter::module::{ModuleInstanceInterface, CallerContext, FunctionSignature}; use interpreter::module::{CallerContext, FunctionSignature};
use interpreter::value::{ use interpreter::value::{
RuntimeValue, TryInto, WrapInto, TryTruncateInto, ExtendInto, RuntimeValue, TryInto, WrapInto, TryTruncateInto, ExtendInto,
ArithmeticOps, Integer, Float, LittleEndianConvert, TransmuteInto, ArithmeticOps, Integer, Float, LittleEndianConvert, TransmuteInto,
@ -23,14 +22,12 @@ pub struct Interpreter<'store> {
} }
/// Function execution context. /// Function execution context.
pub struct FunctionContext<'a> { pub struct FunctionContext {
/// Is context initialized. /// Is context initialized.
pub is_initialized: bool, pub is_initialized: bool,
/// Internal function reference. /// Internal function reference.
pub function: FuncId, pub function: FuncId,
pub module: ModuleId, pub module: ModuleId,
/// Execution-local external modules.
pub externals: &'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>,
/// Function return type. /// Function return type.
pub return_type: BlockType, pub return_type: BlockType,
/// Local variables. /// Local variables.
@ -59,11 +56,11 @@ pub enum InstructionOutcome {
} }
/// Function run result. /// Function run result.
enum RunResult<'a> { enum RunResult {
/// Function has returned (optional) value. /// Function has returned (optional) value.
Return(Option<RuntimeValue>), Return(Option<RuntimeValue>),
/// Function is calling other function. /// Function is calling other function.
NestedCall(FunctionContext<'a>), NestedCall(FunctionContext),
} }
impl<'store> Interpreter<'store> { impl<'store> Interpreter<'store> {
@ -127,7 +124,7 @@ impl<'store> Interpreter<'store> {
} }
} }
fn do_run_function<'a>(&mut self, function_context: &mut FunctionContext<'a>, function_body: &[Opcode], function_labels: &HashMap<usize, usize>) -> Result<RunResult<'a>, Error> { fn do_run_function<'a>(&mut self, function_context: &mut FunctionContext, function_body: &[Opcode], function_labels: &HashMap<usize, usize>) -> Result<RunResult, Error> {
loop { loop {
let instruction = &function_body[function_context.position]; let instruction = &function_body[function_context.position];
@ -165,7 +162,7 @@ impl<'store> Interpreter<'store> {
})) }))
} }
fn run_instruction<'a>(&mut self, context: &mut FunctionContext<'a>, labels: &HashMap<usize, usize>, opcode: &Opcode) -> Result<InstructionOutcome, Error> { fn run_instruction<'a>(&mut self, context: &mut FunctionContext, labels: &HashMap<usize, usize>, opcode: &Opcode) -> Result<InstructionOutcome, Error> {
match opcode { match opcode {
&Opcode::Unreachable => self.run_unreachable(context), &Opcode::Unreachable => self.run_unreachable(context),
&Opcode::Nop => self.run_nop(context), &Opcode::Nop => self.run_nop(context),
@ -367,17 +364,17 @@ impl<'store> Interpreter<'store> {
Ok(InstructionOutcome::RunNextInstruction) Ok(InstructionOutcome::RunNextInstruction)
} }
fn run_block<'a>(&mut self, context: &mut FunctionContext<'a>, labels: &HashMap<usize, usize>, block_type: BlockType) -> Result<InstructionOutcome, Error> { fn run_block<'a>(&mut self, context: &mut FunctionContext, labels: &HashMap<usize, usize>, block_type: BlockType) -> Result<InstructionOutcome, Error> {
context.push_frame(labels, BlockFrameType::Block, block_type)?; context.push_frame(labels, BlockFrameType::Block, block_type)?;
Ok(InstructionOutcome::RunNextInstruction) Ok(InstructionOutcome::RunNextInstruction)
} }
fn run_loop<'a>(&mut self, context: &mut FunctionContext<'a>, labels: &HashMap<usize, usize>, block_type: BlockType) -> Result<InstructionOutcome, Error> { fn run_loop<'a>(&mut self, context: &mut FunctionContext, labels: &HashMap<usize, usize>, block_type: BlockType) -> Result<InstructionOutcome, Error> {
context.push_frame(labels, BlockFrameType::Loop, block_type)?; context.push_frame(labels, BlockFrameType::Loop, block_type)?;
Ok(InstructionOutcome::RunNextInstruction) Ok(InstructionOutcome::RunNextInstruction)
} }
fn run_if<'a>(&mut self, context: &mut FunctionContext<'a>, labels: &HashMap<usize, usize>, block_type: BlockType) -> Result<InstructionOutcome, Error> { fn run_if<'a>(&mut self, context: &mut FunctionContext, labels: &HashMap<usize, usize>, block_type: BlockType) -> Result<InstructionOutcome, Error> {
let branch = context.value_stack_mut().pop_as()?; let branch = context.value_stack_mut().pop_as()?;
let block_frame_type = if branch { BlockFrameType::IfTrue } else { let block_frame_type = if branch { BlockFrameType::IfTrue } else {
let else_pos = labels[&context.position]; let else_pos = labels[&context.position];
@ -425,12 +422,12 @@ impl<'store> Interpreter<'store> {
Ok(InstructionOutcome::Return) Ok(InstructionOutcome::Return)
} }
fn run_call<'a>(&mut self, context: &mut FunctionContext<'a>, func_idx: u32) -> Result<InstructionOutcome, Error> { fn run_call<'a>(&mut self, context: &mut FunctionContext, func_idx: u32) -> Result<InstructionOutcome, Error> {
let func = context.module().resolve_func(self.store, func_idx); let func = context.module().resolve_func(self.store, func_idx);
Ok(InstructionOutcome::ExecuteCall(func)) Ok(InstructionOutcome::ExecuteCall(func))
} }
fn run_call_indirect<'a>(&mut self, context: &mut FunctionContext<'a>, type_idx: u32) -> Result<InstructionOutcome, Error> { fn run_call_indirect<'a>(&mut self, context: &mut FunctionContext, type_idx: u32) -> Result<InstructionOutcome, Error> {
let table_func_idx: u32 = context.value_stack_mut().pop_as()?; let table_func_idx: u32 = context.value_stack_mut().pop_as()?;
let table = context.module().resolve_table(self.store, DEFAULT_TABLE_INDEX).resolve(self.store); let table = context.module().resolve_table(self.store, DEFAULT_TABLE_INDEX).resolve(self.store);
let func_ref = table.get(table_func_idx)?; let func_ref = table.get(table_func_idx)?;
@ -982,8 +979,8 @@ impl<'store> Interpreter<'store> {
} }
} }
impl<'a> FunctionContext<'a> { impl<'a> FunctionContext {
pub fn new(store: &Store, function: FuncId, externals: &'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>, value_stack_limit: usize, frame_stack_limit: usize, function_type: &FunctionSignature, args: Vec<VariableInstance>) -> Self { pub fn new(store: &Store, function: FuncId, value_stack_limit: usize, frame_stack_limit: usize, function_type: &FunctionSignature, args: Vec<VariableInstance>) -> Self {
let func_instance = function.resolve(store); let func_instance = function.resolve(store);
let module = match *func_instance { let module = match *func_instance {
FuncInstance::Defined { module, .. } => module, FuncInstance::Defined { module, .. } => module,
@ -993,7 +990,6 @@ impl<'a> FunctionContext<'a> {
is_initialized: false, is_initialized: false,
function: function, function: function,
module: module, module: module,
externals: externals,
return_type: function_type.return_type().map(|vt| BlockType::Value(vt)).unwrap_or(BlockType::NoResult), return_type: function_type.return_type().map(|vt| BlockType::Value(vt)).unwrap_or(BlockType::NoResult),
value_stack: StackWithLimit::with_limit(value_stack_limit), value_stack: StackWithLimit::with_limit(value_stack_limit),
frame_stack: StackWithLimit::with_limit(frame_stack_limit), frame_stack: StackWithLimit::with_limit(frame_stack_limit),
@ -1021,7 +1017,6 @@ impl<'a> FunctionContext<'a> {
is_initialized: false, is_initialized: false,
function: function, function: function,
module: module, module: module,
externals: self.externals,
return_type: function_return_type, return_type: function_return_type,
value_stack: StackWithLimit::with_limit(self.value_stack.limit() - self.value_stack.len()), value_stack: StackWithLimit::with_limit(self.value_stack.limit() - self.value_stack.len()),
frame_stack: StackWithLimit::with_limit(self.frame_stack.limit() - self.frame_stack.len()), frame_stack: StackWithLimit::with_limit(self.frame_stack.limit() - self.frame_stack.len()),
@ -1050,10 +1045,6 @@ impl<'a> FunctionContext<'a> {
self.module self.module
} }
pub fn externals(&self) -> &HashMap<String, Arc<ModuleInstanceInterface + 'a>> {
&self.externals
}
pub fn set_local(&mut self, index: usize, value: RuntimeValue) -> Result<InstructionOutcome, Error> { pub fn set_local(&mut self, index: usize, value: RuntimeValue) -> Result<InstructionOutcome, Error> {
self.locals.get_mut(index) self.locals.get_mut(index)
.ok_or(Error::Local(format!("expected to have local with index {}", index))) .ok_or(Error::Local(format!("expected to have local with index {}", index)))
@ -1135,7 +1126,7 @@ impl<'a> FunctionContext<'a> {
} }
} }
impl<'a> fmt::Debug for FunctionContext<'a> { impl<'a> fmt::Debug for FunctionContext {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "FunctionContext") write!(f, "FunctionContext")
} }

View File

@ -442,11 +442,11 @@ impl Store {
fn invoke(&mut self, func: FuncId, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error> { fn invoke(&mut self, func: FuncId, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error> {
let ExecutionParams { args, externals } = params; let ExecutionParams { args, externals } = 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, &externals); let outer = CallerContext::topmost(&mut args);
let func_type = func.resolve(self).func_type().resolve(self); let func_type = func.resolve(self).func_type().resolve(self);
let func_signature = FunctionSignature::Module(func_type); let func_signature = FunctionSignature::Module(func_type);
let args = prepare_function_args(&func_signature, outer.value_stack)?; let args = prepare_function_args(&func_signature, outer.value_stack)?;
let inner = FunctionContext::new(self, func, outer.externals, outer.value_stack_limit, outer.frame_stack_limit, &func_signature, args); let inner = FunctionContext::new(self, func, outer.value_stack_limit, outer.frame_stack_limit, &func_signature, args);
let interpreter = Interpreter::new(self); let interpreter = Interpreter::new(self);
interpreter.run_function(inner) interpreter.run_function(inner)
} }