correcter string init

This commit is contained in:
Shautvast 2023-10-17 15:10:15 +02:00
parent 3ce9ce10b4
commit e3f58a7b9f
3 changed files with 65 additions and 28 deletions

View file

@ -1,8 +1,7 @@
use std::cell::{Ref, RefCell, RefMut, UnsafeCell}; use std::cell::{RefCell, UnsafeCell};
use std::collections::HashMap; use std::collections::HashMap;
use std::fmt; use std::fmt;
use std::hash::Hash; use std::hash::Hash;
use std::os::macos::raw::stat;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Arc; use std::sync::Arc;
@ -84,7 +83,7 @@ pub struct Class {
pub access_flags: u16, pub access_flags: u16,
pub name: String, pub name: String,
pub super_class_name: Option<String>, pub super_class_name: Option<String>,
pub super_class: Option<Arc<RefCell<Class>>>, pub super_class: Option<Type>,
pub interface_indices: Vec<u16>, pub interface_indices: Vec<u16>,
pub interfaces: Vec<Class>, pub interfaces: Vec<Class>,
pub fields: HashMap<String, Field>, pub fields: HashMap<String, Field>,
@ -546,7 +545,7 @@ pub enum Value {
F64(f64), F64(f64),
BOOL(bool), BOOL(bool),
CHAR(char), CHAR(char),
Ref(Arc<UnsafeCell<ObjectRef>>), Ref(UnsafeRef),
Utf8(String), Utf8(String),
} }
@ -563,6 +562,19 @@ impl Into<UnsafeValue> for Value {
} }
pub type UnsafeValue = Arc<UnsafeCell<Value>>; pub type UnsafeValue = Arc<UnsafeCell<Value>>;
pub type UnsafeRef = Arc<UnsafeCell<ObjectRef>>;
pub fn unsafe_ref(object: ObjectRef) -> UnsafeRef{
return Arc::new(UnsafeCell::new(object))
}
pub fn unsafe_val(val: Value) -> UnsafeValue{
return Arc::new(UnsafeCell::new(val))
}
pub fn type_ref(class: Class) -> Type{
return Arc::new(RefCell::new(class))
}
pub type Type = Arc<RefCell<Class>>; pub type Type = Arc<RefCell<Class>>;
unsafe impl Send for Value {} unsafe impl Send for Value {}

View file

