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}