From ea3666aad3b76c4886c4bdb6a6ec30d4b12b2d89 Mon Sep 17 00:00:00 2001 From: VegOwOtenks Date: Fri, 30 Aug 2024 15:48:12 +0200 Subject: [PATCH] More code separation --- src/accessmasks.rs | 2 +- src/classfile.rs | 289 ++------------------------------------------ src/constantpool.rs | 275 +++++++++++++++++++++++++++++++++++++++++ src/main.rs | 1 + 4 files changed, 287 insertions(+), 280 deletions(-) create mode 100644 src/constantpool.rs diff --git a/src/accessmasks.rs b/src/accessmasks.rs index bc5f5b1..7392803 100644 --- a/src/accessmasks.rs +++ b/src/accessmasks.rs @@ -1,4 +1,4 @@ -use core::fmt::{Display, Formatter, Debug}; +use core::fmt::{Formatter, Debug}; #[derive(Debug, Copy, Clone)] pub enum MethodAccessFlag { diff --git a/src/classfile.rs b/src/classfile.rs index de94e93..47d39fb 100644 --- a/src/classfile.rs +++ b/src/classfile.rs @@ -3,8 +3,9 @@ use std::error::Error as ErrorTrait; use core::fmt::{Display, Formatter, Debug}; use core::str::Utf8Error; -use crate::bytecode::Bytecode; use crate::accessmasks::*; +use crate::bytecode::Bytecode; +use crate::constantpool::{ ConstantPoolInfo, ConstantUtf8Info }; #[derive(Debug)] pub enum Error { @@ -191,276 +192,6 @@ impl JavaClassFile { } } -#[derive(Debug)] -pub struct ConstantClassInfo { - name_index: u16, -} - -#[derive(Debug)] -pub struct ConstantFieldRefInfo { - class_index: u16, - name_and_type_index: u16, -} - -#[derive(Debug)] -pub struct ConstantMethodRefInfo { - class_index: u16, - name_and_type_index: u16, -} - -#[derive(Debug)] -pub struct ConstantInterfaceMethodRefInfo { - class_index: u16, - name_and_type_index: u16, -} - -#[derive(Debug)] -pub struct ConstantStringInfo { - string_index: u16, -} - -#[derive(Debug)] -pub struct ConstantIntegerInfo { - value: i32, -} - -#[derive(Debug)] -pub struct ConstantFloatInfo { - value: f32, -} - -#[derive(Debug)] -pub struct ConstantLongInfo { - value: u64, -} - -#[derive(Debug)] -pub struct ConstantDoubleInfo { - value: f64, -} - -#[derive(Debug)] -pub struct ConstantNameAndTypeInfo { - name_index: u16, - descriptor_index: u16, -} - -#[derive(Debug)] -pub struct ConstantUtf8Info { - utf8: String -} - -#[derive(Debug)] -#[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 for ConstantMethodHandleType { - type Error = Error; - - fn try_from(value: u8) -> Result { - 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)] -pub struct ConstantMethodHandleInfo { - reference_kind: ConstantMethodHandleType, - reference_index: u16, -} - -#[derive(Debug)] -pub struct ConstantMethodTypeInfo { - descriptor_index: u16, -} - -#[derive(Debug)] -pub struct ConstantInvokeDynamicInfo { - bootstrap_method_attr_index: u16, - name_and_type_index: u16, -} - - -#[derive(Debug)] -#[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 { - fn from_reader(reader: &mut dyn Read) -> Result { - 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_u64(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!() - } - ) - } -} - #[derive(Debug)] pub struct FieldInfo { access_flags: FieldAccessFlagMask, @@ -975,7 +706,7 @@ impl MethodInfo { } -fn read_buffer(reader: &mut dyn Read, size: usize) -> Result, Error> { +pub fn read_buffer(reader: &mut dyn Read, size: usize) -> Result, Error> { let mut buffer: Box<[u8]> = vec![0; size].into_boxed_slice(); reader.read_exact(&mut buffer)?; @@ -983,7 +714,7 @@ fn read_buffer(reader: &mut dyn Read, size: usize) -> Result, Error> { Ok(buffer) } -fn read_f64(reader: &mut dyn Read) -> Result { +pub fn read_f64(reader: &mut dyn Read) -> Result { // let bytes = read_u64(reader)?; // // let sign = if (bytes >> 63) == 0 { 1 } else { -1 } as f64; @@ -1004,28 +735,28 @@ fn read_f64(reader: &mut dyn Read) -> Result { return Ok(f64::from_be_bytes(buffer)); } -fn read_f32(reader: &mut dyn Read) -> Result { +pub fn read_f32(reader: &mut dyn Read) -> Result { let mut buffer: [u8; 4] = [0; 4]; reader.read_exact(&mut buffer)?; return Ok(f32::from_be_bytes(buffer)); } -fn read_i32(reader: &mut dyn Read) -> Result { +pub fn read_i32(reader: &mut dyn Read) -> Result { let mut buffer: [u8; 4] = [0; 4]; reader.read_exact(&mut buffer)?; return Ok(i32::from_be_bytes(buffer)); } -fn read_u64(reader: &mut dyn Read) -> Result { +pub fn read_u64(reader: &mut dyn Read) -> Result { let high_bytes: u64 = read_u32(reader)?.into(); let low_bytes: u64 = read_u32(reader)?.into(); return Ok((high_bytes << 32) | low_bytes); } -fn read_u32(reader: &mut dyn Read) -> Result { +pub fn read_u32(reader: &mut dyn Read) -> Result { let mut u32_buffer: [u8; 4] = [0; 4]; reader.read_exact(&mut u32_buffer)?; @@ -1033,7 +764,7 @@ fn read_u32(reader: &mut dyn Read) -> Result { return Ok(u32::from_be_bytes(u32_buffer)); } -fn read_u16(reader: &mut dyn Read) -> Result { +pub fn read_u16(reader: &mut dyn Read) -> Result { let mut u16_buffer: [u8; 2] = [0; 2]; reader.read_exact(&mut u16_buffer)?; @@ -1041,7 +772,7 @@ fn read_u16(reader: &mut dyn Read) -> Result { return Ok(u16::from_be_bytes(u16_buffer)); } -fn read_u8(reader: &mut dyn Read) -> Result { +pub fn read_u8(reader: &mut dyn Read) -> Result { let mut u8_buffer: [u8; 1] = [0; 1]; reader.read_exact(&mut u8_buffer)?; diff --git a/src/constantpool.rs b/src/constantpool.rs new file mode 100644 index 0000000..0398d26 --- /dev/null +++ b/src/constantpool.rs @@ -0,0 +1,275 @@ +use std::io::Read; + +use crate::classfile::Error; +use crate::classfile::{read_u16, read_u8, read_f32, read_f64, read_u64, read_i32}; + +#[derive(Debug)] +pub struct ConstantClassInfo { + pub name_index: u16, +} + +#[derive(Debug)] +pub struct ConstantFieldRefInfo { + pub class_index: u16, + pub name_and_type_index: u16, +} + +#[derive(Debug)] +pub struct ConstantMethodRefInfo { + pub class_index: u16, + pub name_and_type_index: u16, +} + +#[derive(Debug)] +pub struct ConstantInterfaceMethodRefInfo { + pub class_index: u16, + pub name_and_type_index: u16, +} + +#[derive(Debug)] +pub struct ConstantStringInfo { + pub string_index: u16, +} + +#[derive(Debug)] +pub struct ConstantIntegerInfo { + pub value: i32, +} + +#[derive(Debug)] +pub struct ConstantFloatInfo { + pub value: f32, +} + +#[derive(Debug)] +pub struct ConstantLongInfo { + pub value: u64, +} + +#[derive(Debug)] +pub struct ConstantDoubleInfo { + pub value: f64, +} + +#[derive(Debug)] +pub struct ConstantNameAndTypeInfo { + pub name_index: u16, + pub descriptor_index: u16, +} + +#[derive(Debug)] +pub struct ConstantUtf8Info { + pub utf8: String +} + +#[derive(Debug)] +#[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 for ConstantMethodHandleType { + type Error = Error; + + fn try_from(value: u8) -> Result { + 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)] +pub struct ConstantMethodHandleInfo { + reference_kind: ConstantMethodHandleType, + reference_index: u16, +} + +#[derive(Debug)] +pub struct ConstantMethodTypeInfo { + descriptor_index: u16, +} + +#[derive(Debug)] +pub struct ConstantInvokeDynamicInfo { + bootstrap_method_attr_index: u16, + name_and_type_index: u16, +} + + +#[derive(Debug)] +#[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 { + 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_u64(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!() + } + ) + } +} + diff --git a/src/main.rs b/src/main.rs index b79cc82..eed4a3f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ mod bytecode; mod jvm; mod stackframe; mod accessmasks; +mod constantpool; fn main() { let mut jvm = jvm::JVM::new();