import HsSyn
import DataCon
import CoreUtils
-import CoreUnfold
import Id
import Literal
import Module
dsFImport :: Id
-> ForeignImport
-> DsM ([Binding], SDoc, SDoc)
-dsFImport id (CImport cconv safety _ _ spec) = do
+dsFImport id (CImport cconv safety _ spec) = do
(ids, h, c) <- dsCImport id spec cconv safety
return (ids, h, c)
-> DsM ([Binding], SDoc, SDoc)
dsCImport id (CLabel cid) cconv _ = do
let ty = idType id
+ fod = case splitTyConApp_maybe (repType ty) of
+ Just (tycon, _)
+ | tyConUnique tycon == funPtrTyConKey ->
+ IsFunction
+ _ -> IsData
(resTy, foRhs) <- resultWrapper ty
ASSERT(fromJust resTy `coreEqType` addrPrimTy) -- typechecker ensures this
let
- rhs = foRhs (Lit (MachLabel cid stdcall_info))
+ rhs = foRhs (Lit (MachLabel cid stdcall_info fod))
stdcall_info = fun_type_arg_stdcall_info cconv ty
in
return ([(id, rhs)], empty, empty)
+dsCImport id (CFunction target) cconv@PrimCallConv safety
+ = dsPrimCall id (CCall (CCallSpec target cconv safety))
dsCImport id (CFunction target) cconv safety
= dsFCall id (CCall (CCallSpec target cconv safety))
dsCImport id CWrapper cconv _
-- Build the wrapper
work_app = mkApps (mkVarApps (Var work_id) tvs) val_args
wrapper_body = foldr ($) (res_wrapper work_app) arg_wrappers
- wrap_rhs = mkLams (tvs ++ args) wrapper_body
- fn_id_w_inl = fn_id `setIdUnfolding` mkInlineRule wrap_rhs (length args)
+ wrap_rhs = mkInlineMe (mkLams (tvs ++ args) wrapper_body)
- return ([(work_id, work_rhs), (fn_id_w_inl, wrap_rhs)], empty, empty)
+ return ([(work_id, work_rhs), (fn_id, wrap_rhs)], empty, empty)
\end{code}
%************************************************************************
%* *
+\subsection{Primitive calls}
+%* *
+%************************************************************************
+
+This is for `@foreign import prim@' declarations.
+
+Currently, at the core level we pretend that these primitive calls are
+foreign calls. It may make more sense in future to have them as a distinct
+kind of Id, or perhaps to bundle them with PrimOps since semantically and
+for calling convention they are really prim ops.
+
+\begin{code}
+dsPrimCall :: Id -> ForeignCall -> DsM ([(Id, Expr TyVar)], SDoc, SDoc)
+dsPrimCall fn_id fcall = do
+ let
+ ty = idType fn_id
+ (tvs, fun_ty) = tcSplitForAllTys ty
+ (arg_tys, io_res_ty) = tcSplitFunTys fun_ty
+ -- Must use tcSplit* functions because we want to
+ -- see that (IO t) in the corner
+
+ args <- newSysLocalsDs arg_tys
+
+ ccall_uniq <- newUnique
+ let
+ call_app = mkFCall ccall_uniq fcall (map Var args) io_res_ty
+ rhs = mkLams tvs (mkLams args call_app)
+ return ([(fn_id, rhs)], empty, empty)
+
+\end{code}
+
+%************************************************************************
+%* *
\subsection{Foreign export}
%* *
%************************************************************************
-}
adj_args = [ mkIntLitInt (ccallConvToInt cconv)
, Var stbl_value
- , Lit (MachLabel fe_nm mb_sz_args)
+ , Lit (MachLabel fe_nm mb_sz_args IsFunction)
, Lit (mkMachString typestring)
]
-- name of external entry point providing these services.
, Lam stbl_value ccall_adj
]
- fed = (id `setInlinePragma` NeverActive, io_app)
+ fed = (id `setInlineActivation` NeverActive, io_app)
-- Never inline the f.e.d. function, because the litlit
-- might not be in scope in other modules.
pprCconv = case cc of
CCallConv -> empty
StdCallConv -> text (ccallConvAttribute cc)
- CmmCallConv -> panic "mkFExportCBits/pprCconv CmmCallConv"
+ _ -> panic ("mkFExportCBits/pprCconv " ++ showPpr cc)
header_bits = ptext (sLit "extern") <+> fun_proto <> semi