summaryrefslogtreecommitdiff
path: root/compiler/GHC/Unit/Home/ModInfo.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/GHC/Unit/Home/ModInfo.hs')
-rw-r--r--compiler/GHC/Unit/Home/ModInfo.hs75
1 files changed, 68 insertions, 7 deletions
diff --git a/compiler/GHC/Unit/Home/ModInfo.hs b/compiler/GHC/Unit/Home/ModInfo.hs
index d66019a3ea..45129ddfb0 100644
--- a/compiler/GHC/Unit/Home/ModInfo.hs
+++ b/compiler/GHC/Unit/Home/ModInfo.hs
@@ -1,6 +1,13 @@
-- | Info about modules in the "home" unit
module GHC.Unit.Home.ModInfo
( HomeModInfo (..)
+ , HomeModLinkable(..)
+ , homeModInfoObject
+ , homeModInfoByteCode
+ , emptyHomeModInfoLinkable
+ , justBytecode
+ , justObjects
+ , bytecodeAndObjects
, HomePackageTable
, emptyHomePackageTable
, lookupHpt
@@ -27,7 +34,7 @@ import GHC.Unit.Module.ModIface
import GHC.Unit.Module.ModDetails
import GHC.Unit.Module
-import GHC.Linker.Types ( Linkable(..) )
+import GHC.Linker.Types ( Linkable(..), isObjectLinkable )
import GHC.Types.Unique
import GHC.Types.Unique.DFM
@@ -35,6 +42,7 @@ import GHC.Types.Unique.DFM
import GHC.Utils.Outputable
import Data.List (sortOn)
import Data.Ord
+import GHC.Utils.Panic
-- | Information about modules in the package being compiled
data HomeModInfo = HomeModInfo
@@ -48,25 +56,78 @@ data HomeModInfo = HomeModInfo
-- This field is LAZY because a ModDetails is constructed by knot tying.
- , hm_linkable :: !(Maybe Linkable)
+ , hm_linkable :: !HomeModLinkable
-- ^ The actual artifact we would like to link to access things in
- -- this module.
+ -- this module. See Note [Home module build products]
--
- -- 'hm_linkable' might be Nothing:
+ -- 'hm_linkable' might be empty:
--
-- 1. If this is an .hs-boot module
--
-- 2. Temporarily during compilation if we pruned away
-- the old linkable because it was out of date.
--
- -- After a complete compilation ('GHC.load'), all 'hm_linkable' fields
- -- in the 'HomePackageTable' will be @Just@.
- --
-- When re-linking a module ('GHC.Driver.Main.HscNoRecomp'), we construct the
-- 'HomeModInfo' by building a new 'ModDetails' from the old
-- 'ModIface' (only).
}
+homeModInfoByteCode :: HomeModInfo -> Maybe Linkable
+homeModInfoByteCode = homeMod_bytecode . hm_linkable
+
+homeModInfoObject :: HomeModInfo -> Maybe Linkable
+homeModInfoObject = homeMod_object . hm_linkable
+
+emptyHomeModInfoLinkable :: HomeModLinkable
+emptyHomeModInfoLinkable = HomeModLinkable Nothing Nothing
+
+-- See Note [Home module build products]
+data HomeModLinkable = HomeModLinkable { homeMod_bytecode :: !(Maybe Linkable)
+ , homeMod_object :: !(Maybe Linkable) }
+
+instance Outputable HomeModLinkable where
+ ppr (HomeModLinkable l1 l2) = ppr l1 $$ ppr l2
+
+justBytecode :: Linkable -> HomeModLinkable
+justBytecode lm =
+ assertPpr (not (isObjectLinkable lm)) (ppr lm)
+ $ emptyHomeModInfoLinkable { homeMod_bytecode = Just lm }
+
+justObjects :: Linkable -> HomeModLinkable
+justObjects lm =
+ assertPpr (isObjectLinkable lm) (ppr lm)
+ $ emptyHomeModInfoLinkable { homeMod_object = Just lm }
+
+bytecodeAndObjects :: Linkable -> Linkable -> HomeModLinkable
+bytecodeAndObjects bc o =
+ assertPpr (not (isObjectLinkable bc) && isObjectLinkable o) (ppr bc $$ ppr o)
+ (HomeModLinkable (Just bc) (Just o))
+
+
+{-
+Note [Home module build products]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When compiling a home module we can produce some combination of the following
+build products.
+
+1. A byte code linkable, for use with the byte code interpreter.
+2. An object file linkable, for linking a final executable or the byte code interpreter
+
+What we have produced is recorded in the `HomeModLinkable` type. In the case
+that these linkables are produced they are stored in the relevant field so that
+subsequent modules can retrieve and use them as necessary.
+
+* `-fbyte-code` will *only* produce a byte code linkable. This is the default in GHCi.
+* `-fobject-code` will *only* produce an object file linkable. This is the default in -c and --make mode.
+* `-fbyte-code-and-object-code` produces both a byte-code and object file linkable. So both fields are populated.
+
+Why would you want to produce both an object file and byte code linkable? If you
+also want to use `-fprefer-byte-code` then you should probably also use this
+flag to make sure that byte code is generated for your modules.
+
+-}
+
-- | Helps us find information about modules in the home package
type HomePackageTable = DModuleNameEnv HomeModInfo
-- Domain = modules in the home unit that have been fully compiled