2 % (c) The AQUA Project, Glasgow University, 1994-1996
5 \section[Foreign]{Module @Foreign@}
8 {-# OPTIONS -fno-implicit-prelude #-}
12 #ifndef __PARALLEL_HASKELL__
17 #ifndef __PARALLEL_HASKELL__
18 unpackCStringFO, -- :: ForeignObj -> [Char]
19 unpackNBytesFO, -- :: ForeignObj -> Int -> [Char]
20 unpackCStringFO#, -- :: ForeignObj# -> [Char]
21 unpackNBytesFO# -- :: ForeignObj# -> Int# -> [Char]
34 %*********************************************************
36 \subsection{Type @ForeignObj@ and its operations}
38 %*********************************************************
41 #ifndef __PARALLEL_HASKELL__
42 instance CCallable ForeignObj
43 instance CCallable ForeignObj#
45 eqForeignObj :: ForeignObj -> ForeignObj -> Bool
46 makeForeignObj :: Addr -> Addr -> IO ForeignObj
47 writeForeignObj :: ForeignObj -> Addr -> IO ()
49 {- derived op - attaching a free() finaliser to a malloc() allocated reference. -}
50 makeMallocPtr :: Addr -> IO ForeignObj
52 makeForeignObj (A# obj) (A# finaliser) = IO ( \ s# ->
53 case makeForeignObj# obj finaliser s# of
54 StateAndForeignObj# s1# fo# -> IOok s1# (ForeignObj fo#))
56 writeForeignObj (ForeignObj fo#) (A# datum#) = IO ( \ s# ->
57 case writeForeignObj# fo# datum# s# of { s1# -> IOok s1# () } )
59 makeMallocPtr a = makeForeignObj a (``&free''::Addr)
62 = unsafePerformIO (_ccall_ eqForeignObj mp1 mp2) /= (0::Int)
64 instance Eq ForeignObj where
65 p == q = eqForeignObj p q
66 p /= q = not (eqForeignObj p q)
67 #endif /* !__PARALLEL_HASKELL__ */
70 %*********************************************************
72 \subsection{Type @StablePtr@ and its operations}
74 %*********************************************************
77 #ifndef __PARALLEL_HASKELL__
78 data StablePtr a = StablePtr (StablePtr# a)
79 instance CCallable (StablePtr a)
80 instance CCallable (StablePtr# a)
81 instance CReturnable (StablePtr a)
83 -- Nota Bene: it is important {\em not\/} to inline calls to
84 -- @makeStablePtr#@ since the corresponding macro is very long and we'll
85 -- get terrible code-bloat.
87 makeStablePtr :: a -> IO (StablePtr a)
88 deRefStablePtr :: StablePtr a -> IO a
89 freeStablePtr :: StablePtr a -> IO ()
91 {-# INLINE deRefStablePtr #-}
92 {-# INLINE freeStablePtr #-}
94 makeStablePtr f = IO $ \ rw1# ->
95 case makeStablePtr# f rw1# of
96 StateAndStablePtr# rw2# sp# -> IOok rw2# (StablePtr sp#)
98 deRefStablePtr (StablePtr sp#) = IO $ \ rw1# ->
99 case deRefStablePtr# sp# rw1# of
100 StateAndPtr# rw2# a -> IOok rw2# a
102 freeStablePtr sp = _ccall_ freeStablePointer sp
104 #endif /* !__PARALLEL_HASKELL__ */
107 %*********************************************************
109 \subsection{Ghastly return types}
111 %*********************************************************
114 #ifndef __PARALLEL_HASKELL__
115 data StateAndStablePtr# s a = StateAndStablePtr# (State# s) (StablePtr# a)
117 data StateAndForeignObj# s = StateAndForeignObj# (State# s) ForeignObj#
120 %*********************************************************
122 \subsection{Unpacking Foreigns}
124 %*********************************************************
126 Primitives for converting Foreigns pointing to external
127 sequence of bytes into a list of @Char@s (a renamed version
131 #ifndef __PARALLEL_HASKELL__
132 unpackCStringFO :: ForeignObj -> [Char]
133 unpackCStringFO (ForeignObj fo#) = unpackCStringFO# fo#
135 unpackCStringFO# :: ForeignObj# -> [Char]
136 unpackCStringFO# fo {- ptr. to NUL terminated string-}
140 | ch `eqChar#` '\0'# = []
141 | otherwise = C# ch : unpack (nh +# 1#)
143 ch = indexCharOffForeignObj# fo nh
145 unpackNBytesFO :: ForeignObj -> Int -> [Char]
146 unpackNBytesFO (ForeignObj fo) (I# l) = unpackNBytesFO# fo l
148 unpackNBytesFO# :: ForeignObj# -> Int# -> [Char]
149 -- This one is called by the compiler to unpack literal strings with NULs in them; rare.
150 unpackNBytesFO# fo len
155 | otherwise = C# ch : unpack (i +# 1#)
157 ch = indexCharOffForeignObj# fo i