generified objectrefs, so we can include arrays

This commit is contained in:
Sander Hautvast 2023-10-09 21:36:46 +02:00
parent d4ea4aed58
commit 6feebec373
3 changed files with 39 additions and 16 deletions

View file

@ -1,6 +1,6 @@
use std::cell::{RefCell, UnsafeCell};
use crate::classloader::CpEntry;
use crate::heap::Object;
use crate::heap::{Object, ObjectRef};
use anyhow::{anyhow, Error};
use std::collections::HashMap;
use std::fmt;
@ -265,7 +265,7 @@ pub enum Value {
F64(f64),
BOOL(bool),
CHAR(char),
Ref(Arc<UnsafeCell<Object>>),
Ref(Arc<UnsafeCell<ObjectRef>>),
}
unsafe impl Send for Value {}

View file

@ -13,6 +13,20 @@ pub struct Object {
pub data: HashMap<u16, Arc<UnsafeCell<Value>>>, //TODO optimize
}//arrays
#[derive(Debug)]
pub enum ObjectRef{
ByteArray(Vec<i8>),
ShortArray(Vec<i16>),
IntArray(Vec<i32>),
LongArray(Vec<i64>),
FloatArray(Vec<f32>),
DoubleArray(Vec<f64>),
BooleanArray(Vec<bool>),
CharArray(Vec<char>),
ObjectArray(Vec<Object>),
Object(Object),
}
unsafe impl Send for Object {}
unsafe impl Sync for Object {}
@ -52,7 +66,7 @@ impl fmt::Debug for Object {
}
pub(crate) struct Heap {
objects: Vec<Arc<UnsafeCell<Object>>>,
objects: Vec<Arc<UnsafeCell<ObjectRef>>>,
}
impl Heap {
@ -60,7 +74,7 @@ impl Heap {
Self { objects: vec![] }
}
pub(crate) fn new_object(&mut self, object: Arc<UnsafeCell<Object>>) {
pub(crate) fn new_object(&mut self, object: Arc<UnsafeCell<ObjectRef>>) {
self.objects.push(object);
}
}

View file

@ -8,7 +8,7 @@ use anyhow::Error;
use crate::class::{AttributeType, Class, Value};
use crate::class::Value::Void;
use crate::classloader::{CpEntry, load_class};
use crate::heap::{Heap, Object};
use crate::heap::{Heap, Object, ObjectRef};
use crate::io::*;
use crate::opcodes::*;
@ -237,13 +237,15 @@ impl Vm {
// let index = self.local_stack().pop()?;
// let array_ref = self.local_stack().pop()?;
}
ISTORE => unsafe{
ISTORE => {
unsafe {
let index = read_u8(&code.opcodes, pc);
let value = &*(self.local_stack().pop()?.get());
if let Value::I32(int) = value {
let value = self.local_stack().pop()?;
if let Value::I32(int) = *value.get() {
// TODO local vars
}
}
}
POP => {
self.local_stack().pop().expect("Stack empty");
}
@ -270,13 +272,16 @@ impl Vm {
if let CpEntry::NameAndType(name, _) =
method.constant_pool.get(name_and_type_index).unwrap()
{
let value = (*(*instance).get()).data.get(name).unwrap();
let objectref = &(*instance.get());
if let ObjectRef::Object(object) = objectref {
let value = object.data.get(name).unwrap();
self.local_stack().push_arc(Arc::clone(value));
}
}
}
}
}
}
PUTFIELD => {
unsafe {
let cp_index = read_u16(&code.opcodes, pc);
@ -285,9 +290,13 @@ impl Vm {
{
if let CpEntry::NameAndType(name_index, _) = method.constant_pool.get(name_and_type_index).unwrap() {
let value = self.local_stack().pop()?;
let mut objectref = &*self.local_stack().pop()?.get();
if let Value::Ref(instance) = objectref {
(*(*instance).get()).data.insert(*name_index, value);
let mut objectref = self.local_stack().pop()?;
if let Value::Ref(instance) = &mut *objectref.get() {
if let ObjectRef::Object(ref mut object) = &mut *instance.get() {
object.data.insert(*name_index, value);
} else {
panic!("not an object, maybe array");
}
}
}
}
@ -338,7 +347,7 @@ impl Vm {
{
println!("new {}", new_class);
let class = self.get_class(new_class)?;
let object = Arc::new(UnsafeCell::new(self.new_instance(class)));
let object = Arc::new(UnsafeCell::new(ObjectRef::Object(self.new_instance(class))));
self.local_stack().push(Value::Ref(Arc::clone(&object)));
self.heap.new_object(object);
}