| use cranelift_codegen::Context; |
| use cranelift_codegen::control::ControlPlane; |
| use cranelift_codegen::ir::Signature; |
| use cranelift_codegen::isa::{TargetFrontendConfig, TargetIsa}; |
| use cranelift_module::{ |
| DataDescription, DataId, FuncId, FuncOrDataId, Linkage, Module, ModuleDeclarations, |
| ModuleReloc, ModuleResult, |
| }; |
| use cranelift_object::{ObjectModule, ObjectProduct}; |
| |
| use crate::UnwindContext; |
| |
| /// A wrapper around a [Module] which adds any defined function to the [UnwindContext]. |
| pub(crate) struct UnwindModule<T> { |
| pub(crate) module: T, |
| unwind_context: UnwindContext, |
| } |
| |
| impl<T: Module> UnwindModule<T> { |
| pub(crate) fn new(mut module: T, pic_eh_frame: bool) -> Self { |
| let unwind_context = UnwindContext::new(&mut module, pic_eh_frame); |
| UnwindModule { module, unwind_context } |
| } |
| } |
| |
| impl UnwindModule<ObjectModule> { |
| pub(crate) fn finish(self) -> ObjectProduct { |
| let mut product = self.module.finish(); |
| self.unwind_context.emit(&mut product); |
| product |
| } |
| } |
| |
| #[cfg(feature = "jit")] |
| impl UnwindModule<cranelift_jit::JITModule> { |
| pub(crate) fn finalize_definitions(mut self) -> cranelift_jit::JITModule { |
| self.module.finalize_definitions().unwrap(); |
| unsafe { self.unwind_context.register_jit(&self.module) }; |
| self.module |
| } |
| } |
| |
| impl<T: Module> Module for UnwindModule<T> { |
| fn isa(&self) -> &dyn TargetIsa { |
| self.module.isa() |
| } |
| |
| fn declarations(&self) -> &ModuleDeclarations { |
| self.module.declarations() |
| } |
| |
| fn get_name(&self, name: &str) -> Option<FuncOrDataId> { |
| self.module.get_name(name) |
| } |
| |
| fn target_config(&self) -> TargetFrontendConfig { |
| self.module.target_config() |
| } |
| |
| fn declare_function( |
| &mut self, |
| name: &str, |
| linkage: Linkage, |
| signature: &Signature, |
| ) -> ModuleResult<FuncId> { |
| self.module.declare_function(name, linkage, signature) |
| } |
| |
| fn declare_anonymous_function(&mut self, signature: &Signature) -> ModuleResult<FuncId> { |
| self.module.declare_anonymous_function(signature) |
| } |
| |
| fn declare_data( |
| &mut self, |
| name: &str, |
| linkage: Linkage, |
| writable: bool, |
| tls: bool, |
| ) -> ModuleResult<DataId> { |
| self.module.declare_data(name, linkage, writable, tls) |
| } |
| |
| fn declare_anonymous_data(&mut self, writable: bool, tls: bool) -> ModuleResult<DataId> { |
| self.module.declare_anonymous_data(writable, tls) |
| } |
| |
| fn define_function_with_control_plane( |
| &mut self, |
| func: FuncId, |
| ctx: &mut Context, |
| ctrl_plane: &mut ControlPlane, |
| ) -> ModuleResult<()> { |
| self.module.define_function_with_control_plane(func, ctx, ctrl_plane)?; |
| self.unwind_context.add_function(&mut self.module, func, ctx); |
| Ok(()) |
| } |
| |
| fn define_function_bytes( |
| &mut self, |
| _func_id: FuncId, |
| _alignment: u64, |
| _bytes: &[u8], |
| _relocs: &[ModuleReloc], |
| ) -> ModuleResult<()> { |
| unimplemented!() |
| } |
| |
| fn define_data(&mut self, data_id: DataId, data: &DataDescription) -> ModuleResult<()> { |
| self.module.define_data(data_id, data) |
| } |
| } |