some arithmetic and some bitwise opcodes

This commit is contained in:
Shautvast 2023-12-02 09:28:17 +01:00
parent d9985df822
commit bab0e0d8c2
4 changed files with 100 additions and 4 deletions

View file

@ -1,6 +1,8 @@
use java_rs::vm::runtime::Vm; use java_rs::vm::runtime::Vm;
fn main() { fn main() {
let a = 0.0;
println!("{}", 1.0 / a);
let mut vm = Vm::new(); let mut vm = Vm::new();
vm.run( vm.run(
"/Users/Shautvast/dev/java.rs/tests", "/Users/Shautvast/dev/java.rs/tests",

View file

@ -17,6 +17,10 @@ pub enum Value {
Ref(ObjectRef), Ref(ObjectRef),
// special object // special object
Utf8(String), Utf8(String),
F32Infinity,
F32Nan,
F64Infinity,
F64Nan
} }
impl Value { impl Value {
@ -29,6 +33,14 @@ impl Value {
} }
} }
pub fn into_i64(self) -> i64 {
if let Value::I64(v) = self {
v
} else {
panic!("{:?} is not I64", self);
}
}
pub fn into_f32(self) -> f32 { pub fn into_f32(self) -> f32 {
if let Value::F32(v) = self { if let Value::F32(v) = self {
v v
@ -37,6 +49,14 @@ impl Value {
} }
} }
pub fn into_f64(self) -> f64 {
if let Value::F64(v) = self {
v
} else {
panic!("{:?} is not F64", self);
}
}
pub fn into_object(self) -> ObjectRef { pub fn into_object(self) -> ObjectRef {
if let Value::Ref(v) = self { if let Value::Ref(v) = self {
v v

View file

@ -93,9 +93,9 @@ pub(crate) fn array_store(value: Value, index: Value, arrayref: Value) -> Result
unreachable!() unreachable!()
} }
} }
CharArray(ref mut array) => unsafe { CharArray(ref mut array) => {
if let I32(value) = value { if let I32(value) = value {
array[index as usize] = char::from_u32_unchecked(value as u32); array[index as usize] = char::from_u32(value as u32).unwrap();
} else { } else {
unreachable!() unreachable!()
} }

View file

@ -240,6 +240,21 @@ impl Stackframe {
let value1 = self.pop(); let value1 = self.pop();
self.push(I32(value1.into_i32() / value2.into_i32())); self.push(I32(value1.into_i32() / value2.into_i32()));
} }
LDIV => {
let value2 = self.pop();
let value1 = self.pop();
self.push(I64(value1.into_i64() / value2.into_i64()));
}
FDIV => {
let value2 = self.pop().into_f32();
let value1 = self.pop().into_f32();
self.push(F32(value1 / value2))
}
DDIV => {
let value2 = self.pop().into_f64();
let value1 = self.pop().into_f64();
self.push(F64(value1 / value2))
}
ISHL => { ISHL => {
let value2 = self.pop(); let value2 = self.pop();
let value1 = self.pop(); let value1 = self.pop();
@ -589,6 +604,65 @@ impl Stackframe {
RETURN_VOID => { RETURN_VOID => {
return Void; return Void;
} }
DREM => {
let value2 = self.pop().into_f64();
let value1 = self.pop().into_f64();
self.push(F64(value1 % value2)); // what about Nan?
}
INEG => {
let value = self.pop().into_i32();
self.push(I32(-value));
}
LNEG => {
let value = self.pop().into_i64();
self.push(I64(-value));
}
FNEG => {
let value = self.pop().into_f32();
self.push(F32(-value));
}
DNEG => {
let value = self.pop().into_f64();
self.push(F64(-value));
}
ISHL => {
let value2 = self.pop().into_i32();
let value1 = self.pop().into_i32();
self.push(I32(value1 << value2));
}
LSHL => {
let value2 = self.pop().into_i64();
let value1 = self.pop().into_i64();
self.push(I64(value1 << value2));
}
ISHR => {
let value2 = self.pop().into_i32();
let value1 = self.pop().into_i32();
self.push(I32(value1 >> value2));
}
LSHR => {
let value2 = self.pop().into_i64();
let value1 = self.pop().into_i64();
self.push(I64(value1 >> value2));
}
IUSHR => {
let value2 = self.pop().into_i32();
let value1 = self.pop().into_i32();
if value1 > 0 {
self.push(I32(value1 >> value2));
} else {
self.push(I32(((value1 as u32) >> value2) as i32));
}
}
LUSHR => {
let value2 = self.pop().into_i64();
let value1 = self.pop().into_i64();
if value1 > 0 {
self.push(I64(value1 >> value2));
} else {
self.push(Value::I64(((value1 as u64) >> value2) as i64));
}
}
_ => { _ => {
panic!("opcode not implemented") panic!("opcode not implemented")
} }