X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=Mate%2FTypes.hs;h=de17e3780aa4cf8c695e72ce4a6891fb505a64e8;hb=2ac2a68eb5b709caa636d1a9a56a40268d378550;hp=831744ab27e1c0d96e162cd16fe6de4707b86dc2;hpb=094e3cea9aa9d638b071fb52a12f04f6ddd80dc1;p=mate.git diff --git a/Mate/Types.hs b/Mate/Types.hs index 831744a..de17e37 100644 --- a/Mate/Types.hs +++ b/Mate/Types.hs @@ -1,27 +1,57 @@ {-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE CPP #-} -module Mate.Types where +module Mate.Types + ( BlockID + , BasicBlock(..) + , BBEnd(..) + , MapBB + , RawMethod(..) + , TrapMap, MethodMap, ClassMap, FieldMap + , StringMap, VirtualMap, InterfaceMap + , InterfaceMethodMap + , TrapCause(..) + , StaticFieldInfo(..) + , MethodInfo(..) + , ClassInfo(..) + , setTrapMap, getTrapMap + , setMethodMap, getMethodMap + , setClassMap, getClassMap + , setStringMap, getStringMap + , setVirtualMap, getVirtualMap + , setInterfaceMap, getInterfaceMap + , setInterfaceMethodMap, getInterfaceMethodMap + ) where -import Data.Word import Data.Int +import Data.Functor import qualified Data.Map as M import qualified Data.ByteString.Lazy as B import Data.IORef import System.IO.Unsafe +import Harpy +import Foreign.C.Types + import JVM.ClassFile import JVM.Assembler +import Mate.NativeSizes + type BlockID = Int -- Represents a CFG node data BasicBlock = BasicBlock { code :: [Instruction], + exception :: B.ByteString, successor :: BBEnd } -- describes (leaving) edges of a CFG node -data BBEnd = Return | FallThrough BlockID | OneTarget BlockID | TwoTarget BlockID BlockID deriving Show +data BBEnd + = Return + | FallThrough BlockID + | OneTarget BlockID + | TwoTarget BlockID BlockID + deriving Show type MapBB = M.Map BlockID BasicBlock @@ -29,20 +59,26 @@ data RawMethod = RawMethod { rawMapBB :: MapBB, rawLocals :: Int, rawStackSize :: Int, - rawArgCount :: Word32 } + rawArgCount :: NativeWord, + rawCodeLength :: NativeWord } --- Word32 = point of method call in generated code +-- NativeWord = point of method call in generated code -- MethodInfo = relevant information about callee -type TrapMap = M.Map Word32 TrapCause +type TrapMap = M.Map NativeWord TrapCause + +type TrapPatcher = CPtrdiff -> CodeGen () () CPtrdiff +type TrapPatcherEax = CPtrdiff -> CPtrdiff -> CodeGen () () CPtrdiff +type TrapPatcherEsp = TrapPatcherEax -data TrapCause = - StaticMethod MethodInfo | -- for static calls - VirtualMethod Bool MethodInfo | -- for virtual calls - InterfaceMethod Bool MethodInfo | -- for interface calls - InstanceOf B.ByteString | -- class name - NewObject B.ByteString | -- class name - StaticField StaticFieldInfo deriving Show +data TrapCause + = StaticMethod TrapPatcher -- for static calls + | VirtualCall Bool MethodInfo (IO NativeWord) -- for invoke{interface,virtual} + | InstanceOf TrapPatcherEax + | ThrowException TrapPatcherEsp + | NewObject TrapPatcher + | StaticField StaticFieldInfo + | ObjectField TrapPatcher data StaticFieldInfo = StaticFieldInfo { sfiClassName :: B.ByteString, @@ -51,8 +87,8 @@ data StaticFieldInfo = StaticFieldInfo { -- B.ByteString = name of method --- Word32 = entrypoint of method -type MethodMap = M.Map MethodInfo Word32 +-- NativeWord = entrypoint of method +type MethodMap = M.Map MethodInfo NativeWord data MethodInfo = MethodInfo { methName :: B.ByteString, @@ -75,7 +111,7 @@ data ClassInfo = ClassInfo { ciStaticMap :: FieldMap, ciFieldMap :: FieldMap, ciMethodMap :: FieldMap, - ciMethodBase :: Word32, + ciMethodBase :: NativeWord, ciInitDone :: Bool } @@ -85,20 +121,20 @@ type FieldMap = M.Map B.ByteString Int32 -- java strings are allocated only once, therefore we -- use a hashmap to store the address for a String -type StringMap = M.Map B.ByteString Word32 +type StringMap = M.Map B.ByteString NativeWord -- map "methodtable addr" to "classname" -- we need that to identify the actual type -- on the invokevirtual insn -type VirtualMap = M.Map Word32 B.ByteString +type VirtualMap = M.Map NativeWord B.ByteString -- store each parsed Interface upon first loading type InterfaceMap = M.Map B.ByteString (Class Direct) -- store offset for each pair -type InterfaceMethodMap = M.Map B.ByteString Word32 +type InterfaceMethodMap = M.Map B.ByteString NativeWord {- @@ -106,7 +142,6 @@ toString :: B.ByteString -> String toString bstr = decodeString $ map (chr . fromIntegral) $ B.unpack bstr -} --- better solutions for a global map hack are welcome! (typeclasses, TH, ...?) data MateCtx = MateCtx { ctxMethodMap :: MethodMap, @@ -124,32 +159,47 @@ mateCtx :: IORef MateCtx {-# NOINLINE mateCtx #-} mateCtx = unsafePerformIO $ newIORef emptyMateCtx --- TODO(bernhard): if we ever have thread support, don't forget MVars -#define SETMAP(name) set##name :: name -> IO (); \ - set##name m = do ctx <- readIORef mateCtx; \ - writeIORef mateCtx $ ctx { ctx##name = m }; +setMap :: (MateCtx -> MateCtx) -> IO () +setMap recordupdate = recordupdate <$> readIORef mateCtx >>= writeIORef mateCtx + +setMethodMap :: MethodMap -> IO () +setMethodMap m = setMap (\x -> x {ctxMethodMap = m}) + +getMethodMap :: IO MethodMap +getMethodMap = ctxMethodMap <$> readIORef mateCtx + +setTrapMap :: TrapMap -> IO () +setTrapMap m = setMap (\x -> x {ctxTrapMap = m}) + +getTrapMap :: IO TrapMap +getTrapMap = ctxTrapMap <$> readIORef mateCtx + +setClassMap :: ClassMap -> IO () +setClassMap m = setMap (\x -> x {ctxClassMap = m}) + +getClassMap :: IO ClassMap +getClassMap = ctxClassMap <$> readIORef mateCtx -#define GETMAP(name) get##name :: IO name ; \ - get##name = do ctx <- readIORef mateCtx; \ - return $ ctx##name ctx; +setVirtualMap :: VirtualMap -> IO () +setVirtualMap m = setMap (\x -> x {ctxVirtualMap = m}) -SETMAP(MethodMap); -GETMAP(MethodMap) +getVirtualMap :: IO VirtualMap +getVirtualMap = ctxVirtualMap <$> readIORef mateCtx -SETMAP(TrapMap) -GETMAP(TrapMap) +setStringMap :: StringMap -> IO () +setStringMap m = setMap (\x -> x {ctxStringMap = m}) -SETMAP(ClassMap) -GETMAP(ClassMap) +getStringMap :: IO StringMap +getStringMap = ctxStringMap <$> readIORef mateCtx -SETMAP(VirtualMap) -GETMAP(VirtualMap) +setInterfaceMap :: InterfaceMap -> IO () +setInterfaceMap m = setMap (\x -> x {ctxInterfaceMap = m}) -SETMAP(StringMap) -GETMAP(StringMap) +getInterfaceMap :: IO InterfaceMap +getInterfaceMap = ctxInterfaceMap <$> readIORef mateCtx -SETMAP(InterfaceMap) -GETMAP(InterfaceMap) +setInterfaceMethodMap :: InterfaceMethodMap -> IO () +setInterfaceMethodMap m = setMap (\x -> x {ctxInterfaceMethodMap = m}) -SETMAP(InterfaceMethodMap) -GETMAP(InterfaceMethodMap) +getInterfaceMethodMap :: IO InterfaceMethodMap +getInterfaceMethodMap = ctxInterfaceMethodMap <$> readIORef mateCtx