added constantvalue and code attribute

This commit is contained in:
Shautvast 2023-09-23 08:23:08 +02:00
parent 84a3c1e80c
commit b06a20a7b1
7 changed files with 260 additions and 199 deletions

Binary file not shown.

View file

@ -2,6 +2,9 @@ package dummy;
public class Dummy {
private final static String constant = "meh";
private final int integer = 57;
private final String name;
public Dummy(String name) {

23
src/io.rs Normal file
View file

@ -0,0 +1,23 @@
pub(crate) fn read_u16(data: &[u8], pos: usize) -> u16 {
u16::from_be_bytes(data[pos..pos + 2].try_into().expect("slice with incorrect length"))
}
pub(crate) fn read_i32(data: &[u8], pos: usize) -> i32 {
i32::from_be_bytes(data[pos..pos + 4].try_into().expect("slice with incorrect length"))
}
pub(crate) fn read_u32(data: &[u8], pos: usize) -> u32 {
u32::from_be_bytes(data[pos..pos + 4].try_into().expect("slice with incorrect length"))
}
pub(crate) fn read_f32(data: &[u8], pos: usize) -> f32 {
f32::from_be_bytes(data[pos..pos + 4].try_into().expect("slice with incorrect length"))
}
pub(crate) fn read_i64(data: &[u8], pos: usize) -> i64 {
i64::from_be_bytes(data[pos..pos + 8].try_into().expect("slice with incorrect length"))
}
pub(crate) fn read_f64(data: &[u8], pos: usize) -> f64 {
f64::from_be_bytes(data[pos..pos + 8].try_into().expect("slice with incorrect length"))
}

View file

@ -1,56 +1,63 @@
pub mod types;
mod io;
use std::rc::Rc;
use crate::types::{Attribute, Class, Field, Method};
use crate::io::{read_f32, read_f64, read_i32, read_i64, read_u16, read_u32};
use crate::types::{AttributeType, Class, MethodCode, Exception, Field, Method};
pub fn get_class(bytecode: Vec<u8>) -> Option<Class> {
check_magic(&bytecode);
let constant_pool_count = get_u16(&bytecode, 8);
let constant_pool_count = read_u16(&bytecode, 8);
let mut index = 10;
let mut constant_pool: Vec<CpEntry> = vec![];
for _ in 0..constant_pool_count - 1 {
constant_pool.push(read_constant_pool_entry(&mut index, &bytecode));
for cp_index in 0..constant_pool_count - 1 {
constant_pool.push(read_constant_pool_entry((cp_index + 1) as usize, &mut index, &bytecode));
}
let constant_pool = Rc::new(constant_pool);
let access_flags = get_u16(&bytecode, index);
let this_class = get_u16(&bytecode, index + 2);
let super_class = get_u16(&bytecode, index + 4);
let access_flags = read_u16(&bytecode, index);
let this_class = read_u16(&bytecode, index + 2);
let super_class = read_u16(&bytecode, index + 4);
let interfaces_count = get_u16(&bytecode, index + 6);
let interfaces_count = read_u16(&bytecode, index + 6);
index += 8;
let mut interfaces = vec![];
for _ in 0..interfaces_count {
interfaces.push(get_u16(&bytecode, index));
interfaces.push(read_u16(&bytecode, index));
index += 2;
}
let fields_count = get_u16(&bytecode, index);
let fields_count = read_u16(&bytecode, index);
index += 2;
let mut fields = vec![];
for _ in 0..fields_count {
fields.push(read_field(constant_pool.clone(), &mut index, &bytecode));
}
let methods_count = get_u16(&bytecode, index);
let methods_count = read_u16(&bytecode, index);
index += 2;
let mut methods = vec![];
for _ in 0..methods_count {
methods.push(read_method(constant_pool.clone(), &mut index, &bytecode));
}
let attributes_count = get_u16(&bytecode, index);
let attributes_count = read_u16(&bytecode, index);
index += 2;
let mut attributes = vec![];
for _ in 0..attributes_count {
attributes.push(read_attribute(constant_pool.clone(), &bytecode, &mut index));
let some = read_attribute(constant_pool.clone(), &bytecode, &mut index);
if let Some(att) = some {
attributes.push(att);
} else {
panic!(); // bug/not-implemented
}
}
Some(Class {
minor_version: get_u16(&bytecode, 4),
major_version: get_u16(&bytecode, 6),
minor_version: read_u16(&bytecode, 4),
major_version: read_u16(&bytecode, 6),
constant_pool,
access_flags,
this_class,
@ -68,68 +75,68 @@ fn check_magic(bytecode: &[u8]) {
}
}
fn read_constant_pool_entry(index: &mut usize, bytecode: &[u8]) -> CpEntry {
fn read_constant_pool_entry(cp_index: usize, index: &mut usize, bytecode: &[u8]) -> CpEntry {
let tag = bytecode[*index];
match tag {
1 => {
let len = get_u16(bytecode, *index + 1) as usize;
let len = read_u16(bytecode, *index + 1) as usize;
let utf: Vec<u8> = Vec::from(&bytecode[*index + 3..*index + 3 + len]);
*index += len + 3;
CpEntry::Utf8(String::from_utf8(utf).unwrap())
CpEntry::Utf8(cp_index, String::from_utf8(utf).unwrap())
}
3 => {
let value = get_i32(bytecode, *index + 1);
let value = read_i32(bytecode, *index + 1);
*index += 5;
CpEntry::Integer(value)
CpEntry::Integer(cp_index, value)
}
4 => {
let value = get_f32(bytecode, *index + 1);
let value = read_f32(bytecode, *index + 1);
*index += 5;
CpEntry::Float(value)
CpEntry::Float(cp_index, value)
}
5 => {
let value = get_i64(bytecode, *index + 1);
let value = read_i64(bytecode, *index + 1);
*index += 9;
CpEntry::Long(value)
CpEntry::Long(cp_index, value)
}
6 => {
let value = get_f64(bytecode, *index + 1);
let value = read_f64(bytecode, *index + 1);
*index += 9;
CpEntry::Double(value)
CpEntry::Double(cp_index, value)
}
7 => {
let name_index = get_u16(bytecode, *index + 1);
let name_index = read_u16(bytecode, *index + 1);
*index += 3;
CpEntry::ClassRef(name_index)
CpEntry::ClassRef(cp_index, name_index)
}
8 => {
let string_index = get_u16(bytecode, *index + 1);
let string_index = read_u16(bytecode, *index + 1);
*index += 3;
CpEntry::StringRef(string_index)
CpEntry::StringRef(cp_index, string_index)
}
9 => {
let class_index = get_u16(bytecode, *index + 1);
let name_and_type_index = get_u16(bytecode, *index + 3);
let class_index = read_u16(bytecode, *index + 1);
let name_and_type_index = read_u16(bytecode, *index + 3);
*index += 5;
CpEntry::Fieldref(class_index, name_and_type_index)
CpEntry::Fieldref(cp_index, class_index, name_and_type_index)
}
10 => {
let class_index = get_u16(bytecode, *index + 1);
let name_and_type_index = get_u16(bytecode, *index + 3);
let class_index = read_u16(bytecode, *index + 1);
let name_and_type_index = read_u16(bytecode, *index + 3);
*index += 5;
CpEntry::MethodRef(class_index, name_and_type_index)
CpEntry::MethodRef(cp_index, class_index, name_and_type_index)
}
11 => {
let class_index = get_u16(bytecode, *index + 1);
let name_and_type_index = get_u16(bytecode, *index + 3);
let class_index = read_u16(bytecode, *index + 1);
let name_and_type_index = read_u16(bytecode, *index + 3);
*index += 5;
CpEntry::InterfaceMethodref(class_index, name_and_type_index)
CpEntry::InterfaceMethodref(cp_index, class_index, name_and_type_index)
}
12 => {
let name_index = get_u16(bytecode, *index + 1) as usize;
let descriptor_index = get_u16(bytecode, *index + 3) as usize;
let name_index = read_u16(bytecode, *index + 1) as usize;
let descriptor_index = read_u16(bytecode, *index + 3) as usize;
*index += 5;
CpEntry::NameAndType(name_index, descriptor_index)
CpEntry::NameAndType(cp_index, name_index, descriptor_index)
}
// 15 MethodHandle,
// 16 MethodType,
@ -142,14 +149,18 @@ fn read_constant_pool_entry(index: &mut usize, bytecode: &[u8]) -> CpEntry {
}
fn read_field(constant_pool: Rc<Vec<CpEntry>>, index: &mut usize, bytecode: &[u8]) -> Field {
let access_flags = get_u16(bytecode, *index);
let name_index = get_u16(bytecode, *index + 2) as usize;
let descriptor_index = get_u16(bytecode, *index + 4) as usize;
let attributes_count = get_u16(bytecode, *index + 6);
let access_flags = read_u16(bytecode, *index);
let name_index = read_u16(bytecode, *index + 2) as usize;
let descriptor_index = read_u16(bytecode, *index + 4) as usize;
let attributes_count = read_u16(bytecode, *index + 6);
*index += 8;
let mut attributes = vec![];
for _ in 0..attributes_count {
attributes.push(read_attribute(bytecode, index));
if let Some(att) = read_attribute(constant_pool.clone(), bytecode, index) {
attributes.push(att);
} else {
panic!(); // bug/not-implemented
}
}
Field::new(
constant_pool,
@ -161,15 +172,19 @@ fn read_field(constant_pool: Rc<Vec<CpEntry>>, index: &mut usize, bytecode: &[u8
}
fn read_method(constant_pool: Rc<Vec<CpEntry>>, index: &mut usize, bytecode: &[u8]) -> Method {
let access_flags = get_u16(bytecode, *index);
let name_index = get_u16(bytecode, *index + 2) as usize;
let descriptor_index = get_u16(bytecode, *index + 4) as usize;
let attributes_count = get_u16(bytecode, *index + 6);
let access_flags = read_u16(bytecode, *index);
let name_index = read_u16(bytecode, *index + 2) as usize;
let descriptor_index = read_u16(bytecode, *index + 4) as usize;
let attributes_count = read_u16(bytecode, *index + 6);
*index += 8;
let mut attributes = vec![];
for _ in 0..attributes_count {
attributes.push(read_attribute(bytecode, index));
if let Some(att) = read_attribute(constant_pool.clone(), bytecode, index) {
attributes.push(att);
}
}
Method::new(
constant_pool,
access_flags,
@ -179,60 +194,64 @@ fn read_method(constant_pool: Rc<Vec<CpEntry>>, index: &mut usize, bytecode: &[u
)
}
fn read_attribute(constant_pool: Rc<Vec<CpEntry>>, bytecode: &[u8], index: &mut usize) -> Attribute {
let attribute_name_index = get_u16(bytecode, *index) as usize;
fn read_attribute(constant_pool: Rc<Vec<CpEntry>>, bytecode: &[u8], index: &mut usize) -> Option<AttributeType> {
let attribute_name_index = read_u16(bytecode, *index) as usize;
*index += 2;
let attribute_length = read_u32(bytecode, *index) as usize;
*index += 4;
let info: Vec<u8> = Vec::from(&bytecode[*index..*index + attribute_length]);
*index += attribute_length;
Attribute {
attribute_name_index,
info,
}
}
fn get_u16(data: &[u8], pos: usize) -> u16 {
u16::from_be_bytes(data[pos..pos + 2].try_into().expect("slice with incorrect length"))
if let CpEntry::Utf8(_, s) = &constant_pool[attribute_name_index - 1] {
// println!("{}", s);
return match s.as_str() {
"ConstantValue" => {
assert_eq!(info.len(), 2);
Some(AttributeType::ConstantValue(read_u16(&info, 0)))
}
"Code" => {
let max_stack = read_u16(&info, 0);
let max_locals = read_u16(&info, 2);
let code_length = read_u32(&info, 4) as usize;
let code = Vec::from(&info[8..8 + code_length]);
let exception_table_length = read_u16(&info, 8 + code_length) as usize;
fn get_i32(data: &[u8], pos: usize) -> i32 {
i32::from_be_bytes(data[pos..pos + 4].try_into().expect("slice with incorrect length"))
let mut code_index = 10 + code_length;
let mut exception_table = vec![];
for _ in 0..exception_table_length {
exception_table.push(Exception::read(&info, code_index));
code_index += 8;
}
fn read_u32(data: &[u8], pos: usize) -> u32 {
u32::from_be_bytes(data[pos..pos + 4].try_into().expect("slice with incorrect length"))
let attribute_count = read_u16(&info, code_index);
code_index += 2;
let mut code_attributes = vec![];
for _ in 0..attribute_count {
if let Some(att) = read_attribute(constant_pool.clone(), &info, &mut code_index) {
code_attributes.push(att);
}
fn get_f32(data: &[u8], pos: usize) -> f32 {
f32::from_be_bytes(data[pos..pos + 4].try_into().expect("slice with incorrect length"))
}
fn get_i64(data: &[u8], pos: usize) -> i64 {
i64::from_be_bytes(data[pos..pos + 8].try_into().expect("slice with incorrect length"))
Some(AttributeType::Code(MethodCode::new(max_stack, max_locals, code, exception_table, code_attributes)))
}
fn get_f64(data: &[u8], pos: usize) -> f64 {
f64::from_be_bytes(data[pos..pos + 8].try_into().expect("slice with incorrect length"))
"SourceFile" => Some(AttributeType::SourceFile),
_ => None
};
}
None
}
#[derive(Debug)]
pub enum CpEntry {
Utf8(String),
Integer(i32),
Float(f32),
Long(i64),
Double(f64),
ClassRef(u16),
StringRef(u16),
Fieldref(u16, u16),
MethodRef(u16, u16),
InterfaceMethodref(u16, u16),
NameAndType(usize, usize),
Utf8(usize, String),
Integer(usize, i32),
Float(usize, f32),
Long(usize, i64),
Double(usize, f64),
ClassRef(usize, u16),
StringRef(usize, u16),
Fieldref(usize, u16, u16),
MethodRef(usize, u16, u16),
InterfaceMethodref(usize, u16, u16),
NameAndType(usize, usize, usize),
}

View file

@ -1,6 +1,5 @@
use std::rc::Rc;
use crate::CpEntry;
use crate::CpEntry::NameAndType;
#[derive(Debug)]
//TODO create factory function
@ -14,7 +13,7 @@ pub struct Class {
pub interfaces: Vec<u16>,
pub fields: Vec<Field>,
pub methods: Vec<Method>,
pub attributes: Vec<Attribute>,
pub attributes: Vec<AttributeType>,
}
impl Class {
@ -23,13 +22,19 @@ impl Class {
}
}
#[derive(Debug)]
pub struct Method {
constant_pool: Rc<Vec<CpEntry>>,
access_flags: u16,
name_index: usize,
descriptor_index: usize,
attributes: Vec<Attribute>,
attributes: Vec<AttributeType>,
}
impl fmt::Debug for Method {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Method {{access_flags: {}, name_index: {}, descriptor_index: {}, attributes: {:?} }}",
self.access_flags, self.name_index, self.descriptor_index, self.attributes)
}
}
impl Method {
@ -37,16 +42,16 @@ impl Method {
access_flags: u16,
name_index: usize,
descriptor_index: usize,
attributes: Vec<Attribute>, ) -> Self {
attributes: Vec<AttributeType>, ) -> Self {
Method { constant_pool, access_flags, name_index, descriptor_index, attributes }
}
pub fn name(&self) -> String {
let mut full_name = get_modifier(self.access_flags);
if let CpEntry::Utf8(s) = &self.constant_pool[&self.name_index - 1] {
if let CpEntry::Utf8(_, s) = &self.constant_pool[&self.name_index - 1] {
full_name.push_str(s);
}
if let CpEntry::Utf8(s) = &self.constant_pool[&self.descriptor_index - 1] {
if let CpEntry::Utf8(_, s) = &self.constant_pool[&self.descriptor_index - 1] {
full_name.push_str(s);
}
@ -54,25 +59,34 @@ impl Method {
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);
}
}
}
}
// 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)]
pub struct Field {
constant_pool: Rc<Vec<CpEntry>>,
access_flags: u16,
name_index: usize,
descriptor_index: usize,
_attributes: Vec<Attribute>,
attributes: Vec<AttributeType>,
}
use std::fmt;
use crate::io::read_u16;
impl fmt::Debug for Field {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Field {{access_flags: {}, name_index: {}, descriptor_index: {}, attributes: {:?} }}",
self.access_flags, self.name_index, self.descriptor_index, self.attributes)
}
}
impl Field {
@ -80,18 +94,18 @@ impl Field {
access_flags: u16,
name_index: usize,
descriptor_index: usize,
attributes: Vec<Attribute>, ) -> Self {
Field { constant_pool, access_flags, name_index, descriptor_index, _attributes: attributes }
attributes: Vec<AttributeType>, ) -> Self {
Field { constant_pool, access_flags, name_index, descriptor_index, attributes: attributes }
}
pub fn name(&self) -> String {
let mut full_name = get_modifier(self.access_flags);
if let CpEntry::Utf8(s) = &self.constant_pool[&self.descriptor_index - 1] {
if let CpEntry::Utf8(_, s) = &self.constant_pool[&self.descriptor_index - 1] {
full_name.push_str(s);
}
full_name.push(' ');
if let CpEntry::Utf8(s) = &self.constant_pool[&self.name_index - 1] {
if let CpEntry::Utf8(_, s) = &self.constant_pool[&self.name_index - 1] {
full_name.push_str(s);
}
@ -99,13 +113,6 @@ impl Field {
}
}
#[derive(Debug)]
pub struct Attribute {
pub attribute_name_index: usize,
pub info: Vec<u8>,
}
const MODIFIERS: [(u16, &str); 12] = [
(0x0001, "public "),
(0x0002, "private "),
@ -120,21 +127,19 @@ const MODIFIERS: [(u16, &str); 12] = [
(0x0400, "interface "),
(0x0800, "strict ")];
pub fn get_modifier(value: u16) -> String {
pub fn get_modifier(modifier: u16) -> String {
let mut output = String::new();
for m in MODIFIERS {
if value & m.0 == m.0 { output.push_str(m.1) }
if modifier & m.0 == m.0 { output.push_str(m.1) }
}
output
}
use std::cell::OnceCell;
use std::collections::HashMap;
use crate::types::AttributeType::{BootstrapMethods, Code, ConstantValue, NestHost, NestMembers, PermittedSubclasses, StackMapTable};
enum AttributeType {
ConstantValue,
Code,
#[derive(Debug)]
pub enum AttributeType {
ConstantValue(u16),
Code(MethodCode),
StackMapTable,
BootstrapMethods,
NestHost,
@ -165,16 +170,39 @@ enum AttributeType {
ModuleMainClass,
}
const cell: OnceCell<HashMap<&str, AttributeType>> = OnceCell::new();
#[derive(Debug)]
pub struct Exception {
pub start_pc: u16,
pub end_pc: u16,
pub handler_pc: u16,
pub catch_type: u16,
}
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
});
impl Exception {
pub fn read(code: &[u8], index: usize) -> Self {
Self {
start_pc: read_u16(code, index),
end_pc: read_u16(code, index + 2),
handler_pc: read_u16(code, index + 4),
catch_type: read_u16(code, index + 6),
}
}
}
#[derive(Debug)]
pub struct MethodCode {
max_stack: u16,
max_locals: u16,
code: Vec<u8>,
exception_table: Vec<Exception>,
code_attributes: Vec<AttributeType>,
}
impl MethodCode {
pub(crate) fn new(max_stack: u16, max_locals: u16,
code: Vec<u8>,
exception_table: Vec<Exception>,
code_attributes: Vec<AttributeType>) -> Self {
Self { max_stack, max_locals, code, exception_table, code_attributes }
}
}

View file

@ -1,7 +1,7 @@
mod test {
use std::rc::Rc;
use classfile_reader::CpEntry::*;
use classfile_reader::types::{Attribute, Class, Field, Method};
use classfile_reader::types::{AttributeType, Class, Field, Method};
#[test]
fn get_version() {
@ -25,43 +25,43 @@ mod test {
#[test]
fn get_code() {
let class = get_class();
println!("{:?}", &class.methods[0].get_code());
println!("{:?}", &class.methods[1].get_code());
// println!("{:?}", &class.methods[0].get_code());
// println!("{:?}", &class.methods[1].get_code());
}
fn get_class() -> Class {
let cp = Rc::new(vec![
MethodRef(6, 19),
Fieldref(5, 20),
Fieldref(21, 22),
MethodRef(23, 24),
ClassRef(25),
ClassRef(26),
Utf8("name".to_owned()),
Utf8("Ljava/lang/String;".to_owned()),
Utf8("<init>".to_owned()),
Utf8("(Ljava/lang/String;)V".to_owned()), //10
Utf8("Code".to_owned()),
Utf8("LineNumberTable".to_owned()),
Utf8("getName".to_owned()),
Utf8("()Ljava/lang/String;".to_owned()),
Utf8("print".to_owned()),
Utf8("()V".to_owned()),
Utf8("SourceFile".to_owned()),
Utf8("Dummy.java".to_owned()),
NameAndType(9, 16),
NameAndType(7, 8), //20
ClassRef(27),
NameAndType(28, 29),
ClassRef(30),
NameAndType(31, 10),
Utf8("dummy/Dummy".to_owned()),
Utf8("java/lang/Object".to_owned()),
Utf8("java/lang/System".to_owned()),
Utf8("out".to_owned()),
Utf8("Ljava/io/PrintStream;".to_owned()),
Utf8("java/io/PrintStream".to_owned()),
Utf8("println".to_owned()),
MethodRef(1, 6, 19),
Fieldref(2, 5, 20),
Fieldref(3, 21, 22),
MethodRef(4, 23, 24),
ClassRef(5, 25),
ClassRef(6, 26),
Utf8(7, "name".to_owned()),
Utf8(8, "Ljava/lang/String;".to_owned()),
Utf8(9, "<init>".to_owned()),
Utf8(10, "(Ljava/lang/String;)V".to_owned()), //10
Utf8(11, "Code".to_owned()),
Utf8(12, "LineNumberTable".to_owned()),
Utf8(13, "getName".to_owned()),
Utf8(14, "()Ljava/lang/String;".to_owned()),
Utf8(15, "print".to_owned()),
Utf8(16, "()V".to_owned()),
Utf8(17, "SourceFile".to_owned()),
Utf8(18, "Dummy.java".to_owned()),
NameAndType(19, 9, 16),
NameAndType(20, 7, 8), //20
ClassRef(21, 27),
NameAndType(22, 28, 29),
ClassRef(23, 30),
NameAndType(24, 31, 10),
Utf8(25, "dummy/Dummy".to_owned()),
Utf8(26, "java/lang/Object".to_owned()),
Utf8(27, "java/lang/System".to_owned()),
Utf8(28, "out".to_owned()),
Utf8(29, "Ljava/io/PrintStream;".to_owned()),
Utf8(30, "java/io/PrintStream".to_owned()),
Utf8(31, "println".to_owned()),
]);
Class {
@ -74,27 +74,15 @@ mod test {
interfaces: vec![],
methods: vec![
Method::new(
cp.clone(), 1, 9, 10, vec![Attribute {
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,
0, 0, 1, 0, 12, 0, 0, 0, 14, 0, 3, 0, 0, 0, 7, 0, 4, 0, 8, 0, 9, 0, 9],
}],
cp.clone(), 1, 9, 10, vec![AttributeType::Deprecated
],
),
Method::new(
cp.clone(), 1, 13, 14, vec![Attribute {
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,
0, 0, 6, 0, 1, 0, 0, 0, 12],
}],
),
Method::new(cp.clone(), 1, 15, 16, vec![Attribute {
attribute_name_index: 11,
info: vec![0, 2, 0, 1, 0, 0, 0, 11, 178, 0, 3, 42, 180, 0, 2, 182, 0, 4, 177, 0,
0, 0, 1, 0, 12, 0, 0, 0, 10, 0, 2, 0, 0, 0, 16, 0, 10, 0, 17],
}]),
cp.clone(), 1, 13, 14, vec![AttributeType::Deprecated]),
Method::new(cp.clone(), 1, 15, 16, vec![AttributeType::Deprecated]),
],
fields: vec![Field::new(cp, 18, 7, 8, vec![])],
attributes: vec![Attribute { attribute_name_index: 17, info: vec![0, 18] }],
attributes: vec![AttributeType::SourceFile],
}
}
}