1 % -----------------------------------------------------------------------------
2 % $Id: PrelMarshalAlloc.lhs,v 1.3 2001/08/08 14:36:14 simonmar Exp $
4 % (c) The FFI task force, 2000
7 Marshalling support: basic routines for memory allocation
10 {-# OPTIONS -fno-implicit-prelude #-}
12 module PrelMarshalAlloc (
13 malloc, -- :: Storable a => IO (Ptr a)
14 mallocBytes, -- :: Int -> IO (Ptr a)
16 alloca, -- :: Storable a => (Ptr a -> IO b) -> IO b
17 allocaBytes, -- :: Int -> (Ptr a -> IO b) -> IO b
19 reallocBytes, -- :: Ptr a -> Int -> IO (Ptr a)
21 free -- :: Ptr a -> IO ()
24 #ifdef __GLASGOW_HASKELL__
25 import PrelException ( bracket )
26 import PrelPtr ( Ptr(..), nullPtr )
27 import PrelStorable ( Storable(sizeOf) )
28 import PrelCTypesISO ( CSize )
41 -- allocate space for storable type
43 malloc :: Storable a => IO (Ptr a)
44 malloc = doMalloc undefined
46 doMalloc :: Storable a => a -> IO (Ptr a)
47 doMalloc dummy = mallocBytes (sizeOf dummy)
49 -- allocate given number of bytes of storage
51 mallocBytes :: Int -> IO (Ptr a)
52 mallocBytes size = failWhenNULL "malloc" (_malloc (fromIntegral size))
54 -- temporarily allocate space for a storable type
56 -- * the pointer passed as an argument to the function must *not* escape from
57 -- this function; in other words, in `alloca f' the allocated storage must
58 -- not be used after `f' returns
60 alloca :: Storable a => (Ptr a -> IO b) -> IO b
61 alloca = doAlloca undefined
63 doAlloca :: Storable a => a -> (Ptr a -> IO b) -> IO b
64 doAlloca dummy = allocaBytes (sizeOf dummy)
66 -- temporarily allocate the given number of bytes of storage
68 -- * the pointer passed as an argument to the function must *not* escape from
69 -- this function; in other words, in `allocaBytes n f' the allocated storage
70 -- must not be used after `f' returns
72 #ifdef __GLASGOW_HASKELL__
73 allocaBytes :: Int -> (Ptr a -> IO b) -> IO b
74 allocaBytes (I# size) action = IO $ \ s ->
75 case newPinnedByteArray# size s of { (# s, mbarr# #) ->
76 case unsafeFreezeByteArray# mbarr# s of { (# s, barr# #) ->
77 let addr = Ptr (byteArrayContents# barr#) in
78 case action addr of { IO action ->
79 case action s of { (# s, r #) ->
80 case touch# barr# s of { s ->
84 allocaBytes :: Int -> (Ptr a -> IO b) -> IO b
85 allocaBytes size = bracket (mallocBytes size) free
88 -- adjust a malloc'ed storage area to the given size
90 reallocBytes :: Ptr a -> Int -> IO (Ptr a)
91 reallocBytes ptr size =
92 failWhenNULL "realloc" (_realloc ptr (fromIntegral size))
94 -- free malloc'ed storage
96 free :: Ptr a -> IO ()
100 -- auxilliary routines
101 -- -------------------
103 -- asserts that the pointer returned from the action in the second argument is
106 failWhenNULL :: String -> IO (Ptr a) -> IO (Ptr a)
107 failWhenNULL name f = do
110 #ifdef __GLASGOW_HASKELL__
111 then ioException (IOError Nothing ResourceExhausted name
112 "out of memory" Nothing)
114 then ioError (userError (name++": out of memory"))
118 -- basic C routines needed for memory allocation
120 foreign import "malloc" unsafe _malloc :: CSize -> IO (Ptr a)
121 foreign import "realloc" unsafe _realloc :: Ptr a -> CSize -> IO (Ptr a)
122 foreign import "free" unsafe _free :: Ptr a -> IO ()