ghc-debug-common-0.8.0.0: src/GHC/Debug/Types/Closures.hs
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE UnliftedFFITypes #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE PartialTypeSignatures #-}
{-# LANGUAGE StandaloneDeriving #-}
{- | The Haskell representation of a heap closure, the 'DebugClosure' type
- is quite similar to the one found in the @ghc-heap@ package but with some
- more type parameters and other changes..
-}
module GHC.Debug.Types.Closures (
-- * Closure Representation
Closure
, SizedClosure
, SizedClosureC
, SizedClosureP
, DebugClosure(..)
, TRecEntry(..)
-- * Wrappers
, DebugClosureWithSize
, DebugClosureWithExtra(..)
, Size(..)
, InclusiveSize(..)
, RetainerSize(..)
, noSize
, dcSize
, allClosures
-- * Info Table Representation
, StgInfoTable(..)
, StgInfoTableLayout(..)
, layoutCounts
, isStackFrameType
, usesSelectorLayout
, StgInfoTableLayout(..)
, layoutCounts
, ClosureType(..)
, WhatNext(..)
, WhyBlocked(..)
, TsoFlags(..)
, StgInfoTableWithPtr(..)
-- * Stack Frame Representation
, DebugStackFrame(..)
, FieldValue(..)
, GenStackFrames(..)
, StackFrames
, StackCont(..)
-- * PAP payload representation
, GenPapPayload(..)
, PapPayload
, PayloadCont(..)
-- * Constructor Description Representation
, ConstrDesc(..)
, ConstrDescCont
, parseConstrDesc
-- * SRT field representation
, GenSrtPayload(..)
, SrtPayload
, SrtCont
, ProfHeader(..)
, ProfHeaderWord(..)
, ProfHeaderWithPtr
, CCSPayload
, GenCCSPayload(..)
, CCPayload(..)
, IndexTable(..)
-- * Traversing functions
, Hextraversable(..)
, hexmap
) where
import Prelude -- See note [Why do we import Prelude here?]
import Data.Bits
import Data.Functor.Identity
import Data.Int
import Data.Word
import GHC.Exts
import GHC.Generics
import GHC.Debug.Types.Ptr
import Data.List (intercalate)
import Data.Char
import Control.Applicative
import Data.Monoid
import Data.Bitraversable
import Data.Bifunctor
import Data.Bifoldable
------------------------------------------------------------------------
-- GHC Heap
data ClosureType
= INVALID_OBJECT
| CONSTR
| CONSTR_1_0
| CONSTR_0_1
| CONSTR_2_0
| CONSTR_1_1
| CONSTR_0_2
| CONSTR_NOCAF
| FUN
| FUN_1_0
| FUN_0_1
| FUN_2_0
| FUN_1_1
| FUN_0_2
| FUN_STATIC
| THUNK
| THUNK_1_0
| THUNK_0_1
| THUNK_2_0
| THUNK_1_1
| THUNK_0_2
| THUNK_STATIC
| THUNK_SELECTOR
| BCO
| AP
| PAP
| AP_STACK
| IND
| IND_STATIC
| RET_BCO
| RET_SMALL
| RET_BIG
| RET_FUN
| UPDATE_FRAME
| CATCH_FRAME
| UNDERFLOW_FRAME
| STOP_FRAME
| BLOCKING_QUEUE
| BLACKHOLE
| MVAR_CLEAN
| MVAR_DIRTY
| TVAR
| ARR_WORDS
| MUT_ARR_PTRS_CLEAN
| MUT_ARR_PTRS_DIRTY
| MUT_ARR_PTRS_FROZEN_DIRTY
| MUT_ARR_PTRS_FROZEN_CLEAN
| MUT_VAR_CLEAN
| MUT_VAR_DIRTY
| WEAK
| PRIM
| MUT_PRIM
| TSO
| STACK
| TREC_CHUNK
| ATOMICALLY_FRAME
| CATCH_RETRY_FRAME
| CATCH_STM_FRAME
| WHITEHOLE
| SMALL_MUT_ARR_PTRS_CLEAN
| SMALL_MUT_ARR_PTRS_DIRTY
| SMALL_MUT_ARR_PTRS_FROZEN_DIRTY
| SMALL_MUT_ARR_PTRS_FROZEN_CLEAN
| COMPACT_NFDATA
| CONTINUATION
| ANN_FRAME
| N_CLOSURE_TYPES
deriving (Enum, Eq, Ord, Show, Generic, Read)
isStackFrameType :: ClosureType -> Bool
isStackFrameType ct =
case ct of
RET_BCO -> True
RET_SMALL -> True
RET_BIG -> True
RET_FUN -> True
UPDATE_FRAME -> True
CATCH_FRAME -> True
UNDERFLOW_FRAME -> True
STOP_FRAME -> True
ATOMICALLY_FRAME -> True
CATCH_RETRY_FRAME -> True
CATCH_STM_FRAME -> True
ANN_FRAME -> True
_ -> False
usesSelectorLayout :: ClosureType -> Bool
usesSelectorLayout THUNK_SELECTOR = True
usesSelectorLayout _ = False
type HalfWord = Word32 -- TODO support 32 bit
data StgInfoTableLayout
= StgLayoutPayload { layoutPtrs :: !HalfWord
, layoutNPtrs :: !HalfWord
}
| StgLayoutBitmap !Word64
| StgLayoutSelector !Word32
deriving (Eq, Show, Generic)
data StgInfoTable = StgInfoTable
{ layout :: !StgInfoTableLayout
, tipe :: ClosureType
, srtField :: !HalfWord
} deriving (Eq, Show, Generic)
layoutCounts :: StgInfoTable -> Maybe (HalfWord, HalfWord)
layoutCounts StgInfoTable{ layout = StgLayoutPayload p np } = Just (p, np)
layoutCounts _ = Nothing
data WhatNext
= ThreadRunGHC
| ThreadInterpret
| ThreadKilled
| ThreadComplete
| WhatNextUnknownValue Word16 -- ^ Please report this as a bug
deriving (Eq, Show, Generic, Ord)
data WhyBlocked
= NotBlocked
| BlockedOnMVar
| BlockedOnMVarRead
| BlockedOnBlackHole
| BlockedOnRead
| BlockedOnWrite
| BlockedOnDelay
| BlockedOnSTM
| BlockedOnDoProc
| BlockedOnCCall
| BlockedOnCCall_Interruptible
| BlockedOnMsgThrowTo
| ThreadMigrating
| WhyBlockedUnknownValue Word32 -- ^ Please report this as a bug
deriving (Eq, Show, Generic, Ord)
data TsoFlags
= TsoLocked
| TsoBlockx
| TsoInterruptible
| TsoStoppedOnBreakpoint
| TsoMarked
| TsoSqueezed
| TsoAllocLimit
| TsoFlagsUnknownValue Word32 -- ^ Please report this as a bug
deriving (Eq, Show, Generic, Ord)
newtype StgTSOProfInfo = StgTSOProfInfo {
cccs :: Maybe CCSPtr
} deriving (Show, Generic, Eq, Ord)
------------------------------------------------------------------------
-- Closures
type Closure = DebugClosure CCSPtr SrtCont PayloadCont ConstrDescCont StackCont ClosurePtr
type SizedClosure = DebugClosureWithSize CCSPtr SrtCont PayloadCont ConstrDescCont StackCont ClosurePtr
type SizedClosureC = DebugClosureWithSize CCSPtr SrtCont PayloadCont ConstrDesc StackCont ClosurePtr
type SizedClosureP = DebugClosureWithSize CCSPtr SrtPayload PapPayload ConstrDesc StackCont ClosurePtr
-- | Information needed to decode a 'ConstrDesc'
type ConstrDescCont = InfoTablePtr
-- | Information needed to decode a PAP payload
data PayloadCont = PayloadCont ClosurePtr [Word64] deriving (Show, Eq)
type DebugClosureWithSize = DebugClosureWithExtra Size
data DebugClosureWithExtra x ccs srt pap string s b
= DCS { extraDCS :: x
, unDCS :: DebugClosure ccs srt pap string s b }
deriving (Show, Ord, Eq)
-- | Exclusive size
newtype Size = Size { getSize :: Int }
deriving stock (Show, Generic)
deriving (Semigroup, Monoid) via (Sum Int)
deriving newtype (Num, Ord, Eq, Read)
newtype InclusiveSize = InclusiveSize { getInclusiveSize :: Int }
deriving stock (Show, Generic)
deriving (Semigroup, Monoid) via (Sum Int)
newtype RetainerSize = RetainerSize { getRetainerSize :: Int }
deriving stock (Show, Generic, Ord, Eq)
deriving (Semigroup, Monoid) via (Sum Int)
noSize :: DebugClosureWithSize ccs srt pap string s b -> DebugClosure ccs srt pap string s b
noSize = unDCS
dcSize :: DebugClosureWithSize ccs srt pap string s b -> Size
dcSize = extraDCS
instance Hextraversable (DebugClosureWithExtra x) where
hextraverse f g h i j k (DCS x v) = DCS x <$> hextraverse f g h i j k v
data StgInfoTableWithPtr = StgInfoTableWithPtr {
tableId :: InfoTablePtr
, decodedTable :: StgInfoTable
} deriving (Show)
instance Ord StgInfoTableWithPtr where
compare t1 t2 = compare (tableId t1) (tableId t2)
instance Eq StgInfoTableWithPtr where
t1 == t2 = tableId t1 == tableId t2
data ProfHeader a = ProfHeader { ccs :: a, hp :: ProfHeaderWord }
deriving (Eq, Ord, Show, Functor, Foldable, Traversable)
data ProfHeaderWord
= RetainerHeader { trav :: !Bool, retainerSet :: !RetainerSetPtr }
| LDVWord { state :: !Bool, creationTime :: !Word32, lastUseTime :: !Word32 }
| EraWord Word64
| OtherHeader Word64
deriving (Eq, Ord, Show)
type ProfHeaderWithPtr = ProfHeader CCSPtr
-- | This is the representation of a Haskell value on the heap. It reflects
-- <https://gitlab.haskell.org/ghc/ghc/blob/master/includes/rts/storage/Closures.h>
--
-- The data type is parametrized by 4 type parameters which correspond to
-- different pointer types.
--
-- All Heap objects have the same basic layout. A header containing a pointer
-- to the info table and a payload with various fields. The @info@ field below
-- always refers to the info table pointed to by the header. The remaining
-- fields are the payload.
--
-- See
-- <https://gitlab.haskell.org/ghc/ghc/wikis/commentary/rts/storage/heap-objects>
-- for more information.
data DebugClosure ccs srt pap string s b
= -- | A data constructor
ConstrClosure
{ info :: !StgInfoTableWithPtr
, profHeader :: Maybe (ProfHeader ccs)
, ptrArgs :: ![b] -- ^ Pointer arguments
, dataArgs :: ![Word] -- ^ Non-pointer arguments
, constrDesc :: !string
}
-- | A function
| FunClosure
{ info :: !StgInfoTableWithPtr
, profHeader :: Maybe (ProfHeader ccs)
, srt :: !(srt)
, ptrArgs :: ![b] -- ^ Pointer arguments
, dataArgs :: ![Word] -- ^ Non-pointer arguments
}
-- | A thunk, an expression not obviously in head normal form
| ThunkClosure
{ info :: !StgInfoTableWithPtr
, profHeader :: Maybe (ProfHeader ccs)
, srt :: !(srt)
, ptrArgs :: ![b] -- ^ Pointer arguments
, dataArgs :: ![Word] -- ^ Non-pointer arguments
}
-- | A thunk which performs a simple selection operation
| SelectorClosure
{ info :: !StgInfoTableWithPtr
, profHeader :: Maybe (ProfHeader ccs)
, selectee :: !b -- ^ Pointer to the object being
-- selected from
}
-- | An unsaturated function application
| PAPClosure
{ info :: !StgInfoTableWithPtr
, profHeader :: Maybe (ProfHeader ccs)
, arity :: !HalfWord -- ^ Arity of the partial application
, n_args :: !HalfWord -- ^ Size of the payload in words
, fun :: !b -- ^ Pointer to a 'FunClosure'
, pap_payload :: !pap -- ^ Sequence of already applied
-- arguments
}
-- In GHCi, if Linker.h would allow a reverse lookup, we could for exported
-- functions fun actually find the name here.
-- At least the other direction works via "lookupSymbol
-- base_GHCziBase_zpzp_closure" and yields the same address (up to tags)
-- | A function application
| APClosure
{ info :: !StgInfoTableWithPtr
, profHeader :: Maybe (ProfHeader ccs)
, arity :: !HalfWord -- ^ Always 0
, n_args :: !HalfWord -- ^ Size of payload in words
, fun :: !b -- ^ Pointer to a 'FunClosure'
, ap_payload :: !pap -- ^ Sequence of already applied
-- arguments
}
-- | A suspended thunk evaluation
| APStackClosure
{ info :: !StgInfoTableWithPtr
, profHeader :: Maybe (ProfHeader ccs)
, ap_st_size :: !Word
, fun :: !b -- ^ Function closure
, payload :: !s -- ^ Stack right before suspension
}
-- | A pointer to another closure, introduced when a thunk is updated
-- to point at its value
| IndClosure
{ info :: !StgInfoTableWithPtr
, profHeader :: Maybe (ProfHeader ccs)
, indirectee :: !b -- ^ Target closure
}
-- | A byte-code object (BCO) which can be interpreted by GHC's byte-code
-- interpreter (e.g. as used by GHCi)
| BCOClosure
{ info :: !StgInfoTableWithPtr
, profHeader :: Maybe (ProfHeader ccs)
, instrs :: !b -- ^ A pointer to an ArrWords
-- of instructions
, literals :: !b -- ^ A pointer to an ArrWords
-- of literals
, bcoptrs :: !b -- ^ A pointer to an ArrWords
-- of byte code objects
, arity :: !HalfWord -- ^ The arity of this BCO
, size :: !HalfWord -- ^ The size of this BCO in words
, bitmap :: !PtrBitmap -- ^ An StgLargeBitmap describing the
-- pointerhood of its args/free vars
}
-- | A thunk under evaluation by another thread
| BlackholeClosure
{ info :: !StgInfoTableWithPtr
, profHeader :: Maybe (ProfHeader ccs)
, indirectee :: !b -- ^ The target closure
}
-- | A @ByteArray#@
| ArrWordsClosure
{ info :: !StgInfoTableWithPtr
, profHeader :: Maybe (ProfHeader ccs)
, bytes :: !Word -- ^ Size of array in bytes
, arrWords :: ![Word] -- ^ Array payload
}
-- | A @MutableByteArray#@
| MutArrClosure
{ info :: !StgInfoTableWithPtr
, profHeader :: Maybe (ProfHeader ccs)
, mccPtrs :: !Word -- ^ Number of pointers
, mccSize :: !Word -- ^ ?? Closures.h vs ClosureMacros.h
, mccPayload :: ![b] -- ^ Array payload
-- Card table ignored
}
-- | A @SmallMutableArray#@
--
-- @since 8.10.1
| SmallMutArrClosure
{ info :: !StgInfoTableWithPtr
, profHeader :: Maybe (ProfHeader ccs)
, mccPtrs :: !Word -- ^ Number of pointers
, mccPayload :: ![b] -- ^ Array payload
}
-- | An @MVar#@, with a queue of thread state objects blocking on them
| MVarClosure
{ info :: !StgInfoTableWithPtr
, profHeader :: Maybe (ProfHeader ccs)
, queueHead :: !b -- ^ Pointer to head of queue
, queueTail :: !b -- ^ Pointer to tail of queue
, value :: !b -- ^ Pointer to closure
}
-- | A @MutVar#@
| MutVarClosure
{ info :: !StgInfoTableWithPtr
, profHeader :: Maybe (ProfHeader ccs)
, var :: !b -- ^ Pointer to contents
}
-- | An STM blocking queue.
| BlockingQueueClosure
{ info :: !StgInfoTableWithPtr
, profHeader :: Maybe (ProfHeader ccs)
, link :: !b -- ^ ?? Here so it looks like an IND
, blackHole :: !b -- ^ The blackhole closure
, owner :: !b -- ^ The owning thread state object
, queue :: !b -- ^ ??
}
| TSOClosure
{ info :: !StgInfoTableWithPtr
, profHeader :: Maybe (ProfHeader ccs)
-- pointers
, _link :: !b
, global_link :: !b
, tsoStack :: !b -- ^ stackobj from StgTSO
, trec :: !b
, blocked_exceptions :: !b
, bq :: !b
, threadLabel :: !(Maybe b)
-- values
, what_next :: WhatNext
, why_blocked :: WhyBlocked
, flags :: [TsoFlags]
, threadId :: Word64
, saved_errno :: Word32
, dirty :: Word32
, alloc_limit :: Int64
, tot_stack_size :: Word32
, prof :: Maybe StgTSOProfInfo
}
| StackClosure
{ info :: !StgInfoTableWithPtr
, profHeader :: Maybe (ProfHeader ccs)
, stack_size :: !Word32 -- ^ stack size in *words*
, stack_dirty :: !Word8 -- ^ non-zero => dirty
, stack_marking :: !Word8
, frames :: s
}
| WeakClosure
{ info :: !StgInfoTableWithPtr
, profHeader :: Maybe (ProfHeader ccs)
, cfinalizers :: !b
, key :: !b
, value :: !b
, finalizer :: !b
, mlink :: !(Maybe b) -- ^ next weak pointer for the capability, can be NULL.
}
| TVarClosure
{ info :: !StgInfoTableWithPtr
, profHeader :: Maybe (ProfHeader ccs)
, current_value :: !b
, tvar_watch_queue :: !b
, num_updates :: !Int }
| TRecChunkClosure
{ info :: !StgInfoTableWithPtr
, profHeader :: Maybe (ProfHeader ccs)
, prev_chunk :: !b
, next_idx :: !Word
, entries :: ![TRecEntry b]
}
| MutPrimClosure
{ info :: !StgInfoTableWithPtr
, profHeader :: Maybe (ProfHeader ccs)
, ptrArgs :: ![b]
, dataArgs :: ![Word]
}
| PrimClosure
{ info :: !StgInfoTableWithPtr
, profHeader :: Maybe (ProfHeader ccs)
, ptrArgs :: ![b]
, dataArgs :: ![Word]
}
| CompactNFDataClosure
{ info :: !StgInfoTableWithPtr
, profHeader :: Maybe (ProfHeader ccs)
, totalWords :: !Word64
}
-----------------------------------------------------------
-- Anything else
-- | Another kind of closure
| OtherClosure
{ info :: !StgInfoTableWithPtr
, profHeader :: Maybe (ProfHeader ccs)
, hvalues :: ![b]
, rawWords :: ![Word]
}
| UnsupportedClosure
{ info :: !StgInfoTableWithPtr
, profHeader :: Maybe (ProfHeader ccs)
}
deriving (Show, Generic, Functor, Foldable, Traversable, Ord, Eq)
data TRecEntry b = TRecEntry { tvar :: !b
, expected_value :: !b
, new_value :: !b
, trec_num_updates :: Int -- Only in THREADED, TODO: This is not an Int,
-- is it a pointer
-- to a haskell int
} deriving (Show, Generic, Functor, Foldable, Traversable, Ord, Eq)
newtype GenPapPayload b = GenPapPayload { getValues :: [FieldValue b] }
deriving (Functor, Foldable, Traversable, Show, Ord, Eq)
type PapPayload = GenPapPayload ClosurePtr
newtype GenSrtPayload b = GenSrtPayload { getSrt :: Maybe b }
deriving (Functor, Foldable, Traversable, Show, Ord, Eq)
type SrtPayload = GenSrtPayload ClosurePtr
type SrtCont = InfoTablePtr
data GenCCSPayload ccsPtr ccPtr
= CCSPayload
{ ccsID :: !Int64
, ccsCc :: ccPtr
, ccsPrevStack :: Maybe ccsPtr
, ccsIndexTable :: Maybe IndexTablePtr
, ccsRoot :: Maybe CCSPtr -- todo ccsPtr?
, ccsDepth :: Word
, ccsSccCount :: Word64
, ccsSelected :: Word
, ccsTimeTicks :: Word
, ccsMemAlloc :: Word64
, ccsInheritedAlloc :: Word64
, ccsInheritedTicks :: Word
} deriving (Show, Ord, Eq, Functor)
instance Bifunctor GenCCSPayload where
bimap f g CCSPayload{..} = (\a b -> CCSPayload{ccsPrevStack = a, ccsCc = b, ..})
(fmap f ccsPrevStack)
(g ccsCc)
instance Bifoldable GenCCSPayload where
bifoldMap f g CCSPayload{..} = foldMap f ccsPrevStack <> g ccsCc
instance Bitraversable GenCCSPayload where
bitraverse f g CCSPayload{..} = (\a b -> CCSPayload{ccsPrevStack = a, ccsCc = b, ..})
<$> traverse f ccsPrevStack
<*> g ccsCc
type CCSPayload = GenCCSPayload CCSPtr CCPtr
data CCPayload
= CCPayload
{ ccID :: !Int64
, ccLabel :: String
, ccMod :: String
, ccLoc :: String
, ccMemAlloc :: Word64
, ccTimeTicks :: Word
, ccIsCaf :: Bool
, ccLink :: Maybe CCPtr -- todo ccPtr?
} deriving (Show, Ord, Eq)
-- data IndexTable ccsPtr ccPtr = IndexTable
data IndexTable = IndexTable
{ itCostCentre :: CCPtr
, itCostCentreStack :: CCSPtr
, itNext :: Maybe IndexTablePtr
, itBackEdge :: Bool
} deriving (Show, Ord, Eq)
-- | Information needed to decode a set of stack frames
data StackCont = StackCont StackPtr -- Address of start of frames
RawStack -- The raw frames
deriving (Show, Eq, Ord)
type StackFrames = GenStackFrames SrtCont ClosurePtr
newtype GenStackFrames srt b = GenStackFrames { getFrames :: [DebugStackFrame srt b] }
deriving (Functor, Foldable, Traversable, Show, Ord, Eq)
instance Bifoldable GenStackFrames where
bifoldMap f g (GenStackFrames frames) = foldMap (bifoldMap f g) frames
instance Bitraversable GenStackFrames where
bitraverse f g (GenStackFrames frames) = GenStackFrames <$> traverse (bitraverse f g) frames
instance Bifunctor GenStackFrames where
bimap f g (GenStackFrames frames) = GenStackFrames (fmap (bimap f g) frames)
data DebugStackFrame srt b
= DebugStackFrame
{ frame_info :: !StgInfoTableWithPtr
, frame_srt :: srt
, values :: [FieldValue b]
} deriving (Traversable, Functor, Foldable, Show, Ord, Eq)
instance Bifunctor DebugStackFrame where
bimap f g (DebugStackFrame itbl srt v) = DebugStackFrame itbl (f srt) (fmap (fmap g) v)
instance Bifoldable DebugStackFrame where
bifoldMap f g (DebugStackFrame _ srt v) = f srt <> foldMap (foldMap g) v
instance Bitraversable DebugStackFrame where
bitraverse f g (DebugStackFrame itbl srt v) = DebugStackFrame itbl <$> f srt <*> traverse (traverse g) v
data ConstrDesc = ConstrDesc {
pkg :: !String -- ^ Package name
, modl :: !String -- ^ Module name
, name :: !String -- ^ Constructor name
} deriving (Show, Eq, Ord)
-- Copied from ghc-heap
parseConstrDesc :: String -> ConstrDesc
parseConstrDesc input =
if not . all (>0) . fmap length $ [p,m,occ]
then ConstrDesc "" "" input
else ConstrDesc p m occ
where
(p, rest1) = break (== ':') input
(m, occ)
= (intercalate "." $ reverse modWords, occWord)
where
(modWords, occWord) =
case rest1 of
[] -> parseModOcc [] []
(_:restTail) -> parseModOcc [] restTail
-- We only look for dots if str could start with a module name,
-- i.e. if it starts with an upper case character.
-- Otherwise we might think that "X.:->" is the module name in
-- "X.:->.+", whereas actually "X" is the module name and
-- ":->.+" is a constructor name.
parseModOcc :: [String] -> String -> ([String], String)
parseModOcc acc str@(c : _)
| isUpper c =
case break (== '.') str of
(top, []) -> (acc, top)
(top, _:bot) -> parseModOcc (top : acc) bot
parseModOcc acc str = (acc, str)
class Hextraversable m where
hextraverse ::
Applicative f => (a -> f b)
-> (c -> f d)
-> (e -> f g)
-> (h -> f i)
-> (j -> f k)
-> (l -> f n)
-> m a c e h j l
-> f (m b d g i k n)
hexmap :: forall a b c d e f g h i j k l t . Hextraversable t => (a -> b) -> (c -> d) -> (e -> f) -> (g -> h) -> (i -> j) -> (k -> l) -> t a c e g i k -> t b d f h j l
hexmap = coerce
(hextraverse :: (a -> Identity b)
-> (c -> Identity d)
-> (e -> Identity f)
-> (g -> Identity h)
-> (i -> Identity j)
-> (k -> Identity l)
-> t a c e g i k -> Identity (t b d f h j l))
allClosures :: DebugClosure ccs (GenSrtPayload c) (GenPapPayload c) a (GenStackFrames (GenSrtPayload c) c) c -> [c]
allClosures c = getConst $ hextraverse (const (Const [])) (traverse (Const . (:[]))) (traverse (Const . (:[]))) (const (Const [])) (traverse (Const . (:[]))) (Const . (:[])) c
data FieldValue b = SPtr b
| SNonPtr !Word64 deriving (Show, Traversable, Functor, Foldable, Ord, Eq)
instance Hextraversable DebugClosure where
hextraverse fccs srt p h f g c =
case c of
ConstrClosure a1 ph bs ds str ->
(\ph1 cs cstr -> ConstrClosure a1 ph1 cs ds cstr) <$> (traverse . traverse) fccs ph <*> traverse g bs <*> h str
FunClosure a1 ph srt_p bs ws -> (\ph1 srt' cs -> FunClosure a1 ph1 srt' cs ws) <$> (traverse . traverse) fccs ph <*> srt srt_p <*> traverse g bs
ThunkClosure a1 ph srt_p bs ws -> (\ph1 srt' cs -> ThunkClosure a1 ph1 srt' cs ws) <$> (traverse . traverse) fccs ph <*> srt srt_p <*> traverse g bs
SelectorClosure a1 ph b -> SelectorClosure a1 <$> (traverse . traverse) fccs ph <*> g b
PAPClosure a1 a2 a3 a4 a5 a6 -> (\b2 -> PAPClosure a1 b2 a3 a4) <$> (traverse . traverse) fccs a2 <*> g a5 <*> p a6
APClosure a1 a2 a3 a4 a5 a6 -> (\b2 -> APClosure a1 b2 a3 a4) <$> (traverse . traverse) fccs a2 <*> g a5 <*> p a6
APStackClosure a1 ph s b bs -> (\ph2 -> APStackClosure a1 ph2 s) <$> (traverse . traverse) fccs ph <*> g b <*> f bs
IndClosure a1 ph b -> IndClosure a1 <$> (traverse . traverse) fccs ph <*> g b
BCOClosure a1 ph b1 b2 b3 a2 a3 a4 ->
(\ph2 c1 c2 c3 -> BCOClosure a1 ph2 c1 c2 c3 a2 a3 a4) <$> (traverse . traverse) fccs ph <*> g b1 <*> g b2 <*> g b3
BlackholeClosure a1 ph b -> BlackholeClosure a1 <$> (traverse . traverse) fccs ph <*> g b
ArrWordsClosure a1 ph a2 a3 -> (\ph2 -> ArrWordsClosure a1 ph2 a2 a3) <$> (traverse . traverse) fccs ph
MutArrClosure a1 ph a2 a3 bs -> (\ph2 -> MutArrClosure a1 ph2 a2 a3) <$> (traverse . traverse) fccs ph <*> traverse g bs
SmallMutArrClosure a1 ph a2 bs -> (\ph2 -> SmallMutArrClosure a1 ph2 a2) <$> (traverse . traverse) fccs ph <*> traverse g bs
MVarClosure a1 ph b1 b2 b3 -> MVarClosure a1 <$> (traverse . traverse) fccs ph <*> g b1 <*> g b2 <*> g b3
MutVarClosure a1 ph b -> MutVarClosure a1 <$> (traverse . traverse) fccs ph <*> g b
BlockingQueueClosure a1 ph b1 b2 b3 b4 ->
BlockingQueueClosure a1 <$> (traverse . traverse) fccs ph <*> g b1 <*> g b2 <*> g b3 <*> g b4
TSOClosure a1 ph b1 b2 b3 b4 b5 b6 b7 a2 a3 a4 a5 a6 a7 a8 a9 a10 ->
(\ph2 c1 c2 c3 c4 c5 c6 c7 -> TSOClosure a1 ph2 c1 c2 c3 c4 c5 c6 c7 a2 a3 a4 a5 a6 a7 a8 a9 a10) <$> (traverse . traverse) fccs ph <*> g b1 <*> g b2 <*> g b3 <*> g b4 <*> g b5 <*> g b6 <*> traverse g b7
StackClosure a1 ph a2 a3 a4 a5 -> (\ph2 -> StackClosure a1 ph2 a2 a3 a4) <$> (traverse . traverse) fccs ph <*> f a5
WeakClosure a1 ph a2 a3 a4 a5 a6 ->
WeakClosure a1 <$> (traverse . traverse) fccs ph <*> g a2 <*> g a3 <*> g a4 <*> g a5 <*> traverse g a6
TVarClosure a1 ph a2 a3 a4 ->
TVarClosure a1 <$> (traverse . traverse) fccs ph <*> g a2 <*> g a3 <*> pure a4
TRecChunkClosure a1 ph a2 a3 a4 -> TRecChunkClosure a1 <$> (traverse . traverse) fccs ph <*> g a2 <*> pure a3 <*> traverse (traverse g) a4
MutPrimClosure a1 ph a2 a3 -> MutPrimClosure a1 <$> (traverse . traverse) fccs ph <*> traverse g a2 <*> pure a3
PrimClosure a1 ph a2 a3 -> PrimClosure a1 <$> (traverse . traverse) fccs ph <*> traverse g a2 <*> pure a3
CompactNFDataClosure a1 ph b1 ->
CompactNFDataClosure a1 <$> (traverse . traverse) fccs ph <*> pure b1
OtherClosure a1 ph bs ws -> OtherClosure a1 <$> (traverse . traverse) fccs ph <*> traverse g bs <*> pure ws
UnsupportedClosure i ph -> UnsupportedClosure i <$> (traverse . traverse) fccs ph