{-# LANGUAGE ScopedTypeVariables #-} -- These are replacements for the broken equivalents in Foreign.*. -- The functions in Foreign.* do not obey the required alignment. module LLVM.Util.Foreign where import qualified LLVM.ExecutionEngine as EE import qualified LLVM.Util.Proxy as LP import qualified LLVM.Core as LLVM import Foreign.Marshal.Alloc (allocaBytes) import Foreign.Ptr (alignPtr) with :: (EE.Marshal a) => a -> (LLVM.Ptr a -> IO b) -> IO b with x act = alloca $ \ p -> do EE.poke p x act p alloca :: forall a b. (EE.Marshal a) => (LLVM.Ptr a -> IO b) -> IO b alloca act = allocaBytes (2 * EE.sizeOf (LP.Proxy :: LP.Proxy a)) $ \ p -> act $ LLVM.uncheckedFromPtr $ alignPtr p (EE.alignment (LP.Proxy :: LP.Proxy a)) withArrayLen :: (EE.Marshal a) => [a] -> (Int -> LLVM.Ptr a -> IO b) -> IO b withArrayLen xs act = let l = length xs in allocaBytes ((l+1) * EE.sizeOf (proxyFromList xs)) $ \ p -> do let p' = LLVM.uncheckedFromPtr $ alignPtr p $ EE.alignment $ proxyFromList xs EE.pokeList p' xs act l p' proxyFromList :: [a] -> LP.Proxy a proxyFromList _ = LP.Proxy