[project @ 2001-01-11 17:25:56 by simonmar]
[ghc-hetmet.git] / ghc / lib / std / PrelMarshalAlloc.lhs
1 % -----------------------------------------------------------------------------
2 % $Id: PrelMarshalAlloc.lhs,v 1.1 2001/01/11 17:25:57 simonmar Exp $
3 %
4 % (c) The FFI task force, 2000
5 %
6
7 Marshalling support: basic routines for memory allocation
8
9 \begin{code}
10 module PrelMarshalAlloc (
11   malloc,       -- :: Storable a =>        IO (Ptr a)
12   mallocBytes,  -- ::               Int -> IO (Ptr a)
13
14   alloca,       -- :: Storable a =>        (Ptr a -> IO b) -> IO b
15   allocaBytes,  -- ::               Int -> (Ptr a -> IO b) -> IO b
16
17   reallocBytes, -- :: Ptr a -> Int -> IO (Ptr a)
18
19   free          -- :: Ptr a -> IO ()
20 ) where
21
22 import PrelException    ( bracket )
23 import PrelPtr          ( Ptr, nullPtr )
24 import PrelStorable     ( Storable(sizeOf) )
25 import PrelCTypesISO    ( CSize )
26
27 #ifdef __GLASGOW_HASKELL__
28 import PrelIOBase hiding (malloc, _malloc)
29 #endif
30
31
32 -- exported functions
33 -- ------------------
34
35 -- allocate space for storable type
36 --
37 malloc :: Storable a => IO (Ptr a)
38 malloc  = doMalloc undefined
39   where
40     doMalloc       :: Storable a => a -> IO (Ptr a)
41     doMalloc dummy  = mallocBytes (sizeOf dummy)
42
43 -- allocate given number of bytes of storage
44 --
45 mallocBytes      :: Int -> IO (Ptr a)
46 mallocBytes size  = failWhenNULL "malloc" (_malloc (fromIntegral size))
47
48 -- temporarily allocate space for a storable type
49 --
50 -- * the pointer passed as an argument to the function must *not* escape from
51 --   this function; in other words, in `alloca f' the allocated storage must
52 --   not be used after `f' returns
53 --
54 alloca :: Storable a => (Ptr a -> IO b) -> IO b
55 alloca  = doAlloca undefined
56   where
57     doAlloca       :: Storable a => a -> (Ptr a -> IO b) -> IO b
58     doAlloca dummy  = allocaBytes (sizeOf dummy)
59
60 -- temporarily allocate the given number of bytes of storage
61 --
62 -- * the pointer passed as an argument to the function must *not* escape from
63 --   this function; in other words, in `allocaBytes n f' the allocated storage
64 --   must not be used after `f' returns
65 --
66 allocaBytes      :: Int -> (Ptr a -> IO b) -> IO b
67 allocaBytes size  = bracket (mallocBytes size) free
68
69 -- adjust a malloc'ed storage area to the given size
70 --
71 reallocBytes          :: Ptr a -> Int -> IO (Ptr a)
72 reallocBytes ptr size  = 
73   failWhenNULL "realloc" (_realloc ptr (fromIntegral size))
74
75 -- free malloc'ed storage
76 --
77 free :: Ptr a -> IO ()
78 free  = _free
79
80
81 -- auxilliary routines
82 -- -------------------
83
84 -- asserts that the pointer returned from the action in the second argument is
85 -- non-null
86 --
87 failWhenNULL :: String -> IO (Ptr a) -> IO (Ptr a)
88 failWhenNULL name f = do
89    addr <- f
90    if addr == nullPtr
91 #ifdef __GLASGOW_HASKELL__
92       then ioException (IOError Nothing ResourceExhausted name 
93                                         "out of memory" Nothing)
94 #else
95       then ioError (userError (name++": out of memory"))
96 #endif
97       else return addr
98
99 -- basic C routines needed for memory allocation
100 --
101 foreign import "malloc"  unsafe _malloc  ::          CSize -> IO (Ptr a)
102 foreign import "realloc" unsafe _realloc :: Ptr a -> CSize -> IO (Ptr a)
103 foreign import "free"    unsafe _free    :: Ptr a -> IO ()
104
105 \end{code}