我正在Rust中开发一种小语言。为了提高性能,我想使用x86的fastcall调用约定。 ARM不支持"fastcall"
ABI。
对于x86:
fn add_primitive(&mut self, name: &str, action: extern "fastcall" fn(&mut Self)) {
...
}
extern "fastcall" fn a_primitive(&mut self) {}
对于ARM:
fn add_primitive(&mut self, name: &str, action: fn(&mut Self)) {
...
}
fn a_primitive(&mut self) {}
使用C我可以定义一个宏
#ifdef x86
#define PRIMITIVE extern "fastcall" fn
#endif
#ifdef arm
#define PRIMITIVE fn
#endif
fn add_primitive(&mut self, name: &str, action: PRIMITIVE(&mut Self)) {
...
}
PRIMITIVE a_primitive(&mut self) {}
我不知道如何使用Rust的宏系统来解决这个问题。
编辑:
我需要两个不同的宏。我知道如何使用target_arch来定义不同版本的函数,但不能定义宏。
答案 0 :(得分:1)
#[cfg(target_arch = "arm")]
#[macro_export]
macro_rules! primitive {
(fn $args:tt) => { fn $args };
(fn $f:ident $args:tt $body:tt) => { fn $f $args $body };
(fn $f:ident $args:tt -> isize $body:tt) => { fn $f $args -> isize $body };
}
#[cfg(target_arch = "x86")]
#[macro_export]
macro_rules! primitive {
(fn $args:tt) => { extern "fastcall" fn $args };
(fn $f:ident $args:tt $body:tt) => { extern "fastcall" fn $f $args $body };
(fn $f:ident $args:tt -> isize $body:tt) => { extern "fastcall" fn $f $args -> isize $body };
}
示例:
pub struct Word<Target> {
symbol: Symbol,
is_immediate: bool,
is_compile_only: bool,
hidden: bool,
dfa: usize,
cfa: usize,
action: primitive!{ fn (&mut Target) },
pub(crate) compilation_semantics: fn(&mut Target, usize),
}
primitive!{fn dup(&mut self) {
let slen = self.s_stack().len.wrapping_add(1);
self.s_stack().len = slen;
self.s_stack()[slen.wrapping_sub(1)] = self.s_stack()[slen.wrapping_sub(2)];
}}