[project @ 2001-10-08 13:24:53 by simonmar]
[ghc-hetmet.git] / ghc / compiler / ghci / ByteCodeLink.lhs
index 795c1e9..73ccb95 100644 (file)
@@ -4,6 +4,9 @@
 \section[ByteCodeLink]{Bytecode assembler and linker}
 
 \begin{code}
+
+{-# OPTIONS -optc-DNON_POSIX_SOURCE #-}
+
 module ByteCodeLink ( UnlinkedBCO, UnlinkedBCOExpr, assembleBCO,
                      ClosureEnv, HValue, filterNameMap,
                      linkIModules, linkIExpr,
@@ -30,7 +33,7 @@ import ByteCodeInstr  ( BCInstr(..), ProtoBCO(..) )
 import ByteCodeItbls   ( ItblEnv, ItblPtr )
 
 
-import Monad           ( foldM )
+import Monad           ( when, foldM )
 import ST              ( runST )
 import IArray          ( array )
 import MArray          ( castSTUArray, 
@@ -39,8 +42,9 @@ import MArray         ( castSTUArray,
                          newIntArray, writeIntArray,
                          newAddrArray, writeAddrArray,
                          readWordArray )
-import Foreign         ( Word16, Ptr(..) )
-import Addr            ( Word, Addr, nullAddr )
+import Foreign         ( Word16, Ptr(..), free )
+import Addr            ( Word, Addr(..), nullAddr )
+import Weak            ( addFinalizer )
 import FiniteMap
 
 import PrelBase                ( Int(..) )
@@ -67,8 +71,8 @@ linkIModules :: ItblEnv    -- incoming global itbl env; returned updated
             -> IO ([HValue], ItblEnv, ClosureEnv)
 linkIModules gie gce mods 
    = do let (bcoss, ies) = unzip mods
-            bcos = concat bcoss
-            final_gie = foldr plusFM gie ies
+            bcos         = concat bcoss
+            final_gie    = foldr plusFM gie ies
         (final_gce, linked_bcos) <- linkSomeBCOs True final_gie gce bcos
         return (linked_bcos, final_gie, final_gce)
 
@@ -162,7 +166,7 @@ this BCO.
 -- Top level assembler fn.
 assembleBCO :: ProtoBCO Name -> IO UnlinkedBCO
 
-assembleBCO (ProtoBCO nm instrs origin)
+assembleBCO (ProtoBCO nm instrs origin malloced)
    = let
          -- pass 1: collect up the offsets of the local labels.
          -- Remember that the first insn starts at offset 1 since offset 0
@@ -187,9 +191,19 @@ assembleBCO (ProtoBCO nm instrs origin)
          itbls <- return emptySS :: IO (SizedSeq Name)
          let init_asm_state = (insns,lits,ptrs,itbls)
          (final_insns, final_lits, final_ptrs, final_itbls) 
-            <- mkBits findLabel init_asm_state instrs         
+            <- mkBits findLabel init_asm_state instrs
 
-         return (UnlinkedBCO nm final_insns final_lits final_ptrs final_itbls)
+         let ul_bco = UnlinkedBCO nm final_insns final_lits final_ptrs final_itbls
+
+         -- 8 Aug 01: Finalisers aren't safe when attached to non-primitive
+         -- objects, since they might get run too early.  Disable this until
+         -- we figure out what to do.
+         -- when (not (null malloced)) (addFinalizer ul_bco (mapM_ zonk malloced))
+
+         return ul_bco
+     where
+         zonk (A# a#) = do -- putStrLn ("freeing malloc'd block at " ++ show (A# a#))
+                           free (Ptr a#)
 
 -- instrs nonptrs ptrs itbls
 type AsmState = (SizedSeq Word16, SizedSeq Word, 
@@ -216,6 +230,7 @@ mkBits findLabel st proto_insns
        doInstr :: AsmState -> BCInstr -> IO AsmState
        doInstr st i
           = case i of
+               SWIZZLE   stkoff n -> instr3 st i_SWIZZLE stkoff n
                ARGCHECK  n        -> instr2 st i_ARGCHECK n
                STKCHECK  n        -> instr2 st i_STKCHECK n
                PUSH_L    o1       -> instr2 st i_PUSH_L o1
@@ -226,8 +241,13 @@ mkBits findLabel st proto_insns
                PUSH_AS   nm pk    -> do (p, st2)  <- ptr st (Left nm)
                                         (np, st3) <- ctoi_itbl st2 pk
                                         instr3 st3 i_PUSH_AS p np
-               PUSH_UBX  lit nws  -> do (np, st2) <- literal st lit
+               PUSH_UBX  (Left lit) nws  
+                                  -> do (np, st2) <- literal st lit
+                                        instr3 st2 i_PUSH_UBX np nws
+               PUSH_UBX  (Right aa) nws  
+                                  -> do (np, st2) <- addr st aa
                                         instr3 st2 i_PUSH_UBX np nws
+
                PUSH_TAG  tag      -> instr2 st i_PUSH_TAG tag
                SLIDE     n by     -> instr3 st i_SLIDE n by
                ALLOC     n        -> instr2 st i_ALLOC n
@@ -252,10 +272,12 @@ mkBits findLabel st proto_insns
                TESTLT_P  i l      -> instr3 st i_TESTLT_P i (findLabel l)
                TESTEQ_P  i l      -> instr3 st i_TESTEQ_P i (findLabel l)
                CASEFAIL           -> instr1 st i_CASEFAIL
-               JMP l              -> instr2 st i_JMP (findLabel l)
+               JMP       l        -> instr2 st i_JMP (findLabel l)
                ENTER              -> instr1 st i_ENTER
-               RETURN rep         -> do (itbl_no,st2) <- itoc_itbl st rep
+               RETURN    rep      -> do (itbl_no,st2) <- itoc_itbl st rep
                                         instr2 st2 i_RETURN itbl_no
+               CCALL     m_addr   -> do (np, st2) <- addr st m_addr
+                                        instr2 st2 i_CCALL np
 
        i2s :: Int -> Word16
        i2s = fromIntegral
@@ -315,31 +337,36 @@ mkBits findLabel st proto_insns
        literal st (MachFloat r)  = float st (fromRational r)
        literal st (MachDouble r) = double st (fromRational r)
        literal st (MachChar c)   = int st c
+       literal st other          = pprPanic "ByteCodeLink.literal" (ppr other)
 
        ctoi_itbl st pk
           = addr st ret_itbl_addr
             where
-               ret_itbl_addr = case pk of
-                                  PtrRep    -> stg_ctoi_ret_R1p_info
-                                  WordRep   -> stg_ctoi_ret_R1n_info
-                                  IntRep    -> stg_ctoi_ret_R1n_info
-                                  AddrRep   -> stg_ctoi_ret_R1n_info
-                                  CharRep   -> stg_ctoi_ret_R1n_info
-                                  FloatRep  -> stg_ctoi_ret_F1_info
-                                  DoubleRep -> stg_ctoi_ret_D1_info
-                                  VoidRep   -> stg_ctoi_ret_V_info
-                                  _ -> pprPanic "mkBits.ctoi_itbl" (ppr pk)
+               ret_itbl_addr 
+                  = case pk of
+                       PtrRep    -> stg_ctoi_ret_R1p_info
+                       WordRep   -> stg_ctoi_ret_R1n_info
+                       IntRep    -> stg_ctoi_ret_R1n_info
+                       AddrRep   -> stg_ctoi_ret_R1n_info
+                       CharRep   -> stg_ctoi_ret_R1n_info
+                       FloatRep  -> stg_ctoi_ret_F1_info
+                       DoubleRep -> stg_ctoi_ret_D1_info
+                       VoidRep   -> stg_ctoi_ret_V_info
+                       other     -> pprPanic "ByteCodeLink.ctoi_itbl" (ppr pk)
 
        itoc_itbl st pk
           = addr st ret_itbl_addr
             where
-               ret_itbl_addr = case pk of
-                                  CharRep   -> stg_gc_unbx_r1_info
-                                  IntRep    -> stg_gc_unbx_r1_info
-                                  FloatRep  -> stg_gc_f1_info
-                                  DoubleRep -> stg_gc_d1_info
-                                  VoidRep   -> nullAddr  
-                                  -- Interpreter.c spots this special case
+               ret_itbl_addr 
+                  = case pk of
+                       CharRep   -> stg_gc_unbx_r1_ret_info
+                       IntRep    -> stg_gc_unbx_r1_ret_info
+                       AddrRep   -> stg_gc_unbx_r1_ret_info
+                       FloatRep  -> stg_gc_f1_ret_info
+                       DoubleRep -> stg_gc_d1_ret_info
+                       VoidRep   -> nullAddr  
+                       -- Interpreter.c spots this special case
+                       other     -> pprPanic "ByteCodeLink.itoc_itbl" (ppr pk)
                      
 foreign label "stg_ctoi_ret_R1p_info" stg_ctoi_ret_R1p_info :: Addr
 foreign label "stg_ctoi_ret_R1n_info" stg_ctoi_ret_R1n_info :: Addr
@@ -347,9 +374,9 @@ foreign label "stg_ctoi_ret_F1_info"  stg_ctoi_ret_F1_info :: Addr
 foreign label "stg_ctoi_ret_D1_info"  stg_ctoi_ret_D1_info :: Addr
 foreign label "stg_ctoi_ret_V_info"   stg_ctoi_ret_V_info :: Addr
 
-foreign label "stg_gc_unbx_r1_info" stg_gc_unbx_r1_info :: Addr
-foreign label "stg_gc_f1_info"      stg_gc_f1_info :: Addr
-foreign label "stg_gc_d1_info"      stg_gc_d1_info :: Addr
+foreign label "stg_gc_unbx_r1_ret_info" stg_gc_unbx_r1_ret_info :: Addr
+foreign label "stg_gc_f1_ret_info"      stg_gc_f1_ret_info :: Addr
+foreign label "stg_gc_d1_ret_info"      stg_gc_d1_ret_info :: Addr
 
 -- The size in 16-bit entities of an instruction.
 instrSize16s :: BCInstr -> Int
@@ -513,7 +540,7 @@ lookupCE ce (Right primop)
         case m of
            Just (Ptr addr) -> case addrToHValue# addr of
                                  (# hval #) -> return hval
-           Nothing -> pprPanic "ByteCodeGen.lookupCE(primop)" (ppr primop)
+           Nothing -> pprPanic "ByteCodeLink.lookupCE(primop)" (ppr primop)
 lookupCE ce (Left nm)
    = case lookupFM ce nm of
         Just aa -> return aa
@@ -522,7 +549,7 @@ lookupCE ce (Left nm)
                  case m of
                     Just (Ptr addr) -> case addrToHValue# addr of
                                           (# hval #) -> return hval
-                    Nothing        -> pprPanic "ByteCodeGen.lookupCE" (ppr nm)
+                    Nothing        -> pprPanic "ByteCodeLink.lookupCE" (ppr nm)
 
 lookupIE :: ItblEnv -> Name -> IO (Ptr a)
 lookupIE ie con_nm 
@@ -538,7 +565,7 @@ lookupIE ie con_nm
                              n <- lookupSymbol (nameToCLabel con_nm "static_info")
                              case n of
                                 Just addr -> return addr
-                                Nothing -> pprPanic "ByteCodeGen.lookupIE" (ppr con_nm)
+                                Nothing -> pprPanic "ByteCodeLink.lookupIE" (ppr con_nm)
 
 -- HACKS!!!  ToDo: cleaner
 nameToCLabel :: Name -> String{-suffix-} -> String
@@ -592,6 +619,13 @@ i_ENTER    = (bci_ENTER :: Int)
 i_RETURN   = (bci_RETURN :: Int)
 i_STKCHECK = (bci_STKCHECK :: Int)
 i_JMP      = (bci_JMP :: Int)
+#ifdef bci_CCALL
+i_CCALL    = (bci_CCALL :: Int)
+i_SWIZZLE  = (bci_SWIZZLE :: Int)
+#else
+i_CCALL    = error "Sorry pal, you need to bootstrap to use i_CCALL."
+i_SWIZZLE  = error "Sorry pal, you need to bootstrap to use i_SWIZZLE."
+#endif
 
 iNTERP_STACK_CHECK_THRESH = (INTERP_STACK_CHECK_THRESH :: Int)