Reintroduce FuncInstance; Hide internals

This commit is contained in:
Sergey Pepyakin 2018-01-22 20:07:30 +03:00
parent 730ff68599
commit bf2b2acbc5
6 changed files with 56 additions and 54 deletions

View File

@ -7,7 +7,7 @@ use std::fs::File;
use wasmi::{ use wasmi::{
Error as InterpreterError, ModuleInstance, ModuleRef, Error as InterpreterError, ModuleInstance, ModuleRef,
Externals, RuntimeValue, FuncRef, TryInto, ModuleImportResolver, Externals, RuntimeValue, FuncRef, TryInto, ModuleImportResolver,
HostError, ImportsBuilder, Signature, ValueType, FuncInstance, HostError, ImportsBuilder, Signature, ValueType,
}; };
#[derive(Debug)] #[derive(Debug)]
@ -175,9 +175,9 @@ impl<'a> ModuleImportResolver for RuntimeModuleImportResolver {
) -> Result<FuncRef, InterpreterError> { ) -> Result<FuncRef, InterpreterError> {
let func_ref = match field_name { let func_ref = match field_name {
"set" => { "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( _ => return Err(
InterpreterError::Function( InterpreterError::Function(
format!("host module doesn't export function with name {}", field_name) format!("host module doesn't export function with name {}", field_name)

View File

@ -13,7 +13,8 @@ use wasmi::{
GlobalInstance, GlobalRef, ImportResolver, ImportsBuilder, GlobalInstance, GlobalRef, ImportResolver, ImportsBuilder,
MemoryInstance, MemoryRef, ModuleImportResolver, ModuleInstance, MemoryInstance, MemoryRef, ModuleImportResolver, ModuleInstance,
ModuleRef, RuntimeValue, TableInstance, TableRef, ValueType, ModuleRef, RuntimeValue, TableInstance, TableRef, ValueType,
load_from_buffer, LoadedModule, Signature, MemoryDescriptor, TableDescriptor, GlobalDescriptor, load_from_buffer, LoadedModule, Signature, MemoryDescriptor,
TableDescriptor, GlobalDescriptor, FuncInstance,
}; };
#[derive(Debug)] #[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); return Ok(func);
} }

View File

@ -14,26 +14,17 @@ use common::{DEFAULT_FRAME_STACK_LIMIT, DEFAULT_VALUE_STACK_LIMIT};
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct FuncRef(Rc<FuncInstance>); pub struct FuncRef(Rc<FuncInstance>);
impl FuncRef { impl ::std::ops::Deref for FuncRef {
pub fn alloc_host(signature: Signature, host_func_index: usize) -> FuncRef { type Target = FuncInstance;
let func = FuncInstance::Host { fn deref(&self) -> &FuncInstance {
signature,
host_func_index,
};
FuncRef(Rc::new(func))
}
pub fn signature(&self) -> &Signature {
self.0.signature()
}
pub(crate) fn as_instance(&self) -> &FuncInstance {
&self.0 &self.0
} }
} }
pub struct FuncInstance(FuncInstanceInternal);
#[derive(Clone)] #[derive(Clone)]
pub(crate) enum FuncInstance { pub(crate) enum FuncInstanceInternal {
Internal { Internal {
signature: Rc<Signature>, signature: Rc<Signature>,
module: Weak<ModuleInstance>, module: Weak<ModuleInstance>,
@ -47,8 +38,8 @@ pub(crate) enum FuncInstance {
impl fmt::Debug for FuncInstance { impl fmt::Debug for FuncInstance {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self { match self.as_internal() {
&FuncInstance::Internal { &FuncInstanceInternal::Internal {
ref signature, ref signature,
.. ..
} => { } => {
@ -60,7 +51,7 @@ impl fmt::Debug for FuncInstance {
signature, signature,
) )
} }
&FuncInstance::Host { ref signature, .. } => { &FuncInstanceInternal::Host { ref signature, .. } => {
write!(f, "Host {{ signature={:?} }}", signature) write!(f, "Host {{ signature={:?} }}", signature)
} }
} }
@ -68,30 +59,42 @@ impl fmt::Debug for FuncInstance {
} }
impl 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( pub(crate) fn alloc_internal(
module: Weak<ModuleInstance>, module: Weak<ModuleInstance>,
signature: Rc<Signature>, signature: Rc<Signature>,
body: FuncBody, body: FuncBody,
) -> FuncRef { ) -> FuncRef {
let func = FuncInstance::Internal { let func = FuncInstanceInternal::Internal {
signature, signature,
module: module, module: module,
body: Rc::new(body), body: Rc::new(body),
}; };
FuncRef(Rc::new(func)) FuncRef(Rc::new(FuncInstance(func)))
} }
pub fn signature(&self) -> &Signature { pub fn signature(&self) -> &Signature {
match *self { match *self.as_internal() {
FuncInstance::Internal { ref signature, .. } => signature, FuncInstanceInternal::Internal { ref signature, .. } => signature,
FuncInstance::Host { ref signature, .. } => signature, FuncInstanceInternal::Host { ref signature, .. } => signature,
} }
} }
pub(crate) fn body(&self) -> Option<Rc<FuncBody>> { pub(crate) fn body(&self) -> Option<Rc<FuncBody>> {
match *self { match *self.as_internal() {
FuncInstance::Internal { ref body, .. } => Some(Rc::clone(body)), FuncInstanceInternal::Internal { ref body, .. } => Some(Rc::clone(body)),
FuncInstance::Host { .. } => None, FuncInstanceInternal::Host { .. } => None,
} }
} }
@ -105,8 +108,8 @@ impl FuncInstance {
Host(usize, &'a [RuntimeValue]), Host(usize, &'a [RuntimeValue]),
} }
let result = match *func.as_instance() { let result = match *func.as_internal() {
FuncInstance::Internal { ref signature, .. } => { FuncInstanceInternal::Internal { ref signature, .. } => {
let mut stack = let mut stack =
StackWithLimit::with_data(args.into_iter().cloned(), DEFAULT_VALUE_STACK_LIMIT); StackWithLimit::with_data(args.into_iter().cloned(), DEFAULT_VALUE_STACK_LIMIT);
let args = prepare_function_args(signature, &mut stack)?; let args = prepare_function_args(signature, &mut stack)?;
@ -119,7 +122,7 @@ impl FuncInstance {
); );
InvokeKind::Internal(context) InvokeKind::Internal(context)
} }
FuncInstance::Host { ref host_func_index, .. } => { FuncInstanceInternal::Host { ref host_func_index, .. } => {
InvokeKind::Host(*host_func_index, &*args) InvokeKind::Host(*host_func_index, &*args)
} }
}; };

View File

@ -134,7 +134,7 @@ pub use self::host::{Externals, NopExternals, HostError};
pub use self::imports::{ModuleImportResolver, ImportResolver, ImportsBuilder}; pub use self::imports::{ModuleImportResolver, ImportResolver, ImportsBuilder};
pub use self::module::{ModuleInstance, ModuleRef, ExternVal, NotStartedModuleRef}; pub use self::module::{ModuleInstance, ModuleRef, ExternVal, NotStartedModuleRef};
pub use self::global::{GlobalInstance, GlobalRef}; 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 use self::types::{Signature, ValueType, GlobalDescriptor, TableDescriptor, MemoryDescriptor};
pub struct LoadedModule { pub struct LoadedModule {

View File

@ -7,8 +7,7 @@ use std::collections::{HashMap, VecDeque};
use parity_wasm::elements::{Opcode, BlockType, Local}; use parity_wasm::elements::{Opcode, BlockType, Local};
use {Error, Signature}; use {Error, Signature};
use module::ModuleRef; use module::ModuleRef;
use func::FuncRef; use func::{FuncRef, FuncInstance, FuncInstanceInternal};
use func::FuncInstance;
use value::{ use value::{
RuntimeValue, TryInto, WrapInto, TryTruncateInto, ExtendInto, RuntimeValue, TryInto, WrapInto, TryTruncateInto, ExtendInto,
ArithmeticOps, Integer, Float, LittleEndianConvert, TransmuteInto, 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 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_ref = function_context.function.clone();
let function_body = function_ref let function_body = function_ref
.as_instance()
.body() .body()
.expect( .expect(
"Host functions checked in function_return below; Internal functions always have a body; qed" "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) => { RunResult::NestedCall(nested_func) => {
match *nested_func.as_instance() { match *nested_func.as_internal() {
FuncInstance::Internal { .. } => { FuncInstanceInternal::Internal { .. } => {
let nested_context = function_context.nested(nested_func.clone())?; let nested_context = function_context.nested(nested_func.clone())?;
function_stack.push_back(function_context); function_stack.push_back(function_context);
function_stack.push_back(nested_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 args = prepare_function_args(signature, &mut function_context.value_stack)?;
let return_val = FuncInstance::invoke(nested_func.clone(), args.into(), self.externals)?; let return_val = FuncInstance::invoke(nested_func.clone(), args.into(), self.externals)?;
if let Some(return_val) = return_val { if let Some(return_val) = return_val {
@ -1007,9 +1005,9 @@ impl<'a, E: Externals> Interpreter<'a, E> {
impl FunctionContext { impl FunctionContext {
pub fn new<'store>(function: FuncRef, value_stack_limit: usize, frame_stack_limit: usize, signature: &Signature, args: Vec<RuntimeValue>) -> Self { pub fn new<'store>(function: FuncRef, value_stack_limit: usize, frame_stack_limit: usize, signature: &Signature, args: Vec<RuntimeValue>) -> Self {
let module = match *function.as_instance() { let module = match *function.as_internal() {
FuncInstance::Internal { ref module, .. } => module.upgrade().expect("module deallocated"), FuncInstanceInternal::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"), 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 { FunctionContext {
is_initialized: false, is_initialized: false,
@ -1025,9 +1023,9 @@ impl FunctionContext {
pub fn nested(&mut self, function: FuncRef) -> Result<Self, Error> { pub fn nested(&mut self, function: FuncRef) -> Result<Self, Error> {
let (function_locals, module, function_return_type) = { let (function_locals, module, function_return_type) = {
let module = match *function.as_instance() { let module = match *function.as_internal() {
FuncInstance::Internal { ref module, .. } => module.upgrade().expect("module deallocated"), FuncInstanceInternal::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"), 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_type = function.signature();
let function_return_type = function_type.return_type().map(|vt| BlockType::Value(vt.into_elements())).unwrap_or(BlockType::NoResult); let function_return_type = function_type.return_type().map(|vt| BlockType::Value(vt.into_elements())).unwrap_or(BlockType::NoResult);

View File

@ -1,5 +1,5 @@
use { use {
Error, Signature, Externals, FuncRef, HostError, ImportsBuilder, Error, Signature, Externals, FuncInstance, FuncRef, HostError, ImportsBuilder,
MemoryInstance, MemoryRef, TableInstance, TableRef, ModuleImportResolver, ModuleInstance, ModuleRef, MemoryInstance, MemoryRef, TableInstance, TableRef, ModuleImportResolver, ModuleInstance, ModuleRef,
RuntimeValue, TryInto, LoadedModule, load_from_buffer, TableDescriptor, MemoryDescriptor, 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( 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( 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; let host_func_index = table_index + 1;
self.added_funcs += 1; self.added_funcs += 1;
let added_func = FuncRef::alloc_host( let added_func = FuncInstance::alloc_host(
Signature::new(&[], Some(ValueType::I32)), Signature::new(&[], Some(ValueType::I32)),
host_func_index as usize, 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( fn resolve_table(