Make various assertions work when !DEBUG
[ghc-hetmet.git] / compiler / main / GHC.hs
index a04c06c..f1c7b88 100644 (file)
@@ -15,10 +15,11 @@ module GHC (
 
        -- * Flags and settings
        DynFlags(..), DynFlag(..), Severity(..), HscTarget(..), dopt,
-        GhcMode(..), GhcLink(..),
+        GhcMode(..), GhcLink(..), defaultObjectTarget,
        parseDynamicFlags,
        getSessionDynFlags,
        setSessionDynFlags,
+        parseStaticFlags,
 
        -- * Targets
        Target(..), TargetId(..), Phase,
@@ -40,6 +41,7 @@ module GHC (
        workingDirectoryChanged,
        checkModule, CheckedModule(..),
        TypecheckedSource, ParsedSource, RenamedSource,
+        compileToCore,
 
        -- * Parsing Haddock comments
        parseHaddockComment,
@@ -55,12 +57,12 @@ module GHC (
        getModuleInfo,
        modInfoTyThings,
        modInfoTopLevelScope,
-       modInfoPrintUnqualified,
-       modInfoExports,
+        modInfoExports,
        modInfoInstances,
        modInfoIsExportedName,
        modInfoLookupName,
        lookupGlobalName,
+        mkPrintUnqualifiedForModule,
 
        -- * Printing
        PrintUnqualified, alwaysQualify,
@@ -77,17 +79,26 @@ module GHC (
        exprType,
        typeKind,
        parseName,
-       RunResult(..),  ResumeHandle,
-       runStmt,
+       RunResult(..),  
+       runStmt, SingleStep(..),
         resume,
+        Resume(resumeStmt, resumeThreadId, resumeBreakInfo, resumeSpan,
+               resumeHistory, resumeHistoryIx),
+        History(historyBreakInfo, historyEnclosingDecl), 
+        GHC.getHistorySpan, getHistoryModule,
+        getResumeContext,
+        abandon, abandonAll,
+        InteractiveEval.back,
+        InteractiveEval.forward,
        showModule,
         isModuleInterpreted,
        compileExpr, HValue, dynCompileExpr,
        lookupName,
-        obtainTerm, obtainTerm1,
+        GHC.obtainTerm, GHC.obtainTerm1, GHC.obtainTermB, reconstructType,
+        modInfoModBreaks,
         ModBreaks(..), BreakIndex,
         BreakInfo(breakInfo_number, breakInfo_module),
-        modInfoModBreaks, 
+        BreakArray, setBreakOn, setBreakOff, getBreak,
 #endif
 
        -- * Abstract syntax elements
@@ -101,7 +112,7 @@ module GHC (
 
        -- ** Names
        Name, 
-       nameModule, pprParenSymName, nameSrcLoc,
+       isExternalName, nameModule, pprParenSymName, nameSrcSpan,
        NamedThing(..),
        RdrName(Qual,Unqual),
        
@@ -163,6 +174,14 @@ module GHC (
 
        -- ** Source locations
        SrcLoc, pprDefnLoc,
+        mkSrcLoc, isGoodSrcLoc, noSrcLoc,
+       srcLocFile, srcLocLine, srcLocCol,
+        SrcSpan,
+        mkSrcSpan, srcLocSpan, isGoodSrcSpan, noSrcSpan,
+        srcSpanStart, srcSpanEnd,
+       srcSpanFile, 
+        srcSpanStartLine, srcSpanEndLine, 
+        srcSpanStartCol, srcSpanEndCol,
 
        -- * Exceptions
        GhcException(..), showGhcException,
@@ -182,22 +201,13 @@ module GHC (
 #include "HsVersions.h"
 
 #ifdef GHCI
-import RtClosureInspect ( cvObtainTerm, Term )
-import TcRnDriver      ( tcRnLookupRdrName, tcRnGetInfo,
-                         tcRnLookupName, getModuleExports )
-import VarEnv          ( emptyTidyEnv )
-import GHC.Exts         ( unsafeCoerce#, Ptr )
-import Foreign.StablePtr( deRefStablePtr, StablePtr, newStablePtr, freeStablePtr )
-import Foreign          ( poke )
 import qualified Linker
-
-import Data.Dynamic     ( Dynamic )
-import Linker          ( HValue, getHValue, extendLinkEnv )
-
+import Linker           ( HValue )
 import ByteCodeInstr
-import DebuggerTys
-import IdInfo
-import HscMain          ( hscParseIdentifier, hscTcExpr, hscKcType, hscStmt )
+import BreakArray
+import NameSet
+import TcRnDriver
+import InteractiveEval
 #endif
 
 import Packages
@@ -205,6 +215,7 @@ import NameSet
 import RdrName
 import HsSyn 
 import Type             hiding (typeKind)
+import TcType           hiding (typeKind)
 import Id
 import Var              hiding (setIdType)
 import TysPrim         ( alphaTyVars )
@@ -214,20 +225,23 @@ import FunDeps
 import DataCon
 import Name             hiding ( varName )
 import OccName         ( parenSymOcc )
-import NameEnv
 import InstEnv         ( Instance, instanceDFunId, pprInstance, pprInstanceHdr )
 import SrcLoc
+import CoreSyn
 import DriverPipeline
-import DriverPhases    ( Phase(..), isHaskellSrcFilename, startPhase )
+import DriverPhases    ( HscSource(..), Phase(..), isHaskellSrcFilename, startPhase )
 import HeaderInfo      ( getImports, getOptions )
 import Finder
 import HscMain          ( newHscEnv, hscFileCheck, HscChecked(..) )
 import HscTypes
 import DynFlags
+import StaticFlags
 import SysTools     ( initSysTools, cleanTempFiles, cleanTempFilesExcept,
                       cleanTempDirs )
 import Module
 import UniqFM
+import UniqSet
+import Unique
 import PackageConfig
 import FiniteMap
 import Panic
@@ -241,7 +255,6 @@ import Util
 import StringBuffer    ( StringBuffer, hGetStringBuffer )
 import Outputable
 import BasicTypes
-import TcType           ( tcSplitSigmaTy, isDictTy )
 import Maybes          ( expectJust, mapCatMaybes )
 import HaddockParse
 import HaddockLex       ( tokenise )
@@ -257,14 +270,9 @@ import System.Time ( ClockTime )
 import Control.Exception as Exception hiding (handle)
 import Data.IORef
 import System.IO
-import System.IO.Error ( isDoesNotExistError )
+import System.IO.Error ( try, isDoesNotExistError )
 import Prelude hiding (init)
 
-#if __GLASGOW_HASKELL__ < 600
-import System.IO as System.IO.Error ( try )
-#else
-import System.IO.Error ( try )
-#endif
 
 -- -----------------------------------------------------------------------------
 -- Exception handlers
@@ -321,12 +329,6 @@ defaultCleanupHandler dflags inner =
     inner
 
 
-#if defined(GHCI) 
-GLOBAL_VAR(v_bkptLinkEnv, [], [(Name, HValue)])
-        -- stores the current breakpoint handler to help setContext to
-        -- restore it after a context change
-#endif
-
 -- | Starts a new session.  A session consists of a set of loaded
 -- modules, a set of options (DynFlags), and an interactive context.
 newSession :: Maybe FilePath -> IO Session
@@ -336,6 +338,7 @@ newSession mb_top_dir = do
   modifyMVar_ interruptTargetThread (return . (main_thread :))
   installSignalHandlers
 
+  initStaticOpts
   dflags0 <- initSysTools mb_top_dir defaultDynFlags
   dflags  <- initDynFlags dflags0
   env <- newHscEnv dflags
@@ -347,12 +350,6 @@ newSession mb_top_dir = do
 sessionHscEnv :: Session -> IO HscEnv
 sessionHscEnv (Session ref) = readIORef ref
 
-withSession :: Session -> (HscEnv -> IO a) -> IO a
-withSession (Session ref) f = do h <- readIORef ref; f h
-
-modifySession :: Session -> (HscEnv -> HscEnv) -> IO ()
-modifySession (Session ref) f = do h <- readIORef ref; writeIORef ref $! f h
-
 -- -----------------------------------------------------------------------------
 -- Flags & settings
 
@@ -494,7 +491,6 @@ depanal (Session ref) excluded_mods allow_dup_roots = do
   hsc_env <- readIORef ref
   let
         dflags  = hsc_dflags hsc_env
-        gmode   = ghcMode (hsc_dflags hsc_env)
         targets = hsc_targets hsc_env
         old_graph = hsc_mod_graph hsc_env
        
@@ -541,17 +537,24 @@ load s@(Session ref) how_much
        -- graph is still retained in the Session.  We can tell which modules
        -- were successfully loaded by inspecting the Session's HPT.
        mb_graph <- depanal s [] False
-       case mb_graph of           
-          Just mod_graph -> load2 s how_much mod_graph 
+       case mb_graph of
+          Just mod_graph -> catchingFailure $ load2 s how_much mod_graph
           Nothing        -> return Failed
-
+    where catchingFailure f = f `Exception.catch` \e -> do
+              hsc_env <- readIORef ref
+              -- trac #1565 / test ghci021:
+              -- let bindings may explode if we try to use them after
+              -- failing to reload
+              writeIORef ref $! hsc_env{ hsc_IC = emptyInteractiveContext }
+              throw e
+
+load2 :: Session -> LoadHowMuch -> [ModSummary] -> IO SuccessFlag
 load2 s@(Session ref) how_much mod_graph = do
         guessOutputFile s
        hsc_env <- readIORef ref
 
         let hpt1      = hsc_HPT hsc_env
         let dflags    = hsc_dflags hsc_env
-        let ghci_mode = ghcMode dflags -- this never changes
 
        -- The "bad" boot modules are the ones for which we have
        -- B.hs-boot in the module graph, but no B.hs
@@ -559,10 +562,8 @@ load2 s@(Session ref) how_much mod_graph = do
        -- (see msDeps)
         let all_home_mods = [ms_mod_name s 
                            | s <- mod_graph, not (isBootSummary s)]
-#ifdef DEBUG
            bad_boot_mods = [s        | s <- mod_graph, isBootSummary s,
                                        not (ms_mod_name s `elem` all_home_mods)]
-#endif
        ASSERT( null bad_boot_mods ) return ()
 
         -- mg2_with_srcimps drops the hi-boot nodes, returning a 
@@ -631,9 +632,9 @@ load2 s@(Session ref) how_much mod_graph = do
            -- short of the specified module (unless the specified module
            -- is stable).
            partial_mg
-               | LoadDependenciesOf mod <- how_much
+               | LoadDependenciesOf _mod <- how_much
                = ASSERT( case last partial_mg0 of 
-                           AcyclicSCC ms -> ms_mod_name ms == mod; _ -> False )
+                           AcyclicSCC ms -> ms_mod_name ms == _mod; _ -> False )
                  List.init partial_mg0
                | otherwise
                = partial_mg0
@@ -735,7 +736,8 @@ load2 s@(Session ref) how_much mod_graph = do
 -- Finish up after a load.
 
 -- If the link failed, unload everything and return.
-loadFinish all_ok Failed ref hsc_env
+loadFinish :: SuccessFlag -> SuccessFlag -> IORef HscEnv -> HscEnv -> IO SuccessFlag
+loadFinish _all_ok Failed ref hsc_env
   = do unload hsc_env []
        writeIORef ref $! discardProg hsc_env
        return Failed
@@ -757,6 +759,7 @@ discardProg hsc_env
 -- used to fish out the preprocess output files for the purposes of
 -- cleaning up.  The preprocessed file *might* be the same as the
 -- source file, but that doesn't do any harm.
+ppFilesFromSummaries :: [ModSummary] -> [FilePath]
 ppFilesFromSummaries summaries = map ms_hspp_file summaries
 
 -- -----------------------------------------------------------------------------
@@ -766,7 +769,8 @@ data CheckedModule =
   CheckedModule { parsedSource      :: ParsedSource,
                  renamedSource     :: Maybe RenamedSource,
                  typecheckedSource :: Maybe TypecheckedSource,
-                 checkedModuleInfo :: Maybe ModuleInfo
+                 checkedModuleInfo :: Maybe ModuleInfo,
+                  coreBinds         :: Maybe [CoreBind]
                }
        -- ToDo: improvements that could be made here:
        --  if the module succeeded renaming but not typechecking,
@@ -793,32 +797,33 @@ type TypecheckedSource = LHsBinds Id
 
 
 -- | This is the way to get access to parsed and typechecked source code
--- for a module.  'checkModule' loads all the dependencies of the specified
--- module in the Session, and then attempts to typecheck the module.  If
+-- for a module.  'checkModule' attempts to typecheck the module.  If
 -- successful, it returns the abstract syntax for the module.
-checkModule :: Session -> ModuleName -> IO (Maybe CheckedModule)
-checkModule session@(Session ref) mod = do
-       -- load up the dependencies first
-   r <- load session (LoadDependenciesOf mod)
-   if (failed r) then return Nothing else do
-
-       -- now parse & typecheck the module
+-- If compileToCore is true, it also desugars the module and returns the 
+-- resulting Core bindings as a component of the CheckedModule.
+checkModule :: Session -> ModuleName -> Bool -> IO (Maybe CheckedModule)
+checkModule (Session ref) mod compileToCore = do
+       -- parse & typecheck the module
    hsc_env <- readIORef ref   
    let mg  = hsc_mod_graph hsc_env
    case [ ms | ms <- mg, ms_mod_name ms == mod ] of
        [] -> return Nothing
        (ms:_) -> do 
-          mbChecked <- hscFileCheck hsc_env{hsc_dflags=ms_hspp_opts ms} ms
+          mbChecked <- hscFileCheck 
+                          hsc_env{hsc_dflags=ms_hspp_opts ms} 
+                          ms compileToCore
           case mbChecked of
              Nothing -> return Nothing
-             Just (HscChecked parsed renamed Nothing) ->
+             Just (HscChecked parsed renamed Nothing _) ->
                   return (Just (CheckedModule {
                                        parsedSource = parsed,
                                        renamedSource = renamed,
                                        typecheckedSource = Nothing,
-                                       checkedModuleInfo = Nothing }))
+                                       checkedModuleInfo = Nothing,
+                                        coreBinds = Nothing }))
              Just (HscChecked parsed renamed
-                          (Just (tc_binds, rdr_env, details))) -> do
+                          (Just (tc_binds, rdr_env, details))
+                           maybeCoreBinds) -> do
                   let minf = ModuleInfo {
                                minf_type_env  = md_types details,
                                minf_exports   = availsToNameSet $
@@ -833,9 +838,34 @@ checkModule session@(Session ref) mod = do
                                        parsedSource = parsed,
                                        renamedSource = renamed,
                                        typecheckedSource = Just tc_binds,
-                                       checkedModuleInfo = Just minf }))
-
--- ---------------------------------------------------------------------------
+                                       checkedModuleInfo = Just minf,
+                                        coreBinds = maybeCoreBinds}))
+
+-- | This is the way to get access to the Core bindings corresponding
+-- to a module. 'compileToCore' invokes 'checkModule' to parse, typecheck, and
+-- desugar the module, then returns the resulting list of Core bindings if 
+-- successful. 
+compileToCore :: Session -> FilePath -> IO (Maybe [CoreBind])
+compileToCore session fn = do
+   -- First, set the target to the desired filename
+   target <- guessTarget fn Nothing
+   addTarget session target
+   load session LoadAllTargets
+   -- Then find dependencies
+   maybeModGraph <- depanal session [] True
+   case maybeModGraph of
+     Nothing -> return Nothing
+     Just modGraph -> do
+        let modSummary = expectJust "compileToCore" $
+                          find ((== fn) . msHsFilePath) modGraph
+        -- Now we have the module name;
+        -- parse, typecheck and desugar the module
+        let mod = ms_mod_name modSummary
+        maybeCheckedModule <- checkModule session mod True
+        case maybeCheckedModule of
+             Nothing -> return Nothing 
+             Just checkedMod -> return $ coreBinds checkedMod
+ -- ---------------------------------------------------------------------------
 -- Unloading
 
 unload :: HscEnv -> [Linkable] -> IO ()
