If the size of the argument list isn’t known ’till runtime, you would need to convert the function to something operating on a list anyway. Note that the (IORef [Word32]) type means that an IO action will read/write a (mutable) Word32 list during program execution. Haskell programs only have to say how to mutate/read/write the list — hence the IO() monad.
There’s an examples/List.hs file in the LLVM git project you referenced. It constructs an LLVM assembly routine “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
that increments a pointer to a list of ints, p, and decrements the remaining length, i, in each invocation of the ‘body’ block. That block repeatedly calls ‘loopBody’ and stores the result in ‘vars’, which is eventually returned (untouched at zero) to ‘s’ inside the mList function:
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)
All the extra stuff about nelem/NextListElement is used inside their example for ‘loopBody,’ which shifts the list once to the left. That repo also mentions a mailing list: haskell-llvm@projects.haskellorg.
GHC7 can compile using LLVM, but I guess this would not help in a Haskell program interpreting a language unless GHC also does JIT compilation – anyone know if this is the case?