{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE RecordWildCards #-}
module Debug.RecoverRTTI.FlatClosure (
FlatClosure(..)
, getBoxedClosureData
, Box(..)
, asBox
) where
import Control.Exception (evaluate)
import Control.Monad
import GHC.Exts.Heap (Box(..), asBox)
import qualified GHC.Exts.Heap as H
data FlatClosure =
ConstrClosure {
FlatClosure -> [Box]
ptrArgs :: [Box]
, FlatClosure -> String
pkg :: String
, FlatClosure -> String
modl :: String
, FlatClosure -> String
name :: String
}
| FunClosure
| OtherClosure H.Closure
deriving (Int -> FlatClosure -> ShowS
[FlatClosure] -> ShowS
FlatClosure -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FlatClosure] -> ShowS
$cshowList :: [FlatClosure] -> ShowS
show :: FlatClosure -> String
$cshow :: FlatClosure -> String
showsPrec :: Int -> FlatClosure -> ShowS
$cshowsPrec :: Int -> FlatClosure -> ShowS
Show)
getBoxedClosureData :: Box -> IO FlatClosure
getBoxedClosureData :: Box -> IO FlatClosure
getBoxedClosureData Box
b = do
Box -> IO ()
tryForceBox Box
b
Closure -> IO FlatClosure
fromClosure forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Box -> IO Closure
H.getBoxedClosureData Box
b
where
fromClosure :: H.Closure -> IO FlatClosure
fromClosure :: Closure -> IO FlatClosure
fromClosure = \case
H.BlackholeClosure StgInfoTable
_ Box
x' -> Box -> IO FlatClosure
getBoxedClosureData Box
x'
H.IndClosure StgInfoTable
_ Box
x' -> Box -> IO FlatClosure
getBoxedClosureData Box
x'
H.ConstrClosure{[Box]
ptrArgs :: forall b. GenClosure b -> [b]
ptrArgs :: [Box]
ptrArgs, String
pkg :: forall b. GenClosure b -> String
pkg :: String
pkg, String
modl :: forall b. GenClosure b -> String
modl :: String
modl, String
name :: forall b. GenClosure b -> String
name :: String
name} ->
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ ConstrClosure{String
[Box]
name :: String
modl :: String
pkg :: String
ptrArgs :: [Box]
name :: String
modl :: String
pkg :: String
ptrArgs :: [Box]
..}
H.FunClosure{} -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ FlatClosure
FunClosure
H.PAPClosure{} -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ FlatClosure
FunClosure
H.BCOClosure{} -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ FlatClosure
FunClosure
Closure
otherClosure ->
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Closure -> FlatClosure
OtherClosure Closure
otherClosure
tryForceBox :: Box -> IO ()
tryForceBox :: Box -> IO ()
tryForceBox b :: Box
b@(Box Any
x) = do
Closure
closure <- Box -> IO Closure
H.getBoxedClosureData Box
b
case Closure
closure of
H.APClosure{} -> forall (f :: * -> *) a. Functor f => f a -> f ()
void forall a b. (a -> b) -> a -> b
$ forall a. a -> IO a
evaluate Any
x
H.ThunkClosure{} -> forall (f :: * -> *) a. Functor f => f a -> f ()
void forall a b. (a -> b) -> a -> b
$ forall a. a -> IO a
evaluate Any
x
H.SelectorClosure{} -> forall (f :: * -> *) a. Functor f => f a -> f ()
void forall a b. (a -> b) -> a -> b
$ forall a. a -> IO a
evaluate Any
x
Closure
_otherwise -> forall (m :: * -> *) a. Monad m => a -> m a
return ()