2 % (c) The AQUA Project, Glasgow University, 1994-1996
5 \section[Foreign]{Module @Foreign@}
8 {-# OPTIONS -fno-implicit-prelude #-}
23 %*********************************************************
25 \subsection{Classes @CCallable@ and @CReturnable@}
27 %*********************************************************
33 instance CCallable Char
34 instance CCallable Char#
35 instance CReturnable Char
37 instance CCallable Int
38 instance CCallable Int#
39 instance CReturnable Int
41 -- DsCCall knows how to pass strings...
42 instance CCallable [Char]
44 instance CCallable Float
45 instance CCallable Float#
46 instance CReturnable Float
48 instance CCallable Double
49 instance CCallable Double#
50 instance CReturnable Double
52 data Addr = A# Addr# deriving (Eq, Ord) -- Glasgow extension
54 instance CCallable Addr
55 instance CCallable Addr#
56 instance CReturnable Addr
58 data Word = W# Word# deriving (Eq, Ord) -- Glasgow extension
60 instance CCallable Word
61 instance CCallable Word#
62 instance CReturnable Word
64 instance CReturnable () -- Why, exactly?
68 %*********************************************************
70 \subsection{Type @ForeignObj@ and its operations}
72 %*********************************************************
75 --Defined in PrelBase: data ForeignObj = ForeignObj ForeignObj#
76 data ForeignObj = ForeignObj ForeignObj# -- another one
78 instance CCallable ForeignObj
79 instance CCallable ForeignObj#
81 eqForeignObj :: ForeignObj -> ForeignObj -> Bool
82 makeForeignObj :: Addr -> Addr -> PrimIO ForeignObj
83 writeForeignObj :: ForeignObj -> Addr -> PrimIO ()
85 {- derived op - attaching a free() finaliser to a malloc() allocated reference. -}
86 makeMallocPtr :: Addr -> PrimIO ForeignObj
88 makeForeignObj (A# obj) (A# finaliser) = ST ( \ (S# s#) ->
89 case makeForeignObj# obj finaliser s# of
90 StateAndForeignObj# s1# fo# -> (ForeignObj fo#, S# s1#))
92 writeForeignObj (ForeignObj fo#) (A# datum#) = ST ( \ (S# s#) ->
93 case writeForeignObj# fo# datum# s# of { s1# -> ((), S# s1#) } )
95 makeMallocPtr a = makeForeignObj a (``&free''::Addr)
98 = unsafePerformPrimIO (_ccall_ eqForeignObj mp1 mp2) /= (0::Int)
100 instance Eq ForeignObj where
101 p == q = eqForeignObj p q
102 p /= q = not (eqForeignObj p q)
106 %*********************************************************
108 \subsection{Type @StablePtr@ and its operations}
110 %*********************************************************
113 #ifndef __PARALLEL_HASKELL__
114 data StablePtr a = StablePtr (StablePtr# a)
115 instance CCallable (StablePtr a)
116 instance CCallable (StablePtr# a)
117 instance CReturnable (StablePtr a)
119 -- Nota Bene: it is important {\em not\/} to inline calls to
120 -- @makeStablePtr#@ since the corresponding macro is very long and we'll
121 -- get terrible code-bloat.
123 makeStablePtr :: a -> PrimIO (StablePtr a)
124 deRefStablePtr :: StablePtr a -> PrimIO a
125 freeStablePtr :: StablePtr a -> PrimIO ()
126 performGC :: PrimIO ()
128 {-# INLINE deRefStablePtr #-}
129 {-# INLINE freeStablePtr #-}
130 {-# INLINE performGC #-}
132 makeStablePtr f = ST $ \ (S# rw1#) ->
133 case makeStablePtr# f rw1# of
134 StateAndStablePtr# rw2# sp# -> (StablePtr sp#, S# rw2#)
136 deRefStablePtr (StablePtr sp#) = ST $ \ (S# rw1#) ->
137 case deRefStablePtr# sp# rw1# of
138 StateAndPtr# rw2# a -> (a, S# rw2#)
140 freeStablePtr sp = _ccall_ freeStablePointer sp
142 performGC = _ccall_GC_ StgPerformGarbageCollection
144 #endif /* !__PARALLEL_HASKELL__ */
147 %*********************************************************
149 \subsection{Ghastly return types}
151 %*********************************************************
154 #ifndef __PARALLEL_HASKELL__
155 data StateAndStablePtr# s a = StateAndStablePtr# (State# s) (StablePtr# a)
157 data StateAndForeignObj# s = StateAndForeignObj# (State# s) ForeignObj#