2017-06-05 69 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。 –

相關問題