From 351e7ab45c1138e2f91d4ebd411da658e61c7ec3 Mon Sep 17 00:00:00 2001 From: fro Date: Thu, 17 Aug 2017 16:53:37 +0300 Subject: [PATCH 1/6] comments added to the invoke example --- examples/invoke.rs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/examples/invoke.rs b/examples/invoke.rs index b13dd4e..82617ba 100644 --- a/examples/invoke.rs +++ b/examples/invoke.rs @@ -15,6 +15,7 @@ fn main() { let func_name = &args[2]; let (_, program_args) = args.split_at(3); + // Intrepreter initialization let program = parity_wasm::DefaultProgramInstance::with_env_params( interpreter::EnvParams { total_stack: 128*1024, @@ -24,11 +25,17 @@ 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 where function to be found in let function_section = module.function_section().expect("No function section found"); + // Type section stores function types let type_section = module.type_section().expect("No type section found"); - + + // let found_entry = export_section.entries().iter() .find(|entry| func_name == entry.field()).expect(&format!("No export with name {} found", func_name)); @@ -37,8 +44,9 @@ fn main() { &Internal::Function(index) => index as usize, _ => panic!("Founded export is not a function"), }; + // Counts import section entries 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 +54,16 @@ fn main() { None => 0, }; + // Calculates a function index within function section let function_index_in_section = function_index - import_section_len; + + // Type a type ref (an index inside of types section of module) let func_type_ref: usize = function_section.entries()[function_index_in_section].type_ref() as usize; 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 = function_type.params().iter().enumerate().map(|(i, value)| match value { &ValueType::I32 => RuntimeValue::I32(program_args[i].parse::().expect(&format!("Can't parse arg #{} as i32", program_args[i]))), &ValueType::I64 => RuntimeValue::I64(program_args[i].parse::().expect(&format!("Can't parse arg #{} as i64", program_args[i]))), @@ -61,7 +73,8 @@ fn main() { interpreter::ExecutionParams::from(args) }; - + + // Intialize deserialized module let module = program.add_module("main", module, None).expect("Failed to initialize module"); println!("Result: {:?}", module.execute_export(func_name, execution_params).expect("")); From 70de398f79d4ee238554e2feae56b57d409917bb Mon Sep 17 00:00:00 2001 From: fro Date: Thu, 17 Aug 2017 16:56:45 +0300 Subject: [PATCH 2/6] update --- examples/invoke.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/invoke.rs b/examples/invoke.rs index 82617ba..2d6582d 100644 --- a/examples/invoke.rs +++ b/examples/invoke.rs @@ -35,7 +35,7 @@ fn main() { // Type section stores function types let type_section = module.type_section().expect("No type section found"); - // + // A found export entry by the name let found_entry = export_section.entries().iter() .find(|entry| func_name == entry.field()).expect(&format!("No export with name {} found", func_name)); From 17531ee92eca9a761885cac27f41f88b45adcc19 Mon Sep 17 00:00:00 2001 From: fro Date: Thu, 17 Aug 2017 20:15:36 +0300 Subject: [PATCH 3/6] fix comments --- examples/invoke.rs | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/examples/invoke.rs b/examples/invoke.rs index 2d6582d..f77812e 100644 --- a/examples/invoke.rs +++ b/examples/invoke.rs @@ -15,7 +15,9 @@ fn main() { let func_name = &args[2]; let (_, program_args) = args.split_at(3); - // Intrepreter initialization + // Intrepreter initialization. + // parity_wasm::ProgramInstance can be parameterized with a custom User error which could be returned from imported functions + // parity_wasm::DefaultProgramInstance parametrize ProgramInstance with a pre-defined "DummyUserError" let program = parity_wasm::DefaultProgramInstance::with_env_params( interpreter::EnvParams { total_stack: 128*1024, @@ -30,21 +32,22 @@ fn main() { 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 where function to be found in + // 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 + // Type section stores function types which are referenced by function_section entries let type_section = module.type_section().expect("No type section found"); - // A found export entry by the name + // A 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"), }; - // Counts import section entries + // We need to count import section entries to substract it from let import_section_len: usize = match module.import_section() { Some(import) => import.entries().iter().filter(|entry| match entry.external() { @@ -54,11 +57,13 @@ fn main() { None => 0, }; - // Calculates a function index within function section + // Calculates a function index within module's function section let function_index_in_section = function_index - import_section_len; - // Type a type ref (an index inside of types section of module) + // 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, }; @@ -74,7 +79,7 @@ fn main() { interpreter::ExecutionParams::from(args) }; - // Intialize deserialized module + // Intialize deserialized module. let module = program.add_module("main", module, None).expect("Failed to initialize module"); println!("Result: {:?}", module.execute_export(func_name, execution_params).expect("")); From b06a5a98c8d2a28d21879e4453d529f87d88f2d9 Mon Sep 17 00:00:00 2001 From: fro Date: Thu, 17 Aug 2017 20:21:50 +0300 Subject: [PATCH 4/6] update comments --- examples/invoke.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/invoke.rs b/examples/invoke.rs index f77812e..417db14 100644 --- a/examples/invoke.rs +++ b/examples/invoke.rs @@ -47,7 +47,9 @@ fn main() { &Internal::Function(index) => index as usize, _ => panic!("Founded export is not a function"), }; - // We need to count import section entries to substract it from + + // 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) => import.entries().iter().filter(|entry| match entry.external() { From f06daece563a22f21f7561ed1942a1c94899d782 Mon Sep 17 00:00:00 2001 From: fro Date: Mon, 21 Aug 2017 17:49:36 +0300 Subject: [PATCH 5/6] comments update + remove empty space --- examples/invoke.rs | 11 +++++++++-- src/interpreter/module.rs | 14 +++++++------- src/interpreter/program.rs | 2 +- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/examples/invoke.rs b/examples/invoke.rs index 417db14..2e7bc38 100644 --- a/examples/invoke.rs +++ b/examples/invoke.rs @@ -18,6 +18,7 @@ fn main() { // Intrepreter initialization. // parity_wasm::ProgramInstance can be parameterized with a custom User error which could be returned from imported functions // 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, @@ -37,7 +38,7 @@ fn main() { // Type section stores function types which are referenced by function_section entries let type_section = module.type_section().expect("No type section found"); - // A given function name used to find export section entry which contains + // 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)); @@ -81,7 +82,13 @@ fn main() { interpreter::ExecutionParams::from(args) }; - // Intialize deserialized module. + // Intialize deserialized module. It adds module into It expects 3 parameters: + // - a name for the module + // - a module declaration + // - an optional HashMap of additional external modules (which takes priority over already initialized modules) + // to be: + // - formally validated + // - validated imports against these external modules let module = program.add_module("main", module, None).expect("Failed to initialize module"); println!("Result: {:?}", module.execute_export(func_name, execution_params).expect("")); diff --git a/src/interpreter/module.rs b/src/interpreter/module.rs index 9f0f044..a81a2ba 100644 --- a/src/interpreter/module.rs +++ b/src/interpreter/module.rs @@ -297,7 +297,7 @@ impl ModuleInstance 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 ModuleInstance 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 ModuleInstanceInterface for ModuleInstance 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>, Error> { diff --git a/src/interpreter/program.rs b/src/interpreter/program.rs index 1040cb9..f34236e 100644 --- a/src/interpreter/program.rs +++ b/src/interpreter/program.rs @@ -67,7 +67,7 @@ impl ProgramInstanceEssence where E: UserError { modules.insert("env".into(), env_module); Ok(ProgramInstanceEssence { modules: RwLock::new(modules), - }) + }) } /// Get module reference. From d86167a1455474aca78264c061c11da87c7599e9 Mon Sep 17 00:00:00 2001 From: fro Date: Wed, 23 Aug 2017 15:54:14 +0300 Subject: [PATCH 6/6] comment external parameter --- examples/invoke.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/examples/invoke.rs b/examples/invoke.rs index 2e7bc38..f96d42d 100644 --- a/examples/invoke.rs +++ b/examples/invoke.rs @@ -16,7 +16,7 @@ fn main() { let (_, program_args) = args.split_at(3); // Intrepreter initialization. - // parity_wasm::ProgramInstance can be parameterized with a custom User error which could be returned from imported functions + // 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( @@ -85,10 +85,8 @@ fn main() { // Intialize deserialized module. It adds module into It expects 3 parameters: // - a name for the module // - a module declaration - // - an optional HashMap of additional external modules (which takes priority over already initialized modules) - // to be: - // - formally validated - // - validated imports against these external modules + // - "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(""));