added opcodes
This commit is contained in:
parent
2149c8d3de
commit
a7d772c093
5 changed files with 110 additions and 26 deletions
|
|
@ -1,4 +1,5 @@
|
|||
use java_rs::vm::runtime::Vm;
|
||||
use std::cmp::Ordering::Equal;
|
||||
|
||||
fn main() {
|
||||
let a = 0.0;
|
||||
|
|
|
|||
14
src/value.rs
14
src/value.rs
|
|
@ -1,4 +1,5 @@
|
|||
use crate::vm::object::ObjectRef;
|
||||
use std::ops::{Add, AddAssign};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Value {
|
||||
|
|
@ -12,7 +13,7 @@ pub enum Value {
|
|||
F32(f32),
|
||||
F64(f64),
|
||||
BOOL(bool),
|
||||
CHAR(char),
|
||||
CHAR(i32),
|
||||
// objects and arrays
|
||||
Ref(ObjectRef),
|
||||
// special object
|
||||
|
|
@ -38,8 +39,7 @@ impl Value {
|
|||
| Value::CHAR(_)
|
||||
| Value::Ref(_)
|
||||
| Value::Utf8(_) => ComputationalType::C1,
|
||||
Value::I64(_)
|
||||
| Value::F64(_) => ComputationalType::C2
|
||||
Value::I64(_) | Value::F64(_) => ComputationalType::C2,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -83,4 +83,12 @@ impl Value {
|
|||
panic!();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_utf8(self) -> String {
|
||||
if let Value::Utf8(v) = self {
|
||||
v
|
||||
} else {
|
||||
panic!();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,11 +95,11 @@ pub(crate) fn array_store(value: Value, index: Value, arrayref: Value) -> Result
|
|||
}
|
||||
CharArray(ref mut array) => {
|
||||
if let I32(value) = value {
|
||||
array[index as usize] = char::from_u32(value as u32).unwrap();
|
||||
array[index as usize] = value
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
},
|
||||
}
|
||||
LongArray(ref mut array) => {
|
||||
if let I64(value) = value {
|
||||
array[index as usize] = value;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ pub enum ObjectRef {
|
|||
FloatArray(Vec<f32>),
|
||||
DoubleArray(Vec<f64>),
|
||||
BooleanArray(Vec<bool>),
|
||||
CharArray(Vec<char>),
|
||||
CharArray(Vec<i32>),
|
||||
StringArray(Vec<String>),
|
||||
ObjectArray(ClassId, Vec<ObjectRef>),
|
||||
Object(Rc<RefCell<Object>>),
|
||||
|
|
@ -86,7 +86,7 @@ impl ObjectRef {
|
|||
6 => FloatArray(vec![0.0; size]),
|
||||
7 => DoubleArray(vec![0.0; size]),
|
||||
4 => BooleanArray(vec![false; size]),
|
||||
5 => CharArray(vec![0 as char; size]),
|
||||
5 => CharArray(vec![0; size]),
|
||||
_ => unreachable!("impossible array type"),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -421,19 +421,87 @@ impl Stackframe {
|
|||
value1.into_i32() >> (value2.into_i32() & MASK_LOWER_5BITS)
|
||||
));
|
||||
}
|
||||
LCMP => {
|
||||
let value2 = self.pop().into_i64();
|
||||
let value1 = self.pop().into_i64();
|
||||
self.push(I32(compare(value1, value2)));
|
||||
}
|
||||
IINC(index8, const8) => {
|
||||
self.increment(*index8 as usize, *const8 as u16);
|
||||
}
|
||||
I2L => {
|
||||
let value = self.pop().into_i32() as i64;
|
||||
self.push(I64(value));
|
||||
}
|
||||
I2F => {
|
||||
let value = self.pop().into_i32() as f32;
|
||||
self.push(F32(value));
|
||||
}
|
||||
I2D => {
|
||||
let value = self.pop().into_i32() as f64;
|
||||
self.push(F64(value));
|
||||
}
|
||||
L2I => {
|
||||
let value = self.pop().into_i64() as i32;
|
||||
self.push(I32(value));
|
||||
}
|
||||
L2F => {
|
||||
let value = self.pop().into_i64() as f32;
|
||||
self.push(F32(value));
|
||||
}
|
||||
L2D => {
|
||||
let value = self.pop().into_i64() as f64;
|
||||
self.push(F64(value));
|
||||
}
|
||||
WIDE_IINC(index16, const16) => {
|
||||
self.increment(*index16 as usize, *const16);
|
||||
}
|
||||
F2I => {
|
||||
let value = self.pop().into_f32() as i32;
|
||||
self.push(I32(value));
|
||||
}
|
||||
F2L => {
|
||||
let value = self.pop().into_f32() as i64;
|
||||
self.push(I64(value));
|
||||
}
|
||||
F2D => {
|
||||
let value = self.pop().into_f32() as f64;
|
||||
self.push(F64(value));
|
||||
}
|
||||
D2I => {
|
||||
let value = self.pop().into_f64() as i32;
|
||||
self.push(I32(value));
|
||||
}
|
||||
D2L => {
|
||||
let value = self.pop().into_f64() as i64;
|
||||
self.push(I64(value));
|
||||
}
|
||||
D2F => {
|
||||
let value = self.pop().into_f64() as f32;
|
||||
self.push(F32(value));
|
||||
}
|
||||
I2B => {
|
||||
let value = self.pop().into_i32() as u8;
|
||||
self.push(I32(value as i32));
|
||||
}
|
||||
I2C => {
|
||||
let value = self.pop().into_i32();
|
||||
self.push(CHAR(value));
|
||||
}
|
||||
I2S => {
|
||||
let value = self.pop().into_i32() as i16; //semantics for narrowing seems same as java
|
||||
self.push(I32(value as i32));
|
||||
}
|
||||
FCMPG | FCMPL => {
|
||||
let value2 = self.pop().into_f32();
|
||||
let value1 = self.pop().into_f32();
|
||||
if value1 == value2 {
|
||||
self.push(I32(0))
|
||||
} else if value1 < value2 {
|
||||
self.push(I32(-1))
|
||||
} else if value1 > value2 {
|
||||
self.push(I32(1))
|
||||
self.push(I32(compare(value1, value2)));
|
||||
}
|
||||
//TODO something with NaN
|
||||
DCMPG | DCMPL => {
|
||||
let value2 = self.pop().into_f64();
|
||||
let value1 = self.pop().into_f64();
|
||||
self.push(I32(compare(value1, value2)));
|
||||
}
|
||||
|
||||
IFEQ(jmp_to) | IFNE(jmp_to) | IFLT(jmp_to) | IFGE(jmp_to) | IFGT(jmp_to)
|
||||
| IFLE(jmp_to) => {
|
||||
let value = self.pop();
|
||||
|
|
@ -774,21 +842,11 @@ impl Stackframe {
|
|||
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();
|
||||
|
|
@ -820,6 +878,16 @@ impl Stackframe {
|
|||
Void
|
||||
}
|
||||
|
||||
fn increment(&mut self, index: usize, inc: u16) {
|
||||
match &mut self.locals[index] {
|
||||
I32(l) => *l += (inc as i32),
|
||||
I64(l) => *l += (inc as i64),
|
||||
F32(l) => *l += (inc as f32),
|
||||
F64(l) => *l += (inc as f64),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn store(&mut self, index: u8) -> Result<(), Error> {
|
||||
let index = index as usize;
|
||||
let value = self.pop();
|
||||
|
|
@ -933,3 +1001,10 @@ impl MethodSignature {
|
|||
MethodSignature { name, num_args }
|
||||
}
|
||||
}
|
||||
|
||||
fn compare<T>(a: T, b: T) -> i32
|
||||
where
|
||||
T: PartialOrd,
|
||||
{
|
||||
a.partial_cmp(&b).unwrap() as i32
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue