This commit is contained in:
Sergey Pepyakin
2017-11-27 19:09:48 +03:00
parent 61c2197bd8
commit 05a9f4067e
3 changed files with 31 additions and 23 deletions

View File

@ -92,7 +92,7 @@ struct EmscriptenFunctionExecutor {
params: EnvParams, params: EnvParams,
} }
impl UserFunctionExecutor for EmscriptenFunctionExecutor { impl<'a> UserFunctionExecutor for EmscriptenFunctionExecutor {
fn execute( fn execute(
&mut self, &mut self,
name: &str, name: &str,
@ -241,7 +241,7 @@ pub fn env_module(params: EnvParams) -> Result<Arc<ModuleInstanceInterface>, Err
let stack_top = params.static_size.unwrap_or(DEFAULT_STACK_TOP); let stack_top = params.static_size.unwrap_or(DEFAULT_STACK_TOP);
let elements = UserDefinedElements { let elements = UserDefinedElements {
executor: Some(&mut function_executor), executor: Some(function_executor),
globals: vec![ globals: vec![
("STACK_BASE".into(), Arc::new(VariableInstance::new(false, VariableType::I32, RuntimeValue::I32(stack_top as i32)).unwrap())), ("STACK_BASE".into(), Arc::new(VariableInstance::new(false, VariableType::I32, RuntimeValue::I32(stack_top as i32)).unwrap())),
("STACKTOP".into(), Arc::new(VariableInstance::new(false, VariableType::I32, RuntimeValue::I32(stack_top as i32)).unwrap())), ("STACKTOP".into(), Arc::new(VariableInstance::new(false, VariableType::I32, RuntimeValue::I32(stack_top as i32)).unwrap())),
@ -260,7 +260,7 @@ pub fn env_module(params: EnvParams) -> Result<Arc<ModuleInstanceInterface>, Err
let mut instance = ModuleInstance::new(Weak::default(), "env".into(), module)?; let mut instance = ModuleInstance::new(Weak::default(), "env".into(), module)?;
instance.instantiate(None)?; instance.instantiate(None)?;
Ok(Arc::new(native_module(Arc::new(instance), elements)?)) Ok(native_module(Arc::new(instance), elements)?)
} }
impl Default for EnvParams { impl Default for EnvParams {

View File

@ -69,21 +69,21 @@ impl UserFunctionDescriptor {
} }
/// Set of user-defined module elements. /// Set of user-defined module elements.
pub struct UserDefinedElements<'a> { pub struct UserDefinedElements<E: UserFunctionExecutor> {
/// User globals list. /// User globals list.
pub globals: HashMap<String, Arc<VariableInstance>>, pub globals: HashMap<String, Arc<VariableInstance>>,
/// User functions list. /// User functions list.
pub functions: Cow<'static, [UserFunctionDescriptor]>, pub functions: Cow<'static, [UserFunctionDescriptor]>,
/// Functions executor. /// Functions executor.
pub executor: Option<&'a mut UserFunctionExecutor>, pub executor: Option<E>,
} }
/// Native module instance. /// Native module instance.
pub struct NativeModuleInstance<'a> { pub struct NativeModuleInstance<E: UserFunctionExecutor> {
/// Underlying module reference. /// Underlying module reference.
base: Arc<ModuleInstanceInterface>, base: Arc<ModuleInstanceInterface>,
/// User function executor. /// User function executor.
executor: RwLock<Option<&'a mut UserFunctionExecutor>>, executor: RwLock<Option<E>>,
/// By-name functions index. /// By-name functions index.
functions_by_name: HashMap<String, u32>, functions_by_name: HashMap<String, u32>,
/// User functions list. /// User functions list.
@ -94,9 +94,9 @@ pub struct NativeModuleInstance<'a> {
globals: Vec<Arc<VariableInstance>>, globals: Vec<Arc<VariableInstance>>,
} }
impl<'a> NativeModuleInstance<'a> { impl<E: UserFunctionExecutor> NativeModuleInstance<E> {
/// Create new native module /// Create new native module
pub fn new(base: Arc<ModuleInstanceInterface>, elements: UserDefinedElements<'a>) -> Result<Self, Error> { pub fn new(base: Arc<ModuleInstanceInterface>, elements: UserDefinedElements<E>) -> Result<Self, Error> {
if !elements.functions.is_empty() && elements.executor.is_none() { if !elements.functions.is_empty() && elements.executor.is_none() {
return Err(Error::Function("trying to construct native module with functions, but without executor".into())); return Err(Error::Function("trying to construct native module with functions, but without executor".into()));
} }
@ -112,7 +112,7 @@ impl<'a> NativeModuleInstance<'a> {
} }
} }
impl<'a> ModuleInstanceInterface for NativeModuleInstance<'a> { impl<E: UserFunctionExecutor> ModuleInstanceInterface for NativeModuleInstance<E> {
fn execute_index(&self, index: u32, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error> { fn execute_index(&self, index: u32, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error> {
self.base.execute_index(index, params) self.base.execute_index(index, params)
} }
@ -280,8 +280,8 @@ impl<'a> ModuleInstanceInterface for NativeModuleInstance<'a> {
/// } /// }
/// } /// }
/// ``` /// ```
pub fn native_module<'a>(base: Arc<ModuleInstanceInterface>, user_elements: UserDefinedElements<'a>) -> Result<NativeModuleInstance, Error> { pub fn native_module<'a, E: UserFunctionExecutor + 'a>(base: Arc<ModuleInstanceInterface>, user_elements: UserDefinedElements<E>) -> Result<Arc<ModuleInstanceInterface + 'a>, Error> {
NativeModuleInstance::new(base, user_elements) Ok(Arc::new(NativeModuleInstance::new(base, user_elements)?))
} }
impl<'a> PartialEq for UserFunctionDescriptor { impl<'a> PartialEq for UserFunctionDescriptor {

View File

@ -160,7 +160,7 @@ struct FunctionExecutor {
pub values: Vec<i32>, pub values: Vec<i32>,
} }
impl UserFunctionExecutor for FunctionExecutor { impl<'a> UserFunctionExecutor for &'a mut FunctionExecutor {
fn execute(&mut self, name: &str, context: CallerContext) -> Result<Option<RuntimeValue>, Error> { fn execute(&mut self, name: &str, context: CallerContext) -> Result<Option<RuntimeValue>, Error> {
match name { match name {
"add" => { "add" => {
@ -213,7 +213,7 @@ fn native_env_function() {
globals: HashMap::new(), globals: HashMap::new(),
functions: ::std::borrow::Cow::from(SIGNATURES), functions: ::std::borrow::Cow::from(SIGNATURES),
}; };
let native_env_instance = Arc::new(native_module(env_instance, functions).unwrap()); let native_env_instance = native_module(env_instance, functions).unwrap();
let params = ExecutionParams::with_external("env".into(), native_env_instance); let params = ExecutionParams::with_external("env".into(), native_env_instance);
let module = module() let module = module()
@ -265,7 +265,7 @@ fn native_env_function_own_memory() {
pub memory_ref: Arc<OwnMemoryReference>, pub memory_ref: Arc<OwnMemoryReference>,
} }
impl UserFunctionExecutor for OwnMemoryExecutor { impl<'a> UserFunctionExecutor for &'a mut OwnMemoryExecutor {
fn execute(&mut self, name: &str, context: CallerContext) -> Result<Option<RuntimeValue>, Error> { fn execute(&mut self, name: &str, context: CallerContext) -> Result<Option<RuntimeValue>, Error> {
match name { match name {
"add" => { "add" => {
@ -287,11 +287,11 @@ fn native_env_function_own_memory() {
let env_instance = program.module("env").unwrap(); let env_instance = program.module("env").unwrap();
let memory_ref = Arc::new(OwnMemoryReference { memory: RefCell::new(None) }); let memory_ref = Arc::new(OwnMemoryReference { memory: RefCell::new(None) });
let mut executor = OwnMemoryExecutor { memory_ref: memory_ref.clone() }; let mut executor = OwnMemoryExecutor { memory_ref: memory_ref.clone() };
let native_env_instance = Arc::new(native_module(env_instance, UserDefinedElements { let native_env_instance = native_module(env_instance, UserDefinedElements {
executor: Some(&mut executor), executor: Some(&mut executor),
globals: HashMap::new(), globals: HashMap::new(),
functions: ::std::borrow::Cow::from(SIGNATURES), functions: ::std::borrow::Cow::from(SIGNATURES),
}).unwrap()); }).unwrap();
let params = ExecutionParams::with_external("env".into(), native_env_instance); let params = ExecutionParams::with_external("env".into(), native_env_instance);
// create module definition with its own memory // create module definition with its own memory
@ -324,11 +324,19 @@ fn native_env_function_own_memory() {
#[test] #[test]
fn native_env_global() { fn native_env_global() {
// module constructor struct DummyExecutor;
let module_constructor = |elements| { impl UserFunctionExecutor for DummyExecutor {
fn execute(&mut self, name: &str, context: CallerContext) -> Result<Option<RuntimeValue>, Error> {
// this code should be unreachable, because we actually doesn't call any
// native functions in this test.
unreachable!();
}
}
let module_constructor = |elements: UserDefinedElements<DummyExecutor>| {
let program = ProgramInstance::with_emscripten_env(Default::default()).unwrap(); let program = ProgramInstance::with_emscripten_env(Default::default()).unwrap();
let env_instance = program.module("env").unwrap(); let env_instance = program.module("env").unwrap();
let native_env_instance = Arc::new(native_module(env_instance.clone(), elements).unwrap()); let native_env_instance = native_module(env_instance.clone(), elements).unwrap();
let params = ExecutionParams::with_external("env".into(), native_env_instance); let params = ExecutionParams::with_external("env".into(), native_env_instance);
let module = module() let module = module()
@ -384,7 +392,7 @@ fn native_custom_error() {
globals: HashMap::new(), globals: HashMap::new(),
functions: ::std::borrow::Cow::from(SIGNATURES), functions: ::std::borrow::Cow::from(SIGNATURES),
}; };
let native_env_instance = Arc::new(native_module(env_instance, functions).unwrap()); let native_env_instance = native_module(env_instance, functions).unwrap();
let params = ExecutionParams::with_external("env".into(), native_env_instance); let params = ExecutionParams::with_external("env".into(), native_env_instance);
let module = module() let module = module()
@ -444,11 +452,11 @@ fn env_native_export_entry_type_check() {
memory: program.module("env").unwrap().memory(ItemIndex::Internal(0)).unwrap(), memory: program.module("env").unwrap().memory(ItemIndex::Internal(0)).unwrap(),
values: Vec::new(), values: Vec::new(),
}; };
let native_env_instance = Arc::new(native_module(program.module("env").unwrap(), UserDefinedElements { let native_env_instance = native_module(program.module("env").unwrap(), UserDefinedElements {
executor: Some(&mut function_executor), executor: Some(&mut function_executor),
globals: vec![("ext_global".into(), Arc::new(VariableInstance::new(false, VariableType::I32, RuntimeValue::I32(1312)).unwrap()))].into_iter().collect(), globals: vec![("ext_global".into(), Arc::new(VariableInstance::new(false, VariableType::I32, RuntimeValue::I32(1312)).unwrap()))].into_iter().collect(),
functions: ::std::borrow::Cow::from(SIGNATURES), functions: ::std::borrow::Cow::from(SIGNATURES),
}).unwrap()); }).unwrap();
assert!(native_env_instance.export_entry("add", &ExportEntryType::Function(FunctionSignature::Module(&FunctionType::new(vec![ValueType::I32, ValueType::I32], Some(ValueType::I32))))).is_ok()); assert!(native_env_instance.export_entry("add", &ExportEntryType::Function(FunctionSignature::Module(&FunctionType::new(vec![ValueType::I32, ValueType::I32], Some(ValueType::I32))))).is_ok());
match native_env_instance.export_entry("add", &ExportEntryType::Function(FunctionSignature::Module(&FunctionType::new(vec![], Some(ValueType::I32))))) { match native_env_instance.export_entry("add", &ExportEntryType::Function(FunctionSignature::Module(&FunctionType::new(vec![], Some(ValueType::I32))))) {