pclass_parser/classfile/
attributes.rs

1use std::sync::Arc;
2use crate::classfile::types::{U2, U1, U4};
3use crate::BytesRef;
4
5#[derive(Debug, Clone)]
6pub enum Type {
7    ConstantValue {
8        constant_value_index: U2,
9    },
10    Code(Code),
11    StackMapTable {
12        entries: Vec<StackMapFrame>,
13    },
14    Exceptions {
15        exceptions: Vec<U2>,
16    },
17    InnerClasses {
18        classes: Vec<InnerClass>,
19    },
20    EnclosingMethod {
21        em: EnclosingMethod,
22    },
23    Synthetic,
24    Signature {
25        signature_index: U2,
26    },
27    SourceFile {
28        source_file_index: U2,
29    },
30    SourceDebugExtension {
31        debug_extension: BytesRef,
32    },
33    LineNumberTable {
34        tables: Vec<LineNumber>,
35    },
36    LocalVariableTable {
37        tables: Vec<LocalVariable>,
38    },
39    LocalVariableTypeTable {
40        tables: Vec<LocalVariable>,
41    },
42    Deprecated,
43    RuntimeVisibleAnnotations {
44        raw: BytesRef,
45        annotations: Vec<AnnotationEntry>,
46    },
47    RuntimeInvisibleAnnotations {
48        raw: BytesRef,
49        annotations: Vec<AnnotationEntry>,
50    },
51    RuntimeVisibleParameterAnnotations {
52        raw: BytesRef,
53        annotations: Vec<AnnotationEntry>,
54    },
55    RuntimeInvisibleParameterAnnotations {
56        raw: BytesRef,
57        annotations: Vec<AnnotationEntry>,
58    },
59    RuntimeVisibleTypeAnnotations {
60        raw: BytesRef,
61        annotations: Vec<TypeAnnotation>,
62    },
63    RuntimeInvisibleTypeAnnotations {
64        raw: BytesRef,
65        annotations: Vec<TypeAnnotation>,
66    },
67    AnnotationDefault {
68        raw: BytesRef,
69        default_value: ElementValueType,
70    },
71    BootstrapMethods {
72        n: U2,
73        methods: Vec<BootstrapMethod>,
74    },
75    MethodParameters {
76        parameters: Vec<MethodParameter>,
77    },
78    Unknown,
79}
80
81#[derive(Clone, Copy)]
82pub enum Tag {
83    ConstantValue,
84    Code,
85    StackMapTable,
86    Exceptions,
87    InnerClasses,
88    EnclosingMethod,
89    Synthetic,
90    Signature,
91    SourceFile,
92    SourceDebugExtension,
93    LineNumberTable,
94    LocalVariableTable,
95    LocalVariableTypeTable,
96    Deprecated,
97    RuntimeVisibleAnnotations,
98    RuntimeInvisibleAnnotations,
99    RuntimeVisibleParameterAnnotations,
100    RuntimeInvisibleParameterAnnotations,
101    RuntimeVisibleTypeAnnotations,
102    RuntimeInvisibleTypeAnnotations,
103    AnnotationDefault,
104    BootstrapMethods,
105    MethodParameters,
106    Unknown,
107}
108
109impl From<&[u8]> for Tag {
110    fn from(raw: &[u8]) -> Self {
111        match raw {
112            b"ConstantValue" => Tag::ConstantValue,
113            b"Code" => Tag::Code,
114            b"StackMapTable" => Tag::StackMapTable,
115            b"Exceptions" => Tag::Exceptions,
116            b"InnerClasses" => Tag::InnerClasses,
117            b"EnclosingMethod" => Tag::EnclosingMethod,
118            b"Synthetic" => Tag::Synthetic,
119            b"Signature" => Tag::Signature,
120            b"SourceFile" => Tag::SourceFile,
121            b"SourceDebugExtension" => Tag::SourceDebugExtension,
122            b"LineNumberTable" => Tag::LineNumberTable,
123            b"LocalVariableTable" => Tag::LocalVariableTable,
124            b"LocalVariableTypeTable" => Tag::LocalVariableTypeTable,
125            b"Deprecated" => Tag::Deprecated,
126            b"RuntimeVisibleAnnotations" => Tag::RuntimeVisibleAnnotations,
127            b"RuntimeInvisibleAnnotations" => Tag::RuntimeInvisibleAnnotations,
128            b"RuntimeVisibleParameterAnnotations" => Tag::RuntimeVisibleParameterAnnotations,
129            b"RuntimeInvisibleParameterAnnotations" => Tag::RuntimeInvisibleParameterAnnotations,
130            b"RuntimeVisibleTypeAnnotations" => Tag::RuntimeVisibleTypeAnnotations,
131            b"RuntimeInvisibleTypeAnnotations" => Tag::RuntimeInvisibleTypeAnnotations,
132            b"AnnotationDefault" => Tag::AnnotationDefault,
133            b"BootstrapMethods" => Tag::BootstrapMethods,
134            b"MethodParameters" => Tag::MethodParameters,
135            _ => {
136                info!("Unknown attr {}", unsafe { std::str::from_utf8_unchecked(raw) });
137                // error!("Unknown attr {}", String::from_utf8_lossy(raw));
138                Tag::Unknown
139            }
140        }
141    }
142}
143
144#[derive(Debug, Clone)]
145pub struct Code {
146    pub max_stack: U2,
147    pub max_locals: U2,
148    pub code: Arc<Vec<U1>>,
149    pub exceptions: Vec<CodeException>,
150    pub attrs: Vec<Type>,
151}
152
153#[derive(Debug, Clone)]
154pub struct CodeException {
155    pub start_pc: U2,
156    pub end_pc: U2,
157    pub handler_pc: U2,
158    pub catch_type: U2,
159}
160
161impl CodeException {
162    pub fn contains(&self, pc: U2) -> bool {
163        (self.start_pc..self.end_pc + 1).contains(&pc)
164    }
165
166    pub fn is_finally(&self) -> bool {
167        self.catch_type == 0
168    }
169}
170
171#[derive(Debug, Clone)]
172pub struct AttributeInfo {
173    pub name_index: U2,
174    pub length: U4,
175    pub info: Vec<U1>,
176}
177
178pub enum NestedClassAccessPropertyFlag {
179    AccPublic,
180    AccPrivate,
181    AccProtected,
182    AccStatic,
183    AccFinal,
184    AccInterface,
185    AccAbstract,
186    AccSynthetic,
187    AccAnnotation,
188    AccEnum,
189}
190
191#[derive(Debug, Copy, Clone)]
192pub struct InnerClass {
193    pub inner_class_info_index: U2,
194    pub outer_class_info_index: U2,
195    pub inner_name_index: U2,
196    pub inner_class_access_flags: U2,
197}
198
199#[derive(Debug, Copy, Clone)]
200pub struct LineNumber {
201    pub start_pc: U2,
202    pub number: U2,
203}
204
205#[derive(Debug, Copy, Clone)]
206pub struct LocalVariable {
207    pub start_pc: U2,
208    pub length: U2,
209    pub name_index: U2,
210    pub signature_index: U2,
211    pub index: U2,
212}
213
214#[derive(Debug, Clone, Copy)]
215pub enum ElementValueTag {
216    Byte,
217    Char,
218    Double,
219    Float,
220    Int,
221    Long,
222    Short,
223    Boolean,
224    String,
225    Enum,
226    Class,
227    Annotation,
228    Array,
229    Unknown,
230}
231
232impl From<u8> for ElementValueTag {
233    fn from(v: u8) -> Self {
234        match v {
235            b'B' => ElementValueTag::Byte,
236            b'C' => ElementValueTag::Char,
237            b'D' => ElementValueTag::Double,
238            b'F' => ElementValueTag::Float,
239            b'I' => ElementValueTag::Int,
240            b'J' => ElementValueTag::Long,
241            b'S' => ElementValueTag::Short,
242            b'Z' => ElementValueTag::Boolean,
243            b's' => ElementValueTag::String,
244            b'e' => ElementValueTag::Enum,
245            b'c' => ElementValueTag::Class,
246            b'@' => ElementValueTag::Annotation,
247            b'[' => ElementValueTag::Array,
248            _ => ElementValueTag::Unknown,
249        }
250    }
251}
252
253#[derive(Debug, Clone)]
254pub enum ElementValueType {
255    Byte { val_index: U2 },
256    Char { val_index: U2 },
257    Double { val_index: U2 },
258    Float { val_index: U2 },
259    Int { val_index: U2 },
260    Long { val_index: U2 },
261    Short { val_index: U2 },
262    Boolean { val_index: U2 },
263    String { val_index: U2 },
264    Enum { type_index: U2, val_index: U2 },
265    Class { index: U2 },
266    Annotation(AnnotationElementValue),
267    Array { values: Vec<ElementValueType> },
268    Unknown,
269}
270
271#[derive(Debug, Clone)]
272pub struct AnnotationElementValue {
273    pub value: AnnotationEntry,
274}
275
276#[derive(Debug, Clone)]
277pub struct ElementValuePair {
278    pub name_index: U2,
279    pub value: ElementValueType,
280}
281
282#[derive(Debug, Clone)]
283pub struct AnnotationEntry {
284    pub type_name: BytesRef,
285    pub pairs: Vec<ElementValuePair>,
286}
287
288#[derive(Debug, Clone)]
289pub struct BootstrapMethod {
290    pub method_ref: U2,
291    pub args: Vec<U2>,
292}
293
294#[derive(Debug)]
295pub enum MethodParameterAccessFlag {
296    AccFinal = 0x0010,
297    AccSynthetic = 0x1000,
298    AccMandated = 0x8000,
299}
300
301#[derive(Debug, Copy, Clone)]
302pub struct MethodParameter {
303    pub name_index: U2,
304    pub acc_flags: U2,
305}
306
307#[derive(Debug, Clone)]
308pub enum VerificationTypeInfo {
309    Top,
310    Integer,
311    Float,
312    Long,
313    Double,
314    Null,
315    UninitializedThis,
316    Object { cpool_index: U2 },
317    Uninitialized { offset: U2 },
318}
319
320#[derive(Debug, Clone)]
321pub enum StackMapFrame {
322    Same {
323        tag: U1,
324        offset_delta: U2,
325    },
326    SameLocals1StackItem {
327        tag: U1,
328        offset_delta: U2,
329        stack: [VerificationTypeInfo; 1],
330    },
331    SameLocals1StackItemExtended {
332        tag: U1,
333        offset_delta: U2,
334        stack: [VerificationTypeInfo; 1],
335    },
336    Chop {
337        tag: U1,
338        offset_delta: U2,
339    },
340    SameExtended {
341        tag: U1,
342        offset_delta: U2,
343    },
344    Append {
345        tag: U1,
346        offset_delta: U2,
347        locals: Vec<VerificationTypeInfo>,
348    },
349    Full {
350        tag: U1,
351        offset_delta: U2,
352        locals: Vec<VerificationTypeInfo>,
353        stack: Vec<VerificationTypeInfo>,
354    },
355    Reserved(U1),
356}
357
358#[derive(Debug, Clone)]
359pub struct TypeAnnotation {
360    pub target_info: TargetInfo,
361    pub target_path: Vec<TypePath>,
362    pub type_index: U2,
363    pub pairs: Vec<ElementValuePair>,
364}
365
366#[derive(Debug, Clone)]
367pub enum TargetInfo {
368    TypeParameter {
369        type_parameter_index: U1,
370    },
371    SuperType {
372        supertype_index: U2,
373    },
374    TypeParameterBound {
375        type_parameter_index: U1,
376        bound_index: U1,
377    },
378    Empty,
379    FormalParameter {
380        formal_parameter_index: U1,
381    },
382    Throws {
383        throws_type_index: U2,
384    },
385    LocalVar {
386        table: Vec<LocalVarTargetTable>,
387    },
388    Catch {
389        exception_table_index: U2,
390    },
391    Offset {
392        offset: U2,
393    },
394    TypeArgument {
395        offset: U2,
396        type_argument_index: U1,
397    },
398}
399
400#[derive(Debug, Clone)]
401pub struct LocalVarTargetTable {
402    pub start_pc: U2,
403    pub length: U2,
404    pub index: U2,
405}
406
407#[derive(Debug, Clone)]
408pub struct TypePath {
409    pub type_path_kind: U1,
410    pub type_argument_index: U1,
411}
412
413#[derive(Debug, Clone)]
414pub struct EnclosingMethod {
415    pub class_index: U2,
416    pub method_index: U2,
417}