module StgInterp (
ClosureEnv, ItblEnv,
- filterRdrNameEnv, -- :: [ModuleName] -> FiniteMap RdrName a
- -- -> FiniteMap RdrName a
+ filterNameMap, -- :: [ModuleName] -> FiniteMap Name a
+ -- -> FiniteMap Name a
linkIModules, -- :: ItblEnv -> ClosureEnv
-- -> [([UnlinkedIBind], ItblEnv)]
- converting string literals to Addr# is horrible and introduces
a memory leak. See if something can be done about this.
+ - lots of assumptions about word size vs. double size etc.
+
----------------------------------------------------------------------------- -}
#include "HsVersions.h"
+
+
import Linker
import Id ( Id, idPrimRep )
import Outputable
import Type ( Type, typePrimRep, deNoteType, repType, funResultTy )
import DataCon ( DataCon, dataConTag, dataConRepArgTys )
import ClosureInfo ( mkVirtHeapOffsets )
-import Module ( ModuleName )
-import Name ( toRdrName )
+import Module ( ModuleName, moduleName )
+import RdrName
+import Name hiding (filterNameEnv)
+import Util
import UniqFM
import UniqSet
-import {-# SOURCE #-} MCI_make_constr
+--import {-# SOURCE #-} MCI_make_constr
-import IOExts ( unsafePerformIO ) -- ToDo: remove
-import PrelGHC --( unsafeCoerce#, dataToTag#,
- -- indexPtrOffClosure#, indexWordOffClosure# )
-import PrelAddr ( Addr(..) )
-import PrelFloat ( Float(..), Double(..) )
-import Bits
import FastString
import GlaExts ( Int(..) )
import Module ( moduleNameFS )
import Class ( Class, classTyCon )
import InterpSyn
import StgSyn
-import Addr
-import RdrName ( RdrName, rdrNameModule, rdrNameOcc )
import FiniteMap
-import Panic ( panic )
import OccName ( occNameString )
-import ErrUtils ( showPass )
-import CmdLineOpts ( DynFlags )
+import ErrUtils ( showPass, dumpIfSet_dyn )
+import CmdLineOpts ( DynFlags, DynFlag(..) )
+import Panic ( panic )
+import IOExts
+import Addr
+import Bits
import Foreign
import CTypes
+
import IO
+import PrelGHC --( unsafeCoerce#, dataToTag#,
+ -- indexPtrOffClosure#, indexWordOffClosure# )
+import PrelAddr ( Addr(..) )
+import PrelFloat ( Float(..), Double(..) )
+
+
+#if 1
+interp = panic "interp"
+stgExprToInterpSyn = panic "stgExprToInterpSyn"
+stgBindsToInterpSyn = panic "stgBindsToInterpSyn"
+iExprToHValue = panic "iExprToHValue"
+linkIModules = panic "linkIModules"
+filterNameMap = panic "filterNameMap"
+type ItblEnv = FiniteMap Name (Ptr StgInfoTable)
+type ClosureEnv = FiniteMap Name HValue
+data StgInfoTable = StgInfoTable {
+ ptrs :: Word16,
+ nptrs :: Word16,
+ srtlen :: Word16,
+ tipe :: Word16,
+ code0, code1, code2, code3, code4, code5, code6, code7 :: Word8
+}
+
+#else
+
-- ---------------------------------------------------------------------------
-- Environments needed by the linker
-- ---------------------------------------------------------------------------
-type ItblEnv = FiniteMap RdrName (Ptr StgInfoTable)
-type ClosureEnv = FiniteMap RdrName HValue
+type ItblEnv = FiniteMap Name (Ptr StgInfoTable)
+type ClosureEnv = FiniteMap Name HValue
emptyClosureEnv = emptyFM
-- remove all entries for a given set of modules from the environment
-filterRdrNameEnv :: [ModuleName] -> FiniteMap RdrName a -> FiniteMap RdrName a
-filterRdrNameEnv mods env
- = filterFM (\n _ -> rdrNameModule n `notElem` mods) env
+filterNameMap :: [ModuleName] -> FiniteMap Name a -> FiniteMap Name a
+filterNameMap mods env
+ = filterFM (\n _ -> moduleName (nameModule n) `notElem` mods) env
-- ---------------------------------------------------------------------------
-- Turn an UnlinkedIExpr into a value we can run, for the interpreter
-- ---------------------------------------------------------------------------
iExprToHValue :: ItblEnv -> ClosureEnv -> UnlinkedIExpr -> IO HValue
-iExprToHValue ie ce expr = return (interp (linkIExpr ie ce expr))
+iExprToHValue ie ce expr
+ = do linked_expr <- linkIExpr ie ce expr
+ return (interp linked_expr)
-- ---------------------------------------------------------------------------
-- Convert STG to an unlinked interpretable
= do showPass dflags "StgToInterp"
let ibinds = concatMap (translateBind emptyUniqSet) binds
let tycs = local_tycons ++ map classTyCon local_classes
+ dumpIfSet_dyn dflags Opt_D_dump_InterpSyn
+ "Convert To InterpSyn" (vcat (map pprIBind ibinds))
itblenv <- mkITbls tycs
return (ibinds, itblenv)
-> IO UnlinkedIExpr
stgExprToInterpSyn dflags expr
= do showPass dflags "StgToInterp"
- return (stg2expr emptyUniqSet expr)
+ let iexpr = stg2expr emptyUniqSet expr
+ dumpIfSet_dyn dflags Opt_D_dump_InterpSyn
+ "Convert To InterpSyn" (pprIExpr iexpr)
+ return iexpr
translateBind :: UniqSet Id -> StgBinding -> [UnlinkedIBind]
translateBind ie (StgNonRec v e) = [IBind v (rhs2expr ie e)]
rhsExpr = stg2expr (addListToUniqSet ie args) rhs
rhsRep = repOfStgExpr rhs
mkLambdas [] = rhsExpr
- mkLambdas (v:vs) = mkLam (repOfId v) rhsRep v (mkLambdas vs)
+ mkLambdas [v] = mkLam (repOfId v) rhsRep v rhsExpr
+ mkLambdas (v:vs) = mkLam (repOfId v) RepP v (mkLambdas vs)
rhs2expr ie (StgRhsCon ccs dcon args)
= conapp2expr ie dcon args
conapp2expr ie dcon args
= mkConApp con_rdrname reps exprs
where
- con_rdrname = toRdrName dcon
+ con_rdrname = getName dcon
exprs = map (arg2expr ie) inHeapOrder
reps = map repOfArg inHeapOrder
inHeapOrder = toHeapOrder args
in
rearranged
-foreign label "PrelBase_Izh_con_info" prelbase_Izh_con_info :: Addr
-
-- Handle most common cases specially; do the rest with a generic
-- mechanism (deferred till later :)
-mkConApp :: RdrName -> [Rep] -> [UnlinkedIExpr] -> UnlinkedIExpr
+mkConApp :: Name -> [Rep] -> [UnlinkedIExpr] -> UnlinkedIExpr
mkConApp nm [] [] = ConApp nm
mkConApp nm [RepI] [a1] = ConAppI nm a1
mkConApp nm [RepP] [a1] = ConAppP nm a1
mkConApp nm [RepP,RepP] [a1,a2] = ConAppPP nm a1 a2
-mkConApp nm [RepP,RepP,RepP] [a1,a2,a3] = ConAppPPP nm a1 a2 a3
-mkConApp nm reps args
- = pprPanic "StgInterp.mkConApp: unhandled reps" (hsep (map ppr reps))
+mkConApp nm reps args = ConAppGen nm args
mkLam RepP RepP = LamPP
mkLam RepI RepP = LamIP
| repOfStgExpr scrut /= RepP
-> mkCasePrim (repOfStgExpr stgexpr)
bndr (stg2expr ie scrut)
- (map doPrimAlt alts)
- (def2expr def)
+ (map (doPrimAlt ie') alts)
+ (def2expr ie' def)
+ | otherwise ->
+ pprPanic "stg2expr(StgCase,prim)" (ppr (repOfStgExpr scrut) $$ (case scrut of (StgApp v _) -> ppr v <+> ppr (idType v) <+> ppr (idPrimRep v)) $$ ppr stgexpr)
+ where ie' = addOneToUniqSet ie bndr
StgCase scrut live liveR bndr srt (StgAlgAlts tycon alts def)
| repOfStgExpr scrut == RepP
-> mkCaseAlg (repOfStgExpr stgexpr)
bndr (stg2expr ie scrut)
- (map doAlgAlt alts)
- (def2expr def)
+ (map (doAlgAlt ie') alts)
+ (def2expr ie' def)
+ where ie' = addOneToUniqSet ie bndr
+
StgPrimApp op args res_ty
- -> mkPrimOp (repOfStgExpr stgexpr)
- op (map (arg2expr ie) args)
+ -> mkPrimOp (repOfStgExpr stgexpr) op (map (arg2expr ie) args)
StgConApp dcon args
-> conapp2expr ie dcon args
other
-> pprPanic "stg2expr" (ppr stgexpr)
where
- doPrimAlt (lit,rhs)
+ doPrimAlt ie (lit,rhs)
= AltPrim (lit2expr lit) (stg2expr ie rhs)
- doAlgAlt (dcon,vars,uses,rhs)
+ doAlgAlt ie (dcon,vars,uses,rhs)
= AltAlg (dataConTag dcon - 1)
(map id2VaaRep (toHeapOrder vars))
(stg2expr (addListToUniqSet ie vars) rhs)
in
rearranged
- def2expr StgNoDefault = Nothing
- def2expr (StgBindDefault rhs) = Just (stg2expr ie rhs)
+ def2expr ie StgNoDefault = Nothing
+ def2expr ie (StgBindDefault rhs) = Just (stg2expr ie rhs)
mkAppChain ie result_rep so_far []
= panic "mkAppChain"
RepF -> VarF
RepD -> VarD
RepP -> VarP) var
- | otherwise = Native (toRdrName var)
+ | otherwise = Native (getName var)
mkRec RepI = RecI
mkRec RepP = RecP
-- Link interpretables into something we can run
-- ---------------------------------------------------------------------------
+GLOBAL_VAR(cafTable, [], [HValue])
+
+addCAF :: HValue -> IO ()
+addCAF x = do xs <- readIORef cafTable; writeIORef cafTable (x:xs)
+
linkIModules :: ItblEnv -- incoming global itbl env; returned updated
-> ClosureEnv -- incoming global closure env; returned updated
-> [([UnlinkedIBind], ItblEnv)]
linkIModules gie gce mods = do
let (bindss, ies) = unzip mods
binds = concat bindss
- top_level_binders = map (toRdrName.binder) binds
+ top_level_binders = map (getName.binder) binds
final_gie = foldr plusFM gie ies
- let {-rec-}
- new_gce = addListToFM gce (zip top_level_binders new_rhss)
- new_rhss = map (\b -> evalP (bindee b) emptyUFM) new_binds
- --vvvvvvvvv----------------------------------------^^^^^^^^^-- circular
- new_binds = linkIBinds final_gie new_gce binds
+ (new_binds, new_gce) <-
+ fixIO (\ ~(new_binds, new_gce) -> do
+
+ new_binds <- linkIBinds final_gie new_gce binds
+
+ let new_rhss = map (\b -> evalP (bindee b) emptyUFM) new_binds
+ let new_gce = addListToFM gce (zip top_level_binders new_rhss)
+
+ return (new_binds, new_gce))
return (new_binds, final_gie, new_gce)
-- up and not cache them in the source symbol tables. The interpreted
-- code will still be referenced in the source symbol tables.
-linkIBinds :: ItblEnv -> ClosureEnv -> [UnlinkedIBind] -> [LinkedIBind]
-linkIBinds ie ce binds = map (linkIBind ie ce) binds
+linkIBinds :: ItblEnv -> ClosureEnv -> [UnlinkedIBind] -> IO [LinkedIBind]
+linkIBinds ie ce binds = mapM (linkIBind ie ce) binds
-linkIBind ie ce (IBind bndr expr) = IBind bndr (linkIExpr ie ce expr)
+linkIBind ie ce (IBind bndr expr)
+ = do expr <- linkIExpr ie ce expr
+ return (IBind bndr expr)
-linkIExpr :: ItblEnv -> ClosureEnv -> UnlinkedIExpr -> LinkedIExpr
+linkIExpr :: ItblEnv -> ClosureEnv -> UnlinkedIExpr -> IO LinkedIExpr
linkIExpr ie ce expr = case expr of
- CaseAlgP bndr expr alts dflt ->
- CaseAlgP bndr (linkIExpr ie ce expr) (linkAlgAlts ie ce alts)
- (linkDefault ie ce dflt)
-
- CaseAlgI bndr expr alts dflt ->
- CaseAlgI bndr (linkIExpr ie ce expr) (linkAlgAlts ie ce alts)
- (linkDefault ie ce dflt)
-
- CasePrimP bndr expr alts dflt ->
- CasePrimP bndr (linkIExpr ie ce expr) (linkPrimAlts ie ce alts)
- (linkDefault ie ce dflt)
-
- CasePrimI bndr expr alts dflt ->
- CasePrimI bndr (linkIExpr ie ce expr) (linkPrimAlts ie ce alts)
- (linkDefault ie ce dflt)
+ CaseAlgP bndr expr alts dflt -> linkAlgCase ie ce bndr expr alts dflt CaseAlgP
+ CaseAlgI bndr expr alts dflt -> linkAlgCase ie ce bndr expr alts dflt CaseAlgI
+ CaseAlgF bndr expr alts dflt -> linkAlgCase ie ce bndr expr alts dflt CaseAlgF
+ CaseAlgD bndr expr alts dflt -> linkAlgCase ie ce bndr expr alts dflt CaseAlgD
+
+ CasePrimP bndr expr alts dflt -> linkPrimCase ie ce bndr expr alts dflt CasePrimP
+ CasePrimI bndr expr alts dflt -> linkPrimCase ie ce bndr expr alts dflt CasePrimI
+ CasePrimF bndr expr alts dflt -> linkPrimCase ie ce bndr expr alts dflt CasePrimF
+ CasePrimD bndr expr alts dflt -> linkPrimCase ie ce bndr expr alts dflt CasePrimD
+
+ ConApp con -> lookupNullaryCon ie con
+
+ ConAppI con arg0 -> do
+ con' <- lookupCon ie con
+ arg' <- linkIExpr ie ce arg0
+ return (ConAppI con' arg')
+
+ ConAppP con arg0 -> do
+ con' <- lookupCon ie con
+ arg' <- linkIExpr ie ce arg0
+ return (ConAppP con' arg')
+
+ ConAppPP con arg0 arg1 -> do
+ con' <- lookupCon ie con
+ arg0' <- linkIExpr ie ce arg0
+ arg1' <- linkIExpr ie ce arg1
+ return (ConAppPP con' arg0' arg1')
+
+ ConAppGen con args -> do
+ con <- lookupCon ie con
+ args <- mapM (linkIExpr ie ce) args
+ return (ConAppGen con args)
- ConApp con ->
- ConApp (lookupCon ie con)
-
- ConAppI con arg0 ->
- ConAppI (lookupCon ie con) (linkIExpr ie ce arg0)
-
- ConAppP con arg0 ->
- ConAppP (lookupCon ie con) (linkIExpr ie ce arg0)
+ PrimOpI op args -> linkPrimOp ie ce PrimOpI op args
+ PrimOpP op args -> linkPrimOp ie ce PrimOpP op args
+
+ NonRecP bind expr -> linkNonRec ie ce NonRecP bind expr
+ NonRecI bind expr -> linkNonRec ie ce NonRecI bind expr
+ NonRecF bind expr -> linkNonRec ie ce NonRecF bind expr
+ NonRecD bind expr -> linkNonRec ie ce NonRecD bind expr
- ConAppPP con arg0 arg1 ->
- ConAppPP (lookupCon ie con) (linkIExpr ie ce arg0) (linkIExpr ie ce arg1)
+ RecP binds expr -> linkRec ie ce RecP binds expr
+ RecI binds expr -> linkRec ie ce RecI binds expr
+ RecF binds expr -> linkRec ie ce RecF binds expr
+ RecD binds expr -> linkRec ie ce RecD binds expr
- ConAppPPP con arg0 arg1 arg2 ->
- ConAppPPP (lookupCon ie con) (linkIExpr ie ce arg0)
- (linkIExpr ie ce arg1) (linkIExpr ie ce arg2)
-
- PrimOpI op args -> PrimOpI op (map (linkIExpr ie ce) args)
- PrimOpP op args -> PrimOpP op (map (linkIExpr ie ce) args)
-
- NonRecP bind expr -> NonRecP (linkIBind ie ce bind) (linkIExpr ie ce expr)
- RecP binds expr -> RecP (linkIBinds ie ce binds) (linkIExpr ie ce expr)
-
- NonRecI bind expr -> NonRecI (linkIBind ie ce bind) (linkIExpr ie ce expr)
- RecI binds expr -> RecI (linkIBinds ie ce binds) (linkIExpr ie ce expr)
-
- LitI i -> LitI i
- LitF i -> LitF i
- LitD i -> LitD i
+ LitI i -> return (LitI i)
+ LitF i -> return (LitF i)
+ LitD i -> return (LitD i)
Native var -> lookupNative ce var
VarP v -> lookupVar ce VarP v
VarI v -> lookupVar ce VarI v
+ VarF v -> lookupVar ce VarF v
+ VarD v -> lookupVar ce VarD v
- LamPP bndr expr -> LamPP bndr (linkIExpr ie ce expr)
- LamPI bndr expr -> LamPI bndr (linkIExpr ie ce expr)
- LamIP bndr expr -> LamIP bndr (linkIExpr ie ce expr)
- LamII bndr expr -> LamII bndr (linkIExpr ie ce expr)
+ LamPP bndr expr -> linkLam ie ce LamPP bndr expr
+ LamPI bndr expr -> linkLam ie ce LamPI bndr expr
+ LamPF bndr expr -> linkLam ie ce LamPF bndr expr
+ LamPD bndr expr -> linkLam ie ce LamPD bndr expr
+ LamIP bndr expr -> linkLam ie ce LamIP bndr expr
+ LamII bndr expr -> linkLam ie ce LamII bndr expr
+ LamIF bndr expr -> linkLam ie ce LamIF bndr expr
+ LamID bndr expr -> linkLam ie ce LamID bndr expr
+ LamFP bndr expr -> linkLam ie ce LamFP bndr expr
+ LamFI bndr expr -> linkLam ie ce LamFI bndr expr
+ LamFF bndr expr -> linkLam ie ce LamFF bndr expr
+ LamFD bndr expr -> linkLam ie ce LamFD bndr expr
+ LamDP bndr expr -> linkLam ie ce LamDP bndr expr
+ LamDI bndr expr -> linkLam ie ce LamDI bndr expr
+ LamDF bndr expr -> linkLam ie ce LamDF bndr expr
+ LamDD bndr expr -> linkLam ie ce LamDD bndr expr
- AppPP fun arg -> AppPP (linkIExpr ie ce fun) (linkIExpr ie ce arg)
- AppPI fun arg -> AppPI (linkIExpr ie ce fun) (linkIExpr ie ce arg)
- AppIP fun arg -> AppIP (linkIExpr ie ce fun) (linkIExpr ie ce arg)
- AppII fun arg -> AppII (linkIExpr ie ce fun) (linkIExpr ie ce arg)
+ AppPP fun arg -> linkApp ie ce AppPP fun arg
+ AppPI fun arg -> linkApp ie ce AppPI fun arg
+ AppPF fun arg -> linkApp ie ce AppPF fun arg
+ AppPD fun arg -> linkApp ie ce AppPD fun arg
+ AppIP fun arg -> linkApp ie ce AppIP fun arg
+ AppII fun arg -> linkApp ie ce AppII fun arg
+ AppIF fun arg -> linkApp ie ce AppIF fun arg
+ AppID fun arg -> linkApp ie ce AppID fun arg
+ AppFP fun arg -> linkApp ie ce AppFP fun arg
+ AppFI fun arg -> linkApp ie ce AppFI fun arg
+ AppFF fun arg -> linkApp ie ce AppFF fun arg
+ AppFD fun arg -> linkApp ie ce AppFD fun arg
+ AppDP fun arg -> linkApp ie ce AppDP fun arg
+ AppDI fun arg -> linkApp ie ce AppDI fun arg
+ AppDF fun arg -> linkApp ie ce AppDF fun arg
+ AppDD fun arg -> linkApp ie ce AppDD fun arg
+
+linkAlgCase ie ce bndr expr alts dflt con
+ = do expr <- linkIExpr ie ce expr
+ alts <- mapM (linkAlgAlt ie ce) alts
+ dflt <- linkDefault ie ce dflt
+ return (con bndr expr alts dflt)
+
+linkPrimCase ie ce bndr expr alts dflt con
+ = do expr <- linkIExpr ie ce expr
+ alts <- mapM (linkPrimAlt ie ce) alts
+ dflt <- linkDefault ie ce dflt
+ return (con bndr expr alts dflt)
+
+linkAlgAlt ie ce (AltAlg tag args rhs)
+ = do rhs <- linkIExpr ie ce rhs
+ return (AltAlg tag args rhs)
+
+linkPrimAlt ie ce (AltPrim lit rhs)
+ = do rhs <- linkIExpr ie ce rhs
+ lit <- linkIExpr ie ce lit
+ return (AltPrim lit rhs)
+
+linkDefault ie ce Nothing = return Nothing
+linkDefault ie ce (Just expr)
+ = do expr <- linkIExpr ie ce expr
+ return (Just expr)
+
+linkNonRec ie ce con bind expr
+ = do expr <- linkIExpr ie ce expr
+ bind <- linkIBind ie ce bind
+ return (con bind expr)
+
+linkRec ie ce con binds expr
+ = do expr <- linkIExpr ie ce expr
+ binds <- linkIBinds ie ce binds
+ return (con binds expr)
+
+linkLam ie ce con bndr expr
+ = do expr <- linkIExpr ie ce expr
+ return (con bndr expr)
+
+linkApp ie ce con fun arg
+ = do fun <- linkIExpr ie ce fun
+ arg <- linkIExpr ie ce arg
+ return (con fun arg)
+
+linkPrimOp ie ce con op args
+ = do args <- mapM (linkIExpr ie ce) args
+ return (con op args)
lookupCon ie con =
case lookupFM ie con of
- Just (Ptr addr) -> addr
- Nothing ->
+ Just (Ptr addr) -> return addr
+ Nothing -> do
+ -- try looking up in the object files.
+ m <- lookupSymbol (nameToCLabel con "con_info")
+ case m of
+ Just addr -> return addr
+ Nothing -> pprPanic "linkIExpr" (ppr con)
+
+-- nullary constructors don't have normal _con_info tables.
+lookupNullaryCon ie con =
+ case lookupFM ie con of
+ Just (Ptr addr) -> return (ConApp addr)
+ Nothing -> do
-- try looking up in the object files.
- case {-HACK!!!-}
- unsafePerformIO (lookupSymbol (rdrNameToCLabel con "con_info")) of
- Just addr -> addr
- Nothing -> pprPanic "linkIExpr" (ppr con)
+ m <- lookupSymbol (nameToCLabel con "closure")
+ case m of
+ Just (A# addr) -> return (Native (unsafeCoerce# addr))
+ Nothing -> pprPanic "lookupNullaryCon" (ppr con)
+
lookupNative ce var =
- case lookupFM ce var of
- Just e -> Native e
- Nothing ->
- -- try looking up in the object files.
- let lbl = (rdrNameToCLabel var "closure")
- addr = unsafePerformIO (lookupSymbol lbl) in
- case {- trace (lbl ++ " -> " ++ show addr) $ -} addr of
- Just (A# addr) -> Native (unsafeCoerce# addr)
- Nothing -> pprPanic "linkIExpr" (ppr var)
+ unsafeInterleaveIO (do
+ case lookupFM ce var of
+ Just e -> return (Native e)
+ Nothing -> do
+ -- try looking up in the object files.
+ let lbl = (nameToCLabel var "closure")
+ m <- lookupSymbol lbl
+ case m of
+ Just (A# addr)
+ -> do addCAF (unsafeCoerce# addr)
+ return (Native (unsafeCoerce# addr))
+ Nothing -> pprPanic "linkIExpr" (ppr var)
+ )
-- some VarI/VarP refer to top-level interpreted functions; we change
-- them into Natives here.
lookupVar ce f v =
- case lookupFM ce (toRdrName v) of
- Nothing -> f v
- Just e -> Native e
+ unsafeInterleaveIO (
+ case lookupFM ce (getName v) of
+ Nothing -> return (f v)
+ Just e -> return (Native e)
+ )
-- HACK!!! ToDo: cleaner
-rdrNameToCLabel :: RdrName -> String{-suffix-} -> String
-rdrNameToCLabel rn suffix =
+nameToCLabel :: Name -> String{-suffix-} -> String
+nameToCLabel n suffix =
_UNPK_(moduleNameFS (rdrNameModule rn))
++ '_':occNameString(rdrNameOcc rn) ++ '_':suffix
-
-linkAlgAlts ie ce = map (linkAlgAlt ie ce)
-linkAlgAlt ie ce (AltAlg tag args rhs) = AltAlg tag args (linkIExpr ie ce rhs)
-
-linkPrimAlts ie ce = map (linkPrimAlt ie ce)
-linkPrimAlt ie ce (AltPrim lit rhs)
- = AltPrim (linkIExpr ie ce lit) (linkIExpr ie ce rhs)
-
-linkDefault ie ce Nothing = Nothing
-linkDefault ie ce (Just expr) = Just (linkIExpr ie ce expr)
+ where rn = toRdrName n
-- ---------------------------------------------------------------------------
-- The interpreter proper
-- always has pointer rep.
evalP (AppIP e1 e2) de = unsafeCoerce# (evalP e1 de) (evalI e2 de)
evalP (AppPP e1 e2) de = unsafeCoerce# (evalP e1 de) (evalP e2 de)
-evalP (AppFP e1 e2) de = unsafeCoerce# (evalF e1 de) (evalI e2 de)
-evalP (AppDP e1 e2) de = unsafeCoerce# (evalD e1 de) (evalP e2 de)
+evalP (AppFP e1 e2) de = unsafeCoerce# (evalP e1 de) (evalF e2 de)
+evalP (AppDP e1 e2) de = unsafeCoerce# (evalP e1 de) (evalD e2 de)
-- Lambdas always return P-rep, but we need to do different things
-- depending on both the argument and result representations.
= case helper_casePrim bndr expr alts def de of
(rhs, de') -> evalP rhs de'
-{-
--- ConApp can only be handled by evalP
-evalP (ConApp itbl args) se de
- = loop args
- where
- -- This appalling hack suggested (gleefully) by SDM
- -- It is not well typed (needless to say?)
- loop :: [Expr] -> boxed
- loop []
- = trace "loop-empty" (
- case itbl of A# addr# -> unsafeCoerce# (mci_make_constr addr#)
- )
- loop (a:as)
- = trace "loop-not-empty" (
- case repOf a of
- RepI -> case evalI a de of i# -> loop as i#
- RepP -> let p = evalP a de in loop as p
- )
--}
+evalP (ConApp (A# itbl)) de
+ = mci_make_constr0 itbl
evalP (ConAppI (A# itbl) a1) de
= case evalI a1 de of i1 -> mci_make_constrI itbl i1
-evalP (ConApp (A# itbl)) de
- = mci_make_constr itbl
-
evalP (ConAppP (A# itbl) a1) de
- = let p1 = evalP a1 de
- in mci_make_constrP itbl p1
+ = evalP (ConAppGen (A# itbl) [a1]) de
+-- = let p1 = evalP a1 de
+-- in mci_make_constrP itbl p1
evalP (ConAppPP (A# itbl) a1 a2) de
= let p1 = evalP a1 de
p2 = evalP a2 de
in mci_make_constrPP itbl p1 p2
-evalP (ConAppPPP (A# itbl) a1 a2 a3) de
- = let p1 = evalP a1 de
- p2 = evalP a2 de
- p3 = evalP a3 de
- in mci_make_constrPPP itbl p1 p2 p3
-
-
-
+evalP (ConAppGen itbl args) de
+ = let c = case itbl of A# a# -> mci_make_constr a# in
+ c `seq` loop c 1#{-leave room for hdr-} args
+ where
+ loop :: a{-closure-} -> Int# -> [LinkedIExpr] -> a
+ loop c off [] = c
+ loop c off (a:as)
+ = case repOf a of
+ RepP -> let c' = setPtrOffClosure c off (evalP a de)
+ in c' `seq` loop c' (off +# 1#) as
+ RepI -> case evalI a de of { i# ->
+ let c' = setIntOffClosure c off i#
+ in c' `seq` loop c' (off +# 1#) as }
+ RepF -> case evalF a de of { f# ->
+ let c' = setFloatOffClosure c off f#
+ in c' `seq` loop c' (off +# 1#) as }
+ RepD -> case evalD a de of { d# ->
+ let c' = setDoubleOffClosure c off d#
+ in c' `seq` loop c' (off +# 2#) as }
+
+evalP (PrimOpP IntEqOp [e1,e2]) de
+ = case evalI e1 de of
+ i1# -> case evalI e2 de of
+ i2# -> unsafeCoerce# (i1# ==# i2#)
+
+evalP (PrimOpP primop _) de
+ = error ("evalP: unhandled primop: " ++ showSDoc (ppr primop))
evalP other de
= error ("evalP: unhandled case: " ++ showExprTag other)
evalI (PrimOpI IntAddOp [e1,e2]) de = evalI e1 de +# evalI e2 de
evalI (PrimOpI IntSubOp [e1,e2]) de = evalI e1 de -# evalI e2 de
+evalI (PrimOpI DataToTagOp [e1]) de = dataToTag# (evalP e1 de)
+
+evalI (PrimOpI primop _) de
+ = error ("evalI: unhandled primop: " ++ showSDoc (ppr primop))
--evalI (NonRec (IBind v e) b) de
-- = evalI b (augment de v (eval e de))
repOf (NonRecF _ _) = RepF
repOf (NonRecD _ _) = RepD
+repOf (RecP _ _) = RepP
+repOf (RecI _ _) = RepI
+repOf (RecF _ _) = RepF
+repOf (RecD _ _) = RepD
+
repOf (LitI _) = RepI
repOf (LitF _) = RepF
repOf (LitD _) = RepD
-repOf (VarP _) = RepI
+repOf (Native _) = RepP
+
+repOf (VarP _) = RepP
repOf (VarI _) = RepI
repOf (VarF _) = RepF
repOf (VarD _) = RepD
repOf (ConAppI _ _) = RepP
repOf (ConAppP _ _) = RepP
repOf (ConAppPP _ _ _) = RepP
-repOf (ConAppPPP _ _ _ _) = RepP
+repOf (ConAppGen _ _) = RepP
repOf (CaseAlgP _ _ _ _) = RepP
repOf (CaseAlgI _ _ _ _) = RepI
-> (LinkedIExpr, UniqFM boxed)
helper_casePrim bndr expr alts def de
= case repOf expr of
- -- Umm, can expr have any other rep? Yes ...
- -- CharRep, DoubleRep, FloatRep. What about string reps?
RepI -> case evalI expr de of
i# -> (select_altPrim alts def (LitI i#),
addToUFM de bndr (unsafeCoerce# (I# i#)))
+ RepF -> case evalF expr de of
+ f# -> (select_altPrim alts def (LitF f#),
+ addToUFM de bndr (unsafeCoerce# (F# f#)))
+ RepD -> case evalD expr de of
+ d# -> (select_altPrim alts def (LitD d#),
+ addToUFM de bndr (unsafeCoerce# (D# d#)))
augment_from_constr :: UniqFM boxed -> a -> ([(Id,Rep)],Int) -> UniqFM boxed
= case rep of
RepP -> indexPtrOffClosure con offset
RepI -> unsafeCoerce# (I# (indexIntOffClosure con offset))
+ RepF -> unsafeCoerce# (F# (indexFloatOffClosure con offset))
+ RepD -> unsafeCoerce# (D# (indexDoubleOffClosure con offset))
in
augment_from_constr (addToUFM de v v_binding) con
(vs,offset + repSizeW rep)
eqLits (LitI i1#) (LitI i2#) = i1# ==# i2#
+-- ----------------------------------------------------------------------
+-- Grotty inspection and creation of closures
+-- ----------------------------------------------------------------------
-- a is a constructor
indexPtrOffClosure :: a -> Int -> b
indexIntOffClosure con (I# offset)
= case wordToInt (W# (indexWordOffClosure# con offset)) of I# i# -> i#
+indexFloatOffClosure :: a -> Int -> Float#
+indexFloatOffClosure con (I# offset)
+ = unsafeCoerce# (indexWordOffClosure# con offset)
+ -- TOCK TOCK TOCK! Those GHC developers are crazy.
+
+indexDoubleOffClosure :: a -> Int -> Double#
+indexDoubleOffClosure con (I# offset)
+ = unsafeCoerce# (panic "indexDoubleOffClosure")
+
+setPtrOffClosure :: a -> Int# -> b -> a
+setPtrOffClosure a i b = case setPtrOffClosure# a i b of (# c #) -> c
+
+setIntOffClosure :: a -> Int# -> Int# -> a
+setIntOffClosure a i b = case setWordOffClosure# a i (int2Word# b) of (# c #) -> c
+
+setFloatOffClosure :: a -> Int# -> Float# -> a
+setFloatOffClosure a i b = case setWordOffClosure# a i (unsafeCoerce# b) of (# c #) -> c
+
+setDoubleOffClosure :: a -> Int# -> Double# -> a
+setDoubleOffClosure a i b = unsafeCoerce# (panic "setDoubleOffClosure")
------------------------------------------------------------------------
--- Manufacturing of info tables for DataCons defined in this module ---
mk_dirret_itbl (dcon, conNo)
= mk_itbl dcon conNo mci_constr_entry
- mk_itbl :: DataCon -> Int -> Addr -> IO (RdrName,ItblPtr)
+ mk_itbl :: DataCon -> Int -> Addr -> IO (Name,ItblPtr)
mk_itbl dcon conNo entry_addr
= let (tot_wds, ptr_wds, _)
= mkVirtHeapOffsets typePrimRep (dataConRepArgTys dcon)
entry_addr_w = fromIntegral (addrToInt entry_addr)
in
do addr <- malloc
- putStrLn ("SIZE of itbl is " ++ show (sizeOf itbl))
- putStrLn ("# ptrs of itbl is " ++ show ptrs)
- putStrLn ("# nptrs of itbl is " ++ show nptrs)
+ --putStrLn ("SIZE of itbl is " ++ show (sizeOf itbl))
+ --putStrLn ("# ptrs of itbl is " ++ show ptrs)
+ --putStrLn ("# nptrs of itbl is " ++ show nptrs)
poke addr itbl
- return (toRdrName dcon, addr `plusPtr` 8)
+ return (getName dcon, addr `plusPtr` 8)
byte :: Int -> Word32 -> Word32
-----------------------------------------------------------------------------q
foreign import "strncpy" strncpy :: Ptr a -> ByteArray# -> CInt -> IO ()
+#endif
+
\end{code}