added opcodes

This commit is contained in:
Shautvast 2023-12-06 17:52:59 +01:00
parent 2149c8d3de
commit a7d772c093
5 changed files with 110 additions and 26 deletions

View file

@ -1,4 +1,5 @@
use java_rs::vm::runtime::Vm;
use std::cmp::Ordering::Equal;
fn main() {
let a = 0.0;

View file

@ -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!();
}
}
}

View file

@ -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;

View file

@ -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"),
}
}

View file

@ -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
}