wasmer_compiler_cranelift/translator/
unwind.rs

1//! A `Compilation` contains the compiled function bodies for a WebAssembly
2//! module.
3
4#[cfg(feature = "unwind")]
5use cranelift_codegen::isa::unwind::{UnwindInfo, systemv::UnwindInfo as DwarfFDE};
6#[cfg(feature = "unwind")]
7use cranelift_codegen::print_errors::pretty_error;
8use cranelift_codegen::{Context, isa};
9use wasmer_compiler::types::unwind::CompiledFunctionUnwindInfo;
10use wasmer_types::CompileError;
11
12/// Cranelift specific unwind info
13pub(crate) enum CraneliftUnwindInfo {
14    #[cfg(feature = "unwind")]
15    /// Windows Unwind info
16    WindowsX64(Vec<u8>),
17    /// Dwarf FDE
18    #[cfg(feature = "unwind")]
19    Fde(DwarfFDE),
20    /// No Unwind info attached
21    None,
22}
23
24impl CraneliftUnwindInfo {
25    /// Transform the `CraneliftUnwindInfo` to the Windows format.
26    ///
27    /// We skip the DWARF as it is not needed for trampolines (which are the
28    /// main users of this function)
29    pub fn maybe_into_to_windows_unwind(self) -> Option<CompiledFunctionUnwindInfo> {
30        match self {
31            #[cfg(feature = "unwind")]
32            Self::WindowsX64(unwind_info) => {
33                Some(CompiledFunctionUnwindInfo::WindowsX64(unwind_info))
34            }
35            _ => None,
36        }
37    }
38}
39
40#[cfg(feature = "unwind")]
41/// Constructs unwind info object from Cranelift IR
42pub(crate) fn compiled_function_unwind_info(
43    isa: &dyn isa::TargetIsa,
44    context: &Context,
45) -> Result<CraneliftUnwindInfo, CompileError> {
46    let unwind_info = context
47        .compiled_code()
48        .unwrap()
49        .create_unwind_info(isa)
50        .map_err(|error| CompileError::Codegen(pretty_error(&context.func, error)))?;
51
52    match unwind_info {
53        Some(UnwindInfo::WindowsX64(unwind)) => {
54            let size = unwind.emit_size();
55            let mut data: Vec<u8> = vec![0; size];
56            unwind.emit(&mut data[..]);
57            Ok(CraneliftUnwindInfo::WindowsX64(data))
58        }
59        Some(UnwindInfo::SystemV(unwind)) => Ok(CraneliftUnwindInfo::Fde(unwind)),
60        Some(_) | None => Ok(CraneliftUnwindInfo::None),
61    }
62}
63
64#[cfg(not(feature = "unwind"))]
65/// Constructs unwind info object from Cranelift IR
66pub(crate) fn compiled_function_unwind_info(
67    _isa: &dyn isa::TargetIsa,
68    _context: &Context,
69) -> Result<CraneliftUnwindInfo, CompileError> {
70    Ok(CraneliftUnwindInfo::None)
71}