module LLVM.Wrapper.Internal where

import Foreign.ForeignPtr.Safe (ForeignPtr, newForeignPtr)
import qualified Foreign.Concurrent as FC (newForeignPtr)
import Foreign.Ptr (Ptr)

import Control.Monad
import Data.IORef

import qualified LLVM.FFI.Core as FFI
import qualified LLVM.FFI.Transforms.PassManagerBuilder as FFI

data Module = MkModule (ForeignPtr FFI.Module) (IORef Bool)
              deriving Eq

data PassManager = MkPassManager (ForeignPtr FFI.PassManager)
                 deriving Eq

data PassManagerBuilder = MkPassManagerBuilder (ForeignPtr FFI.PassManagerBuilder)
                        deriving Eq

moduleFinalizer :: Ptr FFI.Module -> IORef Bool -> IO ()
moduleFinalizer m ours = do
  isOurs <- readIORef ours
  when isOurs $ FFI.disposeModule m

initModule :: Ptr FFI.Module -> IO Module
initModule ptr = do
  ours <- newIORef True
  fptr <- FC.newForeignPtr ptr (moduleFinalizer ptr ours)
  return $ MkModule fptr ours

initPassManager :: Ptr FFI.PassManager -> IO PassManager
initPassManager ptr = fmap MkPassManager (newForeignPtr FFI.ptrDisposePassManager ptr)

initPassManagerBuilder :: Ptr FFI.PassManagerBuilder -> IO PassManagerBuilder
initPassManagerBuilder ptr = fmap MkPassManagerBuilder (newForeignPtr FFI.ptrPassManagerBuilderDispose ptr)