mirror of
https://github.com/fluencelabs/parity-wasm
synced 2025-05-24 13:11:34 +00:00
static variants of passed functions
This commit is contained in:
parent
9c2061c63c
commit
f2ee624cea
@ -1,5 +1,6 @@
|
||||
use std::sync::Arc;
|
||||
use std::collections::HashMap;
|
||||
use std::borrow::Cow;
|
||||
use parking_lot::RwLock;
|
||||
use elements::{FunctionType, Internal, ValueType};
|
||||
use interpreter::Error;
|
||||
@ -22,20 +23,62 @@ pub trait UserFunctionExecutor {
|
||||
fn execute(&mut self, name: &str, context: CallerContext) -> Result<Option<RuntimeValue>, Error>;
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum UserFunctionDescriptor {
|
||||
Static(&'static str, &'static [ValueType]),
|
||||
Heap(String, Vec<ValueType>),
|
||||
}
|
||||
|
||||
/// User function type.
|
||||
#[derive(Clone)]
|
||||
pub struct UserFunction {
|
||||
/// User function name.
|
||||
pub name: String,
|
||||
/// User function parameters (for signature matching).
|
||||
pub params: Vec<ValueType>,
|
||||
/// User function return type (for signature matching).
|
||||
pub desc: UserFunctionDescriptor,
|
||||
pub result: Option<ValueType>,
|
||||
}
|
||||
|
||||
impl UserFunction {
|
||||
/// New function with statically known params
|
||||
pub fn statik(name: &'static str, params: &'static [ValueType], result: Option<ValueType>) -> Self {
|
||||
UserFunction {
|
||||
desc: UserFunctionDescriptor::Static(name, params),
|
||||
result: result,
|
||||
}
|
||||
}
|
||||
|
||||
/// New function with statically unknown params
|
||||
pub fn heap(name: String, params: Vec<ValueType>, result: Option<ValueType>) -> Self {
|
||||
UserFunction {
|
||||
desc: UserFunctionDescriptor::Heap(name, params),
|
||||
result: result,
|
||||
}
|
||||
}
|
||||
|
||||
/// Name of the function
|
||||
pub fn name(&self) -> &str {
|
||||
match self.desc {
|
||||
UserFunctionDescriptor::Static(name, _) => name,
|
||||
UserFunctionDescriptor::Heap(ref name, _) => name,
|
||||
}
|
||||
}
|
||||
|
||||
/// Arguments of the function
|
||||
pub fn params(&self) -> &[ValueType] {
|
||||
match self.desc {
|
||||
UserFunctionDescriptor::Static(_, params) => params,
|
||||
UserFunctionDescriptor::Heap(_, ref params) => params,
|
||||
}
|
||||
}
|
||||
|
||||
/// Return type of the function
|
||||
pub fn result(&self) -> Option<ValueType> {
|
||||
self.result
|
||||
}
|
||||
}
|
||||
|
||||
/// Set of user-defined functions
|
||||
pub struct UserFunctions<'a> {
|
||||
/// Functions list.
|
||||
pub functions: Vec<UserFunction>,
|
||||
pub functions: Cow<'static, [UserFunction]>,
|
||||
/// Functions executor.
|
||||
pub executor: &'a mut UserFunctionExecutor,
|
||||
}
|
||||
@ -49,7 +92,7 @@ pub struct NativeModuleInstance<'a> {
|
||||
/// By-name functions index.
|
||||
by_name: HashMap<String, u32>,
|
||||
/// User functions list.
|
||||
functions: Vec<UserFunction>,
|
||||
functions: Cow<'static, [UserFunction]>,
|
||||
}
|
||||
|
||||
impl<'a> NativeModuleInstance<'a> {
|
||||
@ -58,7 +101,7 @@ impl<'a> NativeModuleInstance<'a> {
|
||||
Ok(NativeModuleInstance {
|
||||
env: env,
|
||||
executor: RwLock::new(functions.executor),
|
||||
by_name: functions.functions.iter().enumerate().map(|(i, f)| (f.name.clone(), i as u32)).collect(),
|
||||
by_name: functions.functions.iter().enumerate().map(|(i, f)| (f.name().to_owned(), i as u32)).collect(),
|
||||
functions: functions.functions,
|
||||
})
|
||||
}
|
||||
@ -98,7 +141,7 @@ impl<'a> ModuleInstanceInterface for NativeModuleInstance<'a> {
|
||||
self.functions
|
||||
.get((index - NATIVE_INDEX_FUNC_MIN) as usize)
|
||||
.ok_or(Error::Native(format!("missing native env function with index {}", index)))
|
||||
.map(|f| FunctionType::new(f.params.clone(), f.result.clone()))
|
||||
.map(|f| FunctionType::new(f.params().to_vec(), f.result().clone()))
|
||||
}
|
||||
|
||||
fn table(&self, index: ItemIndex) -> Result<Arc<TableInstance>, Error> {
|
||||
@ -130,7 +173,7 @@ impl<'a> ModuleInstanceInterface for NativeModuleInstance<'a> {
|
||||
self.functions
|
||||
.get((index - NATIVE_INDEX_FUNC_MIN) as usize)
|
||||
.ok_or(Error::Native(format!("trying to call native function with index {}", index)))
|
||||
.and_then(|f| self.executor.write().execute(&f.name, outer))
|
||||
.and_then(|f| self.executor.write().execute(&f.name(), outer))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ use builder::module;
|
||||
use elements::{ExportEntry, Internal, ImportEntry, External, GlobalEntry, GlobalType,
|
||||
InitExpr, ValueType, BlockType, Opcodes, Opcode, FunctionType};
|
||||
use interpreter::Error;
|
||||
use interpreter::env_native::{env_native_module, UserFunction, UserFunctions, UserFunctionExecutor};
|
||||
use interpreter::env_native::{env_native_module, UserFunction, UserFunctions, UserFunctionExecutor, UserFunctionDescriptor};
|
||||
use interpreter::imports::ModuleImports;
|
||||
use interpreter::memory::MemoryInstance;
|
||||
use interpreter::module::{ModuleInstanceInterface, CallerContext, ItemIndex, ExecutionParams};
|
||||
@ -123,6 +123,25 @@ fn global_get_set() {
|
||||
assert_eq!(module.execute_index(2, vec![].into()).unwrap_err(), Error::Variable("trying to update variable of type I32 with value of type Some(I64)".into()));
|
||||
}
|
||||
|
||||
const SIGNATURE_I32: &'static [ValueType] = &[ValueType::I32];
|
||||
|
||||
const SIGNATURES: &'static [UserFunction] = &[
|
||||
UserFunction {
|
||||
desc: UserFunctionDescriptor::Static(
|
||||
"add",
|
||||
SIGNATURE_I32,
|
||||
),
|
||||
result: Some(ValueType::I32),
|
||||
},
|
||||
UserFunction {
|
||||
desc: UserFunctionDescriptor::Static(
|
||||
"sub",
|
||||
SIGNATURE_I32,
|
||||
),
|
||||
result: Some(ValueType::I32),
|
||||
},
|
||||
];
|
||||
|
||||
#[test]
|
||||
fn single_program_different_modules() {
|
||||
// user function executor
|
||||
@ -170,15 +189,7 @@ fn single_program_different_modules() {
|
||||
{
|
||||
let functions: UserFunctions = UserFunctions {
|
||||
executor: &mut executor,
|
||||
functions: vec![UserFunction {
|
||||
name: "add".into(),
|
||||
params: vec![ValueType::I32],
|
||||
result: Some(ValueType::I32),
|
||||
}, UserFunction {
|
||||
name: "sub".into(),
|
||||
params: vec![ValueType::I32],
|
||||
result: Some(ValueType::I32),
|
||||
}],
|
||||
functions: ::std::borrow::Cow::from(SIGNATURES),
|
||||
};
|
||||
let native_env_instance = Arc::new(env_native_module(env_instance, functions).unwrap());
|
||||
let params = ExecutionParams::with_external("env".into(), native_env_instance);
|
||||
|
Loading…
x
Reference in New Issue
Block a user