phoron_core/
deserializer.rs

1//! Module to read a Java (JVM) class file and construct the object model from the raw bytes.
2
3use crate::{
4    error::DeserializeError,
5    model::{
6        attributes::*,
7        constant_pool::{tags::*, types::CpInfo},
8        ClassFile, FieldInfo, MethodInfo,
9    },
10    rw::reader::Reader,
11};
12use std::io::Read;
13
14pub type DeserializeResult<T> = Result<T, DeserializeError>;
15
16/// The Deserializer reads a class file byte stream and converts it into the
17/// object model repreensting the class file.
18pub struct Deserializer<R: Read> {
19    reader: Reader<R>,
20}
21
22impl<R: Read> Deserializer<R> {
23    pub fn new(reader: Reader<R>) -> Self {
24        Deserializer { reader }
25    }
26
27    fn deserialize_target_info(&mut self, target_type: u8) -> DeserializeResult<TargetInfo> {
28        let target_info = match target_type {
29            0x00 | 0x01 => {
30                let type_parameter_index = self.reader.read_unsigned_byte()?;
31                TargetInfo::TypeParameterTarget {
32                    type_parameter_index,
33                }
34            }
35
36            0x10 => {
37                let supertype_index = self.reader.read_unsigned_short()?;
38                TargetInfo::SuperTypeTarget { supertype_index }
39            }
40
41            0x11 | 0x12 => {
42                let type_parameter_index = self.reader.read_unsigned_byte()?;
43                let bound_index = self.reader.read_unsigned_byte()?;
44
45                TargetInfo::TypeParameterBoundTarget {
46                    type_parameter_index,
47                    bound_index,
48                }
49            }
50
51            0x13 | 0x14 | 0x15 => TargetInfo::EmptyTarget,
52            0x16 => {
53                let formal_parameter_index = self.reader.read_unsigned_byte()?;
54                TargetInfo::FormalParameterTarget {
55                    formal_parameter_index,
56                }
57            }
58            0x17 => {
59                let throws_type_index = self.reader.read_unsigned_short()?;
60                TargetInfo::ThrowsTarget { throws_type_index }
61            }
62
63            0x40 | 0x41 => {
64                let table_length = self.reader.read_unsigned_short()?;
65
66                let mut table = Vec::new();
67                for _ in 0..table_length {
68                    let start_pc = self.reader.read_unsigned_short()?;
69                    let length = self.reader.read_unsigned_short()?;
70                    let index = self.reader.read_unsigned_short()?;
71                    table.push(LocalVarEntry {
72                        start_pc,
73                        length,
74                        index,
75                    });
76                }
77                TargetInfo::LocalVarTarget {
78                    table_length,
79                    table,
80                }
81            }
82
83            0x42 => {
84                let exception_table_index = self.reader.read_unsigned_short()?;
85                TargetInfo::CatchTarget {
86                    exception_table_index,
87                }
88            }
89            043 | 0x44 | 0x45 | 0x46 => {
90                let offset = self.reader.read_unsigned_short()?;
91                TargetInfo::OffsetTarget { offset }
92            }
93
94            0x47 | 0x48 | 0x49 | 0x4A | 0x4B => {
95                let offset = self.reader.read_unsigned_short()?;
96                let type_argument_index = self.reader.read_unsigned_byte()?;
97                TargetInfo::TypeArgumentTarget {
98                    offset,
99                    type_argument_index,
100                }
101            }
102            _ => unreachable!(),
103        };
104
105        Ok(target_info)
106    }
107
108    fn deserialize_type_path(&mut self) -> DeserializeResult<TypePath> {
109        let path_length = self.reader.read_unsigned_byte()?;
110
111        let mut path = Vec::new();
112        for _ in 0..path_length {
113            let type_path_kind = self.reader.read_unsigned_byte()?;
114            let type_argument_index = self.reader.read_unsigned_byte()?;
115            path.push(Path {
116                type_path_kind,
117                type_argument_index,
118            });
119        }
120
121        Ok(TypePath { path_length, path })
122    }
123
124    fn deserialize_type_annotation(&mut self) -> DeserializeResult<TypeAnnotation> {
125        let target_type = self.reader.read_unsigned_byte()?;
126        let target_info = self.deserialize_target_info(target_type)?;
127        let target_path = self.deserialize_type_path()?;
128        let type_index = self.reader.read_unsigned_short()?;
129
130        let num_element_value_pairs = self.reader.read_unsigned_short()?;
131        let mut element_value_pairs = Vec::new();
132        for _ in 0..num_element_value_pairs {
133            element_value_pairs.push(self.deserialize_element_value_pair()?);
134        }
135
136        Ok(TypeAnnotation {
137            target_type,
138            target_info,
139            target_path,
140            type_index,
141            num_element_value_pairs,
142            element_value_pairs,
143        })
144    }
145
146    fn deserialize_element_value(&mut self) -> DeserializeResult<ElementValue> {
147        let tag = self.reader.read_unsigned_byte()?;
148        let element_value = match tag {
149            // byte
150            b'B' | b'C' | b'D' | b'F' | b'I' | b'J' | b'S' | b'Z' | b's' => {
151                let const_value_index = self.reader.read_unsigned_short()?;
152                ElementValue::ConstValueIndex {
153                    tag,
154                    const_value_index,
155                }
156            }
157            b'e' => {
158                let type_name_index = self.reader.read_unsigned_short()?;
159                let const_name_index = self.reader.read_unsigned_short()?;
160                ElementValue::EnumConstValue {
161                    tag,
162                    type_name_index,
163                    const_name_index,
164                }
165            }
166
167            b'c' => {
168                let class_info_index = self.reader.read_unsigned_short()?;
169                ElementValue::ClassInfoIndex {
170                    tag,
171                    class_info_index,
172                }
173            }
174
175            b'@' => {
176                let annotation = self.deserialize_annotation()?;
177                ElementValue::AnnotationValue { tag, annotation }
178            }
179
180            b'[' => {
181                let num_values = self.reader.read_unsigned_short()?;
182                let mut values = Vec::new();
183                for _ in 0..num_values {
184                    values.push(self.deserialize_element_value()?);
185                }
186
187                ElementValue::ArrayValue {
188                    tag,
189                    num_values,
190                    values,
191                }
192            }
193            _ => unreachable!(),
194        };
195
196        Ok(element_value)
197    }
198
199    fn deserialize_element_value_pair(&mut self) -> DeserializeResult<ElementValuePair> {
200        let element_name_index = self.reader.read_unsigned_short()?;
201        let value = self.deserialize_element_value()?;
202
203        Ok(ElementValuePair {
204            element_name_index,
205            value,
206        })
207    }
208
209    fn deserialize_annotation(&mut self) -> DeserializeResult<Annotation> {
210        let type_index = self.reader.read_unsigned_short()?;
211
212        let num_element_value_pairs = self.reader.read_unsigned_short()?;
213        let mut element_value_pairs = Vec::new();
214        for _ in 0..num_element_value_pairs {
215            element_value_pairs.push(self.deserialize_element_value_pair()?);
216        }
217
218        Ok(Annotation {
219            type_index,
220            num_element_value_pairs,
221            element_value_pairs,
222        })
223    }
224
225    fn deserialize_verification_type_info(&mut self) -> DeserializeResult<VerificationTypeInfo> {
226        let tag = self.reader.read_unsigned_byte()?;
227        let ver_type_info = match tag {
228            0x00 => VerificationTypeInfo::TopVariableInfo { tag },
229            0x01 => VerificationTypeInfo::IntegerVariableInfo { tag },
230            0x02 => VerificationTypeInfo::FloatVariableInfo { tag },
231            0x03 => VerificationTypeInfo::DoubleVariableInfo { tag },
232            0x04 => VerificationTypeInfo::LongVariableInfo { tag },
233            0x05 => VerificationTypeInfo::NullVariableInfo { tag },
234            0x06 => VerificationTypeInfo::UninitializedThisVariableInfo { tag },
235            0x07 => {
236                let cpool_index = self.reader.read_unsigned_short()?;
237                VerificationTypeInfo::ObjectVariableInfo { tag, cpool_index }
238            }
239            0x08 => {
240                let offset = self.reader.read_unsigned_short()?;
241                VerificationTypeInfo::UninitializedVariableInfo { tag, offset }
242            }
243            _ => unreachable!(),
244        };
245
246        Ok(ver_type_info)
247    }
248
249    /// Deserialize the attributes of the class file.
250    fn deserialize_attributes(
251        &mut self,
252        attributes_count: u16,
253        constant_pool: &Vec<Option<CpInfo>>,
254    ) -> DeserializeResult<Vec<AttributeInfo>> {
255        let mut attributes = Vec::new();
256
257        for _ in 0..attributes_count {
258            let attribute_name_index = self.reader.read_unsigned_short()?;
259            let attribute_length = self.reader.read_unsigned_int()?;
260
261            match &constant_pool[attribute_name_index as usize] {
262                Some(CpInfo::ConstantUtf8Info { bytes, .. }) => {
263                    match String::from_utf8_lossy(bytes).into_owned().as_str() {
264                        predefined_attributes::SOURCE_FILE => {
265                            let sourcefile_index = self.reader.read_unsigned_short()?;
266                            attributes.push(AttributeInfo::SourceFile {
267                                attribute_name_index,
268                                attribute_length,
269                                sourcefile_index,
270                            });
271                        }
272
273                        predefined_attributes::CONSTANT_VALUE => {
274                            let constantvalue_index = self.reader.read_unsigned_short()?;
275                            attributes.push(AttributeInfo::ConstantValue {
276                                attribute_name_index,
277                                attribute_length,
278                                constantvalue_index,
279                            });
280                        }
281
282                        predefined_attributes::CODE => {
283                            let max_stack = self.reader.read_unsigned_short()?;
284                            let max_locals = self.reader.read_unsigned_short()?;
285
286                            let code_length = self.reader.read_unsigned_int()?;
287                            assert!(code_length > 0);
288                            let mut code = Vec::new();
289                            for _ in 0..code_length {
290                                code.push(self.reader.read_unsigned_byte()?);
291                            }
292
293                            let exception_table_length = self.reader.read_unsigned_short()?;
294                            let mut exception_table = Vec::new();
295                            for _ in 0..exception_table_length {
296                                let start_pc = self.reader.read_unsigned_short()?;
297                                let end_pc = self.reader.read_unsigned_short()?;
298                                let handler_pc = self.reader.read_unsigned_short()?;
299                                let mut catch_type = self.reader.read_unsigned_short()?;
300
301                                if catch_type != 0 {
302                                    catch_type -= 1;
303                                }
304
305                                exception_table.push(ExceptionHandler {
306                                    start_pc,
307                                    end_pc,
308                                    handler_pc,
309                                    catch_type,
310                                });
311                            }
312
313                            let code_attributes_count = self.reader.read_unsigned_short()?;
314                            let code_attributes =
315                                self.deserialize_attributes(code_attributes_count, constant_pool)?;
316                            attributes.push(AttributeInfo::Code {
317                                attribute_name_index,
318                                attribute_length,
319                                max_stack,
320                                max_locals,
321                                code_length,
322                                code,
323                                exception_table_length,
324                                exception_table,
325                                code_attributes_count,
326                                code_attributes,
327                            });
328                        }
329
330                        predefined_attributes::EXCEPTIONS => {
331                            let number_of_exceptions = self.reader.read_unsigned_short()?;
332                            let mut exception_index_table =
333                                Vec::with_capacity(number_of_exceptions as usize);
334
335                            for _ in 0..number_of_exceptions {
336                                let mut idx = self.reader.read_unsigned_short()?;
337                                if idx != 0 {
338                                    idx -= 1;
339                                }
340                                exception_index_table.push(idx);
341                            }
342                            attributes.push(AttributeInfo::Exceptions {
343                                attribute_name_index,
344                                attribute_length,
345                                number_of_exceptions,
346                                exception_index_table,
347                            });
348                        }
349
350                        predefined_attributes::LINE_NUMBER_TABLE => {
351                            let line_number_table_length = self.reader.read_unsigned_short()?;
352                            let mut line_number_table =
353                                Vec::with_capacity(line_number_table_length as usize);
354
355                            for _ in 0..line_number_table_length {
356                                let start_pc = self.reader.read_unsigned_short()?;
357                                let line_number = self.reader.read_unsigned_short()?;
358                                line_number_table.push(LineNumber {
359                                    start_pc,
360                                    line_number,
361                                });
362                            }
363
364                            attributes.push(AttributeInfo::LineNumberTable {
365                                attribute_name_index,
366                                attribute_length,
367                                line_number_table_length,
368                                line_number_table,
369                            });
370                        }
371
372                        predefined_attributes::LOCAL_VARIABLE_TABLE => {
373                            let local_variable_table_length = self.reader.read_unsigned_short()?;
374                            let mut local_variable_table =
375                                Vec::with_capacity(local_variable_table_length as usize);
376
377                            for _ in 0..local_variable_table_length {
378                                let start_pc = self.reader.read_unsigned_short()?;
379                                let length = self.reader.read_unsigned_short()?;
380                                let name_index = self.reader.read_unsigned_short()?;
381                                let descriptor_index = self.reader.read_unsigned_short()?;
382                                let index = self.reader.read_unsigned_short()?;
383
384                                local_variable_table.push(LocalVariable {
385                                    start_pc,
386                                    length,
387                                    name_index,
388                                    descriptor_index,
389                                    index,
390                                });
391                            }
392
393                            attributes.push(AttributeInfo::LocalVariableTable {
394                                attribute_name_index,
395                                attribute_length,
396                                local_variable_table_length,
397                                local_variable_table,
398                            });
399                        }
400
401                        predefined_attributes::STACK_MAP_TABLE => {
402                            let number_of_entries = self.reader.read_unsigned_short()?;
403                            let mut entries = Vec::new();
404                            for _ in 0..number_of_entries {
405                                let frame_type = self.reader.read_unsigned_byte()?;
406
407                                let frame = match frame_type {
408                                    // 0 - 63
409                                    0x00..=0x3f => StackMapFrame::SameFrame { frame_type },
410                                    // 64 - 127
411                                    0x40..=0x7f => {
412                                        let mut stack = Vec::with_capacity(1);
413                                        stack.push(self.deserialize_verification_type_info()?);
414                                        StackMapFrame::SameLocals1StackItemFrame {
415                                            frame_type,
416                                            stack,
417                                        }
418                                    }
419
420                                    // 128 - 246 are reserved
421                                    0x80..=0xf6 => unreachable!(),
422
423                                    0xf7 => {
424                                        let offset_delta = self.reader.read_unsigned_short()?;
425                                        let mut stack = Vec::with_capacity(1);
426                                        stack.push(self.deserialize_verification_type_info()?);
427
428                                        StackMapFrame::SameLocals1StackItemFrameExtended {
429                                            frame_type,
430                                            offset_delta,
431                                            stack,
432                                        }
433                                    }
434
435                                    // 248 - 250
436                                    0xf8..=0xfa => {
437                                        let offset_delta = self.reader.read_unsigned_short()?;
438                                        StackMapFrame::ChopFrame {
439                                            frame_type,
440                                            offset_delta,
441                                        }
442                                    }
443
444                                    // 251
445                                    0xfb => {
446                                        let offset_delta = self.reader.read_unsigned_short()?;
447                                        StackMapFrame::SameFrameExtended {
448                                            frame_type,
449                                            offset_delta,
450                                        }
451                                    }
452
453                                    0xfc..=0xfe => {
454                                        let offset_delta = self.reader.read_unsigned_short()?;
455                                        let mut locals = Vec::with_capacity(1);
456                                        locals.push(self.deserialize_verification_type_info()?);
457
458                                        StackMapFrame::AppendFrame {
459                                            frame_type,
460                                            offset_delta,
461                                            locals,
462                                        }
463                                    }
464
465                                    // 255
466                                    0xff => {
467                                        let offset_delta = self.reader.read_unsigned_short()?;
468                                        let number_of_locals = self.reader.read_unsigned_short()?;
469
470                                        let mut locals =
471                                            Vec::with_capacity(number_of_locals as usize);
472                                        for _ in 0..number_of_locals {
473                                            locals.push(self.deserialize_verification_type_info()?);
474                                        }
475
476                                        let number_of_stack_items =
477                                            self.reader.read_unsigned_short()?;
478                                        let mut stack =
479                                            Vec::with_capacity(number_of_stack_items as usize);
480                                        for _ in 0..number_of_stack_items {
481                                            stack.push(self.deserialize_verification_type_info()?);
482                                        }
483
484                                        StackMapFrame::FullFrame {
485                                            frame_type,
486                                            offset_delta,
487                                            number_of_locals,
488                                            locals,
489                                            number_of_stack_items,
490                                            stack,
491                                        }
492                                    }
493                                };
494                                entries.push(frame);
495                            }
496
497                            attributes.push(AttributeInfo::StackMapTable {
498                                attribute_name_index,
499                                attribute_length,
500                                number_of_entries,
501                                entries,
502                            });
503                        }
504                        predefined_attributes::INNER_CLASSES => {
505                            let number_of_classes = self.reader.read_unsigned_short()?;
506
507                            let mut classes = Vec::new();
508                            for _ in 0..number_of_classes {
509                                let inner_class_info_index = self.reader.read_unsigned_short()?;
510                                let outer_class_info_index = self.reader.read_unsigned_short()?;
511                                let inner_name_index = self.reader.read_unsigned_short()?;
512                                let inner_class_access_flags = self.reader.read_unsigned_short()?;
513                                classes.push(Class {
514                                    inner_class_info_index,
515                                    outer_class_info_index,
516                                    inner_name_index,
517                                    inner_class_access_flags,
518                                });
519                            }
520
521                            attributes.push(AttributeInfo::InnerClasses {
522                                attribute_name_index,
523                                attribute_length,
524                                number_of_classes,
525                                classes,
526                            });
527                        }
528
529                        predefined_attributes::ENCLOSING_METHOD => {
530                            let class_index = self.reader.read_unsigned_short()?;
531                            let method_index = self.reader.read_unsigned_short()?;
532                            attributes.push(AttributeInfo::EnclosingMethod {
533                                attribute_name_index,
534                                attribute_length,
535                                class_index,
536                                method_index,
537                            });
538                        }
539
540                        predefined_attributes::SYNTHETIC => {
541                            attributes.push(AttributeInfo::Synthetic {
542                                attribute_name_index,
543                                attribute_length,
544                            });
545                        }
546
547                        predefined_attributes::SIGNATURE => {
548                            let signature_index = self.reader.read_unsigned_short()?;
549                            attributes.push(AttributeInfo::Signature {
550                                attribute_name_index,
551                                attribute_length,
552                                signature_index,
553                            });
554                        }
555
556                        predefined_attributes::SOURCE_DEBUG_EXTENSION => {
557                            let mut debug_extension = Vec::new();
558                            for _ in 0..attribute_length {
559                                debug_extension.push(self.reader.read_unsigned_byte()?);
560                            }
561                            attributes.push(AttributeInfo::SourceDebugExtension {
562                                attribute_name_index,
563                                attribute_length,
564                                debug_extension,
565                            });
566                        }
567
568                        predefined_attributes::LOCAL_VARIABLE_TYPE_TABLE => {
569                            let local_variable_type_table_length =
570                                self.reader.read_unsigned_short()?;
571
572                            let mut local_variable_type_table = Vec::new();
573                            for _ in 0..local_variable_type_table_length {
574                                let start_pc = self.reader.read_unsigned_short()?;
575                                let length = self.reader.read_unsigned_short()?;
576                                let name_index = self.reader.read_unsigned_short()?;
577                                let signature_index = self.reader.read_unsigned_short()?;
578                                let index = self.reader.read_unsigned_short()?;
579
580                                local_variable_type_table.push(LocalVariableType {
581                                    start_pc,
582                                    length,
583                                    name_index,
584                                    signature_index,
585                                    index,
586                                });
587                            }
588
589                            attributes.push(AttributeInfo::LocalVariableTypeTable {
590                                attribute_name_index,
591                                attribute_length,
592                                local_variable_type_table_length,
593                                local_variable_type_table,
594                            });
595                        }
596
597                        predefined_attributes::DEPRECATED => {
598                            attributes.push(AttributeInfo::Deprecated {
599                                attribute_name_index,
600                                attribute_length,
601                            });
602                        }
603
604                        predefined_attributes::RUNTIME_VISIBLE_ANNOTATIONS => {
605                            let num_annotations = self.reader.read_unsigned_short()?;
606
607                            let mut annotations = Vec::new();
608                            for _ in 0..num_annotations {
609                                annotations.push(self.deserialize_annotation()?);
610                            }
611
612                            attributes.push(AttributeInfo::RuntimeVisibleAnnotations {
613                                attribute_name_index,
614                                attribute_length,
615                                num_annotations,
616                                annotations,
617                            });
618                        }
619
620                        predefined_attributes::RUNTIME_INVISIBLE_ANNOTATIONS => {
621                            let num_annotations = self.reader.read_unsigned_short()?;
622
623                            let mut annotations = Vec::new();
624                            for _ in 0..num_annotations {
625                                annotations.push(self.deserialize_annotation()?);
626                            }
627
628                            attributes.push(AttributeInfo::RuntimeInvisibleAnnotations {
629                                attribute_name_index,
630                                attribute_length,
631                                num_annotations,
632                                annotations,
633                            });
634                        }
635
636                        predefined_attributes::RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS => {
637                            let num_parameters = self.reader.read_unsigned_byte()?;
638
639                            let mut parameter_annotations = Vec::new();
640                            for _ in 0..num_parameters {
641                                let num_annotations = self.reader.read_unsigned_short()?;
642                                let mut annotations = Vec::new();
643                                for _ in 0..num_annotations {
644                                    annotations.push(self.deserialize_annotation()?);
645                                }
646                                parameter_annotations.push(ParameterAnnotation {
647                                    num_annotations,
648                                    annotations,
649                                });
650                            }
651
652                            attributes.push(AttributeInfo::RuntimeVisibleParameterAnnotations {
653                                attribute_name_index,
654                                attribute_length,
655                                num_parameters,
656                                parameter_annotations,
657                            });
658                        }
659
660                        predefined_attributes::RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS => {
661                            let num_parameters = self.reader.read_unsigned_byte()?;
662
663                            let mut parameter_annotations = Vec::new();
664                            for _ in 0..num_parameters {
665                                let num_annotations = self.reader.read_unsigned_short()?;
666                                let mut annotations = Vec::new();
667                                for _ in 0..num_annotations {
668                                    annotations.push(self.deserialize_annotation()?);
669                                }
670                                parameter_annotations.push(ParameterAnnotation {
671                                    num_annotations,
672                                    annotations,
673                                });
674                            }
675
676                            attributes.push(AttributeInfo::RuntimeInvisibleParameterAnnotations {
677                                attribute_name_index,
678                                attribute_length,
679                                num_parameters,
680                                parameter_annotations,
681                            });
682                        }
683
684                        predefined_attributes::RUNTIME_VISIBLE_TYPE_ANNOTATIONS => {
685                            let num_annotations = self.reader.read_unsigned_short()?;
686
687                            let mut annotations = Vec::new();
688                            for _ in 0..num_annotations {
689                                annotations.push(self.deserialize_type_annotation()?);
690                            }
691
692                            attributes.push(AttributeInfo::RuntimeVisibleTypeAnnotations {
693                                attribute_name_index,
694                                attribute_length,
695                                num_annotations,
696                                annotations,
697                            })
698                        }
699
700                        predefined_attributes::RUNTIME_INVISIBLE_TYPE_ANNOTATIONS => {
701                            let num_annotations = self.reader.read_unsigned_short()?;
702
703                            let mut annotations = Vec::new();
704                            for _ in 0..num_annotations {
705                                annotations.push(self.deserialize_type_annotation()?);
706                            }
707
708                            attributes.push(AttributeInfo::RuntimeInvisibleTypeAnnotations {
709                                attribute_name_index,
710                                attribute_length,
711                                num_annotations,
712                                annotations,
713                            })
714                        }
715
716                        predefined_attributes::ANNOTATION_DEFAULT => {
717                            let default_value = self.deserialize_element_value()?;
718                            attributes.push(AttributeInfo::AnnotationDefault {
719                                attribute_name_index,
720                                attribute_length,
721                                default_value,
722                            });
723                        }
724
725                        predefined_attributes::BOOTSTRAP_METHODS => {
726                            let num_bootstrap_methods = self.reader.read_unsigned_short()?;
727
728                            let mut bootstrap_methods = Vec::new();
729                            for _ in 0..num_bootstrap_methods {
730                                let bootstrap_method_ref = self.reader.read_unsigned_short()?;
731
732                                let num_bootstrap_arguments = self.reader.read_unsigned_short()?;
733                                let mut bootstrap_arguments = Vec::new();
734                                for _ in 0..num_bootstrap_arguments {
735                                    bootstrap_arguments.push(self.reader.read_unsigned_short()?);
736                                }
737
738                                bootstrap_methods.push(BootstrapMethod {
739                                    bootstrap_method_ref,
740                                    num_bootstrap_arguments,
741                                    bootstrap_arguments,
742                                });
743                            }
744
745                            attributes.push(AttributeInfo::BootstrapMethods {
746                                attribute_name_index,
747                                attribute_length,
748                                num_bootstrap_methods,
749                                bootstrap_methods,
750                            });
751                        }
752
753                        predefined_attributes::METHOD_PARAMETERS => {
754                            let parameters_count = self.reader.read_unsigned_byte()?;
755
756                            let mut parameters = Vec::new();
757                            for _ in 0..parameters_count {
758                                let name_index = self.reader.read_unsigned_short()?;
759                                let access_flags = self.reader.read_unsigned_short()?;
760                                parameters.push(Parameter {
761                                    name_index,
762                                    access_flags,
763                                });
764                            }
765
766                            attributes.push(AttributeInfo::MethodParameters {
767                                attribute_name_index,
768                                attribute_length,
769                                parameters_count,
770                                parameters,
771                            });
772                        }
773
774                        predefined_attributes::MODULE => {
775                            let module_name_index = self.reader.read_unsigned_short()?;
776                            let module_flags = self.reader.read_unsigned_short()?;
777                            let module_version_index = self.reader.read_unsigned_short()?;
778
779                            let requires_count = self.reader.read_unsigned_short()?;
780                            let mut requires = Vec::new();
781                            for _ in 0..requires_count {
782                                let requires_index = self.reader.read_unsigned_short()?;
783                                let requires_flags = self.reader.read_unsigned_short()?;
784                                let requires_version_index = self.reader.read_unsigned_short()?;
785
786                                requires.push(Require {
787                                    requires_index,
788                                    requires_flags,
789                                    requires_version_index,
790                                });
791                            }
792
793                            let exports_count = self.reader.read_unsigned_short()?;
794                            let mut exports = Vec::new();
795                            for _ in 0..exports_count {
796                                let exports_index = self.reader.read_unsigned_short()?;
797                                let exports_flags = self.reader.read_unsigned_short()?;
798
799                                let exports_to_count = self.reader.read_unsigned_short()?;
800                                let mut exports_to_index = Vec::new();
801                                for _ in 0..exports_to_count {
802                                    exports_to_index.push(self.reader.read_unsigned_short()?);
803                                }
804
805                                exports.push(Export {
806                                    exports_index,
807                                    exports_flags,
808                                    exports_to_count,
809                                    exports_to_index,
810                                });
811                            }
812
813                            let opens_count = self.reader.read_unsigned_short()?;
814                            let mut opens = Vec::new();
815                            for _ in 0..opens_count {
816                                let opens_index = self.reader.read_unsigned_short()?;
817                                let opens_flags = self.reader.read_unsigned_short()?;
818
819                                let opens_to_count = self.reader.read_unsigned_short()?;
820                                let mut opens_to_index = Vec::new();
821                                for _ in 0..opens_to_count {
822                                    opens_to_index.push(self.reader.read_unsigned_short()?);
823                                }
824
825                                opens.push(Open {
826                                    opens_index,
827                                    opens_flags,
828                                    opens_to_count,
829                                    opens_to_index,
830                                });
831                            }
832
833                            let uses_count = self.reader.read_unsigned_short()?;
834                            let mut uses_index = Vec::new();
835                            for _ in 0..uses_count {
836                                uses_index.push(self.reader.read_unsigned_short()?);
837                            }
838
839                            let provides_count = self.reader.read_unsigned_short()?;
840                            let mut provides = Vec::new();
841                            for _ in 0..provides_count {
842                                let provides_index = self.reader.read_unsigned_short()?;
843
844                                let provides_with_count = self.reader.read_unsigned_short()?;
845                                let mut provides_with_index = Vec::new();
846                                for _ in 0..provides_with_count {
847                                    provides_with_index.push(self.reader.read_unsigned_short()?);
848                                }
849
850                                provides.push(Provide {
851                                    provides_index,
852                                    provides_with_count,
853                                    provides_with_index,
854                                });
855                            }
856                            attributes.push(AttributeInfo::Module {
857                                attribute_name_index,
858                                attribute_length,
859                                module_name_index,
860                                module_flags,
861                                module_version_index,
862                                requires_count,
863                                requires,
864                                exports_count,
865                                exports,
866                                opens_count,
867                                opens,
868                                uses_count,
869                                uses_index,
870                                provides_count,
871                                provides,
872                            })
873                        }
874
875                        predefined_attributes::MODULE_PACKAGES => {
876                            let package_count = self.reader.read_unsigned_short()?;
877                            let mut package_index = Vec::new();
878                            for _ in 0..package_count {
879                                package_index.push(self.reader.read_unsigned_short()?);
880                            }
881
882                            attributes.push(AttributeInfo::ModulePackages {
883                                attribute_name_index,
884                                attribute_length,
885                                package_count,
886                                package_index,
887                            });
888                        }
889
890                        predefined_attributes::MODULE_MAIN_CLASS => {
891                            let main_class_index = self.reader.read_unsigned_short()?;
892                            attributes.push(AttributeInfo::ModuleMainClass {
893                                attribute_name_index,
894                                attribute_length,
895                                main_class_index,
896                            });
897                        }
898
899                        predefined_attributes::NEST_HOST => {
900                            let host_class_index = self.reader.read_unsigned_short()?;
901                            attributes.push(AttributeInfo::NestHost {
902                                attribute_name_index,
903                                attribute_length,
904                                host_class_index,
905                            });
906                        }
907
908                        predefined_attributes::NEST_MEMBERS => {
909                            let number_of_classes = self.reader.read_unsigned_short()?;
910                            let mut classes = Vec::new();
911                            for _ in 0..number_of_classes {
912                                classes.push(self.reader.read_unsigned_short()?);
913                            }
914                            attributes.push(AttributeInfo::NestMembers {
915                                attribute_name_index,
916                                attribute_length,
917                                number_of_classes,
918                                classes,
919                            });
920                        }
921
922                        predefined_attributes::RECORD => {
923                            let components_count = self.reader.read_unsigned_short()?;
924                            let mut components = Vec::new();
925                            for _ in 0..components_count {
926                                let name_index = self.reader.read_unsigned_short()?;
927                                let descriptor_index = self.reader.read_unsigned_short()?;
928
929                                let attributes_count = self.reader.read_unsigned_short()?;
930                                let attributes =
931                                    self.deserialize_attributes(attributes_count, constant_pool)?;
932
933                                components.push(RecordComponentInfo {
934                                    name_index,
935                                    descriptor_index,
936                                    attributes_count,
937                                    attributes,
938                                });
939                            }
940
941                            attributes.push(AttributeInfo::Record {
942                                attribute_name_index,
943                                attribute_length,
944                                components_count,
945                                components,
946                            });
947                        }
948
949                        predefined_attributes::PERMITTED_SUBCLASSES => {
950                            let number_of_classes = self.reader.read_unsigned_short()?;
951                            let mut classes = Vec::new();
952                            for _ in 0..number_of_classes {
953                                classes.push(self.reader.read_unsigned_short()?);
954                            }
955
956                            attributes.push(AttributeInfo::PermittedSubclasses {
957                                attribute_name_index,
958                                attribute_length,
959                                number_of_classes,
960                                classes,
961                            });
962                        }
963
964                        _ => {
965                            // simply read the bytes and discard for any unknown attributes
966                            // for now - look into providing a pluggable way to store and
967                            // query for custom attributes.
968                            for _ in 0..attribute_length {
969                                let _ = self.reader.read_unsigned_byte()?;
970                            }
971                        }
972                    }
973                }
974                _ => unreachable!(),
975            }
976        }
977
978        Ok(attributes)
979    }
980
981    /// Deserialize the fields of the class file.
982    fn deserialize_fields(
983        &mut self,
984        fields_count: u16,
985        constant_pool: &Vec<Option<CpInfo>>,
986    ) -> DeserializeResult<Vec<FieldInfo>> {
987        let mut fields = Vec::new();
988        for _ in 0..fields_count {
989            let access_flags = self.reader.read_unsigned_short()?;
990            let name_index = self.reader.read_unsigned_short()?;
991            let descriptor_index = self.reader.read_unsigned_short()?;
992            let attributes_count = self.reader.read_unsigned_short()?;
993
994            let attributes = self.deserialize_attributes(attributes_count, constant_pool)?;
995            fields.push(FieldInfo {
996                access_flags,
997                name_index,
998                descriptor_index,
999                attributes_count,
1000                attributes,
1001            });
1002        }
1003
1004        Ok(fields)
1005    }
1006
1007    /// Deserialize the methods of the class file.
1008    fn deserialize_methods(
1009        &mut self,
1010        methods_count: u16,
1011        constant_pool: &Vec<Option<CpInfo>>,
1012    ) -> DeserializeResult<Vec<MethodInfo>> {
1013        let mut methods = Vec::new();
1014
1015        for _ in 0..methods_count {
1016            let access_flags = self.reader.read_unsigned_short()?;
1017            let name_index = self.reader.read_unsigned_short()?;
1018            let descriptor_index = self.reader.read_unsigned_short()?;
1019            let attributes_count = self.reader.read_unsigned_short()?;
1020
1021            let attributes = self.deserialize_attributes(attributes_count, constant_pool)?;
1022            methods.push(MethodInfo {
1023                access_flags,
1024                name_index,
1025                descriptor_index,
1026                attributes_count,
1027                attributes,
1028            });
1029        }
1030
1031        Ok(methods)
1032    }
1033
1034    /// Deserialize the contents of the Constant Pool.
1035    fn deserialize_constant_pool(
1036        &mut self,
1037        constant_pool_count: u16,
1038    ) -> DeserializeResult<Vec<Option<CpInfo>>> {
1039        let mut constant_pool = vec![None; constant_pool_count as usize];
1040        let mut cp_idx = 1usize; // the first cell is not used
1041
1042        while cp_idx < constant_pool_count as usize {
1043            let tag = self.reader.read_unsigned_byte()?;
1044
1045            match tag {
1046                CONSTANT_METHOD_REF => {
1047                    let class_index = self.reader.read_unsigned_short()?;
1048                    let name_and_type_index = self.reader.read_unsigned_short()?;
1049                    constant_pool[cp_idx] = Some(CpInfo::ConstantMethodrefInfo {
1050                        tag,
1051                        class_index,
1052                        name_and_type_index,
1053                    });
1054                }
1055
1056                CONSTANT_CLASS => {
1057                    let name_index = self.reader.read_unsigned_short()?;
1058                    constant_pool[cp_idx] = Some(CpInfo::ConstantClassInfo { tag, name_index });
1059                }
1060
1061                CONSTANT_FIELD_REF => {
1062                    let class_index = self.reader.read_unsigned_short()?;
1063                    let name_and_type_index = self.reader.read_unsigned_short()?;
1064                    constant_pool[cp_idx] = Some(CpInfo::ConstantFieldrefInfo {
1065                        tag,
1066                        class_index,
1067                        name_and_type_index,
1068                    });
1069                }
1070
1071                CONSTANT_INTERFACE_METHOD_REF => {
1072                    let class_index = self.reader.read_unsigned_short()?;
1073                    let name_and_type_index = self.reader.read_unsigned_short()?;
1074                    constant_pool[cp_idx] = Some(CpInfo::ConstantInterfaceMethodrefInfo {
1075                        tag,
1076                        class_index,
1077                        name_and_type_index,
1078                    });
1079                }
1080
1081                CONSTANT_STRING => {
1082                    let string_index = self.reader.read_unsigned_short()?;
1083                    constant_pool[cp_idx] = Some(CpInfo::ConstantStringInfo { tag, string_index });
1084                }
1085
1086                CONSTANT_INTEGER => {
1087                    let bytes = self.reader.read_unsigned_int()?;
1088                    constant_pool[cp_idx] = Some(CpInfo::ConstantIntegerInfo { tag, bytes });
1089                }
1090
1091                CONSTANT_FLOAT => {
1092                    let bytes = self.reader.read_unsigned_int()?;
1093                    constant_pool[cp_idx] = Some(CpInfo::ConstantFloatInfo { tag, bytes });
1094                }
1095
1096                CONSTANT_LONG => {
1097                    let high_bytes = self.reader.read_unsigned_int()?;
1098                    let low_bytes = self.reader.read_unsigned_int()?;
1099                    constant_pool[cp_idx] = Some(CpInfo::ConstantLongInfo {
1100                        tag,
1101                        high_bytes,
1102                        low_bytes,
1103                    });
1104
1105                    // Long values take up two consecutive entries in the Constant Pool.
1106                    cp_idx += 1;
1107                }
1108
1109                CONSTANT_DOUBLE => {
1110                    let high_bytes = self.reader.read_unsigned_int()?;
1111                    let low_bytes = self.reader.read_unsigned_int()?;
1112                    constant_pool[cp_idx] = Some(CpInfo::ConstantDoubleInfo {
1113                        tag,
1114                        high_bytes,
1115                        low_bytes,
1116                    });
1117
1118                    // Double values take up two consuective entries in the Constant Pool.
1119                    cp_idx += 1;
1120                }
1121
1122                CONSTANT_NAME_AND_TYPE => {
1123                    let name_index = self.reader.read_unsigned_short()?;
1124                    let descriptor_index = self.reader.read_unsigned_short()?;
1125                    constant_pool[cp_idx] = Some(CpInfo::ConstantNameAndTypeInfo {
1126                        tag,
1127                        name_index,
1128                        descriptor_index,
1129                    });
1130                }
1131
1132                CONSTANT_UTF8 => {
1133                    let length = self.reader.read_unsigned_short()?;
1134                    let mut bytes = Vec::new();
1135                    for _ in 0..length {
1136                        bytes.push(self.reader.read_unsigned_byte()?);
1137                    }
1138
1139                    constant_pool[cp_idx] = Some(CpInfo::ConstantUtf8Info { tag, length, bytes });
1140                }
1141
1142                CONSTANT_METHOD_HANDLE => {
1143                    let reference_kind = self.reader.read_unsigned_byte()?;
1144                    let reference_index = self.reader.read_unsigned_short()?;
1145                    constant_pool.push(Some(CpInfo::ConstantMethodHandleInfo {
1146                        tag,
1147                        reference_kind,
1148                        reference_index,
1149                    }));
1150                }
1151
1152                CONSTANT_METHOD_TYPE => {
1153                    let descriptor_index = self.reader.read_unsigned_short()?;
1154                    constant_pool.push(Some(CpInfo::ConstantMethodTypeInfo {
1155                        tag,
1156                        descriptor_index,
1157                    }));
1158                }
1159
1160                CONSTANT_DYNAMIC => {
1161                    let bootstrap_method_attr_index = self.reader.read_unsigned_short()?;
1162                    let name_and_type_index = self.reader.read_unsigned_short()?;
1163                    constant_pool.push(Some(CpInfo::ConstantDynamicInfo {
1164                        tag,
1165                        bootstrap_method_attr_index,
1166                        name_and_type_index,
1167                    }));
1168                }
1169
1170                CONSTANT_INVOKE_DYNAMIC => {
1171                    let bootstrap_method_attr_index = self.reader.read_unsigned_short()?;
1172                    let name_and_type_index = self.reader.read_unsigned_short()?;
1173                    constant_pool.push(Some(CpInfo::ConstantInvokeDynamicInfo {
1174                        tag,
1175                        bootstrap_method_attr_index,
1176                        name_and_type_index,
1177                    }));
1178                }
1179
1180                CONSTANT_MODULE => {
1181                    let name_index = self.reader.read_unsigned_short()?;
1182                    constant_pool.push(Some(CpInfo::ConstantModuleInfo { tag, name_index }));
1183                }
1184
1185                CONSTANT_PACKAGE => {
1186                    let name_index = self.reader.read_unsigned_short()?;
1187                    constant_pool.push(Some(CpInfo::ConstantPackageInfo { tag, name_index }));
1188                }
1189
1190                _ => unreachable!(),
1191            }
1192            cp_idx += 1;
1193        }
1194
1195        Ok(constant_pool)
1196    }
1197
1198    /// Deserialize the class file into the object model.
1199    pub fn deserialize(&mut self) -> DeserializeResult<ClassFile> {
1200        // Headers
1201        let magic = self.reader.read_unsigned_int()?;
1202        let minor_version = self.reader.read_unsigned_short()?;
1203        let major_version = self.reader.read_unsigned_short()?;
1204
1205        // Constant Pool
1206        let constant_pool_count = self.reader.read_unsigned_short()?;
1207        assert!(constant_pool_count > 0);
1208        let constant_pool = self.deserialize_constant_pool(constant_pool_count)?;
1209
1210        let access_flags = self.reader.read_unsigned_short()?;
1211        let this_class = self.reader.read_unsigned_short()?;
1212
1213        let super_class = self.reader.read_unsigned_short()?;
1214        // if super_class == 0 then this is ``java.lang.Object``
1215        //if super_class > 0 {
1216        //    super_class -= 1;
1217        //}
1218
1219        let interfaces_count = self.reader.read_unsigned_short()?;
1220        let mut interfaces = Vec::with_capacity(interfaces_count as usize);
1221        for _ in 0..interfaces_count {
1222            interfaces.push(self.reader.read_unsigned_short()?);
1223        }
1224
1225        // Fields
1226        let fields_count = self.reader.read_unsigned_short()?;
1227        let fields = self.deserialize_fields(fields_count, &constant_pool)?;
1228
1229        // methods
1230        let methods_count = self.reader.read_unsigned_short()?;
1231        let methods = self.deserialize_methods(methods_count, &constant_pool)?;
1232
1233        // class attributes
1234        let attributes_count = self.reader.read_unsigned_short()?;
1235        let attributes = self.deserialize_attributes(attributes_count, &constant_pool)?;
1236
1237        Ok(ClassFile {
1238            magic,
1239            minor_version,
1240            major_version,
1241            constant_pool_count,
1242            constant_pool,
1243            access_flags,
1244            this_class,
1245            super_class,
1246            interfaces_count,
1247            interfaces,
1248            fields_count,
1249            fields,
1250            methods_count,
1251            methods,
1252            attributes_count,
1253            attributes,
1254        })
1255    }
1256}
1257
1258#[cfg(test)]
1259mod test {
1260    use super::*;
1261
1262    //Classfile /Users/z0ltan/dev/playground/Minimal.class
1263    //  Last modified 01-Mar-2023; size 259 bytes
1264    //  SHA-256 checksum a50a8c17f31dbb5ea4e7d6b919cfa21d7e58a33e235cf516d86533b003f32f82
1265    //  Compiled from "Minimal.java"
1266    //public class Minimal
1267    //  minor version: 0
1268    //  major version: 65
1269    //  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
1270    //  this_class: #7                          // Minimal
1271    //  super_class: #2                         // java/lang/Object
1272    //  interfaces: 0, fields: 0, methods: 2, attributes: 1
1273    //Constant pool:
1274    //   #1 = Methodref          #2.#3          // java/lang/Object."<init>":()V
1275    //   #2 = Class              #4             // java/lang/Object
1276    //   #3 = NameAndType        #5:#6          // "<init>":()V
1277    //   #4 = Utf8               java/lang/Object
1278    //   #5 = Utf8               <init>
1279    //   #6 = Utf8               ()V
1280    //   #7 = Class              #8             // Minimal
1281    //   #8 = Utf8               Minimal
1282    //   #9 = Utf8               Code
1283    //  #10 = Utf8               LineNumberTable
1284    //  #11 = Utf8               main
1285    //  #12 = Utf8               ([Ljava/lang/String;)V
1286    //  #13 = Utf8               SourceFile
1287    //  #14 = Utf8               Minimal.java
1288    //{
1289    //  public Minimal();
1290    //    descriptor: ()V
1291    //    flags: (0x0001) ACC_PUBLIC
1292    //    Code:
1293    //      stack=1, locals=1, args_size=1
1294    //         0: aload_0
1295    //         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
1296    //         4: return
1297    //      LineNumberTable:
1298    //        line 1: 0
1299    //
1300    //  public static void main(java.lang.String[]);
1301    //    descriptor: ([Ljava/lang/String;)V
1302    //    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
1303    //    Code:
1304    //      stack=0, locals=1, args_size=1
1305    //         0: return
1306    //      LineNumberTable:
1307    //        line 2: 0
1308    //}
1309    //SourceFile: "Minimal.java"
1310    #[test]
1311    fn test_deserialize_minimal() {
1312        use std::io::Cursor;
1313
1314        let bytes = [
1315            0xca, 0xfe, 0xba, 0xbe, 0x00, 0x00, 0x00, 0x41, 0x00, 0x0f, 0x0a, 0x00, 0x02, 0x00,
1316            0x03, 0x07, 0x00, 0x04, 0x0c, 0x00, 0x05, 0x00, 0x06, 0x01, 0x00, 0x10, 0x6a, 0x61,
1317            0x76, 0x61, 0x2f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74,
1318            0x01, 0x00, 0x06, 0x3c, 0x69, 0x6e, 0x69, 0x74, 0x3e, 0x01, 0x00, 0x03, 0x28, 0x29,
1319            0x56, 0x07, 0x00, 0x08, 0x01, 0x00, 0x07, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x6c,
1320            0x01, 0x00, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x01, 0x00, 0x0f, 0x4c, 0x69, 0x6e, 0x65,
1321            0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x01, 0x00, 0x04,
1322            0x6d, 0x61, 0x69, 0x6e, 0x01, 0x00, 0x16, 0x28, 0x5b, 0x4c, 0x6a, 0x61, 0x76, 0x61,
1323            0x2f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3b, 0x29,
1324            0x56, 0x01, 0x00, 0x0a, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x65,
1325            0x01, 0x00, 0x0c, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x2e, 0x6a, 0x61, 0x76,
1326            0x61, 0x00, 0x21, 0x00, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
1327            0x01, 0x00, 0x05, 0x00, 0x06, 0x00, 0x01, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1d, 0x00,
1328            0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x2a, 0xb7, 0x00, 0x01, 0xb1, 0x00, 0x00,
1329            0x00, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
1330            0x00, 0x09, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x09, 0x00, 0x00, 0x00, 0x19,
1331            0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0xb1, 0x00, 0x00, 0x00, 0x01, 0x00,
1332            0x0a, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00,
1333            0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0e,
1334        ];
1335
1336        let mut deserializer = Deserializer::new(Reader::new(Cursor::new(bytes)));
1337        let _classfile = deserializer.deserialize().unwrap();
1338    }
1339}