feat: Field and attribute parsing
This commit is contained in:
parent
62b537a93f
commit
f9fbedc87a
8 changed files with 136 additions and 7 deletions
|
@ -28,13 +28,16 @@ library
|
|||
Data.Enum.Util
|
||||
Data.Hex
|
||||
Language.Java.Classfile
|
||||
Language.Java.Classfile.Attributes
|
||||
Language.Java.Classfile.ClassFlag
|
||||
Language.Java.Classfile.ConstantPool
|
||||
Language.Java.Classfile.ConstantPool.Entry
|
||||
Language.Java.Classfile.ConstantPool.References
|
||||
Language.Java.Classfile.Extract
|
||||
Language.Java.Classfile.Extractable
|
||||
Language.Java.Classfile.Extractable.SizedBytes
|
||||
Language.Java.Classfile.Extractable.WithTag
|
||||
Language.Java.Classfile.Fields
|
||||
Language.Java.Classfile.Flag
|
||||
Language.Java.Classfile.Flags
|
||||
Language.Java.Classfile.FromBigEndian
|
||||
|
|
|
@ -10,6 +10,7 @@ import Language.Java.Classfile.Flags (Flags)
|
|||
import Language.Java.Classfile.ClassFlag (ClassFlag)
|
||||
import Language.Java.Classfile.ConstantPool.References (ClassReference)
|
||||
import Language.Java.Classfile.Interfaces (Interfaces)
|
||||
import Language.Java.Classfile.Fields (Fields)
|
||||
|
||||
data Classfile = Classfile
|
||||
{ magic :: Magic
|
||||
|
@ -19,6 +20,7 @@ data Classfile = Classfile
|
|||
, this :: ClassReference
|
||||
, super :: ClassReference
|
||||
, interfaces :: Interfaces
|
||||
, fields :: Fields
|
||||
}
|
||||
deriving stock (Show, Generic)
|
||||
deriving Extractable via Generically Classfile
|
||||
|
|
21
src/Language/Java/Classfile/Attributes.hs
Normal file
21
src/Language/Java/Classfile/Attributes.hs
Normal file
|
@ -0,0 +1,21 @@
|
|||
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
||||
{-# LANGUAGE DerivingVia #-}
|
||||
{-# LANGUAGE DeriveGeneric #-}
|
||||
module Language.Java.Classfile.Attributes (Attributes(..), Attribute(..)) where
|
||||
import Data.Array.IArray (Array)
|
||||
import Data.Word (Word16, Word32)
|
||||
import Language.Java.Classfile.Extractable (Extractable)
|
||||
import Language.Java.Classfile.ConstantPool.References (Utf8Reference)
|
||||
import Language.Java.Classfile.Extractable.SizedBytes (SizedBytes)
|
||||
import GHC.Generics ( Generic, Generically(..) )
|
||||
|
||||
newtype Attributes = Attributes (Array Word16 Attribute)
|
||||
deriving stock (Show)
|
||||
deriving newtype Extractable
|
||||
|
||||
data Attribute = Attribute
|
||||
{ name :: Utf8Reference
|
||||
, info :: SizedBytes Word32
|
||||
}
|
||||
deriving stock (Show, Generic)
|
||||
deriving Extractable via Generically Attribute
|
|
@ -1,13 +1,15 @@
|
|||
{-# LANGUAGE DerivingStrategies #-}
|
||||
{-# LANGUAGE InstanceSigs #-}
|
||||
{-# LANGUAGE TypeApplications #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
module Language.Java.Classfile.ConstantPool (ConstantPool(..)) where
|
||||
import Data.Word (Word16)
|
||||
import Data.Array.IArray (Array, listArray)
|
||||
import Language.Java.Classfile.ConstantPool.Entry (Entry)
|
||||
import Language.Java.Classfile.ConstantPool.Entry (Entry, StorageCount (..), storageCount)
|
||||
import Language.Java.Classfile.Extractable (Extractable (extract))
|
||||
import Language.Java.Classfile.Extract (Extract, traceIndex)
|
||||
import Language.Java.Classfile.Extract (Extract, traceIndex, traceType)
|
||||
import Control.Monad (forM)
|
||||
import qualified Data.Text as Text
|
||||
|
||||
newtype ConstantPool = ConstantPool (Array Word16 Entry)
|
||||
deriving stock (Show)
|
||||
|
@ -16,5 +18,21 @@ instance Extractable ConstantPool where
|
|||
extract :: Extract ConstantPool
|
||||
extract = do
|
||||
count <- extract @Word16
|
||||
elements <- forM [1..fromIntegral count - 1] $ \ i -> traceIndex i extract
|
||||
pure . ConstantPool $ listArray (1, count - 1) elements
|
||||
|
||||
let typeName = Text.concat
|
||||
[ "ConstantPool ("
|
||||
, Text.pack . show $ count
|
||||
, ")"
|
||||
]
|
||||
|
||||
let extractElements index end
|
||||
| index == end = pure []
|
||||
| otherwise = do
|
||||
element <- traceIndex index extract
|
||||
case storageCount element of
|
||||
Once -> (element:) <$> extractElements (succ index) end
|
||||
Twice -> ([element, element] <>) <$> extractElements (index + 2) end
|
||||
|
||||
traceType typeName $ do
|
||||
elements <- extractElements 1 (fromIntegral count)
|
||||
pure . ConstantPool $ listArray (1, count - 1) elements
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
{-# LANGUAGE TypeApplications #-}
|
||||
{-# LANGUAGE ScopedTypeVariables #-}
|
||||
{-# LANGUAGE InstanceSigs #-}
|
||||
module Language.Java.Classfile.ConstantPool.Entry (Entry(..)) where
|
||||
{-# LANGUAGE LambdaCase #-}
|
||||
{-# LANGUAGE OrPatterns #-}
|
||||
module Language.Java.Classfile.ConstantPool.Entry (Entry(..), StorageCount(..), storageCount) where
|
||||
import GHC.Generics (Generic, Generically(..))
|
||||
import Language.Java.Classfile.Extractable (Extractable (extract))
|
||||
import Language.Java.Classfile.Extractable.WithTag (Word8Tag)
|
||||
|
@ -55,3 +57,11 @@ instance (Integral sizeType, Extractable sizeType) => Extractable (SizedText siz
|
|||
Left err -> fail $ show err
|
||||
Right t -> pure $ SizedText t
|
||||
|
||||
data StorageCount = Once | Twice
|
||||
|
||||
storageCount :: Entry -> StorageCount
|
||||
storageCount = \case
|
||||
(Double _ ; Long _) -> Twice
|
||||
_ -> Once
|
||||
|
||||
|
||||
|
|
|
@ -78,8 +78,8 @@ instance (Extractable index, Extractable element, Ix index, Integral index, Show
|
|||
then pure $ listArray (1, 0) []
|
||||
else traceType typeName $ do
|
||||
|
||||
elements <- forM [0..fromIntegral count] $ \ i -> traceIndex i extract
|
||||
pure $ listArray (1, count) elements
|
||||
elements <- forM [0..fromIntegral count - 1] $ \ i -> traceIndex i extract
|
||||
pure $ listArray (0, count - 1) elements
|
||||
|
||||
deriving via Generically () instance Extractable ()
|
||||
deriving via Generically (a, b) instance (Extractable a, Extractable b) => Extractable (a, b)
|
||||
|
|
20
src/Language/Java/Classfile/Extractable/SizedBytes.hs
Normal file
20
src/Language/Java/Classfile/Extractable/SizedBytes.hs
Normal file
|
@ -0,0 +1,20 @@
|
|||
{-# LANGUAGE DerivingStrategies #-}
|
||||
{-# LANGUAGE InstanceSigs #-}
|
||||
{-# LANGUAGE TypeApplications #-}
|
||||
{-# LANGUAGE ScopedTypeVariables #-}
|
||||
module Language.Java.Classfile.Extractable.SizedBytes (SizedBytes(..)) where
|
||||
import Data.ByteString (ByteString)
|
||||
import Language.Java.Classfile.Extractable (Extractable (..))
|
||||
import Language.Java.Classfile.Extract (Extract, bytes)
|
||||
import qualified Data.ByteString as StrictByteString
|
||||
import qualified Data.ByteString.Lazy as ByteString
|
||||
|
||||
newtype SizedBytes sizeType = SizedBytes ByteString
|
||||
deriving stock Show
|
||||
|
||||
instance (Extractable sizeType, Integral sizeType) => Extractable (SizedBytes sizeType) where
|
||||
extract :: Extract (SizedBytes sizeType)
|
||||
extract = do
|
||||
size <- extract @sizeType
|
||||
SizedBytes . StrictByteString.concat . ByteString.toChunks <$> bytes (fromIntegral size)
|
||||
|
55
src/Language/Java/Classfile/Fields.hs
Normal file
55
src/Language/Java/Classfile/Fields.hs
Normal file
|
@ -0,0 +1,55 @@
|
|||
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
||||
{-# LANGUAGE DerivingVia #-}
|
||||
{-# LANGUAGE DeriveGeneric #-}
|
||||
{-# LANGUAGE TypeFamilies #-}
|
||||
{-# LANGUAGE InstanceSigs #-}
|
||||
{-# LANGUAGE LambdaCase #-}
|
||||
module Language.Java.Classfile.Fields (Fields(..)) where
|
||||
import Data.Array.IArray (Array)
|
||||
import Data.Word (Word16)
|
||||
import Language.Java.Classfile.Extractable (Extractable)
|
||||
import GHC.Generics ( Generically, Generic, Generically(..) )
|
||||
import Language.Java.Classfile.Flags (Flags)
|
||||
import Language.Java.Classfile.Flag (FlagMask (..))
|
||||
import Language.Java.Classfile.ConstantPool.References (Utf8Reference)
|
||||
import Language.Java.Classfile.Attributes (Attributes)
|
||||
|
||||
newtype Fields = Fields (Array Word16 Field)
|
||||
deriving stock Show
|
||||
deriving newtype Extractable
|
||||
|
||||
data FieldFlag
|
||||
= Public
|
||||
| Private
|
||||
| Protected
|
||||
| Static
|
||||
| Final
|
||||
| Volatile
|
||||
| Transient
|
||||
| Synthetic
|
||||
| Enumeration -- original "Enum"
|
||||
deriving stock (Show, Eq, Ord, Enum, Bounded)
|
||||
|
||||
instance FlagMask FieldFlag where
|
||||
type FlagType FieldFlag = Word16
|
||||
maskOf :: FieldFlag -> FlagType FieldFlag
|
||||
maskOf = \case
|
||||
Public -> 0x0001
|
||||
Private -> 0x0002
|
||||
Protected -> 0x0004
|
||||
Static -> 0x0008
|
||||
Final -> 0x0010
|
||||
Volatile -> 0x0040
|
||||
Transient -> 0x0080
|
||||
Synthetic -> 0x1000
|
||||
Enumeration -> 0x4000
|
||||
|
||||
|
||||
data Field = Field
|
||||
{ flags :: Flags FieldFlag
|
||||
, name :: Utf8Reference
|
||||
, descriptor :: Utf8Reference
|
||||
, attribute :: Attributes
|
||||
}
|
||||
deriving stock (Show, Generic)
|
||||
deriving Extractable via Generically Field
|
Loading…
Add table
Add a link
Reference in a new issue