@@ -845,8 +875,10 @@ unload hsc_env stable_linkables    -- Unload everthing *except* 'stable_linkables'
        LinkInMemory -> Linker.unload (hsc_dflags hsc_env) stable_linkables
 #else
        LinkInMemory -> panic "unload: no interpreter"
+                                -- urgh.  avoid warnings:
+                                hsc_env stable_linkables
 #endif
-       other -> return ()
+       _other -> return ()
 
 -- -----------------------------------------------------------------------------
 -- checkStability
@@ -1002,7 +1034,7 @@ findPartiallyCompletedCycles modsDone theGraph
    = chew theGraph
      where
         chew [] = []
-        chew ((AcyclicSCC v):rest) = chew rest    -- acyclic?  not interesting.
+        chew ((AcyclicSCC _):rest) = chew rest    -- acyclic?  not interesting.
         chew ((CyclicSCC vs):rest)
            = let names_in_this_cycle = nub (map ms_mod vs)
                  mods_in_this_cycle  
@@ -1035,17 +1067,18 @@ upsweep
 
 upsweep hsc_env old_hpt stable_mods cleanup mods
    = upsweep' hsc_env old_hpt stable_mods cleanup mods 1 (length mods)
+ where
 
-upsweep' hsc_env old_hpt stable_mods cleanup
+  upsweep' hsc_env _old_hpt _stable_mods _cleanup
      [] _ _
    = return (Succeeded, hsc_env, [])
 
