solved the illegal refs issues

This commit is contained in:
Sander Hautvast 2023-10-19 17:04:15 +02:00
parent 050c1821c2
commit 29d672db50
2 changed files with 74 additions and 37 deletions

View file

@ -39,27 +39,34 @@ pub fn get_class(vm: &mut Vm, _calling_class_name: Option<&str>, class_name: &st
Arc::new(RefCell::new(class)) Arc::new(RefCell::new(class))
}); });
let clone = class.clone(); // not sure why I have to create the clones first
let clone1 = class.clone();
let clone2 = class.clone(); let clone2 = class.clone();
if !class.borrow().inited { let clone3 = class.clone();
let super_class_name = class.borrow().super_class_name.as_ref().map(|n| n.to_owned());
let inited = class.borrow().inited;
if !inited {
// must not enter here twice!
clone1.borrow_mut().inited = true;
let super_class_name = class.clone().borrow().super_class_name.as_ref().map(|n| n.to_owned());
{ {
if let Some(super_class_name) = super_class_name { if let Some(super_class_name) = super_class_name {
if let Ok(super_class) = get_class(vm, Some(class_name), &super_class_name) { if let Ok(super_class) = get_class(vm, Some(class_name), &super_class_name) {
class.borrow_mut().super_class = Some(super_class); clone1.borrow_mut().super_class = Some(super_class);
} else { } else {
unreachable!() unreachable!()
} }
} }
} }
Class::initialize_fields(class.clone()); Class::initialize_fields(clone3);
let clinit = clone.borrow().methods.contains_key("<clinit>()V"); let clinit = clone1.borrow().methods.contains_key("<clinit>()V");
if clinit{ if clinit{
vm.execute_class(class.clone(), "<clinit>()V", vec![]).unwrap(); vm.execute_class(clone1, "<clinit>()V", vec![]).unwrap();
} }
println!("end clinit");
clone.borrow_mut().inited = true;
} }
Ok(clone2) Ok(clone2)
} }
@ -243,7 +250,7 @@ impl Class {
"D" => Value::F64(0.0), "D" => Value::F64(0.0),
_ => Value::Null, _ => Value::Null,
}; };
println!("{} = {:?}", name, value); // println!("{} = {:?}", name, value);
field_data[*index] = Some(value.into()); field_data[*index] = Some(value.into());
} }
} }

View file

@ -121,60 +121,76 @@ impl Vm {
let mut pc = &mut 0; let mut pc = &mut 0;
while *pc < code.opcodes.len() { while *pc < code.opcodes.len() {
let opcode = read_u8(&code.opcodes, pc); let opcode = read_u8(&code.opcodes, pc);
println!("stack {} opcode {} ", self.current_frame().len(), opcode); let f= self.current_frame();
print!("at {}: stack {}, opcode {}: ", f.at, f.len(), opcode);
match opcode { match opcode {
ACONST_NULL => { ACONST_NULL => {
println!("ACONST");
self.current_frame().push(Value::Null); self.current_frame().push(Value::Null);
} }
ICONST_M1 => { ICONST_M1 => {
println!("ICONST");
self.current_frame().push(I32(-1)); self.current_frame().push(I32(-1));
} }
ICONST_0 => { ICONST_0 => {
println!("ICONST_0"); println!("ICONST");
self.current_frame().push(I32(0)); self.current_frame().push(I32(0));
} }
ICONST_1 => { ICONST_1 => {
println!("ICONST_1"); println!("ICONST");
self.current_frame().push(I32(1)); self.current_frame().push(I32(1));
} }
ICONST_2 => { ICONST_2 => {
println!("ICONST");
self.current_frame().push(I32(2)); self.current_frame().push(I32(2));
} }
ICONST_3 => { ICONST_3 => {
println!("ICONST");
self.current_frame().push(I32(3)); self.current_frame().push(I32(3));
} }
ICONST_4 => { ICONST_4 => {
println!("ICONST");
self.current_frame().push(I32(4)); self.current_frame().push(I32(4));
} }
ICONST_5 => { ICONST_5 => {
println!("ICONST");
self.current_frame().push(I32(5)); self.current_frame().push(I32(5));
} }
LCONST_0 => { LCONST_0 => {
println!("LCONST");
self.current_frame().push(Value::I64(0)); self.current_frame().push(Value::I64(0));
} }
LCONST_1 => { LCONST_1 => {
println!("LCONST");
self.current_frame().push(Value::I64(1)); self.current_frame().push(Value::I64(1));
} }
FCONST_0 => { FCONST_0 => {
println!("FCONST");
self.current_frame().push(Value::F32(0.0)); self.current_frame().push(Value::F32(0.0));
} }
FCONST_1 => { FCONST_1 => {
println!("FCONST");
self.current_frame().push(Value::F32(1.0)); self.current_frame().push(Value::F32(1.0));
} }
FCONST_2 => { FCONST_2 => {
println!("FCONST");
self.current_frame().push(Value::F32(2.0)); self.current_frame().push(Value::F32(2.0));
} }
DCONST_0 => { DCONST_0 => {
println!("DCONST");
self.current_frame().push(Value::F64(0.0)); self.current_frame().push(Value::F64(0.0));
} }
DCONST_1 => { DCONST_1 => {
println!("DCONST");
self.current_frame().push(Value::F64(1.0)); self.current_frame().push(Value::F64(1.0));
} }
SIPUSH => { SIPUSH => {
println!("SIPUSH");
let s = read_u16(&code.opcodes, pc) as i32; let s = read_u16(&code.opcodes, pc) as i32;
self.current_frame().push(I32(s)); self.current_frame().push(I32(s));
} }
BIPUSH => { BIPUSH => {
println!("BIPUSH");
let c = read_u8(&code.opcodes, pc) as i32; let c = read_u8(&code.opcodes, pc) as i32;
self.current_frame().push(I32(c)); self.current_frame().push(I32(c));
} }
@ -243,56 +259,67 @@ impl Vm {
} }
} }
ILOAD | LLOAD | FLOAD | DLOAD | ALOAD => { ILOAD | LLOAD | FLOAD | DLOAD | ALOAD => {
println!("LOAD");
// 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_ref(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_0");
self.current_frame() self.current_frame()
.push_ref(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 => {
println!("LOAD_1");
self.current_frame() self.current_frame()
.push_ref(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 => {
println!("LOAD_2");
self.current_frame() self.current_frame()
.push_ref(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 => {
println!("LOAD_3");
self.current_frame() self.current_frame()
.push_ref(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 {
println!("ALOAD");
self.array_load()?; self.array_load()?;
}, },
ISTORE | LSTORE | FSTORE | DSTORE | ASTORE => { ISTORE | LSTORE | FSTORE | DSTORE | ASTORE => {
println!("STORE");
let index = read_u8(&code.opcodes, pc) as usize; let index = read_u8(&code.opcodes, pc) as usize;
self.store(&mut local_params, index)?; self.store(&mut local_params, index)?;
} }
ISTORE_0 | LSTORE_0 | DSTORE_0 | ASTORE_0 | FSTORE_0 => { ISTORE_0 | LSTORE_0 | DSTORE_0 | ASTORE_0 | FSTORE_0 => {
println!("STORE_0");
self.store(&mut local_params, 0)?; self.store(&mut local_params, 0)?;
} }
ISTORE_1 | LSTORE_1 | DSTORE_1 | ASTORE_1 | FSTORE_1 => { ISTORE_1 | LSTORE_1 | DSTORE_1 | ASTORE_1 | FSTORE_1 => {
println!("STORE"); println!("STORE_1");
self.store(&mut local_params, 1)?; self.store(&mut local_params, 1)?;
} }
ISTORE_2 | LSTORE_2 | DSTORE_2 | ASTORE_2 | FSTORE_2 => { ISTORE_2 | LSTORE_2 | DSTORE_2 | ASTORE_2 | FSTORE_2 => {
println!("STORE_2");
self.store(&mut local_params, 2)?; self.store(&mut local_params, 2)?;
} }
ISTORE_3 | LSTORE_3 | DSTORE_3 | ASTORE_3 | FSTORE_3 => { ISTORE_3 | LSTORE_3 | DSTORE_3 | ASTORE_3 | FSTORE_3 => {
println!("STORE_3");
self.store(&mut local_params, 3)?; self.store(&mut local_params, 3)?;
} }
BASTORE | IASTORE | LASTORE | CASTORE | SASTORE | FASTORE | DASTORE BASTORE | IASTORE | LASTORE | CASTORE | SASTORE | FASTORE | DASTORE | AASTORE => unsafe {
| AASTORE => unsafe { self.array_store()? }, println!("ASTORE");
self.array_store()? },
POP => { POP => {
println!("POP");
self.current_frame().pop()?; self.current_frame().pop()?;
} }
DUP => { DUP => {
println!("DUP");
let value = self.current_frame().pop()?; let value = self.current_frame().pop()?;
println!("{:?}", value);
self.current_frame().push_ref(value.clone()); self.current_frame().push_ref(value.clone());
self.current_frame().push_ref(value); self.current_frame().push_ref(value);
} }
@ -308,6 +335,7 @@ impl Vm {
return Ok(Value::void()); return Ok(Value::void());
} }
GETSTATIC => { GETSTATIC => {
println!("GETSTATIC");
let borrow = this_class.borrow(); let borrow = this_class.borrow();
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) =
@ -327,28 +355,29 @@ impl Vm {
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) =
// borrow.cp_field_ref(&cp_index).unwrap(); // all these unwraps are safe as long as the class is valid borrow.cp_field_ref(&cp_index).unwrap(); // all these unwraps are safe as long as the class is valid
// let (name_index, _) = borrow.cp_name_and_type(field_name_and_type_index).unwrap(); let (name_index, _) = borrow.cp_name_and_type(field_name_and_type_index).unwrap();
// let (name) = borrow.cp_utf8(name_index).unwrap(); let (name) = borrow.cp_utf8(name_index).unwrap();
// let class_name_index = borrow.cp_class_ref(class_index).unwrap(); let class_name_index = borrow.cp_class_ref(class_index).unwrap();
// 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 {// may have to apply this in GETSTATIC too 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.current_frame().pop()?; let value = self.current_frame().pop()?;
// borrow.static_data[val_index] = Some(value); borrow.static_data[val_index] = Some(value);
// } else { } else {
// let that = get_class(self, Some(&borrow.name), that_class_name.as_str())?; let that = get_class(self, Some(&borrow.name), that_class_name.as_str())?;
// let that_borrow = that.borrow(); // if already borrowed, then that_class == this_class let that_borrow = that.borrow(); // if already borrowed, then that_class == this_class
// 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();
// let value = self.current_frame().pop()?; let value = self.current_frame().pop()?;
// borrow.static_data[*val_index] = Some(value); borrow.static_data[*val_index] = Some(value);
// } }
} }
GETFIELD => unsafe { GETFIELD => unsafe {
println!("PUTFIELD");
let borrow = this_class.borrow(); let borrow = this_class.borrow();
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) =
@ -372,6 +401,7 @@ impl Vm {
} }
}, },
PUTFIELD => unsafe { PUTFIELD => unsafe {
println!("PUTFIELD");
let borrow = this_class.borrow(); let borrow = this_class.borrow();
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) =
@ -483,7 +513,7 @@ impl Vm {
//TODO implement all opcodes //TODO implement all opcodes
_ => { _ => {
panic!("opcode not implemented {:?}", self.stackframes) panic!("opcode {} not implemented {:?}", opcode, self.stackframes)
//TODO implement proper --stacktraces-- error handling //TODO implement proper --stacktraces-- error handling
} }
} }