wasmer_engine/
engine.rs

1//! Engine trait and associated types.
2
3use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
4use std::sync::Arc;
5use wasmer_compiler::{CompileError, Target};
6use wasmer_types::{FunctionType, FunctionTypeRef};
7use wasmer_vm::{Artifact, Tunables, VMCallerCheckedAnyfunc, VMFuncRef, VMSharedSignatureIndex};
8
9mod private {
10    pub struct Internal(pub(super) ());
11}
12
13/// A unimplemented Wasmer `Engine`.
14///
15/// This trait is used by implementors to implement custom engines
16/// such as: Universal or Native.
17///
18/// The product that an `Engine` produces and consumes is the [`Artifact`].
19pub trait Engine {
20    /// Gets the target
21    fn target(&self) -> &Target;
22
23    /// Register a signature
24    fn register_signature(&self, func_type: FunctionTypeRef<'_>) -> VMSharedSignatureIndex;
25
26    /// Register a function's data.
27    fn register_function_metadata(&self, func_data: VMCallerCheckedAnyfunc) -> VMFuncRef;
28
29    /// Lookup a signature
30    fn lookup_signature(&self, sig: VMSharedSignatureIndex) -> Option<FunctionType>;
31
32    /// Validates a WebAssembly module
33    fn validate(&self, binary: &[u8]) -> Result<(), CompileError>;
34
35    /// Compile a WebAssembly binary
36    fn compile(
37        &self,
38        binary: &[u8],
39        tunables: &dyn Tunables,
40    ) -> Result<Box<dyn crate::Executable>, CompileError>;
41
42    /// Load a compiled executable with this engine.
43    fn load(&self, executable: &(dyn crate::Executable))
44        -> Result<Arc<dyn Artifact>, CompileError>;
45
46    /// A unique identifier for this object.
47    ///
48    /// This exists to allow us to compare two Engines for equality. Otherwise,
49    /// comparing two trait objects unsafely relies on implementation details
50    /// of trait representation.
51    fn id(&self) -> &EngineId;
52
53    /// Clone the engine
54    fn cloned(&self) -> Arc<dyn Engine + Send + Sync>;
55
56    /// Internal: support for downcasting `Engine`s.
57    #[doc(hidden)]
58    fn type_id(&self, _: private::Internal) -> std::any::TypeId
59    where
60        Self: 'static,
61    {
62        std::any::TypeId::of::<Self>()
63    }
64}
65
66#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
67#[repr(transparent)]
68/// A unique identifier for an Engine.
69pub struct EngineId {
70    id: usize,
71}
72
73impl EngineId {
74    /// Format this identifier as a string.
75    pub fn id(&self) -> String {
76        format!("{}", &self.id)
77    }
78}
79
80impl Clone for EngineId {
81    fn clone(&self) -> Self {
82        Self::default()
83    }
84}
85
86impl Default for EngineId {
87    fn default() -> Self {
88        static NEXT_ID: AtomicUsize = AtomicUsize::new(0);
89        Self {
90            id: NEXT_ID.fetch_add(1, SeqCst),
91        }
92    }
93}
94
95impl dyn Engine {
96    /// Downcast a dynamic Executable object to a concrete implementation of the trait.
97    pub fn downcast_ref<T: Engine + 'static>(&self) -> Option<&T> {
98        if std::any::TypeId::of::<T>() == self.type_id(private::Internal(())) {
99            unsafe { Some(&*(self as *const dyn Engine as *const T)) }
100        } else {
101            None
102        }
103    }
104}