small improvements

This commit is contained in:
Sander Hautvast 2023-10-13 17:13:10 +02:00
parent 6cf0365dd0
commit 1e6f7956e8
3 changed files with 32 additions and 55 deletions

View file

@ -1,16 +1,19 @@
use std::cell::{RefCell, UnsafeCell};
use crate::classloader::CpEntry;
use crate::heap::{Object, ObjectRef};
use anyhow::{anyhow, Error};
use std::cell::UnsafeCell;
use std::collections::HashMap;
use std::fmt;
use std::hash::Hash;
use std::rc::Rc;
use std::sync::Arc;
use anyhow::{anyhow, Error};
use crate::classloader::CpEntry;
use crate::heap::ObjectRef;
use crate::io::read_u16;
// the class definition as read from the class file + derived values
/// the class definition as read from the class file + derived values
// TODO implement call to static initializers
// TODO implement storage for static fields
#[derive(Debug)]
pub struct Class {
pub minor_version: u16,
@ -25,7 +28,7 @@ pub struct Class {
pub fields: HashMap<String, Field>,
pub methods: HashMap<String, Method>,
pub attributes: HashMap<String, AttributeType>,
pub(crate) field_mapping: Option<HashMap<String, HashMap<String, (String, usize)>>>, // first key: this/super/supersuper-name(etc), second key: fieldname, value (type, index)
pub(crate) field_mapping: Option<HashMap<String, HashMap<String, (String, usize)>>>, // first key: this/super/supersuper-name(etc), second key: fieldname, value (type, index). See below
}
impl Class {

View file

@ -12,7 +12,7 @@ pub struct Object {
// locked: bool,
// hashcode: i32,
pub class: Rc<Class>,
pub data: Option<Vec<Arc<UnsafeCell<Value>>>>,
pub data: Vec<Arc<UnsafeCell<Value>>>,
}//arrays
// can contain object or array
@ -37,14 +37,15 @@ unsafe impl Sync for Object {}
// object, not array
impl Object {
pub fn new(class: Rc<Class>) -> Self {
Self { class, data: None }
let instance_data = Object::init_fields(&class);
Self { class, data: instance_data}
}
// initializes all non-static fields to their default values
pub(crate) fn init_fields(&mut self) {
let mut field_data = Vec::with_capacity(self.class.n_fields());
pub(crate) fn init_fields(class: &Class) -> Vec<Arc<UnsafeCell<Value>>>{
let mut field_data = Vec::with_capacity(class.n_fields());
for (_, fields) in self.class.field_mapping.as_ref().unwrap() {
for (_, fields) in class.field_mapping.as_ref().unwrap() {
for (_, (fieldtype, _)) in fields {
let value = match fieldtype.as_str() {
"Z" => Value::BOOL(false),
@ -61,19 +62,17 @@ impl Object {
}
}
self.data = Some(field_data);
field_data
}
pub fn set(&mut self, class_name: &String, field_name: &String, value: Arc<UnsafeCell<Value>>) {
let p = self.class.field_mapping.as_ref().unwrap();
let p2 = p.get(class_name).unwrap();
let (_type, index) = p2.get(field_name).unwrap();
self.data.as_mut().unwrap()[*index] = value;
let (_type, index) = self.class.field_mapping.as_ref().unwrap().get(class_name).unwrap().get(field_name).unwrap();
self.data[*index] = value;
}
pub fn get(&mut self, class_name: &String, field_name: &String) -> &Arc<UnsafeCell<Value>> {
let (_type, index) = &self.class.field_mapping.as_ref().unwrap().get(class_name).unwrap().get(field_name).unwrap(); // (index, type)
&self.data.as_ref().unwrap()[*index]
let (_type, index) = &self.class.field_mapping.as_ref().unwrap().get(class_name).unwrap().get(field_name).unwrap();
&self.data[*index]
}
fn get_field_name(&self, cp_index: &u16) -> &str {

View file

@ -100,11 +100,7 @@ impl Vm {
pub fn new_instance(class: Rc<Class>) -> Object {
let mut class = class;
// let mut outer = HashMap::new();
//TODO
let mut instance = Object::new(class.clone());
instance.init_fields();
instance
}
@ -317,24 +313,9 @@ impl Vm {
}
}
}
INVOKEVIRTUAL => unsafe {
INVOKEVIRTUAL | INVOKESPECIAL => unsafe {
let cp_index = read_u16(&code.opcodes, pc);
if let Some(invocation) = get_signature_for_invoke(Rc::clone(&method.constant_pool), cp_index) {
let mut args = Vec::with_capacity(invocation.method.num_args);
for _ in 0..invocation.method.num_args {
args.insert(0, self.local_stack().pop()?);
}
args.insert(0, self.local_stack().pop()?);
let mut returnvalue = self.execute(&invocation.class_name, &invocation.method.name, args)?;
match *returnvalue.get() {
Void => {}
_ => { self.local_stack().push_arc(returnvalue.clone()); }
}
}
}
INVOKESPECIAL => unsafe {
let cp_index = read_u16(&code.opcodes, pc);
if let Some(invocation) = get_signature_for_invoke(Rc::clone(&method.constant_pool), cp_index) {
if let Some(invocation) = get_signature_for_invoke(&method.constant_pool, cp_index) {
let mut args = Vec::with_capacity(invocation.method.num_args);
for _ in 0..invocation.method.num_args {
args.insert(0, self.local_stack().pop()?);
@ -348,22 +329,16 @@ impl Vm {
}
}
NEW => {
let class_index = read_u16(&code.opcodes, pc);
println!("cp_index {}", class_index);
if let CpEntry::ClassRef(class_name_index) =
method.constant_pool.get(&class_index).unwrap()
{
if let CpEntry::Utf8(new_class) =
method.constant_pool.get(class_name_index).unwrap()
{
println!("new {}", new_class);
let class = self.get_class(new_class)?;
let class_index = &read_u16(&code.opcodes, pc);
let class_name_index = class.get_class_ref(class_index).unwrap();
let class_name = class.get_utf8(class_name_index).unwrap();
let class = self.get_class(class_name)?;
let object = Arc::new(UnsafeCell::new(ObjectRef::Object(Box::new(Vm::new_instance(class)))));
self.local_stack().push(Value::Ref(Arc::clone(&object)));
self.heap.new_object(object);
}
}
}
//TODO implement all opcodes
_ => {
panic!("opcode not implemented {:?}", self.stack)
@ -503,7 +478,7 @@ struct MethodSignature {
num_args: usize,
}
fn get_signature_for_invoke(cp: Rc<HashMap<u16, CpEntry>>, index: u16) -> Option<Invocation> {
fn get_signature_for_invoke(cp: &Rc<HashMap<u16, CpEntry>>, index: u16) -> Option<Invocation> {
if let CpEntry::MethodRef(class_index, name_and_type_index) = cp.get(&index).unwrap() {
if let Some(method_signature) = get_name_and_type(Rc::clone(&cp), *name_and_type_index) {
if let CpEntry::ClassRef(class_name_index) = cp.get(class_index).unwrap() {