2012-01-26 4 views
54

In Haskell LLVM bindings, sto cercando di definire una funzione con un numero variabile di argomenti (in realtà intendo un numero costante che non è noto al momento della compilazione). Ho trovato this question e sto cercando di seguire la risposta.Associazione FFI e DSL

Non voglio ricorrere completamente all'utilizzo della FFI per generare LLVM, voglio usare il DSL il più possibile e utilizzare FFI per fare solo le cose che non posso fare tramite la DSL.

Sono riuscito a definire un tipo tramite functionType, non riesco ancora ad aggiungere una funzione a un modulo creato chiamando lo defineModule. Penso anche che il prossimo passo sia aggiungere i blocchi di base alla funzione tramite FFI.appendBasicBlock che ritengo sia facile, ma come ottengo gli argomenti tramite FFI.getParam all'interno di un blocco do nella monade CodeGenFunction.

risposta

2

Se la dimensione dell'elenco di argomenti non è nota fino al runtime, sarà necessario convertire la funzione in qualcosa che funziona in un elenco comunque. Si noti che il tipo (IORef [Word32]) significa che un'azione IO leggerà/scriverà una lista (mutabile) Word32 durante l'esecuzione del programma. I programmi Haskell devono solo dire in che modo modificare/leggere/scrivere l'elenco - da qui la monade IO().

C'è un esempio/file List.hs nel progetto git LLVM a cui si fa riferimento. Si costruisce un assieme di routine 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 

che incrementa un puntatore a una lista di numeri interi, p, e decrementa il rimanente lunghezza, i, in ogni chiamata del blocco di 'body'. Questo blocco chiama ripetutamente 'loopBody' e memorizza il risultato in 'vars', che alla fine viene restituito (intatta a zero) per 's' all'interno della funzione 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) 

Tutto il materiale extra su nelem/NextListElement è usato all'interno del loro esempio per 'loopBody', che sposta l'elenco una volta a sinistra. Quel pronti contro termine menziona anche una mailing list: [email protected]

GHC7 può compilare utilizzando LLVM, ma immagino che questo non sia di aiuto in un programma Haskell che interpreti una lingua a meno che GHC non esegua anche la compilazione JIT - qualcuno sa se questo è il caso?