Wolfgang Jeltsch pushed to branch wip/jeltsch/textual-bytecode-output at Glasgow Haskell Compiler / GHC

Commits:

6 changed files:

Changes:

  • compiler/GHC/ByteCode/Serialize.hs
    ... ... @@ -6,7 +6,7 @@
    6 6
     {- | This module implements the serialization of bytecode objects to and from disk.
    
    7 7
     -}
    
    8 8
     module GHC.ByteCode.Serialize
    
    9
    -  ( writeBinByteCode, readBinByteCode
    
    9
    +  ( writeBinByteCode, readBinByteCode, readOnDiskModuleByteCode
    
    10 10
       , ModuleByteCode(..)
    
    11 11
       , BytecodeLibX(..)
    
    12 12
       , BytecodeLib
    

  • compiler/GHC/ByteCode/Show.hs
    1
    +{-# LANGUAGE ImportQualifiedPost #-}
    
    2
    +{-# LANGUAGE RecordWildCards #-}
    
    3
    +{-# LANGUAGE ScopedTypeVariables #-}
    
    4
    +
    
    5
    +-- | […]
    
    6
    +module GHC.ByteCode.Show (showByteCode) where
    
    7
    +
    
    8
    +import Prelude ((+), (-), Integral, div)
    
    9
    +import Control.Applicative ((<$>), (<*>))
    
    10
    +import Control.Arrow ((>>>))
    
    11
    +import Control.Exception (assert)
    
    12
    +import Data.Eq ((==))
    
    13
    +import Data.Bits (FiniteBits, finiteBitSize)
    
    14
    +import Data.Function (($), id, (.))
    
    15
    +import Data.Tuple (fst, snd, uncurry)
    
    16
    +import Data.Bool (Bool, otherwise, not, (&&))
    
    17
    +import Data.Int (Int)
    
    18
    +import Data.Word (Word, Word16)
    
    19
    +import Data.Maybe (Maybe, maybe)
    
    20
    +import Data.Either (Either, either)
    
    21
    +import Data.List (length, (++), map, zipWith, take, drop, replicate)
    
    22
    +import Data.String (String)
    
    23
    +import Data.ByteString (ByteString, unpack)
    
    24
    +import Data.ByteString.Short (ShortByteString)
    
    25
    +import Data.IntMap (IntMap)
    
    26
    +import Data.IntMap qualified as IntMap (toList)
    
    27
    +import Data.Array.IArray (IArray, bounds, indices, elems)
    
    28
    +import Data.Array.Unboxed (UArray)
    
    29
    +import Numeric (showHex)
    
    30
    +import Text.Show (show)
    
    31
    +import System.IO (IO, FilePath)
    
    32
    +import Foreign.Storable (Storable)
    
    33
    +import GHC.Data.Strict qualified as Strict (Maybe, maybe)
    
    34
    +import GHC.Data.FastString (unpackFS)
    
    35
    +import GHC.Data.FlatBag (FlatBag, elemsFlatBag)
    
    36
    +import GHC.Fingerprint (Fingerprint)
    
    37
    +import GHC.Types.SrcLoc (noSrcSpan)
    
    38
    +import GHC.Types.Name (Name)
    
    39
    +import GHC.Types.Name.Occurrence (OccName)
    
    40
    +import GHC.Types.Tickish (BreakTickIndex, BreakpointId (..))
    
    41
    +import GHC.Types.SptEntry (SptEntry (..))
    
    42
    +import GHC.Types.Error (MessageClass (MCDump))
    
    43
    +import GHC.Utils.Logger (Logger, logMsg)
    
    44
    +import GHC.Utils.Binary (BinSrcSpan (..))
    
    45
    +import GHC.Utils.Encoding.UTF8 (utf8DecodeShortByteString, utf8DecodeByteString)
    
    46
    +import GHC.Utils.Outputable
    
    47
    +       (
    
    48
    +           defaultDumpStyle,
    
    49
    +           SDoc,
    
    50
    +           text,
    
    51
    +           (<>),
    
    52
    +           (<+>),
    
    53
    +           hsep,
    
    54
    +           vcat,
    
    55
    +           hang,
    
    56
    +           withPprStyle,
    
    57
    +           ppr
    
    58
    +       )
    
    59
    +import GHC.Unit.Types (Module)
    
    60
    +import GHC.Iface.Type (IfaceType, IfaceTvBndr, IfaceIdBndr)
    
    61
    +import GHC.HsToCore.Breakpoints (ModBreaks (..))
    
    62
    +import GHC.ByteCode.Types
    
    63
    +       (
    
    64
    +           FFIInfo (..),
    
    65
    +           BCONPtr (..),
    
    66
    +           BCOPtr (..),
    
    67
    +           UnlinkedBCO (..),
    
    68
    +           ByteCodeHpcInfo (..),
    
    69
    +           CompiledByteCode (..)
    
    70
    +       )
    
    71
    +import GHC.ByteCode.Breakpoints
    
    72
    +       (
    
    73
    +           InternalBreakpointId (..),
    
    74
    +           InternalBreakLoc (..),
    
    75
    +           CgBreakInfo (..),
    
    76
    +           InternalModBreaks (..)
    
    77
    +       )
    
    78
    +import GHC.ByteCode.Binary (OnDiskModuleByteCode (..))
    
    79
    +import GHC.ByteCode.Serialize (readOnDiskModuleByteCode)
    
    80
    +import GHC.Driver.Env.Types (HscEnv)
    
    81
    +import GHCi.ResolvedBCO (BCOByteArray, fromBCOByteArray)
    
    82
    +import GHCi.FFI (FFIType)
    
    83
    +import GHCi.Message (ConInfoTable (..))
    
    84
    +
    
    85
    +-- | […]
    
    86
    +showByteCode :: Logger -> HscEnv -> FilePath -> IO ()
    
    87
    +showByteCode logger env path = do
    
    88
    +    byteCode <- readOnDiskModuleByteCode env path
    
    89
    +    logMsg logger
    
    90
    +           MCDump
    
    91
    +           noSrcSpan
    
    92
    +           (withPprStyle defaultDumpStyle $ pprOnDiskModuleByteCode byteCode)
    
    93
    +
    
    94
    +-- | […]
    
    95
    +pprOnDiskModuleByteCode :: OnDiskModuleByteCode -> SDoc
    
    96
    +pprOnDiskModuleByteCode OnDiskModuleByteCode {..}
    
    97
    +    = entry (text "module" <+> ppr odgbc_module) $
    
    98
    +      vcat [
    
    99
    +               pprOnDiskModuleByteCodeHash      $ odgbc_hash,
    
    100
    +               pprCompiledByteCode odgbc_module $ odgbc_compiled_byte_code,
    
    101
    +               pprObjectFileContents            $ odgbc_foreign
    
    102
    +           ]
    
    103
    +
    
    104
    +-- | […]
    
    105
    +pprOnDiskModuleByteCodeHash :: Fingerprint -> SDoc
    
    106
    +pprOnDiskModuleByteCodeHash = entry (text "hash:") . ppr
    
    107
    +
    
    108
    +-- | […]
    
    109
    +pprCompiledByteCode :: Module -> CompiledByteCode -> SDoc
    
    110
    +pprCompiledByteCode currentModule CompiledByteCode {..}
    
    111
    +    = entry (text "compiled bytecode:") $
    
    112
    +      vcat [
    
    113
    +               pprByteCodeObjects currentModule $ bc_bcos,
    
    114
    +               pprDataConstructorInfoTables     $ bc_itbls,
    
    115
    +               pprTopLevelStrings               $ bc_strs,
    
    116
    +               pprBreakpoints currentModule     $ bc_breaks,
    
    117
    +               pprStaticPointerTableEntries     $ bc_spt_entries,
    
    118
    +               pprHPCInfo                       $ bc_hpc_info
    
    119
    +           ]
    
    120
    +
    
    121
    +-- | […]
    
    122
    +pprByteCodeObjects :: Module -> FlatBag UnlinkedBCO -> SDoc
    
    123
    +pprByteCodeObjects currentModule = entry (text "bytecode objects:")      .
    
    124
    +                                   vcatOrNone                            .
    
    125
    +                                   map (pprByteCodeObject currentModule) .
    
    126
    +                                   elemsFlatBag
    
    127
    +
    
    128
    +-- | […]
    
    129
    +pprByteCodeObject :: Module -> UnlinkedBCO -> SDoc
    
    130
    +pprByteCodeObject currentModule byteCodeObject = case byteCodeObject of
    
    131
    +    UnlinkedBCO {..}
    
    132
    +        -> entry (text "ordinary object" <+> ppr unlinkedBCOName <> text ":") $
    
    133
    +           vcat [
    
    134
    +                    pprArity                  $ unlinkedBCOArity,
    
    135
    +                    pprInstructions           $ unlinkedBCOInstrs,
    
    136
    +                    pprBitmap                 $ unlinkedBCOBitmap,
    
    137
    +                    pprLiterals currentModule $ unlinkedBCOLits,
    
    138
    +                    pprPointers currentModule $ unlinkedBCOPtrs
    
    139
    +                ]
    
    140
    +    UnlinkedStaticCon {..}
    
    141
    +        -> entry (
    
    142
    +                     text "static-construction object" <+>
    
    143
    +                     ppr unlinkedStaticConName         <>
    
    144
    +                     text ":"
    
    145
    +                 )
    
    146
    +           $
    
    147
    +           vcat [
    
    148
    +                    pprDataConstructorName    $ unlinkedStaticConDataConName,
    
    149
    +                    pprLiftedness             $ not unlinkedStaticConIsUnlifted,
    
    150
    +                    pprLiterals currentModule $ unlinkedStaticConLits,
    
    151
    +                    pprPointers currentModule $ unlinkedStaticConPtrs
    
    152
    +                ]
    
    153
    +
    
    154
    +-- | […]
    
    155
    +pprArity :: Int -> SDoc
    
    156
    +pprArity = entry (text "arity:") . ppr
    
    157
    +
    
    158
    +-- | […]
    
    159
    +pprInstructions :: BCOByteArray Word16 -> SDoc
    
    160
    +pprInstructions = entry (text "instructions:") . pprBCOByteArray
    
    161
    +
    
    162
    +-- | […]
    
    163
    +pprBitmap :: BCOByteArray Word -> SDoc
    
    164
    +pprBitmap = entry (text "bitmap:") . pprBCOByteArray
    
    165
    +
    
    166
    +-- | […]
    
    167
    +pprDataConstructorName :: Name -> SDoc
    
    168
    +pprDataConstructorName = entry (text "data constructor name:") . ppr
    
    169
    +
    
    170
    +-- | […]
    
    171
    +pprLiftedness :: Bool -> SDoc
    
    172
    +pprLiftedness = entry (text "lifted:") . noOrYes
    
    173
    +
    
    174
    +-- | […]
    
    175
    +pprLiterals :: Module -> FlatBag BCONPtr -> SDoc
    
    176
    +pprLiterals currentModule = entry (text "literals:")       .
    
    177
    +                            vcatOrNone                     .
    
    178
    +                            map (pprLiteral currentModule) .
    
    179
    +                            elemsFlatBag
    
    180
    +
    
    181
    +-- | […]
    
    182
    +pprLiteral :: Module -> BCONPtr -> SDoc
    
    183
    +pprLiteral currentModule literal = case literal of
    
    184
    +    BCONPtrWord word
    
    185
    +        -> text "word" <+>
    
    186
    +           pprFixedSizeNatural word
    
    187
    +    BCONPtrLbl label
    
    188
    +        -> text "label" <+>
    
    189
    +           ppr label
    
    190
    +    BCONPtrItbl infoTableName
    
    191
    +        -> text "info table" <+>
    
    192
    +           ppr infoTableName
    
    193
    +    BCONPtrAddr addrName
    
    194
    +        -> text "address" <+>
    
    195
    +           ppr addrName
    
    196
    +    BCONPtrStr encodedString
    
    197
    +        -> text "top-level string" <+>
    
    198
    +           text (show (utf8DecodeByteString encodedString))
    
    199
    +    BCONPtrFS string
    
    200
    +        -> text "top-level string" <+>
    
    201
    +           text (show (unpackFS string))
    
    202
    +    BCONPtrFFIInfo ffiInfo
    
    203
    +        -> text "foreign function" <+>
    
    204
    +           pprFFIInfo ffiInfo
    
    205
    +    BCONPtrCostCentre breakpointID
    
    206
    +        -> text "cost center" <+>
    
    207
    +           pprInternalBreakpointID currentModule breakpointID
    
    208
    +
    
    209
    +-- | […]
    
    210
    +pprFFIInfo :: FFIInfo -> SDoc
    
    211
    +pprFFIInfo FFIInfo {..}
    
    212
    +    = hsep (map (pprFFIType >>> (<+> text "->")) ffiInfoArgs) <+>
    
    213
    +      pprFFIType ffiInfoRet
    
    214
    +
    
    215
    +-- | […]
    
    216
    +pprFFIType :: FFIType -> SDoc
    
    217
    +pprFFIType ffiType = assert (take 3 ident == "FFI") $ text (drop 3 ident) where
    
    218
    +
    
    219
    +    ident :: String
    
    220
    +    ident = show ffiType
    
    221
    +
    
    222
    +-- | […]
    
    223
    +pprInternalBreakpointID :: Module -> InternalBreakpointId -> SDoc
    
    224
    +pprInternalBreakpointID currentModule InternalBreakpointId {..}
    
    225
    +    | ibi_info_mod == currentModule = indexDoc
    
    226
    +    | otherwise                     = indexDoc         <+>
    
    227
    +                                      text "in"        <+>
    
    228
    +                                      ppr ibi_info_mod
    
    229
    +    where
    
    230
    +
    
    231
    +    indexDoc :: SDoc
    
    232
    +    indexDoc = ppr ibi_info_index
    
    233
    +
    
    234
    +-- | […]
    
    235
    +pprPointers :: Module -> FlatBag BCOPtr -> SDoc
    
    236
    +pprPointers currentModule = entry (text "pointers:")       .
    
    237
    +                            vcatOrNone                     .
    
    238
    +                            map (pprPointer currentModule) .
    
    239
    +                            elemsFlatBag
    
    240
    +
    
    241
    +-- | […]
    
    242
    +pprPointer :: Module -> BCOPtr -> SDoc
    
    243
    +pprPointer currentModule pointer = case pointer of
    
    244
    +    BCOPtrName name
    
    245
    +        -> text "name" <+> ppr name
    
    246
    +    BCOPtrPrimOp primOp
    
    247
    +        -> text "primitive operation" <+> ppr primOp
    
    248
    +    BCOPtrBCO byteCodeObject
    
    249
    +        -> pprByteCodeObject currentModule byteCodeObject
    
    250
    +    BCOPtrBreakArray breakArrayModule
    
    251
    +        -> text "break array of module" <+> ppr breakArrayModule
    
    252
    +
    
    253
    +-- | […]
    
    254
    +pprDataConstructorInfoTables :: [(Name, ConInfoTable)] -> SDoc
    
    255
    +pprDataConstructorInfoTables = entry (text "data constructor info tables:") .
    
    256
    +                               vcatOrNone                                   .
    
    257
    +                               map (uncurry pprDataConstructorInfoTable)
    
    258
    +
    
    259
    +-- | […]
    
    260
    +pprDataConstructorInfoTable :: Name -> ConInfoTable -> SDoc
    
    261
    +pprDataConstructorInfoTable dataConstrName ConInfoTable {..}
    
    262
    +    = entry (text "info table of" <+> ppr dataConstrName <> text ":") $
    
    263
    +      vcat [
    
    264
    +               pprTablePositioning    $ conItblTablesNextToCode,
    
    265
    +               pprPointerWordCount    $ conItblPtrs,
    
    266
    +               pprNonPointerWordCount $ conItblNPtrs,
    
    267
    +               pprConstructorTag      $ conItblConTag,
    
    268
    +               pprPointerTag          $ conItblPtrTag,
    
    269
    +               pprDescription         $ conItblDescr
    
    270
    +           ]
    
    271
    +
    
    272
    +-- | […]
    
    273
    +pprTablePositioning :: Bool -> SDoc
    
    274
    +pprTablePositioning = entry (text "tables next to code:") . noOrYes
    
    275
    +
    
    276
    +-- | […]
    
    277
    +pprPointerWordCount :: Int -> SDoc
    
    278
    +pprPointerWordCount = entry (text "number of words for pointers:") . ppr
    
    279
    +
    
    280
    +-- | […]
    
    281
    +pprNonPointerWordCount :: Int -> SDoc
    
    282
    +pprNonPointerWordCount = entry (text "number of words for non-pointers:") . ppr
    
    283
    +
    
    284
    +-- | […]
    
    285
    +pprConstructorTag :: Int -> SDoc
    
    286
    +pprConstructorTag = entry (text "constructor tag:") . ppr
    
    287
    +
    
    288
    +-- | […]
    
    289
    +pprPointerTag :: Int -> SDoc
    
    290
    +pprPointerTag = entry (text "pointer tag:") . ppr
    
    291
    +
    
    292
    +-- | […]
    
    293
    +pprDescription :: ByteString -> SDoc
    
    294
    +pprDescription = entry (text "description:") .
    
    295
    +                 text                        .
    
    296
    +                 utf8DecodeByteString
    
    297
    +
    
    298
    +-- | […]
    
    299
    +pprTopLevelStrings :: [(Name, ByteString)] -> SDoc
    
    300
    +pprTopLevelStrings = entry (text "top-level strings:") .
    
    301
    +                     vcatOrNone                        .
    
    302
    +                     map (uncurry pprTopLevelString)
    
    303
    +
    
    304
    +-- | […]
    
    305
    +pprTopLevelString :: Name -> ByteString -> SDoc
    
    306
    +pprTopLevelString stringName encodedString
    
    307
    +    = entry (text "string" <+> ppr stringName <> text ":") $
    
    308
    +      text                                                 $
    
    309
    +      show                                                 $
    
    310
    +      utf8DecodeByteString                                 $
    
    311
    +      encodedString
    
    312
    +
    
    313
    +-- | […]
    
    314
    +pprBreakpoints :: Module -> Maybe InternalModBreaks -> SDoc
    
    315
    +pprBreakpoints currentModule
    
    316
    +    = entry (text "breakpoints:") .
    
    317
    +      maybe (text "<none>") (pprBreakpointsData currentModule)
    
    318
    +
    
    319
    +-- | […]
    
    320
    +pprBreakpointsData :: Module -> InternalModBreaks -> SDoc
    
    321
    +pprBreakpointsData currentModule InternalModBreaks {..}
    
    322
    +    = vcat [
    
    323
    +               pprBreakpointsInSource currentModule   $ imodBreaks_modBreaks,
    
    324
    +               pprBreakpointsInByteCode currentModule $ imodBreaks_breakInfo
    
    325
    +           ]
    
    326
    +
    
    327
    +-- | […]
    
    328
    +pprBreakpointsInSource :: Module -> ModBreaks -> SDoc
    
    329
    +pprBreakpointsInSource currentModule ModBreaks {..}
    
    330
    +    = entry (text "breakpoints in source:")                 $
    
    331
    +      assert (modBreaks_module == currentModule)            $
    
    332
    +      assert boundsAreIdentical                             $
    
    333
    +      vcatOrNone                                            $
    
    334
    +      pprBreakpointInSource <$> indices modBreaks_locs_ <*>
    
    335
    +                                elems modBreaks_locs_   <*>
    
    336
    +                                elems modBreaks_decls   <*>
    
    337
    +                                elems modBreaks_vars    <*>
    
    338
    +                                elems modBreaks_ccs
    
    339
    +    where
    
    340
    +
    
    341
    +    boundsAreIdentical :: Bool
    
    342
    +    boundsAreIdentical = bounds modBreaks_locs_ == bounds modBreaks_decls &&
    
    343
    +                         bounds modBreaks_locs_ == bounds modBreaks_vars  &&
    
    344
    +                         bounds modBreaks_locs_ == bounds modBreaks_ccs
    
    345
    +
    
    346
    +-- | […]
    
    347
    +pprBreakpointInSource :: BreakTickIndex
    
    348
    +                      -> BinSrcSpan
    
    349
    +                      -> [String]
    
    350
    +                      -> [OccName]
    
    351
    +                      -> (ShortByteString, ShortByteString)
    
    352
    +                      -> SDoc
    
    353
    +pprBreakpointInSource ix srcSpan declarationPath freeVars costCenterInfo
    
    354
    +    = entry (text "breakpoint" <+> ppr ix <> text ":") $
    
    355
    +      vcat [
    
    356
    +               pprSrcSpan            $ srcSpan,
    
    357
    +               pprDeclarationPath    $ declarationPath,
    
    358
    +               pprFreeVariables      $ freeVars,
    
    359
    +               pprCostCenterPath     $ costCenterPath,
    
    360
    +               pprCostCenterLocation $ costCenterLocation
    
    361
    +           ]
    
    362
    +    where
    
    363
    +
    
    364
    +    costCenterPath :: String
    
    365
    +    costCenterPath = utf8DecodeShortByteString (fst costCenterInfo)
    
    366
    +
    
    367
    +    costCenterLocation :: String
    
    368
    +    costCenterLocation = utf8DecodeShortByteString (snd costCenterInfo)
    
    369
    +
    
    370
    +    -- The structure of the cost center information is apparent from the
    
    371
    +    -- implementation of 'GHC.HsToCore.Breakpoints.mkModBreaks'.
    
    372
    +
    
    373
    +-- | […]
    
    374
    +pprSrcSpan :: BinSrcSpan -> SDoc
    
    375
    +pprSrcSpan = entry (text "source span:") . ppr . unBinSrcSpan
    
    376
    +
    
    377
    +-- | […]
    
    378
    +pprDeclarationPath :: [String] -> SDoc
    
    379
    +pprDeclarationPath = entry (text "declaration path:") . vcat . map text
    
    380
    +
    
    381
    +-- | […]
    
    382
    +pprFreeVariables :: [OccName] -> SDoc
    
    383
    +pprFreeVariables = entry (text "free variables:") . hsep . map ppr
    
    384
    +
    
    385
    +-- | […]
    
    386
    +pprCostCenterPath :: String -> SDoc
    
    387
    +pprCostCenterPath = entry (text "cost center path:") . text
    
    388
    +
    
    389
    +-- | […]
    
    390
    +pprCostCenterLocation :: String -> SDoc
    
    391
    +pprCostCenterLocation = entry (text "cost center location:") . text
    
    392
    +
    
    393
    +-- | […]
    
    394
    +pprBreakpointsInByteCode :: Module -> IntMap CgBreakInfo -> SDoc
    
    395
    +pprBreakpointsInByteCode currentModule
    
    396
    +    = entry (text "breakpoints in bytecode:")               .
    
    397
    +      vcatOrNone                                            .
    
    398
    +      map (uncurry (pprBreakpointInByteCode currentModule)) .
    
    399
    +      IntMap.toList
    
    400
    +
    
    401
    +-- | […]
    
    402
    +pprBreakpointInByteCode :: Module -> Int -> CgBreakInfo -> SDoc
    
    403
    +pprBreakpointInByteCode currentModule ix CgBreakInfo {..}
    
    404
    +    = entry (text "breakpoint" <+> ppr ix <> text ":") $
    
    405
    +      vcat [
    
    406
    +               pprType                 $ cgb_resty,
    
    407
    +               pprTypeVariables        $ cgb_tyvars,
    
    408
    +               pprVariables            $ cgb_vars,
    
    409
    +               pprOrigin currentModule $ cgb_tick_id
    
    410
    +           ]
    
    411
    +    -- That the 'cgb_resty' field holds the type of the breakpoint is apparent
    
    412
    +    -- from the fact that this field is set by
    
    413
    +    -- 'GHC.StgToByteCode.dehydrateCgBreakInfo' using one of its arguments and
    
    414
    +    -- 'dehydrateCgBreakInfo' is always invoked with this argument set to the
    
    415
    +    -- extension field of 'Breakpoint', which in turn holds the type of the
    
    416
    +    -- breakpoint according to Note [Tickish passes] and the comment on the
    
    417
    +    -- instance declaration of @XBreakpoint 'TickishPassStg@.
    
    418
    +
    
    419
    +pprType :: IfaceType -> SDoc
    
    420
    +pprType = entry (text "type:") . ppr
    
    421
    +
    
    422
    +-- | […]
    
    423
    +pprTypeVariables :: [IfaceTvBndr] -> SDoc
    
    424
    +pprTypeVariables = entry (text "type variables:") .
    
    425
    +                   vcat                           .
    
    426
    +                   map pprTypeVariableBinder
    
    427
    +
    
    428
    +-- | […]
    
    429
    +pprTypeVariableBinder :: IfaceTvBndr -> SDoc
    
    430
    +pprTypeVariableBinder (name, kind) = ppr name <+> text "::" <+> ppr kind
    
    431
    +
    
    432
    +-- | […]
    
    433
    +pprVariables :: [Maybe (IfaceIdBndr, Word)] -> SDoc
    
    434
    +pprVariables = entry (text "variables:") .
    
    435
    +               vcat                           .
    
    436
    +               map pprVariable
    
    437
    +
    
    438
    +-- | […]
    
    439
    +pprVariable :: Maybe (IfaceIdBndr, Word) -> SDoc
    
    440
    +pprVariable = maybe (text "<unknown>") (uncurry pprKnownVariable)
    
    441
    +
    
    442
    +pprKnownVariable :: IfaceIdBndr -> Word -> SDoc
    
    443
    +pprKnownVariable binder offset = pprVariableBinder binder   <+>
    
    444
    +                                 text "@"                   <+>
    
    445
    +                                 pprFixedSizeNatural offset
    
    446
    +-- That the second argument is an offset is apparent from the use of the
    
    447
    +-- identifier @offset@ in the implementation of
    
    448
    +-- 'GHC.StgToByteCode.dehydrateCgBreakInfo'.
    
    449
    +
    
    450
    +-- | […]
    
    451
    +pprVariableBinder :: IfaceIdBndr -> SDoc
    
    452
    +pprVariableBinder (multiplicity, name, type_)
    
    453
    +    = text "%" <> ppr multiplicity <+>
    
    454
    +      ppr name <+> text "::" <+> ppr type_
    
    455
    +
    
    456
    +pprOrigin :: Module -> Either InternalBreakLoc BreakpointId -> SDoc
    
    457
    +pprOrigin currentModule = entry (text "origin:")        .
    
    458
    +                          pprBreakpointID currentModule .
    
    459
    +                          either internalBreakLoc id
    
    460
    +
    
    461
    +-- | […] [analogous to 'pprInternalBreakpointID' but the meaning of the index is different]
    
    462
    +pprBreakpointID :: Module -> BreakpointId -> SDoc
    
    463
    +pprBreakpointID currentModule BreakpointId {..}
    
    464
    +    | bi_tick_mod == currentModule = indexDoc
    
    465
    +    | otherwise                    = indexDoc <+> text "in" <+> ppr bi_tick_mod
    
    466
    +    where
    
    467
    +
    
    468
    +    indexDoc :: SDoc
    
    469
    +    indexDoc = ppr bi_tick_index
    
    470
    +
    
    471
    +-- | […]
    
    472
    +pprStaticPointerTableEntries :: [SptEntry] -> SDoc
    
    473
    +pprStaticPointerTableEntries = entry (text "static-pointer table entries:") .
    
    474
    +                               vcatOrNone                                   .
    
    475
    +                               map pprStaticPointerTableEntry
    
    476
    +
    
    477
    +-- | […]
    
    478
    +pprStaticPointerTableEntry :: SptEntry -> SDoc
    
    479
    +pprStaticPointerTableEntry (SptEntry name fingerprint)
    
    480
    +    = ppr fingerprint <> text ":" <+> ppr name
    
    481
    +
    
    482
    +-- | […]
    
    483
    +pprHPCInfo :: Strict.Maybe ByteCodeHpcInfo -> SDoc
    
    484
    +pprHPCInfo = entry (text "HPC information:") .
    
    485
    +             Strict.maybe (text "<none>") pprHPCInfoData
    
    486
    +
    
    487
    +-- | […]
    
    488
    +pprHPCInfoData :: ByteCodeHpcInfo -> SDoc
    
    489
    +pprHPCInfoData ByteCodeHpcInfo {..}
    
    490
    +    = vcat [
    
    491
    +               pprHPCInfoHash $ bchi_hash,
    
    492
    +               pprModuleName  $ bchi_module_name,
    
    493
    +               pprTickBoxName $ bchi_tickbox_name,
    
    494
    +               pprTickCount   $ bchi_tick_count
    
    495
    +           ]
    
    496
    +    where
    
    497
    +
    
    498
    +-- | […]
    
    499
    +pprHPCInfoHash :: Int -> SDoc
    
    500
    +pprHPCInfoHash = entry (text "hash:") . pprFixedSizeNatural
    
    501
    +
    
    502
    +-- | […]
    
    503
    +pprModuleName :: ShortByteString -> SDoc
    
    504
    +pprModuleName = entry (text "module name:") .
    
    505
    +                text                        .
    
    506
    +                utf8DecodeShortByteString
    
    507
    +
    
    508
    +-- | […]
    
    509
    +pprTickBoxName :: ShortByteString -> SDoc
    
    510
    +pprTickBoxName = entry (text "tick box name:") .
    
    511
    +                 text                          .
    
    512
    +                 utf8DecodeShortByteString
    
    513
    +
    
    514
    +-- | […]
    
    515
    +pprTickCount :: Int -> SDoc
    
    516
    +pprTickCount = entry (text "number of ticks:") . ppr
    
    517
    +
    
    518
    +-- | […]
    
    519
    +pprObjectFileContents :: [ByteString] -> SDoc
    
    520
    +pprObjectFileContents = entry (text "contents of object files:") .
    
    521
    +                        vcatOrNone                               .
    
    522
    +                        zipWith pprObjectFileContent [0 ..]
    
    523
    +
    
    524
    +-- | […]
    
    525
    +pprObjectFileContent :: Int -> ByteString -> SDoc
    
    526
    +pprObjectFileContent ix = entry (text "file" <+> ppr ix <> text ":") .
    
    527
    +                          pprByteString
    
    528
    +
    
    529
    +-- | […]
    
    530
    +pprByteString :: ByteString -> SDoc
    
    531
    +pprByteString = pprFixedSizeNaturalList . unpack
    
    532
    +
    
    533
    +-- | […]
    
    534
    +pprBCOByteArray :: (Integral a, FiniteBits a, Storable a, IArray UArray a) =>
    
    535
    +                   BCOByteArray a -> SDoc
    
    536
    +pprBCOByteArray = pprFixedSizeNaturalList . elems . fromBCOByteArray
    
    537
    +
    
    538
    +-- | […]
    
    539
    +pprFixedSizeNaturalList :: (Integral a, FiniteBits a) => [a] -> SDoc
    
    540
    +pprFixedSizeNaturalList []   = text "<empty>"
    
    541
    +pprFixedSizeNaturalList list = hsep (map pprFixedSizeNatural list)
    
    542
    +
    
    543
    +-- | […]
    
    544
    +pprFixedSizeNatural :: (Integral a, FiniteBits a) => a -> SDoc
    
    545
    +pprFixedSizeNatural num
    
    546
    +    = text $ replicate (digitCount - length unpadded) '0' ++ unpadded
    
    547
    +    where
    
    548
    +
    
    549
    +    digitCount :: Int
    
    550
    +    digitCount = (finiteBitSize num + 3) `div` 4
    
    551
    +
    
    552
    +    unpadded :: String
    
    553
    +    unpadded = showHex num ""
    
    554
    +
    
    555
    +-- | […]
    
    556
    +noOrYes :: Bool -> SDoc
    
    557
    +noOrYes bool = text (if bool then "yes" else "no")
    
    558
    +
    
    559
    +-- | […]
    
    560
    +entry :: SDoc -> SDoc -> SDoc
    
    561
    +entry title content = hang title 2 content
    
    562
    +
    
    563
    +-- | […]
    
    564
    +vcatOrNone :: [SDoc] -> SDoc
    
    565
    +vcatOrNone []   = text "<none>"
    
    566
    +vcatOrNone docs = vcat docs

  • compiler/ghc.cabal.in
    ... ... @@ -217,6 +217,7 @@ Library
    217 217
             GHC.ByteCode.Linker
    
    218 218
             GHC.ByteCode.Recomp.Binary
    
    219 219
             GHC.ByteCode.Serialize
    
    220
    +        GHC.ByteCode.Show
    
    220 221
             GHC.ByteCode.Types
    
    221 222
             GHC.Cmm
    
    222 223
             GHC.Cmm.BlockId
    

  • ghc/GHC/Driver/Session/Mode.hs
    ... ... @@ -77,6 +77,7 @@ isShowGhciUsageMode _ = False
    77 77
     
    
    78 78
     data PostLoadMode
    
    79 79
       = ShowInterface FilePath  -- ghc --show-iface
    
    80
    +  | ShowByteCode FilePath   -- ghc --show-byte-code
    
    80 81
       | DoMkDependHS            -- ghc -M
    
    81 82
       | StopBefore StopPhase    -- ghc -E | -C | -S
    
    82 83
                                 -- StopBefore StopLn is the default
    
    ... ... @@ -101,6 +102,9 @@ showUnitsMode = mkPostLoadMode ShowPackages
    101 102
     showInterfaceMode :: FilePath -> Mode
    
    102 103
     showInterfaceMode fp = mkPostLoadMode (ShowInterface fp)
    
    103 104
     
    
    105
    +showByteCodeMode :: FilePath -> Mode
    
    106
    +showByteCodeMode fp = mkPostLoadMode (ShowByteCode fp)
    
    107
    +
    
    104 108
     stopBeforeMode :: StopPhase -> Mode
    
    105 109
     stopBeforeMode phase = mkPostLoadMode (StopBefore phase)
    
    106 110
     
    
    ... ... @@ -231,9 +235,11 @@ mode_flags =
    231 235
             replaceSpace ' ' = '-'
    
    232 236
             replaceSpace c   = c
    
    233 237
       ] ++
    
    234
    -      ------- interfaces ----------------------------------------------------
    
    235
    -  [ defFlag "-show-iface"  (HasArg (\f -> setMode (showInterfaceMode f)
    
    238
    +      ------- textual output of generated data -----------------------------
    
    239
    +  [ defFlag "-show-iface"     (HasArg (\f -> setMode (showInterfaceMode f)
    
    236 240
                                                    "--show-iface"))
    
    241
    +  , defFlag "-show-byte-code" (HasArg (\f -> setMode (showByteCodeMode  f)
    
    242
    +                                               "--show-byte-code"))
    
    237 243
     
    
    238 244
           ------- primary modes ------------------------------------------------
    
    239 245
       , defFlag "c"            (PassFlag (\f -> do setMode (stopBeforeMode NoStop) f
    

  • ghc/Main.hs
    ... ... @@ -73,6 +73,8 @@ import GHC.SysTools.BaseDir
    73 73
     import GHC.Iface.Load
    
    74 74
     import GHC.Iface.Recomp.Binary ( fingerprintBinMem )
    
    75 75
     
    
    76
    +import GHC.ByteCode.Show ( showByteCode )
    
    77
    +
    
    76 78
     import GHC.Tc.Utils.Monad      ( initIfaceCheck )
    
    77 79
     import GHC.Iface.Errors.Ppr
    
    78 80
     
    
    ... ... @@ -266,6 +268,7 @@ main' postLoadMode units dflags0 args flagWarnings = do
    266 268
                                                         (hsc_units  hsc_env)
    
    267 269
                                                         (hsc_NC     hsc_env)
    
    268 270
                                                         f
    
    271
    +       ShowByteCode f         -> liftIO $ showByteCode logger hsc_env f
    
    269 272
            DoMake                 -> doMake units srcs
    
    270 273
            DoMkDependHS           -> doMkDependHS (map fst srcs)
    
    271 274
            StopBefore p           -> liftIO (oneShot hsc_env p srcs)
    

  • libraries/ghci/GHCi/ResolvedBCO.hs
    ... ... @@ -7,6 +7,7 @@ module GHCi.ResolvedBCO
    7 7
       , isLittleEndian
    
    8 8
       , BCOByteArray(..)
    
    9 9
       , mkBCOByteArray
    
    10
    +  , fromBCOByteArray
    
    10 11
       ) where
    
    11 12
     
    
    12 13
     #include "MachDeps.h"
    
    ... ... @@ -20,7 +21,6 @@ import GHCi.BreakArray
    20 21
     import Control.Monad
    
    21 22
     import Data.Array.Base (foldrArray, listArray)
    
    22 23
     import Data.ByteString.Builder.Extra
    
    23
    -import Foreign.Storable
    
    24 24
     #endif
    
    25 25
     
    
    26 26
     import Data.Binary (Binary(..))
    
    ... ... @@ -32,6 +32,7 @@ import GHC.Generics
    32 32
     
    
    33 33
     import GHC.Exts
    
    34 34
     import Data.Array.Base (UArray(..))
    
    35
    +import Foreign.Storable
    
    35 36
     import qualified GHC.Exts.Heap as Heap
    
    36 37
     
    
    37 38
     #include "MachDeps.h"
    
    ... ... @@ -91,13 +92,11 @@ data BCOByteArray a
    91 92
             getBCOByteArray :: !ByteArray#
    
    92 93
       }
    
    93 94
     
    
    94
    -#if SIZEOF_HSWORD == 4
    
    95 95
     fromBCOByteArray :: forall a . Storable a => BCOByteArray a -> UArray Int a
    
    96 96
     fromBCOByteArray (BCOByteArray ba#) = UArray 0 (n - 1) n ba#
    
    97 97
       where
    
    98 98
         len# = sizeofByteArray# ba#
    
    99 99
         n = (I# len#) `div` sizeOf (undefined :: a)
    
    100
    -#endif
    
    101 100
     
    
    102 101
     mkBCOByteArray :: UArray Int a -> BCOByteArray a
    
    103 102
     mkBCOByteArray (UArray _ _ _ arr) = BCOByteArray arr