summaryrefslogtreecommitdiff
path: root/ghc/compiler/simplStg
diff options
context:
space:
mode:
authorsof <unknown>1999-10-25 13:21:16 +0000
committersof <unknown>1999-10-25 13:21:16 +0000
commitbd3fdabc98a87e7ebf124e9c26f6a7f89cb214e1 (patch)
treeed241c2019be9c93da902d4830edeefbf7ec7654 /ghc/compiler/simplStg
parent148227dc4e67d89a2036251ef3ad72fed1e44c0f (diff)
downloadhaskell-bd3fdabc98a87e7ebf124e9c26f6a7f89cb214e1.tar.gz
[project @ 1999-10-25 13:20:57 by sof]
FFI wibble: * disallow the use of {Mutable}ByteArrays in 'safe' foreign imports. * ensure that ForeignObjs live across a _ccall_GC_.
Diffstat (limited to 'ghc/compiler/simplStg')
-rw-r--r--ghc/compiler/simplStg/StgVarInfo.lhs32
1 files changed, 29 insertions, 3 deletions
diff --git a/ghc/compiler/simplStg/StgVarInfo.lhs b/ghc/compiler/simplStg/StgVarInfo.lhs
index f185c19b6a..6e93773e0e 100644
--- a/ghc/compiler/simplStg/StgVarInfo.lhs
+++ b/ghc/compiler/simplStg/StgVarInfo.lhs
@@ -17,9 +17,12 @@ import Id ( setIdArity, getIdArity, Id )
import VarSet
import VarEnv
import Var
+import Const ( Con(..) )
import IdInfo ( ArityInfo(..), InlinePragInfo(..),
setInlinePragInfo )
-import Maybes ( maybeToBool )
+import PrimOp ( PrimOp(..) )
+import TysWiredIn ( isForeignObjTy )
+import Maybes ( maybeToBool, orElse )
import Name ( isLocallyDefined )
import BasicTypes ( Arity )
import Outputable
@@ -294,11 +297,21 @@ varsExpr (StgCase scrut _ _ bndr srt alts)
then modifyIdInfo (`setInlinePragInfo` NoInlinePragInfo) bndr
else modifyIdInfo (`setInlinePragInfo` IAmDead) bndr
+ -- for a _ccall_GC_, some of the *arguments* need to live across the
+ -- call (see findLiveArgs comments.), so we annotate them as being live
+ -- in the alts to achieve the desired effect.
+ mb_live_across_case =
+ case scrut of
+ StgCon (PrimOp (CCallOp _ _ True{- _ccall_GC_ -} _)) args _ ->
+ Just (foldl findLiveArgs emptyVarSet args)
+ _ -> Nothing
+
-- don't consider the default binder as being 'live in alts',
-- since this is from the point of view of the case expr, where
-- the default binder is not free.
- live_in_alts = live_in_cont `unionVarSet`
- (alts_lvs `minusVarSet` unitVarSet bndr)
+ live_in_alts = orElse (FMAP unionVarSet mb_live_across_case) id $
+ live_in_cont `unionVarSet`
+ (alts_lvs `minusVarSet` unitVarSet bndr)
in
-- we tell the scrutinee that everything live in the alts
-- is live in it, too.
@@ -394,6 +407,19 @@ varsExpr (StgLet bind body)
returnLne (new_let, fvs, escs)
\end{code}
+If we've got a case containing a _ccall_GC_ primop, we need to
+ensure that the arguments are kept live for the duration of the
+call. This only an issue
+
+\begin{code}
+findLiveArgs :: StgLiveVars -> StgArg -> StgLiveVars
+findLiveArgs lvs (StgConArg _) = lvs
+findLiveArgs lvs (StgVarArg x)
+ | isForeignObjTy (idType x) = extendVarSet lvs x
+ | otherwise = lvs
+\end{code}
+
+
Applications:
\begin{code}
varsApp :: Maybe UpdateFlag -- Just upd <=> this application is