Skip to main content

wasmedge_sys/
validator.rs

1//! Defines WasmEdge Validator struct.
2
3use crate::{ffi, utils::check, Config, Module, WasmEdgeResult};
4use wasmedge_types::error::WasmEdgeError;
5
6/// Struct of WasmEdge Validator.
7#[derive(Debug)]
8pub struct Validator {
9    pub(crate) inner: InnerValidator,
10}
11impl Validator {
12    /// Creates a new [Validator] to be associated with the given global configuration.
13    ///
14    /// # Arguments
15    ///
16    /// * `config` - The global environment configuration.
17    ///
18    /// # Error
19    ///
20    /// If fail to create a [Validator], then an error is returned.
21    pub fn create(config: Option<&Config>) -> WasmEdgeResult<Self> {
22        let ctx = match config {
23            Some(config) => unsafe { ffi::WasmEdge_ValidatorCreate(config.inner.0) },
24            None => unsafe { ffi::WasmEdge_ValidatorCreate(std::ptr::null_mut()) },
25        };
26        match ctx.is_null() {
27            true => Err(Box::new(WasmEdgeError::CompilerCreate)),
28            false => Ok(Self {
29                inner: InnerValidator(ctx),
30            }),
31        }
32    }
33
34    /// Validates a given WasmEdge [Module](crate::Module).
35    ///
36    /// [Module](crate::Module)s are valid when all components they contain are valid. Furthermore, most definitions are themselves classified with a suitable type.
37    ///
38    /// # Arguments
39    ///
40    /// * `module` - The [Module](crate::Module) to be validated.
41    ///
42    /// # Error
43    ///
44    /// If the validation fails, then an error is returned.
45    pub fn validate(&self, module: &Module) -> WasmEdgeResult<()> {
46        unsafe {
47            check(ffi::WasmEdge_ValidatorValidate(
48                self.inner.0,
49                module.inner.0,
50            ))
51        }
52    }
53
54    /// Provides a raw pointer to the inner Validator context.
55    #[cfg(feature = "ffi")]
56    #[cfg_attr(docsrs, doc(cfg(feature = "ffi")))]
57    pub fn as_ptr(&self) -> *const ffi::WasmEdge_ValidatorContext {
58        self.inner.0 as *const _
59    }
60}
61impl Drop for Validator {
62    fn drop(&mut self) {
63        unsafe { ffi::WasmEdge_ValidatorDelete(self.inner.0) }
64    }
65}
66
67#[derive(Debug)]
68pub(crate) struct InnerValidator(pub(crate) *mut ffi::WasmEdge_ValidatorContext);
69unsafe impl Send for InnerValidator {}
70unsafe impl Sync for InnerValidator {}
71
72#[cfg(test)]
73mod tests {
74    use super::*;
75    use crate::{Config, Loader};
76    use std::{
77        sync::{Arc, Mutex},
78        thread,
79    };
80
81    #[test]
82    #[allow(clippy::assertions_on_result_states)]
83    fn test_validator() {
84        // create a Validator context without configuration
85        let result = Validator::create(None);
86        assert!(result.is_ok());
87
88        // create a Loader context with configuration
89        let result = Config::create();
90        assert!(result.is_ok());
91        let mut config = result.unwrap();
92        config.reference_types(true);
93        let result = Loader::create(Some(&config));
94        assert!(result.is_ok());
95        let loader = result.unwrap();
96
97        // load a WASM module
98        let path = std::env::current_dir()
99            .unwrap()
100            .ancestors()
101            .nth(2)
102            .unwrap()
103            .join("examples/wasmedge-sys/data/test.wasm");
104        let result = loader.from_file(path);
105        assert!(result.is_ok());
106        let module = result.unwrap();
107        assert!(!module.inner.0.is_null());
108
109        // create a Validator context without configuration
110        let result = Validator::create(None);
111        assert!(result.is_ok());
112        let validator = result.unwrap();
113
114        // validate the module loaded.
115        let result = validator.validate(&module);
116        assert!(result.is_ok());
117    }
118
119    #[test]
120    #[allow(clippy::assertions_on_result_states)]
121    fn test_validator_send() {
122        // create a Validator
123        let result = Validator::create(None);
124        assert!(result.is_ok());
125        let validator = result.unwrap();
126
127        let handle = thread::spawn(move || {
128            let result = Loader::create(None);
129            assert!(result.is_ok());
130            let loader = result.unwrap();
131
132            // load a WASM module
133            let path = std::env::current_dir()
134                .unwrap()
135                .ancestors()
136                .nth(2)
137                .unwrap()
138                .join("examples/wasmedge-sys/data/test.wasm");
139            let result = loader.from_file(path);
140            assert!(result.is_ok());
141            let module = result.unwrap();
142            assert!(!module.inner.0.is_null());
143
144            // validate the module loaded.
145            let result = validator.validate(&module);
146            assert!(result.is_ok());
147        });
148
149        handle.join().unwrap();
150    }
151
152    #[test]
153    #[allow(clippy::assertions_on_result_states)]
154    fn test_validator_sync() {
155        // create a Validator
156        let result = Validator::create(None);
157        assert!(result.is_ok());
158        let validator = Arc::new(Mutex::new(result.unwrap()));
159
160        let validator_cloned = Arc::clone(&validator);
161        let handle = thread::spawn(move || {
162            let result = Loader::create(None);
163            assert!(result.is_ok());
164            let loader = result.unwrap();
165
166            // load a WASM module
167            let path = std::env::current_dir()
168                .unwrap()
169                .ancestors()
170                .nth(2)
171                .unwrap()
172                .join("examples/wasmedge-sys/data/test.wasm");
173            let result = loader.from_file(path);
174            assert!(result.is_ok());
175            let module = result.unwrap();
176            assert!(!module.inner.0.is_null());
177
178            // validate the module loaded.
179            let result = validator_cloned.lock();
180            assert!(result.is_ok());
181            let validator = result.unwrap();
182            let result = validator.validate(&module);
183            assert!(result.is_ok());
184        });
185
186        handle.join().unwrap();
187    }
188}