diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/codeGen/CgForeignCall.hs | 4 | ||||
-rw-r--r-- | compiler/codeGen/StgCmmForeign.hs | 4 | ||||
-rw-r--r-- | compiler/coreSyn/MkExternalCore.lhs | 4 | ||||
-rw-r--r-- | compiler/deSugar/DsCCall.lhs | 2 | ||||
-rw-r--r-- | compiler/deSugar/DsForeign.lhs | 10 | ||||
-rw-r--r-- | compiler/deSugar/DsMeta.hs | 5 | ||||
-rw-r--r-- | compiler/ghci/ByteCodeGen.lhs | 4 | ||||
-rw-r--r-- | compiler/hsSyn/HsDecls.lhs | 7 | ||||
-rw-r--r-- | compiler/parser/ParserCore.y | 2 | ||||
-rw-r--r-- | compiler/parser/RdrHsSyn.lhs | 20 | ||||
-rw-r--r-- | compiler/prelude/ForeignCall.lhs | 22 | ||||
-rw-r--r-- | compiler/rename/RnSource.lhs | 4 | ||||
-rw-r--r-- | compiler/stgSyn/CoreToStg.lhs | 2 | ||||
-rw-r--r-- | compiler/typecheck/TcForeign.lhs | 7 |
14 files changed, 68 insertions, 29 deletions
diff --git a/compiler/codeGen/CgForeignCall.hs b/compiler/codeGen/CgForeignCall.hs index 09636bc6b2..16e77eca35 100644 --- a/compiler/codeGen/CgForeignCall.hs +++ b/compiler/codeGen/CgForeignCall.hs @@ -78,9 +78,11 @@ emitForeignCall results (CCall (CCallSpec target cconv safety)) args live where (call_args, cmm_target) = case target of + StaticTarget _ _ False -> + panic "emitForeignCall: unexpected FFI value import" -- If the packageId is Nothing then the label is taken to be in the -- package currently being compiled. - StaticTarget lbl mPkgId + StaticTarget lbl mPkgId True -> let labelSource = case mPkgId of Nothing -> ForeignLabelInThisPackage diff --git a/compiler/codeGen/StgCmmForeign.hs b/compiler/codeGen/StgCmmForeign.hs index af88ba848a..c41832a0ab 100644 --- a/compiler/codeGen/StgCmmForeign.hs +++ b/compiler/codeGen/StgCmmForeign.hs @@ -56,7 +56,9 @@ cgForeignCall results result_hints (CCall (CCallSpec target cconv safety)) stg_a = do { cmm_args <- getFCallArgs stg_args ; let ((call_args, arg_hints), cmm_target) = case target of - StaticTarget lbl mPkgId + StaticTarget _ _ False -> + panic "cgForeignCall: unexpected FFI value import" + StaticTarget lbl mPkgId True -> let labelSource = case mPkgId of Nothing -> ForeignLabelInThisPackage diff --git a/compiler/coreSyn/MkExternalCore.lhs b/compiler/coreSyn/MkExternalCore.lhs index cb12973a60..89c0c911d9 100644 --- a/compiler/coreSyn/MkExternalCore.lhs +++ b/compiler/coreSyn/MkExternalCore.lhs @@ -138,8 +138,10 @@ make_exp (Var v) = do isLocal <- isALocal vName return $ case idDetails v of - FCallId (CCall (CCallSpec (StaticTarget nm _) callconv _)) + FCallId (CCall (CCallSpec (StaticTarget nm _ True) callconv _)) -> C.External (unpackFS nm) (showSDoc (ppr callconv)) (make_ty (varType v)) + FCallId (CCall (CCallSpec (StaticTarget _ _ False) _ _)) -> + panic "make_exp: FFI values not supported" FCallId (CCall (CCallSpec DynamicTarget callconv _)) -> C.DynExternal (showSDoc (ppr callconv)) (make_ty (varType v)) -- Constructors are always exported, so make sure to declare them diff --git a/compiler/deSugar/DsCCall.lhs b/compiler/deSugar/DsCCall.lhs index 06a41bcd1a..2fff5fdb56 100644 --- a/compiler/deSugar/DsCCall.lhs +++ b/compiler/deSugar/DsCCall.lhs @@ -98,7 +98,7 @@ dsCCall lbl args may_gc result_ty (ccall_result_ty, res_wrapper) <- boxResult result_ty uniq <- newUnique let - target = StaticTarget lbl Nothing + target = StaticTarget lbl Nothing True the_fcall = CCall (CCallSpec target CCallConv may_gc) the_prim_app = mkFCall uniq the_fcall unboxed_args ccall_result_ty return (foldr ($) (res_wrapper the_prim_app) arg_wrappers) diff --git a/compiler/deSugar/DsForeign.lhs b/compiler/deSugar/DsForeign.lhs index 46c4a54a5c..88caaef875 100644 --- a/compiler/deSugar/DsForeign.lhs +++ b/compiler/deSugar/DsForeign.lhs @@ -207,13 +207,13 @@ dsFCall fn_id co fcall mDeclHeader = do (fcall', cDoc) <- case fcall of - CCall (CCallSpec (StaticTarget cName mPackageId) CApiConv safety) -> + CCall (CCallSpec (StaticTarget cName mPackageId isFun) CApiConv safety) -> do fcall_uniq <- newUnique let wrapperName = mkFastString "ghc_wrapper_" `appendFS` mkFastString (showSDoc (ppr fcall_uniq)) `appendFS` mkFastString "_" `appendFS` cName - fcall' = CCall (CCallSpec (StaticTarget wrapperName mPackageId) CApiConv safety) + fcall' = CCall (CCallSpec (StaticTarget wrapperName mPackageId True) CApiConv safety) c = includes $$ fun_proto <+> braces (cRet <> semi) includes = vcat [ text "#include <" <> ftext h <> text ">" @@ -222,7 +222,11 @@ dsFCall fn_id co fcall mDeclHeader = do cRet | isVoidRes = cCall | otherwise = text "return" <+> cCall - cCall = ppr cName <> parens argVals + cCall = if isFun + then ppr cName <> parens argVals + else if null arg_tys + then ppr cName + else panic "dsFCall: Unexpected arguments to FFI value import" raw_res_ty = case tcSplitIOType_maybe io_res_ty of Just (_ioTyCon, res_ty) -> res_ty Nothing -> io_res_ty diff --git a/compiler/deSugar/DsMeta.hs b/compiler/deSugar/DsMeta.hs index 181a25eb4d..7daa037395 100644 --- a/compiler/deSugar/DsMeta.hs +++ b/compiler/deSugar/DsMeta.hs @@ -350,10 +350,11 @@ repForD (L loc (ForeignImport name typ _ (CImport cc s mch cis))) where conv_cimportspec (CLabel cls) = notHandled "Foreign label" (doubleQuotes (ppr cls)) conv_cimportspec (CFunction DynamicTarget) = return "dynamic" - conv_cimportspec (CFunction (StaticTarget fs _)) = return (unpackFS fs) + conv_cimportspec (CFunction (StaticTarget fs _ True)) = return (unpackFS fs) + conv_cimportspec (CFunction (StaticTarget _ _ False)) = panic "conv_cimportspec: values not supported yet" conv_cimportspec CWrapper = return "wrapper" static = case cis of - CFunction (StaticTarget _ _) -> "static " + CFunction (StaticTarget _ _ _) -> "static " _ -> "" chStr = case mch of Nothing -> "" diff --git a/compiler/ghci/ByteCodeGen.lhs b/compiler/ghci/ByteCodeGen.lhs index afc51163e3..046d6ec132 100644 --- a/compiler/ghci/ByteCodeGen.lhs +++ b/compiler/ghci/ByteCodeGen.lhs @@ -986,7 +986,9 @@ generateCCall d0 s p (CCallSpec target cconv safety) fn args_r_to_l DynamicTarget -> return (False, panic "ByteCodeGen.generateCCall(dyn)") - StaticTarget target _ + StaticTarget _ _ False -> + panic "generateCCall: unexpected FFI value import" + StaticTarget target _ True -> do res <- ioToBc (lookupStaticPtr stdcall_adj_target) return (True, res) where diff --git a/compiler/hsSyn/HsDecls.lhs b/compiler/hsSyn/HsDecls.lhs index 4d8c01d196..49a5b91717 100644 --- a/compiler/hsSyn/HsDecls.lhs +++ b/compiler/hsSyn/HsDecls.lhs @@ -1024,8 +1024,11 @@ instance Outputable ForeignImport where pprCEntity (CLabel lbl) = ptext (sLit "static") <+> pp_hdr <+> char '&' <> ppr lbl - pprCEntity (CFunction (StaticTarget lbl _)) = - ptext (sLit "static") <+> pp_hdr <+> ppr lbl + pprCEntity (CFunction (StaticTarget lbl _ isFun)) = + ptext (sLit "static") + <+> pp_hdr + <+> (if isFun then empty else ptext (sLit "value")) + <+> ppr lbl pprCEntity (CFunction (DynamicTarget)) = ptext (sLit "dynamic") pprCEntity (CWrapper) = ptext (sLit "wrapper") diff --git a/compiler/parser/ParserCore.y b/compiler/parser/ParserCore.y index 3a786ea04b..80d49430eb 100644 --- a/compiler/parser/ParserCore.y +++ b/compiler/parser/ParserCore.y @@ -278,7 +278,7 @@ exp :: { IfaceExpr } -- "InlineMe" -> IfaceNote IfaceInlineMe $3 -- } | '%external' STRING aty { IfaceFCall (ForeignCall.CCall - (CCallSpec (StaticTarget (mkFastString $2) Nothing) + (CCallSpec (StaticTarget (mkFastString $2) Nothing True) CCallConv PlaySafe)) $3 } diff --git a/compiler/parser/RdrHsSyn.lhs b/compiler/parser/RdrHsSyn.lhs index 3ba967352f..59e6727535 100644 --- a/compiler/parser/RdrHsSyn.lhs +++ b/compiler/parser/RdrHsSyn.lhs @@ -914,7 +914,7 @@ mkImport :: CCallConv -> P (HsDecl RdrName) mkImport cconv safety (L loc entity, v, ty) | cconv == PrimCallConv = do - let funcTarget = CFunction (StaticTarget entity Nothing) + let funcTarget = CFunction (StaticTarget entity Nothing True) importSpec = CImport PrimCallConv safety Nothing funcTarget return (ForD (ForeignImport v ty noForeignImportCoercionYet importSpec)) @@ -937,9 +937,11 @@ parseCImport cconv safety nm str = r <- choice [ string "dynamic" >> return (mk Nothing (CFunction DynamicTarget)), string "wrapper" >> return (mk Nothing CWrapper), - optional (token "static" >> skipSpaces) >> - (mk Nothing <$> cimp nm) +++ - (do h <- munch1 hdr_char; skipSpaces; mk (Just (Header (mkFastString h))) <$> cimp nm) + do optional (token "static" >> skipSpaces) + ((mk Nothing <$> cimp nm) +++ + (do h <- munch1 hdr_char + skipSpaces + mk (Just (Header (mkFastString h))) <$> cimp nm)) ] skipSpaces return r @@ -960,7 +962,15 @@ parseCImport cconv safety nm str = id_char c = isAlphaNum c || c == '_' cimp nm = (ReadP.char '&' >> skipSpaces >> CLabel <$> cid) - +++ ((\c -> CFunction (StaticTarget c Nothing)) <$> cid) + +++ (do isFun <- case cconv of + CApiConv -> + option True + (do token "value" + skipSpaces + return False) + _ -> return True + cid' <- cid + return (CFunction (StaticTarget cid' Nothing isFun))) where cid = return nm +++ (do c <- satisfy id_first_char diff --git a/compiler/prelude/ForeignCall.lhs b/compiler/prelude/ForeignCall.lhs index b245e8314a..b3a2ad3ff1 100644 --- a/compiler/prelude/ForeignCall.lhs +++ b/compiler/prelude/ForeignCall.lhs @@ -127,6 +127,9 @@ data CCallTarget -- The first argument of the import is the name of a function pointer (an Addr#). -- Used when importing a label as "foreign import ccall "dynamic" ..." + Bool -- True => really a function + -- False => a value; only + -- allowed in CAPI imports | DynamicTarget deriving( Eq, Data, Typeable ) @@ -219,11 +222,14 @@ instance Outputable CCallSpec where gc_suf | playSafe safety = text "_GC" | otherwise = empty - ppr_fun (StaticTarget fn Nothing) - = text "__pkg_ccall" <> gc_suf <+> pprCLabelString fn - - ppr_fun (StaticTarget fn (Just pkgId)) - = text "__pkg_ccall" <> gc_suf <+> ppr pkgId <+> pprCLabelString fn + ppr_fun (StaticTarget fn mPkgId isFun) + = text (if isFun then "__pkg_ccall" + else "__pkg_ccall_value") + <> gc_suf + <+> (case mPkgId of + Nothing -> empty + Just pkgId -> ppr pkgId) + <+> pprCLabelString fn ppr_fun DynamicTarget = text "__dyn_ccall" <> gc_suf <+> text "\"\"" @@ -297,10 +303,11 @@ instance Binary CCallSpec where return (CCallSpec aa ab ac) instance Binary CCallTarget where - put_ bh (StaticTarget aa ab) = do + put_ bh (StaticTarget aa ab ac) = do putByte bh 0 put_ bh aa put_ bh ab + put_ bh ac put_ bh DynamicTarget = do putByte bh 1 get bh = do @@ -308,7 +315,8 @@ instance Binary CCallTarget where case h of 0 -> do aa <- get bh ab <- get bh - return (StaticTarget aa ab) + ac <- get bh + return (StaticTarget aa ab ac) _ -> do return DynamicTarget instance Binary CCallConv where diff --git a/compiler/rename/RnSource.lhs b/compiler/rename/RnSource.lhs index e747b85719..1969229321 100644 --- a/compiler/rename/RnSource.lhs +++ b/compiler/rename/RnSource.lhs @@ -407,8 +407,8 @@ patchCImportSpec packageId spec patchCCallTarget :: PackageId -> CCallTarget -> CCallTarget patchCCallTarget packageId callTarget = case callTarget of - StaticTarget label Nothing - -> StaticTarget label (Just packageId) + StaticTarget label Nothing isFun + -> StaticTarget label (Just packageId) isFun _ -> callTarget diff --git a/compiler/stgSyn/CoreToStg.lhs b/compiler/stgSyn/CoreToStg.lhs index 98e5303b02..71bdfe97c9 100644 --- a/compiler/stgSyn/CoreToStg.lhs +++ b/compiler/stgSyn/CoreToStg.lhs @@ -545,7 +545,7 @@ coreToStgApp _ f args = do StgOpApp (StgPrimOp op) args' res_ty -- A call to some primitive Cmm function. - FCallId (CCall (CCallSpec (StaticTarget lbl (Just pkgId)) PrimCallConv _)) + FCallId (CCall (CCallSpec (StaticTarget lbl (Just pkgId) True) PrimCallConv _)) -> ASSERT( saturated ) StgOpApp (StgPrimCallOp (PrimCall lbl pkgId)) args' res_ty diff --git a/compiler/typecheck/TcForeign.lhs b/compiler/typecheck/TcForeign.lhs index 9fbcff62e8..ab850399c8 100644 --- a/compiler/typecheck/TcForeign.lhs +++ b/compiler/typecheck/TcForeign.lhs @@ -263,13 +263,18 @@ tcCheckFIType sig_ty arg_tys res_ty idecl@(CImport cconv safety _ (CFunction tar checkForeignArgs (isFFIArgumentTy dflags safety) arg_tys checkForeignRes nonIOok checkSafe (isFFIImportResultTy dflags) res_ty checkMissingAmpersand dflags arg_tys res_ty + case target of + StaticTarget _ _ False + | not (null arg_tys) -> + addErrTc (text "`value' imports cannot have function types") + _ -> return () return idecl -- This makes a convenient place to check -- that the C identifier is valid for C checkCTarget :: CCallTarget -> TcM () -checkCTarget (StaticTarget str _) = do +checkCTarget (StaticTarget str _ _) = do checkCg checkCOrAsmOrLlvmOrDotNetOrInterp check (isCLabelString str) (badCName str) |