From 8b36758f2089d2a08fc0e3f5b89f7f75210812df Mon Sep 17 00:00:00 2001 From: Simon Marlow Date: Tue, 9 May 2006 09:26:06 +0000 Subject: [PATCH 1/1] add WordPtr and IntPtr types to Foreign.Ptr, with associated conversions As suggested by John Meacham. I had to move the Show instance for Ptr into GHC.ForeignPtr to avoid recursive dependencies. --- Foreign/Ptr.hs | 64 +++++++++++++++++++++++++++++++++++++++-------------- GHC/ForeignPtr.hs | 26 ++++++++++++++++++---- 2 files changed, 69 insertions(+), 21 deletions(-) diff --git a/Foreign/Ptr.hs b/Foreign/Ptr.hs index ad20da4..e6eb205 100644 --- a/Foreign/Ptr.hs +++ b/Foreign/Ptr.hs @@ -37,6 +37,13 @@ module Foreign.Ptr ( freeHaskellFunPtr, -- :: FunPtr a -> IO () -- Free the function pointer created by foreign export dynamic. + -- * Integral types with lossless conversion to/from pointers + IntPtr, + ptrToIntPtr, + intPtrToPtr, + WordPtr, + ptrToWordPtr, + wordPtrToPtr ) where #ifdef __GLASGOW_HASKELL__ @@ -45,8 +52,19 @@ import GHC.IOBase import GHC.Base import GHC.Num import GHC.List +import GHC.Read +import GHC.Real import GHC.Show +import GHC.Enum +import GHC.Word ( Word(..) ) +import Data.Bits +import Data.Typeable ( Typeable(..), mkTyCon, mkTyConApp ) import Numeric +import Foreign.C.Types + +import Foreign.Storable +import Data.Int +import Data.Word #endif #ifdef __NHC__ @@ -71,27 +89,39 @@ 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 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 () + +#include "HsBaseConfig.h" +#include "CTypes.h" + +-- | An unsigend 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 sigend 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#) #endif diff --git a/GHC/ForeignPtr.hs b/GHC/ForeignPtr.hs index c9217ef..4c81136 100644 --- a/GHC/ForeignPtr.hs +++ b/GHC/ForeignPtr.hs @@ -31,16 +31,17 @@ module GHC.ForeignPtr ) where import Control.Monad ( sequence_ ) -import Foreign.Ptr import Foreign.Storable +import Numeric ( showHex ) -import GHC.List ( null ) +import GHC.Show +import GHC.Num +import GHC.List ( null, replicate, length ) import GHC.Base import GHC.IOBase import GHC.STRef ( STRef(..) ) -import GHC.Ptr ( Ptr(..) ) +import GHC.Ptr ( Ptr(..), FunPtr, castFunPtrToPtr ) import GHC.Err -import GHC.Show -- |The type 'ForeignPtr' represents references to objects that are -- maintained in a foreign language, i.e., that are not part of the @@ -82,6 +83,23 @@ instance Ord (ForeignPtr a) where instance Show (ForeignPtr a) where showsPrec p f = showsPrec p (unsafeForeignPtrToPtr f) +#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 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 + -- |A Finalizer is represented as a pointer to a foreign function that, at -- finalisation time, gets as an argument a plain pointer variant of the -- foreign pointer that the finalizer is associated with. -- 1.7.10.4