2011-08-10 42 views
6

調用一個函數我想要定義在LLVM組件,其採用作爲自變量的函數:LLVM組件:使用可變參數

  • 的標識符的一個子功能
  • 一個可變參數

這函數應該做一些預處理,爲標識符找到正確的函數並使用可變參數來調用它,並返回其結果。

喜歡的東西:

define ??? @1 (i32 %identifier, ...vararg...) 
{ 
    switch i32 %identifier, label %def, i32 1, label %a 
a: 
    %1 = tail call @function_for_a, ...vararg... 
    ret ??? %1 
def: 
    ret void 
} 

這似乎並不可能。有沒有辦法做到這一點呢?我認爲應該可以使用普通的彙編程序。

這是爲了面嚮對象語言的調度功能。我寧願它速度快。

我想一個辦法:

  • 從堆棧中刪除使用@ 1
  • 分支到第二功能的第一個參數。

第二個功能將在隨後發生的第一(這是一個尾調用)的執行,但沒有被確切知道的第一個函數(第一函數的可變參數)參數列表。

+0

有沒有可以在C語言中編寫這樣的代碼的選項,用clang/llvm-gcc編譯它並反彙編'.bc'? – osgx

+0

有一個llvm反彙編器:'llvm-dis'。我想要做的事不能在C中完成。 – Mildred

回答

3

首先:如果你想通過可變參數不能使用尾部調用:

http://llvm.org/docs/LangRef.html

  1. 可選的「尾巴」標記表明被調用函數不訪問任何allocas或調用者的可變參數。

二:您的通話約定是什麼?

第三:要處理可變參數(如C語言),你需要使用va_*函數來創建一個新的va_list和複製所有參數到它:

http://llvm.org/docs/LangRef.html#int-varargs

最後:每個函數將被調用這個調度員必須使用va_*函數來獲得它的參數。

UPDATE:

你應該知道調用約定將使用哪(什麼是默認值)之前,你會說堆棧的函數參數的存儲。然後。如果沒有va_ *函數,則不能訪問不傳遞「...」參數,因爲這是在LLVM程序集中訪問它們的唯一方法。

有一種像C中一樣做不好的方法,在這裏printf會調用vfprintf的所有「...「論據與不知道有多少參數傳遞

// 3-clause BSD licensed to The Regents of the University of California. 

int 
printf(const char *fmt, ...) 
{ 
     int ret; 
     va_list ap; 

     va_start(ap, fmt); 
     ret = vfprintf(stdout, fmt, ap); 
     va_end(ap); 
     return (ret); 
} 

Vfprintf特殊的方式來獲得申報」 ...」,並從中提取參數:

int 
vfprintf(FILE *fp, const char *fmt0, __va_list ap) 
{ 
... 
va_arg(ap, type) //to get next arg of type `type` 
+0

我已經看到了所有這些...我修改了我的問題來解釋我想要更好的東西 – Mildred

+0

我的調用約定是任何默認設置。我不想使用va_ *函數,因爲它們不能做我想要的。 – Mildred

+0

osgx你應該更通靈。讓心靈讀書更好一點! –

1

(這個增長過大評論,恐怕我對LLVM沒有太多的實際經驗,所以拿一點鹽吧)

我一直在想這個,我懷疑你會寫這樣的功能。

考慮使用C調用約定以x86_64彙編語言編寫此函數,或者真的支持可變參數(例如參見pg. 20)。通常你會在分支之前移動寄存器(rdi < -rsi,rsi < -rdx等),但是如果參數是例如,你不應該這樣做。漂浮物,所以你必須知道類型!或者你必須使用類似vfprintf的功能。

其他體系結構存在相似的參數,所以我會考慮考慮另一種解決問題的方法。特別是你不能只用跳轉表中的查找和跳轉到%identifier指定的功能指針來替換對@1的調用?這可以作爲一個函數,檢查%identifier並返回正確的函數指針並適當地處理無效標識符。

+0

我認爲你是正確的,在LLVM彙編中沒有辦法做到這一點,我會嘗試找到另一種做事情的方式。我希望'@ 1'的實現對調用者保持不透明,所以它可能會返回一個函數指針,它將由調用者來調用它。如果它認爲它更好,我會讓LLVM內聯它。 – Mildred