code serialization, minimal opcodes

This commit is contained in:
mrab 2024-05-07 15:46:08 +02:00
parent 068b97e0e7
commit 8b5650dd61
3 changed files with 86 additions and 14 deletions

View File

@ -15,11 +15,12 @@ expectedClass = ClassFile {
Utf8Info "java/lang/Object",
Utf8Info "<init>",
Utf8Info "()V",
ClassInfo 8,
Utf8Info "Code",
ClassInfo 9,
Utf8Info "Testklasse"
],
accessFlags = accessPublic,
thisClass = 7,
thisClass = 8,
superClass = 1,
fields = [],
methods = [],
@ -35,21 +36,22 @@ expectedClassWithFields = ClassFile {
Utf8Info "java/lang/Object",
Utf8Info "<init>",
Utf8Info "()V",
ClassInfo 8,
Utf8Info "Code",
ClassInfo 9,
Utf8Info "Testklasse",
FieldRefInfo (fromIntegral 7) (fromIntegral 10),
NameAndTypeInfo (fromIntegral 11) (fromIntegral 12),
FieldRefInfo (fromIntegral 8) (fromIntegral 11),
NameAndTypeInfo (fromIntegral 12) (fromIntegral 13),
Utf8Info "testvariable",
Utf8Info "I"
],
accessFlags = accessPublic,
thisClass = 7,
thisClass = 8,
superClass = 1,
fields = [
MemberInfo {
memberAccessFlags = accessPublic,
memberNameIndex = 11,
memberDescriptorIndex = 12,
memberNameIndex = 12,
memberDescriptorIndex = 13,
memberAttributes = []
}
],

View File

@ -22,7 +22,48 @@ data ConstantInfo = ClassInfo Word16
| Utf8Info [Char]
deriving (Show, Eq)
data Attribute = Attribute Word16 [Word8] deriving (Show, Eq)
{-
Code_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 max_stack;
u2 max_locals;
u4 code_length;
u1 code[code_length];
u2 exception_table_length;
{ u2 start_pc;
u2 end_pc;
u2 handler_pc;
u2 catch_type;
} exception_table[exception_table_length];
u2 attributes_count;
attribute_info attributes[attributes_count];
-}
--data Attribute = Attribute Word16 [Word8] deriving (Show, Eq)
data Operation = Iadd
| Isub
| Imul
| Idiv
| Return
| IReturn
| Sipush Word16
| Ldc_w Word16
| Aload Word16
| Iload Word16
| Astore Word16
| Istore Word16
| Putfield Word16
| GetField Word16
deriving (Show, Eq)
data Attribute = CodeAttribute {
attributeMaxStack :: Word16,
attributeMaxLocals :: Word16,
attributeCode :: [Operation]
} deriving (Show, Eq)
data MemberInfo = MemberInfo {
memberAccessFlags :: Word16,
@ -72,8 +113,36 @@ instance Serializable MemberInfo where
++ unpackWord16 (fromIntegral (length (memberAttributes member)))
++ concatMap serialize (memberAttributes member)
instance Serializable Operation where
serialize Iadd = [0x60]
serialize Isub = [0x64]
serialize Imul = [0x68]
serialize Idiv = [0x6C]
serialize Return = [0xB1]
serialize IReturn = [0xAC]
serialize (Sipush index) = 0x11 : unpackWord16 index
serialize (Ldc_w index) = 0x13 : unpackWord16 index
serialize (Aload index) = [0xC4, 0x19] ++ unpackWord16 index
serialize (Iload index) = [0xC4, 0x15] ++ unpackWord16 index
serialize (Astore index) = [0xC4, 0x3A] ++ unpackWord16 index
serialize (Istore index) = [0xC4, 0x36] ++ unpackWord16 index
serialize (Putfield index) = 0xB5 : unpackWord16 index
serialize (GetField index) = 0xB4 : unpackWord16 index
instance Serializable Attribute where
serialize (Attribute nameIndex bytes) = unpackWord16 nameIndex ++ unpackWord32 (fromIntegral (length bytes)) ++ bytes
serialize (CodeAttribute { attributeMaxStack = maxStack,
attributeMaxLocals = maxLocals,
attributeCode = code }) = let
assembledCode = concat (map serialize code)
in
unpackWord16 7 -- attribute_name_index
++ unpackWord32 (12 + (fromIntegral (length assembledCode))) -- attribute_length
++ unpackWord16 maxStack -- max_stack
++ unpackWord16 maxLocals -- max_locals
++ unpackWord32 (fromIntegral (length assembledCode)) -- code_length
++ assembledCode -- code
++ unpackWord16 0 -- exception_table_length
++ unpackWord16 0 -- attributes_count
instance Serializable ClassFile where
serialize classfile = unpackWord32 0xC0FEBABE -- magic

View File

@ -15,7 +15,7 @@ datatypeDescriptor :: String -> String
datatypeDescriptor "int" = "I"
datatypeDescriptor "char" = "C"
datatypeDescriptor "boolean" = "B"
datatypeDescriptor x = x
datatypeDescriptor x = "L" ++ x
classBuilder :: ClassFileBuilder Class
@ -26,13 +26,14 @@ classBuilder (Class name methods fields) _ = let
NameAndTypeInfo 5 6,
Utf8Info "java/lang/Object",
Utf8Info "<init>",
Utf8Info "()V"
Utf8Info "()V",
Utf8Info "Code"
]
nameConstants = [ClassInfo 8, Utf8Info name]
nameConstants = [ClassInfo 9, Utf8Info name]
nakedClassFile = ClassFile {
constantPool = baseConstants ++ nameConstants,
accessFlags = accessPublic,
thisClass = 7,
thisClass = 8,
superClass = 1,
fields = [],
methods = [],