use crate::{ffi, utils::check, Config, Module, WasmEdgeResult};
use wasmedge_types::error::WasmEdgeError;
#[derive(Debug)]
pub struct Validator {
pub(crate) inner: InnerValidator,
pub(crate) registered: bool,
}
impl Validator {
pub fn create(config: Option<&Config>) -> WasmEdgeResult<Self> {
let ctx = match config {
Some(config) => unsafe { ffi::WasmEdge_ValidatorCreate(config.inner.0) },
None => unsafe { ffi::WasmEdge_ValidatorCreate(std::ptr::null_mut()) },
};
match ctx.is_null() {
true => Err(Box::new(WasmEdgeError::CompilerCreate)),
false => Ok(Self {
inner: InnerValidator(ctx),
registered: false,
}),
}
}
pub fn validate(&self, module: &Module) -> WasmEdgeResult<()> {
unsafe {
check(ffi::WasmEdge_ValidatorValidate(
self.inner.0,
module.inner.0,
))
}
}
#[cfg(feature = "ffi")]
#[cfg_attr(docsrs, doc(cfg(feature = "ffi")))]
pub fn as_ptr(&self) -> *const ffi::WasmEdge_ValidatorContext {
self.inner.0 as *const _
}
}
impl Drop for Validator {
fn drop(&mut self) {
if !self.registered && !self.inner.0.is_null() {
unsafe { ffi::WasmEdge_ValidatorDelete(self.inner.0) }
}
}
}
#[derive(Debug)]
pub(crate) struct InnerValidator(pub(crate) *mut ffi::WasmEdge_ValidatorContext);
unsafe impl Send for InnerValidator {}
unsafe impl Sync for InnerValidator {}
#[cfg(test)]
mod tests {
use super::*;
use crate::{Config, Loader};
use std::{
sync::{Arc, Mutex},
thread,
};
#[test]
#[allow(clippy::assertions_on_result_states)]
fn test_validator() {
let result = Validator::create(None);
assert!(result.is_ok());
let result = Config::create();
assert!(result.is_ok());
let mut config = result.unwrap();
config.reference_types(true);
let result = Loader::create(Some(&config));
assert!(result.is_ok());
let loader = result.unwrap();
let path = std::env::current_dir()
.unwrap()
.ancestors()
.nth(2)
.unwrap()
.join("examples/wasmedge-sys/data/test.wasm");
let result = loader.from_file(path);
assert!(result.is_ok());
let module = result.unwrap();
assert!(!module.inner.0.is_null());
let result = Validator::create(None);
assert!(result.is_ok());
let validator = result.unwrap();
let result = validator.validate(&module);
assert!(result.is_ok());
}
#[test]
#[allow(clippy::assertions_on_result_states)]
fn test_validator_send() {
let result = Validator::create(None);
assert!(result.is_ok());
let validator = result.unwrap();
let handle = thread::spawn(move || {
let result = Loader::create(None);
assert!(result.is_ok());
let loader = result.unwrap();
let path = std::env::current_dir()
.unwrap()
.ancestors()
.nth(2)
.unwrap()
.join("examples/wasmedge-sys/data/test.wasm");
let result = loader.from_file(path);
assert!(result.is_ok());
let module = result.unwrap();
assert!(!module.inner.0.is_null());
let result = validator.validate(&module);
assert!(result.is_ok());
});
handle.join().unwrap();
}
#[test]
#[allow(clippy::assertions_on_result_states)]
fn test_validator_sync() {
let result = Validator::create(None);
assert!(result.is_ok());
let validator = Arc::new(Mutex::new(result.unwrap()));
let validator_cloned = Arc::clone(&validator);
let handle = thread::spawn(move || {
let result = Loader::create(None);
assert!(result.is_ok());
let loader = result.unwrap();
let path = std::env::current_dir()
.unwrap()
.ancestors()
.nth(2)
.unwrap()
.join("examples/wasmedge-sys/data/test.wasm");
let result = loader.from_file(path);
assert!(result.is_ok());
let module = result.unwrap();
assert!(!module.inner.0.is_null());
let result = validator_cloned.lock();
assert!(result.is_ok());
let validator = result.unwrap();
let result = validator.validate(&module);
assert!(result.is_ok());
});
handle.join().unwrap();
}
}