1 //! Result and error types representing the outcome of compiling a function. 2 3 use crate::verifier::VerifierErrors; 4 use std::string::String; 5 6 /// A compilation error. 7 /// 8 /// When Cranelift fails to compile a function, it will return one of these error codes. 9 #[derive(Debug, PartialEq, Eq)] 10 pub enum CodegenError { 11 /// A list of IR verifier errors. 12 /// 13 /// This always represents a bug, either in the code that generated IR for Cranelift, or a bug 14 /// in Cranelift itself. 15 Verifier(VerifierErrors), 16 17 /// An implementation limit was exceeded. 18 /// 19 /// Cranelift can compile very large and complicated functions, but the [implementation has 20 /// limits][limits] that cause compilation to fail when they are exceeded. 21 /// 22 /// [limits]: https://github.com/bytecodealliance/wasmtime/blob/main/cranelift/docs/ir.md#implementation-limits 23 ImplLimitExceeded, 24 25 /// The code size for the function is too large. 26 /// 27 /// Different target ISAs may impose a limit on the size of a compiled function. If that limit 28 /// is exceeded, compilation fails. 29 CodeTooLarge, 30 31 /// Something is not supported by the code generator. This might be an indication that a 32 /// feature is used without explicitly enabling it, or that something is temporarily 33 /// unsupported by a given target backend. 34 Unsupported(String), 35 36 /// A failure to map Cranelift register representation to a DWARF register representation. 37 #[cfg(feature = "unwind")] 38 RegisterMappingError(crate::isa::unwind::systemv::RegisterMappingError), 39 } 40 41 /// A convenient alias for a `Result` that uses `CodegenError` as the error type. 42 pub type CodegenResult<T> = Result<T, CodegenError>; 43 44 // This is manually implementing Error and Display instead of using thiserror to reduce the amount 45 // of dependencies used by Cranelift. 46 impl std::error::Error for CodegenError { 47 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { 48 match self { 49 CodegenError::Verifier(source) => Some(source), 50 CodegenError::ImplLimitExceeded { .. } 51 | CodegenError::CodeTooLarge { .. } 52 | CodegenError::Unsupported { .. } => None, 53 #[cfg(feature = "unwind")] 54 CodegenError::RegisterMappingError { .. } => None, 55 } 56 } 57 } 58 59 impl std::fmt::Display for CodegenError { 60 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 61 match self { 62 CodegenError::Verifier(_) => write!(f, "Verifier errors"), 63 CodegenError::ImplLimitExceeded => write!(f, "Implementation limit exceeded"), 64 CodegenError::CodeTooLarge => write!(f, "Code for function is too large"), 65 CodegenError::Unsupported(feature) => write!(f, "Unsupported feature: {}", feature), 66 #[cfg(feature = "unwind")] 67 CodegenError::RegisterMappingError(_0) => write!(f, "Register mapping error"), 68 } 69 } 70 } 71 72 impl From<VerifierErrors> for CodegenError { 73 fn from(source: VerifierErrors) -> Self { 74 CodegenError::Verifier { 0: source } 75 } 76 } 77