module GHC.Server.Slave where
import GHC.Server.Import
import GHC.Compat
import System.Environment
newSlave :: ThreadId -> IO Slave
newSlave main =
do inChan <- newChan
tid <- forkIO (gcatch (defaultErrorHandler (runGhc (Just libdir)
(do logger (Notice "Starting GHC ...")
initializeSlave
runSlave inChan)))
(\(SomeException e) -> do
logger (Error ("GHC threw an exception:\n "
++ show e
++ "\nThrowing up to main thread ..."))
throwTo main e))
return (Slave inChan tid)
initializeSlave :: Ghc ()
initializeSlave =
do initialDynFlags <- getSessionDynFlags
userFlags <- makeUserFlags
(dflags',_,_) <- parseDynamicFlags initialDynFlags (map (mkGeneralLocated "flag") userFlags)
_ <- setSessionDynFlags (dflags' { hscTarget = HscInterpreted
, ghcLink = LinkInMemory })
(dflags'',_packageids) <- liftIO (initPackages dflags')
io (putStrLn (showppr dflags'' _packageids))
_ <- setSessionDynFlags dflags''
mapM parseImportDecl necessaryImports >>= setContext
return ()
makeUserFlags :: Ghc [String]
makeUserFlags =
do env <- liftIO getEnvironment
case lookup "HSENV" env >> lookup "PACKAGE_DB_FOR_GHC" env of
Just flags -> return (words flags)
Nothing -> return []
runSlave
:: (GHC.Server.Import.MonadIO m, ExceptionMonad m,
GHC.Compat.MonadIO m) =>
Chan (SomeException -> IO b, m b) -> m ()
runSlave slaveInp =
do actions <- liftIO (getChanContents slaveInp)
forM_ actions protect
where protect (onError,m) =
gcatch m
(\se@(SomeException e) ->
do logger (Error ("Slave: " ++ show e))
liftIO (onError se))
showppr :: Outputable a => DynFlags -> a -> String
showppr dflags = showSDocForUser dflags neverQualify . ppr