mirror of
https://github.com/fluencelabs/parity-wasm
synced 2025-06-21 18:51:52 +00:00
Add import resolver
This commit is contained in:
36
src/interpreter/imports.rs
Normal file
36
src/interpreter/imports.rs
Normal file
@ -0,0 +1,36 @@
|
||||
use std::rc::Rc;
|
||||
use elements::{FunctionType, GlobalType, MemoryType, TableType};
|
||||
use interpreter::store::{FuncInstance, GlobalInstance};
|
||||
use interpreter::memory::MemoryInstance;
|
||||
use interpreter::table::TableInstance;
|
||||
use interpreter::Error;
|
||||
|
||||
pub trait ImportResolver {
|
||||
fn resolve_func(
|
||||
&self,
|
||||
module_name: &str,
|
||||
field_name: &str,
|
||||
func_type: &FunctionType,
|
||||
) -> Result<Rc<FuncInstance>, Error>;
|
||||
|
||||
fn resolve_global(
|
||||
&self,
|
||||
module_name: &str,
|
||||
field_name: &str,
|
||||
global_type: &GlobalType,
|
||||
) -> Result<Rc<GlobalInstance>, Error>;
|
||||
|
||||
fn resolve_memory(
|
||||
&self,
|
||||
module_name: &str,
|
||||
field_name: &str,
|
||||
memory_type: &MemoryType,
|
||||
) -> Result<Rc<MemoryInstance>, Error>;
|
||||
|
||||
fn resolve_table(
|
||||
&self,
|
||||
module_name: &str,
|
||||
field_name: &str,
|
||||
table_type: &TableType,
|
||||
) -> Result<Rc<TableInstance>, Error>;
|
||||
}
|
@ -140,6 +140,7 @@ mod value;
|
||||
mod variable;
|
||||
mod store;
|
||||
mod host;
|
||||
mod imports;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
@ -26,10 +26,10 @@ impl ProgramInstance {
|
||||
module: Module,
|
||||
state: &mut St,
|
||||
) -> Result<Rc<ModuleInstance>, Error> {
|
||||
let mut extern_vals = Vec::new();
|
||||
let mut externvals = Vec::new();
|
||||
for import_entry in module.import_section().map(|s| s.entries()).unwrap_or(&[]) {
|
||||
let module = self.modules.get(import_entry.module()).ok_or_else(|| Error::Program(format!("Module {} not found", import_entry.module())))?;
|
||||
let extern_val = module
|
||||
let externval = module
|
||||
.export_by_name(import_entry.field())
|
||||
.ok_or_else(|| {
|
||||
Error::Program(format!(
|
||||
@ -38,10 +38,10 @@ impl ProgramInstance {
|
||||
import_entry.field()
|
||||
))
|
||||
})?;
|
||||
extern_vals.push(extern_val);
|
||||
externvals.push(externval);
|
||||
}
|
||||
|
||||
let module_instance = ModuleInstance::instantiate(&module, &extern_vals, state)?;
|
||||
let module_instance = ModuleInstance::instantiate_with_externvals(&module, &externvals, state)?;
|
||||
self.modules.insert(name.to_owned(), Rc::clone(&module_instance));
|
||||
|
||||
Ok(module_instance)
|
||||
|
@ -9,6 +9,7 @@ use interpreter::{Error, MemoryInstance,
|
||||
RuntimeValue, TableInstance};
|
||||
use interpreter::runner::{prepare_function_args, FunctionContext, Interpreter};
|
||||
use interpreter::host::AnyFunc;
|
||||
use interpreter::imports::ImportResolver;
|
||||
use validation::validate_module;
|
||||
use common::{DEFAULT_FRAME_STACK_LIMIT, DEFAULT_MEMORY_INDEX, DEFAULT_TABLE_INDEX,
|
||||
DEFAULT_VALUE_STACK_LIMIT};
|
||||
@ -190,7 +191,6 @@ impl ModuleInstance {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn memory_by_index(&self, idx: u32) -> Option<Rc<MemoryInstance>> {
|
||||
self
|
||||
.memories
|
||||
@ -417,7 +417,7 @@ impl ModuleInstance {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn instantiate<St: 'static>(
|
||||
pub fn instantiate_with_externvals<St: 'static>(
|
||||
module: &Module,
|
||||
extern_vals: &[ExternVal],
|
||||
state: &mut St,
|
||||
@ -471,6 +471,44 @@ impl ModuleInstance {
|
||||
Ok(instance)
|
||||
}
|
||||
|
||||
pub fn instantiate<St: 'static, I: ImportResolver>(
|
||||
module: &Module,
|
||||
resolver: &I,
|
||||
state: &mut St,
|
||||
) -> Result<Rc<ModuleInstance>, Error> {
|
||||
let mut extern_vals = Vec::new();
|
||||
for import_entry in module.import_section().map(|s| s.entries()).unwrap_or(&[]) {
|
||||
let module_name = import_entry.module();
|
||||
let field_name = import_entry.field();
|
||||
let extern_val = match *import_entry.external() {
|
||||
External::Function(fn_ty_idx) => {
|
||||
// Module is not yet validated so we have to check type indexes.
|
||||
let types = module.type_section().map(|s| s.types()).unwrap_or(&[]);
|
||||
let &Type::Function(ref func_type) = types.get(fn_ty_idx as usize)
|
||||
.ok_or_else(|| Error::Validation(format!("Function type {} not found", fn_ty_idx)))?;
|
||||
|
||||
let func = resolver.resolve_func(module_name, field_name, func_type)?;
|
||||
ExternVal::Func(func)
|
||||
},
|
||||
External::Table(ref table_type) => {
|
||||
let table = resolver.resolve_table(module_name, field_name, table_type)?;
|
||||
ExternVal::Table(table)
|
||||
},
|
||||
External::Memory(ref memory_type) => {
|
||||
let memory = resolver.resolve_memory(module_name, field_name, memory_type)?;
|
||||
ExternVal::Memory(memory)
|
||||
},
|
||||
External::Global(ref global_type) => {
|
||||
let global = resolver.resolve_global(module_name, field_name, global_type)?;
|
||||
ExternVal::Global(global)
|
||||
}
|
||||
};
|
||||
extern_vals.push(extern_val);
|
||||
}
|
||||
|
||||
Self::instantiate_with_externvals(module, &extern_vals, state)
|
||||
}
|
||||
|
||||
pub fn invoke_index<St: 'static>(
|
||||
&self,
|
||||
func_idx: u32,
|
||||
|
Reference in New Issue
Block a user