summaryrefslogtreecommitdiff
path: root/compiler/GHC/Runtime/Interpreter/Types.hs
blob: 6cbf2620eed9aabd9173b8f1dd2bce7070d13400 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
{-# LANGUAGE CPP #-}

-- | Types used by the runtime interpreter
module GHC.Runtime.Interpreter.Types
   ( Interp(..)
   , IServ(..)
   , IServInstance(..)
   , IServConfig(..)
   , IServState(..)
   )
where

import GhcPrelude

import GHCi.RemoteTypes
import GHCi.Message         ( Pipe )
import UniqFM
import Foreign

import Control.Concurrent
import System.Process   ( ProcessHandle, CreateProcess )

-- | Runtime interpreter
data Interp
   = ExternalInterp !IServConfig !IServ -- ^ External interpreter
#if defined(HAVE_INTERNAL_INTERPRETER)
   | InternalInterp                     -- ^ Internal interpreter
#endif

-- | External interpreter
--
-- The external interpreter is spawned lazily (on first use) to avoid slowing
-- down sessions that don't require it. The contents of the MVar reflects the
-- state of the interpreter (running or not).
newtype IServ = IServ (MVar IServState)

-- | State of an external interpreter
data IServState
   = IServPending                 -- ^ Not spawned yet
   | IServRunning !IServInstance  -- ^ Running

-- | Configuration needed to spawn an external interpreter
data IServConfig = IServConfig
  { iservConfProgram  :: !String   -- ^ External program to run
  , iservConfOpts     :: ![String] -- ^ Command-line options
  , iservConfProfiled :: !Bool     -- ^ Use Profiling way
  , iservConfDynamic  :: !Bool     -- ^ Use Dynamic way
  , iservConfHook     :: !(Maybe (CreateProcess -> IO ProcessHandle)) -- ^ Hook
  , iservConfTrace    :: IO ()     -- ^ Trace action executed after spawn
  }

-- | External interpreter instance
data IServInstance = IServInstance
  { iservPipe              :: !Pipe
  , iservProcess           :: !ProcessHandle
  , iservLookupSymbolCache :: !(UniqFM (Ptr ()))
  , iservPendingFrees      :: ![HValueRef]
      -- ^ Values that need to be freed before the next command is sent.
      -- Threads can append values to this list asynchronously (by modifying the
      -- IServ state MVar).
  }