1 {-# LANGUAGE OverloadedStrings #-}
3 module Mate.Types where
6 import qualified Data.Map as M
7 import qualified Data.ByteString.Lazy as B
10 import System.IO.Unsafe
15 import Mate.NativeSizes
19 -- Represents a CFG node
20 data BasicBlock = BasicBlock {
21 code :: [Instruction],
24 -- describes (leaving) edges of a CFG node
25 data BBEnd = Return | FallThrough BlockID | OneTarget BlockID | TwoTarget BlockID BlockID deriving Show
27 type MapBB = M.Map BlockID BasicBlock
29 data RawMethod = RawMethod {
33 rawArgCount :: NativeWord,
34 rawCodeLength :: NativeWord }
37 -- NativeWord = point of method call in generated code
38 -- MethodInfo = relevant information about callee
39 type TrapMap = M.Map NativeWord TrapCause
42 StaticMethod MethodInfo | -- for static calls
43 VirtualCall Bool MethodInfo (IO NativeWord) | -- for invoke{interface,virtual}
44 InstanceOf B.ByteString | -- class name
45 NewObject B.ByteString | -- class name
46 StaticField StaticFieldInfo
48 data StaticFieldInfo = StaticFieldInfo {
49 sfiClassName :: B.ByteString,
50 sfiFieldName :: B.ByteString } deriving Show
54 -- B.ByteString = name of method
55 -- NativeWord = entrypoint of method
56 type MethodMap = M.Map MethodInfo NativeWord
58 data MethodInfo = MethodInfo {
59 methName :: B.ByteString,
60 methClassName :: B.ByteString,
61 methSignature :: MethodSignature
64 instance Show MethodInfo where
65 show (MethodInfo method c sig) =
66 toString c ++ "." ++ toString method ++ "." ++ show sig
70 -- store information of loaded classes
71 type ClassMap = M.Map B.ByteString ClassInfo
73 data ClassInfo = ClassInfo {
74 ciName :: B.ByteString,
75 ciFile :: Class Direct,
76 ciStaticMap :: FieldMap,
77 ciFieldMap :: FieldMap,
78 ciMethodMap :: FieldMap,
79 ciMethodBase :: NativeWord,
83 -- store field offsets in a map
84 type FieldMap = M.Map B.ByteString Int32
87 -- java strings are allocated only once, therefore we
88 -- use a hashmap to store the address for a String
89 type StringMap = M.Map B.ByteString NativeWord
92 -- map "methodtable addr" to "classname"
93 -- we need that to identify the actual type
94 -- on the invokevirtual insn
95 type VirtualMap = M.Map NativeWord B.ByteString
98 -- store each parsed Interface upon first loading
99 type InterfaceMap = M.Map B.ByteString (Class Direct)
101 -- store offset for each <Interface><Method><Signature> pair
102 type InterfaceMethodMap = M.Map B.ByteString NativeWord
106 toString :: B.ByteString -> String
107 toString bstr = decodeString $ map (chr . fromIntegral) $ B.unpack bstr
110 -- better solutions for a global map hack are welcome! (typeclasses, TH, ...?)
112 data MateCtx = MateCtx {
113 ctxMethodMap :: MethodMap,
114 ctxTrapMap :: TrapMap,
115 ctxClassMap :: ClassMap,
116 ctxVirtualMap :: VirtualMap,
117 ctxStringMap :: StringMap,
118 ctxInterfaceMap :: InterfaceMap,
119 ctxInterfaceMethodMap :: InterfaceMethodMap }
121 emptyMateCtx :: MateCtx
122 emptyMateCtx = MateCtx M.empty M.empty M.empty M.empty M.empty M.empty M.empty
124 mateCtx :: IORef MateCtx
125 {-# NOINLINE mateCtx #-}
126 mateCtx = unsafePerformIO $ newIORef emptyMateCtx
128 -- TODO(bernhard): if we ever have thread support, don't forget MVars
129 #define SETMAP(name) set##name :: name -> IO (); \
130 set##name m = do ctx <- readIORef mateCtx; \
131 writeIORef mateCtx $ ctx { ctx##name = m };
133 #define GETMAP(name) get##name :: IO name ; \
134 get##name = do ctx <- readIORef mateCtx; \
135 return $ ctx##name ctx;
155 SETMAP(InterfaceMethodMap)
156 GETMAP(InterfaceMethodMap)