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 #-}
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 -- We may need more clues to distinguish foreign calls
47 -- but this simple printer will do for now
48 instance Outputable ForeignCall where
49 ppr (CCall cc) = ppr cc
55 = PlaySafe -- Might invoke Haskell GC, or do a call back, or
56 -- switch threads, etc. So make sure things are
57 -- tidy before the call. Additionally, in the threaded
58 -- RTS we arrange for the external call to be executed
59 -- by a separate OS thread, i.e., _concurrently_ to the
60 -- execution of other Haskell threads.
62 Bool -- Indicates the deprecated "threadsafe" annotation
63 -- which is now an alias for "safe". This information
64 -- is never used except to emit a deprecation warning.
66 | PlayRisky -- None of the above can happen; the call will return
67 -- without interacting with the runtime system at all
68 deriving ( Eq, Show, Data, Typeable )
69 -- Show used just for Show Lex.Token, I think
70 {-! derive: Binary !-}
72 instance Outputable Safety where
73 ppr (PlaySafe False) = ptext (sLit "safe")
74 ppr (PlaySafe True) = ptext (sLit "threadsafe")
75 ppr PlayRisky = ptext (sLit "unsafe")
77 playSafe :: Safety -> Bool
78 playSafe PlaySafe{} = True
79 playSafe PlayRisky = False
83 %************************************************************************
85 \subsubsection{Calling C}
87 %************************************************************************
91 = CExportStatic -- foreign export ccall foo :: ty
92 CLabelString -- C Name of exported function
94 deriving (Data, Typeable)
95 {-! derive: Binary !-}
98 = CCallSpec CCallTarget -- What to call
99 CCallConv -- Calling convention to use.
102 {-! derive: Binary !-}
109 -- | How to call a particular function in C-land.
111 -- An "unboxed" ccall# to named function in a particular package.
113 CLabelString -- C-land name of label.
115 (Maybe PackageId) -- What package the function is in.
116 -- If Nothing, then it's taken to be in the current package.
117 -- Note: This information is only used for PrimCalls on Windows.
118 -- See CLabel.labelDynamic and CoreToStg.coreToStgApp
119 -- for the difference in representation between PrimCalls
120 -- and ForeignCalls. If the CCallTarget is representing
121 -- a regular ForeignCall then it's safe to set this to Nothing.
123 -- The first argument of the import is the name of a function pointer (an Addr#).
124 -- Used when importing a label as "foreign import ccall "dynamic" ..."
127 deriving( Eq, Data, Typeable )
128 {-! derive: Binary !-}
130 isDynamicTarget :: CCallTarget -> Bool
131 isDynamicTarget DynamicTarget = True
132 isDynamicTarget _ = False
136 Stuff to do with calling convention:
138 ccall: Caller allocates parameters, *and* deallocates them.
140 stdcall: Caller allocates parameters, callee deallocates.
141 Function name has @N after it, where N is number of arg bytes
144 ToDo: The stdcall calling convention is x86 (win32) specific,
145 so perhaps we should emit a warning if it's being used on other
148 See: http://www.programmersheaven.com/2/Calling-conventions
151 data CCallConv = CCallConv | StdCallConv | CmmCallConv | PrimCallConv
152 deriving (Eq, Data, Typeable)
153 {-! derive: Binary !-}
155 instance Outputable CCallConv where
156 ppr StdCallConv = ptext (sLit "stdcall")
157 ppr CCallConv = ptext (sLit "ccall")
158 ppr CmmCallConv = ptext (sLit "C--")
159 ppr PrimCallConv = ptext (sLit "prim")
161 defaultCCallConv :: CCallConv
162 defaultCCallConv = CCallConv
164 ccallConvToInt :: CCallConv -> Int
165 ccallConvToInt StdCallConv = 0
166 ccallConvToInt CCallConv = 1
169 Generate the gcc attribute corresponding to the given
170 calling convention (used by PprAbsC):
173 ccallConvAttribute :: CCallConv -> String
174 ccallConvAttribute StdCallConv = "__attribute__((__stdcall__))"
175 ccallConvAttribute CCallConv = ""
179 type CLabelString = FastString -- A C label, completely unencoded
181 pprCLabelString :: CLabelString -> SDoc
182 pprCLabelString lbl = ftext lbl
184 isCLabelString :: CLabelString -> Bool -- Checks to see if this is a valid C label
186 = all ok (unpackFS lbl)
188 ok c = isAlphaNum c || c == '_' || c == '.'
189 -- The '.' appears in e.g. "foo.so" in the
190 -- module part of a ExtName. Maybe it should be separate
194 Printing into C files:
197 instance Outputable CExportSpec where
198 ppr (CExportStatic str _) = pprCLabelString str
200 instance Outputable CCallSpec where
201 ppr (CCallSpec fun cconv safety)
202 = hcat [ ifPprDebug callconv, ppr_fun fun ]
204 callconv = text "{-" <> ppr cconv <> text "-}"
206 gc_suf | playSafe safety = text "_GC"
209 ppr_fun (StaticTarget fn Nothing)
210 = text "__pkg_ccall" <> gc_suf <+> pprCLabelString fn
212 ppr_fun (StaticTarget fn (Just pkgId))
213 = text "__pkg_ccall" <> gc_suf <+> ppr pkgId <+> pprCLabelString fn
215 ppr_fun DynamicTarget
216 = text "__dyn_ccall" <> gc_suf <+> text "\"\""
220 %************************************************************************
224 %************************************************************************
227 {-* Generated by DrIFT-v1.0 : Look, but Don't Touch. *-}
228 instance Binary ForeignCall where
229 put_ bh (CCall aa) = put_ bh aa
230 get bh = do aa <- get bh; return (CCall aa)
232 instance Binary Safety where
233 put_ bh (PlaySafe aa) = do
236 put_ bh PlayRisky = do
243 _ -> do return PlayRisky
245 instance Binary CExportSpec where
246 put_ bh (CExportStatic aa ab) = do
252 return (CExportStatic aa ab)
254 instance Binary CCallSpec where
255 put_ bh (CCallSpec aa ab ac) = do
263 return (CCallSpec aa ab ac)
265 instance Binary CCallTarget where
266 put_ bh (StaticTarget aa ab) = do
270 put_ bh DynamicTarget = do
277 return (StaticTarget aa ab)
278 _ -> do return DynamicTarget
280 instance Binary CCallConv where
281 put_ bh CCallConv = do
283 put_ bh StdCallConv = do
285 put_ bh PrimCallConv = do
290 0 -> do return CCallConv
291 1 -> do return StdCallConv
292 _ -> do return PrimCallConv