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