2 {-# OPTIONS_GHC -XNoImplicitPrelude #-}
3 {-# OPTIONS_HADDOCK hide #-}
4 -----------------------------------------------------------------------------
7 -- Copyright : (c) The FFI Task Force, 2000-2002
8 -- License : see libraries/base/LICENSE
10 -- Maintainer : ffi@haskell.org
11 -- Stability : internal
12 -- Portability : non-portable (GHC Extensions)
14 -- The 'Ptr' and 'FunPtr' types and operations.
16 -----------------------------------------------------------------------------
24 import GHC.List ( length, replicate )
25 import Numeric ( showHex )
29 ------------------------------------------------------------------------
32 data Ptr a = Ptr Addr# deriving (Eq, Ord)
33 -- ^ A value of type @'Ptr' a@ represents a pointer to an object, or an
34 -- array of objects, which may be marshalled to or from Haskell values
37 -- The type @a@ will often be an instance of class
38 -- 'Foreign.Storable.Storable' which provides the marshalling operations.
39 -- However this is not essential, and you can provide your own operations
40 -- to access the pointer. For example you might write small foreign
41 -- functions to get or set the fields of a C @struct@.
43 -- |The constant 'nullPtr' contains a distinguished value of 'Ptr'
44 -- that is not associated with a valid memory location.
46 nullPtr = Ptr nullAddr#
48 -- |The 'castPtr' function casts a pointer from one type to another.
49 castPtr :: Ptr a -> Ptr b
50 castPtr (Ptr addr) = Ptr addr
52 -- |Advances the given address by the given offset in bytes.
53 plusPtr :: Ptr a -> Int -> Ptr b
54 plusPtr (Ptr addr) (I# d) = Ptr (plusAddr# addr d)
56 -- |Given an arbitrary address and an alignment constraint,
57 -- 'alignPtr' yields the next higher address that fulfills the
58 -- alignment constraint. An alignment constraint @x@ is fulfilled by
59 -- any address divisible by @x@. This operation is idempotent.
60 alignPtr :: Ptr a -> Int -> Ptr a
61 alignPtr addr@(Ptr a) (I# i)
62 = case remAddr# a i of {
64 n -> Ptr (plusAddr# a (i -# n)) }
66 -- |Computes the offset required to get from the second to the first
69 -- > p2 == p1 `plusPtr` (p2 `minusPtr` p1)
70 minusPtr :: Ptr a -> Ptr b -> Int
71 minusPtr (Ptr a1) (Ptr a2) = I# (minusAddr# a1 a2)
73 ------------------------------------------------------------------------
74 -- Function pointers for the default calling convention.
76 data FunPtr a = FunPtr Addr# deriving (Eq, Ord)
77 -- ^ A value of type @'FunPtr' a@ is a pointer to a function callable
78 -- from foreign code. The type @a@ will normally be a /foreign type/,
79 -- a function type with zero or more arguments where
81 -- * the argument types are /marshallable foreign types/,
82 -- i.e. 'Char', 'Int', 'Prelude.Double', 'Prelude.Float',
83 -- 'Bool', 'Data.Int.Int8', 'Data.Int.Int16', 'Data.Int.Int32',
84 -- 'Data.Int.Int64', 'Data.Word.Word8', 'Data.Word.Word16',
85 -- 'Data.Word.Word32', 'Data.Word.Word64', @'Ptr' a@, @'FunPtr' a@,
86 -- @'Foreign.StablePtr.StablePtr' a@ or a renaming of any of these
89 -- * the return type is either a marshallable foreign type or has the form
90 -- @'Prelude.IO' t@ where @t@ is a marshallable foreign type or @()@.
92 -- A value of type @'FunPtr' a@ may be a pointer to a foreign function,
93 -- either returned by another foreign function or imported with a
94 -- a static address import like
96 -- > foreign import ccall "stdlib.h &free"
97 -- > p_free :: FunPtr (Ptr a -> IO ())
99 -- or a pointer to a Haskell function created using a /wrapper/ stub
100 -- declared to produce a 'FunPtr' of the correct type. For example:
102 -- > type Compare = Int -> Int -> Bool
103 -- > foreign import ccall "wrapper"
104 -- > mkCompare :: Compare -> IO (FunPtr Compare)
106 -- Calls to wrapper stubs like @mkCompare@ allocate storage, which
107 -- should be released with 'Foreign.Ptr.freeHaskellFunPtr' when no
110 -- To convert 'FunPtr' values to corresponding Haskell functions, one
111 -- can define a /dynamic/ stub for the specific foreign type, e.g.
113 -- > type IntFunction = CInt -> IO ()
114 -- > foreign import ccall "dynamic"
115 -- > mkFun :: FunPtr IntFunction -> IntFunction
117 -- |The constant 'nullFunPtr' contains a
118 -- distinguished value of 'FunPtr' that is not
119 -- associated with a valid memory location.
120 nullFunPtr :: FunPtr a
121 nullFunPtr = FunPtr nullAddr#
123 -- |Casts a 'FunPtr' to a 'FunPtr' of a different type.
124 castFunPtr :: FunPtr a -> FunPtr b
125 castFunPtr (FunPtr addr) = FunPtr addr
127 -- |Casts a 'FunPtr' to a 'Ptr'.
129 -- /Note:/ this is valid only on architectures where data and function
130 -- pointers range over the same set of addresses, and should only be used
131 -- for bindings to external libraries whose interface already relies on
133 castFunPtrToPtr :: FunPtr a -> Ptr b
134 castFunPtrToPtr (FunPtr addr) = Ptr addr
136 -- |Casts a 'Ptr' to a 'FunPtr'.
138 -- /Note:/ this is valid only on architectures where data and function
139 -- pointers range over the same set of addresses, and should only be used
140 -- for bindings to external libraries whose interface already relies on
142 castPtrToFunPtr :: Ptr a -> FunPtr b
143 castPtrToFunPtr (Ptr addr) = FunPtr addr
146 ------------------------------------------------------------------------
147 -- Show instances for Ptr and FunPtr
148 -- I have absolutely no idea why the WORD_SIZE_IN_BITS stuff is here
150 #if (WORD_SIZE_IN_BITS == 32 || WORD_SIZE_IN_BITS == 64)
151 instance Show (Ptr a) where
152 showsPrec _ (Ptr a) rs = pad_out (showHex (wordToInteger(int2Word#(addr2Int# a))) "")
154 -- want 0s prefixed to pad it out to a fixed length.
156 '0':'x':(replicate (2*SIZEOF_HSPTR - length ls) '0') ++ ls ++ rs
158 instance Show (FunPtr a) where
159 showsPrec p = showsPrec p . castFunPtrToPtr