jvm-binary 0.4.0 → 0.5.0
raw patch · 8 files changed
+97/−11 lines, 8 filesdep +zip-archivePVP ok
version bump matches the API change (PVP)
Dependencies added: zip-archive
API changes (from Hackage documentation)
+ Language.JVM.Constant: AbsVariableMethodId :: !Bool -> !InClass MethodId r -> AbsVariableMethodId r
+ Language.JVM.Constant: [variableIsInterface] :: AbsVariableMethodId r -> !Bool
+ Language.JVM.Constant: [variableMethodId] :: AbsVariableMethodId r -> !InClass MethodId r
+ Language.JVM.Constant: data AbsVariableMethodId r
+ Language.JVM.Constant: instance Control.DeepSeq.NFData (Language.JVM.Constant.AbsVariableMethodId Language.JVM.Stage.High)
+ Language.JVM.Constant: instance Control.DeepSeq.NFData (Language.JVM.Constant.AbsVariableMethodId Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance Data.Binary.Class.Binary (Language.JVM.Constant.AbsVariableMethodId Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Classes.Eq (Language.JVM.Constant.AbsVariableMethodId Language.JVM.Stage.High)
+ Language.JVM.Constant: instance GHC.Classes.Eq (Language.JVM.Constant.AbsVariableMethodId Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Classes.Ord (Language.JVM.Constant.AbsVariableMethodId Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Generics.Generic (Language.JVM.Constant.AbsVariableMethodId Language.JVM.Stage.High)
+ Language.JVM.Constant: instance GHC.Generics.Generic (Language.JVM.Constant.AbsVariableMethodId Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Show.Show (Language.JVM.Constant.AbsVariableMethodId Language.JVM.Stage.High)
+ Language.JVM.Constant: instance GHC.Show.Show (Language.JVM.Constant.AbsVariableMethodId Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance Language.JVM.Constant.Referenceable (Language.JVM.Constant.AbsVariableMethodId Language.JVM.Stage.High)
- Language.JVM.ByteCode: InvkSpecial :: !DeepRef AbsMethodId r -> Invocation r
+ Language.JVM.ByteCode: InvkSpecial :: !DeepRef AbsVariableMethodId r -> Invocation r
- Language.JVM.ByteCode: InvkStatic :: !DeepRef AbsMethodId r -> Invocation r
+ Language.JVM.ByteCode: InvkStatic :: !DeepRef AbsVariableMethodId r -> Invocation r
- Language.JVM.Constant: MHInvokeSpecial :: !DeepRef AbsMethodId r -> MethodHandleMethod r
+ Language.JVM.Constant: MHInvokeSpecial :: !DeepRef AbsVariableMethodId r -> MethodHandleMethod r
- Language.JVM.Constant: MHInvokeStatic :: !DeepRef AbsMethodId r -> MethodHandleMethod r
+ Language.JVM.Constant: MHInvokeStatic :: !DeepRef AbsVariableMethodId r -> MethodHandleMethod r
Files
- CHANGELOG.md +4/−0
- benchmark/Main.hs +3/−3
- jvm-binary.cabal +3/−2
- package.yaml +2/−1
- src/Language/JVM/ByteCode.hs +2/−2
- src/Language/JVM/Constant.hs +27/−3
- test/Language/JVM/ConstantSpec.hs +3/−0
- test/Language/JVMSpec.hs +53/−0
CHANGELOG.md view
@@ -1,5 +1,9 @@ # Change log +## Version 0.5.0+- Reintroduce AbsVariableMethodId+- Small cleanups+ ## Version 0.4.0 - Add Offsets to ByteCode
benchmark/Main.hs view
@@ -60,8 +60,8 @@ Right clf <- readClassFile <$> BL.readFile fp return clf -ex1 :: String-ex1 = "test/data/project/Main.class"-+-- ex1 :: String+-- ex1 = "test/data/project/Main.class"+-- ex2 :: String ex2 = "test/data/SQLite.class"
jvm-binary.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: c647c3fda17f7dd5e2dfec53e2d17a639757b403bd624b71a5f60d831e136b7b+-- hash: b0838b7237f06859c9ba16149ea4153fb80472faa6c7321eef053fdecc6236f7 name: jvm-binary-version: 0.4.0+version: 0.5.0 synopsis: A library for reading Java class-files description: A library for reading Java class-files. category: Language, Java, JVM@@ -103,6 +103,7 @@ , template-haskell , text , vector+ , zip-archive other-modules: Language.JVM.Attribute.BootstrapMethodsSpec Language.JVM.Attribute.CodeSpec
package.yaml view
@@ -1,5 +1,5 @@ name: jvm-binary-version: '0.4.0'+version: '0.5.0' author: Christian Gram Kalhauge maintainer: Christian Gram Kalhauge <kalhauge@cs.ucla.edu> synopsis: A library for reading Java class-files@@ -47,6 +47,7 @@ - hspec >= 2.5.5 - hspec-discover - hspec-expectations-pretty-diff+ - zip-archive ghc-options: - -rtsopts - -threaded
src/Language/JVM/ByteCode.hs view
@@ -371,10 +371,10 @@ deriving (Show, Eq, Ord, Generic, NFData) data Invocation r- = InvkSpecial !(DeepRef AbsMethodId r)+ = InvkSpecial !(DeepRef AbsVariableMethodId r) -- ^ Variable since 52.0 | InvkVirtual !(DeepRef AbsMethodId r)- | InvkStatic !(DeepRef AbsMethodId r)+ | InvkStatic !(DeepRef AbsVariableMethodId r) -- ^ Variable since 52.0 | InvkInterface !Word8 !(DeepRef AbsInterfaceMethodId r) -- ^ Should be a positive number
src/Language/JVM/Constant.hs view
@@ -33,6 +33,7 @@ , AbsMethodId , AbsFieldId , AbsInterfaceMethodId (..)+ , AbsVariableMethodId (..) , MethodId (..) , FieldId (..)@@ -106,11 +107,17 @@ -- | A field id in a class type AbsFieldId = InClass FieldId --- | An interface method, which is a class in a method.+-- | An method which is from an interface newtype AbsInterfaceMethodId r = AbsInterfaceMethodId { interfaceMethodId :: InClass MethodId r } +-- | An method which can be from an interface+data AbsVariableMethodId r = AbsVariableMethodId+ { variableIsInterface :: !Bool+ , variableMethodId :: !(InClass MethodId r)+ }+ newtype MethodId = MethodId (NameAndType MethodDescriptor) deriving (Eq, Show, NFData, Ord, Generic) @@ -144,9 +151,9 @@ data MethodHandleMethod r = MHInvokeVirtual !(DeepRef AbsMethodId r)- | MHInvokeStatic !(DeepRef AbsMethodId r)+ | MHInvokeStatic !(DeepRef AbsVariableMethodId r) -- ^ Since version 52.0- | MHInvokeSpecial !(DeepRef AbsMethodId r)+ | MHInvokeSpecial !(DeepRef AbsVariableMethodId r) -- ^ Since version 52.0 | MHNewInvokeSpecial !(DeepRef AbsMethodId r) @@ -371,6 +378,21 @@ toConst s = return $ CMethodRef s ++instance Referenceable (AbsVariableMethodId High) where+ fromConst _ (CMethodRef s) = do+ return $ AbsVariableMethodId False s+ fromConst _ (CInterfaceMethodRef s) = do+ return $ AbsVariableMethodId True s+ fromConst err c = expected "CMethodRef or CInterfaceMethodRef" err c++ toConst (AbsVariableMethodId t s)+ | t =+ return $ CInterfaceMethodRef s+ | otherwise =+ return $ CMethodRef s++ instance Referenceable (InvokeDynamic High) where fromConst _ (CInvokeDynamic c) = do return $ c@@ -399,6 +421,7 @@ expected name err c = err $ wrongType name c + wrongType :: String -> Constant r -> String wrongType n c = "Expected '" ++ n ++ "', but found '" ++ typeToStr c ++ "'."@@ -420,6 +443,7 @@ $(deriveBaseWithBinary ''AbsMethodId) $(deriveBaseWithBinary ''AbsFieldId) $(deriveBaseWithBinary ''AbsInterfaceMethodId)+$(deriveBaseWithBinary ''AbsVariableMethodId) -- | A constant pool value in java data JValue
test/Language/JVM/ConstantSpec.hs view
@@ -78,6 +78,9 @@ instance Arbitrary (AbsInterfaceMethodId High) where arbitrary = genericArbitraryU +instance Arbitrary (AbsVariableMethodId High) where+ arbitrary = genericArbitraryU+ instance Arbitrary (Constant High) where arbitrary = sized $ \n -> if n < 2
test/Language/JVMSpec.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE LambdaCase #-} module Language.JVMSpec where import SpecHelper@@ -11,9 +12,18 @@ import Data.List as List import qualified Data.Text as Text +-- prelude+import System.Environment++-- filepath+import System.FilePath+ -- vector import qualified Data.Vector as V +-- zip-archive+import Codec.Archive.Zip+ import Language.JVM import qualified Language.JVM.Attribute.Code as C import Language.JVM.Attribute.StackMapTable@@ -38,6 +48,45 @@ Left msg -> fail $ show msg + describe "the standard library" $ do+ runIO (lookupEnv "JAVA_HOME") >>= \case+ Just home -> do+ Right archive <- runIO $ readZipFile (home </> "jre/lib/rt.jar")++ let priorities =+ [ "java/lang/Class.class"+ ]++ forM_ priorities $ \priority -> do+ let Just entry = findEntryByPath priority archive+ it ("can read priority " ++ priority) $ do+ case readClassFile (fromEntry entry) of+ Right _ ->+ True `shouldBe` True+ Left msg ->+ fail $ show msg++ let classes =+ filter (\entry -> takeExtension (eRelativePath entry) == ".class")+ (zEntries archive)+ forM_ classes $ \entry -> do+ it ("can read " ++ eRelativePath entry) $ do+ case readClassFile (fromEntry entry) of+ Right _ ->+ True `shouldBe` True+ Left msg ->+ fail $ show msg++ forM_ classes $ \entry -> do+ it ("can read " ++ eRelativePath entry) $ do+ case readClassFile (fromEntry entry) of+ Right _ ->+ True `shouldBe` True+ Left msg ->+ fail $ show msg+ Nothing -> do+ fail $ "Expecting JAVA_HOME to be set"+ -- spec_reading_classfile spec_reading_classfile :: Spec@@ -177,3 +226,7 @@ cmpPrefixes :: (Foldable t) => (a -> t b) -> a -> a -> ([b] -> [b] -> IO ()) -> IO () cmpPrefixes g ta tb f = forM_ (zip (inits . toList . g $ ta) (inits . toList . g $ tb)) (uncurry f)++readZipFile :: FilePath -> IO (Either String Archive)+readZipFile =+ fmap toArchiveOrFail . BL.readFile