AndLong, IntModulo, ASHRLong and native methods
This commit is contained in:
parent
8e5b6bb2b8
commit
796e52241d
3 changed files with 336 additions and 7 deletions
34
src/jvm.rs
34
src/jvm.rs
|
@ -786,6 +786,14 @@ impl JVM {
|
|||
wrap_stackframe_error(class, method, frame.operand_stack.push_long(long << shift))?;
|
||||
}
|
||||
|
||||
Instruction::ArithmeticShiftLongRight() => {
|
||||
let shift = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))? as u8 % 64;
|
||||
let long = wrap_stackframe_error(class, method, frame.operand_stack.pop_long(0))?;
|
||||
|
||||
// rust does arithmetic shift on signed values
|
||||
wrap_stackframe_error(class, method, frame.operand_stack.push_long(long >> shift))?;
|
||||
}
|
||||
|
||||
Instruction::ArrayLength() => {
|
||||
let array_reference = wrap_stackframe_error(class, method, frame.operand_stack.pop_reference(0))?;
|
||||
|
||||
|
@ -810,6 +818,13 @@ impl JVM {
|
|||
wrap_stackframe_error(class, method, frame.operand_stack.push(StackValue::Int(value_1 & value_2)))?;
|
||||
}
|
||||
|
||||
Instruction::AndLong() => {
|
||||
let value_1 = wrap_stackframe_error(class, method, frame.operand_stack.pop_long(0))?;
|
||||
let value_2 = wrap_stackframe_error(class, method, frame.operand_stack.pop_long(0))?;
|
||||
|
||||
wrap_stackframe_error(class, method, frame.operand_stack.push_long(value_1 & value_2))?;
|
||||
}
|
||||
|
||||
Instruction::BranchAlways(branch_offset) => {
|
||||
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};
|
||||
|
@ -1837,9 +1852,20 @@ impl JVM {
|
|||
let factor_1 = wrap_stackframe_error(class, method, frame.operand_stack.pop_long(0))?;
|
||||
let factor_2 = wrap_stackframe_error(class, method, frame.operand_stack.pop_long(0))?;
|
||||
|
||||
let result = factor_1 * factor_2;
|
||||
let (result, overflowed) = i64::overflowing_mul(factor_1, factor_2);
|
||||
let java_result = if overflowed {
|
||||
if result < 0 && ((factor_1 >= 0 && factor_2 <= 0 ) || (factor_1 < 0 && factor_2 >= 0)) {
|
||||
result.abs()
|
||||
} else if factor_1 < 0 && factor_2 < 0 {
|
||||
if result < 0 { result } else { -result }
|
||||
} else {
|
||||
-result.abs()
|
||||
}
|
||||
} else {
|
||||
result
|
||||
};
|
||||
|
||||
wrap_stackframe_error(class, method, frame.operand_stack.push_long(result))?;
|
||||
wrap_stackframe_error(class, method, frame.operand_stack.push_long(java_result))?;
|
||||
}
|
||||
|
||||
Instruction::ModuloInt() => {
|
||||
|
@ -2282,8 +2308,8 @@ impl JVM {
|
|||
let _ = 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(1, StackValue::Long0(long0)))?;
|
||||
wrap_stackframe_error(class, method, frame.store_local(2, StackValue::Long1()))?;
|
||||
wrap_stackframe_error(class, method, frame.store_local(0, StackValue::Long0(long0)))?;
|
||||
wrap_stackframe_error(class, method, frame.store_local(1, StackValue::Long1()))?;
|
||||
}
|
||||
Instruction::StoreLocalLong1() => {
|
||||
let _ = wrap_stackframe_error(class, method, frame.operand_stack.pop_long1(0))?;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue