jbcrs_basic/tree.rs
1//! The tree package provides the basic structure of a basic class file
2
3use std::collections::BTreeMap;
4
5/// The first 4 bytes of every java class file
6pub const MAGIC: &[u8] = &[0xCA, 0xFE, 0xBA, 0xBE];
7
8/// A java class file.
9#[derive(Debug)]
10pub struct Class {
11 pub minor_version: u16,
12 pub major_version: u16,
13
14 pub access_flags: AccessFlags,
15 pub name: u16,
16 pub super_name: u16,
17 pub interfaces: Vec<u16>,
18
19 pub fields: Vec<Field>,
20 pub methods: Vec<Method>,
21
22 pub attributes: Vec<Attribute>,
23}
24
25/// A field.
26#[derive(Debug)]
27pub struct Field {
28 pub access_flags: AccessFlags,
29 pub name: u16,
30 pub desc: u16,
31 pub attributes: Vec<Attribute>,
32}
33
34/// A method.
35#[derive(Debug)]
36pub struct Method {
37 pub access_flags: AccessFlags,
38 pub name: u16,
39 pub desc: u16,
40 pub attributes: Vec<Attribute>,
41}
42
43/// An Attribute.
44#[derive(Debug)]
45pub enum Attribute {
46 AnnotationDefault(ElementValue),
47 BootstrapMethods(Vec<BootstrapMethod>),
48 Code {
49 max_stack: u16,
50 max_locals: u16,
51 instructions: Vec<Option<Instruction>>,
52 exceptions: Vec<Exception>,
53 attributes: Vec<Attribute>,
54 },
55 ConstantValue(u16),
56 Deprecated,
57 EnclosingMethod {
58 class_index: u16,
59 method_index: u16,
60 },
61 Exceptions(Vec<u16>),
62 InnerClasses(Vec<InnerClass>),
63 LineNumberTable(Vec<LineNumber>),
64 LocalVariableTable(Vec<LocalVariable>),
65 LocalVariableTypeTable(Vec<LocalVariableType>),
66 MethodParameters(Vec<MethodParameter>),
67 Module {
68 name: u16,
69 flags: AccessFlags,
70 version: u16,
71
72 requires: Vec<Requirement>,
73 exports: Vec<Export>,
74 opens: Vec<Opening>,
75 uses: Vec<u16>,
76 provides: Vec<Provider>,
77 },
78 ModuleMainClass(u16),
79 ModulePackages(Vec<u16>),
80 RuntimeVisibleAnnotations(Vec<Annotation>),
81 RuntimeInvisibleAnnotations(Vec<Annotation>),
82 RuntimeVisibleParameterAnnotations(Vec<Vec<Annotation>>),
83 RuntimeInvisibleParameterAnnotations(Vec<Vec<Annotation>>),
84 RuntimeVisibleTypeAnnotations(Vec<TypeAnnotation>),
85 RuntimeInvisibleTypeAnnotations(Vec<TypeAnnotation>),
86 Signature(u16),
87 Synthetic,
88 SourceFile(u16),
89 SourceDebugExtension(String),
90 StackMapTable(Vec<StackMapFrame>),
91 Unknown(u16, Vec<u8>),
92}
93
94bitflags! {
95 /// The access flags of a part of the class
96 pub struct AccessFlags: u16 {
97 const PUBLIC = 0b0000_0000_0000_0001;
98 const PRIVATE = 0b0000_0000_0000_0010;
99 const PROTECTED = 0b0000_0000_0000_0100;
100 const STATIC = 0b0000_0000_0000_1000;
101 const FINAL = 0b0000_0000_0001_0000;
102 const SUPER = 0b0000_0000_0010_0000;
103 const SYNCHRONIZED = 0b0000_0000_0010_0000;
104 const VOLATILE = 0b0000_0000_0100_0000;
105 const BRIDGE = 0b0000_0000_0100_0000;
106 const STATIC_PHASE = 0b0000_0000_0100_0000;
107 const TRANSIENT = 0b0000_0000_1000_0000;
108 const VARARGS = 0b0000_0000_1000_0000;
109 const NATIVE = 0b0000_0001_0000_0000;
110 const INTERFACE = 0b0000_0010_0000_0000;
111 const ABSTRACT = 0b0000_0100_0000_0000;
112 const STRICT = 0b0000_1000_0000_0000;
113 const SYNTHETIC = 0b0001_0000_0000_0000;
114 const ANNOTATION = 0b0010_0000_0000_0000;
115 const ENUM = 0b0100_0000_0000_0000;
116 const MODULE = 0b1000_0000_0000_0001;
117 const MANDATED = 0b1000_0000_0000_0001;
118 }
119}
120
121#[derive(Debug)]
122pub struct Exception {
123 pub start: u16,
124 pub end: u16,
125 pub handler: u16,
126 pub catch_type: u16,
127}
128
129#[derive(Debug)]
130pub struct BootstrapMethod {
131 pub method_ref: u16,
132 pub arguments: Vec<u16>,
133}
134
135#[derive(Debug)]
136pub struct LineNumber {
137 pub start: u16,
138 pub line_number: u16,
139}
140
141#[derive(Debug)]
142pub enum Instruction {
143 /// No operation
144 NOP,
145
146 /// Pushes null on the stack
147 AConstNull,
148
149 /// Pushes the int -1 on the stack
150 IConstM1,
151
152 /// Pushes the int 0 on the stack
153 IConst0,
154 /// Pushes the int 1 on the stack
155 IConst1,
156 /// Pushes the int 2 on the stack
157 IConst2,
158 /// Pushes the int 3 on the stack
159 IConst3,
160 /// Pushes the int 4 on the stack
161 IConst4,
162 /// Pushes the int 5 on the stack
163 IConst5,
164
165 /// Pushes the long 0 on the stack
166 LConst0,
167 /// Pushes the long 1 on the stack
168 LConst1,
169
170 /// Pushes the float 0 on the stack
171 FConst0,
172 /// Pushes the float 1 on the stack
173 FConst1,
174 /// Pushes the float 2 on the stack
175 FConst2,
176
177 /// Pushes the double 0 on the stack
178 DConst0,
179 /// Pushes the double 1 on the stack
180 DConst1,
181
182 /// Pushes a byte on the stack
183 BIPush(i8),
184 /// Pushes a short on the stack
185 SIPush(i16),
186
187 /// Pushes a constant from the constant pool on the stack
188 LDC(u16),
189
190 /// Pushes the int at a specific local variable index on the stack
191 ILoad(u16),
192 /// Pushes the long at a specific local variable index on the stack
193 LLoad(u16),
194 /// Pushes the float at a specific local variable index on the stack
195 FLoad(u16),
196 /// Pushes the double at a specific local variable index on the stack
197 DLoad(u16),
198 /// Pushes the reference at a specific local variable index on the stack
199 ALoad(u16),
200
201 /// Pushes the int at local variable index 0 on the stack
202 ILoad0,
203 /// Pushes the int at local variable index 1 on the stack
204 ILoad1,
205 /// Pushes the int at local variable index 2 on the stack
206 ILoad2,
207 /// Pushes the int at local variable index 3 on the stack
208 ILoad3,
209
210 /// Pushes the long at local variable index 0 on the stack
211 LLoad0,
212 /// Pushes the long at local variable index 1 on the stack
213 LLoad1,
214 /// Pushes the long at local variable index 2 on the stack
215 LLoad2,
216 /// Pushes the long at local variable index 3 on the stack
217 LLoad3,
218
219 /// Pushes the float at local variable index 0 on the stack
220 FLoad0,
221 /// Pushes the float at local variable index 1 on the stack
222 FLoad1,
223 /// Pushes the float at local variable index 2 on the stack
224 FLoad2,
225 /// Pushes the float at local variable index 3 on the stack
226 FLoad3,
227
228 /// Pushes the double at local variable index 0 on the stack
229 DLoad0,
230 /// Pushes the double at local variable index 1 on the stack
231 DLoad1,
232 /// Pushes the double at local variable index 2 on the stack
233 DLoad2,
234 /// Pushes the double at local variable index 3 on the stack
235 DLoad3,
236
237 /// Pushes the reference at local variable index 0 on the stack
238 ALoad0,
239 /// Pushes the reference at local variable index 1 on the stack
240 ALoad1,
241 /// Pushes the reference at local variable index 2 on the stack
242 ALoad2,
243 /// Pushes the reference at local variable index 3 on the stack
244 ALoad3,
245
246 /// Pushes the value from an int array, which is popped from the stack,
247 /// at an index, which is popped from the stack as well, on the stack.
248 IALoad,
249 /// Pushes the value from an long array, which is popped from the stack,
250 /// at an index, which is popped from the stack as well, on the stack.
251 LALoad,
252 /// Pushes the value from an float array, which is popped from the stack,
253 /// at an index, which is popped from the stack as well, on the stack.
254 FALoad,
255 /// Pushes the value from an double array, which is popped from the stack,
256 /// at an index, which is popped from the stack as well, on the stack.
257 DALoad,
258 /// Pushes the value from an reference array, which is popped from the stack,
259 /// at an index, which is popped from the stack as well, on the stack.
260 AALoad,
261 /// Pushes the value from an byte array, which is popped from the stack,
262 /// at an index, which is popped from the stack as well, on the stack.
263 BALoad,
264 /// Pushes the value from an char array, which is popped from the stack,
265 /// at an index, which is popped from the stack as well, on the stack.
266 CALoad,
267 /// Pushes the value from an short array, which is popped from the stack,
268 /// at an index, which is popped from the stack as well, on the stack.
269 SALoad,
270
271 IStore(u16),
272 LStore(u16),
273 FStore(u16),
274 DStore(u16),
275 AStore(u16),
276
277 IStore0,
278 IStore1,
279 IStore2,
280 IStore3,
281
282 LStore0,
283 LStore1,
284 LStore2,
285 LStore3,
286
287 FStore0,
288 FStore1,
289 FStore2,
290 FStore3,
291
292 DStore0,
293 DStore1,
294 DStore2,
295 DStore3,
296
297 AStore0,
298 AStore1,
299 AStore2,
300 AStore3,
301
302 IAStore,
303 LAStore,
304 FAStore,
305 DAStore,
306 AAStore,
307 BAStore,
308 CAStore,
309 SAStore,
310
311 Pop,
312 Pop2,
313
314 Dup,
315 DupX1,
316 DupX2,
317
318 Dup2,
319 Dup2X1,
320 Dup2X2,
321
322 Swap,
323
324 IAdd,
325 LAdd,
326 FAdd,
327 DAdd,
328
329 ISub,
330 LSub,
331 FSub,
332 DSub,
333
334 IMul,
335 LMul,
336 FMul,
337 DMul,
338
339 IDiv,
340 LDiv,
341 FDiv,
342 DDiv,
343
344 IRem,
345 LRem,
346 FRem,
347 DRem,
348
349 INeg,
350 LNeg,
351 FNeg,
352 DNeg,
353
354 IShL,
355 LShL,
356
357 IShR,
358 LShR,
359
360 IUShR,
361 LUShR,
362
363 IAnd,
364 LAnd,
365
366 IOr,
367 LOr,
368
369 IXOr,
370 LXOr,
371
372 IInc(u16, i16),
373
374 I2L,
375 I2F,
376 I2D,
377
378 L2I,
379 L2F,
380 L2D,
381
382 F2I,
383 F2L,
384 F2D,
385
386 D2I,
387 D2L,
388 D2F,
389
390 I2B,
391 I2C,
392 I2S,
393
394 LCmp,
395
396 FCmpL,
397 FCmpG,
398
399 DCmpL,
400 DCmpG,
401
402 IfEq(i16),
403 IfNE(i16),
404 IfLT(i16),
405 IfGE(i16),
406 IfGT(i16),
407 IfLE(i16),
408
409 IfICmpEq(i16),
410 IfICmpNE(i16),
411 IfICmpLT(i16),
412 IfICmpGE(i16),
413 IfICmpGT(i16),
414 IfICmpLE(i16),
415
416 IfACmpEq(i16),
417 IfACmpNE(i16),
418
419 GoTo(i32),
420 JSR(i32),
421 Ret(u16),
422
423 TableSwitch {
424 default: i32,
425 low: i32,
426 high: i32,
427 offsets: Vec<i32>,
428 },
429 LookupSwitch {
430 default: i32,
431 offsets: BTreeMap<i32, i32>,
432 },
433
434 IReturn,
435 LReturn,
436 FReturn,
437 DReturn,
438 AReturn,
439 Return,
440
441 GetStatic(u16),
442 PutStatic(u16),
443 GetField(u16),
444 PutField(u16),
445
446 InvokeVirtual(u16),
447 InvokeSpecial(u16),
448 InvokeStatic(u16),
449 InvokeInterface(u16, u8),
450 InvokeDynamic(u16),
451
452 New(u16),
453 NewArray(ArrayType),
454 ANewArray(u16),
455 ArrayLength,
456
457 AThrow,
458
459 CheckCast(u16),
460 InstanceOf(u16),
461
462 MonitorEnter,
463 MonitorExit,
464
465 MultiANewArray(u16, u8),
466
467 IfNull(i16),
468 IfNonNull(i16),
469
470 BreakPoint,
471 ImpDep1,
472 ImpDep2,
473}
474
475#[derive(Debug)]
476pub enum ArrayType {
477 Boolean,
478 Char,
479 Float,
480 Double,
481 Byte,
482 Short,
483 Int,
484 Long,
485}
486
487#[derive(Debug)]
488pub struct InnerClass {
489 pub inner_class_info: u16,
490 pub outer_class_info: u16,
491 pub inner_name: u16,
492 pub inner_class_access_flags: AccessFlags,
493}
494
495#[derive(Debug)]
496pub enum StackMapFrame {
497 Same {
498 offset_delta: u16,
499 },
500 Same1 {
501 offset_delta: u16,
502 stack: VerificationType,
503 },
504 Chop {
505 offset_delta: u16,
506 count: u8,
507 },
508 Append {
509 offset_delta: u16,
510 locals: Vec<VerificationType>,
511 },
512 Full {
513 offset_delta: u16,
514 locals: Vec<VerificationType>,
515 stack: Vec<VerificationType>,
516 },
517}
518
519#[derive(Debug)]
520pub enum VerificationType {
521 Top,
522 Integer,
523 Float,
524 Double,
525 Long,
526 Null,
527 UninitializedThis,
528 Object(u16),
529 Uninitialized(u16),
530}
531
532#[derive(Debug)]
533pub struct Annotation {
534 /// Must be an index to the constant pool with an `Item::UTF8(_)`
535 /// representing a field descriptor
536 pub type_index: u16,
537 /// The value every single pair holds.
538 /// The first part is an index to the constant pool,
539 /// which must be an `Item::UTF8(_)`.
540 /// The second one is the value itself.
541 pub element_value_pairs: Vec<(u16, ElementValue)>,
542}
543
544#[derive(Debug)]
545pub enum ElementValue {
546 /// The index to the constant pool
547 /// which must be an `Item::Integer(_)`.
548 Byte(u16),
549 /// The index to the constant pool
550 /// which must be an `Item::Integer(_)`.
551 Short(u16),
552 /// The index to the constant pool
553 /// which must be an `Item::Integer(_)`.
554 Char(u16),
555 /// The index to the constant pool
556 /// which must be an `Item::Integer(_)`.
557 Int(u16),
558 /// The index to the constant pool
559 /// which must be an `Item::Long(_)`.
560 Long(u16),
561 /// The index to the constant pool
562 /// which must be an `Item::Float(_)`.
563 Float(u16),
564 /// The index to the constant pool
565 /// which must be an `Item::Double(_)`.
566 Double(u16),
567 /// The index to the constant pool
568 /// which must be an `Item::Integer(_)`.
569 /// Yes, it really needs a constant pool entry for this.
570 Boolean(u16),
571 /// The index to the constant pool
572 /// which must be an `Item::UTF8(_)`.
573 String(u16),
574 /// An enum constant.
575 Enum {
576 /// The index to the constant pool,
577 /// which must be an `Item::UTF8(_)`.
578 /// It results in the internal form of the binary name
579 /// of the type of this enum constant.
580 type_name: u16,
581 /// The index to the constant pool,
582 /// which must be an `Item::UTF8(_)`.
583 /// It results in the simple name
584 /// of this enum constant.
585 const_name: u16,
586 },
587 /// A class literal.
588 /// The index to the constant pool
589 /// which must be an `Item::UTF8(_)`
590 /// representing a return descriptor.
591 Class(u16),
592 /// Another annotation.
593 Annotation(Box<Annotation>),
594 /// Multiple `ElementValue`s
595 Array(Vec<ElementValue>),
596}
597
598#[derive(Debug)]
599pub struct TypeAnnotation {
600 pub target_type: TargetType,
601 pub target_path: Vec<TypePathElement>,
602 pub annotation: Annotation,
603}
604
605#[derive(Debug)]
606pub enum TargetType {
607 /// Indicates that an annotation is present
608 /// on the type parameter of a class.
609 /// The index of the type parameter.
610 TypeParameterClass(u8),
611 /// Indicates that an annotation is present
612 /// on the type parameter of a method.
613 /// The index of the type parameter.
614 TypeParameterMethod(u8),
615 /// Indicates that an annotation is present
616 /// on the implements or extends clause of a class.
617 /// The index of the super type,
618 /// 0xFFFF is the extends clause.
619 SuperType(u16),
620 /// Indicates that an annotation is present
621 /// on a bound of a type parameter of a class.
622 TypeParameterBoundClass {
623 /// The index of the type parameter.
624 type_parameter: u8,
625 /// The index of the bound.
626 bound_index: u8,
627 },
628 /// Indicates that an annotation is present
629 /// on a bound of a type parameter of a method.
630 TypeParameterBoundMethod {
631 /// The index of the type parameter.
632 type_parameter: u8,
633 /// The index of the bound.
634 bound_index: u8,
635 },
636 /// Indicates that an annotation is present
637 /// on the type of a field declaration.
638 EmptyField,
639 /// Indicates that an annotation is present
640 /// on the return type of a method
641 /// or the type of a newly constructed object.
642 EmptyReturn,
643 /// Indicates that an annotation is present
644 /// on the receiver type of a method.
645 EmptyReceiver,
646 /// Indicates that an annotation is present
647 /// on the type in a formal parameter declaration.
648 /// The index of the formal parameter.
649 FormalParameter(u8),
650 /// Indicates that an annotation is present
651 /// on the type in a throws clause.
652 /// The index into the table of the `Exceptions` attribute of the method.
653 Throws(u16),
654 /// Indicates that an annotation is present
655 /// on the type in a local variable declaration.
656 LocalVariable(Vec<LocalVariableTarget>),
657 /// Indicates that an annotation is present
658 /// on the type in a local variable declaration.
659 ResourceVariable(Vec<LocalVariableTarget>),
660 /// Indicates that an annotation is present
661 /// on the type in an exception parameter declaration.
662 Catch(u16),
663 /// Indicates that an annotation is present
664 /// on the type in an instanceof expression.
665 OffsetInstanceOf(u16),
666 /// Indicates that an annotation is present
667 /// on the type in a new expression.
668 OffsetNew(u16),
669 /// Indicates that an annotation is present
670 /// on the type before the ::new
671 /// of a method reference expression.
672 OffsetNewRef(u16),
673 /// Indicates that an annotation is present
674 /// on the type before the ::name
675 /// of a method reference expression.
676 OffsetRef(u16),
677 /// Indicates that an annotation is present
678 /// on the type of a cast expression.
679 TypeArgumentCast { offset: u16, type_argument: u8 },
680 /// Indicates that an annotation is present
681 /// on the type of a method call expression.
682 TypeArgumentMethod { offset: u16, type_argument: u8 },
683 /// Indicates that an annotation is present
684 /// on the type of a new expression.
685 TypeArgumentConstructor { offset: u16, type_argument: u8 },
686 /// Indicates that an annotation is present
687 /// on the type of a ::new expression.
688 TypeArgumentNewRef { offset: u16, type_argument: u8 },
689 /// Indicates that an annotation is present
690 /// on the type of a ::name expression.
691 TypeArgumentRef { offset: u16, type_argument: u8 },
692}
693
694#[derive(Debug)]
695pub struct TypePathElement {
696 pub path_kind: TypePathKind,
697 pub argument_index: u8,
698}
699
700#[derive(Debug)]
701pub enum TypePathKind {
702 /// Annotation is deeper in an array kind
703 ArrayType,
704 /// Annotation is deeper in a nested type
705 NestedType,
706 /// Annotation is on the bound of a wildcard type argument of a parameterized type
707 WildcardType,
708 /// Annotation is on a type argument of a parameterized type
709 Type,
710}
711
712#[derive(Debug)]
713pub struct LocalVariableTarget {
714 /// Start of the Code.
715 pub start: u16,
716 /// Length of the Code.
717 pub length: u16,
718 /// The index in the local variable array of the current frame.
719 /// double and long do occupy two spaces.
720 pub index: u16,
721}
722
723/// An entry of the `LocalVariableTable`
724#[derive(Debug)]
725pub struct LocalVariable {
726 /// Start of the Code.
727 pub start: u16,
728 /// Length of the Code.
729 pub length: u16,
730 /// The index to an `Item::UTF8(_)` representing a valid unqalified name.
731 pub name: u16,
732 /// The index to an `Item::UTF8(_)` representing a field/type descriptor.
733 pub descriptor: u16,
734 /// The index in the local variable array of the current frame.
735 /// double and long do occupy two spaces.
736 pub index: u16,
737}
738
739/// An entry of the `LocalVariableTypeTable`
740#[derive(Debug)]
741pub struct LocalVariableType {
742 /// Start of the Code.
743 pub start: u16,
744 /// Length of the Code.
745 pub length: u16,
746 /// The index to an `Item::UTF8(_)` representing a valid unqalified name.
747 pub name: u16,
748 /// The index to an `Item::UTF8(_)` representing a field signature.
749 pub signature: u16,
750 /// The index in the local variable array of the current frame.
751 /// double and long do occupy two spaces.
752 pub index: u16,
753}
754
755#[derive(Debug)]
756pub struct MethodParameter {
757 pub name: u16,
758 pub access_flags: AccessFlags,
759}
760
761#[derive(Debug)]
762pub struct Requirement {
763 pub index: u16,
764 pub flags: AccessFlags,
765 pub version: u16,
766}
767
768#[derive(Debug)]
769pub struct Export {
770 pub index: u16,
771 pub flags: AccessFlags,
772 pub to: Vec<u16>,
773}
774
775#[derive(Debug)]
776pub struct Opening {
777 pub index: u16,
778 pub flags: AccessFlags,
779 pub to: Vec<u16>,
780}
781
782#[derive(Debug)]
783pub struct Provider {
784 pub index: u16,
785 pub with: Vec<u16>,
786}