diff --git a/src/class.rs b/src/class.rs index 56a6093..e6f78bf 100644 --- a/src/class.rs +++ b/src/class.rs @@ -1,3 +1,4 @@ +use std::cell::RefCell; use crate::classloader::CpEntry; use crate::heap::Object; use anyhow::{anyhow, Error}; @@ -263,7 +264,7 @@ pub enum Value { F64(f64), BOOL(bool), CHAR(char), - Ref(Rc), + Ref(Rc>), } unsafe impl Send for Value {} diff --git a/src/heap.rs b/src/heap.rs index da74a37..d010eae 100644 --- a/src/heap.rs +++ b/src/heap.rs @@ -1,3 +1,4 @@ +use std::cell::RefCell; use crate::class::{Class, Value}; use std::collections::HashMap; use std::fmt; @@ -8,7 +9,7 @@ pub struct Object { // locked: bool, // hashcode: i32, pub class: Rc, - pub data: HashMap>, //TODO optimize + pub data: HashMap>>, //TODO optimize } unsafe impl Send for Object {} @@ -16,7 +17,7 @@ unsafe impl Send for Object {} unsafe impl Sync for Object {} impl Object { - pub fn new(class: Rc, data: HashMap>) -> Self { + pub fn new(class: Rc, data: HashMap>>) -> Self { Self { class, data } } @@ -46,7 +47,7 @@ impl fmt::Debug for Object { } pub(crate) struct Heap { - objects: Vec>, + objects: Vec>>, } impl Heap { @@ -54,7 +55,7 @@ impl Heap { Self { objects: vec![] } } - pub(crate) fn new_object(&mut self, object: Rc) { + pub(crate) fn new_object(&mut self, object: Rc>) { self.objects.push(object); } } diff --git a/src/vm.rs b/src/vm.rs index 9094587..418a721 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -1,4 +1,6 @@ +use std::cell::RefCell; use std::collections::HashMap; +use std::ops::{Deref, DerefMut}; use std::rc::Rc; use anyhow::{anyhow, Error}; @@ -13,7 +15,7 @@ use crate::opcodes::*; #[derive(Debug)] struct StackFrame { at: String, - data: Vec>, + data: Vec>>, } impl StackFrame { @@ -24,11 +26,11 @@ impl StackFrame { Self { at, data: vec![] } } - fn push(&mut self, val: Rc) { + fn push(&mut self, val: Rc>) { self.data.push(val); } - fn pop(&mut self) -> Result, Error> { + fn pop(&mut self) -> Result>, Error> { Ok(self.data.pop().unwrap()) } } @@ -90,7 +92,7 @@ impl Vm { "L" => Value::Null, _ => Value::Void, }; - data.insert(f.name_index, Rc::new(value)); + data.insert(f.name_index, Rc::new(RefCell::new(value))); } Object::new(class.clone(), data) } @@ -100,8 +102,8 @@ impl Vm { &mut self, class_name: &str, method_name: &str, - args: Vec>, - ) -> Result, Error> { + args: Vec>>, + ) -> Result>, Error> { println!("execute {}.{}", class_name, method_name); let class = self.get_class(class_name)?; let method = class.get_method(method_name)?; @@ -118,7 +120,7 @@ impl Vm { BIPUSH => { println!("BISPUSH"); let c = code.opcodes[pc] as i32; - self.local_stack().push(Rc::new(Value::I32(c))); + self.local_stack().push(Rc::new(RefCell::new(Value::I32(c)))); pc += 1; } LDC => { @@ -126,10 +128,10 @@ impl Vm { let cp_index = read_u8(&code.opcodes, pc) as u16; match method.constant_pool.get(&cp_index).unwrap() { CpEntry::Integer(i) => { - self.local_stack().push(Rc::new(Value::I32(*i))); + self.local_stack().push(Rc::new(RefCell::new(Value::I32(*i)))); } CpEntry::Float(f) => { - self.local_stack().push(Rc::new(Value::F32(*f))); + self.local_stack().push(Rc::new(RefCell::new(Value::F32(*f)))); } _ => {} } @@ -139,10 +141,10 @@ impl Vm { let cp_index = read_u16(&code.opcodes, pc); match method.constant_pool.get(&cp_index).unwrap() { CpEntry::Integer(i) => { - self.local_stack().push(Rc::new(Value::I32(*i))); + self.local_stack().push(Rc::new(RefCell::new(Value::I32(*i)))); } CpEntry::Float(f) => { - self.local_stack().push(Rc::new(Value::F32(*f))); + self.local_stack().push(Rc::new(RefCell::new(Value::F32(*f)))); } _ => { panic!("unexpected") @@ -154,10 +156,10 @@ impl Vm { let cp_index = read_u16(&code.opcodes, pc); match method.constant_pool.get(&cp_index).unwrap() { CpEntry::Double(d) => { - self.local_stack().push(Rc::new(Value::F64(*d))); + self.local_stack().push(Rc::new(RefCell::new(Value::F64(*d)))); } CpEntry::Long(l) => { - self.local_stack().push(Rc::new(Value::I64(*l))); + self.local_stack().push(Rc::new(RefCell::new(Value::I64(*l)))); } _ => { panic!("unexpected") @@ -220,7 +222,7 @@ impl Vm { RETURN_VOID => { println!("return"); self.stack.pop(); - return Ok(Rc::new(Void)); + return Ok(Rc::new(RefCell::new(Void))); } GETFIELD => { println!("GETFIELD"); @@ -228,14 +230,14 @@ impl Vm { if let CpEntry::Fieldref(_class_index, name_and_type_index) = method.constant_pool.get(&cp_index).unwrap() { - if let Value::Ref(inst) = &*self.local_stack().pop()? { + if let Value::Ref(instance) = self.local_stack().pop()?.borrow().deref() { //TODO smell? if let CpEntry::NameAndType(name, _) = method.constant_pool.get(name_and_type_index).unwrap() { - let value = inst.data.get(name).unwrap(); - println!("{:?}", value); - self.local_stack().push(value.clone()); + let borrow = instance.borrow(); + let value = borrow.data.get(name).unwrap(); + self.local_stack().push(Rc::clone(value)); } } } @@ -247,10 +249,15 @@ impl Vm { if let CpEntry::Fieldref(_class_index, name_and_type_index) = method.constant_pool.get(&cp_index).unwrap() { - let value = self.local_stack().pop()?; - println!("value {:?}", value); - let objectref = self.local_stack().pop()?; - println!("objectref {:?}", objectref); + if let CpEntry::NameAndType(name_index, _) = method.constant_pool.get(name_and_type_index).unwrap() { + let value = self.local_stack().pop()?; + let objectref = self.local_stack().pop()?; + let mut b = objectref.borrow_mut(); + let b = b.deref_mut(); + if let Value::Ref(object) = b { + object.borrow_mut().data.insert(*name_index, value); + } + } } pc += 2; } @@ -265,8 +272,9 @@ impl Vm { } args.insert(0, self.local_stack().pop()?); let return_value = self.execute(class.as_str(), signature, args)?; - if let Void = *return_value {} else { // not let? - self.local_stack().push(return_value); + let borrow = return_value.borrow(); + if let &Void = borrow.deref() { + self.local_stack().push(return_value.clone()); } } @@ -284,8 +292,9 @@ impl Vm { } args.insert(0, self.local_stack().pop()?); let return_value = self.execute(class.as_str(), signature, args)?; - if let Void = *return_value {} else { // not let? - self.local_stack().push(return_value); + let borrow = return_value.borrow(); + if let &Void = borrow.deref() { + self.local_stack().push(return_value.clone()); } } @@ -302,8 +311,8 @@ impl Vm { { println!("new {}", new_class); let class = self.get_class(new_class)?; - let object = Rc::new(self.new_instance(class)); - self.local_stack().push(Rc::new(Value::Ref(object.clone()))); + let object = Rc::new(RefCell::new(self.new_instance(class))); + self.local_stack().push(Rc::new(RefCell::new(Value::Ref(Rc::clone(&object))))); self.heap.new_object(object); } }