WIP Strings
This commit is contained in:
parent
d132502771
commit
8f6651e303
6 changed files with 60 additions and 17 deletions
|
|
@ -540,6 +540,7 @@ pub enum Value {
|
|||
BOOL(bool),
|
||||
CHAR(char),
|
||||
Ref(Arc<UnsafeCell<ObjectRef>>),
|
||||
Utf8(String)
|
||||
}
|
||||
|
||||
impl Value {
|
||||
|
|
@ -555,6 +556,7 @@ impl Into<UnsafeValue> for Value {
|
|||
}
|
||||
|
||||
pub type UnsafeValue = Arc<UnsafeCell<Value>>;
|
||||
pub type Type = Arc<RefCell<Class>>;
|
||||
|
||||
unsafe impl Send for Value {}
|
||||
|
||||
|
|
|
|||
|
|
@ -226,7 +226,7 @@ fn read_attribute(
|
|||
*index += attribute_length;
|
||||
|
||||
if let CpEntry::Utf8(s) = &constant_pool.get(&attribute_name_index).unwrap() {
|
||||
println!("Att [{}]", s);
|
||||
// println!("Att [{}]", s);
|
||||
return match s.as_str() {
|
||||
"ConstantValue" => {
|
||||
assert_eq!(info.len(), 2);
|
||||
|
|
@ -274,6 +274,7 @@ fn read_attribute(
|
|||
"BootstrapMethods" => Some(("".into(), AttributeType::BootstrapMethods)), //stub
|
||||
"InnerClasses" => Some(("".into(), AttributeType::InnerClasses)), //stub
|
||||
"Signature" => Some(("".into(), AttributeType::Signature)), //stub
|
||||
"NestHost" => Some(("".into(), AttributeType::NestHost)), //stub
|
||||
//TODO more actual attribute implementations
|
||||
_ => None,
|
||||
};
|
||||
|
|
|
|||
24
src/heap.rs
24
src/heap.rs
|
|
@ -1,9 +1,9 @@
|
|||
use std::cell::{RefCell, UnsafeCell};
|
||||
use std::fmt;
|
||||
use std::ops::Deref;
|
||||
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
|
||||
#[derive(Debug)]
|
||||
|
|
@ -16,10 +16,20 @@ pub enum ObjectRef {
|
|||
DoubleArray(Vec<f64>),
|
||||
BooleanArray(Vec<bool>),
|
||||
CharArray(Vec<char>),
|
||||
ObjectArray(Vec<Arc<UnsafeCell<ObjectRef>>>),
|
||||
ObjectArray(Type, Vec<Arc<UnsafeCell<ObjectRef>>>),
|
||||
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
|
||||
pub struct Object {
|
||||
// locked: bool,
|
||||
|
|
@ -66,8 +76,8 @@ impl Object {
|
|||
}
|
||||
|
||||
pub fn set(&mut self, class_name: &String, field_name: &String, value: UnsafeValue) {
|
||||
let borrow = self.class.borrow();
|
||||
let (_type, index) =borrow
|
||||
let borrow = self.class.borrow();
|
||||
let (_type, index) = borrow
|
||||
.object_field_mapping
|
||||
.get(class_name)
|
||||
.unwrap()
|
||||
|
|
@ -77,8 +87,8 @@ impl Object {
|
|||
}
|
||||
|
||||
pub fn get(&mut self, class_name: &String, field_name: &String) -> &UnsafeValue {
|
||||
let borrow = self.class.borrow();
|
||||
let (_type, index) =borrow
|
||||
let borrow = self.class.borrow();
|
||||
let (_type, index) = borrow
|
||||
.object_field_mapping
|
||||
.get(class_name)
|
||||
.unwrap()
|
||||
|
|
|
|||
46
src/vm.rs
46
src/vm.rs
|
|
@ -129,6 +129,7 @@ impl Vm {
|
|||
self.local_stack().push(Value::I32(-1));
|
||||
}
|
||||
ICONST_0 => {
|
||||
println!("ICONST_0");
|
||||
self.local_stack().push(Value::I32(0));
|
||||
}
|
||||
ICONST_1 => {
|
||||
|
|
@ -190,8 +191,14 @@ impl Vm {
|
|||
self.local_stack().push(Value::F64(*d));
|
||||
}
|
||||
CpEntry::StringRef(utf8) => {
|
||||
let string = get_class(self, Some(&this_class.borrow().name), "java/lang/String").unwrap();
|
||||
self.local_stack().push(Value::Ref(Arc::new(UnsafeCell::new(ObjectRef::Object(Box::new(Object::new(string)))))))
|
||||
//TODO
|
||||
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) => {
|
||||
self.local_stack().push(Value::I64(*l));
|
||||
|
|
@ -283,7 +290,7 @@ impl Vm {
|
|||
return self.local_stack().pop();
|
||||
}
|
||||
RETURN_VOID => {
|
||||
self.stack.pop(); // Void is also returned as a value
|
||||
println!("RETURN");
|
||||
return Ok(Value::void());
|
||||
}
|
||||
GETSTATIC => {
|
||||
|
|
@ -303,7 +310,7 @@ impl Vm {
|
|||
self.local_stack().push_arc(borrow.static_data.get(*val_index).unwrap().as_ref().unwrap().clone());
|
||||
}
|
||||
PUTSTATIC => {
|
||||
println!("putstatic");
|
||||
println!("PUTSTATIC");
|
||||
let mut borrow = this_class.borrow_mut();
|
||||
let cp_index = read_u16(&code.opcodes, pc);
|
||||
let (class_index, field_name_and_type_index) =
|
||||
|
|
@ -314,7 +321,7 @@ impl Vm {
|
|||
println!("field {}", name);
|
||||
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 = *val_index;
|
||||
let value = self.local_stack().pop()?;
|
||||
|
|
@ -366,6 +373,8 @@ impl Vm {
|
|||
}
|
||||
},
|
||||
INVOKEVIRTUAL | INVOKESPECIAL => unsafe {
|
||||
println!("INVOKE");
|
||||
// TODO differentiate these opcodes
|
||||
let cp_index = read_u16(&code.opcodes, pc);
|
||||
if let Some(invocation) =
|
||||
get_signature_for_invoke(&method.constant_pool, cp_index)
|
||||
|
|
@ -413,6 +422,7 @@ impl Vm {
|
|||
}
|
||||
},
|
||||
NEW => {
|
||||
println!("NEW");
|
||||
let class_index = &read_u16(&code.opcodes, pc);
|
||||
let borrow = this_class.borrow();
|
||||
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.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
|
||||
_ => {
|
||||
|
|
@ -470,9 +500,9 @@ impl Vm {
|
|||
ObjectRef::DoubleArray(ref array) => {
|
||||
self.local_stack().push(Value::F64(array[index]));
|
||||
}
|
||||
ObjectRef::ObjectArray(ref array) => {
|
||||
ObjectRef::ObjectArray(_arraytype, ref data) => {
|
||||
self.local_stack()
|
||||
.push(Value::Ref(array.get(index).unwrap().clone()));
|
||||
.push(Value::Ref(data[index].clone()));
|
||||
}
|
||||
ObjectRef::Object(_) => {} //throw error?
|
||||
}
|
||||
|
|
@ -535,7 +565,7 @@ impl Vm {
|
|||
array[*index as usize] = value
|
||||
}
|
||||
}
|
||||
ObjectRef::ObjectArray(ref mut array) => {
|
||||
ObjectRef::ObjectArray(arraytype, ref mut array) => {
|
||||
if let Value::Ref(ref value) = *value.get() {
|
||||
array[*index as usize] = value.clone();
|
||||
}
|
||||
|
|
|
|||
BIN
tests/Main.class
BIN
tests/Main.class
Binary file not shown.
|
|
@ -9,6 +9,6 @@ public class Main {
|
|||
public static void main(String[] args){
|
||||
FloatBean f = new FloatBean();
|
||||
f.setValue(42F);
|
||||
System.out.println(f.getValue());
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue