\begin{code}{-# OPTIONS_GHC -XNoImplicitPrelude #-}{-# OPTIONS_HADDOCK hide #-}------------------------------------------------------------------------------- |-- Module : GHC.Ptr-- Copyright : (c) The FFI Task Force, 2000-2002-- License : see libraries/base/LICENSE-- -- Maintainer : ffi@haskell.org-- Stability : internal-- Portability : non-portable (GHC Extensions)---- The 'Ptr' and 'FunPtr' types and operations.--------------------------------------------------------------------------------- #hidemoduleGHC.PtrwhereimportGHC.BaseimportGHC.ShowimportGHC.NumimportGHC.List(length,replicate)importNumeric(showHex)#include "MachDeps.h"-------------------------------------------------------------------------- Data pointers.dataPtra=PtrAddr#deriving(Eq,Ord)-- ^ A value of type @'Ptr' a@ represents a pointer to an object, or an-- array of objects, which may be marshalled to or from Haskell values-- of type @a@.---- The type @a@ will often be an instance of class-- 'Foreign.Storable.Storable' which provides the marshalling operations.-- However this is not essential, and you can provide your own operations-- to access the pointer. For example you might write small foreign-- functions to get or set the fields of a C @struct@.-- |The constant 'nullPtr' contains a distinguished value of 'Ptr'-- that is not associated with a valid memory location.nullPtr::PtranullPtr=PtrnullAddr#-- |The 'castPtr' function casts a pointer from one type to another.castPtr::Ptra->PtrbcastPtr(Ptraddr)=Ptraddr-- |Advances the given address by the given offset in bytes.plusPtr::Ptra->Int->PtrbplusPtr(Ptraddr)(I#d)=Ptr(plusAddr#addrd)-- |Given an arbitrary address and an alignment constraint,-- 'alignPtr' yields the next higher address that fulfills the-- alignment constraint. An alignment constraint @x@ is fulfilled by-- any address divisible by @x@. This operation is idempotent.alignPtr::Ptra->Int->PtraalignPtraddr@(Ptra)(I#i)=caseremAddr#aiof{0#->addr;n->Ptr(plusAddr#a(i-#n))}-- |Computes the offset required to get from the second to the first-- argument. We have ---- > p2 == p1 `plusPtr` (p2 `minusPtr` p1)minusPtr::Ptra->Ptrb->IntminusPtr(Ptra1)(Ptra2)=I#(minusAddr#a1a2)-------------------------------------------------------------------------- Function pointers for the default calling convention.dataFunPtra=FunPtrAddr#deriving(Eq,Ord)-- ^ A value of type @'FunPtr' a@ is a pointer to a function callable-- from foreign code. The type @a@ will normally be a /foreign type/,-- a function type with zero or more arguments where---- * the argument types are /marshallable foreign types/,-- i.e. 'Char', 'Int', 'Double', 'Float',-- 'Bool', 'Data.Int.Int8', 'Data.Int.Int16', 'Data.Int.Int32',-- 'Data.Int.Int64', 'Data.Word.Word8', 'Data.Word.Word16',-- 'Data.Word.Word32', 'Data.Word.Word64', @'Ptr' a@, @'FunPtr' a@,-- @'Foreign.StablePtr.StablePtr' a@ or a renaming of any of these-- using @newtype@.-- -- * the return type is either a marshallable foreign type or has the form-- @'IO' t@ where @t@ is a marshallable foreign type or @()@.---- A value of type @'FunPtr' a@ may be a pointer to a foreign function,-- either returned by another foreign function or imported with a-- a static address import like---- > foreign import ccall "stdlib.h &free"-- > p_free :: FunPtr (Ptr a -> IO ())---- or a pointer to a Haskell function created using a /wrapper/ stub-- declared to produce a 'FunPtr' of the correct type. For example:---- > type Compare = Int -> Int -> Bool-- > foreign import ccall "wrapper"-- > mkCompare :: Compare -> IO (FunPtr Compare)---- Calls to wrapper stubs like @mkCompare@ allocate storage, which-- should be released with 'Foreign.Ptr.freeHaskellFunPtr' when no-- longer required.---- To convert 'FunPtr' values to corresponding Haskell functions, one-- can define a /dynamic/ stub for the specific foreign type, e.g.---- > type IntFunction = CInt -> IO ()-- > foreign import ccall "dynamic" -- > mkFun :: FunPtr IntFunction -> IntFunction-- |The constant 'nullFunPtr' contains a-- distinguished value of 'FunPtr' that is not-- associated with a valid memory location.nullFunPtr::FunPtranullFunPtr=FunPtrnullAddr#-- |Casts a 'FunPtr' to a 'FunPtr' of a different type.castFunPtr::FunPtra->FunPtrbcastFunPtr(FunPtraddr)=FunPtraddr-- |Casts a 'FunPtr' to a 'Ptr'.---- /Note:/ this is valid only on architectures where data and function-- pointers range over the same set of addresses, and should only be used-- for bindings to external libraries whose interface already relies on-- this assumption.castFunPtrToPtr::FunPtra->PtrbcastFunPtrToPtr(FunPtraddr)=Ptraddr-- |Casts a 'Ptr' to a 'FunPtr'.---- /Note:/ this is valid only on architectures where data and function-- pointers range over the same set of addresses, and should only be used-- for bindings to external libraries whose interface already relies on-- this assumption.castPtrToFunPtr::Ptra->FunPtrbcastPtrToFunPtr(Ptraddr)=FunPtraddr-------------------------------------------------------------------------- Show instances for Ptr and FunPtrinstanceShow(Ptra)whereshowsPrec_(Ptra)rs=pad_out(showHex(wordToInteger(int2Word#(addr2Int#a)))"")where-- want 0s prefixed to pad it out to a fixed length.pad_outls='0':'x':(replicate(2*SIZEOF_HSPTR-lengthls)'0')++ls++rsinstanceShow(FunPtra)whereshowsPrecp=showsPrecp.castFunPtrToPtr\end{code}