{-# LANGUAGE ScopedTypeVariables #-}
{-# OPTIONS_GHC -optc-DNON_POSIX_SOURCE #-}
module GHC.ByteCode.InfoTable ( mkITbls ) where
import GHC.Prelude
import GHC.Platform
import GHC.Platform.Profile
import GHC.ByteCode.Types
import GHC.Runtime.Interpreter
import GHC.Types.Name ( Name, getName )
import GHC.Types.Name.Env
import GHC.Types.RepType
import GHC.Core.DataCon ( DataCon, dataConRepArgTys, dataConIdentity )
import GHC.Core.TyCon ( TyCon, tyConFamilySize, isDataTyCon, tyConDataCons )
import GHC.Core.Multiplicity ( scaledThing )
import GHC.StgToCmm.Layout ( mkVirtConstrSizes )
import GHC.StgToCmm.Closure ( tagForCon, NonVoid (..) )
import GHC.Utils.Misc
import GHC.Utils.Panic
mkITbls :: Interp -> Profile -> [TyCon] -> IO ItblEnv
mkITbls :: Interp -> Profile -> [TyCon] -> IO ItblEnv
mkITbls Interp
interp Profile
profile [TyCon]
tcs =
(ItblEnv -> ItblEnv -> ItblEnv) -> ItblEnv -> [ItblEnv] -> ItblEnv
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ItblEnv -> ItblEnv -> ItblEnv
forall a. NameEnv a -> NameEnv a -> NameEnv a
plusNameEnv ItblEnv
forall a. NameEnv a
emptyNameEnv ([ItblEnv] -> ItblEnv) -> IO [ItblEnv] -> IO ItblEnv
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
(TyCon -> IO ItblEnv) -> [TyCon] -> IO [ItblEnv]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM TyCon -> IO ItblEnv
mkITbl ((TyCon -> Bool) -> [TyCon] -> [TyCon]
forall a. (a -> Bool) -> [a] -> [a]
filter TyCon -> Bool
isDataTyCon [TyCon]
tcs)
where
mkITbl :: TyCon -> IO ItblEnv
mkITbl :: TyCon -> IO ItblEnv
mkITbl TyCon
tc
| [DataCon]
dcs [DataCon] -> WordOff -> Bool
forall a. [a] -> WordOff -> Bool
`lengthIs` WordOff
n
= Interp -> Profile -> [DataCon] -> IO ItblEnv
make_constr_itbls Interp
interp Profile
profile [DataCon]
dcs
where
dcs :: [DataCon]
dcs = TyCon -> [DataCon]
tyConDataCons TyCon
tc
n :: WordOff
n = TyCon -> WordOff
tyConFamilySize TyCon
tc
mkITbl TyCon
_ = String -> IO ItblEnv
forall a. HasCallStack => String -> a
panic String
"mkITbl"
mkItblEnv :: [(Name,ItblPtr)] -> ItblEnv
mkItblEnv :: [(Name, ItblPtr)] -> ItblEnv
mkItblEnv [(Name, ItblPtr)]
pairs = [(Name, (Name, ItblPtr))] -> ItblEnv
forall a. [(Name, a)] -> NameEnv a
mkNameEnv [(Name
n, (Name
n,ItblPtr
p)) | (Name
n,ItblPtr
p) <- [(Name, ItblPtr)]
pairs]
make_constr_itbls :: Interp -> Profile -> [DataCon] -> IO ItblEnv
make_constr_itbls :: Interp -> Profile -> [DataCon] -> IO ItblEnv
make_constr_itbls Interp
interp Profile
profile [DataCon]
cons =
[(Name, ItblPtr)] -> ItblEnv
mkItblEnv ([(Name, ItblPtr)] -> ItblEnv)
-> IO [(Name, ItblPtr)] -> IO ItblEnv
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((DataCon, WordOff) -> IO (Name, ItblPtr))
-> [(DataCon, WordOff)] -> IO [(Name, ItblPtr)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM ((DataCon -> WordOff -> IO (Name, ItblPtr))
-> (DataCon, WordOff) -> IO (Name, ItblPtr)
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry DataCon -> WordOff -> IO (Name, ItblPtr)
mk_itbl) ([DataCon] -> [WordOff] -> [(DataCon, WordOff)]
forall a b. [a] -> [b] -> [(a, b)]
zip [DataCon]
cons [WordOff
0..])
where
mk_itbl :: DataCon -> Int -> IO (Name,ItblPtr)
mk_itbl :: DataCon -> WordOff -> IO (Name, ItblPtr)
mk_itbl DataCon
dcon WordOff
conNo = do
let rep_args :: [NonVoid PrimRep]
rep_args = [ PrimRep -> NonVoid PrimRep
forall a. a -> NonVoid a
NonVoid PrimRep
prim_rep
| Scaled Type
arg <- DataCon -> [Scaled Type]
dataConRepArgTys DataCon
dcon
, PrimRep
prim_rep <- HasDebugCallStack => Type -> [PrimRep]
Type -> [PrimRep]
typePrimRep (Scaled Type -> Type
forall a. Scaled a -> a
scaledThing Scaled Type
arg) ]
(WordOff
tot_wds, WordOff
ptr_wds) =
Profile -> [NonVoid PrimRep] -> (WordOff, WordOff)
mkVirtConstrSizes Profile
profile [NonVoid PrimRep]
rep_args
ptrs' :: WordOff
ptrs' = WordOff
ptr_wds
nptrs' :: WordOff
nptrs' = WordOff
tot_wds WordOff -> WordOff -> WordOff
forall a. Num a => a -> a -> a
- WordOff
ptr_wds
nptrs_really :: WordOff
nptrs_really
| WordOff
ptrs' WordOff -> WordOff -> WordOff
forall a. Num a => a -> a -> a
+ WordOff
nptrs' WordOff -> WordOff -> Bool
forall a. Ord a => a -> a -> Bool
>= PlatformConstants -> WordOff
pc_MIN_PAYLOAD_SIZE PlatformConstants
constants = WordOff
nptrs'
| Bool
otherwise = PlatformConstants -> WordOff
pc_MIN_PAYLOAD_SIZE PlatformConstants
constants WordOff -> WordOff -> WordOff
forall a. Num a => a -> a -> a
- WordOff
ptrs'
descr :: ByteString
descr = DataCon -> ByteString
dataConIdentity DataCon
dcon
platform :: Platform
platform = Profile -> Platform
profilePlatform Profile
profile
constants :: PlatformConstants
constants = Platform -> PlatformConstants
platformConstants Platform
platform
tables_next_to_code :: Bool
tables_next_to_code = Platform -> Bool
platformTablesNextToCode Platform
platform
RemotePtr StgInfoTable
r <- Interp
-> Message (RemotePtr StgInfoTable) -> IO (RemotePtr StgInfoTable)
forall a. Binary a => Interp -> Message a -> IO a
interpCmd Interp
interp (Bool
-> WordOff
-> WordOff
-> WordOff
-> WordOff
-> ByteString
-> Message (RemotePtr StgInfoTable)
MkConInfoTable Bool
tables_next_to_code WordOff
ptrs' WordOff
nptrs_really
WordOff
conNo (Platform -> DataCon -> WordOff
tagForCon Platform
platform DataCon
dcon) ByteString
descr)
(Name, ItblPtr) -> IO (Name, ItblPtr)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (DataCon -> Name
forall a. NamedThing a => a -> Name
getName DataCon
dcon, RemotePtr StgInfoTable -> ItblPtr
ItblPtr RemotePtr StgInfoTable
r)