-upsweep' hsc_env old_hpt stable_mods cleanup
+  upsweep' hsc_env _old_hpt _stable_mods _cleanup
      (CyclicSCC ms:_) _ _
    = do fatalErrorMsg (hsc_dflags hsc_env) (cyclicModuleErr ms)
         return (Failed, hsc_env, [])
 
-upsweep' hsc_env old_hpt stable_mods cleanup
+  upsweep' hsc_env old_hpt stable_mods cleanup
      (AcyclicSCC mod:mods) mod_index nmods
    = do -- putStrLn ("UPSWEEP_MOD: hpt = " ++ 
        --           show (map (moduleUserString.moduleName.mi_module.hm_iface) 
@@ -1142,11 +1175,11 @@ upsweep_mod hsc_env old_hpt (stable_obj, stable_bco) summary mod_index nmods
                                     iface = hm_iface hm_info
 
            compile_it :: Maybe Linkable -> IO (Maybe HomeModInfo)
-           compile_it  = upsweep_compile hsc_env old_hpt this_mod_name 
+           compile_it  = upsweep_compile hsc_env
                                summary' mod_index nmods mb_old_iface
 
             compile_it_discard_iface 
-                        = upsweep_compile hsc_env old_hpt this_mod_name 
+                        = upsweep_compile hsc_env
                                summary' mod_index nmods Nothing
 
         in
@@ -1210,10 +1243,9 @@ upsweep_mod hsc_env old_hpt (stable_obj, stable_bco) summary mod_index nmods
 
 
 -- Run hsc to compile a module
-upsweep_compile hsc_env old_hpt this_mod summary
-                mod_index nmods
-                mb_old_iface
-                mb_old_linkable
+upsweep_compile :: HscEnv -> ModSummary -> Int -> Int
+                -> Maybe ModIface -> Maybe Linkable -> IO (Maybe HomeModInfo)
+upsweep_compile hsc_env summary mod_index nmods mb_old_iface mb_old_linkable
  = do
    compresult <- compile hsc_env summary mb_old_linkable mb_old_iface
                         mod_index nmods
@@ -1337,9 +1369,6 @@ mkNodeMap summaries = listToFM [ (msKey s, s) | s <- summaries]
 nodeMapElts :: NodeMap a -> [a]
 nodeMapElts = eltsFM
 
-ms_mod_name :: ModSummary -> ModuleName
-ms_mod_name = moduleName . ms_mod
-
 -- If there are {-# SOURCE #-} imports between strongly connected
 -- components in the topological sort, then those imports can
 -- definitely be replaced by ordinary non-SOURCE imports: if SOURCE
@@ -1349,11 +1378,11 @@ warnUnnecessarySourceImports dflags sccs =
   printBagOfWarnings dflags (listToBag (concat (map (check.flattenSCC) sccs)))
   where check ms =
           let mods_in_this_cycle = map ms_mod_name ms in
-          [ warn m i | m <- ms, i <- ms_srcimps m,
+          [ warn i | m <- ms, i <- ms_srcimps m,
                        unLoc i `notElem`  mods_in_this_cycle ]
 
-       warn :: ModSummary -> Located ModuleName -> WarnMsg
-       warn ms (L loc mod) = 
+       warn :: Located ModuleName -> WarnMsg
+       warn (L loc mod) = 
           mkPlainErrMsg loc
                (ptext SLIT("Warning: {-# SOURCE #-} unnecessary in import of ")
                 <+> quotes (ppr mod))
@@ -1553,7 +1582,7 @@ findSummaryBySourceFile summaries file
   = case [ ms | ms <- summaries, HsSrcFile <- [ms_hsc_src ms],
                                 expectJust "findSummaryBySourceFile" (ml_hs_file (ms_location ms)) == file ] of
        [] -> Nothing
-       (x:xs) -> Just x
+       (x:_) -> Just x
 
 -- Summarise a module, and pick up source and timestamp.
 summariseModule
@@ -1665,6 +1694,7 @@ summariseModule hsc_env old_summary_map is_boot (L loc wanted_mod) maybe_buf exc
                                    ms_obj_date  = obj_timestamp }))
 
 
+getObjTimestamp :: ModLocation -> Bool -> IO (Maybe ClockTime)
 getObjTimestamp location is_boot
   = if is_boot then return Nothing
               else modificationTimeIfExists (ml_obj_file location)
@@ -1678,13 +1708,14 @@ preprocessFile dflags src_fn mb_phase Nothing
        buf <- hGetStringBuffer hspp_fn
        return (dflags', hspp_fn, buf)
 
-preprocessFile dflags src_fn mb_phase (Just (buf, time))
+preprocessFile dflags src_fn mb_phase (Just (buf, _time))
   = do
        -- case we bypass the preprocessing stage?
        let 
            local_opts = getOptions buf src_fn
        --
-       (dflags', errs) <- parseDynamicFlags dflags (map unLoc local_opts)
+       (dflags', _errs) <- parseDynamicFlags dflags (map unLoc local_opts)
+        -- XXX: shouldn't we be reporting the errors?
 
        let
            needs_preprocessing
@@ -1710,14 +1741,17 @@ noModError :: DynFlags -> SrcSpan -> ModuleName -> FindResult -> IO ab
 noModError dflags loc wanted_mod err
   = throwDyn $ mkPlainErrMsg loc $ cannotFindModule dflags wanted_mod err
                                
+noHsFileErr :: SrcSpan -> String -> a
 noHsFileErr loc path
   = throwDyn $ mkPlainErrMsg loc $ text "Can't find" <+> text path
  
+packageModErr :: ModuleName -> a
 packageModErr mod
   = throwDyn $ mkPlainErrMsg noSrcSpan $
        text "module" <+> quotes (ppr mod) <+> text "is a package module"
 
 multiRootsErr :: [ModSummary] -> IO ()
+multiRootsErr [] = panic "multiRootsErr"
 multiRootsErr summs@(summ1:_)
   = throwDyn $ mkPlainErrMsg noSrcSpan $
        text "module" <+> quotes (ppr mod) <+> 
@@ -1759,10 +1793,22 @@ isLoaded s m = withSession s $ \hsc_env ->
   return $! isJust (lookupUFM (hsc_HPT hsc_env) m)
 
 getBindings :: Session -> IO [TyThing]
-getBindings s = withSession s (return . nameEnvElts . ic_type_env . hsc_IC)
+getBindings s = withSession s $ \hsc_env ->
+   -- we have to implement the shadowing behaviour of ic_tmp_ids here
+   -- (see InteractiveContext) and the quickest way is to use an OccEnv.
+   let 
+       tmp_ids = ic_tmp_ids (hsc_IC hsc_env)
+       filtered = foldr f (const []) tmp_ids emptyUniqSet
+       f id rest set 
+           | uniq `elementOfUniqSet` set = rest set
+           | otherwise  = AnId id : rest (addOneToUniqSet set uniq)
+           where uniq = getUnique (nameOccName (idName id))
+   in
+   return filtered
 
 getPrintUnqual :: Session -> IO PrintUnqualified
-getPrintUnqual s = withSession s (return . icPrintUnqual . hsc_IC)
+getPrintUnqual s = withSession s $ \hsc_env ->
+  return (icPrintUnqual (hsc_dflags hsc_env) (hsc_IC hsc_env))
 
 -- | Container for information about a 'Module'.
 data ModuleInfo = ModuleInfo {
@@ -1794,8 +1840,8 @@ getModuleInfo s mdl = withSession s $ \hsc_env -> do
    -- exist... hence the isHomeModule test here.  (ToDo: reinstate)
 
 getPackageModuleInfo :: HscEnv -> Module -> IO (Maybe ModuleInfo)
-getPackageModuleInfo hsc_env mdl = do
 #ifdef GHCI
+getPackageModuleInfo hsc_env mdl = do
   (_msgs, mb_avails) <- getModuleExports hsc_env mdl
   case mb_avails of
     Nothing -> return Nothing
@@ -1815,10 +1861,12 @@ getPackageModuleInfo hsc_env mdl = do
                         minf_modBreaks = emptyModBreaks  
                }))
 #else
+getPackageModuleInfo _hsc_env _mdl = do
   -- bogusly different for non-GHCI (ToDo)
   return Nothing
 #endif
 
+getHomeModuleInfo :: HscEnv -> ModuleName -> IO (Maybe ModuleInfo)
 getHomeModuleInfo hsc_env mdl = 
   case lookupUFM (hsc_HPT hsc_env) mdl of
     Nothing  -> return Nothing
@@ -1830,7 +1878,7 @@ getHomeModuleInfo hsc_env mdl =
                        minf_rdr_env   = mi_globals $! hm_iface hmi,
                        minf_instances = md_insts details
 #ifdef GHCI
-                       ,minf_modBreaks = md_modBreaks details  
+                       ,minf_modBreaks = getModBreaks hmi
 #endif
                        }))
 
