Skip to main content

jvm_assembler/program/
types.rs

1use serde::{Deserialize, Serialize};
2
3/// JVM version information
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
5pub struct JvmVersion {
6    /// Major version number
7    pub major: u16,
8    /// Minor version number
9    pub minor: u16,
10}
11
12impl JvmVersion {
13    /// Creates a new JVM version
14    pub fn new(major: u16, minor: u16) -> Self {
15        Self { major, minor }
16    }
17
18    /// Java 1.1 (version 45.3)
19    pub fn java_1_1() -> Self {
20        Self::new(45, 3)
21    }
22
23    /// Java 1.2 (version 46.0)
24    pub fn java_1_2() -> Self {
25        Self::new(46, 0)
26    }
27
28    /// Java 1.3 (version 47.0)
29    pub fn java_1_3() -> Self {
30        Self::new(47, 0)
31    }
32
33    /// Java 1.4 (version 48.0)
34    pub fn java_1_4() -> Self {
35        Self::new(48, 0)
36    }
37
38    /// Java 5 (version 49.0)
39    pub fn java_5() -> Self {
40        Self::new(49, 0)
41    }
42
43    /// Java 6 (version 50.0)
44    pub fn java_6() -> Self {
45        Self::new(50, 0)
46    }
47
48    /// Java 7 (version 51.0)
49    pub fn java_7() -> Self {
50        Self::new(51, 0)
51    }
52
53    /// Java 8 (version 52.0)
54    pub fn java_8() -> Self {
55        Self::new(52, 0)
56    }
57
58    /// Java 9 (version 53.0)
59    pub fn java_9() -> Self {
60        Self::new(53, 0)
61    }
62
63    /// Java 10 (version 54.0)
64    pub fn java_10() -> Self {
65        Self::new(54, 0)
66    }
67
68    /// Java 11 (version 55.0)
69    pub fn java_11() -> Self {
70        Self::new(55, 0)
71    }
72
73    /// Java 12 (version 56.0)
74    pub fn java_12() -> Self {
75        Self::new(56, 0)
76    }
77
78    /// Java 13 (version 57.0)
79    pub fn java_13() -> Self {
80        Self::new(57, 0)
81    }
82
83    /// Java 14 (version 58.0)
84    pub fn java_14() -> Self {
85        Self::new(58, 0)
86    }
87
88    /// Java 15 (version 59.0)
89    pub fn java_15() -> Self {
90        Self::new(59, 0)
91    }
92
93    /// Java 16 (version 60.0)
94    pub fn java_16() -> Self {
95        Self::new(60, 0)
96    }
97
98    /// Java 17 (version 61.0)
99    pub fn java_17() -> Self {
100        Self::new(61, 0)
101    }
102
103    /// Java 18 (version 62.0)
104    pub fn java_18() -> Self {
105        Self::new(62, 0)
106    }
107
108    /// Java 19 (version 63.0)
109    pub fn java_19() -> Self {
110        Self::new(63, 0)
111    }
112
113    /// Java 20 (version 64.0)
114    pub fn java_20() -> Self {
115        Self::new(64, 0)
116    }
117
118    /// Java 21 (version 65.0)
119    pub fn java_21() -> Self {
120        Self::new(65, 0)
121    }
122
123    /// Java 22 (version 66.0)
124    pub fn java_22() -> Self {
125        Self::new(66, 0)
126    }
127}
128
129/// JVM access flags
130#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
131pub struct JvmAccessFlags {
132    /// public access
133    pub is_public: bool,
134    /// private access
135    pub is_private: bool,
136    /// protected access
137    pub is_protected: bool,
138    /// static member
139    pub is_static: bool,
140    /// final member
141    pub is_final: bool,
142    /// synchronized method
143    pub is_synchronized: bool,
144    /// volatile field
145    pub is_volatile: bool,
146    /// transient field
147    pub is_transient: bool,
148    /// native method
149    pub is_native: bool,
150    /// interface type
151    pub is_interface: bool,
152    /// abstract member
153    pub is_abstract: bool,
154    /// strictfp method
155    pub is_strict: bool,
156    /// synthetic member
157    pub is_synthetic: bool,
158    /// annotation type
159    pub is_annotation: bool,
160    /// enum type
161    pub is_enum: bool,
162    /// module type
163    pub is_module: bool,
164}
165
166impl JvmAccessFlags {
167    /// Creates a new empty access flags
168    pub fn new() -> Self {
169        Self::default()
170    }
171
172    /// Creates access flags with public set to true
173    pub fn public() -> Self {
174        let mut flags = Self::new();
175        flags.is_public = true;
176        flags
177    }
178
179    /// Creates access flags with private set to true
180    pub fn private() -> Self {
181        let mut flags = Self::new();
182        flags.is_private = true;
183        flags
184    }
185
186    /// Creates access flags for an enum type
187    pub fn enum_type() -> Self {
188        let mut flags = Self::public();
189        flags.is_enum = true;
190        flags
191    }
192
193    /// Creates access flags for an annotation type
194    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    /// Converts to JVM bytecode access flags value
202    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    /// Creates JvmAccessFlags from bytecode access flags value
258    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    /// Converts access flags to a vector of string modifiers
280    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/// JVM attribute
335#[derive(Debug, Clone)]
336pub enum JvmAttribute {
337    /// Source file name
338    SourceFile {
339        /// File name
340        filename: String,
341    },
342    /// Constant value for a field
343    ConstantValue {
344        /// The constant value entry in the pool
345        value: super::pool::JvmConstantPoolEntry,
346    },
347    /// Method code
348    Code {
349        /// Maximum stack size
350        max_stack: u16,
351        /// Maximum local variables
352        max_locals: u16,
353        /// List of instructions
354        instructions: Vec<super::instructions::JvmInstruction>,
355        /// Exception handler table
356        exception_table: Vec<super::entities::JvmExceptionHandler>,
357        /// Code attributes
358        attributes: Vec<JvmAttribute>,
359    },
360    /// Stack map table for verification
361    StackMapTable {
362        /// Stack map frames
363        frames: Vec<JvmStackMapFrame>,
364    },
365    /// Exceptions thrown by a method
366    Exceptions {
367        /// List of exception class names
368        exceptions: Vec<String>,
369    },
370    /// Inner classes information
371    InnerClasses {
372        /// List of inner classes
373        classes: Vec<JvmInnerClass>,
374    },
375    /// Enclosing method of a local or anonymous class
376    EnclosingMethod {
377        /// Class name
378        class_name: String,
379        /// Method name
380        method_name: Option<String>,
381        /// Method descriptor
382        method_descriptor: Option<String>,
383    },
384    /// Generic signature
385    Signature {
386        /// Signature string
387        signature: String,
388    },
389    /// Line number table for debugging
390    LineNumberTable {
391        /// Line number entries
392        entries: Vec<JvmLineNumberEntry>,
393    },
394    /// Local variable table for debugging
395    LocalVariableTable {
396        /// Local variable entries
397        entries: Vec<JvmLocalVariableEntry>,
398    },
399    /// Bootstrap methods for invokedynamic
400    BootstrapMethods {
401        /// Bootstrap method entries
402        methods: Vec<JvmBootstrapMethod>,
403    },
404    /// Runtime visible annotations
405    RuntimeVisibleAnnotations {
406        /// Annotations
407        annotations: Vec<JvmAnnotation>,
408    },
409    /// Runtime invisible annotations
410    RuntimeInvisibleAnnotations {
411        /// Annotations
412        annotations: Vec<JvmAnnotation>,
413    },
414    /// Method parameters information
415    MethodParameters {
416        /// Method parameters
417        parameters: Vec<JvmMethodParameter>,
418    },
419    /// Unknown attribute
420    Unknown {
421        /// Attribute name
422        name: String,
423        /// Raw attribute data
424        data: Vec<u8>,
425    },
426}
427
428/// JVM bootstrap method
429#[derive(Debug, Clone)]
430pub struct JvmBootstrapMethod {
431    /// Bootstrap method reference
432    pub method_ref: u16,
433    /// Bootstrap method arguments
434    pub arguments: Vec<u16>,
435}
436
437/// JVM inner class information
438#[derive(Debug, Clone)]
439pub struct JvmInnerClass {
440    /// Inner class name
441    pub inner_class: String,
442    /// Outer class name
443    pub outer_class: Option<String>,
444    /// Inner name
445    pub inner_name: Option<String>,
446    /// Access flags
447    pub access_flags: JvmAccessFlags,
448}
449
450/// JVM line number table entry
451#[derive(Debug, Clone)]
452pub struct JvmLineNumberEntry {
453    /// Starting PC
454    pub start_pc: u16,
455    /// Line number
456    pub line_number: u16,
457}
458
459/// JVM local variable table entry
460#[derive(Debug, Clone)]
461pub struct JvmLocalVariableEntry {
462    /// Starting PC
463    pub start_pc: u16,
464    /// Length of the range
465    pub length: u16,
466    /// Variable name
467    pub name: String,
468    /// Variable descriptor
469    pub descriptor: String,
470    /// Local variable index
471    pub index: u16,
472}
473
474/// JVM annotation
475#[derive(Debug, Clone)]
476pub struct JvmAnnotation {
477    /// Annotation type
478    pub type_name: String,
479    /// Annotation elements
480    pub elements: Vec<JvmAnnotationElement>,
481}
482
483/// JVM annotation element
484#[derive(Debug, Clone)]
485pub struct JvmAnnotationElement {
486    /// Element name
487    pub name: String,
488    /// Element value
489    pub value: JvmAnnotationValue,
490}
491
492/// JVM annotation value
493#[derive(Debug, Clone)]
494pub enum JvmAnnotationValue {
495    /// Byte value
496    Byte(i8),
497    /// Char value
498    Char(u16),
499    /// Double value
500    Double(f64),
501    /// Float value
502    Float(f32),
503    /// Int value
504    Int(i32),
505    /// Long value
506    Long(i64),
507    /// Short value
508    Short(i16),
509    /// Boolean value
510    Boolean(bool),
511    /// String value
512    String(String),
513    /// Enum value
514    Enum { class_name: String, enum_name: String },
515    /// Class value
516    Class(String),
517    /// Annotation value
518    Annotation(JvmAnnotation),
519    /// Array value
520    Array(Vec<JvmAnnotationValue>),
521}
522
523/// JVM method parameter
524#[derive(Debug, Clone)]
525pub struct JvmMethodParameter {
526    /// Parameter name
527    pub name: Option<String>,
528    /// Access flags
529    pub access_flags: u16,
530}
531
532/// JVM verification type (used in StackMapTable)
533#[derive(Debug, Clone, PartialEq, Eq, Hash)]
534pub enum JvmVerificationType {
535    /// Top type
536    Top,
537    /// Integer type
538    Integer,
539    /// Float type
540    Float,
541    /// Double type
542    Double,
543    /// Long type
544    Long,
545    /// Null type
546    Null,
547    /// Uninitialized this
548    UninitializedThis,
549    /// Object type with class name
550    Object {
551        /// Class name
552        class_name: String,
553    },
554    /// Uninitialized object at given offset
555    Uninitialized {
556        /// Bytecode offset
557        offset: u16,
558    },
559}
560
561/// JVM stack map frame
562#[derive(Debug, Clone)]
563pub enum JvmStackMapFrame {
564    /// Same frame
565    Same {
566        /// Offset delta
567        offset_delta: u16,
568    },
569    /// Same frame with 1 stack item
570    SameLocals1StackItem {
571        /// Offset delta
572        offset_delta: u16,
573        /// Stack item verification type
574        stack: JvmVerificationType,
575    },
576    /// Same frame with 1 stack item (extended offset)
577    SameLocals1StackItemExtended {
578        /// Offset delta
579        offset_delta: u16,
580        /// Stack item verification type
581        stack: JvmVerificationType,
582    },
583    /// Chop frame
584    Chop {
585        /// Offset delta
586        offset_delta: u16,
587        /// Number of locals to chop
588        k: u8,
589    },
590    /// Same frame (extended offset)
591    SameExtended {
592        /// Offset delta
593        offset_delta: u16,
594    },
595    /// Append frame
596    Append {
597        /// Offset delta
598        offset_delta: u16,
599        /// New locals
600        locals: Vec<JvmVerificationType>,
601    },
602    /// Full frame
603    Full {
604        /// Offset delta
605        offset_delta: u16,
606        /// All locals
607        locals: Vec<JvmVerificationType>,
608        /// All stack items
609        stack: Vec<JvmVerificationType>,
610    },
611}
612
613/// JVM field information
614#[derive(Debug, Clone)]
615pub struct JvmField {
616    /// Field name
617    pub name: String,
618    /// Field descriptor
619    pub descriptor: String,
620    /// Access flags
621    pub access_flags: JvmAccessFlags,
622    /// Field attributes
623    pub attributes: Vec<JvmAttribute>,
624    /// Constant value for the field (if any)
625    pub constant_value: Option<super::pool::JvmConstantPoolEntry>,
626}
627
628impl JvmField {
629    /// Creates a new JVM field
630    pub fn new(name: String, descriptor: String) -> Self {
631        Self { name, descriptor, access_flags: JvmAccessFlags::new(), attributes: Vec::new(), constant_value: None }
632    }
633}