mirror of
https://github.com/fluencelabs/parity-wasm
synced 2025-06-24 12:12:05 +00:00
cleanup
This commit is contained in:
@ -108,14 +108,6 @@ impl ModuleInstanceInterface for EnvModuleInstance {
|
|||||||
self.instance.export_entry(name, externals, required_type)
|
self.instance.export_entry(name, externals, required_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn function_type<'a>(&self, function_index: ItemIndex, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>) -> Result<FunctionType, Error> {
|
|
||||||
self.instance.function_type(function_index, externals)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn function_type_by_index<'a>(&self, type_index: u32) -> Result<FunctionType, Error> {
|
|
||||||
self.instance.function_type_by_index(type_index)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn table(&self, index: ItemIndex) -> Result<Arc<TableInstance>, Error> {
|
fn table(&self, index: ItemIndex) -> Result<Arc<TableInstance>, Error> {
|
||||||
self.instance.table(index)
|
self.instance.table(index)
|
||||||
}
|
}
|
||||||
@ -128,6 +120,14 @@ impl ModuleInstanceInterface for EnvModuleInstance {
|
|||||||
self.instance.global(index, variable_type)
|
self.instance.global(index, variable_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn function_type<'a>(&self, function_index: ItemIndex, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>) -> Result<FunctionType, Error> {
|
||||||
|
self.instance.function_type(function_index, externals)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn function_type_by_index<'a>(&self, type_index: u32) -> Result<FunctionType, Error> {
|
||||||
|
self.instance.function_type_by_index(type_index)
|
||||||
|
}
|
||||||
|
|
||||||
fn function_reference<'a>(&self, index: ItemIndex, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>) -> Result<InternalFunctionReference<'a>, Error> {
|
fn function_reference<'a>(&self, index: ItemIndex, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>) -> Result<InternalFunctionReference<'a>, Error> {
|
||||||
self.instance.function_reference(index, externals)
|
self.instance.function_reference(index, externals)
|
||||||
}
|
}
|
||||||
@ -136,21 +136,11 @@ impl ModuleInstanceInterface for EnvModuleInstance {
|
|||||||
self.instance.function_reference_indirect(table_idx, type_idx, func_idx, externals)
|
self.instance.function_reference_indirect(table_idx, type_idx, func_idx, externals)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn function_body<'a>(&'a self, internal_index: u32, function_type: Option<&FunctionType>) -> Result<Option<InternalFunction<'a>>, Error> {
|
fn function_body<'a>(&'a self, _internal_index: u32) -> Result<Option<InternalFunction<'a>>, Error> {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
//self.instance.function_body(internal_index, function_type)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*fn call_function(&self, outer: CallerContext, index: ItemIndex, function_type: Option<&FunctionType>) -> Result<Option<RuntimeValue>, Error> {
|
fn call_internal_function(&self, outer: CallerContext, index: u32) -> Result<Option<RuntimeValue>, Error> {
|
||||||
self.instance.call_function(outer, index, function_type)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn call_function_indirect(&self, outer: CallerContext, table_index: ItemIndex, type_index: u32, func_index: u32) -> Result<Option<RuntimeValue>, Error> {
|
|
||||||
self.instance.call_function_indirect(outer, table_index, type_index, func_index)
|
|
||||||
}*/
|
|
||||||
|
|
||||||
fn call_internal_function(&self, outer: CallerContext, index: u32, _function_type: Option<&FunctionType>) -> Result<Option<RuntimeValue>, Error> {
|
|
||||||
// TODO: check function type
|
|
||||||
// to make interpreter independent of *SCRIPTEN runtime, just make abort/assert = interpreter Error
|
// to make interpreter independent of *SCRIPTEN runtime, just make abort/assert = interpreter Error
|
||||||
match index {
|
match index {
|
||||||
INDEX_FUNC_ABORT => self.global(ItemIndex::IndexSpace(INDEX_GLOBAL_ABORT), Some(VariableType::I32))
|
INDEX_FUNC_ABORT => self.global(ItemIndex::IndexSpace(INDEX_GLOBAL_ABORT), Some(VariableType::I32))
|
||||||
|
@ -85,12 +85,24 @@ impl<'a> ModuleInstanceInterface for NativeModuleInstance<'a> {
|
|||||||
self.env.export_entry(name, externals, required_type)
|
self.env.export_entry(name, externals, required_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn table(&self, index: ItemIndex) -> Result<Arc<TableInstance>, Error> {
|
||||||
|
self.env.table(index)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn memory(&self, index: ItemIndex) -> Result<Arc<MemoryInstance>, Error> {
|
||||||
|
self.env.memory(index)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn global(&self, index: ItemIndex, variable_type: Option<VariableType>) -> Result<Arc<VariableInstance>, Error> {
|
||||||
|
self.env.global(index, variable_type)
|
||||||
|
}
|
||||||
|
|
||||||
fn function_type<'b>(&self, function_index: ItemIndex, externals: Option<&'b HashMap<String, Arc<ModuleInstanceInterface + 'b>>>) -> Result<FunctionType, Error> {
|
fn function_type<'b>(&self, function_index: ItemIndex, externals: Option<&'b HashMap<String, Arc<ModuleInstanceInterface + 'b>>>) -> Result<FunctionType, Error> {
|
||||||
let index = match function_index {
|
let index = match function_index {
|
||||||
ItemIndex::IndexSpace(index) | ItemIndex::Internal(index) => index,
|
ItemIndex::IndexSpace(index) | ItemIndex::Internal(index) => index,
|
||||||
ItemIndex::External(_) => unreachable!("trying to call function, exported by native env module"),
|
ItemIndex::External(_) => unreachable!("trying to call function, exported by native env module"),
|
||||||
};
|
};
|
||||||
println!("=== env_native.function_type({})", index);
|
|
||||||
if index < NATIVE_INDEX_FUNC_MIN {
|
if index < NATIVE_INDEX_FUNC_MIN {
|
||||||
return self.env.function_type(function_index, externals);
|
return self.env.function_type(function_index, externals);
|
||||||
}
|
}
|
||||||
@ -105,18 +117,6 @@ println!("=== env_native.function_type({})", index);
|
|||||||
self.function_type(ItemIndex::Internal(type_index), None)
|
self.function_type(ItemIndex::Internal(type_index), None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn table(&self, index: ItemIndex) -> Result<Arc<TableInstance>, Error> {
|
|
||||||
self.env.table(index)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn memory(&self, index: ItemIndex) -> Result<Arc<MemoryInstance>, Error> {
|
|
||||||
self.env.memory(index)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn global(&self, index: ItemIndex, variable_type: Option<VariableType>) -> Result<Arc<VariableInstance>, Error> {
|
|
||||||
self.env.global(index, variable_type)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn function_reference<'b>(&self, index: ItemIndex, externals: Option<&'b HashMap<String, Arc<ModuleInstanceInterface + 'b>>>) -> Result<InternalFunctionReference<'b>, Error> {
|
fn function_reference<'b>(&self, index: ItemIndex, externals: Option<&'b HashMap<String, Arc<ModuleInstanceInterface + 'b>>>) -> Result<InternalFunctionReference<'b>, Error> {
|
||||||
self.env.function_reference(index, externals)
|
self.env.function_reference(index, externals)
|
||||||
}
|
}
|
||||||
@ -125,17 +125,15 @@ println!("=== env_native.function_type({})", index);
|
|||||||
self.env.function_reference_indirect(table_idx, type_idx, func_idx, externals)
|
self.env.function_reference_indirect(table_idx, type_idx, func_idx, externals)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn function_body<'b>(&'b self, internal_index: u32, function_type: Option<&FunctionType>) -> Result<Option<InternalFunction<'b>>, Error> {
|
fn function_body<'b>(&'b self, _internal_index: u32) -> Result<Option<InternalFunction<'b>>, Error> {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
//self.env.function_body(internal_index, function_type)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call_internal_function(&self, outer: CallerContext, index: u32, function_type: Option<&FunctionType>) -> Result<Option<RuntimeValue>, Error> {
|
fn call_internal_function(&self, outer: CallerContext, index: u32) -> Result<Option<RuntimeValue>, Error> {
|
||||||
if index < NATIVE_INDEX_FUNC_MIN {
|
if index < NATIVE_INDEX_FUNC_MIN {
|
||||||
return self.env.call_internal_function(outer, index, function_type);
|
return self.env.call_internal_function(outer, index);
|
||||||
}
|
}
|
||||||
println!("=== env_native.args({:?})", outer.value_stack);
|
|
||||||
// TODO: check type
|
|
||||||
self.functions
|
self.functions
|
||||||
.get((index - NATIVE_INDEX_FUNC_MIN) as usize)
|
.get((index - NATIVE_INDEX_FUNC_MIN) as usize)
|
||||||
.ok_or(Error::Native(format!("trying to call native function with index {}", index)))
|
.ok_or(Error::Native(format!("trying to call native function with index {}", index)))
|
||||||
|
@ -49,28 +49,24 @@ pub trait ModuleInstanceInterface {
|
|||||||
fn execute_export(&self, name: &str, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error>;
|
fn execute_export(&self, name: &str, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error>;
|
||||||
/// Get export entry.
|
/// Get export entry.
|
||||||
fn export_entry<'a>(&self, name: &str, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>, required_type: &ExportEntryType) -> Result<Internal, Error>;
|
fn export_entry<'a>(&self, name: &str, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>, required_type: &ExportEntryType) -> Result<Internal, Error>;
|
||||||
/// Get function type for given function index.
|
|
||||||
fn function_type<'a>(&self, function_index: ItemIndex, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>) -> Result<FunctionType, Error>;
|
|
||||||
/// Get function type for given function index.
|
|
||||||
fn function_type_by_index<'a>(&self, type_index: u32) -> Result<FunctionType, Error>;
|
|
||||||
/// Get table reference.
|
/// Get table reference.
|
||||||
fn table(&self, index: ItemIndex) -> Result<Arc<TableInstance>, Error>;
|
fn table(&self, index: ItemIndex) -> Result<Arc<TableInstance>, Error>;
|
||||||
/// Get memory reference.
|
/// Get memory reference.
|
||||||
fn memory(&self, index: ItemIndex) -> Result<Arc<MemoryInstance>, Error>;
|
fn memory(&self, index: ItemIndex) -> Result<Arc<MemoryInstance>, Error>;
|
||||||
/// Get global reference.
|
/// Get global reference.
|
||||||
fn global(&self, index: ItemIndex, variable_type: Option<VariableType>) -> Result<Arc<VariableInstance>, Error>;
|
fn global(&self, index: ItemIndex, variable_type: Option<VariableType>) -> Result<Arc<VariableInstance>, Error>;
|
||||||
|
/// Get function type for given function index.
|
||||||
|
fn function_type<'a>(&self, function_index: ItemIndex, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>) -> Result<FunctionType, Error>;
|
||||||
|
/// Get function type for given function index.
|
||||||
|
fn function_type_by_index<'a>(&self, type_index: u32) -> Result<FunctionType, Error>;
|
||||||
/// Get function reference.
|
/// Get function reference.
|
||||||
fn function_reference<'a>(&self, index: ItemIndex, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>) -> Result<InternalFunctionReference<'a>, Error>;
|
fn function_reference<'a>(&self, index: ItemIndex, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>) -> Result<InternalFunctionReference<'a>, Error>;
|
||||||
/// Get function indirect reference.
|
/// Get function indirect reference.
|
||||||
fn function_reference_indirect<'a>(&self, table_idx: u32, type_idx: u32, func_idx: u32, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>) -> Result<InternalFunctionReference<'a>, Error>;
|
fn function_reference_indirect<'a>(&self, table_idx: u32, type_idx: u32, func_idx: u32, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>) -> Result<InternalFunctionReference<'a>, Error>;
|
||||||
/// Get internal function for interpretation.
|
/// Get internal function for interpretation.
|
||||||
fn function_body<'a>(&'a self, internal_index: u32, function_type: Option<&FunctionType>) -> Result<Option<InternalFunction<'a>>, Error>;
|
fn function_body<'a>(&'a self, internal_index: u32) -> Result<Option<InternalFunction<'a>>, Error>;
|
||||||
/// Call function with given index in functions index space.
|
/// Call function with given internal index.
|
||||||
//fn call_function<'a>(&self, outer: CallerContext, index: ItemIndex, function_type: Option<&FunctionType>) -> Result<Option<RuntimeValue>, Error>;
|
fn call_internal_function<'a>(&self, outer: CallerContext, index: u32) -> Result<Option<RuntimeValue>, Error>;
|
||||||
/// Call function with given index in the given table.
|
|
||||||
//fn call_function_indirect<'a>(&self, outer: CallerContext, table_index: ItemIndex, type_index: u32, func_index: u32) -> Result<Option<RuntimeValue>, Error>;
|
|
||||||
/// Call function with internal index.
|
|
||||||
fn call_internal_function<'a>(&self, outer: CallerContext, index: u32, function_type: Option<&FunctionType>) -> Result<Option<RuntimeValue>, Error>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Item index in items index space.
|
/// Item index in items index space.
|
||||||
@ -129,8 +125,6 @@ impl<'a> fmt::Debug for InternalFunctionReference<'a> {
|
|||||||
|
|
||||||
/// Internal function ready for interpretation.
|
/// Internal function ready for interpretation.
|
||||||
pub struct InternalFunction<'a> {
|
pub struct InternalFunction<'a> {
|
||||||
/// Function type.
|
|
||||||
pub func_type: &'a FunctionType,
|
|
||||||
/// Function locals.
|
/// Function locals.
|
||||||
pub locals: &'a [Local],
|
pub locals: &'a [Local],
|
||||||
/// Function body.
|
/// Function body.
|
||||||
@ -233,6 +227,19 @@ impl ModuleInstance {
|
|||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_function_type(&self, function_index: ItemIndex, required_function_type: Option<&FunctionType>, externals: Option<&HashMap<String, Arc<ModuleInstanceInterface>>>) -> Result<(), Error> {
|
||||||
|
if let Some(ref required_function_type) = required_function_type {
|
||||||
|
let actual_function_type = self.function_type(function_index, externals)?;
|
||||||
|
if **required_function_type != actual_function_type {
|
||||||
|
return Err(Error::Function(format!("expected function with signature ({:?}) -> {:?} when got with ({:?}) -> {:?}",
|
||||||
|
required_function_type.params(), required_function_type.return_type(),
|
||||||
|
actual_function_type.params(), actual_function_type.return_type())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModuleInstanceInterface for ModuleInstance {
|
impl ModuleInstanceInterface for ModuleInstance {
|
||||||
@ -385,9 +392,8 @@ 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_type = self.function_type(ItemIndex::IndexSpace(index), Some(&externals))?;
|
|
||||||
let function_context = CallerContext::topmost(&mut args, &externals);
|
let function_context = CallerContext::topmost(&mut args, &externals);
|
||||||
function_reference.module.call_internal_function(function_context, function_reference.internal_index, Some(&function_type))
|
function_reference.module.call_internal_function(function_context, function_reference.internal_index)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute_export(&self, name: &str, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error> {
|
fn execute_export(&self, name: &str, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error> {
|
||||||
@ -429,38 +435,6 @@ impl ModuleInstanceInterface for ModuleInstance {
|
|||||||
.ok_or(Error::Program(format!("unresolved import {}", name))))
|
.ok_or(Error::Program(format!("unresolved import {}", name))))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn function_type<'a>(&self, function_index: ItemIndex, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>) -> Result<FunctionType, Error> {
|
|
||||||
println!("=== getting function_type({}, {:?})", self.name, function_index);
|
|
||||||
match self.imports.parse_function_index(function_index) {
|
|
||||||
ItemIndex::IndexSpace(_) => unreachable!("parse_function_index resolves IndexSpace option"),
|
|
||||||
ItemIndex::Internal(index) => self.require_function(ItemIndex::Internal(index))
|
|
||||||
.and_then(|ft| self.function_type_by_index(ft)),
|
|
||||||
ItemIndex::External(index) => self.module.import_section()
|
|
||||||
.ok_or(Error::Function(format!("trying to access external function with index {} in module without import section", index)))
|
|
||||||
.and_then(|s| s.entries().get(index as usize)
|
|
||||||
.ok_or(Error::Function(format!("trying to access external function with index {} in module with {}-entries import section", index, s.entries().len()))))
|
|
||||||
.and_then(|e| {
|
|
||||||
let module = self.imports.module(externals, e.module())?;
|
|
||||||
let function_type = match e.external() {
|
|
||||||
&External::Function(type_index) => self.function_type_by_index(type_index)?,
|
|
||||||
_ => return Err(Error::Function(format!("exported function {} is not a function", index))),
|
|
||||||
};
|
|
||||||
let external_function_index = self.imports.function(externals, e, Some(&function_type))?;
|
|
||||||
module.function_type(ItemIndex::IndexSpace(external_function_index), externals)
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn function_type_by_index<'a>(&self, type_index: u32) -> Result<FunctionType, Error> {
|
|
||||||
self.module.type_section()
|
|
||||||
.ok_or(Error::Validation(format!("type reference {} exists in module without type section", type_index)))
|
|
||||||
.and_then(|s| match s.types().get(type_index as usize) {
|
|
||||||
Some(&Type::Function(ref function_type)) => Ok(function_type),
|
|
||||||
_ => Err(Error::Validation(format!("missing function type with index {}", type_index))),
|
|
||||||
})
|
|
||||||
.map(Clone::clone)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn table(&self, index: ItemIndex) -> Result<Arc<TableInstance>, Error> {
|
fn table(&self, index: ItemIndex) -> Result<Arc<TableInstance>, Error> {
|
||||||
match self.imports.parse_table_index(index) {
|
match self.imports.parse_table_index(index) {
|
||||||
ItemIndex::IndexSpace(_) => unreachable!("parse_table_index resolves IndexSpace option"),
|
ItemIndex::IndexSpace(_) => unreachable!("parse_table_index resolves IndexSpace option"),
|
||||||
@ -500,6 +474,32 @@ println!("=== getting function_type({}, {:?})", self.name, function_index);
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn function_type<'a>(&self, function_index: ItemIndex, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>) -> Result<FunctionType, Error> {
|
||||||
|
match self.imports.parse_function_index(function_index) {
|
||||||
|
ItemIndex::IndexSpace(_) => unreachable!("parse_function_index resolves IndexSpace option"),
|
||||||
|
ItemIndex::Internal(index) => self.require_function(ItemIndex::Internal(index))
|
||||||
|
.and_then(|ft| self.function_type_by_index(ft)),
|
||||||
|
ItemIndex::External(index) => self.module.import_section()
|
||||||
|
.ok_or(Error::Function(format!("trying to access external function with index {} in module without import section", index)))
|
||||||
|
.and_then(|s| s.entries().get(index as usize)
|
||||||
|
.ok_or(Error::Function(format!("trying to access external function with index {} in module with {}-entries import section", index, s.entries().len()))))
|
||||||
|
.and_then(|e| match e.external() {
|
||||||
|
&External::Function(type_index) => self.function_type_by_index(type_index),
|
||||||
|
_ => Err(Error::Function(format!("exported function {} is not a function", index))),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn function_type_by_index<'a>(&self, type_index: u32) -> Result<FunctionType, Error> {
|
||||||
|
self.module.type_section()
|
||||||
|
.ok_or(Error::Validation(format!("type reference {} exists in module without type section", type_index)))
|
||||||
|
.and_then(|s| match s.types().get(type_index as usize) {
|
||||||
|
Some(&Type::Function(ref function_type)) => Ok(function_type),
|
||||||
|
_ => Err(Error::Validation(format!("missing function type with index {}", type_index))),
|
||||||
|
})
|
||||||
|
.map(Clone::clone)
|
||||||
|
}
|
||||||
|
|
||||||
fn function_reference<'a>(&self, index: ItemIndex, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>) -> Result<InternalFunctionReference<'a>, Error> {
|
fn function_reference<'a>(&self, index: ItemIndex, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>) -> Result<InternalFunctionReference<'a>, Error> {
|
||||||
match self.imports.parse_function_index(index) {
|
match self.imports.parse_function_index(index) {
|
||||||
ItemIndex::IndexSpace(_) => unreachable!("parse_function_index resolves IndexSpace option"),
|
ItemIndex::IndexSpace(_) => unreachable!("parse_function_index resolves IndexSpace option"),
|
||||||
@ -508,8 +508,10 @@ println!("=== getting function_type({}, {:?})", self.name, function_index);
|
|||||||
internal_index: index,
|
internal_index: index,
|
||||||
}),
|
}),
|
||||||
ItemIndex::External(index) => {
|
ItemIndex::External(index) => {
|
||||||
let import_section = self.module.import_section().unwrap();
|
let import_entry = self.module.import_section()
|
||||||
let import_entry = import_section.entries().get(index as usize).unwrap();
|
.expect("parse_function_index has returned External(index); it is only returned when import section exists; qed")
|
||||||
|
.entries().get(index as usize)
|
||||||
|
.expect("parse_function_index has returned External(index); it is only returned when entry with index exists in import section exists; qed");
|
||||||
let required_function_type = self.function_type(ItemIndex::External(index), externals)?;
|
let required_function_type = self.function_type(ItemIndex::External(index), externals)?;
|
||||||
let internal_function_index = self.imports.function(externals, import_entry, Some(&required_function_type))?;
|
let internal_function_index = self.imports.function(externals, import_entry, Some(&required_function_type))?;
|
||||||
Ok(InternalFunctionReference {
|
Ok(InternalFunctionReference {
|
||||||
@ -521,13 +523,6 @@ println!("=== getting function_type({}, {:?})", self.name, function_index);
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn function_reference_indirect<'a>(&self, table_idx: u32, type_idx: u32, func_idx: u32, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>) -> Result<InternalFunctionReference<'a>, Error> {
|
fn function_reference_indirect<'a>(&self, table_idx: u32, type_idx: u32, func_idx: u32, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>) -> Result<InternalFunctionReference<'a>, Error> {
|
||||||
let function_type = match self.module.type_section()
|
|
||||||
.ok_or(Error::Function(format!("trying to indirect call function {} with non-existent function section", func_idx)))
|
|
||||||
.and_then(|s| s.types().get(type_idx as usize)
|
|
||||||
.ok_or(Error::Function(format!("trying to indirect call function {} with non-existent type index {}", func_idx, type_idx))))? {
|
|
||||||
&Type::Function(ref function_type) => function_type,
|
|
||||||
};
|
|
||||||
|
|
||||||
let table = self.table(ItemIndex::IndexSpace(table_idx))?;
|
let table = self.table(ItemIndex::IndexSpace(table_idx))?;
|
||||||
let (module, index) = match table.get(func_idx)? {
|
let (module, index) = match table.get(func_idx)? {
|
||||||
RuntimeValue::AnyFunc(module, index) => (module.clone(), index),
|
RuntimeValue::AnyFunc(module, index) => (module.clone(), index),
|
||||||
@ -535,32 +530,18 @@ println!("=== getting function_type({}, {:?})", self.name, function_index);
|
|||||||
};
|
};
|
||||||
|
|
||||||
let module = self.imports.module(externals, &module)?;
|
let module = self.imports.module(externals, &module)?;
|
||||||
|
let required_function_type = self.function_type_by_index(type_idx)?;
|
||||||
|
let actual_function_type = module.function_type(ItemIndex::IndexSpace(index), externals)?;
|
||||||
|
if required_function_type != actual_function_type {
|
||||||
|
return Err(Error::Function(format!("expected indirect function with signature ({:?}) -> {:?} when got with ({:?}) -> {:?}",
|
||||||
|
required_function_type.params(), required_function_type.return_type(),
|
||||||
|
actual_function_type.params(), actual_function_type.return_type())));
|
||||||
|
}
|
||||||
|
|
||||||
module.function_reference(ItemIndex::IndexSpace(index), externals)
|
module.function_reference(ItemIndex::IndexSpace(index), externals)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn function_body<'a>(&'a self, internal_index: u32, function_type: Option<&FunctionType>) -> Result<Option<InternalFunction<'a>>, Error> {
|
fn function_body<'a>(&'a self, internal_index: u32) -> Result<Option<InternalFunction<'a>>, Error> {
|
||||||
// internal index = index of function in functions section && index of code in code section
|
|
||||||
// get function type index
|
|
||||||
let function_type_index = self.module
|
|
||||||
.function_section()
|
|
||||||
.ok_or(Error::Function(format!("trying to call function with index {} in module without function section", internal_index)))
|
|
||||||
.and_then(|s| s.entries()
|
|
||||||
.get(internal_index as usize)
|
|
||||||
.ok_or(Error::Function(format!("trying to call function with index {} in module with {} functions", internal_index, s.entries().len()))))?
|
|
||||||
.type_ref();
|
|
||||||
// function type index = index of function type in types index
|
|
||||||
// get function type
|
|
||||||
let item_type = self.module
|
|
||||||
.type_section()
|
|
||||||
.ok_or(Error::Function(format!("trying to call function with index {} in module without types section", internal_index)))
|
|
||||||
.and_then(|s| s.types()
|
|
||||||
.get(function_type_index as usize)
|
|
||||||
.ok_or(Error::Function(format!("trying to call function with type index {} in module with {} types", function_type_index, s.types().len()))))?;
|
|
||||||
let actual_function_type = match item_type {
|
|
||||||
&Type::Function(ref function_type) => function_type,
|
|
||||||
};
|
|
||||||
|
|
||||||
// get function body
|
|
||||||
let function_body = self.module
|
let function_body = self.module
|
||||||
.code_section()
|
.code_section()
|
||||||
.ok_or(Error::Function(format!("trying to call function with index {} in module without code section", internal_index)))
|
.ok_or(Error::Function(format!("trying to call function with index {} in module without code section", internal_index)))
|
||||||
@ -569,100 +550,14 @@ println!("=== getting function_type({}, {:?})", self.name, function_index);
|
|||||||
.ok_or(Error::Function(format!("trying to call function with index {} in module with {} functions codes", internal_index, s.bodies().len()))))?;
|
.ok_or(Error::Function(format!("trying to call function with index {} in module with {} functions codes", internal_index, s.bodies().len()))))?;
|
||||||
|
|
||||||
Ok(Some(InternalFunction {
|
Ok(Some(InternalFunction {
|
||||||
func_type: actual_function_type,
|
|
||||||
locals: function_body.locals(),
|
locals: function_body.locals(),
|
||||||
body: function_body.code().elements(),
|
body: function_body.code().elements(),
|
||||||
}))
|
}))
|
||||||
/*match self.imports.parse_function_index(index) {
|
|
||||||
ItemIndex::IndexSpace(_) => unreachable!("parse_function_index resolves IndexSpace option"),
|
|
||||||
ItemIndex::Internal(index) => {
|
|
||||||
// internal index = index of function in functions section && index of code in code section
|
|
||||||
// get function type index
|
|
||||||
let function_type_index = self.module
|
|
||||||
.function_section()
|
|
||||||
.ok_or(Error::Function(format!("trying to call function with index {} in module without function section", index)))
|
|
||||||
.and_then(|s| s.entries()
|
|
||||||
.get(index as usize)
|
|
||||||
.ok_or(Error::Function(format!("trying to call function with index {} in module with {} functions", index, s.entries().len()))))?
|
|
||||||
.type_ref();
|
|
||||||
// function type index = index of function type in types index
|
|
||||||
// get function type
|
|
||||||
let item_type = self.module
|
|
||||||
.type_section()
|
|
||||||
.ok_or(Error::Function(format!("trying to call function with index {} in module without types section", index)))
|
|
||||||
.and_then(|s| s.types()
|
|
||||||
.get(function_type_index as usize)
|
|
||||||
.ok_or(Error::Function(format!("trying to call function with type index {} in module with {} types", function_type_index, s.types().len()))))?;
|
|
||||||
let actual_function_type = match item_type {
|
|
||||||
&Type::Function(ref function_type) => function_type,
|
|
||||||
};
|
|
||||||
|
|
||||||
// get function body
|
|
||||||
let function_body = self.module
|
|
||||||
.code_section()
|
|
||||||
.ok_or(Error::Function(format!("trying to call function with index {} in module without code section", index)))
|
|
||||||
.and_then(|s| s.bodies()
|
|
||||||
.get(index as usize)
|
|
||||||
.ok_or(Error::Function(format!("trying to call function with index {} in module with {} functions codes", index, s.bodies().len()))))?;
|
|
||||||
|
|
||||||
Ok(Some(Function {
|
|
||||||
func_type: actual_function_type,
|
|
||||||
body: function_body.code().elements(),
|
|
||||||
}))
|
|
||||||
},
|
|
||||||
ItemIndex::External(index) => {
|
|
||||||
},
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*fn call_function(&self, outer: CallerContext, index: ItemIndex, function_type: Option<&FunctionType>) -> Result<Option<RuntimeValue>, Error> {
|
fn call_internal_function(&self, mut outer: CallerContext, index: u32) -> Result<Option<RuntimeValue>, Error> {
|
||||||
match self.imports.parse_function_index(index) {
|
let function_type = self.function_type(ItemIndex::Internal(index), None)?;
|
||||||
ItemIndex::IndexSpace(_) => unreachable!("parse_function_index resolves IndexSpace option"),
|
|
||||||
ItemIndex::Internal(index) => self.call_internal_function(outer, index, function_type),
|
|
||||||
ItemIndex::External(index) => self.module.import_section()
|
|
||||||
.ok_or(Error::Function(format!("trying to access external function with index {} in module without import section", index)))
|
|
||||||
.and_then(|s| s.entries().get(index as usize)
|
|
||||||
.ok_or(Error::Function(format!("trying to access external function with index {} in module with {}-entries import section", index, s.entries().len()))))
|
|
||||||
.and_then(|e| Ok((self.imports.module(Some(outer.externals), e.module())?,
|
|
||||||
self.imports.function(Some(outer.externals), e, function_type)?)))
|
|
||||||
.and_then(|(m, index)| m.call_internal_function(outer, index, function_type)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn call_function_indirect(&self, outer: CallerContext, table_index: ItemIndex, type_index: u32, func_index: u32) -> Result<Option<RuntimeValue>, Error> {
|
|
||||||
let function_type = match self.module.type_section()
|
|
||||||
.ok_or(Error::Function(format!("trying to indirect call function {} with non-existent function section", func_index)))
|
|
||||||
.and_then(|s| s.types().get(type_index as usize)
|
|
||||||
.ok_or(Error::Function(format!("trying to indirect call function {} with non-existent type index {}", func_index, type_index))))? {
|
|
||||||
&Type::Function(ref function_type) => function_type,
|
|
||||||
};
|
|
||||||
|
|
||||||
let table = self.table(table_index)?;
|
|
||||||
let (module, index) = match table.get(func_index)? {
|
|
||||||
RuntimeValue::AnyFunc(module, index) => (module.clone(), index),
|
|
||||||
_ => return Err(Error::Function(format!("trying to indirect call function {} via non-anyfunc table {:?}", func_index, table_index))),
|
|
||||||
};
|
|
||||||
|
|
||||||
let module = self.imports.module(Some(outer.externals), &module)?;
|
|
||||||
module.call_function(outer, ItemIndex::IndexSpace(index), Some(function_type))
|
|
||||||
}*/
|
|
||||||
|
|
||||||
fn call_internal_function(&self, mut outer: CallerContext, index: u32, required_function_type: Option<&FunctionType>) -> Result<Option<RuntimeValue>, Error> {
|
|
||||||
println!("=== call_internal_function({})", index);
|
|
||||||
let function_type_index = self.require_function(ItemIndex::Internal(index))?;
|
|
||||||
let function_type = self.function_type_by_index(function_type_index)?;
|
|
||||||
let function_body = self.function_body(index, required_function_type)?;
|
|
||||||
|
|
||||||
if let Some(ref required_function_type) = required_function_type {
|
|
||||||
if **required_function_type != function_type {
|
|
||||||
return Err(Error::Function(format!("expected function with signature ({:?}) -> {:?} when got with ({:?}) -> {:?}",
|
|
||||||
required_function_type.params(), required_function_type.return_type(), function_type.params(), function_type.return_type())));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut args = prepare_function_args(&function_type, outer.value_stack)?;
|
let mut args = prepare_function_args(&function_type, outer.value_stack)?;
|
||||||
println!("=== call_internal_Function.function_type: {:?}", function_type);
|
|
||||||
println!("=== call_internal_Function.args: {:?}", args);
|
|
||||||
let function_ref = InternalFunctionReference { module: self.self_ref(Some(outer.externals))?, internal_index: index };
|
let function_ref = InternalFunctionReference { module: self.self_ref(Some(outer.externals))?, internal_index: index };
|
||||||
let inner = FunctionContext::new(function_ref, outer.externals, outer.value_stack_limit, outer.frame_stack_limit, &function_type, args);
|
let inner = FunctionContext::new(function_ref, outer.externals, outer.value_stack_limit, outer.frame_stack_limit, &function_type, args);
|
||||||
Interpreter::run_function(inner)
|
Interpreter::run_function(inner)
|
||||||
@ -701,27 +596,6 @@ pub fn check_limits(limits: &ResizableLimits) -> Result<(), Error> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/*fn prepare_function_locals(function_type: &FunctionType, function_body: &FuncBody, outer: &mut CallerContext) -> Result<Vec<VariableInstance>, Error> {
|
|
||||||
// locals = function arguments + defined locals
|
|
||||||
function_type.params().iter().rev()
|
|
||||||
.map(|param_type| {
|
|
||||||
let param_value = outer.value_stack.pop()?;
|
|
||||||
let actual_type = param_value.variable_type();
|
|
||||||
let expected_type = (*param_type).into();
|
|
||||||
if actual_type != Some(expected_type) {
|
|
||||||
return Err(Error::Function(format!("invalid parameter type {:?} when expected {:?}", actual_type, expected_type)));
|
|
||||||
}
|
|
||||||
|
|
||||||
VariableInstance::new(true, expected_type, param_value)
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>().into_iter().rev()
|
|
||||||
.chain(function_body.locals()
|
|
||||||
.iter()
|
|
||||||
.flat_map(|l| repeat(l.value_type().into()).take(l.count() as usize))
|
|
||||||
.map(|vt| VariableInstance::new(true, vt, RuntimeValue::default(vt))))
|
|
||||||
.collect::<Result<Vec<_>, _>>()
|
|
||||||
}*/
|
|
||||||
|
|
||||||
fn get_initializer(expr: &InitExpr, module: &Module, imports: &ModuleImports, expected_type: VariableType) -> Result<RuntimeValue, Error> {
|
fn get_initializer(expr: &InitExpr, module: &Module, imports: &ModuleImports, expected_type: VariableType) -> Result<RuntimeValue, Error> {
|
||||||
let first_opcode = match expr.code().len() {
|
let first_opcode = match expr.code().len() {
|
||||||
1 => &expr.code()[0],
|
1 => &expr.code()[0],
|
||||||
|
@ -100,7 +100,7 @@ impl Interpreter {
|
|||||||
loop {
|
loop {
|
||||||
let mut function_context = function_stack.pop_back().expect("on loop entry - not empty; on loop continue - checking for emptiness; qed");
|
let mut function_context = function_stack.pop_back().expect("on loop entry - not empty; on loop continue - checking for emptiness; qed");
|
||||||
let function_ref = function_context.function.clone();
|
let function_ref = function_context.function.clone();
|
||||||
let function_body = function_ref.module.function_body(function_ref.internal_index, None)?;
|
let function_body = function_ref.module.function_body(function_ref.internal_index)?;
|
||||||
|
|
||||||
let function_return = match function_body {
|
let function_return = match function_body {
|
||||||
Some(function_body) => {
|
Some(function_body) => {
|
||||||
@ -120,7 +120,7 @@ impl Interpreter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let nested_context = CallerContext::nested(&mut function_context);
|
let nested_context = CallerContext::nested(&mut function_context);
|
||||||
RunResult::Return(function_ref.module.call_internal_function(nested_context, function_ref.internal_index, None)?)
|
RunResult::Return(function_ref.module.call_internal_function(nested_context, function_ref.internal_index)?)
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user