This commit is contained in:
Shautvast 2023-11-06 20:46:26 +01:00
parent 3f7e2e2786
commit 2f7442228b
6 changed files with 52 additions and 15 deletions

View file

@ -119,11 +119,36 @@ impl ObjectRef {
}
}
pub enum ArrayType {
BOOLEAN = 4,
CHAR = 5,
FLOAT = 6,
DOUBLE = 7,
BYTE = 8,
SHORT = 9,
INT = 10,
LONG = 11,
}
impl ObjectRef {
pub fn new_object_array(class: &Class, size: usize) -> Self {
ObjectArray(class.id, Vec::with_capacity(size))
}
pub fn new_array(arraytype: u8, size: usize) -> Self {
match arraytype {
8 => ByteArray(Vec::with_capacity(size)),
9 => ShortArray(Vec::with_capacity(size)),
10 => IntArray(Vec::with_capacity(size)),
11 => LongArray(Vec::with_capacity(size)),
6 => FloatArray(Vec::with_capacity(size)),
7 => DoubleArray(Vec::with_capacity(size)),
4 => BooleanArray(Vec::with_capacity(size)),
5 => CharArray(Vec::with_capacity(size)),
_ => unreachable!("impossible array type")
}
}
pub fn new_int_array(size: usize) -> Self {
IntArray(Vec::with_capacity(size))
}

View file

@ -146,7 +146,6 @@ impl ClassManager {
}
fn get_classdef(&self, id: &ClassId) -> &ClassDef {
debug!("get_classdef {}", *id);
self.classdefs.get(&id).unwrap()
}

View file

@ -3,6 +3,7 @@ use anyhow::{anyhow, Error};
use crate::class::ObjectRef;
use crate::class::Value::{self, *};
pub(crate) fn array_load(index: Value, arrayref: Value) -> Result<Value, Error> {
if let I32(index) = index {
let index = index as usize;
@ -92,7 +93,7 @@ pub(crate) fn array_store(value: Value, index: Value, arrayref: Value) -> Result
unreachable!()
}
}
ObjectRef::CharArray(ref mut array) => unsafe{
ObjectRef::CharArray(ref mut array) => unsafe {
if let I32(value) = value {
array[index as usize] = char::from_u32_unchecked(value as u32);
} else {

View file

@ -190,6 +190,7 @@ pub const _DUP2_X1: u8 = 93;
//(0x5d) Duplicate the top one or two operand stack values and insert two or three values down
pub const _DUP2_X2: u8 = 94; // (0x5e) Duplicate the top one or two operand stack values and insert two, three, or four values down
pub const IADD:u8 = 96;
pub const _FADD: u8 = 98;
// (0x62) Add float
pub const _DADD: u8 = 99; // (0x63) add double
@ -212,6 +213,7 @@ pub const _FNEG: u8 = 118;
// (0x76) Negate float
pub const _DNEG: u8 = 119; // (0x77) Negate double
pub const ISHR:u8 = 122;
pub const _F2I: u8 = 139;
// (0x8b) Convert float to int
pub const _F2L: u8 = 140;
@ -284,6 +286,7 @@ pub const INVOKESTATIC: u8 = 184;
// (0xb8) Invoke a class (static) method
pub const NEW: u8 = 187;
// (0xbb) Create new object
pub const NEWARRAY:u8 = 188;
pub const ANEWARRAY: u8 = 189;
// (0xbd)
pub const ARRAYLENGTH: u8 = 190;
@ -393,6 +396,7 @@ pub const OPCODES:Lazy<Vec<&str>> = Lazy::new(|| {
opcodes[_DUP2 as usize] = "_DUP2" ;
opcodes[_DUP2_X1 as usize] = "_DUP2_X1" ;
opcodes[_DUP2_X2 as usize] = "_DUP2_X2" ;
opcodes[IADD as usize] = "IADD";
opcodes[_FADD as usize] = "_FADD" ;
opcodes[_DADD as usize] = "_DADD" ;
opcodes[_DSUB as usize] = "_DSUB" ;
@ -405,6 +409,7 @@ pub const OPCODES:Lazy<Vec<&str>> = Lazy::new(|| {
opcodes[_DREM as usize] = "_DREM" ;
opcodes[_FNEG as usize] = "_FNEG" ;
opcodes[_DNEG as usize] = "_DNEG" ;
opcodes[ISHR as usize] = "ISHR" ;
opcodes[_F2I as usize] = "_F2I" ;
opcodes[_F2L as usize] = "_F2L" ;
opcodes[_F2D as usize] = "_F2D" ;
@ -441,6 +446,7 @@ pub const OPCODES:Lazy<Vec<&str>> = Lazy::new(|| {
opcodes[INVOKESPECIAL as usize] = "INVOKESPECIAL" ;
opcodes[INVOKESTATIC as usize] = "INVOKESTATIC" ;
opcodes[NEW as usize] = "NEW" ;
opcodes[NEWARRAY as usize] = "NEWARRAY" ;
opcodes[ANEWARRAY as usize] = "ANEWARRAY" ;
opcodes[ARRAYLENGTH as usize] = "ARRAYLENGTH" ;
opcodes[_ATHROW as usize] = "_ATHROW" ;

View file

@ -1,6 +1,7 @@
use std::collections::HashMap;
use anyhow::Error;
use log::debug;
use crate::class::{Class, Value};
use crate::classloader::classdef::CpEntry;
@ -17,7 +18,6 @@ pub(crate) fn get_static(this_class: &Class, field_index: u16) -> Result<Value,
let (name_index, _) =
classdef.cp_name_and_type(field_name_and_type_index);
let field_name = classdef.cp_utf8(name_index);
let that_class_name_index = classdef.cp_class_ref(class_index);
let that_class_name = classdef.cp_utf8(that_class_name_index);
classmanager::load_class_by_name(that_class_name);
@ -30,7 +30,8 @@ pub(crate) fn get_static(this_class: &Class, field_index: u16) -> Result<Value,
.get(field_name)
.unwrap(); // safe because field must be there
Ok(classmanager::get_static(&this_class.id, type_index.index))
debug!("get_static {}.{}", that_class_name, field_name);
Ok(classmanager::get_static(&that_class.id, type_index.index))
}
pub(crate) fn get_name_and_type(cp: &HashMap<u16, CpEntry>, index: u16) -> Option<MethodSignature> {

View file

@ -1,11 +1,11 @@
use std::io::Write;
use anyhow::Error;
use log::{debug, info};
use log::debug;
use crate::class::{Class, ClassId, Object, ObjectRef, Value};
use crate::class::{Class, Object, ObjectRef, Value};
use crate::class::Value::{F32, F64, I32, I64, Null, Ref, Utf8, Void};
use crate::classloader::classdef::{AttributeType, CpEntry, Method, Modifier};
use crate::classloader::classdef::{AttributeType, CpEntry, Modifier};
use crate::classloader::io::{read_u16, read_u8};
use crate::classmanager;
use crate::vm::array::{array_load, array_store};
@ -137,14 +137,9 @@ impl Vm {
) -> Result<Value, Error> {
classmanager::load_class_by_name(class_name);
let class = classmanager::get_class_by_name(class_name).unwrap();
let _classdef = classmanager::get_classdef(&class.id);
self.execute_class(stack, class, method_name, args)
}
pub fn execute_class_id(&self, _stack: &mut Vec<StackFrame>, _this_class: ClassId, _method: &Method, _args: Vec<Value>) -> Result<Value, Error> {
Ok(Null)
}
pub fn execute_class(
&mut self,
stackframes: &mut Vec<StackFrame>,
@ -370,6 +365,12 @@ impl Vm {
Self::current_frame(stackframes).push(value.clone());
Self::current_frame(stackframes).push(value);
}
IADD => {
let stack = Self::current_frame(stackframes);
let value2 = stack.pop()?;
let value1 = stack.pop()?;
stack.push(I32(value1.into_i32() + value2.into_i32()));
}
IDIV => {
let value2 = Self::current_frame(stackframes).pop()?;
let value1 = Self::current_frame(stackframes).pop()?;
@ -597,7 +598,12 @@ impl Vm {
class_to_instantiate,
));
Self::current_frame(stackframes).push(Ref(object));
// self.heap.new_object(object);
}
NEWARRAY =>{
let arraytype = read_u8(&code.opcodes, pc);
let count = Self::current_frame(stackframes).pop()?;
let array = ObjectRef::new_array(arraytype, count.into_i32() as usize);
Self::current_frame(stackframes).push(Ref(array));
}
ANEWARRAY => {
let classdef = classmanager::get_classdef(&this_class.id);
@ -609,8 +615,7 @@ impl Vm {
let count = Self::current_frame(stackframes).pop()?;
if let I32(count) = count {
let array = ObjectRef::new_object_array(arraytype, count as usize);
Self::current_frame(stackframes).push(Value::Ref(array));
Self::current_frame(stackframes).push(Ref(array));
} else {
panic!();
}