@@ -779,34 +779,47 @@ impl<F> Entry<F> {
779779 }
780780}
781781
782- macro_rules! impl_set_handler_fn {
783- ( $h: ty) => {
784- #[ cfg( all( feature = "instructions" , feature = "abi_x86_interrupt" ) ) ]
785- impl Entry <$h> {
786- /// Set the handler function for the IDT entry and sets the present bit.
787- ///
788- /// For the code selector field, this function uses the code segment selector currently
789- /// active in the CPU.
790- ///
791- /// The function returns a mutable reference to the entry's options that allows
792- /// further customization.
793- ///
794- /// This method is only usable with the `abi_x86_interrupt` feature enabled. Without it, the
795- /// unsafe [`Entry::set_handler_addr`] method has to be used instead.
782+ #[ cfg( feature = "instructions" ) ]
783+ impl < F : HandlerFuncType > Entry < F > {
784+ /// Set the handler function for the IDT entry and sets the present bit.
785+ ///
786+ /// For the code selector field, this function uses the code segment selector currently
787+ /// active in the CPU.
788+ ///
789+ /// The function returns a mutable reference to the entry's options that allows
790+ /// further customization.
791+ ///
792+ /// This method is only usable with the `abi_x86_interrupt` feature enabled. Without it, the
793+ /// unsafe [`Entry::set_handler_addr`] method has to be used instead.
794+ #[ inline]
795+ pub fn set_handler_fn ( & mut self , handler : F ) -> & mut EntryOptions {
796+ unsafe { self . set_handler_addr ( handler. to_virt_addr ( ) ) }
797+ }
798+ }
799+
800+ /// The trait for all function types that can be used as a handler function in `Entry`.
801+ pub trait HandlerFuncType {
802+ /// Get the virtual memory address of the function
803+ fn to_virt_addr ( self ) -> VirtAddr ;
804+ }
805+
806+ macro_rules! impl_handler_func_type {
807+ ( $f: ty) => {
808+ #[ cfg( feature = "abi_x86_interrupt" ) ]
809+ impl HandlerFuncType for $f {
796810 #[ inline]
797- pub fn set_handler_fn( & mut self , handler: $h) -> & mut EntryOptions {
798- let handler = VirtAddr :: new( handler as u64 ) ;
799- unsafe { self . set_handler_addr( handler) }
811+ fn to_virt_addr( self ) -> VirtAddr {
812+ VirtAddr :: new( self as u64 )
800813 }
801814 }
802815 } ;
803816}
804817
805- impl_set_handler_fn ! ( HandlerFunc ) ;
806- impl_set_handler_fn ! ( HandlerFuncWithErrCode ) ;
807- impl_set_handler_fn ! ( PageFaultHandlerFunc ) ;
808- impl_set_handler_fn ! ( DivergingHandlerFunc ) ;
809- impl_set_handler_fn ! ( DivergingHandlerFuncWithErrCode ) ;
818+ impl_handler_func_type ! ( HandlerFunc ) ;
819+ impl_handler_func_type ! ( HandlerFuncWithErrCode ) ;
820+ impl_handler_func_type ! ( PageFaultHandlerFunc ) ;
821+ impl_handler_func_type ! ( DivergingHandlerFunc ) ;
822+ impl_handler_func_type ! ( DivergingHandlerFuncWithErrCode ) ;
810823
811824/// Represents the options field of an IDT entry.
812825#[ repr( transparent) ]
0 commit comments