Int Branching instructions

This commit is contained in:
vegowotenks 2024-09-10 01:33:35 +02:00
parent ede316cec3
commit 6610b09c16
4 changed files with 283 additions and 82 deletions

View file

@ -728,6 +728,15 @@ impl JVM {
}
}
Instruction::BranchNonPositive(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::BranchNonZero(branch_offset) => {
let test_value = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?;
@ -755,6 +764,50 @@ impl JVM {
}
}
Instruction::BranchReferenceInequality(branch_offset) => {
let value_2 = wrap_stackframe_error(class, method, frame.operand_stack.pop_reference(0))?;
let value_1 = wrap_stackframe_error(class, method, frame.operand_stack.pop_reference(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::CompareFloatG() => {
let value_2 = wrap_stackframe_error(class, method, frame.operand_stack.pop_float(0))?;
let value_1 = wrap_stackframe_error(class, method, frame.operand_stack.pop_float(0))?;
let comparison_result = if value_1.is_nan() || value_2.is_nan() {
1
} else if value_1 == value_2 {
0
} else if value_1 < value_2 {
-1
} else {
1
};
wrap_stackframe_error(class, method, frame.operand_stack.push(StackValue::Int(comparison_result)))?;
}
Instruction::CompareFloatL() => {
let value_2 = wrap_stackframe_error(class, method, frame.operand_stack.pop_float(0))?;
let value_1 = wrap_stackframe_error(class, method, frame.operand_stack.pop_float(0))?;
let comparison_result = if value_1.is_nan() || value_2.is_nan() {
-1
} else if value_1 == value_2 {
0
} else if value_1 < value_2 {
-1
} else {
1
};
wrap_stackframe_error(class, method, frame.operand_stack.push(StackValue::Int(comparison_result)))?;
}
Instruction::DivideInt() => {
// TODO: Obey all the rules
let quotient = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?;
@ -833,6 +886,10 @@ impl JVM {
wrap_stackframe_error(class, method, frame.operand_stack.push_field_value(fetched_value))?;
}
Instruction::InstanceOf(classref_index) => {
let class_name = class.gather_class(classref_index)?;
}
Instruction::InvokeSpecial(methodref_index) => {
// No instance-based dispatch
let (supplied_class_name, supplied_method_name, supplied_descriptor_string) = class.gather_methodref(methodref_index)?;
@ -1136,6 +1193,19 @@ impl JVM {
}
},
Instruction::LoadLocalFloat0() => {
load_local_float(class, method, frame, 0)?;
}
Instruction::LoadLocalFloat1() => {
load_local_float(class, method, frame, 1)?;
}
Instruction::LoadLocalFloat2() => {
load_local_float(class, method, frame, 2)?;
}
Instruction::LoadLocalFloat3() => {
load_local_float(class, method, frame, 3)?;
}
Instruction::LoadLocalInt0() => {
load_local_int(class, method, frame, 0)?;
}
@ -1253,6 +1323,16 @@ impl JVM {
wrap_stackframe_error(class, method, frame.operand_stack.pop_computational_1(0))?;
}
Instruction::PushConstFloat0() => {
wrap_stackframe_error(class, method, frame.operand_stack.push(StackValue::Float(0.0)))?;
}
Instruction::PushConstFloat1() => {
wrap_stackframe_error(class, method, frame.operand_stack.push(StackValue::Float(1.0)))?;
}
Instruction::PushConstFloat2() => {
wrap_stackframe_error(class, method, frame.operand_stack.push(StackValue::Float(2.0)))?;
}
Instruction::PushConstInt0() => {
wrap_stackframe_error(class, method, frame.operand_stack.push(StackValue::Int(0)))?;
}
@ -1508,6 +1588,14 @@ fn load_local_reference(class: &JavaClassFile, method: &MethodInfo, frame: &mut
Ok(())
}
fn load_local_float(class: &JavaClassFile, method: &MethodInfo, frame: &mut StackFrame, index: usize) -> Result<(), Error> {
let loaded_value = wrap_stackframe_error(class, method, frame.load_local_float(index as u16))?;
wrap_stackframe_error(class, method, frame.operand_stack.push(StackValue::Float(loaded_value)))?;
Ok(())
}
fn load_local_int(class: &JavaClassFile, method: &MethodInfo, frame: &mut StackFrame, index: usize) -> Result<(), Error> {
let loaded_value = wrap_stackframe_error(class, method, frame.load_local_int(index as u16))?;