Description
In Rust, I think resolving #38 entails generating different extern "<something>"
statements depending on the target architecture. The pointer wrapping discussed in #40, if it ends up being implemented, could also use a bit of code generation to automatically turn *const T
into EfiPtr<T>
and *mut T
into EfiPtrMut<T>
.
A general solution to handle this kind of EFI API boilerplate would be to borrow the EFIAPI design from the UEFI spec and turn it into a Rust macro. For example, this code...
efiapi! { fn(u64, usize) -> Status }
...would generate this code on x86_64:
extern "win64" fn(u64, usize) -> Status
...and this code on i386:
extern "cdecl" fn(u64, usize) -> Status
There are limitations to what a declarative macro can generate in Rust (IIRC they can't generate types), and we probably don't want to go for procedural macros on a task this simple, so the final design may be modified to accomodate these limitations. But I think the general idea could portably address the issue of EFI calling conventions without bringing too much boilerplate in the declaration of each individual API entry point.