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 { impl ObjectRef {
pub fn new_object_array(class: &Class, size: usize) -> Self { pub fn new_object_array(class: &Class, size: usize) -> Self {
ObjectArray(class.id, Vec::with_capacity(size)) 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 { pub fn new_int_array(size: usize) -> Self {
IntArray(Vec::with_capacity(size)) IntArray(Vec::with_capacity(size))
} }

View file

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

View file

@ -3,6 +3,7 @@ use anyhow::{anyhow, Error};
use crate::class::ObjectRef; use crate::class::ObjectRef;
use crate::class::Value::{self, *}; use crate::class::Value::{self, *};
pub(crate) fn array_load(index: Value, arrayref: Value) -> Result<Value, Error> { pub(crate) fn array_load(index: Value, arrayref: Value) -> Result<Value, Error> {
if let I32(index) = index { if let I32(index) = index {
let index = index as usize; let index = index as usize;

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

View file

@ -1,6 +1,7 @@
use std::collections::HashMap; use std::collections::HashMap;
use anyhow::Error; use anyhow::Error;
use log::debug;
use crate::class::{Class, Value}; use crate::class::{Class, Value};
use crate::classloader::classdef::CpEntry; 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, _) = let (name_index, _) =
classdef.cp_name_and_type(field_name_and_type_index); classdef.cp_name_and_type(field_name_and_type_index);
let field_name = classdef.cp_utf8(name_index); let field_name = classdef.cp_utf8(name_index);
let that_class_name_index = classdef.cp_class_ref(class_index); let that_class_name_index = classdef.cp_class_ref(class_index);
let that_class_name = classdef.cp_utf8(that_class_name_index); let that_class_name = classdef.cp_utf8(that_class_name_index);
classmanager::load_class_by_name(that_class_name); 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) .get(field_name)
.unwrap(); // safe because field must be there .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> { 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 std::io::Write;
use anyhow::Error; 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::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::classloader::io::{read_u16, read_u8};
use crate::classmanager; use crate::classmanager;
use crate::vm::array::{array_load, array_store}; use crate::vm::array::{array_load, array_store};
@ -137,14 +137,9 @@ impl Vm {
) -> Result<Value, Error> { ) -> Result<Value, Error> {
classmanager::load_class_by_name(class_name); classmanager::load_class_by_name(class_name);
let class = classmanager::get_class_by_name(class_name).unwrap(); 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) 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( pub fn execute_class(
&mut self, &mut self,
stackframes: &mut Vec<StackFrame>, stackframes: &mut Vec<StackFrame>,
@ -370,6 +365,12 @@ impl Vm {
Self::current_frame(stackframes).push(value.clone()); Self::current_frame(stackframes).push(value.clone());
Self::current_frame(stackframes).push(value); 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 => { IDIV => {
let value2 = Self::current_frame(stackframes).pop()?; let value2 = Self::current_frame(stackframes).pop()?;
let value1 = Self::current_frame(stackframes).pop()?; let value1 = Self::current_frame(stackframes).pop()?;
@ -597,7 +598,12 @@ impl Vm {
class_to_instantiate, class_to_instantiate,
)); ));
Self::current_frame(stackframes).push(Ref(object)); 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 => { ANEWARRAY => {
let classdef = classmanager::get_classdef(&this_class.id); let classdef = classmanager::get_classdef(&this_class.id);
@ -609,8 +615,7 @@ impl Vm {
let count = Self::current_frame(stackframes).pop()?; let count = Self::current_frame(stackframes).pop()?;
if let I32(count) = count { if let I32(count) = count {
let array = ObjectRef::new_object_array(arraytype, count as usize); let array = ObjectRef::new_object_array(arraytype, count as usize);
Self::current_frame(stackframes).push(Ref(array));
Self::current_frame(stackframes).push(Value::Ref(array));
} else { } else {
panic!(); panic!();
} }