X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2FdeSugar%2FDsForeign.lhs;h=9127676cf2aae092cf4ebfc9e8561939903399c6;hb=a62da487378d873399d2dedb85fc0d546fa911d8;hp=080289e8f9c5e49b8d6b9ef483737498c8ba5ca8;hpb=176fa33f17dd78355cc572e006d2ab26898e2c69;p=ghc-hetmet.git diff --git a/compiler/deSugar/DsForeign.lhs b/compiler/deSugar/DsForeign.lhs index 080289e..9127676 100644 --- a/compiler/deSugar/DsForeign.lhs +++ b/compiler/deSugar/DsForeign.lhs @@ -124,7 +124,7 @@ because it exposes the boxing to the call site. 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) @@ -142,14 +142,21 @@ dsCImport :: Id -> 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 _ @@ -238,6 +245,39 @@ dsFCall fn_id fcall = do %************************************************************************ %* * +\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} %* * %************************************************************************ @@ -355,7 +395,7 @@ dsFExportDynamic id cconv = do -} 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. @@ -382,7 +422,7 @@ dsFExportDynamic id cconv = do , 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. @@ -482,7 +522,7 @@ mkFExportCBits c_nm maybe_target arg_htys res_hty is_IO_res_ty cc 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