added modifiers

This commit is contained in:
Shautvast 2023-09-20 22:48:54 +02:00
parent 724b2f3eaa
commit c2cebaedad
3 changed files with 118 additions and 87 deletions

View file

@ -163,7 +163,7 @@ fn read_field(index: &mut usize, bytecode: &Vec<u8>) -> Field {
fn read_method(constant_pool: Rc<Vec<CpEntry>>, index: &mut usize, bytecode: &Vec<u8>) -> Method { fn read_method(constant_pool: Rc<Vec<CpEntry>>, index: &mut usize, bytecode: &Vec<u8>) -> Method {
let access_flags = get_u16(bytecode, *index); let access_flags = get_u16(bytecode, *index);
let name_index = get_u16(bytecode, *index + 2) as usize; let name_index = get_u16(bytecode, *index + 2) as usize;
let descriptor_index = get_u16(bytecode, *index + 4); let descriptor_index = get_u16(bytecode, *index + 4) as usize;
let attributes_count = get_u16(bytecode, *index + 6); let attributes_count = get_u16(bytecode, *index + 6);
*index += 8; *index += 8;
let mut attributes = vec![]; let mut attributes = vec![];

View file

@ -1,3 +1,4 @@
use std::borrow::ToOwned;
use std::rc::Rc; use std::rc::Rc;
use crate::types::CpEntry::*; use crate::types::CpEntry::*;
@ -62,16 +63,44 @@ pub struct Method {
pub constant_pool: Rc<Vec<CpEntry>>, pub constant_pool: Rc<Vec<CpEntry>>,
pub access_flags: u16, pub access_flags: u16,
pub name_index: usize, pub name_index: usize,
pub descriptor_index: u16, pub descriptor_index: usize,
pub attributes_count: u16, pub attributes_count: u16,
pub attributes: Vec<Attribute>, pub attributes: Vec<Attribute>,
} }
impl Method { impl Method {
pub fn name(&self) -> &str { pub fn name(&self) -> String {
if let Utf8(s) = &self.constant_pool[self.name_index - 1] { let mut full_name = get_modifier(self.access_flags);
return &s; if let Utf8(s) = &self.constant_pool[&self.name_index - 1] {
full_name.push_str(s);
} }
panic!() // name must be utf8 if let Utf8(s) = &self.constant_pool[&self.descriptor_index - 1] {
full_name.push_str(s);
}
full_name
} }
} }
const MODIFIERS: [(u16, &'static str); 12] = [
(0x0001, "public "),
(0x0002, "private "),
(0x0004, "protected "),
(0x0008, "static "),
(0x0010, "final "),
(0x0020, "synchronized "),
(0x0040, "volatile "),
(0x0080, "transient "),
(0x0100, "native "),
(0x0200, "interface "),
(0x0400, "interface "),
(0x0800, "strict ")];
pub fn get_modifier (value: u16) -> String {
let mut output = String::new();
for m in MODIFIERS {
if value & m.0 == m.0 { output.push_str(&m.1) }
}
output
}

View file

@ -1,87 +1,89 @@
use std::rc::Rc; mod test {
use classfile_reader::types::{Attribute, Class, Field, Method}; use std::rc::Rc;
use classfile_reader::types::CpEntry::*; use classfile_reader::types::{Attribute, Class, Field, Method};
use classfile_reader::types::CpEntry::*;
#[test] #[test]
fn get_version() { fn get_version() {
assert_eq!((55, 0), get_class().get_version()); assert_eq!((55, 0), get_class().get_version());
}
#[test]
fn get_methods() {
for m in get_class().get_methods() {
println!("{}", m.name());
} }
}
fn get_class() -> Class { #[test]
let cp = Rc::new(vec![MethodRef(2, 3), fn get_methods() {
ClassRef(4), for m in get_class().get_methods() {
NameAndType(5, 6), println!("{}", m.name());
Utf8("java/lang/Object".to_owned()), }
Utf8("<init>".to_owned()), }
Utf8("()V".to_owned()),
Fieldref(8, 9),
ClassRef(10),
NameAndType(11, 12),
Utf8("com/github/shautvast/reflective/MetaField".to_owned()),
Utf8("name".to_owned()),
Utf8("Ljava/lang/String;".to_owned()),
Fieldref(8, 14),
NameAndType(15, 16),
Utf8("modifiers".to_owned()),
Utf8("I".to_owned()),
Utf8("(Ljava/lang/String;I)V".to_owned()),
Utf8("Code".to_owned()),
Utf8("LineNumberTable".to_owned()),
Utf8("LocalVariableTable".to_owned()),
Utf8("this".to_owned()),
Utf8("Lcom/github/shautvast/reflective/MetaField;".to_owned()),
Utf8("getName".to_owned()),
Utf8("()Ljava/lang/String;".to_owned()),
Utf8("getModifiers".to_owned()),
Utf8("()I".to_owned()),
Utf8("SourceFile".to_owned()),
Utf8("MetaField.java".to_owned())]);
Class { fn get_class() -> Class {
minor_version: 0, let cp = Rc::new(vec![MethodRef(2, 3),
major_version: 55, ClassRef(4),
constant_pool: cp.clone(), NameAndType(5, 6),
interfaces: vec![], Utf8("java/lang/Object".to_owned()),
super_class: 2, Utf8("<init>".to_owned()),
access_flags: 33, Utf8("()V".to_owned()),
this_class: 8, Fieldref(8, 9),
methods: vec![ ClassRef(10),
Method { NameAndType(11, 12),
constant_pool: cp.clone(), Utf8("com/github/shautvast/reflective/MetaField".to_owned()),
access_flags: 1, Utf8("name".to_owned()),
name_index: 5, Utf8("Ljava/lang/String;".to_owned()),
descriptor_index: 17, Fieldref(8, 14),
attributes_count: 1, NameAndType(15, 16),
attributes: vec![Attribute { Utf8("modifiers".to_owned()),
attribute_name_index: 18, Utf8("I".to_owned()),
info: vec![0, 2, 0, 3, 0, 0, 0, 15, 42, 183, 0, 1, 42, 43, 181, 0, 7, 42, 28, Utf8("(Ljava/lang/String;I)V".to_owned()),
181, 0, 13, 177, 0, 0, 0, 2, 0, 19, 0, 0, 0, Utf8("Code".to_owned()),
18, 0, 4, 0, 0, 0, 8, 0, 4, 0, 9, 0, 9, 0, 10, 0, 14, 0, 11, 0, 20, 0, 0, Utf8("LineNumberTable".to_owned()),
0, 32, 0, 3, 0, 0, 0, 15, 0, 21, 0, 22, 0, 0, 0, 0, 0, 15, 0, 11, Utf8("LocalVariableTable".to_owned()),
0, 12, 0, 1, 0, 0, 0, 15, 0, 15, 0, 16, 0, 2], Utf8("this".to_owned()),
Utf8("Lcom/github/shautvast/reflective/MetaField;".to_owned()),
Utf8("getName".to_owned()),
Utf8("()Ljava/lang/String;".to_owned()),
Utf8("getModifiers".to_owned()),
Utf8("()I".to_owned()),
Utf8("SourceFile".to_owned()),
Utf8("MetaField.java".to_owned())]);
Class {
minor_version: 0,
major_version: 55,
constant_pool: cp.clone(),
interfaces: vec![],
super_class: 2,
access_flags: 33,
this_class: 8,
methods: vec![
Method {
constant_pool: cp.clone(),
access_flags: 1,
name_index: 5,
descriptor_index: 17,
attributes_count: 1,
attributes: vec![Attribute {
attribute_name_index: 18,
info: vec![0, 2, 0, 3, 0, 0, 0, 15, 42, 183, 0, 1, 42, 43, 181, 0, 7, 42, 28,
181, 0, 13, 177, 0, 0, 0, 2, 0, 19, 0, 0, 0,
18, 0, 4, 0, 0, 0, 8, 0, 4, 0, 9, 0, 9, 0, 10, 0, 14, 0, 11, 0, 20, 0, 0,
0, 32, 0, 3, 0, 0, 0, 15, 0, 21, 0, 22, 0, 0, 0, 0, 0, 15, 0, 11,
0, 12, 0, 1, 0, 0, 0, 15, 0, 15, 0, 16, 0, 2],
}],
},
Method {
constant_pool: cp,
access_flags: 1,
name_index: 23,
descriptor_index: 24,
attributes_count: 1,
attributes: vec![Attribute {
attribute_name_index: 18,
info: vec![0, 1, 0, 1, 0, 0, 0, 5, 42, 180, 0, 7, 176, 0, 0, 0, 2, 0, 19, 0, 0, 0, 6, 0,
1, 0, 0, 0, 14, 0, 20, 0, 0, 0, 12, 0, 1, 0, 0, 0, 5, 0, 21, 0, 22, 0, 0],
}],
}], }],
}, fields: vec![Field { access_flags: 18, name_index: 11, descriptor_index: 12, attributes_count: 0, attributes: vec![] },
Method { Field { access_flags: 18, name_index: 15, descriptor_index: 16, attributes_count: 0, attributes: vec![] }],
constant_pool: cp, attributes: vec![Attribute { attribute_name_index: 27, info: vec![0, 28] }],
access_flags: 1, }
name_index: 23,
descriptor_index: 24,
attributes_count: 1,
attributes: vec![Attribute {
attribute_name_index: 18,
info: vec![0, 1, 0, 1, 0, 0, 0, 5, 42, 180, 0, 7, 176, 0, 0, 0, 2, 0, 19, 0, 0, 0, 6, 0,
1, 0, 0, 0, 14, 0, 20, 0, 0, 0, 12, 0, 1, 0, 0, 0, 5, 0, 21, 0, 22, 0, 0],
}],
}],
fields: vec![Field { access_flags: 18, name_index: 11, descriptor_index: 12, attributes_count: 0, attributes: vec![] },
Field { access_flags: 18, name_index: 15, descriptor_index: 16, attributes_count: 0, attributes: vec![] }],
attributes: vec![Attribute { attribute_name_index: 27, info: vec![0, 28] }],
} }
} }