Compare commits

..

No commits in common. "022bfe9ee60bc1160e02d846ffc4548ca1695e30" and "9190d3f7e7f3660dafbd2c0999636eb0cde05f1f" have entirely different histories.

2 changed files with 18 additions and 59 deletions

View file

@ -79,7 +79,6 @@ impl Bytecode {
0x6C => (Instruction::DivideInt(), 1), 0x6C => (Instruction::DivideInt(), 1),
0x6D => (Instruction::DivideLong(), 1), 0x6D => (Instruction::DivideLong(), 1),
0x78 => (Instruction::ArithmeticShiftIntLeft(), 1),
0x7A => (Instruction::ArithmeticShiftIntRight(), 1), 0x7A => (Instruction::ArithmeticShiftIntRight(), 1),
0x7C => (Instruction::LogicalShiftIntRight(), 1), 0x7C => (Instruction::LogicalShiftIntRight(), 1),
0x7E => (Instruction::AndInt(), 1), 0x7E => (Instruction::AndInt(), 1),
@ -88,7 +87,6 @@ impl Bytecode {
0x82 => (Instruction::XorInt(), 1), 0x82 => (Instruction::XorInt(), 1),
0x84 => (Instruction::IncrementLocalInt(self.bytes[offset+1], i8::from_be_bytes([self.bytes[offset+2]])), 3), 0x84 => (Instruction::IncrementLocalInt(self.bytes[offset+1], i8::from_be_bytes([self.bytes[offset+2]])), 3),
0x92 => (Instruction::ConvertIntToChar(), 1),
0x95 => (Instruction::CompareFloatL(), 1), 0x95 => (Instruction::CompareFloatL(), 1),
0x96 => (Instruction::CompareFloatG(), 1), 0x96 => (Instruction::CompareFloatG(), 1),
0x99 => { 0x99 => {
@ -326,8 +324,7 @@ pub enum Instruction {
DivideInt() = 0x6C, // integer division, round toward zero and more rules DivideInt() = 0x6C, // integer division, round toward zero and more rules
DivideLong() = 0x6D, // long division DivideLong() = 0x6D, // long division
ArithmeticShiftIntLeft() = 0x78, // shift int left, preserve sign ArithmeticShiftIntRight() = 0x7A, // shift int
ArithmeticShiftIntRight() = 0x7A, // shift int right, preserve sign
LogicalShiftIntRight() = 0x7C, // shift int right with zero extension LogicalShiftIntRight() = 0x7C, // shift int right with zero extension
AndInt() = 0x7E, // bitwise and AndInt() = 0x7E, // bitwise and
@ -335,7 +332,6 @@ pub enum Instruction {
XorInt() = 0x82, // value, value => xor XorInt() = 0x82, // value, value => xor
IncrementLocalInt(u8, i8) = 0x84, // increment local variable by constant i8 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 CompareFloatL() = 0x95, // compare float, push -1 if one is NaN
CompareFloatG() = 0x96, // 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 BranchZero(i16) = 0x99, // branch if value == 0

View file

@ -678,20 +678,13 @@ impl JVM {
wrap_stackframe_error(class, method, frame.operand_stack.push(StackValue::Int(value_0 + value_1)))?; 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() => { Instruction::ArithmeticShiftIntRight() => {
let shift = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))? as u8 & 0b00011111; 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))?; let int = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?;
// rust does arithmetic shift on singed values // rust does arithmetic shift on singed values
wrap_stackframe_error(class, method, frame.operand_stack.push(StackValue::Int(int >> shift)))?; wrap_stackframe_error(class, method, frame.operand_stack.push(StackValue::Int(int >> shift)))?;
} },
Instruction::ArrayLength() => { Instruction::ArrayLength() => {
let array_reference = wrap_stackframe_error(class, method, frame.operand_stack.pop_reference(0))?; 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) => { Instruction::BranchNonNull(branch_offset) => {
let test_value = wrap_stackframe_error(class, method, frame.operand_stack.pop_reference(0))?; 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)))?; 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() => { Instruction::DivideInt() => {
// TODO: Obey all the rules // TODO: Obey all the rules
let quotient = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?; 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 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 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(); 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))?; let this_object = wrap_stackframe_error(class, method, frame.operand_stack.pop_reference(0))?;
arguments.push_front(StackValue::Reference(this_object)); arguments.push_front(StackValue::Reference(this_object));
@ -1061,24 +1048,11 @@ impl JVM {
} }
} }
// TODO: Filter abstract // TODO: I hate this, now I have to find the 'implementation' of a function
// TODO: Check method info match let interface_class_file = self.class_store.class_file_from_idx(target_interface_class_index).unwrap();
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();
let interface_frame = StackFrame::new( let interface_frame = StackFrame::new(
implementing_class_file, interface_class_file,
class_index, target_interface_class_index,
method_index as u16, method_index as u16,
arguments.make_contiguous() arguments.make_contiguous()
); );
@ -1568,18 +1542,7 @@ impl JVM {
let new_object = self.heap_area.make_object(&self.class_store, class_index); 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)))?; 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() => { Instruction::Pop() => {
wrap_stackframe_error(class, method, frame.operand_stack.pop_computational_1(0))?; wrap_stackframe_error(class, method, frame.operand_stack.pop_computational_1(0))?;