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;
|
||||
|
||||
fn main() {
|
||||
let a = 0.0;
|
||||
println!("{}", 1.0 / a);
|
||||
let mut vm = Vm::new();
|
||||
vm.run(
|
||||
"/Users/Shautvast/dev/java.rs/tests",
|
||||
|
|
|
|||
20
src/value.rs
20
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
|
||||
|
|
|
|||
|
|
@ -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!()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue