2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 \section[Foreign]{Foreign calls}
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
56 | PlayRisky -- None of the above can happen; the call will return
57 -- without interacting with the runtime system at all
59 -- Show used just for Show Lex.Token, I think
61 instance Outputable Safety where
63 ppr PlayRisky = ptext SLIT("unsafe")
65 playSafe PlaySafe = True
66 playSafe PlayRisky = False
70 %************************************************************************
72 \subsubsection{Calling C}
74 %************************************************************************
78 = CExportStatic -- foreign export ccall foo :: ty
79 CLabelString -- C Name of exported function
83 = CCallSpec CCallTarget -- What to call
84 CCallConv -- Calling convention to use.
93 = StaticTarget CLabelString -- An "unboxed" ccall# to `fn'.
94 | DynamicTarget -- First argument (an Addr#) is the function pointer
95 | CasmTarget CLabelString -- Inline C code (now seriously deprecated)
98 isDynamicTarget, isCasmTarget :: CCallTarget -> Bool
99 isDynamicTarget DynamicTarget = True
100 isDynamicTarget other = False
102 isCasmTarget (CasmTarget _) = True
103 isCasmTarget other = False
107 Stuff to do with calling convention:
109 ccall: Caller allocates parameters, *and* deallocates them.
111 stdcall: Caller allocates parameters, callee deallocates.
112 Function name has @N after it, where N is number of arg bytes
115 ToDo: The stdcall calling convention is x86 (win32) specific,
116 so perhaps we should emit a warning if it's being used on other
120 data CCallConv = CCallConv | StdCallConv
123 instance Outputable CCallConv where
124 ppr StdCallConv = ptext SLIT("__stdcall")
125 ppr CCallConv = ptext SLIT("_ccall")
127 defaultCCallConv :: CCallConv
128 defaultCCallConv = CCallConv
130 ccallConvToInt :: CCallConv -> Int
131 ccallConvToInt StdCallConv = 0
132 ccallConvToInt CCallConv = 1
135 Generate the gcc attribute corresponding to the given
136 calling convention (used by PprAbsC):
139 ccallConvAttribute :: CCallConv -> String
140 ccallConvAttribute StdCallConv = "__stdcall"
141 ccallConvAttribute CCallConv = ""
144 Printing into C files:
147 instance Outputable CExportSpec where
148 ppr (CExportStatic str _) = pprCLabelString str
150 instance Outputable CCallSpec where
151 ppr (CCallSpec fun cconv safety)
152 = hcat [ ifPprDebug callconv, ppr_fun fun ]
154 callconv = text "{-" <> ppr cconv <> text "-}"
156 gc_suf | playSafe safety = text "_GC"
159 ppr_fun DynamicTarget = text "__dyn_ccall" <> gc_suf <+> text "\"\""
160 ppr_fun (StaticTarget fn) = text "__ccall" <> gc_suf <+> pprCLabelString fn
161 ppr_fun (CasmTarget fn) = text "__casm" <> gc_suf <+> text "``" <> pprCLabelString fn <> text "''"
165 %************************************************************************
167 \subsubsection{.NET stuff}
169 %************************************************************************
172 data DNCallSpec = DNCallSpec FastString
175 instance Outputable DNCallSpec where
176 ppr (DNCallSpec s) = text "DotNet" <+> ptext s
181 %************************************************************************
185 %************************************************************************
188 okToExposeFCall :: ForeignCall -> Bool
189 -- OK to unfold a Foreign Call in an interface file
190 -- Yes, unless it's a _casm_
191 okToExposeFCall (CCall (CCallSpec target _ _)) = not (isCasmTarget target)
192 okToExposeFCall other = True