{-# LANGUAGE ForeignFunctionInterface #-}
module Mate.ClassPool where
-import Data.Binary
-import Data.String.Utils
import qualified Data.Map as M
import qualified Data.Set as S
import qualified Data.ByteString.Lazy as B
-import System.Plugins
import Text.Printf
import Foreign.Ptr
import Foreign.C.Types
-import Foreign.C.String
-import Foreign.StablePtr
import Foreign.Marshal.Alloc
import JVM.ClassFile
import JVM.Converter
-import Harpy
-import Harpy.X86Disassembler
-
-import Mate.BasicBlocks
import Mate.Types
-import Mate.Utilities
+getClassInfo :: B.ByteString -> IO ClassInfo
+getClassInfo path = do
+ ptr_classmap <- get_classmap
+ class_map <- ptr2classmap ptr_classmap
+ case M.lookup path class_map of
+ Nothing -> loadClass path
+ Just ci -> return ci
getClassFile :: B.ByteString -> IO (Class Resolved)
getClassFile path = do
+ (ClassInfo _ cfile _ _) <- getClassInfo path
+ return cfile
+
+getFieldBase :: B.ByteString -> IO (CUInt)
+getFieldBase path = do
+ (ClassInfo _ _ fs _) <- getClassInfo path
+ return $ fromIntegral $ ptrToIntPtr fs
+
+getFieldOffset :: B.ByteString -> B.ByteString -> IO (CUInt)
+getFieldOffset path field = do
+ (ClassInfo _ _ _ fieldmap) <- getClassInfo path
+ return $ fromIntegral $ fieldmap M.! field
+
+foreign export ccall getFieldAddr :: CUInt -> Ptr () -> IO CUInt
+getFieldAddr :: CUInt -> Ptr () -> IO CUInt
+getFieldAddr from ptr_trapmap = do
+ trapmap <- ptr2tmap ptr_trapmap
+ let w32_from = fromIntegral from
+ let sfi = trapmap M.! w32_from
+ case sfi of
+ (SFI (StaticFieldInfo cls field)) -> do
+ off <- getFieldOffset cls field
+ base <- getFieldBase cls
+ return $ base + off
+ _ -> error $ "getFieldAddr: no trapInfo. abort"
+
+loadClass :: B.ByteString -> IO ClassInfo
+loadClass path = do
ptr_classmap <- get_classmap
class_map <- ptr2classmap ptr_classmap
- case M.lookup path class_map of
- Nothing -> do
- let rpath = toString $ path `B.append` ".class"
- cfile <- parseClassFile rpath
- let class_map' = M.insert path (ClassInfo path cfile) class_map
- classmap2ptr class_map' >>= set_classmap
- return cfile
- Just (ClassInfo name cfs) -> return cfs
+ let rpath = toString $ path `B.append` ".class"
+ cfile <- parseClassFile rpath
+ printf "class fieldlength: %d\n" $ classFieldsCount cfile
+ -- TODO(bernhard): correct sizes. int only atm
+ let filteredfields = filter (S.member ACC_STATIC . fieldAccessFlags) (classFields cfile)
+ let fm = zipWith (\x y -> (fieldName y, x)) [0,4..] filteredfields
+ let fieldmap = M.fromList fm
+ fieldbase <- mallocBytes ((fromIntegral $ M.size fieldmap) * 4)
+ putStrLn $ "fieldmap: " ++ (show fieldmap)
+ let new_ci = ClassInfo path cfile fieldbase fieldmap
+ let class_map' = M.insert path new_ci class_map
+ classmap2ptr class_map' >>= set_classmap
+ return new_ci