Interruptible FFI calls with pthread_kill and CancelSynchronousIO. v4
[ghc-hetmet.git] / compiler / ghci / ByteCodeGen.lhs
index 846737e..d654586 100644 (file)
@@ -5,27 +5,20 @@
 ByteCodeGen: Generate bytecode from Core
 
 \begin{code}
-{-# OPTIONS -w #-}
--- The above warning supression flag is a temporary kludge.
--- While working on this module you are encouraged to remove it and fix
--- any warnings in the module. See
---     http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings
--- for details
-
 module ByteCodeGen ( UnlinkedBCO, byteCodeGen, coreExprToBCOs ) where
 
 #include "HsVersions.h"
 
 import ByteCodeInstr
 import ByteCodeItbls
-import ByteCodeFFI
 import ByteCodeAsm
 import ByteCodeLink
+import LibFFI
 
 import Outputable
 import Name
+import MkId
 import Id
-import FiniteMap
 import ForeignCall
 import HscTypes
 import CoreUtils
@@ -37,10 +30,9 @@ import CoreFVs
 import Type
 import DataCon
 import TyCon
-import Class
-import Type
+-- import Type
 import Util
-import DataCon
+-- import DataCon
 import Var
 import VarSet
 import TysPrim
@@ -54,16 +46,14 @@ import Bitmap
 import OrdList
 import Constants
 
-import Data.List       ( intersperse, sortBy, zip4, zip6, partition )
-import Foreign         ( Ptr, castPtr, mallocBytes, pokeByteOff, Word8,
-                         withForeignPtr, castFunPtrToPtr, nullPtr, plusPtr )
+import Data.List
+import Foreign
 import Foreign.C
-import Control.Exception       ( throwDyn )
 
-import GHC.Exts                ( Int(..), ByteArray# )
+-- import GHC.Exts             ( Int(..) )
 
 import Control.Monad   ( when )
-import Data.Char       ( ord, chr )
+import Data.Char
 
 import UniqSupply
 import BreakArray
@@ -71,6 +61,10 @@ import Data.Maybe
 import Module 
 import IdInfo 
 
+import Data.Map (Map)
+import qualified Data.Map as Map
+import qualified FiniteMap as Map
+
 -- -----------------------------------------------------------------------------
 -- Generating byte code for a complete module 
 
@@ -86,7 +80,7 @@ byteCodeGen dflags binds tycs modBreaks
                        | (bndr, rhs) <- flattenBinds binds]
 
         us <- mkSplitUniqSupply 'y'  
-        (BcM_State _us final_ctr mallocd _, proto_bcos) 
+        (BcM_State _us _final_ctr mallocd _, proto_bcos) 
            <- runBc us modBreaks (mapM schemeTopBind flatBinds)  
 
         when (notNull mallocd)
@@ -110,13 +104,13 @@ coreExprToBCOs dflags expr
 
       -- create a totally bogus name for the top-level BCO; this
       -- should be harmless, since it's never used for anything
-      let invented_name  = mkSystemVarName (mkPseudoUniqueE 0) FSLIT("ExprTopLevel")
+      let invented_name  = mkSystemVarName (mkPseudoUniqueE 0) (fsLit "ExprTopLevel")
           invented_id    = Id.mkLocalId invented_name (panic "invented_id's type")
          
       -- the uniques are needed to generate fresh variables when we introduce new
       -- let bindings for ticked expressions
       us <- mkSplitUniqSupply 'y'
-      (BcM_State _us final_ctr mallocd _ , proto_bco)  
+      (BcM_State _us _final_ctr mallocd _ , proto_bco)  
          <- runBc us emptyModBreaks (schemeTopBind (invented_id, freeVars expr))
 
       when (notNull mallocd)
@@ -132,20 +126,22 @@ coreExprToBCOs dflags expr
 
 type BCInstrList = OrdList BCInstr
 
-type Sequel = Int      -- back off to this depth before ENTER
+type Sequel = Word16 -- back off to this depth before ENTER
 
 -- Maps Ids to the offset from the stack _base_ so we don't have
 -- to mess with it after each push/pop.
-type BCEnv = FiniteMap Id Int  -- To find vars on the stack
+type BCEnv = Map Id Word16 -- To find vars on the stack
 
+{-
 ppBCEnv :: BCEnv -> SDoc
 ppBCEnv p
    = text "begin-env"
-     $$ nest 4 (vcat (map pp_one (sortBy cmp_snd (fmToList p))))
+     $$ nest 4 (vcat (map pp_one (sortBy cmp_snd (Map.toList p))))
      $$ text "end-env"
      where
         pp_one (var, offset) = int offset <> colon <+> ppr var <+> ppr (idCgRep var)
         cmp_snd x y = compare (snd x) (snd y)
+-}
 
 -- Create a BCO and do a spot of peephole optimisation on the insns
 -- at the same time.
@@ -154,7 +150,7 @@ mkProtoBCO
    -> BCInstrList
    -> Either  [AnnAlt Id VarSet] (AnnExpr Id VarSet)
    -> Int
-   -> Int
+   -> Word16
    -> [StgWord]
    -> Bool     -- True <=> is a return point, rather than a function
    -> [BcPtr]
@@ -174,17 +170,17 @@ mkProtoBCO nm instrs_ordlist origin arity bitmap_size bitmap is_ret mallocd_bloc
         -- and if >= iNTERP_STACK_CHECK_THRESH, add an explicit
         -- stack check.  (The interpreter always does a stack check
         -- for iNTERP_STACK_CHECK_THRESH words at the start of each
-        -- BCO anyway, so we only need to add an explicit on in the
+        -- BCO anyway, so we only need to add an explicit one in the
         -- (hopefully rare) cases when the (overestimated) stack use
         -- exceeds iNTERP_STACK_CHECK_THRESH.
         maybe_with_stack_check
-          | is_ret && stack_usage < aP_STACK_SPLIM = peep_d
+          | is_ret && stack_usage < fromIntegral aP_STACK_SPLIM = peep_d
                -- don't do stack checks at return points,
                -- everything is aggregated up to the top BCO
                -- (which must be a function).
                 -- That is, unless the stack usage is >= AP_STACK_SPLIM,
                 -- see bug #1466.
-           | stack_usage >= iNTERP_STACK_CHECK_THRESH
+           | stack_usage >= fromIntegral iNTERP_STACK_CHECK_THRESH
            = STKCHECK stack_usage : peep_d
            | otherwise
            = peep_d    -- the supposedly common case
@@ -257,20 +253,21 @@ schemeR fvs (nm, rhs)
 {-
    | trace (showSDoc (
               (char ' '
-               $$ (ppr.filter (not.isTyVar).varSetElems.fst) rhs
+               $$ (ppr.filter (not.isTyCoVar).varSetElems.fst) rhs
                $$ pprCoreExpr (deAnnotate rhs)
                $$ char ' '
               ))) False
    = undefined
    | otherwise
 -}
-   = schemeR_wrk fvs nm rhs (collect [] rhs)
+   = schemeR_wrk fvs nm rhs (collect rhs)
 
-collect :: [Var] -> AnnExpr Id VarSet -> ([Var], AnnExpr' Id VarSet)
-collect xs (_, AnnNote note e) = collect xs e
-collect xs (_, AnnCast e _)    = collect xs e
-collect xs (_, AnnLam x e)     = collect (if isTyVar x then xs else (x:xs)) e
-collect xs (_, not_lambda)     = (reverse xs, not_lambda)
+collect :: AnnExpr Id VarSet -> ([Var], AnnExpr' Id VarSet)
+collect (_, e) = go [] e
+  where
+    go xs e | Just e' <- bcView e = go xs e'
+    go xs (AnnLam x (_,e))        = go (x:xs) e
+    go xs not_lambda              = (reverse xs, not_lambda)
 
 schemeR_wrk :: [Id] -> Id -> AnnExpr Id VarSet -> ([Var], AnnExpr' Var VarSet) -> BcM (ProtoBCO Name) 
 schemeR_wrk fvs nm original_body (args, body)
@@ -281,13 +278,13 @@ schemeR_wrk fvs nm original_body (args, body)
         -- \fv1..fvn x1..xn -> e 
         -- i.e. the fvs come first
 
-         szsw_args = map idSizeW all_args
+         szsw_args = map (fromIntegral . idSizeW) all_args
          szw_args  = sum szsw_args
-         p_init    = listToFM (zip all_args (mkStackOffsets 0 szsw_args))
+         p_init    = Map.fromList (zip all_args (mkStackOffsets 0 szsw_args))
 
         -- make the arg bitmap
         bits = argBits (reverse (map idCgRep all_args))
-        bitmap_size = length bits
+        bitmap_size = genericLength bits
         bitmap = mkBitmap bits
      in do
      body_code <- schemeER_wrk szw_args p_init body   
@@ -296,12 +293,12 @@ schemeR_wrk fvs nm original_body (args, body)
                arity bitmap_size bitmap False{-not alts-})
 
 -- introduce break instructions for ticked expressions
-schemeER_wrk :: Int -> BCEnv -> AnnExpr' Id VarSet -> BcM BCInstrList
+schemeER_wrk :: Word16 -> BCEnv -> AnnExpr' Id VarSet -> BcM BCInstrList
 schemeER_wrk d p rhs
    | Just (tickInfo, (_annot, newRhs)) <- isTickedExp' rhs = do 
         code <- schemeE d 0 p newRhs 
         arr <- getBreakArray 
-        let idOffSets = getVarOffSets d p tickInfo 
+        let idOffSets = getVarOffSets (fromIntegral d) p tickInfo 
         let tickNumber = tickInfo_number tickInfo
         let breakInfo = BreakInfo 
                         { breakInfo_module = tickInfo_module tickInfo
@@ -309,16 +306,18 @@ schemeER_wrk d p rhs
                         , breakInfo_vars = idOffSets
                         , breakInfo_resty = exprType (deAnnotate' newRhs)
                         }
-        let breakInstr = case arr of (BA arr#) -> BRK_FUN arr# tickNumber breakInfo 
+        let breakInstr = case arr of
+                         BA arr# ->
+                             BRK_FUN arr# (fromIntegral tickNumber) breakInfo
         return $ breakInstr `consOL` code
    | otherwise = schemeE d 0 p rhs 
 
-getVarOffSets :: Int -> BCEnv -> TickInfo -> [(Id, Int)]
+getVarOffSets :: Word16 -> BCEnv -> TickInfo -> [(Id, Word16)]
 getVarOffSets d p = catMaybes . map (getOffSet d p) . tickInfo_locals 
 
-getOffSet :: Int -> BCEnv -> Id -> Maybe (Id, Int)
+getOffSet :: Word16 -> BCEnv -> Id -> Maybe (Id, Word16)
 getOffSet d env id 
-   = case lookupBCEnv_maybe env id of
+   = case lookupBCEnv_maybe id env of
         Nothing     -> Nothing 
         Just offset -> Just (id, d - offset)
 
@@ -333,7 +332,7 @@ fvsToEnv :: BCEnv -> VarSet -> [Id]
 -- it, have to agree about this layout
 fvsToEnv p fvs = [v | v <- varSetElems fvs, 
                      isId v,           -- Could be a type variable
-                     v `elemFM` p]
+                     v `Map.member` p]
 
 -- -----------------------------------------------------------------------------
 -- schemeE
@@ -352,10 +351,14 @@ instance Outputable TickInfo where
 
 -- Compile code to apply the given expression to the remaining args
 -- on the stack, returning a HNF.
-schemeE :: Int -> Sequel -> BCEnv -> AnnExpr' Id VarSet -> BcM BCInstrList
+schemeE :: Word16 -> Sequel -> BCEnv -> AnnExpr' Id VarSet -> BcM BCInstrList
+
+schemeE d s p e
+   | Just e' <- bcView e
+   = schemeE d s p e'
 
 -- Delegate tail-calls to schemeT.
-schemeE d s p e@(AnnApp f a) 
+schemeE d s p e@(AnnApp _ _) 
    = schemeT d s p e
 
 schemeE d s p e@(AnnVar v)
@@ -368,7 +371,7 @@ schemeE d s p e@(AnnVar v)
         -- Heave it on the stack, SLIDE, and RETURN.
         (push, szw) <- pushAtom d p (AnnVar v)
         return (push                   -- value onto stack
-                  `appOL`  mkSLIDE szw (d-s)   -- clear to sequel
+                  `appOL`  mkSLIDE szw (d-s) -- clear to sequel
                   `snocOL` RETURN_UBX v_rep)   -- go
    where
       v_type = idType v
@@ -389,7 +392,7 @@ schemeE d s p (AnnLet (AnnNonRec x (_,rhs)) (_,body))
        -- saturatred constructor application.
        -- Just allocate the constructor and carry on
         alloc_code <- mkConAppCode d s p data_con args_r_to_l
-        body_code <- schemeE (d+1) s (addToFM p x d) body
+        body_code <- schemeE (d+1) s (Map.insert x d p) body
         return (alloc_code `appOL` body_code)
 
 -- General case for let.  Generates correct, if inefficient, code in
@@ -397,26 +400,26 @@ schemeE d s p (AnnLet (AnnNonRec x (_,rhs)) (_,body))
 schemeE d s p (AnnLet binds (_,body))
    = let (xs,rhss) = case binds of AnnNonRec x rhs  -> ([x],[rhs])
                                    AnnRec xs_n_rhss -> unzip xs_n_rhss
-         n_binds = length xs
+         n_binds = genericLength xs
 
          fvss  = map (fvsToEnv p' . fst) rhss
 
          -- Sizes of free vars
-         sizes = map (\rhs_fvs -> sum (map idSizeW rhs_fvs)) fvss
+         sizes = map (\rhs_fvs -> sum (map (fromIntegral . idSizeW) rhs_fvs)) fvss
 
         -- the arity of each rhs
-        arities = map (length . fst . collect []) rhss
+        arities = map (genericLength . fst . collect) rhss
 
          -- This p', d' defn is safe because all the items being pushed
          -- are ptrs, so all have size 1.  d' and p' reflect the stack
          -- after the closures have been allocated in the heap (but not
          -- filled in), and pointers to them parked on the stack.
-         p'    = addListToFM p (zipE xs (mkStackOffsets d (nOfThem n_binds 1)))
+         p'    = Map.insertList (zipE xs (mkStackOffsets d (genericReplicate n_binds 1))) p
          d'    = d + n_binds
          zipE  = zipEqual "schemeE"
 
          -- ToDo: don't build thunks for things with no free variables
-         build_thunk dd [] size bco off arity
+         build_thunk _ [] size bco off arity
             = return (PUSH_BCO bco `consOL` unitOL (mkap (off+size) size))
           where 
                mkap | arity == 0 = MKAP
@@ -427,9 +430,15 @@ schemeE d s p (AnnLet binds (_,body))
               return (push_code `appOL` more_push_code)
 
          alloc_code = toOL (zipWith mkAlloc sizes arities)
-          where mkAlloc sz 0     = ALLOC_AP sz
+          where mkAlloc sz 0
+                    | is_tick     = ALLOC_AP_NOUPD sz
+                    | otherwise   = ALLOC_AP sz
                 mkAlloc sz arity = ALLOC_PAP arity sz
 
+         is_tick = case binds of 
+                     AnnNonRec id _ -> occNameFS (getOccName id) == tickFS
+                     _other -> False
+
         compile_bind d' fvs x rhs size arity off = do
                bco <- schemeR fvs (x,rhs)
                build_thunk d' fvs size bco off arity
@@ -451,9 +460,21 @@ schemeE d s p (AnnLet binds (_,body))
 -- best way to calculate the free vars but it seemed like the least
 -- intrusive thing to do
 schemeE d s p exp@(AnnCase {})
-   | Just (tickInfo,rhs) <- isTickedExp' exp
+   | Just (_tickInfo, _rhs) <- isTickedExp' exp
    = if isUnLiftedType ty
-        then schemeE d s p (snd rhs)
+        then do
+          -- If the result type is unlifted, then we must generate
+          --   let f = \s . case tick# of _ -> e 
+          --   in  f realWorld#
+          -- When we stop at the breakpoint, _result will have an unlifted
+          -- type and hence won't be bound in the environment, but the
+          -- breakpoint will otherwise work fine.
+          id <- newId (mkFunTy realWorldStatePrimTy ty)
+          st <- newId realWorldStatePrimTy
+          let letExp = AnnLet (AnnNonRec id (fvs, AnnLam st (emptyVarSet, exp)))
+                              (emptyVarSet, (AnnApp (emptyVarSet, AnnVar id) 
+                                                    (emptyVarSet, AnnVar realWorldPrimId)))
+          schemeE d s p letExp
         else do
           id <- newId ty
           -- Todo: is emptyVarSet correct on the next line?
@@ -463,7 +484,7 @@ schemeE d s p exp@(AnnCase {})
          fvs  = exprFreeVars exp'
          ty   = exprType exp'
 
-schemeE d s p (AnnCase scrut bndr _ [(DataAlt dc, [bind1, bind2], rhs)])
+schemeE d s p (AnnCase scrut _ _ [(DataAlt dc, [bind1, bind2], rhs)])
    | isUnboxedTupleCon dc, VoidArg <- typeCgRep (idType bind1)
        -- Convert 
        --      case .... of x { (# VoidArg'd-thing, a #) -> ... }
@@ -481,7 +502,7 @@ schemeE d s p (AnnCase scrut bndr _ [(DataAlt dc, [bind1, bind2], rhs)])
    = --trace "automagic mashing of case alts (# a, VoidArg #)" $
      doCase d s p scrut bind1 [(DEFAULT, [], rhs)] True{-unboxed tuple-} 
 
-schemeE d s p (AnnCase scrut bndr _ [(DataAlt dc, [bind1], rhs)])
+schemeE d s p (AnnCase scrut _ _ [(DataAlt dc, [bind1], rhs)])
    | isUnboxedTupleCon dc
        -- Similarly, convert
        --      case .... of x { (# a #) -> ... }
@@ -493,15 +514,9 @@ schemeE d s p (AnnCase scrut bndr _ [(DataAlt dc, [bind1], rhs)])
 schemeE d s p (AnnCase scrut bndr _ alts)
    = doCase d s p scrut bndr alts False{-not an unboxed tuple-} 
 
-schemeE d s p (AnnNote note (_, body))
-   = schemeE d s p body
-
-schemeE d s p (AnnCast (_, body) _)
-   = schemeE d s p body
-
-schemeE d s p other
+schemeE _ _ _ expr
    = pprPanic "ByteCodeGen.schemeE: unhandled case" 
-               (pprCoreExpr (deAnnotate' other))
+               (pprCoreExpr (deAnnotate' expr))
 
 {- 
    Ticked Expressions
@@ -526,9 +541,6 @@ schemeE d s p other
 
 -}
 
-isTickedExp :: AnnExpr Id a -> Maybe (TickInfo, AnnExpr Id a)
-isTickedExp (annot, expr) = isTickedExp' expr 
-
 isTickedExp' :: AnnExpr' Id a -> Maybe (TickInfo, AnnExpr Id a)
 isTickedExp' (AnnCase scrut _bndr _type alts)
    | Just tickInfo <- isTickedScrut scrut,
@@ -550,9 +562,9 @@ isTickedExp' (AnnCase scrut _bndr _type alts)
       idsOfArgs = catMaybes . map exprId 
       exprId :: Expr Id -> Maybe Id
       exprId (Var id) = Just id
-      exprId other    = Nothing
+      exprId _        = Nothing
 
-isTickedExp' other = Nothing
+isTickedExp' _ = Nothing
 
 -- Compile code to do a tail call.  Specifically, push the fn,
 -- slide the on-stack app back down to the sequel depth,
@@ -577,7 +589,7 @@ isTickedExp' other = Nothing
 -- 4.  Otherwise, it must be a function call.  Push the args
 --     right to left, SLIDE and ENTER.
 
-schemeT :: Int                 -- Stack depth
+schemeT :: Word16       -- Stack depth
         -> Sequel      -- Sequel depth
         -> BCEnv       -- stack env
         -> AnnExpr' Id VarSet 
@@ -640,8 +652,8 @@ schemeT d s p app
               (AnnApp (_, AnnApp (_, AnnVar v) (_, AnnType t)) arg)
                  -> case isPrimOpId_maybe v of
                        Just TagToEnumOp -> Just (snd arg, extract_constr_Names t)
-                      other            -> Nothing
-              other -> Nothing
+                      _                -> Nothing
+              _ -> Nothing
 
        -- Extract the args (R->L) and fn
        -- The function will necessarily be a variable, 
@@ -660,18 +672,18 @@ schemeT d s p app
 -- Generate code to build a constructor application, 
 -- leaving it on top of the stack
 
-mkConAppCode :: Int -> Sequel -> BCEnv
+mkConAppCode :: Word16 -> Sequel -> BCEnv
             -> DataCon                 -- The data constructor
             -> [AnnExpr' Id VarSet]    -- Args, in *reverse* order
             -> BcM BCInstrList
 
-mkConAppCode orig_d s p con [] -- Nullary constructor
+mkConAppCode _ _ _ con []      -- Nullary constructor
   = ASSERT( isNullaryRepDataCon con )
     return (unitOL (PUSH_G (getName (dataConWorkId con))))
        -- Instead of doing a PACK, which would allocate a fresh
        -- copy of this constructor, use the single shared version.
 
-mkConAppCode orig_d s p con args_r_to_l 
+mkConAppCode orig_d _ p con args_r_to_l 
   = ASSERT( dataConRepArity con == length args_r_to_l )
     do_pushery orig_d (non_ptr_args ++ ptr_args)
  where
@@ -697,7 +709,7 @@ mkConAppCode orig_d s p con args_r_to_l
 -- returned, even if it is a pointed type.  We always just return.
 
 unboxedTupleReturn
-       :: Int -> Sequel -> BCEnv
+       :: Word16 -> Sequel -> BCEnv
        -> AnnExpr' Id VarSet -> BcM BCInstrList
 unboxedTupleReturn d s p arg = do
   (push, sz) <- pushAtom d p arg
@@ -709,7 +721,7 @@ unboxedTupleReturn d s p arg = do
 -- Generate code for a tail-call
 
 doTailCall
-       :: Int -> Sequel -> BCEnv
+       :: Word16 -> Sequel -> BCEnv
        -> Id -> [AnnExpr' Id VarSet]
        -> BcM BCInstrList
 doTailCall init_d s p fn args
@@ -737,6 +749,7 @@ doTailCall init_d s p fn args
     return (final_d, push_code `appOL` more_push_code)
 
 -- v. similar to CgStackery.findMatch, ToDo: merge
+findPushSeq :: [CgRep] -> (BCInstr, Int, [CgRep])
 findPushSeq (PtrArg: PtrArg: PtrArg: PtrArg: PtrArg: PtrArg: rest)
   = (PUSH_APPLY_PPPPPP, 6, rest)
 findPushSeq (PtrArg: PtrArg: PtrArg: PtrArg: PtrArg: rest)
@@ -765,7 +778,7 @@ findPushSeq _
 -- -----------------------------------------------------------------------------
 -- Case expressions
 
-doCase  :: Int -> Sequel -> BCEnv
+doCase  :: Word16 -> Sequel -> BCEnv
        -> AnnExpr Id VarSet -> Id -> [AnnAlt Id VarSet]
        -> Bool  -- True <=> is an unboxed tuple case, don't enter the result
        -> BcM BCInstrList
@@ -783,7 +796,7 @@ doCase d s p (_,scrut) bndr alts is_unboxed_tuple
                            | otherwise = 1
 
        -- depth of stack after the return value has been pushed
-       d_bndr = d + ret_frame_sizeW + idSizeW bndr
+       d_bndr = d + ret_frame_sizeW + fromIntegral (idSizeW bndr)
 
        -- depth of stack after the extra info table for an unboxed return
        -- has been pushed, if any.  This is the stack depth at the
@@ -792,47 +805,50 @@ doCase d s p (_,scrut) bndr alts is_unboxed_tuple
 
         -- Env in which to compile the alts, not including
         -- any vars bound by the alts themselves
-        p_alts = addToFM p bndr (d_bndr - 1)
+        p_alts = Map.insert bndr (d_bndr - 1) p
 
        bndr_ty = idType bndr
         isAlgCase = not (isUnLiftedType bndr_ty) && not is_unboxed_tuple
 
         -- given an alt, return a discr and code for it.
-       codeAlt alt@(DEFAULT, _, (_,rhs))
+       codeAlt (DEFAULT, _, (_,rhs))
           = do rhs_code <- schemeE d_alts s p_alts rhs
                return (NoDiscr, rhs_code)
 
-        codeAlt alt@(discr, bndrs, (_,rhs))
+        codeAlt alt@(_, bndrs, (_,rhs))
           -- primitive or nullary constructor alt: no need to UNPACK
           | null real_bndrs = do
                rhs_code <- schemeE d_alts s p_alts rhs
                 return (my_discr alt, rhs_code)
           -- algebraic alt with some binders
-           | ASSERT(isAlgCase) otherwise =
+           | otherwise =
              let
                 (ptrs,nptrs) = partition (isFollowableArg.idCgRep) real_bndrs
-                ptr_sizes    = map idSizeW ptrs
-                nptrs_sizes  = map idSizeW nptrs
+                ptr_sizes    = map (fromIntegral . idSizeW) ptrs
+                nptrs_sizes  = map (fromIntegral . idSizeW) nptrs
                 bind_sizes   = ptr_sizes ++ nptrs_sizes
                 size         = sum ptr_sizes + sum nptrs_sizes
                 -- the UNPACK instruction unpacks in reverse order...
-                p' = addListToFM p_alts 
+                p' = Map.insertList
                        (zip (reverse (ptrs ++ nptrs))
                          (mkStackOffsets d_alts (reverse bind_sizes)))
+                        p_alts 
             in do
+             MASSERT(isAlgCase)
             rhs_code <- schemeE (d_alts+size) s p' rhs
              return (my_discr alt, unitOL (UNPACK size) `appOL` rhs_code)
           where
-            real_bndrs = filter (not.isTyVar) bndrs
+            real_bndrs = filter (not.isTyCoVar) bndrs
 
-        my_discr (DEFAULT, binds, rhs) = NoDiscr {-shouldn't really happen-}
-        my_discr (DataAlt dc, binds, rhs) 
+        my_discr (DEFAULT, _, _) = NoDiscr {-shouldn't really happen-}
+        my_discr (DataAlt dc, _, _) 
            | isUnboxedTupleCon dc
            = unboxedTupleException
            | otherwise
-           = DiscrP (dataConTag dc - fIRST_TAG)
-        my_discr (LitAlt l, binds, rhs)
+           = DiscrP (fromIntegral (dataConTag dc - fIRST_TAG))
+        my_discr (LitAlt l, _, _)
            = case l of MachInt i     -> DiscrI (fromInteger i)
+                       MachWord w    -> DiscrW (fromInteger w)
                        MachFloat r   -> DiscrF (fromRational r)
                        MachDouble r  -> DiscrD (fromRational r)
                        MachChar i    -> DiscrI (ord i)
@@ -860,11 +876,13 @@ doCase d s p (_,scrut) bndr alts is_unboxed_tuple
         -- case-of-case expressions, which is the only time we can be compiling a
         -- case expression with s /= 0.
         bitmap_size = d-s
-       bitmap = intsToReverseBitmap bitmap_size{-size-} 
-                        (sortLe (<=) (filter (< bitmap_size) rel_slots))
+        bitmap_size' :: Int
+        bitmap_size' = fromIntegral bitmap_size
+       bitmap = intsToReverseBitmap bitmap_size'{-size-}
+                        (sortLe (<=) (filter (< bitmap_size') rel_slots))
          where
-         binds = fmToList p
-         rel_slots = concat (map spread binds)
+         binds = Map.toList p
+         rel_slots = map fromIntegral $ concat (map spread binds)
          spread (id, offset)
                | isFollowableArg (idCgRep id) = [ rel_offset ]
                | otherwise = []
@@ -898,24 +916,25 @@ doCase d s p (_,scrut) bndr alts is_unboxed_tuple
 -- (machine) code for the ccall, and create bytecodes to call that and
 -- then return in the right way.  
 
-generateCCall :: Int -> Sequel                 -- stack and sequel depths
+generateCCall :: Word16 -> Sequel              -- stack and sequel depths
               -> BCEnv
               -> CCallSpec             -- where to call
               -> Id                    -- of target, for type info
               -> [AnnExpr' Id VarSet]  -- args (atoms)
               -> BcM BCInstrList
 
-generateCCall d0 s p ccall_spec@(CCallSpec target cconv safety) fn args_r_to_l
+generateCCall d0 s p (CCallSpec target cconv safety) fn args_r_to_l
    = let 
          -- useful constants
-         addr_sizeW = cgRepSizeW NonPtrArg
+         addr_sizeW :: Word16
+         addr_sizeW = fromIntegral (cgRepSizeW NonPtrArg)
 
          -- Get the args on the stack, with tags and suitably
          -- dereferenced for the CCall.  For each arg, return the
          -- depth to the first word of the bits for that arg, and the
          -- CgRep of what was actually pushed.
 
-         pargs d [] = return []
+         pargs _ [] = return []
          pargs d (a:az) 
             = let arg_ty = repType (exprType (deAnnotate' a))
 
@@ -925,23 +944,25 @@ generateCCall d0 s p ccall_spec@(CCallSpec target cconv safety) fn args_r_to_l
                    Just (t, _)
                     | t == arrayPrimTyCon || t == mutableArrayPrimTyCon
                        -> do rest <- pargs (d + addr_sizeW) az
-                             code <- parg_ArrayishRep arrPtrsHdrSize d p a
-                             return ((code,NonPtrArg):rest)
+                             code <- parg_ArrayishRep (fromIntegral arrPtrsHdrSize) d p a
+                             return ((code,AddrRep):rest)
 
                     | t == byteArrayPrimTyCon || t == mutableByteArrayPrimTyCon
                        -> do rest <- pargs (d + addr_sizeW) az
-                             code <- parg_ArrayishRep arrWordsHdrSize d p a
-                             return ((code,NonPtrArg):rest)
+                             code <- parg_ArrayishRep (fromIntegral arrWordsHdrSize) d p a
+                             return ((code,AddrRep):rest)
 
                     -- Default case: push taggedly, but otherwise intact.
-                    other
+                    _
                        -> do (code_a, sz_a) <- pushAtom d p a
                              rest <- pargs (d+sz_a) az
-                             return ((code_a, atomRep a) : rest)
+                             return ((code_a, atomPrimRep a) : rest)
 
          -- Do magic for Ptr/Byte arrays.  Push a ptr to the array on
          -- the stack but then advance it over the headers, so as to
          -- point to the payload.
+         parg_ArrayishRep :: Word16 -> Word16 -> BCEnv -> AnnExpr' Id VarSet
+                          -> BcM BCInstrList
          parg_ArrayishRep hdrSize d p a
             = do (push_fo, _) <- pushAtom d p a
                  -- The ptr points at the header.  Advance it over the
@@ -952,11 +973,12 @@ generateCCall d0 s p ccall_spec@(CCallSpec target cconv safety) fn args_r_to_l
      code_n_reps <- pargs d0 args_r_to_l
      let
          (pushs_arg, a_reps_pushed_r_to_l) = unzip code_n_reps
+         a_reps_sizeW = fromIntegral (sum (map primRepSizeW a_reps_pushed_r_to_l))
 
          push_args    = concatOL pushs_arg
-         d_after_args = d0 + sum (map cgRepSizeW a_reps_pushed_r_to_l)
+         d_after_args = d0 + a_reps_sizeW
          a_reps_pushed_RAW
-            | null a_reps_pushed_r_to_l || head a_reps_pushed_r_to_l /= VoidArg
+            | null a_reps_pushed_r_to_l || head a_reps_pushed_r_to_l /= VoidRep
             = panic "ByteCodeGen.generateCCall: missing or invalid World token?"
             | otherwise
             = reverse (tail a_reps_pushed_r_to_l)
@@ -968,7 +990,7 @@ generateCCall d0 s p ccall_spec@(CCallSpec target cconv safety) fn args_r_to_l
          -- Get the result rep.
          (returns_void, r_rep)
             = case maybe_getCCallReturnRep (idType fn) of
-                 Nothing -> (True,  VoidArg)
+                 Nothing -> (True,  VoidRep)
                  Just rr -> (False, rr) 
          {-
          Because the Haskell stack grows down, the a_reps refer to 
@@ -1010,9 +1032,20 @@ generateCCall d0 s p ccall_spec@(CCallSpec target cconv safety) fn args_r_to_l
             = case target of
                  DynamicTarget
                     -> return (False, panic "ByteCodeGen.generateCCall(dyn)")
-                 StaticTarget target
-                    -> do res <- ioToBc (lookupStaticPtr target)
+
+                 StaticTarget target _
+                    -> do res <- ioToBc (lookupStaticPtr stdcall_adj_target)
                           return (True, res)
+                   where
+                      stdcall_adj_target
+#ifdef mingw32_TARGET_OS
+                          | StdCallConv <- cconv
+                          = let size = fromIntegral a_reps_sizeW * wORD_SIZE in
+                            mkFastString (unpackFS target ++ '@':show size)
+#endif
+                          | otherwise
+                          = target
+
      -- in
      (is_static, static_target_addr) <- get_target_info
      let
@@ -1034,7 +1067,7 @@ generateCCall d0 s p ccall_spec@(CCallSpec target cconv safety) fn args_r_to_l
 
          -- Push the return placeholder.  For a call returning nothing,
          -- this is a VoidArg (tag).
-         r_sizeW   = cgRepSizeW r_rep
+         r_sizeW   = fromIntegral (primRepSizeW r_rep)
          d_after_r = d_after_Addr + r_sizeW
          r_lit     = mkDummyLiteral r_rep
          push_r    = (if   returns_void 
@@ -1042,28 +1075,28 @@ generateCCall d0 s p ccall_spec@(CCallSpec target cconv safety) fn args_r_to_l
                       else unitOL (PUSH_UBX (Left r_lit) r_sizeW))
 
          -- generate the marshalling code we're going to call
-         r_offW       = 0 
-         addr_offW    = r_sizeW
-         arg1_offW    = r_sizeW + addr_sizeW
-         args_offW    = map (arg1_offW +) 
-                            (init (scanl (+) 0 (map cgRepSizeW a_reps)))
-     -- in
-     addr_of_marshaller <- ioToBc (mkMarshalCode cconv
-                                (r_offW, r_rep) addr_offW
-                                (zip args_offW a_reps))
-     recordItblMallocBc (ItblPtr (castFunPtrToPtr addr_of_marshaller))
-     let
+
         -- Offset of the next stack frame down the stack.  The CCALL
         -- instruction needs to describe the chunk of stack containing
         -- the ccall args to the GC, so it needs to know how large it
         -- is.  See comment in Interpreter.c with the CCALL instruction.
         stk_offset   = d_after_r - s
 
+     -- in
+     -- the only difference in libffi mode is that we prepare a cif
+     -- describing the call type by calling libffi, and we attach the
+     -- address of this to the CCALL instruction.
+     token <- ioToBc $ prepForeignCall cconv a_reps r_rep
+     let addr_of_marshaller = castPtrToFunPtr token
+
+     recordItblMallocBc (ItblPtr (castFunPtrToPtr addr_of_marshaller))
+     let
          -- do the call
-         do_call      = unitOL (CCALL stk_offset (castFunPtrToPtr addr_of_marshaller))
+         do_call      = unitOL (CCALL stk_offset (castFunPtrToPtr addr_of_marshaller)
+                                 (fromIntegral (fromEnum (playInterruptible safety))))
          -- slide and return
          wrapup       = mkSLIDE r_sizeW (d_after_r - r_sizeW - s)
-                        `snocOL` RETURN_UBX r_rep
+                        `snocOL` RETURN_UBX (primRepToCgRep r_rep)
      --in
          --trace (show (arg1_offW, args_offW  ,  (map cgRepSizeW a_reps) )) $
      return (
@@ -1071,17 +1104,19 @@ generateCCall d0 s p ccall_spec@(CCallSpec target cconv safety) fn args_r_to_l
          push_Addr `appOL` push_r `appOL` do_call `appOL` wrapup
          )
 
-
 -- Make a dummy literal, to be used as a placeholder for FFI return
 -- values on the stack.
-mkDummyLiteral :: CgRep -> Literal
+mkDummyLiteral :: PrimRep -> Literal
 mkDummyLiteral pr
    = case pr of
-        NonPtrArg -> MachWord 0
-        DoubleArg -> MachDouble 0
-        FloatArg  -> MachFloat 0
-        LongArg   -> MachWord64 0
-        _         -> moan64 "mkDummyLiteral" (ppr pr)
+        IntRep    -> MachInt 0
+        WordRep   -> MachWord 0
+        AddrRep   -> MachNullAddr
+        DoubleRep -> MachDouble 0
+        FloatRep  -> MachFloat 0
+        Int64Rep  -> MachInt64 0
+        Word64Rep -> MachWord64 0
+        _         -> panic "mkDummyLiteral"
 
 
 -- Convert (eg) 
@@ -1098,24 +1133,26 @@ mkDummyLiteral pr
 --
 -- to  Nothing
 
-maybe_getCCallReturnRep :: Type -> Maybe CgRep
+maybe_getCCallReturnRep :: Type -> Maybe PrimRep
 maybe_getCCallReturnRep fn_ty
-   = let (a_tys, r_ty) = splitFunTys (dropForAlls fn_ty)
+   = let (_a_tys, r_ty) = splitFunTys (dropForAlls fn_ty)
          maybe_r_rep_to_go  
             = if isSingleton r_reps then Nothing else Just (r_reps !! 1)
          (r_tycon, r_reps) 
             = case splitTyConApp_maybe (repType r_ty) of
-                      (Just (tyc, tys)) -> (tyc, map typeCgRep tys)
+                      (Just (tyc, tys)) -> (tyc, map typePrimRep tys)
                       Nothing -> blargh
-         ok = ( ( r_reps `lengthIs` 2 && VoidArg == head r_reps)
-                || r_reps == [VoidArg] )
+         ok = ( ( r_reps `lengthIs` 2 && VoidRep == head r_reps)
+                || r_reps == [VoidRep] )
               && isUnboxedTupleTyCon r_tycon
               && case maybe_r_rep_to_go of
                     Nothing    -> True
-                    Just r_rep -> r_rep /= PtrArg
+                    Just r_rep -> r_rep /= PtrRep
                                   -- if it was, it would be impossible 
                                   -- to create a valid return value 
                                   -- placeholder on the stack
+
+         blargh :: a -- Used at more than one type
          blargh = pprPanic "maybe_getCCallReturn: can't handle:" 
                            (pprType fn_ty)
      in 
@@ -1128,7 +1165,7 @@ maybe_getCCallReturnRep fn_ty
 implement_tagToId :: [Name] -> BcM BCInstrList
 implement_tagToId names
    = ASSERT( notNull names )
-     do labels <- getLabelsBc (length names)
+     do labels <- getLabelsBc (genericLength names)
         label_fail <- getLabelBc
         label_exit <- getLabelBc
         let infos = zip4 labels (tail labels ++ [label_fail])
@@ -1158,20 +1195,13 @@ implement_tagToId names
 -- to 5 and not to 4.  Stack locations are numbered from zero, so a
 -- depth 6 stack has valid words 0 .. 5.
 
-pushAtom :: Int -> BCEnv -> AnnExpr' Id VarSet -> BcM (BCInstrList, Int)
-
-pushAtom d p (AnnApp f (_, AnnType _))
-   = pushAtom d p (snd f)
+pushAtom :: Word16 -> BCEnv -> AnnExpr' Id VarSet -> BcM (BCInstrList, Word16)
 
-pushAtom d p (AnnNote note e)
-   = pushAtom d p (snd e)
-
-pushAtom d p (AnnLam x e) 
-   | isTyVar x 
-   = pushAtom d p (snd e)
+pushAtom d p e 
+   | Just e' <- bcView e 
+   = pushAtom d p e'
 
 pushAtom d p (AnnVar v)
-
    | idCgRep v == VoidArg
    = return (nilOL, 0)
 
@@ -1181,8 +1211,9 @@ pushAtom d p (AnnVar v)
    | Just primop <- isPrimOpId_maybe v
    = return (unitOL (PUSH_PRIMOP primop), 1)
 
-   | Just d_v <- lookupBCEnv_maybe p v  -- v is a local variable
-   = return (toOL (nOfThem sz (PUSH_L (d-d_v+sz-2))), sz)
+   | Just d_v <- lookupBCEnv_maybe v p  -- v is a local variable
+   = let l = d - d_v + sz - 2
+     in return (toOL (genericReplicate sz (PUSH_L l)), sz)
         -- d - d_v                 the number of words between the TOS 
         --                         and the 1st slot of the object
         --
@@ -1199,21 +1230,24 @@ pushAtom d p (AnnVar v)
       return (unitOL (PUSH_G (getName v)), sz)
 
     where
-         sz = idSizeW v
+         sz :: Word16
+         sz = fromIntegral (idSizeW v)
 
 
-pushAtom d p (AnnLit lit)
+pushAtom _ _ (AnnLit lit)
    = case lit of
-        MachLabel fs _ -> code NonPtrArg
-        MachWord w     -> code NonPtrArg
-        MachInt i      -> code PtrArg
-        MachFloat r    -> code FloatArg
-        MachDouble r   -> code DoubleArg
-        MachChar c     -> code NonPtrArg
-        MachStr s      -> pushStr s
+        MachLabel _ _ _ -> code NonPtrArg
+        MachWord _    -> code NonPtrArg
+        MachInt _     -> code PtrArg
+        MachFloat _   -> code FloatArg
+        MachDouble _  -> code DoubleArg
+        MachChar _    -> code NonPtrArg
+       MachNullAddr  -> code NonPtrArg
+        MachStr s     -> pushStr s
+        l             -> pprPanic "pushAtom" (ppr l)
      where
         code rep
-           = let size_host_words = cgRepSizeW rep
+           = let size_host_words = fromIntegral (cgRepSizeW rep)
              in  return (unitOL (PUSH_UBX (Left lit) size_host_words), 
                            size_host_words)
 
@@ -1243,9 +1277,9 @@ pushAtom d p (AnnLit lit)
 pushAtom d p (AnnCast e _)
    = pushAtom d p (snd e)
 
-pushAtom d p other
+pushAtom _ _ expr
    = pprPanic "ByteCodeGen.pushAtom" 
-              (pprCoreExpr (deAnnotate (undefined, other)))
+              (pprCoreExpr (deAnnotate (undefined, expr)))
 
 foreign import ccall unsafe "memcpy"
  memcpy :: Ptr a -> Ptr b -> CSize -> IO ()
@@ -1268,14 +1302,14 @@ mkMultiBranch maybe_ncons raw_ways
                         (filter (not.isNoDiscr.fst) raw_ways)
 
          mkTree :: [(Discr, BCInstrList)] -> Discr -> Discr -> BcM BCInstrList
-         mkTree [] range_lo range_hi = return the_default
+         mkTree [] _range_lo _range_hi = return the_default
 
          mkTree [val] range_lo range_hi
             | range_lo `eqAlt` range_hi 
             = return (snd val)
             | otherwise
             = do label_neq <- getLabelBc
-                 return (mkTestEQ (fst val) label_neq 
+                 return (testEQ (fst val) label_neq 
                          `consOL` (snd val
                          `appOL`   unitOL (LABEL label_neq)
                           `appOL`   the_default))
@@ -1289,7 +1323,7 @@ mkMultiBranch maybe_ncons raw_ways
               label_geq <- getLabelBc
               code_lo <- mkTree vals_lo range_lo (dec v_mid)
               code_hi <- mkTree vals_hi v_mid range_hi
-              return (mkTestLT v_mid label_geq
+              return (testLT v_mid label_geq
                         `consOL` (code_lo
                        `appOL`   unitOL (LABEL label_geq)
                        `appOL`   code_hi))
@@ -1297,37 +1331,43 @@ mkMultiBranch maybe_ncons raw_ways
          the_default 
             = case d_way of [] -> unitOL CASEFAIL
                             [(_, def)] -> def
+                            _ -> panic "mkMultiBranch/the_default"
+
+         testLT (DiscrI i) fail_label = TESTLT_I i fail_label
+         testLT (DiscrW i) fail_label = TESTLT_W i fail_label
+         testLT (DiscrF i) fail_label = TESTLT_F i fail_label
+         testLT (DiscrD i) fail_label = TESTLT_D i fail_label
+         testLT (DiscrP i) fail_label = TESTLT_P i fail_label
+         testLT NoDiscr    _          = panic "mkMultiBranch NoDiscr"
+
+         testEQ (DiscrI i) fail_label = TESTEQ_I i fail_label
+         testEQ (DiscrW i) fail_label = TESTEQ_W i fail_label
+         testEQ (DiscrF i) fail_label = TESTEQ_F i fail_label
+         testEQ (DiscrD i) fail_label = TESTEQ_D i fail_label
+         testEQ (DiscrP i) fail_label = TESTEQ_P i fail_label
+         testEQ NoDiscr    _          = panic "mkMultiBranch NoDiscr"
 
          -- None of these will be needed if there are no non-default alts
-         (mkTestLT, mkTestEQ, init_lo, init_hi)
+         (init_lo, init_hi)
             | null notd_ways
             = panic "mkMultiBranch: awesome foursome"
             | otherwise
-            = case fst (head notd_ways) of {
-              DiscrI _ -> ( \(DiscrI i) fail_label -> TESTLT_I i fail_label,
-                            \(DiscrI i) fail_label -> TESTEQ_I i fail_label,
-                            DiscrI minBound,
-                            DiscrI maxBound );
-              DiscrF _ -> ( \(DiscrF f) fail_label -> TESTLT_F f fail_label,
-                            \(DiscrF f) fail_label -> TESTEQ_F f fail_label,
-                            DiscrF minF,
-                            DiscrF maxF );
-              DiscrD _ -> ( \(DiscrD d) fail_label -> TESTLT_D d fail_label,
-                            \(DiscrD d) fail_label -> TESTEQ_D d fail_label,
-                            DiscrD minD,
-                            DiscrD maxD );
-              DiscrP _ -> ( \(DiscrP i) fail_label -> TESTLT_P i fail_label,
-                            \(DiscrP i) fail_label -> TESTEQ_P i fail_label,
-                            DiscrP algMinBound,
-                            DiscrP algMaxBound )
-              }
+            = case fst (head notd_ways) of
+               DiscrI _ -> ( DiscrI minBound,  DiscrI maxBound )
+               DiscrW _ -> ( DiscrW minBound,  DiscrW maxBound )
+               DiscrF _ -> ( DiscrF minF,      DiscrF maxF )
+               DiscrD _ -> ( DiscrD minD,      DiscrD maxD )
+               DiscrP _ -> ( DiscrP algMinBound, DiscrP algMaxBound )
+               NoDiscr -> panic "mkMultiBranch NoDiscr"
 
          (algMinBound, algMaxBound)
             = case maybe_ncons of
-                 Just n  -> (0, n - 1)
+                 -- XXX What happens when n == 0?
+                 Just n  -> (0, fromIntegral n - 1)
                  Nothing -> (minBound, maxBound)
 
          (DiscrI i1) `eqAlt` (DiscrI i2) = i1 == i2
+         (DiscrW w1) `eqAlt` (DiscrW w2) = w1 == w2
          (DiscrF f1) `eqAlt` (DiscrF f2) = f1 == f2
          (DiscrD d1) `eqAlt` (DiscrD d2) = d1 == d2
          (DiscrP i1) `eqAlt` (DiscrP i2) = i1 == i2
@@ -1335,6 +1375,7 @@ mkMultiBranch maybe_ncons raw_ways
          _           `eqAlt` _           = False
 
          (DiscrI i1) `leAlt` (DiscrI i2) = i1 <= i2
+         (DiscrW w1) `leAlt` (DiscrW w2) = w1 <= w2
          (DiscrF f1) `leAlt` (DiscrF f2) = f1 <= f2
          (DiscrD d1) `leAlt` (DiscrD d2) = d1 <= d2
          (DiscrP i1) `leAlt` (DiscrP i2) = i1 <= i2
@@ -1345,6 +1386,7 @@ mkMultiBranch maybe_ncons raw_ways
          isNoDiscr _       = False
 
          dec (DiscrI i) = DiscrI (i-1)
+         dec (DiscrW w) = DiscrW (w-1)
          dec (DiscrP i) = DiscrP (i-1)
          dec other      = other                -- not really right, but if you
                -- do cases on floating values, you'll get what you deserve
@@ -1366,21 +1408,23 @@ mkMultiBranch maybe_ncons raw_ways
 -- Describes case alts
 data Discr 
    = DiscrI Int
+   | DiscrW Word
    | DiscrF Float
    | DiscrD Double
-   | DiscrP Int
+   | DiscrP Word16
    | NoDiscr
 
 instance Outputable Discr where
    ppr (DiscrI i) = int i
+   ppr (DiscrW w) = text (show w)
    ppr (DiscrF f) = text (show f)
    ppr (DiscrD d) = text (show d)
-   ppr (DiscrP i) = int i
+   ppr (DiscrP i) = ppr i
    ppr NoDiscr    = text "DEF"
 
 
-lookupBCEnv_maybe :: BCEnv -> Id -> Maybe Int
-lookupBCEnv_maybe = lookupFM
+lookupBCEnv_maybe :: Id -> BCEnv -> Maybe Word16
+lookupBCEnv_maybe = Map.lookup
 
 idSizeW :: Id -> Int
 idSizeW id = cgRepSizeW (typeCgRep (idType id))
@@ -1388,45 +1432,51 @@ idSizeW id = cgRepSizeW (typeCgRep (idType id))
 -- See bug #1257
 unboxedTupleException :: a
 unboxedTupleException 
-   = throwDyn 
+   = ghcError 
         (ProgramError 
            ("Error: bytecode compiler can't handle unboxed tuples.\n"++
             "  Possibly due to foreign import/export decls in source.\n"++
             "  Workaround: use -fobject-code, or compile this module to .o separately."))
 
 
+mkSLIDE :: Word16 -> Word16 -> OrdList BCInstr
 mkSLIDE n d = if d == 0 then nilOL else unitOL (SLIDE n d)
-bind x f    = f x
 
-splitApp :: AnnExpr' id ann -> (AnnExpr' id ann, [AnnExpr' id ann])
+splitApp :: AnnExpr' Var ann -> (AnnExpr' Var ann, [AnnExpr' Var ann])
        -- The arguments are returned in *right-to-left* order
-splitApp (AnnApp (_,f) (_,a))
-              | isTypeAtom a = splitApp f
-              | otherwise    = case splitApp f of 
-                                    (f', as) -> (f', a:as)
-splitApp (AnnNote n (_,e))    = splitApp e
-splitApp (AnnCast (_,e) _)    = splitApp e
-splitApp e                   = (e, [])
-
-
-isTypeAtom :: AnnExpr' id ann -> Bool
-isTypeAtom (AnnType _) = True
-isTypeAtom _           = False
-
-isVoidArgAtom :: AnnExpr' id ann -> Bool
-isVoidArgAtom (AnnVar v)        = typeCgRep (idType v) == VoidArg
-isVoidArgAtom (AnnNote n (_,e)) = isVoidArgAtom e
-isVoidArgAtom (AnnCast (_,e) _) = isVoidArgAtom e
-isVoidArgAtom _                = False
+splitApp e | Just e' <- bcView e = splitApp e'
+splitApp (AnnApp (_,f) (_,a))   = case splitApp f of 
+                                     (f', as) -> (f', a:as)
+splitApp e                      = (e, [])
+
+
+bcView :: AnnExpr' Var ann -> Maybe (AnnExpr' Var ann)
+-- The "bytecode view" of a term discards
+--  a) type abstractions
+--  b) type applications
+--  c) casts
+--  d) notes
+-- Type lambdas *can* occur in random expressions, 
+-- whereas value lambdas cannot; that is why they are nuked here
+bcView (AnnNote _ (_,e))            = Just e
+bcView (AnnCast (_,e) _)            = Just e
+bcView (AnnLam v (_,e)) | isTyCoVar v  = Just e
+bcView (AnnApp (_,e) (_, AnnType _)) = Just e
+bcView _                             = Nothing
+
+isVoidArgAtom :: AnnExpr' Var ann -> Bool
+isVoidArgAtom e | Just e' <- bcView e = isVoidArgAtom e'
+isVoidArgAtom (AnnVar v)              = typePrimRep (idType v) == VoidRep
+isVoidArgAtom _                      = False
+
+atomPrimRep :: AnnExpr' Id ann -> PrimRep
+atomPrimRep e | Just e' <- bcView e = atomPrimRep e'
+atomPrimRep (AnnVar v)             = typePrimRep (idType v)
+atomPrimRep (AnnLit l)             = typePrimRep (literalType l)
+atomPrimRep other = pprPanic "atomPrimRep" (ppr (deAnnotate (undefined,other)))
 
 atomRep :: AnnExpr' Id ann -> CgRep
-atomRep (AnnVar v)    = typeCgRep (idType v)
-atomRep (AnnLit l)    = typeCgRep (literalType l)
-atomRep (AnnNote n b) = atomRep (snd b)
-atomRep (AnnApp f (_, AnnType _)) = atomRep (snd f)
-atomRep (AnnLam x e) | isTyVar x = atomRep (snd e)
-atomRep (AnnCast b _) = atomRep (snd b)
-atomRep other = pprPanic "atomRep" (ppr (deAnnotate (undefined,other)))
+atomRep e = primRepToCgRep (atomPrimRep e)
 
 isPtrAtom :: AnnExpr' Id ann -> Bool
 isPtrAtom e = atomRep e == PtrArg
@@ -1434,7 +1484,7 @@ isPtrAtom e = atomRep e == PtrArg
 -- Let szsw be the sizes in words of some items pushed onto the stack,
 -- which has initial depth d'.  Return the values which the stack environment
 -- should map these items to.
-mkStackOffsets :: Int -> [Int] -> [Int]
+mkStackOffsets :: Word16 -> [Word16] -> [Word16]
 mkStackOffsets original_depth szsw
    = map (subtract 1) (tail (scanl (+) original_depth szsw))
 
@@ -1446,7 +1496,7 @@ type BcPtr = Either ItblPtr (Ptr ())
 data BcM_State 
    = BcM_State { 
         uniqSupply :: UniqSupply,       -- for generating fresh variable names
-       nextlabel :: Int,               -- for generating local labels
+       nextlabel :: Word16,            -- for generating local labels
        malloced  :: [BcPtr],           -- thunks malloced for current BCO
                                        -- Should be free()d when it is GCd
         breakArray :: BreakArray        -- array of breakpoint flags 
@@ -1474,7 +1524,7 @@ thenBc (BcM expr) cont = BcM $ \st0 -> do
 
 thenBc_ :: BcM a -> BcM b -> BcM b
 thenBc_ (BcM expr) (BcM cont) = BcM $ \st0 -> do
-  (st1, q) <- expr st0
+  (st1, _) <- expr st0
   (st2, r) <- cont st1
   return (st2, r)
 
@@ -1498,11 +1548,14 @@ recordItblMallocBc :: ItblPtr -> BcM ()
 recordItblMallocBc a
   = BcM $ \st -> return (st{malloced = Left a : malloced st}, ())
 
-getLabelBc :: BcM Int
+getLabelBc :: BcM Word16
 getLabelBc
-  = BcM $ \st -> return (st{nextlabel = 1 + nextlabel st}, nextlabel st)
+  = BcM $ \st -> do let nl = nextlabel st
+                    when (nl == maxBound) $
+                        panic "getLabelBc: Ran out of labels"
+                    return (st{nextlabel = nl + 1}, nl)
 
-getLabelsBc :: Int -> BcM [Int]
+getLabelsBc :: Word16 -> BcM [Word16]
 getLabelsBc n
   = BcM $ \st -> let ctr = nextlabel st 
                 in return (st{nextlabel = ctr+n}, [ctr .. ctr+n-1])
@@ -1519,5 +1572,8 @@ newUnique = BcM $
 newId :: Type -> BcM Id
 newId ty = do 
     uniq <- newUnique
-    return $ mkSysLocal FSLIT("ticked") uniq ty
+    return $ mkSysLocal tickFS uniq ty
+
+tickFS :: FastString
+tickFS = fsLit "ticked"
 \end{code}