solved the illegal refs issues
This commit is contained in:
parent
050c1821c2
commit
29d672db50
2 changed files with 74 additions and 37 deletions
25
src/class.rs
25
src/class.rs
|
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
86
src/vm.rs
86
src/vm.rs
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue