[project @ 1997-11-11 14:32:34 by simonm]
[ghc-hetmet.git] / ghc / lib / glaExts / Foreign.lhs
index 81abc4f..34d0990 100644 (file)
 
 module Foreign (
        module Foreign,
+#ifndef __PARALLEL_HASKELL__
        ForeignObj(..),
-       Addr, Word
+#endif
+       Word(..),
+
+#ifndef __PARALLEL_HASKELL__
+       unpackCStringFO,   -- :: ForeignObj    -> [Char]
+       unpackNBytesFO,    -- :: ForeignObj    -> Int  -> [Char]
+       unpackCStringFO#,  -- :: ForeignObj#   -> [Char]
+       unpackNBytesFO#    -- :: ForeignObj#   -> Int# -> [Char]
+#endif
    ) where
 
+import IOBase
 import STBase
-import ArrBase
+import Unsafe
 import PrelBase
+import CCall
+import Addr
 import GHC
 \end{code}
 
 
 %*********************************************************
 %*                                                     *
-\subsection{Classes @CCallable@ and @CReturnable@}
-%*                                                     *
-%*********************************************************
-
-\begin{code}
-class CCallable   a
-class CReturnable a
-
-instance CCallable Char
-instance CCallable   Char#
-instance CReturnable Char
-
-instance CCallable   Int
-instance CCallable   Int#
-instance CReturnable Int
-
--- DsCCall knows how to pass strings...
-instance CCallable   [Char]
-
-instance CCallable   Float
-instance CCallable   Float#
-instance CReturnable Float
-
-instance CCallable   Double
-instance CCallable   Double#
-instance CReturnable Double
-
-instance CCallable Addr
-instance CCallable Addr#
-instance CReturnable Addr
-
-instance CCallable Word
-instance CCallable Word#
-instance CReturnable Word
-
--- Is this right?
-instance CCallable (MutableByteArray s ix)
-instance CCallable (MutableByteArray# s)
-
-instance CCallable (ByteArray ix)
-instance CCallable ByteArray#
-
-instance CReturnable () -- Why, exactly?
-\end{code}
-
-
-%*********************************************************
-%*                                                     *
 \subsection{Type @ForeignObj@ and its operations}
 %*                                                     *
 %*********************************************************
 
 \begin{code}
---Defined in PrelBase: data ForeignObj = ForeignObj ForeignObj#
+#ifndef __PARALLEL_HASKELL__
 instance CCallable ForeignObj
 instance CCallable ForeignObj#
 
 eqForeignObj    :: ForeignObj  -> ForeignObj -> Bool
-makeForeignObj  :: Addr        -> Addr       -> PrimIO ForeignObj
-writeForeignObj :: ForeignObj  -> Addr       -> PrimIO ()
+makeForeignObj  :: Addr        -> Addr       -> IO ForeignObj
+writeForeignObj :: ForeignObj  -> Addr       -> IO ()
 
 {- derived op - attaching a free() finaliser to a malloc() allocated reference. -}
-makeMallocPtr   :: Addr        -> PrimIO ForeignObj
+makeMallocPtr   :: Addr        -> IO ForeignObj
 
-makeForeignObj (A# obj) (A# finaliser) = ST ( \ (S# s#) ->
+makeForeignObj (A# obj) (A# finaliser) = IO ( \ s# ->
     case makeForeignObj# obj finaliser s# of
-      StateAndForeignObj# s1# fo# -> (ForeignObj fo#, S# s1#))
+      StateAndForeignObj# s1# fo# -> IOok s1# (ForeignObj fo#))
 
-writeForeignObj (ForeignObj fo#) (A# datum#) = ST ( \ (S# s#) ->
-    case writeForeignObj# fo# datum# s# of { s1# -> ((), S# s1#) } )
+writeForeignObj (ForeignObj fo#) (A# datum#) = IO ( \ s# ->
+    case writeForeignObj# fo# datum# s# of { s1# -> IOok s1# () } )
 
 makeMallocPtr a = makeForeignObj a (``&free''::Addr)
 
 eqForeignObj mp1 mp2
-  = unsafePerformPrimIO (_ccall_ eqForeignObj mp1 mp2) /= (0::Int)
+  = 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}
@@ -121,27 +85,23 @@ instance CReturnable (StablePtr a)
 -- @makeStablePtr#@ since the corresponding macro is very long and we'll
 -- get terrible code-bloat.
 
-makeStablePtr  :: a -> PrimIO (StablePtr a)
-deRefStablePtr :: StablePtr a -> PrimIO a
-freeStablePtr  :: StablePtr a -> PrimIO ()
-performGC      :: PrimIO ()
+makeStablePtr  :: a -> IO (StablePtr a)
+deRefStablePtr :: StablePtr a -> IO a
+freeStablePtr  :: StablePtr a -> IO ()
 
 {-# INLINE deRefStablePtr #-}
 {-# INLINE freeStablePtr #-}
-{-# INLINE performGC #-}
 
-makeStablePtr f = ST $ \ (S# rw1#) ->
+makeStablePtr f = IO $ \ rw1# ->
     case makeStablePtr# f rw1# of
-      StateAndStablePtr# rw2# sp# -> (StablePtr sp#, S# rw2#)
+      StateAndStablePtr# rw2# sp# -> IOok rw2# (StablePtr sp#)
 
-deRefStablePtr (StablePtr sp#) = ST $ \ (S# rw1#) ->
+deRefStablePtr (StablePtr sp#) = IO $ \ rw1# ->
     case deRefStablePtr# sp# rw1# of
-      StateAndPtr# rw2# a -> (a, S# rw2#)
+      StateAndPtr# rw2# a -> IOok rw2# a
 
 freeStablePtr sp = _ccall_ freeStablePointer sp
 
-performGC = _ccall_GC_ StgPerformGarbageCollection
-
 #endif /* !__PARALLEL_HASKELL__ */
 \end{code}
 
@@ -157,3 +117,46 @@ data StateAndStablePtr# s a = StateAndStablePtr# (State# s) (StablePtr# a)
 #endif
 data StateAndForeignObj# s  = StateAndForeignObj# (State# s) ForeignObj#
 \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}
+
+