{-# LANGUAGE Trustworthy #-}
{-# LANGUAGE NoImplicitPrelude, MagicHash, UnboxedTuples,
ScopedTypeVariables #-}
module Foreign.Marshal.Alloc (
alloca,
allocaBytes,
allocaBytesAligned,
malloc,
mallocBytes,
calloc,
callocBytes,
realloc,
reallocBytes,
free,
finalizerFree
) where
import Data.Maybe
import Foreign.C.Types ( CSize(..) )
import Foreign.Storable ( Storable(sizeOf,alignment) )
import Foreign.ForeignPtr ( FinalizerPtr )
import GHC.IO.Exception
import GHC.Real
import GHC.Ptr
import GHC.Base
{-# INLINE malloc #-}
malloc :: forall a . Storable a => IO (Ptr a)
malloc :: IO (Ptr a)
malloc = Int -> IO (Ptr a)
forall a. Int -> IO (Ptr a)
mallocBytes (a -> Int
forall a. Storable a => a -> Int
sizeOf (a
forall a. HasCallStack => a
undefined :: a))
{-# INLINE calloc #-}
calloc :: forall a . Storable a => IO (Ptr a)
calloc :: IO (Ptr a)
calloc = Int -> IO (Ptr a)
forall a. Int -> IO (Ptr a)
callocBytes (a -> Int
forall a. Storable a => a -> Int
sizeOf (a
forall a. HasCallStack => a
undefined :: a))
mallocBytes :: Int -> IO (Ptr a)
mallocBytes :: Int -> IO (Ptr a)
mallocBytes Int
size = String -> IO (Ptr a) -> IO (Ptr a)
forall a. String -> IO (Ptr a) -> IO (Ptr a)
failWhenNULL String
"malloc" (CSize -> IO (Ptr a)
forall a. CSize -> IO (Ptr a)
_malloc (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
size))
callocBytes :: Int -> IO (Ptr a)
callocBytes :: Int -> IO (Ptr a)
callocBytes Int
size = String -> IO (Ptr a) -> IO (Ptr a)
forall a. String -> IO (Ptr a) -> IO (Ptr a)
failWhenNULL String
"calloc" (IO (Ptr a) -> IO (Ptr a)) -> IO (Ptr a) -> IO (Ptr a)
forall a b. (a -> b) -> a -> b
$ CSize -> CSize -> IO (Ptr a)
forall a. CSize -> CSize -> IO (Ptr a)
_calloc CSize
1 (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
size)
{-# INLINE alloca #-}
alloca :: forall a b . Storable a => (Ptr a -> IO b) -> IO b
alloca :: (Ptr a -> IO b) -> IO b
alloca =
Int -> Int -> (Ptr a -> IO b) -> IO b
forall a b. Int -> Int -> (Ptr a -> IO b) -> IO b
allocaBytesAligned (a -> Int
forall a. Storable a => a -> Int
sizeOf (a
forall a. HasCallStack => a
undefined :: a)) (a -> Int
forall a. Storable a => a -> Int
alignment (a
forall a. HasCallStack => a
undefined :: a))
allocaBytes :: Int -> (Ptr a -> IO b) -> IO b
allocaBytes :: Int -> (Ptr a -> IO b) -> IO b
allocaBytes (I# Int#
size) Ptr a -> IO b
action = (State# RealWorld -> (# State# RealWorld, b #)) -> IO b
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, b #)) -> IO b)
-> (State# RealWorld -> (# State# RealWorld, b #)) -> IO b
forall a b. (a -> b) -> a -> b
$ \ State# RealWorld
s0 ->
case Int#
-> State# RealWorld
-> (# State# RealWorld, MutableByteArray# RealWorld #)
forall d. Int# -> State# d -> (# State# d, MutableByteArray# d #)
newPinnedByteArray# Int#
size State# RealWorld
s0 of { (# State# RealWorld
s1, MutableByteArray# RealWorld
mbarr# #) ->
case MutableByteArray# RealWorld
-> State# RealWorld -> (# State# RealWorld, ByteArray# #)
forall d.
MutableByteArray# d -> State# d -> (# State# d, ByteArray# #)
unsafeFreezeByteArray# MutableByteArray# RealWorld
mbarr# State# RealWorld
s1 of { (# State# RealWorld
s2, ByteArray#
barr# #) ->
let addr :: Ptr a
addr = Addr# -> Ptr a
forall a. Addr# -> Ptr a
Ptr (ByteArray# -> Addr#
byteArrayContents# ByteArray#
barr#) in
case Ptr a -> IO b
action Ptr a
forall a. Ptr a
addr of { IO State# RealWorld -> (# State# RealWorld, b #)
action' ->
case State# RealWorld -> (# State# RealWorld, b #)
action' State# RealWorld
s2 of { (# State# RealWorld
s3, b
r #) ->
case ByteArray# -> State# RealWorld -> State# RealWorld
forall a. a -> State# RealWorld -> State# RealWorld
touch# ByteArray#
barr# State# RealWorld
s3 of { State# RealWorld
s4 ->
(# State# RealWorld
s4, b
r #)
}}}}}
{-# NOINLINE allocaBytes #-}
allocaBytesAligned :: Int -> Int -> (Ptr a -> IO b) -> IO b
allocaBytesAligned :: Int -> Int -> (Ptr a -> IO b) -> IO b
allocaBytesAligned (I# Int#
size) (I# Int#
align) Ptr a -> IO b
action = (State# RealWorld -> (# State# RealWorld, b #)) -> IO b
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, b #)) -> IO b)
-> (State# RealWorld -> (# State# RealWorld, b #)) -> IO b
forall a b. (a -> b) -> a -> b
$ \ State# RealWorld
s0 ->
case Int#
-> Int#
-> State# RealWorld
-> (# State# RealWorld, MutableByteArray# RealWorld #)
forall d.
Int# -> Int# -> State# d -> (# State# d, MutableByteArray# d #)
newAlignedPinnedByteArray# Int#
size Int#
align State# RealWorld
s0 of { (# State# RealWorld
s1, MutableByteArray# RealWorld
mbarr# #) ->
case MutableByteArray# RealWorld
-> State# RealWorld -> (# State# RealWorld, ByteArray# #)
forall d.
MutableByteArray# d -> State# d -> (# State# d, ByteArray# #)
unsafeFreezeByteArray# MutableByteArray# RealWorld
mbarr# State# RealWorld
s1 of { (# State# RealWorld
s2, ByteArray#
barr# #) ->
let addr :: Ptr a
addr = Addr# -> Ptr a
forall a. Addr# -> Ptr a
Ptr (ByteArray# -> Addr#
byteArrayContents# ByteArray#
barr#) in
case Ptr a -> IO b
action Ptr a
forall a. Ptr a
addr of { IO State# RealWorld -> (# State# RealWorld, b #)
action' ->
case State# RealWorld -> (# State# RealWorld, b #)
action' State# RealWorld
s2 of { (# State# RealWorld
s3, b
r #) ->
case ByteArray# -> State# RealWorld -> State# RealWorld
forall a. a -> State# RealWorld -> State# RealWorld
touch# ByteArray#
barr# State# RealWorld
s3 of { State# RealWorld
s4 ->
(# State# RealWorld
s4, b
r #)
}}}}}
{-# NOINLINE allocaBytesAligned #-}
realloc :: forall a b . Storable b => Ptr a -> IO (Ptr b)
realloc :: Ptr a -> IO (Ptr b)
realloc Ptr a
ptr = String -> IO (Ptr b) -> IO (Ptr b)
forall a. String -> IO (Ptr a) -> IO (Ptr a)
failWhenNULL String
"realloc" (Ptr a -> CSize -> IO (Ptr b)
forall a b. Ptr a -> CSize -> IO (Ptr b)
_realloc Ptr a
ptr CSize
size)
where
size :: CSize
size = Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (b -> Int
forall a. Storable a => a -> Int
sizeOf (b
forall a. HasCallStack => a
undefined :: b))
reallocBytes :: Ptr a -> Int -> IO (Ptr a)
reallocBytes :: Ptr a -> Int -> IO (Ptr a)
reallocBytes Ptr a
ptr Int
0 = do Ptr a -> IO ()
forall a. Ptr a -> IO ()
free Ptr a
ptr; Ptr a -> IO (Ptr a)
forall (m :: * -> *) a. Monad m => a -> m a
return Ptr a
forall a. Ptr a
nullPtr
reallocBytes Ptr a
ptr Int
size =
String -> IO (Ptr a) -> IO (Ptr a)
forall a. String -> IO (Ptr a) -> IO (Ptr a)
failWhenNULL String
"realloc" (Ptr a -> CSize -> IO (Ptr a)
forall a b. Ptr a -> CSize -> IO (Ptr b)
_realloc Ptr a
ptr (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
size))
free :: Ptr a -> IO ()
free :: Ptr a -> IO ()
free = Ptr a -> IO ()
forall a. Ptr a -> IO ()
_free
failWhenNULL :: String -> IO (Ptr a) -> IO (Ptr a)
failWhenNULL :: String -> IO (Ptr a) -> IO (Ptr a)
failWhenNULL String
name IO (Ptr a)
f = do
Ptr a
addr <- IO (Ptr a)
f
if Ptr a
addr Ptr a -> Ptr a -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr a
forall a. Ptr a
nullPtr
then IOError -> IO (Ptr a)
forall a. IOError -> IO a
ioError (Maybe Handle
-> IOErrorType
-> String
-> String
-> Maybe CInt
-> Maybe String
-> IOError
IOError Maybe Handle
forall a. Maybe a
Nothing IOErrorType
ResourceExhausted String
name
String
"out of memory" Maybe CInt
forall a. Maybe a
Nothing Maybe String
forall a. Maybe a
Nothing)
else Ptr a -> IO (Ptr a)
forall (m :: * -> *) a. Monad m => a -> m a
return Ptr a
addr
foreign import ccall unsafe "stdlib.h malloc" _malloc :: CSize -> IO (Ptr a)
foreign import ccall unsafe "stdlib.h calloc" _calloc :: CSize -> CSize -> IO (Ptr a)
foreign import ccall unsafe "stdlib.h realloc" _realloc :: Ptr a -> CSize -> IO (Ptr b)
foreign import ccall unsafe "stdlib.h free" _free :: Ptr a -> IO ()
foreign import ccall unsafe "stdlib.h &free" finalizerFree :: FinalizerPtr a