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,
/// Stack of the input parameters
pub value_stack: &'a mut StackWithLimit<RuntimeValue>,
/// Execution-local external modules.
pub externals: &'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>,
}
/// Internal function ready for interpretation.
@ -458,7 +456,7 @@ impl ModuleInstanceInterface for ModuleInstance {
let ExecutionParams { args, externals } = params;
let mut args = StackWithLimit::with_data(args, DEFAULT_VALUE_STACK_LIMIT);
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)
}
@ -638,12 +636,11 @@ impl ModuleInstanceInterface for ModuleInstance {
impl<'a> CallerContext<'a> {
/// 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 {
value_stack_limit: DEFAULT_VALUE_STACK_LIMIT,
frame_stack_limit: DEFAULT_FRAME_STACK_LIMIT,
value_stack: args,
externals: externals,
}
}
@ -653,7 +650,6 @@ impl<'a> CallerContext<'a> {
value_stack_limit: outer.value_stack().limit() - outer.value_stack().len(),
frame_stack_limit: outer.frame_stack().limit() - outer.frame_stack().len(),
value_stack: &mut outer.value_stack,
externals: &outer.externals,
}
}
}

View File

@ -1,14 +1,13 @@
use std::mem;
use std::ops;
use std::{u32, usize};
use std::sync::Arc;
use std::fmt::{self, Display};
use std::iter::repeat;
use std::collections::{HashMap, VecDeque};
use elements::{Opcode, BlockType, Local};
use interpreter::Error;
use interpreter::store::{Store, FuncId, ModuleId, FuncInstance};
use interpreter::module::{ModuleInstanceInterface, CallerContext, FunctionSignature};
use interpreter::module::{CallerContext, FunctionSignature};
use interpreter::value::{
RuntimeValue, TryInto, WrapInto, TryTruncateInto, ExtendInto,
ArithmeticOps, Integer, Float, LittleEndianConvert, TransmuteInto,
@ -23,14 +22,12 @@ pub struct Interpreter<'store> {
}
/// Function execution context.
pub struct FunctionContext<'a> {
pub struct FunctionContext {
/// Is context initialized.
pub is_initialized: bool,
/// Internal function reference.
pub function: FuncId,
pub module: ModuleId,
/// Execution-local external modules.
pub externals: &'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>,
/// Function return type.
pub return_type: BlockType,
/// Local variables.
@ -59,11 +56,11 @@ pub enum InstructionOutcome {
}
/// Function run result.
enum RunResult<'a> {
enum RunResult {
/// Function has returned (optional) value.
Return(Option<RuntimeValue>),
/// Function is calling other function.
NestedCall(FunctionContext<'a>),
NestedCall(FunctionContext),
}
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 {
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 {
&Opcode::Unreachable => self.run_unreachable(context),
&Opcode::Nop => self.run_nop(context),
@ -367,17 +364,17 @@ impl<'store> Interpreter<'store> {
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)?;
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)?;
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 block_frame_type = if branch { BlockFrameType::IfTrue } else {
let else_pos = labels[&context.position];
@ -425,12 +422,12 @@ impl<'store> Interpreter<'store> {
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);
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 = context.module().resolve_table(self.store, DEFAULT_TABLE_INDEX).resolve(self.store);
let func_ref = table.get(table_func_idx)?;
@ -982,8 +979,8 @@ impl<'store> Interpreter<'store> {
}
}
impl<'a> FunctionContext<'a> {
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 {
impl<'a> FunctionContext {
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 module = match *func_instance {
FuncInstance::Defined { module, .. } => module,
@ -993,7 +990,6 @@ impl<'a> FunctionContext<'a> {
is_initialized: false,
function: function,
module: module,
externals: externals,
return_type: function_type.return_type().map(|vt| BlockType::Value(vt)).unwrap_or(BlockType::NoResult),
value_stack: StackWithLimit::with_limit(value_stack_limit),
frame_stack: StackWithLimit::with_limit(frame_stack_limit),
@ -1021,7 +1017,6 @@ impl<'a> FunctionContext<'a> {
is_initialized: false,
function: function,
module: module,
externals: self.externals,
return_type: function_return_type,
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()),
@ -1050,10 +1045,6 @@ impl<'a> FunctionContext<'a> {
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> {
self.locals.get_mut(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 {
write!(f, "FunctionContext")
}

View File

@ -442,11 +442,11 @@ impl Store {
fn invoke(&mut self, func: FuncId, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error> {
let ExecutionParams { args, externals } = params;
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_signature = FunctionSignature::Module(func_type);
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);
interpreter.run_function(inner)
}