{-# LANGUAGE CPP #-}
{-# LANGUAGE GHCForeignImportPrim #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedSums #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE UnliftedFFITypes #-}
module GHC.Internal.Stack.Decode.Compat (
StackFrameLocation,
StackSnapshot#,
StackInfoTable (..),
getInfoTableForStack,
getInfoTableOnStack,
advanceStackFrameLocation,
stackHead,
Box (..),
getClosureBox,
) where
import GHC.Exts
import GHC.Stack.CloneStack (StackSnapshot (..))
#if defined(PROFILING)
import GHC.Exts.Heap.InfoTableProf
#else
import GHC.Exts.Heap.InfoTable
#endif
import GHC.Internal.Heap.Closures.Compat
import qualified GHC.Internal.InfoProv.Types as InfoProv
import GHC.Internal.Stack.Constants.Compat (WordOffset)
type StackFrameLocation = (StackSnapshot, WordOffset)
data StackInfoTable = StackInfoTable
{ StackInfoTable -> Ptr StgInfoTable
infoTableStructPtr :: Ptr StgInfoTable
, StackInfoTable -> Ptr StgInfoTable
infoTablePtr :: Ptr InfoProv.StgInfoTable
, StackInfoTable -> StgInfoTable
infoTable :: StgInfoTable
}
getInfoTableOnStack :: StackSnapshot# -> WordOffset -> IO StackInfoTable
getInfoTableOnStack :: StackSnapshot# -> WordOffset -> IO StackInfoTable
getInfoTableOnStack StackSnapshot#
stackSnapshot# WordOffset
index = do
let
!(# Addr#
itbl_struct#, Addr#
itbl_ptr_ipe_key# #) = StackSnapshot# -> Word# -> (# Addr#, Addr# #)
getInfoTableAddrs# StackSnapshot#
stackSnapshot# (WordOffset -> Word#
wordOffsetToWord# WordOffset
index)
itbl_struct :: Ptr StgInfoTable
itbl_struct = Addr# -> Ptr StgInfoTable
forall a. Addr# -> Ptr a
Ptr Addr#
itbl_struct#
itbl_ptr :: Ptr StgInfoTable
itbl_ptr = Addr# -> Ptr StgInfoTable
forall a. Addr# -> Ptr a
Ptr Addr#
itbl_ptr_ipe_key#
itbl <- Ptr StgInfoTable -> IO StgInfoTable
peekItbl Ptr StgInfoTable
itbl_struct
pure
StackInfoTable
{ infoTableStructPtr = itbl_struct
, infoTablePtr = itbl_ptr
, infoTable = itbl
}
getInfoTableForStack :: StackSnapshot# -> IO StgInfoTable
getInfoTableForStack :: StackSnapshot# -> IO StgInfoTable
getInfoTableForStack StackSnapshot#
stackSnapshot# =
Ptr StgInfoTable -> IO StgInfoTable
peekItbl (Ptr StgInfoTable -> IO StgInfoTable)
-> Ptr StgInfoTable -> IO StgInfoTable
forall a b. (a -> b) -> a -> b
$
Addr# -> Ptr StgInfoTable
forall a. Addr# -> Ptr a
Ptr (StackSnapshot# -> Addr#
getStackInfoTableAddr# StackSnapshot#
stackSnapshot#)
advanceStackFrameLocation :: StackFrameLocation -> Maybe StackFrameLocation
advanceStackFrameLocation :: StackFrameLocation -> Maybe StackFrameLocation
advanceStackFrameLocation ((StackSnapshot StackSnapshot#
stackSnapshot#), WordOffset
index) =
case StackSnapshot#
-> Word# -> (# (# #) | (# StackSnapshot#, Word# #) #)
advanceStackFrameLocation# StackSnapshot#
stackSnapshot# (WordOffset -> Word#
wordOffsetToWord# WordOffset
index) of
(# (# #) | #) ->
Maybe StackFrameLocation
forall a. Maybe a
Nothing
(# | (# StackSnapshot#
s', Word#
i' #) #) ->
StackFrameLocation -> Maybe StackFrameLocation
forall a. a -> Maybe a
Just (StackSnapshot# -> StackSnapshot
StackSnapshot StackSnapshot#
s', Word# -> WordOffset
primWordToWordOffset Word#
i')
where
primWordToWordOffset :: Word# -> WordOffset
primWordToWordOffset :: Word# -> WordOffset
primWordToWordOffset Word#
w# = Word -> WordOffset
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word# -> Word
W# Word#
w#)
stackHead :: StackSnapshot# -> StackFrameLocation
stackHead :: StackSnapshot# -> StackFrameLocation
stackHead StackSnapshot#
s# = (StackSnapshot# -> StackSnapshot
StackSnapshot StackSnapshot#
s#, WordOffset
0)
getClosureBox :: StackSnapshot# -> WordOffset -> Box
getClosureBox :: StackSnapshot# -> WordOffset -> Box
getClosureBox StackSnapshot#
stackSnapshot# WordOffset
index =
case StackSnapshot# -> Word# -> Any
getStackClosure# StackSnapshot#
stackSnapshot# (WordOffset -> Word#
wordOffsetToWord# WordOffset
index) of
!Any
c -> Any -> Box
Box Any
c
foreign import prim "advanceStackFrameLocationzh"
advanceStackFrameLocation# :: StackSnapshot# -> Word# -> (# (# #) | (# StackSnapshot#, Word# #) #)
foreign import prim "getInfoTableAddrszh"
getInfoTableAddrs# :: StackSnapshot# -> Word# -> (# Addr#, Addr# #)
foreign import prim "getStackInfoTableAddrzh"
getStackInfoTableAddr# :: StackSnapshot# -> Addr#
foreign import prim "getStackClosurezh"
getStackClosure# :: StackSnapshot# -> Word# -> Any
toInt# :: Int -> Int#
toInt# :: Int -> Int#
toInt# (I# Int#
i) = Int#
i
intToWord# :: Int -> Word#
intToWord# :: Int -> Word#
intToWord# Int
i = Int# -> Word#
int2Word# (Int -> Int#
toInt# Int
i)
wordOffsetToWord# :: WordOffset -> Word#
wordOffsetToWord# :: WordOffset -> Word#
wordOffsetToWord# WordOffset
wo = Int -> Word#
intToWord# (WordOffset -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral WordOffset
wo)