diff --git a/src/bytecode.rs b/src/bytecode.rs index 38247c2..5082bf2 100644 --- a/src/bytecode.rs +++ b/src/bytecode.rs @@ -79,7 +79,6 @@ impl Bytecode { 0x6C => (Instruction::DivideInt(), 1), 0x6D => (Instruction::DivideLong(), 1), - 0x78 => (Instruction::ArithmeticShiftIntLeft(), 1), 0x7A => (Instruction::ArithmeticShiftIntRight(), 1), 0x7C => (Instruction::LogicalShiftIntRight(), 1), 0x7E => (Instruction::AndInt(), 1), @@ -88,7 +87,6 @@ impl Bytecode { 0x82 => (Instruction::XorInt(), 1), 0x84 => (Instruction::IncrementLocalInt(self.bytes[offset+1], i8::from_be_bytes([self.bytes[offset+2]])), 3), - 0x92 => (Instruction::ConvertIntToChar(), 1), 0x95 => (Instruction::CompareFloatL(), 1), 0x96 => (Instruction::CompareFloatG(), 1), 0x99 => { @@ -326,8 +324,7 @@ pub enum Instruction { DivideInt() = 0x6C, // integer division, round toward zero and more rules DivideLong() = 0x6D, // long division - ArithmeticShiftIntLeft() = 0x78, // shift int left, preserve sign - ArithmeticShiftIntRight() = 0x7A, // shift int right, preserve sign + ArithmeticShiftIntRight() = 0x7A, // shift int LogicalShiftIntRight() = 0x7C, // shift int right with zero extension AndInt() = 0x7E, // bitwise and @@ -335,7 +332,6 @@ pub enum Instruction { XorInt() = 0x82, // value, value => xor IncrementLocalInt(u8, i8) = 0x84, // increment local variable by constant i8 - ConvertIntToChar() = 0x92, // truncate int to 16 bits CompareFloatL() = 0x95, // compare float, push -1 if one is NaN CompareFloatG() = 0x96, // compare float, push 1 if one is NaN BranchZero(i16) = 0x99, // branch if value == 0 diff --git a/src/jvm.rs b/src/jvm.rs index c1f869e..bb3f02f 100644 --- a/src/jvm.rs +++ b/src/jvm.rs @@ -678,20 +678,13 @@ impl JVM { wrap_stackframe_error(class, method, frame.operand_stack.push(StackValue::Int(value_0 + value_1)))?; } - Instruction::ArithmeticShiftIntLeft() => { - let shift = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))? as u8 & 0b00011111; - let int = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?; - - // rust does arithmetic shift on singed values - wrap_stackframe_error(class, method, frame.operand_stack.push(StackValue::Int(int << shift)))?; - } Instruction::ArithmeticShiftIntRight() => { let shift = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))? as u8 & 0b00011111; let int = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?; // rust does arithmetic shift on singed values wrap_stackframe_error(class, method, frame.operand_stack.push(StackValue::Int(int >> shift)))?; - } + }, Instruction::ArrayLength() => { let array_reference = wrap_stackframe_error(class, method, frame.operand_stack.pop_reference(0))?; @@ -772,15 +765,6 @@ impl JVM { } } - Instruction::BranchNegative(branch_offset) => { - let test_value = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?; - - if test_value < 0 { - 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::BranchNonNull(branch_offset) => { let test_value = wrap_stackframe_error(class, method, frame.operand_stack.pop_reference(0))?; @@ -914,13 +898,6 @@ impl JVM { wrap_stackframe_error(class, method, frame.operand_stack.push(StackValue::Int(comparison_result)))?; } - Instruction::ConvertIntToChar() => { - let int_value = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?; - let char_value = int_value & 0x0000FFFF; - - frame.operand_stack.push(StackValue::Int(char_value)).unwrap(); - } - Instruction::DivideInt() => { // TODO: Obey all the rules let quotient = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?; @@ -1042,9 +1019,19 @@ impl JVM { let target_interface_class_index = self.class_store.class_idx_from_name(supplied_interface_name).unwrap(); let parsed_expected_descriptor: MethodDescriptor = MethodDescriptor::try_from(supplied_descriptor_string)?; + let (class_index, method_index, method_info) = match ClassMethodIterator::new(target_interface_class_index, &self.class_store) + .filter(|(_cid, _mid, minfo)| minfo.name == *supplied_method_name) + .filter(|(_cid, _mid, minfo)| minfo.descriptor == parsed_expected_descriptor) + .next() { + Some(m) => m, + None => { + // TODO: Throw exception + return Err(Error::RunTimeError(format!("InvokeInterface: Failed to find requested method '{}' with descriptor '{}' in the class '{}'", supplied_method_name, supplied_descriptor_string, supplied_interface_name))); + } + }; let mut arguments = VecDeque::new(); - fill_arguments(class, method, &mut arguments, &parsed_expected_descriptor.argument_types, &mut frame.operand_stack)?; + fill_arguments(class, method, &mut arguments, &method_info.descriptor.argument_types, &mut frame.operand_stack)?; let this_object = wrap_stackframe_error(class, method, frame.operand_stack.pop_reference(0))?; arguments.push_front(StackValue::Reference(this_object)); @@ -1061,24 +1048,11 @@ impl JVM { } } - // TODO: Filter abstract - // TODO: Check method info match - let (class_index, method_index, _method_info) = match ClassMethodIterator::new(object_class_index, &self.class_store) - .filter(|(_cid, _mid, minfo)| minfo.name == *supplied_method_name) - .filter(|(_cid, _mid, minfo)| minfo.descriptor == parsed_expected_descriptor) - .next() { - Some(m) => m, - None => { - // TODO: Throw exception - return Err(Error::RunTimeError(format!("InvokeInterface: Failed to find requested implementation of method '{}' with descriptor '{}' in the class '{}'", supplied_method_name, supplied_descriptor_string, supplied_interface_name))); - } - }; - - - let implementing_class_file = self.class_store.class_file_from_idx(class_index).unwrap(); + // TODO: I hate this, now I have to find the 'implementation' of a function + let interface_class_file = self.class_store.class_file_from_idx(target_interface_class_index).unwrap(); let interface_frame = StackFrame::new( - implementing_class_file, - class_index, + interface_class_file, + target_interface_class_index, method_index as u16, arguments.make_contiguous() ); @@ -1568,18 +1542,7 @@ impl JVM { let new_object = self.heap_area.make_object(&self.class_store, class_index); wrap_stackframe_error(class, method, frame.operand_stack.push(StackValue::Reference(new_object)))?; - } - - Instruction::NoOperation() => { - - } - - Instruction::OrInt() => { - let value_0 = 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))?; - - wrap_stackframe_error(class, method, frame.operand_stack.push(StackValue::Int(value_0 | value_1)))?; - } + }, Instruction::Pop() => { wrap_stackframe_error(class, method, frame.operand_stack.pop_computational_1(0))?;