1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
5pub struct JvmVersion {
6 pub major: u16,
8 pub minor: u16,
10}
11
12impl JvmVersion {
13 pub fn new(major: u16, minor: u16) -> Self {
15 Self { major, minor }
16 }
17
18 pub fn java_8() -> Self {
20 Self::new(52, 0)
21 }
22
23 pub fn java_11() -> Self {
25 Self::new(55, 0)
26 }
27
28 pub fn java_17() -> Self {
30 Self::new(61, 0)
31 }
32
33 pub fn java_21() -> Self {
35 Self::new(65, 0)
36 }
37}
38
39#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
41pub struct JvmAccessFlags {
42 pub is_public: bool,
44 pub is_private: bool,
46 pub is_protected: bool,
48 pub is_static: bool,
50 pub is_final: bool,
52 pub is_synchronized: bool,
54 pub is_volatile: bool,
56 pub is_transient: bool,
58 pub is_native: bool,
60 pub is_interface: bool,
62 pub is_abstract: bool,
64 pub is_strict: bool,
66 pub is_synthetic: bool,
68 pub is_annotation: bool,
70 pub is_enum: bool,
72 pub is_module: bool,
74}
75
76impl JvmAccessFlags {
77 pub fn new() -> Self {
79 Self::default()
80 }
81
82 pub fn public() -> Self {
84 let mut flags = Self::new();
85 flags.is_public = true;
86 flags
87 }
88
89 pub fn private() -> Self {
91 let mut flags = Self::new();
92 flags.is_private = true;
93 flags
94 }
95
96 pub fn to_flags(&self) -> u16 {
98 let mut flags = 0u16;
99
100 if self.is_public {
101 flags |= 0x0001;
102 }
103 if self.is_private {
104 flags |= 0x0002;
105 }
106 if self.is_protected {
107 flags |= 0x0004;
108 }
109 if self.is_static {
110 flags |= 0x0008;
111 }
112 if self.is_final {
113 flags |= 0x0010;
114 }
115 if self.is_synchronized {
116 flags |= 0x0020;
117 }
118 if self.is_volatile {
119 flags |= 0x0040;
120 }
121 if self.is_transient {
122 flags |= 0x0080;
123 }
124 if self.is_native {
125 flags |= 0x0100;
126 }
127 if self.is_interface {
128 flags |= 0x0200;
129 }
130 if self.is_abstract {
131 flags |= 0x0400;
132 }
133 if self.is_strict {
134 flags |= 0x0800;
135 }
136 if self.is_synthetic {
137 flags |= 0x1000;
138 }
139 if self.is_annotation {
140 flags |= 0x2000;
141 }
142 if self.is_enum {
143 flags |= 0x4000;
144 }
145 if self.is_module {
146 flags |= 0x8000;
147 }
148
149 flags
150 }
151
152 pub fn from_flags(flags: u16) -> Self {
154 Self {
155 is_public: (flags & 0x0001) != 0,
156 is_private: (flags & 0x0002) != 0,
157 is_protected: (flags & 0x0004) != 0,
158 is_static: (flags & 0x0008) != 0,
159 is_final: (flags & 0x0010) != 0,
160 is_synchronized: (flags & 0x0020) != 0,
161 is_volatile: (flags & 0x0040) != 0,
162 is_transient: (flags & 0x0080) != 0,
163 is_native: (flags & 0x0100) != 0,
164 is_interface: (flags & 0x0200) != 0,
165 is_abstract: (flags & 0x0400) != 0,
166 is_strict: (flags & 0x0800) != 0,
167 is_synthetic: (flags & 0x1000) != 0,
168 is_annotation: (flags & 0x2000) != 0,
169 is_enum: (flags & 0x4000) != 0,
170 is_module: (flags & 0x8000) != 0,
171 }
172 }
173
174 pub fn to_modifiers(&self) -> Vec<String> {
176 let mut modifiers = Vec::new();
177 if self.is_public {
178 modifiers.push("public".to_string());
179 }
180 if self.is_private {
181 modifiers.push("private".to_string());
182 }
183 if self.is_protected {
184 modifiers.push("protected".to_string());
185 }
186 if self.is_static {
187 modifiers.push("static".to_string());
188 }
189 if self.is_final {
190 modifiers.push("final".to_string());
191 }
192 if self.is_synchronized {
193 modifiers.push("synchronized".to_string());
194 }
195 if self.is_volatile {
196 modifiers.push("volatile".to_string());
197 }
198 if self.is_transient {
199 modifiers.push("transient".to_string());
200 }
201 if self.is_native {
202 modifiers.push("native".to_string());
203 }
204 if self.is_interface {
205 modifiers.push("interface".to_string());
206 }
207 if self.is_abstract {
208 modifiers.push("abstract".to_string());
209 }
210 if self.is_strict {
211 modifiers.push("strictfp".to_string());
212 }
213 if self.is_synthetic {
214 modifiers.push("synthetic".to_string());
215 }
216 if self.is_annotation {
217 modifiers.push("annotation".to_string());
218 }
219 if self.is_enum {
220 modifiers.push("enum".to_string());
221 }
222 if self.is_module {
223 modifiers.push("module".to_string());
224 }
225 modifiers
226 }
227}
228
229#[derive(Debug, Clone)]
231pub enum JvmAttribute {
232 SourceFile {
234 filename: String,
236 },
237 ConstantValue {
239 value: super::pool::JvmConstantPoolEntry,
241 },
242 Code {
244 max_stack: u16,
246 max_locals: u16,
248 instructions: Vec<super::instructions::JvmInstruction>,
250 exception_table: Vec<super::entities::JvmExceptionHandler>,
252 attributes: Vec<JvmAttribute>,
254 },
255 StackMapTable {
257 frames: Vec<JvmStackMapFrame>,
259 },
260 Exceptions {
262 exceptions: Vec<String>,
264 },
265 InnerClasses {
267 classes: Vec<JvmInnerClass>,
269 },
270 EnclosingMethod {
272 class_name: String,
274 method_name: Option<String>,
276 method_descriptor: Option<String>,
278 },
279 Signature {
281 signature: String,
283 },
284 LineNumberTable {
286 entries: Vec<JvmLineNumberEntry>,
288 },
289 LocalVariableTable {
291 entries: Vec<JvmLocalVariableEntry>,
293 },
294 Unknown {
296 name: String,
298 data: Vec<u8>,
300 },
301}
302
303#[derive(Debug, Clone)]
305pub struct JvmInnerClass {
306 pub inner_class: String,
308 pub outer_class: Option<String>,
310 pub inner_name: Option<String>,
312 pub access_flags: JvmAccessFlags,
314}
315
316#[derive(Debug, Clone)]
318pub struct JvmLineNumberEntry {
319 pub start_pc: u16,
321 pub line_number: u16,
323}
324
325#[derive(Debug, Clone)]
327pub struct JvmLocalVariableEntry {
328 pub start_pc: u16,
330 pub length: u16,
332 pub name: String,
334 pub descriptor: String,
336 pub index: u16,
338}
339
340#[derive(Debug, Clone, PartialEq, Eq, Hash)]
342pub enum JvmVerificationType {
343 Top,
345 Integer,
347 Float,
349 Double,
351 Long,
353 Null,
355 UninitializedThis,
357 Object {
359 class_name: String,
361 },
362 Uninitialized {
364 offset: u16,
366 },
367}
368
369#[derive(Debug, Clone)]
371pub enum JvmStackMapFrame {
372 Same {
374 offset_delta: u16,
376 },
377 SameLocals1StackItem {
379 offset_delta: u16,
381 stack: JvmVerificationType,
383 },
384 SameLocals1StackItemExtended {
386 offset_delta: u16,
388 stack: JvmVerificationType,
390 },
391 Chop {
393 offset_delta: u16,
395 k: u8,
397 },
398 SameExtended {
400 offset_delta: u16,
402 },
403 Append {
405 offset_delta: u16,
407 locals: Vec<JvmVerificationType>,
409 },
410 Full {
412 offset_delta: u16,
414 locals: Vec<JvmVerificationType>,
416 stack: Vec<JvmVerificationType>,
418 },
419}
420
421#[derive(Debug, Clone)]
423pub struct JvmField {
424 pub name: String,
426 pub descriptor: String,
428 pub access_flags: JvmAccessFlags,
430 pub attributes: Vec<JvmAttribute>,
432 pub constant_value: Option<super::pool::JvmConstantPoolEntry>,
434}
435
436impl JvmField {
437 pub fn new(name: String, descriptor: String) -> Self {
439 Self { name, descriptor, access_flags: JvmAccessFlags::new(), attributes: Vec::new(), constant_value: None }
440 }
441}