method invocations!

This commit is contained in:
Sander Hautvast 2023-09-30 18:01:25 +02:00
parent f76a89a086
commit c821944fac
6 changed files with 69 additions and 13 deletions

View file

@ -33,9 +33,19 @@ impl Class {
.get(name) .get(name)
.ok_or(anyhow!("Method {} not found", name)) .ok_or(anyhow!("Method {} not found", name))
} }
pub fn get_name(&self) -> &str {
if let CpEntry::ClassRef(name_index ) = self.constant_pool.get(&self.this_class).unwrap(){
if let CpEntry::Utf8(name) = self.constant_pool.get(name_index).unwrap(){
return name;
}
}
panic!();
}
} }
unsafe impl Send for Class {} unsafe impl Send for Class {}
unsafe impl Sync for Class {} unsafe impl Sync for Class {}
pub struct Method { pub struct Method {
pub(crate) constant_pool: Rc<HashMap<u16, CpEntry>>, pub(crate) constant_pool: Rc<HashMap<u16, CpEntry>>,
access_flags: u16, access_flags: u16,

View file

@ -1,21 +1,47 @@
use crate::class::{Class, Value}; use crate::class::{Class, Value};
use std::collections::HashMap; use std::collections::HashMap;
use std::fmt;
use std::sync::Arc; use std::sync::Arc;
use crate::classloader::CpEntry;
#[derive(Debug)]
pub struct Object { pub struct Object {
// locked: bool, // locked: bool,
// hashcode: i32, // hashcode: i32,
_class: Arc<Class>, pub class: Arc<Class>,
pub data: HashMap<u16, Arc<Value>>, //TODO optimize pub data: HashMap<u16, Arc<Value>>, //TODO optimize
} }
unsafe impl Send for Object {} unsafe impl Send for Object {}
unsafe impl Sync for Object {} unsafe impl Sync for Object {}
impl Object { impl Object {
pub fn new(_class: Arc<Class>, data: HashMap<u16, Arc<Value>>) -> Self { pub fn new(class: Arc<Class>, data: HashMap<u16, Arc<Value>>) -> Self {
Self { _class, data } Self { class, data }
}
fn get_field(&self, cp_index: &u16) -> &str {
if let CpEntry::Utf8(name) = self.class.constant_pool.get(&cp_index).unwrap() {
return name;
}
panic!()
}
}
impl fmt::Debug for Object {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let fields: Vec<String> = self.data.iter().map(|(k, v)| {
let mut r: String = self.get_field(k).into();
r.push(':');
r.push_str(format!("{:?}", v).as_str());
r
}
).collect();
write!(
f,
"{} {{ {:?} }}",
self.class.get_name(), fields
)
} }
} }

View file

@ -51,6 +51,7 @@ pub const ALOAD_0: &u8 = &42; // (0x2a)
// pub const bastore:u8 = 84; // (0x54) // pub const bastore:u8 = 84; // (0x54)
// //
// pub const castore:u8 = 85; // (0x55) // pub const castore:u8 = 85; // (0x55)
pub const POP: &u8 = &87; // (0x57) Pop the top operand stack value
pub const DUP: &u8 = &89; // (0x59) duplicate the top operand stack value pub const DUP: &u8 = &89; // (0x59) duplicate the top operand stack value
// pub const dup_x1: u8 = 90; // (0x5a) Duplicate the top operand stack value and insert two values down // pub const dup_x1: u8 = 90; // (0x5a) Duplicate the top operand stack value and insert two values down
// pub const dup_x2: u8 = 91; // (0x5b) Duplicate the top operand stack value and insert two or three values down // pub const dup_x2: u8 = 91; // (0x5b) Duplicate the top operand stack value and insert two or three values down

View file

@ -63,9 +63,9 @@ impl Vm {
println!("get_class {}", class_name); println!("get_class {}", class_name);
let entry = self.classes.entry(class_name.into()); let entry = self.classes.entry(class_name.into());
let entry = entry.or_insert_with(|| { let entry = entry.or_insert_with(|| {
print!("read class {} ", class_name); // print!("read class {} ", class_name);
let resolved_path = find_class(&self.classpath, class_name).expect("Class not found"); let resolved_path = find_class(&self.classpath, class_name).expect("Class not found");
println!("full path {}", resolved_path); // println!("full path {}", resolved_path);
let bytecode = read_bytecode(resolved_path).unwrap(); let bytecode = read_bytecode(resolved_path).unwrap();
Arc::new(load_class(bytecode).unwrap()) Arc::new(load_class(bytecode).unwrap())
}); });
@ -171,26 +171,35 @@ impl Vm {
} }
} }
} }
POP =>{
self.local_stack().pop().expect("Stack empty");
}
DUP => { DUP => {
println!("DUP"); println!("DUP");
let value = self.local_stack().pop().expect("Stack empty"); let value = self.local_stack().pop().expect("Stack empty");
println!("{:?}", value);
self.local_stack().push(value.clone()); self.local_stack().push(value.clone());
self.local_stack().push(value); self.local_stack().push(value);
} }
IRETURN => { IRETURN => {
println!("return I");
return self.local_stack().pop(); return self.local_stack().pop();
} }
DRETURN => { DRETURN => {
println!("return D");
return self.local_stack().pop(); return self.local_stack().pop();
} }
FRETURN => { FRETURN => {
println!("return F");
return self.local_stack().pop(); return self.local_stack().pop();
} }
RETURN_VOID => { RETURN_VOID => {
println!("return");
self.stack.pop(); self.stack.pop();
return Ok(Arc::new(Void)) return Ok(Arc::new(Void));
} }
GETFIELD => { GETFIELD => {
println!("GETFIELD");
let cp_index = read_u16(&code.opcodes, pc); let cp_index = read_u16(&code.opcodes, pc);
if let CpEntry::Fieldref(_class_index, name_and_type_index) = if let CpEntry::Fieldref(_class_index, name_and_type_index) =
method.constant_pool.get(&cp_index).unwrap() method.constant_pool.get(&cp_index).unwrap()
@ -201,22 +210,34 @@ impl Vm {
method.constant_pool.get(name_and_type_index).unwrap() method.constant_pool.get(name_and_type_index).unwrap()
{ {
let value = inst.data.get(name).unwrap(); let value = inst.data.get(name).unwrap();
// println!("{:?}", value); println!("{:?}", value);
self.local_stack().push(value.clone()); self.local_stack().push(value.clone());
} }
} }
} }
pc += 2; pc += 2;
} }
INVOKEVIRTUAL =>{ INVOKEVIRTUAL => {
//TODO implement let cp_index = read_u16(&code.opcodes, pc);
let instance = self.local_stack().pop().unwrap();
if let Some((class, method)) = get_signature_for_invoke(Rc::clone(&method.constant_pool), cp_index) {
let return_value = self.execute(class.as_str(), method.as_str(), Some(instance))?;
if let Void = *return_value {} else { // not let?
self.local_stack().push(return_value);
}
}
pc += 2;
} }
INVOKESPECIAL => { INVOKESPECIAL => {
println!("INVOKESPECIAL"); println!("INVOKESPECIAL");
let cp_index = read_u16(&code.opcodes, pc); let cp_index = read_u16(&code.opcodes, pc);
let instance = self.local_stack().pop().unwrap(); let instance = self.local_stack().pop().unwrap();
if let Some((class, method)) = get_signature_for_invoke(Rc::clone(&method.constant_pool), cp_index) { if let Some((class, method)) = get_signature_for_invoke(Rc::clone(&method.constant_pool), cp_index) {
self.execute(class.as_str(), method.as_str(), Some(instance)); let return_value = self.execute(class.as_str(), method.as_str(), Some(instance))?;
if let Void = *return_value {} else { // not let?
self.local_stack().push(return_value);
}
} }
pc += 2; pc += 2;

Binary file not shown.

View file

@ -1,7 +1,5 @@
public class FloatBean { public class FloatBean {
private final static float f =42.0F;
private float value; private float value;
public float getValue(){ public float getValue(){