-- (c) The FFI task force, [2000..2001] -- -- Provides parametrised data and function pointers module Ptr ( -- Data pointers -- Ptr, -- data Ptr a; instances: Eq, Ord, Show nullPtr, -- :: Ptr a castPtr, -- :: Ptr a -> Ptr b plusPtr, -- :: Ptr a -> Int -> Ptr b alignPtr, -- :: Ptr a -> Int -> Ptr a minusPtr, -- :: Ptr a -> Ptr b -> Int -- Function pointers. -- FunPtr, -- data FunPtr a; instances: Eq, Ord, Show nullFunPtr, -- :: FunPtr a castFunPtr, -- :: FunPtr a -> FunPtr b castFunPtrToPtr, -- :: FunPtr a -> Ptr b castPtrToFunPtr, -- :: Ptr a -> FunPtr b freeHaskellFunPtr -- :: FunPtr a -> IO () ) where import Word -- Parametrised data pointer -- -- * Suitable type arguments can be used to segregate pointers to incompatible -- values such that the type checker can spot coding mistakes -- -- * The size of the value representing a data pointer is system-dependent -- -- * In C land, values of type `Ptr a' are represented by -- -- typedef void *HsPtr; -- newtype Ptr a = Ptr WordXY deriving (Eq, Ord, Show) -- Special pointer value that indicates the absence of a data pointer -- -- * This value should be compatible with the C constant `NULL' -- nullPtr :: Ptr a nullPtr = Ptr primNullPtr -- Change the type parameter of a pointer -- castPtr :: Ptr a -> Ptr b castPtr (Ptr p) = Ptr p -- Advance a pointer by a given number of bytes -- plusPtr :: Ptr a -> Int -> Ptr b plusPtr (Ptr p) d = Ptr (p `primPlusPtr` d) -- Align the given pointer at the next higher address boundary that is a -- multiple of the second argument -- -- * This operation is idempotent -- alignPtr :: Ptr a -> Int -> Ptr a alignPtr (Ptr p) a = Ptr (p `primAlignPtr` a) -- Compute the byte difference between two pointers -- -- * We have -- -- p2 == p1 `plusPtr` (p2 `minusPtr` p1) -- minusPtr :: Ptr a -> Ptr b -> Int minusPtr (Ptr p1) (Ptr p2) = p1 `primMinusPtr` p2 -- Parametrised function pointer -- -- * Suitable type arguments can be used to segregate pointers to incompatible -- values such that the type checker can spot coding mistakes; type -- arguments should be functionals -- -- * The size of the value representing a function pointer is system-dependent -- -- * Data and function pointers may be represented differently on some -- architectures -- -- * Routines defined with "foreign export dynamic" should be declared to -- produce function pointers of the present type -- -- * In C land, values of type `FunPtr a' are represented by -- -- typedef void (*HsFunPtr)(void); -- newtype FunPtr a = FunPtr WordXY deriving (Eq, Ord, Show) -- Special pointer value that indicates the absence of a function pointer -- -- * This value should be compatible with the C constant `NULL' -- nullFunPtr :: FunPtr a nullPtr = Ptr primNullFunPtr -- Change the type parameter of a function pointer -- castFunPtr :: FunPtr a -> FunPtr b castFunPtr (FunPtr p) = FunPtr p -- Convert a function into a data pointer -- castFunPtrToPtr :: FunPtr a -> Ptr b castFunPtrToPtr (FunPtr p) = Ptr (fromIntegral p) -- Convert a data into a function pointer -- castPtrToFunPtr :: Ptr a -> FunPtr b castPtrToFunPtr (Ptr p) = FunPtr (fromIntegral p) -- Deallocate a function pointer obtained via a "foreign export dynamic" -- freeHaskellFunPtr :: FunPtr a -> IO () freeHaskellFunPtr (FunPtr p) = primFreeHaskellFunctionPtr p