@@ -1853,8 +1901,9 @@ modInfoInstances = minf_instances
 modInfoIsExportedName :: ModuleInfo -> Name -> Bool
 modInfoIsExportedName minf name = elemNameSet name (minf_exports minf)
 
-modInfoPrintUnqualified :: ModuleInfo -> Maybe PrintUnqualified
-modInfoPrintUnqualified minf = fmap mkPrintUnqualified (minf_rdr_env minf)
+mkPrintUnqualifiedForModule :: Session -> ModuleInfo -> IO (Maybe PrintUnqualified)
+mkPrintUnqualifiedForModule s minf = withSession s $ \hsc_env -> do
+  return (fmap (mkPrintUnqualified (hsc_dflags hsc_env)) (minf_rdr_env minf))
 
 modInfoLookupName :: Session -> ModuleInfo -> Name -> IO (Maybe TyThing)
 modInfoLookupName s minf name = withSession s $ \hsc_env -> do
@@ -1866,12 +1915,13 @@ modInfoLookupName s minf name = withSession s $ \hsc_env -> do
                            (hsc_HPT hsc_env) (eps_PTE eps) name
 
 #ifdef GHCI
+modInfoModBreaks :: ModuleInfo -> ModBreaks
 modInfoModBreaks = minf_modBreaks  
 #endif
 
 isDictonaryId :: Id -> Bool
 isDictonaryId id
