[project @ 2000-12-15 17:38:45 by sewardj]
[ghc-hetmet.git] / ghc / compiler / ghci / StgInterp.lhs
index d87aafc..8428814 100644 (file)
@@ -8,8 +8,8 @@
 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)]
@@ -42,10 +42,14 @@ module StgInterp (
    - 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
@@ -56,19 +60,15 @@ import Literal              ( Literal(..) )
 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 )
@@ -77,37 +77,66 @@ import TyCon                ( TyCon, isDataTyCon, tyConDataCons, tyConFamilySize )
 import Class           ( Class, classTyCon )
 import InterpSyn
 import StgSyn
-import Addr
-import RdrName         ( RdrName, rdrNameModule, rdrNameOcc, isUnqual )
 import FiniteMap
-import Panic           ( panic )
 import OccName         ( occNameString )
 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
@@ -152,7 +181,8 @@ rhs2expr ie (StgRhsClosure ccs binfo srt fvs uflag args rhs)
         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
 
@@ -160,7 +190,7 @@ conapp2expr :: UniqSet Id -> DataCon -> [StgArg] -> UnlinkedIExpr
 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
@@ -172,11 +202,9 @@ conapp2expr ie dcon 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
@@ -325,6 +353,8 @@ stg2expr ie stgexpr
                          bndr (stg2expr ie scrut) 
                               (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)
@@ -335,9 +365,9 @@ stg2expr ie stgexpr
                              (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
@@ -396,7 +426,7 @@ mkVar ie rep var
           RepF -> VarF
           RepD -> VarD
           RepP -> VarP)  var
-  | otherwise = Native (toRdrName var)
+  | otherwise = Native (getName var)
 
 mkRec RepI = RecI
 mkRec RepP = RecP
@@ -423,6 +453,11 @@ id2VaaRep var = (var, repOfId var)
 -- 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)]
@@ -430,14 +465,18 @@ linkIModules :: ItblEnv    -- incoming global itbl env; returned updated
 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)
 
@@ -448,76 +487,65 @@ linkIModules gie gce mods = do
 -- 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)
-
-   CaseAlgF  bndr expr alts dflt ->
-       CaseAlgF bndr (linkIExpr ie ce expr) (linkAlgAlts ie ce alts)
-                       (linkDefault ie ce dflt)
-
-   CaseAlgD  bndr expr alts dflt ->
-       CaseAlgD 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)
    
-   CasePrimF bndr expr alts dflt ->
-       CasePrimF bndr (linkIExpr ie ce expr) (linkPrimAlts ie ce alts)
-                       (linkDefault ie ce dflt)
+   PrimOpI op args -> linkPrimOp ie ce PrimOpI op args
+   PrimOpP op args -> linkPrimOp ie ce PrimOpP op args
    
-   CasePrimD bndr expr alts dflt ->
-       CasePrimD bndr (linkIExpr ie ce expr) (linkPrimAlts ie ce alts)
-                       (linkDefault ie ce dflt)
-   
-   ConApp con -> 
-       lookupNullaryCon ie con
-
-   ConAppI   con arg0 -> 
-       ConAppI (lookupCon ie con) (linkIExpr ie ce arg0)
+   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
 
-   ConAppP   con arg0 ->
-       ConAppP (lookupCon ie con) (linkIExpr ie ce arg0)
+   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
 
-   ConAppPP  con arg0 arg1 -> 
-       ConAppPP (lookupCon ie con) (linkIExpr ie ce arg0) (linkIExpr ie ce arg1)
-   ConAppGen con args -> ConAppGen (lookupCon ie con) 
-                                       (map (linkIExpr ie ce) args)
-   
-   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)
-   NonRecI bind expr  -> NonRecI (linkIBind ie ce bind) (linkIExpr ie ce expr)
-   NonRecF bind expr  -> NonRecF (linkIBind ie ce bind) (linkIExpr ie ce expr)
-   NonRecD bind expr  -> NonRecD (linkIBind ie ce bind) (linkIExpr ie ce expr)
-
-   RecP    binds expr -> RecP (linkIBinds ie ce binds) (linkIExpr ie ce expr)
-   RecI    binds expr -> RecI (linkIBinds ie ce binds) (linkIExpr ie ce expr)
-   RecF    binds expr -> RecF (linkIBinds ie ce binds) (linkIExpr ie ce expr)
-   RecD    binds expr -> RecD (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
    
@@ -526,97 +554,141 @@ linkIExpr ie ce expr = case expr of
    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)
