Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Serial-ATA committed Jan 27, 2025
1 parent cbf1ea5 commit 92622c8
Show file tree
Hide file tree
Showing 68 changed files with 2,069 additions and 468 deletions.
91 changes: 61 additions & 30 deletions classfile/src/attribute/resolved.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use super::{Annotation, ElementValue, ElementValuePair, ElementValueTag, ElementValueType};
use crate::attribute::BootstrapMethod;
use crate::constant_pool::types::{self, LoadableConstantPoolValue, MethodHandleEntry};
use crate::constant_pool::ConstantPool;

use common::int_types::{s4, s8, u2};
Expand All @@ -10,7 +12,7 @@ pub struct ResolvedAnnotation {

impl ResolvedAnnotation {
pub(crate) fn resolve_from(raw_annotation: &Annotation, constant_pool: &ConstantPool) -> Self {
let name = constant_pool.get_constant_utf8(raw_annotation.type_index);
let name = constant_pool.get::<types::raw::RawConstantUtf8>(raw_annotation.type_index);
let element_value_pairs = raw_annotation
.element_value_pairs
.iter()
Expand All @@ -31,11 +33,12 @@ pub struct ResolvedElementValuePair {

impl ResolvedElementValuePair {
fn resolve_from(raw_value_pair: &ElementValuePair, constant_pool: &ConstantPool) -> Self {
let element_name = constant_pool.get_constant_utf8(raw_value_pair.element_name_index);
let element_name =
constant_pool.get::<types::raw::RawConstantUtf8>(raw_value_pair.element_name_index);
let value = ResolvedElementValue::resolve_from(&raw_value_pair.value, constant_pool);

Self {
element_name: String::from_utf8(element_name.to_vec()).unwrap(),
element_name: String::from_utf8(element_name.to_vec()).unwrap(), // TODO: Error handling
value,
}
}
Expand All @@ -50,41 +53,42 @@ impl ResolvedElementValue {
fn resolve_from(raw_element_value: &ElementValue, constant_pool: &ConstantPool) -> Self {
let tag = raw_element_value.tag;
let value = match &raw_element_value.ty {
ElementValueType::Byte { const_value_index } => {
ResolvedElementValueType::Byte(constant_pool.get_integer(*const_value_index))
},
ElementValueType::Char { const_value_index } => {
ResolvedElementValueType::Char(constant_pool.get_integer(*const_value_index))
},
ElementValueType::Double { const_value_index } => {
ResolvedElementValueType::Double(constant_pool.get_double(*const_value_index))
},
ElementValueType::Float { const_value_index } => {
ResolvedElementValueType::Float(constant_pool.get_float(*const_value_index))
},
ElementValueType::Int { const_value_index } => {
ResolvedElementValueType::Int(constant_pool.get_integer(*const_value_index))
},
ElementValueType::Long { const_value_index } => {
ResolvedElementValueType::Long(constant_pool.get_long(*const_value_index))
},
ElementValueType::Short { const_value_index } => {
ResolvedElementValueType::Short(constant_pool.get_integer(*const_value_index))
},
ElementValueType::Boolean { const_value_index } => {
ResolvedElementValueType::Boolean(constant_pool.get_integer(*const_value_index))
},
ElementValueType::Byte { const_value_index } => ResolvedElementValueType::Byte(
constant_pool.get::<types::raw::Integer>(*const_value_index),
),
ElementValueType::Char { const_value_index } => ResolvedElementValueType::Char(
constant_pool.get::<types::raw::Integer>(*const_value_index),
),
ElementValueType::Double { const_value_index } => ResolvedElementValueType::Double(
constant_pool.get::<types::raw::Double>(*const_value_index),
),
ElementValueType::Float { const_value_index } => ResolvedElementValueType::Float(
constant_pool.get::<types::raw::Float>(*const_value_index),
),
ElementValueType::Int { const_value_index } => ResolvedElementValueType::Int(
constant_pool.get::<types::raw::Integer>(*const_value_index),
),
ElementValueType::Long { const_value_index } => ResolvedElementValueType::Long(
constant_pool.get::<types::raw::Long>(*const_value_index),
),
ElementValueType::Short { const_value_index } => ResolvedElementValueType::Short(
constant_pool.get::<types::raw::Integer>(*const_value_index),
),
ElementValueType::Boolean { const_value_index } => ResolvedElementValueType::Boolean(
constant_pool.get::<types::raw::Integer>(*const_value_index),
),

ElementValueType::String { const_value_index } => {
let value = constant_pool.get_constant_utf8(*const_value_index);
let value = constant_pool.get::<types::raw::RawConstantUtf8>(*const_value_index);
ResolvedElementValueType::String(String::from_utf8(value.to_vec()).unwrap())
},
ElementValueType::Enum {
type_name_index,
const_value_index,
} => {
let type_name = constant_pool.get_constant_utf8(*type_name_index);
let const_value = constant_pool.get_constant_utf8(*const_value_index);
let type_name = constant_pool.get::<types::raw::RawConstantUtf8>(*type_name_index);
let const_value =
constant_pool.get::<types::raw::RawConstantUtf8>(*const_value_index);
ResolvedElementValueType::Enum {
type_name: String::from_utf8(type_name.to_vec()).unwrap(),
const_value: String::from_utf8(const_value.to_vec()).unwrap(),
Expand Down Expand Up @@ -132,3 +136,30 @@ pub enum ResolvedElementValueType {
values: Vec<ResolvedElementValue>,
},
}

pub struct ResolvedBootstrapMethod {
pub method_handle_index: u2,
pub method_handle_info: MethodHandleEntry<'static>,
pub arguments: Vec<LoadableConstantPoolValue<'static>>,
}

impl ResolvedBootstrapMethod {
pub(crate) fn resolve_from(raw: &BootstrapMethod, constant_pool: &ConstantPool) -> Self {
let method_handle_info =
constant_pool.get::<types::raw::RawMethodHandle>(raw.bootstrap_method_ref);
let mut arguments = Vec::with_capacity(raw.bootstrap_arguments.len());
for argument_index in &raw.bootstrap_arguments {
arguments.push(
constant_pool
.get_loadable_entry(*argument_index)
.into_owned(),
);
}

Self {
method_handle_index: raw.bootstrap_method_ref,
method_handle_info: method_handle_info.into_owned(),
arguments,
}
}
}
44 changes: 35 additions & 9 deletions classfile/src/classfile.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use crate::accessflags::ClassAccessFlags;
use crate::attribute::{Attribute, SourceFile};
use crate::constant_pool::ConstantPool;
use crate::attribute::resolved::ResolvedBootstrapMethod;
use crate::attribute::{Attribute, AttributeType, SourceFile};
use crate::constant_pool::{self, ConstantPool};
use crate::fieldinfo::FieldInfo;
use crate::methodinfo::MethodInfo;
use crate::parse::error::Result;
use crate::AttributeType;

use std::borrow::Cow;
use std::io::Read;

use common::int_types::{u1, u2};
Expand All @@ -30,26 +31,32 @@ impl ClassFile {
crate::parse::parse_class(reader)
}

pub fn get_super_class(&self) -> Option<&[u1]> {
pub fn get_super_class(&self) -> Option<Cow<'_, [u1]>> {
// For a class, the value of the super_class item either must be zero or must be a valid
// index into the constant_pool table.
let super_class_index = self.super_class;

let mut super_class_name = None;
let mut super_class = None;

// If the value of the super_class item is zero, then this class file must represent
// the class Object, the only class or interface without a direct superclass.
if super_class_index == 0 {
let this_class_name = self
.constant_pool
.get::<constant_pool::types::raw::RawClassName>(self.this_class)
.name;
assert_eq!(
self.constant_pool.get_class_name(self.this_class),
b"java/lang/Object",
*this_class_name, *b"java/lang/Object",
"Only java/lang/Object can have no superclass!"
);
} else {
super_class_name = Some(self.constant_pool.get_class_name(super_class_index));
super_class = Some(
self.constant_pool
.get::<constant_pool::types::raw::RawClassName>(super_class_index),
);
}

super_class_name
super_class.map(|class| class.name)
}

pub fn source_file_index(&self) -> Option<u2> {
Expand All @@ -61,4 +68,23 @@ impl ClassFile {

None
}

pub fn bootstrap_methods(
&self,
) -> Option<impl Iterator<Item = ResolvedBootstrapMethod> + use<'_>> {
for attr in &self.attributes {
let Some(bootstrap_methods) = attr.bootstrap_methods() else {
continue;
};

let iter = bootstrap_methods
.bootstrap_methods
.iter()
.map(move |bsm| ResolvedBootstrapMethod::resolve_from(bsm, &self.constant_pool));

return Some(iter);
}

None
}
}
Loading

0 comments on commit 92622c8

Please sign in to comment.