jvm/src/constantpool.rs
2024-09-05 00:33:14 +02:00

275 lines
8 KiB
Rust

use std::io::Read;
use crate::classfile::Error;
use crate::classfile::{read_u16, read_u8, read_f32, read_f64, read_i64, read_i32};
#[derive(Debug, Copy, Clone)]
pub struct ConstantClassInfo {
pub name_index: u16,
}
#[derive(Debug, Copy, Clone)]
pub struct ConstantFieldRefInfo {
pub class_index: u16,
pub name_and_type_index: u16,
}
#[derive(Debug, Copy, Clone)]
pub struct ConstantMethodRefInfo {
pub class_index: u16,
pub name_and_type_index: u16,
}
#[derive(Debug, Copy, Clone)]
pub struct ConstantInterfaceMethodRefInfo {
pub class_index: u16,
pub name_and_type_index: u16,
}
#[derive(Debug, Copy, Clone)]
pub struct ConstantStringInfo {
pub string_index: u16,
}
#[derive(Debug, Copy, Clone)]
pub struct ConstantIntegerInfo {
pub value: i32,
}
#[derive(Debug, Copy, Clone)]
pub struct ConstantFloatInfo {
pub value: f32,
}
#[derive(Debug, Copy, Clone)]
pub struct ConstantLongInfo {
pub value: i64,
}
#[derive(Debug, Copy, Clone)]
pub struct ConstantDoubleInfo {
pub value: f64,
}
#[derive(Debug, Copy, Clone)]
pub struct ConstantNameAndTypeInfo {
pub name_index: u16,
pub descriptor_index: u16,
}
#[derive(Debug, Clone)]
pub struct ConstantUtf8Info {
pub utf8: String
}
#[derive(Debug, Copy, Clone)]
#[repr(u8)]
pub enum ConstantMethodHandleType {
RefGetField(u8) = 1,
RefGetStatic(u8) = 2,
RefPutField(u8) = 3,
RefPutStatic(u8) = 4,
RefInvokeVirtual(u8) = 5,
RefInvokeStatic(u8) = 6,
RefInvokeSpecial(u8) = 7,
RefNewInvokeSpecial(u8) = 8,
RefInvokeInterface(u8) = 9,
}
impl TryFrom<u8> for ConstantMethodHandleType {
type Error = Error;
fn try_from(value: u8) -> Result<Self, Self::Error> {
return match value {
1 => Ok(Self::RefGetField(value)),
2 => Ok(Self::RefGetStatic(value)),
3 => Ok(Self::RefPutField(value)),
4 => Ok(Self::RefPutStatic(value)),
5 => Ok(Self::RefInvokeVirtual(value)),
6 => Ok(Self::RefInvokeStatic(value)),
7 => Ok(Self::RefInvokeSpecial(value)),
8 => Ok(Self::RefNewInvokeSpecial(value)),
9 => Ok(Self::RefInvokeInterface(value)),
_ => Err(
Error::BadEnumError(format!("Unexpected MethodHandleType: {}", value))
),
}
}
}
#[derive(Debug, Copy, Clone)]
pub struct ConstantMethodHandleInfo {
reference_kind: ConstantMethodHandleType,
reference_index: u16,
}
#[derive(Debug, Copy, Clone)]
pub struct ConstantMethodTypeInfo {
descriptor_index: u16,
}
#[derive(Debug, Copy, Clone)]
pub struct ConstantInvokeDynamicInfo {
bootstrap_method_attr_index: u16,
name_and_type_index: u16,
}
#[derive(Debug, Clone)]
#[repr(u8)]
pub enum ConstantPoolInfo {
Class(ConstantClassInfo) = 7,
FieldRef(ConstantFieldRefInfo) = 9,
MethodRef(ConstantMethodRefInfo) = 10,
InterfaceMethodRef(ConstantInterfaceMethodRefInfo) = 11,
String(ConstantStringInfo) = 8,
Integer(ConstantIntegerInfo) = 3,
Float(ConstantFloatInfo) = 4,
Long(ConstantLongInfo) = 5,
Double(ConstantDoubleInfo) = 6,
NameAndType(ConstantNameAndTypeInfo) = 12,
Utf8(ConstantUtf8Info) = 1,
MethodHandle(ConstantMethodHandleInfo) = 15,
MethodType(ConstantMethodTypeInfo) = 16,
InvokeDynamic(ConstantInvokeDynamicInfo) = 18,
Nothing() = 255,
}
impl ConstantPoolInfo {
pub fn from_reader(reader: &mut dyn Read) -> Result<Self, Error> {
let tag = read_u8(reader)?;
Ok(
match tag {
1 => {
ConstantPoolInfo::Utf8(
ConstantUtf8Info {
utf8: {
let length = read_u16(reader)?;
let mut buffer: Box<[u8]> = vec![0; length.into()].into_boxed_slice();
reader.read_exact(&mut buffer)?;
std::str::from_utf8(&buffer)?.to_string()
}
}
)
}
3 => {
ConstantPoolInfo::Integer(
ConstantIntegerInfo {
value: read_i32(reader)?
}
)
}
4 => {
ConstantPoolInfo::Float(
ConstantFloatInfo {
value: read_f32(reader)?
}
)
}
5 => {
ConstantPoolInfo::Long(
ConstantLongInfo {
value: read_i64(reader)?
}
)
}
6 => {
ConstantPoolInfo::Double(
ConstantDoubleInfo {
value: read_f64(reader)?
}
)
}
7 => {
ConstantPoolInfo::Class(
ConstantClassInfo {
name_index: read_u16(reader)?
}
)
}
8 => {
ConstantPoolInfo::String(
ConstantStringInfo {
string_index: read_u16(reader)?
}
)
}
9 => {
ConstantPoolInfo::FieldRef(
ConstantFieldRefInfo {
class_index: read_u16(reader)?,
name_and_type_index: read_u16(reader)?
}
)
}
10 => {
ConstantPoolInfo::MethodRef(
ConstantMethodRefInfo {
class_index: read_u16(reader)?,
name_and_type_index: read_u16(reader)?
}
)
}
11 => {
ConstantPoolInfo::InterfaceMethodRef(
ConstantInterfaceMethodRefInfo {
class_index: read_u16(reader)?,
name_and_type_index: read_u16(reader)?
}
)
}
12 => {
ConstantPoolInfo::NameAndType(
ConstantNameAndTypeInfo {
name_index: read_u16(reader)?,
descriptor_index: read_u16(reader)?
}
)
}
15 => {
ConstantPoolInfo::MethodHandle(
ConstantMethodHandleInfo {
reference_kind: ConstantMethodHandleType::try_from(read_u8(reader)?)?,
reference_index: read_u16(reader)?,
}
)
}
16 => {
ConstantPoolInfo::MethodType(
ConstantMethodTypeInfo {
descriptor_index: read_u16(reader)?,
}
)
}
18 => {
ConstantPoolInfo::InvokeDynamic(
ConstantInvokeDynamicInfo {
bootstrap_method_attr_index: read_u16(reader)?,
name_and_type_index: read_u16(reader)?,
}
)
}
_ => unreachable!()
}
)
}
}