From bf2b2acbc5d739781bc9b506abc3db951193f5c1 Mon Sep 17 00:00:00 2001 From: Sergey Pepyakin Date: Mon, 22 Jan 2018 20:07:30 +0300 Subject: [PATCH] Reintroduce FuncInstance; Hide internals --- examples/tictactoe.rs | 6 ++--- spec/src/run.rs | 5 ++-- src/func.rs | 61 +++++++++++++++++++++++-------------------- src/lib.rs | 2 +- src/runner.rs | 22 +++++++--------- src/tests/host.rs | 14 +++++----- 6 files changed, 56 insertions(+), 54 deletions(-) diff --git a/examples/tictactoe.rs b/examples/tictactoe.rs index b7decbb..76760fc 100644 --- a/examples/tictactoe.rs +++ b/examples/tictactoe.rs @@ -7,7 +7,7 @@ use std::fs::File; use wasmi::{ Error as InterpreterError, ModuleInstance, ModuleRef, Externals, RuntimeValue, FuncRef, TryInto, ModuleImportResolver, - HostError, ImportsBuilder, Signature, ValueType, + FuncInstance, HostError, ImportsBuilder, Signature, ValueType, }; #[derive(Debug)] @@ -175,9 +175,9 @@ impl<'a> ModuleImportResolver for RuntimeModuleImportResolver { ) -> Result { let func_ref = match field_name { "set" => { - FuncRef::alloc_host(Signature::new(&[ValueType::I32], None), SET_FUNC_INDEX) + FuncInstance::alloc_host(Signature::new(&[ValueType::I32], None), SET_FUNC_INDEX) }, - "get" => FuncRef::alloc_host(Signature::new(&[ValueType::I32], Some(ValueType::I32)), GET_FUNC_INDEX), + "get" => FuncInstance::alloc_host(Signature::new(&[ValueType::I32], Some(ValueType::I32)), GET_FUNC_INDEX), _ => return Err( InterpreterError::Function( format!("host module doesn't export function with name {}", field_name) diff --git a/spec/src/run.rs b/spec/src/run.rs index 4cd5ac2..e85f833 100644 --- a/spec/src/run.rs +++ b/spec/src/run.rs @@ -13,7 +13,8 @@ use wasmi::{ GlobalInstance, GlobalRef, ImportResolver, ImportsBuilder, MemoryInstance, MemoryRef, ModuleImportResolver, ModuleInstance, ModuleRef, RuntimeValue, TableInstance, TableRef, ValueType, - load_from_buffer, LoadedModule, Signature, MemoryDescriptor, TableDescriptor, GlobalDescriptor, + load_from_buffer, LoadedModule, Signature, MemoryDescriptor, + TableDescriptor, GlobalDescriptor, FuncInstance, }; #[derive(Debug)] @@ -81,7 +82,7 @@ impl ModuleImportResolver for SpecModule { )); } - let func = FuncRef::alloc_host(func_type.clone(), PRINT_FUNC_INDEX); + let func = FuncInstance::alloc_host(func_type.clone(), PRINT_FUNC_INDEX); return Ok(func); } diff --git a/src/func.rs b/src/func.rs index 5cfc8fb..7e1c443 100644 --- a/src/func.rs +++ b/src/func.rs @@ -14,26 +14,17 @@ use common::{DEFAULT_FRAME_STACK_LIMIT, DEFAULT_VALUE_STACK_LIMIT}; #[derive(Clone, Debug)] pub struct FuncRef(Rc); -impl FuncRef { - pub fn alloc_host(signature: Signature, host_func_index: usize) -> FuncRef { - let func = FuncInstance::Host { - signature, - host_func_index, - }; - FuncRef(Rc::new(func)) - } - - pub fn signature(&self) -> &Signature { - self.0.signature() - } - - pub(crate) fn as_instance(&self) -> &FuncInstance { +impl ::std::ops::Deref for FuncRef { + type Target = FuncInstance; + fn deref(&self) -> &FuncInstance { &self.0 } } +pub struct FuncInstance(FuncInstanceInternal); + #[derive(Clone)] -pub(crate) enum FuncInstance { +pub(crate) enum FuncInstanceInternal { Internal { signature: Rc, module: Weak, @@ -47,8 +38,8 @@ pub(crate) enum FuncInstance { impl fmt::Debug for FuncInstance { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - &FuncInstance::Internal { + match self.as_internal() { + &FuncInstanceInternal::Internal { ref signature, .. } => { @@ -60,7 +51,7 @@ impl fmt::Debug for FuncInstance { signature, ) } - &FuncInstance::Host { ref signature, .. } => { + &FuncInstanceInternal::Host { ref signature, .. } => { write!(f, "Host {{ signature={:?} }}", signature) } } @@ -68,30 +59,42 @@ impl fmt::Debug for FuncInstance { } impl FuncInstance { + pub fn alloc_host(signature: Signature, host_func_index: usize) -> FuncRef { + let func = FuncInstanceInternal::Host { + signature, + host_func_index, + }; + FuncRef(Rc::new(FuncInstance(func))) + } + + pub(crate) fn as_internal(&self) -> &FuncInstanceInternal { + &self.0 + } + pub(crate) fn alloc_internal( module: Weak, signature: Rc, body: FuncBody, ) -> FuncRef { - let func = FuncInstance::Internal { + let func = FuncInstanceInternal::Internal { signature, module: module, body: Rc::new(body), }; - FuncRef(Rc::new(func)) + FuncRef(Rc::new(FuncInstance(func))) } pub fn signature(&self) -> &Signature { - match *self { - FuncInstance::Internal { ref signature, .. } => signature, - FuncInstance::Host { ref signature, .. } => signature, + match *self.as_internal() { + FuncInstanceInternal::Internal { ref signature, .. } => signature, + FuncInstanceInternal::Host { ref signature, .. } => signature, } } pub(crate) fn body(&self) -> Option> { - match *self { - FuncInstance::Internal { ref body, .. } => Some(Rc::clone(body)), - FuncInstance::Host { .. } => None, + match *self.as_internal() { + FuncInstanceInternal::Internal { ref body, .. } => Some(Rc::clone(body)), + FuncInstanceInternal::Host { .. } => None, } } @@ -105,8 +108,8 @@ impl FuncInstance { Host(usize, &'a [RuntimeValue]), } - let result = match *func.as_instance() { - FuncInstance::Internal { ref signature, .. } => { + let result = match *func.as_internal() { + FuncInstanceInternal::Internal { ref signature, .. } => { let mut stack = StackWithLimit::with_data(args.into_iter().cloned(), DEFAULT_VALUE_STACK_LIMIT); let args = prepare_function_args(signature, &mut stack)?; @@ -119,7 +122,7 @@ impl FuncInstance { ); InvokeKind::Internal(context) } - FuncInstance::Host { ref host_func_index, .. } => { + FuncInstanceInternal::Host { ref host_func_index, .. } => { InvokeKind::Host(*host_func_index, &*args) } }; diff --git a/src/lib.rs b/src/lib.rs index 497ac58..da44a23 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -134,7 +134,7 @@ pub use self::host::{Externals, NopExternals, HostError}; pub use self::imports::{ModuleImportResolver, ImportResolver, ImportsBuilder}; pub use self::module::{ModuleInstance, ModuleRef, ExternVal, NotStartedModuleRef}; pub use self::global::{GlobalInstance, GlobalRef}; -pub use self::func::{FuncRef}; +pub use self::func::{FuncInstance, FuncRef}; pub use self::types::{Signature, ValueType, GlobalDescriptor, TableDescriptor, MemoryDescriptor}; pub struct LoadedModule { diff --git a/src/runner.rs b/src/runner.rs index cb89262..f418c1f 100644 --- a/src/runner.rs +++ b/src/runner.rs @@ -7,8 +7,7 @@ use std::collections::{HashMap, VecDeque}; use parity_wasm::elements::{Opcode, BlockType, Local}; use {Error, Signature}; use module::ModuleRef; -use func::FuncRef; -use func::FuncInstance; +use func::{FuncRef, FuncInstance, FuncInstanceInternal}; use value::{ RuntimeValue, TryInto, WrapInto, TryTruncateInto, ExtendInto, ArithmeticOps, Integer, Float, LittleEndianConvert, TransmuteInto, @@ -78,7 +77,6 @@ impl<'a, E: Externals> Interpreter<'a, E> { 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_body = function_ref - .as_instance() .body() .expect( "Host functions checked in function_return below; Internal functions always have a body; qed" @@ -101,13 +99,13 @@ impl<'a, E: Externals> Interpreter<'a, E> { } }, RunResult::NestedCall(nested_func) => { - match *nested_func.as_instance() { - FuncInstance::Internal { .. } => { + match *nested_func.as_internal() { + FuncInstanceInternal::Internal { .. } => { let nested_context = function_context.nested(nested_func.clone())?; function_stack.push_back(function_context); function_stack.push_back(nested_context); }, - FuncInstance::Host { ref signature, .. } => { + FuncInstanceInternal::Host { ref signature, .. } => { let args = prepare_function_args(signature, &mut function_context.value_stack)?; let return_val = FuncInstance::invoke(nested_func.clone(), args.into(), self.externals)?; if let Some(return_val) = return_val { @@ -1007,9 +1005,9 @@ impl<'a, E: Externals> Interpreter<'a, E> { impl FunctionContext { pub fn new<'store>(function: FuncRef, value_stack_limit: usize, frame_stack_limit: usize, signature: &Signature, args: Vec) -> Self { - let module = match *function.as_instance() { - FuncInstance::Internal { ref module, .. } => module.upgrade().expect("module deallocated"), - FuncInstance::Host { .. } => panic!("Host functions can't be called as internally defined functions; Thus FunctionContext can be created only with internally defined functions; qed"), + let module = match *function.as_internal() { + FuncInstanceInternal::Internal { ref module, .. } => module.upgrade().expect("module deallocated"), + FuncInstanceInternal::Host { .. } => panic!("Host functions can't be called as internally defined functions; Thus FunctionContext can be created only with internally defined functions; qed"), }; FunctionContext { is_initialized: false, @@ -1025,9 +1023,9 @@ impl FunctionContext { pub fn nested(&mut self, function: FuncRef) -> Result { let (function_locals, module, function_return_type) = { - let module = match *function.as_instance() { - FuncInstance::Internal { ref module, .. } => module.upgrade().expect("module deallocated"), - FuncInstance::Host { .. } => panic!("Host functions can't be called as internally defined functions; Thus FunctionContext can be created only with internally defined functions; qed"), + let module = match *function.as_internal() { + FuncInstanceInternal::Internal { ref module, .. } => module.upgrade().expect("module deallocated"), + FuncInstanceInternal::Host { .. } => panic!("Host functions can't be called as internally defined functions; Thus FunctionContext can be created only with internally defined functions; qed"), }; let function_type = function.signature(); let function_return_type = function_type.return_type().map(|vt| BlockType::Value(vt.into_elements())).unwrap_or(BlockType::NoResult); diff --git a/src/tests/host.rs b/src/tests/host.rs index a952957..c96a2d9 100644 --- a/src/tests/host.rs +++ b/src/tests/host.rs @@ -1,5 +1,5 @@ use { - Error, Signature, Externals, FuncRef, HostError, ImportsBuilder, + Error, Signature, Externals, FuncInstance, FuncRef, HostError, ImportsBuilder, MemoryInstance, MemoryRef, TableInstance, TableRef, ModuleImportResolver, ModuleInstance, ModuleRef, RuntimeValue, TryInto, LoadedModule, load_from_buffer, TableDescriptor, MemoryDescriptor, }; @@ -187,7 +187,7 @@ impl ModuleImportResolver for TestHost { ))); } - Ok(FuncRef::alloc_host(signature.clone(), index)) + Ok(FuncInstance::alloc_host(signature.clone(), index)) } fn resolve_memory( @@ -435,7 +435,7 @@ fn defer_providing_externals() { ))); } - Ok(FuncRef::alloc_host(signature.clone(), INC_FUNC_INDEX)) + Ok(FuncInstance::alloc_host(signature.clone(), INC_FUNC_INDEX)) } fn resolve_memory( @@ -560,7 +560,7 @@ fn two_envs_one_externals() { } }; - Ok(FuncRef::alloc_host(signature.clone(), index)) + Ok(FuncInstance::alloc_host(signature.clone(), index)) } } @@ -584,7 +584,7 @@ fn two_envs_one_externals() { } }; - Ok(FuncRef::alloc_host(signature.clone(), index)) + Ok(FuncInstance::alloc_host(signature.clone(), index)) } } @@ -658,7 +658,7 @@ fn dynamically_add_host_func() { let host_func_index = table_index + 1; self.added_funcs += 1; - let added_func = FuncRef::alloc_host( + let added_func = FuncInstance::alloc_host( Signature::new(&[], Some(ValueType::I32)), host_func_index as usize, ); @@ -688,7 +688,7 @@ fn dynamically_add_host_func() { )) } }; - Ok(FuncRef::alloc_host(signature.clone(), index)) + Ok(FuncInstance::alloc_host(signature.clone(), index)) } fn resolve_table(