X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Flib%2Fstd%2FPrelForeign.lhs;h=01f135df5c1bcecab5d728d8bfc33c75492f7cd1;hb=239e9471e104fd88ec93bf42623c3a68a496657a;hp=a61d27aa8cfae181c4b7b055f3e424a3f5b145e5;hpb=438596897ebbe25a07e1c82085cfbc5bdb00f09e;p=ghc-hetmet.git diff --git a/ghc/lib/std/PrelForeign.lhs b/ghc/lib/std/PrelForeign.lhs index a61d27a..01f135d 100644 --- a/ghc/lib/std/PrelForeign.lhs +++ b/ghc/lib/std/PrelForeign.lhs @@ -1,5 +1,7 @@ +% ------------------------------------------------------------------------------ +% $Id: PrelForeign.lhs,v 1.20 2001/07/16 00:39:04 sof Exp $ % -% (c) The AQUA Project, Glasgow University, 1994-1996 +% (c) The University of Glasgow, 1994-2000 % \section[Foreign]{Module @Foreign@} @@ -7,139 +9,61 @@ \begin{code} {-# OPTIONS -fno-implicit-prelude #-} -module PrelForeign ( - module PrelForeign, -#ifndef __PARALLEL_HASKELL__ - ForeignObj(..), - makeForeignObj, - writeForeignObj -#endif - ) where +module PrelForeign where import PrelIOBase -import PrelST +import PrelNum -- for fromInteger import PrelBase -import PrelCCall -import PrelAddr -import PrelGHC +import PrelPtr \end{code} - %********************************************************* %* * -\subsection{Type @ForeignObj@ and its operations} +\subsection{ForeignPtr} %* * %********************************************************* \begin{code} -#ifndef __PARALLEL_HASKELL__ ---instance CCallable ForeignObj ---instance CCallable ForeignObj# - -makeForeignObj :: Addr -> IO ForeignObj -makeForeignObj (A# obj) = IO ( \ s# -> - case makeForeignObj# obj s# of - (# s1#, fo# #) -> (# s1#, ForeignObj fo# #) ) - -eqForeignObj :: ForeignObj -> ForeignObj -> Bool ---makeForeignObj :: Addr -> Addr -> IO ForeignObj -writeForeignObj :: ForeignObj -> Addr -> IO () - -writeForeignObj (ForeignObj fo#) (A# datum#) = IO ( \ s# -> - case writeForeignObj# fo# datum# s# of { s1# -> (# s1#, () #) } ) - -eqForeignObj mp1 mp2 - = unsafePerformIO (_ccall_ eqForeignObj mp1 mp2) /= (0::Int) - -instance Eq ForeignObj where - p == q = eqForeignObj p q - p /= q = not (eqForeignObj p q) -#endif /* !__PARALLEL_HASKELL__ */ -\end{code} - -%********************************************************* -%* * -\subsection{Type @StablePtr@ and its operations} -%* * -%********************************************************* +data ForeignPtr a = ForeignPtr ForeignObj# +instance CCallable (ForeignPtr a) -\begin{code} -#ifndef __PARALLEL_HASKELL__ -data StablePtr a = StablePtr (StablePtr# a) -instance CCallable (StablePtr a) -instance CCallable (StablePtr# a) -instance CReturnable (StablePtr a) +eqForeignPtr :: ForeignPtr a -> ForeignPtr a -> Bool +eqForeignPtr (ForeignPtr fo1#) (ForeignPtr fo2#) = eqForeignObj# fo1# fo2# --- Nota Bene: it is important {\em not\/} to inline calls to --- @makeStablePtr#@ since the corresponding macro is very long and we'll --- get terrible code-bloat. +instance Eq (ForeignPtr a) where + p == q = eqForeignPtr p q + p /= q = not (eqForeignPtr p q) -makeStablePtr :: a -> IO (StablePtr a) -deRefStablePtr :: StablePtr a -> IO a -freeStablePtr :: StablePtr a -> IO () +newForeignPtr :: Ptr a -> IO () -> IO (ForeignPtr a) +newForeignPtr p finalizer + = do fObj <- mkForeignPtr p + addForeignPtrFinalizer fObj finalizer + return fObj -{-# INLINE deRefStablePtr #-} -{-# INLINE freeStablePtr #-} +addForeignPtrFinalizer :: ForeignPtr a -> IO () -> IO () +addForeignPtrFinalizer (ForeignPtr fo) finalizer = + IO $ \s -> case mkWeak# fo () finalizer s of { (# s1, w #) -> (# s1, () #) } -makeStablePtr f = IO $ \ rw1# -> - case makeStablePtr# f rw1# of - (# rw2#, sp# #) -> (# rw2#, StablePtr sp# #) +mkForeignPtr :: Ptr a -> IO (ForeignPtr a) {- not exported -} +mkForeignPtr (Ptr obj) = IO ( \ s# -> + case mkForeignObj# obj s# of + (# s1#, fo# #) -> (# s1#, ForeignPtr fo# #) ) -deRefStablePtr (StablePtr sp#) = IO $ \ rw1# -> - deRefStablePtr# sp# rw1# +touchForeignPtr :: ForeignPtr a -> IO () +touchForeignPtr (ForeignPtr fo) + = IO $ \s -> case touch# fo s of s -> (# s, () #) -freeStablePtr sp = _ccall_ freeStablePointer sp +withForeignPtr :: ForeignPtr a -> (Ptr a -> IO b) -> IO b +withForeignPtr fo io + = do r <- io (foreignPtrToPtr fo) + touchForeignPtr fo + return r -eqStablePtr :: StablePtr a -> StablePtr b -> Bool -eqStablePtr (StablePtr sp1#) (StablePtr sp2#) = - case eqStablePtr# sp1# sp2# of - 0# -> False - _ -> True +foreignPtrToPtr :: ForeignPtr a -> Ptr a +foreignPtrToPtr (ForeignPtr fo) = Ptr (foreignObjToAddr# fo) -instance Eq (StablePtr a) where - p == q = eqStablePtr p q - p /= q = not (eqStablePtr p q) +castForeignPtr (ForeignPtr a) = ForeignPtr a -#endif /* !__PARALLEL_HASKELL__ */ \end{code} -%********************************************************* -%* * -\subsection{Unpacking Foreigns} -%* * -%********************************************************* - -Primitives for converting Foreigns pointing to external -sequence of bytes into a list of @Char@s (a renamed version -of the code above). -\begin{code} -#ifndef __PARALLEL_HASKELL__ -unpackCStringFO :: ForeignObj -> [Char] -unpackCStringFO (ForeignObj fo#) = unpackCStringFO# fo# - -unpackCStringFO# :: ForeignObj# -> [Char] -unpackCStringFO# fo {- ptr. to NUL terminated string-} - = unpack 0# - where - unpack nh - | ch `eqChar#` '\0'# = [] - | otherwise = C# ch : unpack (nh +# 1#) - where - ch = indexCharOffForeignObj# fo nh - -unpackNBytesFO :: ForeignObj -> Int -> [Char] -unpackNBytesFO (ForeignObj fo) (I# l) = unpackNBytesFO# fo l - -unpackNBytesFO# :: ForeignObj# -> Int# -> [Char] - -- This one is called by the compiler to unpack literal strings with NULs in them; rare. -unpackNBytesFO# fo len - = unpack 0# - where - unpack i - | i >=# len = [] - | otherwise = C# ch : unpack (i +# 1#) - where - ch = indexCharOffForeignObj# fo i -#endif -\end{code}