struct instead of complicated tuple
This commit is contained in:
parent
6a96ce56ee
commit
70094bb3e2
1 changed files with 28 additions and 20 deletions
48
src/vm.rs
48
src/vm.rs
|
|
@ -6,6 +6,7 @@ use std::sync::Arc;
|
||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
|
|
||||||
use crate::class::{AttributeType, Class, Value};
|
use crate::class::{AttributeType, Class, Value};
|
||||||
|
use crate::class::AttributeType::Signature;
|
||||||
use crate::class::Value::Void;
|
use crate::class::Value::Void;
|
||||||
use crate::classloader::{CpEntry, load_class};
|
use crate::classloader::{CpEntry, load_class};
|
||||||
use crate::heap::{Heap, Object};
|
use crate::heap::{Heap, Object};
|
||||||
|
|
@ -111,14 +112,14 @@ impl Vm {
|
||||||
let stackframe = StackFrame::new(class_name, method_name);
|
let stackframe = StackFrame::new(class_name, method_name);
|
||||||
self.stack.push(stackframe);
|
self.stack.push(stackframe);
|
||||||
|
|
||||||
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!("opcode {} ", opcode);
|
println!("opcode {} ", opcode);
|
||||||
match opcode {
|
match opcode {
|
||||||
BIPUSH => {
|
BIPUSH => {
|
||||||
println!("BISPUSH");
|
println!("BISPUSH");
|
||||||
let c =read_u8(&code.opcodes, pc);
|
let c = read_u8(&code.opcodes, pc);
|
||||||
self.local_stack().push(Arc::new(UnsafeCell::new(Value::I32(c as i32))));
|
self.local_stack().push(Arc::new(UnsafeCell::new(Value::I32(c as i32))));
|
||||||
}
|
}
|
||||||
LDC => {
|
LDC => {
|
||||||
|
|
@ -161,7 +162,6 @@ impl Vm {
|
||||||
panic!("unexpected")
|
panic!("unexpected")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
FLOAD_0 => {
|
FLOAD_0 => {
|
||||||
self.local_stack().push(args[0].clone());
|
self.local_stack().push(args[0].clone());
|
||||||
|
|
@ -257,15 +257,13 @@ impl Vm {
|
||||||
INVOKEVIRTUAL => {
|
INVOKEVIRTUAL => {
|
||||||
let cp_index = read_u16(&code.opcodes, pc);
|
let cp_index = read_u16(&code.opcodes, pc);
|
||||||
unsafe {
|
unsafe {
|
||||||
if let Some((class, method)) = get_signature_for_invoke(Rc::clone(&method.constant_pool), cp_index) {
|
if let Some(invocation) = get_signature_for_invoke(Rc::clone(&method.constant_pool), cp_index) {
|
||||||
let signature = method.0.as_str();
|
let mut args = Vec::with_capacity(invocation.method.num_args);
|
||||||
let num_args = method.1;
|
for _ in 0..invocation.method.num_args {
|
||||||
let mut args = Vec::with_capacity(num_args);
|
|
||||||
for _ in 0..num_args {
|
|
||||||
args.insert(0, self.local_stack().pop()?);
|
args.insert(0, self.local_stack().pop()?);
|
||||||
}
|
}
|
||||||
args.insert(0, self.local_stack().pop()?);
|
args.insert(0, self.local_stack().pop()?);
|
||||||
let mut returnvalue = self.execute(class.as_str(), signature, args)?;
|
let mut returnvalue = self.execute(&invocation.class_name, &invocation.method.name, args)?;
|
||||||
match *returnvalue.get() {
|
match *returnvalue.get() {
|
||||||
Void => {}
|
Void => {}
|
||||||
_ => { self.local_stack().push(returnvalue.clone()); }
|
_ => { self.local_stack().push(returnvalue.clone()); }
|
||||||
|
|
@ -277,15 +275,13 @@ impl Vm {
|
||||||
println!("INVOKESPECIAL");
|
println!("INVOKESPECIAL");
|
||||||
unsafe {
|
unsafe {
|
||||||
let cp_index = read_u16(&code.opcodes, pc);
|
let cp_index = read_u16(&code.opcodes, pc);
|
||||||
if let Some((class, method)) = get_signature_for_invoke(Rc::clone(&method.constant_pool), cp_index) {
|
if let Some(invocation) = get_signature_for_invoke(Rc::clone(&method.constant_pool), cp_index) {
|
||||||
let signature = method.0.as_str();
|
let mut args = Vec::with_capacity(invocation.method.num_args);
|
||||||
let num_args = method.1;
|
for _ in 0..invocation.method.num_args {
|
||||||
let mut args = vec![];
|
|
||||||
for _ in 0..num_args {
|
|
||||||
args.insert(0, self.local_stack().pop()?);
|
args.insert(0, self.local_stack().pop()?);
|
||||||
}
|
}
|
||||||
args.insert(0, self.local_stack().pop()?);
|
args.insert(0, self.local_stack().pop()?);
|
||||||
let mut returnvalue = self.execute(class.as_str(), signature, args)?;
|
let mut returnvalue = self.execute(&invocation.class_name, &invocation.method.name, args)?;
|
||||||
match *returnvalue.get() {
|
match *returnvalue.get() {
|
||||||
Void => {}
|
Void => {}
|
||||||
_ => { self.local_stack().push(returnvalue.clone()); }
|
_ => { self.local_stack().push(returnvalue.clone()); }
|
||||||
|
|
@ -323,13 +319,26 @@ impl Vm {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct Invocation {
|
||||||
|
class_name: String,
|
||||||
|
method: MethodSignature,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MethodSignature {
|
||||||
|
name: String,
|
||||||
|
num_args: usize,
|
||||||
|
}
|
||||||
|
|
||||||
//TODO refs with lifetime
|
//TODO refs with lifetime
|
||||||
fn get_signature_for_invoke(cp: Rc<HashMap<u16, CpEntry>>, index: u16) -> Option<(String, (String, usize))> {
|
fn get_signature_for_invoke(cp: Rc<HashMap<u16, CpEntry>>, index: u16) -> Option<Invocation> {
|
||||||
if let CpEntry::MethodRef(class_index, name_and_type_index) = cp.get(&index).unwrap() {
|
if let CpEntry::MethodRef(class_index, name_and_type_index) = cp.get(&index).unwrap() {
|
||||||
if let Some(method_signature) = get_name_and_type(Rc::clone(&cp), *name_and_type_index) {
|
if let Some(method_signature) = get_name_and_type(Rc::clone(&cp), *name_and_type_index) {
|
||||||
if let CpEntry::ClassRef(class_name_index) = cp.get(class_index).unwrap() {
|
if let CpEntry::ClassRef(class_name_index) = cp.get(class_index).unwrap() {
|
||||||
if let CpEntry::Utf8(class_name) = cp.get(class_name_index).unwrap() {
|
if let CpEntry::Utf8(class_name) = cp.get(class_name_index).unwrap() {
|
||||||
return Some((class_name.into(), method_signature));
|
return Some(Invocation {
|
||||||
|
class_name: class_name.into(),
|
||||||
|
method: method_signature
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -337,15 +346,14 @@ fn get_signature_for_invoke(cp: Rc<HashMap<u16, CpEntry>>, index: u16) -> Option
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_name_and_type(cp: Rc<HashMap<u16, CpEntry>>, index: u16) -> Option<(String, usize)> {
|
fn get_name_and_type(cp: Rc<HashMap<u16, CpEntry>>, index: u16) -> Option<MethodSignature> {
|
||||||
if let CpEntry::NameAndType(method_name_index, signature_index) = cp.get(&index).unwrap() {
|
if let CpEntry::NameAndType(method_name_index, signature_index) = cp.get(&index).unwrap() {
|
||||||
if let CpEntry::Utf8(method_name) = cp.get(method_name_index).unwrap() {
|
if let CpEntry::Utf8(method_name) = cp.get(method_name_index).unwrap() {
|
||||||
if let CpEntry::Utf8(signature) = cp.get(signature_index).unwrap() {
|
if let CpEntry::Utf8(signature) = cp.get(signature_index).unwrap() {
|
||||||
let mut method_signature: String = method_name.into();
|
let mut method_signature: String = method_name.into();
|
||||||
let num_args = get_hum_args(signature);
|
let num_args = get_hum_args(signature);
|
||||||
method_signature.push_str(signature);
|
method_signature.push_str(signature);
|
||||||
|
return Some(MethodSignature { name: method_signature, num_args });
|
||||||
return Some((method_signature, num_args));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue