added some attributes

This commit is contained in:
Sander Hautvast 2023-09-23 06:28:59 +02:00
parent 9b92730858
commit 84a3c1e80c
3 changed files with 83 additions and 14 deletions

View file

@ -45,7 +45,7 @@ pub fn get_class(bytecode: Vec<u8>) -> Option<Class> {
index += 2; index += 2;
let mut attributes = vec![]; let mut attributes = vec![];
for _ in 0..attributes_count { for _ in 0..attributes_count {
attributes.push(read_attribute(&bytecode, &mut index)); attributes.push(read_attribute(constant_pool.clone(), &bytecode, &mut index));
} }
Some(Class { Some(Class {
@ -126,8 +126,8 @@ fn read_constant_pool_entry(index: &mut usize, bytecode: &[u8]) -> CpEntry {
CpEntry::InterfaceMethodref(class_index, name_and_type_index) CpEntry::InterfaceMethodref(class_index, name_and_type_index)
} }
12 => { 12 => {
let name_index = get_u16(bytecode, *index + 1); let name_index = get_u16(bytecode, *index + 1) as usize;
let descriptor_index = get_u16(bytecode, *index + 3); let descriptor_index = get_u16(bytecode, *index + 3) as usize;
*index += 5; *index += 5;
CpEntry::NameAndType(name_index, descriptor_index) CpEntry::NameAndType(name_index, descriptor_index)
} }
@ -179,8 +179,8 @@ fn read_method(constant_pool: Rc<Vec<CpEntry>>, index: &mut usize, bytecode: &[u
) )
} }
fn read_attribute(bytecode: &[u8], index: &mut usize) -> Attribute { fn read_attribute(constant_pool: Rc<Vec<CpEntry>>, bytecode: &[u8], index: &mut usize) -> Attribute {
let attribute_name_index = get_u16(bytecode, *index); let attribute_name_index = get_u16(bytecode, *index) as usize;
*index += 2; *index += 2;
let attribute_length = read_u32(bytecode, *index) as usize; let attribute_length = read_u32(bytecode, *index) as usize;
*index += 4; *index += 4;
@ -229,7 +229,7 @@ pub enum CpEntry {
Fieldref(u16, u16), Fieldref(u16, u16),
MethodRef(u16, u16), MethodRef(u16, u16),
InterfaceMethodref(u16, u16), InterfaceMethodref(u16, u16),
NameAndType(u16, u16), NameAndType(usize, usize),
} }

View file

@ -1,5 +1,6 @@
use std::rc::Rc; use std::rc::Rc;
use crate::CpEntry; use crate::CpEntry;
use crate::CpEntry::NameAndType;
#[derive(Debug)] #[derive(Debug)]
//TODO create factory function //TODO create factory function
@ -28,7 +29,7 @@ pub struct Method {
access_flags: u16, access_flags: u16,
name_index: usize, name_index: usize,
descriptor_index: usize, descriptor_index: usize,
_attributes: Vec<Attribute>, attributes: Vec<Attribute>,
} }
impl Method { impl Method {
@ -37,7 +38,7 @@ impl Method {
name_index: usize, name_index: usize,
descriptor_index: usize, descriptor_index: usize,
attributes: Vec<Attribute>, ) -> Self { attributes: Vec<Attribute>, ) -> Self {
Method { constant_pool, access_flags, name_index, descriptor_index, _attributes:attributes } Method { constant_pool, access_flags, name_index, descriptor_index, attributes }
} }
pub fn name(&self) -> String { pub fn name(&self) -> String {
@ -52,6 +53,17 @@ impl Method {
full_name full_name
} }
pub fn get_code(&self) {
for att in &self.attributes {
if let CpEntry::Utf8(str) = &self.constant_pool[&att.attribute_name_index - 1] {
println!("{}", str);
if str == "Code" {
println!("{:?}", att.info);
}
}
}
}
} }
#[derive(Debug)] #[derive(Debug)]
@ -69,7 +81,7 @@ impl Field {
name_index: usize, name_index: usize,
descriptor_index: usize, descriptor_index: usize,
attributes: Vec<Attribute>, ) -> Self { attributes: Vec<Attribute>, ) -> Self {
Field { constant_pool, access_flags, name_index, descriptor_index, _attributes:attributes } Field { constant_pool, access_flags, name_index, descriptor_index, _attributes: attributes }
} }
pub fn name(&self) -> String { pub fn name(&self) -> String {
@ -89,7 +101,7 @@ impl Field {
#[derive(Debug)] #[derive(Debug)]
pub struct Attribute { pub struct Attribute {
pub attribute_name_index: u16, pub attribute_name_index: usize,
pub info: Vec<u8>, pub info: Vec<u8>,
} }
@ -114,4 +126,55 @@ pub fn get_modifier(value: u16) -> String {
if value & m.0 == m.0 { output.push_str(m.1) } if value & m.0 == m.0 { output.push_str(m.1) }
} }
output output
} }
use std::cell::OnceCell;
use std::collections::HashMap;
use crate::types::AttributeType::{BootstrapMethods, Code, ConstantValue, NestHost, NestMembers, PermittedSubclasses, StackMapTable};
enum AttributeType {
ConstantValue,
Code,
StackMapTable,
BootstrapMethods,
NestHost,
NestMembers,
PermittedSubclasses,
Exceptions,
InnerClasses,
EnclosingMethod,
Synthetic,
Signature,
Record,
SourceFile,
LineNumberTable,
LocalVariableTable,
LocalVariableTypeTable,
SourceDebugExtension,
Deprecated,
RuntimeVisibleAnnotations,
RuntimeInvisibleAnnotations,
RuntimeVisibleParameterAnnotations,
RuntimeInvisibleParameterAnnotations,
RuntimeVisibleTypeAnnotations,
RuntimeInvisibleTypeAnnotations,
AnnotationDefault,
MethodParameters,
Module,
ModulePackages,
ModuleMainClass,
}
const cell: OnceCell<HashMap<&str, AttributeType>> = OnceCell::new();
const value: &HashMap<&str, AttributeType> = cell.get_or_init(|| {
let mut map = HashMap::with_capacity(18);
map.insert("ConstantValue", ConstantValue);
map.insert("Code", Code);
map.insert("StackMapTable", StackMapTable);
map.insert("BootstrapMethods", BootstrapMethods);
map.insert("NestHost", NestHost);
map.insert("NestMembers", NestMembers);
map.insert("PermittedSubclasses", PermittedSubclasses);
map
});

View file

@ -14,7 +14,6 @@ mod test {
assert_eq!("public <init>(Ljava/lang/String;)V", &class.methods[0].name()); assert_eq!("public <init>(Ljava/lang/String;)V", &class.methods[0].name());
assert_eq!("public getName()Ljava/lang/String;", &class.methods[1].name()); assert_eq!("public getName()Ljava/lang/String;", &class.methods[1].name());
assert_eq!("public print()V", &class.methods[2].name()); assert_eq!("public print()V", &class.methods[2].name());
} }
#[test] #[test]
@ -23,6 +22,13 @@ mod test {
assert_eq!("private final Ljava/lang/String; name", &class.fields[0].name()) assert_eq!("private final Ljava/lang/String; name", &class.fields[0].name())
} }
#[test]
fn get_code() {
let class = get_class();
println!("{:?}", &class.methods[0].get_code());
println!("{:?}", &class.methods[1].get_code());
}
fn get_class() -> Class { fn get_class() -> Class {
let cp = Rc::new(vec![ let cp = Rc::new(vec![
MethodRef(6, 19), MethodRef(6, 19),
@ -69,14 +75,14 @@ mod test {
methods: vec![ methods: vec![
Method::new( Method::new(
cp.clone(), 1, 9, 10, vec![Attribute { cp.clone(), 1, 9, 10, vec![Attribute {
attribute_name_index: 18, attribute_name_index: 11,
info: vec![0, 2, 0, 2, 0, 0, 0, 10, 42, 183, 0, 1, 42, 43, 181, 0, 2, 177, 0, info: vec![0, 2, 0, 2, 0, 0, 0, 10, 42, 183, 0, 1, 42, 43, 181, 0, 2, 177, 0,
0, 0, 1, 0, 12, 0, 0, 0, 14, 0, 3, 0, 0, 0, 7, 0, 4, 0, 8, 0, 9, 0, 9], 0, 0, 1, 0, 12, 0, 0, 0, 14, 0, 3, 0, 0, 0, 7, 0, 4, 0, 8, 0, 9, 0, 9],
}], }],
), ),
Method::new( Method::new(
cp.clone(), 1, 13, 14, vec![Attribute { cp.clone(), 1, 13, 14, vec![Attribute {
attribute_name_index: 18, attribute_name_index: 11,
info: vec![0, 1, 0, 1, 0, 0, 0, 5, 42, 180, 0, 2, 176, 0, 0, 0, 1, 0, 12, 0, info: vec![0, 1, 0, 1, 0, 0, 0, 5, 42, 180, 0, 2, 176, 0, 0, 0, 1, 0, 12, 0,
0, 0, 6, 0, 1, 0, 0, 0, 12], 0, 0, 6, 0, 1, 0, 0, 0, 12],
}], }],