diff --git a/src/main.rs b/src/main.rs index 814f931..f58b4cc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,8 @@ use java_rs::vm::runtime::Vm; fn main() { + let a = 0.0; + println!("{}", 1.0 / a); let mut vm = Vm::new(); vm.run( "/Users/Shautvast/dev/java.rs/tests", diff --git a/src/value.rs b/src/value.rs index c5528b7..389a26d 100644 --- a/src/value.rs +++ b/src/value.rs @@ -17,6 +17,10 @@ pub enum Value { Ref(ObjectRef), // special object Utf8(String), + F32Infinity, + F32Nan, + F64Infinity, + F64Nan } 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 { if let Value::F32(v) = self { 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 { if let Value::Ref(v) = self { v diff --git a/src/vm/array.rs b/src/vm/array.rs index 8b1e3a3..fbb955f 100644 --- a/src/vm/array.rs +++ b/src/vm/array.rs @@ -93,9 +93,9 @@ pub(crate) fn array_store(value: Value, index: Value, arrayref: Value) -> Result unreachable!() } } - CharArray(ref mut array) => unsafe { + CharArray(ref mut array) => { 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 { unreachable!() } diff --git a/src/vm/runtime.rs b/src/vm/runtime.rs index 08743f1..1bbb70c 100644 --- a/src/vm/runtime.rs +++ b/src/vm/runtime.rs @@ -240,6 +240,21 @@ impl Stackframe { let value1 = self.pop(); 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 => { let value2 = self.pop(); let value1 = self.pop(); @@ -350,7 +365,7 @@ impl Stackframe { invocation.method.name.as_str(), args, ) - .unwrap() + .unwrap() // TODO remove unwrap in line above, error handling } else { let mut new_stackframe = Stackframe::new(args); @@ -395,7 +410,7 @@ impl Stackframe { invocation.method.name.as_str(), args, ) - .unwrap() + .unwrap() // TODO remove unwrap in line above, error handling } else { let mut new_stackframe = Stackframe::new(args); @@ -589,6 +604,65 @@ impl Stackframe { 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") }