classreader/
model.rs

1macro_rules! modifier_raw {
2    ($name:ident, $field:ident, $mask:expr) => {
3        pub fn $name(&self) -> bool {
4            self.$field & $mask == $mask
5        }
6    }
7}
8
9macro_rules! modifier {
10    ($name:ident, $mask:expr) => { modifier_raw!($name, access_flags, $mask); }
11}
12
13macro_rules! modifier_inner {
14    ($name:ident, $mask:expr) => { modifier_raw!($name, inner_class_access_flags, $mask); }
15}
16
17#[derive(Debug)]
18pub struct Class {
19    pub magic: u32,
20    pub minor_version: u16,
21    pub major_version: u16,
22    pub constant_pool: Vec<ConstantPoolInfo>,
23    pub access_flags: u16,
24    pub this_class: u16,
25    pub super_class: u16,
26    pub interfaces: Vec<u16>,
27    pub fields: Vec<Field>,
28    pub methods: Vec<Method>,
29    pub attributes: Vec<Attribute>
30}
31
32impl Class {
33    modifier!(is_public, 0x0001);
34    modifier!(is_final, 0x0010);
35    modifier!(is_super, 0x0020);
36    modifier!(is_interface, 0x0200);
37    modifier!(is_abstract, 0x0400);
38    modifier!(is_synthetic, 0x1000);
39    modifier!(is_annotation, 0x2000);
40    modifier!(is_enum, 0x4000);
41}
42
43#[derive(Debug)]
44pub enum ConstantPoolInfo {
45    Utf8(String),                       // 1
46    Integer(i32),                       // 3
47    Float(f32),                         // 4
48    Long(i64),                          // 5
49    Double(f64),                        // 6
50    Class(u16),                         // 7
51    String(u16),                        // 8
52    Fieldref(u16, u16),                 // 9
53    Methodref(u16, u16),                // 10
54    InterfaceMethodref(u16, u16),       // 11
55    NameAndType(u16, u16),              // 12
56    MethodHandle(u8, u16),              // 15
57    MethodType(u16),                    // 16
58    InvokeDynamic(u16, u16),            // 18
59    Invalid
60}
61
62#[derive(Debug)]
63pub struct Field {
64    pub access_flags: u16,
65    pub name_index: u16,
66    pub descriptor_index: u16,
67    pub attributes: Vec<Attribute>
68}
69
70impl Field {
71    modifier!(is_public, 0x0001);
72    modifier!(is_private, 0x0002);
73    modifier!(is_protected, 0x0004);
74    modifier!(is_static, 0x0008);
75    modifier!(is_final, 0x0010);
76    modifier!(is_volatile, 0x0040);
77    modifier!(is_transient, 0x0080);
78    modifier!(is_synthetic, 0x1000);
79    modifier!(is_enum, 0x4000);
80}
81
82#[derive(Debug)]
83pub struct Method {
84    pub access_flags: u16,
85    pub name_index: u16,
86    pub descriptor_index: u16,
87    pub attributes: Vec<Attribute>
88}
89
90impl Method {
91    modifier!(is_public, 0x0001);
92    modifier!(is_private, 0x0002);
93    modifier!(is_protected, 0x0004);
94    modifier!(is_static, 0x0008);
95    modifier!(is_final, 0x0010);
96    modifier!(is_synchronized, 0x0020);
97    modifier!(is_bridge, 0x0040);
98    modifier!(is_varargs, 0x0080);
99    modifier!(is_native, 0x01000);
100    modifier!(is_abstract, 0x0400);
101    modifier!(is_strict, 0x0800);
102    modifier!(is_synthetic, 0x1000);
103}
104
105#[derive(Debug)]
106pub enum Attribute {
107    ConstantValue{ constvalue_index: u16 },
108    Code {
109        max_stack: u16,
110        max_locals: u16,
111        code: Vec<(u32, Instruction)>,
112        exception_table: Vec<Exception>,
113        attributes: Vec<Attribute>
114    },
115    StackMapTable(Vec<StackMapFrame>),
116    Exceptions { exception_index_table: Vec<u16> },
117    InnerClasses { classes: Vec<InnerClass> },
118    EnclosingMethod { class_index: u16, method_index: u16 },
119    Synthetic,
120    Signature { signature_index: u16 },
121    SourceFile { sourcefile_index: u16 },
122    SourceDebugExtension(Vec<u8>),
123    LineNumberTable(Vec<LineNumber>),
124    LocalVariableTable(Vec<LocalVariable>),
125    LocalVariableTypeTable(Vec<LocalVariable>),
126    Deprecated,
127    RuntimeVisibleAnnotations(Vec<Annotation>),
128    RuntimeInvisibleAnnotations(Vec<Annotation>),
129    RuntimeVisibleParameterAnnotations(Vec<Vec<Annotation>>),
130    RuntimeInvisibleParameterAnnotations(Vec<Vec<Annotation>>),
131    RuntimeVisibleTypeAnnotations(Vec<TypeAnnotation>),
132    RuntimeInvisibleTypeAnnotations(Vec<TypeAnnotation>),
133    AnnotationDefault { element_value: ElementValue },
134    BootstrapMethods(Vec<BootstrapMethod>),
135    MethodParameters(Vec<MethodParameter>),
136    Unknown(Vec<u8>)
137}
138
139#[derive(Debug)]
140pub struct Exception {
141    pub start_pc: u16,
142    pub end_pc: u16,
143    pub handler_pc: u16,
144    pub catch_type: u16
145}
146
147#[derive(Debug)]
148pub enum StackMapFrame {
149    SameFrame,
150    SameLocals1StackItemFrame(VerificationType),
151    SameLocals1StackItemFrameExtended { offset_delta: u16, stack: VerificationType },
152    ChopFrame { offset_delta: u16 },
153    SameFrameExtended { offset_delta: u16 },
154    AppendFrame { offset_delta: u16, locals: Vec<VerificationType> },
155    FullFrame {
156        offset_delta: u16,
157        locals: Vec<VerificationType>,
158        stack: Vec<VerificationType>
159    }
160}
161
162#[derive(Debug)]
163pub enum VerificationType {
164    Top,                                        // 0
165    Integer,                                    // 1
166    Float,                                      // 2
167    Double,                                     // 3
168    Long,                                       // 4
169    Null,                                       // 5
170    UninitializedThis,                          // 6
171    Object { index: u16 },                      // 7
172    UninitializedVariable { offset: u16 },      // 8
173}
174
175#[derive(Debug)]
176pub struct InnerClass {
177    pub inner_class_info_index: u16,
178    pub outer_class_info_index: u16,
179    pub inner_name_index: u16,
180    pub inner_class_access_flags: u16
181}
182
183impl InnerClass {
184    modifier_inner!(is_public, 0x0001);
185    modifier_inner!(is_private, 0x0002);
186    modifier_inner!(is_protected, 0x0004);
187    modifier_inner!(is_static, 0x0008);
188    modifier_inner!(is_final, 0x0010);
189    modifier_inner!(is_interface, 0x0200);
190    modifier_inner!(is_abstract, 0x0400);
191    modifier_inner!(is_synthetic, 0x1000);
192    modifier_inner!(is_annotation, 0x2000);
193    modifier_inner!(is_enum, 0x4000);
194}
195
196#[derive(Debug)]
197pub struct LineNumber {
198    pub start_pc: u16,
199    pub line_number: u16
200}
201
202#[derive(Debug)]
203pub struct LocalVariable {
204    pub start_pc: u16,
205    pub length: u16,
206    pub name_index: u16,
207    pub descriptor_or_signature_index: u16,
208    pub index: u16
209}
210
211#[derive(Debug)]
212pub struct Annotation {
213    pub type_index: u16,
214    pub element_value_pairs: Vec<ElementValuePair>
215}
216
217#[derive(Debug)]
218pub struct TypeAnnotation {
219    pub target_type: TargetType,
220    pub target_info: TargetInfo,
221    pub type_path: TypePath,
222    pub type_index: u16,
223    pub element_value_pairs: Vec<ElementValuePair>
224}
225
226#[derive(Debug)]
227pub struct ElementValuePair {
228    pub element_name_index: u16,
229    pub value: ElementValue
230}
231
232#[derive(Debug)]
233pub enum ElementValue {
234    Constant { const_value_index: u16 },
235    EnumConstant { type_name_index: u16, const_name_index: u16 },
236    Class { class_info_index: u16 },
237    Annotation(Annotation),
238    Array(Vec<ElementValue>)
239}
240
241#[derive(Debug)]
242pub enum TargetType {
243    Type,                               // 0x00
244    Method,                             // 0x01
245    Supertype,                          // 0x10
246    TypeBound,                          // 0x11
247    MethodBound,                        // 0x12
248    Field,                              // 0x13
249    MethodReturnType,                   // 0x14
250    ReceiverType,                       // 0x15
251    Parameter,                          // 0x16
252    Throws,                             // 0x17
253    LocalVariableDeclaration,           // 0x40
254    ResourceVariableDeclaration,        // 0x41
255    ExceptionParameterDeclaration,      // 0x42
256    Instanceof,                         // 0x43
257    New,                                // 0x44
258    MethodReferenceNew,                 // 0x45
259    MethodReference,                    // 0x46
260    Cast,                               // 0x47
261    ConstructorArgument,                // 0x48
262    MethodArgument,                     // 0x49
263    MethodReferenceNewArgument,         // 0x4A
264    MethodReferenceArgument             // 0x4B
265}
266
267#[derive(Debug)]
268pub enum TargetInfo {
269    TypeParameter { index: u8 },
270    Supertype { index: u16 },
271    TypeParameterBound { index: u8, bound_index: u8 },
272    Empty,
273    MethodFormalParameter { index: u8 },
274    Throws { type_index: u16 },
275    Localvar(Vec<LocalVariableTarget>),
276    Catch { exception_table_index: u16 },
277    Offset(u16),
278    TypeArgument { offset: u16, index: u8 }
279}
280
281#[derive(Debug)]
282pub struct TypePath {
283    pub path: Vec<PathElement>
284}
285
286#[derive(Debug)]
287pub struct PathElement {
288    pub kind: TypePathKind,
289    pub argument_index: u8
290}
291
292#[derive(Debug)]
293pub enum TypePathKind {
294    Array,              // 0
295    Nested,             // 1
296    WildcardBound,      // 2
297    TypeArgument        // 3
298}
299
300#[derive(Debug)]
301pub struct LocalVariableTarget {
302    pub start_pc: u16,
303    pub length: u16,
304    pub index: u16
305}
306
307#[derive(Debug)]
308pub struct BootstrapMethod {
309    pub method_ref: u16,
310    pub arguments: Vec<u16>
311}
312
313#[derive(Debug)]
314pub struct MethodParameter {
315    pub name_index: u16,
316    pub access_flags: u16
317}
318
319#[derive(Debug)]
320#[allow(non_camel_case_types)]
321pub enum Instruction {
322    aaload,                                     //  50 (0x32)
323    aastore,                                    //  83 (0x53)
324    aconst_null,                                //   1 (0x01)
325    aload(u8),                                  //  25 (0x19)
326    aload_0,                                    //  42 (0x2a)
327    aload_1,                                    //  43 (0x2b)
328    aload_2,                                    //  44 (0x2c)
329    aload_3,                                    //  45 (0x2d)
330    anewarray(u16),                             // 189 (0xbd)
331    areturn,                                    // 176 (0xb0)
332    arraylength,                                // 190 (0xbe)
333    astore(u8),                                 //  58 (0x3a)
334    astore_0,                                   //  75 (0x4b)
335    astore_1,                                   //  76 (0x4c)
336    astore_2,                                   //  77 (0x4d)
337    astore_3,                                   //  78 (0x4e)
338    athrow,                                     // 191 (0xbf)
339    baload,                                     //  51 (0x33)
340    bastore,                                    //  84 (0x54)
341    bipush(i8),                                 //  16 (0x10)
342    caload,                                     //  52 (0x34)
343    castore,                                    //  85 (0x55)
344    checkcast(u16),                             // 192 (0xc0)
345    d2f,                                        // 144 (0x90)
346    d2i,                                        // 142 (0x8e)
347    d2l,                                        // 143 (0x8f)
348    dadd,                                       //  99 (0x63)
349    daload,                                     //  49 (0x31)
350    dastore,                                    //  82 (0x52)
351    dcmpg,                                      // 152 (0x98)
352    dcmpl,                                      // 151 (0x97)
353    dconst_0,                                   //  14 (0x0e)
354    dconst_1,                                   //  15 (0x0f)
355    ddiv,                                       // 111 (0x6f)
356    dload(u8),                                  //  24 (0x18)
357    dload_0,                                    //  38 (0x26)
358    dload_1,                                    //  39 (0x27)
359    dload_2,                                    //  40 (0x28)
360    dload_3,                                    //  41 (0x29)
361    dmul,                                       // 107 (0x6b)
362    dneg,                                       // 119 (0x77)
363    drem,                                       // 115 (0x73)
364    dreturn,                                    // 175 (0xaf)
365    dstore(u8),                                 //  57 (0x39)
366    dstore_0,                                   //  71 (0x47)
367    dstore_1,                                   //  72 (0x48)
368    dstore_2,                                   //  73 (0x49)
369    dstore_3,                                   //  74 (0x4a)
370    dsub,                                       // 103 (0x67)
371    dup,                                        //  89 (0x59)
372    dup_x1,                                     //  90 (0x5a)
373    dup_x2,                                     //  91 (0x5b)
374    dup2,                                       //  92 (0x5c)
375    dup2_x1,                                    //  93 (0x5d)
376    dup2_x2,                                    //  94 (0x5e)
377    f2d,                                        // 141 (0x8d)
378    f2i,                                        // 193 (0x8b)
379    f2l,                                        // 140 (0x8c)
380    fadd,                                       //  98 (0x62)
381    faload,                                     //  48 (0x30)
382    fastore,                                    //  81 (0x51)
383    fcmpg,                                      // 150 (0x96)
384    fcmpl,                                      // 149 (0x95)
385    fconst_0,                                   //  11 (0x0b)
386    fconst_1,                                   //  12 (0x0c)
387    fconst_2,                                   //  13 (0x0d)
388    fdiv,                                       // 110 (0x6e)
389    fload(u8),                                  //  23 (0x17)
390    fload_0,                                    //  34 (0x22)
391    fload_1,                                    //  35 (0x23)
392    fload_2,                                    //  36 (0x24)
393    fload_3,                                    //  37 (0x25)
394    fmul,                                       // 106 (0x6a)
395    fneg,                                       // 118 (0x76)
396    frem,                                       // 114 (0x72)
397    freturn,                                    // 174 (0xae)
398    fstore(u8),                                 //  56 (0x38)
399    fstore_0,                                   //  67 (0x43)
400    fstore_1,                                   //  68 (0x44)
401    fstore_2,                                   //  69 (0x45)
402    fstore_3,                                   //  70 (0x46)
403    fsub,                                       // 102 (0x66)
404    getfield(u16),                              // 180 (0xb4)
405    getstatic(u16),                             // 178 (0xb2)
406    goto(i16),                                  // 167 (0xa7)
407    goto_w(i32),                                // 200 (0xc8)
408    i2b,                                        // 145 (0x91)
409    i2c,                                        // 146 (0x92)
410    i2d,                                        // 135 (0x87)
411    i2f,                                        // 134 (0x86)
412    i2l,                                        // 133 (0x85)
413    i2s,                                        // 147 (0x93)
414    iadd,                                       //  96 (0x60)
415    iaload,                                     //  46 (0x2e)
416    iand,                                       // 126 (0x7e)
417    iastore,                                    //  79 (0x4f)
418    iconst_m1,                                  //   2 (0x02)
419    iconst_0,                                   //   3 (0x03)
420    iconst_1,                                   //   4 (0x04)
421    iconst_2,                                   //   5 (0x05)
422    iconst_3,                                   //   6 (0x06)
423    iconst_4,                                   //   7 (0x07)
424    iconst_5,                                   //   8 (0x08)
425    idiv,                                       // 108 (0x6c)
426    if_acmpeq(i16),                             // 165 (0xa5)
427    if_acmpne(i16),                             // 166 (0xa6)
428    if_icmpeq(i16),                             // 159 (0x9f)
429    if_icmpne(i16),                             // 160 (0xa0)
430    if_icmplt(i16),                             // 161 (0xa1)
431    if_icmpge(i16),                             // 162 (0xa2)
432    if_icmpgt(i16),                             // 163 (0xa3)
433    if_icmple(i16),                             // 164 (0xa4)
434    ifeq(i16),                                  // 153 (0x99)
435    ifne(i16),                                  // 154 (0x9a)
436    iflt(i16),                                  // 155 (0x9b)
437    ifge(i16),                                  // 156 (0x9c)
438    ifgt(i16),                                  // 157 (0x9d)
439    ifle(i16),                                  // 158 (0x9e)
440    ifnonnull(i16),                             // 199 (0xc7)
441    ifnull(i16),                                // 198 (0xc6)
442    iinc(u8, i8),                               // 132 (0x84)
443    iload(u8),                                  //  21 (0x15)
444    iload_0,                                    //  26 (0x1a)
445    iload_1,                                    //  27 (0x1b)
446    iload_2,                                    //  28 (0x1c)
447    iload_3,                                    //  29 (0x1d)
448    imul,                                       // 104 (0x68)
449    ineg,                                       // 116 (0x74)
450    instanceof(u16),                            // 193 (0xc1)
451    invokedynamic(u16),                         // 186 (0xba)
452    invokeinterface(u16, u8),                   // 185 (0xb9)
453    invokespecial(u16),                         // 183 (0xb7)
454    invokestatic(u16),                          // 184 (0xb8)
455    invokevirtual(u16),                         // 182 (0xb6)
456    ior,                                        // 128 (0x80)
457    irem,                                       // 112 (0x70)
458    ireturn,                                    // 172 (0xac)
459    ishl,                                       // 120 (0x78)
460    ishr,                                       // 122 (0x7a)
461    istore(u8),                                 //  54 (0x36)
462    istore_0,                                   //  59 (0x3b)
463    istore_1,                                   //  60 (0x3c)
464    istore_2,                                   //  61 (0x3d)
465    istore_3,                                   //  62 (0x3e)
466    isub,                                       // 100 (0x64)
467    iushr,                                      // 124 (0x7c)
468    ixor,                                       // 130 (0x82)
469    jsr(i16),                                   // 168 (0xa8)
470    jsr_w(i32),                                 // 201 (0xc9)
471    l2d,                                        // 138 (0x8a)
472    l2f,                                        // 137 (0x89)
473    l2i,                                        // 136 (0x88)
474    ladd,                                       //  97 (0x61)
475    laload,                                     //  47 (0x2f)
476    land,                                       // 127 (0x7f)
477    lastore,                                    //  80 (0x50)
478    lcmp,                                       // 148 (0x94)
479    lconst_0,                                   //   9 (0x09)
480    lconst_1,                                   //  10 (0x0a)
481    ldc(u8),                                    //  18 (0x12)
482    ldc_w(u16),                                 //  19 (0x13)
483    ldc2_w(u16),                                //  20 (0x14)
484    ldiv,                                       // 109 (0x6d)
485    lload(u8),                                  //  22 (0x16)
486    lload_0,                                    //  30 (0x1e)
487    lload_1,                                    //  31 (0x1f)
488    lload_2,                                    //  32 (0x20)
489    lload_3,                                    //  33 (0x21)
490    lmul,                                       // 105 (0x69)
491    lneg,                                       // 117 (0x75)
492    lookupswitch(i32, Box<[(i32, i32)]>),       // 171 (0xab)
493    lor,                                        // 129 (0x81)
494    lrem,                                       // 113 (0x71)
495    lreturn,                                    // 173 (0xad)
496    lshl,                                       // 121 (0x79)
497    lshr,                                       // 123 (0x7b)
498    lstore(u8),                                 //  55 (0x37)
499    lstore_0,                                   //  63 (0x3f)
500    lstore_1,                                   //  64 (0x40)
501    lstore_2,                                   //  65 (0x41)
502    lstore_3,                                   //  66 (0x42)
503    lsub,                                       // 101 (0x65)
504    lushr,                                      // 125 (0x7d)
505    lxor,                                       // 131 (0x83)
506    monitorenter,                               // 194 (0xc2)
507    monitorexit,                                // 195 (0xc3)
508    multianewarray(u16, u8),                    // 197 (0xc5)
509    new(u16),                                   // 187 (0xbb)
510    newarray(ArrayType),                        // 188 (0xbc)
511    nop,                                        //   0 (0x00)
512    pop,                                        //  87 (0x57)
513    pop2,                                       //  88 (0x58)
514    putfield(u16),                              // 181 (0xb5)
515    putstatic(u16),                             // 179 (0xb3)
516    ret(u8),                                    // 169 (0xa9)
517    return_,                                    // 177 (0xb1)
518    saload,                                     //  53 (0x35)
519    sastore,                                    //  86 (0x56)
520    sipush(i16),                                //  17 (0x11)
521    swap,                                       //  95 (0x5f)
522    tableswitch(i32, i32, Box<[i32]>),          // 170 (0xaa)
523    iload_w(u16),                               // 196 (0xc4)
524    fload_w(u16),                               // 196 (0xc4)
525    aload_w(u16),                               // 196 (0xc4)
526    lload_w(u16),                               // 196 (0xc4)
527    dload_w(u16),                               // 196 (0xc4)
528    istore_w(u16),                              // 196 (0xc4)
529    fstore_w(u16),                              // 196 (0xc4)
530    astore_w(u16),                              // 196 (0xc4)
531    lstore_w(u16),                              // 196 (0xc4)
532    dstore_w(u16),                              // 196 (0xc4)
533    ret_w(u16),                                 // 196 (0xc4)
534    iinc_w(u16, i16)                            // 196 (0xc4)
535}
536
537#[derive(Debug)]
538pub enum ArrayType {
539    Boolean,    //  4
540    Char,       //  5
541    Float,      //  6
542    Double,     //  7
543    Byte,       //  8
544    Short,      //  9
545    Int,        // 10
546    Long        // 11
547}
548
549impl ConstantPoolInfo {
550    pub fn is_double_length(self: &ConstantPoolInfo) -> bool {
551        match *self {
552            ConstantPoolInfo::Long(_) | ConstantPoolInfo::Double(_) => { true },
553            _ => { false }
554        }
555    }
556}