This commit is contained in:
Sergey Pepyakin 2017-12-18 16:12:59 +03:00
parent 569d89357f
commit e74b47758a
2 changed files with 55 additions and 39 deletions

View File

@ -1,7 +1,7 @@
use std::rc::Rc;
use std::collections::HashMap;
use std::collections::hash_map::Entry;
use elements::{FunctionType, ValueType, GlobalType, MemoryType, TableType};
use elements::{FunctionType, GlobalType, MemoryType, TableType, ValueType};
use interpreter::module::{ExternVal, ModuleInstance};
use interpreter::func::FuncInstance;
use interpreter::global::GlobalInstance;
@ -11,7 +11,8 @@ use interpreter::value::{RuntimeValue, TryInto};
use interpreter::Error;
use interpreter::ImportResolver;
pub type HostFunc<St> = Fn(&St, &[RuntimeValue]) -> Result<Option<RuntimeValue>, Error>;
pub type HostFunc<St> = Fn(&St, &[RuntimeValue])
-> Result<Option<RuntimeValue>, Error>;
pub struct HostModuleBuilder<St> {
exports: HashMap<String, ExternVal<St>>,
@ -34,10 +35,12 @@ impl<St> HostModuleBuilder<St> {
f: Cl,
) {
let func_type = FunctionType::new(vec![], Ret::value_type());
let host_func = Rc::new(move |state: &St, _args: &[RuntimeValue]| -> Result<Option<RuntimeValue>, Error> {
let result = f(state)?.into_return_val();
Ok(result)
});
let host_func = Rc::new(
move |state: &St, _args: &[RuntimeValue]| -> Result<Option<RuntimeValue>, Error> {
let result = f(state)?.into_return_val();
Ok(result)
},
);
let func = FuncInstance::alloc_host(Rc::new(func_type), host_func);
self.insert_func(name, func);
@ -54,11 +57,13 @@ impl<St> HostModuleBuilder<St> {
f: Cl,
) {
let func_type = FunctionType::new(vec![P1::value_type()], Ret::value_type());
let host_func = Rc::new(move |state: &St, args: &[RuntimeValue]| -> Result<Option<RuntimeValue>, Error> {
let arg0 = P1::from_arg(&args[0]);
let result = f(state, arg0)?.into_return_val();
Ok(result)
});
let host_func = Rc::new(
move |state: &St, args: &[RuntimeValue]| -> Result<Option<RuntimeValue>, Error> {
let arg0 = P1::from_arg(&args[0]);
let result = f(state, arg0)?.into_return_val();
Ok(result)
},
);
let func = FuncInstance::alloc_host(Rc::new(func_type), host_func);
self.insert_func(name, func);
@ -75,13 +80,16 @@ impl<St> HostModuleBuilder<St> {
name: N,
f: Cl,
) {
let func_type = FunctionType::new(vec![P1::value_type(), P2::value_type()], Ret::value_type());
let host_func = Rc::new(move |state: &St, args: &[RuntimeValue]| -> Result<Option<RuntimeValue>, Error> {
let p1 = P1::from_arg(&args[0]);
let p2 = P2::from_arg(&args[1]);
let result = f(state, p1, p2)?.into_return_val();
Ok(result)
});
let func_type =
FunctionType::new(vec![P1::value_type(), P2::value_type()], Ret::value_type());
let host_func = Rc::new(
move |state: &St, args: &[RuntimeValue]| -> Result<Option<RuntimeValue>, Error> {
let p1 = P1::from_arg(&args[0]);
let p2 = P2::from_arg(&args[1]);
let result = f(state, p1, p2)?.into_return_val();
Ok(result)
},
);
let func = FuncInstance::alloc_host(Rc::new(func_type), host_func);
self.insert_func(name, func);
@ -127,9 +135,7 @@ impl<St> HostModuleBuilder<St> {
pub fn build(self) -> HostModule<St> {
let internal_instance = Rc::new(ModuleInstance::with_exports(self.exports));
HostModule {
internal_instance
}
HostModule { internal_instance }
}
}
@ -157,7 +163,8 @@ impl<St> ImportResolver<St> for HostModule<St> {
field_name: &str,
global_type: &GlobalType,
) -> Result<Rc<GlobalInstance>, Error> {
self.internal_instance.resolve_global(field_name, global_type)
self.internal_instance
.resolve_global(field_name, global_type)
}
fn resolve_memory(
@ -165,7 +172,8 @@ impl<St> ImportResolver<St> for HostModule<St> {
field_name: &str,
memory_type: &MemoryType,
) -> Result<Rc<MemoryInstance>, Error> {
self.internal_instance.resolve_memory(field_name, memory_type)
self.internal_instance
.resolve_memory(field_name, memory_type)
}
fn resolve_table(
@ -177,7 +185,10 @@ impl<St> ImportResolver<St> for HostModule<St> {
}
}
pub trait FromArg where Self: Sized {
pub trait FromArg
where
Self: Sized,
{
fn from_arg(arg: &RuntimeValue) -> Self;
fn value_type() -> ValueType;
}

View File

@ -3,12 +3,12 @@ use std::cell::RefCell;
use std::fmt;
use std::collections::HashMap;
use std::borrow::Cow;
use elements::{External, FunctionType, GlobalType, InitExpr, Internal, MemoryType, Module,
Opcode, ResizableLimits, TableType, Type};
use elements::{External, FunctionType, GlobalType, InitExpr, Internal, MemoryType, Module, Opcode,
ResizableLimits, TableType, Type};
use interpreter::{Error, MemoryInstance, RuntimeValue, TableInstance};
use interpreter::imports::{ImportResolver, Imports};
use interpreter::global::GlobalInstance;
use interpreter::func::{FuncInstance, FuncBody};
use interpreter::func::{FuncBody, FuncInstance};
use validation::validate_module;
use common::{DEFAULT_MEMORY_INDEX, DEFAULT_TABLE_INDEX};
@ -32,12 +32,16 @@ impl<St> Clone for ExternVal<St> {
impl<St> fmt::Debug for ExternVal<St> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "ExternVal {{ {} }}", match *self {
ExternVal::Func(_) => "Func",
ExternVal::Table(_) => "Table",
ExternVal::Memory(_) => "Memory",
ExternVal::Global(_) => "Global",
})
write!(
f,
"ExternVal {{ {} }}",
match *self {
ExternVal::Func(_) => "Func",
ExternVal::Table(_) => "Table",
ExternVal::Memory(_) => "Memory",
ExternVal::Global(_) => "Global",
}
)
}
}
@ -244,11 +248,8 @@ impl<St> ModuleInstance<St> {
opcodes: body.code().clone(),
labels: labels,
};
let func_instance = FuncInstance::alloc_internal(
Rc::clone(instance),
func_type,
func_body
);
let func_instance =
FuncInstance::alloc_internal(Rc::clone(instance), func_type, func_body);
instance.push_func(func_instance);
}
}
@ -625,7 +626,11 @@ fn match_limits(l1: &ResizableLimits, l2: &ResizableLimits) -> Result<(), Error>
pub fn check_limits(limits: &ResizableLimits) -> Result<(), Error> {
if let Some(maximum) = limits.maximum() {
if maximum < limits.initial() {
return Err(Error::Validation(format!("maximum limit {} is lesser than minimum {}", maximum, limits.initial())));
return Err(Error::Validation(format!(
"maximum limit {} is lesser than minimum {}",
maximum,
limits.initial()
)));
}
}