From 3fd30b80b6203dd989bfb0cdbce475c8dce6df8c Mon Sep 17 00:00:00 2001 From: VegOwOtenks Date: Sat, 2 Nov 2024 09:10:42 +0100 Subject: [PATCH] I dont know, I changed things --- src/bytecode.rs | 4 +++ src/heap_area.rs | 41 ++++++++++++++++++++++++++++++ src/jvm.rs | 58 +++++++++++++++++++++++++++++++++++++------ src/native_methods.rs | 1 + src/stackframe.rs | 4 +-- 5 files changed, 98 insertions(+), 10 deletions(-) diff --git a/src/bytecode.rs b/src/bytecode.rs index a0ff1c4..5af57e1 100644 --- a/src/bytecode.rs +++ b/src/bytecode.rs @@ -57,6 +57,7 @@ impl Bytecode { 0x32 => (Instruction::ArrayElement(), 1), 0x33 => (Instruction::LoadFromBArray(), 1), 0x36 => (Instruction::StoreLocalInt(self.bytes[offset+1]), 2), + 0x37 => (Instruction::StoreLocalLong(self.bytes[offset+1]), 2), 0x38 => (Instruction::StoreLocalFloat(self.bytes[offset+1]), 2), 0x3A => (Instruction::StoreLocalReference(self.bytes[offset+1]), 2), 0x3B => (Instruction::StoreLocalInt0(), 1), @@ -68,6 +69,7 @@ impl Bytecode { 0x4D => (Instruction::StoreLocalReference2(), 1), 0x4E => (Instruction::StoreLocalReference3(), 1), + 0x4F => (Instruction::StoreIntoIArray(), 1), 0x53 => (Instruction::StoreIntoRArray(), 1), 0x54 => (Instruction::StoreIntoBArray(), 1), 0x55 => (Instruction::StoreIntoCArray(), 1), @@ -311,6 +313,7 @@ pub enum Instruction { ArrayElement() = 0x32, // load element from array LoadFromBArray() = 0x33, // store into byte array StoreLocalInt(u8) = 0x36, // store into indexed local variable + StoreLocalLong(u8) = 0x37, // store into indexed local variable StoreLocalFloat(u8) = 0x38, // store into indexed local variable StoreLocalReference(u8) = 0x3A, // store into indexed local variable StoreLocalInt0() = 0x3B, // store int into local variable @@ -322,6 +325,7 @@ pub enum Instruction { StoreLocalReference2() = 0x4D, // store reference into local variable StoreLocalReference3() = 0x4E, // store reference into local variable + StoreIntoIArray() = 0x4F, // store value into integer array StoreIntoRArray() = 0x53, // store value into reference array StoreIntoBArray() = 0x54, // store value into byte or boolean array StoreIntoCArray() = 0x55, // store value into char array diff --git a/src/heap_area.rs b/src/heap_area.rs index cc2785e..5242190 100644 --- a/src/heap_area.rs +++ b/src/heap_area.rs @@ -98,6 +98,13 @@ impl HeapArea { array_ref } + + pub fn make_primitive_int_array(&mut self, array_capacity: usize, class_store: &ClassStore) -> ObjectReference { + let (array_ref, size) = self.object_area.make_primitive_int_array(array_capacity, class_store); + self.memory_used += size; + + array_ref + } } #[derive(Clone, Copy, Debug, Default, PartialEq)] @@ -368,6 +375,11 @@ impl ObjectArea { *array_element = match element { FieldValue::Char(c) => c, _ => unreachable!() } ; } + CompartmentEntry::IntArray(array) => { + let array_element = array.content.get_mut(index).unwrap(); + + *array_element = match element { FieldValue::Int(i) => i, _ => unreachable!() } ; + } _ => unreachable!(), }; @@ -435,6 +447,27 @@ impl ObjectArea { (array_ref, array_size) } + + fn make_primitive_int_array(&mut self, array_capacity: usize, class_store: &ClassStore) -> (ObjectReference, usize) { + // make new type desc + let array_type_desc = AbstractTypeDescription { + array_level: 1, + kind: AbstractTypeKind::Int(), + }; + + let array_class_ref = class_store.get_array_class_ref(&array_type_desc).unwrap(); + + let array_size = array_capacity * std::mem::size_of::() + std::mem::size_of::(); + + let array_object = IntArray { + class_ref: array_class_ref, + content: vec![0; array_capacity].into(), + }; + + let array_ref = self.store_entry(CompartmentEntry::IntArray(array_object)); + + (array_ref, array_size) + } } pub struct ObjectCompartment { @@ -477,6 +510,7 @@ impl ObjectCompartment { CompartmentEntry::ReferenceArray(_) => unreachable!(), CompartmentEntry::ByteArray(_) => unreachable!(), CompartmentEntry::CharArray(_) => unreachable!(), + CompartmentEntry::IntArray(_) => unreachable!(), } *self.objects.get_mut(compartment_index).unwrap() = object; @@ -507,6 +541,7 @@ pub enum CompartmentEntry { ReferenceArray(ReferenceArray), ByteArray(ByteArray), CharArray(CharArray), + IntArray(IntArray), EmptyNext(usize), EmptyTail(), // last empty value } @@ -517,6 +552,12 @@ pub struct CharArray { content: Box<[u16]>, } +#[derive(Debug)] +pub struct IntArray { + class_ref: ObjectReference, + content: Box<[i32]>, +} + #[derive(Debug)] pub struct ByteArray { class_ref: ObjectReference, diff --git a/src/jvm.rs b/src/jvm.rs index eebc89b..2cde5af 100644 --- a/src/jvm.rs +++ b/src/jvm.rs @@ -744,6 +744,16 @@ impl JVM { } } + Instruction::BranchIntGreaterThan(branch_offset) => { + let value_2 = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?; + let value_1 = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?; + + if value_1 > value_2 { + frame.instruction_pointer -= offset as u32; + frame.instruction_pointer = if branch_offset < 0 { frame.instruction_pointer - branch_offset.abs() as u32} else { frame.instruction_pointer + branch_offset.abs() as u32}; + } + } + Instruction::BranchIntInequality(branch_offset) => { let value_2 = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?; let value_1 = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?; @@ -1208,11 +1218,20 @@ impl JVM { return Ok(JVMCallbackOperation::InitClass(supplied_class_name.to_string())); } + let supplied_descriptor: MethodDescriptor = supplied_descriptor_string.try_into()?; + // TODO: Throw exception on fail + let (callee_class_file, callee_class_index) = self.class_store.get_class(supplied_class_name)?; - // TODO: Throw exception on fail - let callee_method_index = callee_class_file.find_method_index(supplied_method_name).unwrap(); - // TODO: Throw exception on fail - let callee_method_info = &callee_class_file.methods[callee_method_index]; + let (callee_class_index, callee_method_index, callee_method_info) = match ClassMethodIterator::new(callee_class_index, &self.class_store) + .filter(|(_, _, minfo)| minfo.name == *supplied_method_name) + .filter(|(_, _, minfo)| minfo.descriptor == supplied_descriptor) + .next() { + Some(m) => m, + None => { + // TODO: Throw exception + return Err(Error::RunTimeError(format!("InvokeStatic: Failed to find requested method '{}' with descriptor '{}' in the class '{}'", supplied_method_name, supplied_descriptor_string, supplied_class_name))); + } + }; if ! (callee_method_info.access_flags & MethodAccessFlag::Static) { // TODO: Throw IncompatibleClassChangeError @@ -1225,8 +1244,6 @@ impl JVM { ))); } - let supplied_descriptor: MethodDescriptor = supplied_descriptor_string.try_into()?; - // TODO: Throw exception on fail if supplied_descriptor != callee_method_info.descriptor { // TODO: Throw exception on fail @@ -1618,6 +1635,7 @@ impl JVM { const CHAR: u8 = 5; const BYTE: u8 = 8; + const INT: u8 = 10; let array_ref = match array_type { BYTE => { let array_ref = self.heap_area.make_primitive_byte_array(array_capacity as usize, &self.class_store); @@ -1631,6 +1649,12 @@ impl JVM { array_ref } + INT => { + let array_ref = self.heap_area.make_primitive_int_array(array_capacity as usize, &self.class_store); + + array_ref + } + _ => todo!() }; @@ -1877,6 +1901,16 @@ impl JVM { } } + Instruction::StoreIntoIArray() => { + let value = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?; + let index = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?; + let array_ref = wrap_stackframe_error(class, method, frame.operand_stack.pop_reference(0))?; + + // TODO: Type checking + + self.heap_area.object_area.set_array_element(array_ref, index as usize, FieldValue::Int(value)); + } + Instruction::StoreIntoRArray() => { let value = wrap_stackframe_error(class, method, frame.operand_stack.pop_reference(0))?; let index = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?; @@ -1926,6 +1960,14 @@ impl JVM { wrap_stackframe_error(class, method, frame.store_local(3, StackValue::Int(int)))?; } + Instruction::StoreLocalLong(index) => { + let long1 = wrap_stackframe_error(class, method, frame.operand_stack.pop_long1(0))?; + let long0 = wrap_stackframe_error(class, method, frame.operand_stack.pop_long0(0))?; + + wrap_stackframe_error(class, method, frame.store_local(index as u16, StackValue::Long0(long0)))?; + wrap_stackframe_error(class, method, frame.store_local(index as u16 + 1, StackValue::Long1(long1)))?; + } + Instruction::StoreLocalReference(index) => { let reference = wrap_stackframe_error(class, method, frame.operand_stack.pop_reference(0))?; @@ -2043,12 +2085,12 @@ fn fill_arguments(class: &JavaClassFile, method: &MethodInfo, arguments: &mut Ve }, AbstractTypeKind::Char() => { arguments.push_front( - StackValue::Char( + StackValue::Int( wrap_stackframe_error( class, method, stack.pop_char(0) - )? + )? as i32 ) ) }, diff --git a/src/native_methods.rs b/src/native_methods.rs index d3df129..71f8fa3 100644 --- a/src/native_methods.rs +++ b/src/native_methods.rs @@ -403,6 +403,7 @@ impl JdkInternalUtilSystemPropsRaw { ("user.script", ""), ("user.country", "US"), ("user.variant", ""), + ("sun.nio.MaxDirectMemorySize", "9223372036854775807"), ]; // TODO: Cross-Platform tmpdir // TODO: locale detection diff --git a/src/stackframe.rs b/src/stackframe.rs index 2795a9a..f3a1ee2 100644 --- a/src/stackframe.rs +++ b/src/stackframe.rs @@ -153,8 +153,8 @@ impl OperandStack { let value = self.stack[absolute_index]; self.depth -= 1; match value { - StackValue::Char(c) => Ok(c), - _ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Char but found '{:?}'", index, value))) + StackValue::Int(c) => Ok(c as u16), + _ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Int(Char) but found '{:?}'", index, value))) } }