{-# OPTIONS_GHC -XNoImplicitPrelude #-}------------------------------------------------------------------------------- |-- Module : Foreign.Marshal.Alloc-- Copyright : (c) The FFI task force 2001-- License : BSD-style (see the file libraries/base/LICENSE)-- -- Maintainer : ffi@haskell.org-- Stability : provisional-- Portability : portable---- The module "Foreign.Marshal.Alloc" provides operations to allocate and-- deallocate blocks of raw memory (i.e., unstructured chunks of memory-- outside of the area maintained by the Haskell storage manager). These-- memory blocks are commonly used to pass compound data structures to-- foreign functions or to provide space in which compound result values-- are obtained from foreign functions.-- -- If any of the allocation functions fails, a value of 'nullPtr' is-- produced. If 'free' or 'reallocBytes' is applied to a memory area-- that has been allocated with 'alloca' or 'allocaBytes', the-- behaviour is undefined. Any further access to memory areas allocated with-- 'alloca' or 'allocaBytes', after the computation that was passed to-- the allocation function has terminated, leads to undefined behaviour. Any-- further access to the memory area referenced by a pointer passed to-- 'realloc', 'reallocBytes', or 'free' entails undefined-- behaviour.-- -- All storage allocated by functions that allocate based on a /size in bytes/-- must be sufficiently aligned for any of the basic foreign types-- that fits into the newly allocated storage. All storage allocated by-- functions that allocate based on a specific type must be sufficiently-- aligned for that type. Array allocation routines need to obey the same-- alignment constraints for each array element.-------------------------------------------------------------------------------moduleForeign.Marshal.Alloc(-- * Memory allocation-- ** Local allocationalloca,-- :: Storable a => (Ptr a -> IO b) -> IO ballocaBytes,-- :: Int -> (Ptr a -> IO b) -> IO ballocaBytesAligned,-- :: Int -> Int -> (Ptr a -> IO b) -> IO b-- ** Dynamic allocationmalloc,-- :: Storable a => IO (Ptr a)mallocBytes,-- :: Int -> IO (Ptr a)realloc,-- :: Storable b => Ptr a -> IO (Ptr b)reallocBytes,-- :: Ptr a -> Int -> IO (Ptr a)free,-- :: Ptr a -> IO ()finalizerFree-- :: FinalizerPtr a)whereimportData.MaybeimportForeign.C.Types(CSize)importForeign.Storable(Storable(sizeOf,alignment))#ifndef __GLASGOW_HASKELL__importForeign.Ptr(Ptr,nullPtr,FunPtr)#endif#ifdef __GLASGOW_HASKELL__importForeign.ForeignPtr(FinalizerPtr)importGHC.IO.ExceptionimportGHC.RealimportGHC.PtrimportGHC.ErrimportGHC.Base#elif defined(__NHC__)importNHC.FFI(FinalizerPtr,CInt(..))importIO(bracket)#elseimportControl.Exception.Base(bracket)#endif#ifdef __HUGS__importHugs.Prelude(IOException(IOError),IOErrorType(ResourceExhausted))importHugs.ForeignPtr(FinalizerPtr)#endif-- exported functions-- -------------------- |Allocate a block of memory that is sufficient to hold values of type-- @a@. The size of the area allocated is determined by the 'sizeOf'-- method from the instance of 'Storable' for the appropriate type.---- The memory may be deallocated using 'free' or 'finalizerFree' when-- no longer required.--{-# INLINE malloc #-}malloc::Storablea=>IO(Ptra)malloc=doMallocundefinedwheredoMalloc::Storableb=>b->IO(Ptrb)doMallocdummy=mallocBytes(sizeOfdummy)-- |Allocate a block of memory of the given number of bytes.-- The block of memory is sufficiently aligned for any of the basic-- foreign types that fits into a memory block of the allocated size.---- The memory may be deallocated using 'free' or 'finalizerFree' when-- no longer required.--mallocBytes::Int->IO(Ptra)mallocBytessize=failWhenNULL"malloc"(_malloc(fromIntegralsize))-- |@'alloca' f@ executes the computation @f@, passing as argument-- a pointer to a temporarily allocated block of memory sufficient to-- hold values of type @a@.---- The memory is freed when @f@ terminates (either normally or via an-- exception), so the pointer passed to @f@ must /not/ be used after this.--{-# INLINE alloca #-}alloca::Storablea=>(Ptra->IOb)->IOballoca=doAllocaundefinedwheredoAlloca::Storablea'=>a'->(Ptra'->IOb')->IOb'doAllocadummy=allocaBytesAligned(sizeOfdummy)(alignmentdummy)-- |@'allocaBytes' n f@ executes the computation @f@, passing as argument-- a pointer to a temporarily allocated block of memory of @n@ bytes.-- The block of memory is sufficiently aligned for any of the basic-- foreign types that fits into a memory block of the allocated size.---- The memory is freed when @f@ terminates (either normally or via an-- exception), so the pointer passed to @f@ must /not/ be used after this.--#ifdef __GLASGOW_HASKELL__allocaBytes::Int->(Ptra->IOb)->IOballocaBytes(I#size)action=IO$\s0->casenewPinnedByteArray#sizes0of{(#s1,mbarr##)->caseunsafeFreezeByteArray#mbarr#s1of{(#s2,barr##)->letaddr=Ptr(byteArrayContents#barr#)incaseactionaddrof{IOaction'->caseaction's2of{(#s3,r#)->casetouch#barr#s3of{s4->(#s4,r#)}}}}}allocaBytesAligned::Int->Int->(Ptra->IOb)->IOballocaBytesAligned(I#size)(I#align)action=IO$\s0->casenewAlignedPinnedByteArray#sizealigns0of{(#s1,mbarr##)->caseunsafeFreezeByteArray#mbarr#s1of{(#s2,barr##)->letaddr=Ptr(byteArrayContents#barr#)incaseactionaddrof{IOaction'->caseaction's2of{(#s3,r#)->casetouch#barr#s3of{s4->(#s4,r#)}}}}}#elseallocaBytes::Int->(Ptra->IOb)->IOballocaBytessize=bracket(mallocBytessize)freeallocaBytesAligned::Int->Int->(Ptra->IOb)->IOballocaBytesAlignedsizealign=allocaBytessize-- wrong#endif-- |Resize a memory area that was allocated with 'malloc' or 'mallocBytes'-- to the size needed to store values of type @b@. The returned pointer-- may refer to an entirely different memory area, but will be suitably-- aligned to hold values of type @b@. The contents of the referenced-- memory area will be the same as of the original pointer up to the-- minimum of the original size and the size of values of type @b@.---- If the argument to 'realloc' is 'nullPtr', 'realloc' behaves like-- 'malloc'.--realloc::Storableb=>Ptra->IO(Ptrb)realloc=doReallocundefinedwheredoRealloc::Storableb'=>b'->Ptra'->IO(Ptrb')doReallocdummyptr=letsize=fromIntegral(sizeOfdummy)infailWhenNULL"realloc"(_reallocptrsize)-- |Resize a memory area that was allocated with 'malloc' or 'mallocBytes'-- to the given size. The returned pointer may refer to an entirely-- different memory area, but will be sufficiently aligned for any of the-- basic foreign types that fits into a memory block of the given size.-- The contents of the referenced memory area will be the same as of-- the original pointer up to the minimum of the original size and the-- given size.---- If the pointer argument to 'reallocBytes' is 'nullPtr', 'reallocBytes'-- behaves like 'malloc'. If the requested size is 0, 'reallocBytes'-- behaves like 'free'.--reallocBytes::Ptra->Int->IO(Ptra)reallocBytesptr0=dofreeptr;returnnullPtrreallocBytesptrsize=failWhenNULL"realloc"(_reallocptr(fromIntegralsize))-- |Free a block of memory that was allocated with 'malloc',-- 'mallocBytes', 'realloc', 'reallocBytes', 'Foreign.Marshal.Utils.new'-- or any of the @new@/X/ functions in "Foreign.Marshal.Array" or-- "Foreign.C.String".--free::Ptra->IO()free=_free-- auxilliary routines-- --------------------- asserts that the pointer returned from the action in the second argument is-- non-null--failWhenNULL::String->IO(Ptra)->IO(Ptra)failWhenNULLnamef=doaddr<-fifaddr==nullPtr#if __GLASGOW_HASKELL__thenioError(IOErrorNothingResourceExhaustedname"out of memory"NothingNothing)#elif __HUGS__thenioError(IOErrorNothingResourceExhaustedname"out of memory"Nothing)#elsethenioError(userError(name++": out of memory"))#endifelsereturnaddr-- basic C routines needed for memory allocation--foreignimportccallunsafe"stdlib.h malloc"_malloc::CSize->IO(Ptra)foreignimportccallunsafe"stdlib.h realloc"_realloc::Ptra->CSize->IO(Ptrb)foreignimportccallunsafe"stdlib.h free"_free::Ptra->IO()-- | A pointer to a foreign function equivalent to 'free', which may be-- used as a finalizer (cf 'Foreign.ForeignPtr.ForeignPtr') for storage-- allocated with 'malloc', 'mallocBytes', 'realloc' or 'reallocBytes'.foreignimportccallunsafe"stdlib.h &free"finalizerFree::FinalizerPtra