1use 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
13pub trait Engine {
20 fn target(&self) -> &Target;
22
23 fn register_signature(&self, func_type: FunctionTypeRef<'_>) -> VMSharedSignatureIndex;
25
26 fn register_function_metadata(&self, func_data: VMCallerCheckedAnyfunc) -> VMFuncRef;
28
29 fn lookup_signature(&self, sig: VMSharedSignatureIndex) -> Option<FunctionType>;
31
32 fn validate(&self, binary: &[u8]) -> Result<(), CompileError>;
34
35 fn compile(
37 &self,
38 binary: &[u8],
39 tunables: &dyn Tunables,
40 ) -> Result<Box<dyn crate::Executable>, CompileError>;
41
42 fn load(&self, executable: &(dyn crate::Executable))
44 -> Result<Arc<dyn Artifact>, CompileError>;
45
46 fn id(&self) -> &EngineId;
52
53 fn cloned(&self) -> Arc<dyn Engine + Send + Sync>;
55
56 #[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)]
68pub struct EngineId {
70 id: usize,
71}
72
73impl EngineId {
74 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 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}