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