module Main where import qualified LLVM.FFI.ExecutionEngine as EE import qualified LLVM.FFI.Target as Target import qualified LLVM.FFI.Core as LLVM import qualified LLVM.Target.Native as Native import qualified Foreign.Marshal.Array as Array import qualified Foreign.Marshal.Alloc as Alloc import Foreign.C.String (withCString, peekCString) import Foreign.C.Types (CUInt, CULLong) import Foreign.Storable (Storable, peek) import Foreign.Ptr (Ptr) import qualified System.Exit as Exit import Control.Exception (finally) import Control.Monad (when) import Text.Printf (printf) withArrayLen :: (Storable a) => [a] -> (CUInt -> Ptr a -> IO b) -> IO b withArrayLen xs act = Array.withArrayLen xs $ \len ptr -> act (fromIntegral len) ptr offset :: IO CULLong offset = do Native.initializeNativeTarget int1Type <- LLVM.int1Type int8Type <- LLVM.int8Type int32Type <- LLVM.int32Type int64Type <- LLVM.int64Type structType <- withArrayLen [int1Type, int32Type, int8Type] $ \n ptr -> LLVM.structType ptr n LLVM.false nullPtr <- LLVM.constPointerNull structType zero <- LLVM.constInt int32Type 0 LLVM.false one <- LLVM.constInt int32Type 1 LLVM.false putStrLn "getElementPtr" -- crash elementPtr <- withArrayLen [zero,one] $ \n ixsPtr -> LLVM.constGEP nullPtr ixsPtr n putStrLn "ptrToInt" elementOffset <- LLVM.constPtrToInt elementPtr int64Type LLVM.constIntGetZExtValue elementOffset noResult :: IO () -> IO () noResult = id offsetTarget :: IO [CULLong] offsetTarget = do Native.initializeNativeTarget int1Type <- LLVM.int1Type int8Type <- LLVM.int8Type int32Type <- LLVM.int32Type structType <- withArrayLen [int1Type, int1Type, int32Type, int8Type] $ \n ptr -> LLVM.structType ptr n LLVM.false modul <- withCString "_module" LLVM.moduleCreateWithName withCString LLVM.hostTriple $ LLVM.setTarget modul Alloc.alloca $ \execEngineRef -> do Alloc.alloca $ \errorMsgRef -> do err <- EE.createExecutionEngineForModuleCPU execEngineRef modul errorMsgRef when (err/=LLVM.false) $ do noResult $ printf "createExecutionEngine: %s\n" =<< peekCString =<< peek errorMsgRef Exit.exitFailure execEngine <- peek execEngineRef flip finally (EE.disposeExecutionEngine execEngine) $ do td <- EE.getExecutionEngineTargetData execEngine mapM (Target.offsetOfElement td structType) [0..2] main :: IO () main = print =<< offsetTarget