method invocations!
This commit is contained in:
parent
f76a89a086
commit
c821944fac
6 changed files with 69 additions and 13 deletions
10
src/class.rs
10
src/class.rs
|
|
@ -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,
|
||||
|
|
|
|||
34
src/heap.rs
34
src/heap.rs
|
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
35
src/vm.rs
35
src/vm.rs
|
|
@ -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,22 +210,34 @@ 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
pc += 2;
|
||||
}
|
||||
INVOKEVIRTUAL =>{
|
||||
//TODO implement
|
||||
INVOKEVIRTUAL => {
|
||||
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.
|
|
@ -1,7 +1,5 @@
|
|||
public class FloatBean {
|
||||
|
||||
private final static float f =42.0F;
|
||||
|
||||
private float value;
|
||||
|
||||
public float getValue(){
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue