2012-01-26 7 views
54

Haskell LLVM bindingsでは、可変数の引数を持つ関数を定義しようとしています(実際には、コンパイル時には知られていない定数を意味します)。私はthis questionを見つけました。私はその答えに従っています。FFIとDSLのバインド

LLVMを生成するためにFFIを使用することに完全には戻りたくないので、私はできるだけDSLを使用し、FFIを使用してDSL経由で行うことはできません。

functionTypeで型を定義することができましたが、私はまだdefineModuleを呼び出して作成したモジュールに関数を追加できません。私はまた、次のステップは、簡単なことだと思うFFI.appendBasicBlock経由で基本ブロックを関数に追加することだと考えていますが、CodeGenFunctionモナドのdoブロックの中にFFI.getParamという引数をどのようにして取得しますか?

答えて

2

引数リストのサイズがランタイムまでわからない場合は、関数をリスト上で動作するものに変換する必要があります。 (IORef [Word32])タイプは、プログラムの実行中にIOアクションが(変更可能な)Word32リストを読み書きすることを意味します。ハスケルプログラムはと言うだけで、リストを変更/読み書きする方法はだから、IO()モナド。

参照しているLLVM gitプロジェクトにexamples/List.hsファイルがあります。それは身体ブロックの各呼び出しで、P、intのリストへのポインタをインクリメントすること

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 

、LLVMアセンブリルーチン「arrayLoop」を構成し、残りの長さをデクリメント、I。そのブロックを繰り返しmList関数内で「S」に最終的に(ゼロで手付かず)返される、「loopBody」呼び出すと「varsの」で結果を格納:

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を使ってコンパイルすることができますが、GHCもJITコンパイルを行わない限り、これはHaskellプログラムが言語を解釈するのに役立ちません。