+-- Linking stuff
+linkIModules :: ItblEnv -- incoming global itbl env; returned updated
+ -> ClosureEnv -- incoming global closure env; returned updated
+ -> [([UnlinkedBCO], ItblEnv)]
+ -> IO ([HValue], ItblEnv, ClosureEnv)
+linkIModules gie gce mods = do
+ let (bcoss, ies) = unzip mods
+ bcos = concat bcoss
+ top_level_binders = map nameOfUnlinkedBCO bcos
+ final_gie = foldr plusFM gie ies
+
+ (new_bcos, new_gce) <-
+ fixIO (\ ~(new_bcos, new_gce) -> do
+ new_bcos <- linkBCOs final_gie new_gce bcos
+ let new_gce = addListToFM gce (zip top_level_binders new_bcos)
+ return (new_bcos, new_gce))
+
+ return (new_bcos, final_gie, new_gce)
+
+
+linkIExpr :: ItblEnv -> ClosureEnv -> UnlinkedBCOExpr
+ -> IO HValue -- IO BCO# really
+linkIExpr ie ce (root_ul_bco, aux_ul_bcos)
+ = do let aux_ul_binders = map nameOfUnlinkedBCO aux_ul_bcos
+ (aux_bcos, aux_ce)
+ <- fixIO
+ (\ ~(aux_bcos, new_ce)
+ -> do new_bcos <- linkBCOs ie new_ce aux_ul_bcos
+ let new_ce = addListToFM ce (zip aux_ul_binders new_bcos)
+ return (new_bcos, new_ce)
+ )
+ [root_bco]
+ <- linkBCOs ie aux_ce [root_ul_bco]
+ return root_bco
+
+