From 2f7442228bed02c598e1561f701abfabf04d025a Mon Sep 17 00:00:00 2001 From: Shautvast Date: Mon, 6 Nov 2023 20:46:26 +0100 Subject: [PATCH] newarray --- src/class.rs | 25 +++++++++++++++++++++++++ src/classmanager.rs | 1 - src/vm/array.rs | 3 ++- src/vm/opcodes.rs | 6 ++++++ src/vm/operations.rs | 5 +++-- src/vm/vm.rs | 27 ++++++++++++++++----------- 6 files changed, 52 insertions(+), 15 deletions(-) diff --git a/src/class.rs b/src/class.rs index 954b4de..63d0109 100644 --- a/src/class.rs +++ b/src/class.rs @@ -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)) } diff --git a/src/classmanager.rs b/src/classmanager.rs index 969cf49..718d60e 100644 --- a/src/classmanager.rs +++ b/src/classmanager.rs @@ -146,7 +146,6 @@ impl ClassManager { } fn get_classdef(&self, id: &ClassId) -> &ClassDef { - debug!("get_classdef {}", *id); self.classdefs.get(&id).unwrap() } diff --git a/src/vm/array.rs b/src/vm/array.rs index 8ce814d..bf8ff8e 100644 --- a/src/vm/array.rs +++ b/src/vm/array.rs @@ -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 { 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 { diff --git a/src/vm/opcodes.rs b/src/vm/opcodes.rs index adab1ae..6e087f1 100644 --- a/src/vm/opcodes.rs +++ b/src/vm/opcodes.rs @@ -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> = 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> = 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> = 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" ; diff --git a/src/vm/operations.rs b/src/vm/operations.rs index 402ef5e..2ba18e2 100644 --- a/src/vm/operations.rs +++ b/src/vm/operations.rs @@ -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 Result, index: u16) -> Option { diff --git a/src/vm/vm.rs b/src/vm/vm.rs index e8c8917..f4b8da1 100644 --- a/src/vm/vm.rs +++ b/src/vm/vm.rs @@ -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 { 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, _this_class: ClassId, _method: &Method, _args: Vec) -> Result { - Ok(Null) - } - pub fn execute_class( &mut self, stackframes: &mut Vec, @@ -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!(); }