2019-01-19 06:28:41 +00:00
|
|
|
//! Utility functions for the WebAssembly module
|
2018-10-24 09:44:33 +00:00
|
|
|
|
2019-12-11 01:12:35 +00:00
|
|
|
use wasmer_runtime::{types::Type, Module, Value};
|
|
|
|
use wasmer_runtime_core::{backend::SigRegistry, module::ExportIndex};
|
|
|
|
|
2019-01-19 06:28:41 +00:00
|
|
|
/// Detect if a provided binary is a Wasm file
|
|
|
|
pub fn is_wasm_binary(binary: &[u8]) -> bool {
|
2018-10-11 19:29:36 +00:00
|
|
|
binary.starts_with(&[b'\0', b'a', b's', b'm'])
|
|
|
|
}
|
2019-12-11 01:12:35 +00:00
|
|
|
|
2019-12-11 01:37:22 +00:00
|
|
|
#[derive(Debug, Clone)]
|
2019-12-11 01:12:35 +00:00
|
|
|
pub enum InvokeError {
|
|
|
|
CouldNotFindFunction,
|
|
|
|
ExportNotFunction,
|
|
|
|
WrongNumArgs { expected: u16, found: u16 },
|
2019-12-11 01:37:22 +00:00
|
|
|
CouldNotParseArg(String),
|
2019-12-11 01:12:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Parses arguments for the `--invoke` flag on the run command
|
|
|
|
pub fn parse_args(
|
|
|
|
module: &Module,
|
|
|
|
fn_name: &str,
|
|
|
|
args: &[String],
|
|
|
|
) -> Result<Vec<Value>, InvokeError> {
|
|
|
|
let export_index = module
|
|
|
|
.info()
|
|
|
|
.exports
|
|
|
|
.get(fn_name)
|
|
|
|
.ok_or(InvokeError::CouldNotFindFunction)?;
|
|
|
|
|
|
|
|
let signature = if let ExportIndex::Func(func_index) = export_index {
|
|
|
|
let sig_index = module
|
|
|
|
.info()
|
|
|
|
.func_assoc
|
|
|
|
.get(*func_index)
|
|
|
|
.expect("broken invariant, incorrect func index");
|
|
|
|
SigRegistry.lookup_signature_ref(&module.info().signatures[*sig_index])
|
|
|
|
} else {
|
|
|
|
return Err(InvokeError::ExportNotFunction);
|
|
|
|
};
|
|
|
|
|
|
|
|
let parameter_types = signature.params();
|
2019-12-11 01:37:22 +00:00
|
|
|
let mut arg_error = None;
|
2019-12-11 01:12:35 +00:00
|
|
|
|
|
|
|
if args.len() != parameter_types.len() {
|
|
|
|
return Err(InvokeError::WrongNumArgs {
|
|
|
|
expected: parameter_types.len() as _,
|
|
|
|
found: args.len() as _,
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
args.iter()
|
|
|
|
.enumerate()
|
|
|
|
.try_fold(
|
|
|
|
Vec::with_capacity(args.len()),
|
|
|
|
|mut accumulator, (nth, argument)| {
|
|
|
|
if let Some(value) = match parameter_types[nth] {
|
|
|
|
Type::I32 => argument
|
|
|
|
.parse::<i32>()
|
|
|
|
.map(|v| Some(Value::I32(v)))
|
|
|
|
.unwrap_or_else(|_| {
|
2019-12-11 01:37:22 +00:00
|
|
|
arg_error = Some(InvokeError::CouldNotParseArg(format!(
|
|
|
|
"Failed to parse `{:?}` as an `i32`",
|
|
|
|
argument
|
|
|
|
)));
|
2019-12-11 01:12:35 +00:00
|
|
|
None
|
|
|
|
}),
|
|
|
|
Type::I64 => argument
|
|
|
|
.parse::<i64>()
|
|
|
|
.map(|v| Some(Value::I64(v)))
|
|
|
|
.unwrap_or_else(|_| {
|
2019-12-11 01:37:22 +00:00
|
|
|
arg_error = Some(InvokeError::CouldNotParseArg(format!(
|
|
|
|
"Failed to parse `{:?}` as an `i64`",
|
|
|
|
argument
|
|
|
|
)));
|
2019-12-11 01:12:35 +00:00
|
|
|
None
|
|
|
|
}),
|
|
|
|
Type::V128 => argument
|
|
|
|
.parse::<u128>()
|
|
|
|
.map(|v| Some(Value::V128(v)))
|
|
|
|
.unwrap_or_else(|_| {
|
2019-12-11 01:37:22 +00:00
|
|
|
arg_error = Some(InvokeError::CouldNotParseArg(format!(
|
|
|
|
"Failed to parse `{:?}` as an `i128`",
|
|
|
|
argument
|
|
|
|
)));
|
2019-12-11 01:12:35 +00:00
|
|
|
None
|
|
|
|
}),
|
|
|
|
Type::F32 => argument
|
|
|
|
.parse::<f32>()
|
|
|
|
.map(|v| Some(Value::F32(v)))
|
|
|
|
.unwrap_or_else(|_| {
|
2019-12-11 01:37:22 +00:00
|
|
|
arg_error = Some(InvokeError::CouldNotParseArg(format!(
|
|
|
|
"Failed to parse `{:?}` as an `f32`",
|
|
|
|
argument
|
|
|
|
)));
|
2019-12-11 01:12:35 +00:00
|
|
|
None
|
|
|
|
}),
|
|
|
|
Type::F64 => argument
|
|
|
|
.parse::<f64>()
|
|
|
|
.map(|v| Some(Value::F64(v)))
|
|
|
|
.unwrap_or_else(|_| {
|
2019-12-11 01:37:22 +00:00
|
|
|
arg_error = Some(InvokeError::CouldNotParseArg(format!(
|
|
|
|
"Failed to parse `{:?}` as an `f64`",
|
|
|
|
argument
|
|
|
|
)));
|
2019-12-11 01:12:35 +00:00
|
|
|
None
|
|
|
|
}),
|
|
|
|
} {
|
|
|
|
accumulator.push(value);
|
|
|
|
|
|
|
|
Some(accumulator)
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
},
|
|
|
|
)
|
|
|
|
.map_or_else(
|
2019-12-11 01:37:22 +00:00
|
|
|
|| Err(arg_error.unwrap()),
|
2019-12-11 01:12:35 +00:00
|
|
|
|arguments: Vec<Value>| Ok(arguments),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|