jvm-binary 0.0.2 → 0.1.0
raw patch · 57 files changed
+4812/−1636 lines, 57 filesdep +QuickCheckdep +attoparsecdep +data-binary-ieee754dep ~basePVP ok
version bump matches the API change (PVP)
Dependencies added: QuickCheck, attoparsec, data-binary-ieee754, deepseq, deriving-compat, generic-random, hspec-expectations-pretty-diff, mtl, template-haskell
Dependency ranges changed: base
API changes (from Hackage documentation)
- Language.JVM: decodeClassFile :: ByteString -> Either String ClassFile
- Language.JVM.AccessFlag: FSynchronized :: FAccessFlag
- Language.JVM.AccessFlag: FUnused6 :: FAccessFlag
- Language.JVM.Attribute: Attribute :: !ConstantRef -> !SizedByteString32 -> Attribute
- Language.JVM.Attribute: [aInfo'] :: Attribute -> !SizedByteString32
- Language.JVM.Attribute: [aNameIndex] :: Attribute -> !ConstantRef
- Language.JVM.Attribute: aInfo :: Attribute -> ByteString
- Language.JVM.Attribute: aName :: ConstantPool -> Attribute -> Maybe Text
- Language.JVM.Attribute: attrName :: IsAttribute a => Const Text a
- Language.JVM.Attribute: class IsAttribute a where fromAttribute' cp as = do { name <- aName cp as; if name == unConst (attrName :: Const Text a) then return $ fromAttribute as else Nothing }
- Language.JVM.Attribute: codeStackMapTable :: ConstantPool -> Code -> Maybe (Either String BootstrapMethods)
- Language.JVM.Attribute: data Attribute
- Language.JVM.Attribute: data Const a b
- Language.JVM.Attribute: fromAttribute :: IsAttribute a => Attribute -> Either String a
- Language.JVM.Attribute: fromAttribute' :: IsAttribute a => ConstantPool -> Attribute -> Maybe (Either String a)
- Language.JVM.Attribute: instance Data.Binary.Class.Binary Language.JVM.Attribute.Attribute
- Language.JVM.Attribute: instance GHC.Classes.Eq Language.JVM.Attribute.Attribute
- Language.JVM.Attribute: instance GHC.Generics.Generic Language.JVM.Attribute.Attribute
- Language.JVM.Attribute: instance GHC.Show.Show Language.JVM.Attribute.Attribute
- Language.JVM.Attribute: instance Language.JVM.Attribute.IsAttribute Language.JVM.Attribute.BootstrapMethods.BootstrapMethods
- Language.JVM.Attribute: instance Language.JVM.Attribute.IsAttribute Language.JVM.Attribute.Code
- Language.JVM.Attribute: instance Language.JVM.Attribute.IsAttribute Language.JVM.Attribute.ConstantValue.ConstantValue
- Language.JVM.Attribute: instance Language.JVM.Attribute.IsAttribute Language.JVM.Attribute.Exceptions.Exceptions
- Language.JVM.Attribute: instance Language.JVM.Attribute.IsAttribute Language.JVM.Attribute.StackMapTable.StackMapTable
- Language.JVM.Attribute: type Code = Code Attribute
- Language.JVM.Attribute.BootstrapMethods: [arguments'] :: BootstrapMethod -> SizedList16 ConstantRef
- Language.JVM.Attribute.BootstrapMethods: [methodIndex] :: BootstrapMethod -> ConstantRef
- Language.JVM.Attribute.BootstrapMethods: arguments :: BootstrapMethod -> [ConstantRef]
- Language.JVM.Attribute.BootstrapMethods: data BootstrapMethods
- Language.JVM.Attribute.BootstrapMethods: instance Data.Binary.Class.Binary Language.JVM.Attribute.BootstrapMethods.BootstrapMethod
- Language.JVM.Attribute.BootstrapMethods: instance Data.Binary.Class.Binary Language.JVM.Attribute.BootstrapMethods.BootstrapMethods
- Language.JVM.Attribute.BootstrapMethods: instance GHC.Classes.Eq Language.JVM.Attribute.BootstrapMethods.BootstrapMethod
- Language.JVM.Attribute.BootstrapMethods: instance GHC.Classes.Eq Language.JVM.Attribute.BootstrapMethods.BootstrapMethods
- Language.JVM.Attribute.BootstrapMethods: instance GHC.Generics.Generic Language.JVM.Attribute.BootstrapMethods.BootstrapMethod
- Language.JVM.Attribute.BootstrapMethods: instance GHC.Generics.Generic Language.JVM.Attribute.BootstrapMethods.BootstrapMethods
- Language.JVM.Attribute.BootstrapMethods: instance GHC.Show.Show Language.JVM.Attribute.BootstrapMethods.BootstrapMethod
- Language.JVM.Attribute.BootstrapMethods: instance GHC.Show.Show Language.JVM.Attribute.BootstrapMethods.BootstrapMethods
- Language.JVM.Attribute.Code: ABoolean :: ArrayType a
- Language.JVM.Attribute.Code: AByte :: ArrayType a
- Language.JVM.Attribute.Code: AChar :: ArrayType a
- Language.JVM.Attribute.Code: ADouble :: ArrayType a
- Language.JVM.Attribute.Code: AFloat :: ArrayType a
- Language.JVM.Attribute.Code: AInt :: ArrayType a
- Language.JVM.Attribute.Code: ALong :: ArrayType a
- Language.JVM.Attribute.Code: ARef :: a -> ArrayType a
- Language.JVM.Attribute.Code: AShort :: ArrayType a
- Language.JVM.Attribute.Code: Add :: BinOpr
- Language.JVM.Attribute.Code: And :: BitOpr
- Language.JVM.Attribute.Code: ArrayLength :: ByteCodeOpr
- Language.JVM.Attribute.Code: ArrayLoad :: (ArrayType ()) -> ByteCodeOpr
- Language.JVM.Attribute.Code: ArrayStore :: (ArrayType ()) -> ByteCodeOpr
- Language.JVM.Attribute.Code: BinaryOpr :: BinOpr -> ArithmeticType -> ByteCodeOpr
- Language.JVM.Attribute.Code: BitOpr :: BitOpr -> WordSize -> ByteCodeOpr
- Language.JVM.Attribute.Code: ByteCode :: [ByteCodeInst] -> ByteCode
- Language.JVM.Attribute.Code: ByteCodeInst :: LongOffset -> ByteCodeOpr -> ByteCodeInst
- Language.JVM.Attribute.Code: CByte :: Int8 -> Constant
- Language.JVM.Attribute.Code: CDouble0 :: Constant
- Language.JVM.Attribute.Code: CDouble1 :: Constant
- Language.JVM.Attribute.Code: CEq :: CmpOpr
- Language.JVM.Attribute.Code: CFloat0 :: Constant
- Language.JVM.Attribute.Code: CFloat1 :: Constant
- Language.JVM.Attribute.Code: CFloat2 :: Constant
- Language.JVM.Attribute.Code: CGe :: CmpOpr
- Language.JVM.Attribute.Code: CGt :: CmpOpr
- Language.JVM.Attribute.Code: CHalfRef :: ConstantRef -> Constant
- Language.JVM.Attribute.Code: CInt0 :: Constant
- Language.JVM.Attribute.Code: CInt1 :: Constant
- Language.JVM.Attribute.Code: CInt2 :: Constant
- Language.JVM.Attribute.Code: CInt3 :: Constant
- Language.JVM.Attribute.Code: CInt4 :: Constant
- Language.JVM.Attribute.Code: CInt5 :: Constant
- Language.JVM.Attribute.Code: CIntM1 :: Constant
- Language.JVM.Attribute.Code: CLe :: CmpOpr
- Language.JVM.Attribute.Code: CLong0 :: Constant
- Language.JVM.Attribute.Code: CLong1 :: Constant
- Language.JVM.Attribute.Code: CLt :: CmpOpr
- Language.JVM.Attribute.Code: CNe :: CmpOpr
- Language.JVM.Attribute.Code: CNull :: Constant
- Language.JVM.Attribute.Code: CRef :: WordSize -> ConstantRef -> Constant
- Language.JVM.Attribute.Code: CShort :: Int16 -> Constant
- Language.JVM.Attribute.Code: Cast :: ArithmeticType -> ArithmeticType -> ByteCodeOpr
- Language.JVM.Attribute.Code: CastDown :: SmallArithmeticType -> ByteCodeOpr
- Language.JVM.Attribute.Code: CheckCast :: ConstantRef -> ByteCodeOpr
- Language.JVM.Attribute.Code: CompareFloating :: Bool -> WordSize -> ByteCodeOpr
- Language.JVM.Attribute.Code: CompareLongs :: ByteCodeOpr
- Language.JVM.Attribute.Code: Div :: BinOpr
- Language.JVM.Attribute.Code: Dup :: WordSize -> ByteCodeOpr
- Language.JVM.Attribute.Code: DupX1 :: WordSize -> ByteCodeOpr
- Language.JVM.Attribute.Code: DupX2 :: WordSize -> ByteCodeOpr
- Language.JVM.Attribute.Code: FldField :: FieldAccess
- Language.JVM.Attribute.Code: FldStatic :: FieldAccess
- Language.JVM.Attribute.Code: Get :: FieldAccess -> ConstantRef -> ByteCodeOpr
- Language.JVM.Attribute.Code: Goto :: LongOffset -> ByteCodeOpr
- Language.JVM.Attribute.Code: ISingle :: Int8 -> IncrementAmount
- Language.JVM.Attribute.Code: IWide :: Int16 -> IncrementAmount
- Language.JVM.Attribute.Code: If :: CmpOpr -> OneOrTwo -> Offset -> ByteCodeOpr
- Language.JVM.Attribute.Code: IfRef :: Bool -> OneOrTwo -> Offset -> ByteCodeOpr
- Language.JVM.Attribute.Code: IncrLocal :: !LocalAddress -> !IncrementAmount -> ByteCodeOpr
- Language.JVM.Attribute.Code: InstanceOf :: ConstantRef -> ByteCodeOpr
- Language.JVM.Attribute.Code: InvkDynamic :: Invokation
- Language.JVM.Attribute.Code: InvkInterface :: Word8 -> Invokation
- Language.JVM.Attribute.Code: InvkSpecial :: Invokation
- Language.JVM.Attribute.Code: InvkStatic :: Invokation
- Language.JVM.Attribute.Code: InvkVirtual :: Invokation
- Language.JVM.Attribute.Code: Invoke :: Invokation -> ConstantRef -> ByteCodeOpr
- Language.JVM.Attribute.Code: Jsr :: LongOffset -> ByteCodeOpr
- Language.JVM.Attribute.Code: LDouble :: LocalType
- Language.JVM.Attribute.Code: LFloat :: LocalType
- Language.JVM.Attribute.Code: LInt :: LocalType
- Language.JVM.Attribute.Code: LLong :: LocalType
- Language.JVM.Attribute.Code: LRef :: LocalType
- Language.JVM.Attribute.Code: LSingle :: Word8 -> LocalAddress
- Language.JVM.Attribute.Code: LWide :: Word16 -> LocalAddress
- Language.JVM.Attribute.Code: Load :: LocalType -> LocalAddress -> ByteCodeOpr
- Language.JVM.Attribute.Code: LookupSwitch :: Int32 -> (Vector (Int32, Int32)) -> ByteCodeOpr
- Language.JVM.Attribute.Code: MByte :: SmallArithmeticType
- Language.JVM.Attribute.Code: MChar :: SmallArithmeticType
- Language.JVM.Attribute.Code: MDouble :: ArithmeticType
- Language.JVM.Attribute.Code: MFloat :: ArithmeticType
- Language.JVM.Attribute.Code: MInt :: ArithmeticType
- Language.JVM.Attribute.Code: MLong :: ArithmeticType
- Language.JVM.Attribute.Code: MShort :: SmallArithmeticType
- Language.JVM.Attribute.Code: Monitor :: Bool -> ByteCodeOpr
- Language.JVM.Attribute.Code: Mul :: BinOpr
- Language.JVM.Attribute.Code: MultiNewArray :: ConstantRef -> Word8 -> ByteCodeOpr
- Language.JVM.Attribute.Code: Neg :: ArithmeticType -> ByteCodeOpr
- Language.JVM.Attribute.Code: New :: ConstantRef -> ByteCodeOpr
- Language.JVM.Attribute.Code: NewArray :: (ArrayType ConstantRef) -> ByteCodeOpr
- Language.JVM.Attribute.Code: Nop :: ByteCodeOpr
- Language.JVM.Attribute.Code: One :: OneOrTwo
- Language.JVM.Attribute.Code: Or :: BitOpr
- Language.JVM.Attribute.Code: Pop :: WordSize -> ByteCodeOpr
- Language.JVM.Attribute.Code: Push :: Constant -> ByteCodeOpr
- Language.JVM.Attribute.Code: Put :: FieldAccess -> ConstantRef -> ByteCodeOpr
- Language.JVM.Attribute.Code: Rem :: BinOpr
- Language.JVM.Attribute.Code: Ret :: LocalAddress -> ByteCodeOpr
- Language.JVM.Attribute.Code: Return :: (Maybe LocalType) -> ByteCodeOpr
- Language.JVM.Attribute.Code: ShL :: BitOpr
- Language.JVM.Attribute.Code: ShR :: BitOpr
- Language.JVM.Attribute.Code: Store :: LocalType -> LocalAddress -> ByteCodeOpr
- Language.JVM.Attribute.Code: Sub :: BinOpr
- Language.JVM.Attribute.Code: Swap :: ByteCodeOpr
- Language.JVM.Attribute.Code: TableSwitch :: Int32 -> Int32 -> Int32 -> (Vector Int32) -> ByteCodeOpr
- Language.JVM.Attribute.Code: Throw :: ByteCodeOpr
- Language.JVM.Attribute.Code: Two :: OneOrTwo
- Language.JVM.Attribute.Code: UShR :: BitOpr
- Language.JVM.Attribute.Code: XOr :: BitOpr
- Language.JVM.Attribute.Code: [attributes] :: Code a -> SizedList16 a
- Language.JVM.Attribute.Code: [bytecode] :: Code a -> ByteCode
- Language.JVM.Attribute.Code: [exceptionTable] :: Code a -> SizedList16 ExceptionTable
- Language.JVM.Attribute.Code: [maxLocals] :: Code a -> Int16
- Language.JVM.Attribute.Code: [maxStack] :: Code a -> Int16
- Language.JVM.Attribute.Code: [offset] :: ByteCodeInst -> LongOffset
- Language.JVM.Attribute.Code: [opcode] :: ByteCodeInst -> ByteCodeOpr
- Language.JVM.Attribute.Code: [unByteCode] :: ByteCode -> [ByteCodeInst]
- Language.JVM.Attribute.Code: data ArithmeticType
- Language.JVM.Attribute.Code: data ArrayType a
- Language.JVM.Attribute.Code: data BinOpr
- Language.JVM.Attribute.Code: data BitOpr
- Language.JVM.Attribute.Code: data ByteCodeInst
- Language.JVM.Attribute.Code: data ByteCodeOpr
- Language.JVM.Attribute.Code: data CmpOpr
- Language.JVM.Attribute.Code: data Constant
- Language.JVM.Attribute.Code: data FieldAccess
- Language.JVM.Attribute.Code: data IncrementAmount
- Language.JVM.Attribute.Code: data Invokation
- Language.JVM.Attribute.Code: data LocalAddress
- Language.JVM.Attribute.Code: data LocalType
- Language.JVM.Attribute.Code: data OneOrTwo
- Language.JVM.Attribute.Code: data SmallArithmeticType
- Language.JVM.Attribute.Code: instance Data.Binary.Class.Binary Language.JVM.Attribute.Code.ByteCode
- Language.JVM.Attribute.Code: instance Data.Binary.Class.Binary Language.JVM.Attribute.Code.ByteCodeInst
- Language.JVM.Attribute.Code: instance Data.Binary.Class.Binary Language.JVM.Attribute.Code.ByteCodeOpr
- Language.JVM.Attribute.Code: instance Data.Binary.Class.Binary Language.JVM.Attribute.Code.ExceptionTable
- Language.JVM.Attribute.Code: instance Data.Binary.Class.Binary a => Data.Binary.Class.Binary (Language.JVM.Attribute.Code.Code a)
- Language.JVM.Attribute.Code: instance GHC.Classes.Eq Language.JVM.Attribute.Code.ArithmeticType
- Language.JVM.Attribute.Code: instance GHC.Classes.Eq Language.JVM.Attribute.Code.BinOpr
- Language.JVM.Attribute.Code: instance GHC.Classes.Eq Language.JVM.Attribute.Code.BitOpr
- Language.JVM.Attribute.Code: instance GHC.Classes.Eq Language.JVM.Attribute.Code.ByteCode
- Language.JVM.Attribute.Code: instance GHC.Classes.Eq Language.JVM.Attribute.Code.ByteCodeInst
- Language.JVM.Attribute.Code: instance GHC.Classes.Eq Language.JVM.Attribute.Code.ByteCodeOpr
- Language.JVM.Attribute.Code: instance GHC.Classes.Eq Language.JVM.Attribute.Code.CmpOpr
- Language.JVM.Attribute.Code: instance GHC.Classes.Eq Language.JVM.Attribute.Code.Constant
- Language.JVM.Attribute.Code: instance GHC.Classes.Eq Language.JVM.Attribute.Code.ExceptionTable
- Language.JVM.Attribute.Code: instance GHC.Classes.Eq Language.JVM.Attribute.Code.FieldAccess
- Language.JVM.Attribute.Code: instance GHC.Classes.Eq Language.JVM.Attribute.Code.IncrementAmount
- Language.JVM.Attribute.Code: instance GHC.Classes.Eq Language.JVM.Attribute.Code.Invokation
- Language.JVM.Attribute.Code: instance GHC.Classes.Eq Language.JVM.Attribute.Code.LocalAddress
- Language.JVM.Attribute.Code: instance GHC.Classes.Eq Language.JVM.Attribute.Code.LocalType
- Language.JVM.Attribute.Code: instance GHC.Classes.Eq Language.JVM.Attribute.Code.OneOrTwo
- Language.JVM.Attribute.Code: instance GHC.Classes.Eq Language.JVM.Attribute.Code.SmallArithmeticType
- Language.JVM.Attribute.Code: instance GHC.Classes.Eq a => GHC.Classes.Eq (Language.JVM.Attribute.Code.ArrayType a)
- Language.JVM.Attribute.Code: instance GHC.Classes.Eq a => GHC.Classes.Eq (Language.JVM.Attribute.Code.Code a)
- Language.JVM.Attribute.Code: instance GHC.Classes.Ord Language.JVM.Attribute.Code.OneOrTwo
- Language.JVM.Attribute.Code: instance GHC.Enum.Bounded Language.JVM.Attribute.Code.ArithmeticType
- Language.JVM.Attribute.Code: instance GHC.Enum.Bounded Language.JVM.Attribute.Code.LocalType
- Language.JVM.Attribute.Code: instance GHC.Enum.Bounded Language.JVM.Attribute.Code.OneOrTwo
- Language.JVM.Attribute.Code: instance GHC.Enum.Bounded Language.JVM.Attribute.Code.SmallArithmeticType
- Language.JVM.Attribute.Code: instance GHC.Enum.Enum Language.JVM.Attribute.Code.ArithmeticType
- Language.JVM.Attribute.Code: instance GHC.Enum.Enum Language.JVM.Attribute.Code.LocalType
- Language.JVM.Attribute.Code: instance GHC.Enum.Enum Language.JVM.Attribute.Code.OneOrTwo
- Language.JVM.Attribute.Code: instance GHC.Enum.Enum Language.JVM.Attribute.Code.SmallArithmeticType
- Language.JVM.Attribute.Code: instance GHC.Generics.Generic (Language.JVM.Attribute.Code.Code a)
- Language.JVM.Attribute.Code: instance GHC.Generics.Generic Language.JVM.Attribute.Code.ByteCodeInst
- Language.JVM.Attribute.Code: instance GHC.Generics.Generic Language.JVM.Attribute.Code.ExceptionTable
- Language.JVM.Attribute.Code: instance GHC.Show.Show Language.JVM.Attribute.Code.ArithmeticType
- Language.JVM.Attribute.Code: instance GHC.Show.Show Language.JVM.Attribute.Code.BinOpr
- Language.JVM.Attribute.Code: instance GHC.Show.Show Language.JVM.Attribute.Code.BitOpr
- Language.JVM.Attribute.Code: instance GHC.Show.Show Language.JVM.Attribute.Code.ByteCode
- Language.JVM.Attribute.Code: instance GHC.Show.Show Language.JVM.Attribute.Code.ByteCodeInst
- Language.JVM.Attribute.Code: instance GHC.Show.Show Language.JVM.Attribute.Code.ByteCodeOpr
- Language.JVM.Attribute.Code: instance GHC.Show.Show Language.JVM.Attribute.Code.CmpOpr
- Language.JVM.Attribute.Code: instance GHC.Show.Show Language.JVM.Attribute.Code.Constant
- Language.JVM.Attribute.Code: instance GHC.Show.Show Language.JVM.Attribute.Code.ExceptionTable
- Language.JVM.Attribute.Code: instance GHC.Show.Show Language.JVM.Attribute.Code.FieldAccess
- Language.JVM.Attribute.Code: instance GHC.Show.Show Language.JVM.Attribute.Code.IncrementAmount
- Language.JVM.Attribute.Code: instance GHC.Show.Show Language.JVM.Attribute.Code.Invokation
- Language.JVM.Attribute.Code: instance GHC.Show.Show Language.JVM.Attribute.Code.LocalAddress
- Language.JVM.Attribute.Code: instance GHC.Show.Show Language.JVM.Attribute.Code.LocalType
- Language.JVM.Attribute.Code: instance GHC.Show.Show Language.JVM.Attribute.Code.OneOrTwo
- Language.JVM.Attribute.Code: instance GHC.Show.Show Language.JVM.Attribute.Code.SmallArithmeticType
- Language.JVM.Attribute.Code: instance GHC.Show.Show a => GHC.Show.Show (Language.JVM.Attribute.Code.ArrayType a)
- Language.JVM.Attribute.Code: instance GHC.Show.Show a => GHC.Show.Show (Language.JVM.Attribute.Code.Code a)
- Language.JVM.Attribute.Code: newtype ByteCode
- Language.JVM.Attribute.Code: type LongOffset = Int32
- Language.JVM.Attribute.Code: type Offset = Int16
- Language.JVM.Attribute.Code: type WordSize = OneOrTwo
- Language.JVM.Attribute.ConstantValue: [constantValueIndex] :: ConstantValue -> !ConstantRef
- Language.JVM.Attribute.ConstantValue: instance Data.Binary.Class.Binary Language.JVM.Attribute.ConstantValue.ConstantValue
- Language.JVM.Attribute.ConstantValue: instance GHC.Classes.Eq Language.JVM.Attribute.ConstantValue.ConstantValue
- Language.JVM.Attribute.ConstantValue: instance GHC.Generics.Generic Language.JVM.Attribute.ConstantValue.ConstantValue
- Language.JVM.Attribute.ConstantValue: instance GHC.Show.Show Language.JVM.Attribute.ConstantValue.ConstantValue
- Language.JVM.Attribute.Exceptions: [exceptionIndexTable'] :: Exceptions -> SizedList16 ConstantRef
- Language.JVM.Attribute.Exceptions: data Exceptions
- Language.JVM.Attribute.Exceptions: exceptionIndexTable :: Exceptions -> [ConstantRef]
- Language.JVM.Attribute.Exceptions: instance Data.Binary.Class.Binary Language.JVM.Attribute.Exceptions.Exceptions
- Language.JVM.Attribute.Exceptions: instance GHC.Classes.Eq Language.JVM.Attribute.Exceptions.Exceptions
- Language.JVM.Attribute.Exceptions: instance GHC.Generics.Generic Language.JVM.Attribute.Exceptions.Exceptions
- Language.JVM.Attribute.Exceptions: instance GHC.Show.Show Language.JVM.Attribute.Exceptions.Exceptions
- Language.JVM.Attribute.StackMapTable: VDouble :: VerificationTypeInfo
- Language.JVM.Attribute.StackMapTable: VFloat :: VerificationTypeInfo
- Language.JVM.Attribute.StackMapTable: VInteger :: VerificationTypeInfo
- Language.JVM.Attribute.StackMapTable: VLong :: VerificationTypeInfo
- Language.JVM.Attribute.StackMapTable: VNull :: VerificationTypeInfo
- Language.JVM.Attribute.StackMapTable: VObject :: !ConstantRef -> VerificationTypeInfo
- Language.JVM.Attribute.StackMapTable: VTop :: VerificationTypeInfo
- Language.JVM.Attribute.StackMapTable: VUninitialized :: !Word16 -> VerificationTypeInfo
- Language.JVM.Attribute.StackMapTable: VUninitializedThis :: VerificationTypeInfo
- Language.JVM.Attribute.StackMapTable: data StackMapTable
- Language.JVM.Attribute.StackMapTable: instance Data.Binary.Class.Binary Language.JVM.Attribute.StackMapTable.StackMapFrame
- Language.JVM.Attribute.StackMapTable: instance Data.Binary.Class.Binary Language.JVM.Attribute.StackMapTable.StackMapTable
- Language.JVM.Attribute.StackMapTable: instance Data.Binary.Class.Binary Language.JVM.Attribute.StackMapTable.VerificationTypeInfo
- Language.JVM.Attribute.StackMapTable: instance GHC.Classes.Eq Language.JVM.Attribute.StackMapTable.StackMapFrame
- Language.JVM.Attribute.StackMapTable: instance GHC.Classes.Eq Language.JVM.Attribute.StackMapTable.StackMapFrameType
- Language.JVM.Attribute.StackMapTable: instance GHC.Classes.Eq Language.JVM.Attribute.StackMapTable.StackMapTable
- Language.JVM.Attribute.StackMapTable: instance GHC.Classes.Eq Language.JVM.Attribute.StackMapTable.VerificationTypeInfo
- Language.JVM.Attribute.StackMapTable: instance GHC.Generics.Generic Language.JVM.Attribute.StackMapTable.StackMapTable
- Language.JVM.Attribute.StackMapTable: instance GHC.Show.Show Language.JVM.Attribute.StackMapTable.StackMapFrame
- Language.JVM.Attribute.StackMapTable: instance GHC.Show.Show Language.JVM.Attribute.StackMapTable.StackMapFrameType
- Language.JVM.Attribute.StackMapTable: instance GHC.Show.Show Language.JVM.Attribute.StackMapTable.StackMapTable
- Language.JVM.Attribute.StackMapTable: instance GHC.Show.Show Language.JVM.Attribute.StackMapTable.VerificationTypeInfo
- Language.JVM.ClassFile: [cAccessFlags] :: ClassFile -> BitSet16 CAccessFlag
- Language.JVM.ClassFile: [cAttributes'] :: ClassFile -> SizedList16 Attribute
- Language.JVM.ClassFile: [cInterfaces'] :: ClassFile -> SizedList16 ConstantRef
- Language.JVM.ClassFile: [cSuperClassIndex] :: ClassFile -> !ConstantRef
- Language.JVM.ClassFile: [cThisClassIndex] :: ClassFile -> !ConstantRef
- Language.JVM.ClassFile: cAttributes :: ClassFile -> [Attribute]
- Language.JVM.ClassFile: cInterfaces :: ClassFile -> [ConstantRef]
- Language.JVM.ClassFile: cSuperClass :: ConstantPool -> ClassFile -> Maybe Text
- Language.JVM.ClassFile: cThisClass :: ConstantPool -> ClassFile -> Maybe Text
- Language.JVM.ClassFile: instance Data.Binary.Class.Binary Language.JVM.ClassFile.ClassFile
- Language.JVM.ClassFile: instance GHC.Classes.Eq Language.JVM.ClassFile.ClassFile
- Language.JVM.ClassFile: instance GHC.Generics.Generic Language.JVM.ClassFile.ClassFile
- Language.JVM.ClassFile: instance GHC.Show.Show Language.JVM.ClassFile.ClassFile
- Language.JVM.Constant: ClassRef :: !ConstantRef -> Constant
- Language.JVM.Constant: ConstantPool :: IntMap Constant -> ConstantPool
- Language.JVM.Constant: ConstantRef :: Word16 -> ConstantRef
- Language.JVM.Constant: Double :: !Word64 -> Constant
- Language.JVM.Constant: FieldRef :: !ConstantRef -> !ConstantRef -> Constant
- Language.JVM.Constant: Float :: !Word32 -> Constant
- Language.JVM.Constant: Integer :: !Word32 -> Constant
- Language.JVM.Constant: InterfaceMethodRef :: !ConstantRef -> !ConstantRef -> Constant
- Language.JVM.Constant: Long :: !Word64 -> Constant
- Language.JVM.Constant: MethodHandle :: !Word8 -> !ConstantRef -> Constant
- Language.JVM.Constant: MethodRef :: !ConstantRef -> !ConstantRef -> Constant
- Language.JVM.Constant: MethodType :: !ConstantRef -> Constant
- Language.JVM.Constant: String :: !SizedByteString16 -> Constant
- Language.JVM.Constant: StringRef :: !ConstantRef -> Constant
- Language.JVM.Constant: [unConstantPool] :: ConstantPool -> IntMap Constant
- Language.JVM.Constant: instance Data.Binary.Class.Binary Language.JVM.Constant.Constant
- Language.JVM.Constant: instance Data.Binary.Class.Binary Language.JVM.Constant.ConstantPool
- Language.JVM.Constant: instance Data.Binary.Class.Binary Language.JVM.Constant.ConstantRef
- Language.JVM.Constant: instance GHC.Classes.Eq Language.JVM.Constant.Constant
- Language.JVM.Constant: instance GHC.Classes.Eq Language.JVM.Constant.ConstantPool
- Language.JVM.Constant: instance GHC.Classes.Eq Language.JVM.Constant.ConstantRef
- Language.JVM.Constant: instance GHC.Generics.Generic Language.JVM.Constant.ConstantRef
- Language.JVM.Constant: instance GHC.Show.Show Language.JVM.Constant.Constant
- Language.JVM.Constant: instance GHC.Show.Show Language.JVM.Constant.ConstantPool
- Language.JVM.Constant: instance GHC.Show.Show Language.JVM.Constant.ConstantRef
- Language.JVM.Constant: lookupClassName :: ConstantRef -> ConstantPool -> Maybe Text
- Language.JVM.Constant: lookupConstant :: ConstantRef -> ConstantPool -> Maybe Constant
- Language.JVM.Constant: lookupText :: ConstantRef -> ConstantPool -> Maybe Text
- Language.JVM.Constant: newtype ConstantPool
- Language.JVM.Constant: newtype ConstantRef
- Language.JVM.Constant: toListOfConstants :: ConstantPool -> [(ConstantRef, Constant)]
- Language.JVM.Field: [fAccessFlags] :: Field -> BitSet16 FAccessFlag
- Language.JVM.Field: [fDescriptorIndex] :: Field -> !ConstantRef
- Language.JVM.Field: [fNameIndex] :: Field -> !ConstantRef
- Language.JVM.Field: instance Data.Binary.Class.Binary Language.JVM.Field.Field
- Language.JVM.Field: instance GHC.Classes.Eq Language.JVM.Field.Field
- Language.JVM.Field: instance GHC.Generics.Generic Language.JVM.Field.Field
- Language.JVM.Field: instance GHC.Show.Show Language.JVM.Field.Field
- Language.JVM.Method: [mAttributes'] :: Method -> SizedList16 Attribute
- Language.JVM.Method: [mDescriptorIndex] :: Method -> !ConstantRef
- Language.JVM.Method: [mNameIndex] :: Method -> !ConstantRef
- Language.JVM.Method: instance Data.Binary.Class.Binary Language.JVM.Method.Method
- Language.JVM.Method: instance GHC.Classes.Eq Language.JVM.Method.Method
- Language.JVM.Method: instance GHC.Generics.Generic Language.JVM.Method.Method
- Language.JVM.Method: instance GHC.Show.Show Language.JVM.Method.Method
- Language.JVM.Method: mAttributes :: Method -> [Attribute]
- Language.JVM.Method: mDescriptor :: ConstantPool -> Method -> Maybe Text
- Language.JVM.Method: mName :: ConstantPool -> Method -> Maybe Text
- Language.JVM.Utils: instance (Data.Bits.Bits w, Data.Binary.Class.Binary w, Language.JVM.Utils.Enumish a) => Data.Binary.Class.Binary (Language.JVM.Utils.BitSet w a)
+ Language.JVM.AccessFlag: CInterface :: CAccessFlag
+ Language.JVM.AccessFlag: CModule :: CAccessFlag
+ Language.JVM.AccessFlag: instance Control.DeepSeq.NFData Language.JVM.AccessFlag.CAccessFlag
+ Language.JVM.AccessFlag: instance Control.DeepSeq.NFData Language.JVM.AccessFlag.FAccessFlag
+ Language.JVM.AccessFlag: instance Control.DeepSeq.NFData Language.JVM.AccessFlag.MAccessFlag
+ Language.JVM.AccessFlag: instance GHC.Generics.Generic Language.JVM.AccessFlag.CAccessFlag
+ Language.JVM.AccessFlag: instance GHC.Generics.Generic Language.JVM.AccessFlag.FAccessFlag
+ Language.JVM.AccessFlag: instance GHC.Generics.Generic Language.JVM.AccessFlag.MAccessFlag
+ Language.JVM.Attribute: data Code r
+ Language.JVM.Attribute: data LineNumberTable r
+ Language.JVM.Attribute: data Signature a
+ Language.JVM.Attribute.Base: Attribute :: !(Ref Text r) -> !(SizedByteString32) -> Attribute r
+ Language.JVM.Attribute.Base: Const :: a -> Const a b
+ Language.JVM.Attribute.Base: [aInfo'] :: Attribute r -> !(SizedByteString32)
+ Language.JVM.Attribute.Base: [aName] :: Attribute r -> !(Ref Text r)
+ Language.JVM.Attribute.Base: [unConst] :: Const a b -> a
+ Language.JVM.Attribute.Base: aInfo :: Attribute r -> ByteString
+ Language.JVM.Attribute.Base: attrName :: IsAttribute a => Const Text a
+ Language.JVM.Attribute.Base: class (Binary a) => IsAttribute a
+ Language.JVM.Attribute.Base: collect :: (Monad m) => c -> Attribute High -> [Attribute High -> Maybe (m c)] -> m c
+ Language.JVM.Attribute.Base: data Attribute r
+ Language.JVM.Attribute.Base: devolveAttribute :: (IsAttribute (a Low), DevolveM m) => (a High -> m (a Low)) -> a High -> m (Attribute Low)
+ Language.JVM.Attribute.Base: firstOne :: [a] -> Maybe a
+ Language.JVM.Attribute.Base: fromAttribute' :: IsAttribute a => Attribute r -> Either String a
+ Language.JVM.Attribute.Base: fromAttributes :: (Foldable f, EvolveM m, Monoid a) => (Attribute High -> m a) -> f (Attribute Low) -> m a
+ Language.JVM.Attribute.Base: instance Control.DeepSeq.NFData (Language.JVM.Attribute.Base.Attribute Language.JVM.Stage.High)
+ Language.JVM.Attribute.Base: instance Control.DeepSeq.NFData (Language.JVM.Attribute.Base.Attribute Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Base: instance Data.Binary.Class.Binary (Language.JVM.Attribute.Base.Attribute Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Base: instance GHC.Classes.Eq (Language.JVM.Attribute.Base.Attribute Language.JVM.Stage.High)
+ Language.JVM.Attribute.Base: instance GHC.Classes.Eq (Language.JVM.Attribute.Base.Attribute Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Base: instance GHC.Classes.Ord (Language.JVM.Attribute.Base.Attribute Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Base: instance GHC.Generics.Generic (Language.JVM.Attribute.Base.Attribute Language.JVM.Stage.High)
+ Language.JVM.Attribute.Base: instance GHC.Generics.Generic (Language.JVM.Attribute.Base.Attribute Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Base: instance GHC.Show.Show (Language.JVM.Attribute.Base.Attribute Language.JVM.Stage.High)
+ Language.JVM.Attribute.Base: instance GHC.Show.Show (Language.JVM.Attribute.Base.Attribute Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Base: instance Language.JVM.Staged.Staged Language.JVM.Attribute.Base.Attribute
+ Language.JVM.Attribute.Base: newtype Const a b
+ Language.JVM.Attribute.Base: toAttribute :: (IsAttribute (a Low), Staged a, DevolveM m) => a High -> m (Attribute Low)
+ Language.JVM.Attribute.Base: toAttribute' :: forall a. IsAttribute a => a -> Attribute High
+ Language.JVM.Attribute.Base: toC :: (EvolveM m, Staged a, IsAttribute (a Low)) => (a High -> c) -> Attribute High -> Maybe (m c)
+ Language.JVM.Attribute.Base: toC' :: (EvolveM m, IsAttribute (a Low)) => (a Low -> m (a High)) -> (a High -> c) -> Attribute High -> Maybe (m c)
+ Language.JVM.Attribute.Base: type Attributes b r = Choice (SizedList16 (Attribute r)) (b r) r
+ Language.JVM.Attribute.BootstrapMethods: [arguments] :: BootstrapMethod r -> !(SizedList16 (Ref JValue r))
+ Language.JVM.Attribute.BootstrapMethods: [method] :: BootstrapMethod r -> !(DeepRef MethodHandle r)
+ Language.JVM.Attribute.BootstrapMethods: instance Control.DeepSeq.NFData (Language.JVM.Attribute.BootstrapMethods.BootstrapMethod Language.JVM.Stage.High)
+ Language.JVM.Attribute.BootstrapMethods: instance Control.DeepSeq.NFData (Language.JVM.Attribute.BootstrapMethods.BootstrapMethod Language.JVM.Stage.Low)
+ Language.JVM.Attribute.BootstrapMethods: instance Control.DeepSeq.NFData (Language.JVM.Attribute.BootstrapMethods.BootstrapMethods Language.JVM.Stage.High)
+ Language.JVM.Attribute.BootstrapMethods: instance Control.DeepSeq.NFData (Language.JVM.Attribute.BootstrapMethods.BootstrapMethods Language.JVM.Stage.Low)
+ Language.JVM.Attribute.BootstrapMethods: instance Data.Binary.Class.Binary (Language.JVM.Attribute.BootstrapMethods.BootstrapMethod Language.JVM.Stage.Low)
+ Language.JVM.Attribute.BootstrapMethods: instance Data.Binary.Class.Binary (Language.JVM.Attribute.BootstrapMethods.BootstrapMethods Language.JVM.Stage.Low)
+ Language.JVM.Attribute.BootstrapMethods: instance GHC.Classes.Eq (Language.JVM.Attribute.BootstrapMethods.BootstrapMethod Language.JVM.Stage.High)
+ Language.JVM.Attribute.BootstrapMethods: instance GHC.Classes.Eq (Language.JVM.Attribute.BootstrapMethods.BootstrapMethod Language.JVM.Stage.Low)
+ Language.JVM.Attribute.BootstrapMethods: instance GHC.Classes.Eq (Language.JVM.Attribute.BootstrapMethods.BootstrapMethods Language.JVM.Stage.High)
+ Language.JVM.Attribute.BootstrapMethods: instance GHC.Classes.Eq (Language.JVM.Attribute.BootstrapMethods.BootstrapMethods Language.JVM.Stage.Low)
+ Language.JVM.Attribute.BootstrapMethods: instance GHC.Classes.Ord (Language.JVM.Attribute.BootstrapMethods.BootstrapMethod Language.JVM.Stage.Low)
+ Language.JVM.Attribute.BootstrapMethods: instance GHC.Classes.Ord (Language.JVM.Attribute.BootstrapMethods.BootstrapMethods Language.JVM.Stage.Low)
+ Language.JVM.Attribute.BootstrapMethods: instance GHC.Generics.Generic (Language.JVM.Attribute.BootstrapMethods.BootstrapMethod Language.JVM.Stage.High)
+ Language.JVM.Attribute.BootstrapMethods: instance GHC.Generics.Generic (Language.JVM.Attribute.BootstrapMethods.BootstrapMethod Language.JVM.Stage.Low)
+ Language.JVM.Attribute.BootstrapMethods: instance GHC.Generics.Generic (Language.JVM.Attribute.BootstrapMethods.BootstrapMethods Language.JVM.Stage.High)
+ Language.JVM.Attribute.BootstrapMethods: instance GHC.Generics.Generic (Language.JVM.Attribute.BootstrapMethods.BootstrapMethods Language.JVM.Stage.Low)
+ Language.JVM.Attribute.BootstrapMethods: instance GHC.Show.Show (Language.JVM.Attribute.BootstrapMethods.BootstrapMethod Language.JVM.Stage.High)
+ Language.JVM.Attribute.BootstrapMethods: instance GHC.Show.Show (Language.JVM.Attribute.BootstrapMethods.BootstrapMethod Language.JVM.Stage.Low)
+ Language.JVM.Attribute.BootstrapMethods: instance GHC.Show.Show (Language.JVM.Attribute.BootstrapMethods.BootstrapMethods Language.JVM.Stage.High)
+ Language.JVM.Attribute.BootstrapMethods: instance GHC.Show.Show (Language.JVM.Attribute.BootstrapMethods.BootstrapMethods Language.JVM.Stage.Low)
+ Language.JVM.Attribute.BootstrapMethods: instance Language.JVM.Attribute.Base.IsAttribute (Language.JVM.Attribute.BootstrapMethods.BootstrapMethods Language.JVM.Stage.Low)
+ Language.JVM.Attribute.BootstrapMethods: instance Language.JVM.Staged.Staged Language.JVM.Attribute.BootstrapMethods.BootstrapMethod
+ Language.JVM.Attribute.BootstrapMethods: instance Language.JVM.Staged.Staged Language.JVM.Attribute.BootstrapMethods.BootstrapMethods
+ Language.JVM.Attribute.BootstrapMethods: newtype BootstrapMethods r
+ Language.JVM.Attribute.Code: CodeAttributes :: [StackMapTable r] -> [LineNumberTable r] -> [Attribute r] -> CodeAttributes r
+ Language.JVM.Attribute.Code: [caLineNumberTable] :: CodeAttributes r -> [LineNumberTable r]
+ Language.JVM.Attribute.Code: [caOthers] :: CodeAttributes r -> [Attribute r]
+ Language.JVM.Attribute.Code: [caStackMapTable] :: CodeAttributes r -> [StackMapTable r]
+ Language.JVM.Attribute.Code: [codeAttributes] :: Code r -> !(Attributes CodeAttributes r)
+ Language.JVM.Attribute.Code: [codeByteCode] :: Code r -> !((ByteCode r))
+ Language.JVM.Attribute.Code: [codeExceptionTable] :: Code r -> !(SizedList16 (ExceptionTable r))
+ Language.JVM.Attribute.Code: [codeMaxLocals] :: Code r -> !(Word16)
+ Language.JVM.Attribute.Code: [codeMaxStack] :: Code r -> !(Word16)
+ Language.JVM.Attribute.Code: codeByteCodeInsts :: Code Low -> Vector (ByteCodeInst Low)
+ Language.JVM.Attribute.Code: codeByteCodeOprs :: Code High -> Vector (ByteCodeOpr High)
+ Language.JVM.Attribute.Code: codeStackMapTable :: Code High -> Maybe (StackMapTable High)
+ Language.JVM.Attribute.Code: data CodeAttributes r
+ Language.JVM.Attribute.Code: instance Control.DeepSeq.NFData (Language.JVM.Attribute.Code.Code Language.JVM.Stage.High)
+ Language.JVM.Attribute.Code: instance Control.DeepSeq.NFData (Language.JVM.Attribute.Code.Code Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Code: instance Control.DeepSeq.NFData (Language.JVM.Attribute.Code.CodeAttributes Language.JVM.Stage.High)
+ Language.JVM.Attribute.Code: instance Control.DeepSeq.NFData (Language.JVM.Attribute.Code.CodeAttributes Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Code: instance Control.DeepSeq.NFData (Language.JVM.Attribute.Code.ExceptionTable Language.JVM.Stage.High)
+ Language.JVM.Attribute.Code: instance Control.DeepSeq.NFData (Language.JVM.Attribute.Code.ExceptionTable Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Code: instance Data.Binary.Class.Binary (Language.JVM.Attribute.Code.Code Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Code: instance Data.Binary.Class.Binary (Language.JVM.Attribute.Code.ExceptionTable Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Code: instance GHC.Classes.Eq (Language.JVM.Attribute.Code.Code Language.JVM.Stage.High)
+ Language.JVM.Attribute.Code: instance GHC.Classes.Eq (Language.JVM.Attribute.Code.Code Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Code: instance GHC.Classes.Eq (Language.JVM.Attribute.Code.CodeAttributes Language.JVM.Stage.High)
+ Language.JVM.Attribute.Code: instance GHC.Classes.Eq (Language.JVM.Attribute.Code.CodeAttributes Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Code: instance GHC.Classes.Eq (Language.JVM.Attribute.Code.ExceptionTable Language.JVM.Stage.High)
+ Language.JVM.Attribute.Code: instance GHC.Classes.Eq (Language.JVM.Attribute.Code.ExceptionTable Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Code: instance GHC.Classes.Ord (Language.JVM.Attribute.Code.Code Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Code: instance GHC.Classes.Ord (Language.JVM.Attribute.Code.CodeAttributes Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Code: instance GHC.Classes.Ord (Language.JVM.Attribute.Code.ExceptionTable Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Code: instance GHC.Generics.Generic (Language.JVM.Attribute.Code.Code Language.JVM.Stage.High)
+ Language.JVM.Attribute.Code: instance GHC.Generics.Generic (Language.JVM.Attribute.Code.Code Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Code: instance GHC.Generics.Generic (Language.JVM.Attribute.Code.CodeAttributes Language.JVM.Stage.High)
+ Language.JVM.Attribute.Code: instance GHC.Generics.Generic (Language.JVM.Attribute.Code.CodeAttributes Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Code: instance GHC.Generics.Generic (Language.JVM.Attribute.Code.ExceptionTable Language.JVM.Stage.High)
+ Language.JVM.Attribute.Code: instance GHC.Generics.Generic (Language.JVM.Attribute.Code.ExceptionTable Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Code: instance GHC.Show.Show (Language.JVM.Attribute.Code.Code Language.JVM.Stage.High)
+ Language.JVM.Attribute.Code: instance GHC.Show.Show (Language.JVM.Attribute.Code.Code Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Code: instance GHC.Show.Show (Language.JVM.Attribute.Code.CodeAttributes Language.JVM.Stage.High)
+ Language.JVM.Attribute.Code: instance GHC.Show.Show (Language.JVM.Attribute.Code.CodeAttributes Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Code: instance GHC.Show.Show (Language.JVM.Attribute.Code.ExceptionTable Language.JVM.Stage.High)
+ Language.JVM.Attribute.Code: instance GHC.Show.Show (Language.JVM.Attribute.Code.ExceptionTable Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Code: instance Language.JVM.Attribute.Base.IsAttribute (Language.JVM.Attribute.Code.Code Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Code: instance Language.JVM.ByteCode.ByteCodeStaged Language.JVM.Attribute.Code.ExceptionTable
+ Language.JVM.Attribute.Code: instance Language.JVM.Staged.Staged Language.JVM.Attribute.Code.Code
+ Language.JVM.Attribute.ConstantValue: [constantValue] :: ConstantValue r -> !(Ref JValue r)
+ Language.JVM.Attribute.ConstantValue: instance Control.DeepSeq.NFData (Language.JVM.Attribute.ConstantValue.ConstantValue Language.JVM.Stage.High)
+ Language.JVM.Attribute.ConstantValue: instance Control.DeepSeq.NFData (Language.JVM.Attribute.ConstantValue.ConstantValue Language.JVM.Stage.Low)
+ Language.JVM.Attribute.ConstantValue: instance Data.Binary.Class.Binary (Language.JVM.Attribute.ConstantValue.ConstantValue Language.JVM.Stage.Low)
+ Language.JVM.Attribute.ConstantValue: instance GHC.Classes.Eq (Language.JVM.Attribute.ConstantValue.ConstantValue Language.JVM.Stage.High)
+ Language.JVM.Attribute.ConstantValue: instance GHC.Classes.Eq (Language.JVM.Attribute.ConstantValue.ConstantValue Language.JVM.Stage.Low)
+ Language.JVM.Attribute.ConstantValue: instance GHC.Classes.Ord (Language.JVM.Attribute.ConstantValue.ConstantValue Language.JVM.Stage.Low)
+ Language.JVM.Attribute.ConstantValue: instance GHC.Generics.Generic (Language.JVM.Attribute.ConstantValue.ConstantValue Language.JVM.Stage.High)
+ Language.JVM.Attribute.ConstantValue: instance GHC.Generics.Generic (Language.JVM.Attribute.ConstantValue.ConstantValue Language.JVM.Stage.Low)
+ Language.JVM.Attribute.ConstantValue: instance GHC.Show.Show (Language.JVM.Attribute.ConstantValue.ConstantValue Language.JVM.Stage.High)
+ Language.JVM.Attribute.ConstantValue: instance GHC.Show.Show (Language.JVM.Attribute.ConstantValue.ConstantValue Language.JVM.Stage.Low)
+ Language.JVM.Attribute.ConstantValue: instance Language.JVM.Attribute.Base.IsAttribute (Language.JVM.Attribute.ConstantValue.ConstantValue Language.JVM.Stage.Low)
+ Language.JVM.Attribute.ConstantValue: instance Language.JVM.Staged.Staged Language.JVM.Attribute.ConstantValue.ConstantValue
+ Language.JVM.Attribute.Exceptions: [exceptions] :: Exceptions r -> SizedList16 (Ref ClassName r)
+ Language.JVM.Attribute.Exceptions: instance Control.DeepSeq.NFData (Language.JVM.Attribute.Exceptions.Exceptions Language.JVM.Stage.High)
+ Language.JVM.Attribute.Exceptions: instance Control.DeepSeq.NFData (Language.JVM.Attribute.Exceptions.Exceptions Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Exceptions: instance Data.Binary.Class.Binary (Language.JVM.Attribute.Exceptions.Exceptions Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Exceptions: instance GHC.Classes.Eq (Language.JVM.Attribute.Exceptions.Exceptions Language.JVM.Stage.High)
+ Language.JVM.Attribute.Exceptions: instance GHC.Classes.Eq (Language.JVM.Attribute.Exceptions.Exceptions Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Exceptions: instance GHC.Classes.Ord (Language.JVM.Attribute.Exceptions.Exceptions Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Exceptions: instance GHC.Generics.Generic (Language.JVM.Attribute.Exceptions.Exceptions Language.JVM.Stage.High)
+ Language.JVM.Attribute.Exceptions: instance GHC.Generics.Generic (Language.JVM.Attribute.Exceptions.Exceptions Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Exceptions: instance GHC.Show.Show (Language.JVM.Attribute.Exceptions.Exceptions Language.JVM.Stage.High)
+ Language.JVM.Attribute.Exceptions: instance GHC.Show.Show (Language.JVM.Attribute.Exceptions.Exceptions Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Exceptions: instance Language.JVM.Attribute.Base.IsAttribute (Language.JVM.Attribute.Exceptions.Exceptions Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Exceptions: instance Language.JVM.Staged.Staged Language.JVM.Attribute.Exceptions.Exceptions
+ Language.JVM.Attribute.Exceptions: newtype Exceptions r
+ Language.JVM.Attribute.LineNumberTable: LineNumberTable :: IntMap LineNumber -> LineNumberTable r
+ Language.JVM.Attribute.LineNumberTable: [lineNumberTable] :: LineNumberTable r -> IntMap LineNumber
+ Language.JVM.Attribute.LineNumberTable: instance Control.DeepSeq.NFData (Language.JVM.Attribute.LineNumberTable.LineNumberTable r)
+ Language.JVM.Attribute.LineNumberTable: instance Data.Binary.Class.Binary (Language.JVM.Attribute.LineNumberTable.LineNumberTable Language.JVM.Stage.Low)
+ Language.JVM.Attribute.LineNumberTable: instance GHC.Classes.Eq (Language.JVM.Attribute.LineNumberTable.LineNumberTable r)
+ Language.JVM.Attribute.LineNumberTable: instance GHC.Classes.Ord (Language.JVM.Attribute.LineNumberTable.LineNumberTable r)
+ Language.JVM.Attribute.LineNumberTable: instance GHC.Generics.Generic (Language.JVM.Attribute.LineNumberTable.LineNumberTable r)
+ Language.JVM.Attribute.LineNumberTable: instance GHC.Show.Show (Language.JVM.Attribute.LineNumberTable.LineNumberTable r)
+ Language.JVM.Attribute.LineNumberTable: instance Language.JVM.Attribute.Base.IsAttribute (Language.JVM.Attribute.LineNumberTable.LineNumberTable Language.JVM.Stage.Low)
+ Language.JVM.Attribute.LineNumberTable: instance Language.JVM.ByteCode.ByteCodeStaged Language.JVM.Attribute.LineNumberTable.LineNumberTable
+ Language.JVM.Attribute.LineNumberTable: linenumber :: Int -> LineNumberTable r -> Maybe LineNumber
+ Language.JVM.Attribute.LineNumberTable: linenumber' :: Integral a => a -> LineNumberTable r -> Maybe LineNumber
+ Language.JVM.Attribute.LineNumberTable: newtype LineNumberTable r
+ Language.JVM.Attribute.LineNumberTable: type BinaryFormat = SizedList16 (Word16, LineNumber)
+ Language.JVM.Attribute.LineNumberTable: type LineNumber = Word16
+ Language.JVM.Attribute.Signature: Signature :: (Ref Text a) -> Signature a
+ Language.JVM.Attribute.Signature: data Signature a
+ Language.JVM.Attribute.Signature: instance Control.DeepSeq.NFData (Language.JVM.Attribute.Signature.Signature Language.JVM.Stage.High)
+ Language.JVM.Attribute.Signature: instance Control.DeepSeq.NFData (Language.JVM.Attribute.Signature.Signature Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Signature: instance Data.Binary.Class.Binary (Language.JVM.Attribute.Signature.Signature Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Signature: instance GHC.Classes.Eq (Language.JVM.Attribute.Signature.Signature Language.JVM.Stage.High)
+ Language.JVM.Attribute.Signature: instance GHC.Classes.Eq (Language.JVM.Attribute.Signature.Signature Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Signature: instance GHC.Classes.Ord (Language.JVM.Attribute.Signature.Signature Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Signature: instance GHC.Generics.Generic (Language.JVM.Attribute.Signature.Signature Language.JVM.Stage.High)
+ Language.JVM.Attribute.Signature: instance GHC.Generics.Generic (Language.JVM.Attribute.Signature.Signature Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Signature: instance GHC.Show.Show (Language.JVM.Attribute.Signature.Signature Language.JVM.Stage.High)
+ Language.JVM.Attribute.Signature: instance GHC.Show.Show (Language.JVM.Attribute.Signature.Signature Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Signature: instance Language.JVM.Attribute.Base.IsAttribute (Language.JVM.Attribute.Signature.Signature Language.JVM.Stage.Low)
+ Language.JVM.Attribute.Signature: instance Language.JVM.Staged.Staged Language.JVM.Attribute.Signature.Signature
+ Language.JVM.Attribute.Signature: signatureFromText :: Text -> Signature High
+ Language.JVM.Attribute.Signature: signatureToText :: Signature High -> Text
+ Language.JVM.Attribute.StackMapTable: VTDouble :: VerificationTypeInfo r
+ Language.JVM.Attribute.StackMapTable: VTFloat :: VerificationTypeInfo r
+ Language.JVM.Attribute.StackMapTable: VTInteger :: VerificationTypeInfo r
+ Language.JVM.Attribute.StackMapTable: VTLong :: VerificationTypeInfo r
+ Language.JVM.Attribute.StackMapTable: VTNull :: VerificationTypeInfo r
+ Language.JVM.Attribute.StackMapTable: VTObject :: (Ref ClassName r) -> VerificationTypeInfo r
+ Language.JVM.Attribute.StackMapTable: VTTop :: VerificationTypeInfo r
+ Language.JVM.Attribute.StackMapTable: VTUninitialized :: !Word16 -> VerificationTypeInfo r
+ Language.JVM.Attribute.StackMapTable: VTUninitializedThis :: VerificationTypeInfo r
+ Language.JVM.Attribute.StackMapTable: instance Control.DeepSeq.NFData (Language.JVM.Attribute.StackMapTable.StackMapFrame Language.JVM.Stage.High)
+ Language.JVM.Attribute.StackMapTable: instance Control.DeepSeq.NFData (Language.JVM.Attribute.StackMapTable.StackMapFrame Language.JVM.Stage.Low)
+ Language.JVM.Attribute.StackMapTable: instance Control.DeepSeq.NFData (Language.JVM.Attribute.StackMapTable.StackMapFrameType Language.JVM.Stage.High)
+ Language.JVM.Attribute.StackMapTable: instance Control.DeepSeq.NFData (Language.JVM.Attribute.StackMapTable.StackMapFrameType Language.JVM.Stage.Low)
+ Language.JVM.Attribute.StackMapTable: instance Control.DeepSeq.NFData (Language.JVM.Attribute.StackMapTable.StackMapTable Language.JVM.Stage.High)
+ Language.JVM.Attribute.StackMapTable: instance Control.DeepSeq.NFData (Language.JVM.Attribute.StackMapTable.StackMapTable Language.JVM.Stage.Low)
+ Language.JVM.Attribute.StackMapTable: instance Control.DeepSeq.NFData (Language.JVM.Attribute.StackMapTable.VerificationTypeInfo Language.JVM.Stage.High)
+ Language.JVM.Attribute.StackMapTable: instance Control.DeepSeq.NFData (Language.JVM.Attribute.StackMapTable.VerificationTypeInfo Language.JVM.Stage.Low)
+ Language.JVM.Attribute.StackMapTable: instance Data.Binary.Class.Binary (Language.JVM.Attribute.StackMapTable.StackMapFrame Language.JVM.Stage.Low)
+ Language.JVM.Attribute.StackMapTable: instance Data.Binary.Class.Binary (Language.JVM.Attribute.StackMapTable.StackMapTable Language.JVM.Stage.Low)
+ Language.JVM.Attribute.StackMapTable: instance Data.Binary.Class.Binary (Language.JVM.Attribute.StackMapTable.VerificationTypeInfo Language.JVM.Stage.Low)
+ Language.JVM.Attribute.StackMapTable: instance GHC.Classes.Eq (Language.JVM.Attribute.StackMapTable.StackMapFrame Language.JVM.Stage.High)
+ Language.JVM.Attribute.StackMapTable: instance GHC.Classes.Eq (Language.JVM.Attribute.StackMapTable.StackMapFrame Language.JVM.Stage.Low)
+ Language.JVM.Attribute.StackMapTable: instance GHC.Classes.Eq (Language.JVM.Attribute.StackMapTable.StackMapFrameType Language.JVM.Stage.High)
+ Language.JVM.Attribute.StackMapTable: instance GHC.Classes.Eq (Language.JVM.Attribute.StackMapTable.StackMapFrameType Language.JVM.Stage.Low)
+ Language.JVM.Attribute.StackMapTable: instance GHC.Classes.Eq (Language.JVM.Attribute.StackMapTable.StackMapTable Language.JVM.Stage.High)
+ Language.JVM.Attribute.StackMapTable: instance GHC.Classes.Eq (Language.JVM.Attribute.StackMapTable.StackMapTable Language.JVM.Stage.Low)
+ Language.JVM.Attribute.StackMapTable: instance GHC.Classes.Eq (Language.JVM.Attribute.StackMapTable.VerificationTypeInfo Language.JVM.Stage.High)
+ Language.JVM.Attribute.StackMapTable: instance GHC.Classes.Eq (Language.JVM.Attribute.StackMapTable.VerificationTypeInfo Language.JVM.Stage.Low)
+ Language.JVM.Attribute.StackMapTable: instance GHC.Classes.Ord (Language.JVM.Attribute.StackMapTable.StackMapFrame Language.JVM.Stage.Low)
+ Language.JVM.Attribute.StackMapTable: instance GHC.Classes.Ord (Language.JVM.Attribute.StackMapTable.StackMapFrameType Language.JVM.Stage.Low)
+ Language.JVM.Attribute.StackMapTable: instance GHC.Classes.Ord (Language.JVM.Attribute.StackMapTable.StackMapTable Language.JVM.Stage.Low)
+ Language.JVM.Attribute.StackMapTable: instance GHC.Classes.Ord (Language.JVM.Attribute.StackMapTable.VerificationTypeInfo Language.JVM.Stage.Low)
+ Language.JVM.Attribute.StackMapTable: instance GHC.Generics.Generic (Language.JVM.Attribute.StackMapTable.StackMapFrame Language.JVM.Stage.High)
+ Language.JVM.Attribute.StackMapTable: instance GHC.Generics.Generic (Language.JVM.Attribute.StackMapTable.StackMapFrame Language.JVM.Stage.Low)
+ Language.JVM.Attribute.StackMapTable: instance GHC.Generics.Generic (Language.JVM.Attribute.StackMapTable.StackMapFrameType Language.JVM.Stage.High)
+ Language.JVM.Attribute.StackMapTable: instance GHC.Generics.Generic (Language.JVM.Attribute.StackMapTable.StackMapFrameType Language.JVM.Stage.Low)
+ Language.JVM.Attribute.StackMapTable: instance GHC.Generics.Generic (Language.JVM.Attribute.StackMapTable.StackMapTable Language.JVM.Stage.High)
+ Language.JVM.Attribute.StackMapTable: instance GHC.Generics.Generic (Language.JVM.Attribute.StackMapTable.StackMapTable Language.JVM.Stage.Low)
+ Language.JVM.Attribute.StackMapTable: instance GHC.Generics.Generic (Language.JVM.Attribute.StackMapTable.VerificationTypeInfo Language.JVM.Stage.High)
+ Language.JVM.Attribute.StackMapTable: instance GHC.Generics.Generic (Language.JVM.Attribute.StackMapTable.VerificationTypeInfo Language.JVM.Stage.Low)
+ Language.JVM.Attribute.StackMapTable: instance GHC.Show.Show (Language.JVM.Attribute.StackMapTable.StackMapFrame Language.JVM.Stage.High)
+ Language.JVM.Attribute.StackMapTable: instance GHC.Show.Show (Language.JVM.Attribute.StackMapTable.StackMapFrame Language.JVM.Stage.Low)
+ Language.JVM.Attribute.StackMapTable: instance GHC.Show.Show (Language.JVM.Attribute.StackMapTable.StackMapFrameType Language.JVM.Stage.High)
+ Language.JVM.Attribute.StackMapTable: instance GHC.Show.Show (Language.JVM.Attribute.StackMapTable.StackMapFrameType Language.JVM.Stage.Low)
+ Language.JVM.Attribute.StackMapTable: instance GHC.Show.Show (Language.JVM.Attribute.StackMapTable.StackMapTable Language.JVM.Stage.High)
+ Language.JVM.Attribute.StackMapTable: instance GHC.Show.Show (Language.JVM.Attribute.StackMapTable.StackMapTable Language.JVM.Stage.Low)
+ Language.JVM.Attribute.StackMapTable: instance GHC.Show.Show (Language.JVM.Attribute.StackMapTable.VerificationTypeInfo Language.JVM.Stage.High)
+ Language.JVM.Attribute.StackMapTable: instance GHC.Show.Show (Language.JVM.Attribute.StackMapTable.VerificationTypeInfo Language.JVM.Stage.Low)
+ Language.JVM.Attribute.StackMapTable: instance Language.JVM.Attribute.Base.IsAttribute (Language.JVM.Attribute.StackMapTable.StackMapTable Language.JVM.Stage.Low)
+ Language.JVM.Attribute.StackMapTable: instance Language.JVM.ByteCode.ByteCodeStaged Language.JVM.Attribute.StackMapTable.StackMapTable
+ Language.JVM.Attribute.StackMapTable: instance Language.JVM.Staged.Staged Language.JVM.Attribute.StackMapTable.StackMapFrameType
+ Language.JVM.Attribute.StackMapTable: instance Language.JVM.Staged.Staged Language.JVM.Attribute.StackMapTable.VerificationTypeInfo
+ Language.JVM.Attribute.StackMapTable: newtype StackMapTable r
+ Language.JVM.Attribute.StackMapTable: offsetDelta :: Word16 -> Word16 -> Word16
+ Language.JVM.Attribute.StackMapTable: offsetDeltaInv :: Word16 -> Word16 -> Word16
+ Language.JVM.ByteCode: AByte :: ArrayType
+ Language.JVM.ByteCode: AChar :: ArrayType
+ Language.JVM.ByteCode: ADouble :: ArrayType
+ Language.JVM.ByteCode: AFloat :: ArrayType
+ Language.JVM.ByteCode: AInt :: ArrayType
+ Language.JVM.ByteCode: ALong :: ArrayType
+ Language.JVM.ByteCode: ARef :: ArrayType
+ Language.JVM.ByteCode: AShort :: ArrayType
+ Language.JVM.ByteCode: Add :: BinOpr
+ Language.JVM.ByteCode: And :: BitOpr
+ Language.JVM.ByteCode: ArrayLength :: ByteCodeOpr r
+ Language.JVM.ByteCode: ArrayLoad :: ArrayType -> ByteCodeOpr r
+ Language.JVM.ByteCode: ArrayStore :: ArrayType -> ByteCodeOpr r
+ Language.JVM.ByteCode: BinaryOpr :: BinOpr -> ArithmeticType -> ByteCodeOpr r
+ Language.JVM.ByteCode: BitOpr :: BitOpr -> WordSize -> ByteCodeOpr r
+ Language.JVM.ByteCode: ByteCode :: Choice (Word32, Vector (ByteCodeInst Low)) (Vector (ByteCodeOpr High)) i -> ByteCode i
+ Language.JVM.ByteCode: ByteCodeInst :: !(ByteCodeOffset) -> !(ByteCodeOpr r) -> ByteCodeInst r
+ Language.JVM.ByteCode: CByte :: Int8 -> CConstant r
+ Language.JVM.ByteCode: CDouble0 :: CConstant r
+ Language.JVM.ByteCode: CDouble1 :: CConstant r
+ Language.JVM.ByteCode: CEq :: CmpOpr
+ Language.JVM.ByteCode: CFloat0 :: CConstant r
+ Language.JVM.ByteCode: CFloat1 :: CConstant r
+ Language.JVM.ByteCode: CFloat2 :: CConstant r
+ Language.JVM.ByteCode: CGe :: CmpOpr
+ Language.JVM.ByteCode: CGt :: CmpOpr
+ Language.JVM.ByteCode: CInt0 :: CConstant r
+ Language.JVM.ByteCode: CInt1 :: CConstant r
+ Language.JVM.ByteCode: CInt2 :: CConstant r
+ Language.JVM.ByteCode: CInt3 :: CConstant r
+ Language.JVM.ByteCode: CInt4 :: CConstant r
+ Language.JVM.ByteCode: CInt5 :: CConstant r
+ Language.JVM.ByteCode: CIntM1 :: CConstant r
+ Language.JVM.ByteCode: CLe :: CmpOpr
+ Language.JVM.ByteCode: CLong0 :: CConstant r
+ Language.JVM.ByteCode: CLong1 :: CConstant r
+ Language.JVM.ByteCode: CLt :: CmpOpr
+ Language.JVM.ByteCode: CNe :: CmpOpr
+ Language.JVM.ByteCode: CNull :: CConstant r
+ Language.JVM.ByteCode: CRef :: (Maybe WordSize) -> (Ref JValue r) -> CConstant r
+ Language.JVM.ByteCode: CShort :: Int16 -> CConstant r
+ Language.JVM.ByteCode: Cast :: CastOpr -> ByteCodeOpr r
+ Language.JVM.ByteCode: CastDown :: SmallArithmeticType -> CastOpr
+ Language.JVM.ByteCode: CastTo :: ArithmeticType -> ArithmeticType -> CastOpr
+ Language.JVM.ByteCode: CheckCast :: (Ref ClassName r) -> ByteCodeOpr r
+ Language.JVM.ByteCode: CompareFloating :: Bool -> WordSize -> ByteCodeOpr r
+ Language.JVM.ByteCode: CompareLongs :: ByteCodeOpr r
+ Language.JVM.ByteCode: Div :: BinOpr
+ Language.JVM.ByteCode: Dup :: WordSize -> ByteCodeOpr r
+ Language.JVM.ByteCode: DupX1 :: WordSize -> ByteCodeOpr r
+ Language.JVM.ByteCode: DupX2 :: WordSize -> ByteCodeOpr r
+ Language.JVM.ByteCode: EABoolean :: ExactArrayType r
+ Language.JVM.ByteCode: EAByte :: ExactArrayType r
+ Language.JVM.ByteCode: EAChar :: ExactArrayType r
+ Language.JVM.ByteCode: EADouble :: ExactArrayType r
+ Language.JVM.ByteCode: EAFloat :: ExactArrayType r
+ Language.JVM.ByteCode: EAInt :: ExactArrayType r
+ Language.JVM.ByteCode: EALong :: ExactArrayType r
+ Language.JVM.ByteCode: EARef :: (Ref ClassName r) -> ExactArrayType r
+ Language.JVM.ByteCode: EAShort :: ExactArrayType r
+ Language.JVM.ByteCode: FldField :: FieldAccess
+ Language.JVM.ByteCode: FldStatic :: FieldAccess
+ Language.JVM.ByteCode: Get :: FieldAccess -> (DeepRef (InClass FieldId) r) -> ByteCodeOpr r
+ Language.JVM.ByteCode: Goto :: (LongRelativeRef r) -> ByteCodeOpr r
+ Language.JVM.ByteCode: If :: CmpOpr -> OneOrTwo -> (ShortRelativeRef r) -> ByteCodeOpr r
+ Language.JVM.ByteCode: IfRef :: Bool -> OneOrTwo -> (ShortRelativeRef r) -> ByteCodeOpr r
+ Language.JVM.ByteCode: IncrLocal :: !LocalAddress -> !IncrementAmount -> ByteCodeOpr r
+ Language.JVM.ByteCode: InstanceOf :: (Ref ClassName r) -> ByteCodeOpr r
+ Language.JVM.ByteCode: InvkDynamic :: (DeepRef InvokeDynamic r) -> Invocation r
+ Language.JVM.ByteCode: InvkInterface :: Word8 -> (DeepRef AbsInterfaceMethodId r) -> Invocation r
+ Language.JVM.ByteCode: InvkSpecial :: (DeepRef AbsVariableMethodId r) -> Invocation r
+ Language.JVM.ByteCode: InvkStatic :: (DeepRef AbsVariableMethodId r) -> Invocation r
+ Language.JVM.ByteCode: InvkVirtual :: (DeepRef AbsMethodId r) -> Invocation r
+ Language.JVM.ByteCode: Invoke :: (Invocation r) -> ByteCodeOpr r
+ Language.JVM.ByteCode: Jsr :: (LongRelativeRef r) -> ByteCodeOpr r
+ Language.JVM.ByteCode: LDouble :: LocalType
+ Language.JVM.ByteCode: LFloat :: LocalType
+ Language.JVM.ByteCode: LInt :: LocalType
+ Language.JVM.ByteCode: LLong :: LocalType
+ Language.JVM.ByteCode: LRef :: LocalType
+ Language.JVM.ByteCode: Load :: LocalType -> LocalAddress -> ByteCodeOpr r
+ Language.JVM.ByteCode: LookupSwitch :: Int32 -> (Vector (Int32, Int32)) -> ByteCodeOpr r
+ Language.JVM.ByteCode: MByte :: SmallArithmeticType
+ Language.JVM.ByteCode: MChar :: SmallArithmeticType
+ Language.JVM.ByteCode: MDouble :: ArithmeticType
+ Language.JVM.ByteCode: MFloat :: ArithmeticType
+ Language.JVM.ByteCode: MInt :: ArithmeticType
+ Language.JVM.ByteCode: MLong :: ArithmeticType
+ Language.JVM.ByteCode: MShort :: SmallArithmeticType
+ Language.JVM.ByteCode: Monitor :: Bool -> ByteCodeOpr r
+ Language.JVM.ByteCode: Mul :: BinOpr
+ Language.JVM.ByteCode: MultiNewArray :: (Ref ClassName r) -> Word8 -> ByteCodeOpr r
+ Language.JVM.ByteCode: Neg :: ArithmeticType -> ByteCodeOpr r
+ Language.JVM.ByteCode: New :: (Ref ClassName r) -> ByteCodeOpr r
+ Language.JVM.ByteCode: NewArray :: (ExactArrayType r) -> ByteCodeOpr r
+ Language.JVM.ByteCode: Nop :: ByteCodeOpr r
+ Language.JVM.ByteCode: One :: OneOrTwo
+ Language.JVM.ByteCode: Or :: BitOpr
+ Language.JVM.ByteCode: Pop :: WordSize -> ByteCodeOpr r
+ Language.JVM.ByteCode: Push :: (BConstant r) -> ByteCodeOpr r
+ Language.JVM.ByteCode: Put :: FieldAccess -> (DeepRef (InClass FieldId) r) -> ByteCodeOpr r
+ Language.JVM.ByteCode: Rem :: BinOpr
+ Language.JVM.ByteCode: Ret :: LocalAddress -> ByteCodeOpr r
+ Language.JVM.ByteCode: Return :: (Maybe LocalType) -> ByteCodeOpr r
+ Language.JVM.ByteCode: ShL :: BitOpr
+ Language.JVM.ByteCode: ShR :: BitOpr
+ Language.JVM.ByteCode: Store :: LocalType -> LocalAddress -> ByteCodeOpr r
+ Language.JVM.ByteCode: Sub :: BinOpr
+ Language.JVM.ByteCode: Swap :: ByteCodeOpr r
+ Language.JVM.ByteCode: SwitchTable :: Int32 -> Vector (LongRelativeRef r) -> SwitchTable r
+ Language.JVM.ByteCode: TableSwitch :: Int32 -> (SwitchTable r) -> ByteCodeOpr r
+ Language.JVM.ByteCode: Throw :: ByteCodeOpr r
+ Language.JVM.ByteCode: Two :: OneOrTwo
+ Language.JVM.ByteCode: UShR :: BitOpr
+ Language.JVM.ByteCode: XOr :: BitOpr
+ Language.JVM.ByteCode: [offset] :: ByteCodeInst r -> !(ByteCodeOffset)
+ Language.JVM.ByteCode: [opcode] :: ByteCodeInst r -> !(ByteCodeOpr r)
+ Language.JVM.ByteCode: [switchLow] :: SwitchTable r -> Int32
+ Language.JVM.ByteCode: [switchOffsets] :: SwitchTable r -> Vector (LongRelativeRef r)
+ Language.JVM.ByteCode: [unByteCode] :: ByteCode i -> Choice (Word32, Vector (ByteCodeInst Low)) (Vector (ByteCodeOpr High)) i
+ Language.JVM.ByteCode: class ByteCodeStaged s
+ Language.JVM.ByteCode: data ArithmeticType
+ Language.JVM.ByteCode: data ArrayType
+ Language.JVM.ByteCode: data BinOpr
+ Language.JVM.ByteCode: data BitOpr
+ Language.JVM.ByteCode: data ByteCodeInst r
+ Language.JVM.ByteCode: data ByteCodeOpr r
+ Language.JVM.ByteCode: data CConstant r
+ Language.JVM.ByteCode: data CastOpr
+ Language.JVM.ByteCode: data CmpOpr
+ Language.JVM.ByteCode: data ExactArrayType r
+ Language.JVM.ByteCode: data FieldAccess
+ Language.JVM.ByteCode: data Invocation r
+ Language.JVM.ByteCode: data LocalType
+ Language.JVM.ByteCode: data OneOrTwo
+ Language.JVM.ByteCode: data SmallArithmeticType
+ Language.JVM.ByteCode: data SwitchTable r
+ Language.JVM.ByteCode: devolveBC :: (ByteCodeStaged s, DevolveM m) => (ByteCodeIndex -> m ByteCodeOffset) -> s High -> m (s Low)
+ Language.JVM.ByteCode: devolveByteCode :: DevolveM m => ByteCode High -> m (ByteCode Low)
+ Language.JVM.ByteCode: devolveOffset :: DevolveM m => ByteCode Low -> ByteCodeIndex -> m (ByteCodeOffset)
+ Language.JVM.ByteCode: evolveBC :: (ByteCodeStaged s, EvolveM m) => (ByteCodeOffset -> m ByteCodeIndex) -> s Low -> m (s High)
+ Language.JVM.ByteCode: evolveByteCode :: EvolveM m => ByteCode Low -> m (OffsetMap, ByteCode High)
+ Language.JVM.ByteCode: evolveOffset :: EvolveM m => OffsetMap -> ByteCodeOffset -> m (ByteCodeIndex)
+ Language.JVM.ByteCode: indexOffset :: ByteCode Low -> ByteCodeIndex -> Maybe (ByteCodeOffset)
+ Language.JVM.ByteCode: instance Control.DeepSeq.NFData (Language.JVM.ByteCode.ByteCode Language.JVM.Stage.High)
+ Language.JVM.ByteCode: instance Control.DeepSeq.NFData (Language.JVM.ByteCode.ByteCode Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance Control.DeepSeq.NFData (Language.JVM.ByteCode.ByteCodeInst Language.JVM.Stage.High)
+ Language.JVM.ByteCode: instance Control.DeepSeq.NFData (Language.JVM.ByteCode.ByteCodeInst Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance Control.DeepSeq.NFData (Language.JVM.ByteCode.ByteCodeOpr Language.JVM.Stage.High)
+ Language.JVM.ByteCode: instance Control.DeepSeq.NFData (Language.JVM.ByteCode.ByteCodeOpr Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance Control.DeepSeq.NFData (Language.JVM.ByteCode.CConstant Language.JVM.Stage.High)
+ Language.JVM.ByteCode: instance Control.DeepSeq.NFData (Language.JVM.ByteCode.CConstant Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance Control.DeepSeq.NFData (Language.JVM.ByteCode.ExactArrayType Language.JVM.Stage.High)
+ Language.JVM.ByteCode: instance Control.DeepSeq.NFData (Language.JVM.ByteCode.ExactArrayType Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance Control.DeepSeq.NFData (Language.JVM.ByteCode.Invocation Language.JVM.Stage.High)
+ Language.JVM.ByteCode: instance Control.DeepSeq.NFData (Language.JVM.ByteCode.Invocation Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance Control.DeepSeq.NFData (Language.JVM.ByteCode.SwitchTable Language.JVM.Stage.High)
+ Language.JVM.ByteCode: instance Control.DeepSeq.NFData (Language.JVM.ByteCode.SwitchTable Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance Control.DeepSeq.NFData Language.JVM.ByteCode.ArithmeticType
+ Language.JVM.ByteCode: instance Control.DeepSeq.NFData Language.JVM.ByteCode.ArrayType
+ Language.JVM.ByteCode: instance Control.DeepSeq.NFData Language.JVM.ByteCode.BinOpr
+ Language.JVM.ByteCode: instance Control.DeepSeq.NFData Language.JVM.ByteCode.BitOpr
+ Language.JVM.ByteCode: instance Control.DeepSeq.NFData Language.JVM.ByteCode.CastOpr
+ Language.JVM.ByteCode: instance Control.DeepSeq.NFData Language.JVM.ByteCode.CmpOpr
+ Language.JVM.ByteCode: instance Control.DeepSeq.NFData Language.JVM.ByteCode.FieldAccess
+ Language.JVM.ByteCode: instance Control.DeepSeq.NFData Language.JVM.ByteCode.LocalType
+ Language.JVM.ByteCode: instance Control.DeepSeq.NFData Language.JVM.ByteCode.OneOrTwo
+ Language.JVM.ByteCode: instance Control.DeepSeq.NFData Language.JVM.ByteCode.SmallArithmeticType
+ Language.JVM.ByteCode: instance Data.Binary.Class.Binary (Language.JVM.ByteCode.ByteCode Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance Data.Binary.Class.Binary (Language.JVM.ByteCode.ByteCodeInst Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance Data.Binary.Class.Binary (Language.JVM.ByteCode.ByteCodeOpr Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance GHC.Classes.Eq (Language.JVM.ByteCode.ByteCode Language.JVM.Stage.High)
+ Language.JVM.ByteCode: instance GHC.Classes.Eq (Language.JVM.ByteCode.ByteCode Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance GHC.Classes.Eq (Language.JVM.ByteCode.ByteCodeInst Language.JVM.Stage.High)
+ Language.JVM.ByteCode: instance GHC.Classes.Eq (Language.JVM.ByteCode.ByteCodeInst Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance GHC.Classes.Eq (Language.JVM.ByteCode.ByteCodeOpr Language.JVM.Stage.High)
+ Language.JVM.ByteCode: instance GHC.Classes.Eq (Language.JVM.ByteCode.ByteCodeOpr Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance GHC.Classes.Eq (Language.JVM.ByteCode.CConstant Language.JVM.Stage.High)
+ Language.JVM.ByteCode: instance GHC.Classes.Eq (Language.JVM.ByteCode.CConstant Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance GHC.Classes.Eq (Language.JVM.ByteCode.ExactArrayType Language.JVM.Stage.High)
+ Language.JVM.ByteCode: instance GHC.Classes.Eq (Language.JVM.ByteCode.ExactArrayType Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance GHC.Classes.Eq (Language.JVM.ByteCode.Invocation Language.JVM.Stage.High)
+ Language.JVM.ByteCode: instance GHC.Classes.Eq (Language.JVM.ByteCode.Invocation Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance GHC.Classes.Eq (Language.JVM.ByteCode.SwitchTable Language.JVM.Stage.High)
+ Language.JVM.ByteCode: instance GHC.Classes.Eq (Language.JVM.ByteCode.SwitchTable Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance GHC.Classes.Eq Language.JVM.ByteCode.ArithmeticType
+ Language.JVM.ByteCode: instance GHC.Classes.Eq Language.JVM.ByteCode.ArrayType
+ Language.JVM.ByteCode: instance GHC.Classes.Eq Language.JVM.ByteCode.BinOpr
+ Language.JVM.ByteCode: instance GHC.Classes.Eq Language.JVM.ByteCode.BitOpr
+ Language.JVM.ByteCode: instance GHC.Classes.Eq Language.JVM.ByteCode.CastOpr
+ Language.JVM.ByteCode: instance GHC.Classes.Eq Language.JVM.ByteCode.CmpOpr
+ Language.JVM.ByteCode: instance GHC.Classes.Eq Language.JVM.ByteCode.FieldAccess
+ Language.JVM.ByteCode: instance GHC.Classes.Eq Language.JVM.ByteCode.LocalType
+ Language.JVM.ByteCode: instance GHC.Classes.Eq Language.JVM.ByteCode.OneOrTwo
+ Language.JVM.ByteCode: instance GHC.Classes.Eq Language.JVM.ByteCode.SmallArithmeticType
+ Language.JVM.ByteCode: instance GHC.Classes.Ord (Language.JVM.ByteCode.ByteCode Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance GHC.Classes.Ord (Language.JVM.ByteCode.ByteCodeInst Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance GHC.Classes.Ord (Language.JVM.ByteCode.ByteCodeOpr Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance GHC.Classes.Ord (Language.JVM.ByteCode.CConstant Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance GHC.Classes.Ord (Language.JVM.ByteCode.ExactArrayType Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance GHC.Classes.Ord (Language.JVM.ByteCode.Invocation Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance GHC.Classes.Ord (Language.JVM.ByteCode.SwitchTable Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance GHC.Classes.Ord Language.JVM.ByteCode.ArithmeticType
+ Language.JVM.ByteCode: instance GHC.Classes.Ord Language.JVM.ByteCode.ArrayType
+ Language.JVM.ByteCode: instance GHC.Classes.Ord Language.JVM.ByteCode.BinOpr
+ Language.JVM.ByteCode: instance GHC.Classes.Ord Language.JVM.ByteCode.BitOpr
+ Language.JVM.ByteCode: instance GHC.Classes.Ord Language.JVM.ByteCode.CastOpr
+ Language.JVM.ByteCode: instance GHC.Classes.Ord Language.JVM.ByteCode.CmpOpr
+ Language.JVM.ByteCode: instance GHC.Classes.Ord Language.JVM.ByteCode.FieldAccess
+ Language.JVM.ByteCode: instance GHC.Classes.Ord Language.JVM.ByteCode.LocalType
+ Language.JVM.ByteCode: instance GHC.Classes.Ord Language.JVM.ByteCode.OneOrTwo
+ Language.JVM.ByteCode: instance GHC.Classes.Ord Language.JVM.ByteCode.SmallArithmeticType
+ Language.JVM.ByteCode: instance GHC.Enum.Bounded Language.JVM.ByteCode.ArithmeticType
+ Language.JVM.ByteCode: instance GHC.Enum.Bounded Language.JVM.ByteCode.LocalType
+ Language.JVM.ByteCode: instance GHC.Enum.Bounded Language.JVM.ByteCode.OneOrTwo
+ Language.JVM.ByteCode: instance GHC.Enum.Bounded Language.JVM.ByteCode.SmallArithmeticType
+ Language.JVM.ByteCode: instance GHC.Enum.Enum Language.JVM.ByteCode.ArithmeticType
+ Language.JVM.ByteCode: instance GHC.Enum.Enum Language.JVM.ByteCode.LocalType
+ Language.JVM.ByteCode: instance GHC.Enum.Enum Language.JVM.ByteCode.OneOrTwo
+ Language.JVM.ByteCode: instance GHC.Enum.Enum Language.JVM.ByteCode.SmallArithmeticType
+ Language.JVM.ByteCode: instance GHC.Generics.Generic (Language.JVM.ByteCode.ByteCode Language.JVM.Stage.High)
+ Language.JVM.ByteCode: instance GHC.Generics.Generic (Language.JVM.ByteCode.ByteCode Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance GHC.Generics.Generic (Language.JVM.ByteCode.ByteCodeInst Language.JVM.Stage.High)
+ Language.JVM.ByteCode: instance GHC.Generics.Generic (Language.JVM.ByteCode.ByteCodeInst Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance GHC.Generics.Generic (Language.JVM.ByteCode.ByteCodeOpr Language.JVM.Stage.High)
+ Language.JVM.ByteCode: instance GHC.Generics.Generic (Language.JVM.ByteCode.ByteCodeOpr Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance GHC.Generics.Generic (Language.JVM.ByteCode.CConstant Language.JVM.Stage.High)
+ Language.JVM.ByteCode: instance GHC.Generics.Generic (Language.JVM.ByteCode.CConstant Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance GHC.Generics.Generic (Language.JVM.ByteCode.ExactArrayType Language.JVM.Stage.High)
+ Language.JVM.ByteCode: instance GHC.Generics.Generic (Language.JVM.ByteCode.ExactArrayType Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance GHC.Generics.Generic (Language.JVM.ByteCode.Invocation Language.JVM.Stage.High)
+ Language.JVM.ByteCode: instance GHC.Generics.Generic (Language.JVM.ByteCode.Invocation Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance GHC.Generics.Generic (Language.JVM.ByteCode.SwitchTable Language.JVM.Stage.High)
+ Language.JVM.ByteCode: instance GHC.Generics.Generic (Language.JVM.ByteCode.SwitchTable Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance GHC.Generics.Generic Language.JVM.ByteCode.ArithmeticType
+ Language.JVM.ByteCode: instance GHC.Generics.Generic Language.JVM.ByteCode.ArrayType
+ Language.JVM.ByteCode: instance GHC.Generics.Generic Language.JVM.ByteCode.BinOpr
+ Language.JVM.ByteCode: instance GHC.Generics.Generic Language.JVM.ByteCode.BitOpr
+ Language.JVM.ByteCode: instance GHC.Generics.Generic Language.JVM.ByteCode.CastOpr
+ Language.JVM.ByteCode: instance GHC.Generics.Generic Language.JVM.ByteCode.CmpOpr
+ Language.JVM.ByteCode: instance GHC.Generics.Generic Language.JVM.ByteCode.FieldAccess
+ Language.JVM.ByteCode: instance GHC.Generics.Generic Language.JVM.ByteCode.LocalType
+ Language.JVM.ByteCode: instance GHC.Generics.Generic Language.JVM.ByteCode.OneOrTwo
+ Language.JVM.ByteCode: instance GHC.Generics.Generic Language.JVM.ByteCode.SmallArithmeticType
+ Language.JVM.ByteCode: instance GHC.Show.Show (Language.JVM.ByteCode.ByteCode Language.JVM.Stage.High)
+ Language.JVM.ByteCode: instance GHC.Show.Show (Language.JVM.ByteCode.ByteCode Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance GHC.Show.Show (Language.JVM.ByteCode.ByteCodeInst Language.JVM.Stage.High)
+ Language.JVM.ByteCode: instance GHC.Show.Show (Language.JVM.ByteCode.ByteCodeInst Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance GHC.Show.Show (Language.JVM.ByteCode.ByteCodeOpr Language.JVM.Stage.High)
+ Language.JVM.ByteCode: instance GHC.Show.Show (Language.JVM.ByteCode.ByteCodeOpr Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance GHC.Show.Show (Language.JVM.ByteCode.CConstant Language.JVM.Stage.High)
+ Language.JVM.ByteCode: instance GHC.Show.Show (Language.JVM.ByteCode.CConstant Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance GHC.Show.Show (Language.JVM.ByteCode.ExactArrayType Language.JVM.Stage.High)
+ Language.JVM.ByteCode: instance GHC.Show.Show (Language.JVM.ByteCode.ExactArrayType Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance GHC.Show.Show (Language.JVM.ByteCode.Invocation Language.JVM.Stage.High)
+ Language.JVM.ByteCode: instance GHC.Show.Show (Language.JVM.ByteCode.Invocation Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance GHC.Show.Show (Language.JVM.ByteCode.SwitchTable Language.JVM.Stage.High)
+ Language.JVM.ByteCode: instance GHC.Show.Show (Language.JVM.ByteCode.SwitchTable Language.JVM.Stage.Low)
+ Language.JVM.ByteCode: instance GHC.Show.Show Language.JVM.ByteCode.ArithmeticType
+ Language.JVM.ByteCode: instance GHC.Show.Show Language.JVM.ByteCode.ArrayType
+ Language.JVM.ByteCode: instance GHC.Show.Show Language.JVM.ByteCode.BinOpr
+ Language.JVM.ByteCode: instance GHC.Show.Show Language.JVM.ByteCode.BitOpr
+ Language.JVM.ByteCode: instance GHC.Show.Show Language.JVM.ByteCode.CastOpr
+ Language.JVM.ByteCode: instance GHC.Show.Show Language.JVM.ByteCode.CmpOpr
+ Language.JVM.ByteCode: instance GHC.Show.Show Language.JVM.ByteCode.FieldAccess
+ Language.JVM.ByteCode: instance GHC.Show.Show Language.JVM.ByteCode.LocalType
+ Language.JVM.ByteCode: instance GHC.Show.Show Language.JVM.ByteCode.OneOrTwo
+ Language.JVM.ByteCode: instance GHC.Show.Show Language.JVM.ByteCode.SmallArithmeticType
+ Language.JVM.ByteCode: instance Language.JVM.ByteCode.ByteCodeStaged Language.JVM.ByteCode.ByteCodeInst
+ Language.JVM.ByteCode: instance Language.JVM.Staged.Staged Language.JVM.ByteCode.CConstant
+ Language.JVM.ByteCode: instance Language.JVM.Staged.Staged Language.JVM.ByteCode.ExactArrayType
+ Language.JVM.ByteCode: instance Language.JVM.Staged.Staged Language.JVM.ByteCode.Invocation
+ Language.JVM.ByteCode: newtype ByteCode i
+ Language.JVM.ByteCode: offsetIndex :: OffsetMap -> ByteCodeOffset -> Maybe (ByteCodeIndex)
+ Language.JVM.ByteCode: offsetMap :: ByteCode Low -> OffsetMap
+ Language.JVM.ByteCode: switchHigh :: SwitchTable Low -> Int32
+ Language.JVM.ByteCode: type ByteCodeIndex = Int
+ Language.JVM.ByteCode: type ByteCodeOffset = Word16
+ Language.JVM.ByteCode: type ByteCodeRef i = Choice ByteCodeOffset ByteCodeIndex i
+ Language.JVM.ByteCode: type ByteOffset = Int64
+ Language.JVM.ByteCode: type IncrementAmount = Int16
+ Language.JVM.ByteCode: type LocalAddress = Word16
+ Language.JVM.ByteCode: type OffsetMap = IntMap ByteCodeIndex
+ Language.JVM.ByteCode: type WordSize = OneOrTwo
+ Language.JVM.ClassFile: ClassAttributes :: [BootstrapMethods r] -> [Signature r] -> [Attribute r] -> ClassAttributes r
+ Language.JVM.ClassFile: [cAccessFlags'] :: ClassFile r -> !(BitSet16 CAccessFlag)
+ Language.JVM.ClassFile: [cAttributes] :: ClassFile r -> !(Attributes ClassAttributes r)
+ Language.JVM.ClassFile: [cInterfaces] :: ClassFile r -> !(SizedList16 (Ref ClassName r))
+ Language.JVM.ClassFile: [cSuperClass] :: ClassFile r -> !(Ref ClassName r)
+ Language.JVM.ClassFile: [cThisClass] :: ClassFile r -> !(Ref ClassName r)
+ Language.JVM.ClassFile: [caBootstrapMethods] :: ClassAttributes r -> [BootstrapMethods r]
+ Language.JVM.ClassFile: [caOthers] :: ClassAttributes r -> [Attribute r]
+ Language.JVM.ClassFile: [caSignature] :: ClassAttributes r -> [Signature r]
+ Language.JVM.ClassFile: cAccessFlags :: ClassFile r -> Set CAccessFlag
+ Language.JVM.ClassFile: cSignature :: ClassFile High -> Maybe (Signature High)
+ Language.JVM.ClassFile: data ClassAttributes r
+ Language.JVM.ClassFile: instance Control.DeepSeq.NFData (Language.JVM.ClassFile.ClassAttributes Language.JVM.Stage.High)
+ Language.JVM.ClassFile: instance Control.DeepSeq.NFData (Language.JVM.ClassFile.ClassAttributes Language.JVM.Stage.Low)
+ Language.JVM.ClassFile: instance Control.DeepSeq.NFData (Language.JVM.ClassFile.ClassFile Language.JVM.Stage.High)
+ Language.JVM.ClassFile: instance Control.DeepSeq.NFData (Language.JVM.ClassFile.ClassFile Language.JVM.Stage.Low)
+ Language.JVM.ClassFile: instance Data.Binary.Class.Binary (Language.JVM.ClassFile.ClassFile Language.JVM.Stage.Low)
+ Language.JVM.ClassFile: instance GHC.Classes.Eq (Language.JVM.ClassFile.ClassAttributes Language.JVM.Stage.High)
+ Language.JVM.ClassFile: instance GHC.Classes.Eq (Language.JVM.ClassFile.ClassAttributes Language.JVM.Stage.Low)
+ Language.JVM.ClassFile: instance GHC.Classes.Eq (Language.JVM.ClassFile.ClassFile Language.JVM.Stage.High)
+ Language.JVM.ClassFile: instance GHC.Classes.Eq (Language.JVM.ClassFile.ClassFile Language.JVM.Stage.Low)
+ Language.JVM.ClassFile: instance GHC.Classes.Ord (Language.JVM.ClassFile.ClassAttributes Language.JVM.Stage.Low)
+ Language.JVM.ClassFile: instance GHC.Classes.Ord (Language.JVM.ClassFile.ClassFile Language.JVM.Stage.Low)
+ Language.JVM.ClassFile: instance GHC.Generics.Generic (Language.JVM.ClassFile.ClassAttributes Language.JVM.Stage.High)
+ Language.JVM.ClassFile: instance GHC.Generics.Generic (Language.JVM.ClassFile.ClassAttributes Language.JVM.Stage.Low)
+ Language.JVM.ClassFile: instance GHC.Generics.Generic (Language.JVM.ClassFile.ClassFile Language.JVM.Stage.High)
+ Language.JVM.ClassFile: instance GHC.Generics.Generic (Language.JVM.ClassFile.ClassFile Language.JVM.Stage.Low)
+ Language.JVM.ClassFile: instance GHC.Show.Show (Language.JVM.ClassFile.ClassAttributes Language.JVM.Stage.High)
+ Language.JVM.ClassFile: instance GHC.Show.Show (Language.JVM.ClassFile.ClassAttributes Language.JVM.Stage.Low)
+ Language.JVM.ClassFile: instance GHC.Show.Show (Language.JVM.ClassFile.ClassFile Language.JVM.Stage.High)
+ Language.JVM.ClassFile: instance GHC.Show.Show (Language.JVM.ClassFile.ClassFile Language.JVM.Stage.Low)
+ Language.JVM.ClassFile: instance Language.JVM.Staged.Staged Language.JVM.ClassFile.ClassFile
+ Language.JVM.ClassFileReader: CPBuilder :: Map (Constant Low) Index -> ConstantPool Low -> CPBuilder
+ Language.JVM.ClassFileReader: [cpbConstantPool] :: CPBuilder -> ConstantPool Low
+ Language.JVM.ClassFileReader: [cpbMapper] :: CPBuilder -> Map (Constant Low) Index
+ Language.JVM.ClassFileReader: bootstrapConstantPool :: ConstantPool Low -> Either ClassFileError (ConstantPool High)
+ Language.JVM.ClassFileReader: builderFromConstantPool :: ConstantPool Low -> CPBuilder
+ Language.JVM.ClassFileReader: cpbEmpty :: CPBuilder
+ Language.JVM.ClassFileReader: data CPBuilder
+ Language.JVM.ClassFileReader: data ClassFileError
+ Language.JVM.ClassFileReader: data ConstantPoolBuilder a
+ Language.JVM.ClassFileReader: data Evolve a
+ Language.JVM.ClassFileReader: decodeClassFile :: ByteString -> Either ClassFileError (ClassFile Low)
+ Language.JVM.ClassFileReader: devolveClassFile :: ClassFile High -> ClassFile Low
+ Language.JVM.ClassFileReader: devolveClassFile' :: ConstantPool Low -> ClassFile High -> ClassFile Low
+ Language.JVM.ClassFileReader: encodeClassFile :: ClassFile Low -> ByteString
+ Language.JVM.ClassFileReader: evolveClassFile :: ClassFile Low -> Either ClassFileError (ClassFile High)
+ Language.JVM.ClassFileReader: instance Control.DeepSeq.NFData Language.JVM.ClassFileReader.ClassFileError
+ Language.JVM.ClassFileReader: instance Control.Monad.Error.Class.MonadError Language.JVM.ClassFileReader.ClassFileError Language.JVM.ClassFileReader.Evolve
+ Language.JVM.ClassFileReader: instance Control.Monad.Reader.Class.MonadReader (GHC.Base.String, Language.JVM.ConstantPool.ConstantPool Language.JVM.Stage.High) Language.JVM.ClassFileReader.Evolve
+ Language.JVM.ClassFileReader: instance Control.Monad.State.Class.MonadState Language.JVM.ClassFileReader.CPBuilder Language.JVM.ClassFileReader.ConstantPoolBuilder
+ Language.JVM.ClassFileReader: instance GHC.Base.Applicative Language.JVM.ClassFileReader.ConstantPoolBuilder
+ Language.JVM.ClassFileReader: instance GHC.Base.Applicative Language.JVM.ClassFileReader.Evolve
+ Language.JVM.ClassFileReader: instance GHC.Base.Functor Language.JVM.ClassFileReader.ConstantPoolBuilder
+ Language.JVM.ClassFileReader: instance GHC.Base.Functor Language.JVM.ClassFileReader.Evolve
+ Language.JVM.ClassFileReader: instance GHC.Base.Monad Language.JVM.ClassFileReader.ConstantPoolBuilder
+ Language.JVM.ClassFileReader: instance GHC.Base.Monad Language.JVM.ClassFileReader.Evolve
+ Language.JVM.ClassFileReader: instance GHC.Classes.Eq Language.JVM.ClassFileReader.ClassFileError
+ Language.JVM.ClassFileReader: instance GHC.Generics.Generic Language.JVM.ClassFileReader.ClassFileError
+ Language.JVM.ClassFileReader: instance GHC.Show.Show Language.JVM.ClassFileReader.ClassFileError
+ Language.JVM.ClassFileReader: instance Language.JVM.Staged.DevolveM Language.JVM.ClassFileReader.ConstantPoolBuilder
+ Language.JVM.ClassFileReader: instance Language.JVM.Staged.EvolveM Language.JVM.ClassFileReader.Evolve
+ Language.JVM.ClassFileReader: instance Language.JVM.Staged.LabelM Language.JVM.ClassFileReader.ConstantPoolBuilder
+ Language.JVM.ClassFileReader: instance Language.JVM.Staged.LabelM Language.JVM.ClassFileReader.Evolve
+ Language.JVM.ClassFileReader: readClassFile :: ByteString -> Either ClassFileError (ClassFile High)
+ Language.JVM.ClassFileReader: runConstantPoolBuilder :: ConstantPoolBuilder a -> CPBuilder -> (a, CPBuilder)
+ Language.JVM.ClassFileReader: runEvolve :: ConstantPool High -> Evolve a -> Either ClassFileError a
+ Language.JVM.ClassFileReader: writeClassFile :: ClassFile High -> ByteString
+ Language.JVM.ClassFileReader: writeClassFile' :: ConstantPool Low -> ClassFile High -> ByteString
+ Language.JVM.Constant: AbsInterfaceMethodId :: InClass MethodId r -> AbsInterfaceMethodId r
+ Language.JVM.Constant: CClassRef :: !(Ref Text r) -> Constant r
+ Language.JVM.Constant: CDouble :: !Double -> Constant r
+ Language.JVM.Constant: CFieldRef :: !(InClass FieldId r) -> Constant r
+ Language.JVM.Constant: CFloat :: !Float -> Constant r
+ Language.JVM.Constant: CInteger :: !Int32 -> Constant r
+ Language.JVM.Constant: CInterfaceMethodRef :: !(InClass MethodId r) -> Constant r
+ Language.JVM.Constant: CInvokeDynamic :: !(InvokeDynamic r) -> Constant r
+ Language.JVM.Constant: CLong :: !Int64 -> Constant r
+ Language.JVM.Constant: CMethodHandle :: !(MethodHandle r) -> Constant r
+ Language.JVM.Constant: CMethodRef :: !(InClass MethodId r) -> Constant r
+ Language.JVM.Constant: CMethodType :: !(Ref MethodDescriptor r) -> Constant r
+ Language.JVM.Constant: CNameAndType :: !(Ref Text r) -> !(Ref Text r) -> Constant r
+ Language.JVM.Constant: CString :: !SizedByteString16 -> Constant r
+ Language.JVM.Constant: CStringRef :: !(Ref ByteString r) -> Constant r
+ Language.JVM.Constant: ClassName :: Text -> ClassName
+ Language.JVM.Constant: FieldId :: (NameAndType FieldDescriptor) -> FieldId
+ Language.JVM.Constant: InClass :: !(Ref ClassName r) -> !(Ref a r) -> InClass a r
+ Language.JVM.Constant: MHField :: !(MethodHandleField r) -> MethodHandle r
+ Language.JVM.Constant: MHGetField :: MethodHandleFieldKind
+ Language.JVM.Constant: MHGetStatic :: MethodHandleFieldKind
+ Language.JVM.Constant: MHInterface :: !(MethodHandleInterface r) -> MethodHandle r
+ Language.JVM.Constant: MHInvokeSpecial :: !(DeepRef AbsVariableMethodId r) -> MethodHandleMethod r
+ Language.JVM.Constant: MHInvokeStatic :: !(DeepRef AbsVariableMethodId r) -> MethodHandleMethod r
+ Language.JVM.Constant: MHInvokeVirtual :: !(DeepRef AbsMethodId r) -> MethodHandleMethod r
+ Language.JVM.Constant: MHMethod :: !(MethodHandleMethod r) -> MethodHandle r
+ Language.JVM.Constant: MHNewInvokeSpecial :: !(DeepRef AbsMethodId r) -> MethodHandleMethod r
+ Language.JVM.Constant: MHPutField :: MethodHandleFieldKind
+ Language.JVM.Constant: MHPutStatic :: MethodHandleFieldKind
+ Language.JVM.Constant: MethodHandleField :: !MethodHandleFieldKind -> !(DeepRef AbsFieldId r) -> MethodHandleField r
+ Language.JVM.Constant: MethodHandleInterface :: !(DeepRef AbsInterfaceMethodId r) -> MethodHandleInterface r
+ Language.JVM.Constant: MethodId :: (NameAndType MethodDescriptor) -> MethodId
+ Language.JVM.Constant: VClass :: ClassName -> JValue
+ Language.JVM.Constant: VDouble :: Double -> JValue
+ Language.JVM.Constant: VFloat :: Float -> JValue
+ Language.JVM.Constant: VInteger :: Int32 -> JValue
+ Language.JVM.Constant: VInterfaceMethodId :: !(AbsInterfaceMethodId r) -> AbsVariableMethodId r
+ Language.JVM.Constant: VLong :: Int64 -> JValue
+ Language.JVM.Constant: VMethodHandle :: (MethodHandle High) -> JValue
+ Language.JVM.Constant: VMethodId :: !(AbsMethodId r) -> AbsVariableMethodId r
+ Language.JVM.Constant: VMethodType :: (MethodDescriptor) -> JValue
+ Language.JVM.Constant: VString :: ByteString -> JValue
+ Language.JVM.Constant: [classNameAsText] :: ClassName -> Text
+ Language.JVM.Constant: [inClassId] :: InClass a r -> !(Ref a r)
+ Language.JVM.Constant: [inClassName] :: InClass a r -> !(Ref ClassName r)
+ Language.JVM.Constant: [interfaceMethodId] :: AbsInterfaceMethodId r -> InClass MethodId r
+ Language.JVM.Constant: [invokeDynamicAttrIndex] :: InvokeDynamic r -> !Word16
+ Language.JVM.Constant: [invokeDynamicMethod] :: InvokeDynamic r -> !(Ref MethodId r)
+ Language.JVM.Constant: [methodHandleFieldKind] :: MethodHandleField r -> !MethodHandleFieldKind
+ Language.JVM.Constant: [methodHandleFieldRef] :: MethodHandleField r -> !(DeepRef AbsFieldId r)
+ Language.JVM.Constant: [methodHandleInterfaceRef] :: MethodHandleInterface r -> !(DeepRef AbsInterfaceMethodId r)
+ Language.JVM.Constant: [ntDescriptor] :: NameAndType a -> a
+ Language.JVM.Constant: [ntName] :: NameAndType a -> Text
+ Language.JVM.Constant: class Referenceable a
+ Language.JVM.Constant: data AbsVariableMethodId r
+ Language.JVM.Constant: data FieldDescriptor
+ Language.JVM.Constant: data High
+ Language.JVM.Constant: data InClass a r
+ Language.JVM.Constant: data InvokeDynamic r
+ Language.JVM.Constant: data JValue
+ Language.JVM.Constant: data Low
+ Language.JVM.Constant: data MethodDescriptor
+ Language.JVM.Constant: data MethodHandle r
+ Language.JVM.Constant: data MethodHandleField r
+ Language.JVM.Constant: data MethodHandleFieldKind
+ Language.JVM.Constant: data MethodHandleInterface r
+ Language.JVM.Constant: data MethodHandleMethod r
+ Language.JVM.Constant: data NameAndType a
+ Language.JVM.Constant: fromConst :: (Referenceable a, (Monad m)) => (forall a'. String -> m a') -> Constant High -> m a
+ Language.JVM.Constant: instance Control.DeepSeq.NFData (Language.JVM.Constant.AbsInterfaceMethodId Language.JVM.Stage.High)
+ Language.JVM.Constant: instance Control.DeepSeq.NFData (Language.JVM.Constant.AbsInterfaceMethodId Language.JVM.Stage.Low)
+ 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 Control.DeepSeq.NFData (Language.JVM.Constant.Constant Language.JVM.Stage.High)
+ Language.JVM.Constant: instance Control.DeepSeq.NFData (Language.JVM.Constant.Constant Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance Control.DeepSeq.NFData (Language.JVM.Constant.InClass Language.JVM.Constant.FieldId Language.JVM.Stage.High)
+ Language.JVM.Constant: instance Control.DeepSeq.NFData (Language.JVM.Constant.InClass Language.JVM.Constant.FieldId Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance Control.DeepSeq.NFData (Language.JVM.Constant.InClass Language.JVM.Constant.MethodId Language.JVM.Stage.High)
+ Language.JVM.Constant: instance Control.DeepSeq.NFData (Language.JVM.Constant.InClass Language.JVM.Constant.MethodId Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance Control.DeepSeq.NFData (Language.JVM.Constant.InvokeDynamic Language.JVM.Stage.High)
+ Language.JVM.Constant: instance Control.DeepSeq.NFData (Language.JVM.Constant.InvokeDynamic Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance Control.DeepSeq.NFData (Language.JVM.Constant.MethodHandle Language.JVM.Stage.High)
+ Language.JVM.Constant: instance Control.DeepSeq.NFData (Language.JVM.Constant.MethodHandle Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance Control.DeepSeq.NFData (Language.JVM.Constant.MethodHandleField Language.JVM.Stage.High)
+ Language.JVM.Constant: instance Control.DeepSeq.NFData (Language.JVM.Constant.MethodHandleField Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance Control.DeepSeq.NFData (Language.JVM.Constant.MethodHandleInterface Language.JVM.Stage.High)
+ Language.JVM.Constant: instance Control.DeepSeq.NFData (Language.JVM.Constant.MethodHandleInterface Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance Control.DeepSeq.NFData (Language.JVM.Constant.MethodHandleMethod Language.JVM.Stage.High)
+ Language.JVM.Constant: instance Control.DeepSeq.NFData (Language.JVM.Constant.MethodHandleMethod Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance Control.DeepSeq.NFData Language.JVM.Constant.FieldId
+ Language.JVM.Constant: instance Control.DeepSeq.NFData Language.JVM.Constant.JValue
+ Language.JVM.Constant: instance Control.DeepSeq.NFData Language.JVM.Constant.MethodHandleFieldKind
+ Language.JVM.Constant: instance Control.DeepSeq.NFData Language.JVM.Constant.MethodId
+ Language.JVM.Constant: instance Data.Binary.Class.Binary (Language.JVM.Constant.AbsInterfaceMethodId Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance Data.Binary.Class.Binary (Language.JVM.Constant.AbsVariableMethodId Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance Data.Binary.Class.Binary (Language.JVM.Constant.Constant Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance Data.Binary.Class.Binary (Language.JVM.Constant.InClass Language.JVM.Constant.FieldId Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance Data.Binary.Class.Binary (Language.JVM.Constant.InClass Language.JVM.Constant.MethodId Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance Data.Binary.Class.Binary (Language.JVM.Constant.InvokeDynamic Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance Data.Binary.Class.Binary (Language.JVM.Constant.MethodHandle Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance Data.String.IsString Language.JVM.Constant.FieldId
+ Language.JVM.Constant: instance Data.String.IsString Language.JVM.Constant.MethodId
+ Language.JVM.Constant: instance GHC.Classes.Eq (Language.JVM.Constant.AbsInterfaceMethodId Language.JVM.Stage.High)
+ Language.JVM.Constant: instance GHC.Classes.Eq (Language.JVM.Constant.AbsInterfaceMethodId 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.Eq (Language.JVM.Constant.Constant Language.JVM.Stage.High)
+ Language.JVM.Constant: instance GHC.Classes.Eq (Language.JVM.Constant.Constant Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Classes.Eq (Language.JVM.Constant.InClass Language.JVM.Constant.FieldId Language.JVM.Stage.High)
+ Language.JVM.Constant: instance GHC.Classes.Eq (Language.JVM.Constant.InClass Language.JVM.Constant.FieldId Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Classes.Eq (Language.JVM.Constant.InClass Language.JVM.Constant.MethodId Language.JVM.Stage.High)
+ Language.JVM.Constant: instance GHC.Classes.Eq (Language.JVM.Constant.InClass Language.JVM.Constant.MethodId Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Classes.Eq (Language.JVM.Constant.InvokeDynamic Language.JVM.Stage.High)
+ Language.JVM.Constant: instance GHC.Classes.Eq (Language.JVM.Constant.InvokeDynamic Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Classes.Eq (Language.JVM.Constant.MethodHandle Language.JVM.Stage.High)
+ Language.JVM.Constant: instance GHC.Classes.Eq (Language.JVM.Constant.MethodHandle Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Classes.Eq (Language.JVM.Constant.MethodHandleField Language.JVM.Stage.High)
+ Language.JVM.Constant: instance GHC.Classes.Eq (Language.JVM.Constant.MethodHandleField Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Classes.Eq (Language.JVM.Constant.MethodHandleInterface Language.JVM.Stage.High)
+ Language.JVM.Constant: instance GHC.Classes.Eq (Language.JVM.Constant.MethodHandleInterface Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Classes.Eq (Language.JVM.Constant.MethodHandleMethod Language.JVM.Stage.High)
+ Language.JVM.Constant: instance GHC.Classes.Eq (Language.JVM.Constant.MethodHandleMethod Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Classes.Eq Language.JVM.Constant.FieldId
+ Language.JVM.Constant: instance GHC.Classes.Eq Language.JVM.Constant.JValue
+ Language.JVM.Constant: instance GHC.Classes.Eq Language.JVM.Constant.MethodHandleFieldKind
+ Language.JVM.Constant: instance GHC.Classes.Eq Language.JVM.Constant.MethodId
+ Language.JVM.Constant: instance GHC.Classes.Ord (Language.JVM.Constant.AbsInterfaceMethodId Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Classes.Ord (Language.JVM.Constant.AbsVariableMethodId Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Classes.Ord (Language.JVM.Constant.Constant Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Classes.Ord (Language.JVM.Constant.InClass Language.JVM.Constant.FieldId Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Classes.Ord (Language.JVM.Constant.InClass Language.JVM.Constant.MethodId Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Classes.Ord (Language.JVM.Constant.InvokeDynamic Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Classes.Ord (Language.JVM.Constant.MethodHandle Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Classes.Ord (Language.JVM.Constant.MethodHandleField Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Classes.Ord (Language.JVM.Constant.MethodHandleInterface Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Classes.Ord (Language.JVM.Constant.MethodHandleMethod Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Classes.Ord Language.JVM.Constant.FieldId
+ Language.JVM.Constant: instance GHC.Classes.Ord Language.JVM.Constant.MethodHandleFieldKind
+ Language.JVM.Constant: instance GHC.Classes.Ord Language.JVM.Constant.MethodId
+ Language.JVM.Constant: instance GHC.Generics.Generic (Language.JVM.Constant.AbsInterfaceMethodId Language.JVM.Stage.High)
+ Language.JVM.Constant: instance GHC.Generics.Generic (Language.JVM.Constant.AbsInterfaceMethodId 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.Generics.Generic (Language.JVM.Constant.Constant Language.JVM.Stage.High)
+ Language.JVM.Constant: instance GHC.Generics.Generic (Language.JVM.Constant.Constant Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Generics.Generic (Language.JVM.Constant.InClass Language.JVM.Constant.FieldId Language.JVM.Stage.High)
+ Language.JVM.Constant: instance GHC.Generics.Generic (Language.JVM.Constant.InClass Language.JVM.Constant.FieldId Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Generics.Generic (Language.JVM.Constant.InClass Language.JVM.Constant.MethodId Language.JVM.Stage.High)
+ Language.JVM.Constant: instance GHC.Generics.Generic (Language.JVM.Constant.InClass Language.JVM.Constant.MethodId Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Generics.Generic (Language.JVM.Constant.InvokeDynamic Language.JVM.Stage.High)
+ Language.JVM.Constant: instance GHC.Generics.Generic (Language.JVM.Constant.InvokeDynamic Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Generics.Generic (Language.JVM.Constant.MethodHandle Language.JVM.Stage.High)
+ Language.JVM.Constant: instance GHC.Generics.Generic (Language.JVM.Constant.MethodHandle Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Generics.Generic (Language.JVM.Constant.MethodHandleField Language.JVM.Stage.High)
+ Language.JVM.Constant: instance GHC.Generics.Generic (Language.JVM.Constant.MethodHandleField Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Generics.Generic (Language.JVM.Constant.MethodHandleInterface Language.JVM.Stage.High)
+ Language.JVM.Constant: instance GHC.Generics.Generic (Language.JVM.Constant.MethodHandleInterface Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Generics.Generic (Language.JVM.Constant.MethodHandleMethod Language.JVM.Stage.High)
+ Language.JVM.Constant: instance GHC.Generics.Generic (Language.JVM.Constant.MethodHandleMethod Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Generics.Generic Language.JVM.Constant.FieldId
+ Language.JVM.Constant: instance GHC.Generics.Generic Language.JVM.Constant.JValue
+ Language.JVM.Constant: instance GHC.Generics.Generic Language.JVM.Constant.MethodHandleFieldKind
+ Language.JVM.Constant: instance GHC.Generics.Generic Language.JVM.Constant.MethodId
+ Language.JVM.Constant: instance GHC.Show.Show (Language.JVM.Constant.AbsInterfaceMethodId Language.JVM.Stage.High)
+ Language.JVM.Constant: instance GHC.Show.Show (Language.JVM.Constant.AbsInterfaceMethodId 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 GHC.Show.Show (Language.JVM.Constant.Constant Language.JVM.Stage.High)
+ Language.JVM.Constant: instance GHC.Show.Show (Language.JVM.Constant.Constant Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Show.Show (Language.JVM.Constant.InClass Language.JVM.Constant.FieldId Language.JVM.Stage.High)
+ Language.JVM.Constant: instance GHC.Show.Show (Language.JVM.Constant.InClass Language.JVM.Constant.FieldId Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Show.Show (Language.JVM.Constant.InClass Language.JVM.Constant.MethodId Language.JVM.Stage.High)
+ Language.JVM.Constant: instance GHC.Show.Show (Language.JVM.Constant.InClass Language.JVM.Constant.MethodId Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Show.Show (Language.JVM.Constant.InvokeDynamic Language.JVM.Stage.High)
+ Language.JVM.Constant: instance GHC.Show.Show (Language.JVM.Constant.InvokeDynamic Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Show.Show (Language.JVM.Constant.MethodHandle Language.JVM.Stage.High)
+ Language.JVM.Constant: instance GHC.Show.Show (Language.JVM.Constant.MethodHandle Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Show.Show (Language.JVM.Constant.MethodHandleField Language.JVM.Stage.High)
+ Language.JVM.Constant: instance GHC.Show.Show (Language.JVM.Constant.MethodHandleField Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Show.Show (Language.JVM.Constant.MethodHandleInterface Language.JVM.Stage.High)
+ Language.JVM.Constant: instance GHC.Show.Show (Language.JVM.Constant.MethodHandleInterface Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Show.Show (Language.JVM.Constant.MethodHandleMethod Language.JVM.Stage.High)
+ Language.JVM.Constant: instance GHC.Show.Show (Language.JVM.Constant.MethodHandleMethod Language.JVM.Stage.Low)
+ Language.JVM.Constant: instance GHC.Show.Show Language.JVM.Constant.FieldId
+ Language.JVM.Constant: instance GHC.Show.Show Language.JVM.Constant.JValue
+ Language.JVM.Constant: instance GHC.Show.Show Language.JVM.Constant.MethodHandleFieldKind
+ Language.JVM.Constant: instance GHC.Show.Show Language.JVM.Constant.MethodId
+ Language.JVM.Constant: instance Language.JVM.Constant.Referenceable (Language.JVM.Constant.AbsInterfaceMethodId Language.JVM.Stage.High)
+ Language.JVM.Constant: instance Language.JVM.Constant.Referenceable (Language.JVM.Constant.AbsVariableMethodId Language.JVM.Stage.High)
+ Language.JVM.Constant: instance Language.JVM.Constant.Referenceable (Language.JVM.Constant.Constant Language.JVM.Stage.High)
+ Language.JVM.Constant: instance Language.JVM.Constant.Referenceable (Language.JVM.Constant.InClass Language.JVM.Constant.FieldId Language.JVM.Stage.High)
+ Language.JVM.Constant: instance Language.JVM.Constant.Referenceable (Language.JVM.Constant.InClass Language.JVM.Constant.MethodId Language.JVM.Stage.High)
+ Language.JVM.Constant: instance Language.JVM.Constant.Referenceable (Language.JVM.Constant.InvokeDynamic Language.JVM.Stage.High)
+ Language.JVM.Constant: instance Language.JVM.Constant.Referenceable (Language.JVM.Constant.MethodHandle Language.JVM.Stage.High)
+ Language.JVM.Constant: instance Language.JVM.Constant.Referenceable Data.ByteString.Internal.ByteString
+ Language.JVM.Constant: instance Language.JVM.Constant.Referenceable Data.Text.Internal.Text
+ Language.JVM.Constant: instance Language.JVM.Constant.Referenceable Language.JVM.Constant.FieldId
+ Language.JVM.Constant: instance Language.JVM.Constant.Referenceable Language.JVM.Constant.JValue
+ Language.JVM.Constant: instance Language.JVM.Constant.Referenceable Language.JVM.Constant.MethodId
+ Language.JVM.Constant: instance Language.JVM.Constant.Referenceable Language.JVM.Type.ClassName
+ Language.JVM.Constant: instance Language.JVM.Constant.Referenceable Language.JVM.Type.FieldDescriptor
+ Language.JVM.Constant: instance Language.JVM.Constant.Referenceable Language.JVM.Type.MethodDescriptor
+ Language.JVM.Constant: instance Language.JVM.Type.TypeParse a => Language.JVM.Constant.Referenceable (Language.JVM.Type.NameAndType a)
+ Language.JVM.Constant: newtype AbsInterfaceMethodId r
+ Language.JVM.Constant: newtype ClassName
+ Language.JVM.Constant: newtype FieldId
+ Language.JVM.Constant: newtype MethodId
+ Language.JVM.Constant: toConst :: (Referenceable a, (Monad m)) => a -> m (Constant High)
+ Language.JVM.Constant: type AbsFieldId = InClass FieldId
+ Language.JVM.Constant: type AbsMethodId = InClass MethodId
+ Language.JVM.Constant: typeToStr :: Constant r -> String
+ Language.JVM.ConstantPool: ConstantPool :: IntMap (Constant r) -> ConstantPool r
+ Language.JVM.ConstantPool: PoolAccessError :: !Word16 -> String -> PoolAccessError
+ Language.JVM.ConstantPool: [paErrorMsg] :: PoolAccessError -> String
+ Language.JVM.ConstantPool: [paErrorRef] :: PoolAccessError -> !Word16
+ Language.JVM.ConstantPool: [unConstantPool] :: ConstantPool r -> IntMap (Constant r)
+ Language.JVM.ConstantPool: access :: Index -> ConstantPool r -> Either PoolAccessError (Constant r)
+ Language.JVM.ConstantPool: append :: Constant r -> ConstantPool r -> (Index, ConstantPool r)
+ Language.JVM.ConstantPool: data PoolAccessError
+ Language.JVM.ConstantPool: empty :: ConstantPool r
+ Language.JVM.ConstantPool: instance Control.DeepSeq.NFData (Language.JVM.ConstantPool.ConstantPool Language.JVM.Stage.High)
+ Language.JVM.ConstantPool: instance Control.DeepSeq.NFData (Language.JVM.ConstantPool.ConstantPool Language.JVM.Stage.Low)
+ Language.JVM.ConstantPool: instance Control.DeepSeq.NFData Language.JVM.ConstantPool.PoolAccessError
+ Language.JVM.ConstantPool: instance Data.Binary.Class.Binary (Language.JVM.ConstantPool.ConstantPool Language.JVM.Stage.Low)
+ Language.JVM.ConstantPool: instance GHC.Classes.Eq (Language.JVM.ConstantPool.ConstantPool Language.JVM.Stage.High)
+ Language.JVM.ConstantPool: instance GHC.Classes.Eq (Language.JVM.ConstantPool.ConstantPool Language.JVM.Stage.Low)
+ Language.JVM.ConstantPool: instance GHC.Classes.Eq Language.JVM.ConstantPool.PoolAccessError
+ Language.JVM.ConstantPool: instance GHC.Classes.Ord (Language.JVM.ConstantPool.ConstantPool Language.JVM.Stage.Low)
+ Language.JVM.ConstantPool: instance GHC.Generics.Generic (Language.JVM.ConstantPool.ConstantPool Language.JVM.Stage.High)
+ Language.JVM.ConstantPool: instance GHC.Generics.Generic (Language.JVM.ConstantPool.ConstantPool Language.JVM.Stage.Low)
+ Language.JVM.ConstantPool: instance GHC.Generics.Generic Language.JVM.ConstantPool.PoolAccessError
+ Language.JVM.ConstantPool: instance GHC.Show.Show (Language.JVM.ConstantPool.ConstantPool Language.JVM.Stage.High)
+ Language.JVM.ConstantPool: instance GHC.Show.Show (Language.JVM.ConstantPool.ConstantPool Language.JVM.Stage.Low)
+ Language.JVM.ConstantPool: instance GHC.Show.Show Language.JVM.ConstantPool.PoolAccessError
+ Language.JVM.ConstantPool: newtype ConstantPool r
+ Language.JVM.Field: FieldAttributes :: [ConstantValue r] -> [Signature r] -> [Attribute r] -> FieldAttributes r
+ Language.JVM.Field: [fAccessFlags'] :: Field r -> !(BitSet16 FAccessFlag)
+ Language.JVM.Field: [fDescriptor] :: Field r -> !(Ref FieldDescriptor r)
+ Language.JVM.Field: [fName] :: Field r -> !(Ref Text r)
+ Language.JVM.Field: [faConstantValues] :: FieldAttributes r -> [ConstantValue r]
+ Language.JVM.Field: [faOthers] :: FieldAttributes r -> [Attribute r]
+ Language.JVM.Field: [faSignatures] :: FieldAttributes r -> [Signature r]
+ Language.JVM.Field: data FieldAttributes r
+ Language.JVM.Field: fAccessFlags :: Field r -> Set FAccessFlag
+ Language.JVM.Field: fSignature :: Field High -> Maybe (Signature High)
+ Language.JVM.Field: instance Control.DeepSeq.NFData (Language.JVM.Field.Field Language.JVM.Stage.High)
+ Language.JVM.Field: instance Control.DeepSeq.NFData (Language.JVM.Field.Field Language.JVM.Stage.Low)
+ Language.JVM.Field: instance Control.DeepSeq.NFData (Language.JVM.Field.FieldAttributes Language.JVM.Stage.High)
+ Language.JVM.Field: instance Control.DeepSeq.NFData (Language.JVM.Field.FieldAttributes Language.JVM.Stage.Low)
+ Language.JVM.Field: instance Data.Binary.Class.Binary (Language.JVM.Field.Field Language.JVM.Stage.Low)
+ Language.JVM.Field: instance GHC.Classes.Eq (Language.JVM.Field.Field Language.JVM.Stage.High)
+ Language.JVM.Field: instance GHC.Classes.Eq (Language.JVM.Field.Field Language.JVM.Stage.Low)
+ Language.JVM.Field: instance GHC.Classes.Eq (Language.JVM.Field.FieldAttributes Language.JVM.Stage.High)
+ Language.JVM.Field: instance GHC.Classes.Eq (Language.JVM.Field.FieldAttributes Language.JVM.Stage.Low)
+ Language.JVM.Field: instance GHC.Classes.Ord (Language.JVM.Field.Field Language.JVM.Stage.Low)
+ Language.JVM.Field: instance GHC.Classes.Ord (Language.JVM.Field.FieldAttributes Language.JVM.Stage.Low)
+ Language.JVM.Field: instance GHC.Generics.Generic (Language.JVM.Field.Field Language.JVM.Stage.High)
+ Language.JVM.Field: instance GHC.Generics.Generic (Language.JVM.Field.Field Language.JVM.Stage.Low)
+ Language.JVM.Field: instance GHC.Generics.Generic (Language.JVM.Field.FieldAttributes Language.JVM.Stage.High)
+ Language.JVM.Field: instance GHC.Generics.Generic (Language.JVM.Field.FieldAttributes Language.JVM.Stage.Low)
+ Language.JVM.Field: instance GHC.Show.Show (Language.JVM.Field.Field Language.JVM.Stage.High)
+ Language.JVM.Field: instance GHC.Show.Show (Language.JVM.Field.Field Language.JVM.Stage.Low)
+ Language.JVM.Field: instance GHC.Show.Show (Language.JVM.Field.FieldAttributes Language.JVM.Stage.High)
+ Language.JVM.Field: instance GHC.Show.Show (Language.JVM.Field.FieldAttributes Language.JVM.Stage.Low)
+ Language.JVM.Field: instance Language.JVM.Staged.Staged Language.JVM.Field.Field
+ Language.JVM.Method: MethodAttributes :: [Code r] -> [Exceptions r] -> [Signature r] -> [Attribute r] -> MethodAttributes r
+ Language.JVM.Method: [mAttributes] :: Method r -> !(Attributes MethodAttributes r)
+ Language.JVM.Method: [mDescriptor] :: Method r -> !(Ref MethodDescriptor r)
+ Language.JVM.Method: [mName] :: Method r -> !(Ref Text r)
+ Language.JVM.Method: [maCode] :: MethodAttributes r -> [Code r]
+ Language.JVM.Method: [maExceptions] :: MethodAttributes r -> [Exceptions r]
+ Language.JVM.Method: [maOthers] :: MethodAttributes r -> [Attribute r]
+ Language.JVM.Method: [maSignatures] :: MethodAttributes r -> [Signature r]
+ Language.JVM.Method: data MethodAttributes r
+ Language.JVM.Method: instance Control.DeepSeq.NFData (Language.JVM.Method.Method Language.JVM.Stage.High)
+ Language.JVM.Method: instance Control.DeepSeq.NFData (Language.JVM.Method.Method Language.JVM.Stage.Low)
+ Language.JVM.Method: instance Control.DeepSeq.NFData (Language.JVM.Method.MethodAttributes Language.JVM.Stage.High)
+ Language.JVM.Method: instance Control.DeepSeq.NFData (Language.JVM.Method.MethodAttributes Language.JVM.Stage.Low)
+ Language.JVM.Method: instance Data.Binary.Class.Binary (Language.JVM.Method.Method Language.JVM.Stage.Low)
+ Language.JVM.Method: instance GHC.Classes.Eq (Language.JVM.Method.Method Language.JVM.Stage.High)
+ Language.JVM.Method: instance GHC.Classes.Eq (Language.JVM.Method.Method Language.JVM.Stage.Low)
+ Language.JVM.Method: instance GHC.Classes.Eq (Language.JVM.Method.MethodAttributes Language.JVM.Stage.High)
+ Language.JVM.Method: instance GHC.Classes.Eq (Language.JVM.Method.MethodAttributes Language.JVM.Stage.Low)
+ Language.JVM.Method: instance GHC.Classes.Ord (Language.JVM.Method.Method Language.JVM.Stage.Low)
+ Language.JVM.Method: instance GHC.Classes.Ord (Language.JVM.Method.MethodAttributes Language.JVM.Stage.Low)
+ Language.JVM.Method: instance GHC.Generics.Generic (Language.JVM.Method.Method Language.JVM.Stage.High)
+ Language.JVM.Method: instance GHC.Generics.Generic (Language.JVM.Method.Method Language.JVM.Stage.Low)
+ Language.JVM.Method: instance GHC.Generics.Generic (Language.JVM.Method.MethodAttributes Language.JVM.Stage.High)
+ Language.JVM.Method: instance GHC.Generics.Generic (Language.JVM.Method.MethodAttributes Language.JVM.Stage.Low)
+ Language.JVM.Method: instance GHC.Show.Show (Language.JVM.Method.Method Language.JVM.Stage.High)
+ Language.JVM.Method: instance GHC.Show.Show (Language.JVM.Method.Method Language.JVM.Stage.Low)
+ Language.JVM.Method: instance GHC.Show.Show (Language.JVM.Method.MethodAttributes Language.JVM.Stage.High)
+ Language.JVM.Method: instance GHC.Show.Show (Language.JVM.Method.MethodAttributes Language.JVM.Stage.Low)
+ Language.JVM.Method: instance Language.JVM.Staged.Staged Language.JVM.Method.Method
+ Language.JVM.Method: mExceptions' :: Method High -> Maybe (Exceptions High)
+ Language.JVM.Method: mSignature :: Method High -> Maybe (Signature High)
+ Language.JVM.Stage: data High
+ Language.JVM.Stage: data Low
+ Language.JVM.Stage: type DeepRef v r = Ref (v r) r
+ Language.JVM.Stage: type Index = Word16
+ Language.JVM.Stage: type Ref v r = Choice Index v r
+ Language.JVM.Staged: attributeError :: EvolveM m => String -> m r
+ Language.JVM.Staged: class LabelM m => DevolveM m
+ Language.JVM.Staged: class LabelM m => EvolveM m
+ Language.JVM.Staged: class Monad m => LabelM m
+ Language.JVM.Staged: class Staged s
+ Language.JVM.Staged: devolve :: (Staged s, DevolveM m) => s High -> m (s Low)
+ Language.JVM.Staged: evolve :: (Staged s, EvolveM m) => s Low -> m (s High)
+ Language.JVM.Staged: instance Language.JVM.Constant.Referenceable r => Language.JVM.Staged.Staged (Language.JVM.Constant.InClass r)
+ Language.JVM.Staged: instance Language.JVM.Staged.Staged Language.JVM.Constant.Constant
+ Language.JVM.Staged: instance Language.JVM.Staged.Staged Language.JVM.Constant.InvokeDynamic
+ Language.JVM.Staged: instance Language.JVM.Staged.Staged Language.JVM.Constant.MethodHandle
+ Language.JVM.Staged: instance Language.JVM.Staged.Staged Language.JVM.Constant.MethodHandleField
+ Language.JVM.Staged: instance Language.JVM.Staged.Staged Language.JVM.Constant.MethodHandleInterface
+ Language.JVM.Staged: instance Language.JVM.Staged.Staged Language.JVM.Constant.MethodHandleMethod
+ Language.JVM.Staged: label :: LabelM m => String -> m a -> m a
+ Language.JVM.Staged: link :: (EvolveM m, Referenceable r) => Index -> m r
+ Language.JVM.Staged: stage :: (Staged s, LabelM m) => (forall s'. Staged s' => s' r -> m (s' r')) -> s r -> m (s r')
+ Language.JVM.Staged: unlink :: (DevolveM m, Referenceable r) => r -> m Index
+ Language.JVM.TH: deriveBase :: Name -> Q [Dec]
+ Language.JVM.TH: deriveBaseWithBinary :: Name -> Q [Dec]
+ Language.JVM.TH: deriveBases :: [Name] -> Q [Dec]
+ Language.JVM.Type: (<:>) :: Text -> a -> NameAndType a
+ Language.JVM.Type: ClassName :: Text -> ClassName
+ Language.JVM.Type: FieldDescriptor :: JType -> FieldDescriptor
+ Language.JVM.Type: JTArray :: JType -> JType
+ Language.JVM.Type: JTBase :: JBaseType -> JType
+ Language.JVM.Type: JTBoolean :: JBaseType
+ Language.JVM.Type: JTByte :: JBaseType
+ Language.JVM.Type: JTChar :: JBaseType
+ Language.JVM.Type: JTClass :: ClassName -> JType
+ Language.JVM.Type: JTDouble :: JBaseType
+ Language.JVM.Type: JTFloat :: JBaseType
+ Language.JVM.Type: JTInt :: JBaseType
+ Language.JVM.Type: JTLong :: JBaseType
+ Language.JVM.Type: JTShort :: JBaseType
+ Language.JVM.Type: MethodDescriptor :: [JType] -> Maybe JType -> MethodDescriptor
+ Language.JVM.Type: NameAndType :: Text -> a -> NameAndType a
+ Language.JVM.Type: [classNameAsText] :: ClassName -> Text
+ Language.JVM.Type: [fieldDescriptorType] :: FieldDescriptor -> JType
+ Language.JVM.Type: [methodDescriptorArguments] :: MethodDescriptor -> [JType]
+ Language.JVM.Type: [methodDescriptorReturnType] :: MethodDescriptor -> Maybe JType
+ Language.JVM.Type: [ntDescriptor] :: NameAndType a -> a
+ Language.JVM.Type: [ntName] :: NameAndType a -> Text
+ Language.JVM.Type: class TypeParse a
+ Language.JVM.Type: data JBaseType
+ Language.JVM.Type: data JType
+ Language.JVM.Type: data MethodDescriptor
+ Language.JVM.Type: data NameAndType a
+ Language.JVM.Type: dotCls :: Text -> ClassName
+ Language.JVM.Type: fromText :: TypeParse a => Text -> Either String a
+ Language.JVM.Type: instance Control.DeepSeq.NFData Language.JVM.Type.ClassName
+ Language.JVM.Type: instance Control.DeepSeq.NFData Language.JVM.Type.FieldDescriptor
+ Language.JVM.Type: instance Control.DeepSeq.NFData Language.JVM.Type.JBaseType
+ Language.JVM.Type: instance Control.DeepSeq.NFData Language.JVM.Type.JType
+ Language.JVM.Type: instance Control.DeepSeq.NFData Language.JVM.Type.MethodDescriptor
+ Language.JVM.Type: instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Language.JVM.Type.NameAndType a)
+ Language.JVM.Type: instance Data.String.IsString Language.JVM.Type.ClassName
+ Language.JVM.Type: instance Data.String.IsString Language.JVM.Type.FieldDescriptor
+ Language.JVM.Type: instance Data.String.IsString Language.JVM.Type.JType
+ Language.JVM.Type: instance Data.String.IsString Language.JVM.Type.MethodDescriptor
+ Language.JVM.Type: instance GHC.Classes.Eq Language.JVM.Type.ClassName
+ Language.JVM.Type: instance GHC.Classes.Eq Language.JVM.Type.FieldDescriptor
+ Language.JVM.Type: instance GHC.Classes.Eq Language.JVM.Type.JBaseType
+ Language.JVM.Type: instance GHC.Classes.Eq Language.JVM.Type.JType
+ Language.JVM.Type: instance GHC.Classes.Eq Language.JVM.Type.MethodDescriptor
+ Language.JVM.Type: instance GHC.Classes.Eq a => GHC.Classes.Eq (Language.JVM.Type.NameAndType a)
+ Language.JVM.Type: instance GHC.Classes.Ord Language.JVM.Type.ClassName
+ Language.JVM.Type: instance GHC.Classes.Ord Language.JVM.Type.FieldDescriptor
+ Language.JVM.Type: instance GHC.Classes.Ord Language.JVM.Type.JBaseType
+ Language.JVM.Type: instance GHC.Classes.Ord Language.JVM.Type.JType
+ Language.JVM.Type: instance GHC.Classes.Ord Language.JVM.Type.MethodDescriptor
+ Language.JVM.Type: instance GHC.Classes.Ord a => GHC.Classes.Ord (Language.JVM.Type.NameAndType a)
+ Language.JVM.Type: instance GHC.Generics.Generic (Language.JVM.Type.NameAndType a)
+ Language.JVM.Type: instance GHC.Generics.Generic Language.JVM.Type.ClassName
+ Language.JVM.Type: instance GHC.Generics.Generic Language.JVM.Type.FieldDescriptor
+ Language.JVM.Type: instance GHC.Generics.Generic Language.JVM.Type.JBaseType
+ Language.JVM.Type: instance GHC.Generics.Generic Language.JVM.Type.JType
+ Language.JVM.Type: instance GHC.Generics.Generic Language.JVM.Type.MethodDescriptor
+ Language.JVM.Type: instance GHC.Show.Show Language.JVM.Type.ClassName
+ Language.JVM.Type: instance GHC.Show.Show Language.JVM.Type.FieldDescriptor
+ Language.JVM.Type: instance GHC.Show.Show Language.JVM.Type.JBaseType
+ Language.JVM.Type: instance GHC.Show.Show Language.JVM.Type.JType
+ Language.JVM.Type: instance GHC.Show.Show Language.JVM.Type.MethodDescriptor
+ Language.JVM.Type: instance GHC.Show.Show a => GHC.Show.Show (Language.JVM.Type.NameAndType a)
+ Language.JVM.Type: instance Language.JVM.Type.TypeParse Language.JVM.Type.FieldDescriptor
+ Language.JVM.Type: instance Language.JVM.Type.TypeParse Language.JVM.Type.JType
+ Language.JVM.Type: instance Language.JVM.Type.TypeParse Language.JVM.Type.MethodDescriptor
+ Language.JVM.Type: instance Language.JVM.Type.TypeParse t => Data.String.IsString (Language.JVM.Type.NameAndType t)
+ Language.JVM.Type: instance Language.JVM.Type.TypeParse t => Language.JVM.Type.TypeParse (Language.JVM.Type.NameAndType t)
+ Language.JVM.Type: newtype ClassName
+ Language.JVM.Type: newtype FieldDescriptor
+ Language.JVM.Type: parseText :: TypeParse a => Parser a
+ Language.JVM.Type: strCls :: String -> ClassName
+ Language.JVM.Type: toText :: TypeParse a => a -> Text
+ Language.JVM.Utils: instance (GHC.Show.Show w, Data.Bits.Bits w, Data.Binary.Class.Binary w, Language.JVM.Utils.Enumish a) => Data.Binary.Class.Binary (Language.JVM.Utils.BitSet w a)
+ Language.JVM.Utils: instance Control.DeepSeq.NFData (Language.JVM.Utils.SizedByteString w)
+ Language.JVM.Utils: instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Language.JVM.Utils.BitSet w a)
+ Language.JVM.Utils: instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Language.JVM.Utils.SizedList w a)
+ Language.JVM.Utils: instance Data.String.IsString (Language.JVM.Utils.SizedByteString w)
+ Language.JVM.Utils: instance GHC.Classes.Ord (Language.JVM.Utils.SizedByteString w)
+ Language.JVM.Utils: instance GHC.Classes.Ord a => GHC.Classes.Ord (Language.JVM.Utils.SizedList w a)
+ Language.JVM.Utils: sizedByteStringFromText :: Text -> SizedByteString w
+ Language.JVM.Utils: sizedByteStringToText :: SizedByteString w -> Either UnicodeException Text
+ Language.JVM.Utils: tryDecode :: ByteString -> Either UnicodeException Text
- Language.JVM.Attribute: data BootstrapMethods
+ Language.JVM.Attribute: data BootstrapMethods r
- Language.JVM.Attribute: data ConstantValue
+ Language.JVM.Attribute: data ConstantValue r
- Language.JVM.Attribute: data Exceptions
+ Language.JVM.Attribute: data Exceptions r
- Language.JVM.Attribute: data StackMapTable
+ Language.JVM.Attribute: data StackMapTable r
- Language.JVM.Attribute.BootstrapMethods: BootstrapMethod :: ConstantRef -> SizedList16 ConstantRef -> BootstrapMethod
+ Language.JVM.Attribute.BootstrapMethods: BootstrapMethod :: !(DeepRef MethodHandle r) -> !(SizedList16 (Ref JValue r)) -> BootstrapMethod r
- Language.JVM.Attribute.BootstrapMethods: BootstrapMethods :: SizedList16 BootstrapMethod -> BootstrapMethods
+ Language.JVM.Attribute.BootstrapMethods: BootstrapMethods :: SizedList16 (BootstrapMethod r) -> BootstrapMethods r
- Language.JVM.Attribute.BootstrapMethods: [methods'] :: BootstrapMethods -> SizedList16 BootstrapMethod
+ Language.JVM.Attribute.BootstrapMethods: [methods'] :: BootstrapMethods r -> SizedList16 (BootstrapMethod r)
- Language.JVM.Attribute.BootstrapMethods: data BootstrapMethod
+ Language.JVM.Attribute.BootstrapMethods: data BootstrapMethod r
- Language.JVM.Attribute.BootstrapMethods: methods :: BootstrapMethods -> [BootstrapMethod]
+ Language.JVM.Attribute.BootstrapMethods: methods :: BootstrapMethods r -> [BootstrapMethod r]
- Language.JVM.Attribute.Code: Code :: Int16 -> Int16 -> ByteCode -> SizedList16 ExceptionTable -> SizedList16 a -> Code a
+ Language.JVM.Attribute.Code: Code :: !(Word16) -> !(Word16) -> !((ByteCode r)) -> !(SizedList16 (ExceptionTable r)) -> !(Attributes CodeAttributes r) -> Code r
- Language.JVM.Attribute.Code: ExceptionTable :: !Word16 -> !Word16 -> !Word16 -> !ConstantRef -> ExceptionTable
+ Language.JVM.Attribute.Code: ExceptionTable :: !(ByteCodeRef r) -> !(ByteCodeRef r) -> !(ByteCodeRef r) -> !(Ref (Maybe ClassName) r) -> ExceptionTable r
- Language.JVM.Attribute.Code: [catchType] :: ExceptionTable -> !ConstantRef
+ Language.JVM.Attribute.Code: [catchType] :: ExceptionTable r -> !(Ref (Maybe ClassName) r)
- Language.JVM.Attribute.Code: [end] :: ExceptionTable -> !Word16
+ Language.JVM.Attribute.Code: [end] :: ExceptionTable r -> !(ByteCodeRef r)
- Language.JVM.Attribute.Code: [handler] :: ExceptionTable -> !Word16
+ Language.JVM.Attribute.Code: [handler] :: ExceptionTable r -> !(ByteCodeRef r)
- Language.JVM.Attribute.Code: [start] :: ExceptionTable -> !Word16
+ Language.JVM.Attribute.Code: [start] :: ExceptionTable r -> !(ByteCodeRef r)
- Language.JVM.Attribute.Code: data Code a
+ Language.JVM.Attribute.Code: data Code r
- Language.JVM.Attribute.Code: data ExceptionTable
+ Language.JVM.Attribute.Code: data ExceptionTable r
- Language.JVM.Attribute.ConstantValue: ConstantValue :: !ConstantRef -> ConstantValue
+ Language.JVM.Attribute.ConstantValue: ConstantValue :: !(Ref JValue r) -> ConstantValue r
- Language.JVM.Attribute.ConstantValue: data ConstantValue
+ Language.JVM.Attribute.ConstantValue: data ConstantValue r
- Language.JVM.Attribute.Exceptions: Exceptions :: SizedList16 ConstantRef -> Exceptions
+ Language.JVM.Attribute.Exceptions: Exceptions :: SizedList16 (Ref ClassName r) -> Exceptions r
- Language.JVM.Attribute.StackMapTable: AppendFrame :: [VerificationTypeInfo] -> StackMapFrameType
+ Language.JVM.Attribute.StackMapTable: AppendFrame :: [VerificationTypeInfo r] -> StackMapFrameType r
- Language.JVM.Attribute.StackMapTable: ChopFrame :: Word8 -> StackMapFrameType
+ Language.JVM.Attribute.StackMapTable: ChopFrame :: Word8 -> StackMapFrameType r
- Language.JVM.Attribute.StackMapTable: FullFrame :: (SizedList16 VerificationTypeInfo) -> (SizedList16 VerificationTypeInfo) -> StackMapFrameType
+ Language.JVM.Attribute.StackMapTable: FullFrame :: (SizedList16 (VerificationTypeInfo r)) -> (SizedList16 (VerificationTypeInfo r)) -> StackMapFrameType r
- Language.JVM.Attribute.StackMapTable: SameFrame :: StackMapFrameType
+ Language.JVM.Attribute.StackMapTable: SameFrame :: StackMapFrameType r
- Language.JVM.Attribute.StackMapTable: SameLocals1StackItemFrame :: VerificationTypeInfo -> StackMapFrameType
+ Language.JVM.Attribute.StackMapTable: SameLocals1StackItemFrame :: (VerificationTypeInfo r) -> StackMapFrameType r
- Language.JVM.Attribute.StackMapTable: StackMapFrame :: DeltaOffset -> StackMapFrameType -> StackMapFrame
+ Language.JVM.Attribute.StackMapTable: StackMapFrame :: DeltaOffset r -> StackMapFrameType r -> StackMapFrame r
- Language.JVM.Attribute.StackMapTable: StackMapTable :: SizedList16 StackMapFrame -> StackMapTable
+ Language.JVM.Attribute.StackMapTable: StackMapTable :: Choice (SizedList16 (StackMapFrame Low)) [StackMapFrame High] r -> StackMapTable r
- Language.JVM.Attribute.StackMapTable: [deltaOffset] :: StackMapFrame -> DeltaOffset
+ Language.JVM.Attribute.StackMapTable: [deltaOffset] :: StackMapFrame r -> DeltaOffset r
- Language.JVM.Attribute.StackMapTable: [frameType] :: StackMapFrame -> StackMapFrameType
+ Language.JVM.Attribute.StackMapTable: [frameType] :: StackMapFrame r -> StackMapFrameType r
- Language.JVM.Attribute.StackMapTable: [stackMapTable] :: StackMapTable -> SizedList16 StackMapFrame
+ Language.JVM.Attribute.StackMapTable: [stackMapTable] :: StackMapTable r -> Choice (SizedList16 (StackMapFrame Low)) [StackMapFrame High] r
- Language.JVM.Attribute.StackMapTable: data StackMapFrame
+ Language.JVM.Attribute.StackMapTable: data StackMapFrame r
- Language.JVM.Attribute.StackMapTable: data StackMapFrameType
+ Language.JVM.Attribute.StackMapTable: data StackMapFrameType r
- Language.JVM.Attribute.StackMapTable: data VerificationTypeInfo
+ Language.JVM.Attribute.StackMapTable: data VerificationTypeInfo r
- Language.JVM.Attribute.StackMapTable: type DeltaOffset = Word8
+ Language.JVM.Attribute.StackMapTable: type DeltaOffset i = Choice Word16 Int i
- Language.JVM.ClassFile: ClassFile :: !Word32 -> !Word16 -> !Word16 -> !ConstantPool -> BitSet16 CAccessFlag -> !ConstantRef -> !ConstantRef -> SizedList16 ConstantRef -> SizedList16 Field -> SizedList16 Method -> SizedList16 Attribute -> ClassFile
+ Language.JVM.ClassFile: ClassFile :: !Word32 -> !Word16 -> !Word16 -> !(Choice (ConstantPool r) () r) -> !(BitSet16 CAccessFlag) -> !(Ref ClassName r) -> !(Ref ClassName r) -> !(SizedList16 (Ref ClassName r)) -> !(SizedList16 (Field r)) -> !(SizedList16 (Method r)) -> !(Attributes ClassAttributes r) -> ClassFile r
- Language.JVM.ClassFile: [cConstantPool] :: ClassFile -> !ConstantPool
+ Language.JVM.ClassFile: [cConstantPool] :: ClassFile r -> !(Choice (ConstantPool r) () r)
- Language.JVM.ClassFile: [cFields'] :: ClassFile -> SizedList16 Field
+ Language.JVM.ClassFile: [cFields'] :: ClassFile r -> !(SizedList16 (Field r))
- Language.JVM.ClassFile: [cMagicNumber] :: ClassFile -> !Word32
+ Language.JVM.ClassFile: [cMagicNumber] :: ClassFile r -> !Word32
- Language.JVM.ClassFile: [cMajorVersion] :: ClassFile -> !Word16
+ Language.JVM.ClassFile: [cMajorVersion] :: ClassFile r -> !Word16
- Language.JVM.ClassFile: [cMethods'] :: ClassFile -> SizedList16 Method
+ Language.JVM.ClassFile: [cMethods'] :: ClassFile r -> !(SizedList16 (Method r))
- Language.JVM.ClassFile: [cMinorVersion] :: ClassFile -> !Word16
+ Language.JVM.ClassFile: [cMinorVersion] :: ClassFile r -> !Word16
- Language.JVM.ClassFile: cBootstrapMethods :: ConstantPool -> ClassFile -> Maybe (Either String BootstrapMethods)
+ Language.JVM.ClassFile: cBootstrapMethods :: ClassFile High -> [BootstrapMethod High]
- Language.JVM.ClassFile: cFields :: ClassFile -> [Field]
+ Language.JVM.ClassFile: cFields :: ClassFile r -> [Field r]
- Language.JVM.ClassFile: cMethods :: ClassFile -> [Method]
+ Language.JVM.ClassFile: cMethods :: ClassFile r -> [Method r]
- Language.JVM.ClassFile: data ClassFile
+ Language.JVM.ClassFile: data ClassFile r
- Language.JVM.Constant: InvokeDynamic :: !ConstantRef -> !ConstantRef -> Constant
+ Language.JVM.Constant: InvokeDynamic :: !Word16 -> !(Ref MethodId r) -> InvokeDynamic r
- Language.JVM.Constant: NameAndType :: !ConstantRef -> !ConstantRef -> Constant
+ Language.JVM.Constant: NameAndType :: Text -> a -> NameAndType a
- Language.JVM.Constant: constantSize :: Constant -> Int
+ Language.JVM.Constant: constantSize :: Constant r -> Int
- Language.JVM.Constant: data Constant
+ Language.JVM.Constant: data Constant r
- Language.JVM.Field: Field :: BitSet16 FAccessFlag -> !ConstantRef -> !ConstantRef -> SizedList16 Attribute -> Field
+ Language.JVM.Field: Field :: !(BitSet16 FAccessFlag) -> !(Ref Text r) -> !(Ref FieldDescriptor r) -> !(Attributes FieldAttributes r) -> Field r
- Language.JVM.Field: [fAttributes] :: Field -> SizedList16 Attribute
+ Language.JVM.Field: [fAttributes] :: Field r -> !(Attributes FieldAttributes r)
- Language.JVM.Field: data Field
+ Language.JVM.Field: data Field r
- Language.JVM.Field: fConstantValue :: ConstantPool -> Field -> Maybe (Either String ConstantValue)
+ Language.JVM.Field: fConstantValue :: Field High -> Maybe (ConstantValue High)
- Language.JVM.Method: Method :: BitSet16 MAccessFlag -> !ConstantRef -> !ConstantRef -> SizedList16 Attribute -> Method
+ Language.JVM.Method: Method :: !(BitSet16 MAccessFlag) -> !(Ref Text r) -> !(Ref MethodDescriptor r) -> !(Attributes MethodAttributes r) -> Method r
- Language.JVM.Method: [mAccessFlags'] :: Method -> BitSet16 MAccessFlag
+ Language.JVM.Method: [mAccessFlags'] :: Method r -> !(BitSet16 MAccessFlag)
- Language.JVM.Method: data Method
+ Language.JVM.Method: data Method r
- Language.JVM.Method: mAccessFlags :: Method -> Set MAccessFlag
+ Language.JVM.Method: mAccessFlags :: Method r -> Set MAccessFlag
- Language.JVM.Method: mCode :: ConstantPool -> Method -> Maybe (Either String Code)
+ Language.JVM.Method: mCode :: Method High -> Maybe (Code High)
- Language.JVM.Method: mExceptions :: ConstantPool -> Method -> Maybe (Either String Exceptions)
+ Language.JVM.Method: mExceptions :: Method High -> [ClassName]
- Language.JVM.Utils: class (Eq a, Ord a) => Enumish a where fromEnumish a = let Just (i, _) = find ((== a) . snd) $ inOrder in i toEnumish i = snd <$> (find ((== i) . fst) $ inOrder)
+ Language.JVM.Utils: class (Eq a, Ord a) => Enumish a
Files
- CHANGELOG.md +12/−1
- README.md +21/−6
- benchmark/Main.hs +55/−5
- jvm-binary.cabal +67/−18
- package.yaml +22/−19
- src/Language/JVM.hs +16/−13
- src/Language/JVM/AccessFlag.hs +16/−13
- src/Language/JVM/Attribute.hs +10/−115
- src/Language/JVM/Attribute/Base.hs +160/−0
- src/Language/JVM/Attribute/BootstrapMethods.hs +33/−21
- src/Language/JVM/Attribute/Code.hs +105/−633
- src/Language/JVM/Attribute/ConstantValue.hs +22/−8
- src/Language/JVM/Attribute/Exceptions.hs +20/−14
- src/Language/JVM/Attribute/LineNumberTable.hs +79/−0
- src/Language/JVM/Attribute/Signature.hs +97/−0
- src/Language/JVM/Attribute/StackMapTable.hs +153/−68
- src/Language/JVM/ByteCode.hs +1322/−0
- src/Language/JVM/ClassFile.hs +114/−47
- src/Language/JVM/ClassFileReader.hs +225/−0
- src/Language/JVM/Constant.hs +422/−131
- src/Language/JVM/ConstantPool.hs +105/−0
- src/Language/JVM/Field.hs +69/−18
- src/Language/JVM/Method.hs +82/−41
- src/Language/JVM/Stage.hs +49/−0
- src/Language/JVM/Staged.hs +146/−0
- src/Language/JVM/TH.hs +87/−0
- src/Language/JVM/Type.hs +194/−0
- src/Language/JVM/Utils.hs +70/−14
- stack.yaml +2/−3
- test-suite/Language/JVM/Attribute/CodeTest.hs +0/−84
- test-suite/Language/JVM/Attribute/StackMapTableTest.hs +0/−50
- test-suite/Language/JVM/AttributeTest.hs +0/−21
- test-suite/Language/JVM/ClassFileTest.hs +0/−33
- test-suite/Language/JVM/ConstantTest.hs +0/−42
- test-suite/Language/JVM/FieldTest.hs +0/−19
- test-suite/Language/JVM/MethodTest.hs +0/−19
- test-suite/Language/JVM/UtilsTest.hs +0/−22
- test-suite/Language/JVMTest.hs +0/−30
- test-suite/SpecHelper.hs +0/−68
- test-suite/Test.hs +0/−60
- test/Language/JVM/Attribute/BootstrapMethodsTest.hs +20/−0
- test/Language/JVM/Attribute/CodeTest.hs +178/−0
- test/Language/JVM/Attribute/ConstantValueTest.hs +15/−0
- test/Language/JVM/Attribute/ExceptionsTest.hs +15/−0
- test/Language/JVM/Attribute/LineNumberTableTest.hs +26/−0
- test/Language/JVM/Attribute/SignatureTest.hs +27/−0
- test/Language/JVM/Attribute/StackMapTableTest.hs +77/−0
- test/Language/JVM/AttributeTest.hs +23/−0
- test/Language/JVM/ClassFileTest.hs +43/−0
- test/Language/JVM/ConstantTest.hs +124/−0
- test/Language/JVM/FieldTest.hs +26/−0
- test/Language/JVM/MethodTest.hs +29/−0
- test/Language/JVM/TypeTest.hs +50/−0
- test/Language/JVM/UtilsTest.hs +64/−0
- test/Language/JVMTest.hs +164/−0
- test/SpecHelper.hs +155/−0
- test/Test.hs +1/−0
CHANGELOG.md view
@@ -1,6 +1,17 @@ # Change log -## Version 0.0.X+## Version 0.1.0 ++- Fix documentation+- Remove ConstantRef+- Add better method and field descriptions +- Introducing a stageing system+- Added Code writing+- Changed Megaparsec to Attoparsec of improved performance.+- A lot of extra work++- Add Attributes + - LineNumberTable ## Version 0.0.2
README.md view
@@ -9,19 +9,34 @@ ```haskell import Language.JVM import qualified Language.JVM.Attribute.Code as Code++import qualified Data.ByteString.Lazy as BL++main :: IO ()+main = + ecfl <- readClassFile <$> BL.readFile "test/data/project/Main.class" + case ecfl of + Right clf -> do+ print (cThisClass clf)+ print (cSuperClass clf)+ Left msg -> + print msg ``` -## Todo's+## Stages -- Add more Attributes as to the-[docs](http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7).-The most notable and required are:+There are two stages in the current state of the repository. `Low` is closer+to the class-file, while the `High` stage is easier to work with. The reason+that we have the two stages is that the class-file representation has indices+into the Constant Pool. The `High` stage eliminates all these problems. - - LineNumberTable -- Add lenses for better access of deep fields+## Todo's +- Add more Attributes as to the+[docs](http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7). - Add documentation for Code+- Setup regular benchmarks ## Developing
benchmark/Main.hs view
@@ -7,9 +7,59 @@ import Data.ByteString.Lazy as BL main :: IO ()-main = defaultMain- [ bench "simple load" (- whnfIO $ decodeClassFile <$>- BL.readFile "test-suite/data/project/Main.class"- )+main = defaultMain $+ [ decodebm+ , encodebm+ , evolvebm+ , devolvebm+ ] <*> [ ex2 ]++decodebm :: FilePath -> Benchmark+decodebm fp = bgroup ("decode " ++ fp)+ [ bench "lazy"+ (whnfIO $ decodeClassFile <$> BL.readFile ex2)+ , bench "strict"+ (nfIO $ decodeClassFile <$> BL.readFile ex2) ]++encodebm :: FilePath -> Benchmark+encodebm fp =+ env (decodeClassFile' fp) $ \clf ->+ bgroup ("encode " ++ fp)+ [ bench "lazy"+ (whnf encodeClassFile clf)+ , bench "strict"+ (nf encodeClassFile clf)+ ]++evolvebm :: FilePath -> Benchmark+evolvebm fp =+ env (decodeClassFile' fp)$ \clf ->+ bgroup ("evolve " ++ fp)+ [ bench "strict"+ (nf evolveClassFile clf)+ ]++devolvebm :: FilePath -> Benchmark+devolvebm fp =+ env (readClassFile' fp) $ \clf ->+ bgroup ("devolve " ++ fp)+ [ bench "strict"+ (nf devolveClassFile clf)+ ]++decodeClassFile' :: FilePath -> IO (ClassFile Low)+decodeClassFile' fp = do+ Right clf <- decodeClassFile <$> BL.readFile fp+ return clf++readClassFile' :: FilePath -> IO (ClassFile High)+readClassFile' fp = do+ Right clf <- readClassFile <$> BL.readFile fp+ return clf++ex1 :: String+ex1 = "test/data/project/Main.class"++ex2 :: String+ex2 = "test/data/java/util/zip/ZipOutputStream.class"
jvm-binary.cabal view
@@ -1,12 +1,14 @@--- This file has been generated from package.yaml by hpack version 0.17.1.+-- This file has been generated from package.yaml by hpack version 0.20.0. -- -- see: https://github.com/sol/hpack+--+-- hash: 097c125068d4157309ad1e355ed38e1c038f019d7b88ee213afb43df08ad7784 name: jvm-binary-version: 0.0.2+version: 0.1.0 synopsis: A library for reading Java class-files description: A library for reading Java class-files.-category: Language, Java+category: Language, Java, JVM homepage: https://github.com/ucla-pls/jvm-binary#readme bug-reports: https://github.com/ucla-pls/jvm-binary/issues author: Christian Gram Kalhauge@@ -32,58 +34,93 @@ src ghc-options: -Wall build-depends:- base >= 4.9 && < 4.10+ attoparsec+ , base >=4.9 && <4.11 , binary , bytestring , containers+ , data-binary-ieee754+ , deepseq >=1.4.3.0+ , deriving-compat+ , mtl+ , template-haskell , text , vector exposed-modules: Language.JVM Language.JVM.AccessFlag Language.JVM.Attribute+ Language.JVM.Attribute.Base Language.JVM.Attribute.BootstrapMethods Language.JVM.Attribute.Code Language.JVM.Attribute.ConstantValue Language.JVM.Attribute.Exceptions+ Language.JVM.Attribute.LineNumberTable+ Language.JVM.Attribute.Signature Language.JVM.Attribute.StackMapTable+ Language.JVM.ByteCode Language.JVM.ClassFile+ Language.JVM.ClassFileReader Language.JVM.Constant+ Language.JVM.ConstantPool Language.JVM.Field Language.JVM.Method+ Language.JVM.Stage+ Language.JVM.Staged+ Language.JVM.TH+ Language.JVM.Type Language.JVM.Utils+ other-modules:+ Paths_jvm_binary default-language: Haskell2010 -test-suite jvm-binary-test-suite+test-suite jvm-binary-test type: exitcode-stdio-1.0 main-is: Test.hs hs-source-dirs:- test-suite- ghc-options: -Wall -rtsopts -threaded -with-rtsopts=-N -fno-warn-orphans+ test+ ghc-options: -rtsopts -threaded -with-rtsopts=-N -fno-warn-orphans build-depends:- base >= 4.9 && < 4.10- , jvm-binary- , tasty- , tasty-hspec- , tasty-discover- , tasty-quickcheck+ QuickCheck+ , attoparsec+ , base >=4.9 && <4.11 , binary , bytestring , containers- , filepath+ , data-binary-ieee754+ , deepseq >=1.4.3.0+ , deriving-compat , directory+ , filepath+ , generic-random+ , hspec-expectations-pretty-diff+ , jvm-binary+ , mtl+ , tasty+ , tasty-discover+ , tasty-hspec+ , tasty-quickcheck+ , template-haskell , text+ , vector other-modules:+ Language.JVM.Attribute.BootstrapMethodsTest Language.JVM.Attribute.CodeTest+ Language.JVM.Attribute.ConstantValueTest+ Language.JVM.Attribute.ExceptionsTest+ Language.JVM.Attribute.LineNumberTableTest+ Language.JVM.Attribute.SignatureTest Language.JVM.Attribute.StackMapTableTest Language.JVM.AttributeTest Language.JVM.ClassFileTest Language.JVM.ConstantTest Language.JVM.FieldTest Language.JVM.MethodTest+ Language.JVM.TypeTest Language.JVM.UtilsTest Language.JVMTest SpecHelper+ Paths_jvm_binary default-language: Haskell2010 benchmark jvm-binary-benchmarks@@ -91,10 +128,22 @@ main-is: Main.hs hs-source-dirs: benchmark- ghc-options: -Wall -rtsopts -threaded -funbox-strict-fields -with-rtsopts=-N+ ghc-options: -rtsopts -threaded -funbox-strict-fields -with-rtsopts=-N build-depends:- base >= 4.9 && < 4.10- , jvm-binary- , criterion+ attoparsec+ , base >=4.9 && <4.11+ , binary , bytestring+ , containers+ , criterion+ , data-binary-ieee754+ , deepseq >=1.4.3.0+ , deriving-compat+ , jvm-binary+ , mtl+ , template-haskell+ , text+ , vector+ other-modules:+ Paths_jvm_binary default-language: Haskell2010
package.yaml view
@@ -1,18 +1,16 @@ name: jvm-binary-version: '0.0.2'+version: '0.1.0' author: Christian Gram Kalhauge maintainer: Christian Gram Kalhauge <kalhauge@cs.ucla.edu> synopsis: A library for reading Java class-files license: MIT license-file: LICENSE.md-category: Language, Java+category: Language, Java, JVM github: ucla-pls/jvm-binary description: A library for reading Java class-files. -ghc-options: -Wall- extra-source-files: - CHANGELOG.md - LICENSE.md@@ -20,46 +18,51 @@ - README.md - stack.yaml +dependencies:+- base >= 4.9 && < 4.11+- binary+- bytestring+- containers+- text+- vector+- deepseq >= 1.4.3.0+- deriving-compat+- attoparsec+- mtl+- data-binary-ieee754+- template-haskell+ library:- dependencies:- - base >= 4.9 && < 4.10- - binary- - bytestring- - containers- - text- - vector source-dirs: src+ ghc-options: -Wall tests:- jvm-binary-test-suite:+ jvm-binary-test: dependencies:- - base >= 4.9 && < 4.10 - jvm-binary - tasty - tasty-hspec - tasty-discover - tasty-quickcheck- - binary- - bytestring- - containers+ - QuickCheck - filepath - directory - text+ - generic-random+ - hspec-expectations-pretty-diff ghc-options: - -rtsopts - -threaded - -with-rtsopts=-N - -fno-warn-orphans main: Test.hs- source-dirs: test-suite+ source-dirs: test benchmarks: jvm-binary-benchmarks: dependencies:- - base >= 4.9 && < 4.10 - jvm-binary - criterion- - bytestring ghc-options: - -rtsopts - -threaded
src/Language/JVM.hs view
@@ -8,28 +8,31 @@ -} module Language.JVM- ( decodeClassFile-+ ( module Language.JVM.AccessFlag , module Language.JVM.Attribute , module Language.JVM.ClassFile+ , module Language.JVM.ClassFileReader , module Language.JVM.Constant+ , module Language.JVM.ConstantPool , module Language.JVM.Field , module Language.JVM.Method+ , module Language.JVM.Stage+ , module Language.JVM.Staged+ , module Language.JVM.Utils+ , module Language.JVM.Type+ , module Language.JVM.ByteCode ) where -import qualified Data.ByteString.Lazy as BL-import Data.Binary-+import Language.JVM.AccessFlag import Language.JVM.Attribute+import Language.JVM.ByteCode import Language.JVM.ClassFile+import Language.JVM.ClassFileReader import Language.JVM.Constant+import Language.JVM.ConstantPool import Language.JVM.Field import Language.JVM.Method---- | Create a class file from a lazy 'BL.ByteString'-decodeClassFile :: BL.ByteString -> Either String ClassFile-decodeClassFile bs = do- case decodeOrFail bs of- Right (_, _, cf) -> Right cf- Left (_, _, msg) -> Left msg-+import Language.JVM.Stage+import Language.JVM.Staged+import Language.JVM.Type+import Language.JVM.Utils
src/Language/JVM/AccessFlag.hs view
@@ -6,7 +6,8 @@ Contains the AccessFlags used in the different modules. -}-+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DeriveAnyClass #-} module Language.JVM.AccessFlag ( MAccessFlag(..), mflags , FAccessFlag(..), fflags@@ -15,6 +16,9 @@ import Language.JVM.Utils +import GHC.Generics (Generic)+import Control.DeepSeq (NFData)+ -- | Access flags for the 'Language.JVM.Method.Method' data MAccessFlag = MPublic@@ -29,8 +33,7 @@ | MAbstract | MStrictFP | MSynthetic- deriving (Ord, Show, Eq)-+ deriving (Ord, Show, Eq, NFData, Generic) -- | The 'Enumish' mapping of the 'MAccessFlag' mflags :: [(Int, MAccessFlag)]@@ -57,11 +60,13 @@ = CPublic | CFinal | CSuper+ | CInterface | CAbstract | CSynthetic | CAnnotation | CEnum- deriving (Ord, Show, Eq)+ | CModule+ deriving (Ord, Show, Eq, NFData, Generic) -- | The 'Enumish' mapping of the 'CAccessFlag' cflags :: [(Int, CAccessFlag)]@@ -69,10 +74,12 @@ [ (0, CPublic) , (4, CFinal) , (5, CSuper)+ , (9, CInterface) , (10, CAbstract) , (12, CSynthetic) , (13, CAnnotation) , (14, CEnum)+ , (15, CModule) ] instance Enumish CAccessFlag where@@ -85,13 +92,11 @@ | FProtected | FStatic | FFinal- | FSynchronized- | FUnused6 | FVolatile | FTransient | FSynthetic | FEnum- deriving (Ord, Show, Eq)+ deriving (Ord, Show, Eq, NFData, Generic) -- | The 'Enumish' mapping of the 'FAccessFlag' fflags :: [(Int, FAccessFlag)]@@ -101,12 +106,10 @@ , (2, FProtected) , (3, FStatic) , (4, FFinal)- , (5, FSynchronized)- , (6, FUnused6)- , (7, FVolatile)- , (8, FTransient)- , (13, FSynthetic)- , (15, FEnum)+ , (6, FVolatile)+ , (7, FTransient)+ , (12, FSynthetic)+ , (14, FEnum) ] instance Enumish FAccessFlag where
src/Language/JVM/Attribute.hs view
@@ -7,134 +7,29 @@ This is the main module for accessing all kinds of Attributes. -} +{-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeSynonymInstances #-} module Language.JVM.Attribute- ( Attribute (..)- , aInfo-- , aName-- , IsAttribute (..)- -- * SubAttributes+ ( module Language.JVM.Attribute.Base+ -- * Subattributes+ , BootstrapMethods , Code- , codeStackMapTable , ConstantValue , Exceptions+ , LineNumberTable , StackMapTable- , BootstrapMethods-- -- * Helpers- , Const+ , Signature ) where -import GHC.Generics (Generic)--import Data.Bifunctor-import Data.Binary-import qualified Data.ByteString as BS-import qualified Data.ByteString.Lazy as BL-import Data.Monoid-import Data.Text as Text--import Language.JVM.Constant (ConstantPool,- ConstantRef,- lookupText)-import Language.JVM.Utils (SizedByteString32,- trd,- unSizedByteString)-+import Language.JVM.Attribute.Base import Language.JVM.Attribute.BootstrapMethods (BootstrapMethods)-import qualified Language.JVM.Attribute.Code as Code+import Language.JVM.Attribute.Code (Code) import Language.JVM.Attribute.ConstantValue (ConstantValue) import Language.JVM.Attribute.Exceptions (Exceptions)+import Language.JVM.Attribute.LineNumberTable (LineNumberTable)+import Language.JVM.Attribute.Signature (Signature) import Language.JVM.Attribute.StackMapTable (StackMapTable)---- | An Attribute, simply contains of a reference to a name and--- contains info.-data Attribute = Attribute- { aNameIndex :: ! ConstantRef- , aInfo' :: ! SizedByteString32- } deriving (Show, Eq, Generic)--instance Binary Attribute where---- | A small helper function to extract the info as a--- lazy 'Data.ByteString.Lazy.ByteString'.-aInfo :: Attribute -> BS.ByteString-aInfo = unSizedByteString . aInfo'---- | Extracts the name from the attribute, if it exists in the--- ConstantPool.-aName :: ConstantPool -> Attribute -> Maybe Text.Text-aName cp as = lookupText (aNameIndex as) cp---- | Create a type dependent on another type 'b',--- used for accessing the correct 'attrName' in 'IsAttribute'.-newtype Const a b = Const { unConst :: a }---- | A class-type that describes a data-type 'a' as an Attribute. Most notable--- it provides the 'fromAttribute'' method that enables converting an Attribute--- to a data-type 'a'.-class IsAttribute a where- attrName :: Const Text.Text a- -- ^ The name of the attribute.-- fromAttribute :: Attribute -> Either String a- -- ^ Generate a 'a' from an Attribute.-- fromAttribute'- :: ConstantPool- -> Attribute- -> Maybe (Either String a)- fromAttribute' cp as = do- name <- aName cp as- if name == unConst (attrName :: Const Text.Text a) then- return $ fromAttribute as- else Nothing--readFromStrict :: Binary a => Attribute -> Either String a-readFromStrict =- bimap trd trd . decodeOrFail . BL.fromStrict . aInfo---- # Attributes----- | 'Code' is an Attribute.-instance IsAttribute Code where- attrName = Const "Code"- fromAttribute = readFromStrict---- | 'ConstantValue' is an Attribute.-instance IsAttribute ConstantValue where- attrName = Const "ConstantValue"- fromAttribute = readFromStrict---- | 'Exceptions' is an Attribute.-instance IsAttribute Exceptions where- attrName = Const "Exceptions"- fromAttribute = readFromStrict---- | 'StackMapTable' is an Attribute.-instance IsAttribute StackMapTable where- attrName = Const "StackMapTable"- fromAttribute = readFromStrict---- | 'BootstrapMethods' is an Attribute.-instance IsAttribute BootstrapMethods where- attrName = Const "BootstrapMethods"- fromAttribute = readFromStrict---- | Code is redefined with Attribute, as it is recursively containing--- 'Attribute'. This is a small hack to fix it.-type Code = Code.Code Attribute---- | The a attribute of the code is the StackMapTable. There can be at most one.--- If the version number of the file is more than 50, and there is no StackMapTable.--- there is an implicit empty StackMapTable.-codeStackMapTable :: ConstantPool -> Code -> Maybe (Either String BootstrapMethods)-codeStackMapTable cp =- getFirst . foldMap (First . fromAttribute' cp) . Code.attributes
+ src/Language/JVM/Attribute/Base.hs view
@@ -0,0 +1,160 @@+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TemplateHaskell #-}+{-|+Module : Language.JVM.Attribute.Base+Copyright : (c) Christian Gram Kalhauge, 2017+License : MIT+Maintainer : kalhuage@cs.ucla.edu+-}+module Language.JVM.Attribute.Base+ ( Attribute (..)+ , aInfo+ , toAttribute+ , devolveAttribute+ , fromAttribute'+ , toAttribute'++ -- * Helpers+ , IsAttribute (..)+ , Attributes+ , fromAttributes+ , toC+ , toC'+ , collect+ , Const (..)+ , firstOne+ ) where++import Control.Monad+import Data.Bifunctor+import Data.Binary+import qualified Data.ByteString as BS+import qualified Data.ByteString.Lazy as BL+import qualified Data.List as List+import qualified Data.Text as Text++import Language.JVM.Staged+import Language.JVM.Utils++-- | Maybe return the first element of a list+firstOne :: [a] -> Maybe a+firstOne as = fst <$> List.uncons as++-- | An Attribute, simply contains of a reference to a name and+-- contains info.+data Attribute r = Attribute+ { aName :: ! (Ref Text.Text r)+ , aInfo' :: ! (SizedByteString32)+ }++-- | A small helper function to extract the info as a+-- lazy 'Data.ByteString.Lazy.ByteString'.+aInfo :: Attribute r -> BS.ByteString+aInfo = unSizedByteString . aInfo'++instance Staged Attribute where+ evolve (Attribute an ai) = do+ an' <- link an+ return $ Attribute an' ai+ devolve (Attribute an ai) = do+ an' <- unlink an+ return $ Attribute an' ai++$(deriveBaseWithBinary ''Attribute)++-- | A list of attributes and described by the expected values.+type Attributes b r = Choice (SizedList16 (Attribute r)) (b r) r++-- | Create a type dependent on another type 'b',+-- used for accessing the correct 'attrName' in 'IsAttribute'.+newtype Const a b = Const { unConst :: a }++-- | A class-type that describes a data-type 'a' as an Attribute. Most notable+-- it provides the 'fromAttribute'' method that enables converting an Attribute+-- to a data-type 'a'.+class (Binary a) => IsAttribute a where+ -- | The name of an attribute. This is used to lookup an attribute.+ attrName :: Const Text.Text a++-- | Generate an attribute in a low stage 'Low'.+fromAttribute' :: IsAttribute a => Attribute r -> Either String a+fromAttribute' = readFromStrict++toAttribute' :: forall a. IsAttribute a => a -> Attribute High+toAttribute' a =+ let name = unConst (attrName :: Const Text.Text a)+ bytes = encode a+ in Attribute name (SizedByteString . BL.toStrict $ bytes)++toAttribute :: (IsAttribute (a Low), Staged a, DevolveM m) => a High -> m (Attribute Low)+toAttribute =+ devolveAttribute devolve++devolveAttribute :: (IsAttribute (a Low), DevolveM m) => (a High -> m (a Low)) -> a High -> m (Attribute Low)+devolveAttribute f a = do+ a' <- f a+ devolve $ toAttribute' a'++-- | Generate an attribute in the 'EvolveM' monad+fromAttribute ::+ forall a m. (IsAttribute (a Low), Staged a, EvolveM m)+ => Attribute High+ -> Maybe (m (a High))+fromAttribute as =+ if aName as == unConst (attrName :: Const Text.Text (a Low))+ then Just $ do+ either attributeError evolve $ fromAttribute' as+ else Nothing++-- | Generate an attribute in the 'EvolveM' monad+evolveAttribute ::+ forall a m. (IsAttribute (a Low), EvolveM m)+ => (a Low -> m (a High))+ -> Attribute High+ -> Maybe (m (a High))+evolveAttribute g as =+ if aName as == unConst (attrName :: Const Text.Text (a Low))+ then Just $ do+ either attributeError g $ fromAttribute' as+ else Nothing++toC :: (EvolveM m, Staged a, IsAttribute (a Low)) => (a High -> c) -> Attribute High -> Maybe (m c)+toC f attr =+ case fromAttribute attr of+ Just m -> Just $ f <$> m+ Nothing -> Nothing++toC' :: (EvolveM m, IsAttribute (a Low)) => (a Low -> m (a High)) -> (a High -> c) -> Attribute High -> Maybe (m c)+toC' g f attr =+ case evolveAttribute g attr of+ Just m -> Just $ f <$> m+ Nothing -> Nothing++collect :: (Monad m) => c -> Attribute High -> [Attribute High -> Maybe (m c)] -> m c+collect c attr options =+ case msum $ Prelude.map ($ attr) options of+ Just x -> x+ Nothing -> return c++-- | Given a 'Foldable' structure 'f', and a function that can calculate a+-- monoid given an 'Attribute' calculate the monoid over all attributes.+fromAttributes ::+ (Foldable f, EvolveM m, Monoid a)+ => (Attribute High -> m a)+ -> f (Attribute Low)+ -> m a+fromAttributes f attrs =+ Prelude.foldl g (return mempty) attrs+ where+ g m a' = do+ b <- m+ x <- f =<< evolve a'+ return $ b `mappend` x++readFromStrict :: Binary a => Attribute r -> Either String a+readFromStrict =+ bimap trd trd . decodeOrFail . BL.fromStrict . aInfo
src/Language/JVM/Attribute/BootstrapMethods.hs view
@@ -1,3 +1,9 @@+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE StandaloneDeriving #-} {-| Module : Language.JVM.Attribute.BootstrapMethods Copyright : (c) Christian Gram Kalhauge, 2017@@ -7,41 +13,47 @@ Based on the BootstrapMethods Attribute, as documented [here](http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.23). -}-{-# LANGUAGE DeriveGeneric #-} module Language.JVM.Attribute.BootstrapMethods ( BootstrapMethods (..) , methods , BootstrapMethod (..)- , arguments ) where -import GHC.Generics (Generic)--import Data.Binary--import Language.JVM.Constant (ConstantRef (..))+import Language.JVM.Constant+import Language.JVM.Attribute.Base+import Language.JVM.Staged import Language.JVM.Utils --- | Is a list of bootstrapped methods.-data BootstrapMethods = BootstrapMethods- { methods' :: SizedList16 BootstrapMethod- } deriving (Show, Eq, Generic)+-- | 'BootstrapMethods' is an Attribute.+instance IsAttribute (BootstrapMethods Low) where+ attrName = Const "BootstrapMethods" -instance Binary BootstrapMethods where+-- | Is a list of bootstrapped methods.+newtype BootstrapMethods r = BootstrapMethods+ { methods' :: SizedList16 (BootstrapMethod r)+ } -- | The methods as list-methods :: BootstrapMethods -> [ BootstrapMethod ]+methods :: BootstrapMethods r -> [ BootstrapMethod r ] methods = unSizedList . methods' -- | A bootstraped methods.-data BootstrapMethod = BootstrapMethod- { methodIndex :: ConstantRef- , arguments' :: SizedList16 ConstantRef- } deriving (Show, Eq, Generic)+data BootstrapMethod r = BootstrapMethod+ { method :: !(DeepRef MethodHandle r)+ , arguments :: !(SizedList16 (Ref JValue r))+ } --- | The arguments is a cool-arguments :: BootstrapMethod -> [ ConstantRef ]-arguments = unSizedList . arguments'+instance Staged BootstrapMethods where+ stage f (BootstrapMethods m) =+ label "BootstrapMethods" $ BootstrapMethods <$> mapM f m -instance Binary BootstrapMethod where+instance Staged BootstrapMethod where+ evolve (BootstrapMethod a m) =+ BootstrapMethod <$> link a <*> mapM link m++ devolve (BootstrapMethod a m) =+ BootstrapMethod <$> unlink a <*> mapM unlink m++$(deriveBaseWithBinary ''BootstrapMethod)+$(deriveBaseWithBinary ''BootstrapMethods)
src/Language/JVM/Attribute/Code.hs view
@@ -1,664 +1,136 @@ {-| Module : Language.JVM.Attribute.Code-Copyright : (c) Christian Gram Kalhauge, 2017+Copyright : (c) Christian Gram Kalhauge, 2018 License : MIT Maintainer : kalhuage@cs.ucla.edu -}--{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE TemplateHaskell #-}+{-# OPTIONS_GHC -fno-warn-name-shadowing #-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TemplateHaskell #-} module Language.JVM.Attribute.Code ( Code (..)-- , ByteCode (..)+ , CodeAttributes (..) , ExceptionTable (..)-- , ByteCodeInst (..)- , ByteCodeOpr (..)-- , Constant (..)- , WordSize- , OneOrTwo (..)- , ArithmeticType (..)- , SmallArithmeticType (..)- , BinOpr (..)- , LocalType (..)- , ArrayType (..)- , CmpOpr (..)- , LongOffset- , Offset-- , LocalAddress (..)- , IncrementAmount (..)- , BitOpr (..)- , FieldAccess (..)- , Invokation (..)+ , codeStackMapTable+ , codeByteCodeOprs+ , codeByteCodeInsts ) where -import GHC.Generics (Generic)--import Prelude hiding (fail)-import qualified Prelude as P--import Numeric (showHex)--import Control.Monad hiding (fail)-import Control.Monad.Fail (fail)+import Prelude hiding (fail) import Data.Binary-import Data.Binary.Get hiding (Get)-import Data.Binary.Put hiding (Put)-import qualified Data.ByteString.Lazy as BL-import Data.Int-import qualified Data.Vector as V+import Data.Monoid+import qualified Data.Vector as V -import Language.JVM.Constant (ConstantRef (..))+import Language.JVM.Attribute.Base+import Language.JVM.Attribute.LineNumberTable+import Language.JVM.Attribute.StackMapTable+import Language.JVM.ByteCode+import Language.JVM.Constant+import Language.JVM.Staged import Language.JVM.Utils --data Code a = Code- { maxStack :: Int16- , maxLocals :: Int16- , bytecode :: ByteCode- , exceptionTable :: SizedList16 ExceptionTable- , attributes :: SizedList16 a- } deriving (Show, Eq, Generic)--instance (Binary a) => Binary (Code a) where- -- Auto implemented by generic--newtype ByteCode = ByteCode- { unByteCode :: [ByteCodeInst]- } deriving (Show, Eq)--instance Binary ByteCode where- get = do- x <- getWord32be- bs <- getLazyByteString (fromIntegral x)- case runGetOrFail go bs of- Right (_,_,bcs) -> return $ ByteCode bcs- Left (_,_,msg) -> fail msg- where- go = isEmpty >>= \t ->- if t- then return []- else do- x <- get- (x:) <$> go--- put (ByteCode lst)= do- let bs = runPut (mapM_ put lst)- putWord32be (fromIntegral $ BL.length bs)- putLazyByteString bs+-- | 'Code' is an Attribute.+instance IsAttribute (Code Low) where+ attrName = Const "Code" +-- | Code contains the actual byte-code. The 'i' type parameter is added to+-- allow indicate the two stages of the code file, before and after access to+-- the 'ConstantPool'. i should be either 'Ref' or 'Deref'.+data Code r = Code+ { codeMaxStack :: !(Word16)+ , codeMaxLocals :: !(Word16)+ , codeByteCode :: !((ByteCode r))+ , codeExceptionTable :: !(SizedList16 (ExceptionTable r))+ , codeAttributes :: !(Attributes CodeAttributes r)+ } -data ExceptionTable = ExceptionTable- { start :: ! Word16+data ExceptionTable r = ExceptionTable+ { start :: ! (ByteCodeRef r) -- ^ Inclusive program counter into 'code'- , end :: ! Word16+ , end :: ! (ByteCodeRef r) -- ^ Exclusive program counter into 'code'- , handler :: ! Word16+ , handler :: ! (ByteCodeRef r) -- ^ A program counter into 'code' indicating the handler.- , catchType :: ! ConstantRef+ , catchType :: ! (Ref (Maybe ClassName) r) }- deriving (Show, Eq, Generic) -instance Binary ExceptionTable where--data ByteCodeInst = ByteCodeInst- { offset :: LongOffset- , opcode :: ByteCodeOpr- }- deriving (Show, Eq, Generic)--instance Binary ByteCodeInst where- get =- ByteCodeInst <$> (fromIntegral <$> bytesRead) <*> get- put x =- put $ opcode x--data ArithmeticType = MInt | MLong | MFloat | MDouble- deriving (Show, Eq, Enum, Bounded)--data SmallArithmeticType = MByte | MChar | MShort- deriving (Show, Eq, Enum, Bounded)--data LocalType = LInt | LLong | LFloat | LDouble | LRef- deriving (Show, Eq, Enum, Bounded)--data ArrayType a- = ABoolean | AByte | AChar | AShort | AInt | ALong- | AFloat | ADouble | ARef a- deriving (Show, Eq)--data Invokation- = InvkSpecial- | InvkVirtual- | InvkStatic- | InvkInterface Word8- | InvkDynamic- deriving (Show, Eq)--data FieldAccess- = FldStatic- | FldField- deriving (Show, Eq)--data OneOrTwo = One | Two- deriving (Show, Ord, Bounded, Eq, Enum)--type WordSize = OneOrTwo--data Constant- = CNull-- | CIntM1- | CInt0- | CInt1- | CInt2- | CInt3- | CInt4- | CInt5-- | CLong0- | CLong1-- | CFloat0- | CFloat1- | CFloat2-- | CDouble0- | CDouble1-- | CByte Int8- | CShort Int16-- | CHalfRef ConstantRef- | CRef WordSize ConstantRef- deriving (Show, Eq)--data BinOpr- = Add- | Sub- | Mul- | Div- | Rem- deriving (Show, Eq)--data BitOpr- = ShL- | ShR- | UShR- | And- | Or- | XOr- deriving (Show, Eq)--type Offset = Int16-type LongOffset = Int32--data LocalAddress- = LWide Word16- | LSingle Word8- deriving (Show, Eq)--data IncrementAmount- = IWide Int16- | ISingle Int8- deriving (Show, Eq)--data CmpOpr- = CEq | CNe | CLt | CGe | CGt | CLe- deriving (Show, Eq)--data ByteCodeOpr- = ArrayLoad (ArrayType ())- -- ^ aaload baload ...- | ArrayStore (ArrayType ())- -- ^ aastore bastore ...-- | Push Constant-- | Load LocalType LocalAddress- -- ^ aload_0, bload_2, iload 5 ...- | Store LocalType LocalAddress- -- ^ aload, bload ...-- | BinaryOpr BinOpr ArithmeticType- -- ^ iadd ...- | Neg ArithmeticType- -- ^ ineg ...-- | BitOpr BitOpr WordSize- -- ^ Exclusively on int and long, identified by the word-size-- | IncrLocal !LocalAddress !IncrementAmount- -- ^ Only works on ints, increment local #1, with #2-- | Cast ArithmeticType ArithmeticType- -- ^ Only valid on different types-- | CastDown SmallArithmeticType- -- ^ Only valid on different types-- | CompareLongs-- | CompareFloating Bool WordSize- -- ^ Compare two floating values, #1 indicates if greater-than, #2- -- is if float or double should be used.-- | If CmpOpr OneOrTwo Offset- -- ^ compare with 0 if #2 is False, and two ints from the stack if- -- True. the last value is the offset-- | IfRef Bool OneOrTwo Offset- -- ^ check if two objects are equal, or not equal. If #2 is True, compare- -- with null.-- | Goto LongOffset- | Jsr LongOffset- | Ret LocalAddress-- | TableSwitch Int32 Int32 Int32 (V.Vector Int32)- -- ^ a table switch has 3 values `default` `low` `high` and a list of- -- offets.- | LookupSwitch Int32 (V.Vector (Int32, Int32))- -- ^ a lookup switch has a `default` value and a list of pairs.-- | Get FieldAccess ConstantRef- | Put FieldAccess ConstantRef-- | Invoke Invokation ConstantRef-- | New ConstantRef- | NewArray (ArrayType ConstantRef)-- | ArrayLength-- | Throw-- | CheckCast ConstantRef- | InstanceOf ConstantRef-- | Monitor Bool- -- ^ True => Enter, False => Exit-- | MultiNewArray ConstantRef Word8- -- ^ Create a new multi array of #1 and with #2 dimensions-- | Return (Maybe LocalType)-- | Nop-- | Pop WordSize-- | Dup WordSize- | DupX1 WordSize- | DupX2 WordSize-- | Swap-- deriving (Show, Eq)--instance Binary ByteCodeOpr where- get = do- cmd <- getWord8- case cmd of- 0x00 -> return Nop- 0x01 -> return $ Push CNull-- 0x02 -> return $ Push CIntM1- 0x03 -> return $ Push CInt0- 0x04 -> return $ Push CInt1- 0x05 -> return $ Push CInt2- 0x06 -> return $ Push CInt3- 0x07 -> return $ Push CInt4- 0x08 -> return $ Push CInt5-- 0x09 -> return $ Push CLong0- 0x0a -> return $ Push CLong1-- 0x0b -> return $ Push CFloat0- 0x0c -> return $ Push CFloat1- 0x0d -> return $ Push CFloat2-- 0x0e -> return $ Push CDouble0- 0x0f -> return $ Push CDouble1-- 0x10 -> Push . CByte <$> get- 0x11 -> Push . CShort <$> get-- 0x12 -> Push . CHalfRef . ConstantRef . fromIntegral <$> getWord8- 0x13 -> Push . CRef One <$> get- 0x14 -> Push . CRef Two <$> get-- 0x15 -> Load LInt . LSingle <$> get- 0x16 -> Load LLong . LSingle <$> get- 0x17 -> Load LFloat . LSingle <$> get- 0x18 -> Load LDouble . LSingle <$> get- 0x19 -> Load LRef . LSingle <$> get-- 0x1a -> return $ Load LInt (LSingle 0)- 0x1b -> return $ Load LInt (LSingle 1)- 0x1c -> return $ Load LInt (LSingle 2)- 0x1d -> return $ Load LInt (LSingle 3)-- 0x1e -> return $ Load LLong (LSingle 0)- 0x1f -> return $ Load LLong (LSingle 1)- 0x20 -> return $ Load LLong (LSingle 2)- 0x21 -> return $ Load LLong (LSingle 3)-- 0x22 -> return $ Load LFloat (LSingle 0)- 0x23 -> return $ Load LFloat (LSingle 1)- 0x24 -> return $ Load LFloat (LSingle 2)- 0x25 -> return $ Load LFloat (LSingle 3)-- 0x26 -> return $ Load LDouble (LSingle 0)- 0x27 -> return $ Load LDouble (LSingle 1)- 0x28 -> return $ Load LDouble (LSingle 2)- 0x29 -> return $ Load LDouble (LSingle 3)-- 0x2a -> return $ Load LRef (LSingle 0)- 0x2b -> return $ Load LRef (LSingle 1)- 0x2c -> return $ Load LRef (LSingle 2)- 0x2d -> return $ Load LRef (LSingle 3)-- 0x2e -> return $ ArrayLoad AInt- 0x2f -> return $ ArrayLoad ALong- 0x30 -> return $ ArrayLoad AFloat- 0x31 -> return $ ArrayLoad ADouble- 0x32 -> return $ ArrayLoad (ARef ())- 0x33 -> return $ ArrayLoad AByte- 0x34 -> return $ ArrayLoad AChar- 0x35 -> return $ ArrayLoad AShort-- 0x36 -> Store LInt . LSingle <$> get- 0x37 -> Store LLong . LSingle <$> get- 0x38 -> Store LFloat . LSingle <$> get- 0x39 -> Store LDouble . LSingle <$> get- 0x3a -> Store LRef . LSingle <$> get-- 0x3b -> return $ Store LInt (LSingle 0)- 0x3c -> return $ Store LInt (LSingle 1)- 0x3d -> return $ Store LInt (LSingle 2)- 0x3e -> return $ Store LInt (LSingle 3)-- 0x3f -> return $ Store LLong (LSingle 0)- 0x40 -> return $ Store LLong (LSingle 1)- 0x41 -> return $ Store LLong (LSingle 2)- 0x42 -> return $ Store LLong (LSingle 3)-- 0x43 -> return $ Store LFloat (LSingle 0)- 0x44 -> return $ Store LFloat (LSingle 1)- 0x45 -> return $ Store LFloat (LSingle 2)- 0x46 -> return $ Store LFloat (LSingle 3)-- 0x47 -> return $ Store LDouble (LSingle 0)- 0x48 -> return $ Store LDouble (LSingle 1)- 0x49 -> return $ Store LDouble (LSingle 2)- 0x4a -> return $ Store LDouble (LSingle 3)-- 0x4b -> return $ Store LRef (LSingle 0)- 0x4c -> return $ Store LRef (LSingle 1)- 0x4d -> return $ Store LRef (LSingle 2)- 0x4e -> return $ Store LRef (LSingle 3)-- 0x4f -> return $ ArrayStore AInt- 0x50 -> return $ ArrayStore ALong- 0x51 -> return $ ArrayStore AFloat- 0x52 -> return $ ArrayStore ADouble- 0x53 -> return $ ArrayStore (ARef ())- 0x54 -> return $ ArrayStore AByte- 0x55 -> return $ ArrayStore AChar- 0x56 -> return $ ArrayStore AShort-- 0x57 -> return $ Pop One- 0x58 -> return $ Pop Two-- 0x59 -> return $ Dup One- 0x5a -> return $ DupX1 One- 0x5b -> return $ DupX2 One-- 0x5c -> return $ Dup Two- 0x5d -> return $ DupX1 Two- 0x5e -> return $ DupX2 Two-- 0x5f -> return $ Swap-- 0x60 -> return $ BinaryOpr Add MInt- 0x61 -> return $ BinaryOpr Add MLong- 0x62 -> return $ BinaryOpr Add MFloat- 0x63 -> return $ BinaryOpr Add MDouble-- 0x64 -> return $ BinaryOpr Sub MInt- 0x65 -> return $ BinaryOpr Sub MLong- 0x66 -> return $ BinaryOpr Sub MFloat- 0x67 -> return $ BinaryOpr Sub MDouble-- 0x68 -> return $ BinaryOpr Mul MInt- 0x69 -> return $ BinaryOpr Mul MLong- 0x6a -> return $ BinaryOpr Mul MFloat- 0x6b -> return $ BinaryOpr Mul MDouble-- 0x6c -> return $ BinaryOpr Div MInt- 0x6d -> return $ BinaryOpr Div MLong- 0x6e -> return $ BinaryOpr Div MFloat- 0x6f -> return $ BinaryOpr Div MDouble-- 0x70 -> return $ BinaryOpr Rem MInt- 0x71 -> return $ BinaryOpr Rem MLong- 0x72 -> return $ BinaryOpr Rem MFloat- 0x73 -> return $ BinaryOpr Rem MDouble-- 0x74 -> return $ Neg MInt- 0x75 -> return $ Neg MLong- 0x76 -> return $ Neg MFloat- 0x77 -> return $ Neg MDouble-- 0x78 -> return $ BitOpr ShL One- 0x79 -> return $ BitOpr ShL Two- 0x7a -> return $ BitOpr ShR One- 0x7b -> return $ BitOpr ShR Two-- 0x7c -> return $ BitOpr UShR One- 0x7d -> return $ BitOpr UShR Two-- 0x7e -> return $ BitOpr And One- 0x7f -> return $ BitOpr And Two- 0x80 -> return $ BitOpr Or One- 0x81 -> return $ BitOpr Or Two- 0x82 -> return $ BitOpr XOr One- 0x83 -> return $ BitOpr XOr Two-- 0x84 -> IncrLocal <$> (LSingle <$> get) <*> (ISingle <$> get)-- 0x85 -> return $ Cast MInt MLong- 0x86 -> return $ Cast MInt MFloat- 0x87 -> return $ Cast MInt MDouble-- 0x88 -> return $ Cast MLong MInt- 0x89 -> return $ Cast MLong MFloat- 0x8a -> return $ Cast MLong MDouble-- 0x8b -> return $ Cast MFloat MInt- 0x8c -> return $ Cast MFloat MLong- 0x8d -> return $ Cast MFloat MDouble-- 0x8e -> return $ Cast MDouble MInt- 0x8f -> return $ Cast MDouble MLong- 0x90 -> return $ Cast MDouble MFloat-- 0x91 -> return $ CastDown MByte- 0x92 -> return $ CastDown MChar- 0x93 -> return $ CastDown MShort-- 0x94 -> return $ CompareLongs-- 0x95 -> return $ CompareFloating True One- 0x96 -> return $ CompareFloating False Two-- 0x97 -> return $ CompareFloating True One- 0x98 -> return $ CompareFloating False Two-- 0x99 -> If CEq One <$> get- 0x9a -> If CNe One <$> get- 0x9b -> If CLt One <$> get- 0x9c -> If CGe One <$> get- 0x9d -> If CGt One <$> get- 0x9e -> If CLe One <$> get-- 0x9f -> If CEq Two <$> get- 0xa0 -> If CNe Two <$> get- 0xa1 -> If CLt Two <$> get- 0xa2 -> If CGe Two <$> get- 0xa3 -> If CGt Two <$> get- 0xa4 -> If CLe Two <$> get-- 0xa5 -> IfRef True Two <$> get- 0xa6 -> IfRef False Two <$> get-- 0xa7 -> Goto . fromIntegral <$> getInt16be- 0xa8 -> Jsr . fromIntegral <$> getInt16be- 0xa9 -> Ret . LSingle <$> get-- 0xaa -> do- offset' <- bytesRead- let skipAmount = (4 - offset' `mod` 4) `mod` 4- if skipAmount > 0 then skip $ fromIntegral skipAmount else return ()- dft <- getInt32be- low <- getInt32be- high <- getInt32be- table <- V.replicateM (fromIntegral $ high - low + 1) getInt32be- return $ TableSwitch dft low high table-- 0xab -> do- offset' <- bytesRead- let skipAmount = (4 - offset' `mod` 4) `mod` 4- if skipAmount > 0 then skip $ fromIntegral skipAmount else return ()- dft <- getInt32be- npairs <- getInt32be- pairs <- V.replicateM (fromIntegral npairs) get- return $ LookupSwitch dft pairs-- 0xac -> return . Return . Just $ LInt- 0xad -> return . Return . Just $ LLong- 0xae -> return . Return . Just $ LFloat- 0xaf -> return . Return . Just $ LDouble- 0xb0 -> return . Return . Just $ LRef- 0xb1 -> return . Return $ Nothing-- 0xb2 -> Get FldStatic <$> get- 0xb3 -> Put FldStatic <$> get-- 0xb4 -> Get FldField <$> get- 0xb5 -> Put FldField <$> get-- 0xb6 -> Invoke InvkVirtual <$> get- 0xb7 -> Invoke InvkSpecial <$> get- 0xb8 -> Invoke InvkStatic <$> get- 0xb9 -> do- ref <- get- count <- get- when (count == 0) $ fail "Should be not zero"- zero <- getWord8- when (zero /= 0) $ fail "Should be zero"- return $ Invoke (InvkInterface count) ref- 0xba -> do- ref <- get- count <- getWord8- when (count /= 0) $ fail "Should be zero"- zero <- getWord8- when (zero /= 0) $ fail "Should be zero"- return $ Invoke InvkDynamic ref- 0xbb -> New <$> get-- 0xbc -> do- x <- getWord8- NewArray <$> case x of- 4 -> return ABoolean- 5 -> return AChar- 6 -> return AFloat- 7 -> return ADouble- 8 -> return AByte- 9 -> return AShort- 10 -> return AInt- 11 -> return ALong- _ -> fail $ "Unknown type '0x" ++ showHex x "'."-- 0xbd -> NewArray . ARef <$> get-- 0xbe -> return ArrayLength-- 0xbf -> return Throw-- 0xc0 -> CheckCast <$> get- 0xc1 -> InstanceOf <$> get-- 0xc2 -> return $ Monitor True- 0xc3 -> return $ Monitor False-- 0xc4 -> do- subopcode <- getWord8- case subopcode of- 0x15 -> Load LInt . LWide <$> get- 0x16 -> Load LLong . LWide <$> get- 0x17 -> Load LFloat . LWide <$> get- 0x18 -> Load LDouble . LWide <$> get- 0x19 -> Load LRef . LWide <$> get-- 0x36 -> Store LInt . LWide <$> get- 0x37 -> Store LLong . LWide <$> get- 0x38 -> Store LFloat . LWide <$> get- 0x39 -> Store LDouble . LWide <$> get- 0x3a -> Store LRef . LWide <$> get+-- | Extracts a list of bytecode operation+codeByteCodeOprs :: Code High -> V.Vector (ByteCodeOpr High)+codeByteCodeOprs =+ unByteCode . codeByteCode - 0x84 -> IncrLocal <$> (LWide <$> get)- <*> (IWide <$> get)+-- | Extracts a list of bytecode instructions+codeByteCodeInsts :: Code Low -> V.Vector (ByteCodeInst Low)+codeByteCodeInsts =+ snd . unByteCode . codeByteCode - 0xa9 -> Ret . LWide <$> get+-- | Returns the StackMapTable attribute if any+codeStackMapTable :: Code High -> Maybe (StackMapTable High)+codeStackMapTable =+ firstOne . caStackMapTable . codeAttributes - _ -> fail $ "Wide does not work for opcode 'Ox"- ++ showHex subopcode "'"+data CodeAttributes r = CodeAttributes+ { caStackMapTable :: [ StackMapTable r ]+ , caLineNumberTable :: [ LineNumberTable r ]+ , caOthers :: [ Attribute r ]+ } - 0xc5 -> MultiNewArray <$> get <*> get+instance Staged Code where+ evolve Code{..} = label "Code" $ do+ (offsets, codeByteCode) <- evolveByteCode codeByteCode+ let evolver = (evolveOffset offsets)+ codeExceptionTable <- mapM (evolveBC evolver) codeExceptionTable+ codeAttributes <- fromCollector <$> fromAttributes (collect' evolver) codeAttributes+ return $ Code {..}+ where+ fromCollector (a, b, c) =+ CodeAttributes (appEndo a []) (appEndo b []) (appEndo c [])+ collect' evolver attr =+ collect (mempty, mempty, Endo (attr:)) attr+ [ toC' (evolveBC evolver) $ \e -> (Endo (e:), mempty, mempty)+ , toC' (evolveBC evolver) $ \e -> (mempty, Endo (e:), mempty)+ ] - 0xc6 -> IfRef False One <$> get- 0xc7 -> IfRef True One <$> get+ devolve Code{..} = do+ codeByteCode <- devolveByteCode codeByteCode+ let bcdevolver = devolveOffset codeByteCode+ codeExceptionTable <-+ mapM (devolveBC bcdevolver) codeExceptionTable+ codeAttributes <- SizedList <$> fromCodeAttributes bcdevolver codeAttributes+ return $ Code {..}+ where+ fromCodeAttributes bcdevolver (CodeAttributes a b c) = do+ a' <- mapM (devolveAttribute (devolveBC bcdevolver)) a+ b' <- mapM (devolveAttribute (devolveBC bcdevolver)) b+ c' <- mapM devolve c+ return (a' ++ b' ++ c') - 0xc8 -> Goto <$> getInt32be- 0xc9 -> Jsr <$> getInt32be+instance ByteCodeStaged ExceptionTable where+ evolveBC f ExceptionTable{..} = label "ExceptionTable" $ do+ catchType <- case catchType of+ 0 -> return $ Nothing+ n -> Just <$> link n+ start <- f start+ end <- f end+ handler <- f handler+ return $ ExceptionTable {..} - _ -> fail $ "I do not know this bytecode '0x" ++ showHex cmd "'."+ devolveBC f ExceptionTable{..} = do+ catchType <- case catchType of+ Just s -> unlink s+ Nothing -> return $ 0+ start <- f start+ end <- f end+ handler <- f handler+ return $ ExceptionTable {..} - put bc =- case bc of- Nop -> putInt8 0x00- Push CNull -> putInt8 0x01-- Push CIntM1 -> putInt8 0x02- Push CInt0 -> putInt8 0x03- Push CInt1 -> putInt8 0x04- Push CInt2 -> putInt8 0x05- Push CInt3 -> putInt8 0x06- Push CInt4 -> putInt8 0x07- Push CInt5 -> putInt8 0x08-- Push CLong0 -> putInt8 0x09- Push CLong1 -> putInt8 0x0a-- Push CFloat0 -> putInt8 0x0b- Push CFloat1 -> putInt8 0x0c- Push CFloat2 -> putInt8 0x0d-- Push CDouble0 -> putInt8 0x0e- Push CDouble1 -> putInt8 0x0f-- Push (CByte x) -> putInt8 0x10 >> put x- Push (CShort x) -> putInt8 0x11 >> put x-- Push (CHalfRef (ConstantRef r)) -> putInt8 0x12 >> putWord8 (fromIntegral r)- Push (CRef One (ConstantRef r)) -> putInt8 0x13 >> put r- Push (CRef Two (ConstantRef r)) -> putInt8 0x14 >> put r- _ -> P.fail $ "Is not able to print '" ++ show bc ++ "' yet."+$(deriveBaseWithBinary ''Code)+$(deriveBaseWithBinary ''ExceptionTable)+$(deriveBase ''CodeAttributes)
src/Language/JVM/Attribute/ConstantValue.hs view
@@ -1,3 +1,9 @@+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TemplateHaskell #-} {-| Module : Language.JVM.Attribute.ConstantValue Copyright : (c) Christian Gram Kalhauge, 2017@@ -6,21 +12,29 @@ Based on the ConstantValue, as documented [here](http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.5). -}-{-# LANGUAGE DeriveGeneric #-} module Language.JVM.Attribute.ConstantValue ( ConstantValue (..) ) where -import GHC.Generics (Generic)+import Language.JVM.Attribute.Base+import Language.JVM.Constant+import Language.JVM.Staged -import Data.Binary+-- | 'ConstantValue' is an Attribute.+instance IsAttribute (ConstantValue Low) where+ attrName = Const "ConstantValue" -import Language.JVM.Constant (ConstantRef (..)) -- | A constant value is just a index into the constant pool.-data ConstantValue = ConstantValue- { constantValueIndex :: !ConstantRef- } deriving (Show, Eq, Generic)+data ConstantValue r = ConstantValue+ { constantValue :: !(Ref JValue r)+ } -instance Binary ConstantValue where+instance Staged ConstantValue where+ evolve (ConstantValue r) =+ ConstantValue <$> link r+ devolve (ConstantValue r) =+ ConstantValue <$> unlink r++$(deriveBaseWithBinary ''ConstantValue)
src/Language/JVM/Attribute/Exceptions.hs view
@@ -1,3 +1,9 @@+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DeriveAnyClass #-} {-| Module : Language.JVM.Attribute.Exceptions Copyright : (c) Christian Gram Kalhauge, 2017@@ -7,28 +13,28 @@ Based on the Exceptions Attribute, as documented [here](http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.5). It describes the checked exceptions that a method can make. -}-{-# LANGUAGE DeriveGeneric #-}- module Language.JVM.Attribute.Exceptions ( Exceptions (..)- , exceptionIndexTable ) where -import GHC.Generics (Generic)+import Language.JVM.Attribute.Base+import Language.JVM.Staged+import Language.JVM.Constant+import Language.JVM.Utils -import Data.Binary -import Language.JVM.Constant (ConstantRef (..))-import Language.JVM.Utils+-- | 'Exceptions' is an Attribute.+instance IsAttribute (Exceptions Low) where+ attrName = Const "Exceptions" -- | An Exceptions attribute is a list of references into the -- constant pool.-data Exceptions = Exceptions- { exceptionIndexTable' :: SizedList16 ConstantRef- } deriving (Show, Eq, Generic)+newtype Exceptions r = Exceptions+ { exceptions :: SizedList16 (Ref ClassName r)+ } --- | Get the constant refs that points .-exceptionIndexTable :: Exceptions -> [ConstantRef]-exceptionIndexTable = unSizedList . exceptionIndexTable'+instance Staged Exceptions where+ evolve (Exceptions t) = Exceptions <$> mapM link t+ devolve (Exceptions t) = Exceptions <$> mapM unlink t -instance Binary Exceptions where+$(deriveBaseWithBinary ''Exceptions)
+ src/Language/JVM/Attribute/LineNumberTable.hs view
@@ -0,0 +1,79 @@+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TemplateHaskell #-}+{-|+Module : Language.JVM.Attribute.LineNumberTable+Copyright : (c) Christian Gram Kalhauge, 2018+License : MIT+Maintainer : kalhuage@cs.ucla.edu++Based on the LineNumberTable Attribute,+as documented [here](http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.12).+-}++module Language.JVM.Attribute.LineNumberTable+ ( LineNumberTable (..)+ , LineNumber++ , BinaryFormat+ -- * Helper functions+ , linenumber+ , linenumber'+ ) where++import Control.DeepSeq (NFData)+import Data.Binary+import qualified Data.IntMap as IM+import GHC.Generics (Generic)+import Language.JVM.Attribute.Base+import Language.JVM.ByteCode+import Language.JVM.Utils+import Language.JVM.Staged++-- | 'Signature' is an Attribute.+instance IsAttribute (LineNumberTable Low) where+ attrName = Const "LineNumberTable"++type LineNumber = Word16++-- | The 'LineNumberTable' is just a mapping from offsets to linenumbers.+newtype LineNumberTable r = LineNumberTable+ { lineNumberTable :: IM.IntMap LineNumber+ } deriving (Show, Eq, Ord, Generic, NFData)+++instance ByteCodeStaged LineNumberTable where+ evolveBC f (LineNumberTable mp) =+ LineNumberTable+ . IM.fromList <$> (mapM (\(x, y) -> do x' <- f (fromIntegral x); pure (x', y)) . IM.toList) mp++ devolveBC f (LineNumberTable mp) =+ LineNumberTable+ . IM.fromList <$> (mapM (\(x, y) -> do x' <- f x; pure (fromIntegral x', y)) . IM.toList) mp++-- | Returns the line number of an offset.+linenumber :: Int -> LineNumberTable r -> Maybe LineNumber+linenumber i (LineNumberTable t) =+ snd <$> IM.lookupLE i t++-- | Returns the line number of an offset. Helper function that also+-- does the conversion from integral to int.+linenumber' :: Integral a => a -> LineNumberTable r -> Maybe LineNumber+linenumber' i = linenumber (fromIntegral i)++type BinaryFormat = SizedList16 (Word16, LineNumber)++instance Binary (LineNumberTable Low) where+ get = do+ LineNumberTable . IM.fromList . map f . unSizedList <$> (get :: Get BinaryFormat)+ where+ f (a,b) = (fromIntegral a, b)+ put (LineNumberTable x) = do+ put sl+ where+ sl :: BinaryFormat+ sl = SizedList . map f . IM.toList $ x+ f (a,b) = (fromIntegral a, b)
+ src/Language/JVM/Attribute/Signature.hs view
@@ -0,0 +1,97 @@+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TemplateHaskell #-}+{-|+Module : Language.JVM.Attribute.Signature+Copyright : (c) Christian Gram Kalhauge, 2018+License : MIT+Maintainer : kalhuage@cs.ucla.edu++Based on the Signature Attribute,+as documented [here](http://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.9),+and the signature syntax defined [here](https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.9.1).+-}++module Language.JVM.Attribute.Signature+ ( Signature (..)+ , signatureToText+ , signatureFromText+ ) where++-- import Control.DeepSeq (NFData)+-- import Data.Binary+-- import qualified Data.IntMap as IM+import qualified Data.Text as Text+-- import GHC.Generics (Generic)+import Language.JVM.Attribute.Base+import Language.JVM.Staged+-- import Language.JVM.Type++instance IsAttribute (Signature Low) where+ attrName = Const "Signature"++data Signature a =+ Signature (Ref Text.Text a)++signatureToText :: Signature High -> Text.Text+signatureToText (Signature s) = s++signatureFromText :: Text.Text -> Signature High+signatureFromText s = Signature s++-- data ClassSignature = ClassSignature+-- { csTypeParameters :: [TypeParameter]+-- , csSuperclassSignature :: ClassTypeSignature+-- , csInterfaceSignatures :: [ClassTypeSignature]+-- }++-- data TypeParameter =+-- TypeParameter+-- { tpIndentifier :: Text.Text+-- , tpClassBound :: Maybe ClassName+-- , tpInterfaceBound :: [ClassName]+-- }++-- data ClassTypeSignature+-- = ClassTypeSignature+-- { ctsClassName :: ClassName+-- , ctsTypeArguments :: [TypeArgument]+-- }+-- | InnerClassTypeSignature+-- { ctsInnerClassName :: Text.Text+-- , ctsTypeArguments :: [TypeArgument]+-- }++-- data TypeArgument+-- = AnyTypeArgument+-- | TypeArgument+-- { taWildcard :: Maybe Wildcard+-- , taType :: ReferenceType+-- }++-- data ReferenceType+-- = RTClassType ClassTypeSignature+-- | RTTypeVariable TypeVariableSignature+-- | RTArrayType JavaTypeSignature++-- newtype TypeVariableSignature+-- = TypeVariableSignature Text.Text++-- data JavaTypeSignature+-- = ReferenceType ReferenceType+-- | BaseType JBaseType++-- data Wildcard =+-- WPlus | WMinus++instance Staged Signature where+ evolve (Signature a) =+ label "Signature" $ Signature <$> link a++ devolve (Signature a) =+ label "Signature" $ Signature <$> unlink a++$(deriveBaseWithBinary ''Signature)
src/Language/JVM/Attribute/StackMapTable.hs view
@@ -1,6 +1,13 @@+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TemplateHaskell #-} {-| Module : Language.JVM.Attribute.StackMapTable-Copyright : (c) Christian Gram Kalhauge, 2017+Copyright : (c) Christian Gram Kalhauge, 2018 License : MIT Maintainer : kalhuage@cs.ucla.edu @@ -8,7 +15,6 @@ as documented [here](http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.4). -}-{-# LANGUAGE DeriveGeneric #-} module Language.JVM.Attribute.StackMapTable ( StackMapTable (..)@@ -17,76 +23,86 @@ , StackMapFrameType (..) , VerificationTypeInfo (..)- ) where -import GHC.Generics (Generic)+ -- * Helper functions+ , offsetDelta+ , offsetDeltaInv+ ) where +import Control.Monad (replicateM) import Data.Binary+import Data.Binary.Get hiding (label)+import Data.Binary.Put+import Data.Foldable import Numeric-import Control.Monad (replicateM)+import Unsafe.Coerce -import Language.JVM.Constant (ConstantRef (..))+import Language.JVM.Attribute.Base+import Language.JVM.ByteCode+import Language.JVM.Constant+import Language.JVM.Staged import Language.JVM.Utils +-- | 'StackMapTable' is an Attribute.+instance IsAttribute (StackMapTable Low) where+ attrName = Const "StackMapTable"+ -- | An Exceptions attribute is a list of references into the -- constant pool.-data StackMapTable = StackMapTable- { stackMapTable :: SizedList16 StackMapFrame- } deriving (Show, Eq, Generic)--instance Binary StackMapTable where+newtype StackMapTable r = StackMapTable+ { stackMapTable :: Choice (SizedList16 (StackMapFrame Low)) [StackMapFrame High] r+ } -- | A delta offset-type DeltaOffset = Word8+type DeltaOffset i = Choice Word16 Int i -- | An stack map frame-data StackMapFrame = StackMapFrame- { deltaOffset :: DeltaOffset- , frameType :: StackMapFrameType- } deriving (Show, Eq)+data StackMapFrame r = StackMapFrame+ { deltaOffset :: DeltaOffset r+ , frameType :: StackMapFrameType r+ } -- | An stack map frame type-data StackMapFrameType+data StackMapFrameType r = SameFrame- | SameLocals1StackItemFrame VerificationTypeInfo+ | SameLocals1StackItemFrame (VerificationTypeInfo r) | ChopFrame Word8- | AppendFrame [VerificationTypeInfo]+ | AppendFrame [VerificationTypeInfo r] | FullFrame- (SizedList16 VerificationTypeInfo)- (SizedList16 VerificationTypeInfo)- deriving (Show, Eq)+ (SizedList16 (VerificationTypeInfo r))+ (SizedList16 (VerificationTypeInfo r)) -instance Binary StackMapFrame where+instance Binary (StackMapFrame Low) where get = do ft <- getWord8 let framegetter | 0 <= ft && ft <= 63- = return $ StackMapFrame ft SameFrame+ = return $ StackMapFrame (fromIntegral ft) SameFrame | 64 <= ft && ft <= 127- = StackMapFrame (ft - 64) . SameLocals1StackItemFrame <$> get+ = StackMapFrame (fromIntegral $ ft - 64) . SameLocals1StackItemFrame <$> get | 128 <= ft && ft <= 246 = fail $ "Reserved for further use: '0x" ++ showHex ft "'" | ft == 247- = StackMapFrame <$> get <*> (SameLocals1StackItemFrame <$> get)+ = StackMapFrame <$> getWord16be <*> (SameLocals1StackItemFrame <$> get) | 248 <= ft && ft <= 250- = StackMapFrame <$> get <*> pure (ChopFrame (251 - ft))+ = StackMapFrame <$> getWord16be <*> pure (ChopFrame (251 - ft)) | ft == 251- = StackMapFrame <$> get <*> pure SameFrame+ = StackMapFrame <$> getWord16be <*> pure SameFrame | 252 <= ft && ft <= 254 = do- offset <- get+ offset' <- getWord16be locals <- replicateM (fromIntegral $ ft - 251) get- return $ StackMapFrame offset (AppendFrame locals)+ return $ StackMapFrame offset' (AppendFrame locals) | ft == 255- = StackMapFrame <$> get <*> (FullFrame <$> get <*> get)+ = StackMapFrame <$> getWord16be <*> (FullFrame <$> get <*> get) | otherwise = fail $ "Unknown frame type '0x" ++ showHex ft "'"@@ -97,77 +113,146 @@ SameFrame | off <= 63 ->- putWord8 off+ putWord8 (fromIntegral off) | otherwise -> do putWord8 251- putWord8 off+ putWord16be off SameLocals1StackItemFrame vt | off <= 63 -> do- putWord8 (64 + off)+ putWord8 $ fromIntegral (64 + off) put vt | otherwise -> do putWord8 247- putWord8 off+ putWord16be off put vt ChopFrame w | 0 < w && w <= 3 -> do putWord8 (251 - w)- putWord8 off+ putWord16be off | otherwise -> fail $ "Can't write a cutoff value outside ]0,3], but was: " ++ show w AppendFrame vs | length vs <= 3 && 0 < length vs -> do putWord8 (fromIntegral $ 251 + length vs)- putWord8 off+ putWord16be off mapM_ put vs | otherwise -> fail $ "The AppendFrame has to contain at least 1 and at most 3 elements: " ++ show vs FullFrame ls1 ls2 -> do putWord8 255- put off+ putWord16be off put ls1 put ls2 -- | The types info of the stack map frame.-data VerificationTypeInfo- = VTop- | VInteger- | VFloat- | VLong- | VDouble- | VNull- | VUninitializedThis- | VObject !ConstantRef- | VUninitialized !Word16- deriving (Show, Eq)+data VerificationTypeInfo r+ = VTTop+ | VTInteger+ | VTFloat+ | VTLong+ | VTDouble+ | VTNull+ | VTUninitializedThis+ | VTObject (Ref ClassName r)+ | VTUninitialized !Word16 -instance Binary VerificationTypeInfo where++instance Binary (VerificationTypeInfo Low) where get = do tag <- getWord8 case tag of- 0 -> pure VTop- 1 -> pure VInteger- 2 -> pure VFloat- 3 -> pure VLong- 4 -> pure VDouble- 5 -> pure VNull- 6 -> pure VUninitializedThis- 7 -> VObject <$> get- 8 -> VUninitialized <$> get+ 0 -> pure VTTop+ 1 -> pure VTInteger+ 2 -> pure VTFloat+ 3 -> pure VTLong+ 4 -> pure VTDouble+ 5 -> pure VTNull+ 6 -> pure VTUninitializedThis+ 7 -> VTObject <$> get+ 8 -> VTUninitialized <$> get _ -> fail $ "Unexpected tag : '0x" ++ showHex tag "'" put a = do case a of- VTop -> putWord8 0- VInteger -> putWord8 1- VFloat -> putWord8 2- VLong -> putWord8 3- VDouble -> putWord8 4- VNull -> putWord8 5- VUninitializedThis -> putWord8 6- VObject s -> do putWord8 7; put s- VUninitialized s -> do putWord8 8; put s+ VTTop -> putWord8 0+ VTInteger -> putWord8 1+ VTFloat -> putWord8 2+ VTLong -> putWord8 3+ VTDouble -> putWord8 4+ VTNull -> putWord8 5+ VTUninitializedThis -> putWord8 6+ VTObject s -> do putWord8 7; put s+ VTUninitialized s -> do putWord8 8; put s++instance ByteCodeStaged StackMapTable where+ evolveBC f (StackMapTable ls) =+ label "StackMapTable" $+ StackMapTable . reverse . snd <$> foldl' acc (return (0, [])) ls+ where+ acc a (StackMapFrame delta frm) = do+ (lidx, lst) <- a+ frm' <- evolve frm+ let bco = if lst /= [] then offsetDelta lidx delta else delta+ x <- f bco+ return (bco, StackMapFrame x frm' : lst)++ devolveBC f (StackMapTable ls) =+ label "StackMapTable" $+ StackMapTable . SizedList . reverse . snd <$> foldl' acc (return (0 :: Word16, [])) ls+ where+ acc a (StackMapFrame x frm) = do+ (lidx, lst) <- a+ frm' <- devolve frm+ tidx <- f x+ let delta = if lst /= [] then offsetDeltaInv lidx tidx else tidx+ return (tidx, StackMapFrame delta frm' : lst)+++offsetDelta ::+ Word16+ -- ^ Last Index+ -> Word16+ -- ^ Delta+ -> Word16+ -- ^ This Index+offsetDelta lidx delta+ = lidx + delta + 1++offsetDeltaInv ::+ Word16+ -- ^ Last Index+ -> Word16+ -- ^ Current Index+ -> Word16+ -- ^ Delta+offsetDeltaInv lidx tidx+ = tidx - lidx - 1++instance Staged StackMapFrameType where+ stage f x =+ case x of+ SameLocals1StackItemFrame a -> SameLocals1StackItemFrame <$> f a+ AppendFrame ls -> AppendFrame <$> mapM f ls+ FullFrame bs as -> FullFrame <$> mapM f bs <*> mapM f as+ a -> return $ unsafeCoerce a++instance Staged VerificationTypeInfo where+ devolve x =+ case x of+ VTObject a -> VTObject <$> unlink a+ a -> return $ unsafeCoerce a++ evolve x =+ case x of+ VTObject a -> VTObject <$> link a+ a -> return $ unsafeCoerce a+++$(deriveBaseWithBinary ''StackMapTable)+$(deriveBase ''StackMapFrame)+$(deriveBase ''StackMapFrameType)+$(deriveBase ''VerificationTypeInfo)
+ src/Language/JVM/ByteCode.hs view
@@ -0,0 +1,1322 @@+{-# OPTIONS_GHC -fno-warn-name-shadowing #-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TupleSections #-}+{-|+Module : Language.JVM.ByteCode+Copyright : (c) Christian Gram Kalhauge, 2018+License : MIT+Maintainer : kalhuage@cs.ucla.edu+-}+module Language.JVM.ByteCode+ ( ByteCode (..)++ -- * evolve and devolve+ , evolveByteCode+ , devolveByteCode+ , evolveOffset+ , devolveOffset++ , ByteCodeStaged (..)++ -- * Managing offsets+ , ByteCodeInst (..)+ , ByteCodeRef+ , ByteCodeOffset+ , ByteCodeIndex+ , OffsetMap+ , indexOffset+ , offsetIndex+ , offsetMap++ -- * ByteCode Operations+ , ByteCodeOpr (..)++ , CConstant (..)+ , OneOrTwo (..)++ , SwitchTable (..)+ , switchHigh++ , FieldAccess (..)+ , Invocation (..)++ -- * Operations+ , BinOpr (..)+ , BitOpr (..)+ , CmpOpr (..)+ , CastOpr (..)++ -- * Type sets+ , ArithmeticType (..)+ , SmallArithmeticType (..)+ , LocalType (..)+ , ArrayType (..)+ , ExactArrayType (..)++ -- * Renames+ , WordSize+ , ByteOffset+ , LocalAddress+ , IncrementAmount+ ) where++import GHC.Generics (Generic)++import Numeric (showHex)+import Prelude hiding (fail)++import Control.DeepSeq (NFData)+import Control.Monad hiding (fail)+import Control.Monad.Fail (fail)+import Unsafe.Coerce++import Data.Binary+import Data.Binary.Get hiding (Get, label)+import Data.Binary.Put hiding (Put)+import qualified Data.ByteString.Lazy as BL+import Data.Int+import qualified Data.IntMap as IM+import qualified Data.Vector as V++import Language.JVM.Constant+import Language.JVM.Staged++-- | ByteCode is a newtype wrapper around a list of ByteCode instructions.+-- if the ByteCode is in the Low stage then the byte code instructions are+-- annotated with the byte code offsets.+newtype ByteCode i = ByteCode+ { unByteCode ::+ Choice (Word32, V.Vector (ByteCodeInst Low)) (V.Vector (ByteCodeOpr High)) i+ }++-- | The offset in the byte code+type ByteCodeOffset = Word16++-- | The index of the byte code.+type ByteCodeIndex = Int++-- | A ByteCode reference is either byte code offset in the+-- low stage, and a byte code index in the high state+type ByteCodeRef i = Choice ByteCodeOffset ByteCodeIndex i++-- | The offset map, maps offset to instruction ids.+type OffsetMap = IM.IntMap ByteCodeIndex++-- | Given an `OffsetMap` turn a offset into a bytecode index+offsetIndex :: OffsetMap -> ByteCodeOffset -> Maybe (ByteCodeIndex)+offsetIndex o i = IM.lookup (fromIntegral i) o++-- | Given an `OffsetMap` turn a offset into a bytecode index+evolveOffset ::+ EvolveM m+ => OffsetMap+ -> ByteCodeOffset+ -> m (ByteCodeIndex)+evolveOffset o i =+ case offsetIndex o i of+ Just a -> return $ a+ Nothing ->+ attributeError $ "Not valid offset " ++ show i++-- | Given low byte code we can create an `OffsetMap`+offsetMap :: ByteCode Low -> OffsetMap+offsetMap (ByteCode (l, v)) =+ IM.fromList+ . ((fromIntegral l, V.length v):)+ . V.ifoldl' (\ls idx i -> (fromIntegral $ offset i, idx) : ls) []+ $ v++-- | Given an `OffsetMap` turn a offset into a bytecode index+devolveOffset ::+ DevolveM m+ => ByteCode Low+ -> ByteCodeIndex+ -> m (ByteCodeOffset)+devolveOffset v i = do+ case indexOffset v i of+ Just x ->+ return x+ Nothing ->+ error $ "Bad index " ++ show i++-- | Return the bytecode offset from the bytecode.+indexOffset :: ByteCode Low -> ByteCodeIndex -> Maybe (ByteCodeOffset)+indexOffset (ByteCode (x, bc)) i =+ if i == V.length bc+ then return (fromIntegral x)+ else offset <$> bc V.!? i++devolveOffset' ::+ DevolveM m+ => V.Vector ByteCodeOffset+ -> ByteCodeIndex+ -> m (ByteCodeOffset)+devolveOffset' v i = do+ case indexOffset' v i of+ Just x ->+ return x+ Nothing ->+ error $ "Bad index " ++ show i++indexOffset' :: V.Vector ByteCodeOffset -> ByteCodeIndex -> Maybe (ByteCodeOffset)+indexOffset' c i = c V.!? i++-- | The byte code instruction is mostly used to succinctly read and+-- write an bytecode instruction from a bytestring.+data ByteCodeInst r = ByteCodeInst+ { offset :: !(ByteCodeOffset)+ , opcode :: !(ByteCodeOpr r)+ }++(...) :: (b -> c) -> (a1 -> a2 -> b) -> a1 -> a2 -> c+(...) = (.) . (.)++evolveByteCode :: EvolveM m => ByteCode Low -> m (OffsetMap, ByteCode High)+evolveByteCode bc@(ByteCode (_, v)) = do+ let om = offsetMap bc+ (om,) . ByteCode <$> V.mapM (fmap opcode . evolveByteCodeInst (evolveOffset om)) v++devolveByteCode :: DevolveM m => ByteCode High -> m (ByteCode Low)+devolveByteCode (ByteCode bc) = do+ -- Devolving byte code is not straight forward.+ (len, vect) <- V.foldM' acc (0,[]) bc+ let offsets = V.fromList . reverse $ vect+ ByteCode . (fromIntegral len,)+ <$> V.zipWithM (devolveByteCodeInst (devolveOffset' offsets) ... ByteCodeInst) offsets bc+ where+ acc (off, lst) opr = do+ inst <- devolveByteCodeInst (const $ return 0) (ByteCodeInst off opr)+ let o = off + byteSize inst+ return (o, off:lst)++class ByteCodeStaged s where+ evolveBC ::+ EvolveM m+ => (ByteCodeOffset -> m ByteCodeIndex)+ -> s Low+ -> m (s High)++ devolveBC ::+ DevolveM m+ => (ByteCodeIndex -> m ByteCodeOffset)+ -> s High+ -> m (s Low)++byteSize :: ByteCodeInst Low -> Word16+byteSize inst =+ fromIntegral . BL.length . runPut $ putByteCode (offset inst) (opcode inst)++instance ByteCodeStaged ByteCodeInst where+ evolveBC = evolveByteCodeInst+ devolveBC = devolveByteCodeInst++evolveByteCodeInst ::+ EvolveM m+ => (ByteCodeOffset -> m ByteCodeIndex)+ -> ByteCodeInst Low+ -> m (ByteCodeInst High)+evolveByteCodeInst g (ByteCodeInst ofs opr) = do+ x <- case opr of+ Push c -> label "Push" $ Push <$> evolveBConstant c+ Get fa r -> label "Get" $ Get fa <$> link r+ Put fa r -> label "Put" $ Put fa <$> link r+ Invoke r -> label "Invoke" $ Invoke <$> evolve r+ New r -> label "New" $ New <$> link r+ NewArray r -> label "NewArray" $ NewArray <$> evolve r+ MultiNewArray r u -> label "MultiNewArray" $ MultiNewArray <$> link r <*> pure u+ CheckCast r -> label "CheckCast" $ CheckCast <$> link r+ InstanceOf r -> label "InstanceOf" $ InstanceOf <$> link r+ If cp on r -> label "If" $ If cp on <$> calcOffset r+ IfRef b on r -> label "IfRef" $ IfRef b on <$> calcOffset r+ Goto r -> label "Goto" $ Goto <$> calcOffset r+ Jsr r -> label "Jsr" $ Jsr <$> calcOffset r+ TableSwitch i (SwitchTable l ofss) ->+ label "TableSwitch" $ (TableSwitch i . SwitchTable l <$> V.mapM calcOffset ofss)+ a -> return $ unsafeCoerce a+ return (ByteCodeInst ofs x)+ where+ calcOffset r =+ g (fromIntegral $ fromIntegral ofs + r)++devolveByteCodeInst ::+ DevolveM m+ => (ByteCodeIndex -> m ByteCodeOffset)+ -> ByteCodeInst High+ -> m (ByteCodeInst Low)+devolveByteCodeInst g (ByteCodeInst ofs opr) =+ ByteCodeInst ofs <$> case opr of+ Push c -> label "Push" $ Push <$> devolveBConstant c+ Get fa r -> label "Get" $ Get fa <$> unlink r+ Put fa r -> label "Put" $ Put fa <$> unlink r+ Invoke r -> label "Invoke" $ Invoke <$> devolve r+ New r -> label "New" $ New <$> unlink r+ NewArray r -> label "NewArray" $ NewArray <$> devolve r+ MultiNewArray r u -> label "MultiNewArray" $ MultiNewArray <$> unlink r <*> pure u+ CheckCast r -> label "CheckCast" $ CheckCast <$> unlink r+ InstanceOf r -> label "InstanceOf" $ InstanceOf <$> unlink r+ If cp on r -> label "If" $ If cp on <$> calcOffset r+ IfRef b on r -> label "IfRef" $ IfRef b on <$> calcOffset r+ Goto r -> label "Goto" $ Goto <$> calcOffset r+ Jsr r -> label "Jsr" $ Jsr <$> calcOffset r+ TableSwitch i (SwitchTable l ofss) -> label "TableSwitch" $+ (TableSwitch i . SwitchTable l <$> V.mapM calcOffset ofss)+ a -> return $ unsafeCoerce a+ where+ calcOffset r = do+ x <- g r+ return (fromIntegral x - fromIntegral ofs)++instance Staged Invocation where+ evolve i =+ case i of+ InvkSpecial r -> label "InvkSpecial" $ InvkSpecial <$> link r+ InvkVirtual r -> label "InvkVirtual" $ InvkVirtual <$> link r+ InvkStatic r -> label "InvkStatic" $ InvkStatic <$> link r+ InvkInterface w r -> label "InvkInterface" $ InvkInterface w <$> link r+ InvkDynamic r -> label "InvkDynamic" $ InvkDynamic <$> link r++ devolve i =+ case i of+ InvkSpecial r -> label "InvkSpecial" $ InvkSpecial <$> unlink r+ InvkVirtual r -> label "InvkVirtual" $ InvkVirtual <$> unlink r+ InvkStatic r -> label "InvkStatic" $ InvkStatic <$> unlink r+ InvkInterface w r -> label "InvkInterface" $ InvkInterface w <$> unlink r+ InvkDynamic r -> label "InvkDynamic" $ InvkDynamic <$> unlink r+++instance Staged ExactArrayType where+ evolve x =+ case x of+ EARef r -> EARef <$> link r+ a -> return $ unsafeCoerce a+ devolve x =+ case x of+ EARef r -> EARef <$> unlink r+ a -> return $ unsafeCoerce a+++instance Binary (ByteCode Low) where+ get = do+ x <- getWord32be+ bs <- getLazyByteString (fromIntegral x)+ case runGetOrFail go bs of+ Right (_,_,bcs) -> return . ByteCode . (x,) . V.fromList $ bcs+ Left (_,_,msg) -> fail msg+ where+ go = isEmpty >>= \t ->+ if t+ then return []+ else do+ x <- get+ (x:) <$> go++ put (ByteCode (_, lst))= do+ let bs = runPut (mapM_ put lst)+ putWord32be (fromIntegral $ BL.length bs)+ putLazyByteString bs++instance Binary (ByteCodeInst Low) where+ get =+ ByteCodeInst <$> (fromIntegral <$> bytesRead) <*> get+ put x =+ putByteCode (offset x) $ opcode x++-- | A short relative bytecode ref is defined in correspondence with the+type ShortRelativeRef i = Choice Int16 ByteCodeIndex i++-- | A Long relative reference. The only reason this exist because+-- the signed nature of int, looses a bit.+type LongRelativeRef i = Choice Int32 ByteCodeIndex i++data ArithmeticType = MInt | MLong | MFloat | MDouble+ deriving (Show, Ord, Eq, Enum, Bounded, Generic, NFData)++data SmallArithmeticType = MByte | MChar | MShort+ deriving (Show, Ord, Eq, Enum, Bounded, Generic, NFData)++data LocalType = LInt | LLong | LFloat | LDouble | LRef+ deriving (Show, Ord, Eq, Enum, Bounded, Generic, NFData)++data ArrayType+ = AByte | AChar | AShort | AInt | ALong+ | AFloat | ADouble | ARef+ deriving (Show, Eq, Ord, Generic, NFData)++data ExactArrayType r+ = EABoolean | EAByte | EAChar | EAShort | EAInt | EALong+ | EAFloat | EADouble | EARef (Ref ClassName r)++data Invocation r+ = InvkSpecial (DeepRef AbsVariableMethodId r)+ -- ^ Variable since 52.0+ | InvkVirtual (DeepRef AbsMethodId r)+ | InvkStatic (DeepRef AbsVariableMethodId r)+ -- ^ Variable since 52.0+ | InvkInterface Word8 (DeepRef AbsInterfaceMethodId r)+ -- ^ Should be a positive number+ | InvkDynamic (DeepRef InvokeDynamic r)++data FieldAccess+ = FldStatic+ | FldField+ deriving (Show, Ord, Eq, Generic, NFData)++data OneOrTwo = One | Two+ deriving (Show, Ord, Bounded, Eq, Enum, Generic, NFData)++type WordSize = OneOrTwo+++evolveBConstant :: EvolveM m => BConstant Low -> m (BConstant High)+evolveBConstant ccnst = do+ x <- evolve ccnst+ return $ case x of+ CNull -> Nothing+ CIntM1 -> Just $ VInteger (-1)+ CInt0 -> Just $ VInteger 0+ CInt1 -> Just $ VInteger 1+ CInt2 -> Just $ VInteger 2+ CInt3 -> Just $ VInteger 3+ CInt4 -> Just $ VInteger 4+ CInt5 -> Just $ VInteger 5+ CLong0 -> Just $ VLong 0+ CLong1 -> Just $ VLong 1+ CFloat0 -> Just $ VFloat 0+ CFloat1 -> Just $ VFloat 1+ CFloat2 -> Just $ VFloat 2+ CDouble0 -> Just $ VDouble 0+ CDouble1 -> Just $ VDouble 1+ CByte i -> Just $ VInteger (fromIntegral i)+ CShort i -> Just $ VInteger (fromIntegral i)+ CRef _ r -> Just $ r++devolveBConstant :: DevolveM m => BConstant High -> m (BConstant Low)+devolveBConstant x = do+ devolve v+ where+ v :: CConstant High+ v = case x of+ Nothing -> CNull+ Just x' -> case x' of+ VInteger i ->+ case i of+ (-1) -> CIntM1; 0 -> CInt0; 1 -> CInt1; 2 -> CInt2; 3 -> CInt3; 4 -> CInt4; 5 -> CInt5;+ i | -128 <= i && i <= 127 -> CByte (fromIntegral i)+ | -32768 <= i && i <= 32767 -> CShort (fromIntegral i)+ | otherwise -> CRef Nothing x'+ VLong 0 -> CLong0+ VLong 1 -> CLong1+ VFloat 0 -> CFloat0+ VFloat 1 -> CFloat1+ VFloat 2 -> CFloat2+ VDouble 0 -> CDouble0+ VDouble 1 -> CDouble1+ VDouble _ -> CRef (Just Two) x'+ VLong _ -> CRef (Just Two) x'+ _ -> CRef Nothing x'+++-- | A Wrapper around CConstant.+type BConstant r = Choice (CConstant r) (Maybe JValue) r++instance Staged CConstant where+ evolve x =+ case x of+ CRef w r -> label "Ref" $ CRef w <$> link r+ a -> return $ unsafeCoerce a++ devolve x =+ case x of+ CRef w r -> label "Ref" $ CRef w <$> unlink r+ a -> return $ unsafeCoerce a+++data CConstant r+ = CNull++ | CIntM1+ -- ^ -1+ | CInt0+ | CInt1+ | CInt2+ | CInt3+ | CInt4+ | CInt5++ | CLong0+ | CLong1++ | CFloat0+ | CFloat1+ | CFloat2++ | CDouble0+ | CDouble1++ | CByte Int8+ | CShort Int16++ | CRef (Maybe WordSize) (Ref JValue r)++data BinOpr+ = Add+ | Sub+ | Mul+ | Div+ | Rem+ deriving (Show, Ord, Eq, Generic, NFData)++data BitOpr+ = ShL+ | ShR+ | UShR+ | And+ | Or+ | XOr+ deriving (Show, Ord, Eq, Generic, NFData)++type LocalAddress = Word16+type IncrementAmount = Int16++maxWord8 :: Word16+maxWord8 = 0xff++data CmpOpr+ = CEq | CNe | CLt | CGe | CGt | CLe+ deriving (Show, Ord, Eq, Generic, NFData)++data CastOpr+ = CastDown SmallArithmeticType+ -- ^ Cast from Int to a smaller type+ | CastTo ArithmeticType ArithmeticType+ -- ^ Cast from any to any arithmetic type. Cannot be the same type.+ deriving (Show, Ord, Eq, Generic, NFData)+++data SwitchTable r = SwitchTable+ { switchLow :: Int32+ , switchOffsets :: V.Vector (LongRelativeRef r)+ }++switchHigh :: SwitchTable Low -> Int32+switchHigh st =+ len - 1 + switchLow st+ where+ len = fromIntegral . V.length $ switchOffsets st++data ByteCodeOpr r+ = ArrayLoad ArrayType+ -- ^ aaload baload ...+ | ArrayStore ArrayType+ -- ^ aastore bastore ...++ | Push (BConstant r)++ | Load LocalType LocalAddress+ -- ^ aload_0, bload_2, iload 5 ...+ | Store LocalType LocalAddress+ -- ^ aload, bload ...++ | BinaryOpr BinOpr ArithmeticType+ -- ^ iadd ...+ | Neg ArithmeticType+ -- ^ ineg ...++ | BitOpr BitOpr WordSize+ -- ^ Exclusively on int and long, identified by the word-size++ | IncrLocal !LocalAddress !IncrementAmount+ -- ^ Only works on ints, increment local #1, with #2++ | Cast CastOpr+ -- ^ Only valid on different types++ | CompareLongs++ | CompareFloating Bool WordSize+ -- ^ Compare two floating values, #1 indicates if greater-than, #2+ -- is if float or double should be used.++ | If CmpOpr OneOrTwo (ShortRelativeRef r)+ -- ^ compare with 0 if #2 is False, and two ints from the stack if+ -- True. the last value is the offset++ | IfRef Bool OneOrTwo (ShortRelativeRef r)+ -- ^ check if two objects are equal, or not equal. If #2 is True, compare+ -- with null.++ | Goto (LongRelativeRef r)+ | Jsr (LongRelativeRef r)+ | Ret LocalAddress++ | TableSwitch Int32 (SwitchTable r)+ -- ^ a table switch has 2 values a `default` and a `SwitchTable`+ | LookupSwitch Int32 (V.Vector (Int32, Int32))+ -- ^ a lookup switch has a `default` value and a list of pairs.++ | Get FieldAccess (DeepRef (InClass FieldId) r)+ | Put FieldAccess (DeepRef (InClass FieldId) r)++ | Invoke (Invocation r)++ | New (Ref ClassName r)++ | NewArray (ExactArrayType r)++ | ArrayLength++ | Throw++ | CheckCast (Ref ClassName r)+ | InstanceOf (Ref ClassName r)++ | Monitor Bool+ -- ^ True => Enter, False => Exit++ -- TODO: Fix this so that its more clear what it points to.+ | MultiNewArray (Ref ClassName r) Word8+ -- ^ Create a new multi array of #1 and with #2 dimensions+ -- ^ This might point to an array type.++ | Return (Maybe LocalType)++ | Nop++ | Pop WordSize++ | Dup WordSize+ | DupX1 WordSize+ | DupX2 WordSize++ | Swap+++instance Binary (ByteCodeOpr Low) where+ get = do+ cmd <- getWord8+ case cmd of+ 0x00 -> return Nop+ 0x01 -> return $ Push CNull++ 0x02 -> return $ Push CIntM1+ 0x03 -> return $ Push CInt0+ 0x04 -> return $ Push CInt1+ 0x05 -> return $ Push CInt2+ 0x06 -> return $ Push CInt3+ 0x07 -> return $ Push CInt4+ 0x08 -> return $ Push CInt5++ 0x09 -> return $ Push CLong0+ 0x0a -> return $ Push CLong1++ 0x0b -> return $ Push CFloat0+ 0x0c -> return $ Push CFloat1+ 0x0d -> return $ Push CFloat2++ 0x0e -> return $ Push CDouble0+ 0x0f -> return $ Push CDouble1++ 0x10 -> Push . CByte <$> get+ 0x11 -> Push . CShort <$> get++ 0x12 -> Push . CRef Nothing . fromIntegral <$> getWord8+ 0x13 -> Push . CRef (Just One) <$> get+ 0x14 -> Push . CRef (Just Two) <$> get++ 0x15 -> Load LInt . fromIntegral <$> getWord8+ 0x16 -> Load LLong . fromIntegral <$> getWord8+ 0x17 -> Load LFloat . fromIntegral <$> getWord8+ 0x18 -> Load LDouble . fromIntegral <$> getWord8+ 0x19 -> Load LRef . fromIntegral <$> getWord8++ 0x1a -> return $ Load LInt 0+ 0x1b -> return $ Load LInt 1+ 0x1c -> return $ Load LInt 2+ 0x1d -> return $ Load LInt 3++ 0x1e -> return $ Load LLong 0+ 0x1f -> return $ Load LLong 1+ 0x20 -> return $ Load LLong 2+ 0x21 -> return $ Load LLong 3++ 0x22 -> return $ Load LFloat 0+ 0x23 -> return $ Load LFloat 1+ 0x24 -> return $ Load LFloat 2+ 0x25 -> return $ Load LFloat 3++ 0x26 -> return $ Load LDouble 0+ 0x27 -> return $ Load LDouble 1+ 0x28 -> return $ Load LDouble 2+ 0x29 -> return $ Load LDouble 3++ 0x2a -> return $ Load LRef 0+ 0x2b -> return $ Load LRef 1+ 0x2c -> return $ Load LRef 2+ 0x2d -> return $ Load LRef 3++ 0x2e -> return $ ArrayLoad AInt+ 0x2f -> return $ ArrayLoad ALong+ 0x30 -> return $ ArrayLoad AFloat+ 0x31 -> return $ ArrayLoad ADouble+ 0x32 -> return $ ArrayLoad ARef+ 0x33 -> return $ ArrayLoad AByte+ 0x34 -> return $ ArrayLoad AChar+ 0x35 -> return $ ArrayLoad AShort++ 0x36 -> Store LInt . fromIntegral <$> getWord8+ 0x37 -> Store LLong . fromIntegral <$> getWord8+ 0x38 -> Store LFloat . fromIntegral <$> getWord8+ 0x39 -> Store LDouble . fromIntegral <$> getWord8+ 0x3a -> Store LRef . fromIntegral <$> getWord8++ 0x3b -> return $ Store LInt 0+ 0x3c -> return $ Store LInt 1+ 0x3d -> return $ Store LInt 2+ 0x3e -> return $ Store LInt 3++ 0x3f -> return $ Store LLong 0+ 0x40 -> return $ Store LLong 1+ 0x41 -> return $ Store LLong 2+ 0x42 -> return $ Store LLong 3++ 0x43 -> return $ Store LFloat 0+ 0x44 -> return $ Store LFloat 1+ 0x45 -> return $ Store LFloat 2+ 0x46 -> return $ Store LFloat 3++ 0x47 -> return $ Store LDouble 0+ 0x48 -> return $ Store LDouble 1+ 0x49 -> return $ Store LDouble 2+ 0x4a -> return $ Store LDouble 3++ 0x4b -> return $ Store LRef 0+ 0x4c -> return $ Store LRef 1+ 0x4d -> return $ Store LRef 2+ 0x4e -> return $ Store LRef 3++ 0x4f -> return $ ArrayStore AInt+ 0x50 -> return $ ArrayStore ALong+ 0x51 -> return $ ArrayStore AFloat+ 0x52 -> return $ ArrayStore ADouble+ 0x53 -> return $ ArrayStore ARef+ 0x54 -> return $ ArrayStore AByte+ 0x55 -> return $ ArrayStore AChar+ 0x56 -> return $ ArrayStore AShort++ 0x57 -> return $ Pop One+ 0x58 -> return $ Pop Two++ 0x59 -> return $ Dup One+ 0x5a -> return $ DupX1 One+ 0x5b -> return $ DupX2 One++ 0x5c -> return $ Dup Two+ 0x5d -> return $ DupX1 Two+ 0x5e -> return $ DupX2 Two++ 0x5f -> return $ Swap++ 0x60 -> return $ BinaryOpr Add MInt+ 0x61 -> return $ BinaryOpr Add MLong+ 0x62 -> return $ BinaryOpr Add MFloat+ 0x63 -> return $ BinaryOpr Add MDouble++ 0x64 -> return $ BinaryOpr Sub MInt+ 0x65 -> return $ BinaryOpr Sub MLong+ 0x66 -> return $ BinaryOpr Sub MFloat+ 0x67 -> return $ BinaryOpr Sub MDouble++ 0x68 -> return $ BinaryOpr Mul MInt+ 0x69 -> return $ BinaryOpr Mul MLong+ 0x6a -> return $ BinaryOpr Mul MFloat+ 0x6b -> return $ BinaryOpr Mul MDouble++ 0x6c -> return $ BinaryOpr Div MInt+ 0x6d -> return $ BinaryOpr Div MLong+ 0x6e -> return $ BinaryOpr Div MFloat+ 0x6f -> return $ BinaryOpr Div MDouble++ 0x70 -> return $ BinaryOpr Rem MInt+ 0x71 -> return $ BinaryOpr Rem MLong+ 0x72 -> return $ BinaryOpr Rem MFloat+ 0x73 -> return $ BinaryOpr Rem MDouble++ 0x74 -> return $ Neg MInt+ 0x75 -> return $ Neg MLong+ 0x76 -> return $ Neg MFloat+ 0x77 -> return $ Neg MDouble++ 0x78 -> return $ BitOpr ShL One+ 0x79 -> return $ BitOpr ShL Two+ 0x7a -> return $ BitOpr ShR One+ 0x7b -> return $ BitOpr ShR Two++ 0x7c -> return $ BitOpr UShR One+ 0x7d -> return $ BitOpr UShR Two++ 0x7e -> return $ BitOpr And One+ 0x7f -> return $ BitOpr And Two+ 0x80 -> return $ BitOpr Or One+ 0x81 -> return $ BitOpr Or Two+ 0x82 -> return $ BitOpr XOr One+ 0x83 -> return $ BitOpr XOr Two++ 0x84 -> IncrLocal <$> (fromIntegral <$> getWord8) <*> (fromIntegral <$> getInt8)++ 0x85 -> return $ Cast (CastTo MInt MLong)+ 0x86 -> return $ Cast (CastTo MInt MFloat)+ 0x87 -> return $ Cast (CastTo MInt MDouble)++ 0x88 -> return $ Cast (CastTo MLong MInt)+ 0x89 -> return $ Cast (CastTo MLong MFloat)+ 0x8a -> return $ Cast (CastTo MLong MDouble)++ 0x8b -> return $ Cast (CastTo MFloat MInt)+ 0x8c -> return $ Cast (CastTo MFloat MLong)+ 0x8d -> return $ Cast (CastTo MFloat MDouble)++ 0x8e -> return $ Cast (CastTo MDouble MInt)+ 0x8f -> return $ Cast (CastTo MDouble MLong)+ 0x90 -> return $ Cast (CastTo MDouble MFloat)++ 0x91 -> return $ Cast (CastDown MByte)+ 0x92 -> return $ Cast (CastDown MChar)+ 0x93 -> return $ Cast (CastDown MShort)++ 0x94 -> return $ CompareLongs++ 0x95 -> return $ CompareFloating True One+ 0x96 -> return $ CompareFloating False One++ 0x97 -> return $ CompareFloating True Two+ 0x98 -> return $ CompareFloating False Two++ 0x99 -> If CEq One <$> get+ 0x9a -> If CNe One <$> get+ 0x9b -> If CLt One <$> get+ 0x9c -> If CGe One <$> get+ 0x9d -> If CGt One <$> get+ 0x9e -> If CLe One <$> get++ 0x9f -> If CEq Two <$> get+ 0xa0 -> If CNe Two <$> get+ 0xa1 -> If CLt Two <$> get+ 0xa2 -> If CGe Two <$> get+ 0xa3 -> If CGt Two <$> get+ 0xa4 -> If CLe Two <$> get++ 0xa5 -> IfRef True Two <$> get+ 0xa6 -> IfRef False Two <$> get++ 0xa7 -> Goto . fromIntegral <$> getInt16be+ 0xa8 -> Jsr . fromIntegral <$> getInt16be++ 0xa9 -> Ret . fromIntegral <$> getWord8++ 0xaa -> do+ offset' <- bytesRead+ let skipAmount = (4 - offset' `mod` 4) `mod` 4+ skip $ fromIntegral skipAmount+ dft <- getInt32be+ low <- getInt32be+ high <- getInt32be+ table <- V.replicateM (fromIntegral $ high - low + 1) getInt32be+ return $ TableSwitch dft (SwitchTable low table)++ 0xab -> do+ offset' <- bytesRead+ let skipAmount = ((4 - offset' `mod` 4) `mod` 4)+ skip $ fromIntegral skipAmount+ dft <- getInt32be+ npairs <- getInt32be+ pairs <- V.replicateM (fromIntegral npairs) get+ return $ LookupSwitch dft pairs++ 0xac -> return . Return . Just $ LInt+ 0xad -> return . Return . Just $ LLong+ 0xae -> return . Return . Just $ LFloat+ 0xaf -> return . Return . Just $ LDouble+ 0xb0 -> return . Return . Just $ LRef+ 0xb1 -> return . Return $ Nothing++ 0xb2 -> Get FldStatic <$> get+ 0xb3 -> Put FldStatic <$> get++ 0xb4 -> Get FldField <$> get+ 0xb5 -> Put FldField <$> get++ 0xb6 -> Invoke . InvkVirtual <$> get+ 0xb7 -> Invoke . InvkSpecial <$> get+ 0xb8 -> Invoke . InvkStatic <$> get+ 0xb9 -> do+ ref <- get+ count <- get+ when (count == 0) $ fail "Should be not zero"+ zero <- getWord8+ when (zero /= 0) $ fail "Should be zero"+ return $ Invoke (InvkInterface count ref)+ 0xba -> do+ ref <- get+ count <- getWord8+ when (count /= 0) $ fail "Should be zero"+ zero <- getWord8+ when (zero /= 0) $ fail "Should be zero"+ return $ Invoke (InvkDynamic ref)+ 0xbb -> New <$> get++ 0xbc -> do+ x <- getWord8+ NewArray <$> case x of+ 4 -> return EABoolean+ 5 -> return EAChar+ 6 -> return EAFloat+ 7 -> return EADouble+ 8 -> return EAByte+ 9 -> return EAShort+ 10 -> return EAInt+ 11 -> return EALong+ _ -> fail $ "Unknown type '0x" ++ showHex x "'."++ 0xbd -> NewArray . EARef <$> get++ 0xbe -> return ArrayLength++ 0xbf -> return Throw++ 0xc0 -> CheckCast <$> get+ 0xc1 -> InstanceOf <$> get++ 0xc2 -> return $ Monitor True+ 0xc3 -> return $ Monitor False++ 0xc4 -> do+ subopcode <- getWord8+ case subopcode of+ 0x15 -> Load LInt <$> get+ 0x16 -> Load LLong <$> get+ 0x17 -> Load LFloat <$> get+ 0x18 -> Load LDouble <$> get+ 0x19 -> Load LRef <$> get++ 0x36 -> Store LInt <$> get+ 0x37 -> Store LLong <$> get+ 0x38 -> Store LFloat <$> get+ 0x39 -> Store LDouble <$> get+ 0x3a -> Store LRef <$> get++ 0x84 -> IncrLocal <$> get <*> get++ 0xa9 -> Ret <$> get++ _ -> fail $ "Wide does not work for opcode '0x"+ ++ showHex subopcode "'"++ 0xc5 -> MultiNewArray <$> get <*> get++ 0xc6 -> IfRef False One <$> get+ 0xc7 -> IfRef True One <$> get++ 0xc8 -> Goto <$> getInt32be+ 0xc9 -> Jsr <$> getInt32be++ _ -> fail $ "I do not know this bytecode '0x" ++ showHex cmd "'."++ put = putByteCode 0++putByteCode :: Word16 -> ByteCodeOpr Low -> Put+putByteCode n bc =+ case bc of+ Nop -> putWord8 0x00+ Push CNull -> putWord8 0x01++ Push CIntM1 -> putWord8 0x02+ Push CInt0 -> putWord8 0x03+ Push CInt1 -> putWord8 0x04+ Push CInt2 -> putWord8 0x05+ Push CInt3 -> putWord8 0x06+ Push CInt4 -> putWord8 0x07+ Push CInt5 -> putWord8 0x08++ Push CLong0 -> putWord8 0x09+ Push CLong1 -> putWord8 0x0a++ Push CFloat0 -> putWord8 0x0b+ Push CFloat1 -> putWord8 0x0c+ Push CFloat2 -> putWord8 0x0d++ Push CDouble0 -> putWord8 0x0e+ Push CDouble1 -> putWord8 0x0f++ Push (CByte x) -> putWord8 0x10 >> put x+ Push (CShort x) -> putWord8 0x11 >> put x++ Push (CRef (Just One) x) ->+ putWord8 0x13 >> put x+ -- In this case force the wide+ Push (CRef Nothing x)+ | x <= 0xff -> putWord8 0x12 >> (putWord8 . fromIntegral $ x)+ | otherwise -> putWord8 0x13 >> put x+ -- Here there is no direct restrictions+ Push (CRef (Just Two) r) -> putWord8 0x14 >> put r++ Load tp vl ->+ case tp of+ LInt ->+ case vl of+ 0 -> putWord8 0x1a+ 1 -> putWord8 0x1b+ 2 -> putWord8 0x1c+ 3 -> putWord8 0x1d+ a | a <= maxWord8 -> do+ putWord8 0x15+ putWord8 (fromIntegral a)+ a -> do+ putWord8 0xc4 >> putWord8 0x15 >> put a+ LLong ->+ case vl of+ 0 -> putWord8 0x1e+ 1 -> putWord8 0x1f+ 2 -> putWord8 0x20+ 3 -> putWord8 0x21+ a | a <= maxWord8 -> do+ putWord8 0x16+ putWord8 (fromIntegral a)+ a -> do+ putWord8 0xc4 >> putWord8 0x16 >> put a+ LFloat ->+ case vl of+ 0 -> putWord8 0x22+ 1 -> putWord8 0x23+ 2 -> putWord8 0x24+ 3 -> putWord8 0x25+ a | a <= maxWord8 -> do+ putWord8 0x17+ putWord8 (fromIntegral a)+ a -> do+ putWord8 0xc4 >> putWord8 0x17 >> put a+ LDouble ->+ case vl of+ 0 -> putWord8 0x26+ 1 -> putWord8 0x27+ 2 -> putWord8 0x28+ 3 -> putWord8 0x29+ a | a <= maxWord8 -> do+ putWord8 0x18+ putWord8 (fromIntegral a)+ a -> do+ putWord8 0xc4 >> putWord8 0x18 >> put a+ LRef ->+ case vl of+ 0 -> putWord8 0x2a+ 1 -> putWord8 0x2b+ 2 -> putWord8 0x2c+ 3 -> putWord8 0x2d+ a | a <= maxWord8 -> do+ putWord8 0x19+ putWord8 (fromIntegral a)+ a -> do+ putWord8 0xc4 >> putWord8 0x19 >> put a+++ ArrayLoad t ->+ case t of+ AInt -> putWord8 0x2e+ ALong -> putWord8 0x2f+ AFloat -> putWord8 0x30+ ADouble -> putWord8 0x31+ ARef -> putWord8 0x32+ AByte -> putWord8 0x33+ AChar -> putWord8 0x34+ AShort -> putWord8 0x35++ Store tp vl ->+ case tp of+ LInt ->+ case vl of+ 0 -> putWord8 0x3b+ 1 -> putWord8 0x3c+ 2 -> putWord8 0x3d+ 3 -> putWord8 0x3e+ a | a <= maxWord8 -> do+ putWord8 0x36+ putWord8 (fromIntegral a)+ a -> do+ putWord8 0xc4 >> putWord8 0x36 >> put a++ LLong ->+ case vl of+ 0 -> putWord8 0x3f+ 1 -> putWord8 0x40+ 2 -> putWord8 0x41+ 3 -> putWord8 0x42+ a | a <= maxWord8 -> do+ putWord8 0x37+ putWord8 (fromIntegral a)+ a -> do+ putWord8 0xc4 >> putWord8 0x37 >> put a++ LFloat ->+ case vl of+ 0 -> putWord8 0x43+ 1 -> putWord8 0x44+ 2 -> putWord8 0x45+ 3 -> putWord8 0x46+ a | a <= maxWord8 -> do+ putWord8 0x38+ putWord8 (fromIntegral a)+ a -> do+ putWord8 0xc4 >> putWord8 0x38 >> put a++ LDouble ->+ case vl of+ 0 -> putWord8 0x47+ 1 -> putWord8 0x48+ 2 -> putWord8 0x49+ 3 -> putWord8 0x4a+ a | a <= maxWord8 -> do+ putWord8 0x39+ putWord8 (fromIntegral a)+ a -> do+ putWord8 0xc4 >> putWord8 0x39 >> put a++ LRef ->+ case vl of+ 0 -> putWord8 0x4b+ 1 -> putWord8 0x4c+ 2 -> putWord8 0x4d+ 3 -> putWord8 0x4e+ a | a <= maxWord8 -> do+ putWord8 0x3a+ putWord8 (fromIntegral a)+ a -> do+ putWord8 0xc4 >> putWord8 0x3a >> put a++ ArrayStore AInt -> putWord8 0x4f+ ArrayStore ALong -> putWord8 0x50+ ArrayStore AFloat -> putWord8 0x51+ ArrayStore ADouble -> putWord8 0x52+ ArrayStore ARef -> putWord8 0x53+ ArrayStore AByte -> putWord8 0x54+ ArrayStore AChar -> putWord8 0x55+ ArrayStore AShort -> putWord8 0x56++ Pop One -> putWord8 0x57+ Pop Two -> putWord8 0x58++ Dup One -> putWord8 0x59+ DupX1 One -> putWord8 0x5a+ DupX2 One -> putWord8 0x5b++ Dup Two -> putWord8 0x5c+ DupX1 Two -> putWord8 0x5d+ DupX2 Two -> putWord8 0x5e++ Swap -> putWord8 0x5f++ BinaryOpr Add MInt -> putWord8 0x60+ BinaryOpr Add MLong -> putWord8 0x61+ BinaryOpr Add MFloat -> putWord8 0x62+ BinaryOpr Add MDouble -> putWord8 0x63++ BinaryOpr Sub MInt -> putWord8 0x64+ BinaryOpr Sub MLong -> putWord8 0x65+ BinaryOpr Sub MFloat -> putWord8 0x66+ BinaryOpr Sub MDouble -> putWord8 0x67++ BinaryOpr Mul MInt -> putWord8 0x68+ BinaryOpr Mul MLong -> putWord8 0x69+ BinaryOpr Mul MFloat -> putWord8 0x6a+ BinaryOpr Mul MDouble -> putWord8 0x6b++ BinaryOpr Div MInt -> putWord8 0x6c+ BinaryOpr Div MLong -> putWord8 0x6d+ BinaryOpr Div MFloat -> putWord8 0x6e+ BinaryOpr Div MDouble -> putWord8 0x6f++ BinaryOpr Rem MInt -> putWord8 0x70+ BinaryOpr Rem MLong -> putWord8 0x71+ BinaryOpr Rem MFloat -> putWord8 0x72+ BinaryOpr Rem MDouble -> putWord8 0x73++ Neg MInt -> putWord8 0x74+ Neg MLong -> putWord8 0x75+ Neg MFloat -> putWord8 0x76+ Neg MDouble -> putWord8 0x77++ BitOpr ShL One -> putWord8 0x78+ BitOpr ShL Two -> putWord8 0x79+ BitOpr ShR One -> putWord8 0x7a+ BitOpr ShR Two -> putWord8 0x7b++ BitOpr UShR One -> putWord8 0x7c+ BitOpr UShR Two -> putWord8 0x7d++ BitOpr And One -> putWord8 0x7e+ BitOpr And Two -> putWord8 0x7f+ BitOpr Or One -> putWord8 0x80+ BitOpr Or Two -> putWord8 0x81+ BitOpr XOr One -> putWord8 0x82+ BitOpr XOr Two -> putWord8 0x83++ IncrLocal s1 s2 ->+ if s1 > maxWord8 || s2 > fromIntegral (maxBound :: Int8) || s2 < fromIntegral (minBound :: Int8) then+ putWord8 0xc4 >> putWord8 0x84 >> put s1 >> put s2+ else+ putWord8 0x84 >> putWord8 (fromIntegral s1) >> putInt8 (fromIntegral s2)++ Cast a ->+ case a of+ CastTo MInt MLong -> putWord8 0x85+ CastTo MInt MFloat -> putWord8 0x86+ CastTo MInt MDouble -> putWord8 0x87++ CastTo MLong MInt -> putWord8 0x88+ CastTo MLong MFloat -> putWord8 0x89+ CastTo MLong MDouble -> putWord8 0x8a++ CastTo MFloat MInt -> putWord8 0x8b+ CastTo MFloat MLong -> putWord8 0x8c+ CastTo MFloat MDouble -> putWord8 0x8d++ CastTo MDouble MInt -> putWord8 0x8e+ CastTo MDouble MLong -> putWord8 0x8f+ CastTo MDouble MFloat -> putWord8 0x90++ CastDown MByte -> putWord8 0x91+ CastDown MChar -> putWord8 0x92+ CastDown MShort -> putWord8 0x93++ _ -> error $ "Cannot cast from " ++ show a ++ " to " ++ show a ++ "."++ CompareLongs -> putWord8 0x94++ CompareFloating True One -> putWord8 0x95+ CompareFloating False One -> putWord8 0x96++ CompareFloating True Two -> putWord8 0x97+ CompareFloating False Two -> putWord8 0x98++ If CEq One a -> putWord8 0x99 >> put a+ If CNe One a -> putWord8 0x9a >> put a+ If CLt One a -> putWord8 0x9b >> put a+ If CGe One a -> putWord8 0x9c >> put a+ If CGt One a -> putWord8 0x9d >> put a+ If CLe One a -> putWord8 0x9e >> put a++ If CEq Two a -> putWord8 0x9f >> put a+ If CNe Two a -> putWord8 0xa0 >> put a+ If CLt Two a -> putWord8 0xa1 >> put a+ If CGe Two a -> putWord8 0xa2 >> put a+ If CGt Two a -> putWord8 0xa3 >> put a+ If CLe Two a -> putWord8 0xa4 >> put a++ IfRef True Two a -> putWord8 0xa5 >> put a+ IfRef False Two a -> putWord8 0xa6 >> put a++ Goto a -> do+ if (abs a) < (2 :: Int32) ^ (15 :: Int32) then do+ putWord8 0xa7+ putInt16be (fromIntegral a)+ else do+ putWord8 0xc8+ putInt32be a+ Jsr a ->+ if (abs a) < (2 :: Int32) ^ (15 :: Int32) then do+ putWord8 0xa8+ putInt16be (fromIntegral a)+ else do+ putWord8 0xc9+ putInt32be a++ Ret a ->+ -- Check if correct size+ if a <= maxWord8+ then do+ putWord8 0xa9+ putWord8 (fromIntegral a)+ else do+ putWord8 0xc4 >> putWord8 0xa9 >> put a++ TableSwitch dft table -> do+ putWord8 0xaa+ -- missing pad+ replicateM_ (fromIntegral ((4 - (n + 1) `mod` 4) `mod` 4)) $ putWord8 0x00+ putInt32be dft+ putInt32be (switchLow table)+ putInt32be (switchHigh table)+ V.mapM_ putInt32be (switchOffsets table)++ LookupSwitch dft pairs -> do+ putWord8 0xab+ replicateM_ (fromIntegral ((4 - (n + 1) `mod` 4) `mod` 4)) $ putWord8 0x00+ putInt32be dft+ putInt32be . fromIntegral $ V.length pairs+ V.mapM_ put pairs++ Return ( Just LInt ) -> putWord8 0xac+ Return ( Just LLong ) -> putWord8 0xad+ Return ( Just LFloat ) -> putWord8 0xae+ Return ( Just LDouble ) -> putWord8 0xaf+ Return ( Just LRef ) -> putWord8 0xb0+ Return Nothing -> putWord8 0xb1++ Get FldStatic a -> putWord8 0xb2 >> put a+ Put FldStatic a -> putWord8 0xb3 >> put a++ Get FldField a -> putWord8 0xb4 >> put a+ Put FldField a -> putWord8 0xb5 >> put a++ Invoke i ->+ case i of+ InvkVirtual a -> putWord8 0xb6 >> put a+ InvkSpecial a -> putWord8 0xb7 >> put a+ InvkStatic a -> putWord8 0xb8 >> put a+ InvkInterface count a -> do+ when (count == 0) $ error "Should be not zero"+ putWord8 0xb9+ put a+ put count+ putWord8 0+ InvkDynamic a ->+ putWord8 0xba >> put a >> putWord8 0 >> putWord8 0++ New a -> putWord8 0xbb >> put a+ NewArray x -> do+ case x of+ EABoolean -> putWord8 0xbc >> putWord8 4+ EAChar -> putWord8 0xbc >> putWord8 5+ EAFloat -> putWord8 0xbc >> putWord8 6+ EADouble -> putWord8 0xbc >> putWord8 7+ EAByte -> putWord8 0xbc >> putWord8 8+ EAShort -> putWord8 0xbc >> putWord8 9+ EAInt -> putWord8 0xbc >> putWord8 10+ EALong -> putWord8 0xbc >> putWord8 11+ EARef a -> putWord8 0xbd >> put a+ ArrayLength -> putWord8 0xbe+ Throw -> putWord8 0xbf++ CheckCast a -> putWord8 0xc0 >> put a+ InstanceOf a -> putWord8 0xc1 >> put a++ Monitor True -> putWord8 0xc2+ Monitor False -> putWord8 0xc3++ MultiNewArray a b -> putWord8 0xc5 >> put a >> put b++ IfRef False One a -> putWord8 0xc6 >> put a+ IfRef True One a -> putWord8 0xc7 >> put a+++$(deriveBase ''ByteCode)+$(deriveBase ''ByteCodeInst)+$(deriveBase ''ByteCodeOpr)+$(deriveBase ''SwitchTable)+$(deriveBase ''Invocation)+$(deriveBase ''CConstant)+$(deriveBase ''ExactArrayType)
src/Language/JVM/ClassFile.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TemplateHaskell #-} {-| Module : Language.JVM.ClassFile Copyright : (c) Christian Gram Kalhauge, 2017@@ -6,85 +8,150 @@ The class file is described in this module. -}--{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE StandaloneDeriving #-} module Language.JVM.ClassFile ( ClassFile (..)-- , cInterfaces+ , cAccessFlags , cFields , cMethods- , cAttributes-- , cThisClass- , cSuperClass+ , cSignature -- * Attributes+ , ClassAttributes (..) , cBootstrapMethods ) where import Data.Binary import Data.Monoid-import qualified Data.Text as Text-import GHC.Generics (Generic)+import Data.Set import Language.JVM.AccessFlag-import Language.JVM.Attribute (Attribute, BootstrapMethods, fromAttribute')+import Language.JVM.Attribute+import Language.JVM.Attribute.BootstrapMethods+-- import Language.JVM.Attribute.Signature import Language.JVM.Constant-import Language.JVM.Field (Field)-import Language.JVM.Method (Method)+import Language.JVM.ConstantPool as CP+import Language.JVM.Field (Field)+import Language.JVM.Method (Method)+import Language.JVM.Staged import Language.JVM.Utils -- | A 'ClassFile' as described -- [here](http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html). -data ClassFile = ClassFile- { cMagicNumber :: !Word32-- , cMinorVersion :: !Word16- , cMajorVersion :: !Word16+data ClassFile r = ClassFile+ { cMagicNumber :: !Word32 - , cConstantPool :: !ConstantPool+ , cMinorVersion :: !Word16+ , cMajorVersion :: !Word16 - , cAccessFlags :: BitSet16 CAccessFlag+ , cConstantPool :: !(Choice (ConstantPool r) () r) - , cThisClassIndex :: !ConstantRef- , cSuperClassIndex :: !ConstantRef+ , cAccessFlags' :: !(BitSet16 CAccessFlag) - , cInterfaces' :: SizedList16 ConstantRef- , cFields' :: SizedList16 Field- , cMethods' :: SizedList16 Method- , cAttributes' :: SizedList16 Attribute- } deriving (Show, Eq, Generic)+ , cThisClass :: !(Ref ClassName r)+ , cSuperClass :: !(Ref ClassName r) -instance Binary ClassFile where+ , cInterfaces :: !(SizedList16 (Ref ClassName r))+ , cFields' :: !(SizedList16 (Field r))+ , cMethods' :: !(SizedList16 (Method r))+ , cAttributes :: !(Attributes ClassAttributes r)+ } --- | Get a list of 'ConstantRef's to interfaces.-cInterfaces :: ClassFile -> [ConstantRef]-cInterfaces = unSizedList . cInterfaces'+-- | Get the set of access flags+cAccessFlags :: ClassFile r -> Set CAccessFlag+cAccessFlags = toSet . cAccessFlags' -- | Get a list of 'Field's of a ClassFile.-cFields :: ClassFile -> [Field]+cFields :: ClassFile r -> [Field r] cFields = unSizedList . cFields' -- | Get a list of 'Method's of a ClassFile.-cMethods :: ClassFile -> [Method]+cMethods :: ClassFile r -> [Method r] cMethods = unSizedList . cMethods' --- | Lookup the this class in a ConstantPool-cThisClass :: ConstantPool -> ClassFile -> Maybe Text.Text-cThisClass cp = flip lookupClassName cp . cThisClassIndex --- | Lookup the super class in the ConstantPool-cSuperClass :: ConstantPool -> ClassFile -> Maybe Text.Text-cSuperClass cp = flip lookupClassName cp . cSuperClassIndex+-- | Fetch the 'BootstrapMethods' attribute.+-- There can only one bootstrap methods per class, but there might not be+-- one.+cBootstrapMethods' :: ClassFile High -> Maybe (BootstrapMethods High)+cBootstrapMethods' =+ firstOne . caBootstrapMethods . cAttributes --- | Get a list of 'Attribute's of a ClassFile.-cAttributes :: ClassFile -> [Attribute]-cAttributes = unSizedList . cAttributes'+cBootstrapMethods :: ClassFile High -> [BootstrapMethod High]+cBootstrapMethods =+ maybe [] methods . cBootstrapMethods' --- | Fetch the 'BootstrapMethods' attribute.--- There can only one be one exceptions attribute on a class-file.-cBootstrapMethods :: ConstantPool -> ClassFile -> Maybe (Either String BootstrapMethods)-cBootstrapMethods cp =- getFirst . foldMap (First . fromAttribute' cp) . cAttributes+cSignature :: ClassFile High -> Maybe (Signature High)+cSignature =+ firstOne . caSignature . cAttributes++data ClassAttributes r = ClassAttributes+ { caBootstrapMethods :: [ BootstrapMethods r]+ , caSignature :: [ Signature r ]+ , caOthers :: [ Attribute r ]+ }++instance Staged ClassFile where+ evolve cf = label "ClassFile" $ do+ tci' <- link (cThisClass cf)+ sci' <-+ if tci' /= ClassName "java/lang/Object"+ then do+ link (cSuperClass cf)+ else do+ return $ ClassName "java/lang/Object"+ cii' <- mapM link $ cInterfaces cf+ cf' <- mapM evolve $ cFields' cf+ cm' <- mapM evolve $ cMethods' cf+ ca' <- fromCollector <$> fromAttributes collect' (cAttributes cf)+ return $ cf+ { cConstantPool = ()+ , cThisClass = tci'+ , cSuperClass = sci'+ , cInterfaces = cii'+ , cFields' = cf'+ , cMethods' = cm'+ , cAttributes = ca'+ }+ where+ fromCollector (a, b, c) =+ ClassAttributes (appEndo a []) (appEndo b []) (appEndo c [])+ collect' attr =+ collect (mempty, mempty, Endo (attr:)) attr+ [ toC $ \e -> (Endo (e:), mempty, mempty)+ , toC $ \e -> (mempty, Endo (e:), mempty)]++ devolve cf = do+ tci' <- unlink (cThisClass cf)+ sci' <-+ if cThisClass cf /= ClassName "java/lang/Object" then+ unlink (cSuperClass cf)+ else+ return $ 0+ cii' <- mapM unlink $ cInterfaces cf+ cf' <- mapM devolve $ cFields' cf+ cm' <- mapM devolve $ cMethods' cf+ ca' <- fromClassAttributes $ cAttributes cf+ return $ cf+ { cConstantPool = CP.empty+ -- We cannot yet set the constant pool+ , cThisClass = tci'+ , cSuperClass = sci'+ , cInterfaces = cii'+ , cFields' = cf'+ , cMethods' = cm'+ , cAttributes = SizedList ca'+ }+ where+ fromClassAttributes (ClassAttributes cm cs at) = do+ cm' <- mapM toAttribute cm+ cs' <- mapM toAttribute cs+ at' <- mapM devolve at+ return (cm' ++ cs' ++ at')++$(deriveBase ''ClassAttributes)+$(deriveBaseWithBinary ''ClassFile)
+ src/Language/JVM/ClassFileReader.hs view
@@ -0,0 +1,225 @@+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MonoLocalBinds #-}+{-# LANGUAGE RankNTypes #-}+module Language.JVM.ClassFileReader+ ( readClassFile+ , writeClassFile++ , writeClassFile'++ -- * Finer granularity commands+ , decodeClassFile+ , encodeClassFile+ , evolveClassFile+ , devolveClassFile+ , devolveClassFile'++ -- * Evolve+ , Evolve+ , ClassFileError+ , runEvolve+ , bootstrapConstantPool++ -- * Builder+ , ConstantPoolBuilder+ , runConstantPoolBuilder+ , CPBuilder (..)+ , builderFromConstantPool+ , cpbEmpty+ ) where++import Control.DeepSeq (NFData)+import Control.Monad.Except+import Control.Monad.Reader+import Control.Monad.State+import qualified Data.ByteString.Lazy as BL+import qualified Data.IntMap as IM+import qualified Data.Map as Map+import Data.Monoid+import Data.Binary+import GHC.Generics (Generic)++import Language.JVM.ClassFile+import Language.JVM.Constant+import Language.JVM.ConstantPool as CP+import Language.JVM.Staged++-- | Decode a class file from a lazy 'BL.ByteString'. Ensures that the lazy+-- bytestring is read to EOF, and thereby closing any open files.+decodeClassFile :: BL.ByteString -> Either ClassFileError (ClassFile Low)+decodeClassFile bs = do+ case decodeOrFail bs of+ Right (rest, off, cf)+ | BL.length rest == 0 -> Right cf+ | otherwise ->+ unreadable rest off "expected end of file"+ Left (rest, off, msg) ->+ unreadable rest off msg+ where+ unreadable rest off msg =+ Left $ CFEUnreadableFile ((show off) ++ "/" ++ (show $ BL.length rest) ++ ": " ++ msg)++-- | Create a lazy byte string from a class file+encodeClassFile :: ClassFile Low -> BL.ByteString+encodeClassFile clf = do+ encode clf++-- | Changed the stage from Index to Deref+evolveClassFile :: ClassFile Low -> Either ClassFileError (ClassFile High)+evolveClassFile cf = do+ cp <- bootstrapConstantPool (cConstantPool cf)+ runEvolve cp (evolve cf)++-- | Devolve a ClassFile from High to Low. This might make the 'ClassFile' contain+-- invalid attributes, since we can't read all attributes. If this this is a problem+-- see 'devolveClassFile''.+devolveClassFile :: ClassFile High -> ClassFile Low+devolveClassFile cf =+ let (cf', cpb) = runConstantPoolBuilder (devolve cf) cpbEmpty in+ cf' { cConstantPool = cpbConstantPool cpb }++-- | Devolve a 'ClassFile' form 'High' to 'Low', while maintaining the class+-- pool of the original class file. This is useful if we care that unread+-- attributes are still valid. This can cause untended bloat as we do not+-- want to throw away anything in the program+devolveClassFile' :: ConstantPool Low -> ClassFile High -> ClassFile Low+devolveClassFile' cp cf =+ let (cf', cpb) = runConstantPoolBuilder (devolve cf) (builderFromConstantPool cp) in+ cf' { cConstantPool = cpbConstantPool cpb }+++-- | Top level command that combines 'decode' and 'evolve'.+readClassFile :: BL.ByteString -> Either ClassFileError (ClassFile High)+readClassFile bs = do+ clf <- decodeClassFile bs+ evolveClassFile clf++-- | Top level command that combines 'devolve' and 'encode'.+writeClassFile :: ClassFile High -> BL.ByteString+writeClassFile =+ encodeClassFile . devolveClassFile++-- | Top level command that combines 'devolve' and 'encode', but tries+-- to retain exact syntax of a previous run using the class pool.+writeClassFile' :: ConstantPool Low -> ClassFile High -> BL.ByteString+writeClassFile' cp =+ encodeClassFile . devolveClassFile' cp+++-- $deref+-- Dereffing is the flattening of the constant pool to get the values+-- of all references.++-- | An error while reading a class file is represented using+-- this data structure+data ClassFileError+ = CFEPoolAccessError !String !PoolAccessError+ | CFEInconsistentClassPool !String !String+ | CFEConversionError !String !String+ | CFEUnreadableFile !String+ deriving (Show, Eq, Generic)++instance NFData ClassFileError++newtype Evolve a =+ Evolve (ReaderT (String, ConstantPool High) (Either ClassFileError) a)+ deriving+ ( Functor+ , Applicative+ , Monad+ , MonadReader (String, ConstantPool High)+ , MonadError ClassFileError+ )++runEvolve :: ConstantPool High -> Evolve a -> Either ClassFileError a+runEvolve cp (Evolve m) = runReaderT m ("", cp)++instance LabelM Evolve where+ label str (Evolve m) = do+ Evolve . withReaderT (\(x, cp) -> (x ++ "/" ++ str, cp)) $ m++instance EvolveM Evolve where+ link w = do+ (lvl, cp) <- ask+ r <- either (throwError . CFEPoolAccessError lvl ) return $ access w cp+ fromConst (throwError . CFEInconsistentClassPool lvl) r++ attributeError msg = do+ (lvl, _) <- ask+ throwError (CFEConversionError lvl msg)++-- | Untie the constant pool, this requires a special operation as the constant pool+-- might reference itself.+bootstrapConstantPool :: ConstantPool Low -> Either ClassFileError (ConstantPool High)+bootstrapConstantPool reffed =+ case stage' IM.empty (IM.toList $ unConstantPool reffed) of+ Right cp ->+ Right $ ConstantPool cp+ Left xs ->+ Left . CFEInconsistentClassPool "ConstantPool"+ $ "Could not load all constants in the constant pool: " ++ (show xs)+ where+ stage' cp mis =+ let (cp', mis') = foldMap (grow cp) mis in+ case appEndo mis' [] of+ [] | IM.null cp' -> Right cp+ xs+ | IM.null cp' ->+ Left xs+ | otherwise ->+ stage' (cp `IM.union` cp') (map snd xs)++ grow cp (k,a) =+ case runEvolve (ConstantPool cp) $ evolve a of+ Right c -> (IM.singleton k c, Endo id)+ Left msg -> (IM.empty, Endo ((msg, (k,a)):))++-- $build++data CPBuilder = CPBuilder+ { cpbMapper :: Map.Map (Constant Low) Index+ , cpbConstantPool :: ConstantPool Low+ }++cpbEmpty :: CPBuilder+cpbEmpty = CPBuilder Map.empty CP.empty++builderFromConstantPool :: ConstantPool Low -> CPBuilder+builderFromConstantPool cp =+ CPBuilder (Map.fromList . map change . IM.toList $ unConstantPool cp) cp+ where+ change (a, b) = (b, fromIntegral a)+++newtype ConstantPoolBuilder a =+ ConstantPoolBuilder (State CPBuilder a)+ deriving (Monad, MonadState CPBuilder, Functor, Applicative)++runConstantPoolBuilder :: ConstantPoolBuilder a -> CPBuilder -> (a, CPBuilder)+runConstantPoolBuilder (ConstantPoolBuilder m) a=+ runState m a++instance LabelM ConstantPoolBuilder++instance DevolveM ConstantPoolBuilder where+ unlink r = do+ c <- toConst r+ c' <- devolve c+ mw <- gets (Map.lookup c' . cpbMapper)+ case mw of+ Just w -> return w+ Nothing -> do+ w <- state . stateCPBuilder $ c'+ return w++stateCPBuilder+ :: Constant Low+ -> CPBuilder+ -> (Word16, CPBuilder)+stateCPBuilder c' cpb =+ let (w, cp') = append c' . cpbConstantPool $ cpb in+ (w, cpb { cpbConstantPool = cp'+ , cpbMapper = Map.insert c' w . cpbMapper $ cpb+ })
src/Language/JVM/Constant.hs view
@@ -1,5 +1,12 @@+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TemplateHaskell #-} {-|-Module : Language.JVM.Constant Copyright : (c) Christian Gram Kalhauge, 2017 License : MIT Maintainer : kalhuage@cs.ucla.edu@@ -8,173 +15,457 @@ are essential for accessing data in the class-file. -} -{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE RankNTypes #-} module Language.JVM.Constant- (- -- * Constant- Constant (..)+ ( Constant (..) , constantSize- , ConstantRef (..)+ , typeToStr - -- * Constant Pool- -- $ConstantPool- , ConstantPool (..)+ , Referenceable (..) - , lookupConstant- , lookupText- , lookupClassName+ , JValue (..) - , toListOfConstants- ) where+ -- * Special constants+ , ClassName (..) -import GHC.Generics (Generic)+ , InClass (..) -import Prelude hiding (fail, lookup)+ , AbsMethodId+ , AbsFieldId+ , AbsInterfaceMethodId (..)+ , AbsVariableMethodId (..) -import Control.Monad (forM_)-import Control.Monad.Fail (fail)+ , MethodId (..)+ , FieldId (..)+ , NameAndType (..) ++ , MethodDescriptor+ , FieldDescriptor+++ , MethodHandle (..)+ , MethodHandleField (..)+ , MethodHandleMethod (..)+ , MethodHandleInterface (..)+ , MethodHandleFieldKind (..)+ , InvokeDynamic (..)++ -- * re-exports+ , High+ , Low+ ) where++import Control.DeepSeq (NFData)+import Control.Monad.Reader import Data.Binary-import Data.Binary.Get-import Data.Binary.Put-import qualified Data.IntMap.Strict as IM+import Data.String+import Data.Binary.IEEE754+import qualified Data.ByteString as BS+import Data.Int+import qualified Data.Text as Text+import qualified Data.Text.Encoding.Error as TE+import GHC.Generics (Generic)+import Numeric (showHex)+import Prelude hiding (fail, lookup) +import Language.JVM.Stage+import Language.JVM.TH+import Language.JVM.Type import Language.JVM.Utils -import qualified Data.Text as Text-import qualified Data.Text.Encoding as TE+-- | A constant is a multi word item in the 'ConstantPool'. Each of+-- the constructors are pretty much self-explanatory from the types.+data Constant r+ = CString !SizedByteString16+ | CInteger !Int32+ | CFloat !Float+ | CLong !Int64+ | CDouble !Double+ | CClassRef !(Ref Text.Text r)+ | CStringRef !(Ref BS.ByteString r)+ | CFieldRef !(InClass FieldId r)+ | CMethodRef !(InClass MethodId r)+ | CInterfaceMethodRef !(InClass MethodId r)+ | CNameAndType !(Ref Text.Text r) !(Ref Text.Text r)+ | CMethodHandle !(MethodHandle r)+ | CMethodType !(Ref MethodDescriptor r)+ | CInvokeDynamic !(InvokeDynamic r) --- | A constant is referenced by the ConstantRef data type. It is--- just a 16 bit word, but wrapped for type safety.-newtype ConstantRef =- ConstantRef Word16- deriving (Eq, Show, Generic)+--deriving (Show, Eq, Generic, NFData) -instance Binary ConstantRef where+-- | Anything pointing inside a class+data InClass a r = InClass+ { inClassName :: !(Ref ClassName r)+ , inClassId :: !(Ref a r)+ } --- | A constant is a multi word item in the 'ConstantPool'. Each of--- the constructors are pretty much self expiatory from the types.-data Constant- = String !SizedByteString16- | Integer !Word32- | Float !Word32- | Long !Word64- | Double !Word64- | ClassRef !ConstantRef- | StringRef !ConstantRef- | FieldRef !ConstantRef !ConstantRef- | MethodRef !ConstantRef !ConstantRef- | InterfaceMethodRef !ConstantRef !ConstantRef- | NameAndType !ConstantRef !ConstantRef- | MethodHandle !Word8 !ConstantRef- | MethodType !ConstantRef- | InvokeDynamic !ConstantRef !ConstantRef- deriving (Show, Eq)+-- | A method id in a class.+type AbsMethodId = InClass MethodId -instance Binary Constant where+-- | A field id in a class+type AbsFieldId = InClass FieldId++-- | An interface method, which is a class in a method.+newtype AbsInterfaceMethodId r = AbsInterfaceMethodId+ { interfaceMethodId :: InClass MethodId r+ }++newtype MethodId = MethodId (NameAndType MethodDescriptor)+ deriving (Eq, Show, NFData, Ord, Generic)++newtype FieldId = FieldId (NameAndType FieldDescriptor)+ deriving (Eq, Show, NFData, Ord, Generic)++instance IsString FieldId where+ fromString = FieldId . fromString++instance IsString MethodId where+ fromString = MethodId . fromString++-- | In some cases we can both point to interface methods and+-- regular methods.+data AbsVariableMethodId r+ = VInterfaceMethodId !(AbsInterfaceMethodId r)+ | VMethodId !(AbsMethodId r)++-- | The union type over the different method handles.+data MethodHandle r+ = MHField !(MethodHandleField r)+ | MHMethod !(MethodHandleMethod r)+ | MHInterface !(MethodHandleInterface r)+++data MethodHandleField r = MethodHandleField+ { methodHandleFieldKind :: !MethodHandleFieldKind+ , methodHandleFieldRef :: !(DeepRef AbsFieldId r)+ }++data MethodHandleFieldKind+ = MHGetField+ | MHGetStatic+ | MHPutField+ | MHPutStatic+ deriving (Eq, Show, NFData, Generic, Ord)++data MethodHandleMethod r+ = MHInvokeVirtual !(DeepRef AbsMethodId r)+ | MHInvokeStatic !(DeepRef AbsVariableMethodId r)+ -- ^ Since version 52.0+ | MHInvokeSpecial !(DeepRef AbsVariableMethodId r)+ -- ^ Since version 52.0+ | MHNewInvokeSpecial !(DeepRef AbsMethodId r)++data MethodHandleInterface r = MethodHandleInterface+ { methodHandleInterfaceRef :: !(DeepRef AbsInterfaceMethodId r)+ }++data InvokeDynamic r = InvokeDynamic+ { invokeDynamicAttrIndex :: !Word16+ , invokeDynamicMethod :: !(Ref MethodId r)+ }++-- | Hack that returns the name of a constant.+typeToStr :: Constant r -> String+typeToStr c =+ case c of+ CString _ -> "CString"+ CInteger _ -> "CInteger"+ CFloat _ -> "CFloat"+ CLong _ -> "CLong"+ CDouble _ -> "CDouble"+ CClassRef _ -> "CClassRef"+ CStringRef _ -> "CStringRef"+ CFieldRef _ -> "CFieldRef"+ CMethodRef _ -> "CMethodRef"+ CInterfaceMethodRef _ -> "CInterfaceMethodRef"+ CNameAndType _ _ -> "CNameAndType"+ CMethodHandle _ -> "CMethodHandle"+ CMethodType _ -> "CMethodType"+ CInvokeDynamic _ -> "CInvokeDynamic"++instance Binary (Constant Low) where get = do ident <- getWord8 case ident of- 1 -> String <$> get- 3 -> Integer <$> get- 4 -> Float <$> get- 5 -> Long <$> get- 6 -> Double <$> get- 7 -> ClassRef <$> get- 8 -> StringRef <$> get- 9 -> FieldRef <$> get <*> get- 10 -> MethodRef <$> get <*> get- 11 -> InterfaceMethodRef <$> get <*> get- 12 -> NameAndType <$> get <*> get- 15 -> MethodHandle <$> get <*> get- 16 -> MethodType <$> get- 18 -> InvokeDynamic <$> get <*> get+ 1 -> CString <$> get+ 3 -> CInteger <$> get+ 4 -> CFloat <$> getFloat32be+ 5 -> CLong <$> get+ 6 -> CDouble <$> getFloat64be+ 7 -> CClassRef <$> get+ 8 -> CStringRef <$> get+ 9 -> CFieldRef <$> get+ 10 -> CMethodRef <$> get+ 11 -> CInterfaceMethodRef <$> get+ 12 -> CNameAndType <$> get <*> get+ 15 -> CMethodHandle <$> get+ 16 -> CMethodType <$> get+ 18 -> CInvokeDynamic <$> get _ -> fail $ "Unkown identifier " ++ show ident put x = case x of- String bs -> do putWord8 1; put bs- Integer i -> do putWord8 3; put i- Float i -> do putWord8 4; put i- Long i -> do putWord8 5; put i- Double i -> do putWord8 6; put i- ClassRef i -> do putWord8 7; put i- StringRef i -> do putWord8 8; put i- FieldRef i j -> do putWord8 9; put i; put j- MethodRef i j -> do putWord8 10; put i; put j- InterfaceMethodRef i j -> do putWord8 11; put i; put j- NameAndType i j -> do putWord8 12; put i; put j- MethodHandle i j -> do putWord8 15; put i; put j- MethodType i -> do putWord8 16; put i;- InvokeDynamic i j -> do putWord8 18; put i; put j+ CString bs -> do putWord8 1; put bs+ CInteger i -> do putWord8 3; put i+ CFloat i -> do putWord8 4; putFloat32be i+ CLong i -> do putWord8 5; put i+ CDouble i -> do putWord8 6; putFloat64be i+ CClassRef i -> do putWord8 7; put i+ CStringRef i -> do putWord8 8; put i+ CFieldRef i -> do putWord8 9; put i+ CMethodRef i -> do putWord8 10; put i+ CInterfaceMethodRef i -> do putWord8 11; put i+ CNameAndType i j -> do putWord8 12; put i; put j+ CMethodHandle h -> do putWord8 15; put h+ CMethodType i -> do putWord8 16; put i;+ CInvokeDynamic i -> do putWord8 18; put i +instance Binary (MethodHandle Low) where+ get = do+ w <- getWord8+ case w of+ 1 -> MHField . MethodHandleField MHGetField <$> get+ 2 -> MHField . MethodHandleField MHGetStatic <$> get+ 3 -> MHField . MethodHandleField MHPutField <$> get+ 4 -> MHField . MethodHandleField MHPutStatic <$> get++ 5 -> MHMethod . MHInvokeVirtual <$> get+ 6 -> MHMethod . MHInvokeStatic <$> get+ 7 -> MHMethod . MHInvokeSpecial<$> get+ 8 -> MHMethod . MHNewInvokeSpecial <$> get++ 9 -> MHInterface . MethodHandleInterface <$> get++ _ -> fail $ "Unknown method handle kind 'x" ++ showHex w "'"++ put x = case x of+ MHField h -> do+ putWord8 $ case methodHandleFieldKind h of+ MHGetField -> 1+ MHGetStatic -> 2+ MHPutField -> 3+ MHPutStatic -> 4+ put $ methodHandleFieldRef h++ MHMethod h -> do+ case h of+ MHInvokeVirtual m -> putWord8 5 >> put m+ MHInvokeStatic m -> putWord8 6 >> put m+ MHInvokeSpecial m -> putWord8 7 >> put m+ MHNewInvokeSpecial m -> putWord8 8 >> put m++ MHInterface h -> do+ putWord8 9+ put $ methodHandleInterfaceRef h+ -- | Some of the 'Constant's take up more space in the constant pool than other. -- Notice that 'Language.JVM.Constant.String' and 'MethodType' is not of size -- 32, but is still awarded value 1. This is due to an -- [inconsistency](http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4.5) -- in JVM.-constantSize :: Constant -> Int+constantSize :: Constant r -> Int constantSize x = case x of- Double _ -> 2- Long _ -> 2- _ -> 1+ CDouble _ -> 2+ CLong _ -> 2+ _ -> 1 --- $ConstantPool------ The 'ConstantPool' contains all the constants, and is accessible using the--- Lookup methods.+-- | 'Referenceable' is something that can exist in the constant pool.+class Referenceable a where+ fromConst+ :: (Monad m)+ => (forall a'. String -> m a')+ -> Constant High+ -> m a+ toConst+ :: (Monad m)+ => a+ -> m (Constant High) --- | A ConstantPool is just an 'IntMap'. A 'IntMap' is used, because constants are--- accessed after their byte-offset. 'constantSize'-newtype ConstantPool = ConstantPool- { unConstantPool :: IM.IntMap Constant- } deriving (Show, Eq)+instance Referenceable (Constant High) where+ fromConst _ a = return a+ toConst a = return a --- | Return a list of reference-constant pairs.-toListOfConstants :: ConstantPool -> [(ConstantRef, Constant)]-toListOfConstants =- map (\(a,b) -> (ConstantRef . fromIntegral $ a, b)) . IM.toList . unConstantPool+instance TypeParse a => Referenceable (NameAndType a) where+ fromConst err (CNameAndType rn txt) = do+ md <- either err return $ fromText txt+ return $ NameAndType rn md+ fromConst e c = expected "CNameAndType" e c -instance Binary ConstantPool where- get = do- len <- fromIntegral <$> getInt16be- list <- go len 1- return . ConstantPool $ IM.fromList list- where- go len n | len > n = do- constant <- get- rest <- go len (n + constantSize constant)- return $ (n, constant) : rest- go _ _ = return []- put (ConstantPool p)= do- case IM.maxViewWithKey p of- Just ((key, e), _) -> do- putInt16be (fromIntegral (key + constantSize e))- forM_ (IM.toAscList p) (put . snd)- Nothing -> do- putInt16be 0+ toConst (NameAndType rn md) =+ return $ CNameAndType rn (toText md) --- | Lookup a 'Constant' in the 'ConstantPool'.-lookupConstant :: ConstantRef -> ConstantPool -> Maybe Constant-lookupConstant (ConstantRef ref) (ConstantPool cp) =- IM.lookup (fromIntegral ref) cp+-- TODO: Find good encoding of string.+instance Referenceable Text.Text where+ fromConst err c =+ case c of+ CString str ->+ case sizedByteStringToText str of+ Left (TE.DecodeError msg _) ->+ err $ badEncoding msg (unSizedByteString str)+ Left _ -> error "This is deprecated in the api"+ Right txt -> return txt+ a -> err $ wrongType "String" a --- | Lookup a 'Text.Text' in the 'ConstantPool', returns 'Nothing' if the--- reference does not point to something in the ConstantPool, if it points to--- something not a 'Language.JVM.Constant.String' Constant, or if it is--- impossible to decode the 'ByteString' as Utf8.-lookupText :: ConstantRef -> ConstantPool -> Maybe Text.Text-lookupText ref cp = do- String str <- lookupConstant ref cp- case TE.decodeUtf8' . unSizedByteString $ str of- Left _ -> Nothing- Right txt -> Just txt+ toConst =+ return . CString . sizedByteStringFromText --- | Lookup a class name in the 'ConstantPool', returns 'Nothing' otherwise.-lookupClassName :: ConstantRef -> ConstantPool -> Maybe Text.Text-lookupClassName ref cp = do- ClassRef r <- lookupConstant ref cp- lookupText r cp+instance Referenceable BS.ByteString where+ fromConst err c =+ case c of+ CString str -> return $ unSizedByteString str+ a -> err $ wrongType "String" a+ toConst =+ return . CString . SizedByteString+++instance Referenceable ClassName where+ fromConst _ (CClassRef r) =+ return . ClassName $ r+ fromConst err a =+ err $ wrongType "ClassRef" a++ toConst (ClassName txt) = do+ return . CClassRef $ txt++instance Referenceable MethodDescriptor where+ fromConst err =+ fromConst err >=> either err pure . fromText+ toConst = toConst . toText++instance Referenceable FieldDescriptor where+ fromConst err =+ fromConst err >=> either err pure . fromText+ toConst = toConst . toText++-- instance TypeParse f => Referenceable (NameAndType f) where+-- fromConst err =+-- fromConst err >=> either err pure . fromText+-- toConst = toConst . toText++instance Referenceable MethodId where+ fromConst err x = MethodId <$> fromConst err x+ toConst (MethodId s) = toConst s++instance Referenceable FieldId where+ fromConst err x = FieldId <$> fromConst err x+ toConst (FieldId s) = toConst s++instance Referenceable (InClass FieldId High) where+ fromConst _ (CFieldRef s) = do+ return $ s+ fromConst err c = expected "CFieldRef" err c++ toConst s =+ return $ CFieldRef s++instance Referenceable (InClass MethodId High) where+ fromConst _ (CMethodRef s) = do+ return $ s+ fromConst err c = expected "CMethodRef" err c++ toConst s =+ return $ CMethodRef s++instance Referenceable (InvokeDynamic High) where+ fromConst _ (CInvokeDynamic c) = do+ return $ c+ fromConst err c = expected "CInvokeDynamic" err c++ toConst s =+ return $ CInvokeDynamic s++instance Referenceable (MethodHandle High) where+ fromConst _ (CMethodHandle c) = do+ return $ c+ fromConst err c = expected "CMethodHandle" err c++ toConst s =+ return $ CMethodHandle s++instance Referenceable (AbsInterfaceMethodId High) where+ fromConst _ (CInterfaceMethodRef s) = do+ return . AbsInterfaceMethodId $ s+ fromConst err c = expected "CInterfaceMethodRef" err c++ toConst (AbsInterfaceMethodId s) =+ return $ CInterfaceMethodRef s++instance Referenceable (AbsVariableMethodId High) where+ fromConst _ (CInterfaceMethodRef s) = do+ return . VInterfaceMethodId . AbsInterfaceMethodId $ s++ fromConst _ (CMethodRef s) = do+ return . VMethodId $ s++ fromConst err c = expected "CInterfaceMethodRef or CMethodRef" err c++ toConst (VInterfaceMethodId (AbsInterfaceMethodId s)) =+ return $ CInterfaceMethodRef s++ toConst (VMethodId s) =+ return $ CMethodRef s++expected :: String -> (String -> a) -> (Constant r) -> a+expected name err c =+ err $ wrongType name c++wrongType :: String -> Constant r -> String+wrongType n c =+ "Expected '" ++ n ++ "', but found '" ++ typeToStr c ++ "'."++badEncoding :: String -> BS.ByteString -> String+badEncoding str bs =+ "Could not encode '" ++ str ++ "': " ++ show bs++-- $(deriveBaseWithBinary ''MethodId)+-- $(deriveBaseWithBinary ''FieldId)++$(deriveBase ''Constant)+$(deriveBase ''MethodHandle)+$(deriveBase ''MethodHandleField)+$(deriveBase ''MethodHandleMethod)+$(deriveBase ''MethodHandleInterface)+$(deriveBaseWithBinary ''InvokeDynamic)++$(deriveBaseWithBinary ''AbsMethodId)+$(deriveBaseWithBinary ''AbsFieldId)+$(deriveBaseWithBinary ''AbsInterfaceMethodId)+$(deriveBaseWithBinary ''AbsVariableMethodId)++-- | A constant pool value in java+data JValue+ = VInteger Int32+ | VLong Int64+ | VFloat Float+ | VDouble Double+ | VString BS.ByteString+ | VClass ClassName+ | VMethodType (MethodDescriptor)+ | VMethodHandle (MethodHandle High)+ deriving (Show, Eq, Generic, NFData)++instance Referenceable JValue where+ fromConst err c = do+ case c of+ CStringRef s -> return $ VString s+ CInteger i -> return $ VInteger i+ CFloat f -> return $ VFloat f+ CLong l -> return $ VLong l+ CDouble d -> return $ VDouble d+ CClassRef r -> return $ VClass (ClassName r)+ CMethodHandle m -> return $ VMethodHandle m+ CMethodType t -> return $ VMethodType t+ x -> expected "Expected a Value" err x++ toConst c =+ return $ case c of+ VString s -> CStringRef s+ VInteger i -> CInteger i+ VFloat f -> CFloat f+ VLong l -> CLong l+ VDouble d -> CDouble d+ VClass (ClassName r) -> CClassRef r+ VMethodHandle m -> CMethodHandle m+ VMethodType t -> CMethodType t
+ src/Language/JVM/ConstantPool.hs view
@@ -0,0 +1,105 @@+{-# LANGUAGE TupleSections #-}+{-# LANGUAGE DeriveFunctor #-}+-- {-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TemplateHaskell #-}+{-|+Copyright : (c) Christian Gram Kalhauge, 2018+License : MIT+Maintainer : kalhuage@cs.ucla.edu++This module contains the 'ConstantPool' data structure and multiple+other types, and classes.+-}+module Language.JVM.ConstantPool+ (+ -- * Constant Pool+ -- $ConstantPool+ ConstantPool (..)+ , access+ , append+ , empty+ , PoolAccessError (..)+ ) where++import Control.DeepSeq (NFData)+import Control.Monad.Except+import Data.Binary+-- import Debug.Trace+import Data.Binary.Get+import Data.Binary.Put+import qualified Data.IntMap as IM+import GHC.Generics (Generic)++import Language.JVM.Constant+import Language.JVM.Stage+import Language.JVM.TH+++-- $ConstantPool+-- The 'ConstantPool' contains all the constants, and is accessible using the+-- Lookup methods.++-- | A ConstantPool is just an 'IntMap'. A 'IntMap' is used, because constants are+-- accessed using their byte-offset, and sometimes the offset depends on the constant+-- size. See 'constantSize'.+newtype ConstantPool r = ConstantPool+ { unConstantPool :: IM.IntMap (Constant r)+ }++instance Binary (ConstantPool Low) where+ get = do+ len <- fromIntegral <$> getWord16be+ list <- go len 1+ return . ConstantPool $ IM.fromList list+ where+ go len n | len > n = do+ constant <- get+ rest <- go len (n + constantSize constant)+ return $ (n, constant) : rest+ go _ _ = return []+ put (ConstantPool p) = do+ case IM.maxViewWithKey p of+ Just ((key, e), _) -> do+ putInt16be (fromIntegral (key + constantSize e))+ forM_ (IM.toAscList p) (put . snd)+ Nothing -> do+ putInt16be 0++-- | A pool access error+data PoolAccessError = PoolAccessError+ { paErrorRef :: !Word16+ , paErrorMsg :: String+ } deriving (Show, Eq, Generic)++instance NFData PoolAccessError++-- | Creates an empty constant pool+empty :: ConstantPool r+empty = ConstantPool (IM.empty)++-- | Access a constant in the constant pool+access :: Index -> ConstantPool r -> Either PoolAccessError (Constant r)+access ref (ConstantPool cp) =+ case IM.lookup (fromIntegral ref) cp of+ Just x -> Right x+ Nothing -> Left $ PoolAccessError ref "No such element."++-- | Append a constant to the constant pool, and get the offset.+append :: Constant r -> ConstantPool r -> (Index, ConstantPool r)+append c (ConstantPool cp) =+ (fromIntegral i, ConstantPool $ IM.insert i c cp)+ where+ i =+ case IM.toDescList cp of+ (k, a):_ ->+ k + constantSize a+ _ -> 1++$(deriveBase ''ConstantPool)
src/Language/JVM/Field.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE TemplateHaskell #-} {-| Module : Language.JVM.Field Copyright : (c) Christian Gram Kalhauge, 2017@@ -5,36 +6,86 @@ Maintainer : kalhuage@cs.ucla.edu -} -{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE StandaloneDeriving #-} module Language.JVM.Field ( Field (..)-+ , fAccessFlags -- * Attributes , fConstantValue+ , fSignature+ , FieldAttributes (..) ) where -import Data.Binary-import Data.Monoid-import GHC.Generics (Generic) +import Data.Monoid+import qualified Data.Set as Set+import qualified Data.Text as Text+ import Language.JVM.AccessFlag-import Language.JVM.Attribute (Attribute, ConstantValue, fromAttribute')-import Language.JVM.Constant (ConstantRef, ConstantPool)+import Language.JVM.Attribute+import Language.JVM.Constant+import Language.JVM.Staged import Language.JVM.Utils + -- | A Field in the class-file, as described -- [here](http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.5).-data Field = Field- { fAccessFlags :: BitSet16 FAccessFlag- , fNameIndex :: ! ConstantRef- , fDescriptorIndex :: ! ConstantRef- , fAttributes :: SizedList16 Attribute- } deriving (Show, Eq, Generic)+data Field r = Field+ { fAccessFlags' :: !(BitSet16 FAccessFlag)+ , fName :: !(Ref Text.Text r)+ , fDescriptor :: !(Ref FieldDescriptor r)+ , fAttributes :: !(Attributes FieldAttributes r)+ } -instance Binary Field where+-- | Get the set of access flags+fAccessFlags :: Field r -> Set.Set FAccessFlag+fAccessFlags = toSet . fAccessFlags' -- | Fetch the 'ConstantValue' attribute.--- There can only one be one exceptions attribute on a field.-fConstantValue :: ConstantPool -> Field -> Maybe (Either String ConstantValue)-fConstantValue cp =- getFirst . foldMap (First . fromAttribute' cp) . fAttributes+fConstantValue :: Field High -> Maybe (ConstantValue High)+fConstantValue =+ firstOne . faConstantValues . fAttributes++-- | Fetches the 'Signature' attribute, if any.+fSignature :: Field High -> Maybe (Signature High)+fSignature =+ firstOne . faSignatures . fAttributes++data FieldAttributes r = FieldAttributes+ { faConstantValues :: [ ConstantValue r ]+ , faSignatures :: [ Signature r ]+ , faOthers :: [ Attribute r ]+ }++instance Staged Field where+ evolve field = label "Field" $ do+ fi <- link (fName field)+ fd <- link (fDescriptor field)+ fattr <- fromCollector <$> fromAttributes collect' (fAttributes field)+ return $ Field (fAccessFlags' field) fi fd fattr+ where+ fromCollector (cv, sig, others) =+ FieldAttributes (appEndo cv []) (appEndo sig []) (appEndo others [])+ collect' attr =+ collect (mempty, mempty, Endo(attr:)) attr+ [ toC $ \x -> (Endo (x:), mempty, mempty)+ , toC $ \x -> (mempty, Endo (x:), mempty) ]++ devolve field = do+ fi <- unlink (fName field)+ fd <- unlink (fDescriptor field)+ fattr <- fromFieldAttributes (fAttributes field)+ return $ Field (fAccessFlags' field) fi fd (SizedList fattr)++ where+ fromFieldAttributes (FieldAttributes cvs fsg attr) =+ (\a b c -> a ++ b ++ c)+ <$> mapM toAttribute cvs+ <*> mapM toAttribute fsg+ <*> mapM devolve attr++$(deriveBase ''FieldAttributes)+$(deriveBaseWithBinary ''Field)
src/Language/JVM/Method.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TemplateHaskell #-} {-| Module : Language.JVM.Method Copyright : (c) Christian Gram Kalhauge, 2017@@ -5,69 +7,108 @@ Maintainer : kalhuage@cs.ucla.edu -} -{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE StandaloneDeriving #-} module Language.JVM.Method ( Method (..)- , mAccessFlags- , mAttributes - , mName- , mDescriptor- -- * Attributes+ , MethodAttributes (..) , mCode+ , mExceptions' , mExceptions+ , mSignature ) where -import Data.Binary-import Data.Set (Set)-import qualified Data.Text as Text-import GHC.Generics (Generic)-+import Data.Maybe import Data.Monoid+import Data.Set (Set)+import qualified Data.Text as Text import Language.JVM.AccessFlag-import Language.JVM.Attribute (Attribute, fromAttribute', Code, Exceptions)-import Language.JVM.Constant (ConstantRef, ConstantPool, lookupText)+import Language.JVM.Attribute+import Language.JVM.Attribute.Exceptions (exceptions)+import Language.JVM.Constant+import Language.JVM.Staged+import Language.JVM.Type import Language.JVM.Utils -- | A Method in the class-file, as described -- [here](http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.6).-data Method = Method- { mAccessFlags' :: BitSet16 MAccessFlag- , mNameIndex :: ! ConstantRef- , mDescriptorIndex :: ! ConstantRef- , mAttributes' :: SizedList16 Attribute- } deriving (Show, Eq, Generic)--instance Binary Method where+data Method r = Method+ { mAccessFlags' :: !(BitSet16 MAccessFlag)+ , mName :: !(Ref Text.Text r)+ , mDescriptor :: !(Ref MethodDescriptor r)+ , mAttributes :: !(Attributes MethodAttributes r)+ } -- | Unpack the BitSet and get the AccessFlags as a Set.-mAccessFlags :: Method -> Set MAccessFlag+mAccessFlags :: Method r -> Set MAccessFlag mAccessFlags = toSet . mAccessFlags' --- | Unpack the SizedList and get the attributes as a List.-mAttributes :: Method -> [Attribute]-mAttributes = unSizedList . mAttributes'---- | Lookup the name of the method in the 'ConstantPool'.-mName :: ConstantPool -> Method -> Maybe Text.Text-mName cp = flip lookupText cp . mNameIndex---- | Lookup the descriptor of the method in the 'ConstantPool'.-mDescriptor :: ConstantPool -> Method -> Maybe Text.Text-mDescriptor cp = flip lookupText cp . mDescriptorIndex+data MethodAttributes r = MethodAttributes+ { maCode :: [Code r]+ , maExceptions :: [Exceptions r]+ , maSignatures :: [Signature r]+ , maOthers :: [Attribute r]+ } -- | Fetch the 'Code' attribute, if any.--- There can only one be one code attribute on a method.-mCode :: ConstantPool -> Method -> Maybe (Either String Code)-mCode cp =- getFirst . foldMap (First . fromAttribute' cp) . mAttributes+-- There can only be one code attribute in a method.+mCode :: Method High -> Maybe (Code High)+mCode =+ firstOne . maCode . mAttributes -- | Fetch the 'Exceptions' attribute.--- There can only one be one exceptions attribute on a method.-mExceptions :: ConstantPool -> Method -> Maybe (Either String Exceptions)-mExceptions cp =- getFirst . foldMap (First . fromAttribute' cp) . mAttributes+-- There can only be one exceptions attribute in a method.+mExceptions' :: Method High -> Maybe (Exceptions High)+mExceptions' =+ firstOne . maExceptions . mAttributes++-- | Fetches the 'Exceptions' attribute, but turns it into an list of exceptions.+-- If no exceptions field where found the empty list is returned+mExceptions :: Method High -> [ClassName]+mExceptions =+ fromMaybe [] . fmap (unSizedList . exceptions) . mExceptions'++-- | Fetches the 'Signature' attribute, if any.+mSignature :: Method High -> Maybe (Signature High)+mSignature =+ firstOne . maSignatures . mAttributes++instance Staged Method where+ evolve (Method mf mn md mattr) = do+ mn' <- link mn+ md' <- link md+ mattr' <- label (Text.unpack (mn' <> ":" <> toText md'))+ $ fromCollector <$> fromAttributes collect' mattr+ return $ Method mf mn' md' mattr'+ where+ fromCollector (a, b, c, d) =+ MethodAttributes (appEndo a []) (appEndo b []) (appEndo c []) (appEndo d [])+ collect' attr =+ collect (mempty, mempty, mempty, Endo (attr:)) attr+ [ toC $ \e -> (Endo (e:), mempty, mempty, mempty)+ , toC $ \e -> (mempty, Endo (e:), mempty, mempty)+ , toC $ \e -> (mempty, mempty, Endo (e:), mempty)+ ]++ devolve (Method mf mn md mattr) = do+ mn' <- unlink mn+ md' <- unlink md+ mattr' <- fromMethodAttributes $ mattr+ return $ Method mf mn' md' (SizedList mattr')+ where+ fromMethodAttributes (MethodAttributes a b c d) = do+ a' <- mapM toAttribute a+ b' <- mapM toAttribute b+ c' <- mapM toAttribute c+ d' <- mapM devolve d+ return (a' ++ b' ++ c' ++ d')++$(deriveBase ''MethodAttributes)+$(deriveBaseWithBinary ''Method)
+ src/Language/JVM/Stage.hs view
@@ -0,0 +1,49 @@+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE RankNTypes #-}+{-|+Copyright : (c) Christian Gram Kalhauge, 2018+License : MIT+Maintainer : kalhuage@cs.ucla.edu++This module contains the stages, there are two stages; 'Low' and 'High'. 'Low'+represents closest to the metal and 'High' represents closer to the conceptual+representation.+-}+module Language.JVM.Stage+ ( Low+ , High+ , Ref+ , Index+ , DeepRef+ , Choice+ ) where++import Data.Word++-- | Any data structure that is in the low stage should be serializable using+-- the binary library.+data Low++-- | Any data structure in the 'High' stage, is easier to read.+data High++-- | The basic part of the stage system is the choice. The 'Choice' chooses+-- between two types depending on the stage.+type family Choice a b r+type instance Choice a b High = b+type instance Choice a b Low = a++-- | An index into the constant pool.+type Index = Word16++-- | A reference is a choice between an index and a value.+type Ref v r = Choice Index v r++-- | A deep reference points to something that itself is staged.+type DeepRef v r = Ref (v r) r
+ src/Language/JVM/Staged.hs view
@@ -0,0 +1,146 @@+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE AllowAmbiguousTypes #-}+{-|+Copyright : (c) Christian Gram Kalhauge, 2018+License : MIT+Maintainer : kalhuage@cs.ucla.edu++-}+module Language.JVM.Staged+ ( Staged (..)++ -- * Monad Classes+ , LabelM (..)+ , EvolveM (..)+ , DevolveM (..)+ -- * Re-exports+ , module Language.JVM.Stage+ , module Language.JVM.TH+ ) where++import Language.JVM.Constant+import Language.JVM.Stage+import Language.JVM.TH++class Monad m => LabelM m where+ label :: String -> m a -> m a+ -- ^ label the current position in the class-file, good for debugging+ label _ = id++class LabelM m => EvolveM m where+ link :: Referenceable r => Index -> m r+ attributeError :: String -> m r++class LabelM m => DevolveM m where+ unlink :: Referenceable r => r -> m Index++class Staged s where+ {-# MINIMAL stage | evolve, devolve #-}+ stage :: LabelM m => (forall s'. Staged s' => s' r -> m (s' r')) -> s r -> m (s r')+ stage f a = f a++ evolve :: EvolveM m => s Low -> m (s High)+ evolve = stage evolve++ devolve :: DevolveM m => s High -> m (s Low)+ devolve = stage devolve++instance Staged Constant where+ evolve c =+ case c of+ CString s -> pure $ CString s+ CInteger i -> pure $ CInteger i+ CFloat d -> pure $ CFloat d+ CLong l -> pure $ CLong l+ CDouble d -> pure $ CDouble d+ CClassRef r -> label "CClassRef" $ CClassRef <$> link r+ CStringRef r -> label "CStringRef" $ CStringRef <$> link r+ CFieldRef r -> label "CFieldRef" $ CFieldRef <$> evolve r+ CMethodRef r -> label "CMethodRef" $ CMethodRef <$> evolve r+ CInterfaceMethodRef r -> label "CInterfaceMethodRef" $ CInterfaceMethodRef <$> evolve r+ CNameAndType r1 r2 -> label "CNameAndType" $ CNameAndType <$> link r1 <*> link r2+ CMethodHandle mh -> label "CMetho" $ CMethodHandle <$> evolve mh+ CMethodType r -> label "CMethodType" $ CMethodType <$> link r+ CInvokeDynamic i -> label "CInvokeDynamic" $ CInvokeDynamic <$> evolve i++ devolve c =+ case c of+ CString s -> pure $ CString s+ CInteger i -> pure $ CInteger i+ CFloat d -> pure $ CFloat d+ CLong l -> pure $ CLong l+ CDouble d -> pure $ CDouble d+ CClassRef r -> label "CClassRef" $ CClassRef <$> unlink r+ CStringRef r -> label "CStringRef" $ CStringRef <$> unlink r+ CFieldRef r -> label "CFieldRef" $ CFieldRef <$> devolve r+ CMethodRef r -> label "CMethodRef" $ CMethodRef <$> devolve r+ CInterfaceMethodRef r -> label "CInterfaceMethodRef" $ CInterfaceMethodRef <$> devolve r+ CNameAndType r1 r2 -> label "CNameAndType" $ CNameAndType <$> unlink r1 <*> unlink r2+ CMethodHandle mh -> label "CMetho" $ CMethodHandle <$> devolve mh+ CMethodType r -> label "CMethodType" $ CMethodType <$> unlink r+ CInvokeDynamic i -> label "CInvokeDynamic" $ CInvokeDynamic <$> devolve i+++instance Staged InvokeDynamic where+ evolve (InvokeDynamic w ref) =+ InvokeDynamic w <$> link ref++ devolve (InvokeDynamic w ref) =+ InvokeDynamic w <$> unlink ref++-- instance Staged MethodId where+-- evolve (MethodId n d) =+-- MethodId <$> link n <*> link d++-- devolve (MethodId n d) =+-- MethodId <$> unlink n <*> unlink d++instance Referenceable r => Staged (InClass r) where+ evolve (InClass cn cid) =+ InClass <$> link cn <*> link cid+ devolve (InClass cn cid) =+ InClass <$> unlink cn <*> unlink cid++instance Staged MethodHandle where+ evolve m =+ case m of+ MHField r -> MHField <$> evolve r+ MHMethod r -> MHMethod <$> evolve r+ MHInterface r -> MHInterface <$> evolve r++ devolve m =+ case m of+ MHField r -> MHField <$> devolve r+ MHMethod r -> MHMethod <$> devolve r+ MHInterface r -> MHInterface <$> devolve r++instance Staged MethodHandleMethod where+ evolve g =+ case g of+ MHInvokeVirtual m -> MHInvokeVirtual <$> link m+ MHInvokeStatic m -> MHInvokeStatic <$> link m+ MHInvokeSpecial m -> MHInvokeSpecial <$> link m+ MHNewInvokeSpecial m -> MHNewInvokeSpecial <$> link m++ devolve g =+ case g of+ MHInvokeVirtual m -> MHInvokeVirtual <$> unlink m+ MHInvokeStatic m -> MHInvokeStatic <$> unlink m+ MHInvokeSpecial m -> MHInvokeSpecial <$> unlink m+ MHNewInvokeSpecial m -> MHNewInvokeSpecial <$> unlink m++instance Staged MethodHandleField where+ evolve (MethodHandleField k ref) =+ MethodHandleField k <$> link ref++ devolve (MethodHandleField k ref) =+ MethodHandleField k <$> unlink ref++instance Staged MethodHandleInterface where+ evolve (MethodHandleInterface ref) =+ MethodHandleInterface <$> link ref++ devolve (MethodHandleInterface ref) =+ MethodHandleInterface <$> unlink ref
+ src/Language/JVM/TH.hs view
@@ -0,0 +1,87 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskellQuotes #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE StandaloneDeriving #-}+{-|+Module : Language.JVM.TH+Copyright : (c) Christian Gram Kalhauge, 2018+License : MIT+Maintainer : kalhuage@cs.ucla.edu++This module contains some Template Haskell functions for internal use.+-}++module Language.JVM.TH+ ( deriveBase+ , deriveBases+ , deriveBaseWithBinary+ ) where++import Language.Haskell.TH++import GHC.Generics+import Control.DeepSeq+import Data.Binary++import Language.JVM.Stage++-- | Derives the 'NFData', 'Show', 'Eq', and 'Generic'+-- from something that is 'Staged'+deriveBase :: Name -> Q [Dec]+deriveBase name =+ concat <$> sequence+ [ [d|deriving instance Show ($n Low)|]+ , [d|deriving instance Eq ($n Low)|]+ , [d|deriving instance Generic ($n Low)|]+ , [d|deriving instance NFData ($n Low)|]+ , [d|deriving instance Ord ($n Low)|]++ , [d|deriving instance Show ($n High)|]+ , [d|deriving instance Eq ($n High)|]+ , [d|deriving instance Generic ($n High)|]+ , [d|deriving instance NFData ($n High)|]+ ]+ where n = conT name++-- | Derives the bases of a list of names+deriveBases :: [Name] -> Q [Dec]+deriveBases names =+ concat <$> mapM deriveBase names++-- | Derives the 'NFData', 'Show', 'Eq', and 'Generic' from something that is+-- 'Staged'+deriveBaseWithBinary :: Name -> Q [Dec]+deriveBaseWithBinary name = do+ b <- deriveBase name+ m1 <- deriveBinary name+ return (b ++ m1)++deriveBinary :: Name -> Q [Dec]+deriveBinary name =+ [d|deriving instance Binary ($n Low)|]+ where+ n = conT name++-- -- | Derives the 'NFData', 'Show', 'Eq', and 'Generic'+-- -- from something that is 'Staged'+-- deriveBaseO :: Name -> Name -> Q [Dec]+-- deriveBaseO tp name = do+-- b <- deriveBase name+-- m1 <- [d|deriving instance Eq ($n $t)|]+-- m2 <- [d|deriving instance Ord ($n $t)|]+-- return (b ++ m1 ++ m2)+-- where+-- n = conT name+-- t = conT tp++-- -- | Derives the 'NFData', 'Show', 'Eq', and 'Generic'+-- -- from something that is 'Staged'+-- deriveBaseBO :: Name -> Name -> Q [Dec]+-- deriveBaseBO tp name = do+-- b <- deriveBaseB tp name+-- m1 <- [d|deriving instance Eq ($n $t)|]+-- m2 <- [d|deriving instance Ord ($n $t)|]+-- return (b ++ m1 ++ m2)+-- where+-- n = conT name+-- t = conT tp
+ src/Language/JVM/Type.hs view
@@ -0,0 +1,194 @@+{-|+Module : Language.JVM.Type+Copyright : (c) Christian Gram Kalhauge, 2018+License : MIT+Maintainer : kalhuage@cs.ucla.edu++This module contains the 'JType', 'ClassName', 'MethodDescriptor', and+'FieldDescriptor'.+-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE OverloadedStrings #-}+module Language.JVM.Type+ (+ -- * Base types+ -- ** ClassName+ ClassName (..)+ , strCls+ , dotCls++ -- ** JType+ , JType (..)+ , JBaseType (..)++ -- ** MethodDescriptor+ , MethodDescriptor (..)++ -- ** FieldDescriptor+ , FieldDescriptor (..)++ -- ** NameAndType+ , NameAndType (..)+ , (<:>)++ , TypeParse (..)+ ) where++import Control.DeepSeq (NFData)+import Data.Attoparsec.Text+import Data.String+import qualified Data.Text as Text+import GHC.Generics (Generic)+import Prelude hiding (takeWhile)++-- | A class name+newtype ClassName = ClassName+ { classNameAsText :: Text.Text+ } deriving (Eq, Ord, Generic, NFData)++instance Show ClassName where+ show = show . classNameAsText++-- | Wrapper method that converts a string representation of a class into+-- a class.+strCls :: String -> ClassName+strCls = dotCls . Text.pack++-- | Takes the dot representation and converts it into a class.+dotCls :: Text.Text -> ClassName+dotCls = ClassName . Text.intercalate "/" . Text.splitOn "."++-- | The Jvm Primitive Types+data JBaseType+ = JTByte+ | JTChar+ | JTDouble+ | JTFloat+ | JTInt+ | JTLong+ | JTShort+ | JTBoolean+ deriving (Show, Eq, Ord, Generic, NFData)++-- | The JVM types+data JType+ = JTBase JBaseType+ | JTClass ClassName+ | JTArray JType+ deriving (Show, Eq, Ord, Generic, NFData)++-- | Method Descriptor+data MethodDescriptor = MethodDescriptor+ { methodDescriptorArguments :: [JType]+ , methodDescriptorReturnType :: Maybe JType+ } deriving (Show, Ord, Eq, Generic, NFData)++-- | Field Descriptor+newtype FieldDescriptor = FieldDescriptor+ { fieldDescriptorType :: JType+ } deriving (Show, Ord, Eq, Generic, NFData)++-- | A name and a type+data NameAndType a = NameAndType+ { ntName :: Text.Text+ , ntDescriptor :: a+ } deriving (Show, Eq, Ord, Generic, NFData)++(<:>) :: Text.Text -> a -> NameAndType a+(<:>) = NameAndType++class TypeParse a where+ fromText :: Text.Text -> Either String a+ fromText = parseOnly parseText+ parseText :: Parser a+ toText :: a -> Text.Text++instance TypeParse JType where+ parseText = try $ do+ s <- anyChar+ case s :: Char of+ 'B' -> return $ JTBase JTByte+ 'C' -> return $ JTBase JTChar+ 'D' -> return $ JTBase JTDouble+ 'F' -> return $ JTBase JTFloat+ 'I' -> return $ JTBase JTInt+ 'J' -> return $ JTBase JTLong+ 'L' -> do+ txt <- takeWhile (/= ';')+ _ <- char ';'+ return $ JTClass (ClassName txt)+ 'S' -> return $ JTBase JTShort+ 'Z' -> return $ JTBase JTBoolean+ '[' -> JTArray <$> parseText+ _ -> fail $ "Unknown char " ++ show s+ toText tp =+ Text.pack $ go tp ""+ where+ go x =+ case x of+ JTBase y -> textbase y+ JTClass (ClassName cn) -> ((('L':Text.unpack cn) ++ ";") ++)+ JTArray tp' -> ('[':) . go tp'+ textbase y =+ case y of+ JTByte -> ('B':)+ JTChar -> ('C':)+ JTDouble -> ('D':)+ JTFloat -> ('F':)+ JTInt -> ('I':)+ JTLong -> ('J':)+ JTShort -> ('S':)+ JTBoolean -> ('Z':)++instance TypeParse MethodDescriptor where+ toText md =+ Text.concat (+ ["("]+ ++ map toText (methodDescriptorArguments md)+ ++ [")", maybe "V" toText $ methodDescriptorReturnType md ]+ )+ parseText = do+ _ <- char '('+ args <- many' parseText <?> "method arguments"+ _ <- char ')'+ returnType <- choice+ [ char 'V' >> return Nothing+ , Just <$> parseText+ ] <?> "return type"+ return $ MethodDescriptor args returnType++instance TypeParse FieldDescriptor where+ parseText = FieldDescriptor <$> parseText+ toText (FieldDescriptor t) = toText t++instance TypeParse t => TypeParse (NameAndType t) where+ parseText = do+ name <- many1 $ notChar ':'+ _ <- char ':'+ _type <- parseText+ return $ NameAndType (Text.pack name) _type+ toText (NameAndType name _type) =+ Text.concat [ name , ":" , toText _type ]++fromString' ::+ TypeParse t+ => String+ -> t+fromString' =+ either (error . ("Failed " ++)) id . fromText . Text.pack++instance IsString ClassName where+ fromString = strCls++instance IsString JType where+ fromString = fromString'++instance IsString FieldDescriptor where+ fromString = fromString'++instance IsString MethodDescriptor where+ fromString = fromString'++instance TypeParse t => IsString (NameAndType t) where+ fromString = fromString'
src/Language/JVM/Utils.hs view
@@ -7,8 +7,10 @@ This module contains utilities missing not in other libraries. -} -{-# LANGUAGE DeriveFunctor #-}-{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-} module Language.JVM.Utils ( -- * Sized Data Structures@@ -24,7 +26,11 @@ , SizedList16 , SizedByteString32 , SizedByteString16+ , sizedByteStringFromText+ , sizedByteStringToText + , tryDecode+ -- * Bit Set -- -- $BitSet@@ -43,14 +49,23 @@ import Data.Binary.Get import Data.Binary.Put import Data.Bits-import Data.List as List-import Data.Set as Set+import Data.List as List+import Data.Set as Set+import Data.String +import Control.DeepSeq (NFData) import Control.Monad -import qualified Data.ByteString as BS+import qualified Data.Text as Text +import qualified Data.Text.Encoding as TE+import qualified Data.Text.Encoding.Error as TE +import qualified Data.ByteString as BS++-- import Debug.Trace++ -- $SizedDataStructures -- These data structures enables binary reading and writing of lists and -- byte strings that are prepended with the number of elements to read or write.@@ -60,7 +75,7 @@ -- length N of type 'w' and then N items of type 'a'. newtype SizedList w a = SizedList { unSizedList :: [ a ]- } deriving (Show, Eq, Functor)+ } deriving (Show, Eq, Functor, NFData, Ord) -- | Get the size of the sized list. listSize :: Num w => SizedList w a -> w@@ -87,7 +102,7 @@ -- | A byte string with a size w. newtype SizedByteString w = SizedByteString { unSizedByteString :: BS.ByteString- } deriving (Show, Eq)+ } deriving (Show, Eq, NFData, Ord, IsString) -- | Get the size of a SizedByteString byteStringSize :: (Num w) => SizedByteString w -> w@@ -102,6 +117,42 @@ put (byteStringSize sbs) putByteString bs +replaceJavaZeroWithNormalZero :: BS.ByteString -> BS.ByteString+replaceJavaZeroWithNormalZero = go+ where+ go bs =+ case BS.breakSubstring "\192\128" bs of+ (h, "") -> h+ (h, t) -> h `BS.append` "\0" `BS.append` go (BS.drop 2 t)++replaceNormalZeroWithJavaZero::BS.ByteString -> BS.ByteString+replaceNormalZeroWithJavaZero = go+ where+ go bs =+ case BS.breakSubstring "\0" bs of+ (h, "") -> h+ (h, t) -> h `BS.append` "\192\128" `BS.append` go (BS.drop 1 t)++-- | Convert a Sized bytestring to Utf8 Text.+sizedByteStringToText ::+ SizedByteString w+ -> Either TE.UnicodeException Text.Text+sizedByteStringToText (SizedByteString bs) =+ let rst = TE.decodeUtf8' bs+ in case rst of+ Right txt -> Right txt+ Left _ -> tryDecode bs++tryDecode :: BS.ByteString -> Either TE.UnicodeException Text.Text+tryDecode = TE.decodeUtf8' . replaceJavaZeroWithNormalZero++-- | Convert a Sized bytestring from Utf8 Text.+sizedByteStringFromText ::+ Text.Text+ -> SizedByteString w+sizedByteStringFromText t+ = SizedByteString . replaceNormalZeroWithJavaZero . TE.encodeUtf8 $ t+ -- $BitSet -- A bit set is a set where each element is represented a bit in a word. This -- section also defines the 'Enumish' type class. It is different than a 'Enum'@@ -123,18 +174,23 @@ -- | A bit set of size w newtype BitSet w a = BitSet { toSet :: Set.Set a- } deriving (Ord, Show, Eq)+ } deriving (Ord, Show, Eq, NFData) -instance (Bits w, Binary w, Enumish a) => Binary (BitSet w a) where++bitSetToWord :: (Enumish a, Bits w) => BitSet w a -> w+bitSetToWord =+ toWord . Set.toList . toSet++toWord :: (Enumish a, Bits w) => [a] -> w+toWord =+ List.foldl' (\a -> setBit a . fromEnumish) zeroBits++instance (Show w, Bits w, Binary w, Enumish a) => Binary (BitSet w a) where get = do word <- get :: Get w return . BitSet $ Set.fromList [ x | (i, x) <- inOrder, testBit word i ] - put (BitSet f) = do- let word =- List.foldl' setBit zeroBits- (List.map fromEnumish $ Set.toList f) :: w- put word+ put = put . bitSetToWord -- | A sized list using a 16 bit word as length type SizedList16 = SizedList Word16
stack.yaml view
@@ -1,6 +1,5 @@-resolver: lts-9.3+resolver: lts-10.5 packages: - .-extra-deps: [] flags: {}-extra-package-dbs: []+extra-deps: []
− test-suite/Language/JVM/Attribute/CodeTest.hs
@@ -1,84 +0,0 @@-{-# LANGUAGE OverloadedStrings, FlexibleInstances #-}-{-# OPTIONS_GHC -fno-warn-orphans #-}-module Language.JVM.Attribute.CodeTest where--import SpecHelper--import Data.Word--import Language.JVM.Attribute (Attribute)-import Language.JVM.AttributeTest ()--import Language.JVM.Attribute.Code-import qualified Language.JVM.Constant as Constant-import Language.JVM.UtilsTest ()----- prop_encode_and_decode_ByteCode :: ByteCode -> Property--- prop_encode_and_decode_ByteCode = isoBinary---- prop_encode_and_decode :: Code Attribute -> Property--- prop_encode_and_decode = isoBinary--instance Arbitrary (Code Attribute) where- arbitrary = Code- <$> arbitrary- <*> arbitrary- <*> arbitrary- <*> arbitrary- <*> arbitrary---instance Arbitrary ArithmeticType where- arbitrary = elements [ MInt, MLong, MFloat, MDouble ]--instance Arbitrary LocalType where- arbitrary = elements [ LInt, LLong, LFloat, LDouble, LRef ]--instance Arbitrary ByteCodeInst where- arbitrary = ByteCodeInst <$> arbitrary <*> arbitrary--instance Arbitrary ByteCodeOpr where- arbitrary = oneof- [ pure Nop- , Push <$> arbitrary- ]--instance Arbitrary Constant where- arbitrary = oneof- [ pure CNull- , pure CIntM1- , pure CInt0- , pure CInt1- , pure CInt2- , pure CInt3- , pure CInt4- , pure CInt5-- , pure CLong0- , pure CLong1-- , pure CFloat0- , pure CFloat1- , pure CFloat2-- , pure CDouble0- , pure CDouble1-- , CByte <$> arbitrary- , CShort <$> arbitrary-- , CHalfRef . Constant.ConstantRef . fromIntegral <$> (arbitrary :: Gen Word8)- , CRef One <$> arbitrary- , CRef Two <$> arbitrary- ]--instance Arbitrary ByteCode where- arbitrary = ByteCode <$> arbitrary--instance Arbitrary ExceptionTable where- arbitrary = ExceptionTable- <$> arbitrary- <*> arbitrary- <*> arbitrary- <*> arbitrary
− test-suite/Language/JVM/Attribute/StackMapTableTest.hs
@@ -1,50 +0,0 @@-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE OverloadedStrings #-}-{-# OPTIONS_GHC -fno-warn-orphans #-}--module Language.JVM.Attribute.StackMapTableTest where--import SpecHelper--import Language.JVM.AttributeTest ()-import Language.JVM.ConstantTest ()-import Language.JVM.UtilsTest ()--import Language.JVM.Attribute.StackMapTable--prop_encode_and_decode :: StackMapTable -> Property-prop_encode_and_decode = isoBinary--prop_StackMapFrame_encode_and_decode :: StackMapFrame -> Property-prop_StackMapFrame_encode_and_decode = isoBinary--instance Arbitrary StackMapTable where- arbitrary = StackMapTable <$> arbitrary--instance Arbitrary StackMapFrame where- arbitrary =- StackMapFrame <$> arbitrary <*> arbitrary--instance Arbitrary StackMapFrameType where- arbitrary = oneof- [ pure SameFrame- , SameLocals1StackItemFrame <$> arbitrary- , ChopFrame <$> choose (1,3)- , AppendFrame <$> (choose (1,3) >>= flip vectorOf arbitrary)- , FullFrame <$> arbitrary <*> arbitrary- ]--instance Arbitrary (VerificationTypeInfo) where- arbitrary = oneof- [ pure VTop- , pure VInteger- , pure VTop- , pure VInteger- , pure VFloat- , pure VLong- , pure VDouble- , pure VNull- , pure VUninitializedThis- , VObject <$> arbitrary- , VUninitialized <$> arbitrary- ]
− test-suite/Language/JVM/AttributeTest.hs
@@ -1,21 +0,0 @@-{-# OPTIONS_GHC -fno-warn-orphans #-}-module Language.JVM.AttributeTest where--import SpecHelper--import Language.JVM.Attribute (Attribute (..))-import Language.JVM.ConstantTest ()-import Language.JVM.Utils-import Language.JVM.UtilsTest ()--import qualified Data.ByteString as BS--prop_encode_and_decode :: Attribute -> Property-prop_encode_and_decode = isoBinary--instance Arbitrary Attribute where- arbitrary = do- idx <- arbitrary- len <- choose (0, 50)- bs <- SizedByteString . BS.pack <$> sequence (replicate len arbitrary)- return $ Attribute idx bs
− test-suite/Language/JVM/ClassFileTest.hs
@@ -1,33 +0,0 @@-{-# OPTIONS_GHC -fno-warn-orphans #-}-module Language.JVM.ClassFileTest where--import SpecHelper--import qualified Data.IntMap as IM--import Language.JVM.ClassFile-import Language.JVM.Constant--import Language.JVM.Utils-import Language.JVM.UtilsTest ()-import Language.JVM.AttributeTest ()-import Language.JVM.ConstantTest ()-import Language.JVM.FieldTest ()-import Language.JVM.MethodTest ()--prop_encode_and_decode :: ClassFile -> Property-prop_encode_and_decode = isoBinary--instance Arbitrary ClassFile where- arbitrary = ClassFile- <$> arbitrary- <*> arbitrary- <*> arbitrary- <*> (pure $ ConstantPool IM.empty)- <*> arbitrary- <*> arbitrary- <*> arbitrary- <*> (pure $ SizedList [])- <*> (pure $ SizedList [])- <*> (pure $ SizedList [])- <*> (pure $ SizedList [])
− test-suite/Language/JVM/ConstantTest.hs
@@ -1,42 +0,0 @@-{-# OPTIONS_GHC -fno-warn-orphans #-}-module Language.JVM.ConstantTest where--import SpecHelper--import Language.JVM.Constant-import Language.JVM.UtilsTest ()--import qualified Data.IntMap as IM--prop_encode_and_decode :: ConstantPool -> Property-prop_encode_and_decode = isoBinary--instance Arbitrary ConstantRef where- arbitrary =- ConstantRef <$> arbitrary--instance Arbitrary ConstantPool where- arbitrary =- ConstantPool . IM.fromList . go 1 <$> arbitrary- where- go n (e : lst) =- (n, e) : go (n + constantSize e) lst- go _ [] = []--instance Arbitrary Constant where- arbitrary = oneof- [ String <$> arbitrary- , Integer <$> arbitrary- , Float <$> arbitrary- , Long <$> arbitrary- , Double <$> arbitrary- , ClassRef <$> arbitrary- , StringRef <$> arbitrary- , FieldRef <$> arbitrary <*> arbitrary- , MethodRef <$> arbitrary <*> arbitrary- , InterfaceMethodRef <$> arbitrary <*> arbitrary- , NameAndType <$> arbitrary <*> arbitrary- , MethodHandle <$> arbitrary <*> arbitrary- , MethodType <$> arbitrary- , InvokeDynamic <$> arbitrary <*> arbitrary- ]
− test-suite/Language/JVM/FieldTest.hs
@@ -1,19 +0,0 @@-{-# OPTIONS_GHC -fno-warn-orphans #-}-module Language.JVM.FieldTest where--import SpecHelper--import Language.JVM.Field-import Language.JVM.UtilsTest ()-import Language.JVM.ConstantTest ()-import Language.JVM.AttributeTest ()--prop_encode_and_decode :: Field -> Property-prop_encode_and_decode = isoBinary--instance Arbitrary Field where- arbitrary = Field- <$> arbitrary- <*> arbitrary- <*> arbitrary- <*> arbitrary
− test-suite/Language/JVM/MethodTest.hs
@@ -1,19 +0,0 @@-{-# OPTIONS_GHC -fno-warn-orphans #-}-module Language.JVM.MethodTest where--import SpecHelper--import Language.JVM.Method-import Language.JVM.UtilsTest ()-import Language.JVM.ConstantTest ()-import Language.JVM.AttributeTest ()--prop_encode_and_decode :: Method -> Property-prop_encode_and_decode = isoBinary--instance Arbitrary Method where- arbitrary = Method- <$> arbitrary- <*> arbitrary- <*> arbitrary- <*> arbitrary
− test-suite/Language/JVM/UtilsTest.hs
@@ -1,22 +0,0 @@-{-# OPTIONS_GHC -fno-warn-orphans #-}-module Language.JVM.UtilsTest where--import SpecHelper--import qualified Data.ByteString as BS--import Data.Set as Set-import Language.JVM.Utils--instance Arbitrary a => Arbitrary (SizedList w a) where- arbitrary =- SizedList <$> arbitrary--instance Arbitrary (SizedByteString w) where- arbitrary = do- len <- choose (0, 50)- SizedByteString . BS.pack <$> sequence (replicate len arbitrary)--instance (Enumish a) => Arbitrary (BitSet w a) where- arbitrary =- BitSet . Set.fromList <$> sublistOf (snd <$> inOrder)
− test-suite/Language/JVMTest.hs
@@ -1,30 +0,0 @@-module Language.JVMTest where--import SpecHelper--import Control.Monad--- import Data.Text as Text-import Data.Maybe-import Data.Either--- import Debug.Trace--import Language.JVM-import Language.JVM.Attribute.Code ()--test_reading_classfile :: IO [TestTree]-test_reading_classfile = testAllFiles $ do- it "can parse the bytestring" $ \bs -> do- decodeClassFile bs `shouldSatisfy` isRight-- beforeWith (\bs -> either fail return $ decodeClassFile bs) $ do-- it "has a the magic number: 0xCAFEBABE" $ \cls ->- cMagicNumber cls `shouldBe` 0xCAFEBABE-- it "has a class name" $ \cls ->- cThisClass (cConstantPool cls) cls `shouldSatisfy` isJust-- it "can parse all method codes" $ \cls ->- forM_ (catMaybes . map (mCode (cConstantPool cls)) $ cMethods cls) $- \code-> do- code `shouldSatisfy` isRight
− test-suite/SpecHelper.hs
@@ -1,68 +0,0 @@-module SpecHelper- ( module Test.Tasty- , module Test.Tasty.Hspec- , module Test.Tasty.QuickCheck- , decode- , encode- , blReadFile- , isoBinary- , testAllFiles- , testSomeFiles- ) where--import Test.Tasty-import Test.Tasty.Hspec-import Test.Tasty.QuickCheck-import qualified Data.ByteString.Lazy as BL--import System.FilePath-import System.Directory--import Control.Monad-import Data.Binary-import Data.Bits--blReadFile :: FilePath -> IO BL.ByteString-blReadFile = BL.readFile--toHex :: Word8 -> String-toHex x =- [ alpha !! fromIntegral (x `shift` (-4))- , alpha !! fromIntegral (x `mod` 16)- ]- where alpha = "0123456789abcdef"--testAllFiles :: SpecWith BL.ByteString -> IO [TestTree]-testAllFiles spec = do- files <- filter isClass <$> recursiveContents "test-suite/data"- forM files $ \file -> testSpec file (beforeAll (blReadFile file) spec)- where- isClass p = takeExtension p == ".class"---testSomeFiles :: SpecWith BL.ByteString -> IO [TestTree]-testSomeFiles spec =- forM files $ \file -> testSpec file (beforeAll (blReadFile file) spec)- where- files =- [ "test-suite/data/java/util/zip/ZipOutputStream.class"- -- , "test-suite/data/project/Main.class"- ]--isoBinary :: (Binary a, Eq a, Show a) => a -> Property-isoBinary a =- let bs = encode a- in counterexample (concat . map toHex $ BL.unpack bs) $- decode bs === a--folderContents :: FilePath -> IO [ FilePath ]-folderContents fp =- map (fp </>) <$> listDirectory fp--recursiveContents :: FilePath -> IO [ FilePath ]-recursiveContents fp = do- test <- doesDirectoryExist fp- (fp:) <$> if test then do- content <- folderContents fp- concat <$> mapM recursiveContents content- else return []
− test-suite/Test.hs
@@ -1,60 +0,0 @@-{-# OPTIONS_GHC -F -pgmF tasty-discover -optF --tree-display #-}----- {-# LANGUAGE OverloadedStrings #-}--- import Language.JVM.Binary.Attribute (Attribute(..))--- import Language.JVM.Binary.ClassFile----- import Data.Binary (decode, encode)--- import qualified Data.ByteString.Lazy as LBS--- import qualified Data.ByteString.Char8 as BC--- import qualified Data.ByteString as BS---- import qualified Test.Tasty--- import Test.Tasty.Hspec--- import Test.Tasty.QuickCheck as QC----- main :: IO ()--- main = do--- putStrLn ".."--- test <- testSpec "jvmhs" classfileSpec--- Test.Tasty.defaultMain (Test.Tasty.testGroup "All of it" [ test, encodedecode ])---- classfileSpec :: Spec--- classfileSpec = beforeAll (LBS.readFile "test-suite/project/Main.class") $ do--- it "can read the bytestring" $--- \bs -> let classfile = decode bs--- in (magicNumber classfile) `shouldBe` 3405691582---- it "can encode and decode attributes" $--- \_ -> let attr = Attribute 1 (BC.pack "Hello")--- in (decode . encode ) attr `shouldBe` attr---- it "will encode and decode back to a class file" $ \bs ->--- let classfile = decode bs :: ClassFile--- encoding = encode classfile--- in (methods classfile) `shouldBe` (methods $ decode (LBS.append encoding (LBS.repeat 0)))---- it "will encode the data back to the same format" $ \bs ->--- let classfile = decode bs :: ClassFile--- in bs `shouldBe` encode classfile----- encodedecode :: Test.Tasty.TestTree--- encodedecode =--- Test.Tasty.testGroup "encode . decode == id"--- [ QC.testProperty "Attribute" $ \(ArbAttribute attr) ->--- (decode . encode) attr == attr--- ]---- newtype ArbAttribute =--- ArbAttribute Attribute deriving (Show, Eq)---- instance Arbitrary ArbAttribute where--- arbitrary = do--- index <- arbitrary--- len <- choose (0, 50)--- bs <- BS.pack <$> sequence (replicate len arbitrary)--- return $ ArbAttribute (Attribute index bs)
+ test/Language/JVM/Attribute/BootstrapMethodsTest.hs view
@@ -0,0 +1,20 @@+{-# LANGUAGE FlexibleInstances #-}++module Language.JVM.Attribute.BootstrapMethodsTest where++import SpecHelper++import Language.JVM.ConstantTest ()++import Language.JVM.Attribute.BootstrapMethods+import Language.JVM++prop_roundtrip_BootstrapMethods :: BootstrapMethods High -> Property+prop_roundtrip_BootstrapMethods = isoRoundtrip++instance Arbitrary (BootstrapMethods High) where+ arbitrary = genericArbitraryU++instance Arbitrary (BootstrapMethod High) where+ arbitrary =+ BootstrapMethod <$> arbitrary <*> (SizedList <$> listOf (resize 1 arbitrary))
+ test/Language/JVM/Attribute/CodeTest.hs view
@@ -0,0 +1,178 @@+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}+module Language.JVM.Attribute.CodeTest where++import qualified Data.Vector as V+import Generic.Random+++import SpecHelper++import Language.JVM.Attribute.LineNumberTableTest ()+import Language.JVM.Attribute.StackMapTableTest ()+import Language.JVM.AttributeTest ()+import Language.JVM.UtilsTest ()++import Language.JVM+import Language.JVM.Attribute.Code++prop_roundtrip_Code :: Code High -> Property+prop_roundtrip_Code = isoRoundtrip++-- prop_roundtrip_ByteCode :: ByteCode High -> Property+-- prop_roundtrip_ByteCode = isoRoundtrip++prop_roundtrip_ExceptionTable :: ExceptionTable High -> Property+prop_roundtrip_ExceptionTable = isoByteCodeRoundtrip++prop_roundtrip_ByteCodeInst :: ByteCodeInst High -> Property+prop_roundtrip_ByteCodeInst = isoByteCodeRoundtrip+++spec_ByteCode_examples :: SpecWith ()+spec_ByteCode_examples = do+ it "can round trip 'push (i127)'" $ do+ let opr = ByteCodeInst 0 (Push (Just (VInteger 127)))+ (snd <$> byteCodeRoundtrip opr) `shouldBe` Right opr++ it "can round trip 'push (i-129)'" $ do+ let opr = ByteCodeInst 0 (Push (Just (VInteger (-129))))+ (snd <$> byteCodeRoundtrip opr) `shouldBe` Right opr++instance Arbitrary (Code High) where+ arbitrary = do+ bc <- arbitrary+ Code+ <$> arbitrary+ <*> arbitrary+ <*> pure bc+ <*> (SizedList <$> listOf (genExceptionTable (fromIntegral . V.length . unByteCode $ bc)))+ <*> pure (CodeAttributes [] [] [])++genExceptionTable :: Int -> Gen (ExceptionTable High)+genExceptionTable i =+ ExceptionTable+ <$> (arbitraryRef i)+ <*> (arbitraryRef i)+ <*> (arbitraryRef i)+ <*> arbitrary++arbitraryRef :: Int -> Gen Int+arbitraryRef i =+ choose (0, i - 1)++instance Arbitrary (CodeAttributes High) where+ arbitrary = genericArbitraryU++instance Arbitrary (ExceptionTable High) where+ arbitrary =+ ExceptionTable <$> arbitraryRef 0xffff <*> arbitraryRef 0xffff <*> arbitraryRef 0xffff <*> arbitrary++instance Arbitrary (ByteCode High) where+ arbitrary = do+ s <- getSize+ ByteCode . V.fromList <$> vectorOf s (genByteCodeOpr s)++instance Arbitrary (ByteCodeInst High) where+ arbitrary =+ ByteCodeInst <$> pure 0 <*> genByteCodeOpr 0xffff++instance Arbitrary ArithmeticType where+ arbitrary = elements [ MInt, MLong, MFloat, MDouble ]++instance Arbitrary LocalType where+ arbitrary = elements [ LInt, LLong, LFloat, LDouble, LRef ]+++genByteCodeOpr :: Int -> Gen (ByteCodeOpr High)+genByteCodeOpr i = do+ x <- (genericArbitraryU :: Gen (ByteCodeOpr High))+ case x of+ If cp on _ -> If cp on <$> arbitraryRef i+ IfRef b on _ -> IfRef b on <$> arbitraryRef i+ Goto _ -> Goto <$> arbitraryRef i+ Jsr _ -> Jsr <$> arbitraryRef i+ TableSwitch r (SwitchTable l ofss) ->+ TableSwitch r . SwitchTable l <$> V.mapM (const $ arbitraryRef i) ofss+ _ -> return x++instance Arbitrary a => Arbitrary (V.Vector a) where+ arbitrary = V.fromList <$> arbitrary++instance Arbitrary ArrayType where+ arbitrary = genericArbitrary uniform++instance Arbitrary (ExactArrayType High) where+ arbitrary =+ oneof+ [ pure EABoolean+ , pure EAByte+ , pure EAChar+ , pure EAShort+ , pure EAInt+ , pure EALong+ , pure EAFloat+ , pure EADouble+ , EARef <$> arbitrary+ ]++instance Arbitrary BinOpr where+ arbitrary = genericArbitrary uniform++instance Arbitrary CastOpr where+ arbitrary =+ oneof . map pure $+ [ CastTo MInt MLong+ , CastTo MInt MFloat+ , CastTo MInt MDouble++ , CastTo MLong MInt+ , CastTo MLong MFloat+ , CastTo MLong MDouble++ , CastTo MFloat MInt+ , CastTo MFloat MLong+ , CastTo MFloat MDouble++ , CastTo MDouble MInt+ , CastTo MDouble MLong+ , CastTo MDouble MFloat++ , CastDown MByte+ , CastDown MChar+ , CastDown MShort+ ]++instance Arbitrary BitOpr where+ arbitrary = genericArbitraryU++instance Arbitrary OneOrTwo where+ arbitrary = genericArbitraryU++instance Arbitrary SmallArithmeticType where+ arbitrary = genericArbitraryU++instance Arbitrary CmpOpr where+ arbitrary = genericArbitraryU++instance Arbitrary FieldAccess where+ arbitrary = genericArbitrary uniform++instance Arbitrary (Invocation High) where+ arbitrary =+ oneof+ [ InvkSpecial <$> arbitrary+ , InvkVirtual <$> arbitrary+ , InvkStatic <$> arbitrary+ , InvkInterface <$> (arbitrary `suchThat` \i -> i > 0) <*> arbitrary+ , InvkDynamic <$> arbitrary+ ]+instance Arbitrary (CConstant High) where+ arbitrary = genericArbitraryU++instance Arbitrary (SwitchTable High) where+ arbitrary = genericArbitraryU+
+ test/Language/JVM/Attribute/ConstantValueTest.hs view
@@ -0,0 +1,15 @@+{-# LANGUAGE FlexibleInstances #-}++module Language.JVM.Attribute.ConstantValueTest where++import SpecHelper++import Language.JVM.ConstantTest ()++import Language.JVM++prop_roundtrip_ConstantValue :: ConstantValue High -> Property+prop_roundtrip_ConstantValue = isoRoundtrip++instance Arbitrary (ConstantValue High) where+ arbitrary = genericArbitraryU
+ test/Language/JVM/Attribute/ExceptionsTest.hs view
@@ -0,0 +1,15 @@+{-# LANGUAGE FlexibleInstances #-}++module Language.JVM.Attribute.ExceptionsTest where++import SpecHelper++import Language.JVM++import Language.JVM.ConstantTest ()++prop_roundtrip_Exceptions :: Exceptions High -> Property+prop_roundtrip_Exceptions = isoRoundtrip++instance Arbitrary (Exceptions High) where+ arbitrary = genericArbitraryU
+ test/Language/JVM/Attribute/LineNumberTableTest.hs view
@@ -0,0 +1,26 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE OverloadedStrings #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}++module Language.JVM.Attribute.LineNumberTableTest where++import qualified Data.IntMap as IM++import SpecHelper++import Language.JVM.AttributeTest ()+import Language.JVM.ConstantTest ()+import Language.JVM.TypeTest ()+import Language.JVM.UtilsTest ()++import Language.JVM+import Language.JVM.Attribute.LineNumberTable++-- prop_roundtrip_LineNumberTable :: LineNumberTable High -> Property+-- prop_roundtrip_LineNumberTable = isoRoundtrip++instance Arbitrary (LineNumberTable High) where+ arbitrary =+ LineNumberTable . IM.fromList . map f . unSizedList <$> (arbitrary :: Gen BinaryFormat)+ where+ f (a,b) = (fromIntegral a, b)
+ test/Language/JVM/Attribute/SignatureTest.hs view
@@ -0,0 +1,27 @@+{-# LANGUAGE FlexibleInstances #-}++module Language.JVM.Attribute.SignatureTest where++import SpecHelper++import Language.JVM.ConstantTest ()++import Language.JVM.Attribute.Signature+import Language.JVM++prop_roundtrip_SignatureTest :: Signature High -> Property+prop_roundtrip_SignatureTest = isoRoundtrip++-- test_real_signatures :: SpecWith ()+-- test_real_signatures = do+-- it "can handle Iterator" $ do+-- let signature = "<T:Ljava/lang/Object;>Ljava/lang/Object;"++instance Arbitrary (Signature High) where+ arbitrary = genericArbitraryU+++-- "Lcom/apple/eawt/_AppEventHandler$_AppEventDispatcher<Lcom/apple/eawt/QuitHandler;>;"+-- "Lcom/apple/eawt/_AppEventHandler$_BooleanAppEventMultiplexor<Lcom/apple/eawt/ScreenSleepListener;Lcom/apple/eawt/AppEvent$ScreenSleepEvent;>;"+-- "Lcom/apple/eawt/_AppEventHandler$_BooleanAppEventMultiplexor<Lcom/apple/eawt/SystemSleepListener;Lcom/apple/eawt/AppEvent$SystemSleepEvent;>;"+-- "Lcom/apple/eawt/_AppEventHandler$_BooleanAppEventMultiplexor<Lcom/apple/eawt/UserSessionListener;Lcom/apple/eawt/AppEvent$UserSessionEvent;>;"
+ test/Language/JVM/Attribute/StackMapTableTest.hs view
@@ -0,0 +1,77 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE OverloadedStrings #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}++module Language.JVM.Attribute.StackMapTableTest where++import SpecHelper++import Data.Bifunctor+import Data.Binary+import qualified Data.ByteString.Lazy as BL+import Data.Either++import Language.JVM.Attribute.StackMapTable+import Language.JVM++import Language.JVM.AttributeTest ()+import Language.JVM.ConstantTest ()+import Language.JVM.TypeTest ()++-- prop_encode_and_decode :: StackMapTable Low -> Property+-- prop_encode_and_decode = isoBinary++spec_parses :: SpecWith ()+spec_parses = do+ describe "decoding" $ do+ let+ bs = BL.fromStrict "\NUL\ACK\253\NUL\t\SOH\SOH\253\NUL%\SOH\SOH\t\ETB\249\NUL\t\249\NUL\r"+ -- 0006fd00 090101fd 00250101 0917f900 09f9000d+ it ("can decode " ++ hexString bs) $ do+ let+ r :: Either String (StackMapTable Low)+ r = bimap trd trd $ decodeOrFail bs++ r `shouldSatisfy` isRight++-- prop_offset_delta :: (Word16, Word16) -> Bool+prop_offset_delta :: (Word16, Word16) -> Property+prop_offset_delta (lidx, delta) =+ let tidx = offsetDelta lidx delta+ in counterexample (show tidx) $+ offsetDeltaInv lidx tidx === delta++-- prop_roundtrip_StackMapTable :: StackMapTable High -> Property+-- prop_roundtrip_StackMapTable = isoRoundtrip++-- prop_roundtrip_StackMapFrame :: StackMapFrame High -> Property+-- prop_roundtrip_StackMapFrame = isoRoundtrip++instance Arbitrary (StackMapTable High) where+ arbitrary = StackMapTable <$> arbitrary++instance Arbitrary ( StackMapFrame High) where+ arbitrary =+ StackMapFrame <$> arbitrary <*> arbitrary++instance Arbitrary (StackMapFrameType High) where+ arbitrary = oneof+ [ pure SameFrame+ , SameLocals1StackItemFrame <$> arbitrary+ , ChopFrame <$> choose (1,3)+ , AppendFrame <$> (choose (1,3) >>= flip vectorOf arbitrary)+ , FullFrame <$> arbitrary <*> arbitrary+ ]++instance Arbitrary (VerificationTypeInfo High) where+ arbitrary = oneof+ [ pure VTTop+ , pure VTInteger+ , pure VTFloat+ , pure VTLong+ , pure VTDouble+ , pure VTNull+ , pure VTUninitializedThis+ , VTObject <$> arbitrary+ , VTUninitialized <$> arbitrary+ ]
+ test/Language/JVM/AttributeTest.hs view
@@ -0,0 +1,23 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}+{-# LANGUAGE FlexibleInstances #-}+module Language.JVM.AttributeTest where++import SpecHelper++import Language.JVM++import Language.JVM.Attribute (Attribute (..))+import Language.JVM.ConstantTest ()+import Language.JVM.UtilsTest ()++import qualified Data.ByteString as BS++prop_roundtrip_Attribute :: Attribute High -> Property+prop_roundtrip_Attribute = isoRoundtrip++instance Arbitrary (Attribute High) where+ arbitrary = do+ _idx <- arbitrary+ len <- choose (0, 50)+ bs <- SizedByteString . BS.pack <$> sequence (replicate len arbitrary)+ return $ Attribute _idx bs
+ test/Language/JVM/ClassFileTest.hs view
@@ -0,0 +1,43 @@+{-# LANGUAGE RecordWildCards #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}+{-# OPTIONS_GHC -fno-warn-name-shadowing #-}+{-# LANGUAGE FlexibleInstances #-}+module Language.JVM.ClassFileTest where++import SpecHelper++import Language.JVM++import Language.JVM.Attribute.BootstrapMethodsTest ()+import Language.JVM.AttributeTest ()+import Language.JVM.ConstantTest ()+import Language.JVM.FieldTest ()+import Language.JVM.MethodTest ()+import Language.JVM.UtilsTest ()++prop_roundtrip_ClassFile :: ClassFile High -> Property+prop_roundtrip_ClassFile = isoRoundtrip++instance Arbitrary (ClassAttributes High) where+ arbitrary = ClassAttributes <$> pure [] <*> pure [] <*> pure []++instance Arbitrary (ClassFile High) where+ arbitrary = ClassFile+ <$> arbitrary+ <*> arbitrary+ <*> arbitrary+ <*> (pure ())+ <*> arbitrary+ <*> arbitrary+ <*> arbitrary+ <*> arbitrary+ <*> (resize 2 arbitrary)+ <*> (resize 2 arbitrary)+ <*> arbitrary++ shrink ClassFile{..} = do+ cInterfaces <- shrink cInterfaces+ cAttributes <- shrink cAttributes+ cMethods' <- shrink cMethods'+ cFields' <- shrink cFields'+ return $ClassFile {..}
+ test/Language/JVM/ConstantTest.hs view
@@ -0,0 +1,124 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE OverloadedStrings #-}+module Language.JVM.ConstantTest where++import SpecHelper++import qualified Data.IntMap as IM+import qualified Data.Text as Text+import qualified Data.ByteString as BS++import Language.JVM.Constant+import Language.JVM.Staged+import Language.JVM.ConstantPool+import Language.JVM.ClassFileReader+import Language.JVM.UtilsTest ()+import Language.JVM.TypeTest ()++prop_encode_and_decode :: ConstantPool Low -> Property+prop_encode_and_decode = isoBinary++instance Arbitrary (ConstantPool Low) where+ arbitrary = do+ lst <- arbitrary :: Gen [Constant High]+ let (_, x) = runConstantPoolBuilder (mapM devolve lst) cpbEmpty+ return (cpbConstantPool x)++-- prop_Constant_encode_and_decode :: Constant Low -> Property+-- prop_Constant_encode_and_decode = isoBinary++prop_roundtrip_Constant :: Constant High -> Property+prop_roundtrip_Constant = isoRoundtrip++instance Arbitrary Text.Text where+ arbitrary =+ elements+ [ "Package"+ , "test"+ , "number"+ , "stuff"+ , "\0 asd ßåæ∂ø∆œ˜˜¬å˚¬"+ ]++instance Arbitrary BS.ByteString where+ arbitrary =+ elements+ [ "Package"+ , "test"+ , "number"+ , "stuff"+ , "\0 asd ßåæ∂ø∆œ˜˜¬å˚¬"+ ]++instance Arbitrary (ConstantPool High) where+ arbitrary =+ ConstantPool . IM.fromList . go 1 <$> arbitrary+ where+ go n (e : lst) =+ (n, e) : go (n + constantSize e) lst+ go _ [] = []++instance Arbitrary (AbsInterfaceMethodId High) where+ arbitrary = genericArbitraryU++instance Arbitrary (Constant High) where+ arbitrary = sized $ \n ->+ if n < 2+ then oneof+ [ CString <$> arbitrary+ , CInteger <$> arbitrary+ , CFloat <$> arbitrary+ , CLong <$> arbitrary+ , CDouble <$> arbitrary+ ]+ else scale (flip div 2) $ oneof+ [ CString <$> arbitrary+ , CInteger <$> arbitrary+ , CFloat <$> arbitrary+ , CLong <$> arbitrary+ , CDouble <$> arbitrary+ , CClassRef <$> arbitrary+ , CStringRef <$> arbitrary+ , CFieldRef <$> arbitrary+ , CMethodRef <$> arbitrary+ , CInterfaceMethodRef <$> arbitrary+ , CNameAndType <$> arbitrary <*> arbitrary+ , CMethodHandle <$> arbitrary+ , CMethodType <$> arbitrary+ , CInvokeDynamic <$> arbitrary+ ]++instance (Arbitrary a) => Arbitrary (InClass a High) where+ arbitrary = InClass <$> arbitrary <*> arbitrary++instance Arbitrary (FieldId) where+ arbitrary = FieldId <$> arbitrary++instance Arbitrary (MethodId) where+ arbitrary = MethodId <$> arbitrary++instance Arbitrary (MethodHandle High) where+ arbitrary =+ oneof+ [ MHField <$> ( MethodHandleField <$> arbitrary <*> arbitrary)+ , MHMethod <$> arbitrary+ , MHInterface <$> ( MethodHandleInterface <$> arbitrary)+ ]++instance Arbitrary MethodHandleFieldKind where+ arbitrary =+ oneof [ pure x | x <- [ MHGetField, MHGetStatic, MHPutField, MHPutStatic ] ]++instance Arbitrary (MethodHandleMethod High) where+ arbitrary =+ genericArbitraryU++instance Arbitrary (AbsVariableMethodId High) where+ arbitrary = genericArbitraryU++instance Arbitrary (InvokeDynamic High) where+ arbitrary = InvokeDynamic <$> arbitrary <*> arbitrary++instance Arbitrary JValue where+ arbitrary = genericArbitraryU
+ test/Language/JVM/FieldTest.hs view
@@ -0,0 +1,26 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}+{-# LANGUAGE FlexibleInstances #-}+module Language.JVM.FieldTest where++import SpecHelper++import Language.JVM.UtilsTest ()+import Language.JVM.ConstantTest ()+import Language.JVM.AttributeTest ()+import Language.JVM.Attribute.ConstantValueTest ()++import Language.JVM++prop_roundtrip_Field :: Field High -> Property+prop_roundtrip_Field = isoRoundtrip++instance Arbitrary (FieldAttributes High) where+ arbitrary =+ FieldAttributes <$> arbitrary <*> pure [] <*> pure []++instance Arbitrary (Field High) where+ arbitrary = Field+ <$> arbitrary+ <*> arbitrary+ <*> arbitrary+ <*> arbitrary
+ test/Language/JVM/MethodTest.hs view
@@ -0,0 +1,29 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+module Language.JVM.MethodTest where++import SpecHelper++import Language.JVM.Attribute.CodeTest ()+import Language.JVM.Attribute.ExceptionsTest ()+import Language.JVM.AttributeTest ()+import Language.JVM.ConstantTest ()+import Language.JVM.UtilsTest ()++import Language.JVM++prop_roundtrip_Method :: Method High -> Property+prop_roundtrip_Method = isoRoundtrip++instance Arbitrary (MethodAttributes High) where+ arbitrary =+ MethodAttributes <$> pure [] <*> arbitrary <*> pure [] <*> pure []+ shrink (MethodAttributes a b c d ) =+ MethodAttributes <$> shrink a <*> shrink b <*> pure c <*> pure d++instance Arbitrary (Method High) where+ arbitrary =+ Method <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary+ shrink (Method a b c d) =+ Method <$> shrink a <*> shrink b <*> shrink c <*> shrink d
+ test/Language/JVM/TypeTest.hs view
@@ -0,0 +1,50 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}+{-# LANGUAGE OverloadedStrings #-}+module Language.JVM.TypeTest where++import SpecHelper++import Language.JVM.Type++-- import Text.Megaparsec+-- import Test.Hspec.Megaparsec++-- spec_JType_parsing :: Spec+-- spec_JType_parsing = do+-- it "can parse \"[B\" as an array" $+-- parse parseJType "" "[B" `shouldParse` JTArray JTByte+-- it "can parse an array of strings" $+-- parse parseJType "" "[Ljava/lang/String;" `shouldParse`+-- JTArray (JTClass (ClassName "java/lang/String"))++-- spec_MethodDescriptor_parsing :: Spec+-- spec_MethodDescriptor_parsing = do+-- it "can parse the empty method" $+-- parse parseMethodDescriptor "" "()V" `shouldParse`+-- MethodDescriptor [] Nothing+-- it "can parse method arguments" $+-- parse parseMethodDescriptor "" "(BZ)B" `shouldParse`+-- MethodDescriptor [JTByte, JTBoolean] (Just JTByte)+-- it "does not parse if there is too much" $+-- methodDescriptorFromText "(BZ)Bx" `shouldBe` Nothing++instance Arbitrary ClassName where+ arbitrary = pure $ ClassName "package.Main"++instance Arbitrary JType where+ arbitrary = genericArbitrary uniform++instance Arbitrary JBaseType where+ arbitrary = genericArbitrary uniform++instance Arbitrary MethodDescriptor where+ arbitrary = genericArbitrary uniform++instance Arbitrary FieldDescriptor where+ arbitrary = genericArbitrary uniform++instance Arbitrary t => Arbitrary (NameAndType t) where+ arbitrary =+ NameAndType+ <$> elements ["a", "f", "x", "y"]+ <*> arbitrary
+ test/Language/JVM/UtilsTest.hs view
@@ -0,0 +1,64 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}+{-# LANGUAGE OverloadedStrings #-}+module Language.JVM.UtilsTest where++import SpecHelper++import qualified Data.ByteString as BS++import Data.Set as Set+import qualified Data.Text.Encoding as TE+import qualified Data.Text as Text+import Language.JVM.Utils++prop_test_our_zero_decoder :: Text.Text -> Bool+prop_test_our_zero_decoder a =+ tryDecode (TE.encodeUtf8 a) == Right a++spec_parse_zero_text :: SpecWith ()+spec_parse_zero_text = do+ it "can read zero" $ do+ sizedByteStringToText "\192\128" `shouldBe` Right "\0"++ it "can read zero padded with text" $ do+ sizedByteStringToText "Some text \192\128 a x" `shouldBe` Right "Some text \0 a x"++ it "can convert a zero back again" $ do+ sizedByteStringFromText "\0" `shouldBe` "\192\128"++ it "can convert a padded zero back again" $ do+ sizedByteStringFromText "Some text \0 a x" `shouldBe` "Some text \192\128 a x"++ it "works on wierd strings" $ do+ tryDecode (TE.encodeUtf8 "\0 asd ßåæ∂ø∆œ˜˜¬å˚¬") `shouldBe` Right "\0 asd ßåæ∂ø∆œ˜˜¬å˚¬"++ it "works on chinese characters" $ do+ tryDecode (TE.encodeUtf8 "试一试中文") `shouldBe` Right "试一试中文"++ -- xit "works on http:/foo/p\237\160\128" $ do+ -- -- I don't know exactly the right result of this string, but it should be a correct java byte-string+ -- sizedByteStringToText "http:/foo/p\237\160\128" `shouldBe` Right "http:/foo/p?"++ -- xit "works on long and obscure byte string" $ do+ -- -- I don't know exactly the right result of this string, but it should be a correct java byte-string+ -- sizedByteStringToText obscureByteString `shouldBe` Right "?"++obscureByteString :: SizedByteString a+obscureByteString = SizedByteString+ "\192\128\DEL\194\128\195\191\196\128\197\191\198\128\201\143\201\144\202\175\202\176\203\191\204\128\205\175\205\176\207\191\224\144\128\224\147\191\224\148\176\224\150\143\224\150\144\224\151\191\224\152\128\224\155\191\224\156\128\224\157\143\224\158\128\224\158\191\224\164\128\224\165\191\224\166\128\224\167\191\224\168\128\224\169\191\224\170\128\224\171\191\224\172\128\224\173\191\224\174\128\224\175\191\224\176\128\224\177\191\224\178\128\224\179\191\224\180\128\224\181\191\224\182\128\224\183\191\224\184\128\224\185\191\224\186\128\224\187\191\224\188\128\224\191\191\225\128\128\225\130\159\225\130\160\225\131\191\225\132\128\225\135\191\225\136\128\225\141\191\225\142\160\225\143\191\225\144\128\225\153\191\225\154\128\225\154\159\225\154\160\225\155\191\225\158\128\225\159\191\225\160\128\225\162\175\225\184\128\225\187\191\225\188\128\225\191\191\226\128\128\226\129\175\226\129\176\226\130\159\226\130\160\226\131\143\226\131\144\226\131\191\226\132\128\226\133\143\226\133\144\226\134\143\226\134\144\226\135\191\226\136\128\226\139\191\226\140\128\226\143\191\226\144\128\226\144\191\226\145\128\226\145\159\226\145\160\226\147\191\226\148\128\226\149\191\226\150\128\226\150\159\226\150\160\226\151\191\226\152\128\226\155\191\226\156\128\226\158\191\226\160\128\226\163\191\226\186\128\226\187\191\226\188\128\226\191\159\226\191\176\226\191\191\227\128\128\227\128\191\227\129\128\227\130\159\227\130\160\227\131\191\227\132\128\227\132\175\227\132\176\227\134\143\227\134\144\227\134\159\227\134\160\227\134\191\227\136\128\227\139\191\227\140\128\227\143\191\227\144\128\228\182\181\228\184\128\233\191\191\234\128\128\234\146\143\234\146\144\234\147\143\234\176\128\237\158\163\238\128\128\239\163\191\239\164\128\239\171\191\239\172\128\239\173\143\239\173\144\239\183\191\239\184\160\239\184\175\239\184\176\239\185\143\239\185\144\239\185\175\239\185\176\239\187\190\239\187\191\239\187\191\239\188\128\239\191\175"+++instance Arbitrary a => Arbitrary (SizedList w a) where+ arbitrary =+ SizedList <$> arbitrary+ shrink (SizedList c) =+ SizedList <$> shrink c++instance Arbitrary (SizedByteString w) where+ arbitrary = do+ len <- choose (0, 50)+ SizedByteString . BS.pack <$> sequence (replicate len arbitrary)++instance (Enumish a) => Arbitrary (BitSet w a) where+ arbitrary =+ BitSet . Set.fromList <$> sublistOf (snd <$> inOrder)
+ test/Language/JVMTest.hs view
@@ -0,0 +1,164 @@+{-# LANGUAGE OverloadedStrings #-}+module Language.JVMTest where++import SpecHelper++import Data.Either+import qualified Data.IntMap as IM+import Data.List as List+import qualified Data.Text as Text+import qualified Data.ByteString.Lazy as BL+import Data.Foldable++import Language.JVM+import qualified Language.JVM.Attribute.Code as C+import Language.JVM.Attribute.StackMapTable++spec_testing_example :: SpecWith ()+spec_testing_example =+ it "can read classfile from file" $ do+ eclf <- readClassFile <$> BL.readFile "test/data/project/Main.class"+ case eclf of+ Right clf -> do+ cThisClass clf `shouldBe` ClassName "Main"+ cSuperClass clf `shouldBe` ClassName "java/lang/Object"+ Left msg ->+ fail $ show msg++test_reading_classfile :: IO [TestTree]+test_reading_classfile = testAllFiles $ \bs -> do+ let d = decodeClassFile bs+ it "can parse the bytestring" $ do+ d `shouldSatisfy` isRight++ let Right cls = d+ it "has a the magic number: 0xCAFEBABE" $ do+ cMagicNumber cls `shouldBe` 0xCAFEBABE++ it "can bootstrap the constant pool" $ do+ let+ cp = bootstrapConstantPool (cConstantPool cls)+ cp `shouldSatisfy` isRight+ let Right cp' = cp+ forM_ (cMethods' cls) $ \m -> do+ case (runEvolve cp' (evolve m)) of+ Right _ -> return ()+ Left err -> do+ putStr (show err) >> putStr ": "+ print . runEvolve cp' $ do+ x <- link (mDescriptor m)+ n <- link (mName m)+ return ((n, x) :: (MethodDescriptor, Text.Text))+ forM_ (mAttributes m) $ \a -> do+ -- Assume code+ case fromAttribute' a :: Either String (C.Code Low) of+ Right c -> do+ forM_ (unByteCode . C.codeByteCode $ c) $ \i ->+ putStr " -> " >> print i++ forM_ (C.codeAttributes c) $ \ca -> do+ print $ runEvolve cp' (evolve ca)+ putStrLn (hexStringS $ aInfo ca)+ case fromAttribute' ca :: Either String (StackMapTable Low) of+ Right x ->+ print x+ Left msg ->+ print msg+ Left x ->+ print x++ describe "encoding/decoding" $ do+ let e = encodeClassFile cls+ it "should encode to the original bytestring" $+ e `shouldBe` bs++ it "should decode to the same thing" $+ decodeClassFile e `shouldBe` Right cls++ describe "evolving/devolving" $ do+ let me = evolveClassFile cls+ it "can evolve the whole class file" $ do+ me `shouldSatisfy` isRight++ let Right x = me+ it "has same or smaller constant pool" $ do+ let d' = devolveClassFile x+ (IM.size . unConstantPool $ cConstantPool d') `shouldSatisfy`+ (<= (IM.size . unConstantPool $ cConstantPool cls))++ -- it "is the same when devolving with the original constant pool" $+ -- devolveClassFile' (cConstantPool cls) x `shouldMatchClass'` cls++ it "can do full read - write - read process" $ do+ let w = writeClassFile' (cConstantPool cls) x+ let y' = readClassFile w+ y' `shouldSatisfy` isRight+ let Right y = y'+ x `shouldMatchClass` y++shouldMatchClass :: ClassFile High -> ClassFile High -> IO ()+shouldMatchClass y x = do+ cAccessFlags' y `shouldBe` cAccessFlags' x+ cThisClass y `shouldBe` cThisClass x+ cSuperClass y `shouldBe` cSuperClass x+ cInterfaces y `shouldBe` cInterfaces x+ cFields' y `shouldBe` cFields' x+ forM_ (zip (cMethods y) (cMethods x)) $ \ (ym, xm) -> do+ ym `shouldMatchMethod` xm+ y `shouldBe` x++shouldMatchClass' :: ClassFile Low -> ClassFile Low -> IO ()+shouldMatchClass' y x = do+ cAccessFlags' y `shouldBe` cAccessFlags' x+ cThisClass y `shouldBe` cThisClass x+ cSuperClass y `shouldBe` cSuperClass x+ cInterfaces y `shouldBe` cInterfaces x+ cFields' y `shouldBe` cFields' x+ forM_ (zip (cMethods y) (cMethods x)) $ \(ym, xm) -> do+ shouldMatchMethod' ym xm++shouldMatchMethod :: Method High -> Method High -> IO ()+shouldMatchMethod ym xm = do+ mAccessFlags ym `shouldBe` mAccessFlags xm+ mName ym `shouldBe` mName xm+ mDescriptor ym `shouldBe` mDescriptor xm+ mExceptions ym `shouldMatchList` mExceptions xm+ case (mCode ym, mCode xm) of+ (Just yc, Just xc) -> do+ cmpOver C.codeByteCodeOprs yc xc $ \ yb xb -> do+ yb `shouldBe` xb+ _ -> mCode ym `shouldBe` mCode xm++shouldMatchMethod' :: Method Low -> Method Low -> IO ()+shouldMatchMethod' ym xm = do+ mAccessFlags ym `shouldBe` mAccessFlags xm+ mName ym `shouldBe` mName xm+ mDescriptor ym `shouldBe` mDescriptor xm+ forM_ (zip (unSizedList $ mAttributes ym ) (unSizedList $ mAttributes xm)) $ \(ya, xa) -> do+ case (fromAttribute' ya, fromAttribute' xa) of+ (Right yc, Right xc) -> do+ cmpOn C.codeMaxStack yc xc+ cmpOn C.codeMaxLocals yc xc+ cmpOn C.codeByteCodeInsts yc xc+ cmpOn C.codeExceptionTable yc xc+ cmpOver (List.sort . unSizedList .C.codeAttributes) yc xc $ \ yca xca -> do+ case (fromAttribute' yca, fromAttribute' xca)+ :: (Either String (StackMapTable Low), Either String (StackMapTable Low)) of+ (Right yst, Right xst) -> do+ cmpOver stackMapTable yst xst $ shouldBe+ (yst, xst) ->+ yst `shouldBe` xst+ (yc, xc) ->+ yc `shouldBe` xc++cmpOn :: (Show b, Eq b) => (a -> b) -> a -> a -> IO ()+cmpOn f a b =+ f a `shouldBe` f b++cmpOver :: (Foldable t) => (a -> t b) -> a -> a -> (b -> b -> IO ()) -> IO ()+cmpOver g ta tb f =+ forM_ (zip (toList . g $ ta) (toList . g $ tb)) (uncurry f)++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)
+ test/SpecHelper.hs view
@@ -0,0 +1,155 @@++module SpecHelper+ ( module Test.Tasty+ , module Test.Hspec.Expectations.Pretty+ , module Test.Tasty.QuickCheck+ , module Generic.Random+ , decode+ , encode+ , blReadFile+ , isoBinary+ , isoRoundtrip+ , isoByteCodeRoundtrip+ , byteCodeRoundtrip+ , testAllFiles+ , hexStringS+ , hexString+ , Spec+ , SpecWith+ , it+ , xit+ , describe+ ) where++import Test.Hspec.Expectations.Pretty++import Test.Tasty+import Test.Tasty.Hspec hiding (shouldBe)+import Test.Tasty.QuickCheck+import qualified Test.QuickCheck.Property as P+import qualified Data.ByteString.Lazy as BL+import qualified Data.ByteString as BS++import Data.Bifunctor++import System.FilePath+import System.Directory+import Generic.Random++import Control.Monad+import Data.Binary+import Data.Bits+import qualified Data.List as List++import Language.JVM.ByteCode+import Language.JVM.Utils+import Language.JVM.Staged+import Language.JVM.ClassFileReader++blReadFile :: FilePath -> IO BL.ByteString+blReadFile = BL.readFile++toHex :: Word8 -> String+toHex x =+ [ alpha !! fromIntegral (x `shift` (-4))+ , alpha !! fromIntegral (x `mod` 16)+ ]+ where alpha = "0123456789abcdef"++testAllFiles :: (BL.ByteString -> Spec) -> IO [TestTree]+testAllFiles spec = do+ files <- filter isClass <$> recursiveContents "test/data"+ forM files $ \file -> do+ bs <- blReadFile file+ testSpec file $ spec bs+ where+ isClass p =+ takeExtension p == ".class"+ && p /= "test/data/SQLite.class"+++-- testSomeFiles :: SpecWith BL.ByteString -> IO [TestTree]+-- testSomeFiles spec =+-- forM files $ \file -> testSpec file (beforeAll (blReadFile file) spec)+-- where+-- files =+-- [ "test/data/java/util/zip/ZipOutputStream.class"+-- , "test/data/project/Main.class"+-- , "test/data/com/sun/istack/internal/localization/Localizable.class"+-- , "test/data/SQLite.class"+-- , "test/data/Emitter.class"+-- , "test/data/EventExecutorGroup.class"+-- , "test/data/NioEventLoopGroup.class"+-- ]++hexStringS :: BS.ByteString -> String+hexStringS =+ hexString . BL.fromStrict++hexString :: BL.ByteString -> String+hexString =+ List.intercalate " " . group 8 . concat . map toHex . BL.unpack++isoBinary :: (Binary a, Eq a, Show a) => a -> Property+isoBinary a =+ let bs = encode a+ in counterexample (hexString bs) $+ decode bs === a++-- | Test that a value can go from the Highest state to binary and back again+-- without losing data.+isoRoundtrip ::+ (Staged a, Eq (a High), Show (a High), Binary (a Low))+ => (a High) -> Property+isoRoundtrip a =+ case roundtrip a of+ Right (_, a') ->+ a' === a+ Left msg -> property $ P.failed { P.reason = msg }+ where+ roundtrip a1 = do+ let (a', CPBuilder _ cp) = runConstantPoolBuilder (devolve a1) cpbEmpty+ let bs = encode a'+ a'' <- bimap trd trd $ decodeOrFail bs+ cp' <- first show $ bootstrapConstantPool cp+ a3 <- first show $ runEvolve cp' (evolve a'')+ return (bs, a3)++-- | Test that a value can go from the Highest state to binary and back again+-- without losing data.+isoByteCodeRoundtrip ::+ (ByteCodeStaged a, Eq (a High), Show (a High), Binary (a Low))+ => (a High) -> Property+isoByteCodeRoundtrip a =+ case byteCodeRoundtrip a of+ Right (_, a') ->+ a' === a+ Left msg -> property $ P.failed { P.reason = msg }+ where++byteCodeRoundtrip :: (ByteCodeStaged s, Binary (s Low)) => s High -> Either String (BL.ByteString, s High)+byteCodeRoundtrip a1 = do+ let (a', CPBuilder _ cp) = runConstantPoolBuilder (devolveBC (return . fromIntegral) a1) cpbEmpty+ let bs = encode a'+ a'' <- bimap trd trd $ decodeOrFail bs+ cp' <- first show $ bootstrapConstantPool cp+ a3 <- first show $ runEvolve cp' (evolveBC (return . fromIntegral) a'')+ return (bs, a3)++folderContents :: FilePath -> IO [ FilePath ]+folderContents fp =+ map (fp </>) <$> listDirectory fp++recursiveContents :: FilePath -> IO [ FilePath ]+recursiveContents fp = do+ test <- doesDirectoryExist fp+ (fp:) <$> if test then do+ content <- folderContents fp+ concat <$> mapM recursiveContents content+ else return []++group :: Int -> [a] -> [[a]]+group _ [] = []+group n l+ | n > 0 = (take n l) : (group n (drop n l))+ | otherwise = error "Negative n"
+ test/Test.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -F -pgmF tasty-discover -optF --tree-display #-}