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
18 CExportSpec(..), CLabelString, isCLabelString, pprCLabelString,
20 CCallTarget(..), isDynamicTarget,
21 CCallConv(..), defaultCCallConv, ccallConvToInt, ccallConvAttribute,
23 DNCallSpec(..), DNKind(..), DNType(..),
35 %************************************************************************
37 \subsubsection{Data types}
39 %************************************************************************
45 deriving( Eq ) -- We compare them when seeing if an interface
46 -- has changed (for versioning purposes)
47 {-! derive: Binary !-}
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
53 ppr (DNCall dn) = ppr dn
59 = PlaySafe -- Might invoke Haskell GC, or do a call back, or
60 -- switch threads, etc. So make sure things are
61 -- tidy before the call. Additionally, in the threaded
62 -- RTS we arrange for the external call to be executed
63 -- by a separate OS thread, i.e., _concurrently_ to the
64 -- execution of other Haskell threads.
66 Bool -- Indicates the deprecated "threadsafe" annotation
67 -- which is now an alias for "safe". This information
68 -- is never used except to emit a deprecation warning.
70 | PlayRisky -- None of the above can happen; the call will return
71 -- without interacting with the runtime system at all
73 -- Show used just for Show Lex.Token, I think
74 {-! derive: Binary !-}
76 instance Outputable Safety where
77 ppr (PlaySafe False) = ptext (sLit "safe")
78 ppr (PlaySafe True) = ptext (sLit "threadsafe")
79 ppr PlayRisky = ptext (sLit "unsafe")
81 playSafe :: Safety -> Bool
82 playSafe PlaySafe{} = True
83 playSafe PlayRisky = False
87 %************************************************************************
89 \subsubsection{Calling C}
91 %************************************************************************
95 = CExportStatic -- foreign export ccall foo :: ty
96 CLabelString -- C Name of exported function
98 {-! derive: Binary !-}
101 = CCallSpec CCallTarget -- What to call
102 CCallConv -- Calling convention to use.
105 {-! derive: Binary !-}
112 = StaticTarget CLabelString -- An "unboxed" ccall# to `fn'.
113 | DynamicTarget -- First argument (an Addr#) is the function pointer
115 {-! derive: Binary !-}
117 isDynamicTarget :: CCallTarget -> Bool
118 isDynamicTarget DynamicTarget = True
119 isDynamicTarget _ = False
123 Stuff to do with calling convention:
125 ccall: Caller allocates parameters, *and* deallocates them.
127 stdcall: Caller allocates parameters, callee deallocates.
128 Function name has @N after it, where N is number of arg bytes
131 ToDo: The stdcall calling convention is x86 (win32) specific,
132 so perhaps we should emit a warning if it's being used on other
135 See: http://www.programmersheaven.com/2/Calling-conventions
138 data CCallConv = CCallConv | StdCallConv | CmmCallConv | PrimCallConv
140 {-! derive: Binary !-}
142 instance Outputable CCallConv where
143 ppr StdCallConv = ptext (sLit "stdcall")
144 ppr CCallConv = ptext (sLit "ccall")
145 ppr CmmCallConv = ptext (sLit "C--")
146 ppr PrimCallConv = ptext (sLit "prim")
148 defaultCCallConv :: CCallConv
149 defaultCCallConv = CCallConv
151 ccallConvToInt :: CCallConv -> Int
152 ccallConvToInt StdCallConv = 0
153 ccallConvToInt CCallConv = 1
156 Generate the gcc attribute corresponding to the given
157 calling convention (used by PprAbsC):
160 ccallConvAttribute :: CCallConv -> String
161 ccallConvAttribute StdCallConv = "__attribute__((__stdcall__))"
162 ccallConvAttribute CCallConv = ""
166 type CLabelString = FastString -- A C label, completely unencoded
168 pprCLabelString :: CLabelString -> SDoc
169 pprCLabelString lbl = ftext lbl
171 isCLabelString :: CLabelString -> Bool -- Checks to see if this is a valid C label
173 = all ok (unpackFS lbl)
175 ok c = isAlphaNum c || c == '_' || c == '.'
176 -- The '.' appears in e.g. "foo.so" in the
177 -- module part of a ExtName. Maybe it should be separate
181 Printing into C files:
184 instance Outputable CExportSpec where
185 ppr (CExportStatic str _) = pprCLabelString str
187 instance Outputable CCallSpec where
188 ppr (CCallSpec fun cconv safety)
189 = hcat [ ifPprDebug callconv, ppr_fun fun ]
191 callconv = text "{-" <> ppr cconv <> text "-}"
193 gc_suf | playSafe safety = text "_GC"
196 ppr_fun DynamicTarget = text "__dyn_ccall" <> gc_suf <+> text "\"\""
197 ppr_fun (StaticTarget fn) = text "__ccall" <> gc_suf <+> pprCLabelString fn
201 %************************************************************************
203 \subsubsection{.NET interop}
205 %************************************************************************
209 DNCallSpec Bool -- True => static method/field
210 DNKind -- what type of access
212 String -- fully qualified method/field name.
213 [DNType] -- argument types.
214 DNType -- result type.
216 {-! derive: Binary !-}
223 {-! derive: Binary !-}
245 {-! derive: Binary !-}
247 withDNTypes :: DNCallSpec -> [DNType] -> DNType -> DNCallSpec
248 withDNTypes (DNCallSpec isStatic k assem nm _ _) argTys resTy
249 = DNCallSpec isStatic k assem nm argTys resTy
251 instance Outputable DNCallSpec where
252 ppr (DNCallSpec isStatic kind ass nm _ _ )
254 (if isStatic then text "static" else empty) <+>
255 (text (case kind of { DNMethod -> "method" ; DNField -> "field"; DNConstructor -> "ctor" })) <+>
256 (if null ass then char ' ' else char '[' <> text ass <> char ']') <>
263 %************************************************************************
267 %************************************************************************
270 {-* Generated by DrIFT-v1.0 : Look, but Don't Touch. *-}
271 instance Binary ForeignCall where
272 put_ bh (CCall aa) = do
275 put_ bh (DNCall ab) = do
286 instance Binary Safety where
287 put_ bh (PlaySafe aa) = do
290 put_ bh PlayRisky = do
297 _ -> do return PlayRisky
299 instance Binary CExportSpec where
300 put_ bh (CExportStatic aa ab) = do
306 return (CExportStatic aa ab)
308 instance Binary CCallSpec where
309 put_ bh (CCallSpec aa ab ac) = do
317 return (CCallSpec aa ab ac)
319 instance Binary CCallTarget where
320 put_ bh (StaticTarget aa) = do
323 put_ bh DynamicTarget = do
329 return (StaticTarget aa)
330 _ -> do return DynamicTarget
332 instance Binary CCallConv where
333 put_ bh CCallConv = do
335 put_ bh StdCallConv = do
337 put_ bh PrimCallConv = do
342 0 -> do return CCallConv
343 1 -> do return StdCallConv
344 _ -> do return PrimCallConv
346 instance Binary DNCallSpec where
347 put_ bh (DNCallSpec isStatic kind ass nm _ _) = do
357 return (DNCallSpec isStatic kind ass nm [] undefined)
359 instance Binary DNKind where
360 put_ bh DNMethod = do
364 put_ bh DNConstructor = do
369 0 -> do return DNMethod
370 1 -> do return DNField
371 _ -> do return DNConstructor
373 instance Binary DNType where
380 put_ bh DNDouble = do
396 put_ bh DNWord16 = do
398 put_ bh DNWord32 = do
400 put_ bh DNWord64 = do
406 put_ bh DNObject = do
408 put_ bh DNString = do
425 11 -> return DNWord16
426 12 -> return DNWord32
427 13 -> return DNWord64
430 16 -> return DNObject
431 17 -> return DNString
433 -- Imported from other files :-