Implement unboxed sum primitive type
[ghc.git] / compiler / ghci / ByteCodeGen.hs
1 {-# LANGUAGE CPP, MagicHash, RecordWildCards #-}
2 --
3 -- (c) The University of Glasgow 2002-2006
4 --
5
6 -- | ByteCodeGen: Generate bytecode from Core
7 module ByteCodeGen ( UnlinkedBCO, byteCodeGen, coreExprToBCOs ) where
8
9 #include "HsVersions.h"
10
11 import ByteCodeInstr
12 import ByteCodeAsm
13 import ByteCodeTypes
14
15 import GHCi
16 import GHCi.FFI
17 import GHCi.RemoteTypes
18 import BasicTypes
19 import DynFlags
20 import Outputable
21 import Platform
22 import Name
23 import MkId
24 import Id
25 import ForeignCall
26 import HscTypes
27 import CoreUtils
28 import CoreSyn
29 import PprCore
30 import Literal
31 import PrimOp
32 import CoreFVs
33 import Type
34 import RepType
35 import Kind ( isLiftedTypeKind )
36 import DataCon
37 import TyCon
38 import Util
39 import VarSet
40 import TysPrim
41 import ErrUtils
42 import Unique
43 import FastString
44 import Panic
45 import StgCmmLayout ( ArgRep(..), toArgRep, argRepSizeW )
46 import SMRep
47 import Bitmap
48 import OrdList
49 import Maybes
50
51 import Data.List
52 import Foreign
53 import Control.Monad
54 import Data.Char
55
56 import UniqSupply
57 import Module
58 import Control.Arrow ( second )
59
60 import Data.Array
61 import Data.Map (Map)
62 import Data.IntMap (IntMap)
63 import qualified Data.Map as Map
64 import qualified Data.IntMap as IntMap
65 import qualified FiniteMap as Map
66 import Data.Ord
67 import GHC.Stack.CCS
68
69 -- -----------------------------------------------------------------------------
70 -- Generating byte code for a complete module
71
72 byteCodeGen :: HscEnv
73 -> Module
74 -> CoreProgram
75 -> [TyCon]
76 -> Maybe ModBreaks
77 -> IO CompiledByteCode
78 byteCodeGen hsc_env this_mod binds tycs mb_modBreaks
79 = withTiming (pure dflags)
80 (text "ByteCodeGen"<+>brackets (ppr this_mod))
81 (const ()) $ do
82 let flatBinds = [ (bndr, simpleFreeVars rhs)
83 | (bndr, rhs) <- flattenBinds binds]
84
85 us <- mkSplitUniqSupply 'y'
86 (BcM_State{..}, proto_bcos) <-
87 runBc hsc_env us this_mod mb_modBreaks $
88 mapM schemeTopBind flatBinds
89
90 when (notNull ffis)
91 (panic "ByteCodeGen.byteCodeGen: missing final emitBc?")
92
93 dumpIfSet_dyn dflags Opt_D_dump_BCOs
94 "Proto-BCOs" (vcat (intersperse (char ' ') (map ppr proto_bcos)))
95
96 assembleBCOs hsc_env proto_bcos tycs
97 (case modBreaks of
98 Nothing -> Nothing
99 Just mb -> Just mb{ modBreaks_breakInfo = breakInfo })
100 where dflags = hsc_dflags hsc_env
101
102 -- -----------------------------------------------------------------------------
103 -- Generating byte code for an expression
104
105 -- Returns: the root BCO for this expression
106 coreExprToBCOs :: HscEnv
107 -> Module
108 -> CoreExpr
109 -> IO UnlinkedBCO
110 coreExprToBCOs hsc_env this_mod expr
111 = withTiming (pure dflags)
112 (text "ByteCodeGen"<+>brackets (ppr this_mod))
113 (const ()) $ do
114 -- create a totally bogus name for the top-level BCO; this
115 -- should be harmless, since it's never used for anything
116 let invented_name = mkSystemVarName (mkPseudoUniqueE 0) (fsLit "ExprTopLevel")
117 invented_id = Id.mkLocalId invented_name (panic "invented_id's type")
118
119 -- the uniques are needed to generate fresh variables when we introduce new
120 -- let bindings for ticked expressions
121 us <- mkSplitUniqSupply 'y'
122 (BcM_State _dflags _us _this_mod _final_ctr mallocd _ _ , proto_bco)
123 <- runBc hsc_env us this_mod Nothing $
124 schemeTopBind (invented_id, simpleFreeVars expr)
125
126 when (notNull mallocd)
127 (panic "ByteCodeGen.coreExprToBCOs: missing final emitBc?")
128
129 dumpIfSet_dyn dflags Opt_D_dump_BCOs "Proto-BCOs" (ppr proto_bco)
130
131 assembleOneBCO hsc_env proto_bco
132 where dflags = hsc_dflags hsc_env
133
134 -- The regular freeVars function gives more information than is useful to
135 -- us here. simpleFreeVars does the impedence matching.
136 simpleFreeVars :: CoreExpr -> AnnExpr Id DVarSet
137 simpleFreeVars = go . freeVars
138 where
139 go :: AnnExpr Id FVAnn -> AnnExpr Id DVarSet
140 go (ann, e) = (freeVarsOfAnn ann, go' e)
141
142 go' :: AnnExpr' Id FVAnn -> AnnExpr' Id DVarSet
143 go' (AnnVar id) = AnnVar id
144 go' (AnnLit lit) = AnnLit lit
145 go' (AnnLam bndr body) = AnnLam bndr (go body)
146 go' (AnnApp fun arg) = AnnApp (go fun) (go arg)
147 go' (AnnCase scrut bndr ty alts) = AnnCase (go scrut) bndr ty (map go_alt alts)
148 go' (AnnLet bind body) = AnnLet (go_bind bind) (go body)
149 go' (AnnCast expr (ann, co)) = AnnCast (go expr) (freeVarsOfAnn ann, co)
150 go' (AnnTick tick body) = AnnTick tick (go body)
151 go' (AnnType ty) = AnnType ty
152 go' (AnnCoercion co) = AnnCoercion co
153
154 go_alt (con, args, expr) = (con, args, go expr)
155
156 go_bind (AnnNonRec bndr rhs) = AnnNonRec bndr (go rhs)
157 go_bind (AnnRec pairs) = AnnRec (map (second go) pairs)
158
159 -- -----------------------------------------------------------------------------
160 -- Compilation schema for the bytecode generator
161
162 type BCInstrList = OrdList BCInstr
163
164 type Sequel = Word -- back off to this depth before ENTER
165
166 -- Maps Ids to the offset from the stack _base_ so we don't have
167 -- to mess with it after each push/pop.
168 type BCEnv = Map Id Word -- To find vars on the stack
169
170 {-
171 ppBCEnv :: BCEnv -> SDoc
172 ppBCEnv p
173 = text "begin-env"
174 $$ nest 4 (vcat (map pp_one (sortBy cmp_snd (Map.toList p))))
175 $$ text "end-env"
176 where
177 pp_one (var, offset) = int offset <> colon <+> ppr var <+> ppr (bcIdArgRep var)
178 cmp_snd x y = compare (snd x) (snd y)
179 -}
180
181 -- Create a BCO and do a spot of peephole optimisation on the insns
182 -- at the same time.
183 mkProtoBCO
184 :: DynFlags
185 -> name
186 -> BCInstrList
187 -> Either [AnnAlt Id DVarSet] (AnnExpr Id DVarSet)
188 -> Int
189 -> Word16
190 -> [StgWord]
191 -> Bool -- True <=> is a return point, rather than a function
192 -> [FFIInfo]
193 -> ProtoBCO name
194 mkProtoBCO dflags nm instrs_ordlist origin arity bitmap_size bitmap is_ret ffis
195 = ProtoBCO {
196 protoBCOName = nm,
197 protoBCOInstrs = maybe_with_stack_check,
198 protoBCOBitmap = bitmap,
199 protoBCOBitmapSize = bitmap_size,
200 protoBCOArity = arity,
201 protoBCOExpr = origin,
202 protoBCOFFIs = ffis
203 }
204 where
205 -- Overestimate the stack usage (in words) of this BCO,
206 -- and if >= iNTERP_STACK_CHECK_THRESH, add an explicit
207 -- stack check. (The interpreter always does a stack check
208 -- for iNTERP_STACK_CHECK_THRESH words at the start of each
209 -- BCO anyway, so we only need to add an explicit one in the
210 -- (hopefully rare) cases when the (overestimated) stack use
211 -- exceeds iNTERP_STACK_CHECK_THRESH.
212 maybe_with_stack_check
213 | is_ret && stack_usage < fromIntegral (aP_STACK_SPLIM dflags) = peep_d
214 -- don't do stack checks at return points,
215 -- everything is aggregated up to the top BCO
216 -- (which must be a function).
217 -- That is, unless the stack usage is >= AP_STACK_SPLIM,
218 -- see bug #1466.
219 | stack_usage >= fromIntegral iNTERP_STACK_CHECK_THRESH
220 = STKCHECK stack_usage : peep_d
221 | otherwise
222 = peep_d -- the supposedly common case
223
224 -- We assume that this sum doesn't wrap
225 stack_usage = sum (map bciStackUse peep_d)
226
227 -- Merge local pushes
228 peep_d = peep (fromOL instrs_ordlist)
229
230 peep (PUSH_L off1 : PUSH_L off2 : PUSH_L off3 : rest)
231 = PUSH_LLL off1 (off2-1) (off3-2) : peep rest
232 peep (PUSH_L off1 : PUSH_L off2 : rest)
233 = PUSH_LL off1 (off2-1) : peep rest
234 peep (i:rest)
235 = i : peep rest
236 peep []
237 = []
238
239 argBits :: DynFlags -> [ArgRep] -> [Bool]
240 argBits _ [] = []
241 argBits dflags (rep : args)
242 | isFollowableArg rep = False : argBits dflags args
243 | otherwise = take (argRepSizeW dflags rep) (repeat True) ++ argBits dflags args
244
245 -- -----------------------------------------------------------------------------
246 -- schemeTopBind
247
248 -- Compile code for the right-hand side of a top-level binding
249
250 schemeTopBind :: (Id, AnnExpr Id DVarSet) -> BcM (ProtoBCO Name)
251
252
253 schemeTopBind (id, rhs)
254 | Just data_con <- isDataConWorkId_maybe id,
255 isNullaryRepDataCon data_con = do
256 dflags <- getDynFlags
257 -- Special case for the worker of a nullary data con.
258 -- It'll look like this: Nil = /\a -> Nil a
259 -- If we feed it into schemeR, we'll get
260 -- Nil = Nil
261 -- because mkConAppCode treats nullary constructor applications
262 -- by just re-using the single top-level definition. So
263 -- for the worker itself, we must allocate it directly.
264 -- ioToBc (putStrLn $ "top level BCO")
265 emitBc (mkProtoBCO dflags (getName id) (toOL [PACK data_con 0, ENTER])
266 (Right rhs) 0 0 [{-no bitmap-}] False{-not alts-})
267
268 | otherwise
269 = schemeR [{- No free variables -}] (id, rhs)
270
271
272 -- -----------------------------------------------------------------------------
273 -- schemeR
274
275 -- Compile code for a right-hand side, to give a BCO that,
276 -- when executed with the free variables and arguments on top of the stack,
277 -- will return with a pointer to the result on top of the stack, after
278 -- removing the free variables and arguments.
279 --
280 -- Park the resulting BCO in the monad. Also requires the
281 -- variable to which this value was bound, so as to give the
282 -- resulting BCO a name.
283
284 schemeR :: [Id] -- Free vars of the RHS, ordered as they
285 -- will appear in the thunk. Empty for
286 -- top-level things, which have no free vars.
287 -> (Id, AnnExpr Id DVarSet)
288 -> BcM (ProtoBCO Name)
289 schemeR fvs (nm, rhs)
290 {-
291 | trace (showSDoc (
292 (char ' '
293 $$ (ppr.filter (not.isTyVar).dVarSetElems.fst) rhs
294 $$ pprCoreExpr (deAnnotate rhs)
295 $$ char ' '
296 ))) False
297 = undefined
298 | otherwise
299 -}
300 = schemeR_wrk fvs nm rhs (collect rhs)
301
302 collect :: AnnExpr Id DVarSet -> ([Var], AnnExpr' Id DVarSet)
303 collect (_, e) = go [] e
304 where
305 go xs e | Just e' <- bcView e = go xs e'
306 go xs (AnnLam x (_,e))
307 | repTypeArgs (idType x) `lengthExceeds` 1
308 = multiValException
309 | otherwise
310 = go (x:xs) e
311 go xs not_lambda = (reverse xs, not_lambda)
312
313 schemeR_wrk :: [Id] -> Id -> AnnExpr Id DVarSet -> ([Var], AnnExpr' Var DVarSet) -> BcM (ProtoBCO Name)
314 schemeR_wrk fvs nm original_body (args, body)
315 = do
316 dflags <- getDynFlags
317 let
318 all_args = reverse args ++ fvs
319 arity = length all_args
320 -- all_args are the args in reverse order. We're compiling a function
321 -- \fv1..fvn x1..xn -> e
322 -- i.e. the fvs come first
323
324 szsw_args = map (fromIntegral . idSizeW dflags) all_args
325 szw_args = sum szsw_args
326 p_init = Map.fromList (zip all_args (mkStackOffsets 0 szsw_args))
327
328 -- make the arg bitmap
329 bits = argBits dflags (reverse (map bcIdArgRep all_args))
330 bitmap_size = genericLength bits
331 bitmap = mkBitmap dflags bits
332 body_code <- schemeER_wrk szw_args p_init body
333
334 emitBc (mkProtoBCO dflags (getName nm) body_code (Right original_body)
335 arity bitmap_size bitmap False{-not alts-})
336
337 -- introduce break instructions for ticked expressions
338 schemeER_wrk :: Word -> BCEnv -> AnnExpr' Id DVarSet -> BcM BCInstrList
339 schemeER_wrk d p rhs
340 | AnnTick (Breakpoint tick_no fvs) (_annot, newRhs) <- rhs
341 = do code <- schemeE (fromIntegral d) 0 p newRhs
342 cc_arr <- getCCArray
343 this_mod <- moduleName <$> getCurrentModule
344 let idOffSets = getVarOffSets d p fvs
345 let breakInfo = CgBreakInfo
346 { cgb_vars = idOffSets
347 , cgb_resty = exprType (deAnnotate' newRhs)
348 }
349 newBreakInfo tick_no breakInfo
350 dflags <- getDynFlags
351 let cc | interpreterProfiled dflags = cc_arr ! tick_no
352 | otherwise = toRemotePtr nullPtr
353 let breakInstr = BRK_FUN (fromIntegral tick_no) (getUnique this_mod) cc
354 return $ breakInstr `consOL` code
355 | otherwise = schemeE (fromIntegral d) 0 p rhs
356
357 getVarOffSets :: Word -> BCEnv -> [Id] -> [(Id, Word16)]
358 getVarOffSets d p = catMaybes . map (getOffSet d p)
359
360 getOffSet :: Word -> BCEnv -> Id -> Maybe (Id, Word16)
361 getOffSet d env id
362 = case lookupBCEnv_maybe id env of
363 Nothing -> Nothing
364 Just offset -> Just (id, trunc16 $ d - offset)
365
366 trunc16 :: Word -> Word16
367 trunc16 w
368 | w > fromIntegral (maxBound :: Word16)
369 = panic "stack depth overflow"
370 | otherwise
371 = fromIntegral w
372
373 fvsToEnv :: BCEnv -> DVarSet -> [Id]
374 -- Takes the free variables of a right-hand side, and
375 -- delivers an ordered list of the local variables that will
376 -- be captured in the thunk for the RHS
377 -- The BCEnv argument tells which variables are in the local
378 -- environment: these are the ones that should be captured
379 --
380 -- The code that constructs the thunk, and the code that executes
381 -- it, have to agree about this layout
382 fvsToEnv p fvs = [v | v <- dVarSetElems fvs,
383 isId v, -- Could be a type variable
384 v `Map.member` p]
385
386 -- -----------------------------------------------------------------------------
387 -- schemeE
388
389 returnUnboxedAtom :: Word -> Sequel -> BCEnv
390 -> AnnExpr' Id DVarSet -> ArgRep
391 -> BcM BCInstrList
392 -- Returning an unlifted value.
393 -- Heave it on the stack, SLIDE, and RETURN.
394 returnUnboxedAtom d s p e e_rep
395 = do (push, szw) <- pushAtom d p e
396 return (push -- value onto stack
397 `appOL` mkSLIDE szw (d-s) -- clear to sequel
398 `snocOL` RETURN_UBX e_rep) -- go
399
400 -- Compile code to apply the given expression to the remaining args
401 -- on the stack, returning a HNF.
402 schemeE :: Word -> Sequel -> BCEnv -> AnnExpr' Id DVarSet -> BcM BCInstrList
403
404 schemeE d s p e
405 | Just e' <- bcView e
406 = schemeE d s p e'
407
408 -- Delegate tail-calls to schemeT.
409 schemeE d s p e@(AnnApp _ _) = schemeT d s p e
410
411 schemeE d s p e@(AnnLit lit) = returnUnboxedAtom d s p e (typeArgRep (literalType lit))
412 schemeE d s p e@(AnnCoercion {}) = returnUnboxedAtom d s p e V
413
414 schemeE d s p e@(AnnVar v)
415 | isUnliftedType (idType v) = returnUnboxedAtom d s p e (bcIdArgRep v)
416 | otherwise = schemeT d s p e
417
418 schemeE d s p (AnnLet (AnnNonRec x (_,rhs)) (_,body))
419 | (AnnVar v, args_r_to_l) <- splitApp rhs,
420 Just data_con <- isDataConWorkId_maybe v,
421 dataConRepArity data_con == length args_r_to_l
422 = do -- Special case for a non-recursive let whose RHS is a
423 -- saturatred constructor application.
424 -- Just allocate the constructor and carry on
425 alloc_code <- mkConAppCode d s p data_con args_r_to_l
426 body_code <- schemeE (d+1) s (Map.insert x d p) body
427 return (alloc_code `appOL` body_code)
428
429 -- General case for let. Generates correct, if inefficient, code in
430 -- all situations.
431 schemeE d s p (AnnLet binds (_,body)) = do
432 dflags <- getDynFlags
433 let (xs,rhss) = case binds of AnnNonRec x rhs -> ([x],[rhs])
434 AnnRec xs_n_rhss -> unzip xs_n_rhss
435 n_binds = genericLength xs
436
437 fvss = map (fvsToEnv p' . fst) rhss
438
439 -- Sizes of free vars
440 sizes = map (\rhs_fvs -> sum (map (fromIntegral . idSizeW dflags) rhs_fvs)) fvss
441
442 -- the arity of each rhs
443 arities = map (genericLength . fst . collect) rhss
444
445 -- This p', d' defn is safe because all the items being pushed
446 -- are ptrs, so all have size 1. d' and p' reflect the stack
447 -- after the closures have been allocated in the heap (but not
448 -- filled in), and pointers to them parked on the stack.
449 p' = Map.insertList (zipE xs (mkStackOffsets d (genericReplicate n_binds 1))) p
450 d' = d + fromIntegral n_binds
451 zipE = zipEqual "schemeE"
452
453 -- ToDo: don't build thunks for things with no free variables
454 build_thunk _ [] size bco off arity
455 = return (PUSH_BCO bco `consOL` unitOL (mkap (off+size) size))
456 where
457 mkap | arity == 0 = MKAP
458 | otherwise = MKPAP
459 build_thunk dd (fv:fvs) size bco off arity = do
460 (push_code, pushed_szw) <- pushAtom dd p' (AnnVar fv)
461 more_push_code <- build_thunk (dd + fromIntegral pushed_szw) fvs size bco off arity
462 return (push_code `appOL` more_push_code)
463
464 alloc_code = toOL (zipWith mkAlloc sizes arities)
465 where mkAlloc sz 0
466 | is_tick = ALLOC_AP_NOUPD sz
467 | otherwise = ALLOC_AP sz
468 mkAlloc sz arity = ALLOC_PAP arity sz
469
470 is_tick = case binds of
471 AnnNonRec id _ -> occNameFS (getOccName id) == tickFS
472 _other -> False
473
474 compile_bind d' fvs x rhs size arity off = do
475 bco <- schemeR fvs (x,rhs)
476 build_thunk d' fvs size bco off arity
477
478 compile_binds =
479 [ compile_bind d' fvs x rhs size arity n
480 | (fvs, x, rhs, size, arity, n) <-
481 zip6 fvss xs rhss sizes arities [n_binds, n_binds-1 .. 1]
482 ]
483 body_code <- schemeE d' s p' body
484 thunk_codes <- sequence compile_binds
485 return (alloc_code `appOL` concatOL thunk_codes `appOL` body_code)
486
487 -- Introduce a let binding for a ticked case expression. This rule
488 -- *should* only fire when the expression was not already let-bound
489 -- (the code gen for let bindings should take care of that). Todo: we
490 -- call exprFreeVars on a deAnnotated expression, this may not be the
491 -- best way to calculate the free vars but it seemed like the least
492 -- intrusive thing to do
493 schemeE d s p exp@(AnnTick (Breakpoint _id _fvs) _rhs)
494 | isLiftedTypeKind (typeKind ty)
495 = do id <- newId ty
496 -- Todo: is emptyVarSet correct on the next line?
497 let letExp = AnnLet (AnnNonRec id (fvs, exp)) (emptyDVarSet, AnnVar id)
498 schemeE d s p letExp
499
500 | otherwise
501 = do -- If the result type is not definitely lifted, then we must generate
502 -- let f = \s . tick<n> e
503 -- in f realWorld#
504 -- When we stop at the breakpoint, _result will have an unlifted
505 -- type and hence won't be bound in the environment, but the
506 -- breakpoint will otherwise work fine.
507 --
508 -- NB (Trac #12007) this /also/ applies for if (ty :: TYPE r), where
509 -- r :: RuntimeRep is a variable. This can happen in the
510 -- continuations for a pattern-synonym matcher
511 -- match = /\(r::RuntimeRep) /\(a::TYPE r).
512 -- \(k :: Int -> a) \(v::T).
513 -- case v of MkV n -> k n
514 -- Here (k n) :: a :: Type r, so we don't know if it's lifted
515 -- or not; but that should be fine provided we add that void arg.
516
517 id <- newId (mkFunTy realWorldStatePrimTy ty)
518 st <- newId realWorldStatePrimTy
519 let letExp = AnnLet (AnnNonRec id (fvs, AnnLam st (emptyDVarSet, exp)))
520 (emptyDVarSet, (AnnApp (emptyDVarSet, AnnVar id)
521 (emptyDVarSet, AnnVar realWorldPrimId)))
522 schemeE d s p letExp
523
524 where
525 exp' = deAnnotate' exp
526 fvs = exprFreeVarsDSet exp'
527 ty = exprType exp'
528
529 -- ignore other kinds of tick
530 schemeE d s p (AnnTick _ (_, rhs)) = schemeE d s p rhs
531
532 schemeE d s p (AnnCase (_,scrut) _ _ []) = schemeE d s p scrut
533 -- no alts: scrut is guaranteed to diverge
534
535 schemeE d s p (AnnCase scrut bndr _ [(DataAlt dc, [bind1, bind2], rhs)])
536 | isUnboxedTupleCon dc -- handles pairs with one void argument (e.g. state token)
537 , [rep_ty1] <- repTypeArgs (idType bind1)
538 , [rep_ty2] <- repTypeArgs (idType bind2)
539 -- Convert
540 -- case .... of x { (# V'd-thing, a #) -> ... }
541 -- to
542 -- case .... of a { DEFAULT -> ... }
543 -- because the return convention for both are identical.
544 --
545 -- Note that it does not matter losing the void-rep thing from the
546 -- envt (it won't be bound now) because we never look such things up.
547 , Just res <- case () of
548 _ | isVoidTy rep_ty1 && not (isVoidTy rep_ty2)
549 -> Just $ doCase d s p scrut bind2 [(DEFAULT, [], rhs)] (Just bndr)
550 | isVoidTy rep_ty2 && not (isVoidTy rep_ty1)
551 -> Just $ doCase d s p scrut bind1 [(DEFAULT, [], rhs)] (Just bndr)
552 | otherwise
553 -> Nothing
554 = res
555
556 schemeE d s p (AnnCase scrut bndr _ [(DataAlt dc, [bind1], rhs)])
557 | isUnboxedTupleCon dc
558 , repTypeArgs (idType bndr) `lengthIs` 1 -- handles unit tuples
559 = doCase d s p scrut bind1 [(DEFAULT, [], rhs)] (Just bndr)
560
561 schemeE d s p (AnnCase scrut bndr _ alt@[(DEFAULT, [], _)])
562 | isUnboxedTupleType (idType bndr)
563 , [ty] <- repTypeArgs (idType bndr)
564 -- handles any pattern with a single non-void binder; in particular I/O
565 -- monad returns (# RealWorld#, a #)
566 = doCase d s p scrut (bndr `setIdType` ty) alt (Just bndr)
567
568 schemeE d s p (AnnCase scrut bndr _ alts)
569 = doCase d s p scrut bndr alts Nothing{-not an unboxed tuple-}
570
571 schemeE _ _ _ expr
572 = pprPanic "ByteCodeGen.schemeE: unhandled case"
573 (pprCoreExpr (deAnnotate' expr))
574
575 {-
576 Ticked Expressions
577 ------------------
578
579 The idea is that the "breakpoint<n,fvs> E" is really just an annotation on
580 the code. When we find such a thing, we pull out the useful information,
581 and then compile the code as if it was just the expression E.
582
583 -}
584
585 -- Compile code to do a tail call. Specifically, push the fn,
586 -- slide the on-stack app back down to the sequel depth,
587 -- and enter. Four cases:
588 --
589 -- 0. (Nasty hack).
590 -- An application "GHC.Prim.tagToEnum# <type> unboxed-int".
591 -- The int will be on the stack. Generate a code sequence
592 -- to convert it to the relevant constructor, SLIDE and ENTER.
593 --
594 -- 1. The fn denotes a ccall. Defer to generateCCall.
595 --
596 -- 2. (Another nasty hack). Spot (# a::V, b #) and treat
597 -- it simply as b -- since the representations are identical
598 -- (the V takes up zero stack space). Also, spot
599 -- (# b #) and treat it as b.
600 --
601 -- 3. Application of a constructor, by defn saturated.
602 -- Split the args into ptrs and non-ptrs, and push the nonptrs,
603 -- then the ptrs, and then do PACK and RETURN.
604 --
605 -- 4. Otherwise, it must be a function call. Push the args
606 -- right to left, SLIDE and ENTER.
607
608 schemeT :: Word -- Stack depth
609 -> Sequel -- Sequel depth
610 -> BCEnv -- stack env
611 -> AnnExpr' Id DVarSet
612 -> BcM BCInstrList
613
614 schemeT d s p app
615
616 -- | trace ("schemeT: env in = \n" ++ showSDocDebug (ppBCEnv p)) False
617 -- = panic "schemeT ?!?!"
618
619 -- | trace ("\nschemeT\n" ++ showSDoc (pprCoreExpr (deAnnotate' app)) ++ "\n") False
620 -- = error "?!?!"
621
622 -- Case 0
623 | Just (arg, constr_names) <- maybe_is_tagToEnum_call app
624 = implement_tagToId d s p arg constr_names
625
626 -- Case 1
627 | Just (CCall ccall_spec) <- isFCallId_maybe fn
628 = if isSupportedCConv ccall_spec
629 then generateCCall d s p ccall_spec fn args_r_to_l
630 else unsupportedCConvException
631
632
633 -- Case 2: Constructor application
634 | Just con <- maybe_saturated_dcon
635 , isUnboxedTupleCon con
636 = case args_r_to_l of
637 [arg1,arg2] | isVAtom arg1 ->
638 unboxedTupleReturn d s p arg2
639 [arg1,arg2] | isVAtom arg2 ->
640 unboxedTupleReturn d s p arg1
641 _other -> multiValException
642
643 -- Case 3: Ordinary data constructor
644 | Just con <- maybe_saturated_dcon
645 = do alloc_con <- mkConAppCode d s p con args_r_to_l
646 return (alloc_con `appOL`
647 mkSLIDE 1 (d - s) `snocOL`
648 ENTER)
649
650 -- Case 4: Tail call of function
651 | otherwise
652 = doTailCall d s p fn args_r_to_l
653
654 where
655 -- Extract the args (R->L) and fn
656 -- The function will necessarily be a variable,
657 -- because we are compiling a tail call
658 (AnnVar fn, args_r_to_l) = splitApp app
659
660 -- Only consider this to be a constructor application iff it is
661 -- saturated. Otherwise, we'll call the constructor wrapper.
662 n_args = length args_r_to_l
663 maybe_saturated_dcon
664 = case isDataConWorkId_maybe fn of
665 Just con | dataConRepArity con == n_args -> Just con
666 _ -> Nothing
667
668 -- -----------------------------------------------------------------------------
669 -- Generate code to build a constructor application,
670 -- leaving it on top of the stack
671
672 mkConAppCode :: Word -> Sequel -> BCEnv
673 -> DataCon -- The data constructor
674 -> [AnnExpr' Id DVarSet] -- Args, in *reverse* order
675 -> BcM BCInstrList
676
677 mkConAppCode _ _ _ con [] -- Nullary constructor
678 = ASSERT( isNullaryRepDataCon con )
679 return (unitOL (PUSH_G (getName (dataConWorkId con))))
680 -- Instead of doing a PACK, which would allocate a fresh
681 -- copy of this constructor, use the single shared version.
682
683 mkConAppCode orig_d _ p con args_r_to_l
684 = ASSERT( dataConRepArity con == length args_r_to_l )
685 do_pushery orig_d (non_ptr_args ++ ptr_args)
686 where
687 -- The args are already in reverse order, which is the way PACK
688 -- expects them to be. We must push the non-ptrs after the ptrs.
689 (ptr_args, non_ptr_args) = partition isPtrAtom args_r_to_l
690
691 do_pushery d (arg:args)
692 = do (push, arg_words) <- pushAtom d p arg
693 more_push_code <- do_pushery (d + fromIntegral arg_words) args
694 return (push `appOL` more_push_code)
695 do_pushery d []
696 = return (unitOL (PACK con n_arg_words))
697 where
698 n_arg_words = trunc16 $ d - orig_d
699
700
701 -- -----------------------------------------------------------------------------
702 -- Returning an unboxed tuple with one non-void component (the only
703 -- case we can handle).
704 --
705 -- Remember, we don't want to *evaluate* the component that is being
706 -- returned, even if it is a pointed type. We always just return.
707
708 unboxedTupleReturn
709 :: Word -> Sequel -> BCEnv
710 -> AnnExpr' Id DVarSet -> BcM BCInstrList
711 unboxedTupleReturn d s p arg = returnUnboxedAtom d s p arg (atomRep arg)
712
713 -- -----------------------------------------------------------------------------
714 -- Generate code for a tail-call
715
716 doTailCall
717 :: Word -> Sequel -> BCEnv
718 -> Id -> [AnnExpr' Id DVarSet]
719 -> BcM BCInstrList
720 doTailCall init_d s p fn args
721 = do_pushes init_d args (map atomRep args)
722 where
723 do_pushes d [] reps = do
724 ASSERT( null reps ) return ()
725 (push_fn, sz) <- pushAtom d p (AnnVar fn)
726 ASSERT( sz == 1 ) return ()
727 return (push_fn `appOL` (
728 mkSLIDE (trunc16 $ d - init_d + 1) (init_d - s) `appOL`
729 unitOL ENTER))
730 do_pushes d args reps = do
731 let (push_apply, n, rest_of_reps) = findPushSeq reps
732 (these_args, rest_of_args) = splitAt n args
733 (next_d, push_code) <- push_seq d these_args
734 instrs <- do_pushes (next_d + 1) rest_of_args rest_of_reps
735 -- ^^^ for the PUSH_APPLY_ instruction
736 return (push_code `appOL` (push_apply `consOL` instrs))
737
738 push_seq d [] = return (d, nilOL)
739 push_seq d (arg:args) = do
740 (push_code, sz) <- pushAtom d p arg
741 (final_d, more_push_code) <- push_seq (d + fromIntegral sz) args
742 return (final_d, push_code `appOL` more_push_code)
743
744 -- v. similar to CgStackery.findMatch, ToDo: merge
745 findPushSeq :: [ArgRep] -> (BCInstr, Int, [ArgRep])
746 findPushSeq (P: P: P: P: P: P: rest)
747 = (PUSH_APPLY_PPPPPP, 6, rest)
748 findPushSeq (P: P: P: P: P: rest)
749 = (PUSH_APPLY_PPPPP, 5, rest)
750 findPushSeq (P: P: P: P: rest)
751 = (PUSH_APPLY_PPPP, 4, rest)
752 findPushSeq (P: P: P: rest)
753 = (PUSH_APPLY_PPP, 3, rest)
754 findPushSeq (P: P: rest)
755 = (PUSH_APPLY_PP, 2, rest)
756 findPushSeq (P: rest)
757 = (PUSH_APPLY_P, 1, rest)
758 findPushSeq (V: rest)
759 = (PUSH_APPLY_V, 1, rest)
760 findPushSeq (N: rest)
761 = (PUSH_APPLY_N, 1, rest)
762 findPushSeq (F: rest)
763 = (PUSH_APPLY_F, 1, rest)
764 findPushSeq (D: rest)
765 = (PUSH_APPLY_D, 1, rest)
766 findPushSeq (L: rest)
767 = (PUSH_APPLY_L, 1, rest)
768 findPushSeq _
769 = panic "ByteCodeGen.findPushSeq"
770
771 -- -----------------------------------------------------------------------------
772 -- Case expressions
773
774 doCase :: Word -> Sequel -> BCEnv
775 -> AnnExpr Id DVarSet -> Id -> [AnnAlt Id DVarSet]
776 -> Maybe Id -- Just x <=> is an unboxed tuple case with scrut binder, don't enter the result
777 -> BcM BCInstrList
778 doCase d s p (_,scrut) bndr alts is_unboxed_tuple
779 | repTypeArgs (idType bndr) `lengthExceeds` 1
780 = multiValException
781 | otherwise
782 = do
783 dflags <- getDynFlags
784 let
785 profiling
786 | gopt Opt_ExternalInterpreter dflags = gopt Opt_SccProfilingOn dflags
787 | otherwise = rtsIsProfiled
788
789 -- Top of stack is the return itbl, as usual.
790 -- underneath it is the pointer to the alt_code BCO.
791 -- When an alt is entered, it assumes the returned value is
792 -- on top of the itbl.
793 ret_frame_sizeW :: Word
794 ret_frame_sizeW = 2
795
796 -- The extra frame we push to save/restor the CCCS when profiling
797 save_ccs_sizeW | profiling = 2
798 | otherwise = 0
799
800 -- An unlifted value gets an extra info table pushed on top
801 -- when it is returned.
802 unlifted_itbl_sizeW :: Word
803 unlifted_itbl_sizeW | isAlgCase = 0
804 | otherwise = 1
805
806 -- depth of stack after the return value has been pushed
807 d_bndr = d + ret_frame_sizeW + fromIntegral (idSizeW dflags bndr)
808
809 -- depth of stack after the extra info table for an unboxed return
810 -- has been pushed, if any. This is the stack depth at the
811 -- continuation.
812 d_alts = d_bndr + unlifted_itbl_sizeW
813
814 -- Env in which to compile the alts, not including
815 -- any vars bound by the alts themselves
816 d_bndr' = fromIntegral d_bndr - 1
817 p_alts0 = Map.insert bndr d_bndr' p
818 p_alts = case is_unboxed_tuple of
819 Just ubx_bndr -> Map.insert ubx_bndr d_bndr' p_alts0
820 Nothing -> p_alts0
821
822 bndr_ty = idType bndr
823 isAlgCase = not (isUnliftedType bndr_ty) && isNothing is_unboxed_tuple
824
825 -- given an alt, return a discr and code for it.
826 codeAlt (DEFAULT, _, (_,rhs))
827 = do rhs_code <- schemeE d_alts s p_alts rhs
828 return (NoDiscr, rhs_code)
829
830 codeAlt alt@(_, bndrs, (_,rhs))
831 -- primitive or nullary constructor alt: no need to UNPACK
832 | null real_bndrs = do
833 rhs_code <- schemeE d_alts s p_alts rhs
834 return (my_discr alt, rhs_code)
835 -- algebraic alt with some binders
836 | otherwise =
837 let
838 (ptrs,nptrs) = partition (isFollowableArg.bcIdArgRep) real_bndrs
839 ptr_sizes = map (fromIntegral . idSizeW dflags) ptrs
840 nptrs_sizes = map (fromIntegral . idSizeW dflags) nptrs
841 bind_sizes = ptr_sizes ++ nptrs_sizes
842 size = sum ptr_sizes + sum nptrs_sizes
843 -- the UNPACK instruction unpacks in reverse order...
844 p' = Map.insertList
845 (zip (reverse (ptrs ++ nptrs))
846 (mkStackOffsets d_alts (reverse bind_sizes)))
847 p_alts
848 in do
849 MASSERT(isAlgCase)
850 rhs_code <- schemeE (d_alts + size) s p' rhs
851 return (my_discr alt, unitOL (UNPACK (trunc16 size)) `appOL` rhs_code)
852 where
853 real_bndrs = filterOut isTyVar bndrs
854
855 my_discr (DEFAULT, _, _) = NoDiscr {-shouldn't really happen-}
856 my_discr (DataAlt dc, _, _)
857 | isUnboxedTupleCon dc || isUnboxedSumCon dc
858 = multiValException
859 | otherwise
860 = DiscrP (fromIntegral (dataConTag dc - fIRST_TAG))
861 my_discr (LitAlt l, _, _)
862 = case l of MachInt i -> DiscrI (fromInteger i)
863 MachWord w -> DiscrW (fromInteger w)
864 MachFloat r -> DiscrF (fromRational r)
865 MachDouble r -> DiscrD (fromRational r)
866 MachChar i -> DiscrI (ord i)
867 _ -> pprPanic "schemeE(AnnCase).my_discr" (ppr l)
868
869 maybe_ncons
870 | not isAlgCase = Nothing
871 | otherwise
872 = case [dc | (DataAlt dc, _, _) <- alts] of
873 [] -> Nothing
874 (dc:_) -> Just (tyConFamilySize (dataConTyCon dc))
875
876 -- the bitmap is relative to stack depth d, i.e. before the
877 -- BCO, info table and return value are pushed on.
878 -- This bit of code is v. similar to buildLivenessMask in CgBindery,
879 -- except that here we build the bitmap from the known bindings of
880 -- things that are pointers, whereas in CgBindery the code builds the
881 -- bitmap from the free slots and unboxed bindings.
882 -- (ToDo: merge?)
883 --
884 -- NOTE [7/12/2006] bug #1013, testcase ghci/should_run/ghci002.
885 -- The bitmap must cover the portion of the stack up to the sequel only.
886 -- Previously we were building a bitmap for the whole depth (d), but we
887 -- really want a bitmap up to depth (d-s). This affects compilation of
888 -- case-of-case expressions, which is the only time we can be compiling a
889 -- case expression with s /= 0.
890 bitmap_size = trunc16 $ d-s
891 bitmap_size' :: Int
892 bitmap_size' = fromIntegral bitmap_size
893 bitmap = intsToReverseBitmap dflags bitmap_size'{-size-}
894 (sort (filter (< bitmap_size') rel_slots))
895 where
896 binds = Map.toList p
897 -- NB: unboxed tuple cases bind the scrut binder to the same offset
898 -- as one of the alt binders, so we have to remove any duplicates here:
899 rel_slots = nub $ map fromIntegral $ concat (map spread binds)
900 spread (id, offset) | isFollowableArg (bcIdArgRep id) = [ rel_offset ]
901 | otherwise = []
902 where rel_offset = trunc16 $ d - fromIntegral offset - 1
903
904 alt_stuff <- mapM codeAlt alts
905 alt_final <- mkMultiBranch maybe_ncons alt_stuff
906
907 let
908 alt_bco_name = getName bndr
909 alt_bco = mkProtoBCO dflags alt_bco_name alt_final (Left alts)
910 0{-no arity-} bitmap_size bitmap True{-is alts-}
911 -- trace ("case: bndr = " ++ showSDocDebug (ppr bndr) ++ "\ndepth = " ++ show d ++ "\nenv = \n" ++ showSDocDebug (ppBCEnv p) ++
912 -- "\n bitmap = " ++ show bitmap) $ do
913
914 scrut_code <- schemeE (d + ret_frame_sizeW + save_ccs_sizeW)
915 (d + ret_frame_sizeW + save_ccs_sizeW)
916 p scrut
917 alt_bco' <- emitBc alt_bco
918 let push_alts
919 | isAlgCase = PUSH_ALTS alt_bco'
920 | otherwise = PUSH_ALTS_UNLIFTED alt_bco' (typeArgRep bndr_ty)
921 return (push_alts `consOL` scrut_code)
922
923
924 -- -----------------------------------------------------------------------------
925 -- Deal with a CCall.
926
927 -- Taggedly push the args onto the stack R->L,
928 -- deferencing ForeignObj#s and adjusting addrs to point to
929 -- payloads in Ptr/Byte arrays. Then, generate the marshalling
930 -- (machine) code for the ccall, and create bytecodes to call that and
931 -- then return in the right way.
932
933 generateCCall :: Word -> Sequel -- stack and sequel depths
934 -> BCEnv
935 -> CCallSpec -- where to call
936 -> Id -- of target, for type info
937 -> [AnnExpr' Id DVarSet] -- args (atoms)
938 -> BcM BCInstrList
939
940 generateCCall d0 s p (CCallSpec target cconv safety) fn args_r_to_l
941 = do
942 dflags <- getDynFlags
943
944 let
945 -- useful constants
946 addr_sizeW :: Word16
947 addr_sizeW = fromIntegral (argRepSizeW dflags N)
948
949 -- Get the args on the stack, with tags and suitably
950 -- dereferenced for the CCall. For each arg, return the
951 -- depth to the first word of the bits for that arg, and the
952 -- ArgRep of what was actually pushed.
953
954 pargs _ [] = return []
955 pargs d (a:az)
956 = let [arg_ty] = repTypeArgs (exprType (deAnnotate' a))
957
958 in case tyConAppTyCon_maybe arg_ty of
959 -- Don't push the FO; instead push the Addr# it
960 -- contains.
961 Just t
962 | t == arrayPrimTyCon || t == mutableArrayPrimTyCon
963 -> do rest <- pargs (d + fromIntegral addr_sizeW) az
964 code <- parg_ArrayishRep (fromIntegral (arrPtrsHdrSize dflags)) d p a
965 return ((code,AddrRep):rest)
966
967 | t == smallArrayPrimTyCon || t == smallMutableArrayPrimTyCon
968 -> do rest <- pargs (d + fromIntegral addr_sizeW) az
969 code <- parg_ArrayishRep (fromIntegral (smallArrPtrsHdrSize dflags)) d p a
970 return ((code,AddrRep):rest)
971
972 | t == byteArrayPrimTyCon || t == mutableByteArrayPrimTyCon
973 -> do rest <- pargs (d + fromIntegral addr_sizeW) az
974 code <- parg_ArrayishRep (fromIntegral (arrWordsHdrSize dflags)) d p a
975 return ((code,AddrRep):rest)
976
977 -- Default case: push taggedly, but otherwise intact.
978 _
979 -> do (code_a, sz_a) <- pushAtom d p a
980 rest <- pargs (d + fromIntegral sz_a) az
981 return ((code_a, atomPrimRep a) : rest)
982
983 -- Do magic for Ptr/Byte arrays. Push a ptr to the array on
984 -- the stack but then advance it over the headers, so as to
985 -- point to the payload.
986 parg_ArrayishRep :: Word16 -> Word -> BCEnv -> AnnExpr' Id DVarSet
987 -> BcM BCInstrList
988 parg_ArrayishRep hdrSize d p a
989 = do (push_fo, _) <- pushAtom d p a
990 -- The ptr points at the header. Advance it over the
991 -- header and then pretend this is an Addr#.
992 return (push_fo `snocOL` SWIZZLE 0 hdrSize)
993
994 code_n_reps <- pargs d0 args_r_to_l
995 let
996 (pushs_arg, a_reps_pushed_r_to_l) = unzip code_n_reps
997 a_reps_sizeW = fromIntegral (sum (map (primRepSizeW dflags) a_reps_pushed_r_to_l))
998
999 push_args = concatOL pushs_arg
1000 d_after_args = d0 + a_reps_sizeW
1001 a_reps_pushed_RAW
1002 | null a_reps_pushed_r_to_l || head a_reps_pushed_r_to_l /= VoidRep
1003 = panic "ByteCodeGen.generateCCall: missing or invalid World token?"
1004 | otherwise
1005 = reverse (tail a_reps_pushed_r_to_l)
1006
1007 -- Now: a_reps_pushed_RAW are the reps which are actually on the stack.
1008 -- push_args is the code to do that.
1009 -- d_after_args is the stack depth once the args are on.
1010
1011 -- Get the result rep.
1012 (returns_void, r_rep)
1013 = case maybe_getCCallReturnRep (idType fn) of
1014 Nothing -> (True, VoidRep)
1015 Just rr -> (False, rr)
1016 {-
1017 Because the Haskell stack grows down, the a_reps refer to
1018 lowest to highest addresses in that order. The args for the call
1019 are on the stack. Now push an unboxed Addr# indicating
1020 the C function to call. Then push a dummy placeholder for the
1021 result. Finally, emit a CCALL insn with an offset pointing to the
1022 Addr# just pushed, and a literal field holding the mallocville
1023 address of the piece of marshalling code we generate.
1024 So, just prior to the CCALL insn, the stack looks like this
1025 (growing down, as usual):
1026
1027 <arg_n>
1028 ...
1029 <arg_1>
1030 Addr# address_of_C_fn
1031 <placeholder-for-result#> (must be an unboxed type)
1032
1033 The interpreter then calls the marshall code mentioned
1034 in the CCALL insn, passing it (& <placeholder-for-result#>),
1035 that is, the addr of the topmost word in the stack.
1036 When this returns, the placeholder will have been
1037 filled in. The placeholder is slid down to the sequel
1038 depth, and we RETURN.
1039
1040 This arrangement makes it simple to do f-i-dynamic since the Addr#
1041 value is the first arg anyway.
1042
1043 The marshalling code is generated specifically for this
1044 call site, and so knows exactly the (Haskell) stack
1045 offsets of the args, fn address and placeholder. It
1046 copies the args to the C stack, calls the stacked addr,
1047 and parks the result back in the placeholder. The interpreter
1048 calls it as a normal C call, assuming it has a signature
1049 void marshall_code ( StgWord* ptr_to_top_of_stack )
1050 -}
1051 -- resolve static address
1052 maybe_static_target =
1053 case target of
1054 DynamicTarget -> Nothing
1055 StaticTarget _ _ _ False ->
1056 panic "generateCCall: unexpected FFI value import"
1057 StaticTarget _ target _ True ->
1058 Just (MachLabel target mb_size IsFunction)
1059 where
1060 mb_size
1061 | OSMinGW32 <- platformOS (targetPlatform dflags)
1062 , StdCallConv <- cconv
1063 = Just (fromIntegral a_reps_sizeW * wORD_SIZE dflags)
1064 | otherwise
1065 = Nothing
1066
1067 let
1068 is_static = isJust maybe_static_target
1069
1070 -- Get the arg reps, zapping the leading Addr# in the dynamic case
1071 a_reps -- | trace (showSDoc (ppr a_reps_pushed_RAW)) False = error "???"
1072 | is_static = a_reps_pushed_RAW
1073 | otherwise = if null a_reps_pushed_RAW
1074 then panic "ByteCodeGen.generateCCall: dyn with no args"
1075 else tail a_reps_pushed_RAW
1076
1077 -- push the Addr#
1078 (push_Addr, d_after_Addr)
1079 | Just machlabel <- maybe_static_target
1080 = (toOL [PUSH_UBX machlabel addr_sizeW],
1081 d_after_args + fromIntegral addr_sizeW)
1082 | otherwise -- is already on the stack
1083 = (nilOL, d_after_args)
1084
1085 -- Push the return placeholder. For a call returning nothing,
1086 -- this is a V (tag).
1087 r_sizeW = fromIntegral (primRepSizeW dflags r_rep)
1088 d_after_r = d_after_Addr + fromIntegral r_sizeW
1089 push_r = (if returns_void
1090 then nilOL
1091 else unitOL (PUSH_UBX (mkDummyLiteral r_rep) r_sizeW))
1092
1093 -- generate the marshalling code we're going to call
1094
1095 -- Offset of the next stack frame down the stack. The CCALL
1096 -- instruction needs to describe the chunk of stack containing
1097 -- the ccall args to the GC, so it needs to know how large it
1098 -- is. See comment in Interpreter.c with the CCALL instruction.
1099 stk_offset = trunc16 $ d_after_r - s
1100
1101 conv = case cconv of
1102 CCallConv -> FFICCall
1103 StdCallConv -> FFIStdCall
1104 _ -> panic "ByteCodeGen: unexpected calling convention"
1105
1106 -- the only difference in libffi mode is that we prepare a cif
1107 -- describing the call type by calling libffi, and we attach the
1108 -- address of this to the CCALL instruction.
1109
1110
1111 let ffires = primRepToFFIType dflags r_rep
1112 ffiargs = map (primRepToFFIType dflags) a_reps
1113 hsc_env <- getHscEnv
1114 token <- ioToBc $ iservCmd hsc_env (PrepFFI conv ffiargs ffires)
1115 recordFFIBc token
1116
1117 let
1118 -- do the call
1119 do_call = unitOL (CCALL stk_offset token
1120 (fromIntegral (fromEnum (playInterruptible safety))))
1121 -- slide and return
1122 wrapup = mkSLIDE r_sizeW (d_after_r - fromIntegral r_sizeW - s)
1123 `snocOL` RETURN_UBX (toArgRep r_rep)
1124 --trace (show (arg1_offW, args_offW , (map argRepSizeW a_reps) )) $
1125 return (
1126 push_args `appOL`
1127 push_Addr `appOL` push_r `appOL` do_call `appOL` wrapup
1128 )
1129
1130 primRepToFFIType :: DynFlags -> PrimRep -> FFIType
1131 primRepToFFIType dflags r
1132 = case r of
1133 VoidRep -> FFIVoid
1134 IntRep -> signed_word
1135 WordRep -> unsigned_word
1136 Int64Rep -> FFISInt64
1137 Word64Rep -> FFIUInt64
1138 AddrRep -> FFIPointer
1139 FloatRep -> FFIFloat
1140 DoubleRep -> FFIDouble
1141 _ -> panic "primRepToFFIType"
1142 where
1143 (signed_word, unsigned_word)
1144 | wORD_SIZE dflags == 4 = (FFISInt32, FFIUInt32)
1145 | wORD_SIZE dflags == 8 = (FFISInt64, FFIUInt64)
1146 | otherwise = panic "primTyDescChar"
1147
1148 -- Make a dummy literal, to be used as a placeholder for FFI return
1149 -- values on the stack.
1150 mkDummyLiteral :: PrimRep -> Literal
1151 mkDummyLiteral pr
1152 = case pr of
1153 IntRep -> MachInt 0
1154 WordRep -> MachWord 0
1155 AddrRep -> MachNullAddr
1156 DoubleRep -> MachDouble 0
1157 FloatRep -> MachFloat 0
1158 Int64Rep -> MachInt64 0
1159 Word64Rep -> MachWord64 0
1160 _ -> pprPanic "mkDummyLiteral" (ppr pr)
1161
1162
1163 -- Convert (eg)
1164 -- GHC.Prim.Char# -> GHC.Prim.State# GHC.Prim.RealWorld
1165 -- -> (# GHC.Prim.State# GHC.Prim.RealWorld, GHC.Prim.Int# #)
1166 --
1167 -- to Just IntRep
1168 -- and check that an unboxed pair is returned wherein the first arg is V'd.
1169 --
1170 -- Alternatively, for call-targets returning nothing, convert
1171 --
1172 -- GHC.Prim.Char# -> GHC.Prim.State# GHC.Prim.RealWorld
1173 -- -> (# GHC.Prim.State# GHC.Prim.RealWorld #)
1174 --
1175 -- to Nothing
1176
1177 maybe_getCCallReturnRep :: Type -> Maybe PrimRep
1178 maybe_getCCallReturnRep fn_ty
1179 = let
1180 (_a_tys, r_ty) = splitFunTys (dropForAlls fn_ty)
1181 r_reps = repTypeArgs r_ty
1182
1183 blargh :: a -- Used at more than one type
1184 blargh = pprPanic "maybe_getCCallReturn: can't handle:"
1185 (pprType fn_ty)
1186 in
1187 case r_reps of
1188 [] -> panic "empty repTypeArgs"
1189 [ty]
1190 | typePrimRep ty == PtrRep
1191 -> blargh
1192 | isVoidTy ty
1193 -> Nothing
1194 | otherwise
1195 -> Just (typePrimRep ty)
1196 -- if it was, it would be impossible to create a
1197 -- valid return value placeholder on the stack
1198 _ -> blargh
1199
1200 maybe_is_tagToEnum_call :: AnnExpr' Id DVarSet -> Maybe (AnnExpr' Id DVarSet, [Name])
1201 -- Detect and extract relevant info for the tagToEnum kludge.
1202 maybe_is_tagToEnum_call app
1203 | AnnApp (_, AnnApp (_, AnnVar v) (_, AnnType t)) arg <- app
1204 , Just TagToEnumOp <- isPrimOpId_maybe v
1205 = Just (snd arg, extract_constr_Names t)
1206 | otherwise
1207 = Nothing
1208 where
1209 extract_constr_Names ty
1210 | [rep_ty] <- repTypeArgs ty
1211 , Just tyc <- tyConAppTyCon_maybe rep_ty
1212 , isDataTyCon tyc
1213 = map (getName . dataConWorkId) (tyConDataCons tyc)
1214 -- NOTE: use the worker name, not the source name of
1215 -- the DataCon. See DataCon.hs for details.
1216 | otherwise
1217 = pprPanic "maybe_is_tagToEnum_call.extract_constr_Ids" (ppr ty)
1218
1219 {- -----------------------------------------------------------------------------
1220 Note [Implementing tagToEnum#]
1221 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1222 (implement_tagToId arg names) compiles code which takes an argument
1223 'arg', (call it i), and enters the i'th closure in the supplied list
1224 as a consequence. The [Name] is a list of the constructors of this
1225 (enumeration) type.
1226
1227 The code we generate is this:
1228 push arg
1229 push bogus-word
1230
1231 TESTEQ_I 0 L1
1232 PUSH_G <lbl for first data con>
1233 JMP L_Exit
1234
1235 L1: TESTEQ_I 1 L2
1236 PUSH_G <lbl for second data con>
1237 JMP L_Exit
1238 ...etc...
1239 Ln: TESTEQ_I n L_fail
1240 PUSH_G <lbl for last data con>
1241 JMP L_Exit
1242
1243 L_fail: CASEFAIL
1244
1245 L_exit: SLIDE 1 n
1246 ENTER
1247
1248 The 'bogus-word' push is because TESTEQ_I expects the top of the stack
1249 to have an info-table, and the next word to have the value to be
1250 tested. This is very weird, but it's the way it is right now. See
1251 Interpreter.c. We don't acutally need an info-table here; we just
1252 need to have the argument to be one-from-top on the stack, hence pushing
1253 a 1-word null. See Trac #8383.
1254 -}
1255
1256
1257 implement_tagToId :: Word -> Sequel -> BCEnv
1258 -> AnnExpr' Id DVarSet -> [Name] -> BcM BCInstrList
1259 -- See Note [Implementing tagToEnum#]
1260 implement_tagToId d s p arg names
1261 = ASSERT( notNull names )
1262 do (push_arg, arg_words) <- pushAtom d p arg
1263 labels <- getLabelsBc (genericLength names)
1264 label_fail <- getLabelBc
1265 label_exit <- getLabelBc
1266 let infos = zip4 labels (tail labels ++ [label_fail])
1267 [0 ..] names
1268 steps = map (mkStep label_exit) infos
1269
1270 return (push_arg
1271 `appOL` unitOL (PUSH_UBX MachNullAddr 1)
1272 -- Push bogus word (see Note [Implementing tagToEnum#])
1273 `appOL` concatOL steps
1274 `appOL` toOL [ LABEL label_fail, CASEFAIL,
1275 LABEL label_exit ]
1276 `appOL` mkSLIDE 1 (d - s + fromIntegral arg_words + 1)
1277 -- "+1" to account for bogus word
1278 -- (see Note [Implementing tagToEnum#])
1279 `appOL` unitOL ENTER)
1280 where
1281 mkStep l_exit (my_label, next_label, n, name_for_n)
1282 = toOL [LABEL my_label,
1283 TESTEQ_I n next_label,
1284 PUSH_G name_for_n,
1285 JMP l_exit]
1286
1287
1288 -- -----------------------------------------------------------------------------
1289 -- pushAtom
1290
1291 -- Push an atom onto the stack, returning suitable code & number of
1292 -- stack words used.
1293 --
1294 -- The env p must map each variable to the highest- numbered stack
1295 -- slot for it. For example, if the stack has depth 4 and we
1296 -- tagged-ly push (v :: Int#) on it, the value will be in stack[4],
1297 -- the tag in stack[5], the stack will have depth 6, and p must map v
1298 -- to 5 and not to 4. Stack locations are numbered from zero, so a
1299 -- depth 6 stack has valid words 0 .. 5.
1300
1301 pushAtom :: Word -> BCEnv -> AnnExpr' Id DVarSet -> BcM (BCInstrList, Word16)
1302
1303 pushAtom d p e
1304 | Just e' <- bcView e
1305 = pushAtom d p e'
1306
1307 pushAtom _ _ (AnnCoercion {}) -- Coercions are zero-width things,
1308 = return (nilOL, 0) -- treated just like a variable V
1309
1310 -- See Note [Empty case alternatives] in coreSyn/CoreSyn.hs
1311 -- and Note [Bottoming expressions] in coreSyn/CoreUtils.hs:
1312 -- The scrutinee of an empty case evaluates to bottom
1313 pushAtom d p (AnnCase (_, a) _ _ []) -- trac #12128
1314 = pushAtom d p a
1315
1316 pushAtom d p (AnnVar v)
1317 | [rep_ty] <- repTypeArgs (idType v)
1318 , V <- typeArgRep rep_ty
1319 = return (nilOL, 0)
1320
1321 | isFCallId v
1322 = pprPanic "pushAtom: shouldn't get an FCallId here" (ppr v)
1323
1324 | Just primop <- isPrimOpId_maybe v
1325 = return (unitOL (PUSH_PRIMOP primop), 1)
1326
1327 | Just d_v <- lookupBCEnv_maybe v p -- v is a local variable
1328 = do dflags <- getDynFlags
1329 let sz :: Word16
1330 sz = fromIntegral (idSizeW dflags v)
1331 l = trunc16 $ d - d_v + fromIntegral sz - 2
1332 return (toOL (genericReplicate sz (PUSH_L l)), sz)
1333 -- d - d_v the number of words between the TOS
1334 -- and the 1st slot of the object
1335 --
1336 -- d - d_v - 1 the offset from the TOS of the 1st slot
1337 --
1338 -- d - d_v - 1 + sz - 1 the offset from the TOS of the last slot
1339 -- of the object.
1340 --
1341 -- Having found the last slot, we proceed to copy the right number of
1342 -- slots on to the top of the stack.
1343
1344 | otherwise -- v must be a global variable
1345 = do dflags <- getDynFlags
1346 let sz :: Word16
1347 sz = fromIntegral (idSizeW dflags v)
1348 MASSERT(sz == 1)
1349 return (unitOL (PUSH_G (getName v)), sz)
1350
1351
1352 pushAtom _ _ (AnnLit lit) = do
1353 dflags <- getDynFlags
1354 let code rep
1355 = let size_host_words = fromIntegral (argRepSizeW dflags rep)
1356 in return (unitOL (PUSH_UBX lit size_host_words),
1357 size_host_words)
1358
1359 case lit of
1360 MachLabel _ _ _ -> code N
1361 MachWord _ -> code N
1362 MachInt _ -> code N
1363 MachWord64 _ -> code L
1364 MachInt64 _ -> code L
1365 MachFloat _ -> code F
1366 MachDouble _ -> code D
1367 MachChar _ -> code N
1368 MachNullAddr -> code N
1369 MachStr _ -> code N
1370 -- No LitInteger's should be left by the time this is called.
1371 -- CorePrep should have converted them all to a real core
1372 -- representation.
1373 LitInteger {} -> panic "pushAtom: LitInteger"
1374
1375 pushAtom _ _ expr
1376 = pprPanic "ByteCodeGen.pushAtom"
1377 (pprCoreExpr (deAnnotate' expr))
1378
1379
1380 -- -----------------------------------------------------------------------------
1381 -- Given a bunch of alts code and their discrs, do the donkey work
1382 -- of making a multiway branch using a switch tree.
1383 -- What a load of hassle!
1384
1385 mkMultiBranch :: Maybe Int -- # datacons in tycon, if alg alt
1386 -- a hint; generates better code
1387 -- Nothing is always safe
1388 -> [(Discr, BCInstrList)]
1389 -> BcM BCInstrList
1390 mkMultiBranch maybe_ncons raw_ways = do
1391 lbl_default <- getLabelBc
1392
1393 let
1394 mkTree :: [(Discr, BCInstrList)] -> Discr -> Discr -> BcM BCInstrList
1395 mkTree [] _range_lo _range_hi = return (unitOL (JMP lbl_default))
1396 -- shouldn't happen?
1397
1398 mkTree [val] range_lo range_hi
1399 | range_lo == range_hi
1400 = return (snd val)
1401 | null defaults -- Note [CASEFAIL]
1402 = do lbl <- getLabelBc
1403 return (testEQ (fst val) lbl
1404 `consOL` (snd val
1405 `appOL` (LABEL lbl `consOL` unitOL CASEFAIL)))
1406 | otherwise
1407 = return (testEQ (fst val) lbl_default `consOL` snd val)
1408
1409 -- Note [CASEFAIL] It may be that this case has no default
1410 -- branch, but the alternatives are not exhaustive - this
1411 -- happens for GADT cases for example, where the types
1412 -- prove that certain branches are impossible. We could
1413 -- just assume that the other cases won't occur, but if
1414 -- this assumption was wrong (because of a bug in GHC)
1415 -- then the result would be a segfault. So instead we
1416 -- emit an explicit test and a CASEFAIL instruction that
1417 -- causes the interpreter to barf() if it is ever
1418 -- executed.
1419
1420 mkTree vals range_lo range_hi
1421 = let n = length vals `div` 2
1422 vals_lo = take n vals
1423 vals_hi = drop n vals
1424 v_mid = fst (head vals_hi)
1425 in do
1426 label_geq <- getLabelBc
1427 code_lo <- mkTree vals_lo range_lo (dec v_mid)
1428 code_hi <- mkTree vals_hi v_mid range_hi
1429 return (testLT v_mid label_geq
1430 `consOL` (code_lo
1431 `appOL` unitOL (LABEL label_geq)
1432 `appOL` code_hi))
1433
1434 the_default
1435 = case defaults of
1436 [] -> nilOL
1437 [(_, def)] -> LABEL lbl_default `consOL` def
1438 _ -> panic "mkMultiBranch/the_default"
1439 instrs <- mkTree notd_ways init_lo init_hi
1440 return (instrs `appOL` the_default)
1441 where
1442 (defaults, not_defaults) = partition (isNoDiscr.fst) raw_ways
1443 notd_ways = sortBy (comparing fst) not_defaults
1444
1445 testLT (DiscrI i) fail_label = TESTLT_I i fail_label
1446 testLT (DiscrW i) fail_label = TESTLT_W i fail_label
1447 testLT (DiscrF i) fail_label = TESTLT_F i fail_label
1448 testLT (DiscrD i) fail_label = TESTLT_D i fail_label
1449 testLT (DiscrP i) fail_label = TESTLT_P i fail_label
1450 testLT NoDiscr _ = panic "mkMultiBranch NoDiscr"
1451
1452 testEQ (DiscrI i) fail_label = TESTEQ_I i fail_label
1453 testEQ (DiscrW i) fail_label = TESTEQ_W i fail_label
1454 testEQ (DiscrF i) fail_label = TESTEQ_F i fail_label
1455 testEQ (DiscrD i) fail_label = TESTEQ_D i fail_label
1456 testEQ (DiscrP i) fail_label = TESTEQ_P i fail_label
1457 testEQ NoDiscr _ = panic "mkMultiBranch NoDiscr"
1458
1459 -- None of these will be needed if there are no non-default alts
1460 (init_lo, init_hi)
1461 | null notd_ways
1462 = panic "mkMultiBranch: awesome foursome"
1463 | otherwise
1464 = case fst (head notd_ways) of
1465 DiscrI _ -> ( DiscrI minBound, DiscrI maxBound )
1466 DiscrW _ -> ( DiscrW minBound, DiscrW maxBound )
1467 DiscrF _ -> ( DiscrF minF, DiscrF maxF )
1468 DiscrD _ -> ( DiscrD minD, DiscrD maxD )
1469 DiscrP _ -> ( DiscrP algMinBound, DiscrP algMaxBound )
1470 NoDiscr -> panic "mkMultiBranch NoDiscr"
1471
1472 (algMinBound, algMaxBound)
1473 = case maybe_ncons of
1474 -- XXX What happens when n == 0?
1475 Just n -> (0, fromIntegral n - 1)
1476 Nothing -> (minBound, maxBound)
1477
1478 isNoDiscr NoDiscr = True
1479 isNoDiscr _ = False
1480
1481 dec (DiscrI i) = DiscrI (i-1)
1482 dec (DiscrW w) = DiscrW (w-1)
1483 dec (DiscrP i) = DiscrP (i-1)
1484 dec other = other -- not really right, but if you
1485 -- do cases on floating values, you'll get what you deserve
1486
1487 -- same snotty comment applies to the following
1488 minF, maxF :: Float
1489 minD, maxD :: Double
1490 minF = -1.0e37
1491 maxF = 1.0e37
1492 minD = -1.0e308
1493 maxD = 1.0e308
1494
1495
1496 -- -----------------------------------------------------------------------------
1497 -- Supporting junk for the compilation schemes
1498
1499 -- Describes case alts
1500 data Discr
1501 = DiscrI Int
1502 | DiscrW Word
1503 | DiscrF Float
1504 | DiscrD Double
1505 | DiscrP Word16
1506 | NoDiscr
1507 deriving (Eq, Ord)
1508
1509 instance Outputable Discr where
1510 ppr (DiscrI i) = int i
1511 ppr (DiscrW w) = text (show w)
1512 ppr (DiscrF f) = text (show f)
1513 ppr (DiscrD d) = text (show d)
1514 ppr (DiscrP i) = ppr i
1515 ppr NoDiscr = text "DEF"
1516
1517
1518 lookupBCEnv_maybe :: Id -> BCEnv -> Maybe Word
1519 lookupBCEnv_maybe = Map.lookup
1520
1521 idSizeW :: DynFlags -> Id -> Int
1522 idSizeW dflags = argRepSizeW dflags . bcIdArgRep
1523
1524 bcIdArgRep :: Id -> ArgRep
1525 bcIdArgRep = toArgRep . bcIdPrimRep
1526
1527 bcIdPrimRep :: Id -> PrimRep
1528 bcIdPrimRep = typePrimRep . bcIdUnaryType
1529
1530 isFollowableArg :: ArgRep -> Bool
1531 isFollowableArg P = True
1532 isFollowableArg _ = False
1533
1534 isVoidArg :: ArgRep -> Bool
1535 isVoidArg V = True
1536 isVoidArg _ = False
1537
1538 bcIdUnaryType :: Id -> UnaryType
1539 bcIdUnaryType x = case repTypeArgs (idType x) of
1540 [rep_ty] -> rep_ty
1541 _ -> pprPanic "bcIdUnaryType" (ppr x $$ ppr (idType x))
1542
1543 -- See bug #1257
1544 multiValException :: a
1545 multiValException = throwGhcException (ProgramError
1546 ("Error: bytecode compiler can't handle unboxed tuples and sums.\n"++
1547 " Possibly due to foreign import/export decls in source.\n"++
1548 " Workaround: use -fobject-code, or compile this module to .o separately."))
1549
1550 -- | Indicate if the calling convention is supported
1551 isSupportedCConv :: CCallSpec -> Bool
1552 isSupportedCConv (CCallSpec _ cconv _) = case cconv of
1553 CCallConv -> True -- we explicitly pattern match on every
1554 StdCallConv -> True -- convention to ensure that a warning
1555 PrimCallConv -> False -- is triggered when a new one is added
1556 JavaScriptCallConv -> False
1557 CApiConv -> False
1558
1559 -- See bug #10462
1560 unsupportedCConvException :: a
1561 unsupportedCConvException = throwGhcException (ProgramError
1562 ("Error: bytecode compiler can't handle some foreign calling conventions\n"++
1563 " Workaround: use -fobject-code, or compile this module to .o separately."))
1564
1565 mkSLIDE :: Word16 -> Word -> OrdList BCInstr
1566 mkSLIDE n d
1567 -- if the amount to slide doesn't fit in a word,
1568 -- generate multiple slide instructions
1569 | d > fromIntegral limit
1570 = SLIDE n limit `consOL` mkSLIDE n (d - fromIntegral limit)
1571 | d == 0
1572 = nilOL
1573 | otherwise
1574 = if d == 0 then nilOL else unitOL (SLIDE n $ fromIntegral d)
1575 where
1576 limit :: Word16
1577 limit = maxBound
1578
1579 splitApp :: AnnExpr' Var ann -> (AnnExpr' Var ann, [AnnExpr' Var ann])
1580 -- The arguments are returned in *right-to-left* order
1581 splitApp e | Just e' <- bcView e = splitApp e'
1582 splitApp (AnnApp (_,f) (_,a)) = case splitApp f of
1583 (f', as) -> (f', a:as)
1584 splitApp e = (e, [])
1585
1586
1587 bcView :: AnnExpr' Var ann -> Maybe (AnnExpr' Var ann)
1588 -- The "bytecode view" of a term discards
1589 -- a) type abstractions
1590 -- b) type applications
1591 -- c) casts
1592 -- d) ticks (but not breakpoints)
1593 -- Type lambdas *can* occur in random expressions,
1594 -- whereas value lambdas cannot; that is why they are nuked here
1595 bcView (AnnCast (_,e) _) = Just e
1596 bcView (AnnLam v (_,e)) | isTyVar v = Just e
1597 bcView (AnnApp (_,e) (_, AnnType _)) = Just e
1598 bcView (AnnTick Breakpoint{} _) = Nothing
1599 bcView (AnnTick _other_tick (_,e)) = Just e
1600 bcView _ = Nothing
1601
1602 isVAtom :: AnnExpr' Var ann -> Bool
1603 isVAtom e | Just e' <- bcView e = isVAtom e'
1604 isVAtom (AnnVar v) = isVoidArg (bcIdArgRep v)
1605 isVAtom (AnnCoercion {}) = True
1606 isVAtom _ = False
1607
1608 atomPrimRep :: AnnExpr' Id ann -> PrimRep
1609 atomPrimRep e | Just e' <- bcView e = atomPrimRep e'
1610 atomPrimRep (AnnVar v) = bcIdPrimRep v
1611 atomPrimRep (AnnLit l) = typePrimRep (literalType l)
1612
1613 -- Trac #12128:
1614 -- A case expresssion can be an atom because empty cases evaluate to bottom.
1615 -- See Note [Empty case alternatives] in coreSyn/CoreSyn.hs
1616 atomPrimRep (AnnCase _ _ ty _) = ASSERT(typePrimRep ty == PtrRep) PtrRep
1617 atomPrimRep (AnnCoercion {}) = VoidRep
1618 atomPrimRep other = pprPanic "atomPrimRep" (ppr (deAnnotate' other))
1619
1620 atomRep :: AnnExpr' Id ann -> ArgRep
1621 atomRep e = toArgRep (atomPrimRep e)
1622
1623 isPtrAtom :: AnnExpr' Id ann -> Bool
1624 isPtrAtom e = isFollowableArg (atomRep e)
1625
1626 -- Let szsw be the sizes in words of some items pushed onto the stack,
1627 -- which has initial depth d'. Return the values which the stack environment
1628 -- should map these items to.
1629 mkStackOffsets :: Word -> [Word] -> [Word]
1630 mkStackOffsets original_depth szsw
1631 = map (subtract 1) (tail (scanl (+) original_depth szsw))
1632
1633 typeArgRep :: Type -> ArgRep
1634 typeArgRep = toArgRep . typePrimRep
1635
1636 -- -----------------------------------------------------------------------------
1637 -- The bytecode generator's monad
1638
1639 data BcM_State
1640 = BcM_State
1641 { bcm_hsc_env :: HscEnv
1642 , uniqSupply :: UniqSupply -- for generating fresh variable names
1643 , thisModule :: Module -- current module (for breakpoints)
1644 , nextlabel :: Word16 -- for generating local labels
1645 , ffis :: [FFIInfo] -- ffi info blocks, to free later
1646 -- Should be free()d when it is GCd
1647 , modBreaks :: Maybe ModBreaks -- info about breakpoints
1648 , breakInfo :: IntMap CgBreakInfo
1649 }
1650
1651 newtype BcM r = BcM (BcM_State -> IO (BcM_State, r))
1652
1653 ioToBc :: IO a -> BcM a
1654 ioToBc io = BcM $ \st -> do
1655 x <- io
1656 return (st, x)
1657
1658 runBc :: HscEnv -> UniqSupply -> Module -> Maybe ModBreaks -> BcM r
1659 -> IO (BcM_State, r)
1660 runBc hsc_env us this_mod modBreaks (BcM m)
1661 = m (BcM_State hsc_env us this_mod 0 [] modBreaks IntMap.empty)
1662
1663 thenBc :: BcM a -> (a -> BcM b) -> BcM b
1664 thenBc (BcM expr) cont = BcM $ \st0 -> do
1665 (st1, q) <- expr st0
1666 let BcM k = cont q
1667 (st2, r) <- k st1
1668 return (st2, r)
1669
1670 thenBc_ :: BcM a -> BcM b -> BcM b
1671 thenBc_ (BcM expr) (BcM cont) = BcM $ \st0 -> do
1672 (st1, _) <- expr st0
1673 (st2, r) <- cont st1
1674 return (st2, r)
1675
1676 returnBc :: a -> BcM a
1677 returnBc result = BcM $ \st -> (return (st, result))
1678
1679 instance Functor BcM where
1680 fmap = liftM
1681
1682 instance Applicative BcM where
1683 pure = returnBc
1684 (<*>) = ap
1685 (*>) = thenBc_
1686
1687 instance Monad BcM where
1688 (>>=) = thenBc
1689 (>>) = (*>)
1690
1691 instance HasDynFlags BcM where
1692 getDynFlags = BcM $ \st -> return (st, hsc_dflags (bcm_hsc_env st))
1693
1694 getHscEnv :: BcM HscEnv
1695 getHscEnv = BcM $ \st -> return (st, bcm_hsc_env st)
1696
1697 emitBc :: ([FFIInfo] -> ProtoBCO Name) -> BcM (ProtoBCO Name)
1698 emitBc bco
1699 = BcM $ \st -> return (st{ffis=[]}, bco (ffis st))
1700
1701 recordFFIBc :: RemotePtr C_ffi_cif -> BcM ()
1702 recordFFIBc a
1703 = BcM $ \st -> return (st{ffis = FFIInfo a : ffis st}, ())
1704
1705 getLabelBc :: BcM Word16
1706 getLabelBc
1707 = BcM $ \st -> do let nl = nextlabel st
1708 when (nl == maxBound) $
1709 panic "getLabelBc: Ran out of labels"
1710 return (st{nextlabel = nl + 1}, nl)
1711
1712 getLabelsBc :: Word16 -> BcM [Word16]
1713 getLabelsBc n
1714 = BcM $ \st -> let ctr = nextlabel st
1715 in return (st{nextlabel = ctr+n}, [ctr .. ctr+n-1])
1716
1717 getCCArray :: BcM (Array BreakIndex (RemotePtr CostCentre))
1718 getCCArray = BcM $ \st ->
1719 let breaks = expectJust "ByteCodeGen.getCCArray" $ modBreaks st in
1720 return (st, modBreaks_ccs breaks)
1721
1722
1723 newBreakInfo :: BreakIndex -> CgBreakInfo -> BcM ()
1724 newBreakInfo ix info = BcM $ \st ->
1725 return (st{breakInfo = IntMap.insert ix info (breakInfo st)}, ())
1726
1727 newUnique :: BcM Unique
1728 newUnique = BcM $
1729 \st -> case takeUniqFromSupply (uniqSupply st) of
1730 (uniq, us) -> let newState = st { uniqSupply = us }
1731 in return (newState, uniq)
1732
1733 getCurrentModule :: BcM Module
1734 getCurrentModule = BcM $ \st -> return (st, thisModule st)
1735
1736 newId :: Type -> BcM Id
1737 newId ty = do
1738 uniq <- newUnique
1739 return $ mkSysLocal tickFS uniq ty
1740
1741 tickFS :: FastString
1742 tickFS = fsLit "ticked"