go-ify foldr2
[packages/base.git] / GHC / Ptr.lhs
1 \begin{code}
2 {-# LANGUAGE Unsafe #-}
3 {-# LANGUAGE CPP, NoImplicitPrelude, MagicHash, RoleAnnotations #-}
4 {-# OPTIONS_HADDOCK hide #-}
5
6 -----------------------------------------------------------------------------
7 -- |
8 -- Module      :  GHC.Ptr
9 -- Copyright   :  (c) The FFI Task Force, 2000-2002
10 -- License     :  see libraries/base/LICENSE
11 -- 
12 -- Maintainer  :  ffi@haskell.org
13 -- Stability   :  internal
14 -- Portability :  non-portable (GHC Extensions)
15 --
16 -- The 'Ptr' and 'FunPtr' types and operations.
17 --
18 -----------------------------------------------------------------------------
19
20 module GHC.Ptr (
21         Ptr(..), FunPtr(..),
22         nullPtr, castPtr, plusPtr, alignPtr, minusPtr,
23         nullFunPtr, castFunPtr,
24
25         -- * Unsafe functions
26         castFunPtrToPtr, castPtrToFunPtr
27     ) where
28
29 import GHC.Base
30 import GHC.Show
31 import GHC.Num
32 import GHC.List ( length, replicate )
33 import Numeric          ( showHex )
34
35 #include "MachDeps.h"
36
37 ------------------------------------------------------------------------
38 -- Data pointers.
39
40 type role Ptr representational
41 data Ptr a = Ptr Addr# deriving (Eq, Ord)
42 -- ^ A value of type @'Ptr' a@ represents a pointer to an object, or an
43 -- array of objects, which may be marshalled to or from Haskell values
44 -- of type @a@.
45 --
46 -- The type @a@ will often be an instance of class
47 -- 'Foreign.Storable.Storable' which provides the marshalling operations.
48 -- However this is not essential, and you can provide your own operations
49 -- to access the pointer.  For example you might write small foreign
50 -- functions to get or set the fields of a C @struct@.
51
52 -- |The constant 'nullPtr' contains a distinguished value of 'Ptr'
53 -- that is not associated with a valid memory location.
54 nullPtr :: Ptr a
55 nullPtr = Ptr nullAddr#
56
57 -- |The 'castPtr' function casts a pointer from one type to another.
58 castPtr :: Ptr a -> Ptr b
59 castPtr (Ptr addr) = Ptr addr
60
61 -- |Advances the given address by the given offset in bytes.
62 plusPtr :: Ptr a -> Int -> Ptr b
63 plusPtr (Ptr addr) (I# d) = Ptr (plusAddr# addr d)
64
65 -- |Given an arbitrary address and an alignment constraint,
66 -- 'alignPtr' yields the next higher address that fulfills the
67 -- alignment constraint.  An alignment constraint @x@ is fulfilled by
68 -- any address divisible by @x@.  This operation is idempotent.
69 alignPtr :: Ptr a -> Int -> Ptr a
70 alignPtr addr@(Ptr a) (I# i)
71   = case remAddr# a i of {
72       0# -> addr;
73       n -> Ptr (plusAddr# a (i -# n)) }
74
75 -- |Computes the offset required to get from the second to the first
76 -- argument.  We have 
77 --
78 -- > p2 == p1 `plusPtr` (p2 `minusPtr` p1)
79 minusPtr :: Ptr a -> Ptr b -> Int
80 minusPtr (Ptr a1) (Ptr a2) = I# (minusAddr# a1 a2)
81
82 ------------------------------------------------------------------------
83 -- Function pointers for the default calling convention.
84
85 type role FunPtr representational
86 data FunPtr a = FunPtr Addr# deriving (Eq, Ord)
87 -- ^ A value of type @'FunPtr' a@ is a pointer to a function callable
88 -- from foreign code.  The type @a@ will normally be a /foreign type/,
89 -- a function type with zero or more arguments where
90 --
91 -- * the argument types are /marshallable foreign types/,
92 --   i.e. 'Char', 'Int', 'Double', 'Float',
93 --   'Bool', 'Data.Int.Int8', 'Data.Int.Int16', 'Data.Int.Int32',
94 --   'Data.Int.Int64', 'Data.Word.Word8', 'Data.Word.Word16',
95 --   'Data.Word.Word32', 'Data.Word.Word64', @'Ptr' a@, @'FunPtr' a@,
96 --   @'Foreign.StablePtr.StablePtr' a@ or a renaming of any of these
97 --   using @newtype@.
98 -- 
99 -- * the return type is either a marshallable foreign type or has the form
100 --   @'IO' t@ where @t@ is a marshallable foreign type or @()@.
101 --
102 -- A value of type @'FunPtr' a@ may be a pointer to a foreign function,
103 -- either returned by another foreign function or imported with a
104 -- a static address import like
105 --
106 -- > foreign import ccall "stdlib.h &free"
107 -- >   p_free :: FunPtr (Ptr a -> IO ())
108 --
109 -- or a pointer to a Haskell function created using a /wrapper/ stub
110 -- declared to produce a 'FunPtr' of the correct type.  For example:
111 --
112 -- > type Compare = Int -> Int -> Bool
113 -- > foreign import ccall "wrapper"
114 -- >   mkCompare :: Compare -> IO (FunPtr Compare)
115 --
116 -- Calls to wrapper stubs like @mkCompare@ allocate storage, which
117 -- should be released with 'Foreign.Ptr.freeHaskellFunPtr' when no
118 -- longer required.
119 --
120 -- To convert 'FunPtr' values to corresponding Haskell functions, one
121 -- can define a /dynamic/ stub for the specific foreign type, e.g.
122 --
123 -- > type IntFunction = CInt -> IO ()
124 -- > foreign import ccall "dynamic" 
125 -- >   mkFun :: FunPtr IntFunction -> IntFunction
126
127 -- |The constant 'nullFunPtr' contains a
128 -- distinguished value of 'FunPtr' that is not
129 -- associated with a valid memory location.
130 nullFunPtr :: FunPtr a
131 nullFunPtr = FunPtr nullAddr#
132
133 -- |Casts a 'FunPtr' to a 'FunPtr' of a different type.
134 castFunPtr :: FunPtr a -> FunPtr b
135 castFunPtr (FunPtr addr) = FunPtr addr
136
137 -- |Casts a 'FunPtr' to a 'Ptr'.
138 --
139 -- /Note:/ this is valid only on architectures where data and function
140 -- pointers range over the same set of addresses, and should only be used
141 -- for bindings to external libraries whose interface already relies on
142 -- this assumption.
143 castFunPtrToPtr :: FunPtr a -> Ptr b
144 castFunPtrToPtr (FunPtr addr) = Ptr addr
145
146 -- |Casts a 'Ptr' to a 'FunPtr'.
147 --
148 -- /Note:/ this is valid only on architectures where data and function
149 -- pointers range over the same set of addresses, and should only be used
150 -- for bindings to external libraries whose interface already relies on
151 -- this assumption.
152 castPtrToFunPtr :: Ptr a -> FunPtr b
153 castPtrToFunPtr (Ptr addr) = FunPtr addr
154
155
156 ------------------------------------------------------------------------
157 -- Show instances for Ptr and FunPtr
158
159 instance Show (Ptr a) where
160    showsPrec _ (Ptr a) rs = pad_out (showHex (wordToInteger(int2Word#(addr2Int# a))) "")
161      where
162         -- want 0s prefixed to pad it out to a fixed length.
163        pad_out ls = 
164           '0':'x':(replicate (2*SIZEOF_HSPTR - length ls) '0') ++ ls ++ rs
165
166 instance Show (FunPtr a) where
167    showsPrec p = showsPrec p . castFunPtrToPtr
168
169 \end{code}