wasmer/backend/sys/entities/
engine.rs1use std::{path::Path, sync::Arc};
4
5use shared_buffer::OwnedBuffer;
6pub use wasmer_compiler::{Artifact, BaseTunables, Engine, EngineBuilder, Tunables};
7use wasmer_types::{CompilationProgressCallback, DeserializeError, Features, target::Target};
8
9use crate::{BackendEngine, BackendModule};
10
11#[allow(unreachable_code)]
13#[cfg(feature = "compiler")]
14pub fn get_default_compiler_config() -> Option<Box<dyn wasmer_compiler::CompilerConfig>> {
15 cfg_if::cfg_if! {
16 if #[cfg(feature = "cranelift")] {
17 Some(Box::<wasmer_compiler_cranelift::Cranelift>::default())
18 } else if #[cfg(feature = "llvm")] {
19 Some(Box::<wasmer_compiler_llvm::LLVM>::default())
20 } else if #[cfg(feature = "singlepass")] {
21 Some(Box::<wasmer_compiler_singlepass::Singlepass>::default())
22 }
23 else {
24 None
25 }
26 }
27}
28
29pub fn default_engine() -> Engine {
31 #[cfg(feature = "compiler")]
32 fn get_engine() -> Engine {
33 if let Some(config) = get_default_compiler_config() {
34 EngineBuilder::new(config).engine()
35 } else {
36 EngineBuilder::headless().engine()
37 }
38 }
39
40 #[cfg(not(feature = "compiler"))]
41 fn get_engine() -> Engine {
42 EngineBuilder::headless().engine()
43 }
44
45 let mut engine = get_engine();
46 let tunables = BaseTunables::for_target(engine.target());
47 engine.set_tunables(tunables);
48 engine
49}
50
51pub trait NativeEngineExt {
54 #[cfg(feature = "compiler")]
56 fn new(
57 compiler_config: Box<dyn wasmer_compiler::CompilerConfig>,
58 target: Target,
59 features: Features,
60 ) -> Self;
61
62 fn headless() -> Self;
76
77 fn target(&self) -> &Target;
79
80 fn set_tunables(&mut self, tunables: impl Tunables + Send + Sync + 'static);
82
83 fn tunables(&self) -> &dyn Tunables;
85
86 fn new_module_with_progress(
99 &self,
100 bytes: &[u8],
101 on_progress: CompilationProgressCallback,
102 ) -> Result<crate::Module, wasmer_types::CompileError>;
103
104 unsafe fn deserialize_from_mmapped_file_unchecked(
111 &self,
112 file_ref: &Path,
113 ) -> Result<crate::Module, DeserializeError>;
114
115 unsafe fn deserialize_from_mmapped_file(
120 &self,
121 file_ref: &Path,
122 ) -> Result<crate::Module, DeserializeError>;
123}
124
125impl NativeEngineExt for crate::engine::Engine {
126 #[cfg(feature = "compiler")]
127 fn new(
128 compiler_config: Box<dyn wasmer_compiler::CompilerConfig>,
129 target: Target,
130 features: Features,
131 ) -> Self {
132 Self {
133 be: BackendEngine::Sys(Engine::new(compiler_config, target, features)),
134 id: Self::atomic_next_engine_id(),
135 }
136 }
137
138 fn headless() -> Self {
139 Self {
140 be: BackendEngine::Sys(Engine::headless()),
141 id: Self::atomic_next_engine_id(),
142 }
143 }
144
145 fn target(&self) -> &Target {
146 match self.be {
147 BackendEngine::Sys(ref s) => s.target(),
148 _ => panic!("Not a `sys` engine!"),
149 }
150 }
151
152 fn set_tunables(&mut self, tunables: impl Tunables + Send + Sync + 'static) {
153 match self.be {
154 BackendEngine::Sys(ref mut s) => s.set_tunables(tunables),
155 _ => panic!("Not a `sys` engine!"),
156 }
157 }
158
159 fn tunables(&self) -> &dyn Tunables {
160 match self.be {
161 BackendEngine::Sys(ref s) => s.tunables(),
162 _ => panic!("Not a `sys` engine!"),
163 }
164 }
165
166 fn new_module_with_progress(
167 &self,
168 bytes: &[u8],
169 on_progress: CompilationProgressCallback,
170 ) -> Result<crate::Module, wasmer_types::CompileError> {
171 crate::BackendModule::new_with_progress(self, bytes, on_progress).map(crate::Module)
172 }
173
174 unsafe fn deserialize_from_mmapped_file_unchecked(
175 &self,
176 file_ref: &Path,
177 ) -> Result<crate::Module, DeserializeError> {
178 let file = std::fs::File::open(file_ref)?;
179 let buffer = OwnedBuffer::from_file(&file)
180 .map_err(|e| DeserializeError::Generic(format!("{e:?}")))?;
181 let artifact = unsafe { Arc::new(Artifact::deserialize_unchecked(self.as_sys(), buffer)?) };
182 Ok(crate::Module(BackendModule::Sys(
183 super::module::Module::from_artifact(artifact),
184 )))
185 }
186
187 unsafe fn deserialize_from_mmapped_file(
188 &self,
189 file_ref: &Path,
190 ) -> Result<crate::Module, DeserializeError> {
191 let file = std::fs::File::open(file_ref)?;
192 let buffer = OwnedBuffer::from_file(&file)
193 .map_err(|e| DeserializeError::Generic(format!("{e:?}")))?;
194 let artifact = unsafe { Arc::new(Artifact::deserialize(self.as_sys(), buffer)?) };
195 Ok(crate::Module(BackendModule::Sys(
196 super::module::Module::from_artifact(artifact),
197 )))
198 }
199}
200
201impl crate::Engine {
202 pub fn into_sys(self) -> crate::backend::sys::engine::Engine {
204 match self.be {
205 BackendEngine::Sys(s) => s,
206 _ => panic!("Not a `sys` engine!"),
207 }
208 }
209
210 pub fn as_sys(&self) -> &crate::backend::sys::engine::Engine {
212 match self.be {
213 BackendEngine::Sys(ref s) => s,
214 _ => panic!("Not a `sys` engine!"),
215 }
216 }
217
218 pub fn as_sys_mut(&mut self) -> &mut crate::backend::sys::engine::Engine {
220 match self.be {
221 BackendEngine::Sys(ref mut s) => s,
222 _ => panic!("Not a `sys` engine!"),
223 }
224 }
225
226 pub fn is_sys(&self) -> bool {
228 matches!(self.be, BackendEngine::Sys(_))
229 }
230}
231
232impl From<Engine> for crate::Engine {
233 fn from(value: Engine) -> Self {
234 Self {
235 be: BackendEngine::Sys(value),
236 id: Self::atomic_next_engine_id(),
237 }
238 }
239}
240
241impl From<&Engine> for crate::Engine {
242 fn from(value: &Engine) -> Self {
243 Self {
244 be: BackendEngine::Sys(value.cloned()),
245 id: Self::atomic_next_engine_id(),
246 }
247 }
248}
249
250impl From<EngineBuilder> for crate::Engine {
251 fn from(value: EngineBuilder) -> Self {
252 Self {
253 be: BackendEngine::Sys(value.engine()),
254 id: Self::atomic_next_engine_id(),
255 }
256 }
257}
258
259#[cfg(feature = "cranelift")]
260impl From<wasmer_compiler_cranelift::Cranelift> for crate::Engine {
261 fn from(value: wasmer_compiler_cranelift::Cranelift) -> Self {
262 Self {
263 be: BackendEngine::Sys(value.into()),
264 id: Self::atomic_next_engine_id(),
265 }
266 }
267}
268
269#[cfg(feature = "singlepass")]
270impl From<wasmer_compiler_singlepass::Singlepass> for crate::Engine {
271 fn from(value: wasmer_compiler_singlepass::Singlepass) -> Self {
272 Self {
273 be: BackendEngine::Sys(value.into()),
274 id: Self::atomic_next_engine_id(),
275 }
276 }
277}
278
279#[cfg(feature = "llvm")]
280impl From<wasmer_compiler_llvm::LLVM> for crate::Engine {
281 fn from(value: wasmer_compiler_llvm::LLVM) -> Self {
282 Self {
283 be: BackendEngine::Sys(value.into()),
284 id: Self::atomic_next_engine_id(),
285 }
286 }
287}