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 java_rs::vm::runtime::Vm;
|
||||||
|
use std::cmp::Ordering::Equal;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let a = 0.0;
|
let a = 0.0;
|
||||||
|
|
|
||||||
14
src/value.rs
14
src/value.rs
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::vm::object::ObjectRef;
|
use crate::vm::object::ObjectRef;
|
||||||
|
use std::ops::{Add, AddAssign};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Value {
|
pub enum Value {
|
||||||
|
|
@ -12,7 +13,7 @@ pub enum Value {
|
||||||
F32(f32),
|
F32(f32),
|
||||||
F64(f64),
|
F64(f64),
|
||||||
BOOL(bool),
|
BOOL(bool),
|
||||||
CHAR(char),
|
CHAR(i32),
|
||||||
// objects and arrays
|
// objects and arrays
|
||||||
Ref(ObjectRef),
|
Ref(ObjectRef),
|
||||||
// special object
|
// special object
|
||||||
|
|
@ -38,8 +39,7 @@ impl Value {
|
||||||
| Value::CHAR(_)
|
| Value::CHAR(_)
|
||||||
| Value::Ref(_)
|
| Value::Ref(_)
|
||||||
| Value::Utf8(_) => ComputationalType::C1,
|
| Value::Utf8(_) => ComputationalType::C1,
|
||||||
Value::I64(_)
|
Value::I64(_) | Value::F64(_) => ComputationalType::C2,
|
||||||
| Value::F64(_) => ComputationalType::C2
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -83,4 +83,12 @@ impl Value {
|
||||||
panic!();
|
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) => {
|
CharArray(ref mut array) => {
|
||||||
if let I32(value) = value {
|
if let I32(value) = value {
|
||||||
array[index as usize] = char::from_u32(value as u32).unwrap();
|
array[index as usize] = value
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
LongArray(ref mut array) => {
|
LongArray(ref mut array) => {
|
||||||
if let I64(value) = value {
|
if let I64(value) = value {
|
||||||
array[index as usize] = value;
|
array[index as usize] = value;
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ pub enum ObjectRef {
|
||||||
FloatArray(Vec<f32>),
|
FloatArray(Vec<f32>),
|
||||||
DoubleArray(Vec<f64>),
|
DoubleArray(Vec<f64>),
|
||||||
BooleanArray(Vec<bool>),
|
BooleanArray(Vec<bool>),
|
||||||
CharArray(Vec<char>),
|
CharArray(Vec<i32>),
|
||||||
StringArray(Vec<String>),
|
StringArray(Vec<String>),
|
||||||
ObjectArray(ClassId, Vec<ObjectRef>),
|
ObjectArray(ClassId, Vec<ObjectRef>),
|
||||||
Object(Rc<RefCell<Object>>),
|
Object(Rc<RefCell<Object>>),
|
||||||
|
|
@ -86,7 +86,7 @@ impl ObjectRef {
|
||||||
6 => FloatArray(vec![0.0; size]),
|
6 => FloatArray(vec![0.0; size]),
|
||||||
7 => DoubleArray(vec![0.0; size]),
|
7 => DoubleArray(vec![0.0; size]),
|
||||||
4 => BooleanArray(vec![false; size]),
|
4 => BooleanArray(vec![false; size]),
|
||||||
5 => CharArray(vec![0 as char; size]),
|
5 => CharArray(vec![0; size]),
|
||||||
_ => unreachable!("impossible array type"),
|
_ => unreachable!("impossible array type"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -421,19 +421,87 @@ impl Stackframe {
|
||||||
value1.into_i32() >> (value2.into_i32() & MASK_LOWER_5BITS)
|
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 => {
|
FCMPG | FCMPL => {
|
||||||
let value2 = self.pop().into_f32();
|
let value2 = self.pop().into_f32();
|
||||||
let value1 = self.pop().into_f32();
|
let value1 = self.pop().into_f32();
|
||||||
if value1 == value2 {
|
self.push(I32(compare(value1, value2)));
|
||||||
self.push(I32(0))
|
|
||||||
} else if value1 < value2 {
|
|
||||||
self.push(I32(-1))
|
|
||||||
} else if value1 > value2 {
|
|
||||||
self.push(I32(1))
|
|
||||||
}
|
}
|
||||||
//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)
|
IFEQ(jmp_to) | IFNE(jmp_to) | IFLT(jmp_to) | IFGE(jmp_to) | IFGT(jmp_to)
|
||||||
| IFLE(jmp_to) => {
|
| IFLE(jmp_to) => {
|
||||||
let value = self.pop();
|
let value = self.pop();
|
||||||
|
|
@ -774,21 +842,11 @@ impl Stackframe {
|
||||||
let value = self.pop().into_f64();
|
let value = self.pop().into_f64();
|
||||||
self.push(F64(-value));
|
self.push(F64(-value));
|
||||||
}
|
}
|
||||||
ISHL => {
|
|
||||||
let value2 = self.pop().into_i32();
|
|
||||||
let value1 = self.pop().into_i32();
|
|
||||||
self.push(I32(value1 << value2));
|
|
||||||
}
|
|
||||||
LSHL => {
|
LSHL => {
|
||||||
let value2 = self.pop().into_i64();
|
let value2 = self.pop().into_i64();
|
||||||
let value1 = self.pop().into_i64();
|
let value1 = self.pop().into_i64();
|
||||||
self.push(I64(value1 << value2));
|
self.push(I64(value1 << value2));
|
||||||
}
|
}
|
||||||
ISHR => {
|
|
||||||
let value2 = self.pop().into_i32();
|
|
||||||
let value1 = self.pop().into_i32();
|
|
||||||
self.push(I32(value1 >> value2));
|
|
||||||
}
|
|
||||||
LSHR => {
|
LSHR => {
|
||||||
let value2 = self.pop().into_i64();
|
let value2 = self.pop().into_i64();
|
||||||
let value1 = self.pop().into_i64();
|
let value1 = self.pop().into_i64();
|
||||||
|
|
@ -820,6 +878,16 @@ impl Stackframe {
|
||||||
Void
|
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> {
|
fn store(&mut self, index: u8) -> Result<(), Error> {
|
||||||
let index = index as usize;
|
let index = index as usize;
|
||||||
let value = self.pop();
|
let value = self.pop();
|
||||||
|
|
@ -933,3 +1001,10 @@ impl MethodSignature {
|
||||||
MethodSignature { name, num_args }
|
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