some arithmetic and some bitwise opcodes
This commit is contained in:
parent
d9985df822
commit
bab0e0d8c2
4 changed files with 100 additions and 4 deletions
|
|
@ -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",
|
||||||
|
|
|
||||||
20
src/value.rs
20
src/value.rs
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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!()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue