1 {-# LANGUAGE OverloadedStrings #-}
2 module Mate.Types where
5 import qualified Data.Map as M
6 import qualified Data.ByteString.Lazy as B
9 import System.IO.Unsafe
14 import Mate.NativeSizes
18 -- Represents a CFG node
19 data BasicBlock = BasicBlock {
20 code :: [Instruction],
23 -- describes (leaving) edges of a CFG node
28 | TwoTarget BlockID BlockID
31 type MapBB = M.Map BlockID BasicBlock
33 data RawMethod = RawMethod {
37 rawArgCount :: NativeWord,
38 rawCodeLength :: NativeWord }
41 -- NativeWord = point of method call in generated code
42 -- MethodInfo = relevant information about callee
43 type TrapMap = M.Map NativeWord TrapCause
46 = StaticMethod MethodInfo -- for static calls
47 | VirtualCall Bool MethodInfo (IO NativeWord) -- for invoke{interface,virtual}
48 | InstanceOf B.ByteString -- class name
49 | NewObject B.ByteString -- class name
50 | StaticField StaticFieldInfo
52 data StaticFieldInfo = StaticFieldInfo {
53 sfiClassName :: B.ByteString,
54 sfiFieldName :: B.ByteString } deriving Show
58 -- B.ByteString = name of method
59 -- NativeWord = entrypoint of method
60 type MethodMap = M.Map MethodInfo NativeWord
62 data MethodInfo = MethodInfo {
63 methName :: B.ByteString,
64 methClassName :: B.ByteString,
65 methSignature :: MethodSignature
68 instance Show MethodInfo where
69 show (MethodInfo method c sig) =
70 toString c ++ "." ++ toString method ++ "." ++ show sig
74 -- store information of loaded classes
75 type ClassMap = M.Map B.ByteString ClassInfo
77 data ClassInfo = ClassInfo {
78 ciName :: B.ByteString,
79 ciFile :: Class Direct,
80 ciStaticMap :: FieldMap,
81 ciFieldMap :: FieldMap,
82 ciMethodMap :: FieldMap,
83 ciMethodBase :: NativeWord,
87 -- store field offsets in a map
88 type FieldMap = M.Map B.ByteString Int32
91 -- java strings are allocated only once, therefore we
92 -- use a hashmap to store the address for a String
93 type StringMap = M.Map B.ByteString NativeWord
96 -- map "methodtable addr" to "classname"
97 -- we need that to identify the actual type
98 -- on the invokevirtual insn
99 type VirtualMap = M.Map NativeWord B.ByteString
102 -- store each parsed Interface upon first loading
103 type InterfaceMap = M.Map B.ByteString (Class Direct)
105 -- store offset for each <Interface><Method><Signature> pair
106 type InterfaceMethodMap = M.Map B.ByteString NativeWord
110 toString :: B.ByteString -> String
111 toString bstr = decodeString $ map (chr . fromIntegral) $ B.unpack bstr
115 data MateCtx = MateCtx {
116 ctxMethodMap :: MethodMap,
117 ctxTrapMap :: TrapMap,
118 ctxClassMap :: ClassMap,
119 ctxVirtualMap :: VirtualMap,
120 ctxStringMap :: StringMap,
121 ctxInterfaceMap :: InterfaceMap,
122 ctxInterfaceMethodMap :: InterfaceMethodMap }
124 emptyMateCtx :: MateCtx
125 emptyMateCtx = MateCtx M.empty M.empty M.empty M.empty M.empty M.empty M.empty
127 mateCtx :: IORef MateCtx
128 {-# NOINLINE mateCtx #-}
129 mateCtx = unsafePerformIO $ newIORef emptyMateCtx
132 setMethodMap :: MethodMap -> IO ()
134 ctx <- readIORef mateCtx
135 writeIORef mateCtx $ ctx { ctxMethodMap = m }
137 getMethodMap :: IO MethodMap
139 ctx <- readIORef mateCtx
140 return $ ctxMethodMap ctx
143 setTrapMap :: TrapMap -> IO ()
145 ctx <- readIORef mateCtx
146 writeIORef mateCtx $ ctx { ctxTrapMap = m }
148 getTrapMap :: IO TrapMap
150 ctx <- readIORef mateCtx
151 return $ ctxTrapMap ctx
154 setClassMap :: ClassMap -> IO ()
156 ctx <- readIORef mateCtx
157 writeIORef mateCtx $ ctx { ctxClassMap = m }
159 getClassMap :: IO ClassMap
161 ctx <- readIORef mateCtx
162 return $ ctxClassMap ctx
165 setVirtualMap :: VirtualMap -> IO ()
167 ctx <- readIORef mateCtx
168 writeIORef mateCtx $ ctx { ctxVirtualMap = m }
170 getVirtualMap :: IO VirtualMap
172 ctx <- readIORef mateCtx
173 return $ ctxVirtualMap ctx
176 setStringMap :: StringMap -> IO ()
178 ctx <- readIORef mateCtx
179 writeIORef mateCtx $ ctx { ctxStringMap = m }
181 getStringMap :: IO StringMap
183 ctx <- readIORef mateCtx
184 return $ ctxStringMap ctx
187 setInterfaceMap :: InterfaceMap -> IO ()
188 setInterfaceMap m = do
189 ctx <- readIORef mateCtx
190 writeIORef mateCtx $ ctx { ctxInterfaceMap = m }
192 getInterfaceMap :: IO InterfaceMap
194 ctx <- readIORef mateCtx
195 return $ ctxInterfaceMap ctx
198 setInterfaceMethodMap :: InterfaceMethodMap -> IO ()
199 setInterfaceMethodMap m = do
200 ctx <- readIORef mateCtx
201 writeIORef mateCtx $ ctx { ctxInterfaceMethodMap = m }
203 getInterfaceMethodMap :: IO InterfaceMethodMap
204 getInterfaceMethodMap = do
205 ctx <- readIORef mateCtx
206 return $ ctxInterfaceMethodMap ctx