summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/ghci/GHCi.hsc7
-rw-r--r--compiler/main/DriverPipeline.hs5
-rw-r--r--compiler/main/GHC.hs17
-rw-r--r--compiler/main/GhcMake.hs12
-rw-r--r--compiler/main/HscMain.hs24
-rw-r--r--compiler/main/HscTypes.hs30
-rw-r--r--compiler/main/InteractiveEval.hs2
-rw-r--r--compiler/main/StaticPtrTable.hs38
-rw-r--r--compiler/main/TidyPgm.hs18
-rw-r--r--compiler/rename/RnExpr.hs9
10 files changed, 118 insertions, 44 deletions
diff --git a/compiler/ghci/GHCi.hsc b/compiler/ghci/GHCi.hsc
index 2c6860f126..849c8db7fa 100644
--- a/compiler/ghci/GHCi.hsc
+++ b/compiler/ghci/GHCi.hsc
@@ -14,6 +14,7 @@ module GHCi
, evalStringToIOString
, mallocData
, createBCOs
+ , addSptEntry
, mkCostCentres
, costCentreStackInfo
, newBreakArray
@@ -52,6 +53,7 @@ import GHCi.Run
import GHCi.RemoteTypes
import GHCi.ResolvedBCO
import GHCi.BreakArray (BreakArray)
+import Fingerprint
import HscTypes
import UniqFM
import Panic
@@ -326,6 +328,11 @@ createBCOs hsc_env rbcos = do
parMap f (x:xs) = fx `par` (fxs `pseq` (fx : fxs))
where fx = f x; fxs = parMap f xs
+addSptEntry :: HscEnv -> Fingerprint -> ForeignHValue -> IO ()
+addSptEntry hsc_env fpr ref =
+ withForeignRef ref $ \val ->
+ iservCmd hsc_env (AddSptEntry fpr val)
+
costCentreStackInfo :: HscEnv -> RemotePtr CostCentreStack -> IO [String]
costCentreStackInfo hsc_env ccs =
iservCmd hsc_env (CostCentreStackInfo ccs)
diff --git a/compiler/main/DriverPipeline.hs b/compiler/main/DriverPipeline.hs
index 08af37cdda..463b715807 100644
--- a/compiler/main/DriverPipeline.hs
+++ b/compiler/main/DriverPipeline.hs
@@ -182,7 +182,8 @@ compileOne' m_tc_result mHscMessage
let linkable = LM o_time this_mod [DotO object_filename]
return hmi0 { hm_linkable = Just linkable }
(HscRecomp cgguts summary, HscInterpreted) -> do
- (hasStub, comp_bc) <- hscInteractive hsc_env cgguts summary
+ (hasStub, comp_bc, spt_entries) <-
+ hscInteractive hsc_env cgguts summary
stub_o <- case hasStub of
Nothing -> return []
@@ -190,7 +191,7 @@ compileOne' m_tc_result mHscMessage
stub_o <- compileStub hsc_env stub_c
return [DotO stub_o]
- let hs_unlinked = [BCOs comp_bc]
+ let hs_unlinked = [BCOs comp_bc spt_entries]
unlinked_time = ms_hs_date summary
-- Why do we use the timestamp of the source file here,
-- rather than the current time? This works better in
diff --git a/compiler/main/GHC.hs b/compiler/main/GHC.hs
index 25c1484770..bc406d5c59 100644
--- a/compiler/main/GHC.hs
+++ b/compiler/main/GHC.hs
@@ -323,7 +323,7 @@ import Annotations
import Module
import Panic
import Platform
-import Bag ( unitBag )
+import Bag ( listToBag, unitBag )
import ErrUtils
import MonadUtils
import Util
@@ -615,7 +615,8 @@ getProgramDynFlags = getSessionDynFlags
setInteractiveDynFlags :: GhcMonad m => DynFlags -> m ()
setInteractiveDynFlags dflags = do
dflags' <- checkNewDynFlags dflags
- modifySession $ \h -> h{ hsc_IC = (hsc_IC h) { ic_dflags = dflags' }}
+ dflags'' <- checkNewInteractiveDynFlags dflags'
+ modifySession $ \h -> h{ hsc_IC = (hsc_IC h) { ic_dflags = dflags'' }}
-- | Get the 'DynFlags' used to evaluate interactive expressions.
getInteractiveDynFlags :: GhcMonad m => m DynFlags
@@ -637,6 +638,18 @@ checkNewDynFlags dflags = do
liftIO $ handleFlagWarnings dflags warnings
return dflags'
+checkNewInteractiveDynFlags :: MonadIO m => DynFlags -> m DynFlags
+checkNewInteractiveDynFlags dflags0 = do
+ dflags1 <-
+ if xopt LangExt.StaticPointers dflags0
+ then do liftIO $ printOrThrowWarnings dflags0 $ listToBag
+ [mkPlainWarnMsg dflags0 interactiveSrcSpan
+ $ text "StaticPointers is not supported in GHCi interactive expressions."]
+ return $ xopt_unset dflags0 LangExt.StaticPointers
+ else return dflags0
+ return dflags1
+
+
-- %************************************************************************
-- %* *
-- Setting, getting, and modifying the targets
diff --git a/compiler/main/GhcMake.hs b/compiler/main/GhcMake.hs
index 94c02d5017..77b9581a2e 100644
--- a/compiler/main/GhcMake.hs
+++ b/compiler/main/GhcMake.hs
@@ -1286,6 +1286,18 @@ upsweep mHscMessage old_hpt stable_mods cleanup sccs = do
hsc_env4 <- liftIO $ reTypecheckLoop hsc_env3 mod done'
setSession hsc_env4
+ -- Add any necessary entries to the static pointer
+ -- table. See Note [Grand plan for static forms] in
+ -- StaticPtrTable.
+ when (hscTarget (hsc_dflags hsc_env4) == HscInterpreted) $
+ liftIO $ hscAddSptEntries hsc_env4
+ [ spt
+ | Just linkable <- pure $ hm_linkable mod_info
+ , unlinked <- linkableUnlinked linkable
+ , BCOs _ spts <- pure unlinked
+ , spt <- spts
+ ]
+
upsweep' old_hpt1 done' mods (mod_index+1) nmods uids_to_check' done_holes'
unitIdsToCheck :: DynFlags -> [UnitId]
diff --git a/compiler/main/HscMain.hs b/compiler/main/HscMain.hs
index 092f04c1aa..c8aa0ab390 100644
--- a/compiler/main/HscMain.hs
+++ b/compiler/main/HscMain.hs
@@ -79,10 +79,12 @@ module HscMain
, hscFileFrontEnd, genericHscFrontend, dumpIfaceStats
, ioMsgMaybe
, showModuleIndex
+ , hscAddSptEntries
) where
import Data.Data hiding (Fixity, TyCon)
import Id
+import GHCi ( addSptEntry )
import GHCi.RemoteTypes ( ForeignHValue )
import ByteCodeGen ( byteCodeGen, coreExprToBCOs )
import Linker
@@ -1308,7 +1310,7 @@ hscGenHardCode hsc_env cgguts mod_summary output_filename = do
hscInteractive :: HscEnv
-> CgGuts
-> ModSummary
- -> IO (Maybe FilePath, CompiledByteCode)
+ -> IO (Maybe FilePath, CompiledByteCode, [SptEntry])
hscInteractive hsc_env cgguts mod_summary = do
let dflags = hsc_dflags hsc_env
let CgGuts{ -- This is the last use of the ModGuts in a compilation.
@@ -1317,7 +1319,8 @@ hscInteractive hsc_env cgguts mod_summary = do
cg_binds = core_binds,
cg_tycons = tycons,
cg_foreign = foreign_stubs,
- cg_modBreaks = mod_breaks } = cgguts
+ cg_modBreaks = mod_breaks,
+ cg_spt_entries = spt_entries } = cgguts
location = ms_location mod_summary
data_tycons = filter isDataTyCon tycons
@@ -1331,10 +1334,10 @@ hscInteractive hsc_env cgguts mod_summary = do
corePrepPgm hsc_env this_mod location core_binds data_tycons
----------------- Generate byte code ------------------
comp_bc <- byteCodeGen hsc_env this_mod prepd_binds data_tycons mod_breaks
- ------------------ Create f-x-dynamic C-side stuff ---
+ ------------------ Create f-x-dynamic C-side stuff -----
(_istub_h_exists, istub_c_exists)
<- outputForeignStubs dflags this_mod location foreign_stubs
- return (istub_c_exists, comp_bc)
+ return (istub_c_exists, comp_bc, spt_entries)
------------------------------
@@ -1572,6 +1575,9 @@ hscDeclsWithLocation hsc_env0 str source linenumber =
let src_span = srcLocSpan interactiveSrcLoc
liftIO $ linkDecls hsc_env src_span cbc
+ {- Load static pointer table entries -}
+ liftIO $ hscAddSptEntries hsc_env (cg_spt_entries tidy_cg)
+
let tcs = filterOut isImplicitTyCon (mg_tcs simpl_mg)
patsyns = mg_patsyns simpl_mg
@@ -1593,6 +1599,16 @@ hscDeclsWithLocation hsc_env0 str source linenumber =
fam_insts defaults fix_env
return (new_tythings, new_ictxt)
+-- | Load the given static-pointer table entries into the interpreter.
+-- See Note [Grand plan for static forms] in StaticPtrTable.
+hscAddSptEntries :: HscEnv -> [SptEntry] -> IO ()
+hscAddSptEntries hsc_env entries = do
+ let add_spt_entry :: SptEntry -> IO ()
+ add_spt_entry (SptEntry i fpr) = do
+ val <- getHValue hsc_env (idName i)
+ pprTrace "add_spt_entry" (ppr fpr <+> ppr i) $
+ addSptEntry hsc_env fpr val
+ mapM_ add_spt_entry entries
{-
Note [Fixity declarations in GHCi]
diff --git a/compiler/main/HscTypes.hs b/compiler/main/HscTypes.hs
index 0fcf58229b..f44a261e76 100644
--- a/compiler/main/HscTypes.hs
+++ b/compiler/main/HscTypes.hs
@@ -22,7 +22,7 @@ module HscTypes (
-- * Information about modules
ModDetails(..), emptyModDetails,
ModGuts(..), CgGuts(..), ForeignStubs(..), appendStubC,
- ImportedMods, ImportedModsVal(..),
+ ImportedMods, ImportedModsVal(..), SptEntry(..),
ModSummary(..), ms_imps, ms_installed_mod, ms_mod_name, showModMsg, isBootSummary,
msHsFilePath, msHiFilePath, msObjFilePath,
@@ -1281,8 +1281,12 @@ data CgGuts
cg_foreign :: !ForeignStubs, -- ^ Foreign export stubs
cg_dep_pkgs :: ![InstalledUnitId], -- ^ Dependent packages, used to
-- generate #includes for C code gen
- cg_hpc_info :: !HpcInfo, -- ^ Program coverage tick box information
- cg_modBreaks :: !(Maybe ModBreaks) -- ^ Module breakpoints
+ cg_hpc_info :: !HpcInfo, -- ^ Program coverage tick box information
+ cg_modBreaks :: !(Maybe ModBreaks), -- ^ Module breakpoints
+ cg_spt_entries :: [SptEntry]
+ -- ^ Static pointer table entries for static forms defined in
+ -- the module.
+ -- See Note [Grand plan for static forms] in StaticPtrTable
}
-----------------------------------
@@ -1303,6 +1307,13 @@ appendStubC :: ForeignStubs -> SDoc -> ForeignStubs
appendStubC NoStubs c_code = ForeignStubs empty c_code
appendStubC (ForeignStubs h c) c_code = ForeignStubs h (c $$ c_code)
+-- | An entry to be inserted into a module's static pointer table.
+-- See Note [Grand plan for static forms] in StaticPtrTable.
+data SptEntry = SptEntry Id Fingerprint
+
+instance Outputable SptEntry where
+ ppr (SptEntry id fpr) = ppr id <> colon <+> ppr fpr
+
{-
************************************************************************
* *
@@ -2951,13 +2962,18 @@ data Unlinked
= DotO FilePath -- ^ An object file (.o)
| DotA FilePath -- ^ Static archive file (.a)
| DotDLL FilePath -- ^ Dynamically linked library file (.so, .dll, .dylib)
- | BCOs CompiledByteCode -- ^ A byte-code object, lives only in memory
+ | BCOs CompiledByteCode
+ [SptEntry] -- ^ A byte-code object, lives only in memory. Also
+ -- carries some static pointer table entries which
+ -- should be loaded along with the BCOs.
+ -- See Note [Grant plan for static forms] in
+ -- StaticPtrTable.
instance Outputable Unlinked where
ppr (DotO path) = text "DotO" <+> text path
ppr (DotA path) = text "DotA" <+> text path
ppr (DotDLL path) = text "DotDLL" <+> text path
- ppr (BCOs bcos) = text "BCOs" <+> ppr bcos
+ ppr (BCOs bcos spt) = text "BCOs" <+> ppr bcos <+> ppr spt
-- | Is this an actual file on disk we can link in somehow?
isObject :: Unlinked -> Bool
@@ -2979,8 +2995,8 @@ nameOfObject other = pprPanic "nameOfObject" (ppr other)
-- | Retrieve the compiled byte-code if possible. Panic if it is a file-based linkable
byteCodeOfObject :: Unlinked -> CompiledByteCode
-byteCodeOfObject (BCOs bc) = bc
-byteCodeOfObject other = pprPanic "byteCodeOfObject" (ppr other)
+byteCodeOfObject (BCOs bc _) = bc
+byteCodeOfObject other = pprPanic "byteCodeOfObject" (ppr other)
-------------------------------------------
diff --git a/compiler/main/InteractiveEval.hs b/compiler/main/InteractiveEval.hs
index 93abb07ec0..1fa269825d 100644
--- a/compiler/main/InteractiveEval.hs
+++ b/compiler/main/InteractiveEval.hs
@@ -116,7 +116,7 @@ getHistorySpan hsc_env History{..} =
getModBreaks :: HomeModInfo -> ModBreaks
getModBreaks hmi
| Just linkable <- hm_linkable hmi,
- [BCOs cbc] <- linkableUnlinked linkable
+ [BCOs cbc _] <- linkableUnlinked linkable
= fromMaybe emptyModBreaks (bc_breaks cbc)
| otherwise
= emptyModBreaks -- probably object code
diff --git a/compiler/main/StaticPtrTable.hs b/compiler/main/StaticPtrTable.hs
index 7a836e6068..f61714db61 100644
--- a/compiler/main/StaticPtrTable.hs
+++ b/compiler/main/StaticPtrTable.hs
@@ -45,8 +45,11 @@
-- > }
--
-{-# LANGUAGE ViewPatterns #-}
-module StaticPtrTable (sptCreateStaticBinds) where
+{-# LANGUAGE ViewPatterns, TupleSections #-}
+module StaticPtrTable
+ ( sptCreateStaticBinds
+ , sptModuleInitCode
+ ) where
{- Note [Grand plan for static forms]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -114,10 +117,15 @@ Here is a running example:
where a distinct key is generated for each binding.
- We produce also a C function which inserts all these bindings in the static
- pointer table (see the call to StaticPtrTable.sptCreateStaticBinds in
- TidyPgm). As the Ids of floated static pointers are exported, they can be
- linked with the C function.
+* If we are compiling to object code we insert a C stub (generated by
+ sptModuleInitCode) into the final object which runs when the module is loaded,
+ inserting the static forms defined by the module into the RTS's static pointer
+ table.
+
+* If we are compiling for the byte-code interpreter, we instead explicitly add
+ the SPT entries (recorded in CgGuts' cg_spt_entries field) to the interpreter
+ process' SPT table using the addSptEntry interpreter message. This happens
+ in upsweep after we have compiled the module (see GhcMake.upsweep').
-}
import CLabel
@@ -157,15 +165,15 @@ import qualified GHC.LanguageExtensions as LangExt
-- It also yields the C stub that inserts these bindings into the static
-- pointer table.
sptCreateStaticBinds :: HscEnv -> Module -> CoreProgram
- -> IO (SDoc, CoreProgram)
+ -> IO ([SptEntry], CoreProgram)
sptCreateStaticBinds hsc_env this_mod binds
| not (xopt LangExt.StaticPointers dflags) =
- return (Outputable.empty, binds)
+ return ([], binds)
| otherwise = do
-- Make sure the required interface files are loaded.
_ <- lookupGlobal hsc_env unpackCStringName
(fps, binds') <- evalStateT (go [] [] binds) 0
- return (sptModuleInitCode this_mod fps, binds')
+ return (fps, binds')
where
go fps bs xs = case xs of
[] -> return (reverse fps, reverse bs)
@@ -179,7 +187,7 @@ sptCreateStaticBinds hsc_env this_mod binds
--
-- The 'Int' state is used to produce a different key for each binding.
replaceStaticBind :: CoreBind
- -> StateT Int IO ([(Id, Fingerprint)], CoreBind)
+ -> StateT Int IO ([SptEntry], CoreBind)
replaceStaticBind (NonRec b e) = do (mfp, (b', e')) <- replaceStatic b e
return (maybeToList mfp, NonRec b' e')
replaceStaticBind (Rec rbs) = do
@@ -187,13 +195,13 @@ sptCreateStaticBinds hsc_env this_mod binds
return (catMaybes mfps, Rec rbs')
replaceStatic :: Id -> CoreExpr
- -> StateT Int IO (Maybe (Id, Fingerprint), (Id, CoreExpr))
+ -> StateT Int IO (Maybe SptEntry, (Id, CoreExpr))
replaceStatic b e@(collectTyBinders -> (tvs, e0)) =
case collectMakeStaticArgs e0 of
Nothing -> return (Nothing, (b, e))
Just (_, t, info, arg) -> do
(fp, e') <- mkStaticBind t info arg
- return (Just (b, fp), (b, foldr Lam e' tvs))
+ return (Just (SptEntry b fp), (b, foldr Lam e' tvs))
mkStaticBind :: Type -> CoreExpr -> CoreExpr
-> StateT Int IO (Fingerprint, CoreExpr)
@@ -249,7 +257,7 @@ sptCreateStaticBinds hsc_env this_mod binds
--
-- @fps@ is a list associating each binding corresponding to a static entry with
-- its fingerprint.
-sptModuleInitCode :: Module -> [(Id, Fingerprint)] -> SDoc
+sptModuleInitCode :: Module -> [SptEntry] -> SDoc
sptModuleInitCode _ [] = Outputable.empty
sptModuleInitCode this_mod entries = vcat
[ text "static void hs_spt_init_" <> ppr this_mod
@@ -267,7 +275,7 @@ sptModuleInitCode this_mod entries = vcat
]
)
<> semi
- | (i, (n, fp)) <- zip [0..] entries
+ | (i, SptEntry n fp) <- zip [0..] entries
]
, text "static void hs_spt_fini_" <> ppr this_mod
<> text "(void) __attribute__((destructor));"
@@ -276,7 +284,7 @@ sptModuleInitCode this_mod entries = vcat
[ text "StgWord64 k" <> int i <> text "[2] = "
<> pprFingerprint fp <> semi
$$ text "hs_spt_remove" <> parens (char 'k' <> int i) <> semi
- | (i, (_, fp)) <- zip [0..] entries
+ | (i, (SptEntry _ fp)) <- zip [0..] entries
]
]
where
diff --git a/compiler/main/TidyPgm.hs b/compiler/main/TidyPgm.hs
index c546e5c257..0fc153ad4c 100644
--- a/compiler/main/TidyPgm.hs
+++ b/compiler/main/TidyPgm.hs
@@ -377,8 +377,18 @@ tidyProgram hsc_env (ModGuts { mg_module = mod
; tidy_type_env = tidyTypeEnv omit_prags type_env2
}
-- See Note [Grand plan for static forms] in StaticPtrTable.
- ; (spt_init_code, tidy_binds') <-
+ ; (spt_entries, tidy_binds') <-
sptCreateStaticBinds hsc_env mod tidy_binds
+ ; let { spt_init_code = sptModuleInitCode mod spt_entries
+ ; add_spt_init_code =
+ case hscTarget dflags of
+ -- If we are compiling for the interpreter we will insert
+ -- any necessary SPT entries dynamically
+ HscInterpreted -> id
+ -- otherwise add a C stub to do so
+ _ -> (`appendStubC` spt_init_code)
+ }
+
; let { -- See Note [Injecting implicit bindings]
all_tidy_binds = implicit_binds ++ tidy_binds'
@@ -415,11 +425,11 @@ tidyProgram hsc_env (ModGuts { mg_module = mod
; return (CgGuts { cg_module = mod,
cg_tycons = alg_tycons,
cg_binds = all_tidy_binds,
- cg_foreign = foreign_stubs `appendStubC`
- spt_init_code,
+ cg_foreign = add_spt_init_code foreign_stubs,
cg_dep_pkgs = map fst $ dep_pkgs deps,
cg_hpc_info = hpc_info,
- cg_modBreaks = modBreaks },
+ cg_modBreaks = modBreaks,
+ cg_spt_entries = spt_entries },
ModDetails { md_types = tidy_type_env,
md_rules = tidy_rules,
diff --git a/compiler/rename/RnExpr.hs b/compiler/rename/RnExpr.hs
index 17c9042f22..769dff0fb6 100644
--- a/compiler/rename/RnExpr.hs
+++ b/compiler/rename/RnExpr.hs
@@ -360,15 +360,6 @@ wired-in. See the Notes about the NameSorts in Name.hs.
-}
rnExpr e@(HsStatic _ expr) = do
- target <- fmap hscTarget getDynFlags
- case target of
- -- SPT entries are expected to exist in object code so far, and this is
- -- not the case in interpreted mode. See bug #9878.
- HscInterpreted -> addErr $ sep
- [ text "The static form is not supported in interpreted mode."
- , text "Please use -fobject-code."
- ]
- _ -> return ()
(expr',fvExpr) <- rnLExpr expr
stage <- getStage
case stage of