Re-working of the breakpoint support
[ghc-hetmet.git] / compiler / ghci / ByteCodeInstr.lhs
1 %
2 % (c) The University of Glasgow 2000-2006
3 %
4 ByteCodeInstrs: Bytecode instruction definitions
5
6 \begin{code}
7 module ByteCodeInstr ( 
8         BCInstr(..), ProtoBCO(..), bciStackUse, BreakInfo (..) 
9   ) where
10
11 #include "HsVersions.h"
12 #include "../includes/MachDeps.h"
13
14 import ByteCodeItbls    ( ItblPtr )
15
16 import Outputable
17 import Name
18 import Id
19 import CoreSyn
20 import PprCore
21 import Literal
22 import DataCon
23 import VarSet
24 import PrimOp
25 import SMRep
26
27 import GHC.Ptr
28
29 import Module (Module)
30 import GHC.Prim
31
32
33 -- ----------------------------------------------------------------------------
34 -- Bytecode instructions
35
36 data ProtoBCO a 
37    = ProtoBCO { 
38         protoBCOName       :: a,          -- name, in some sense
39         protoBCOInstrs     :: [BCInstr],  -- instrs
40         -- arity and GC info
41         protoBCOBitmap     :: [StgWord],
42         protoBCOBitmapSize :: Int,
43         protoBCOArity      :: Int,
44         -- what the BCO came from
45         protoBCOExpr       :: Either  [AnnAlt Id VarSet] (AnnExpr Id VarSet),
46         -- malloc'd pointers
47         protoBCOPtrs       :: [Either ItblPtr (Ptr ())]
48    }
49
50 type LocalLabel = Int
51
52 data BCInstr
53    -- Messing with the stack
54    = STKCHECK  Int
55
56    -- Push locals (existing bits of the stack)
57    | PUSH_L    Int{-offset-}
58    | PUSH_LL   Int Int{-2 offsets-}
59    | PUSH_LLL  Int Int Int{-3 offsets-}
60
61    -- Push a ptr  (these all map to PUSH_G really)
62    | PUSH_G       Name
63    | PUSH_PRIMOP  PrimOp
64    | PUSH_BCO     (ProtoBCO Name)
65
66    -- Push an alt continuation
67    | PUSH_ALTS          (ProtoBCO Name)
68    | PUSH_ALTS_UNLIFTED (ProtoBCO Name) CgRep
69
70    -- Pushing literals
71    | PUSH_UBX  (Either Literal (Ptr ())) Int
72         -- push this int/float/double/addr, on the stack.  Int
73         -- is # of words to copy from literal pool.  Eitherness reflects
74         -- the difficulty of dealing with MachAddr here, mostly due to
75         -- the excessive (and unnecessary) restrictions imposed by the
76         -- designers of the new Foreign library.  In particular it is
77         -- quite impossible to convert an Addr to any other integral
78         -- type, and it appears impossible to get hold of the bits of
79         -- an addr, even though we need to to assemble BCOs.
80
81    -- various kinds of application
82    | PUSH_APPLY_N
83    | PUSH_APPLY_V
84    | PUSH_APPLY_F
85    | PUSH_APPLY_D
86    | PUSH_APPLY_L
87    | PUSH_APPLY_P
88    | PUSH_APPLY_PP
89    | PUSH_APPLY_PPP
90    | PUSH_APPLY_PPPP
91    | PUSH_APPLY_PPPPP
92    | PUSH_APPLY_PPPPPP
93
94    | SLIDE     Int{-this many-} Int{-down by this much-}
95
96    -- To do with the heap
97    | ALLOC_AP  Int      -- make an AP with this many payload words
98    | ALLOC_PAP Int Int  -- make a PAP with this arity / payload words
99    | MKAP      Int{-ptr to AP is this far down stack-} Int{-# words-}
100    | MKPAP     Int{-ptr to PAP is this far down stack-} Int{-# words-}
101    | UNPACK    Int      -- unpack N words from t.o.s Constr
102    | PACK      DataCon Int
103                         -- after assembly, the DataCon is an index into the
104                         -- itbl array
105    -- For doing case trees
106    | LABEL     LocalLabel
107    | TESTLT_I  Int    LocalLabel
108    | TESTEQ_I  Int    LocalLabel
109    | TESTLT_F  Float  LocalLabel
110    | TESTEQ_F  Float  LocalLabel
111    | TESTLT_D  Double LocalLabel
112    | TESTEQ_D  Double LocalLabel
113
114    -- The Int value is a constructor number and therefore
115    -- stored in the insn stream rather than as an offset into
116    -- the literal pool.
117    | TESTLT_P  Int    LocalLabel
118    | TESTEQ_P  Int    LocalLabel
119
120    | CASEFAIL
121    | JMP              LocalLabel
122
123    -- For doing calls to C (via glue code generated by ByteCodeFFI)
124    | CCALL            Int       -- stack frame size
125                       (Ptr ())  -- addr of the glue code
126
127    -- For doing magic ByteArray passing to foreign calls
128    | SWIZZLE          Int       -- to the ptr N words down the stack,
129                       Int       -- add M (interpreted as a signed 16-bit entity)
130
131    -- To Infinity And Beyond
132    | ENTER
133    | RETURN             -- return a lifted value
134    | RETURN_UBX CgRep -- return an unlifted value, here's its rep
135
136    -- Breakpoints 
137    | BRK_FUN          (MutableByteArray# RealWorld) Int BreakInfo
138
139 data BreakInfo 
140    = BreakInfo
141    { breakInfo_module :: Module
142    , breakInfo_number :: Int
143    , breakInfo_vars   :: [(Id,Int)]
144    }
145
146 instance Outputable BreakInfo where
147    ppr info = text "BreakInfo" <+>
148               parens (ppr (breakInfo_module info) <+>
149                       ppr (breakInfo_number info) <+>
150                       ppr (breakInfo_vars info))
151
152 -- -----------------------------------------------------------------------------
153 -- Printing bytecode instructions
154
155 instance Outputable a => Outputable (ProtoBCO a) where
156    ppr (ProtoBCO name instrs bitmap bsize arity origin malloced)
157       = (text "ProtoBCO" <+> ppr name <> char '#' <> int arity 
158                 <+> text (show malloced) <> colon)
159         $$ nest 6 (text "bitmap: " <+> text (show bsize) <+> text (show bitmap))
160         $$ nest 6 (vcat (map ppr instrs))
161         $$ case origin of
162               Left alts -> vcat (map (pprCoreAlt.deAnnAlt) alts)
163               Right rhs -> pprCoreExpr (deAnnotate rhs)
164
165 instance Outputable BCInstr where
166    ppr (STKCHECK n)          = text "STKCHECK" <+> int n
167    ppr (PUSH_L offset)       = text "PUSH_L  " <+> int offset
168    ppr (PUSH_LL o1 o2)       = text "PUSH_LL " <+> int o1 <+> int o2
169    ppr (PUSH_LLL o1 o2 o3)   = text "PUSH_LLL" <+> int o1 <+> int o2 <+> int o3
170    ppr (PUSH_G nm)           = text "PUSH_G  " <+> ppr nm
171    ppr (PUSH_PRIMOP op)      = text "PUSH_G  " <+> text "GHC.PrimopWrappers." 
172                                                <> ppr op
173    ppr (PUSH_BCO bco)        = text "PUSH_BCO" <+> nest 3 (ppr bco)
174    ppr (PUSH_ALTS bco)       = text "PUSH_ALTS " <+> ppr bco
175    ppr (PUSH_ALTS_UNLIFTED bco pk) = text "PUSH_ALTS_UNLIFTED " <+> ppr pk <+> ppr bco
176
177    ppr (PUSH_UBX (Left lit) nw) = text "PUSH_UBX" <+> parens (int nw) <+> ppr lit
178    ppr (PUSH_UBX (Right aa) nw) = text "PUSH_UBX" <+> parens (int nw) <+> text (show aa)
179    ppr PUSH_APPLY_N             = text "PUSH_APPLY_N"
180    ppr PUSH_APPLY_V             = text "PUSH_APPLY_V"
181    ppr PUSH_APPLY_F             = text "PUSH_APPLY_F"
182    ppr PUSH_APPLY_D             = text "PUSH_APPLY_D"
183    ppr PUSH_APPLY_L             = text "PUSH_APPLY_L"
184    ppr PUSH_APPLY_P             = text "PUSH_APPLY_P"
185    ppr PUSH_APPLY_PP            = text "PUSH_APPLY_PP"
186    ppr PUSH_APPLY_PPP           = text "PUSH_APPLY_PPP"
187    ppr PUSH_APPLY_PPPP          = text "PUSH_APPLY_PPPP"
188    ppr PUSH_APPLY_PPPPP         = text "PUSH_APPLY_PPPPP"
189    ppr PUSH_APPLY_PPPPPP        = text "PUSH_APPLY_PPPPPP"
190
191    ppr (SLIDE n d)           = text "SLIDE   " <+> int n <+> int d
192    ppr (ALLOC_AP sz)         = text "ALLOC_AP   " <+> int sz
193    ppr (ALLOC_PAP arity sz)  = text "ALLOC_PAP   " <+> int arity <+> int sz
194    ppr (MKAP offset sz)      = text "MKAP    " <+> int sz <+> text "words," 
195                                                <+> int offset <+> text "stkoff"
196    ppr (MKPAP offset sz)     = text "MKPAP   " <+> int sz <+> text "words,"
197                                                <+> int offset <+> text "stkoff"
198    ppr (UNPACK sz)           = text "UNPACK  " <+> int sz
199    ppr (PACK dcon sz)        = text "PACK    " <+> ppr dcon <+> ppr sz
200    ppr (LABEL     lab)       = text "__"       <> int lab <> colon
201    ppr (TESTLT_I  i lab)     = text "TESTLT_I" <+> int i <+> text "__" <> int lab
202    ppr (TESTEQ_I  i lab)     = text "TESTEQ_I" <+> int i <+> text "__" <> int lab
203    ppr (TESTLT_F  f lab)     = text "TESTLT_F" <+> float f <+> text "__" <> int lab
204    ppr (TESTEQ_F  f lab)     = text "TESTEQ_F" <+> float f <+> text "__" <> int lab
205    ppr (TESTLT_D  d lab)     = text "TESTLT_D" <+> double d <+> text "__" <> int lab
206    ppr (TESTEQ_D  d lab)     = text "TESTEQ_D" <+> double d <+> text "__" <> int lab
207    ppr (TESTLT_P  i lab)     = text "TESTLT_P" <+> int i <+> text "__" <> int lab
208    ppr (TESTEQ_P  i lab)     = text "TESTEQ_P" <+> int i <+> text "__" <> int lab
209    ppr CASEFAIL              = text "CASEFAIL"
210    ppr (JMP lab)             = text "JMP"      <+> int lab
211    ppr (CCALL off marshall_addr) = text "CCALL   " <+> int off 
212                                                 <+> text "marshall code at" 
213                                                <+> text (show marshall_addr)
214    ppr (SWIZZLE stkoff n)    = text "SWIZZLE " <+> text "stkoff" <+> int stkoff 
215                                                <+> text "by" <+> int n 
216    ppr ENTER                 = text "ENTER"
217    ppr RETURN                = text "RETURN"
218    ppr (RETURN_UBX pk)       = text "RETURN_UBX  " <+> ppr pk
219    ppr (BRK_FUN breakArray index info) = text "BRK_FUN" <+> text "<array>" <+> int index <+> ppr info 
220
221 -- -----------------------------------------------------------------------------
222 -- The stack use, in words, of each bytecode insn.  These _must_ be
223 -- correct, or overestimates of reality, to be safe.
224
225 -- NOTE: we aggregate the stack use from case alternatives too, so that
226 -- we can do a single stack check at the beginning of a function only.
227
228 -- This could all be made more accurate by keeping track of a proper
229 -- stack high water mark, but it doesn't seem worth the hassle.
230
231 protoBCOStackUse :: ProtoBCO a -> Int
232 protoBCOStackUse bco = sum (map bciStackUse (protoBCOInstrs bco))
233
234 bciStackUse :: BCInstr -> Int
235 bciStackUse STKCHECK{}            = 0
236 bciStackUse PUSH_L{}              = 1
237 bciStackUse PUSH_LL{}             = 2
238 bciStackUse PUSH_LLL{}            = 3
239 bciStackUse PUSH_G{}              = 1
240 bciStackUse PUSH_PRIMOP{}         = 1
241 bciStackUse PUSH_BCO{}            = 1
242 bciStackUse (PUSH_ALTS bco)       = 2 + protoBCOStackUse bco
243 bciStackUse (PUSH_ALTS_UNLIFTED bco _) = 2 + protoBCOStackUse bco
244 bciStackUse (PUSH_UBX _ nw)       = nw
245 bciStackUse PUSH_APPLY_N{}        = 1
246 bciStackUse PUSH_APPLY_V{}        = 1
247 bciStackUse PUSH_APPLY_F{}        = 1
248 bciStackUse PUSH_APPLY_D{}        = 1
249 bciStackUse PUSH_APPLY_L{}        = 1
250 bciStackUse PUSH_APPLY_P{}        = 1
251 bciStackUse PUSH_APPLY_PP{}       = 1
252 bciStackUse PUSH_APPLY_PPP{}      = 1
253 bciStackUse PUSH_APPLY_PPPP{}     = 1
254 bciStackUse PUSH_APPLY_PPPPP{}    = 1
255 bciStackUse PUSH_APPLY_PPPPPP{}   = 1
256 bciStackUse ALLOC_AP{}            = 1
257 bciStackUse ALLOC_PAP{}           = 1
258 bciStackUse (UNPACK sz)           = sz
259 bciStackUse LABEL{}               = 0
260 bciStackUse TESTLT_I{}            = 0
261 bciStackUse TESTEQ_I{}            = 0
262 bciStackUse TESTLT_F{}            = 0
263 bciStackUse TESTEQ_F{}            = 0
264 bciStackUse TESTLT_D{}            = 0
265 bciStackUse TESTEQ_D{}            = 0
266 bciStackUse TESTLT_P{}            = 0
267 bciStackUse TESTEQ_P{}            = 0
268 bciStackUse CASEFAIL{}            = 0
269 bciStackUse JMP{}                 = 0
270 bciStackUse ENTER{}               = 0
271 bciStackUse RETURN{}              = 0
272 bciStackUse RETURN_UBX{}          = 1
273 bciStackUse CCALL{}               = 0
274 bciStackUse SWIZZLE{}             = 0
275 bciStackUse BRK_FUN{}             = 0
276
277 -- These insns actually reduce stack use, but we need the high-tide level,
278 -- so can't use this info.  Not that it matters much.
279 bciStackUse SLIDE{}               = 0
280 bciStackUse MKAP{}                = 0
281 bciStackUse MKPAP{}               = 0
282 bciStackUse PACK{}                = 1 -- worst case is PACK 0 words
283 \end{code}