mirror of
https://github.com/fluencelabs/parity-wasm
synced 2025-06-23 03:31:56 +00:00
Clean externals
This commit is contained in:
@ -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,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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")
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user