use crate::{ error::CompileResult, module::ModuleInner, state::ModuleStateMap, typed_func::Wasm, types::{LocalFuncIndex, SigIndex}, vm, }; use crate::{ cache::{Artifact, Error as CacheError}, codegen::BreakpointMap, module::ModuleInfo, sys::Memory, }; use std::{any::Any, ptr::NonNull}; use hashbrown::HashMap; pub mod sys { pub use crate::sys::*; } pub use crate::sig_registry::SigRegistry; #[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq)] pub enum Backend { Cranelift, Singlepass, LLVM, } impl Backend { pub fn variants() -> &'static [&'static str] { &[ "cranelift", #[cfg(feature = "backend-singlepass")] "singlepass", #[cfg(feature = "backend-llvm")] "llvm", ] } /// stable string representation of the backend /// can be used as part of a cache key, for example pub fn to_string(&self) -> &'static str { match self { Backend::Cranelift => "cranelift", Backend::Singlepass => "singlepass", Backend::LLVM => "llvm", } } } impl Default for Backend { fn default() -> Self { Backend::Cranelift } } impl std::str::FromStr for Backend { type Err = String; fn from_str(s: &str) -> Result { match s.to_lowercase().as_str() { "singlepass" => Ok(Backend::Singlepass), "cranelift" => Ok(Backend::Cranelift), "llvm" => Ok(Backend::LLVM), _ => Err(format!("The backend {} doesn't exist", s)), } } } #[cfg(test)] mod backend_test { use super::*; use std::str::FromStr; #[test] fn str_repr_matches() { // if this test breaks, think hard about why it's breaking // can we avoid having these be different? for &backend in &[Backend::Cranelift, Backend::LLVM, Backend::Singlepass] { assert_eq!(backend, Backend::from_str(backend.to_string()).unwrap()); } } } /// This type cannot be constructed from /// outside the runtime crate. pub struct Token { _private: (), } impl Token { pub(crate) fn generate() -> Self { Self { _private: () } } } #[derive(Copy, Clone, Debug)] pub enum MemoryBoundCheckMode { Default, Enable, Disable, } impl Default for MemoryBoundCheckMode { fn default() -> MemoryBoundCheckMode { MemoryBoundCheckMode::Default } } /// Configuration data for the compiler #[derive(Default)] pub struct CompilerConfig { /// Symbol information generated from emscripten; used for more detailed debug messages pub symbol_map: Option>, pub memory_bound_check_mode: MemoryBoundCheckMode, pub enforce_stack_check: bool, pub track_state: bool, } pub trait Compiler { /// Compiles a `Module` from WebAssembly binary format. /// The `CompileToken` parameter ensures that this can only /// be called from inside the runtime. fn compile( &self, wasm: &[u8], comp_conf: CompilerConfig, _: Token, ) -> CompileResult; unsafe fn from_cache(&self, cache: Artifact, _: Token) -> Result; } pub trait RunnableModule: Send + Sync { /// This returns a pointer to the function designated by the `local_func_index` /// parameter. fn get_func( &self, info: &ModuleInfo, local_func_index: LocalFuncIndex, ) -> Option>; fn get_module_state_map(&self) -> Option { None } fn get_breakpoints(&self) -> Option { None } /// A wasm trampoline contains the necessary data to dynamically call an exported wasm function. /// Given a particular signature index, we are returned a trampoline that is matched with that /// signature and an invoke function that can call the trampoline. fn get_trampoline(&self, info: &ModuleInfo, sig_index: SigIndex) -> Option; unsafe fn do_early_trap(&self, data: Box) -> !; /// Returns the machine code associated with this module. fn get_code(&self) -> Option<&[u8]> { None } /// Returns the beginning offsets of all functions, including import trampolines. fn get_offsets(&self) -> Option> { None } } pub trait CacheGen: Send + Sync { fn generate_cache(&self) -> Result<(Box<[u8]>, Memory), CacheError>; }