2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 \section[Foreign]{Foreign calls}
8 -- The above warning supression flag is a temporary kludge.
9 -- While working on this module you are encouraged to remove it and fix
10 -- any warnings in the module. See
11 -- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings
13 {-# LANGUAGE DeriveDataTypeable #-}
16 ForeignCall(..), isSafeForeignCall,
17 Safety(..), playSafe, playInterruptible,
19 CExportSpec(..), CLabelString, isCLabelString, pprCLabelString,
21 CCallTarget(..), isDynamicTarget,
22 CCallConv(..), defaultCCallConv, ccallConvToInt, ccallConvAttribute,
35 %************************************************************************
37 \subsubsection{Data types}
39 %************************************************************************
42 newtype ForeignCall = CCall CCallSpec
44 {-! derive: Binary !-}
46 isSafeForeignCall :: ForeignCall -> Bool
47 isSafeForeignCall (CCall (CCallSpec _ _ safe)) = playSafe safe
49 -- We may need more clues to distinguish foreign calls
50 -- but this simple printer will do for now
51 instance Outputable ForeignCall where
52 ppr (CCall cc) = ppr cc
58 = PlaySafe -- Might invoke Haskell GC, or do a call back, or
59 -- switch threads, etc. So make sure things are
60 -- tidy before the call. Additionally, in the threaded
61 -- RTS we arrange for the external call to be executed
62 -- by a separate OS thread, i.e., _concurrently_ to the
63 -- execution of other Haskell threads.
65 Bool -- Indicates the deprecated "threadsafe" annotation
66 -- which is now an alias for "safe". This information
67 -- is never used except to emit a deprecation warning.
69 | PlayInterruptible -- Like PlaySafe, but additionally
70 -- the worker thread running this foreign call may
71 -- be unceremoniously killed, so it must be scheduled
72 -- on an unbound thread.
74 | PlayRisky -- None of the above can happen; the call will return
75 -- without interacting with the runtime system at all
76 deriving ( Eq, Show, Data, Typeable )
77 -- Show used just for Show Lex.Token, I think
78 {-! derive: Binary !-}
80 instance Outputable Safety where
81 ppr (PlaySafe False) = ptext (sLit "safe")
82 ppr (PlaySafe True) = ptext (sLit "threadsafe")
83 ppr PlayInterruptible = ptext (sLit "interruptible")
84 ppr PlayRisky = ptext (sLit "unsafe")
86 playSafe :: Safety -> Bool
87 playSafe PlaySafe{} = True
88 playSafe PlayInterruptible = True
89 playSafe PlayRisky = False
91 playInterruptible :: Safety -> Bool
92 playInterruptible PlayInterruptible = True
93 playInterruptible _ = False
97 %************************************************************************
99 \subsubsection{Calling C}
101 %************************************************************************
105 = CExportStatic -- foreign export ccall foo :: ty
106 CLabelString -- C Name of exported function
108 deriving (Data, Typeable)
109 {-! derive: Binary !-}
112 = CCallSpec CCallTarget -- What to call
113 CCallConv -- Calling convention to use.
116 {-! derive: Binary !-}
123 -- | How to call a particular function in C-land.
125 -- An "unboxed" ccall# to named function in a particular package.
127 CLabelString -- C-land name of label.
129 (Maybe PackageId) -- What package the function is in.
130 -- If Nothing, then it's taken to be in the current package.
131 -- Note: This information is only used for PrimCalls on Windows.
132 -- See CLabel.labelDynamic and CoreToStg.coreToStgApp
133 -- for the difference in representation between PrimCalls
134 -- and ForeignCalls. If the CCallTarget is representing
135 -- a regular ForeignCall then it's safe to set this to Nothing.
137 -- The first argument of the import is the name of a function pointer (an Addr#).
138 -- Used when importing a label as "foreign import ccall "dynamic" ..."
141 deriving( Eq, Data, Typeable )
142 {-! derive: Binary !-}
144 isDynamicTarget :: CCallTarget -> Bool
145 isDynamicTarget DynamicTarget = True
146 isDynamicTarget _ = False
150 Stuff to do with calling convention:
152 ccall: Caller allocates parameters, *and* deallocates them.
154 stdcall: Caller allocates parameters, callee deallocates.
155 Function name has @N after it, where N is number of arg bytes
158 ToDo: The stdcall calling convention is x86 (win32) specific,
159 so perhaps we should emit a warning if it's being used on other
162 See: http://www.programmersheaven.com/2/Calling-conventions
165 data CCallConv = CCallConv | StdCallConv | CmmCallConv | PrimCallConv
166 deriving (Eq, Data, Typeable)
167 {-! derive: Binary !-}
169 instance Outputable CCallConv where
170 ppr StdCallConv = ptext (sLit "stdcall")
171 ppr CCallConv = ptext (sLit "ccall")
172 ppr CmmCallConv = ptext (sLit "C--")
173 ppr PrimCallConv = ptext (sLit "prim")
175 defaultCCallConv :: CCallConv
176 defaultCCallConv = CCallConv
178 ccallConvToInt :: CCallConv -> Int
179 ccallConvToInt StdCallConv = 0
180 ccallConvToInt CCallConv = 1
183 Generate the gcc attribute corresponding to the given
184 calling convention (used by PprAbsC):
187 ccallConvAttribute :: CCallConv -> String
188 ccallConvAttribute StdCallConv = "__attribute__((__stdcall__))"
189 ccallConvAttribute CCallConv = ""
193 type CLabelString = FastString -- A C label, completely unencoded
195 pprCLabelString :: CLabelString -> SDoc
196 pprCLabelString lbl = ftext lbl
198 isCLabelString :: CLabelString -> Bool -- Checks to see if this is a valid C label
200 = all ok (unpackFS lbl)
202 ok c = isAlphaNum c || c == '_' || c == '.'
203 -- The '.' appears in e.g. "foo.so" in the
204 -- module part of a ExtName. Maybe it should be separate
208 Printing into C files:
211 instance Outputable CExportSpec where
212 ppr (CExportStatic str _) = pprCLabelString str
214 instance Outputable CCallSpec where
215 ppr (CCallSpec fun cconv safety)
216 = hcat [ ifPprDebug callconv, ppr_fun fun ]
218 callconv = text "{-" <> ppr cconv <> text "-}"
220 gc_suf | playSafe safety = text "_GC"
223 ppr_fun (StaticTarget fn Nothing)
224 = text "__pkg_ccall" <> gc_suf <+> pprCLabelString fn
226 ppr_fun (StaticTarget fn (Just pkgId))
227 = text "__pkg_ccall" <> gc_suf <+> ppr pkgId <+> pprCLabelString fn
229 ppr_fun DynamicTarget
230 = text "__dyn_ccall" <> gc_suf <+> text "\"\""
234 %************************************************************************
238 %************************************************************************
241 {-* Generated by DrIFT-v1.0 : Look, but Don't Touch. *-}
242 instance Binary ForeignCall where
243 put_ bh (CCall aa) = put_ bh aa
244 get bh = do aa <- get bh; return (CCall aa)
246 instance Binary Safety where
247 put_ bh (PlaySafe aa) = do
250 put_ bh PlayInterruptible = do
252 put_ bh PlayRisky = do
259 1 -> do return PlayInterruptible
260 _ -> do return PlayRisky
262 instance Binary CExportSpec where
263 put_ bh (CExportStatic aa ab) = do
269 return (CExportStatic aa ab)
271 instance Binary CCallSpec where
272 put_ bh (CCallSpec aa ab ac) = do
280 return (CCallSpec aa ab ac)
282 instance Binary CCallTarget where
283 put_ bh (StaticTarget aa ab) = do
287 put_ bh DynamicTarget = do
294 return (StaticTarget aa ab)
295 _ -> do return DynamicTarget
297 instance Binary CCallConv where
298 put_ bh CCallConv = do
300 put_ bh StdCallConv = do
302 put_ bh PrimCallConv = do
307 0 -> do return CCallConv
308 1 -> do return StdCallConv
309 _ -> do return PrimCallConv