import Control.Monad
import Control.Applicative
+import Data.Ix (inRange)
import Data.Word
import qualified Data.Binary as Binary
import qualified Data.ByteString.Lazy as B
-import Data.Array
import Data.BinaryState
import JVM.ClassFile
import Data.Bits
import Data.Binary
import qualified Data.ByteString.Lazy as B
-import Data.Array
import qualified Data.Set as S
import qualified Data.Map as M
toCPInfo :: Pool -> [CpInfo]
toCPInfo pool = result
where
- result = map cpInfo $ elems pool
+ result = map cpInfo $ M.elems pool
cpInfo (CClass name) = CONSTANT_Class (force "class" $ poolIndex result name)
cpInfo (CField cls name) =
constantPoolArray list = pool
where
pool :: Pool
- pool = listArray (1,n) $ map convert list
+ pool = M.fromList $ zip [1..] $ map convert list
n = fromIntegral $ length list
convertNameType :: (HasSignature a, Binary (Signature a)) => Word16 -> NameType a
module JVM.Dump where
import Control.Monad
-import Data.Array
+import qualified Data.Map as M
import qualified Data.ByteString.Lazy as B
import Text.Printf
putStr "Class: "
B.putStrLn (this cls)
putStrLn "Constants pool:"
- forM_ (assocs $ constantPool cls) $ \(i, c) ->
+ forM_ (M.assocs $ constantPool cls) $ \(i, c) ->
putStrLn $ printf " #%d:\t%s" i (show c)
putStrLn "Methods:"
forM_ (methods cls) $ \m -> do
module JVM.Generator where
import Control.Monad.State as St
-import Data.Array
import Data.Word
import Data.List
import Data.Binary
emptyGState = GState {
generated = [],
- currentPool = listArray (0,0) [CInteger 0],
+ currentPool = M.empty,
doneMethods = [],
currentMethod = Nothing }
appendPool :: Constant -> Pool -> (Pool, Word16)
appendPool c pool =
- let list = assocs pool
- size = fromIntegral (length list)
- list' = list ++ [(size, c)]
- in (array (0, size) list',
- size)
+ let size = fromIntegral (M.size pool)
+ pool' = M.insert size c pool
+ in (pool', size)
addItem :: Constant -> Generate Word16
addItem c = do
pool <- St.gets currentPool
- if pool ! 0 == CInteger 0
- then do
- st <- St.get
- St.put $ st {currentPool = listArray (0,0) [c]}
- return 1
- else case lookupPool c pool of
- Just i -> return i
- Nothing -> do
- let (pool', i) = appendPool c pool
- st <- St.get
- St.put $ st {currentPool = pool'}
- return (i+1)
+ case lookupPool c pool of
+ Just i -> return i
+ Nothing -> do
+ let (pool', i) = appendPool c pool
+ st <- St.get
+ St.put $ st {currentPool = pool'}
+ return (i+1)
lookupPool :: Constant -> Pool -> Maybe Word16
lookupPool c pool =
- fromIntegral `fmap` findIndex (== c) (elems pool)
+ fromIntegral `fmap` findIndex (== c) (M.elems pool)
addNT :: Binary (Signature a) => NameType a -> Generate Word16
addNT (NameType name sig) = do
import Codec.Binary.UTF8.String hiding (encode, decode)
import Control.Applicative
-import Data.Array
import Data.Binary
import Data.Binary.Put
import qualified Data.ByteString.Lazy as B
toCharList bstr = map fromIntegral $ B.unpack bstr
-- | Constant pool
-type Pool = Array Word16 Constant
+type Pool = M.Map Word16 Constant
-asize :: (Ix i) => Array i e -> Int
-asize = length . elems
+poolSize :: Pool -> Int
+poolSize = M.size
+
+(!) :: (Ord k) => M.Map k a -> k -> a
+(!) = (M.!)
showListIx :: (Show a) => [a] -> String
showListIx list = unlines $ zipWith s [1..] list
import JVM.ClassFile
import JVM.Converter
import JVM.Assembler
+import JVM.Dump
main = do
args <- getArgs
[clspath,outpath] -> do
cls <- parseClassFile clspath
clsfile <- decodeFile clspath :: IO ClassFile
- putStr "Class: "
- B.putStrLn (this cls)
- putStrLn "Constants pool:"
- forM_ (assocs $ constantPool cls) $ \(i, c) ->
- putStrLn $ printf " #%d:\t%s" i (show c)
- putStrLn "Methods:"
- forM_ (methods cls) $ \m -> do
- putStr ">> Method "
- B.putStr (methodName m)
- print (methodSignature m)
- case attrByName m "Code" of
- Nothing -> putStrLn "(no code)\n"
- Just bytecode -> let code = decodeMethod bytecode
- in forM_ (codeInstructions code) $ \i -> do
- putStr " "
- print i
+ dumpClass cls
putStrLn $ "Source pool:\n" ++ showListIx (constsPool clsfile)
let result = classFile cls
putStrLn $ "Result pool:\n" ++ showListIx (constsPool result)