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 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}