1#![doc = include_str!("readme.md")]
2use gaia_types::{GaiaError, Result};
3use serde::{Deserialize, Serialize};
4
5use std::collections::HashMap;
6
7#[derive(Debug, Clone)]
9pub struct JvmProgram {
10 pub name: String,
12 pub access_flags: JvmAccessFlags,
14 pub super_class: Option<String>,
16 pub interfaces: Vec<String>,
18 pub fields: Vec<JvmField>,
20 pub methods: Vec<JvmMethod>,
22 pub attributes: Vec<JvmAttribute>,
24 pub constant_pool: JvmConstantPool,
26 pub version: JvmVersion,
28 pub source_file: Option<String>,
30}
31
32#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
34pub struct JvmVersion {
35 pub major: u16,
37 pub minor: u16,
39}
40
41#[derive(Debug, Clone)]
43pub struct JvmAccessFlags {
44 pub is_public: bool,
46 pub is_final: bool,
48 pub is_super: bool,
50 pub is_interface: bool,
52 pub is_abstract: bool,
54 pub is_synthetic: bool,
56 pub is_annotation: bool,
58 pub is_enum: bool,
60 pub is_static: bool,
62 pub is_private: bool,
64 pub is_protected: bool,
66 pub is_volatile: bool,
68 pub is_transient: bool,
70 pub is_synchronized: bool,
72 pub is_native: bool,
74 pub is_bridge: bool,
76 pub is_varargs: bool,
78 pub is_strict: bool,
80}
81
82impl JvmAccessFlags {
83 pub const PUBLIC: JvmAccessFlags = JvmAccessFlags {
85 is_public: true,
86 is_final: false,
87 is_super: false,
88 is_interface: false,
89 is_abstract: false,
90 is_synthetic: false,
91 is_annotation: false,
92 is_enum: false,
93 is_static: false,
94 is_private: false,
95 is_protected: false,
96 is_volatile: false,
97 is_transient: false,
98 is_synchronized: false,
99 is_native: false,
100 is_bridge: false,
101 is_varargs: false,
102 is_strict: false,
103 };
104
105 pub const PRIVATE: JvmAccessFlags = JvmAccessFlags {
106 is_public: false,
107 is_final: false,
108 is_super: false,
109 is_interface: false,
110 is_abstract: false,
111 is_synthetic: false,
112 is_annotation: false,
113 is_enum: false,
114 is_static: false,
115 is_private: true,
116 is_protected: false,
117 is_volatile: false,
118 is_transient: false,
119 is_synchronized: false,
120 is_native: false,
121 is_bridge: false,
122 is_varargs: false,
123 is_strict: false,
124 };
125
126 pub const PROTECTED: JvmAccessFlags = JvmAccessFlags {
127 is_public: false,
128 is_final: false,
129 is_super: false,
130 is_interface: false,
131 is_abstract: false,
132 is_synthetic: false,
133 is_annotation: false,
134 is_enum: false,
135 is_static: false,
136 is_private: false,
137 is_protected: true,
138 is_volatile: false,
139 is_transient: false,
140 is_synchronized: false,
141 is_native: false,
142 is_bridge: false,
143 is_varargs: false,
144 is_strict: false,
145 };
146
147 pub const STATIC: JvmAccessFlags = JvmAccessFlags {
148 is_public: false,
149 is_final: false,
150 is_super: false,
151 is_interface: false,
152 is_abstract: false,
153 is_synthetic: false,
154 is_annotation: false,
155 is_enum: false,
156 is_static: true,
157 is_private: false,
158 is_protected: false,
159 is_volatile: false,
160 is_transient: false,
161 is_synchronized: false,
162 is_native: false,
163 is_bridge: false,
164 is_varargs: false,
165 is_strict: false,
166 };
167
168 pub const FINAL: JvmAccessFlags = JvmAccessFlags {
169 is_public: false,
170 is_final: true,
171 is_super: false,
172 is_interface: false,
173 is_abstract: false,
174 is_synthetic: false,
175 is_annotation: false,
176 is_enum: false,
177 is_static: false,
178 is_private: false,
179 is_protected: false,
180 is_volatile: false,
181 is_transient: false,
182 is_synchronized: false,
183 is_native: false,
184 is_bridge: false,
185 is_varargs: false,
186 is_strict: false,
187 };
188
189 pub const ABSTRACT: JvmAccessFlags = JvmAccessFlags {
190 is_public: false,
191 is_final: false,
192 is_super: false,
193 is_interface: false,
194 is_abstract: true,
195 is_synthetic: false,
196 is_annotation: false,
197 is_enum: false,
198 is_static: false,
199 is_private: false,
200 is_protected: false,
201 is_volatile: false,
202 is_transient: false,
203 is_synchronized: false,
204 is_native: false,
205 is_bridge: false,
206 is_varargs: false,
207 is_strict: false,
208 };
209
210 pub const VOLATILE: JvmAccessFlags = JvmAccessFlags {
211 is_public: false,
212 is_final: false,
213 is_super: false,
214 is_interface: false,
215 is_abstract: false,
216 is_synthetic: false,
217 is_annotation: false,
218 is_enum: false,
219 is_static: false,
220 is_private: false,
221 is_protected: false,
222 is_volatile: true,
223 is_transient: false,
224 is_synchronized: false,
225 is_native: false,
226 is_bridge: false,
227 is_varargs: false,
228 is_strict: false,
229 };
230
231 pub const TRANSIENT: JvmAccessFlags = JvmAccessFlags {
232 is_public: false,
233 is_final: false,
234 is_super: false,
235 is_interface: false,
236 is_abstract: false,
237 is_synthetic: false,
238 is_annotation: false,
239 is_enum: false,
240 is_static: false,
241 is_private: false,
242 is_protected: false,
243 is_volatile: false,
244 is_transient: true,
245 is_synchronized: false,
246 is_native: false,
247 is_bridge: false,
248 is_varargs: false,
249 is_strict: false,
250 };
251
252 pub const SYNCHRONIZED: JvmAccessFlags = JvmAccessFlags {
253 is_public: false,
254 is_final: false,
255 is_super: false,
256 is_interface: false,
257 is_abstract: false,
258 is_synthetic: false,
259 is_annotation: false,
260 is_enum: false,
261 is_static: false,
262 is_private: false,
263 is_protected: false,
264 is_volatile: false,
265 is_transient: false,
266 is_synchronized: true,
267 is_native: false,
268 is_bridge: false,
269 is_varargs: false,
270 is_strict: false,
271 };
272
273 pub const NATIVE: JvmAccessFlags = JvmAccessFlags {
274 is_public: false,
275 is_final: false,
276 is_super: false,
277 is_interface: false,
278 is_abstract: false,
279 is_synthetic: false,
280 is_annotation: false,
281 is_enum: false,
282 is_static: false,
283 is_private: false,
284 is_protected: false,
285 is_volatile: false,
286 is_transient: false,
287 is_synchronized: false,
288 is_native: true,
289 is_bridge: false,
290 is_varargs: false,
291 is_strict: false,
292 };
293
294 pub const INTERFACE: JvmAccessFlags = JvmAccessFlags {
295 is_public: false,
296 is_final: false,
297 is_super: false,
298 is_interface: true,
299 is_abstract: false,
300 is_synthetic: false,
301 is_annotation: false,
302 is_enum: false,
303 is_static: false,
304 is_private: false,
305 is_protected: false,
306 is_volatile: false,
307 is_transient: false,
308 is_synchronized: false,
309 is_native: false,
310 is_bridge: false,
311 is_varargs: false,
312 is_strict: false,
313 };
314
315 pub const SYNTHETIC: JvmAccessFlags = JvmAccessFlags {
316 is_public: false,
317 is_final: false,
318 is_super: false,
319 is_interface: false,
320 is_abstract: false,
321 is_synthetic: true,
322 is_annotation: false,
323 is_enum: false,
324 is_static: false,
325 is_private: false,
326 is_protected: false,
327 is_volatile: false,
328 is_transient: false,
329 is_synchronized: false,
330 is_native: false,
331 is_bridge: false,
332 is_varargs: false,
333 is_strict: false,
334 };
335
336 pub const ANNOTATION: JvmAccessFlags = JvmAccessFlags {
337 is_public: false,
338 is_final: false,
339 is_super: false,
340 is_interface: false,
341 is_abstract: false,
342 is_synthetic: false,
343 is_annotation: true,
344 is_enum: false,
345 is_static: false,
346 is_private: false,
347 is_protected: false,
348 is_volatile: false,
349 is_transient: false,
350 is_synchronized: false,
351 is_native: false,
352 is_bridge: false,
353 is_varargs: false,
354 is_strict: false,
355 };
356
357 pub const ENUM: JvmAccessFlags = JvmAccessFlags {
358 is_public: false,
359 is_final: false,
360 is_super: false,
361 is_interface: false,
362 is_abstract: false,
363 is_synthetic: false,
364 is_annotation: false,
365 is_enum: true,
366 is_static: false,
367 is_private: false,
368 is_protected: false,
369 is_volatile: false,
370 is_transient: false,
371 is_synchronized: false,
372 is_native: false,
373 is_bridge: false,
374 is_varargs: false,
375 is_strict: false,
376 };
377
378 pub const BRIDGE: JvmAccessFlags = JvmAccessFlags {
379 is_public: false,
380 is_final: false,
381 is_super: false,
382 is_interface: false,
383 is_abstract: false,
384 is_synthetic: false,
385 is_annotation: false,
386 is_enum: false,
387 is_static: false,
388 is_private: false,
389 is_protected: false,
390 is_volatile: false,
391 is_transient: false,
392 is_synchronized: false,
393 is_native: false,
394 is_bridge: true,
395 is_varargs: false,
396 is_strict: false,
397 };
398
399 pub const VARARGS: JvmAccessFlags = JvmAccessFlags {
400 is_public: false,
401 is_final: false,
402 is_super: false,
403 is_interface: false,
404 is_abstract: false,
405 is_synthetic: false,
406 is_annotation: false,
407 is_enum: false,
408 is_static: false,
409 is_private: false,
410 is_protected: false,
411 is_volatile: false,
412 is_transient: false,
413 is_synchronized: false,
414 is_native: false,
415 is_bridge: false,
416 is_varargs: true,
417 is_strict: false,
418 };
419
420 pub const STRICT: JvmAccessFlags = JvmAccessFlags {
421 is_public: false,
422 is_final: false,
423 is_super: false,
424 is_interface: false,
425 is_abstract: false,
426 is_synthetic: false,
427 is_annotation: false,
428 is_enum: false,
429 is_static: false,
430 is_private: false,
431 is_protected: false,
432 is_volatile: false,
433 is_transient: false,
434 is_synchronized: false,
435 is_native: false,
436 is_bridge: false,
437 is_varargs: false,
438 is_strict: true,
439 };
440}
441
442use std::ops::{BitOr, BitOrAssign};
443
444impl BitOr for JvmAccessFlags {
445 type Output = Self;
446
447 fn bitor(self, rhs: Self) -> Self {
448 let mut res = self;
449 res |= rhs;
450 res
451 }
452}
453
454impl BitOrAssign for JvmAccessFlags {
455 fn bitor_assign(&mut self, rhs: Self) {
456 self.is_public |= rhs.is_public;
457 self.is_final |= rhs.is_final;
458 self.is_super |= rhs.is_super;
459 self.is_interface |= rhs.is_interface;
460 self.is_abstract |= rhs.is_abstract;
461 self.is_synthetic |= rhs.is_synthetic;
462 self.is_synchronized |= rhs.is_synchronized;
463 self.is_native |= rhs.is_native;
464 self.is_bridge |= rhs.is_bridge;
465 self.is_varargs |= rhs.is_varargs;
466 self.is_strict |= rhs.is_strict;
467 self.is_annotation |= rhs.is_annotation;
468 self.is_enum |= rhs.is_enum;
469 self.is_static |= rhs.is_static;
470 self.is_private |= rhs.is_private;
471 self.is_protected |= rhs.is_protected;
472 self.is_volatile |= rhs.is_volatile;
473 self.is_transient |= rhs.is_transient;
474 }
475}
476
477#[derive(Debug, Clone)]
479pub struct JvmConstantPool {
480 pub symbol_table: HashMap<String, u16>,
482 pub entries: Vec<JvmConstantPoolEntry>,
484}
485
486#[derive(Debug, Clone, PartialEq)]
488pub enum JvmConstantPoolEntry {
489 Nop,
490 Utf8 {
491 value: String,
492 },
493 Integer {
495 value: i32,
496 },
497 Float {
499 value: f32,
500 },
501 Long {
503 value: i64,
504 },
505 Double {
507 value: f64,
508 },
509 Class {
511 name: String,
512 },
513 String {
515 value: String,
516 },
517 Fieldref {
519 class_name: String,
520 name: String,
521 descriptor: String,
522 },
523 Methodref {
525 class_name: String,
526 name: String,
527 descriptor: String,
528 },
529 InterfaceMethodref {
531 class_name: String,
532 name: String,
533 descriptor: String,
534 },
535 NameAndType {
537 name: String,
538 descriptor: String,
539 },
540}
541
542#[derive(Debug, Clone)]
544pub struct JvmMethod {
545 pub name: String,
547 pub descriptor: String,
549 pub access_flags: JvmAccessFlags,
551 pub instructions: Vec<JvmInstruction>,
553 pub max_stack: u16,
555 pub max_locals: u16,
557 pub exception_handlers: Vec<JvmExceptionHandler>,
559 pub exceptions: Vec<String>,
561 pub attributes: Vec<JvmAttribute>,
563}
564
565#[derive(Debug, Clone)]
567pub struct JvmField {
568 pub name: String,
570 pub descriptor: String,
572 pub access_flags: JvmAccessFlags,
574 pub constant_value: Option<JvmConstantPoolEntry>,
576 pub attributes: Vec<JvmAttribute>,
578}
579
580#[derive(Debug, Clone, PartialEq)]
582pub enum JvmInstruction {
583 Nop,
585 AconstNull,
586 IconstM1,
587 Iconst0,
588 Iconst1,
589 Iconst2,
590 Iconst3,
591 Iconst4,
592 Iconst5,
593 Lconst0,
594 Lconst1,
595 Fconst0,
596 Fconst1,
597 Fconst2,
598 Dconst0,
599 Dconst1,
600
601 Bipush { value: i8 },
603 Sipush { value: i16 },
604
605 Ldc { symbol: String },
607 LdcW { symbol: String },
608 Ldc2W { symbol: String },
609
610 Iload { index: u16 },
612 Lload { index: u16 },
613 Fload { index: u16 },
614 Dload { index: u16 },
615 Aload { index: u16 },
616 Iload0,
617 Iload1,
618 Iload2,
619 Iload3,
620 Lload0,
621 Lload1,
622 Lload2,
623 Lload3,
624 Fload0,
625 Fload1,
626 Fload2,
627 Fload3,
628 Dload0,
629 Dload1,
630 Dload2,
631 Dload3,
632 Aload0,
633 Aload1,
634 Aload2,
635 Aload3,
636
637 Istore { index: u16 },
639 Lstore { index: u16 },
640 Fstore { index: u16 },
641 Dstore { index: u16 },
642 Astore { index: u16 },
643 Istore0,
644 Istore1,
645 Istore2,
646 Istore3,
647 Lstore0,
648 Lstore1,
649 Lstore2,
650 Lstore3,
651 Fstore0,
652 Fstore1,
653 Fstore2,
654 Fstore3,
655 Dstore0,
656 Dstore1,
657 Dstore2,
658 Dstore3,
659 Astore0,
660 Astore1,
661 Astore2,
662 Astore3,
663
664 Pop,
666 Pop2,
667 Dup,
668 DupX1,
669 DupX2,
670 Dup2,
671 Dup2X1,
672 Dup2X2,
673 Swap,
674
675 Iadd,
677 Ladd,
678 Fadd,
679 Dadd,
680 Isub,
681 Lsub,
682 Fsub,
683 Dsub,
684 Imul,
685 Lmul,
686 Fmul,
687 Dmul,
688 Idiv,
689 Ldiv,
690 Fdiv,
691 Ddiv,
692 Irem,
693 Lrem,
694 Frem,
695 Drem,
696 Ineg,
697 Lneg,
698 Fneg,
699 Dneg,
700
701 Ishl,
703 Lshl,
704 Ishr,
705 Lshr,
706 Iushr,
707 Lushr,
708 Iand,
709 Land,
710 Ior,
711 Lor,
712 Ixor,
713 Lxor,
714
715 Lcmp,
717 Fcmpl,
718 Fcmpg,
719 Dcmpl,
720 Dcmpg,
721
722 Ifeq { target: String },
724 Ifne { target: String },
725 Iflt { target: String },
726 Ifge { target: String },
727 Ifgt { target: String },
728 Ifle { target: String },
729 IfIcmpeq { target: String },
730 IfIcmpne { target: String },
731 IfIcmplt { target: String },
732 IfIcmpge { target: String },
733 IfIcmpgt { target: String },
734 IfIcmple { target: String },
735 IfAcmpeq { target: String },
736 IfAcmpne { target: String },
737 Goto { target: String },
738 Jsr { target: String },
739 Ret { index: u16 },
740
741 Ireturn,
743 Lreturn,
744 Freturn,
745 Dreturn,
746 Areturn,
747 Return,
748
749 Getstatic { class_name: String, field_name: String, descriptor: String },
751 Putstatic { class_name: String, field_name: String, descriptor: String },
752 Getfield { class_name: String, field_name: String, descriptor: String },
753 Putfield { class_name: String, field_name: String, descriptor: String },
754
755 Invokevirtual { class_name: String, method_name: String, descriptor: String },
757 Invokespecial { class_name: String, method_name: String, descriptor: String },
758 Invokestatic { class_name: String, method_name: String, descriptor: String },
759 Invokeinterface { class_name: String, method_name: String, descriptor: String },
760 Invokedynamic { class_name: String, method_name: String, descriptor: String },
761
762 New { class_name: String },
764 Newarray { atype: u8 },
765 Anewarray { class_name: String },
766 Arraylength,
767 Athrow,
768 Checkcast { class_name: String },
769 Instanceof { class_name: String },
770 Monitorenter,
771 Monitorexit,
772
773 Iaload,
775 Laload,
776 Faload,
777 Daload,
778 Aaload,
779 Baload,
780 Saload,
781 Iastore,
782 Lastore,
783 Fastore,
784 Dastore,
785 Aastore,
786 Bastore,
787 Sastore,
788
789 Wide,
791 Label { name: String },
792 Multianewarray { class_name: String, dimensions: u8 },
793 Ifnull { target: String },
794 Ifnonnull { target: String },
795 GotoW { target: String },
796 JsrW { target: String },
797 Iinc { index: u16, increment: i16 },
798 Tableswitch { low: i32, high: i32, default: String, targets: Vec<String> },
799 Lookupswitch { default: String, pairs: Vec<(i32, String)> },
800}
801
802impl JvmInstruction {
803 pub fn to_byte(&self) -> u8 {
805 match self {
806 JvmInstruction::Nop => 0x00,
807 JvmInstruction::AconstNull => 0x01,
808 JvmInstruction::IconstM1 => 0x02,
809 JvmInstruction::Iconst0 => 0x03,
810 JvmInstruction::Iconst1 => 0x04,
811 JvmInstruction::Iconst2 => 0x05,
812 JvmInstruction::Iconst3 => 0x06,
813 JvmInstruction::Iconst4 => 0x07,
814 JvmInstruction::Iconst5 => 0x08,
815 JvmInstruction::Lconst0 => 0x09,
816 JvmInstruction::Lconst1 => 0x0A,
817 JvmInstruction::Fconst0 => 0x0B,
818 JvmInstruction::Fconst1 => 0x0C,
819 JvmInstruction::Fconst2 => 0x0D,
820 JvmInstruction::Dconst0 => 0x0E,
821 JvmInstruction::Dconst1 => 0x0F,
822 JvmInstruction::Bipush { .. } => 0x10,
823 JvmInstruction::Sipush { .. } => 0x11,
824 JvmInstruction::Ldc { .. } => 0x12,
825 JvmInstruction::LdcW { .. } => 0x13,
826 JvmInstruction::Ldc2W { .. } => 0x14,
827 JvmInstruction::Iload { .. } => 0x15,
828 JvmInstruction::Lload { .. } => 0x16,
829 JvmInstruction::Fload { .. } => 0x17,
830 JvmInstruction::Dload { .. } => 0x18,
831 JvmInstruction::Aload { .. } => 0x19,
832 JvmInstruction::Iload0 => 0x1A,
833 JvmInstruction::Iload1 => 0x1B,
834 JvmInstruction::Iload2 => 0x1C,
835 JvmInstruction::Iload3 => 0x1D,
836 JvmInstruction::Lload0 => 0x1E,
837 JvmInstruction::Lload1 => 0x1F,
838 JvmInstruction::Lload2 => 0x20,
839 JvmInstruction::Lload3 => 0x21,
840 JvmInstruction::Fload0 => 0x22,
841 JvmInstruction::Fload1 => 0x23,
842 JvmInstruction::Fload2 => 0x24,
843 JvmInstruction::Fload3 => 0x25,
844 JvmInstruction::Dload0 => 0x26,
845 JvmInstruction::Dload1 => 0x27,
846 JvmInstruction::Dload2 => 0x28,
847 JvmInstruction::Dload3 => 0x29,
848 JvmInstruction::Aload0 => 0x2A,
849 JvmInstruction::Aload1 => 0x2B,
850 JvmInstruction::Aload2 => 0x2C,
851 JvmInstruction::Aload3 => 0x2D,
852 JvmInstruction::Istore { .. } => 0x36,
853 JvmInstruction::Lstore { .. } => 0x37,
854 JvmInstruction::Fstore { .. } => 0x38,
855 JvmInstruction::Dstore { .. } => 0x39,
856 JvmInstruction::Astore { .. } => 0x3A,
857 JvmInstruction::Istore0 => 0x3B,
858 JvmInstruction::Istore1 => 0x3C,
859 JvmInstruction::Istore2 => 0x3D,
860 JvmInstruction::Istore3 => 0x3E,
861 JvmInstruction::Lstore0 => 0x3F,
862 JvmInstruction::Lstore1 => 0x40,
863 JvmInstruction::Lstore2 => 0x41,
864 JvmInstruction::Lstore3 => 0x42,
865 JvmInstruction::Fstore0 => 0x43,
866 JvmInstruction::Fstore1 => 0x44,
867 JvmInstruction::Fstore2 => 0x45,
868 JvmInstruction::Fstore3 => 0x46,
869 JvmInstruction::Dstore0 => 0x47,
870 JvmInstruction::Dstore1 => 0x48,
871 JvmInstruction::Dstore2 => 0x49,
872 JvmInstruction::Dstore3 => 0x4A,
873 JvmInstruction::Astore0 => 0x4B,
874 JvmInstruction::Astore1 => 0x4C,
875 JvmInstruction::Astore2 => 0x4D,
876 JvmInstruction::Astore3 => 0x4E,
877 JvmInstruction::Pop => 0x57,
878 JvmInstruction::Pop2 => 0x58,
879 JvmInstruction::Dup => 0x59,
880 JvmInstruction::DupX1 => 0x5A,
881 JvmInstruction::DupX2 => 0x5B,
882 JvmInstruction::Dup2 => 0x5C,
883 JvmInstruction::Dup2X1 => 0x5D,
884 JvmInstruction::Dup2X2 => 0x5E,
885 JvmInstruction::Swap => 0x5F,
886 JvmInstruction::Iadd => 0x60,
887 JvmInstruction::Ladd => 0x61,
888 JvmInstruction::Fadd => 0x62,
889 JvmInstruction::Dadd => 0x63,
890 JvmInstruction::Isub => 0x64,
891 JvmInstruction::Lsub => 0x65,
892 JvmInstruction::Fsub => 0x66,
893 JvmInstruction::Dsub => 0x67,
894 JvmInstruction::Imul => 0x68,
895 JvmInstruction::Lmul => 0x69,
896 JvmInstruction::Fmul => 0x6A,
897 JvmInstruction::Dmul => 0x6B,
898 JvmInstruction::Idiv => 0x6C,
899 JvmInstruction::Ldiv => 0x6D,
900 JvmInstruction::Fdiv => 0x6E,
901 JvmInstruction::Ddiv => 0x6F,
902 JvmInstruction::Irem => 0x70,
903 JvmInstruction::Lrem => 0x71,
904 JvmInstruction::Frem => 0x72,
905 JvmInstruction::Drem => 0x73,
906 JvmInstruction::Ineg => 0x74,
907 JvmInstruction::Lneg => 0x75,
908 JvmInstruction::Fneg => 0x76,
909 JvmInstruction::Dneg => 0x77,
910 JvmInstruction::Ishl => 0x78,
911 JvmInstruction::Lshl => 0x79,
912 JvmInstruction::Ishr => 0x7A,
913 JvmInstruction::Lshr => 0x7B,
914 JvmInstruction::Iushr => 0x7C,
915 JvmInstruction::Lushr => 0x7D,
916 JvmInstruction::Iand => 0x7E,
917 JvmInstruction::Land => 0x7F,
918 JvmInstruction::Ior => 0x80,
919 JvmInstruction::Lor => 0x81,
920 JvmInstruction::Ixor => 0x82,
921 JvmInstruction::Lxor => 0x83,
922 JvmInstruction::Lcmp => 0x94,
923 JvmInstruction::Fcmpl => 0x95,
924 JvmInstruction::Fcmpg => 0x96,
925 JvmInstruction::Dcmpl => 0x97,
926 JvmInstruction::Dcmpg => 0x98,
927 JvmInstruction::Ifeq { .. } => 0x99,
928 JvmInstruction::Ifne { .. } => 0x9A,
929 JvmInstruction::Iflt { .. } => 0x9B,
930 JvmInstruction::Ifge { .. } => 0x9C,
931 JvmInstruction::Ifgt { .. } => 0x9D,
932 JvmInstruction::Ifle { .. } => 0x9E,
933 JvmInstruction::IfIcmpeq { .. } => 0x9F,
934 JvmInstruction::IfIcmpne { .. } => 0xA0,
935 JvmInstruction::IfIcmplt { .. } => 0xA1,
936 JvmInstruction::IfIcmpge { .. } => 0xA2,
937 JvmInstruction::IfIcmpgt { .. } => 0xA3,
938 JvmInstruction::IfIcmple { .. } => 0xA4,
939 JvmInstruction::IfAcmpeq { .. } => 0xA5,
940 JvmInstruction::IfAcmpne { .. } => 0xA6,
941 JvmInstruction::Goto { .. } => 0xA7,
942 JvmInstruction::Jsr { .. } => 0xA8,
943 JvmInstruction::Ret { .. } => 0xA9,
944 JvmInstruction::Ireturn => 0xAC,
945 JvmInstruction::Lreturn => 0xAD,
946 JvmInstruction::Freturn => 0xAE,
947 JvmInstruction::Dreturn => 0xAF,
948 JvmInstruction::Areturn => 0xB0,
949 JvmInstruction::Return => 0xB1,
950 JvmInstruction::Getstatic { .. } => 0xB2,
951 JvmInstruction::Putstatic { .. } => 0xB3,
952 JvmInstruction::Getfield { .. } => 0xB4,
953 JvmInstruction::Putfield { .. } => 0xB5,
954 JvmInstruction::Invokevirtual { .. } => 0xB6,
955 JvmInstruction::Invokespecial { .. } => 0xB7,
956 JvmInstruction::Invokestatic { .. } => 0xB8,
957 JvmInstruction::Invokeinterface { .. } => 0xB9,
958 JvmInstruction::Invokedynamic { .. } => 0xBA,
959 JvmInstruction::New { .. } => 0xBB,
960 JvmInstruction::Newarray { .. } => 0xBC,
961 JvmInstruction::Anewarray { .. } => 0xBD,
962 JvmInstruction::Arraylength => 0xBE,
963 JvmInstruction::Athrow => 0xBF,
964 JvmInstruction::Checkcast { .. } => 0xC0,
965 JvmInstruction::Instanceof { .. } => 0xC1,
966 JvmInstruction::Monitorenter => 0xC2,
967 JvmInstruction::Monitorexit => 0xC3,
968 JvmInstruction::Iaload => 0x2E,
969 JvmInstruction::Laload => 0x2F,
970 JvmInstruction::Faload => 0x30,
971 JvmInstruction::Daload => 0x31,
972 JvmInstruction::Aaload => 0x32,
973 JvmInstruction::Baload => 0x33,
974 JvmInstruction::Saload => 0x34,
975 JvmInstruction::Iastore => 0x4F,
976 JvmInstruction::Lastore => 0x50,
977 JvmInstruction::Fastore => 0x51,
978 JvmInstruction::Dastore => 0x52,
979 JvmInstruction::Aastore => 0x53,
980 JvmInstruction::Bastore => 0x54,
981 JvmInstruction::Sastore => 0x55,
982 JvmInstruction::Wide => 0xC4,
983 JvmInstruction::Label { .. } => 0x00, JvmInstruction::Multianewarray { .. } => 0xC5,
985 JvmInstruction::Ifnull { .. } => 0xC6,
986 JvmInstruction::Ifnonnull { .. } => 0xC7,
987 JvmInstruction::GotoW { .. } => 0xC8,
988 JvmInstruction::JsrW { .. } => 0xC9,
989 JvmInstruction::Iinc { .. } => 0x84,
990 JvmInstruction::Tableswitch { .. } => 0xAA,
991 JvmInstruction::Lookupswitch { .. } => 0xAB,
992 }
993 }
994}
995
996#[derive(Debug, Clone)]
998pub struct JvmExceptionHandler {
999 pub start_label: String,
1001 pub end_label: String,
1003 pub handler_label: String,
1005 pub catch_type: Option<String>,
1007}
1008
1009#[derive(Debug, Clone)]
1011pub struct RawExceptionHandler {
1012 pub start_pc: u16,
1014 pub end_pc: u16,
1016 pub handler_pc: u16,
1018 pub catch_type_index: u16,
1020}
1021
1022#[derive(Debug, Clone)]
1024pub enum JvmAttribute {
1025 SourceFile { filename: String },
1027 Code {
1029 max_stack: u16,
1030 max_locals: u16,
1031 code: Vec<u8>,
1032 exception_table: Vec<RawExceptionHandler>,
1033 attributes: Vec<JvmAttribute>,
1034 },
1035 ConstantValue { value: JvmConstantPoolEntry },
1037 Signature { signature: String },
1039 Exceptions { exceptions: Vec<String> },
1041 LineNumberTable { entries: Vec<(u16, u16)> },
1043 LocalVariableTable { entries: Vec<JvmLocalVariable> },
1045 InnerClasses { classes: Vec<JvmInnerClass> },
1047 EnclosingMethod { class_name: String, method_name: Option<String>, method_descriptor: Option<String> },
1049 StackMapTable { frames: Vec<JvmStackMapFrame> },
1051 Unknown { name: String, data: Vec<u8> },
1053}
1054
1055#[derive(Debug, Clone)]
1057pub enum JvmStackMapFrame {
1058 Same { offset_delta: u16 },
1059 SameLocals1StackItem { offset_delta: u16, stack: JvmVerificationType },
1060 SameLocals1StackItemExtended { offset_delta: u16, stack: JvmVerificationType },
1061 Chop { offset_delta: u16, k: u8 },
1062 SameExtended { offset_delta: u16 },
1063 Append { offset_delta: u16, locals: Vec<JvmVerificationType> },
1064 Full { offset_delta: u16, locals: Vec<JvmVerificationType>, stack: Vec<JvmVerificationType> },
1065}
1066
1067#[derive(Debug, Clone, PartialEq, Eq)]
1069pub enum JvmVerificationType {
1070 Top,
1071 Integer,
1072 Float,
1073 Long,
1074 Double,
1075 Null,
1076 UninitializedThis,
1077 Object { class_name: String },
1078 Uninitialized { offset: u16 },
1079}
1080
1081#[derive(Debug, Clone)]
1083pub struct JvmInnerClass {
1084 pub inner_class: String,
1086 pub outer_class: Option<String>,
1088 pub inner_name: Option<String>,
1090 pub access_flags: JvmAccessFlags,
1092}
1093
1094#[derive(Debug, Clone)]
1096pub struct JvmLocalVariable {
1097 pub start_pc: u16,
1099 pub length: u16,
1101 pub name: String,
1103 pub descriptor: String,
1105 pub index: u16,
1107}
1108
1109impl JvmProgram {
1110 pub fn new(name: String) -> Self {
1112 Self {
1113 name,
1114 access_flags: JvmAccessFlags::default(),
1115 super_class: None,
1116 interfaces: Vec::new(),
1117 fields: Vec::new(),
1118 methods: Vec::new(),
1119 attributes: Vec::new(),
1120 constant_pool: JvmConstantPool::new(),
1121 version: JvmVersion { major: 61, minor: 0 }, source_file: None,
1123 }
1124 }
1125
1126 pub fn add_method(&mut self, method: JvmMethod) {
1128 self.methods.push(method);
1129 }
1130
1131 pub fn add_field(&mut self, field: JvmField) {
1133 self.fields.push(field);
1134 }
1135
1136 pub fn set_source_file(&mut self, filename: String) {
1138 self.source_file = Some(filename.clone());
1139 self.attributes.push(JvmAttribute::SourceFile { filename });
1140 }
1141
1142 pub fn validate(&self) -> Result<()> {
1144 if self.name.is_empty() {
1146 return Err(GaiaError::custom_error("Class name cannot be empty".to_string()));
1147 }
1148
1149 for method in &self.methods {
1151 method.validate()?;
1152 }
1153
1154 for field in &self.fields {
1156 field.validate()?;
1157 }
1158
1159 Ok(())
1160 }
1161}
1162
1163impl JvmConstantPool {
1164 pub fn new() -> Self {
1166 Self { symbol_table: HashMap::new(), entries: Vec::new() }
1167 }
1168
1169 pub fn add_entry(&mut self, entry: JvmConstantPoolEntry) -> u16 {
1171 for (index, existing_entry) in self.entries.iter().enumerate() {
1173 if existing_entry == &entry {
1174 return (index + 1) as u16; }
1176 }
1177
1178 let index = (self.entries.len() + 1) as u16;
1179 self.entries.push(entry);
1180 index
1181 }
1182
1183 pub fn find_symbol(&self, symbol: &str) -> Option<u16> {
1185 self.symbol_table.get(symbol).copied()
1186 }
1187
1188 pub fn add_symbol(&mut self, symbol: String, index: u16) {
1190 self.symbol_table.insert(symbol, index);
1191 }
1192
1193 pub fn add_utf8(&mut self, value: String) -> u16 {
1194 self.add_entry(JvmConstantPoolEntry::Utf8 { value })
1195 }
1196
1197 pub fn add_class(&mut self, name: String) -> u16 {
1198 let name_index = self.add_utf8(name);
1199 self.add_entry(JvmConstantPoolEntry::Class { name: name_index.to_string() })
1200 }
1201
1202 pub fn add_string(&mut self, value: String) -> u16 {
1203 let utf8_index = self.add_utf8(value);
1204 self.add_entry(JvmConstantPoolEntry::String { value: utf8_index.to_string() })
1205 }
1206
1207 pub fn add_name_and_type(&mut self, name: String, descriptor: String) -> u16 {
1208 let name_index = self.add_utf8(name);
1209 let descriptor_index = self.add_utf8(descriptor);
1210 self.add_entry(JvmConstantPoolEntry::NameAndType {
1211 name: name_index.to_string(),
1212 descriptor: descriptor_index.to_string(),
1213 })
1214 }
1215
1216 pub fn add_methodref(&mut self, class_name: String, name: String, descriptor: String) -> u16 {
1217 let class_index = self.add_class(class_name);
1218 let name_and_type_index = self.add_name_and_type(name, descriptor);
1219 self.add_entry(JvmConstantPoolEntry::Methodref {
1220 class_name: class_index.to_string(),
1221 name: name_and_type_index.to_string(),
1222 descriptor: "".to_string(),
1223 })
1224 }
1225
1226 pub fn add_fieldref(&mut self, class_name: String, name: String, descriptor: String) -> u16 {
1227 let class_index = self.add_class(class_name);
1228 let name_and_type_index = self.add_name_and_type(name, descriptor);
1229 self.add_entry(JvmConstantPoolEntry::Fieldref {
1230 class_name: class_index.to_string(),
1231 name: name_and_type_index.to_string(),
1232 descriptor: "".to_string(),
1233 })
1234 }
1235}
1236
1237impl JvmMethod {
1238 pub fn new(name: String, descriptor: String) -> Self {
1240 Self {
1241 name,
1242 descriptor,
1243 access_flags: JvmAccessFlags::default(),
1244 instructions: Vec::new(),
1245 max_stack: 0,
1246 max_locals: 0,
1247 exception_handlers: Vec::new(),
1248 exceptions: Vec::new(),
1249 attributes: Vec::new(),
1250 }
1251 }
1252
1253 pub fn add_exception_handler(&mut self, handler: JvmExceptionHandler) {
1255 self.exception_handlers.push(handler);
1256 }
1257
1258 pub fn add_exception(&mut self, exception: String) {
1260 self.exceptions.push(exception);
1261 }
1262
1263 pub fn with_access_flags(mut self, access_flags: JvmAccessFlags) -> Self {
1265 self.access_flags = access_flags;
1266 self
1267 }
1268
1269 pub fn with_public(mut self) -> Self {
1271 self.access_flags |= JvmAccessFlags::PUBLIC;
1272 self
1273 }
1274
1275 pub fn with_private(mut self) -> Self {
1277 self.access_flags |= JvmAccessFlags::PRIVATE;
1278 self
1279 }
1280
1281 pub fn with_protected(mut self) -> Self {
1283 self.access_flags |= JvmAccessFlags::PROTECTED;
1284 self
1285 }
1286
1287 pub fn with_static(mut self) -> Self {
1289 self.access_flags |= JvmAccessFlags::STATIC;
1290 self
1291 }
1292
1293 pub fn with_final(mut self) -> Self {
1295 self.access_flags |= JvmAccessFlags::FINAL;
1296 self
1297 }
1298
1299 pub fn with_abstract(mut self) -> Self {
1301 self.access_flags |= JvmAccessFlags::ABSTRACT;
1302 self
1303 }
1304
1305 pub fn with_max_stack(mut self, max_stack: u16) -> Self {
1307 self.max_stack = max_stack;
1308 self
1309 }
1310
1311 pub fn with_max_locals(mut self, max_locals: u16) -> Self {
1313 self.max_locals = max_locals;
1314 self
1315 }
1316
1317 pub fn with_instruction(mut self, instruction: JvmInstruction) -> Self {
1319 self.instructions.push(instruction);
1320 self
1321 }
1322
1323 pub fn with_instructions(mut self, instructions: Vec<JvmInstruction>) -> Self {
1325 self.instructions.extend(instructions);
1326 self
1327 }
1328
1329 pub fn with_exception_handler(mut self, handler: JvmExceptionHandler) -> Self {
1331 self.exception_handlers.push(handler);
1332 self
1333 }
1334
1335 pub fn with_attribute(mut self, attribute: JvmAttribute) -> Self {
1337 self.attributes.push(attribute);
1338 self
1339 }
1340
1341 pub fn with_attributes(mut self, attributes: Vec<JvmAttribute>) -> Self {
1343 self.attributes.extend(attributes);
1344 self
1345 }
1346
1347 pub fn add_instruction(&mut self, instruction: JvmInstruction) {
1349 self.instructions.push(instruction);
1350 }
1351
1352 pub fn validate(&self) -> Result<()> {
1354 if self.name.is_empty() {
1355 return Err(GaiaError::custom_error("Method name cannot be empty".to_string()));
1356 }
1357 if self.descriptor.is_empty() {
1358 return Err(GaiaError::custom_error("Method descriptor cannot be empty".to_string()));
1359 }
1360 Ok(())
1361 }
1362}
1363
1364impl JvmField {
1365 pub fn new(name: String, descriptor: String) -> Self {
1367 Self { name, descriptor, access_flags: JvmAccessFlags::default(), constant_value: None, attributes: Vec::new() }
1368 }
1369
1370 pub fn with_access_flags(mut self, access_flags: JvmAccessFlags) -> Self {
1372 self.access_flags = access_flags;
1373 self
1374 }
1375
1376 pub fn with_public(mut self) -> Self {
1378 self.access_flags |= JvmAccessFlags::PUBLIC;
1379 self
1380 }
1381
1382 pub fn with_private(mut self) -> Self {
1384 self.access_flags |= JvmAccessFlags::PRIVATE;
1385 self
1386 }
1387
1388 pub fn with_protected(mut self) -> Self {
1390 self.access_flags |= JvmAccessFlags::PROTECTED;
1391 self
1392 }
1393
1394 pub fn with_static(mut self) -> Self {
1396 self.access_flags |= JvmAccessFlags::STATIC;
1397 self
1398 }
1399
1400 pub fn with_final(mut self) -> Self {
1402 self.access_flags |= JvmAccessFlags::FINAL;
1403 self
1404 }
1405
1406 pub fn with_volatile(mut self) -> Self {
1408 self.access_flags |= JvmAccessFlags::VOLATILE;
1409 self
1410 }
1411
1412 pub fn with_transient(mut self) -> Self {
1414 self.access_flags |= JvmAccessFlags::TRANSIENT;
1415 self
1416 }
1417
1418 pub fn with_constant_value(mut self, value: JvmConstantPoolEntry) -> Self {
1420 self.constant_value = Some(value);
1421 self
1422 }
1423
1424 pub fn with_attribute(mut self, attribute: JvmAttribute) -> Self {
1426 self.attributes.push(attribute);
1427 self
1428 }
1429
1430 pub fn with_attributes(mut self, attributes: Vec<JvmAttribute>) -> Self {
1432 self.attributes.extend(attributes);
1433 self
1434 }
1435
1436 pub fn validate(&self) -> Result<()> {
1438 if self.name.is_empty() {
1439 return Err(GaiaError::custom_error("Field name cannot be empty".to_string()));
1440 }
1441 if self.descriptor.is_empty() {
1442 return Err(GaiaError::custom_error("Field descriptor cannot be empty".to_string()));
1443 }
1444 Ok(())
1445 }
1446}
1447
1448impl Default for JvmAccessFlags {
1449 fn default() -> Self {
1450 Self {
1451 is_public: false,
1452 is_final: false,
1453 is_super: true, is_interface: false,
1455 is_abstract: false,
1456 is_synthetic: false,
1457 is_annotation: false,
1458 is_enum: false,
1459 is_static: false,
1460 is_private: false,
1461 is_protected: false,
1462 is_volatile: false,
1463 is_transient: false,
1464 is_synchronized: false,
1465 is_native: false,
1466 is_bridge: false,
1467 is_varargs: false,
1468 is_strict: false,
1469 }
1470 }
1471}
1472
1473impl JvmAccessFlags {
1474 pub fn from_modifiers(modifiers: &[String]) -> Self {
1476 let mut flags = Self::default();
1477
1478 for modifier in modifiers {
1479 match modifier.as_str() {
1480 "public" => flags.is_public = true,
1481 "private" => flags.is_private = true,
1482 "protected" => flags.is_protected = true,
1483 "static" => flags.is_static = true,
1484 "final" => flags.is_final = true,
1485 "super" => flags.is_super = true,
1486 "interface" => flags.is_interface = true,
1487 "abstract" => flags.is_abstract = true,
1488 "synthetic" => flags.is_synthetic = true,
1489 "annotation" => flags.is_annotation = true,
1490 "enum" => flags.is_enum = true,
1491 "volatile" => flags.is_volatile = true,
1492 "transient" => flags.is_transient = true,
1493 "native" => flags.is_native = true,
1494 "synchronized" => flags.is_synchronized = true,
1495 "bridge" => flags.is_bridge = true,
1496 "varargs" => flags.is_varargs = true,
1497 "strict" => flags.is_strict = true,
1498 _ => {} }
1500 }
1501
1502 flags
1503 }
1504
1505 pub fn from_flags(flags: u16) -> Self {
1507 Self {
1508 is_public: (flags & 0x0001) != 0,
1509 is_private: (flags & 0x0002) != 0,
1510 is_protected: (flags & 0x0004) != 0,
1511 is_static: (flags & 0x0008) != 0,
1512 is_final: (flags & 0x0010) != 0,
1513 is_super: (flags & 0x0020) != 0,
1514 is_synchronized: (flags & 0x0020) != 0,
1515 is_volatile: (flags & 0x0040) != 0,
1516 is_bridge: (flags & 0x0040) != 0,
1517 is_transient: (flags & 0x0080) != 0,
1518 is_varargs: (flags & 0x0080) != 0,
1519 is_native: (flags & 0x0100) != 0,
1520 is_interface: (flags & 0x0200) != 0,
1521 is_abstract: (flags & 0x0400) != 0,
1522 is_strict: (flags & 0x0800) != 0,
1523 is_synthetic: (flags & 0x1000) != 0,
1524 is_annotation: (flags & 0x2000) != 0,
1525 is_enum: (flags & 0x4000) != 0,
1526 }
1527 }
1528
1529 pub fn to_modifiers(&self) -> Vec<String> {
1531 let mut modifiers = Vec::new();
1532 if self.is_public {
1533 modifiers.push("public".to_string());
1534 }
1535 if self.is_private {
1536 modifiers.push("private".to_string());
1537 }
1538 if self.is_protected {
1539 modifiers.push("protected".to_string());
1540 }
1541 if self.is_static {
1542 modifiers.push("static".to_string());
1543 }
1544 if self.is_final {
1545 modifiers.push("final".to_string());
1546 }
1547 if self.is_super {
1548 modifiers.push("super".to_string());
1549 }
1550 if self.is_interface {
1551 modifiers.push("interface".to_string());
1552 }
1553 if self.is_abstract {
1554 modifiers.push("abstract".to_string());
1555 }
1556 if self.is_synthetic {
1557 modifiers.push("synthetic".to_string());
1558 }
1559 if self.is_annotation {
1560 modifiers.push("annotation".to_string());
1561 }
1562 if self.is_enum {
1563 modifiers.push("enum".to_string());
1564 }
1565 if self.is_volatile {
1566 modifiers.push("volatile".to_string());
1567 }
1568 if self.is_transient {
1569 modifiers.push("transient".to_string());
1570 }
1571 if self.is_synchronized {
1572 modifiers.push("synchronized".to_string());
1573 }
1574 if self.is_native {
1575 modifiers.push("native".to_string());
1576 }
1577 if self.is_bridge {
1578 modifiers.push("bridge".to_string());
1579 }
1580 if self.is_varargs {
1581 modifiers.push("varargs".to_string());
1582 }
1583 if self.is_strict {
1584 modifiers.push("strict".to_string());
1585 }
1586 modifiers
1587 }
1588
1589 pub fn to_flags(&self) -> u16 {
1591 let mut flags = 0u16;
1592
1593 if self.is_public {
1594 flags |= 0x0001;
1595 }
1596 if self.is_private {
1597 flags |= 0x0002;
1598 }
1599 if self.is_protected {
1600 flags |= 0x0004;
1601 }
1602 if self.is_static {
1603 flags |= 0x0008;
1604 }
1605 if self.is_final {
1606 flags |= 0x0010;
1607 }
1608 if self.is_super || self.is_synchronized {
1609 flags |= 0x0020;
1610 }
1611 if self.is_volatile || self.is_bridge {
1612 flags |= 0x0040;
1613 }
1614 if self.is_transient || self.is_varargs {
1615 flags |= 0x0080;
1616 }
1617 if self.is_native {
1618 flags |= 0x0100;
1619 }
1620 if self.is_interface {
1621 flags |= 0x0200;
1622 }
1623 if self.is_abstract {
1624 flags |= 0x0400;
1625 }
1626 if self.is_strict {
1627 flags |= 0x0800;
1628 }
1629 if self.is_synthetic {
1630 flags |= 0x1000;
1631 }
1632 if self.is_annotation {
1633 flags |= 0x2000;
1634 }
1635 if self.is_enum {
1636 flags |= 0x4000;
1637 }
1638 flags
1639 }
1640}
1641
1642pub use JvmConstantPoolEntry as ConstantPoolEntry;
1644
1645#[derive(Debug, Clone, PartialEq)]
1647pub struct JvmInstructionCompat {
1648 pub opcode: u8,
1650 pub operands: Vec<u8>,
1652 pub metadata: Option<String>,
1654}
1655
1656impl JvmInstructionCompat {
1657 pub fn new(opcode: u8, operands: Vec<u8>) -> Self {
1659 Self { opcode, operands, metadata: None }
1660 }
1661
1662 pub fn with_metadata(opcode: u8, operands: Vec<u8>, metadata: String) -> Self {
1664 Self { opcode, operands, metadata: Some(metadata) }
1665 }
1666
1667 pub fn to_bytes(&self) -> Vec<u8> {
1669 let mut bytes = vec![self.opcode];
1670 bytes.extend_from_slice(&self.operands);
1671 bytes
1672 }
1673
1674 pub fn len(&self) -> usize {
1676 1 + self.operands.len()
1677 }
1678
1679 pub fn is_empty(&self) -> bool {
1681 false }
1683}
1684
1685#[derive(Debug, Clone)]
1687pub struct JvmClassCompat {
1688 pub magic: u32,
1690 pub minor_version: u16,
1692 pub major_version: u16,
1694 pub constant_pool: Vec<ConstantPoolEntry>,
1696 pub access_flags: u16,
1698 pub this_class: u16,
1700 pub super_class: u16,
1702 pub interfaces: Vec<u16>,
1704 pub fields: Vec<JvmFieldCompat>,
1706 pub methods: Vec<JvmMethodCompat>,
1708}
1709
1710impl Default for JvmClassCompat {
1711 fn default() -> Self {
1712 Self {
1713 magic: 0xCAFEBABE,
1714 minor_version: 0,
1715 major_version: 65, constant_pool: Vec::new(),
1717 access_flags: 0x0021, this_class: 0,
1719 super_class: 0,
1720 interfaces: Vec::new(),
1721 fields: Vec::new(),
1722 methods: Vec::new(),
1723 }
1724 }
1725}
1726
1727#[derive(Debug, Clone)]
1729pub struct JvmMethodCompat {
1730 pub access_flags: u16,
1732 pub name_index: u16,
1734 pub descriptor_index: u16,
1736 pub instructions: Vec<JvmInstructionCompat>,
1738 pub max_stack: u16,
1740 pub max_locals: u16,
1742}
1743
1744impl JvmMethodCompat {
1745 pub fn new(name_index: u16, descriptor_index: u16) -> Self {
1747 Self {
1748 access_flags: 0x0001, name_index,
1750 descriptor_index,
1751 instructions: Vec::new(),
1752 max_stack: 2,
1753 max_locals: 1,
1754 }
1755 }
1756
1757 pub fn add_instruction(&mut self, instruction: JvmInstructionCompat) {
1759 self.instructions.push(instruction);
1760 }
1761
1762 pub fn code_length(&self) -> u32 {
1764 self.instructions.iter().map(|i| i.len() as u32).sum()
1765 }
1766}
1767
1768#[derive(Debug, Clone)]
1770pub struct JvmFieldCompat {
1771 pub access_flags: u16,
1773 pub name_index: u16,
1775 pub descriptor_index: u16,
1777}
1778
1779pub mod opcodes {
1781 pub const ACONST_NULL: u8 = 0x01;
1782 pub const ICONST_M1: u8 = 0x02;
1783 pub const ICONST_0: u8 = 0x03;
1784 pub const ICONST_1: u8 = 0x04;
1785 pub const ICONST_2: u8 = 0x05;
1786 pub const ICONST_3: u8 = 0x06;
1787 pub const ICONST_4: u8 = 0x07;
1788 pub const ICONST_5: u8 = 0x08;
1789 pub const LCONST_0: u8 = 0x09;
1790 pub const LCONST_1: u8 = 0x0A;
1791 pub const FCONST_0: u8 = 0x0B;
1792 pub const FCONST_1: u8 = 0x0C;
1793 pub const FCONST_2: u8 = 0x0D;
1794 pub const DCONST_0: u8 = 0x0E;
1795 pub const DCONST_1: u8 = 0x0F;
1796 pub const BIPUSH: u8 = 0x10;
1797 pub const SIPUSH: u8 = 0x11;
1798 pub const LDC: u8 = 0x12;
1799 pub const LDC_W: u8 = 0x13;
1800 pub const LDC2_W: u8 = 0x14;
1801
1802 pub const ILOAD: u8 = 0x15;
1804 pub const LLOAD: u8 = 0x16;
1805 pub const FLOAD: u8 = 0x17;
1806 pub const DLOAD: u8 = 0x18;
1807 pub const ALOAD: u8 = 0x19;
1808 pub const ILOAD_0: u8 = 0x1A;
1809 pub const ILOAD_1: u8 = 0x1B;
1810 pub const ILOAD_2: u8 = 0x1C;
1811 pub const ILOAD_3: u8 = 0x1D;
1812 pub const LLOAD_0: u8 = 0x1E;
1813 pub const LLOAD_1: u8 = 0x1F;
1814 pub const LLOAD_2: u8 = 0x20;
1815 pub const LLOAD_3: u8 = 0x21;
1816 pub const FLOAD_0: u8 = 0x22;
1817 pub const FLOAD_1: u8 = 0x23;
1818 pub const FLOAD_2: u8 = 0x24;
1819 pub const FLOAD_3: u8 = 0x25;
1820 pub const DLOAD_0: u8 = 0x26;
1821 pub const DLOAD_1: u8 = 0x27;
1822 pub const DLOAD_2: u8 = 0x28;
1823 pub const DLOAD_3: u8 = 0x29;
1824 pub const ALOAD_0: u8 = 0x2A;
1825 pub const ALOAD_1: u8 = 0x2B;
1826 pub const ALOAD_2: u8 = 0x2C;
1827 pub const ALOAD_3: u8 = 0x2D;
1828
1829 pub const ISTORE: u8 = 0x36;
1831 pub const LSTORE: u8 = 0x37;
1832 pub const FSTORE: u8 = 0x38;
1833 pub const DSTORE: u8 = 0x39;
1834 pub const ASTORE: u8 = 0x3A;
1835 pub const ISTORE_0: u8 = 0x3B;
1836 pub const ISTORE_1: u8 = 0x3C;
1837 pub const ISTORE_2: u8 = 0x3D;
1838 pub const ISTORE_3: u8 = 0x3E;
1839 pub const LSTORE_0: u8 = 0x3F;
1840 pub const LSTORE_1: u8 = 0x40;
1841 pub const LSTORE_2: u8 = 0x41;
1842 pub const LSTORE_3: u8 = 0x42;
1843 pub const FSTORE_0: u8 = 0x43;
1844 pub const FSTORE_1: u8 = 0x44;
1845 pub const FSTORE_2: u8 = 0x45;
1846 pub const FSTORE_3: u8 = 0x46;
1847 pub const DSTORE_0: u8 = 0x47;
1848 pub const DSTORE_1: u8 = 0x48;
1849 pub const DSTORE_2: u8 = 0x49;
1850 pub const DSTORE_3: u8 = 0x4A;
1851 pub const ASTORE_0: u8 = 0x4B;
1852 pub const ASTORE_1: u8 = 0x4C;
1853 pub const ASTORE_2: u8 = 0x4D;
1854 pub const ASTORE_3: u8 = 0x4E;
1855
1856 pub const POP: u8 = 0x57;
1858 pub const POP2: u8 = 0x58;
1859 pub const DUP: u8 = 0x59;
1860 pub const DUP_X1: u8 = 0x5A;
1861 pub const DUP_X2: u8 = 0x5B;
1862 pub const DUP2: u8 = 0x5C;
1863 pub const DUP2_X1: u8 = 0x5D;
1864 pub const DUP2_X2: u8 = 0x5E;
1865 pub const SWAP: u8 = 0x5F;
1866
1867 pub const IADD: u8 = 0x60;
1869 pub const LADD: u8 = 0x61;
1870 pub const FADD: u8 = 0x62;
1871 pub const DADD: u8 = 0x63;
1872 pub const ISUB: u8 = 0x64;
1873 pub const LSUB: u8 = 0x65;
1874 pub const FSUB: u8 = 0x66;
1875 pub const DSUB: u8 = 0x67;
1876 pub const IMUL: u8 = 0x68;
1877 pub const LMUL: u8 = 0x69;
1878 pub const FMUL: u8 = 0x6A;
1879 pub const DMUL: u8 = 0x6B;
1880 pub const IDIV: u8 = 0x6C;
1881 pub const LDIV: u8 = 0x6D;
1882 pub const FDIV: u8 = 0x6E;
1883 pub const DDIV: u8 = 0x6F;
1884
1885 pub const INVOKEVIRTUAL: u8 = 0xB6;
1887 pub const INVOKESPECIAL: u8 = 0xB7;
1888 pub const INVOKESTATIC: u8 = 0xB8;
1889 pub const INVOKEINTERFACE: u8 = 0xB9;
1890
1891 pub const IRETURN: u8 = 0xAC;
1893 pub const LRETURN: u8 = 0xAD;
1894 pub const FRETURN: u8 = 0xAE;
1895 pub const DRETURN: u8 = 0xAF;
1896 pub const ARETURN: u8 = 0xB0;
1897 pub const RETURN: u8 = 0xB1;
1898
1899 pub const GETSTATIC: u8 = 0xB2;
1901 pub const PUTSTATIC: u8 = 0xB3;
1902 pub const GETFIELD: u8 = 0xB4;
1903 pub const PUTFIELD: u8 = 0xB5;
1904
1905 pub const NOP: u8 = 0x00;
1907}