X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2FdeSugar%2FDsForeign.lhs;h=51f03c2f8f2c883153f46dbc4813bc9d5a2a97aa;hb=48f550f99f6f82f26de79529cf256b1e0a2b8e88;hp=1b1b7f04f4a93cfc579734aa8f6ad2ffad64513c;hpb=1fede4bc9501744bf2269ce2a4cb9fb735969caa;p=ghc-hetmet.git diff --git a/compiler/deSugar/DsForeign.lhs b/compiler/deSugar/DsForeign.lhs index 1b1b7f0..51f03c2 100644 --- a/compiler/deSugar/DsForeign.lhs +++ b/compiler/deSugar/DsForeign.lhs @@ -19,6 +19,7 @@ import DsMonad import HsSyn import DataCon import CoreUtils +import CoreUnfold import Id import Literal import Module @@ -91,8 +92,6 @@ dsForeigns fos = do do_decl (ForeignExport (L _ id) _ (CExport (CExportStatic ext_nm cconv))) = do (h, c, _, _) <- dsFExport id (idType id) ext_nm cconv False return (h, c, [id], []) - - do_decl d = pprPanic "dsForeigns/do_decl" (ppr d) \end{code} @@ -207,9 +206,10 @@ dsFCall fn_id fcall = do -- Build the wrapper work_app = mkApps (mkVarApps (Var work_id) tvs) val_args wrapper_body = foldr ($) (res_wrapper work_app) arg_wrappers - wrap_rhs = mkInlineMe (mkLams (tvs ++ args) wrapper_body) + wrap_rhs = mkLams (tvs ++ args) wrapper_body + fn_id_w_inl = fn_id `setIdUnfolding` mkInlineRule wrap_rhs (Just (length args)) - return ([(work_id, work_rhs), (fn_id, wrap_rhs)], empty, empty) + return ([(work_id, work_rhs), (fn_id_w_inl, wrap_rhs)], empty, empty) \end{code} @@ -488,6 +488,19 @@ mkFExportCBits c_nm maybe_target arg_htys res_hty is_IO_res_ty cc cResType | res_hty_is_unit = text "void" | otherwise = showStgType res_hty + -- when the return type is integral and word-sized or smaller, it + -- must be assigned as type ffi_arg (#3516). To see what type + -- libffi is expecting here, take a look in its own testsuite, e.g. + -- libffi/testsuite/libffi.call/cls_align_ulonglong.c + ffi_cResType + | is_ffi_arg_type = text "ffi_arg" + | otherwise = cResType + where + res_ty_key = getUnique (getName (typeTyCon res_hty)) + is_ffi_arg_type = res_ty_key `notElem` + [floatTyConKey, doubleTyConKey, + int64TyConKey, word64TyConKey] + -- Now we can cook up the prototype for the exported function. pprCconv = case cc of CCallConv -> empty @@ -569,9 +582,9 @@ mkFExportCBits c_nm maybe_target arg_htys res_hty is_IO_res_ty cc <> comma <> text "cap") <> semi , assignCResult , ptext (sLit "rts_unlock(cap);") - , if res_hty_is_unit then empty - else if libffi - then char '*' <> parens (cResType <> char '*') <> + , ppUnless res_hty_is_unit $ + if libffi + then char '*' <> parens (ffi_cResType <> char '*') <> ptext (sLit "resp = cret;") else ptext (sLit "return cret;") , rbrace @@ -608,11 +621,12 @@ showStgType :: Type -> SDoc showStgType t = text "Hs" <> text (showFFIType t) showFFIType :: Type -> String -showFFIType t = getOccString (getName tc) - where - tc = case tcSplitTyConApp_maybe (repType t) of - Just (tc,_) -> tc - Nothing -> pprPanic "showFFIType" (ppr t) +showFFIType t = getOccString (getName (typeTyCon t)) + +typeTyCon :: Type -> TyCon +typeTyCon ty = case tcSplitTyConApp_maybe (repType ty) of + Just (tc,_) -> tc + Nothing -> pprPanic "DsForeign.typeTyCon" (ppr ty) insertRetAddr :: CCallConv -> [(SDoc, SDoc, Type, CmmType)] -> [(SDoc, SDoc, Type, CmmType)]