2 % (c) The AQUA Project, Glasgow University, 1994-1996
5 \section[Foreign]{Module @Foreign@}
8 {-# OPTIONS -fno-implicit-prelude #-}
12 #ifndef __PARALLEL_HASKELL__
19 import UnsafeST ( unsafePerformPrimIO )
25 %*********************************************************
27 \subsection{Classes @CCallable@ and @CReturnable@}
29 %*********************************************************
35 instance CCallable Char
36 instance CCallable Char#
37 instance CReturnable Char
39 instance CCallable Int
40 instance CCallable Int#
41 instance CReturnable Int
43 -- DsCCall knows how to pass strings...
44 instance CCallable [Char]
46 instance CCallable Float
47 instance CCallable Float#
48 instance CReturnable Float
50 instance CCallable Double
51 instance CCallable Double#
52 instance CReturnable Double
54 data Addr = A# Addr# deriving (Eq, Ord) -- Glasgow extension
56 instance CCallable Addr
57 instance CCallable Addr#
58 instance CReturnable Addr
60 data Word = W# Word# deriving (Eq, Ord) -- Glasgow extension
62 instance CCallable Word
63 instance CCallable Word#
64 instance CReturnable Word
66 instance CReturnable () -- Why, exactly?
70 %*********************************************************
72 \subsection{Type @ForeignObj@ and its operations}
74 %*********************************************************
77 #ifndef __PARALLEL_HASKELL__
78 --Defined in PrelBase: data ForeignObj = ForeignObj ForeignObj#
79 data ForeignObj = ForeignObj ForeignObj# -- another one
81 instance CCallable ForeignObj
82 instance CCallable ForeignObj#
84 eqForeignObj :: ForeignObj -> ForeignObj -> Bool
85 makeForeignObj :: Addr -> Addr -> PrimIO ForeignObj
86 writeForeignObj :: ForeignObj -> Addr -> PrimIO ()
88 {- derived op - attaching a free() finaliser to a malloc() allocated reference. -}
89 makeMallocPtr :: Addr -> PrimIO ForeignObj
91 makeForeignObj (A# obj) (A# finaliser) = ST ( \ s# ->
92 case makeForeignObj# obj finaliser s# of
93 StateAndForeignObj# s1# fo# -> STret s1# (ForeignObj fo#))
95 writeForeignObj (ForeignObj fo#) (A# datum#) = ST ( \ s# ->
96 case writeForeignObj# fo# datum# s# of { s1# -> STret s1# () } )
98 makeMallocPtr a = makeForeignObj a (``&free''::Addr)
101 = unsafePerformPrimIO (_ccall_ eqForeignObj mp1 mp2) /= (0::Int)
103 instance Eq ForeignObj where
104 p == q = eqForeignObj p q
105 p /= q = not (eqForeignObj p q)
106 #endif /* !__PARALLEL_HASKELL__ */
110 %*********************************************************
112 \subsection{Type @StablePtr@ and its operations}
114 %*********************************************************
117 #ifndef __PARALLEL_HASKELL__
118 data StablePtr a = StablePtr (StablePtr# a)
119 instance CCallable (StablePtr a)
120 instance CCallable (StablePtr# a)
121 instance CReturnable (StablePtr a)
123 -- Nota Bene: it is important {\em not\/} to inline calls to
124 -- @makeStablePtr#@ since the corresponding macro is very long and we'll
125 -- get terrible code-bloat.
127 makeStablePtr :: a -> PrimIO (StablePtr a)
128 deRefStablePtr :: StablePtr a -> PrimIO a
129 freeStablePtr :: StablePtr a -> PrimIO ()
130 performGC :: PrimIO ()
132 {-# INLINE deRefStablePtr #-}
133 {-# INLINE freeStablePtr #-}
134 {-# INLINE performGC #-}
136 makeStablePtr f = ST $ \ rw1# ->
137 case makeStablePtr# f rw1# of
138 StateAndStablePtr# rw2# sp# -> STret rw2# (StablePtr sp#)
140 deRefStablePtr (StablePtr sp#) = ST $ \ rw1# ->
141 case deRefStablePtr# sp# rw1# of
142 StateAndPtr# rw2# a -> STret rw2# a
144 freeStablePtr sp = _ccall_ freeStablePointer sp
146 performGC = _ccall_GC_ StgPerformGarbageCollection
148 #endif /* !__PARALLEL_HASKELL__ */
151 %*********************************************************
153 \subsection{Ghastly return types}
155 %*********************************************************
158 #ifndef __PARALLEL_HASKELL__
159 data StateAndStablePtr# s a = StateAndStablePtr# (State# s) (StablePtr# a)
161 data StateAndForeignObj# s = StateAndForeignObj# (State# s) ForeignObj#