@ -4,7 +4,7 @@ use std::fmt::{Debug, Formatter};
use std::sync::Arc; use std::sync::Arc;
use crate::class::{Class, Type, UnsafeValue, Value}; use crate::class::{Class, Type, UnsafeValue, Value};
use crate::heap::ObjectRef::{IntArray, ObjectArray}; use crate::heap::ObjectRef::{ByteArray, IntArray, ObjectArray};
// can contain object or array // can contain object or array
pub enum ObjectRef { pub enum ObjectRef {
@ -20,6 +20,23 @@ pub enum ObjectRef {
Object(Box<Object>), Object(Box<Object>),
} }
fn into_vec_i8(v: Vec<u8>) -> Vec<i8> {
// ideally we'd use Vec::into_raw_parts, but it's unstable,
// so we have to do it manually:
// first, make sure v's destructor doesn't free the data
// it thinks it owns when it goes out of scope
let mut v = std::mem::ManuallyDrop::new(v);
// then, pick apart the existing Vec
let p = v.as_mut_ptr();
let len = v.len();
let cap = v.capacity();
// finally, adopt the data into a new Vec
unsafe { Vec::from_raw_parts(p as *mut i8, len, cap) }
}
impl ObjectRef { impl ObjectRef {
pub fn new_object_array(class: Type, size: usize) -> Self { pub fn new_object_array(class: Type, size: usize) -> Self {
ObjectArray(class, Vec::with_capacity(size)) ObjectArray(class, Vec::with_capacity(size))
@ -28,6 +45,10 @@ impl ObjectRef {
pub fn new_int_array(size: usize) -> Self { pub fn new_int_array(size: usize) -> Self {
IntArray(Vec::with_capacity(size)) IntArray(Vec::with_capacity(size))
} }
pub fn new_byte_array(d: Vec<u8>) -> Arc<UnsafeCell<Self>> {
Arc::new(UnsafeCell::new(ByteArray(into_vec_i8(d))))
}
} }
impl Debug for ObjectRef{ impl Debug for ObjectRef{

View file

@ -2,11 +2,12 @@ use std::cell::{RefCell, UnsafeCell};
use std::collections::HashMap; use std::collections::HashMap;
use std::ops::Deref; use std::ops::Deref;
use std::rc::Rc; use std::rc::Rc;
use std::string;
use std::sync::Arc; use std::sync::Arc;
use anyhow::{anyhow, Error}; use anyhow::{anyhow, Error};
use crate::class::{AttributeType, Class, get_class, Modifier, UnsafeValue, Value}; use crate::class::{AttributeType, Class, get_class, Modifier, unsafe_ref, unsafe_val, UnsafeValue, Value};
use crate::class::Value::Void; use crate::class::Value::Void;
use crate::classloader::CpEntry; use crate::classloader::CpEntry;
use crate::heap::{Heap, Object, ObjectRef}; use crate::heap::{Heap, Object, ObjectRef};
@ -30,10 +31,10 @@ impl StackFrame {
} }
fn push(&mut self, val: Value) { fn push(&mut self, val: Value) {
self.data.push(Arc::new(UnsafeCell::new(val))); self.data.push(unsafe_val(val));
} }
fn push_arc(&mut self, val: UnsafeValue) { fn push_ref(&mut self, val: UnsafeValue) {
self.data.push(val); self.data.push(val);
} }
@ -195,12 +196,15 @@ impl Vm {
CpEntry::StringRef(utf8) => { CpEntry::StringRef(utf8) => {
//TODO //TODO
let stringclass = get_class(self, Some(&this_class.borrow().name), "java/lang/String").unwrap(); let stringclass = get_class(self, Some(&this_class.borrow().name), "java/lang/String").unwrap();
let stringinstance = Arc::new(UnsafeCell::new(ObjectRef::Object(Box::new( let stringinstance = unsafe_val(
Vm::new_instance(stringclass.clone()), Value::Ref(unsafe_ref(ObjectRef::Object(Box::new(
)))); Vm::new_instance(stringclass.clone()))))));
let string = this_class.borrow().cp_utf8(utf8).unwrap().to_owned(); let string: Vec<u8> = this_class.borrow().cp_utf8(utf8).unwrap().to_owned().as_bytes().into();
let s = self.execute_class(stringclass, "<init>", vec![Arc::new(UnsafeCell::new(Value::Utf8(string)))])?;
self.current_frame().push(Value::Ref(stringinstance)); self.execute_class(stringclass, "<init>([B)V",
vec![stringinstance.clone(),
unsafe_val(Value::Ref(ObjectRef::new_byte_array(string)))])?;
self.current_frame().push_ref(stringinstance);
} }
CpEntry::Long(l) => { CpEntry::Long(l) => {
self.current_frame().push(Value::I64(*l)); self.current_frame().push(Value::I64(*l));
@ -242,24 +246,24 @@ impl Vm {
// omitting the type checks so far // omitting the type checks so far
let n = read_u8(&code.opcodes, pc) as usize; let n = read_u8(&code.opcodes, pc) as usize;
self.current_frame() self.current_frame()
.push_arc(local_params[n].as_ref().unwrap().clone()); .push_ref(local_params[n].as_ref().unwrap().clone());
} }
ILOAD_0 | LLOAD_0 | FLOAD_0 | DLOAD_0 | ALOAD_0 => { ILOAD_0 | LLOAD_0 | FLOAD_0 | DLOAD_0 | ALOAD_0 => {
println!("LOAD"); println!("LOAD");
self.current_frame() self.current_frame()
.push_arc(local_params[0].as_ref().unwrap().clone()); .push_ref(local_params[0].as_ref().unwrap().clone());
} }
ILOAD_1 | LLOAD_1 | FLOAD_1 | DLOAD_1 | ALOAD_1 => { ILOAD_1 | LLOAD_1 | FLOAD_1 | DLOAD_1 | ALOAD_1 => {
self.current_frame() self.current_frame()
.push_arc(local_params[1].as_ref().unwrap().clone()); .push_ref(local_params[1].as_ref().unwrap().clone());
} }
ILOAD_2 | LLOAD_2 | FLOAD_2 | DLOAD_2 | ALOAD_2 => { ILOAD_2 | LLOAD_2 | FLOAD_2 | DLOAD_2 | ALOAD_2 => {
self.current_frame() self.current_frame()
.push_arc(local_params[2].as_ref().unwrap().clone()); .push_ref(local_params[2].as_ref().unwrap().clone());
} }
ILOAD_3 | LLOAD_3 | FLOAD_3 | DLOAD_3 | ALOAD_3 => { ILOAD_3 | LLOAD_3 | FLOAD_3 | DLOAD_3 | ALOAD_3 => {
self.current_frame() self.current_frame()
.push_arc(local_params[3].as_ref().unwrap().clone()); .push_ref(local_params[3].as_ref().unwrap().clone());
} }
IALOAD | LALOAD | FALOAD | DALOAD | AALOAD | BALOAD | CALOAD | SALOAD => unsafe { IALOAD | LALOAD | FALOAD | DALOAD | AALOAD | BALOAD | CALOAD | SALOAD => unsafe {
self.array_load()?; self.array_load()?;
@ -289,8 +293,8 @@ impl Vm {
DUP => { DUP => {
let value = self.current_frame().pop()?; let value = self.current_frame().pop()?;
println!("{:?}", value); println!("{:?}", value);
self.current_frame().push_arc(value.clone()); self.current_frame().push_ref(value.clone());
self.current_frame().push_arc(value); self.current_frame().push_ref(value);
} }
IRETURN | FRETURN | DRETURN => { IRETURN | FRETURN | DRETURN => {
println!("RETURN"); println!("RETURN");
@ -317,7 +321,7 @@ impl Vm {
let that_borrow = that.borrow(); let that_borrow = that.borrow();
let (_, val_index) = that_borrow.static_field_mapping.get(that_class_name).unwrap().get(name).unwrap(); let (_, val_index) = that_borrow.static_field_mapping.get(that_class_name).unwrap().get(name).unwrap();
println!("get static field {}", name); println!("get static field {}", name);
self.current_frame().push_arc(borrow.static_data.get(*val_index).unwrap().as_ref().unwrap().clone()); self.current_frame().push_ref(borrow.static_data.get(*val_index).unwrap().as_ref().unwrap().clone());
} }
PUTSTATIC => { PUTSTATIC => {
println!("PUTSTATIC"); println!("PUTSTATIC");
@ -369,7 +373,7 @@ impl Vm {
if let Value::Ref(instance) = &mut *objectref.get() { if let Value::Ref(instance) = &mut *objectref.get() {
if let ObjectRef::Object(ref mut object) = &mut *instance.get() { if let ObjectRef::Object(ref mut object) = &mut *instance.get() {
let value = object.get(class_name, field_name); let value = object.get(class_name, field_name);
self.current_frame().push_arc(Arc::clone(value)); self.current_frame().push_ref(Arc::clone(value));
} else { } else {
unreachable!() unreachable!()
} }
@ -419,7 +423,7 @@ impl Vm {
match *return_value.get() { match *return_value.get() {
Void => {} Void => {}
_ => { _ => {
self.current_frame().push_arc(return_value.clone()); self.current_frame().push_ref(return_value.clone());
} }
} }
println!("stack {} at {}", self.current_frame().len(), self.current_frame().at) println!("stack {} at {}", self.current_frame().len(), self.current_frame().at)
@ -445,7 +449,7 @@ impl Vm {
match *returnvalue.get() { match *returnvalue.get() {
Void => {} Void => {}
_ => { _ => {
self.current_frame().push_arc(returnvalue.clone()); self.current_frame().push_ref(returnvalue.clone());
} }
} }
} else { } else {
@ -460,9 +464,9 @@ impl Vm {
let class_name = borrow.cp_utf8(class_name_index).unwrap(); let class_name = borrow.cp_utf8(class_name_index).unwrap();
let class_to_instantiate = get_class(self, Some(&borrow.name), class_name)?; let class_to_instantiate = get_class(self, Some(&borrow.name), class_name)?;
let object = Arc::new(UnsafeCell::new(ObjectRef::Object(Box::new( let object = unsafe_ref(ObjectRef::Object(Box::new(
Vm::new_instance(class_to_instantiate), Vm::new_instance(class_to_instantiate),
)))); )));
self.current_frame().push(Value::Ref(Arc::clone(&object))); self.current_frame().push(Value::Ref(Arc::clone(&object)));
self.heap.new_object(object); self.heap.new_object(object);
} }
@ -476,7 +480,7 @@ impl Vm {
let count = self.current_frame().pop()?; let count = self.current_frame().pop()?;
if let Value::I32(count) = *count.get() { // why does pop()?.get() give weird results? 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 = ObjectRef::new_object_array(arraytype, count as usize);
let array = Arc::new(UnsafeCell::new(array)); let array = unsafe_ref(array);
self.current_frame().push(Value::Ref(Arc::clone(&array))); self.current_frame().push(Value::Ref(Arc::clone(&array)));
println!("{}", self.current_frame().len()); println!("{}", self.current_frame().len());