3f147c53388435088a12098ef7c6d192b56474df
[ghc-hetmet.git] / compiler / ghci / ByteCodeGen.lhs
1 %
2 % (c) The University of Glasgow 2002-2006
3 %
4
5 ByteCodeGen: Generate bytecode from Core
6
7 \begin{code}
8 module ByteCodeGen ( UnlinkedBCO, byteCodeGen, coreExprToBCOs ) where
9
10 #include "HsVersions.h"
11
12 import ByteCodeInstr
13 import ByteCodeItbls
14 import ByteCodeFFI
15 import ByteCodeAsm
16 import ByteCodeLink
17
18 import Outputable
19 import Name
20 import Id
21 import FiniteMap
22 import ForeignCall
23 import HscTypes
24 import CoreUtils
25 import CoreSyn
26 import PprCore
27 import Literal
28 import PrimOp
29 import CoreFVs
30 import Type
31 import DataCon
32 import TyCon
33 import Class
34 import Type
35 import Util
36 import DataCon
37 import Var
38 import VarSet
39 import TysPrim
40 import DynFlags
41 import ErrUtils
42 import Unique
43 import FastString
44 import Panic
45 import SMRep
46 import Bitmap
47 import OrdList
48 import Constants
49
50 import Data.List        ( intersperse, sortBy, zip4, zip6, partition )
51 import Foreign          ( Ptr, castPtr, mallocBytes, pokeByteOff, Word8,
52                           withForeignPtr, castFunPtrToPtr, nullPtr, plusPtr )
53 import Foreign.C
54 import Control.Exception        ( throwDyn )
55
56 import GHC.Exts         ( Int(..), ByteArray# )
57
58 import Control.Monad    ( when )
59 import Data.Char        ( ord, chr )
60
61 import UniqSupply
62 import BreakArray
63 import Data.Maybe
64 import Module 
65 import IdInfo 
66
67 -- -----------------------------------------------------------------------------
68 -- Generating byte code for a complete module 
69
70 byteCodeGen :: DynFlags
71             -> [CoreBind]
72             -> [TyCon]
73             -> ModBreaks 
74             -> IO CompiledByteCode
75 byteCodeGen dflags binds tycs modBreaks 
76    = do showPass dflags "ByteCodeGen"
77
78         let flatBinds = [ (bndr, freeVars rhs) 
79                         | (bndr, rhs) <- flattenBinds binds]
80
81         us <- mkSplitUniqSupply 'y'  
82         (BcM_State _us final_ctr mallocd _, proto_bcos) 
83            <- runBc us modBreaks (mapM schemeTopBind flatBinds)  
84
85         when (notNull mallocd)
86              (panic "ByteCodeGen.byteCodeGen: missing final emitBc?")
87
88         dumpIfSet_dyn dflags Opt_D_dump_BCOs
89            "Proto-BCOs" (vcat (intersperse (char ' ') (map ppr proto_bcos)))
90
91         assembleBCOs proto_bcos tycs
92         
93 -- -----------------------------------------------------------------------------
94 -- Generating byte code for an expression
95
96 -- Returns: (the root BCO for this expression, 
97 --           a list of auxilary BCOs resulting from compiling closures)
98 coreExprToBCOs :: DynFlags
99                -> CoreExpr
100                -> IO UnlinkedBCO
101 coreExprToBCOs dflags expr
102  = do showPass dflags "ByteCodeGen"
103
104       -- create a totally bogus name for the top-level BCO; this
105       -- should be harmless, since it's never used for anything
106       let invented_name  = mkSystemVarName (mkPseudoUniqueE 0) FSLIT("ExprTopLevel")
107           invented_id    = Id.mkLocalId invented_name (panic "invented_id's type")
108           
109       -- the uniques are needed to generate fresh variables when we introduce new
110       -- let bindings for ticked expressions
111       us <- mkSplitUniqSupply 'y'
112       (BcM_State _us final_ctr mallocd _ , proto_bco)  
113          <- runBc us emptyModBreaks (schemeTopBind (invented_id, freeVars expr))
114
115       when (notNull mallocd)
116            (panic "ByteCodeGen.coreExprToBCOs: missing final emitBc?")
117
118       dumpIfSet_dyn dflags Opt_D_dump_BCOs "Proto-BCOs" (ppr proto_bco)
119
120       assembleBCO proto_bco
121
122
123 -- -----------------------------------------------------------------------------
124 -- Compilation schema for the bytecode generator
125
126 type BCInstrList = OrdList BCInstr
127
128 type Sequel = Int       -- back off to this depth before ENTER
129
130 -- Maps Ids to the offset from the stack _base_ so we don't have
131 -- to mess with it after each push/pop.
132 type BCEnv = FiniteMap Id Int   -- To find vars on the stack
133
134 ppBCEnv :: BCEnv -> SDoc
135 ppBCEnv p
136    = text "begin-env"
137      $$ nest 4 (vcat (map pp_one (sortBy cmp_snd (fmToList p))))
138      $$ text "end-env"
139      where
140         pp_one (var, offset) = int offset <> colon <+> ppr var <+> ppr (idCgRep var)
141         cmp_snd x y = compare (snd x) (snd y)
142
143 -- Create a BCO and do a spot of peephole optimisation on the insns
144 -- at the same time.
145 mkProtoBCO
146    :: name
147    -> BCInstrList
148    -> Either  [AnnAlt Id VarSet] (AnnExpr Id VarSet)
149    -> Int
150    -> Int
151    -> [StgWord]
152    -> Bool      -- True <=> is a return point, rather than a function
153    -> [BcPtr]
154    -> ProtoBCO name
155 mkProtoBCO nm instrs_ordlist origin arity bitmap_size bitmap is_ret mallocd_blocks 
156    = ProtoBCO {
157         protoBCOName = nm,
158         protoBCOInstrs = maybe_with_stack_check,
159         protoBCOBitmap = bitmap,
160         protoBCOBitmapSize = bitmap_size,
161         protoBCOArity = arity,
162         protoBCOExpr = origin,
163         protoBCOPtrs = mallocd_blocks
164       }
165      where
166         -- Overestimate the stack usage (in words) of this BCO,
167         -- and if >= iNTERP_STACK_CHECK_THRESH, add an explicit
168         -- stack check.  (The interpreter always does a stack check
169         -- for iNTERP_STACK_CHECK_THRESH words at the start of each
170         -- BCO anyway, so we only need to add an explicit on in the
171         -- (hopefully rare) cases when the (overestimated) stack use
172         -- exceeds iNTERP_STACK_CHECK_THRESH.
173         maybe_with_stack_check
174            | is_ret = peep_d
175                 -- don't do stack checks at return points;
176                 -- everything is aggregated up to the top BCO
177                 -- (which must be a function)
178            | stack_overest >= iNTERP_STACK_CHECK_THRESH
179            = STKCHECK stack_overest : peep_d
180            | otherwise
181            = peep_d     -- the supposedly common case
182              
183         -- We assume that this sum doesn't wrap
184         stack_overest = sum (map bciStackUse peep_d)
185
186         -- Merge local pushes
187         peep_d = peep (fromOL instrs_ordlist)
188
189         peep (PUSH_L off1 : PUSH_L off2 : PUSH_L off3 : rest)
190            = PUSH_LLL off1 (off2-1) (off3-2) : peep rest
191         peep (PUSH_L off1 : PUSH_L off2 : rest)
192            = PUSH_LL off1 (off2-1) : peep rest
193         peep (i:rest)
194            = i : peep rest
195         peep []
196            = []
197
198 argBits :: [CgRep] -> [Bool]
199 argBits [] = []
200 argBits (rep : args)
201   | isFollowableArg rep = False : argBits args
202   | otherwise = take (cgRepSizeW rep) (repeat True) ++ argBits args
203
204 -- -----------------------------------------------------------------------------
205 -- schemeTopBind
206
207 -- Compile code for the right-hand side of a top-level binding
208
209 schemeTopBind :: (Id, AnnExpr Id VarSet) -> BcM (ProtoBCO Name)
210
211
212 schemeTopBind (id, rhs) 
213   | Just data_con <- isDataConWorkId_maybe id,
214     isNullaryRepDataCon data_con = do
215         -- Special case for the worker of a nullary data con.
216         -- It'll look like this:        Nil = /\a -> Nil a
217         -- If we feed it into schemeR, we'll get 
218         --      Nil = Nil
219         -- because mkConAppCode treats nullary constructor applications
220         -- by just re-using the single top-level definition.  So
221         -- for the worker itself, we must allocate it directly.
222     -- ioToBc (putStrLn $ "top level BCO")
223     emitBc (mkProtoBCO (getName id) (toOL [PACK data_con 0, ENTER])
224                        (Right rhs) 0 0 [{-no bitmap-}] False{-not alts-}) 
225
226   | otherwise
227   = schemeR [{- No free variables -}] (id, rhs)
228
229
230 -- -----------------------------------------------------------------------------
231 -- schemeR
232
233 -- Compile code for a right-hand side, to give a BCO that,
234 -- when executed with the free variables and arguments on top of the stack,
235 -- will return with a pointer to the result on top of the stack, after
236 -- removing the free variables and arguments.
237 --
238 -- Park the resulting BCO in the monad.  Also requires the
239 -- variable to which this value was bound, so as to give the
240 -- resulting BCO a name. 
241
242 schemeR :: [Id]                 -- Free vars of the RHS, ordered as they
243                                 -- will appear in the thunk.  Empty for
244                                 -- top-level things, which have no free vars.
245         -> (Id, AnnExpr Id VarSet)
246         -> BcM (ProtoBCO Name)
247 schemeR fvs (nm, rhs)
248 {-
249    | trace (showSDoc (
250               (char ' '
251                $$ (ppr.filter (not.isTyVar).varSetElems.fst) rhs
252                $$ pprCoreExpr (deAnnotate rhs)
253                $$ char ' '
254               ))) False
255    = undefined
256    | otherwise
257 -}
258    = schemeR_wrk fvs nm rhs (collect [] rhs)
259
260 collect :: [Var] -> AnnExpr Id VarSet -> ([Var], AnnExpr' Id VarSet)
261 collect xs (_, AnnNote note e) = collect xs e
262 collect xs (_, AnnCast e _)    = collect xs e
263 collect xs (_, AnnLam x e)     = collect (if isTyVar x then xs else (x:xs)) e
264 collect xs (_, not_lambda)     = (reverse xs, not_lambda)
265
266 schemeR_wrk :: [Id] -> Id -> AnnExpr Id VarSet -> ([Var], AnnExpr' Var VarSet) -> BcM (ProtoBCO Name) 
267 schemeR_wrk fvs nm original_body (args, body)
268    = let 
269          all_args  = reverse args ++ fvs
270          arity     = length all_args
271          -- all_args are the args in reverse order.  We're compiling a function
272          -- \fv1..fvn x1..xn -> e 
273          -- i.e. the fvs come first
274
275          szsw_args = map idSizeW all_args
276          szw_args  = sum szsw_args
277          p_init    = listToFM (zip all_args (mkStackOffsets 0 szsw_args))
278
279          -- make the arg bitmap
280          bits = argBits (reverse (map idCgRep all_args))
281          bitmap_size = length bits
282          bitmap = mkBitmap bits
283      in do
284      body_code <- schemeER_wrk szw_args p_init body   
285  
286      emitBc (mkProtoBCO (getName nm) body_code (Right original_body)
287                 arity bitmap_size bitmap False{-not alts-})
288
289 -- introduce break instructions for ticked expressions
290 schemeER_wrk :: Int -> BCEnv -> AnnExpr' Id VarSet -> BcM BCInstrList
291 schemeER_wrk d p rhs
292    | Just (tickInfo, (_annot, newRhs)) <- isTickedExp' rhs = do 
293         code <- schemeE d 0 p newRhs 
294         arr <- getBreakArray 
295         let idOffSets = getVarOffSets d p tickInfo 
296         let tickNumber = tickInfo_number tickInfo
297         let breakInfo = BreakInfo 
298                         { breakInfo_module = tickInfo_module tickInfo
299                         , breakInfo_number = tickNumber 
300                         , breakInfo_vars = idOffSets
301                         , breakInfo_resty = exprType (deAnnotate' newRhs)
302                         }
303         let breakInstr = case arr of (BA arr#) -> BRK_FUN arr# tickNumber breakInfo 
304         return $ breakInstr `consOL` code
305    | otherwise = schemeE d 0 p rhs 
306
307 getVarOffSets :: Int -> BCEnv -> TickInfo -> [(Id, Int)]
308 getVarOffSets d p = catMaybes . map (getOffSet d p) . tickInfo_locals 
309
310 getOffSet :: Int -> BCEnv -> Id -> Maybe (Id, Int)
311 getOffSet d env id 
312    = case lookupBCEnv_maybe env id of
313         Nothing     -> Nothing 
314         Just offset -> Just (id, d - offset)
315
316 fvsToEnv :: BCEnv -> VarSet -> [Id]
317 -- Takes the free variables of a right-hand side, and
318 -- delivers an ordered list of the local variables that will
319 -- be captured in the thunk for the RHS
320 -- The BCEnv argument tells which variables are in the local
321 -- environment: these are the ones that should be captured
322 --
323 -- The code that constructs the thunk, and the code that executes
324 -- it, have to agree about this layout
325 fvsToEnv p fvs = [v | v <- varSetElems fvs, 
326                       isId v,           -- Could be a type variable
327                       v `elemFM` p]
328
329 -- -----------------------------------------------------------------------------
330 -- schemeE
331
332 data TickInfo 
333    = TickInfo   
334      { tickInfo_number :: Int     -- the (module) unique number of the tick
335      , tickInfo_module :: Module  -- the origin of the ticked expression 
336      , tickInfo_locals :: [Id]    -- the local vars in scope at the ticked expression
337      } 
338
339 instance Outputable TickInfo where
340    ppr info = text "TickInfo" <+> 
341               parens (int (tickInfo_number info) <+> ppr (tickInfo_module info) <+>
342                       ppr (tickInfo_locals info))
343
344 -- Compile code to apply the given expression to the remaining args
345 -- on the stack, returning a HNF.
346 schemeE :: Int -> Sequel -> BCEnv -> AnnExpr' Id VarSet -> BcM BCInstrList
347
348 -- Delegate tail-calls to schemeT.
349 schemeE d s p e@(AnnApp f a) 
350    = schemeT d s p e
351
352 schemeE d s p e@(AnnVar v)
353    | not (isUnLiftedType v_type)
354    =  -- Lifted-type thing; push it in the normal way
355      schemeT d s p e
356
357    | otherwise
358    = do -- Returning an unlifted value.  
359         -- Heave it on the stack, SLIDE, and RETURN.
360         (push, szw) <- pushAtom d p (AnnVar v)
361         return (push                    -- value onto stack
362                   `appOL`  mkSLIDE szw (d-s)    -- clear to sequel
363                   `snocOL` RETURN_UBX v_rep)    -- go
364    where
365       v_type = idType v
366       v_rep = typeCgRep v_type
367
368 schemeE d s p (AnnLit literal)
369    = do (push, szw) <- pushAtom d p (AnnLit literal)
370         let l_rep = typeCgRep (literalType literal)
371         return (push                    -- value onto stack
372                `appOL`  mkSLIDE szw (d-s)       -- clear to sequel
373                `snocOL` RETURN_UBX l_rep)       -- go
374
375 schemeE d s p (AnnLet (AnnNonRec x (_,rhs)) (_,body))
376    | (AnnVar v, args_r_to_l) <- splitApp rhs,
377      Just data_con <- isDataConWorkId_maybe v,
378      dataConRepArity data_con == length args_r_to_l
379    = do -- Special case for a non-recursive let whose RHS is a 
380         -- saturatred constructor application.
381         -- Just allocate the constructor and carry on
382         alloc_code <- mkConAppCode d s p data_con args_r_to_l
383         body_code <- schemeE (d+1) s (addToFM p x d) body
384         return (alloc_code `appOL` body_code)
385
386 -- General case for let.  Generates correct, if inefficient, code in
387 -- all situations.
388 schemeE d s p (AnnLet binds (_,body))
389    = let (xs,rhss) = case binds of AnnNonRec x rhs  -> ([x],[rhs])
390                                    AnnRec xs_n_rhss -> unzip xs_n_rhss
391          n_binds = length xs
392
393          fvss  = map (fvsToEnv p' . fst) rhss
394
395          -- Sizes of free vars
396          sizes = map (\rhs_fvs -> sum (map idSizeW rhs_fvs)) fvss
397
398          -- the arity of each rhs
399          arities = map (length . fst . collect []) rhss
400
401          -- This p', d' defn is safe because all the items being pushed
402          -- are ptrs, so all have size 1.  d' and p' reflect the stack
403          -- after the closures have been allocated in the heap (but not
404          -- filled in), and pointers to them parked on the stack.
405          p'    = addListToFM p (zipE xs (mkStackOffsets d (nOfThem n_binds 1)))
406          d'    = d + n_binds
407          zipE  = zipEqual "schemeE"
408
409          -- ToDo: don't build thunks for things with no free variables
410          build_thunk dd [] size bco off arity
411             = return (PUSH_BCO bco `consOL` unitOL (mkap (off+size) size))
412            where 
413                 mkap | arity == 0 = MKAP
414                      | otherwise  = MKPAP
415          build_thunk dd (fv:fvs) size bco off arity = do
416               (push_code, pushed_szw) <- pushAtom dd p' (AnnVar fv) 
417               more_push_code <- build_thunk (dd+pushed_szw) fvs size bco off arity
418               return (push_code `appOL` more_push_code)
419
420          alloc_code = toOL (zipWith mkAlloc sizes arities)
421            where mkAlloc sz 0     = ALLOC_AP sz
422                  mkAlloc sz arity = ALLOC_PAP arity sz
423
424          compile_bind d' fvs x rhs size arity off = do
425                 bco <- schemeR fvs (x,rhs)
426                 build_thunk d' fvs size bco off arity
427
428          compile_binds = 
429             [ compile_bind d' fvs x rhs size arity n
430             | (fvs, x, rhs, size, arity, n) <- 
431                 zip6 fvss xs rhss sizes arities [n_binds, n_binds-1 .. 1]
432             ]
433      in do
434      body_code <- schemeE d' s p' body
435      thunk_codes <- sequence compile_binds
436      return (alloc_code `appOL` concatOL thunk_codes `appOL` body_code)
437
438 -- introduce a let binding for a ticked case expression. This rule
439 -- *should* only fire when the expression was not already let-bound
440 -- (the code gen for let bindings should take care of that).  Todo: we
441 -- call exprFreeVars on a deAnnotated expression, this may not be the
442 -- best way to calculate the free vars but it seemed like the least
443 -- intrusive thing to do
444 schemeE d s p exp@(AnnCase {})
445    | Just (tickInfo,rhs) <- isTickedExp' exp
446    = if isUnLiftedType ty
447         then schemeE d s p (snd rhs)
448         else do
449           id <- newId ty
450           -- Todo: is emptyVarSet correct on the next line?
451           let letExp = AnnLet (AnnNonRec id (fvs, exp)) (emptyVarSet, AnnVar id)
452           schemeE d s p letExp
453    where exp' = deAnnotate' exp
454          fvs  = exprFreeVars exp'
455          ty   = exprType exp'
456
457 schemeE d s p (AnnCase scrut bndr _ [(DataAlt dc, [bind1, bind2], rhs)])
458    | isUnboxedTupleCon dc, VoidArg <- typeCgRep (idType bind1)
459         -- Convert 
460         --      case .... of x { (# VoidArg'd-thing, a #) -> ... }
461         -- to
462         --      case .... of a { DEFAULT -> ... }
463         -- becuse the return convention for both are identical.
464         --
465         -- Note that it does not matter losing the void-rep thing from the
466         -- envt (it won't be bound now) because we never look such things up.
467
468    = --trace "automagic mashing of case alts (# VoidArg, a #)" $
469      doCase d s p scrut bind2 [(DEFAULT, [], rhs)] True{-unboxed tuple-} 
470
471    | isUnboxedTupleCon dc, VoidArg <- typeCgRep (idType bind2)
472    = --trace "automagic mashing of case alts (# a, VoidArg #)" $
473      doCase d s p scrut bind1 [(DEFAULT, [], rhs)] True{-unboxed tuple-} 
474
475 schemeE d s p (AnnCase scrut bndr _ [(DataAlt dc, [bind1], rhs)])
476    | isUnboxedTupleCon dc
477         -- Similarly, convert
478         --      case .... of x { (# a #) -> ... }
479         -- to
480         --      case .... of a { DEFAULT -> ... }
481    = --trace "automagic mashing of case alts (# a #)"  $
482      doCase d s p scrut bind1 [(DEFAULT, [], rhs)] True{-unboxed tuple-} 
483
484 schemeE d s p (AnnCase scrut bndr _ alts)
485    = doCase d s p scrut bndr alts False{-not an unboxed tuple-} 
486
487 schemeE d s p (AnnNote note (_, body))
488    = schemeE d s p body
489
490 schemeE d s p (AnnCast (_, body) _)
491    = schemeE d s p body
492
493 schemeE d s p other
494    = pprPanic "ByteCodeGen.schemeE: unhandled case" 
495                (pprCoreExpr (deAnnotate' other))
496
497 {- 
498    Ticked Expressions
499    ------------------
500   
501    A ticked expression looks like this:
502
503       case tick<n> var1 ... varN of DEFAULT -> e
504
505    (*) <n> is the number of the tick, which is unique within a module
506    (*) var1 ... varN are the local variables in scope at the tick site
507
508    If we find a ticked expression we return:
509
510       Just ((n, [var1 ... varN]), e)
511
512   otherwise we return Nothing.
513
514   The idea is that the "case tick<n> ..." is really just an annotation on 
515   the code. When we find such a thing, we pull out the useful information,
516   and then compile the code as if it was just the expression "e".
517
518 -}
519
520 isTickedExp :: AnnExpr Id a -> Maybe (TickInfo, AnnExpr Id a)
521 isTickedExp (annot, expr) = isTickedExp' expr 
522
523 isTickedExp' :: AnnExpr' Id a -> Maybe (TickInfo, AnnExpr Id a)
524 isTickedExp' (AnnCase scrut _bndr _type alts)
525    | Just tickInfo <- isTickedScrut scrut,
526      [(DEFAULT, _bndr, rhs)] <- alts 
527      = Just (tickInfo, rhs)
528    where
529    isTickedScrut :: (AnnExpr Id a) -> Maybe TickInfo 
530    isTickedScrut expr
531       | Var id <- f,
532         Just (TickBox modName tickNumber) <- isTickBoxOp_maybe id
533            = Just $ TickInfo { tickInfo_number = tickNumber
534                              , tickInfo_module = modName
535                              , tickInfo_locals = idsOfArgs args
536                              }
537       | otherwise = Nothing
538       where
539       (f, args) = collectArgs $ deAnnotate expr
540       idsOfArgs :: [Expr Id] -> [Id]
541       idsOfArgs = catMaybes . map exprId 
542       exprId :: Expr Id -> Maybe Id
543       exprId (Var id) = Just id
544       exprId other    = Nothing
545
546 isTickedExp' other = Nothing
547
548 -- Compile code to do a tail call.  Specifically, push the fn,
549 -- slide the on-stack app back down to the sequel depth,
550 -- and enter.  Four cases:
551 --
552 -- 0.  (Nasty hack).
553 --     An application "GHC.Prim.tagToEnum# <type> unboxed-int".
554 --     The int will be on the stack.  Generate a code sequence
555 --     to convert it to the relevant constructor, SLIDE and ENTER.
556 --
557 -- 1.  The fn denotes a ccall.  Defer to generateCCall.
558 --
559 -- 2.  (Another nasty hack).  Spot (# a::VoidArg, b #) and treat
560 --     it simply as  b  -- since the representations are identical
561 --     (the VoidArg takes up zero stack space).  Also, spot
562 --     (# b #) and treat it as  b.
563 --
564 -- 3.  Application of a constructor, by defn saturated.
565 --     Split the args into ptrs and non-ptrs, and push the nonptrs, 
566 --     then the ptrs, and then do PACK and RETURN.
567 --
568 -- 4.  Otherwise, it must be a function call.  Push the args
569 --     right to left, SLIDE and ENTER.
570
571 schemeT :: Int          -- Stack depth
572         -> Sequel       -- Sequel depth
573         -> BCEnv        -- stack env
574         -> AnnExpr' Id VarSet 
575         -> BcM BCInstrList
576
577 schemeT d s p app
578
579 --   | trace ("schemeT: env in = \n" ++ showSDocDebug (ppBCEnv p)) False
580 --   = panic "schemeT ?!?!"
581
582 --   | trace ("\nschemeT\n" ++ showSDoc (pprCoreExpr (deAnnotate' app)) ++ "\n") False
583 --   = error "?!?!" 
584
585    -- Case 0
586    | Just (arg, constr_names) <- maybe_is_tagToEnum_call
587    = do (push, arg_words) <- pushAtom d p arg
588         tagToId_sequence <- implement_tagToId constr_names
589         return (push `appOL`  tagToId_sequence            
590                        `appOL`  mkSLIDE 1 (d+arg_words-s)
591                        `snocOL` ENTER)
592
593    -- Case 1
594    | Just (CCall ccall_spec) <- isFCallId_maybe fn
595    = generateCCall d s p ccall_spec fn args_r_to_l
596
597    -- Case 2: Constructor application
598    | Just con <- maybe_saturated_dcon,
599      isUnboxedTupleCon con
600    = case args_r_to_l of
601         [arg1,arg2] | isVoidArgAtom arg1 -> 
602                   unboxedTupleReturn d s p arg2
603         [arg1,arg2] | isVoidArgAtom arg2 -> 
604                   unboxedTupleReturn d s p arg1
605         _other -> unboxedTupleException
606
607    -- Case 3: Ordinary data constructor
608    | Just con <- maybe_saturated_dcon
609    = do alloc_con <- mkConAppCode d s p con args_r_to_l
610         return (alloc_con        `appOL` 
611                   mkSLIDE 1 (d - s) `snocOL`
612                   ENTER)
613
614    -- Case 4: Tail call of function 
615    | otherwise
616    = doTailCall d s p fn args_r_to_l
617
618    where
619       -- Detect and extract relevant info for the tagToEnum kludge.
620       maybe_is_tagToEnum_call
621          = let extract_constr_Names ty
622                  | Just (tyc, []) <- splitTyConApp_maybe (repType ty),
623                    isDataTyCon tyc
624                    = map (getName . dataConWorkId) (tyConDataCons tyc)
625                    -- NOTE: use the worker name, not the source name of
626                    -- the DataCon.  See DataCon.lhs for details.
627                  | otherwise
628                    = panic "maybe_is_tagToEnum_call.extract_constr_Ids"
629            in
630            case app of
631               (AnnApp (_, AnnApp (_, AnnVar v) (_, AnnType t)) arg)
632                  -> case isPrimOpId_maybe v of
633                        Just TagToEnumOp -> Just (snd arg, extract_constr_Names t)
634                        other            -> Nothing
635               other -> Nothing
636
637         -- Extract the args (R->L) and fn
638         -- The function will necessarily be a variable, 
639         -- because we are compiling a tail call
640       (AnnVar fn, args_r_to_l) = splitApp app
641
642       -- Only consider this to be a constructor application iff it is
643       -- saturated.  Otherwise, we'll call the constructor wrapper.
644       n_args = length args_r_to_l
645       maybe_saturated_dcon  
646         = case isDataConWorkId_maybe fn of
647                 Just con | dataConRepArity con == n_args -> Just con
648                 _ -> Nothing
649
650 -- -----------------------------------------------------------------------------
651 -- Generate code to build a constructor application, 
652 -- leaving it on top of the stack
653
654 mkConAppCode :: Int -> Sequel -> BCEnv
655              -> DataCon                 -- The data constructor
656              -> [AnnExpr' Id VarSet]    -- Args, in *reverse* order
657              -> BcM BCInstrList
658
659 mkConAppCode orig_d s p con []  -- Nullary constructor
660   = ASSERT( isNullaryRepDataCon con )
661     return (unitOL (PUSH_G (getName (dataConWorkId con))))
662         -- Instead of doing a PACK, which would allocate a fresh
663         -- copy of this constructor, use the single shared version.
664
665 mkConAppCode orig_d s p con args_r_to_l 
666   = ASSERT( dataConRepArity con == length args_r_to_l )
667     do_pushery orig_d (non_ptr_args ++ ptr_args)
668  where
669         -- The args are already in reverse order, which is the way PACK
670         -- expects them to be.  We must push the non-ptrs after the ptrs.
671       (ptr_args, non_ptr_args) = partition isPtrAtom args_r_to_l
672
673       do_pushery d (arg:args)
674          = do (push, arg_words) <- pushAtom d p arg
675               more_push_code <- do_pushery (d+arg_words) args
676               return (push `appOL` more_push_code)
677       do_pushery d []
678          = return (unitOL (PACK con n_arg_words))
679          where
680            n_arg_words = d - orig_d
681
682
683 -- -----------------------------------------------------------------------------
684 -- Returning an unboxed tuple with one non-void component (the only
685 -- case we can handle).
686 --
687 -- Remember, we don't want to *evaluate* the component that is being
688 -- returned, even if it is a pointed type.  We always just return.
689
690 unboxedTupleReturn
691         :: Int -> Sequel -> BCEnv
692         -> AnnExpr' Id VarSet -> BcM BCInstrList
693 unboxedTupleReturn d s p arg = do
694   (push, sz) <- pushAtom d p arg
695   return (push `appOL`
696             mkSLIDE sz (d-s) `snocOL`
697             RETURN_UBX (atomRep arg))
698
699 -- -----------------------------------------------------------------------------
700 -- Generate code for a tail-call
701
702 doTailCall
703         :: Int -> Sequel -> BCEnv
704         -> Id -> [AnnExpr' Id VarSet]
705         -> BcM BCInstrList
706 doTailCall init_d s p fn args
707   = do_pushes init_d args (map atomRep args)
708   where
709   do_pushes d [] reps = do
710         ASSERT( null reps ) return ()
711         (push_fn, sz) <- pushAtom d p (AnnVar fn)
712         ASSERT( sz == 1 ) return ()
713         return (push_fn `appOL` (
714                   mkSLIDE ((d-init_d) + 1) (init_d - s) `appOL`
715                   unitOL ENTER))
716   do_pushes d args reps = do
717       let (push_apply, n, rest_of_reps) = findPushSeq reps
718           (these_args, rest_of_args) = splitAt n args
719       (next_d, push_code) <- push_seq d these_args
720       instrs <- do_pushes (next_d + 1) rest_of_args rest_of_reps 
721                 --                ^^^ for the PUSH_APPLY_ instruction
722       return (push_code `appOL` (push_apply `consOL` instrs))
723
724   push_seq d [] = return (d, nilOL)
725   push_seq d (arg:args) = do
726     (push_code, sz) <- pushAtom d p arg 
727     (final_d, more_push_code) <- push_seq (d+sz) args
728     return (final_d, push_code `appOL` more_push_code)
729
730 -- v. similar to CgStackery.findMatch, ToDo: merge
731 findPushSeq (PtrArg: PtrArg: PtrArg: PtrArg: PtrArg: PtrArg: rest)
732   = (PUSH_APPLY_PPPPPP, 6, rest)
733 findPushSeq (PtrArg: PtrArg: PtrArg: PtrArg: PtrArg: rest)
734   = (PUSH_APPLY_PPPPP, 5, rest)
735 findPushSeq (PtrArg: PtrArg: PtrArg: PtrArg: rest)
736   = (PUSH_APPLY_PPPP, 4, rest)
737 findPushSeq (PtrArg: PtrArg: PtrArg: rest)
738   = (PUSH_APPLY_PPP, 3, rest)
739 findPushSeq (PtrArg: PtrArg: rest)
740   = (PUSH_APPLY_PP, 2, rest)
741 findPushSeq (PtrArg: rest)
742   = (PUSH_APPLY_P, 1, rest)
743 findPushSeq (VoidArg: rest)
744   = (PUSH_APPLY_V, 1, rest)
745 findPushSeq (NonPtrArg: rest)
746   = (PUSH_APPLY_N, 1, rest)
747 findPushSeq (FloatArg: rest)
748   = (PUSH_APPLY_F, 1, rest)
749 findPushSeq (DoubleArg: rest)
750   = (PUSH_APPLY_D, 1, rest)
751 findPushSeq (LongArg: rest)
752   = (PUSH_APPLY_L, 1, rest)
753 findPushSeq _
754   = panic "ByteCodeGen.findPushSeq"
755
756 -- -----------------------------------------------------------------------------
757 -- Case expressions
758
759 doCase  :: Int -> Sequel -> BCEnv
760         -> AnnExpr Id VarSet -> Id -> [AnnAlt Id VarSet]
761         -> Bool  -- True <=> is an unboxed tuple case, don't enter the result
762         -> BcM BCInstrList
763 doCase d s p (_,scrut) bndr alts is_unboxed_tuple 
764   = let
765         -- Top of stack is the return itbl, as usual.
766         -- underneath it is the pointer to the alt_code BCO.
767         -- When an alt is entered, it assumes the returned value is
768         -- on top of the itbl.
769         ret_frame_sizeW = 2
770
771         -- An unlifted value gets an extra info table pushed on top
772         -- when it is returned.
773         unlifted_itbl_sizeW | isAlgCase = 0
774                             | otherwise = 1
775
776         -- depth of stack after the return value has been pushed
777         d_bndr = d + ret_frame_sizeW + idSizeW bndr
778
779         -- depth of stack after the extra info table for an unboxed return
780         -- has been pushed, if any.  This is the stack depth at the
781         -- continuation.
782         d_alts = d_bndr + unlifted_itbl_sizeW
783
784         -- Env in which to compile the alts, not including
785         -- any vars bound by the alts themselves
786         p_alts = addToFM p bndr (d_bndr - 1)
787
788         bndr_ty = idType bndr
789         isAlgCase = not (isUnLiftedType bndr_ty) && not is_unboxed_tuple
790
791         -- given an alt, return a discr and code for it.
792         codeAlt alt@(DEFAULT, _, (_,rhs))
793            = do rhs_code <- schemeE d_alts s p_alts rhs
794                 return (NoDiscr, rhs_code)
795
796         codeAlt alt@(discr, bndrs, (_,rhs))
797            -- primitive or nullary constructor alt: no need to UNPACK
798            | null real_bndrs = do
799                 rhs_code <- schemeE d_alts s p_alts rhs
800                 return (my_discr alt, rhs_code)
801            -- algebraic alt with some binders
802            | ASSERT(isAlgCase) otherwise =
803              let
804                  (ptrs,nptrs) = partition (isFollowableArg.idCgRep) real_bndrs
805                  ptr_sizes    = map idSizeW ptrs
806                  nptrs_sizes  = map idSizeW nptrs
807                  bind_sizes   = ptr_sizes ++ nptrs_sizes
808                  size         = sum ptr_sizes + sum nptrs_sizes
809                  -- the UNPACK instruction unpacks in reverse order...
810                  p' = addListToFM p_alts 
811                         (zip (reverse (ptrs ++ nptrs))
812                           (mkStackOffsets d_alts (reverse bind_sizes)))
813              in do
814              rhs_code <- schemeE (d_alts+size) s p' rhs
815              return (my_discr alt, unitOL (UNPACK size) `appOL` rhs_code)
816            where
817              real_bndrs = filter (not.isTyVar) bndrs
818
819         my_discr (DEFAULT, binds, rhs) = NoDiscr {-shouldn't really happen-}
820         my_discr (DataAlt dc, binds, rhs) 
821            | isUnboxedTupleCon dc
822            = unboxedTupleException
823            | otherwise
824            = DiscrP (dataConTag dc - fIRST_TAG)
825         my_discr (LitAlt l, binds, rhs)
826            = case l of MachInt i     -> DiscrI (fromInteger i)
827                        MachFloat r   -> DiscrF (fromRational r)
828                        MachDouble r  -> DiscrD (fromRational r)
829                        MachChar i    -> DiscrI (ord i)
830                        _ -> pprPanic "schemeE(AnnCase).my_discr" (ppr l)
831
832         maybe_ncons 
833            | not isAlgCase = Nothing
834            | otherwise 
835            = case [dc | (DataAlt dc, _, _) <- alts] of
836                 []     -> Nothing
837                 (dc:_) -> Just (tyConFamilySize (dataConTyCon dc))
838
839         -- the bitmap is relative to stack depth d, i.e. before the
840         -- BCO, info table and return value are pushed on.
841         -- This bit of code is v. similar to buildLivenessMask in CgBindery,
842         -- except that here we build the bitmap from the known bindings of
843         -- things that are pointers, whereas in CgBindery the code builds the
844         -- bitmap from the free slots and unboxed bindings.
845         -- (ToDo: merge?)
846         --
847         -- NOTE [7/12/2006] bug #1013, testcase ghci/should_run/ghci002.
848         -- The bitmap must cover the portion of the stack up to the sequel only.
849         -- Previously we were building a bitmap for the whole depth (d), but we
850         -- really want a bitmap up to depth (d-s).  This affects compilation of
851         -- case-of-case expressions, which is the only time we can be compiling a
852         -- case expression with s /= 0.
853         bitmap_size = d-s
854         bitmap = intsToReverseBitmap bitmap_size{-size-} 
855                         (sortLe (<=) (filter (< bitmap_size) rel_slots))
856           where
857           binds = fmToList p
858           rel_slots = concat (map spread binds)
859           spread (id, offset)
860                 | isFollowableArg (idCgRep id) = [ rel_offset ]
861                 | otherwise = []
862                 where rel_offset = d - offset - 1
863
864      in do
865      alt_stuff <- mapM codeAlt alts
866      alt_final <- mkMultiBranch maybe_ncons alt_stuff
867
868      let 
869          alt_bco_name = getName bndr
870          alt_bco = mkProtoBCO alt_bco_name alt_final (Left alts)
871                         0{-no arity-} bitmap_size bitmap True{-is alts-}
872      -- in
873 --     trace ("case: bndr = " ++ showSDocDebug (ppr bndr) ++ "\ndepth = " ++ show d ++ "\nenv = \n" ++ showSDocDebug (ppBCEnv p) ++
874 --           "\n      bitmap = " ++ show bitmap) $ do
875      scrut_code <- schemeE (d + ret_frame_sizeW) (d + ret_frame_sizeW) p scrut
876      alt_bco' <- emitBc alt_bco
877      let push_alts
878             | isAlgCase = PUSH_ALTS alt_bco'
879             | otherwise = PUSH_ALTS_UNLIFTED alt_bco' (typeCgRep bndr_ty)
880      return (push_alts `consOL` scrut_code)
881
882
883 -- -----------------------------------------------------------------------------
884 -- Deal with a CCall.
885
886 -- Taggedly push the args onto the stack R->L,
887 -- deferencing ForeignObj#s and adjusting addrs to point to
888 -- payloads in Ptr/Byte arrays.  Then, generate the marshalling
889 -- (machine) code for the ccall, and create bytecodes to call that and
890 -- then return in the right way.  
891
892 generateCCall :: Int -> Sequel          -- stack and sequel depths
893               -> BCEnv
894               -> CCallSpec              -- where to call
895               -> Id                     -- of target, for type info
896               -> [AnnExpr' Id VarSet]   -- args (atoms)
897               -> BcM BCInstrList
898
899 generateCCall d0 s p ccall_spec@(CCallSpec target cconv safety) fn args_r_to_l
900    = let 
901          -- useful constants
902          addr_sizeW = cgRepSizeW NonPtrArg
903
904          -- Get the args on the stack, with tags and suitably
905          -- dereferenced for the CCall.  For each arg, return the
906          -- depth to the first word of the bits for that arg, and the
907          -- CgRep of what was actually pushed.
908
909          pargs d [] = return []
910          pargs d (a:az) 
911             = let arg_ty = repType (exprType (deAnnotate' a))
912
913               in case splitTyConApp_maybe arg_ty of
914                     -- Don't push the FO; instead push the Addr# it
915                     -- contains.
916                     Just (t, _)
917                      | t == arrayPrimTyCon || t == mutableArrayPrimTyCon
918                        -> do rest <- pargs (d + addr_sizeW) az
919                              code <- parg_ArrayishRep arrPtrsHdrSize d p a
920                              return ((code,NonPtrArg):rest)
921
922                      | t == byteArrayPrimTyCon || t == mutableByteArrayPrimTyCon
923                        -> do rest <- pargs (d + addr_sizeW) az
924                              code <- parg_ArrayishRep arrWordsHdrSize d p a
925                              return ((code,NonPtrArg):rest)
926
927                     -- Default case: push taggedly, but otherwise intact.
928                     other
929                        -> do (code_a, sz_a) <- pushAtom d p a
930                              rest <- pargs (d+sz_a) az
931                              return ((code_a, atomRep a) : rest)
932
933          -- Do magic for Ptr/Byte arrays.  Push a ptr to the array on
934          -- the stack but then advance it over the headers, so as to
935          -- point to the payload.
936          parg_ArrayishRep hdrSize d p a
937             = do (push_fo, _) <- pushAtom d p a
938                  -- The ptr points at the header.  Advance it over the
939                  -- header and then pretend this is an Addr#.
940                  return (push_fo `snocOL` SWIZZLE 0 hdrSize)
941
942      in do
943      code_n_reps <- pargs d0 args_r_to_l
944      let
945          (pushs_arg, a_reps_pushed_r_to_l) = unzip code_n_reps
946
947          push_args    = concatOL pushs_arg
948          d_after_args = d0 + sum (map cgRepSizeW a_reps_pushed_r_to_l)
949          a_reps_pushed_RAW
950             | null a_reps_pushed_r_to_l || head a_reps_pushed_r_to_l /= VoidArg
951             = panic "ByteCodeGen.generateCCall: missing or invalid World token?"
952             | otherwise
953             = reverse (tail a_reps_pushed_r_to_l)
954
955          -- Now: a_reps_pushed_RAW are the reps which are actually on the stack.
956          -- push_args is the code to do that.
957          -- d_after_args is the stack depth once the args are on.
958
959          -- Get the result rep.
960          (returns_void, r_rep)
961             = case maybe_getCCallReturnRep (idType fn) of
962                  Nothing -> (True,  VoidArg)
963                  Just rr -> (False, rr) 
964          {-
965          Because the Haskell stack grows down, the a_reps refer to 
966          lowest to highest addresses in that order.  The args for the call
967          are on the stack.  Now push an unboxed Addr# indicating
968          the C function to call.  Then push a dummy placeholder for the 
969          result.  Finally, emit a CCALL insn with an offset pointing to the 
970          Addr# just pushed, and a literal field holding the mallocville
971          address of the piece of marshalling code we generate.
972          So, just prior to the CCALL insn, the stack looks like this 
973          (growing down, as usual):
974                  
975             <arg_n>
976             ...
977             <arg_1>
978             Addr# address_of_C_fn
979             <placeholder-for-result#> (must be an unboxed type)
980
981          The interpreter then calls the marshall code mentioned
982          in the CCALL insn, passing it (& <placeholder-for-result#>), 
983          that is, the addr of the topmost word in the stack.
984          When this returns, the placeholder will have been
985          filled in.  The placeholder is slid down to the sequel
986          depth, and we RETURN.
987
988          This arrangement makes it simple to do f-i-dynamic since the Addr#
989          value is the first arg anyway.
990
991          The marshalling code is generated specifically for this
992          call site, and so knows exactly the (Haskell) stack
993          offsets of the args, fn address and placeholder.  It
994          copies the args to the C stack, calls the stacked addr,
995          and parks the result back in the placeholder.  The interpreter
996          calls it as a normal C call, assuming it has a signature
997             void marshall_code ( StgWord* ptr_to_top_of_stack )
998          -}
999          -- resolve static address
1000          get_target_info
1001             = case target of
1002                  DynamicTarget
1003                     -> return (False, panic "ByteCodeGen.generateCCall(dyn)")
1004                  StaticTarget target
1005                     -> do res <- ioToBc (lookupStaticPtr target)
1006                           return (True, res)
1007      -- in
1008      (is_static, static_target_addr) <- get_target_info
1009      let
1010
1011          -- Get the arg reps, zapping the leading Addr# in the dynamic case
1012          a_reps --  | trace (showSDoc (ppr a_reps_pushed_RAW)) False = error "???"
1013                 | is_static = a_reps_pushed_RAW
1014                 | otherwise = if null a_reps_pushed_RAW 
1015                               then panic "ByteCodeGen.generateCCall: dyn with no args"
1016                               else tail a_reps_pushed_RAW
1017
1018          -- push the Addr#
1019          (push_Addr, d_after_Addr)
1020             | is_static
1021             = (toOL [PUSH_UBX (Right static_target_addr) addr_sizeW],
1022                d_after_args + addr_sizeW)
1023             | otherwise -- is already on the stack
1024             = (nilOL, d_after_args)
1025
1026          -- Push the return placeholder.  For a call returning nothing,
1027          -- this is a VoidArg (tag).
1028          r_sizeW   = cgRepSizeW r_rep
1029          d_after_r = d_after_Addr + r_sizeW
1030          r_lit     = mkDummyLiteral r_rep
1031          push_r    = (if   returns_void 
1032                       then nilOL 
1033                       else unitOL (PUSH_UBX (Left r_lit) r_sizeW))
1034
1035          -- generate the marshalling code we're going to call
1036          r_offW       = 0 
1037          addr_offW    = r_sizeW
1038          arg1_offW    = r_sizeW + addr_sizeW
1039          args_offW    = map (arg1_offW +) 
1040                             (init (scanl (+) 0 (map cgRepSizeW a_reps)))
1041      -- in
1042      addr_of_marshaller <- ioToBc (mkMarshalCode cconv
1043                                 (r_offW, r_rep) addr_offW
1044                                 (zip args_offW a_reps))
1045      recordItblMallocBc (ItblPtr (castFunPtrToPtr addr_of_marshaller))
1046      let
1047          -- Offset of the next stack frame down the stack.  The CCALL
1048          -- instruction needs to describe the chunk of stack containing
1049          -- the ccall args to the GC, so it needs to know how large it
1050          -- is.  See comment in Interpreter.c with the CCALL instruction.
1051          stk_offset   = d_after_r - s
1052
1053          -- do the call
1054          do_call      = unitOL (CCALL stk_offset (castFunPtrToPtr addr_of_marshaller))
1055          -- slide and return
1056          wrapup       = mkSLIDE r_sizeW (d_after_r - r_sizeW - s)
1057                         `snocOL` RETURN_UBX r_rep
1058      --in
1059          --trace (show (arg1_offW, args_offW  ,  (map cgRepSizeW a_reps) )) $
1060      return (
1061          push_args `appOL`
1062          push_Addr `appOL` push_r `appOL` do_call `appOL` wrapup
1063          )
1064
1065
1066 -- Make a dummy literal, to be used as a placeholder for FFI return
1067 -- values on the stack.
1068 mkDummyLiteral :: CgRep -> Literal
1069 mkDummyLiteral pr
1070    = case pr of
1071         NonPtrArg -> MachWord 0
1072         DoubleArg -> MachDouble 0
1073         FloatArg  -> MachFloat 0
1074         LongArg   -> MachWord64 0
1075         _         -> moan64 "mkDummyLiteral" (ppr pr)
1076
1077
1078 -- Convert (eg) 
1079 --     GHC.Prim.Char# -> GHC.Prim.State# GHC.Prim.RealWorld
1080 --                   -> (# GHC.Prim.State# GHC.Prim.RealWorld, GHC.Prim.Int# #)
1081 --
1082 -- to  Just IntRep
1083 -- and check that an unboxed pair is returned wherein the first arg is VoidArg'd.
1084 --
1085 -- Alternatively, for call-targets returning nothing, convert
1086 --
1087 --     GHC.Prim.Char# -> GHC.Prim.State# GHC.Prim.RealWorld
1088 --                   -> (# GHC.Prim.State# GHC.Prim.RealWorld #)
1089 --
1090 -- to  Nothing
1091
1092 maybe_getCCallReturnRep :: Type -> Maybe CgRep
1093 maybe_getCCallReturnRep fn_ty
1094    = let (a_tys, r_ty) = splitFunTys (dropForAlls fn_ty)
1095          maybe_r_rep_to_go  
1096             = if isSingleton r_reps then Nothing else Just (r_reps !! 1)
1097          (r_tycon, r_reps) 
1098             = case splitTyConApp_maybe (repType r_ty) of
1099                       (Just (tyc, tys)) -> (tyc, map typeCgRep tys)
1100                       Nothing -> blargh
1101          ok = ( ( r_reps `lengthIs` 2 && VoidArg == head r_reps)
1102                 || r_reps == [VoidArg] )
1103               && isUnboxedTupleTyCon r_tycon
1104               && case maybe_r_rep_to_go of
1105                     Nothing    -> True
1106                     Just r_rep -> r_rep /= PtrArg
1107                                   -- if it was, it would be impossible 
1108                                   -- to create a valid return value 
1109                                   -- placeholder on the stack
1110          blargh = pprPanic "maybe_getCCallReturn: can't handle:" 
1111                            (pprType fn_ty)
1112      in 
1113      --trace (showSDoc (ppr (a_reps, r_reps))) $
1114      if ok then maybe_r_rep_to_go else blargh
1115
1116 -- Compile code which expects an unboxed Int on the top of stack,
1117 -- (call it i), and pushes the i'th closure in the supplied list 
1118 -- as a consequence.
1119 implement_tagToId :: [Name] -> BcM BCInstrList
1120 implement_tagToId names
1121    = ASSERT( notNull names )
1122      do labels <- getLabelsBc (length names)
1123         label_fail <- getLabelBc
1124         label_exit <- getLabelBc
1125         let infos = zip4 labels (tail labels ++ [label_fail])
1126                                 [0 ..] names
1127             steps = map (mkStep label_exit) infos
1128         return (concatOL steps
1129                   `appOL` 
1130                   toOL [LABEL label_fail, CASEFAIL, LABEL label_exit])
1131      where
1132         mkStep l_exit (my_label, next_label, n, name_for_n)
1133            = toOL [LABEL my_label, 
1134                    TESTEQ_I n next_label, 
1135                    PUSH_G name_for_n, 
1136                    JMP l_exit]
1137
1138
1139 -- -----------------------------------------------------------------------------
1140 -- pushAtom
1141
1142 -- Push an atom onto the stack, returning suitable code & number of
1143 -- stack words used.
1144 --
1145 -- The env p must map each variable to the highest- numbered stack
1146 -- slot for it.  For example, if the stack has depth 4 and we
1147 -- tagged-ly push (v :: Int#) on it, the value will be in stack[4],
1148 -- the tag in stack[5], the stack will have depth 6, and p must map v
1149 -- to 5 and not to 4.  Stack locations are numbered from zero, so a
1150 -- depth 6 stack has valid words 0 .. 5.
1151
1152 pushAtom :: Int -> BCEnv -> AnnExpr' Id VarSet -> BcM (BCInstrList, Int)
1153
1154 pushAtom d p (AnnApp f (_, AnnType _))
1155    = pushAtom d p (snd f)
1156
1157 pushAtom d p (AnnNote note e)
1158    = pushAtom d p (snd e)
1159
1160 pushAtom d p (AnnLam x e) 
1161    | isTyVar x 
1162    = pushAtom d p (snd e)
1163
1164 pushAtom d p (AnnVar v)
1165
1166    | idCgRep v == VoidArg
1167    = return (nilOL, 0)
1168
1169    | isFCallId v
1170    = pprPanic "pushAtom: shouldn't get an FCallId here" (ppr v)
1171
1172    | Just primop <- isPrimOpId_maybe v
1173    = return (unitOL (PUSH_PRIMOP primop), 1)
1174
1175    | Just d_v <- lookupBCEnv_maybe p v  -- v is a local variable
1176    = return (toOL (nOfThem sz (PUSH_L (d-d_v+sz-2))), sz)
1177          -- d - d_v                 the number of words between the TOS 
1178          --                         and the 1st slot of the object
1179          --
1180          -- d - d_v - 1             the offset from the TOS of the 1st slot
1181          --
1182          -- d - d_v - 1 + sz - 1    the offset from the TOS of the last slot
1183          --                         of the object.
1184          --
1185          -- Having found the last slot, we proceed to copy the right number of
1186          -- slots on to the top of the stack.
1187
1188     | otherwise  -- v must be a global variable
1189     = ASSERT(sz == 1) 
1190       return (unitOL (PUSH_G (getName v)), sz)
1191
1192     where
1193          sz = idSizeW v
1194
1195
1196 pushAtom d p (AnnLit lit)
1197    = case lit of
1198         MachLabel fs _ -> code NonPtrArg
1199         MachWord w     -> code NonPtrArg
1200         MachInt i      -> code PtrArg
1201         MachFloat r    -> code FloatArg
1202         MachDouble r   -> code DoubleArg
1203         MachChar c     -> code NonPtrArg
1204         MachStr s      -> pushStr s
1205      where
1206         code rep
1207            = let size_host_words = cgRepSizeW rep
1208              in  return (unitOL (PUSH_UBX (Left lit) size_host_words), 
1209                            size_host_words)
1210
1211         pushStr s 
1212            = let getMallocvilleAddr
1213                     = case s of
1214                          FastString _ n _ fp _ -> 
1215                             -- we could grab the Ptr from the ForeignPtr,
1216                             -- but then we have no way to control its lifetime.
1217                             -- In reality it'll probably stay alive long enoungh
1218                             -- by virtue of the global FastString table, but
1219                             -- to be on the safe side we copy the string into
1220                             -- a malloc'd area of memory.
1221                                 do ptr <- ioToBc (mallocBytes (n+1))
1222                                    recordMallocBc ptr
1223                                    ioToBc (
1224                                       withForeignPtr fp $ \p -> do
1225                                          memcpy ptr p (fromIntegral n)
1226                                          pokeByteOff ptr n (fromIntegral (ord '\0') :: Word8)
1227                                          return ptr
1228                                       )
1229              in do
1230                 addr <- getMallocvilleAddr
1231                 -- Get the addr on the stack, untaggedly
1232                 return (unitOL (PUSH_UBX (Right addr) 1), 1)
1233
1234 pushAtom d p (AnnCast e _)
1235    = pushAtom d p (snd e)
1236
1237 pushAtom d p other
1238    = pprPanic "ByteCodeGen.pushAtom" 
1239               (pprCoreExpr (deAnnotate (undefined, other)))
1240
1241 foreign import ccall unsafe "memcpy"
1242  memcpy :: Ptr a -> Ptr b -> CSize -> IO ()
1243
1244
1245 -- -----------------------------------------------------------------------------
1246 -- Given a bunch of alts code and their discrs, do the donkey work
1247 -- of making a multiway branch using a switch tree.
1248 -- What a load of hassle!
1249
1250 mkMultiBranch :: Maybe Int      --  # datacons in tycon, if alg alt
1251                                 -- a hint; generates better code
1252                                 -- Nothing is always safe
1253               -> [(Discr, BCInstrList)] 
1254               -> BcM BCInstrList
1255 mkMultiBranch maybe_ncons raw_ways
1256    = let d_way     = filter (isNoDiscr.fst) raw_ways
1257          notd_ways = sortLe 
1258                         (\w1 w2 -> leAlt (fst w1) (fst w2))
1259                         (filter (not.isNoDiscr.fst) raw_ways)
1260
1261          mkTree :: [(Discr, BCInstrList)] -> Discr -> Discr -> BcM BCInstrList
1262          mkTree [] range_lo range_hi = return the_default
1263
1264          mkTree [val] range_lo range_hi
1265             | range_lo `eqAlt` range_hi 
1266             = return (snd val)
1267             | otherwise
1268             = do label_neq <- getLabelBc
1269                  return (mkTestEQ (fst val) label_neq 
1270                           `consOL` (snd val
1271                           `appOL`   unitOL (LABEL label_neq)
1272                           `appOL`   the_default))
1273
1274          mkTree vals range_lo range_hi
1275             = let n = length vals `div` 2
1276                   vals_lo = take n vals
1277                   vals_hi = drop n vals
1278                   v_mid = fst (head vals_hi)
1279               in do
1280               label_geq <- getLabelBc
1281               code_lo <- mkTree vals_lo range_lo (dec v_mid)
1282               code_hi <- mkTree vals_hi v_mid range_hi
1283               return (mkTestLT v_mid label_geq
1284                         `consOL` (code_lo
1285                         `appOL`   unitOL (LABEL label_geq)
1286                         `appOL`   code_hi))
1287  
1288          the_default 
1289             = case d_way of [] -> unitOL CASEFAIL
1290                             [(_, def)] -> def
1291
1292          -- None of these will be needed if there are no non-default alts
1293          (mkTestLT, mkTestEQ, init_lo, init_hi)
1294             | null notd_ways
1295             = panic "mkMultiBranch: awesome foursome"
1296             | otherwise
1297             = case fst (head notd_ways) of {
1298               DiscrI _ -> ( \(DiscrI i) fail_label -> TESTLT_I i fail_label,
1299                             \(DiscrI i) fail_label -> TESTEQ_I i fail_label,
1300                             DiscrI minBound,
1301                             DiscrI maxBound );
1302               DiscrF _ -> ( \(DiscrF f) fail_label -> TESTLT_F f fail_label,
1303                             \(DiscrF f) fail_label -> TESTEQ_F f fail_label,
1304                             DiscrF minF,
1305                             DiscrF maxF );
1306               DiscrD _ -> ( \(DiscrD d) fail_label -> TESTLT_D d fail_label,
1307                             \(DiscrD d) fail_label -> TESTEQ_D d fail_label,
1308                             DiscrD minD,
1309                             DiscrD maxD );
1310               DiscrP _ -> ( \(DiscrP i) fail_label -> TESTLT_P i fail_label,
1311                             \(DiscrP i) fail_label -> TESTEQ_P i fail_label,
1312                             DiscrP algMinBound,
1313                             DiscrP algMaxBound )
1314               }
1315
1316          (algMinBound, algMaxBound)
1317             = case maybe_ncons of
1318                  Just n  -> (0, n - 1)
1319                  Nothing -> (minBound, maxBound)
1320
1321          (DiscrI i1) `eqAlt` (DiscrI i2) = i1 == i2
1322          (DiscrF f1) `eqAlt` (DiscrF f2) = f1 == f2
1323          (DiscrD d1) `eqAlt` (DiscrD d2) = d1 == d2
1324          (DiscrP i1) `eqAlt` (DiscrP i2) = i1 == i2
1325          NoDiscr     `eqAlt` NoDiscr     = True
1326          _           `eqAlt` _           = False
1327
1328          (DiscrI i1) `leAlt` (DiscrI i2) = i1 <= i2
1329          (DiscrF f1) `leAlt` (DiscrF f2) = f1 <= f2
1330          (DiscrD d1) `leAlt` (DiscrD d2) = d1 <= d2
1331          (DiscrP i1) `leAlt` (DiscrP i2) = i1 <= i2
1332          NoDiscr     `leAlt` NoDiscr     = True
1333          _           `leAlt` _           = False
1334
1335          isNoDiscr NoDiscr = True
1336          isNoDiscr _       = False
1337
1338          dec (DiscrI i) = DiscrI (i-1)
1339          dec (DiscrP i) = DiscrP (i-1)
1340          dec other      = other         -- not really right, but if you
1341                 -- do cases on floating values, you'll get what you deserve
1342
1343          -- same snotty comment applies to the following
1344          minF, maxF :: Float
1345          minD, maxD :: Double
1346          minF = -1.0e37
1347          maxF =  1.0e37
1348          minD = -1.0e308
1349          maxD =  1.0e308
1350      in
1351          mkTree notd_ways init_lo init_hi
1352
1353
1354 -- -----------------------------------------------------------------------------
1355 -- Supporting junk for the compilation schemes
1356
1357 -- Describes case alts
1358 data Discr 
1359    = DiscrI Int
1360    | DiscrF Float
1361    | DiscrD Double
1362    | DiscrP Int
1363    | NoDiscr
1364
1365 instance Outputable Discr where
1366    ppr (DiscrI i) = int i
1367    ppr (DiscrF f) = text (show f)
1368    ppr (DiscrD d) = text (show d)
1369    ppr (DiscrP i) = int i
1370    ppr NoDiscr    = text "DEF"
1371
1372
1373 lookupBCEnv_maybe :: BCEnv -> Id -> Maybe Int
1374 lookupBCEnv_maybe = lookupFM
1375
1376 idSizeW :: Id -> Int
1377 idSizeW id = cgRepSizeW (typeCgRep (idType id))
1378
1379 unboxedTupleException :: a
1380 unboxedTupleException 
1381    = throwDyn 
1382         (Panic 
1383            ("Bytecode generator can't handle unboxed tuples.  Possibly due\n" ++
1384             "\tto foreign import/export decls in source.  Workaround:\n" ++
1385             "\tcompile this module to a .o file, then restart session."))
1386
1387
1388 mkSLIDE n d = if d == 0 then nilOL else unitOL (SLIDE n d)
1389 bind x f    = f x
1390
1391 splitApp :: AnnExpr' id ann -> (AnnExpr' id ann, [AnnExpr' id ann])
1392         -- The arguments are returned in *right-to-left* order
1393 splitApp (AnnApp (_,f) (_,a))
1394                | isTypeAtom a = splitApp f
1395                | otherwise    = case splitApp f of 
1396                                      (f', as) -> (f', a:as)
1397 splitApp (AnnNote n (_,e))    = splitApp e
1398 splitApp (AnnCast (_,e) _)    = splitApp e
1399 splitApp e                    = (e, [])
1400
1401
1402 isTypeAtom :: AnnExpr' id ann -> Bool
1403 isTypeAtom (AnnType _) = True
1404 isTypeAtom _           = False
1405
1406 isVoidArgAtom :: AnnExpr' id ann -> Bool
1407 isVoidArgAtom (AnnVar v)        = typeCgRep (idType v) == VoidArg
1408 isVoidArgAtom (AnnNote n (_,e)) = isVoidArgAtom e
1409 isVoidArgAtom (AnnCast (_,e) _) = isVoidArgAtom e
1410 isVoidArgAtom _                 = False
1411
1412 atomRep :: AnnExpr' Id ann -> CgRep
1413 atomRep (AnnVar v)    = typeCgRep (idType v)
1414 atomRep (AnnLit l)    = typeCgRep (literalType l)
1415 atomRep (AnnNote n b) = atomRep (snd b)
1416 atomRep (AnnApp f (_, AnnType _)) = atomRep (snd f)
1417 atomRep (AnnLam x e) | isTyVar x = atomRep (snd e)
1418 atomRep (AnnCast b _) = atomRep (snd b)
1419 atomRep other = pprPanic "atomRep" (ppr (deAnnotate (undefined,other)))
1420
1421 isPtrAtom :: AnnExpr' Id ann -> Bool
1422 isPtrAtom e = atomRep e == PtrArg
1423
1424 -- Let szsw be the sizes in words of some items pushed onto the stack,
1425 -- which has initial depth d'.  Return the values which the stack environment
1426 -- should map these items to.
1427 mkStackOffsets :: Int -> [Int] -> [Int]
1428 mkStackOffsets original_depth szsw
1429    = map (subtract 1) (tail (scanl (+) original_depth szsw))
1430
1431 -- -----------------------------------------------------------------------------
1432 -- The bytecode generator's monad
1433
1434 type BcPtr = Either ItblPtr (Ptr ())
1435
1436 data BcM_State 
1437    = BcM_State { 
1438         uniqSupply :: UniqSupply,       -- for generating fresh variable names
1439         nextlabel :: Int,               -- for generating local labels
1440         malloced  :: [BcPtr],           -- thunks malloced for current BCO
1441                                         -- Should be free()d when it is GCd
1442         breakArray :: BreakArray        -- array of breakpoint flags 
1443         }
1444
1445 newtype BcM r = BcM (BcM_State -> IO (BcM_State, r))
1446
1447 ioToBc :: IO a -> BcM a
1448 ioToBc io = BcM $ \st -> do 
1449   x <- io 
1450   return (st, x)
1451
1452 runBc :: UniqSupply -> ModBreaks -> BcM r -> IO (BcM_State, r)
1453 runBc us modBreaks (BcM m) 
1454    = m (BcM_State us 0 [] breakArray)   
1455    where
1456    breakArray = modBreaks_flags modBreaks
1457
1458 thenBc :: BcM a -> (a -> BcM b) -> BcM b
1459 thenBc (BcM expr) cont = BcM $ \st0 -> do
1460   (st1, q) <- expr st0
1461   let BcM k = cont q 
1462   (st2, r) <- k st1
1463   return (st2, r)
1464
1465 thenBc_ :: BcM a -> BcM b -> BcM b
1466 thenBc_ (BcM expr) (BcM cont) = BcM $ \st0 -> do
1467   (st1, q) <- expr st0
1468   (st2, r) <- cont st1
1469   return (st2, r)
1470
1471 returnBc :: a -> BcM a
1472 returnBc result = BcM $ \st -> (return (st, result))
1473
1474 instance Monad BcM where
1475   (>>=) = thenBc
1476   (>>)  = thenBc_
1477   return = returnBc
1478
1479 emitBc :: ([BcPtr] -> ProtoBCO Name) -> BcM (ProtoBCO Name)
1480 emitBc bco
1481   = BcM $ \st -> return (st{malloced=[]}, bco (malloced st))
1482
1483 recordMallocBc :: Ptr a -> BcM ()
1484 recordMallocBc a
1485   = BcM $ \st -> return (st{malloced = Right (castPtr a) : malloced st}, ())
1486
1487 recordItblMallocBc :: ItblPtr -> BcM ()
1488 recordItblMallocBc a
1489   = BcM $ \st -> return (st{malloced = Left a : malloced st}, ())
1490
1491 getLabelBc :: BcM Int
1492 getLabelBc
1493   = BcM $ \st -> return (st{nextlabel = 1 + nextlabel st}, nextlabel st)
1494
1495 getLabelsBc :: Int -> BcM [Int]
1496 getLabelsBc n
1497   = BcM $ \st -> let ctr = nextlabel st 
1498                  in return (st{nextlabel = ctr+n}, [ctr .. ctr+n-1])
1499
1500 getBreakArray :: BcM BreakArray 
1501 getBreakArray = BcM $ \st -> return (st, breakArray st)
1502
1503 newUnique :: BcM Unique
1504 newUnique = BcM $
1505    \st -> case splitUniqSupply (uniqSupply st) of
1506              (us1, us2) -> let newState = st { uniqSupply = us2 } 
1507                            in  return (newState, uniqFromSupply us1) 
1508
1509 newId :: Type -> BcM Id
1510 newId ty = do 
1511     uniq <- newUnique
1512     return $ mkSysLocal FSLIT("ticked") uniq ty
1513 \end{code}