java_asm/jvms/
element.rs

1use java_asm_macro::{ReadFrom, WriteInto};
2
3// ClassFile {
4//     u4             magic;
5//     u2             minor_version;
6//     u2             major_version;
7//     u2             constant_pool_count;
8//     cp_info        constant_pool[constant_pool_count-1];
9//     u2             access_flags;
10//     u2             this_class;
11//     u2             super_class;
12//     u2             interfaces_count;
13//     u2             interfaces[interfaces_count];
14//     u2             fields_count;
15//     field_info     fields[fields_count];
16//     u2             methods_count;
17//     method_info    methods[methods_count];
18//     u2             attributes_count;
19//     attribute_info attributes[attributes_count];
20// }
21use crate::jvms::attr::Attribute;
22
23/// [JVMS4](https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html)
24#[derive(Clone, Debug, WriteInto)]
25pub struct ClassFile {
26    pub magic: u32,
27    pub minor_version: u16,
28    pub major_version: u16,
29    pub constant_pool_count: u16,
30    pub constant_pool: Vec<CPInfo>,
31    pub access_flags: u16,
32    pub this_class: u16,
33    pub super_class: u16,
34    pub interfaces_count: u16,
35    pub interfaces: Vec<u16>,
36    pub fields_count: u16,
37    pub fields: Vec<FieldInfo>,
38    pub methods_count: u16,
39    pub methods: Vec<MethodInfo>,
40    pub attributes_count: u16,
41    pub attributes: Vec<AttributeInfo>,
42}
43
44// cp_info {
45//     u1 tag;
46//     u1 info[];
47// }
48#[derive(Clone, Debug, WriteInto)]
49pub struct CPInfo {
50    pub tag: u8,
51    pub info: Const,
52}
53
54#[derive(Clone, Debug, WriteInto)]
55pub enum Const {
56    // invalid const's tag is 0
57    Invalid,
58    // CONSTANT_Class_info {
59    //     u1 tag;
60    //     u2 name_index; // index of a CONSTANT_Utf8_info structure
61    // }
62    Class { name_index: u16 },
63    // CONSTANT_Fieldref_info { (similar with Method/Interface)
64    //     u1 tag;
65    //     u2 class_index; // CONSTANT_Class_info
66    //     u2 name_and_type_index; // CONSTANT_NameAndType_info
67    // }
68    Field { class_index: u16, name_and_type_index: u16 },
69    Method { class_index: u16, name_and_type_index: u16 },
70    InterfaceMethod { class_index: u16, name_and_type_index: u16 },
71    // CONSTANT_String_info {
72    //     u1 tag;
73    //     u2 string_index; // CONSTANT_Utf8_info 
74    // }
75    String { string_index: u16 },
76    // CONSTANT_Integer_info { (similar with Float)
77    //     u1 tag;
78    //     u4 bytes;
79    // }
80    // - Stored in big-endian (high byte first) order.
81    Integer { bytes: u32 },
82    Float { bytes: u32 }, // IEEE 754 floating-point single format
83    // CONSTANT_Long_info { (similar with Double)
84    //     u1 tag;
85    //     u4 high_bytes;
86    //     u4 low_bytes;
87    // }
88    // - All 8-byte constants take up two entries in the constant_pool table of the class file. 
89    //   If a CONSTANT_Long_info or CONSTANT_Double_info structure is the item in the constant_pool table at index n, 
90    //   then the next usable item in the pool is located at index n+2. 
91    //   The constant_pool index n+1 must be valid but is considered unusable.
92    // - Stored in big-endian (high byte first) order.
93    Long { high_bytes: u32, low_bytes: u32 },
94    Double { high_bytes: u32, low_bytes: u32 }, // IEEE 754 floating-point double format
95    // CONSTANT_NameAndType_info {
96    //     u1 tag;
97    //     u2 name_index; // CONSTANT_Utf8_info 
98    //     u2 descriptor_index; // CONSTANT_Utf8_info 
99    // }
100    NameAndType { name_index: u16, descriptor_index: u16 },
101    // CONSTANT_Utf8_info {
102    //     u1 tag;
103    //     u2 length;
104    //     u1 bytes[length];
105    // }
106    Utf8 { length: u16, bytes: Vec<u8> },
107    // CONSTANT_MethodHandle_info {
108    //     u1 tag;
109    //     u1 reference_kind;
110    //     u2 reference_index; // Field/Method/Interface
111    // }
112    MethodHandle { reference_kind: u8, reference_index: u16 },
113    // CONSTANT_MethodType_info {
114    //     u1 tag;
115    //     u2 descriptor_index; // CONSTANT_Utf8_info 
116    // }
117    MethodType { descriptor_index: u16 },
118    // CONSTANT_Dynamic_info { (similar with CONSTANT_InvokeDynamic_info)
119    //     u1 tag;
120    //     u2 bootstrap_method_attr_index; // BootstrapMethods_attribute 
121    //     u2 name_and_type_index; // CONSTANT_NameAndType_info 
122    // }
123    Dynamic { bootstrap_method_attr_index: u16, name_and_type_index: u16 },
124    InvokeDynamic { bootstrap_method_attr_index: u16, name_and_type_index: u16 },
125    // CONSTANT_Module_info {
126    //     u1 tag;
127    //     u2 name_index; // CONSTANT_Utf8_info
128    // }
129    Module { name_index: u16 },
130    // CONSTANT_Package_info {
131    //     u1 tag;
132    //     u2 name_index;
133    // }
134    Package { name_index: u16 },
135}
136
137// field_info {
138//     u2             access_flags;
139//     u2             name_index; // CONSTANT_Utf8_info
140//     u2             descriptor_index; // CONSTANT_Utf8_info
141//     u2             attributes_count;
142//     attribute_info attributes[attributes_count];
143// }
144#[derive(Clone, Debug, ReadFrom, WriteInto)]
145pub struct FieldInfo {
146    pub access_flags: u16,
147    pub name_index: u16,
148    pub descriptor_index: u16,
149    pub attributes_count: u16,
150    #[index(attributes_count)]
151    pub attributes: Vec<AttributeInfo>,
152}
153
154// method_info {
155//     u2             access_flags;
156//     u2             name_index; // CONSTANT_Utf8_info
157//     u2             descriptor_index; // CONSTANT_Utf8_info
158//     u2             attributes_count;
159//     attribute_info attributes[attributes_count];
160// }
161#[derive(Clone, Debug, ReadFrom, WriteInto)]
162pub struct MethodInfo {
163    pub access_flags: u16,
164    pub name_index: u16,
165    pub descriptor_index: u16,
166    pub attributes_count: u16,
167    #[index(attributes_count)]
168    pub attributes: Vec<AttributeInfo>,
169}
170
171// attribute_info {
172//     u2 attribute_name_index; // CONSTANT_Utf8_info
173//     u4 attribute_length;
174//     u1 info[attribute_length];
175// }
176#[derive(Clone, Debug, WriteInto)]
177pub struct AttributeInfo {
178    pub attribute_name_index: u16,
179    pub attribute_length: u32,
180    pub info: Attribute,
181}
182
183