-  = case tcSplitSigmaTy (idType id) of { (tvs, theta, tau) -> isDictTy tau }
+  = case tcSplitSigmaTy (idType id) of { (_tvs, _theta, tau) -> isDictTy tau }
 
 -- | Looks up a global name: that is, any top-level name in any
 -- visible module.  Unlike 'lookupName', lookupGlobalName does not use
@@ -1923,9 +1973,6 @@ getTokenStream :: Session -> Module -> IO [Located Token]
 -- using the algorithm that is used for an @import@ declaration.
 findModule :: Session -> ModuleName -> Maybe PackageId -> IO Module
 findModule s mod_name maybe_pkg = withSession s $ \hsc_env ->
-  findModule' hsc_env mod_name maybe_pkg
-
-findModule' hsc_env mod_name maybe_pkg =
   let
         dflags = hsc_dflags hsc_env
         hpt    = hsc_HPT hsc_env
@@ -1944,392 +1991,20 @@ findModule' hsc_env mod_name maybe_pkg =
                   throwDyn (CmdLineError (showSDoc msg))
 
 #ifdef GHCI
+getHistorySpan :: Session -> History -> IO SrcSpan
+getHistorySpan sess h = withSession sess $ \hsc_env -> 
+                          return$ InteractiveEval.getHistorySpan hsc_env h
 
