2 % (c) The University of Glasgow, 2000
4 \section[CmLink]{Linker for GHCI}
7 module CmLink ( Linkable(..), Unlinked(..),
9 modname_of_linkable, is_package_linkable,
12 PersistentLinkerState{-abstractly!-}, emptyPLS )
15 import StgInterp ( linkIModules, ClosureEnv, ItblEnv )
17 import CmStaticInfo ( PackageConfigInfo )
18 import Module ( ModuleName, PackageName )
19 import InterpSyn ( UnlinkedIBind, HValue, binder )
20 import Module ( Module )
21 import Outputable ( SDoc )
22 import FiniteMap ( emptyFM )
23 import Digraph ( SCC(..) )
25 import Panic ( panic )
27 #include "HsVersions.h"
31 data PersistentLinkerState
32 = PersistentLinkerState {
33 closure_env :: ClosureEnv,
35 -- notionally here, but really lives in the C part of the linker:
36 -- object_symtab :: FiniteMap String Addr
40 = LinkOK PersistentLinkerState
41 | LinkErrs PersistentLinkerState [SDoc]
47 | Trees [UnlinkedIBind] -- bunch of interpretable bindings
49 instance Outputable Unlinked where
50 ppr (DotO path) = text "DotO" <+> text path
51 ppr (DotA path) = text "DotA" <+> text path
52 ppr (DotDLL path) = text "DotDLL" <+> text path
53 ppr (Trees binds) = text "Trees" <+> ppr (map binder binds)
56 isObject (DotO _) = True
57 isObject (DotA _) = True
58 isObject (DotDLL _) = True
61 isInterpretable (Trees _) = True
62 isInterpretable _ = False
65 = LM ModuleName [Unlinked]
68 instance Outputable Linkable where
69 ppr (LM mod_nm unlinkeds) = text "LinkableM" <+> ppr mod_nm <+> ppr unlinkeds
70 ppr (LP package_nm) = text "LinkableP" <+> ptext package_nm
72 emptyPLS :: IO PersistentLinkerState
73 emptyPLS = return (PersistentLinkerState { closure_env = emptyFM,
78 link :: PackageConfigInfo
80 -> PersistentLinkerState
84 --link = panic "CmLink.link: not implemented"
86 = do putStrLn "Hello from the Linker!"
87 putStrLn (showSDoc (vcat (map ppLinkableSCC groups)))
88 putStrLn "Bye-bye from the Linker!"
91 ppLinkableSCC :: SCC Linkable -> SDoc
92 ppLinkableSCC (CyclicSCC xs) = ppr xs
93 ppLinkableSCC (AcyclicSCC x) = ppr [x]
97 link pci [] pls = return (LinkOK pls)
98 link pci (group:groups) pls = do
99 -- the group is either all objects or all interpretable, for now
100 if all isObject group
101 then do mapM loadObj [ file | DotO file <- group ]
104 else if all isInterpretable group
105 then do (new_closure_env, new_itbl_env) <-
106 linkIModules (closure_env pls)
108 [ trees | Trees trees <- group ]
109 link pci groups (PersistentLinkerState{
110 closure_env=new_closure_env,
111 itbl_env=new_itbl_env})
113 return (LinkErrs pls (ptext SLIT("linker: group must contain all objects or all interpreted modules")))
116 modname_of_linkable (LM nm _) = nm
117 modname_of_linkable (LP _) = panic "modname_of_linkable: package"
119 is_package_linkable (LP _) = True
120 is_package_linkable (LM _ _) = False
122 filterModuleLinkables :: (ModuleName -> Bool)
125 filterModuleLinkables p [] = []
126 filterModuleLinkables p (li:lis)
129 LM modnm _ -> if p modnm then retain else dump
131 dump = filterModuleLinkables p lis