2

我正在用 Rust 开发一种小语言。为了提高性能,我想使用 x86 的 fastcall 调用约定。"fastcall"ARM 不支持 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) {}

使用 CI 可以定义宏

#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 来定义不同版本的函数,但不知道宏。

4

1 回答 1

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)];
}}
于 2017-06-22T22:33:42.640 回答