2 % (c) The University of Glasgow, 2000
4 \section[CmLink]{Linker for GHCI}
7 module CmLink ( Linkable(..), Unlinked(..),
9 findModuleLinkable_maybe,
10 modname_of_linkable, is_package_linkable,
14 PersistentLinkerState{-abstractly!-}, emptyPLS,
24 import CmStaticInfo ( GhciMode(..) )
25 import Outputable ( SDoc )
26 import Digraph ( SCC(..), flattenSCC )
27 import Module ( ModuleName )
30 import ErrUtils ( showPass )
31 import CmdLineOpts ( DynFlags(..) )
32 import Panic ( panic, GhcException(..) )
38 #include "HsVersions.h"
42 data PersistentLinkerState
43 = PersistentLinkerState {
47 -- Current global mapping from RdrNames to closure addresses
48 closure_env :: ClosureEnv,
50 -- the current global mapping from RdrNames of DataCons to
51 -- info table addresses.
52 -- When a new Unlinked is linked into the running image, or an existing
53 -- module in the image is replaced, the itbl_env must be updated
57 -- list of objects we've loaded (we'll need to unload them again
58 -- before re-loading the same module).
59 objects_loaded :: [FilePath]
61 -- notionally here, but really lives in the C part of the linker:
62 -- object_symtab :: FiniteMap String Addr
64 dummy :: () -- sigh, can't have an empty record
70 = LinkOK PersistentLinkerState
71 | LinkErrs PersistentLinkerState [SDoc]
73 findModuleLinkable_maybe :: [Linkable] -> ModuleName -> Maybe Linkable
74 findModuleLinkable_maybe lis mod
75 = case [LM time nm us | LM time nm us <- lis, nm == mod] of
78 many -> pprPanic "findModuleLinkable" (ppr mod)
81 emptyPLS :: IO PersistentLinkerState
83 emptyPLS = return (PersistentLinkerState { closure_env = emptyFM,
85 objects_loaded = [] })
87 emptyPLS = return (PersistentLinkerState {})
92 link :: GhciMode -- interactive or batch
93 -> DynFlags -- dynamic flags
94 -> Bool -- attempt linking in batch mode?
95 -> [Linkable] -- only contains LMs, not LPs
96 -> PersistentLinkerState
99 -- For the moment, in the batch linker, we don't bother to tell doLink
100 -- which packages to link -- it just tries all that are available.
101 -- batch_attempt_linking should only be *looked at* in batch mode. It
102 -- should only be True if the upsweep was successful and someone
103 -- exports main, i.e., we have good reason to believe that linking
106 -- There will be (ToDo: are) two lists passed to link. These
109 -- 1. The list of all linkables in the current home package. This is
110 -- used by the batch linker to link the program, and by the interactive
111 -- linker to decide which modules from the previous link it can
113 -- 2. The list of modules on which we just called "compile". This list
114 -- is used by the interactive linker to decide which modules need
115 -- to be actually linked this time around (or unlinked and re-linked
116 -- if the module was recompiled).
118 link mode dflags batch_attempt_linking linkables pls1
119 = do let verb = verbosity dflags
120 when (verb >= 3) $ do
121 hPutStrLn stderr "CmLink.link: linkables are ..."
122 hPutStrLn stderr (showSDoc (vcat (map ppr linkables)))
123 res <- link' mode dflags batch_attempt_linking linkables pls1
125 hPutStrLn stderr "CmLink.link: done"
128 link' Batch dflags batch_attempt_linking linkables pls1
129 | batch_attempt_linking
130 = do let o_files = concatMap getOfiles linkables
132 hPutStrLn stderr "ghc: linking ..."
133 -- don't showPass in Batch mode; doLink will do that for us.
135 -- doLink only returns if it succeeds
138 = do when (verb >= 3) $ do
139 hPutStrLn stderr "CmLink.link(batch): upsweep (partially) failed OR"
140 hPutStrLn stderr " Main.main not exported; not linking."
143 verb = verbosity dflags
144 getOfiles (LP _) = panic "CmLink.link(getOfiles): found package linkable"
145 getOfiles (LM _ _ us) = map nameOfObject (filter isObject us)
147 link' Interactive dflags batch_attempt_linking linkables pls1
148 = do showPass dflags "Linking"
150 linkObjs linkables [] pls2
151 -- reverse the linkables, to get the leaves of the tree first.
153 ppLinkableSCC :: SCC Linkable -> SDoc
154 ppLinkableSCC = ppr . flattenSCC
157 modname_of_linkable (LM _ nm _) = nm
158 modname_of_linkable (LP _) = panic "modname_of_linkable: package"
160 is_package_linkable (LP _) = True
161 is_package_linkable (LM _ _ _) = False
163 filterModuleLinkables :: (ModuleName -> Bool)
166 filterModuleLinkables p [] = []
167 filterModuleLinkables p (li:lis)
170 LM _ modnm _ -> if p modnm then retain else dump
172 dump = filterModuleLinkables p lis
175 -----------------------------------------------------------------------------
176 -- Linker for interactive mode
179 linkObjs = panic "CmLink.linkObjs: no interpreter"
180 unload = panic "CmLink.unload: no interpreter"
181 lookupClosure = panic "CmLink.lookupClosure: no interpreter"
183 linkObjs [] mods pls = linkFinish pls [] []
184 linkObjs (l@(LM _ m uls) : ls) mods pls
185 | all isObject uls = do
186 let objs = [ file | DotO file <- uls ]
188 linkObjs ls (m:mods) pls{objects_loaded = objs++objects_loaded pls}
189 | all isInterpretable uls = linkInterpretedCode (l:ls) mods [] pls
190 | otherwise = invalidLinkable
192 panic "CmLink.linkObjs: found package linkable"
195 linkInterpretedCode [] mods ul_trees pls = linkFinish pls mods ul_trees
196 linkInterpretedCode (LM _ m uls : ls) mods ul_trees pls
197 | all isInterpretable uls =
198 linkInterpretedCode ls (m:mods) (uls++ul_trees) pls
200 = throwDyn (OtherError
201 "can't link object code that depends on interpreted code")
202 | otherwise = invalidLinkable
203 linkInterpretedCode _ _ _ pls =
204 panic "CmLink.linkInterpretedCode: found package linkable"
206 invalidLinkable = panic "CmLink: linkable doesn't contain entirely objects or interpreted code"
209 -- link all the interpreted code in one go. We first remove from the
210 -- various environments any previous versions of these modules.
211 linkFinish pls mods ul_bcos = do
213 let itbl_env' = filterNameMap mods (itbl_env pls)
214 closure_env' = filterNameMap mods (closure_env pls)
215 stuff = [ (bcos,itbls) | BCOs bcos itbls <- ul_bcos ]
217 (ibinds, new_itbl_env, new_closure_env) <-
218 linkIModules itbl_env' closure_env' stuff
220 let new_pls = pls { closure_env = new_closure_env,
221 itbl_env = new_itbl_env
223 return (LinkOK new_pls)
225 -- purge the current "linked image"
226 unload :: PersistentLinkerState -> IO PersistentLinkerState
228 mapM unloadObj (objects_loaded pls)
229 return pls{ closure_env = emptyFM,
231 objects_loaded = [] }
233 linkExpr :: PersistentLinkerState -> UnlinkedBCOExpr -> IO HValue
234 linkExpr PersistentLinkerState{ itbl_env = ie, closure_env = ce } bcos
235 = linkIExpr ie ce bcos