{-# LANGUAGE GADTs, RecordWildCards, MagicHash, ScopedTypeVariables, CPP,
UnboxedTuples #-}
{-# OPTIONS_GHC -fno-warn-name-shadowing #-}
module GHCi.Run
( run, redirectInterrupts
) where
import Prelude
import GHCi.CreateBCO
import GHCi.InfoTable
import GHCi.FFI
import GHCi.Message
import GHCi.ObjLink
import GHCi.RemoteTypes
import GHCi.TH
import GHCi.BreakArray
import GHCi.StaticPtrTable
import Control.Concurrent
import Control.DeepSeq
import Control.Exception
import Control.Monad
import Data.Binary
import Data.Binary.Get
import Data.ByteString (ByteString)
import qualified Data.ByteString.Unsafe as B
import GHC.Exts
import qualified GHC.Exts.Heap as Heap
import GHC.Stack
import Foreign hiding (void)
import Foreign.C
import GHC.Conc.Sync
import GHC.IO hiding ( bracket )
import System.Mem.Weak ( deRefWeak )
import Unsafe.Coerce
foreign import ccall "revertCAFs" rts_revertCAFs :: IO ()
run :: Message a -> IO a
run :: forall a. Message a -> IO a
run Message a
m = case Message a
m of
Message a
InitLinker -> ShouldRetainCAFs -> IO ()
initObjLinker ShouldRetainCAFs
RetainCAFs
Message a
RtsRevertCAFs -> IO ()
rts_revertCAFs
LookupSymbol String
str -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Ptr a -> RemotePtr a
toRemotePtr forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. String -> IO (Maybe (Ptr a))
lookupSymbol String
str
LookupClosure String
str -> String -> IO (Maybe HValueRef)
lookupClosure String
str
LoadDLL String
str -> String -> IO (Maybe String)
loadDLL String
str
LoadArchive String
str -> String -> IO ()
loadArchive String
str
LoadObj String
str -> String -> IO ()
loadObj String
str
UnloadObj String
str -> String -> IO ()
unloadObj String
str
AddLibrarySearchPath String
str -> forall a. Ptr a -> RemotePtr a
toRemotePtr forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO (Ptr ())
addLibrarySearchPath String
str
RemoveLibrarySearchPath RemotePtr ()
ptr -> Ptr () -> IO Bool
removeLibrarySearchPath (forall a. RemotePtr a -> Ptr a
fromRemotePtr RemotePtr ()
ptr)
Message a
ResolveObjs -> IO Bool
resolveObjs
FindSystemLibrary String
str -> String -> IO (Maybe String)
findSystemLibrary String
str
CreateBCOs [ByteString]
bcos -> [ResolvedBCO] -> IO [HValueRef]
createBCOs (forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (forall a. Get a -> ByteString -> a
runGet forall t. Binary t => Get t
get) [ByteString]
bcos)
FreeHValueRefs [HValueRef]
rs -> forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ forall a. RemoteRef a -> IO ()
freeRemoteRef [HValueRef]
rs
AddSptEntry Fingerprint
fpr HValueRef
r -> forall a. RemoteRef a -> IO a
localRef HValueRef
r forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Fingerprint -> HValue -> IO ()
sptAddEntry Fingerprint
fpr
EvalStmt EvalOpts
opts EvalExpr HValueRef
r -> EvalOpts
-> EvalExpr HValueRef -> IO (EvalStatus_ [HValueRef] [HValueRef])
evalStmt EvalOpts
opts EvalExpr HValueRef
r
ResumeStmt EvalOpts
opts RemoteRef (ResumeContext [HValueRef])
r -> EvalOpts
-> RemoteRef (ResumeContext [HValueRef])
-> IO (EvalStatus_ [HValueRef] [HValueRef])
resumeStmt EvalOpts
opts RemoteRef (ResumeContext [HValueRef])
r
AbandonStmt RemoteRef (ResumeContext [HValueRef])
r -> RemoteRef (ResumeContext [HValueRef]) -> IO ()
abandonStmt RemoteRef (ResumeContext [HValueRef])
r
EvalString HValueRef
r -> HValueRef -> IO (EvalResult String)
evalString HValueRef
r
EvalStringToString HValueRef
r String
s -> HValueRef -> String -> IO (EvalResult String)
evalStringToString HValueRef
r String
s
EvalIO HValueRef
r -> HValueRef -> IO (EvalResult ())
evalIO HValueRef
r
MkCostCentres String
mod [(String, String)]
ccs -> String -> [(String, String)] -> IO [RemotePtr CostCentre]
mkCostCentres String
mod [(String, String)]
ccs
CostCentreStackInfo RemotePtr CostCentreStack
ptr -> Ptr CostCentreStack -> IO [String]
ccsToStrings (forall a. RemotePtr a -> Ptr a
fromRemotePtr RemotePtr CostCentreStack
ptr)
NewBreakArray Int
sz -> forall a. a -> IO (RemoteRef a)
mkRemoteRef forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Int -> IO BreakArray
newBreakArray Int
sz
SetupBreakpoint RemoteRef BreakArray
ref Int
ix Int
cnt -> do
BreakArray
arr <- forall a. RemoteRef a -> IO a
localRef RemoteRef BreakArray
ref;
Bool
_ <- BreakArray -> Int -> Int -> IO Bool
setupBreakpoint BreakArray
arr Int
ix Int
cnt
forall (m :: * -> *) a. Monad m => a -> m a
return ()
BreakpointStatus RemoteRef BreakArray
ref Int
ix -> do
BreakArray
arr <- forall a. RemoteRef a -> IO a
localRef RemoteRef BreakArray
ref; Maybe Int
r <- BreakArray -> Int -> IO (Maybe Int)
getBreak BreakArray
arr Int
ix
case Maybe Int
r of
Maybe Int
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
Just Int
w -> forall (m :: * -> *) a. Monad m => a -> m a
return (Int
w forall a. Eq a => a -> a -> Bool
== Int
0)
GetBreakpointVar HValueRef
ref Int
ix -> do
HValue
aps <- forall a. RemoteRef a -> IO a
localRef HValueRef
ref
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall a. a -> IO (RemoteRef a)
mkRemoteRef forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< HValue -> Int -> IO (Maybe HValue)
getIdValFromApStack HValue
aps Int
ix
MallocData ByteString
bs -> ByteString -> IO (RemotePtr ())
mkString ByteString
bs
MallocStrings [ByteString]
bss -> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM ByteString -> IO (RemotePtr ())
mkString0 [ByteString]
bss
PrepFFI FFIConv
conv [FFIType]
args FFIType
res -> forall a. Ptr a -> RemotePtr a
toRemotePtr forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FFIConv -> [FFIType] -> FFIType -> IO (Ptr C_ffi_cif)
prepForeignCall FFIConv
conv [FFIType]
args FFIType
res
FreeFFI RemotePtr C_ffi_cif
p -> Ptr C_ffi_cif -> IO ()
freeForeignCallInfo (forall a. RemotePtr a -> Ptr a
fromRemotePtr RemotePtr C_ffi_cif
p)
MkConInfoTable Bool
tc Int
ptrs Int
nptrs Int
tag Int
ptrtag ByteString
desc ->
forall a. Ptr a -> RemotePtr a
toRemotePtr forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Bool
-> Int -> Int -> Int -> Int -> ByteString -> IO (Ptr StgInfoTable)
mkConInfoTable Bool
tc Int
ptrs Int
nptrs Int
tag Int
ptrtag ByteString
desc
Message a
StartTH -> IO (RemoteRef (IORef QState))
startTH
GetClosure HValueRef
ref -> do
Closure
clos <- forall a. HasHeapRep a => a -> IO Closure
Heap.getClosureData forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. RemoteRef a -> IO a
localRef HValueRef
ref
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (\(Heap.Box Any
x) -> forall a. a -> IO (RemoteRef a)
mkRemoteRef (Any -> HValue
HValue Any
x)) Closure
clos
Seq HValueRef
ref -> forall a. RemoteRef a -> IO (EvalStatus_ () ())
doSeq HValueRef
ref
ResumeSeq RemoteRef (ResumeContext ())
ref -> RemoteRef (ResumeContext ()) -> IO (EvalStatus_ () ())
resumeSeq RemoteRef (ResumeContext ())
ref
Message a
_other -> forall a. HasCallStack => String -> a
error String
"GHCi.Run.run"
evalStmt :: EvalOpts -> EvalExpr HValueRef -> IO (EvalStatus [HValueRef])
evalStmt :: EvalOpts
-> EvalExpr HValueRef -> IO (EvalStatus_ [HValueRef] [HValueRef])
evalStmt EvalOpts
opts EvalExpr HValueRef
expr = do
HValue
io <- EvalExpr HValueRef -> IO HValue
mkIO EvalExpr HValueRef
expr
forall a. EvalOpts -> IO a -> IO (EvalStatus a)
sandboxIO EvalOpts
opts forall a b. (a -> b) -> a -> b
$ do
[HValue]
rs <- forall a b. a -> b
unsafeCoerce HValue
io :: IO [HValue]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall a. a -> IO (RemoteRef a)
mkRemoteRef [HValue]
rs
where
mkIO :: EvalExpr HValueRef -> IO HValue
mkIO (EvalThis HValueRef
href) = forall a. RemoteRef a -> IO a
localRef HValueRef
href
mkIO (EvalApp EvalExpr HValueRef
l EvalExpr HValueRef
r) = do
HValue
l' <- EvalExpr HValueRef -> IO HValue
mkIO EvalExpr HValueRef
l
HValue
r' <- EvalExpr HValueRef -> IO HValue
mkIO EvalExpr HValueRef
r
forall (m :: * -> *) a. Monad m => a -> m a
return ((forall a b. a -> b
unsafeCoerce HValue
l' :: HValue -> HValue) HValue
r')
evalIO :: HValueRef -> IO (EvalResult ())
evalIO :: HValueRef -> IO (EvalResult ())
evalIO HValueRef
r = do
HValue
io <- forall a. RemoteRef a -> IO a
localRef HValueRef
r
forall a. IO a -> IO (EvalResult a)
tryEval (forall a b. a -> b
unsafeCoerce HValue
io :: IO ())
evalString :: HValueRef -> IO (EvalResult String)
evalString :: HValueRef -> IO (EvalResult String)
evalString HValueRef
r = do
HValue
io <- forall a. RemoteRef a -> IO a
localRef HValueRef
r
forall a. IO a -> IO (EvalResult a)
tryEval forall a b. (a -> b) -> a -> b
$ do
String
r <- forall a b. a -> b
unsafeCoerce HValue
io :: IO String
forall a. a -> IO a
evaluate (forall a. NFData a => a -> a
force String
r)
evalStringToString :: HValueRef -> String -> IO (EvalResult String)
evalStringToString :: HValueRef -> String -> IO (EvalResult String)
evalStringToString HValueRef
r String
str = do
HValue
io <- forall a. RemoteRef a -> IO a
localRef HValueRef
r
forall a. IO a -> IO (EvalResult a)
tryEval forall a b. (a -> b) -> a -> b
$ do
String
r <- (forall a b. a -> b
unsafeCoerce HValue
io :: String -> IO String) String
str
forall a. a -> IO a
evaluate (forall a. NFData a => a -> a
force String
r)
doSeq :: RemoteRef a -> IO (EvalStatus ())
doSeq :: forall a. RemoteRef a -> IO (EvalStatus_ () ())
doSeq RemoteRef a
ref = do
forall a. EvalOpts -> IO a -> IO (EvalStatus a)
sandboxIO EvalOpts
evalOptsSeq forall a b. (a -> b) -> a -> b
$ do
()
_ <- (forall (f :: * -> *) a. Functor f => f a -> f ()
void forall a b. (a -> b) -> a -> b
$ forall a. a -> IO a
evaluate forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. RemoteRef a -> IO a
localRef RemoteRef a
ref)
forall (m :: * -> *) a. Monad m => a -> m a
return ()
resumeSeq :: RemoteRef (ResumeContext ()) -> IO (EvalStatus ())
resumeSeq :: RemoteRef (ResumeContext ()) -> IO (EvalStatus_ () ())
resumeSeq RemoteRef (ResumeContext ())
hvref = do
ResumeContext{ThreadId
MVar ()
MVar (EvalStatus_ () ())
resumeThreadId :: forall a. ResumeContext a -> ThreadId
resumeStatusMVar :: forall a. ResumeContext a -> MVar (EvalStatus a)
resumeBreakMVar :: forall a. ResumeContext a -> MVar ()
resumeThreadId :: ThreadId
resumeStatusMVar :: MVar (EvalStatus_ () ())
resumeBreakMVar :: MVar ()
..} <- forall a. RemoteRef a -> IO a
localRef RemoteRef (ResumeContext ())
hvref
forall b a.
EvalOpts -> MVar () -> MVar (EvalStatus b) -> IO a -> IO a
withBreakAction EvalOpts
evalOptsSeq MVar ()
resumeBreakMVar MVar (EvalStatus_ () ())
resumeStatusMVar forall a b. (a -> b) -> a -> b
$
forall a. IO a -> IO a
mask_ forall a b. (a -> b) -> a -> b
$ do
forall a. MVar a -> a -> IO ()
putMVar MVar ()
resumeBreakMVar ()
forall a. ThreadId -> IO a -> IO a
redirectInterrupts ThreadId
resumeThreadId forall a b. (a -> b) -> a -> b
$ forall a. MVar a -> IO a
takeMVar MVar (EvalStatus_ () ())
resumeStatusMVar
evalOptsSeq :: EvalOpts
evalOptsSeq :: EvalOpts
evalOptsSeq = EvalOpts
{ useSandboxThread :: Bool
useSandboxThread = Bool
True
, singleStep :: Bool
singleStep = Bool
False
, breakOnException :: Bool
breakOnException = Bool
False
, breakOnError :: Bool
breakOnError = Bool
False
}
sandboxIO :: EvalOpts -> IO a -> IO (EvalStatus a)
sandboxIO :: forall a. EvalOpts -> IO a -> IO (EvalStatus a)
sandboxIO EvalOpts
opts IO a
io = do
MVar ()
breakMVar <- forall a. IO (MVar a)
newEmptyMVar
MVar (EvalStatus a)
statusMVar <- forall a. IO (MVar a)
newEmptyMVar
forall b a.
EvalOpts -> MVar () -> MVar (EvalStatus b) -> IO a -> IO a
withBreakAction EvalOpts
opts MVar ()
breakMVar MVar (EvalStatus a)
statusMVar forall a b. (a -> b) -> a -> b
$ do
let runIt :: IO (EvalStatus a)
runIt = forall a. IO (EvalResult a) -> IO (EvalStatus a)
measureAlloc forall a b. (a -> b) -> a -> b
$ forall a. IO a -> IO (EvalResult a)
tryEval forall a b. (a -> b) -> a -> b
$ forall a. EvalOpts -> IO a -> IO a
rethrow EvalOpts
opts forall a b. (a -> b) -> a -> b
$ forall a. IO a -> IO a
clearCCS IO a
io
if EvalOpts -> Bool
useSandboxThread EvalOpts
opts
then do
ThreadId
tid <- IO () -> IO ThreadId
forkIO forall a b. (a -> b) -> a -> b
$ do forall a. IO a -> IO a
unsafeUnmask IO (EvalStatus a)
runIt forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall a. MVar a -> a -> IO ()
putMVar MVar (EvalStatus a)
statusMVar
forall a. ThreadId -> IO a -> IO a
redirectInterrupts ThreadId
tid forall a b. (a -> b) -> a -> b
$ forall a. IO a -> IO a
unsafeUnmask forall a b. (a -> b) -> a -> b
$ forall a. MVar a -> IO a
takeMVar MVar (EvalStatus a)
statusMVar
else
IO (EvalStatus a)
runIt
rethrow :: EvalOpts -> IO a -> IO a
rethrow :: forall a. EvalOpts -> IO a -> IO a
rethrow EvalOpts{Bool
breakOnError :: Bool
breakOnException :: Bool
singleStep :: Bool
useSandboxThread :: Bool
breakOnError :: EvalOpts -> Bool
breakOnException :: EvalOpts -> Bool
singleStep :: EvalOpts -> Bool
useSandboxThread :: EvalOpts -> Bool
..} IO a
io =
forall e a. Exception e => IO a -> (e -> IO a) -> IO a
catch IO a
io forall a b. (a -> b) -> a -> b
$ \SomeException
se -> do
if Bool
breakOnError Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
breakOnException
then forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr CInt
exceptionFlag CInt
1
else case forall e. Exception e => SomeException -> Maybe e
fromException SomeException
se of
Just AsyncException
UserInterrupt -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
Maybe AsyncException
_ -> forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr CInt
exceptionFlag CInt
0
forall e a. Exception e => e -> IO a
throwIO SomeException
se
redirectInterrupts :: ThreadId -> IO a -> IO a
redirectInterrupts :: forall a. ThreadId -> IO a -> IO a
redirectInterrupts ThreadId
target IO a
wait = do
Weak ThreadId
wtid <- ThreadId -> IO (Weak ThreadId)
mkWeakThreadId ThreadId
target
IO a
wait forall e a. Exception e => IO a -> (e -> IO a) -> IO a
`catch` \SomeException
e -> do
Maybe ThreadId
m <- forall v. Weak v -> IO (Maybe v)
deRefWeak Weak ThreadId
wtid
case Maybe ThreadId
m of
Maybe ThreadId
Nothing -> IO a
wait
Just ThreadId
target -> do forall e. Exception e => ThreadId -> e -> IO ()
throwTo ThreadId
target (SomeException
e :: SomeException); IO a
wait
measureAlloc :: IO (EvalResult a) -> IO (EvalStatus a)
measureAlloc :: forall a. IO (EvalResult a) -> IO (EvalStatus a)
measureAlloc IO (EvalResult a)
io = do
Int64 -> IO ()
setAllocationCounter Int64
0
EvalResult a
a <- IO (EvalResult a)
io
Int64
ctr <- IO Int64
getAllocationCounter
let allocs :: Word64
allocs = forall a. Num a => a -> a
negate forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
ctr
forall (m :: * -> *) a. Monad m => a -> m a
return (forall a b. Word64 -> EvalResult a -> EvalStatus_ a b
EvalComplete Word64
allocs EvalResult a
a)
tryEval :: IO a -> IO (EvalResult a)
tryEval :: forall a. IO a -> IO (EvalResult a)
tryEval IO a
io = do
Either SomeException a
e <- forall e a. Exception e => IO a -> IO (Either e a)
try IO a
io
case Either SomeException a
e of
Left SomeException
ex -> forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. SerializableException -> EvalResult a
EvalException (SomeException -> SerializableException
toSerializableException SomeException
ex))
Right a
a -> forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> EvalResult a
EvalSuccess a
a)
withBreakAction :: EvalOpts -> MVar () -> MVar (EvalStatus b) -> IO a -> IO a
withBreakAction :: forall b a.
EvalOpts -> MVar () -> MVar (EvalStatus b) -> IO a -> IO a
withBreakAction EvalOpts
opts MVar ()
breakMVar MVar (EvalStatus b)
statusMVar IO a
act
= forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket IO (StablePtr BreakpointCallback)
setBreakAction forall {a}. StablePtr a -> IO ()
resetBreakAction (\StablePtr BreakpointCallback
_ -> IO a
act)
where
setBreakAction :: IO (StablePtr BreakpointCallback)
setBreakAction = do
StablePtr BreakpointCallback
stablePtr <- forall a. a -> IO (StablePtr a)
newStablePtr BreakpointCallback
onBreak
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr (StablePtr BreakpointCallback)
breakPointIOAction StablePtr BreakpointCallback
stablePtr
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (EvalOpts -> Bool
breakOnException EvalOpts
opts) forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr CInt
exceptionFlag CInt
1
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (EvalOpts -> Bool
singleStep EvalOpts
opts) forall a b. (a -> b) -> a -> b
$ IO ()
setStepFlag
forall (m :: * -> *) a. Monad m => a -> m a
return StablePtr BreakpointCallback
stablePtr
onBreak :: BreakpointCallback
onBreak :: BreakpointCallback
onBreak Int#
ix# Int#
uniq# Bool
is_exception HValue
apStack = do
ThreadId
tid <- IO ThreadId
myThreadId
let resume :: ResumeContext b
resume = ResumeContext
{ resumeBreakMVar :: MVar ()
resumeBreakMVar = MVar ()
breakMVar
, resumeStatusMVar :: MVar (EvalStatus b)
resumeStatusMVar = MVar (EvalStatus b)
statusMVar
, resumeThreadId :: ThreadId
resumeThreadId = ThreadId
tid }
RemoteRef (ResumeContext b)
resume_r <- forall a. a -> IO (RemoteRef a)
mkRemoteRef ResumeContext b
resume
HValueRef
apStack_r <- forall a. a -> IO (RemoteRef a)
mkRemoteRef HValue
apStack
RemotePtr CostCentreStack
ccs <- forall a. Ptr a -> RemotePtr a
toRemotePtr forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. a -> IO (Ptr CostCentreStack)
getCCSOf HValue
apStack
forall a. MVar a -> a -> IO ()
putMVar MVar (EvalStatus b)
statusMVar forall a b. (a -> b) -> a -> b
$ forall a b.
Bool
-> HValueRef
-> Int
-> Int
-> RemoteRef (ResumeContext b)
-> RemotePtr CostCentreStack
-> EvalStatus_ a b
EvalBreak Bool
is_exception HValueRef
apStack_r (Int# -> Int
I# Int#
ix#) (Int# -> Int
I# Int#
uniq#) RemoteRef (ResumeContext b)
resume_r RemotePtr CostCentreStack
ccs
forall a. MVar a -> IO a
takeMVar MVar ()
breakMVar
resetBreakAction :: StablePtr a -> IO ()
resetBreakAction StablePtr a
stablePtr = do
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr (StablePtr BreakpointCallback)
breakPointIOAction StablePtr BreakpointCallback
noBreakStablePtr
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr CInt
exceptionFlag CInt
0
IO ()
resetStepFlag
forall {a}. StablePtr a -> IO ()
freeStablePtr StablePtr a
stablePtr
resumeStmt
:: EvalOpts -> RemoteRef (ResumeContext [HValueRef])
-> IO (EvalStatus [HValueRef])
resumeStmt :: EvalOpts
-> RemoteRef (ResumeContext [HValueRef])
-> IO (EvalStatus_ [HValueRef] [HValueRef])
resumeStmt EvalOpts
opts RemoteRef (ResumeContext [HValueRef])
hvref = do
ResumeContext{ThreadId
MVar ()
MVar (EvalStatus_ [HValueRef] [HValueRef])
resumeThreadId :: ThreadId
resumeStatusMVar :: MVar (EvalStatus_ [HValueRef] [HValueRef])
resumeBreakMVar :: MVar ()
resumeThreadId :: forall a. ResumeContext a -> ThreadId
resumeStatusMVar :: forall a. ResumeContext a -> MVar (EvalStatus a)
resumeBreakMVar :: forall a. ResumeContext a -> MVar ()
..} <- forall a. RemoteRef a -> IO a
localRef RemoteRef (ResumeContext [HValueRef])
hvref
forall b a.
EvalOpts -> MVar () -> MVar (EvalStatus b) -> IO a -> IO a
withBreakAction EvalOpts
opts MVar ()
resumeBreakMVar MVar (EvalStatus_ [HValueRef] [HValueRef])
resumeStatusMVar forall a b. (a -> b) -> a -> b
$
forall a. IO a -> IO a
mask_ forall a b. (a -> b) -> a -> b
$ do
forall a. MVar a -> a -> IO ()
putMVar MVar ()
resumeBreakMVar ()
forall a. ThreadId -> IO a -> IO a
redirectInterrupts ThreadId
resumeThreadId forall a b. (a -> b) -> a -> b
$ forall a. MVar a -> IO a
takeMVar MVar (EvalStatus_ [HValueRef] [HValueRef])
resumeStatusMVar
abandonStmt :: RemoteRef (ResumeContext [HValueRef]) -> IO ()
abandonStmt :: RemoteRef (ResumeContext [HValueRef]) -> IO ()
abandonStmt RemoteRef (ResumeContext [HValueRef])
hvref = do
ResumeContext{ThreadId
MVar ()
MVar (EvalStatus_ [HValueRef] [HValueRef])
resumeThreadId :: ThreadId
resumeStatusMVar :: MVar (EvalStatus_ [HValueRef] [HValueRef])
resumeBreakMVar :: MVar ()
resumeThreadId :: forall a. ResumeContext a -> ThreadId
resumeStatusMVar :: forall a. ResumeContext a -> MVar (EvalStatus a)
resumeBreakMVar :: forall a. ResumeContext a -> MVar ()
..} <- forall a. RemoteRef a -> IO a
localRef RemoteRef (ResumeContext [HValueRef])
hvref
ThreadId -> IO ()
killThread ThreadId
resumeThreadId
forall a. MVar a -> a -> IO ()
putMVar MVar ()
resumeBreakMVar ()
EvalStatus_ [HValueRef] [HValueRef]
_ <- forall a. MVar a -> IO a
takeMVar MVar (EvalStatus_ [HValueRef] [HValueRef])
resumeStatusMVar
forall (m :: * -> *) a. Monad m => a -> m a
return ()
foreign import ccall "&rts_stop_next_breakpoint" stepFlag :: Ptr CInt
foreign import ccall "&rts_stop_on_exception" exceptionFlag :: Ptr CInt
setStepFlag :: IO ()
setStepFlag :: IO ()
setStepFlag = forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr CInt
stepFlag CInt
1
resetStepFlag :: IO ()
resetStepFlag :: IO ()
resetStepFlag = forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr CInt
stepFlag CInt
0
type BreakpointCallback
= Int#
-> Int#
-> Bool
-> HValue
-> IO ()
foreign import ccall "&rts_breakpoint_io_action"
breakPointIOAction :: Ptr (StablePtr BreakpointCallback)
noBreakStablePtr :: StablePtr BreakpointCallback
noBreakStablePtr :: StablePtr BreakpointCallback
noBreakStablePtr = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ forall a. a -> IO (StablePtr a)
newStablePtr BreakpointCallback
noBreakAction
noBreakAction :: BreakpointCallback
noBreakAction :: BreakpointCallback
noBreakAction Int#
_ Int#
_ Bool
False HValue
_ = String -> IO ()
putStrLn String
"*** Ignoring breakpoint"
noBreakAction Int#
_ Int#
_ Bool
True HValue
_ = forall (m :: * -> *) a. Monad m => a -> m a
return ()
mkString :: ByteString -> IO (RemotePtr ())
mkString :: ByteString -> IO (RemotePtr ())
mkString ByteString
bs = forall a. ByteString -> (CStringLen -> IO a) -> IO a
B.unsafeUseAsCStringLen ByteString
bs forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
cstr,Int
len) -> do
Ptr CChar
ptr <- forall a. Int -> IO (Ptr a)
mallocBytes Int
len
forall a. Ptr a -> Ptr a -> Int -> IO ()
copyBytes Ptr CChar
ptr Ptr CChar
cstr Int
len
forall (m :: * -> *) a. Monad m => a -> m a
return (forall a b. RemotePtr a -> RemotePtr b
castRemotePtr (forall a. Ptr a -> RemotePtr a
toRemotePtr Ptr CChar
ptr))
mkString0 :: ByteString -> IO (RemotePtr ())
mkString0 :: ByteString -> IO (RemotePtr ())
mkString0 ByteString
bs = forall a. ByteString -> (CStringLen -> IO a) -> IO a
B.unsafeUseAsCStringLen ByteString
bs forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
cstr,Int
len) -> do
Ptr CChar
ptr <- forall a. Int -> IO (Ptr a)
mallocBytes (Int
lenforall a. Num a => a -> a -> a
+Int
1)
forall a. Ptr a -> Ptr a -> Int -> IO ()
copyBytes Ptr CChar
ptr Ptr CChar
cstr Int
len
forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff (Ptr CChar
ptr :: Ptr CChar) Int
len CChar
0
forall (m :: * -> *) a. Monad m => a -> m a
return (forall a b. RemotePtr a -> RemotePtr b
castRemotePtr (forall a. Ptr a -> RemotePtr a
toRemotePtr Ptr CChar
ptr))
mkCostCentres :: String -> [(String,String)] -> IO [RemotePtr CostCentre]
#if defined(PROFILING)
mkCostCentres mod ccs = do
c_module <- newCString mod
mapM (mk_one c_module) ccs
where
mk_one c_module (decl_path,srcspan) = do
c_name <- newCString decl_path
c_srcspan <- newCString srcspan
toRemotePtr <$> c_mkCostCentre c_name c_module c_srcspan
foreign import ccall unsafe "mkCostCentre"
c_mkCostCentre :: Ptr CChar -> Ptr CChar -> Ptr CChar -> IO (Ptr CostCentre)
#else
mkCostCentres :: String -> [(String, String)] -> IO [RemotePtr CostCentre]
mkCostCentres String
_ [(String, String)]
_ = forall (m :: * -> *) a. Monad m => a -> m a
return []
#endif
getIdValFromApStack :: HValue -> Int -> IO (Maybe HValue)
getIdValFromApStack :: HValue -> Int -> IO (Maybe HValue)
getIdValFromApStack HValue
apStack (I# Int#
stackDepth) = do
case forall a b. a -> Int# -> (# Int#, b #)
getApStackVal# HValue
apStack Int#
stackDepth of
(# Int#
ok, Any
result #) ->
case Int#
ok of
Int#
0# -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
Int#
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Maybe a
Just (unsafeCoerce# :: forall a b. a -> b
unsafeCoerce# Any
result))