Int Branching instructions
This commit is contained in:
parent
ede316cec3
commit
6610b09c16
4 changed files with 283 additions and 82 deletions
88
src/jvm.rs
88
src/jvm.rs
|
@ -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))?;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue