2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 \section[Foreign]{Foreign calls}
9 Safety(..), playSafe, playThreadSafe,
13 CCallTarget(..), isDynamicTarget, isCasmTarget,
14 CCallConv(..), defaultCCallConv, ccallConvToInt, ccallConvAttribute,
21 #include "HsVersions.h"
23 import CStrings ( CLabelString, pprCLabelString )
24 import FastString ( FastString )
29 %************************************************************************
31 \subsubsection{Data types}
33 %************************************************************************
39 deriving( Eq ) -- We compare them when seeing if an interface
40 -- has changed (for versioning purposes)
42 -- We may need more clues to distinguish foreign calls
43 -- but this simple printer will do for now
44 instance Outputable ForeignCall where
45 ppr (CCall cc) = ppr cc
46 ppr (DNCall dn) = ppr dn
52 = PlaySafe -- Might invoke Haskell GC, or do a call back, or
53 -- switch threads, etc. So make sure things are
54 -- tidy before the call
55 Bool -- => True, external function is also re-entrant.
56 -- [if supported, RTS arranges for the external call
57 -- to be executed by a separate OS thread, i.e.,
58 -- _concurrently_ to the execution of other Haskell threads.]
60 | PlayRisky -- None of the above can happen; the call will return
61 -- without interacting with the runtime system at all
63 -- Show used just for Show Lex.Token, I think
65 instance Outputable Safety where
66 ppr (PlaySafe False) = ptext SLIT("safe")
67 ppr (PlaySafe True) = ptext SLIT("threadsafe")
68 ppr PlayRisky = ptext SLIT("unsafe")
70 playSafe :: Safety -> Bool
71 playSafe PlaySafe{} = True
72 playSafe PlayRisky = False
74 playThreadSafe :: Safety -> Bool
75 playThreadSafe (PlaySafe x) = x
76 playThreadSafe _ = False
80 %************************************************************************
82 \subsubsection{Calling C}
84 %************************************************************************
88 = CExportStatic -- foreign export ccall foo :: ty
89 CLabelString -- C Name of exported function
93 = CCallSpec CCallTarget -- What to call
94 CCallConv -- Calling convention to use.
103 = StaticTarget CLabelString -- An "unboxed" ccall# to `fn'.
104 | DynamicTarget -- First argument (an Addr#) is the function pointer
105 | CasmTarget CLabelString -- Inline C code (now seriously deprecated)
108 isDynamicTarget, isCasmTarget :: CCallTarget -> Bool
109 isDynamicTarget DynamicTarget = True
110 isDynamicTarget other = False
112 isCasmTarget (CasmTarget _) = True
113 isCasmTarget other = False
117 Stuff to do with calling convention:
119 ccall: Caller allocates parameters, *and* deallocates them.
121 stdcall: Caller allocates parameters, callee deallocates.
122 Function name has @N after it, where N is number of arg bytes
125 ToDo: The stdcall calling convention is x86 (win32) specific,
126 so perhaps we should emit a warning if it's being used on other
130 data CCallConv = CCallConv | StdCallConv
133 instance Outputable CCallConv where
134 ppr StdCallConv = ptext SLIT("stdcall")
135 ppr CCallConv = ptext SLIT("ccall")
137 defaultCCallConv :: CCallConv
138 defaultCCallConv = CCallConv
140 ccallConvToInt :: CCallConv -> Int
141 ccallConvToInt StdCallConv = 0
142 ccallConvToInt CCallConv = 1
145 Generate the gcc attribute corresponding to the given
146 calling convention (used by PprAbsC):
149 ccallConvAttribute :: CCallConv -> String
150 ccallConvAttribute StdCallConv = "__stdcall"
151 ccallConvAttribute CCallConv = ""
154 Printing into C files:
157 instance Outputable CExportSpec where
158 ppr (CExportStatic str _) = pprCLabelString str
160 instance Outputable CCallSpec where
161 ppr (CCallSpec fun cconv safety)
162 = hcat [ ifPprDebug callconv, ppr_fun fun ]
164 callconv = text "{-" <> ppr cconv <> text "-}"
166 gc_suf | playSafe safety = text "_GC"
169 ppr_fun DynamicTarget = text "__dyn_ccall" <> gc_suf <+> text "\"\""
170 ppr_fun (StaticTarget fn) = text "__ccall" <> gc_suf <+> pprCLabelString fn
171 ppr_fun (CasmTarget fn) = text "__casm" <> gc_suf <+> text "``" <> pprCLabelString fn <> text "''"
175 %************************************************************************
177 \subsubsection{.NET stuff}
179 %************************************************************************
182 data DNCallSpec = DNCallSpec FastString
185 instance Outputable DNCallSpec where
186 ppr (DNCallSpec s) = char '"' <> ptext s <> char '"'
191 %************************************************************************
195 %************************************************************************
198 okToExposeFCall :: ForeignCall -> Bool
199 -- OK to unfold a Foreign Call in an interface file
200 -- Yes, unless it's a _casm_
201 okToExposeFCall (CCall (CCallSpec target _ _)) = not (isCasmTarget target)
202 okToExposeFCall other = True