1//! This module mainly outputs the `Compiler` trait that custom
2//! compilers will need to implement.
34use crate::types::{module::CompileModuleInfo, symbols::SymbolRegistry};
5use crate::{
6 lib::std::{boxed::Box, sync::Arc},
7 translator::ModuleMiddleware,
8 types::function::Compilation,
9 FunctionBodyData, ModuleTranslationState,
10};
11use enumset::EnumSet;
12use wasmer_types::{
13 entity::PrimaryMap,
14 error::CompileError,
15 target::{CpuFeature, Target, UserCompilerOptimizations},
16 Features, LocalFunctionIndex,
17};
18#[cfg(feature = "translator")]
19use wasmparser::{Validator, WasmFeatures};
2021/// The compiler configuration options.
22pub trait CompilerConfig {
23/// Enable Position Independent Code (PIC).
24 ///
25 /// This is required for shared object generation (Native Engine),
26 /// but will make the JIT Engine to fail, since PIC is not yet
27 /// supported in the JIT linking phase.
28fn enable_pic(&mut self) {
29// By default we do nothing, each backend will need to customize this
30 // in case they do something special for emitting PIC code.
31}
3233/// Enable compiler IR verification.
34 ///
35 /// For compilers capable of doing so, this enables internal consistency
36 /// checking.
37fn enable_verifier(&mut self) {
38// By default we do nothing, each backend will need to customize this
39 // in case they create an IR that they can verify.
40}
4142/// Enable generation of perfmaps to sample the JIT compiled frames.
43fn enable_perfmap(&mut self) {
44// By default we do nothing, each backend will need to customize this
45 // in case they create an IR that they can verify.
46}
4748/// Enable NaN canonicalization.
49 ///
50 /// NaN canonicalization is useful when trying to run WebAssembly
51 /// deterministically across different architectures.
52fn canonicalize_nans(&mut self, _enable: bool) {
53// By default we do nothing, each backend will need to customize this
54 // in case they create an IR that they can verify.
55}
5657/// Gets the custom compiler config
58fn compiler(self: Box<Self>) -> Box<dyn Compiler>;
5960/// Gets the default features for this compiler in the given target
61fn default_features_for_target(&self, target: &Target) -> Features {
62self.supported_features_for_target(target)
63 }
6465/// Gets the supported features for this compiler in the given target
66fn supported_features_for_target(&self, _target: &Target) -> Features {
67 Features::default()
68 }
6970/// Pushes a middleware onto the back of the middleware chain.
71fn push_middleware(&mut self, middleware: Arc<dyn ModuleMiddleware>);
72}
7374impl<T> From<T> for Box<dyn CompilerConfig + 'static>
75where
76T: CompilerConfig + 'static,
77{
78fn from(other: T) -> Self {
79 Box::new(other)
80 }
81}
8283/// An implementation of a Compiler from parsed WebAssembly module to Compiled native code.
84pub trait Compiler: Send + std::fmt::Debug {
85/// Returns a descriptive name for this compiler.
86 ///
87 /// Note that this is an API breaking change since 3.0
88fn name(&self) -> &str;
8990/// Returns the deterministic id of this compiler. Same compilers with different
91 /// optimizations map to different deterministic IDs.
92fn deterministic_id(&self) -> String;
9394/// Add suggested optimizations to this compiler.
95 ///
96 /// # Note
97 ///
98 /// Not every compiler supports every optimization. This function may fail (i.e. not set the
99 /// suggested optimizations) silently if the underlying compiler does not support one or
100 /// more optimizations.
101fn with_opts(
102&mut self,
103 suggested_compiler_opts: &UserCompilerOptimizations,
104 ) -> Result<(), CompileError> {
105_ = suggested_compiler_opts;
106Ok(())
107 }
108109/// Validates a module.
110 ///
111 /// It returns the a succesful Result in case is valid, `CompileError` in case is not.
112#[cfg(feature = "translator")]
113fn validate_module(&self, features: &Features, data: &[u8]) -> Result<(), CompileError> {
114let mut wasm_features = WasmFeatures::default();
115 wasm_features.set(WasmFeatures::BULK_MEMORY, features.bulk_memory);
116 wasm_features.set(WasmFeatures::THREADS, features.threads);
117 wasm_features.set(WasmFeatures::REFERENCE_TYPES, features.reference_types);
118 wasm_features.set(WasmFeatures::MULTI_VALUE, features.multi_value);
119 wasm_features.set(WasmFeatures::SIMD, features.simd);
120 wasm_features.set(WasmFeatures::TAIL_CALL, features.tail_call);
121 wasm_features.set(WasmFeatures::MULTI_MEMORY, features.multi_memory);
122 wasm_features.set(WasmFeatures::MEMORY64, features.memory64);
123 wasm_features.set(WasmFeatures::EXCEPTIONS, features.exceptions);
124 wasm_features.set(WasmFeatures::EXTENDED_CONST, features.extended_const);
125 wasm_features.set(WasmFeatures::RELAXED_SIMD, features.relaxed_simd);
126 wasm_features.set(WasmFeatures::MUTABLE_GLOBAL, true);
127 wasm_features.set(WasmFeatures::SATURATING_FLOAT_TO_INT, true);
128 wasm_features.set(WasmFeatures::FLOATS, true);
129 wasm_features.set(WasmFeatures::SIGN_EXTENSION, true);
130 wasm_features.set(WasmFeatures::GC_TYPES, true);
131132// Not supported
133wasm_features.set(WasmFeatures::COMPONENT_MODEL, false);
134 wasm_features.set(WasmFeatures::FUNCTION_REFERENCES, false);
135 wasm_features.set(WasmFeatures::MEMORY_CONTROL, false);
136 wasm_features.set(WasmFeatures::GC, false);
137 wasm_features.set(WasmFeatures::COMPONENT_MODEL_VALUES, false);
138 wasm_features.set(WasmFeatures::COMPONENT_MODEL_NESTED_NAMES, false);
139140let mut validator = Validator::new_with_features(wasm_features);
141 validator
142 .validate_all(data)
143 .map_err(|e| CompileError::Validate(format!("{e}")))?;
144Ok(())
145 }
146147/// Compiles a parsed module.
148 ///
149 /// It returns the [`Compilation`] or a [`CompileError`].
150fn compile_module(
151&self,
152 target: &Target,
153 module: &CompileModuleInfo,
154 module_translation: &ModuleTranslationState,
155// The list of function bodies
156function_body_inputs: PrimaryMap<LocalFunctionIndex, FunctionBodyData<'_>>,
157 ) -> Result<Compilation, CompileError>;
158159/// Compiles a module into a native object file.
160 ///
161 /// It returns the bytes as a `&[u8]` or a [`CompileError`].
162fn experimental_native_compile_module(
163&self,
164 _target: &Target,
165 _module: &CompileModuleInfo,
166 _module_translation: &ModuleTranslationState,
167// The list of function bodies
168_function_body_inputs: &PrimaryMap<LocalFunctionIndex, FunctionBodyData<'_>>,
169 _symbol_registry: &dyn SymbolRegistry,
170// The metadata to inject into the wasmer_metadata section of the object file.
171_wasmer_metadata: &[u8],
172 ) -> Option<Result<Vec<u8>, CompileError>> {
173None
174}
175176/// Get the middlewares for this compiler
177fn get_middlewares(&self) -> &[Arc<dyn ModuleMiddleware>];
178179/// Get the CpuFeatues used by the compiler
180fn get_cpu_features_used(&self, cpu_features: &EnumSet<CpuFeature>) -> EnumSet<CpuFeature> {
181*cpu_features
182 }
183184/// Get whether `perfmap` is enabled or not.
185fn get_perfmap_enabled(&self) -> bool {
186false
187}
188}