1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
use crate::attributes::{get_attributes, Attribute};
use crate::constant_pool::ConstantPool;
use crate::error::Result;
use crate::extractors::{get_bitfield, get_int};
use bitflags::bitflags;
use derive_new::new;
use getset::{CopyGetters, Getters};
bitflags! {
#[derive(Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
/// Method access and property modifiers
pub struct MethodFlags: u16 {
/// Declared public; may be accessed from outside its package.
const ACC_PUBLIC = 0x0001;
/// Declared private; accessible only within the defining class and other classes belonging to the same nest (JVMS §5.4.4).
const ACC_PRIVATE = 0x0002;
/// Declared protected; may be accessed within subclasses.
const ACC_PROTECTED = 0x0004;
/// Declared static.
const ACC_STATIC = 0x0008;
/// Declared final; must not be overridden (JVMS §5.4.5).
const ACC_FINAL = 0x0010;
/// Declared synchronized; invocation is wrapped by a monitor use.
const ACC_SYNCHRONIZED = 0x0020;
/// A bridge method, generated by the compiler.
const ACC_BRIDGE = 0x0040;
/// Declared with variable number of arguments.
const ACC_VARARGS = 0x0080;
/// Declared native; implemented in a language other than the Java programming language.
const ACC_NATIVE = 0x0100;
/// Declared abstract; no implementation is provided.
const ACC_ABSTRACT = 0x0400;
/// In a class file whose major version number is at least 46 and at most 60: Declared strictfp.
const ACC_STRICT = 0x0800;
/// Declared synthetic; not present in the source code.
const ACC_SYNTHETIC = 0x1000;
}
}
#[derive(Debug, PartialEq, Getters, CopyGetters, new)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
/// `method_info` structure (JVMS §4.6).
pub struct MethodInfo {
#[get = "pub"]
/// Access and property flags for the method
access_flags: MethodFlags,
#[get_copy = "pub"]
/// Name index in the constant pool
name_index: u16,
#[get_copy = "pub"]
/// Descriptor index in the constant pool
descriptor_index: u16,
#[get = "pub"]
/// Attributes associated with the method
attributes: Vec<Attribute>,
}
pub(crate) fn get_methods(
data: &[u8],
mut start_from: &mut usize,
constant_pool_vec: &Vec<ConstantPool>,
) -> Result<Vec<MethodInfo>> {
let methods_count: u16 = get_int(&data, &mut start_from)?;
let mut methods = Vec::with_capacity(methods_count as usize);
for _ in 0..methods_count {
methods.push(MethodInfo::new(
get_bitfield(&data, &mut start_from)?,
get_int(&data, &mut start_from)?,
get_int(&data, &mut start_from)?,
get_attributes(&data, &mut start_from, &constant_pool_vec)?,
))
}
Ok(methods)
}