Merge pull request #85 from NikVolf/invoke_example_comments

Comments added to the invoke example
This commit is contained in:
Nikolay Volf 2017-08-23 16:13:16 +03:00 committed by GitHub
commit c57797aaad
3 changed files with 37 additions and 12 deletions

View File

@ -15,6 +15,10 @@ fn main() {
let func_name = &args[2];
let (_, program_args) = args.split_at(3);
// Intrepreter initialization.
// parity_wasm::ProgramInstance can be parameterized with a custom User error to be returned from native modules
// parity_wasm::DefaultProgramInstance parametrize ProgramInstance with a pre-defined "DummyUserError"
// Initializes a default "env" module also.
let program = parity_wasm::DefaultProgramInstance::with_env_params(
interpreter::EnvParams {
total_stack: 128*1024,
@ -24,21 +28,31 @@ fn main() {
).expect("Program instance to load");
let module = parity_wasm::deserialize_file(&args[1]).expect("File to be deserialized");
// Extracts call arguments from command-line arguments
let execution_params = {
// Export section has an entry with a func_name with an index inside a module
let export_section = module.export_section().expect("No export section found");
// It's a section with function declarations (which are references to the type section entries)
let function_section = module.function_section().expect("No function section found");
// Type section stores function types which are referenced by function_section entries
let type_section = module.type_section().expect("No type section found");
// Given function name used to find export section entry which contains
// an `internal` field which points to the index in the function index space
let found_entry = export_section.entries().iter()
.find(|entry| func_name == entry.field()).expect(&format!("No export with name {} found", func_name));
// Function index with imported functions
// Function index in the function index space (internally-defined + imported)
let function_index: usize = match found_entry.internal() {
&Internal::Function(index) => index as usize,
_ => panic!("Founded export is not a function"),
};
// We need to count import section entries (functions only!) to subtract it from function_index
// and obtain the index within the function section
let import_section_len: usize = match module.import_section() {
Some(import) =>
Some(import) =>
import.entries().iter().filter(|entry| match entry.external() {
&External::Function(_) => true,
_ => false,
@ -46,12 +60,18 @@ fn main() {
None => 0,
};
// Calculates a function index within module's function section
let function_index_in_section = function_index - import_section_len;
// Getting a type reference from a function section entry
let func_type_ref: usize = function_section.entries()[function_index_in_section].type_ref() as usize;
// Use the reference to get an actual function type
let function_type: &FunctionType = match &type_section.types()[func_type_ref] {
&Type::Function(ref func_type) => func_type,
};
// Parses arguments and constructs runtime values in correspondence of their types
let args: Vec<RuntimeValue> = function_type.params().iter().enumerate().map(|(i, value)| match value {
&ValueType::I32 => RuntimeValue::I32(program_args[i].parse::<i32>().expect(&format!("Can't parse arg #{} as i32", program_args[i]))),
&ValueType::I64 => RuntimeValue::I64(program_args[i].parse::<i64>().expect(&format!("Can't parse arg #{} as i64", program_args[i]))),
@ -61,7 +81,12 @@ fn main() {
interpreter::ExecutionParams::from(args)
};
// Intialize deserialized module. It adds module into It expects 3 parameters:
// - a name for the module
// - a module declaration
// - "main" module doesn't import native module(s) this is why we don't need to provide external native modules here
// This test shows how to implement native module https://github.com/NikVolf/parity-wasm/blob/master/src/interpreter/tests/basics.rs#L197
let module = program.add_module("main", module, None).expect("Failed to initialize module");
println!("Result: {:?}", module.execute_export(func_name, execution_params).expect(""));

View File

@ -297,7 +297,7 @@ impl<E> ModuleInstance<E> where E: UserError {
export_function_type.params(), export_function_type.return_type())));
}
}
},
},
&External::Global(ref global_type) => if global_type.is_mutable() {
return Err(Error::Validation(format!("trying to import mutable global {}", import.field())));
} else {
@ -347,15 +347,15 @@ impl<E> ModuleInstance<E> where E: UserError {
let mut context = FunctionValidationContext::new(
self,
externals,
&locals,
DEFAULT_VALUE_STACK_LIMIT,
DEFAULT_FRAME_STACK_LIMIT,
&locals,
DEFAULT_VALUE_STACK_LIMIT,
DEFAULT_FRAME_STACK_LIMIT,
function_type.clone());
let block_type = function_type.return_type().map(BlockType::Value).unwrap_or(BlockType::NoResult);
Validator::validate_function(&mut context, block_type, function_body.code().elements())
.map_err(|e| {
if let Error::Validation(msg) = e {
.map_err(|e| {
if let Error::Validation(msg) = e {
Error::Validation(format!("Function #{} validation error: {}", index, msg))
} else {
e
@ -474,7 +474,7 @@ impl<E> ModuleInstanceInterface<E> for ModuleInstance<E> where E: UserError {
},
})
.map(|i| *i)
.ok_or(Error::Program(format!("unresolved import {}", name))))
.ok_or(Error::Program(format!("unresolved export {}", name))))
}
fn table(&self, index: ItemIndex) -> Result<Arc<TableInstance<E>>, Error<E>> {

View File

@ -67,7 +67,7 @@ impl<E> ProgramInstanceEssence<E> where E: UserError {
modules.insert("env".into(), env_module);
Ok(ProgramInstanceEssence {
modules: RwLock::new(modules),
})
})
}
/// Get module reference.