1 {-# OPTIONS_GHC -XNoImplicitPrelude #-}
2 -----------------------------------------------------------------------------
4 -- Module : Foreign.Marshal.Alloc
5 -- Copyright : (c) The FFI task force 2001
6 -- License : BSD-style (see the file libraries/base/LICENSE)
8 -- Maintainer : ffi@haskell.org
9 -- Stability : provisional
10 -- Portability : portable
12 -- The module "Foreign.Marshal.Alloc" provides operations to allocate and
13 -- deallocate blocks of raw memory (i.e., unstructured chunks of memory
14 -- outside of the area maintained by the Haskell storage manager). These
15 -- memory blocks are commonly used to pass compound data structures to
16 -- foreign functions or to provide space in which compound result values
17 -- are obtained from foreign functions.
19 -- If any of the allocation functions fails, a value of 'nullPtr' is
20 -- produced. If 'free' or 'reallocBytes' is applied to a memory area
21 -- that has been allocated with 'alloca' or 'allocaBytes', the
22 -- behaviour is undefined. Any further access to memory areas allocated with
23 -- 'alloca' or 'allocaBytes', after the computation that was passed to
24 -- the allocation function has terminated, leads to undefined behaviour. Any
25 -- further access to the memory area referenced by a pointer passed to
26 -- 'realloc', 'reallocBytes', or 'free' entails undefined
29 -- All storage allocated by functions that allocate based on a /size in bytes/
30 -- must be sufficiently aligned for any of the basic foreign types
31 -- that fits into the newly allocated storage. All storage allocated by
32 -- functions that allocate based on a specific type must be sufficiently
33 -- aligned for that type. Array allocation routines need to obey the same
34 -- alignment constraints for each array element.
36 -----------------------------------------------------------------------------
38 module Foreign.Marshal.Alloc (
39 -- * Memory allocation
40 -- ** Local allocation
41 alloca, -- :: Storable a => (Ptr a -> IO b) -> IO b
42 allocaBytes, -- :: Int -> (Ptr a -> IO b) -> IO b
43 allocaBytesAligned, -- :: Int -> Int -> (Ptr a -> IO b) -> IO b
45 -- ** Dynamic allocation
46 malloc, -- :: Storable a => IO (Ptr a)
47 mallocBytes, -- :: Int -> IO (Ptr a)
49 realloc, -- :: Storable b => Ptr a -> IO (Ptr b)
50 reallocBytes, -- :: Ptr a -> Int -> IO (Ptr a)
52 free, -- :: Ptr a -> IO ()
53 finalizerFree -- :: FinalizerPtr a
57 import Foreign.C.Types ( CSize )
58 import Foreign.Storable ( Storable(sizeOf,alignment) )
60 #ifndef __GLASGOW_HASKELL__
61 import Foreign.Ptr ( Ptr, nullPtr, FunPtr )
64 #ifdef __GLASGOW_HASKELL__
65 import Foreign.ForeignPtr ( FinalizerPtr )
66 import GHC.IO.Exception
72 #elif defined(__NHC__)
73 import NHC.FFI ( FinalizerPtr, CInt(..) )
76 import Control.Exception.Base ( bracket )
80 import Hugs.Prelude ( IOException(IOError),
81 IOErrorType(ResourceExhausted) )
82 import Hugs.ForeignPtr ( FinalizerPtr )
89 -- |Allocate a block of memory that is sufficient to hold values of type
90 -- @a@. The size of the area allocated is determined by the 'sizeOf'
91 -- method from the instance of 'Storable' for the appropriate type.
93 -- The memory may be deallocated using 'free' or 'finalizerFree' when
94 -- no longer required.
97 malloc :: Storable a => IO (Ptr a)
98 malloc = doMalloc undefined
100 doMalloc :: Storable b => b -> IO (Ptr b)
101 doMalloc dummy = mallocBytes (sizeOf dummy)
103 -- |Allocate a block of memory of the given number of bytes.
104 -- The block of memory is sufficiently aligned for any of the basic
105 -- foreign types that fits into a memory block of the allocated size.
107 -- The memory may be deallocated using 'free' or 'finalizerFree' when
108 -- no longer required.
110 mallocBytes :: Int -> IO (Ptr a)
111 mallocBytes size = failWhenNULL "malloc" (_malloc (fromIntegral size))
113 -- |@'alloca' f@ executes the computation @f@, passing as argument
114 -- a pointer to a temporarily allocated block of memory sufficient to
115 -- hold values of type @a@.
117 -- The memory is freed when @f@ terminates (either normally or via an
118 -- exception), so the pointer passed to @f@ must /not/ be used after this.
120 {-# INLINE alloca #-}
121 alloca :: Storable a => (Ptr a -> IO b) -> IO b
122 alloca = doAlloca undefined
124 doAlloca :: Storable a' => a' -> (Ptr a' -> IO b') -> IO b'
125 doAlloca dummy = allocaBytesAligned (sizeOf dummy) (alignment dummy)
127 -- |@'allocaBytes' n f@ executes the computation @f@, passing as argument
128 -- a pointer to a temporarily allocated block of memory of @n@ bytes.
129 -- The block of memory is sufficiently aligned for any of the basic
130 -- foreign types that fits into a memory block of the allocated size.
132 -- The memory is freed when @f@ terminates (either normally or via an
133 -- exception), so the pointer passed to @f@ must /not/ be used after this.
135 #ifdef __GLASGOW_HASKELL__
136 allocaBytes :: Int -> (Ptr a -> IO b) -> IO b
137 allocaBytes (I# size) action = IO $ \ s0 ->
138 case newPinnedByteArray# size s0 of { (# s1, mbarr# #) ->
139 case unsafeFreezeByteArray# mbarr# s1 of { (# s2, barr# #) ->
140 let addr = Ptr (byteArrayContents# barr#) in
141 case action addr of { IO action' ->
142 case action' s2 of { (# s3, r #) ->
143 case touch# barr# s3 of { s4 ->
147 allocaBytesAligned :: Int -> Int -> (Ptr a -> IO b) -> IO b
148 allocaBytesAligned (I# size) (I# align) action = IO $ \ s0 ->
149 case newAlignedPinnedByteArray# size align s0 of { (# s1, mbarr# #) ->
150 case unsafeFreezeByteArray# mbarr# s1 of { (# s2, barr# #) ->
151 let addr = Ptr (byteArrayContents# barr#) in
152 case action addr of { IO action' ->
153 case action' s2 of { (# s3, r #) ->
154 case touch# barr# s3 of { s4 ->
158 allocaBytes :: Int -> (Ptr a -> IO b) -> IO b
159 allocaBytes size = bracket (mallocBytes size) free
161 allocaBytesAligned :: Int -> Int -> (Ptr a -> IO b) -> IO b
162 allocaBytesAligned size align = allocaBytes size -- wrong
165 -- |Resize a memory area that was allocated with 'malloc' or 'mallocBytes'
166 -- to the size needed to store values of type @b@. The returned pointer
167 -- may refer to an entirely different memory area, but will be suitably
168 -- aligned to hold values of type @b@. The contents of the referenced
169 -- memory area will be the same as of the original pointer up to the
170 -- minimum of the original size and the size of values of type @b@.
172 -- If the argument to 'realloc' is 'nullPtr', 'realloc' behaves like
175 realloc :: Storable b => Ptr a -> IO (Ptr b)
176 realloc = doRealloc undefined
178 doRealloc :: Storable b' => b' -> Ptr a' -> IO (Ptr b')
179 doRealloc dummy ptr = let
180 size = fromIntegral (sizeOf dummy)
182 failWhenNULL "realloc" (_realloc ptr size)
184 -- |Resize a memory area that was allocated with 'malloc' or 'mallocBytes'
185 -- to the given size. The returned pointer may refer to an entirely
186 -- different memory area, but will be sufficiently aligned for any of the
187 -- basic foreign types that fits into a memory block of the given size.
188 -- The contents of the referenced memory area will be the same as of
189 -- the original pointer up to the minimum of the original size and the
192 -- If the pointer argument to 'reallocBytes' is 'nullPtr', 'reallocBytes'
193 -- behaves like 'malloc'. If the requested size is 0, 'reallocBytes'
194 -- behaves like 'free'.
196 reallocBytes :: Ptr a -> Int -> IO (Ptr a)
197 reallocBytes ptr 0 = do free ptr; return nullPtr
198 reallocBytes ptr size =
199 failWhenNULL "realloc" (_realloc ptr (fromIntegral size))
201 -- |Free a block of memory that was allocated with 'malloc',
202 -- 'mallocBytes', 'realloc', 'reallocBytes', 'Foreign.Marshal.Utils.new'
203 -- or any of the @new@/X/ functions in "Foreign.Marshal.Array" or
204 -- "Foreign.C.String".
206 free :: Ptr a -> IO ()
210 -- auxilliary routines
211 -- -------------------
213 -- asserts that the pointer returned from the action in the second argument is
216 failWhenNULL :: String -> IO (Ptr a) -> IO (Ptr a)
217 failWhenNULL name f = do
220 #if __GLASGOW_HASKELL__
221 then ioError (IOError Nothing ResourceExhausted name
222 "out of memory" Nothing Nothing)
224 then ioError (IOError Nothing ResourceExhausted name
225 "out of memory" Nothing)
227 then ioError (userError (name++": out of memory"))
231 -- basic C routines needed for memory allocation
233 foreign import ccall unsafe "stdlib.h malloc" _malloc :: CSize -> IO (Ptr a)
234 foreign import ccall unsafe "stdlib.h realloc" _realloc :: Ptr a -> CSize -> IO (Ptr b)
235 foreign import ccall unsafe "stdlib.h free" _free :: Ptr a -> IO ()
237 -- | A pointer to a foreign function equivalent to 'free', which may be
238 -- used as a finalizer (cf 'Foreign.ForeignPtr.ForeignPtr') for storage
239 -- allocated with 'malloc', 'mallocBytes', 'realloc' or 'reallocBytes'.
240 foreign import ccall unsafe "stdlib.h &free" finalizerFree :: FinalizerPtr a