linera_wasmer_compiler/
compiler.rs

1//! This module mainly outputs the `Compiler` trait that custom
2//! compilers will need to implement.
3
4use crate::lib::std::boxed::Box;
5use crate::lib::std::sync::Arc;
6use crate::translator::ModuleMiddleware;
7use crate::FunctionBodyData;
8use crate::ModuleTranslationState;
9use enumset::EnumSet;
10use wasmer_types::compilation::function::Compilation;
11use wasmer_types::compilation::module::CompileModuleInfo;
12use wasmer_types::compilation::symbols::SymbolRegistry;
13use wasmer_types::compilation::target::Target;
14use wasmer_types::entity::PrimaryMap;
15use wasmer_types::error::CompileError;
16use wasmer_types::{CpuFeature, Features, LocalFunctionIndex};
17use wasmparser::{Validator, WasmFeatures};
18
19/// The compiler configuration options.
20pub trait CompilerConfig {
21    /// Enable Position Independent Code (PIC).
22    ///
23    /// This is required for shared object generation (Native Engine),
24    /// but will make the JIT Engine to fail, since PIC is not yet
25    /// supported in the JIT linking phase.
26    fn enable_pic(&mut self) {
27        // By default we do nothing, each backend will need to customize this
28        // in case they do something special for emitting PIC code.
29    }
30
31    /// Enable compiler IR verification.
32    ///
33    /// For compilers capable of doing so, this enables internal consistency
34    /// checking.
35    fn enable_verifier(&mut self) {
36        // By default we do nothing, each backend will need to customize this
37        // in case they create an IR that they can verify.
38    }
39
40    /// Enable NaN canonicalization.
41    ///
42    /// NaN canonicalization is useful when trying to run WebAssembly
43    /// deterministically across different architectures.
44    fn canonicalize_nans(&mut self, _enable: bool) {
45        // By default we do nothing, each backend will need to customize this
46        // in case they create an IR that they can verify.
47    }
48
49    /// Gets the custom compiler config
50    fn compiler(self: Box<Self>) -> Box<dyn Compiler>;
51
52    /// Gets the default features for this compiler in the given target
53    fn default_features_for_target(&self, _target: &Target) -> Features {
54        Features::default()
55    }
56
57    /// Pushes a middleware onto the back of the middleware chain.
58    fn push_middleware(&mut self, middleware: Arc<dyn ModuleMiddleware>);
59}
60
61impl<T> From<T> for Box<dyn CompilerConfig + 'static>
62where
63    T: CompilerConfig + 'static,
64{
65    fn from(other: T) -> Self {
66        Box::new(other)
67    }
68}
69
70/// An implementation of a Compiler from parsed WebAssembly module to Compiled native code.
71pub trait Compiler: Send {
72    /// Returns a descriptive name for this compiler.
73    ///
74    /// Note that this is an API breaking change since 3.0
75    fn name(&self) -> &str;
76
77    /// Validates a module.
78    ///
79    /// It returns the a succesful Result in case is valid, `CompileError` in case is not.
80    fn validate_module(&self, features: &Features, data: &[u8]) -> Result<(), CompileError> {
81        let wasm_features = WasmFeatures {
82            bulk_memory: features.bulk_memory,
83            threads: features.threads,
84            reference_types: features.reference_types,
85            multi_value: features.multi_value,
86            simd: features.simd,
87            tail_call: features.tail_call,
88            multi_memory: features.multi_memory,
89            memory64: features.memory64,
90            exceptions: features.exceptions,
91            extended_const: features.extended_const,
92            relaxed_simd: features.relaxed_simd,
93            mutable_global: true,
94            saturating_float_to_int: true,
95            floats: true,
96            sign_extension: true,
97
98            // Not supported
99            component_model: false,
100            function_references: false,
101            memory_control: false,
102            gc: false,
103            component_model_values: false,
104            component_model_nested_names: false,
105        };
106        let mut validator = Validator::new_with_features(wasm_features);
107        validator
108            .validate_all(data)
109            .map_err(|e| CompileError::Validate(format!("{}", e)))?;
110        Ok(())
111    }
112
113    /// Compiles a parsed module.
114    ///
115    /// It returns the [`Compilation`] or a [`CompileError`].
116    fn compile_module(
117        &self,
118        target: &Target,
119        module: &CompileModuleInfo,
120        module_translation: &ModuleTranslationState,
121        // The list of function bodies
122        function_body_inputs: PrimaryMap<LocalFunctionIndex, FunctionBodyData<'_>>,
123    ) -> Result<Compilation, CompileError>;
124
125    /// Compiles a module into a native object file.
126    ///
127    /// It returns the bytes as a `&[u8]` or a [`CompileError`].
128    fn experimental_native_compile_module(
129        &self,
130        _target: &Target,
131        _module: &CompileModuleInfo,
132        _module_translation: &ModuleTranslationState,
133        // The list of function bodies
134        _function_body_inputs: &PrimaryMap<LocalFunctionIndex, FunctionBodyData<'_>>,
135        _symbol_registry: &dyn SymbolRegistry,
136        // The metadata to inject into the wasmer_metadata section of the object file.
137        _wasmer_metadata: &[u8],
138    ) -> Option<Result<Vec<u8>, CompileError>> {
139        None
140    }
141
142    /// Get the middlewares for this compiler
143    fn get_middlewares(&self) -> &[Arc<dyn ModuleMiddleware>];
144
145    /// Get the CpuFeatues used by the compiler
146    fn get_cpu_features_used(&self, cpu_features: &EnumSet<CpuFeature>) -> EnumSet<CpuFeature> {
147        *cpu_features
148    }
149}