use crate::types::{module::CompileModuleInfo, symbols::SymbolRegistry, target::Target};
use crate::{
lib::std::{boxed::Box, sync::Arc},
translator::ModuleMiddleware,
types::{function::Compilation, target::CpuFeature},
FunctionBodyData, ModuleTranslationState,
};
use enumset::EnumSet;
use wasmer_types::{entity::PrimaryMap, error::CompileError, Features, LocalFunctionIndex};
use wasmparser::{Validator, WasmFeatures};
pub trait CompilerConfig {
fn enable_pic(&mut self) {
}
fn enable_verifier(&mut self) {
}
fn canonicalize_nans(&mut self, _enable: bool) {
}
fn compiler(self: Box<Self>) -> Box<dyn Compiler>;
fn default_features_for_target(&self, _target: &Target) -> Features {
Features::default()
}
fn push_middleware(&mut self, middleware: Arc<dyn ModuleMiddleware>);
}
impl<T> From<T> for Box<dyn CompilerConfig + 'static>
where
T: CompilerConfig + 'static,
{
fn from(other: T) -> Self {
Box::new(other)
}
}
pub trait Compiler: Send {
fn name(&self) -> &str;
fn validate_module(&self, features: &Features, data: &[u8]) -> Result<(), CompileError> {
let mut wasm_features = WasmFeatures::default();
wasm_features.set(WasmFeatures::BULK_MEMORY, features.bulk_memory);
wasm_features.set(WasmFeatures::THREADS, features.threads);
wasm_features.set(WasmFeatures::REFERENCE_TYPES, features.reference_types);
wasm_features.set(WasmFeatures::MULTI_VALUE, features.multi_value);
wasm_features.set(WasmFeatures::SIMD, features.simd);
wasm_features.set(WasmFeatures::TAIL_CALL, features.tail_call);
wasm_features.set(WasmFeatures::MULTI_MEMORY, features.multi_memory);
wasm_features.set(WasmFeatures::MEMORY64, features.memory64);
wasm_features.set(WasmFeatures::EXCEPTIONS, features.exceptions);
wasm_features.set(WasmFeatures::EXTENDED_CONST, features.extended_const);
wasm_features.set(WasmFeatures::RELAXED_SIMD, features.relaxed_simd);
wasm_features.set(WasmFeatures::MUTABLE_GLOBAL, true);
wasm_features.set(WasmFeatures::SATURATING_FLOAT_TO_INT, true);
wasm_features.set(WasmFeatures::FLOATS, true);
wasm_features.set(WasmFeatures::SIGN_EXTENSION, true);
wasm_features.set(WasmFeatures::GC_TYPES, true);
wasm_features.set(WasmFeatures::COMPONENT_MODEL, false);
wasm_features.set(WasmFeatures::FUNCTION_REFERENCES, false);
wasm_features.set(WasmFeatures::MEMORY_CONTROL, false);
wasm_features.set(WasmFeatures::GC, false);
wasm_features.set(WasmFeatures::COMPONENT_MODEL_VALUES, false);
wasm_features.set(WasmFeatures::COMPONENT_MODEL_NESTED_NAMES, false);
let mut validator = Validator::new_with_features(wasm_features);
validator
.validate_all(data)
.map_err(|e| CompileError::Validate(format!("{}", e)))?;
Ok(())
}
fn compile_module(
&self,
target: &Target,
module: &CompileModuleInfo,
module_translation: &ModuleTranslationState,
function_body_inputs: PrimaryMap<LocalFunctionIndex, FunctionBodyData<'_>>,
) -> Result<Compilation, CompileError>;
fn experimental_native_compile_module(
&self,
_target: &Target,
_module: &CompileModuleInfo,
_module_translation: &ModuleTranslationState,
_function_body_inputs: &PrimaryMap<LocalFunctionIndex, FunctionBodyData<'_>>,
_symbol_registry: &dyn SymbolRegistry,
_wasmer_metadata: &[u8],
) -> Option<Result<Vec<u8>, CompileError>> {
None
}
fn get_middlewares(&self) -> &[Arc<dyn ModuleMiddleware>];
fn get_cpu_features_used(&self, cpu_features: &EnumSet<CpuFeature>) -> EnumSet<CpuFeature> {
*cpu_features
}
}