module LLVM.Extra.ForeignPtr (
newInit, newParam,
new, with,
) where
import qualified LLVM.Extra.Memory as Memory
import LLVM.Extra.Class (MakeValueTuple, )
import qualified Foreign.Marshal.Utils as Marshal
import qualified Foreign.ForeignPtr as FPtr
import qualified Foreign.Concurrent as FC
import Foreign.Storable (Storable, poke, )
import Foreign.Ptr (Ptr, FunPtr, )
type Importer f = FunPtr f -> f
foreign import ccall safe "dynamic" derefStartPtr ::
Importer (IO (Ptr a))
newInit ::
FunPtr (Ptr a -> IO ()) ->
FunPtr (IO (Ptr a)) ->
IO (FPtr.ForeignPtr a)
newInit stop start =
FPtr.newForeignPtr stop =<< derefStartPtr start
foreign import ccall safe "dynamic" derefStartParamPtr ::
Importer (Ptr b -> IO (Ptr a))
newParam ::
(Storable b, MakeValueTuple b bl, Memory.C bl bp) =>
FunPtr (Ptr a -> IO ()) ->
FunPtr (Ptr bp -> IO (Ptr a)) ->
b -> IO (FPtr.ForeignPtr a)
newParam stop start b =
FPtr.newForeignPtr stop =<<
Marshal.with b (derefStartParamPtr start . Memory.castStorablePtr)
new ::
Storable a =>
IO () ->
a -> IO (FPtr.ForeignPtr a)
new finalizer a = do
ptr <- FPtr.mallocForeignPtr
FC.addForeignPtrFinalizer ptr finalizer
FPtr.withForeignPtr ptr (flip poke a)
return ptr
with ::
(Storable a, MakeValueTuple a al, Memory.C al ap) =>
FPtr.ForeignPtr a -> (Ptr ap -> IO b) -> IO b
with fp func =
FPtr.withForeignPtr fp (func . Memory.castStorablePtr)