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_1_1() -> Self {
20 Self::new(45, 3)
21 }
22
23 pub fn java_1_2() -> Self {
25 Self::new(46, 0)
26 }
27
28 pub fn java_1_3() -> Self {
30 Self::new(47, 0)
31 }
32
33 pub fn java_1_4() -> Self {
35 Self::new(48, 0)
36 }
37
38 pub fn java_5() -> Self {
40 Self::new(49, 0)
41 }
42
43 pub fn java_6() -> Self {
45 Self::new(50, 0)
46 }
47
48 pub fn java_7() -> Self {
50 Self::new(51, 0)
51 }
52
53 pub fn java_8() -> Self {
55 Self::new(52, 0)
56 }
57
58 pub fn java_9() -> Self {
60 Self::new(53, 0)
61 }
62
63 pub fn java_10() -> Self {
65 Self::new(54, 0)
66 }
67
68 pub fn java_11() -> Self {
70 Self::new(55, 0)
71 }
72
73 pub fn java_12() -> Self {
75 Self::new(56, 0)
76 }
77
78 pub fn java_13() -> Self {
80 Self::new(57, 0)
81 }
82
83 pub fn java_14() -> Self {
85 Self::new(58, 0)
86 }
87
88 pub fn java_15() -> Self {
90 Self::new(59, 0)
91 }
92
93 pub fn java_16() -> Self {
95 Self::new(60, 0)
96 }
97
98 pub fn java_17() -> Self {
100 Self::new(61, 0)
101 }
102
103 pub fn java_18() -> Self {
105 Self::new(62, 0)
106 }
107
108 pub fn java_19() -> Self {
110 Self::new(63, 0)
111 }
112
113 pub fn java_20() -> Self {
115 Self::new(64, 0)
116 }
117
118 pub fn java_21() -> Self {
120 Self::new(65, 0)
121 }
122
123 pub fn java_22() -> Self {
125 Self::new(66, 0)
126 }
127}
128
129#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
131pub struct JvmAccessFlags {
132 pub is_public: bool,
134 pub is_private: bool,
136 pub is_protected: bool,
138 pub is_static: bool,
140 pub is_final: bool,
142 pub is_synchronized: bool,
144 pub is_volatile: bool,
146 pub is_transient: bool,
148 pub is_native: bool,
150 pub is_interface: bool,
152 pub is_abstract: bool,
154 pub is_strict: bool,
156 pub is_synthetic: bool,
158 pub is_annotation: bool,
160 pub is_enum: bool,
162 pub is_module: bool,
164}
165
166impl JvmAccessFlags {
167 pub fn new() -> Self {
169 Self::default()
170 }
171
172 pub fn public() -> Self {
174 let mut flags = Self::new();
175 flags.is_public = true;
176 flags
177 }
178
179 pub fn private() -> Self {
181 let mut flags = Self::new();
182 flags.is_private = true;
183 flags
184 }
185
186 pub fn enum_type() -> Self {
188 let mut flags = Self::public();
189 flags.is_enum = true;
190 flags
191 }
192
193 pub fn annotation_type() -> Self {
195 let mut flags = Self::public();
196 flags.is_interface = true;
197 flags.is_annotation = true;
198 flags
199 }
200
201 pub fn to_flags(&self) -> u16 {
203 let mut flags = 0u16;
204
205 if self.is_public {
206 flags |= 0x0001;
207 }
208 if self.is_private {
209 flags |= 0x0002;
210 }
211 if self.is_protected {
212 flags |= 0x0004;
213 }
214 if self.is_static {
215 flags |= 0x0008;
216 }
217 if self.is_final {
218 flags |= 0x0010;
219 }
220 if self.is_synchronized {
221 flags |= 0x0020;
222 }
223 if self.is_volatile {
224 flags |= 0x0040;
225 }
226 if self.is_transient {
227 flags |= 0x0080;
228 }
229 if self.is_native {
230 flags |= 0x0100;
231 }
232 if self.is_interface {
233 flags |= 0x0200;
234 }
235 if self.is_abstract {
236 flags |= 0x0400;
237 }
238 if self.is_strict {
239 flags |= 0x0800;
240 }
241 if self.is_synthetic {
242 flags |= 0x1000;
243 }
244 if self.is_annotation {
245 flags |= 0x2000;
246 }
247 if self.is_enum {
248 flags |= 0x4000;
249 }
250 if self.is_module {
251 flags |= 0x8000;
252 }
253
254 flags
255 }
256
257 pub fn from_flags(flags: u16) -> Self {
259 Self {
260 is_public: (flags & 0x0001) != 0,
261 is_private: (flags & 0x0002) != 0,
262 is_protected: (flags & 0x0004) != 0,
263 is_static: (flags & 0x0008) != 0,
264 is_final: (flags & 0x0010) != 0,
265 is_synchronized: (flags & 0x0020) != 0,
266 is_volatile: (flags & 0x0040) != 0,
267 is_transient: (flags & 0x0080) != 0,
268 is_native: (flags & 0x0100) != 0,
269 is_interface: (flags & 0x0200) != 0,
270 is_abstract: (flags & 0x0400) != 0,
271 is_strict: (flags & 0x0800) != 0,
272 is_synthetic: (flags & 0x1000) != 0,
273 is_annotation: (flags & 0x2000) != 0,
274 is_enum: (flags & 0x4000) != 0,
275 is_module: (flags & 0x8000) != 0,
276 }
277 }
278
279 pub fn to_modifiers(&self) -> Vec<String> {
281 let mut modifiers = Vec::new();
282 if self.is_public {
283 modifiers.push("public".to_string());
284 }
285 if self.is_private {
286 modifiers.push("private".to_string());
287 }
288 if self.is_protected {
289 modifiers.push("protected".to_string());
290 }
291 if self.is_static {
292 modifiers.push("static".to_string());
293 }
294 if self.is_final {
295 modifiers.push("final".to_string());
296 }
297 if self.is_synchronized {
298 modifiers.push("synchronized".to_string());
299 }
300 if self.is_volatile {
301 modifiers.push("volatile".to_string());
302 }
303 if self.is_transient {
304 modifiers.push("transient".to_string());
305 }
306 if self.is_native {
307 modifiers.push("native".to_string());
308 }
309 if self.is_interface {
310 modifiers.push("interface".to_string());
311 }
312 if self.is_abstract {
313 modifiers.push("abstract".to_string());
314 }
315 if self.is_strict {
316 modifiers.push("strictfp".to_string());
317 }
318 if self.is_synthetic {
319 modifiers.push("synthetic".to_string());
320 }
321 if self.is_annotation {
322 modifiers.push("annotation".to_string());
323 }
324 if self.is_enum {
325 modifiers.push("enum".to_string());
326 }
327 if self.is_module {
328 modifiers.push("module".to_string());
329 }
330 modifiers
331 }
332}
333
334#[derive(Debug, Clone)]
336pub enum JvmAttribute {
337 SourceFile {
339 filename: String,
341 },
342 ConstantValue {
344 value: super::pool::JvmConstantPoolEntry,
346 },
347 Code {
349 max_stack: u16,
351 max_locals: u16,
353 instructions: Vec<super::instructions::JvmInstruction>,
355 exception_table: Vec<super::entities::JvmExceptionHandler>,
357 attributes: Vec<JvmAttribute>,
359 },
360 StackMapTable {
362 frames: Vec<JvmStackMapFrame>,
364 },
365 Exceptions {
367 exceptions: Vec<String>,
369 },
370 InnerClasses {
372 classes: Vec<JvmInnerClass>,
374 },
375 EnclosingMethod {
377 class_name: String,
379 method_name: Option<String>,
381 method_descriptor: Option<String>,
383 },
384 Signature {
386 signature: String,
388 },
389 LineNumberTable {
391 entries: Vec<JvmLineNumberEntry>,
393 },
394 LocalVariableTable {
396 entries: Vec<JvmLocalVariableEntry>,
398 },
399 BootstrapMethods {
401 methods: Vec<JvmBootstrapMethod>,
403 },
404 RuntimeVisibleAnnotations {
406 annotations: Vec<JvmAnnotation>,
408 },
409 RuntimeInvisibleAnnotations {
411 annotations: Vec<JvmAnnotation>,
413 },
414 MethodParameters {
416 parameters: Vec<JvmMethodParameter>,
418 },
419 Unknown {
421 name: String,
423 data: Vec<u8>,
425 },
426}
427
428#[derive(Debug, Clone)]
430pub struct JvmBootstrapMethod {
431 pub method_ref: u16,
433 pub arguments: Vec<u16>,
435}
436
437#[derive(Debug, Clone)]
439pub struct JvmInnerClass {
440 pub inner_class: String,
442 pub outer_class: Option<String>,
444 pub inner_name: Option<String>,
446 pub access_flags: JvmAccessFlags,
448}
449
450#[derive(Debug, Clone)]
452pub struct JvmLineNumberEntry {
453 pub start_pc: u16,
455 pub line_number: u16,
457}
458
459#[derive(Debug, Clone)]
461pub struct JvmLocalVariableEntry {
462 pub start_pc: u16,
464 pub length: u16,
466 pub name: String,
468 pub descriptor: String,
470 pub index: u16,
472}
473
474#[derive(Debug, Clone)]
476pub struct JvmAnnotation {
477 pub type_name: String,
479 pub elements: Vec<JvmAnnotationElement>,
481}
482
483#[derive(Debug, Clone)]
485pub struct JvmAnnotationElement {
486 pub name: String,
488 pub value: JvmAnnotationValue,
490}
491
492#[derive(Debug, Clone)]
494pub enum JvmAnnotationValue {
495 Byte(i8),
497 Char(u16),
499 Double(f64),
501 Float(f32),
503 Int(i32),
505 Long(i64),
507 Short(i16),
509 Boolean(bool),
511 String(String),
513 Enum { class_name: String, enum_name: String },
515 Class(String),
517 Annotation(JvmAnnotation),
519 Array(Vec<JvmAnnotationValue>),
521}
522
523#[derive(Debug, Clone)]
525pub struct JvmMethodParameter {
526 pub name: Option<String>,
528 pub access_flags: u16,
530}
531
532#[derive(Debug, Clone, PartialEq, Eq, Hash)]
534pub enum JvmVerificationType {
535 Top,
537 Integer,
539 Float,
541 Double,
543 Long,
545 Null,
547 UninitializedThis,
549 Object {
551 class_name: String,
553 },
554 Uninitialized {
556 offset: u16,
558 },
559}
560
561#[derive(Debug, Clone)]
563pub enum JvmStackMapFrame {
564 Same {
566 offset_delta: u16,
568 },
569 SameLocals1StackItem {
571 offset_delta: u16,
573 stack: JvmVerificationType,
575 },
576 SameLocals1StackItemExtended {
578 offset_delta: u16,
580 stack: JvmVerificationType,
582 },
583 Chop {
585 offset_delta: u16,
587 k: u8,
589 },
590 SameExtended {
592 offset_delta: u16,
594 },
595 Append {
597 offset_delta: u16,
599 locals: Vec<JvmVerificationType>,
601 },
602 Full {
604 offset_delta: u16,
606 locals: Vec<JvmVerificationType>,
608 stack: Vec<JvmVerificationType>,
610 },
611}
612
613#[derive(Debug, Clone)]
615pub struct JvmField {
616 pub name: String,
618 pub descriptor: String,
620 pub access_flags: JvmAccessFlags,
622 pub attributes: Vec<JvmAttribute>,
624 pub constant_value: Option<super::pool::JvmConstantPoolEntry>,
626}
627
628impl JvmField {
629 pub fn new(name: String, descriptor: String) -> Self {
631 Self { name, descriptor, access_flags: JvmAccessFlags::new(), attributes: Vec::new(), constant_value: None }
632 }
633}