X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=GHC%2FPtr.lhs;h=bf78f713bd04105f6264e53ce6b73af745431fc9;hb=41e8fba828acbae1751628af50849f5352b27873;hp=61b7f3e2e0853f4f66a700b06daf46b57f5a9569;hpb=7f1f4e7a695c402ddd3a1dc2cc7114e649a78ebc;p=ghc-base.git diff --git a/GHC/Ptr.lhs b/GHC/Ptr.lhs index 61b7f3e..bf78f71 100644 --- a/GHC/Ptr.lhs +++ b/GHC/Ptr.lhs @@ -1,61 +1,160 @@ +\begin{code} +{-# LANGUAGE CPP, NoImplicitPrelude, MagicHash #-} +{-# OPTIONS_HADDOCK hide #-} + ----------------------------------------------------------------------------- --- $Id: Ptr.lhs,v 1.1 2001/06/28 14:15:03 simonmar Exp $ +-- | +-- Module : GHC.Ptr +-- Copyright : (c) The FFI Task Force, 2000-2002 +-- License : see libraries/base/LICENSE -- --- (c) The FFI Task Force, 2000 --- --- Module GHC.Ptr +-- Maintainer : ffi@haskell.org +-- Stability : internal +-- Portability : non-portable (GHC Extensions) +-- +-- The 'Ptr' and 'FunPtr' types and operations. +-- +----------------------------------------------------------------------------- -\begin{code} -{-# OPTIONS -fno-implicit-prelude #-} +-- #hide module GHC.Ptr where import GHC.Base +import GHC.Show +import GHC.Num +import GHC.List ( length, replicate ) +import Numeric ( showHex ) + +#include "MachDeps.h" ------------------------------------------------------------------------ -- Data pointers. data Ptr a = Ptr Addr# 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 :: Ptr a -nullPtr = Ptr (int2Addr# 0#) +nullPtr = Ptr nullAddr# +-- |The 'castPtr' function casts a pointer from one type to another. castPtr :: Ptr a -> Ptr b castPtr (Ptr addr) = Ptr addr +-- |Advances the given address by the given offset in bytes. plusPtr :: Ptr a -> Int -> Ptr b -plusPtr (Ptr addr) (I# d) = Ptr (int2Addr# (addr2Int# addr +# d)) +plusPtr (Ptr addr) (I# d) = Ptr (plusAddr# addr d) +-- |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 :: Ptr a -> Int -> Ptr a alignPtr addr@(Ptr a) (I# i) - = case addr2Int# a of { ai -> - case remInt# ai i of { + = case remAddr# a i of { 0# -> addr; - n -> Ptr (int2Addr# (ai +# (i -# n))) }} + 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 :: Ptr a -> Ptr b -> Int -minusPtr (Ptr a1) (Ptr a2) = I# (addr2Int# a1 -# addr2Int# a2) - -instance CCallable (Ptr a) -instance CReturnable (Ptr a) +minusPtr (Ptr a1) (Ptr a2) = I# (minusAddr# a1 a2) ------------------------------------------------------------------------ -- Function pointers for the default calling convention. data FunPtr a = FunPtr Addr# 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 :: FunPtr a -nullFunPtr = FunPtr (int2Addr# 0#) +nullFunPtr = FunPtr nullAddr# +-- |Casts a 'FunPtr' to a 'FunPtr' of a different type. castFunPtr :: FunPtr a -> FunPtr b castFunPtr (FunPtr addr) = FunPtr addr +-- |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 :: FunPtr a -> Ptr b castFunPtrToPtr (FunPtr addr) = Ptr addr +-- |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 :: Ptr a -> FunPtr b castPtrToFunPtr (Ptr addr) = FunPtr addr -instance CCallable (FunPtr a) -instance CReturnable (FunPtr a) +------------------------------------------------------------------------ +-- Show instances for Ptr and FunPtr + +instance Show (Ptr a) where + showsPrec _ (Ptr a) rs = pad_out (showHex (wordToInteger(int2Word#(addr2Int# a))) "") + where + -- want 0s prefixed to pad it out to a fixed length. + pad_out ls = + '0':'x':(replicate (2*SIZEOF_HSPTR - length ls) '0') ++ ls ++ rs + +instance Show (FunPtr a) where + showsPrec p = showsPrec p . castFunPtrToPtr \end{code} +