--- | Set the interactive evaluation context.
---
--- Setting the context doesn't throw away any bindings; the bindings
--- we've built up in the InteractiveContext simply move to the new
--- module.  They always shadow anything in scope in the current context.
-setContext :: Session
-          -> [Module]  -- entire top level scope of these modules
-          -> [Module]  -- exports only of these modules
-          -> IO ()
-setContext sess@(Session ref) toplev_mods export_mods = do 
-  hsc_env <- readIORef ref
-  let old_ic  = hsc_IC     hsc_env
-      hpt     = hsc_HPT    hsc_env
-  --
-  export_env  <- mkExportEnv hsc_env export_mods
-  toplev_envs <- mapM (mkTopLevEnv hpt) toplev_mods
-  let all_env = foldr plusGlobalRdrEnv export_env toplev_envs
-  writeIORef ref hsc_env{ hsc_IC = old_ic { ic_toplev_scope = toplev_mods,
-                                           ic_exports      = export_mods,
-                                           ic_rn_gbl_env   = all_env }}
-
--- Make a GlobalRdrEnv based on the exports of the modules only.
-mkExportEnv :: HscEnv -> [Module] -> IO GlobalRdrEnv
-mkExportEnv hsc_env mods = do
-  stuff <- mapM (getModuleExports hsc_env) mods
-  let 
-       (_msgs, mb_name_sets) = unzip stuff
-       gres = [ nameSetToGlobalRdrEnv (availsToNameSet avails) (moduleName mod)
-              | (Just avails, mod) <- zip mb_name_sets mods ]
-  --
-  return $! foldr plusGlobalRdrEnv emptyGlobalRdrEnv gres
-
-nameSetToGlobalRdrEnv :: NameSet -> ModuleName -> GlobalRdrEnv
-nameSetToGlobalRdrEnv names mod =
-  mkGlobalRdrEnv [ GRE  { gre_name = name, gre_prov = vanillaProv mod }
-                | name <- nameSetToList names ]
-
-vanillaProv :: ModuleName -> Provenance
--- We're building a GlobalRdrEnv as if the user imported
--- all the specified modules into the global interactive module
-vanillaProv mod_name = Imported [ImpSpec { is_decl = decl, is_item = ImpAll}]
-  where
-    decl = ImpDeclSpec { is_mod = mod_name, is_as = mod_name, 
-                        is_qual = False, 
-                        is_dloc = srcLocSpan interactiveSrcLoc }
-
-mkTopLevEnv :: HomePackageTable -> Module -> IO GlobalRdrEnv
-mkTopLevEnv hpt modl
-  = case lookupUFM hpt (moduleName modl) of
-      Nothing -> throwDyn (ProgramError ("mkTopLevEnv: not a home module " ++ 
-                                                showSDoc (ppr modl)))
-      Just details ->
-        case mi_globals (hm_iface details) of
-               Nothing  -> 
-                  throwDyn (ProgramError ("mkTopLevEnv: not interpreted " 
-                                               ++ showSDoc (ppr modl)))
-               Just env -> return env
-
--- | Get the interactive evaluation context, consisting of a pair of the
--- set of modules from which we take the full top-level scope, and the set
--- of modules from which we take just the exports respectively.
-getContext :: Session -> IO ([Module],[Module])
-getContext s = withSession s (\HscEnv{ hsc_IC=ic } ->
-                               return (ic_toplev_scope ic, ic_exports ic))
-
--- | Returns 'True' if the specified module is interpreted, and hence has
--- its full top-level scope available.
-moduleIsInterpreted :: Session -> Module -> IO Bool
-moduleIsInterpreted s modl = withSession s $ \h ->
- if modulePackageId modl /= thisPackage (hsc_dflags h)
-        then return False
-        else case lookupUFM (hsc_HPT h) (moduleName modl) of
-                Just details       -> return (isJust (mi_globals (hm_iface details)))
-                _not_a_home_module -> return False
-
--- | Looks up an identifier in the current interactive context (for :info)
-getInfo :: Session -> Name -> IO (Maybe (TyThing,Fixity,[Instance]))
-getInfo s name = withSession s $ \hsc_env -> tcRnGetInfo hsc_env name
-
--- | Returns all names in scope in the current interactive context
-getNamesInScope :: Session -> IO [Name]
-getNamesInScope s = withSession s $ \hsc_env -> do
-  return (map gre_name (globalRdrEnvElts (ic_rn_gbl_env (hsc_IC hsc_env))))
-
-getRdrNamesInScope :: Session -> IO [RdrName]
-getRdrNamesInScope  s = withSession s $ \hsc_env -> do
-  let env = ic_rn_gbl_env (hsc_IC hsc_env)
-  return (concat (map greToRdrNames (globalRdrEnvElts env)))
-
--- ToDo: move to RdrName
-greToRdrNames :: GlobalRdrElt -> [RdrName]
-greToRdrNames GRE{ gre_name = name, gre_prov = prov }
-  = case prov of
-     LocalDef -> [unqual]
-     Imported specs -> concat (map do_spec (map is_decl specs))
-  where
-    occ = nameOccName name
-    unqual = Unqual occ
-    do_spec decl_spec
-       | is_qual decl_spec = [qual]
-       | otherwise         = [unqual,qual]
-       where qual = Qual (is_as decl_spec) occ
-
--- | Parses a string as an identifier, and returns the list of 'Name's that
--- the identifier can refer to in the current interactive context.
-parseName :: Session -> String -> IO [Name]
-parseName s str = withSession s $ \hsc_env -> do
-   maybe_rdr_name <- hscParseIdentifier (hsc_dflags hsc_env) str
-   case maybe_rdr_name of
-       Nothing -> return []
-       Just (L _ rdr_name) -> do
-           mb_names <- tcRnLookupRdrName hsc_env rdr_name
-           case mb_names of
-               Nothing -> return []
-               Just ns -> return ns
-               -- ToDo: should return error messages
-
--- | Returns the 'TyThing' for a 'Name'.  The 'Name' may refer to any
--- entity known to GHC, including 'Name's defined using 'runStmt'.
-lookupName :: Session -> Name -> IO (Maybe TyThing)
-lookupName s name = withSession s $ \hsc_env -> tcRnLookupName hsc_env name
-
--- -----------------------------------------------------------------------------
--- Getting the type of an expression
-
--- | Get the type of an expression
-exprType :: Session -> String -> IO (Maybe Type)
-exprType s expr = withSession s $ \hsc_env -> do
-   maybe_stuff <- hscTcExpr hsc_env expr
-   case maybe_stuff of
-       Nothing -> return Nothing
-       Just ty -> return (Just tidy_ty)
-            where 
-               tidy_ty = tidyType emptyTidyEnv ty
-
--- -----------------------------------------------------------------------------
--- Getting the kind of a type
-
--- | Get the kind of a  type
-typeKind  :: Session -> String -> IO (Maybe Kind)
-typeKind s str = withSession s $ \hsc_env -> do
-   maybe_stuff <- hscKcType hsc_env str
-   case maybe_stuff of
-       Nothing -> return Nothing
-       Just kind -> return (Just kind)
-
------------------------------------------------------------------------------
--- cmCompileExpr: compile an expression and deliver an HValue
-
-compileExpr :: Session -> String -> IO (Maybe HValue)
-compileExpr s expr = withSession s $ \hsc_env -> do
-  maybe_stuff <- hscStmt hsc_env ("let __cmCompileExpr = "++expr)
-  case maybe_stuff of
-       Nothing -> return Nothing
-       Just (new_ic, names, hval) -> do
-                       -- Run it!
-               hvals <- (unsafeCoerce# hval) :: IO [HValue]
-
-               case (names,hvals) of
-                 ([n],[hv]) -> return (Just hv)
-                 _          -> panic "compileExpr"
-
--- -----------------------------------------------------------------------------
--- Compile an expression into a dynamic
-
-dynCompileExpr :: Session -> String -> IO (Maybe Dynamic)
-dynCompileExpr ses expr = do
-    (full,exports) <- getContext ses
-    setContext ses full $
-        (mkModule
-            (stringToPackageId "base") (mkModuleName "Data.Dynamic")
-        ):exports
-    let stmt = "let __dynCompileExpr = Data.Dynamic.toDyn (" ++ expr ++ ")"
-    res <- withSession ses (flip hscStmt stmt)
-    setContext ses full exports
-    case res of
-        Nothing -> return Nothing
-        Just (_, names, hvals) -> do
-            vals <- (unsafeCoerce# hvals :: IO [Dynamic])
-            case (names,vals) of
-                (_:[], v:[])    -> return (Just v)
-                _               -> panic "dynCompileExpr"
-
--- -----------------------------------------------------------------------------
--- running a statement interactively
-
-data RunResult
-  = RunOk [Name]               -- ^ names bound by this evaluation
-  | RunFailed                  -- ^ statement failed compilation
-  | RunException Exception     -- ^ statement raised an exception
-  | RunBreak ThreadId [Name] BreakInfo ResumeHandle
-
-data Status
-   = Break HValue BreakInfo ThreadId ResumeHandle -- ^ the computation hit a breakpoint
-   | Complete (Either Exception [HValue]) -- ^ the computation completed with either an exception or a value
-
-data ResumeHandle = ResumeHandle (MVar ()) (MVar Status) [Name]
-
--- | Run a statement in the current interactive context.  Statement
--- may bind multple values.
-runStmt :: Session -> String -> IO RunResult
-runStmt (Session ref) expr
-   = do 
-       hsc_env <- readIORef ref
-
-        breakMVar  <- newEmptyMVar  -- wait on this when we hit a breakpoint
-        statusMVar <- newEmptyMVar  -- wait on this when a computation is running 
-
-       -- Turn off -fwarn-unused-bindings when running a statement, to hide
-       -- warnings about the implicit bindings we introduce.
-       let dflags'  = dopt_unset (hsc_dflags hsc_env) Opt_WarnUnusedBinds
-           hsc_env' = hsc_env{ hsc_dflags = dflags' }
-
-        maybe_stuff <- hscStmt hsc_env' expr
-
-        case maybe_stuff of
-          Nothing -> return RunFailed
-          Just (new_hsc_env, names, hval) -> do
-              writeIORef ref new_hsc_env
-
-              let resume_handle = ResumeHandle breakMVar statusMVar names
-              -- set the onBreakAction to be performed when we hit a
-              -- breakpoint this is visible in the Byte Code
-              -- Interpreter, thus it is a global variable,
-              -- implemented with stable pointers
-              stablePtr <- setBreakAction resume_handle
-
-              let thing_to_run = unsafeCoerce# hval :: IO [HValue]
-              status <- sandboxIO statusMVar thing_to_run
-              freeStablePtr stablePtr -- be careful not to leak stable pointers!
-              handleRunStatus ref names status
-
-handleRunStatus ref names status =
-   case status of  
-      -- did we hit a breakpoint or did we complete?
-      (Break apStack info tid res) -> do
-                hsc_env <- readIORef ref
-                (new_hsc_env, names) <- extendEnvironment hsc_env apStack 
-                                                (breakInfo_vars info)
-                writeIORef ref new_hsc_env 
-                return (RunBreak tid names info res)
-      (Complete either_hvals) ->
-               case either_hvals of
-                   Left e -> return (RunException e)
-                   Right hvals -> do
-                       extendLinkEnv (zip names hvals)
-                       return (RunOk names)
-           
--- this points to the IO action that is executed when a breakpoint is hit
-foreign import ccall "&breakPointIOAction" 
-        breakPointIOAction :: Ptr (StablePtr (BreakInfo -> HValue -> IO ())) 
-
--- When running a computation, we redirect ^C exceptions to the running
--- thread.  ToDo: we might want a way to continue even if the target
--- thread doesn't die when it receives the exception... "this thread
--- is not responding".
-sandboxIO :: MVar Status -> IO [HValue] -> IO Status
-sandboxIO statusMVar thing = do
-  ts <- takeMVar interruptTargetThread
-  child <- forkIO (do res <- Exception.try thing; putMVar statusMVar (Complete res))
-  putMVar interruptTargetThread (child:ts)
-  takeMVar statusMVar `finally` modifyMVar_ interruptTargetThread (return.tail)
-
-setBreakAction res@(ResumeHandle breakMVar statusMVar names) = do 
-  stablePtr <- newStablePtr onBreak
-  poke breakPointIOAction stablePtr
-  return stablePtr
-  where onBreak ids apStack = do
-                tid <- myThreadId
-                putMVar statusMVar (Break apStack ids tid res)
-                takeMVar breakMVar
-
-resume :: Session -> ResumeHandle -> IO RunResult
-resume (Session ref) res@(ResumeHandle breakMVar statusMVar names) = do
-   stablePtr <- setBreakAction res
-   putMVar breakMVar ()
-   status <- takeMVar statusMVar
-   handleRunStatus ref names status
-
-{-
--- This version of sandboxIO runs the expression in a completely new
--- RTS main thread.  It is disabled for now because ^C exceptions
--- won't be delivered to the new thread, instead they'll be delivered
--- to the (blocked) GHCi main thread.
-
--- SLPJ: when re-enabling this, reflect a wrong-stat error as an exception
-
-sandboxIO :: IO a -> IO (Either Int (Either Exception a))
-sandboxIO thing = do
-  st_thing <- newStablePtr (Exception.try thing)
-  alloca $ \ p_st_result -> do
-    stat <- rts_evalStableIO st_thing p_st_result
-    freeStablePtr st_thing
-    if stat == 1
-       then do st_result <- peek p_st_result
-               result <- deRefStablePtr st_result
-               freeStablePtr st_result
-               return (Right result)
-       else do
-               return (Left (fromIntegral stat))
-
-foreign import "rts_evalStableIO"  {- safe -}
-  rts_evalStableIO :: StablePtr (IO a) -> Ptr (StablePtr a) -> IO CInt
-  -- more informative than the C type!
-
-XXX the type of rts_evalStableIO no longer matches the above
-
--}
-
--- -----------------------------------------------------------------------------
--- After stopping at a breakpoint, add free variables to the environment
-
--- Todo: turn this into a primop, and provide special version(s) for unboxed things
-foreign import ccall "rts_getApStackVal" getApStackVal :: StablePtr a -> Int -> IO (StablePtr b)
-
-getIdValFromApStack :: a -> (Id, Int) -> IO (Id, HValue)
-getIdValFromApStack apStack (identifier, stackDepth) = do
-   -- ToDo: check the type of the identifer and decide whether it is unboxed or not
-   apSptr <- newStablePtr apStack
-   resultSptr <- getApStackVal apSptr (stackDepth - 1)
-   result <- deRefStablePtr resultSptr
-   freeStablePtr apSptr
-   freeStablePtr resultSptr 
-   return (identifier, unsafeCoerce# result)
-
-extendEnvironment :: HscEnv -> a -> [(Id, Int)] -> IO (HscEnv, [Name])
-extendEnvironment hsc_env apStack idsOffsets = do
-   idsVals <- mapM (getIdValFromApStack apStack) idsOffsets 
-   let (ids, hValues) = unzip idsVals 
-   let names = map idName ids
-   let global_ids = map globaliseAndTidy ids
-   typed_ids  <- mapM instantiateIdType global_ids
-   let ictxt = hsc_IC hsc_env
-       rn_env   = ic_rn_local_env ictxt
-       type_env = ic_type_env ictxt
-       bound_names = map idName typed_ids
-       new_rn_env  = extendLocalRdrEnv rn_env bound_names
-       -- Remove any shadowed bindings from the type_env;
-       -- they are inaccessible but might, I suppose, cause 
-       -- a space leak if we leave them there
-       shadowed = [ n | name <- bound_names,
-                    let rdr_name = mkRdrUnqual (nameOccName name),
-                    Just n <- [lookupLocalRdrEnv rn_env rdr_name] ]
-       filtered_type_env = delListFromNameEnv type_env shadowed
-       new_type_env = extendTypeEnvWithIds filtered_type_env (typed_ids)
-       new_ic = ictxt { ic_rn_local_env = new_rn_env, 
-                       ic_type_env     = new_type_env }
-   extendLinkEnv (zip names hValues) -- ToDo: we must remember to restore the old env after we finish a breakpoint
-   return (hsc_env{hsc_IC = new_ic}, names)
-  where
-   globaliseAndTidy :: Id -> Id
-   globaliseAndTidy id
-      = let tidied_type = tidyTopType$ idType id
-        in setIdType (globaliseId VanillaGlobal id) tidied_type
-
-   -- | Instantiate the tyVars with GHC.Base.Unknown
-   instantiateIdType :: Id -> IO Id
-   instantiateIdType id = do
-      instantiatedType <- instantiateTyVarsToUnknown hsc_env (idType id)
-      return$ setIdType id instantiatedType
-
------------------------------------------------------------------------------
--- show a module and it's source/object filenames
-
-showModule :: Session -> ModSummary -> IO String
-showModule s mod_summary = withSession s $                        \hsc_env -> 
-                           isModuleInterpreted s mod_summary >>=  \interpreted -> 
-                           return (showModMsg (hscTarget(hsc_dflags hsc_env)) interpreted mod_summary)
-
-isModuleInterpreted :: Session -> ModSummary -> IO Bool
-isModuleInterpreted s mod_summary = withSession s $ \hsc_env -> 
-  case lookupUFM (hsc_HPT hsc_env) (ms_mod_name mod_summary) of
-       Nothing       -> panic "missing linkable"
-       Just mod_info -> return (not obj_linkable)
-                     where
-                        obj_linkable = isObjectLinkable (expectJust "showModule" (hm_linkable mod_info))
+obtainTerm :: Session -> Bool -> Id -> IO Term
+obtainTerm sess force id = withSession sess $ \hsc_env ->
+                            InteractiveEval.obtainTerm hsc_env force id
 
 obtainTerm1 :: Session -> Bool -> Maybe Type -> a -> IO Term
-obtainTerm1 sess force mb_ty x = withSession sess $ \hsc_env -> cvObtainTerm hsc_env force mb_ty (unsafeCoerce# x)
+obtainTerm1 sess force mb_ty a = withSession sess $ \hsc_env ->
+                               InteractiveEval.obtainTerm1 hsc_env force mb_ty a
 
-obtainTerm :: Session -> Bool -> Id -> IO (Maybe Term)
-obtainTerm sess force id = withSession sess $ \hsc_env -> do
-              mb_v <- getHValue (varName id) 
-              case mb_v of
-                Just v  -> fmap Just$ cvObtainTerm hsc_env force (Just$ idType id) v
-                Nothing -> return Nothing
+obtainTermB :: Session -> Int -> Bool -> Id -> IO Term
+obtainTermB sess bound force id = withSession sess $ \hsc_env ->
+                            InteractiveEval.obtainTermB hsc_env bound force id
 
-#endif /* GHCI */
+#endif