Skip to main content

vtable

Attribute Macro vtable 

Source
#[vtable]
Expand description

Declares or implements a vtable trait.

Linux’s use of pure vtables is very close to Rust traits, but they differ in how unimplemented functions are represented. In Rust, traits can provide default implementation for all non-required methods (and the default implementation could just return Error::EINVAL); Linux typically use C NULL pointers to represent these functions.

This attribute closes that gap. A trait can be annotated with the #[vtable] attribute. Implementers of the trait will then also have to annotate the trait with #[vtable]. This attribute generates a HAS_* associated constant bool for each method in the trait that is set to true if the implementer has overridden the associated method.

For a trait method to be optional for normal traits, it must have a default implementation. However, for many users of #[vtable], the functions will be called through function pointers installed in C side vtables. When an optional method is not implemented on a #[vtable] trait, a NULL entry is installed in the vtable; thus the default implementation is never called. If this is the case, #[optional] can be applied on the optional method. Methods annotated as such do not need to be implemented nor need a default implementation. Calling these methods on types that do not implement them will fail to build using the build_error! mechanism.

This macro should not be used when all functions are required.

Additionally, this macro automatically handles the OwnerModule associated type: on the trait side, type OwnerModule: ModuleMetadata; is added as a required associated type if not already defined; on the impl side, type OwnerModule = LocalModule; is automatically inserted if not explicitly defined.

§Examples

use kernel::prelude::*;

// Declares a `#[vtable]` trait
#[vtable]
pub trait Operations: Send + Sync + Sized {
    #[optional]
    fn foo(&self) -> Result<()>;

    #[optional]
    fn bar(&self) -> Result<()>;
}

struct Foo;

// Implements the `#[vtable]` trait
#[vtable]
impl Operations for Foo {
    fn foo(&self) -> Result<()> {
        // ...
    }
}

assert_eq!(<Foo as Operations>::HAS_FOO, true);
assert_eq!(<Foo as Operations>::HAS_BAR, false);