1 {-# LANGUAGE OverloadedStrings #-}
3 module Mate.Types where
7 import qualified Data.Map as M
8 import qualified Data.ByteString.Lazy as B
11 import System.IO.Unsafe
18 -- Represents a CFG node
19 data BasicBlock = BasicBlock {
20 code :: [Instruction],
23 -- describes (leaving) edges of a CFG node
24 data BBEnd = Return | FallThrough BlockID | OneTarget BlockID | TwoTarget BlockID BlockID deriving Show
26 type MapBB = M.Map BlockID BasicBlock
28 data RawMethod = RawMethod {
32 rawArgCount :: Word32 }
35 -- Word32 = point of method call in generated code
36 -- MethodInfo = relevant information about callee
37 type TrapMap = M.Map Word32 TrapCause
40 StaticMethod MethodInfo | -- for static calls
41 VirtualMethod Bool MethodInfo | -- for virtual calls
42 InterfaceMethod Bool MethodInfo | -- for interface calls
43 StaticField StaticFieldInfo deriving Show
45 data StaticFieldInfo = StaticFieldInfo {
46 sfiClassName :: B.ByteString,
47 sfiFieldName :: B.ByteString } deriving Show
51 -- B.ByteString = name of method
52 -- Word32 = entrypoint of method
53 type MethodMap = M.Map MethodInfo Word32
55 data MethodInfo = MethodInfo {
56 methName :: B.ByteString,
57 methClassName :: B.ByteString,
58 methSignature :: MethodSignature
61 instance Show MethodInfo where
62 show (MethodInfo method c sig) =
63 toString c ++ "." ++ toString method ++ "." ++ show sig
67 -- store information of loaded classes
68 type ClassMap = M.Map B.ByteString ClassInfo
70 data ClassInfo = ClassInfo {
71 ciName :: B.ByteString,
72 ciFile :: Class Direct,
73 ciStaticMap :: FieldMap,
74 ciFieldMap :: FieldMap,
75 ciMethodMap :: FieldMap,
76 ciMethodBase :: Word32,
80 -- store field offsets in a map
81 type FieldMap = M.Map B.ByteString Int32
84 -- java strings are allocated only once, therefore we
85 -- use a hashmap to store the address for a String
86 type StringMap = M.Map B.ByteString Word32
89 -- map "methodtable addr" to "classname"
90 -- we need that to identify the actual type
91 -- on the invokevirtual insn
92 type VirtualMap = M.Map Word32 B.ByteString
95 -- store each parsed Interface upon first loading
96 type InterfaceMap = M.Map B.ByteString (Class Direct)
98 -- store offset for each <Interface><Method><Signature> pair
99 type InterfaceMethodMap = M.Map B.ByteString Word32
103 toString :: B.ByteString -> String
104 toString bstr = decodeString $ map (chr . fromIntegral) $ B.unpack bstr
107 -- better solutions for a global map hack are welcome! (typeclasses, TH, ...?)
109 data MateCtx = MateCtx {
110 ctxMethodMap :: MethodMap,
111 ctxTrapMap :: TrapMap,
112 ctxClassMap :: ClassMap,
113 ctxVirtualMap :: VirtualMap,
114 ctxStringMap :: StringMap,
115 ctxInterfaceMap :: InterfaceMap,
116 ctxInterfaceMethodMap :: InterfaceMethodMap }
118 emptyMateCtx :: MateCtx
119 emptyMateCtx = MateCtx M.empty M.empty M.empty M.empty M.empty M.empty M.empty
121 mateCtx :: IORef MateCtx
122 {-# NOINLINE mateCtx #-}
123 mateCtx = unsafePerformIO $ newIORef emptyMateCtx
125 -- TODO(bernhard): if we ever have thread support, don't forget MVars
126 #define SETMAP(name) set##name :: name -> IO (); \
127 set##name m = do ctx <- readIORef mateCtx; \
128 writeIORef mateCtx $ ctx { ctx##name = m };
130 #define GETMAP(name) get##name :: IO name ; \
131 get##name = do ctx <- readIORef mateCtx; \
132 return $ ctx##name ctx;
152 SETMAP(InterfaceMethodMap)
153 GETMAP(InterfaceMethodMap)