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