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 )
18 import CmStaticInfo ( PackageConfigInfo )
19 import Module ( ModuleName, PackageName )
20 import InterpSyn ( UnlinkedIBind, HValue, binder )
21 import Module ( Module )
22 import Outputable ( SDoc )
23 import FiniteMap ( FiniteMap, emptyFM )
24 import RdrName ( RdrName )
25 import Digraph ( SCC(..) )
28 import Panic ( panic )
30 #include "HsVersions.h"
34 data PersistentLinkerState
35 = PersistentLinkerState {
36 closure_env :: ClosureEnv,
38 -- notionally here, but really lives in the C part of the linker:
39 -- object_symtab :: FiniteMap String Addr
43 = LinkOK PersistentLinkerState
44 | LinkErrs PersistentLinkerState [SDoc]
50 | Trees [UnlinkedIBind] -- bunch of interpretable bindings
52 instance Outputable Unlinked where
53 ppr (DotO path) = text "DotO" <+> text path
54 ppr (DotA path) = text "DotA" <+> text path
55 ppr (DotDLL path) = text "DotDLL" <+> text path
56 ppr (Trees binds) = text "Trees" <+> ppr (map binder binds)
59 isObject (DotO _) = True
60 isObject (DotA _) = True
61 isObject (DotDLL _) = True
64 isInterpretable (Trees _) = True
65 isInterpretable _ = False
68 = LM ModuleName [Unlinked]
71 instance Outputable Linkable where
72 ppr (LM mod_nm unlinkeds) = text "LinkableM" <+> ppr mod_nm <+> ppr unlinkeds
73 ppr (LP package_nm) = text "LinkableP" <+> ptext package_nm
75 emptyPLS :: IO PersistentLinkerState
76 emptyPLS = return (PersistentLinkerState { closure_env = emptyFM,
81 link :: PackageConfigInfo
83 -> PersistentLinkerState
87 --link = panic "CmLink.link: not implemented"
89 = do putStrLn "Hello from the Linker!"
90 putStrLn (showSDoc (vcat (map ppLinkableSCC groups)))
91 putStrLn "Bye-bye from the Linker!"
94 ppLinkableSCC :: SCC Linkable -> SDoc
95 ppLinkableSCC (CyclicSCC xs) = ppr xs
96 ppLinkableSCC (AcyclicSCC x) = ppr [x]
100 link pci [] pls = return (LinkOK pls)
101 link pci (group:groups) pls = do
102 -- the group is either all objects or all interpretable, for now
103 if all isObject group
104 then do mapM loadObj [ file | DotO file <- group ]
107 else if all isInterpretable group
108 then do (new_closure_env, new_itbl_env) <-
109 linkIModules (closure_env pls)
111 [ trees | Trees trees <- group ]
112 link pci groups (PersistentLinkerState{
113 closure_env=new_closure_env,
114 itbl_env=new_itbl_env})
116 return (LinkErrs pls (ptext SLIT("linker: group must contain all objects or all interpreted modules")))
119 modname_of_linkable (LM nm _) = nm
120 modname_of_linkable (LP _) = panic "modname_of_linkable: package"
122 is_package_linkable (LP _) = True
123 is_package_linkable (LM _ _) = False
125 filterModuleLinkables :: (ModuleName -> Bool)
128 filterModuleLinkables p [] = []
129 filterModuleLinkables p (li:lis)
132 LM modnm _ -> if p modnm then retain else dump
134 dump = filterModuleLinkables p lis