WIP Strings

This commit is contained in:
Sander Hautvast 2023-10-17 12:06:24 +02:00
parent d132502771
commit 8f6651e303
6 changed files with 60 additions and 17 deletions

View file

@ -540,6 +540,7 @@ pub enum Value {
BOOL(bool), BOOL(bool),
CHAR(char), CHAR(char),
Ref(Arc<UnsafeCell<ObjectRef>>), Ref(Arc<UnsafeCell<ObjectRef>>),
Utf8(String)
} }
impl Value { impl Value {
@ -555,6 +556,7 @@ impl Into<UnsafeValue> for Value {
} }
pub type UnsafeValue = Arc<UnsafeCell<Value>>; pub type UnsafeValue = Arc<UnsafeCell<Value>>;
pub type Type = Arc<RefCell<Class>>;
unsafe impl Send for Value {} unsafe impl Send for Value {}

View file

@ -226,7 +226,7 @@ fn read_attribute(
*index += attribute_length; *index += attribute_length;
if let CpEntry::Utf8(s) = &constant_pool.get(&attribute_name_index).unwrap() { if let CpEntry::Utf8(s) = &constant_pool.get(&attribute_name_index).unwrap() {
println!("Att [{}]", s); // println!("Att [{}]", s);
return match s.as_str() { return match s.as_str() {
"ConstantValue" => { "ConstantValue" => {
assert_eq!(info.len(), 2); assert_eq!(info.len(), 2);
@ -274,6 +274,7 @@ fn read_attribute(
"BootstrapMethods" => Some(("".into(), AttributeType::BootstrapMethods)), //stub "BootstrapMethods" => Some(("".into(), AttributeType::BootstrapMethods)), //stub
"InnerClasses" => Some(("".into(), AttributeType::InnerClasses)), //stub "InnerClasses" => Some(("".into(), AttributeType::InnerClasses)), //stub
"Signature" => Some(("".into(), AttributeType::Signature)), //stub "Signature" => Some(("".into(), AttributeType::Signature)), //stub
"NestHost" => Some(("".into(), AttributeType::NestHost)), //stub
//TODO more actual attribute implementations //TODO more actual attribute implementations
_ => None, _ => None,
}; };

View file

@ -1,9 +1,9 @@
use std::cell::{RefCell, UnsafeCell}; use std::cell::{RefCell, UnsafeCell};
use std::fmt; use std::fmt;
use std::ops::Deref;
use std::sync::Arc; use std::sync::Arc;
use crate::class::{Class, UnsafeValue, Value}; use crate::class::{Class, Type, UnsafeValue, Value};
use crate::heap::ObjectRef::{IntArray, ObjectArray};
// can contain object or array // can contain object or array
#[derive(Debug)] #[derive(Debug)]
@ -16,10 +16,20 @@ pub enum ObjectRef {
DoubleArray(Vec<f64>), DoubleArray(Vec<f64>),
BooleanArray(Vec<bool>), BooleanArray(Vec<bool>),
CharArray(Vec<char>), CharArray(Vec<char>),
ObjectArray(Vec<Arc<UnsafeCell<ObjectRef>>>), ObjectArray(Type, Vec<Arc<UnsafeCell<ObjectRef>>>),
Object(Box<Object>), Object(Box<Object>),
} }
impl ObjectRef {
pub fn new_object_array(class: Type, size: usize) -> Self {
ObjectArray(class, Vec::with_capacity(size))
}
pub fn new_int_array(size: usize) -> Self {
IntArray(Vec::with_capacity(size))
}
}
// trying to implement efficient object instance storage // trying to implement efficient object instance storage
pub struct Object { pub struct Object {
// locked: bool, // locked: bool,
@ -67,7 +77,7 @@ impl Object {
pub fn set(&mut self, class_name: &String, field_name: &String, value: UnsafeValue) { pub fn set(&mut self, class_name: &String, field_name: &String, value: UnsafeValue) {
let borrow = self.class.borrow(); let borrow = self.class.borrow();
let (_type, index) =borrow let (_type, index) = borrow
.object_field_mapping .object_field_mapping
.get(class_name) .get(class_name)
.unwrap() .unwrap()
@ -78,7 +88,7 @@ impl Object {
pub fn get(&mut self, class_name: &String, field_name: &String) -> &UnsafeValue { pub fn get(&mut self, class_name: &String, field_name: &String) -> &UnsafeValue {
let borrow = self.class.borrow(); let borrow = self.class.borrow();
let (_type, index) =borrow let (_type, index) = borrow
.object_field_mapping .object_field_mapping
.get(class_name) .get(class_name)
.unwrap() .unwrap()

View file

@ -129,6 +129,7 @@ impl Vm {
self.local_stack().push(Value::I32(-1)); self.local_stack().push(Value::I32(-1));
} }
ICONST_0 => { ICONST_0 => {
println!("ICONST_0");
self.local_stack().push(Value::I32(0)); self.local_stack().push(Value::I32(0));
} }
ICONST_1 => { ICONST_1 => {
@ -190,8 +191,14 @@ impl Vm {
self.local_stack().push(Value::F64(*d)); self.local_stack().push(Value::F64(*d));
} }
CpEntry::StringRef(utf8) => { CpEntry::StringRef(utf8) => {
let string = get_class(self, Some(&this_class.borrow().name), "java/lang/String").unwrap(); //TODO
self.local_stack().push(Value::Ref(Arc::new(UnsafeCell::new(ObjectRef::Object(Box::new(Object::new(string))))))) let stringclass = get_class(self, Some(&this_class.borrow().name), "java/lang/String").unwrap();
let stringinstance = Arc::new(UnsafeCell::new(ObjectRef::Object(Box::new(
Vm::new_instance(stringclass.clone()),
))));
let string = this_class.borrow().cp_utf8(utf8).unwrap().to_owned();
let s = self.execute_class(stringclass, "<init>", vec![Arc::new(UnsafeCell::new(Value::Utf8(string)))])?;
self.local_stack().push(Value::Ref(stringinstance));
} }
CpEntry::Long(l) => { CpEntry::Long(l) => {
self.local_stack().push(Value::I64(*l)); self.local_stack().push(Value::I64(*l));
@ -283,7 +290,7 @@ impl Vm {
return self.local_stack().pop(); return self.local_stack().pop();
} }
RETURN_VOID => { RETURN_VOID => {
self.stack.pop(); // Void is also returned as a value println!("RETURN");
return Ok(Value::void()); return Ok(Value::void());
} }
GETSTATIC => { GETSTATIC => {
@ -303,7 +310,7 @@ impl Vm {
self.local_stack().push_arc(borrow.static_data.get(*val_index).unwrap().as_ref().unwrap().clone()); self.local_stack().push_arc(borrow.static_data.get(*val_index).unwrap().as_ref().unwrap().clone());
} }
PUTSTATIC => { PUTSTATIC => {
println!("putstatic"); println!("PUTSTATIC");
let mut borrow = this_class.borrow_mut(); let mut borrow = this_class.borrow_mut();
let cp_index = read_u16(&code.opcodes, pc); let cp_index = read_u16(&code.opcodes, pc);
let (class_index, field_name_and_type_index) = let (class_index, field_name_and_type_index) =
@ -314,7 +321,7 @@ impl Vm {
println!("field {}", name); println!("field {}", name);
let that_class_name = borrow.cp_utf8(class_name_index).unwrap(); let that_class_name = borrow.cp_utf8(class_name_index).unwrap();
if &borrow.name == that_class_name { if &borrow.name == that_class_name {// may have to apply this in GETSTATIC too
let (_, val_index) = borrow.static_field_mapping.get(that_class_name).unwrap().get(name).as_ref().unwrap(); let (_, val_index) = borrow.static_field_mapping.get(that_class_name).unwrap().get(name).as_ref().unwrap();
let val_index = *val_index; let val_index = *val_index;
let value = self.local_stack().pop()?; let value = self.local_stack().pop()?;
@ -366,6 +373,8 @@ impl Vm {
} }
}, },
INVOKEVIRTUAL | INVOKESPECIAL => unsafe { INVOKEVIRTUAL | INVOKESPECIAL => unsafe {
println!("INVOKE");
// TODO differentiate these opcodes
let cp_index = read_u16(&code.opcodes, pc); let cp_index = read_u16(&code.opcodes, pc);
if let Some(invocation) = if let Some(invocation) =
get_signature_for_invoke(&method.constant_pool, cp_index) get_signature_for_invoke(&method.constant_pool, cp_index)
@ -413,6 +422,7 @@ impl Vm {
} }
}, },
NEW => { NEW => {
println!("NEW");
let class_index = &read_u16(&code.opcodes, pc); let class_index = &read_u16(&code.opcodes, pc);
let borrow = this_class.borrow(); let borrow = this_class.borrow();
let class_name_index = borrow.cp_class_ref(class_index).unwrap(); let class_name_index = borrow.cp_class_ref(class_index).unwrap();
@ -425,6 +435,26 @@ impl Vm {
self.local_stack().push(Value::Ref(Arc::clone(&object))); self.local_stack().push(Value::Ref(Arc::clone(&object)));
self.heap.new_object(object); self.heap.new_object(object);
} }
ANEWARRAY => unsafe{
println!("ANEWARRAY");
let class_index = &read_u16(&code.opcodes, pc);
let borrow = this_class.borrow();
let class_name_index = borrow.cp_class_ref(class_index).unwrap();
let class_name = borrow.cp_utf8(class_name_index).unwrap();
let arraytype = get_class(self, Some(&borrow.name), class_name)?;
let count = self.local_stack().pop()?;
if let Value::I32(count) = *count.get(){ // why does pop()?.get() give weird results?
let array = ObjectRef::new_object_array(arraytype, count as usize);
let array = Arc::new(UnsafeCell::new(array));
self.local_stack().push(Value::Ref(Arc::clone(&array)));
println!("{}",self.local_stack().len());
self.heap.new_object(array);
} else {
panic!();
}
}
//TODO implement all opcodes //TODO implement all opcodes
_ => { _ => {
@ -470,9 +500,9 @@ impl Vm {
ObjectRef::DoubleArray(ref array) => { ObjectRef::DoubleArray(ref array) => {
self.local_stack().push(Value::F64(array[index])); self.local_stack().push(Value::F64(array[index]));
} }
ObjectRef::ObjectArray(ref array) => { ObjectRef::ObjectArray(_arraytype, ref data) => {
self.local_stack() self.local_stack()
.push(Value::Ref(array.get(index).unwrap().clone())); .push(Value::Ref(data[index].clone()));
} }
ObjectRef::Object(_) => {} //throw error? ObjectRef::Object(_) => {} //throw error?
} }
@ -535,7 +565,7 @@ impl Vm {
array[*index as usize] = value array[*index as usize] = value
} }
} }
ObjectRef::ObjectArray(ref mut array) => { ObjectRef::ObjectArray(arraytype, ref mut array) => {
if let Value::Ref(ref value) = *value.get() { if let Value::Ref(ref value) = *value.get() {
array[*index as usize] = value.clone(); array[*index as usize] = value.clone();
} }

Binary file not shown.

View file

@ -9,6 +9,6 @@ public class Main {
public static void main(String[] args){ public static void main(String[] args){
FloatBean f = new FloatBean(); FloatBean f = new FloatBean();
f.setValue(42F); f.setValue(42F);
System.out.println(f.getValue());
} }
} }