2012-01-26 11 views
54

En Haskell LLVM bindings, estoy tratando de definir una función con un número variable de argumentos (en realidad me refiero a un número constante que no se conoce en tiempo de compilación). Encontré this question y trato de seguir la respuesta.Encuadernación FFI y DSL

No quiero volver a utilizar completamente el FFI para generar LLVM, quiero usar el DSL tanto como me fuera posible y usar FFI para hacer solo lo que no puedo hacer a través del DSL.

Logré definir un tipo mediante functionType, todavía no puedo agregar una función a un módulo creado llamando al defineModule. También creo que el siguiente paso es agregar los bloques básicos a la función a través de FFI.appendBasicBlock que creo que es fácil, pero ¿cómo obtengo los argumentos a través de FFI.getParam dentro de un bloque do en la mónada CodeGenFunction?

Respuesta

2

Si no se conoce el tamaño de la lista de argumentos 'hasta el tiempo de ejecución, tendrá que convertir la función en algo que funcione en una lista de todos modos. Tenga en cuenta que el tipo (IORef [Word32]) significa que una acción IO leerá/escribirá una lista Word32 (mutable) durante la ejecución del programa. Los programas Haskell solo tienen que decir cómo para mutar/leer/escribir la lista, de ahí la mónada IO().

Hay un archivo examples/List.hs en el proyecto git de LLVM al que hizo referencia. Se construye una rutina de montaje 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 

que incrementa un puntero a una lista de enteros, p, y decrementa la longitud restante, i, en cada invocación del bloque 'cuerpo'. Ese bloque llama repetidamente 'loopBody' y almacena el resultado en 'vars', que se volvió eventual (sin tocar en cero) a 's' dentro de la función 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) 

Todo el material extra sobre nelem/NextListElement es utilizado dentro de su ejemplo para 'loopBody', que desplaza la lista una vez hacia la izquierda. Ese repositorio también menciona una lista de correo: [email protected]

GHC7 puede compilar usando LLVM, pero supongo que esto no ayudaría en un programa Haskell a interpretar un lenguaje a menos que GHC también haga compilación JIT: ¿alguien sabe si este es el caso?