From 4ee673d5ff56179cac60ab1bad7ae9f0e808f959 Mon Sep 17 00:00:00 2001 From: VegOwOtenks Date: Mon, 2 Sep 2024 17:46:00 +0200 Subject: [PATCH] Refactor to StackValue --- src/heap_area.rs | 9 ++++---- src/jvm.rs | 52 ++++++++++++++++++++++----------------------- src/main.rs | 2 +- src/stackframe.rs | 54 +++++++++++++++++++++++------------------------ 4 files changed, 58 insertions(+), 59 deletions(-) diff --git a/src/heap_area.rs b/src/heap_area.rs index 7ddd4d0..2345787 100644 --- a/src/heap_area.rs +++ b/src/heap_area.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use crate::accessmasks::FieldAccessFlag; -use crate::stackframe::Value; +use crate::stackframe::StackValue; use crate::classfile::{ JavaClassFile, AbstractTypeDescription, MethodInfo }; #[derive(Debug)] @@ -65,7 +65,7 @@ impl StaticArea { StaticField { name: field.name.clone(), type_description: field.descriptor.clone(), - value: Value::default_for(field.descriptor), + value: StackValue::default_for(field.descriptor), } ) } @@ -92,12 +92,11 @@ pub struct StaticObject { pub struct StaticField { pub name: String, pub type_description: AbstractTypeDescription, - pub value: Value, + pub value: StackValue, } #[derive(Debug)] pub struct ObjectField { pub type_description: AbstractTypeDescription, - pub value: Value, + pub value: StackValue, } - diff --git a/src/jvm.rs b/src/jvm.rs index cb8de55..2479d57 100644 --- a/src/jvm.rs +++ b/src/jvm.rs @@ -12,7 +12,7 @@ use crate::classstore::ClassStore; use crate::constantpool::{ ConstantPoolInfo, ConstantClassInfo, ConstantUtf8Info, ConstantMethodRefInfo, ConstantNameAndTypeInfo}; use crate::heap_area::HeapArea; use crate::stackframe; -use crate::stackframe::{ StackFrame, Value, OperandStack }; +use crate::stackframe::{ StackFrame, StackValue, OperandStack }; #[derive(Debug)] pub enum Error { @@ -63,7 +63,7 @@ impl JVM { } } - pub fn entrypoint(&mut self, class_name: &String, method_name: &String, arguments: &[Value]) -> Result<(), Error> { + pub fn entrypoint(&mut self, class_name: &String, method_name: &String, arguments: &[StackValue]) -> Result<(), Error> { let entry_class = JavaClassFile { minor_version: 0, major_version: 0, @@ -184,7 +184,7 @@ impl JVM { Ok(()) } - fn prepare_invoke_static(&mut self, class_index: usize, method_name: &String, arguments: &[Value]) -> Result<(), Error> { + fn prepare_invoke_static(&mut self, class_index: usize, method_name: &String, arguments: &[StackValue]) -> Result<(), Error> { let class_file = self.class_store.class_file_from_idx(class_index).unwrap(); @@ -283,7 +283,7 @@ impl JVM { // sign extend into int let i8_int = i8::from_be_bytes([byte]); - let frame_result = frame.operand_stack.push(Value::Int(i8_int as i32)); + let frame_result = frame.operand_stack.push(StackValue::Int(i8_int as i32)); match frame_result { Ok(_) => (), Err(err) => return Err(Error::StackFrameError(err, format!("in '{}', in class '{}'", method.name, class.get_classname().unwrap()))), @@ -306,11 +306,11 @@ impl JVM { Instruction::MultiplyInt() => { let factor_1 = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?; let factor_2 = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?; - wrap_stackframe_error(class, method, frame.operand_stack.push(Value::Int(factor_1 * factor_2)))?; + wrap_stackframe_error(class, method, frame.operand_stack.push(StackValue::Int(factor_1 * factor_2)))?; } Instruction::PushConstInt5() => { - let frame_result = frame.operand_stack.push(Value::Int(5)); + let frame_result = frame.operand_stack.push(StackValue::Int(5)); match frame_result { Ok(_) => (), Err(err) => return Err(Error::StackFrameError(err, format!("in '{}', in class '{}'", method.name, class.get_classname().unwrap()))), @@ -328,7 +328,7 @@ impl JVM { let int = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?; - return Ok(JVMCallbackOperation::ReturnFrame(Value::Int(int))); + return Ok(JVMCallbackOperation::ReturnFrame(StackValue::Int(int))); } Instruction::ReturnVoid() => { let expected_type = AbstractTypeDescription { @@ -346,22 +346,22 @@ impl JVM { Instruction::StoreLocalInt0() => { let int = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?; - wrap_stackframe_error(class, method, frame.store_local(0, Value::Int(int)))?; + wrap_stackframe_error(class, method, frame.store_local(0, StackValue::Int(int)))?; }, Instruction::StoreLocalInt1() => { let int = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(1))?; - wrap_stackframe_error(class, method, frame.store_local(0, Value::Int(int)))?; + wrap_stackframe_error(class, method, frame.store_local(0, StackValue::Int(int)))?; }, Instruction::StoreLocalInt2() => { let int = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(2))?; - wrap_stackframe_error(class, method, frame.store_local(0, Value::Int(int)))?; + wrap_stackframe_error(class, method, frame.store_local(0, StackValue::Int(int)))?; }, Instruction::StoreLocalInt3() => { let int = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(3))?; - wrap_stackframe_error(class, method, frame.store_local(0, Value::Int(int)))?; + wrap_stackframe_error(class, method, frame.store_local(0, StackValue::Int(int)))?; }, _ => { @@ -379,7 +379,7 @@ impl JVM { enum JVMCallbackOperation { PopFrame(), - ReturnFrame(Value), + ReturnFrame(StackValue), PushFrame(StackFrame), LoadClass(String), InitClass(String), @@ -394,19 +394,19 @@ fn load_local_int(class: &JavaClassFile, method: &MethodInfo, frame: &mut StackF Err(err) => return Err(Error::StackFrameError(err, format!("in '{}', in class '{}'", method.name, class.get_classname().unwrap()))), }; - let frame_result = frame.operand_stack.push(Value::Int(local_int)); + let frame_result = frame.operand_stack.push(StackValue::Int(local_int)); match frame_result { Ok(_) => Ok(()), Err(err) => return Err(Error::StackFrameError(err, format!("in '{}', in class '{}'", method.name, class.get_classname().unwrap()))), } } -fn fill_arguments(class: &JavaClassFile, method: &MethodInfo, arguments: &mut VecDeque, argument_types: &Box<[AbstractTypeDescription]>, stack: &mut OperandStack) -> Result<(), Error> { +fn fill_arguments(class: &JavaClassFile, method: &MethodInfo, arguments: &mut VecDeque, argument_types: &Box<[AbstractTypeDescription]>, stack: &mut OperandStack) -> Result<(), Error> { for argument_type in argument_types { if argument_type.array_level != 0 { // TODO: Type checking arguments.push_front( - Value::Reference(wrap_stackframe_error(class, method, stack.pop_reference(0))?), + StackValue::Reference(wrap_stackframe_error(class, method, stack.pop_reference(0))?), ) } else { match argument_type.kind { @@ -414,7 +414,7 @@ fn fill_arguments(class: &JavaClassFile, method: &MethodInfo, arguments: &mut Ve // TODO: Add better description AbstractTypeKind::Byte() => { arguments.push_front( - Value::Byte( + StackValue::Byte( wrap_stackframe_error( class, method, @@ -425,7 +425,7 @@ fn fill_arguments(class: &JavaClassFile, method: &MethodInfo, arguments: &mut Ve }, AbstractTypeKind::Char() => { arguments.push_front( - Value::Char( + StackValue::Char( wrap_stackframe_error( class, method, @@ -436,7 +436,7 @@ fn fill_arguments(class: &JavaClassFile, method: &MethodInfo, arguments: &mut Ve }, AbstractTypeKind::Double() => { arguments.push_front( - Value::Double1( + StackValue::Double1( wrap_stackframe_error( class, method, @@ -445,7 +445,7 @@ fn fill_arguments(class: &JavaClassFile, method: &MethodInfo, arguments: &mut Ve ) ); arguments.push_front( - Value::Double0( + StackValue::Double0( wrap_stackframe_error( class, method, @@ -456,7 +456,7 @@ fn fill_arguments(class: &JavaClassFile, method: &MethodInfo, arguments: &mut Ve }, AbstractTypeKind::Float() => { arguments.push_front( - Value::Float( + StackValue::Float( wrap_stackframe_error( class, method, @@ -467,7 +467,7 @@ fn fill_arguments(class: &JavaClassFile, method: &MethodInfo, arguments: &mut Ve }, AbstractTypeKind::Int() => { arguments.push_front( - Value::Int( + StackValue::Int( wrap_stackframe_error( class, method, @@ -478,7 +478,7 @@ fn fill_arguments(class: &JavaClassFile, method: &MethodInfo, arguments: &mut Ve }, AbstractTypeKind::Long() => { arguments.push_front( - Value::Long1( + StackValue::Long1( wrap_stackframe_error( class, method, @@ -487,7 +487,7 @@ fn fill_arguments(class: &JavaClassFile, method: &MethodInfo, arguments: &mut Ve ) ); arguments.push_front( - Value::Long0( + StackValue::Long0( wrap_stackframe_error( class, method, @@ -499,7 +499,7 @@ fn fill_arguments(class: &JavaClassFile, method: &MethodInfo, arguments: &mut Ve AbstractTypeKind::Classname(ref name) => { // TODO: Type checking arguments.push_front( - Value::Reference( + StackValue::Reference( wrap_stackframe_error( class, method, @@ -510,7 +510,7 @@ fn fill_arguments(class: &JavaClassFile, method: &MethodInfo, arguments: &mut Ve }, AbstractTypeKind::Short() => { arguments.push_front( - Value::Short( + StackValue::Short( wrap_stackframe_error( class, method, @@ -521,7 +521,7 @@ fn fill_arguments(class: &JavaClassFile, method: &MethodInfo, arguments: &mut Ve }, AbstractTypeKind::Boolean() => { arguments.push_front( - Value::Boolean( + StackValue::Boolean( wrap_stackframe_error( class, method, diff --git a/src/main.rs b/src/main.rs index a82cc32..03dcf99 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,7 +9,7 @@ mod heap_area; use std::fs::File; -use crate::stackframe::Value; +use crate::stackframe::StackValue; use crate::classfile::JavaClassFile; fn main() { diff --git a/src/stackframe.rs b/src/stackframe.rs index bb8404a..21efbf4 100644 --- a/src/stackframe.rs +++ b/src/stackframe.rs @@ -2,7 +2,7 @@ use crate::classfile::{ JavaClassFile, AttributeData, AbstractTypeDescription }; use crate::heap_area::ObjectReference; #[derive(Copy, Clone, Debug)] -pub enum Value { +pub enum StackValue { Boolean(bool), Byte(u8), Char(u16), @@ -18,13 +18,13 @@ pub enum Value { Empty(), } -impl Value { +impl StackValue { fn default_for(t: AbstractTypeDescription) -> Self { match t { AbstractTypeDescription::Void() => unreachable!(), - AbstractTypeDescription::Byte() => Value::Byte(0), - AbstractTypeDescription::Char() => Value::Char(0), - AbstractTypeDescription::Double() => Value::Double(0), + AbstractTypeDescription::Byte() => StackValue::Byte(0), + AbstractTypeDescription::Char() => StackValue::Char(0), + AbstractTypeDescription::Double() => StackValue::Double(0), AbstractTypeDescription::Float() => , AbstractTypeDescription::Int() => , AbstractTypeDescription::Long() => , @@ -37,7 +37,7 @@ impl Value { #[derive(Debug)] pub struct OperandStack { - stack: Box<[Value]>, + stack: Box<[StackValue]>, depth: u16, } @@ -50,12 +50,12 @@ pub enum Error { impl OperandStack { fn new(size: u16) -> Self { return OperandStack { - stack: vec![Value::Empty(); size.into()].into_boxed_slice(), + stack: vec![StackValue::Empty(); size.into()].into_boxed_slice(), depth: 0, } } - pub fn push(&mut self, value: Value) -> Result<(), Error> { + pub fn push(&mut self, value: StackValue) -> Result<(), Error> { if self.depth as usize == self.stack.len() { return Err(Error::PushError(format!("Trying to push onto full operand stack, capacity: {}, value: {:?}", self.depth, value))) } @@ -71,7 +71,7 @@ impl OperandStack { let value = self.stack[absolute_index]; self.depth -= 1; match value { - Value::Boolean(b) => Ok(b), + StackValue::Boolean(b) => Ok(b), _ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Boolean but found '{:?}'", index, value))) } } @@ -80,7 +80,7 @@ impl OperandStack { let absolute_index = self.depth as usize - 1 - index; let value = self.stack[absolute_index]; match value { - Value::Byte(b) => Ok(b), + StackValue::Byte(b) => Ok(b), _ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Byte but found '{:?}'", index, value))) } } @@ -90,7 +90,7 @@ impl OperandStack { let value = self.stack[absolute_index]; self.depth -= 1; match value { - Value::Char(c) => Ok(c), + StackValue::Char(c) => Ok(c), _ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Char but found '{:?}'", index, value))) } } @@ -100,7 +100,7 @@ impl OperandStack { let value = self.stack[absolute_index]; self.depth -= 1; match value { - Value::Short(s) => Ok(s), + StackValue::Short(s) => Ok(s), _ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Short but found '{:?}'", index, value))) } } @@ -110,7 +110,7 @@ impl OperandStack { let value = self.stack[absolute_index]; self.depth -= 1; match value { - Value::Int(i) => Ok(i), + StackValue::Int(i) => Ok(i), _ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Int but found '{:?}'", index, value))) } } @@ -120,7 +120,7 @@ impl OperandStack { let value = self.stack[absolute_index]; self.depth -= 1; match value { - Value::Float(f) => Ok(f), + StackValue::Float(f) => Ok(f), _ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Float but found '{:?}'", index, value))) } } @@ -130,7 +130,7 @@ impl OperandStack { let value = self.stack[absolute_index]; self.depth -= 1; match value { - Value::Reference(o) => Ok(o), + StackValue::Reference(o) => Ok(o), _ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Reference but found '{:?}'", index, value))) } } @@ -140,7 +140,7 @@ impl OperandStack { let value = self.stack[absolute_index]; self.depth -= 1; match value { - Value::ReturnAddress(a) => Ok(a), + StackValue::ReturnAddress(a) => Ok(a), _ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected ReturnAddress but found '{:?}'", index, value))) } } @@ -150,7 +150,7 @@ impl OperandStack { let value = self.stack[absolute_index]; self.depth -= 1; match value { - Value::Double0(a) => Ok(a), + StackValue::Double0(a) => Ok(a), _ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Double0 but found '{:?}'", index, value))) } } @@ -160,7 +160,7 @@ impl OperandStack { let value = self.stack[absolute_index]; self.depth -= 1; match value { - Value::Double1(a) => Ok(a), + StackValue::Double1(a) => Ok(a), _ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Double1 but found '{:?}'", index, value))) } } @@ -170,7 +170,7 @@ impl OperandStack { let value = self.stack[absolute_index]; self.depth -= 1; match value { - Value::Long0(a) => Ok(a), + StackValue::Long0(a) => Ok(a), _ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Long0 but found '{:?}'", index, value))) } } @@ -180,7 +180,7 @@ impl OperandStack { let value = self.stack[absolute_index]; self.depth -= 1; match value { - Value::Long1(a) => Ok(a), + StackValue::Long1(a) => Ok(a), _ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Long1 but found '{:?}'", index, value))) } } @@ -191,7 +191,7 @@ impl OperandStack { let lower_bytes = self.stack[absolute_index + 1]; self.depth -= 2; match (higher_bytes, lower_bytes) { - (Value::Double0(hi), Value::Double1(lo)) => { + (StackValue::Double0(hi), StackValue::Double1(lo)) => { let v: u64 = ((hi as u64) << 32) | lo as u64; Ok( f64::from_bits(v) @@ -207,7 +207,7 @@ impl OperandStack { let lower_bytes = self.stack[absolute_index + 1]; self.depth -= 2; match (higher_bytes, lower_bytes) { - (Value::Long0(hi), Value::Long1(lo)) => { + (StackValue::Long0(hi), StackValue::Long1(lo)) => { Ok(((hi as u64) << 32) | lo as u64) }, _ => Err(Error::LocalError(format!("Mismatched types at index {} of the function operand stack, expected (Long0, Long1) but found '{:?}'", index, (higher_bytes, lower_bytes)))) @@ -217,7 +217,7 @@ impl OperandStack { #[derive(Debug)] pub struct StackFrame { - pub locals: Box<[Value]>, + pub locals: Box<[StackValue]>, pub operand_stack: OperandStack, pub class_index: usize, pub method_index: u16, @@ -225,13 +225,13 @@ pub struct StackFrame { } impl StackFrame { - pub fn new(classfile: &JavaClassFile, class_index: usize, method_index: u16, arguments: &[Value]) -> Self { + pub fn new(classfile: &JavaClassFile, class_index: usize, method_index: u16, arguments: &[StackValue]) -> Self { let method_info = &classfile.methods[method_index as usize]; let code_data = match &method_info.attributes[method_info.code_attribute_index].data { AttributeData::Code(data) => data, _ => unreachable!(), }; - let mut locals = vec![Value::Empty(); code_data.max_locals.into()].into_boxed_slice(); + let mut locals = vec![StackValue::Empty(); code_data.max_locals.into()].into_boxed_slice(); assert!(locals.len() >= arguments.len()); @@ -251,12 +251,12 @@ impl StackFrame { pub fn load_local_int(&self, index: u16) -> Result { let local = self.locals[index as usize]; match local { - Value::Int(i) => Ok(i), + StackValue::Int(i) => Ok(i), _ => Err(Error::LocalError(format!("Mismatched type at index {} of the function locals, expected Int but found '{:?}'", index, local))) } } - pub fn store_local(&mut self, index: u16, value: Value) -> Result<(), Error> { + pub fn store_local(&mut self, index: u16, value: StackValue) -> Result<(), Error> { let field = self.locals.get_mut(index as usize); match field { Some(f) => {