{-# LANGUAGE LexicalNegation #-}
{-# LANGUAGE RecordWildCards #-}
module JVM.Data.Convert.Method where
import Control.Applicative (liftA2)
import Control.Monad (foldM)
import Data.List (mapAccumL, nubBy, sortOn)
import Data.TypeMergingList qualified as TML
import Data.Vector qualified as V
import Data.Word (Word16)
import Effectful
import GHC.Stack (HasCallStack)
import JVM.Data.Abstract.ClassFile.Method
import JVM.Data.Abstract.ClassFile.Method qualified as Abs
import JVM.Data.Abstract.ConstantPool (ConstantPoolEntry (..))
import JVM.Data.Convert.AccessFlag (accessFlagsToWord16)
import JVM.Data.Convert.ConstantPool
import JVM.Data.Convert.Descriptor (convertMethodDescriptor)
import JVM.Data.Convert.Instruction (CodeConverterEff, convertInstructions, fullyResolveAbs, fullyRunCodeConverter)
import JVM.Data.Convert.Monad
import JVM.Data.Raw.ClassFile qualified as Raw
import JVM.Data.Raw.Types
foldMWith :: (Monad m) => (a -> b -> m (a, c)) -> a -> [b] -> m (a, [c])
foldMWith :: forall (m :: * -> *) a b c.
Monad m =>
(a -> b -> m (a, c)) -> a -> [b] -> m (a, [c])
foldMWith a -> b -> m (a, c)
_ a
a [] = (a, [c]) -> m (a, [c])
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a
a, [])
foldMWith a -> b -> m (a, c)
f a
a (b
x : [b]
xs) = do
(a', x') <- a -> b -> m (a, c)
f a
a b
x
(a'', xs') <- foldMWith f a' xs
pure (a'', x' : xs')
convertMethodAttribute :: (ConvertEff r) => (HasCallStack) => Abs.MethodAttribute -> Eff r Raw.AttributeInfo
convertMethodAttribute :: forall (r :: [Effect]).
(ConvertEff r, HasCallStack) =>
MethodAttribute -> Eff r AttributeInfo
convertMethodAttribute (Abs.Code (Abs.CodeAttributeData{[Instruction]
[CodeAttribute]
[ExceptionTableEntry]
U2
maxStack :: U2
maxLocals :: U2
code :: [Instruction]
exceptionTable :: [ExceptionTableEntry]
codeAttributes :: [CodeAttribute]
codeAttributes :: CodeAttributeData -> [CodeAttribute]
exceptionTable :: CodeAttributeData -> [ExceptionTableEntry]
code :: CodeAttributeData -> [Instruction]
maxLocals :: CodeAttributeData -> U2
maxStack :: CodeAttributeData -> U2
..})) = do
(code', attributes') <- Eff (State ConvertState : r) ([Instruction], Vector AttributeInfo)
-> Eff r ([Instruction], Vector AttributeInfo)
forall (r' :: [Effect]) a.
ConvertEff r' =>
Eff (State ConvertState : r') a -> Eff r' a
fullyRunCodeConverter (Eff (State ConvertState : r) ([Instruction], Vector AttributeInfo)
-> Eff r ([Instruction], Vector AttributeInfo))
-> Eff
(State ConvertState : r) ([Instruction], Vector AttributeInfo)
-> Eff r ([Instruction], Vector AttributeInfo)
forall a b. (a -> b) -> a -> b
$ do
([Instruction]
-> Vector AttributeInfo -> ([Instruction], Vector AttributeInfo))
-> Eff (State ConvertState : r) [Instruction]
-> Eff (State ConvertState : r) (Vector AttributeInfo)
-> Eff
(State ConvertState : r) ([Instruction], Vector AttributeInfo)
forall a b c.
(a -> b -> c)
-> Eff (State ConvertState : r) a
-> Eff (State ConvertState : r) b
-> Eff (State ConvertState : r) c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (,) ([Instruction] -> Eff (State ConvertState : r) [Instruction]
forall (r :: [Effect]).
CodeConverterEff r =>
[Instruction] -> Eff r [Instruction]
convertInstructions [Instruction]
code) ([CodeAttribute]
-> Eff (State ConvertState : r) (Vector AttributeInfo)
forall (r :: [Effect]).
CodeConverterEff r =>
[CodeAttribute] -> Eff r (Vector AttributeInfo)
convertCodeAttributes [CodeAttribute]
codeAttributes)
exceptionTable' <- convertExceptionTable exceptionTable
nameIndex <- findIndexOf (CPUTF8Entry "Code")
pure $ Raw.AttributeInfo (fromIntegral nameIndex) (Raw.CodeAttribute maxStack maxLocals (V.fromList code') exceptionTable' attributes')
where
convertExceptionTable :: (ConvertEff r) => [Abs.ExceptionTableEntry] -> Eff r (V.Vector Raw.ExceptionTableEntry)
convertExceptionTable :: forall (r :: [Effect]).
ConvertEff r =>
[ExceptionTableEntry] -> Eff r (Vector ExceptionTableEntry)
convertExceptionTable = ([ExceptionTableEntry] -> Vector ExceptionTableEntry)
-> Eff r [ExceptionTableEntry]
-> Eff r (Vector ExceptionTableEntry)
forall a b. (a -> b) -> Eff r a -> Eff r b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [ExceptionTableEntry] -> Vector ExceptionTableEntry
forall a. [a] -> Vector a
V.fromList (Eff r [ExceptionTableEntry] -> Eff r (Vector ExceptionTableEntry))
-> ([ExceptionTableEntry] -> Eff r [ExceptionTableEntry])
-> [ExceptionTableEntry]
-> Eff r (Vector ExceptionTableEntry)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ExceptionTableEntry -> Eff r ExceptionTableEntry)
-> [ExceptionTableEntry] -> Eff r [ExceptionTableEntry]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ExceptionTableEntry -> Eff r ExceptionTableEntry
forall (r :: [Effect]).
ExceptionTableEntry -> Eff r ExceptionTableEntry
convertExceptionTableEntry
convertExceptionTableEntry :: Abs.ExceptionTableEntry -> Eff r Raw.ExceptionTableEntry
convertExceptionTableEntry :: forall (r :: [Effect]).
ExceptionTableEntry -> Eff r ExceptionTableEntry
convertExceptionTableEntry = ExceptionTableEntry -> Eff r ExceptionTableEntry
forall a. HasCallStack => a
undefined
convertCodeAttributes :: (CodeConverterEff r) => [Abs.CodeAttribute] -> Eff r (V.Vector Raw.AttributeInfo)
convertCodeAttributes :: forall (r :: [Effect]).
CodeConverterEff r =>
[CodeAttribute] -> Eff r (Vector AttributeInfo)
convertCodeAttributes = ([AttributeInfo] -> Vector AttributeInfo)
-> Eff r [AttributeInfo] -> Eff r (Vector AttributeInfo)
forall a b. (a -> b) -> Eff r a -> Eff r b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [AttributeInfo] -> Vector AttributeInfo
forall a. [a] -> Vector a
V.fromList (Eff r [AttributeInfo] -> Eff r (Vector AttributeInfo))
-> ([CodeAttribute] -> Eff r [AttributeInfo])
-> [CodeAttribute]
-> Eff r (Vector AttributeInfo)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CodeAttribute -> Eff r AttributeInfo)
-> [CodeAttribute] -> Eff r [AttributeInfo]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse CodeAttribute -> Eff r AttributeInfo
forall (r :: [Effect]).
CodeConverterEff r =>
CodeAttribute -> Eff r AttributeInfo
convertCodeAttribute'
convertCodeAttribute' :: (CodeConverterEff r) => Abs.CodeAttribute -> Eff r Raw.AttributeInfo
convertCodeAttribute' :: forall (r :: [Effect]).
CodeConverterEff r =>
CodeAttribute -> Eff r AttributeInfo
convertCodeAttribute' (LineNumberTable [LineNumberTableEntry]
lns) = do
lns' <- [LineNumberTableEntry] -> Eff r (Vector LineNumberTableEntry)
forall (r :: [Effect]).
[LineNumberTableEntry] -> Eff r (Vector LineNumberTableEntry)
convertLineNumberTable [LineNumberTableEntry]
lns
nameIndex <- findIndexOf (CPUTF8Entry "LineNumberTable")
pure $ Raw.AttributeInfo (fromIntegral nameIndex) (Raw.LineNumberTableAttribute lns')
where
convertLineNumberTable :: [Abs.LineNumberTableEntry] -> Eff r (V.Vector Raw.LineNumberTableEntry)
convertLineNumberTable :: forall (r :: [Effect]).
[LineNumberTableEntry] -> Eff r (Vector LineNumberTableEntry)
convertLineNumberTable = ([LineNumberTableEntry] -> Vector LineNumberTableEntry)
-> Eff r [LineNumberTableEntry]
-> Eff r (Vector LineNumberTableEntry)
forall a b. (a -> b) -> Eff r a -> Eff r b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [LineNumberTableEntry] -> Vector LineNumberTableEntry
forall a. [a] -> Vector a
V.fromList (Eff r [LineNumberTableEntry]
-> Eff r (Vector LineNumberTableEntry))
-> ([LineNumberTableEntry] -> Eff r [LineNumberTableEntry])
-> [LineNumberTableEntry]
-> Eff r (Vector LineNumberTableEntry)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (LineNumberTableEntry -> Eff r LineNumberTableEntry)
-> [LineNumberTableEntry] -> Eff r [LineNumberTableEntry]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse LineNumberTableEntry -> Eff r LineNumberTableEntry
forall (r :: [Effect]).
LineNumberTableEntry -> Eff r LineNumberTableEntry
convertLineNumberTableEntry
convertLineNumberTableEntry :: Abs.LineNumberTableEntry -> Eff r Raw.LineNumberTableEntry
convertLineNumberTableEntry :: forall (r :: [Effect]).
LineNumberTableEntry -> Eff r LineNumberTableEntry
convertLineNumberTableEntry (Abs.LineNumberTableEntry U2
a U2
b) = LineNumberTableEntry -> Eff r LineNumberTableEntry
forall a. a -> Eff r a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (LineNumberTableEntry -> Eff r LineNumberTableEntry)
-> LineNumberTableEntry -> Eff r LineNumberTableEntry
forall a b. (a -> b) -> a -> b
$ U2 -> U2 -> LineNumberTableEntry
Raw.LineNumberTableEntry U2
a U2
b
convertCodeAttribute' (StackMapTable [StackMapFrame]
frames) = do
frames' <- [StackMapFrame] -> Eff r (Vector StackMapFrame)
forall (r :: [Effect]).
CodeConverterEff r =>
[StackMapFrame] -> Eff r (Vector StackMapFrame)
convertStackMapTable [StackMapFrame]
frames
nameIndex <- findIndexOf (CPUTF8Entry "StackMapTable")
pure $ Raw.AttributeInfo (fromIntegral nameIndex) (Raw.StackMapTableAttribute frames')
where
convertStackMapTable :: (CodeConverterEff r) => [Abs.StackMapFrame] -> Eff r (V.Vector Raw.StackMapFrame)
convertStackMapTable :: forall (r :: [Effect]).
CodeConverterEff r =>
[StackMapFrame] -> Eff r (Vector StackMapFrame)
convertStackMapTable [StackMapFrame]
fs = do
resolvedFrames <- (StackMapFrame -> Eff r (U2, StackMapFrame))
-> [StackMapFrame] -> Eff r [(U2, StackMapFrame)]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse StackMapFrame -> Eff r (U2, StackMapFrame)
forall (r :: [Effect]).
CodeConverterEff r =>
StackMapFrame -> Eff r (U2, StackMapFrame)
resolveFrame [StackMapFrame]
fs
let uniqueFrames =
((U2, StackMapFrame) -> (U2, StackMapFrame) -> Bool)
-> [(U2, StackMapFrame)] -> [(U2, StackMapFrame)]
forall a. (a -> a -> Bool) -> [a] -> [a]
nubBy (\(U2
o1, StackMapFrame
_) (U2
o2, StackMapFrame
_) -> U2
o1 U2 -> U2 -> Bool
forall a. Eq a => a -> a -> Bool
== U2
o2) ([(U2, StackMapFrame)] -> [(U2, StackMapFrame)])
-> [(U2, StackMapFrame)] -> [(U2, StackMapFrame)]
forall a b. (a -> b) -> a -> b
$
((U2, StackMapFrame) -> U2)
-> [(U2, StackMapFrame)] -> [(U2, StackMapFrame)]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn (U2, StackMapFrame) -> U2
forall a b. (a, b) -> a
fst [(U2, StackMapFrame)]
resolvedFrames
V.fromList . reverse . snd <$> foldM convertAndAccumulate (-1, []) uniqueFrames
resolveFrame :: (CodeConverterEff r) => Abs.StackMapFrame -> Eff r (Word16, Abs.StackMapFrame)
resolveFrame :: forall (r :: [Effect]).
CodeConverterEff r =>
StackMapFrame -> Eff r (U2, StackMapFrame)
resolveFrame StackMapFrame
f = do
off <- Label -> Eff r U2
forall (r :: [Effect]). CodeConverterEff r => Label -> Eff r U2
fullyResolveAbs (StackMapFrame -> Label
getFrameLabel StackMapFrame
f)
pure (off, f)
getFrameLabel :: StackMapFrame -> Label
getFrameLabel (Abs.SameFrame Label
l) = Label
l
getFrameLabel (Abs.ChopFrame U1
_ Label
l) = Label
l
getFrameLabel (Abs.SameLocals1StackItemFrame VerificationTypeInfo
_ Label
l) = Label
l
getFrameLabel (Abs.AppendFrame [VerificationTypeInfo]
_ Label
l) = Label
l
getFrameLabel (Abs.FullFrame [VerificationTypeInfo]
_ [VerificationTypeInfo]
_ Label
l) = Label
l
convertAndAccumulate :: (CodeConverterEff r) => (Int, [Raw.StackMapFrame]) -> (Word16, Abs.StackMapFrame) -> Eff r (Int, [Raw.StackMapFrame])
convertAndAccumulate :: forall (r :: [Effect]).
CodeConverterEff r =>
(Int, [StackMapFrame])
-> (U2, StackMapFrame) -> Eff r (Int, [StackMapFrame])
convertAndAccumulate (Int
prev, [StackMapFrame]
acc) (U2
absLabel16, StackMapFrame
frame) = do
let current :: Int
current = U2 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral U2
absLabel16
let delta :: Int
delta = Int
current Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
prev Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
rawFrame <- case StackMapFrame
frame of
Abs.SameFrame Label
_ ->
StackMapFrame -> Eff r StackMapFrame
forall a. a -> Eff r a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (StackMapFrame -> Eff r StackMapFrame)
-> StackMapFrame -> Eff r StackMapFrame
forall a b. (a -> b) -> a -> b
$
if Int
delta Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
63
then U1 -> StackMapFrame
Raw.SameFrame (Int -> U1
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
delta)
else U2 -> StackMapFrame
Raw.SameFrameExtended (Int -> U2
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
delta)
Abs.ChopFrame U1
x Label
_ ->
StackMapFrame -> Eff r StackMapFrame
forall a. a -> Eff r a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (StackMapFrame -> Eff r StackMapFrame)
-> StackMapFrame -> Eff r StackMapFrame
forall a b. (a -> b) -> a -> b
$ U1 -> U2 -> StackMapFrame
Raw.ChopFrame U1
x (Int -> U2
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
delta)
Abs.SameLocals1StackItemFrame VerificationTypeInfo
x Label
_ -> do
x' <- VerificationTypeInfo -> Eff r VerificationTypeInfo
forall (r :: [Effect]).
CodeConverterEff r =>
VerificationTypeInfo -> Eff r VerificationTypeInfo
convertVerificationTypeInfo VerificationTypeInfo
x
pure $
if delta <= 63
then Raw.SameLocals1StackItemFrame x' (fromIntegral delta)
else Raw.SameLocals1StackItemFrameExtended x' (fromIntegral delta)
Abs.AppendFrame [VerificationTypeInfo]
x Label
_ -> do
x' <- (VerificationTypeInfo -> Eff r VerificationTypeInfo)
-> [VerificationTypeInfo] -> Eff r [VerificationTypeInfo]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse VerificationTypeInfo -> Eff r VerificationTypeInfo
forall (r :: [Effect]).
CodeConverterEff r =>
VerificationTypeInfo -> Eff r VerificationTypeInfo
convertVerificationTypeInfo [VerificationTypeInfo]
x
pure $ Raw.AppendFrame (V.fromList x') (fromIntegral delta)
Abs.FullFrame [VerificationTypeInfo]
x [VerificationTypeInfo]
y Label
_ -> do
x' <- (VerificationTypeInfo -> Eff r VerificationTypeInfo)
-> [VerificationTypeInfo] -> Eff r [VerificationTypeInfo]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse VerificationTypeInfo -> Eff r VerificationTypeInfo
forall (r :: [Effect]).
CodeConverterEff r =>
VerificationTypeInfo -> Eff r VerificationTypeInfo
convertVerificationTypeInfo [VerificationTypeInfo]
x
y' <- traverse convertVerificationTypeInfo y
pure $ Raw.FullFrame (V.fromList x') (V.fromList y') (fromIntegral delta)
pure (current, rawFrame : acc)
convertVerificationTypeInfo :: (CodeConverterEff r) => Abs.VerificationTypeInfo -> Eff r Raw.VerificationTypeInfo
convertVerificationTypeInfo :: forall (r :: [Effect]).
CodeConverterEff r =>
VerificationTypeInfo -> Eff r VerificationTypeInfo
convertVerificationTypeInfo VerificationTypeInfo
Abs.TopVariableInfo = VerificationTypeInfo -> Eff r VerificationTypeInfo
forall a. a -> Eff r a
forall (f :: * -> *) a. Applicative f => a -> f a
pure VerificationTypeInfo
Raw.TopVariableInfo
convertVerificationTypeInfo VerificationTypeInfo
Abs.IntegerVariableInfo = VerificationTypeInfo -> Eff r VerificationTypeInfo
forall a. a -> Eff r a
forall (f :: * -> *) a. Applicative f => a -> f a
pure VerificationTypeInfo
Raw.IntegerVariableInfo
convertVerificationTypeInfo VerificationTypeInfo
Abs.FloatVariableInfo = VerificationTypeInfo -> Eff r VerificationTypeInfo
forall a. a -> Eff r a
forall (f :: * -> *) a. Applicative f => a -> f a
pure VerificationTypeInfo
Raw.FloatVariableInfo
convertVerificationTypeInfo VerificationTypeInfo
Abs.LongVariableInfo = VerificationTypeInfo -> Eff r VerificationTypeInfo
forall a. a -> Eff r a
forall (f :: * -> *) a. Applicative f => a -> f a
pure VerificationTypeInfo
Raw.LongVariableInfo
convertVerificationTypeInfo VerificationTypeInfo
Abs.DoubleVariableInfo = VerificationTypeInfo -> Eff r VerificationTypeInfo
forall a. a -> Eff r a
forall (f :: * -> *) a. Applicative f => a -> f a
pure VerificationTypeInfo
Raw.DoubleVariableInfo
convertVerificationTypeInfo VerificationTypeInfo
Abs.NullVariableInfo = VerificationTypeInfo -> Eff r VerificationTypeInfo
forall a. a -> Eff r a
forall (f :: * -> *) a. Applicative f => a -> f a
pure VerificationTypeInfo
Raw.NullVariableInfo
convertVerificationTypeInfo VerificationTypeInfo
Abs.UninitializedThisVariableInfo = VerificationTypeInfo -> Eff r VerificationTypeInfo
forall a. a -> Eff r a
forall (f :: * -> *) a. Applicative f => a -> f a
pure VerificationTypeInfo
Raw.UninitializedThisVariableInfo
convertVerificationTypeInfo (Abs.ObjectVariableInfo ClassInfoType
x) = do
cpIndex <- ConstantPoolEntry -> Eff r U2
forall (r :: [Effect]).
(ConstantPool :> r) =>
ConstantPoolEntry -> Eff r U2
findIndexOf (ClassInfoType -> ConstantPoolEntry
CPClassEntry ClassInfoType
x)
pure $ Raw.ObjectVariableInfo (fromIntegral cpIndex)
convertVerificationTypeInfo (Abs.UninitializedVariableInfo Label
x) = do
label <- Label -> Eff r U2
forall (r :: [Effect]). CodeConverterEff r => Label -> Eff r U2
fullyResolveAbs Label
x
pure $ Raw.UninitializedVariableInfo (fromIntegral label)
convertMethod :: (ConvertEff r) => Abs.ClassFileMethod -> Eff r Raw.MethodInfo
convertMethod :: forall (r :: [Effect]).
ConvertEff r =>
ClassFileMethod -> Eff r MethodInfo
convertMethod Abs.ClassFileMethod{[MethodAccessFlag]
Text
MethodDescriptor
TypeMergingList MethodAttribute
methodAccessFlags :: [MethodAccessFlag]
methodName :: Text
methodDescriptor :: MethodDescriptor
methodAttributes :: TypeMergingList MethodAttribute
methodAttributes :: ClassFileMethod -> TypeMergingList MethodAttribute
methodDescriptor :: ClassFileMethod -> MethodDescriptor
methodName :: ClassFileMethod -> Text
methodAccessFlags :: ClassFileMethod -> [MethodAccessFlag]
..} = do
let flags :: U2
flags = [MethodAccessFlag] -> U2
forall a. ConvertAccessFlag a => [a] -> U2
accessFlagsToWord16 [MethodAccessFlag]
methodAccessFlags
nameIndex <- ConstantPoolEntry -> Eff r U2
forall (r :: [Effect]).
(ConstantPool :> r) =>
ConstantPoolEntry -> Eff r U2
findIndexOf (Text -> ConstantPoolEntry
CPUTF8Entry Text
methodName)
descriptorIndex <- findIndexOf (CPUTF8Entry (convertMethodDescriptor methodDescriptor))
attributes <- traverse convertMethodAttribute (TML.toVector methodAttributes)
pure $ Raw.MethodInfo flags (fromIntegral nameIndex) (fromIntegral descriptorIndex) attributes