Code (..),
IMM (..),
CMP (..),
+ atype2byte,
+ encodeInstructions,
encodeMethod,
decodeMethod
)
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
codeExceptionsN :: Word16,
codeExceptions :: [CodeException],
codeAttrsN :: Word16,
- codeAttributes :: [AttributeInfo] }
+ codeAttributes :: Attributes Pointers }
deriving (Eq, Show)
-- | Exception descriptor
get = CodeException <$> get <*> get <*> get <*> get
-instance BinaryState Integer AttributeInfo where
+instance BinaryState Integer Attribute where
put a = do
let sz = 6 + attributeLength a -- full size of AttributeInfo structure
liftOffset (fromIntegral sz) Binary.put a
put codeExceptionsN
forM_ codeExceptions put
put codeAttrsN
- forM_ codeAttributes put
+ forM_ (attributesList codeAttributes) put
get = do
stackSz <- get
excs <- replicateM (fromIntegral excn) get
nAttrs <- get
attrs <- replicateM (fromIntegral nAttrs) get
- return $ Code stackSz locals len code excn excs nAttrs attrs
+ return $ Code stackSz locals len code excn excs nAttrs (AP attrs)
-- | Read sequence of instructions (to end of stream)
readInstructions :: GetState Integer [Instruction]
| inRange (153, 158) c -> return $ IF (toEnum $ fromIntegral $ c-153)
| inRange (159, 164) c -> IF_ICMP (toEnum $ fromIntegral $ c-159) <$> get
| otherwise -> fail $ "Unknown instruction byte code: " ++ show c
+
+encodeInstructions :: [Instruction] -> B.ByteString
+encodeInstructions code =
+ let p list = forM_ list put
+ in encodeWith p (0 :: Integer) code
-- | Decode Java method
decodeMethod :: B.ByteString -> Code