From 07267813db19c659441c448a3d2823e0ee642db2 Mon Sep 17 00:00:00 2001 From: Andrew Dirksen Date: Wed, 21 Nov 2018 16:58:33 -0800 Subject: [PATCH] move invoke into Interpreter --- benches/src/reuse.rs | 29 +++++++++++++------------- src/func.rs | 48 ++------------------------------------------ src/module.rs | 5 +++-- src/runner.rs | 41 +++++++++++++++++++++++++++++++------ 4 files changed, 55 insertions(+), 68 deletions(-) diff --git a/benches/src/reuse.rs b/benches/src/reuse.rs index 8fa42bd..3f38040 100644 --- a/benches/src/reuse.rs +++ b/benches/src/reuse.rs @@ -1,7 +1,7 @@ use std::error; use std::fs::File; use test::Bencher; -use wasmi::{FuncInstance, ImportsBuilder, Interpreter, Module, ModuleInstance, NopExternals, RuntimeValue}; +use wasmi::{ImportsBuilder, Interpreter, Module, ModuleInstance, NopExternals, RuntimeValue}; // Load a module from a file. fn load_from_file(filename: &str) -> Result> { @@ -39,7 +39,7 @@ fn bench_tiny_keccak(b: &mut Bencher) { b.iter(|| { interpreter.reset(); - FuncInstance::invoke_configurable(&func, &[test_data_ptr], &mut NopExternals, &mut interpreter).unwrap() + interpreter.invoke(&func, &[test_data_ptr], &mut NopExternals).unwrap() }); } @@ -85,7 +85,7 @@ fn bench_rev_comp(b: &mut Bencher) { b.iter(|| { interpreter.reset(); - FuncInstance::invoke_configurable(&func, &[test_data_ptr], &mut NopExternals, &mut interpreter).unwrap() + interpreter.invoke(&func, &[test_data_ptr], &mut NopExternals).unwrap() }); // Verify the result. @@ -142,7 +142,7 @@ fn bench_regex_redux(b: &mut Bencher) { b.iter(|| { interpreter.reset(); - FuncInstance::invoke_configurable(&func, &[test_data_ptr], &mut NopExternals, &mut interpreter).unwrap() + interpreter.invoke(&func, &[test_data_ptr], &mut NopExternals).unwrap() }); } @@ -174,9 +174,9 @@ fn fac_recursive(b: &mut Bencher) { b.iter(|| { interpreter.reset(); - let value = - FuncInstance::invoke_configurable(&func, &[RuntimeValue::I64(25)], &mut NopExternals, &mut interpreter) - .unwrap(); + let value = interpreter + .invoke(&func, &[RuntimeValue::I64(25)], &mut NopExternals) + .unwrap(); assert_matches!(value, Some(RuntimeValue::I64(7034535277573963776))); }); } @@ -214,9 +214,9 @@ fn fac_opt(b: &mut Bencher) { b.iter(|| { interpreter.reset(); - let value = - FuncInstance::invoke_configurable(&func, &[RuntimeValue::I64(25)], &mut NopExternals, &mut interpreter) - .unwrap(); + let value = interpreter + .invoke(&func, &[RuntimeValue::I64(25)], &mut NopExternals) + .unwrap(); assert_matches!(value, Some(RuntimeValue::I64(7034535277573963776))); }); } @@ -255,9 +255,9 @@ fn recursive_ok(b: &mut Bencher) { b.iter(|| { interpreter.reset(); - let value = - FuncInstance::invoke_configurable(&func, &[RuntimeValue::I32(8000)], &mut NopExternals, &mut interpreter) - .unwrap(); + let value = interpreter + .invoke(&func, &[RuntimeValue::I32(8000)], &mut NopExternals) + .unwrap(); assert_matches!(value, Some(RuntimeValue::I32(0))); }); } @@ -295,7 +295,8 @@ fn recursive_trap(b: &mut Bencher) { b.iter(|| { interpreter.reset(); - FuncInstance::invoke_configurable(&func, &[RuntimeValue::I32(1000)], &mut NopExternals, &mut interpreter) + interpreter + .invoke(&func, &[RuntimeValue::I32(1000)], &mut NopExternals) .unwrap_err(); }); } diff --git a/src/func.rs b/src/func.rs index 09879cd..26103db 100644 --- a/src/func.rs +++ b/src/func.rs @@ -6,7 +6,7 @@ use host::Externals; use isa; use module::ModuleInstance; use parity_wasm::elements::Local; -use runner::{check_function_args, Interpreter, InterpreterState}; +use runner::{Interpreter, InterpreterState}; use types::ValueType; use value::RuntimeValue; use {Signature, Trap}; @@ -117,50 +117,6 @@ impl FuncInstance { } } - /// Invoke this function with extra configuration parameters. - /// - /// This is an experimental API - /// - /// # Errors - /// - /// Returns `Err` if `args` types is not match function [`signature`] or - /// if [`Trap`] at execution time occured. - /// - /// [`signature`]: #method.signature - /// [`Trap`]: #enum.Trap.html - pub fn invoke_configurable( - func: &FuncRef, - args: &[RuntimeValue], - externals: &mut E, - interpreter: &mut Interpreter, - ) -> Result, Trap> { - check_function_args(func.signature(), &args)?; - match *func.as_internal() { - FuncInstanceInternal::Internal { .. } => interpreter.start_execution(externals, func, args), - FuncInstanceInternal::Host { - ref host_func_index, .. - } => externals.invoke_index(*host_func_index, args.into()), - } - } - - /// Invoke this function. - /// - /// # Errors - /// - /// Returns `Err` if `args` types is not match function [`signature`] or - /// if [`Trap`] at execution time occured. - /// - /// [`signature`]: #method.signature - /// [`Trap`]: #enum.Trap.html - pub fn invoke( - func: &FuncRef, - args: &[RuntimeValue], - externals: &mut E, - ) -> Result, Trap> { - let mut interpreter = Interpreter::new(); - Self::invoke_configurable(func, args, externals, &mut interpreter) - } - /// Invoke the function, get a resumable handle. This handle can then be used to [`start_execution`]. If a /// Host trap happens, caller can use [`resume_execution`] to feed the expected return value back in, and then /// continue the execution. @@ -267,7 +223,7 @@ impl FuncInvocation { if interpreter.state() != &InterpreterState::Initialized { return Err(ResumableError::AlreadyStarted); } - Ok(interpreter.start_execution(externals, func, args)?) + Ok(interpreter.start_execution(func, args, externals)?) } FuncInvocationKind::Host { ref mut finished, diff --git a/src/module.rs b/src/module.rs index 6a52c15..4ac2205 100644 --- a/src/module.rs +++ b/src/module.rs @@ -21,6 +21,7 @@ use host::Externals; use common::{DEFAULT_MEMORY_INDEX, DEFAULT_TABLE_INDEX}; use types::{GlobalDescriptor, TableDescriptor, MemoryDescriptor}; use memory_units::Pages; +use runner::Interpreter; /// Reference to a [`ModuleInstance`]. /// @@ -629,7 +630,7 @@ impl ModuleInstance { } }; - FuncInstance::invoke(&func_instance, args, externals) + Interpreter::new().invoke(&func_instance, args, externals) .map_err(|t| Error::Trap(t)) } @@ -688,7 +689,7 @@ impl<'a> NotStartedModuleRef<'a> { let start_func = self.instance.func_by_index(start_fn_idx).expect( "Due to validation start function should exists", ); - FuncInstance::invoke(&start_func, &[], state)?; + Interpreter::new().invoke(&start_func, &[], state)?; } Ok(self.instance) } diff --git a/src/runner.rs b/src/runner.rs index 43ba860..46d8494 100644 --- a/src/runner.rs +++ b/src/runner.rs @@ -5,8 +5,8 @@ use common::{DEFAULT_MEMORY_INDEX, DEFAULT_TABLE_INDEX}; use core::fmt; use core::ops; use core::{u32, usize}; -use func::{FuncInstance, FuncInstanceInternal, FuncRef}; -use host::Externals; +use func::{FuncInstanceInternal, FuncRef}; +use host::{Externals, RuntimeArgs}; use isa; use memory::MemoryRef; use memory_units::Pages; @@ -222,11 +222,35 @@ impl Interpreter { &self.state } - pub(crate) fn start_execution( + /// Run func using this interpreter. + /// + /// # Errors + /// + /// Returns `Err` if `args` types is not match function [`signature`] or + /// if [`Trap`] at execution time occured. + /// + /// [`signature`]: #method.signature + /// [`Trap`]: #enum.Trap.html + pub fn invoke( &mut self, - externals: &mut E, func: &FuncRef, args: &[RuntimeValue], + externals: &mut E, + ) -> Result, Trap> { + check_function_args(func.signature(), &args)?; + match *func.as_internal() { + FuncInstanceInternal::Internal { .. } => self.start_execution(func, args, externals), + FuncInstanceInternal::Host { + ref host_func_index, .. + } => externals.invoke_index(*host_func_index, args.into()), + } + } + + pub(crate) fn start_execution( + &mut self, + func: &FuncRef, + args: &[RuntimeValue], + externals: &mut E, ) -> Result, Trap> { // Ensure that the VM has not been executed. This is checked in `FuncInvocation::start_execution`. assert!(self.state == InterpreterState::Initialized); @@ -318,12 +342,17 @@ impl Interpreter { self.call_stack.push(function_context)?; self.call_stack.push(nested_context)?; } - FuncInstanceInternal::Host { ref signature, .. } => { + FuncInstanceInternal::Host { + ref signature, + host_func_index, + } => { let args = prepare_function_args(signature, &mut self.value_stack); // We push the function context first. If the VM is not resumable, it does no harm. If it is, we then save the context here. self.call_stack.push(function_context)?; - let return_val = match FuncInstance::invoke(&nested_func, &args, externals) { + let return_val = match externals + .invoke_index(host_func_index, RuntimeArgs::from(args.as_ref())) + { Ok(val) => val, Err(trap) => { if trap.kind().is_host() {