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)
.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 Sync for Class {}
pub struct Method {
pub(crate) constant_pool: Rc<HashMap<u16, CpEntry>>,
access_flags: u16,

View file

@ -1,21 +1,47 @@
use crate::class::{Class, Value};
use std::collections::HashMap;
use std::fmt;
use std::sync::Arc;
use crate::classloader::CpEntry;
#[derive(Debug)]
pub struct Object {
// locked: bool,
// hashcode: i32,
_class: Arc<Class>,
pub class: Arc<Class>,
pub data: HashMap<u16, Arc<Value>>, //TODO optimize
}
unsafe impl Send for Object {}
unsafe impl Sync for Object {}
impl Object {
pub fn new(_class: Arc<Class>, data: HashMap<u16, Arc<Value>>) -> Self {
Self { _class, data }
pub fn new(class: Arc<Class>, data: HashMap<u16, Arc<Value>>) -> Self {
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 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_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

View file

@ -63,9 +63,9 @@ impl Vm {
println!("get_class {}", class_name);
let entry = self.classes.entry(class_name.into());
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");
println!("full path {}", resolved_path);
// println!("full path {}", resolved_path);
let bytecode = read_bytecode(resolved_path).unwrap();
Arc::new(load_class(bytecode).unwrap())
});
@ -171,26 +171,35 @@ impl Vm {
}
}
}
POP =>{
self.local_stack().pop().expect("Stack empty");
}
DUP => {
println!("DUP");
let value = self.local_stack().pop().expect("Stack empty");
println!("{:?}", value);
self.local_stack().push(value.clone());
self.local_stack().push(value);
}
IRETURN => {
println!("return I");
return self.local_stack().pop();
}
DRETURN => {
println!("return D");
return self.local_stack().pop();
}
FRETURN => {
println!("return F");
return self.local_stack().pop();
}
RETURN_VOID => {
println!("return");
self.stack.pop();
return Ok(Arc::new(Void))
return Ok(Arc::new(Void));
}
GETFIELD => {
println!("GETFIELD");
let cp_index = read_u16(&code.opcodes, pc);
if let CpEntry::Fieldref(_class_index, name_and_type_index) =
method.constant_pool.get(&cp_index).unwrap()
@ -201,7 +210,7 @@ impl Vm {
method.constant_pool.get(name_and_type_index).unwrap()
{
let value = inst.data.get(name).unwrap();
// println!("{:?}", value);
println!("{:?}", value);
self.local_stack().push(value.clone());
}
}
@ -209,14 +218,26 @@ impl Vm {
pc += 2;
}
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 => {
println!("INVOKESPECIAL");
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) {
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;

Binary file not shown.

View file

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