2012-01-26 62 views
54

在Haskell LLVM bindings,我想定義一個具有可變數量參數的函數(實際上我的意思是一個在編譯時不知道的常數)。我找到了this question,我試圖按照答案。綁定FFI和DSL

我不想完全回退使用FFI來生成LLVM,我想盡可能多地使用DSL並使用FFI來做我不能通過DSL做的事情。

我設法通過functionType定義一個類型,我仍然無法將一個函數添加到通過調用defineModule創建的模塊中。我還認爲下一步是通過FFI.appendBasicBlock將基本塊添加到函數中,我認爲這很容易,但是如何通過CodeGenFunction monad中的do塊中的FFI.getParam獲取參數。

回答

2

如果參數列表的大小在運行時不是已知的,那麼您需要將該函數轉換爲在列表上運行的某個東西。請注意,(IORef [Word32])類型意味着IO操作將在程序執行期間讀/寫一個(可變的)Word32列表。 Haskell程序只需要說如何突變/讀取/寫入列表 - 因此IO()monad。

在你引用的LLVM git項目中有一個examples/List.hs文件。它構造的LLVM彙編程序「arrayLoop」,

arrayLoop :: 
    (Phi a, IsType b, 
    Num i, IsConst i, IsInteger i, IsFirstClass i, CmpRet i Bool) => 
    Value i -> Value (Ptr b) -> a -> 
    (Value (Ptr b) -> a -> CodeGenFunction r a) -> 
    CodeGenFunction r a 
arrayLoop len ptr start loopBody = do 

該遞增一個指針整數,p的列表,並遞減剩餘長度,I,在「體」塊的每個調用。該塊重複調用「loopBody」並將結果保存在「瓦爾」,這是最終返回(在零不變),以「S」的mList函數內部:

mList :: 
    CodeGenModule (Function 
     (StablePtr (IORef [Word32]) -> Word32 -> Ptr Word32 -> IO Int32)) 
mList = 
    createFunction ExternalLinkage $ \ ref size ptr -> do 
    next <- staticFunction nelem 
    let _ = next :: Function (StablePtr (IORef [Word32]) -> IO Word32) 
    s <- arrayLoop size ptr (valueOf 0) $ \ ptri y -> do 
     flip store ptri =<< call next ref 
     return y 
    ret (s :: Value Int32) 

所有關於nelem個多餘的東西/ NextListElement是在他們的例子中用於'loopBody',它將列表向左移動一次。該回購還提到了一個郵件列表:[email protected]

GHC7可以使用LLVM進行編譯,但我想這不會幫助解釋一種語言的Haskell程序,除非GHC也執行JIT編譯 - 任何人都知道這是否是這種情況?