X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=Foreign%2FPtr.hs;h=90d395ff3d9951b9ad415bd5d452a1a354089ed3;hb=cea15f6a28aa36d14e9410ebea671d5af643f94d;hp=4344a9017e902226c72d3e68e84588fd6bf62108;hpb=fd0f2fbadf218f080a60c392221820a9f07933df;p=ghc-base.git diff --git a/Foreign/Ptr.hs b/Foreign/Ptr.hs index 4344a90..90d395f 100644 --- a/Foreign/Ptr.hs +++ b/Foreign/Ptr.hs @@ -1,4 +1,4 @@ -{-# OPTIONS -fno-implicit-prelude #-} +{-# OPTIONS_GHC -fno-implicit-prelude #-} ----------------------------------------------------------------------------- -- | -- Module : Foreign.Ptr @@ -37,19 +37,39 @@ module Foreign.Ptr ( freeHaskellFunPtr, -- :: FunPtr a -> IO () -- Free the function pointer created by foreign export dynamic. +#ifndef __NHC__ + -- * Integral types with lossless conversion to and from pointers + IntPtr, + ptrToIntPtr, + intPtrToPtr, + WordPtr, + ptrToWordPtr, + wordPtrToPtr +#endif ) where #ifdef __GLASGOW_HASKELL__ import GHC.Ptr import GHC.IOBase -import GHC.Err import GHC.Base import GHC.Num -import GHC.List +import GHC.Read +import GHC.Real import GHC.Show -import Numeric +import GHC.Enum +import GHC.Word ( Word(..) ) + +import Data.Int +import Data.Word +#else +import Control.Monad ( liftM ) +import Foreign.C.Types #endif +import Data.Bits +import Data.Typeable ( Typeable(..), mkTyCon, mkTyConApp ) +import Foreign.Storable ( Storable(..) ) + #ifdef __NHC__ import NHC.FFI ( Ptr @@ -72,23 +92,63 @@ import Hugs.Ptr #endif #ifdef __GLASGOW_HASKELL__ -#include "MachDeps.h" - -#if (WORD_SIZE_IN_BITS == 32 || WORD_SIZE_IN_BITS == 64) -instance Show (Ptr a) where - showsPrec p (Ptr a) rs = pad_out (showHex (word2Integer(int2Word#(addr2Int# a))) "") rs - where - -- want 0s prefixed to pad it out to a fixed length. - pad_out ('0':'x':ls) rs = - '0':'x':(replicate (2*SIZEOF_HSPTR - length ls) '0') ++ ls ++ rs - -- word2Integer :: Word# -> Integer (stolen from Word.lhs) - word2Integer w = case word2Integer# w of - (# s, d #) -> J# s d - -instance Show (FunPtr a) where - showsPrec p = showsPrec p . castFunPtrToPtr -#endif - +-- | Release the storage associated with the given 'FunPtr', which +-- must have been obtained from a wrapper stub. This should be called +-- whenever the return value from a foreign import wrapper function is +-- no longer required; otherwise, the storage it uses will leak. foreign import ccall unsafe "freeHaskellFunctionPtr" freeHaskellFunPtr :: FunPtr a -> IO () #endif + +#ifndef __NHC__ +# include "HsBaseConfig.h" +# include "CTypes.h" + +# ifdef __GLASGOW_HASKELL__ +-- | An unsigned integral type that can be losslessly converted to and from +-- @Ptr@. +INTEGRAL_TYPE(WordPtr,tyConWordPtr,"WordPtr",Word) + -- Word and Int are guaranteed pointer-sized in GHC + +-- | A signed integral type that can be losslessly converted to and from +-- @Ptr@. +INTEGRAL_TYPE(IntPtr,tyConIntPtr,"IntPtr",Int) + -- Word and Int are guaranteed pointer-sized in GHC + +-- | casts a @Ptr@ to a @WordPtr@ +ptrToWordPtr :: Ptr a -> WordPtr +ptrToWordPtr (Ptr a#) = WordPtr (W# (int2Word# (addr2Int# a#))) + +-- | casts a @WordPtr@ to a @Ptr@ +wordPtrToPtr :: WordPtr -> Ptr a +wordPtrToPtr (WordPtr (W# w#)) = Ptr (int2Addr# (word2Int# w#)) + +-- | casts a @Ptr@ to an @IntPtr@ +ptrToIntPtr :: Ptr a -> IntPtr +ptrToIntPtr (Ptr a#) = IntPtr (I# (addr2Int# a#)) + +-- | casts an @IntPtr@ to a @Ptr@ +intPtrToPtr :: IntPtr -> Ptr a +intPtrToPtr (IntPtr (I# i#)) = Ptr (int2Addr# i#) + +# else /* !__GLASGOW_HASKELL__ */ + +INTEGRAL_TYPE(WordPtr,tyConWordPtr,"WordPtr",CUIntPtr) +INTEGRAL_TYPE(IntPtr,tyConIntPtr,"IntPtr",CIntPtr) + +{-# CFILES cbits/PrelIOUtils.c #-} + +foreign import ccall unsafe "__hscore_to_uintptr" + ptrToWordPtr :: Ptr a -> WordPtr + +foreign import ccall unsafe "__hscore_from_uintptr" + wordPtrToPtr :: WordPtr -> Ptr a + +foreign import ccall unsafe "__hscore_to_intptr" + ptrToIntPtr :: Ptr a -> IntPtr + +foreign import ccall unsafe "__hscore_from_intptr" + intPtrToPtr :: IntPtr -> Ptr a + +# endif /* !__GLASGOW_HASKELL__ */ +#endif /* !__NHC_ */