hit a wall
This commit is contained in:
parent
76304fa616
commit
fa10621c56
1 changed files with 39 additions and 34 deletions
69
src/vm/vm.rs
69
src/vm/vm.rs
|
|
@ -6,6 +6,7 @@ use std::sync::Arc;
|
||||||
|
|
||||||
use anyhow::{anyhow, Error};
|
use anyhow::{anyhow, Error};
|
||||||
use log::{debug, info};
|
use log::{debug, info};
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
|
||||||
use Value::*;
|
use Value::*;
|
||||||
|
|
||||||
|
|
@ -18,7 +19,7 @@ use crate::native::invoke_native;
|
||||||
use crate::opcodes;
|
use crate::opcodes;
|
||||||
use crate::opcodes::*;
|
use crate::opcodes::*;
|
||||||
use crate::vm::array::{array_load, array_store};
|
use crate::vm::array::{array_load, array_store};
|
||||||
use crate::vm::operations::{get_name_and_type, get_signature_for_invoke, get_static};
|
use crate::vm::operations::{get_signature_for_invoke, get_static};
|
||||||
use crate::vm::stack::StackFrame;
|
use crate::vm::stack::StackFrame;
|
||||||
|
|
||||||
pub struct Vm {
|
pub struct Vm {
|
||||||
|
|
@ -164,7 +165,7 @@ impl Vm {
|
||||||
let mut local_params: Vec<Option<Value>> =
|
let mut local_params: Vec<Option<Value>> =
|
||||||
args.clone().iter().map(|e| Some(e.clone())).collect();
|
args.clone().iter().map(|e| Some(e.clone())).collect();
|
||||||
if method.is(Modifier::Native) {
|
if method.is(Modifier::Native) {
|
||||||
return Ok(invoke_native(&this_class.borrow().name, &method.name(), args));
|
return invoke_native(self, &this_class.borrow().name, &method.name(), args);
|
||||||
}
|
}
|
||||||
if let AttributeType::Code(code) = method.attributes.get("Code").unwrap() {
|
if let AttributeType::Code(code) = method.attributes.get("Code").unwrap() {
|
||||||
let stackframe = StackFrame::new(&this_class.borrow().name, &method.name());
|
let stackframe = StackFrame::new(&this_class.borrow().name, &method.name());
|
||||||
|
|
@ -256,7 +257,6 @@ impl Vm {
|
||||||
let string: Vec<u8> = this_class
|
let string: Vec<u8> = this_class
|
||||||
.borrow()
|
.borrow()
|
||||||
.cp_utf8(utf8)
|
.cp_utf8(utf8)
|
||||||
.unwrap()
|
|
||||||
.to_owned()
|
.to_owned()
|
||||||
.as_bytes()
|
.as_bytes()
|
||||||
.into();
|
.into();
|
||||||
|
|
@ -275,7 +275,7 @@ impl Vm {
|
||||||
self.current_frame().push(Value::I64(*l));
|
self.current_frame().push(Value::I64(*l));
|
||||||
}
|
}
|
||||||
CpEntry::ClassRef(utf8) => {
|
CpEntry::ClassRef(utf8) => {
|
||||||
let class_name = this_class.borrow().cp_utf8(utf8).unwrap().to_owned();
|
let class_name = this_class.borrow().cp_utf8(utf8).to_owned();
|
||||||
unsafe {
|
unsafe {
|
||||||
if let Some(class) = CLASSES.get(&class_name) {
|
if let Some(class) = CLASSES.get(&class_name) {
|
||||||
self.current_frame().push(class.clone());
|
self.current_frame().push(class.clone());
|
||||||
|
|
@ -302,9 +302,7 @@ impl Vm {
|
||||||
CpEntry::StringRef(utf8_index) => {
|
CpEntry::StringRef(utf8_index) => {
|
||||||
if let CpEntry::Utf8(s) = method.constant_pool.get(utf8_index).unwrap() {
|
if let CpEntry::Utf8(s) = method.constant_pool.get(utf8_index).unwrap() {
|
||||||
self.current_frame().push(Utf8(s.to_owned()));
|
self.current_frame().push(Utf8(s.to_owned()));
|
||||||
} else {
|
} else {}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
println!("{:?}", cp_entry);
|
println!("{:?}", cp_entry);
|
||||||
|
|
@ -384,6 +382,12 @@ impl Vm {
|
||||||
self.current_frame().push(value.clone());
|
self.current_frame().push(value.clone());
|
||||||
self.current_frame().push(value);
|
self.current_frame().push(value);
|
||||||
}
|
}
|
||||||
|
IDIV => {
|
||||||
|
let value1 = self.current_frame().pop()?;
|
||||||
|
let value2 = self.current_frame().pop()?;
|
||||||
|
self.current_frame().push(I32(value1.into_i32() / value2.into_i32()));
|
||||||
|
}
|
||||||
|
|
||||||
IFEQ | IFNE | IFLT | IFGE | IFGT | IFLE => {
|
IFEQ | IFNE | IFLT | IFGE | IFGT | IFLE => {
|
||||||
let jmp_to = read_u16(&code.opcodes, pc) - 3; // -3 so that offset = location of Cmp opcode
|
let jmp_to = read_u16(&code.opcodes, pc) - 3; // -3 so that offset = location of Cmp opcode
|
||||||
let value = self.current_frame().pop()?;
|
let value = self.current_frame().pop()?;
|
||||||
|
|
@ -415,19 +419,19 @@ impl Vm {
|
||||||
}
|
}
|
||||||
GETSTATIC => {
|
GETSTATIC => {
|
||||||
let field_index = read_u16(&code.opcodes, pc);
|
let field_index = read_u16(&code.opcodes, pc);
|
||||||
let field_value = get_static(self, this_class.clone(), field_index);
|
let field_value = get_static(self, this_class.clone(), field_index)?;
|
||||||
self.current_frame().push(field_value);
|
self.current_frame().push(field_value);
|
||||||
}
|
}
|
||||||
PUTSTATIC => {
|
PUTSTATIC => {
|
||||||
let mut borrow = this_class.borrow_mut();
|
let mut borrow = this_class.borrow_mut();
|
||||||
let cp_index = read_u16(&code.opcodes, pc);
|
let cp_index = read_u16(&code.opcodes, pc);
|
||||||
let (class_index, field_name_and_type_index) =
|
let (class_index, field_name_and_type_index) =
|
||||||
borrow.cp_field_ref(&cp_index).unwrap(); // all these unwraps are safe as long as the class is valid
|
borrow.cp_field_ref(&cp_index); // all these unwraps are safe as long as the class is valid
|
||||||
let (name_index, _) =
|
let (name_index, _) =
|
||||||
borrow.cp_name_and_type(field_name_and_type_index).unwrap();
|
borrow.cp_name_and_type(field_name_and_type_index);
|
||||||
let name = borrow.cp_utf8(name_index).unwrap();
|
let name = borrow.cp_utf8(name_index);
|
||||||
let class_name_index = borrow.cp_class_ref(class_index).unwrap();
|
let class_name_index = borrow.cp_class_ref(class_index);
|
||||||
let that_class_name = borrow.cp_utf8(class_name_index).unwrap();
|
let that_class_name = borrow.cp_utf8(class_name_index);
|
||||||
|
|
||||||
let val_index = if &borrow.name == that_class_name {
|
let val_index = if &borrow.name == that_class_name {
|
||||||
// may have to apply this in GETSTATIC too
|
// may have to apply this in GETSTATIC too
|
||||||
|
|
@ -437,7 +441,7 @@ impl Vm {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.get(name)
|
.get(name)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.1
|
.index
|
||||||
} else {
|
} else {
|
||||||
let that =
|
let that =
|
||||||
get_class(self, that_class_name.as_str())?;
|
get_class(self, that_class_name.as_str())?;
|
||||||
|
|
@ -448,21 +452,21 @@ impl Vm {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.get(name)
|
.get(name)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.1
|
.index
|
||||||
};
|
};
|
||||||
let value = self.current_frame().pop()?;
|
let value = self.current_frame().pop()?;
|
||||||
borrow.static_data[val_index] = Some(value);
|
borrow.static_data[val_index] = value;
|
||||||
}
|
}
|
||||||
GETFIELD => unsafe {
|
GETFIELD => unsafe {
|
||||||
let borrow = this_class.borrow();
|
let borrow = this_class.borrow();
|
||||||
let cp_index = read_u16(&code.opcodes, pc);
|
let cp_index = read_u16(&code.opcodes, pc);
|
||||||
let (class_index, field_name_and_type_index) =
|
let (class_index, field_name_and_type_index) =
|
||||||
borrow.cp_field_ref(&cp_index).unwrap();
|
borrow.cp_field_ref(&cp_index);
|
||||||
let (field_name_index, _) =
|
let (field_name_index, _) =
|
||||||
borrow.cp_name_and_type(field_name_and_type_index).unwrap();
|
borrow.cp_name_and_type(field_name_and_type_index);
|
||||||
let class_name_index = borrow.cp_class_ref(class_index).unwrap();
|
let class_name_index = borrow.cp_class_ref(class_index);
|
||||||
let class_name = borrow.cp_utf8(class_name_index).unwrap();
|
let class_name = borrow.cp_utf8(class_name_index);
|
||||||
let field_name = borrow.cp_utf8(field_name_index).unwrap();
|
let field_name = borrow.cp_utf8(field_name_index);
|
||||||
|
|
||||||
let objectref = self.current_frame().pop()?;
|
let objectref = self.current_frame().pop()?;
|
||||||
if let Ref(instance) = objectref {
|
if let Ref(instance) = objectref {
|
||||||
|
|
@ -473,19 +477,19 @@ impl Vm {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!("objectref {:?}", objectref)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
PUTFIELD => unsafe {
|
PUTFIELD => unsafe {
|
||||||
let borrow = this_class.borrow();
|
let borrow = this_class.borrow();
|
||||||
let cp_index = read_u16(&code.opcodes, pc);
|
let cp_index = read_u16(&code.opcodes, pc);
|
||||||
let (class_index, field_name_and_type_index) =
|
let (class_index, field_name_and_type_index) =
|
||||||
borrow.cp_field_ref(&cp_index).unwrap();
|
borrow.cp_field_ref(&cp_index);
|
||||||
let (field_name_index, _) =
|
let (field_name_index, _) =
|
||||||
borrow.cp_name_and_type(field_name_and_type_index).unwrap();
|
borrow.cp_name_and_type(field_name_and_type_index);
|
||||||
let class_name_index = borrow.cp_class_ref(class_index).unwrap();
|
let class_name_index = borrow.cp_class_ref(class_index);
|
||||||
let class_name = borrow.cp_utf8(class_name_index).unwrap();
|
let class_name = borrow.cp_utf8(class_name_index);
|
||||||
let field_name = borrow.cp_utf8(field_name_index).unwrap();
|
let field_name = borrow.cp_utf8(field_name_index);
|
||||||
|
|
||||||
let value = self.current_frame().pop()?;
|
let value = self.current_frame().pop()?;
|
||||||
let objectref = self.current_frame().pop()?;
|
let objectref = self.current_frame().pop()?;
|
||||||
|
|
@ -599,8 +603,8 @@ impl Vm {
|
||||||
NEW => {
|
NEW => {
|
||||||
let class_index = &read_u16(&code.opcodes, pc);
|
let class_index = &read_u16(&code.opcodes, pc);
|
||||||
let borrow = this_class.borrow();
|
let borrow = this_class.borrow();
|
||||||
let class_name_index = borrow.cp_class_ref(class_index).unwrap();
|
let class_name_index = borrow.cp_class_ref(class_index);
|
||||||
let class_name = borrow.cp_utf8(class_name_index).unwrap();
|
let class_name = borrow.cp_utf8(class_name_index);
|
||||||
let class_to_instantiate = get_class(self, class_name)?;
|
let class_to_instantiate = get_class(self, class_name)?;
|
||||||
|
|
||||||
let object = unsafe_ref(ObjectRef::Object(Box::new(Vm::new_instance(
|
let object = unsafe_ref(ObjectRef::Object(Box::new(Vm::new_instance(
|
||||||
|
|
@ -612,8 +616,8 @@ impl Vm {
|
||||||
ANEWARRAY => unsafe {
|
ANEWARRAY => unsafe {
|
||||||
let class_index = &read_u16(&code.opcodes, pc);
|
let class_index = &read_u16(&code.opcodes, pc);
|
||||||
let borrow = this_class.borrow();
|
let borrow = this_class.borrow();
|
||||||
let class_name_index = borrow.cp_class_ref(class_index).unwrap();
|
let class_name_index = borrow.cp_class_ref(class_index);
|
||||||
let class_name = borrow.cp_utf8(class_name_index).unwrap();
|
let class_name = borrow.cp_utf8(class_name_index);
|
||||||
let arraytype = get_class(self, class_name)?;
|
let arraytype = get_class(self, class_name)?;
|
||||||
let count = self.current_frame().pop()?;
|
let count = self.current_frame().pop()?;
|
||||||
if let I32(count) = count {
|
if let I32(count) = count {
|
||||||
|
|
@ -715,7 +719,8 @@ pub(crate) struct Invocation {
|
||||||
impl Invocation {
|
impl Invocation {
|
||||||
pub fn new(class_name: String, method: MethodSignature) -> Self {
|
pub fn new(class_name: String, method: MethodSignature) -> Self {
|
||||||
Self {
|
Self {
|
||||||
class_name, method
|
class_name,
|
||||||
|
method,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue