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 java_rs::vm::runtime::Vm;
use std::cmp::Ordering::Equal;
fn main() { fn main() {
let a = 0.0; let a = 0.0;

View file

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

View file

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

View file

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

View file

@ -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 { DCMPG | DCMPL => {
self.push(I32(-1)) let value2 = self.pop().into_f64();
} else if value1 > value2 { let value1 = self.pop().into_f64();
self.push(I32(1)) self.push(I32(compare(value1, value2)));
}
//TODO something with NaN
} }
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
}