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)
|
.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,
|
||||||
|
|
|
||||||
34
src/heap.rs
34
src/heap.rs
|
|
@ -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
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
33
src/vm.rs
33
src/vm.rs
|
|
@ -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,7 +210,7 @@ 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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -209,14 +218,26 @@ impl Vm {
|
||||||
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.
|
|
@ -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(){
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue