2017-06-05 68 views
2

我正在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) {} 

使用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) {} 

我不知道如何解决使用锈病的宏系统这个问题。

编辑:

我需要两个不同的宏。我知道如何使用target_arch来定义不同版本的函数,但不是宏。

+2

的可能的复制[?如何锈病检查架构是32或64比特](https://stackoverflow.com/questions/41896462/how-to-检入防锈如果体系结构是32位或64位) - 问题稍有不同,但答案是一样的。 –

+1

[如何检查Rust如果体系结构是32位或64位?]的答案(https://stackoverflow.com/questions/41896462/how-to-check-in-rust-if-architecture-is-32-或64位)是不足以解决我的问题。因为我需要两个不同版本的宏。我知道如何使用target_arch来定义不同版本的函数,但不是宏。 –

+2

'#[cfg]'在宏上工作就像它在函数上一样。 –

回答

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)]; 
}} 
+0

你可以举一个如何使用它的例子吗? – Boiethios

+0

@Boiethios这是一个维基答案,可以自由地改进它,我只是创建它,因为OP在问题中有答案。我不知道这项工作或者目的是什么。 – Stargateur

+1

我用我自己的名字来定义原始的单词。请参阅https://github.com/chengchangwu/rtforth/blob/master/src/core.rs。 –

相关问题