-   LamPF  bndr expr -> LamPF bndr (linkIExpr ie ce expr)
-   LamPD  bndr expr -> LamPD bndr (linkIExpr ie ce expr)
-   LamIP  bndr expr -> LamIP bndr (linkIExpr ie ce expr)
-   LamII  bndr expr -> LamII bndr (linkIExpr ie ce expr)
-   LamIF  bndr expr -> LamIF bndr (linkIExpr ie ce expr)
-   LamID  bndr expr -> LamID bndr (linkIExpr ie ce expr)
-   LamFP  bndr expr -> LamFP bndr (linkIExpr ie ce expr)
-   LamFI  bndr expr -> LamFI bndr (linkIExpr ie ce expr)
-   LamFF  bndr expr -> LamFF bndr (linkIExpr ie ce expr)
-   LamFD  bndr expr -> LamFD bndr (linkIExpr ie ce expr)
-   LamDP  bndr expr -> LamDP bndr (linkIExpr ie ce expr)
-   LamDI  bndr expr -> LamDI bndr (linkIExpr ie ce expr)
-   LamDF  bndr expr -> LamDF bndr (linkIExpr ie ce expr)
-   LamDD  bndr expr -> LamDD 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)
-   AppPF  fun arg -> AppPF (linkIExpr ie ce fun) (linkIExpr ie ce arg)
-   AppPD  fun arg -> AppPD (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)
-   AppIF  fun arg -> AppIF (linkIExpr ie ce fun) (linkIExpr ie ce arg)
-   AppID  fun arg -> AppID (linkIExpr ie ce fun) (linkIExpr ie ce arg)
-   AppFP  fun arg -> AppFP (linkIExpr ie ce fun) (linkIExpr ie ce arg)
-   AppFI  fun arg -> AppFI (linkIExpr ie ce fun) (linkIExpr ie ce arg)
-   AppFF  fun arg -> AppFF (linkIExpr ie ce fun) (linkIExpr ie ce arg)
-   AppFD  fun arg -> AppFD (linkIExpr ie ce fun) (linkIExpr ie ce arg)
-   AppDP  fun arg -> AppDP (linkIExpr ie ce fun) (linkIExpr ie ce arg)
-   AppDI  fun arg -> AppDI (linkIExpr ie ce fun) (linkIExpr ie ce arg)
-   AppDF  fun arg -> AppDF (linkIExpr ie ce fun) (linkIExpr ie ce arg)
-   AppDD  fun arg -> AppDD (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.
-       case {-HACK!!!-}
-               unsafePerformIO (lookupSymbol (rdrNameToCLabel con "con_info")) of
-           Just addr -> addr
-           Nothing   -> pprPanic "linkIExpr" (ppr con)
+        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) -> ConApp addr
-    Nothing -> 
+    Just (Ptr addr) -> return (ConApp addr)
+    Nothing -> do
        -- try looking up in the object files.
-       case {-HACK!!!-}
-               unsafePerformIO (lookupSymbol (rdrNameToCLabel con "closure")) of
-           Just (A# addr) -> Native (unsafeCoerce# addr)
+       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
-  | isUnqual rn = pprPanic "rdrNameToCLabel" (ppr rn)
-  | otherwise =
+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
@@ -730,20 +802,32 @@ evalP (ConAppPP (A# itbl) a1 a2) de
      in  mci_make_constrPP itbl p1 p2
 
 evalP (ConAppGen itbl args) de
-   = loop args
+   = let c = case itbl of A# a# -> mci_make_constr a# in
+     c `seq` loop c 1#{-leave room for hdr-} args
      where
-        -- This appalling hack suggested (gleefully) by SDM
-        -- It is not well typed (needless to say?)
-        loop :: [LinkedIExpr] -> boxed
-        loop [] 
-           = case itbl of A# addr# -> unsafeCoerce# (mci_make_constr addr#)
-        loop (a:as) 
+        loop :: a{-closure-} -> Int# -> [LinkedIExpr] -> a
+        loop c off [] = c
+        loop c off (a:as)
            = case repOf a of
-                RepP -> let p = evalP a de in loop as p
-                RepI -> case evalI a de of i# -> loop as i#
-               RepF -> case evalF a de of f# -> loop as f#
-               RepD -> case evalD a de of d# -> loop as d#
-
+                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)
 
@@ -799,6 +883,10 @@ evalI (CasePrimI bndr expr alts def) de
 
 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))
@@ -1104,6 +1192,9 @@ select_altPrim ((AltPrim lit rhs):alts) def literal
 
 eqLits (LitI i1#) (LitI i2#) = i1# ==# i2#
 
+-- ----------------------------------------------------------------------
+-- Grotty inspection and creation of closures
+-- ----------------------------------------------------------------------
 
 -- a is a constructor
 indexPtrOffClosure :: a -> Int -> b
@@ -1116,7 +1207,24 @@ indexIntOffClosure con (I# offset)
 
 indexFloatOffClosure :: a -> Int -> Float#
 indexFloatOffClosure con (I# offset)
-   = unsafeCoerce# (indexWordOffClosure# con offset) -- eek!
+   = 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 ---
@@ -1165,7 +1273,7 @@ make_constr_itbls cons
         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)
@@ -1196,11 +1304,11 @@ make_constr_itbls cons
                  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
@@ -1311,5 +1419,7 @@ load addr = do x <- peek addr
 -----------------------------------------------------------------------------q
 
 foreign import "strncpy" strncpy :: Ptr a -> ByteArray# -> CInt -> IO ()
+#endif
+
 \end{code}