This commit is contained in:
Sander Hautvast 2023-09-29 18:18:32 +02:00
parent 9168867ab7
commit 121b0869f1
5 changed files with 46 additions and 40 deletions

View file

@ -36,7 +36,8 @@ impl Class {
self.methods.get(name).expect("ClassNountFoundException")
}
}
unsafe impl Send for Class {}
unsafe impl Sync for Class {}
pub struct Method {
pub(crate) constant_pool: Rc<HashMap<u16, CpEntry>>,
access_flags: u16,
@ -96,7 +97,7 @@ impl Field {
name_index: u16,
descriptor_index: u16,
attributes: HashMap<String, AttributeType>, ) -> Self {
Field { constant_pool, access_flags, name_index, descriptor_index, attributes: attributes }
Field { constant_pool, access_flags, name_index, descriptor_index, attributes }
}
pub fn name(&self) -> String {
@ -197,19 +198,19 @@ impl Exception {
#[derive(Debug)]
pub struct MethodCode {
max_stack: u16,
max_locals: u16,
_max_stack: u16,
_max_locals: u16,
pub(crate) opcodes: Vec<u8>,
exception_table: Vec<Exception>,
code_attributes: HashMap<String, AttributeType>,
_exception_table: Vec<Exception>,
_code_attributes: HashMap<String, AttributeType>,
}
impl MethodCode {
pub(crate) fn new(max_stack: u16, max_locals: u16,
pub(crate) fn new(_max_stack: u16, _max_locals: u16,
code: Vec<u8>,
exception_table: Vec<Exception>,
code_attributes: HashMap<String, AttributeType>) -> Self {
Self { max_stack, max_locals, opcodes: code, exception_table, code_attributes }
_exception_table: Vec<Exception>,
_code_attributes: HashMap<String, AttributeType>) -> Self {
Self { _max_stack, _max_locals, opcodes: code, _exception_table, _code_attributes }
}
}
@ -224,5 +225,8 @@ pub enum Value {
F64(f64),
BOOL(bool),
CHAR(char),
Ref(Arc<Object>)
Ref(Arc<Object>),
}
unsafe impl Send for Value {}
unsafe impl Sync for Value {}

View file

@ -1,5 +1,4 @@
use std::collections::HashMap;
use std::rc::Rc;
use std::sync::Arc;
use crate::class::{Class, Value};
@ -7,14 +6,17 @@ use crate::class::{Class, Value};
pub struct Object {
// locked: bool,
// hashcode: i32,
class: Arc<Class>,
_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 {
pub fn new(_class: Arc<Class>, data: HashMap<u16, Arc<Value>>) -> Self {
Self {
class,
_class,
data,
}
}

View file

@ -33,7 +33,7 @@ pub(crate) fn read_f64(data: &[u8], pos: usize) -> f64 {
pub fn find_class(classpath: &Vec<String>, class_name: &str) -> Result<String, Error> {
for clp_entry in classpath {
let mut maybe_path = clp_entry.clone();
maybe_path.push_str("/");
maybe_path.push('/');
maybe_path.push_str(class_name);
maybe_path.push_str(".class");
println!("{}", maybe_path);
@ -41,7 +41,7 @@ pub fn find_class(classpath: &Vec<String>, class_name: &str) -> Result<String, E
return Ok(maybe_path);
}
}
return Err(anyhow!("Class not found {}", class_name));
Err(anyhow!("Class not found {}", class_name))
}
pub fn read_class_file(name: String) -> Result<Vec<u8>, Error> {

View file

@ -6,9 +6,9 @@
// pub const dconst_1:u8 = 15; // (0xf) push double 1
// TODO turn all into references
pub const BIPUSH: &u8 = &16; // (0x10) Push byte
pub const LDC: u8 = 18; // (0x12) Push item from run-time pub constant pool
pub const LDC_W: u8 = 19; // (0x13) Push item from run-time constant pool (wide index)
pub const LDC2_W: u8 = 20; // (0x14) Push long or double from run-time constant pool (wide index)
pub const LDC: &u8 = &18; // (0x12) Push item from run-time pub constant pool
pub const LDC_W: &u8 = &19; // (0x13) Push item from run-time constant pool (wide index)
pub const LDC2_W: &u8 = &20; // (0x14) Push long or double from run-time constant pool (wide index)
// pub const fload:u8 = 23; // (0x17) Load float from local variable
// pub const dload:u8 = 24; // (0x18) load double from local variable
// pub const aload:u8 = 25; //0x19
@ -21,7 +21,7 @@ pub const LDC2_W: u8 = 20; // (0x14) Push long or double from run-time constant
// pub const dload_1:u8 = 39; // (0x27) Load double 1 from local variable
// pub const dload_2:u8 = 40; // (0x28) Load double 2 from local variable
// pub const dload_3:u8 = 41; // (0x29) Load double 3 from local variable
pub const ALOAD_0:u8 = 42;// (0x2a)
pub const ALOAD_0:&u8 = &42;// (0x2a)
// pub const aload_1:u8 = 43;// (0x2a)
// pub const aload_2:u8 = 44;// (0x2b)
// pub const aload_3:u8 = 45;// (0x2c)
@ -81,13 +81,13 @@ pub const ALOAD_0:u8 = 42;// (0x2a)
// pub const dcmpl:u8 = 151; // (0x97) compare double (less than)
// pub const dcmpg:u8 = 152; // (0x98) compare double (greater than)
//
pub const IRETURN: u8 = 172; // (0xac) ireturn
pub const FRETURN: u8 = 174; // (0xae) Return float from method
pub const DRETURN: u8 = 175; // (0xaf) Return double from method
pub const IRETURN: &u8 = &172; // (0xac) ireturn
pub const FRETURN: &u8 = &174; // (0xae) Return float from method
pub const DRETURN: &u8 = &175; // (0xaf) Return double from method
// pub const areturn: u8 = 176; //(0xb0) return reference
// pub const return_v: u8 = 177; // (0xb1) Return void from method (actually 'return' but that's a keyword)
pub const GETFIELD: u8 = 180; // (0xb4) Fetch field from object3
pub const NEW: u8 = 187; // (0xbb) Create new object
pub const GETFIELD: &u8 = &180; // (0xb4) Fetch field from object3
pub const NEW: &u8 = &187; // (0xbb) Create new object
// pub const invokevirtual: u8 = 182; // (0xb6) Invoke instance method; dispatch based on class
//
// pub const getstatic: u8 = 178; // (0xb2) Get static field from class

View file

@ -39,7 +39,7 @@ pub struct Vm {
impl Vm {
pub fn new(classpath: &'static str) -> Self {
Self {
classpath: classpath.split(":").into_iter().map(|s| s.to_owned()).collect(),
classpath: classpath.split(':').map(|s| s.to_owned()).collect(),
classes: HashMap::new(),
heap: Heap::new(),
}
@ -91,7 +91,7 @@ impl Vm {
stack.push(Arc::new(Value::I32(c)));
pc += 1;
}
&opcodes::LDC => {
opcodes::LDC => {
let cp_index = read_u8(&code.opcodes, pc) as u16;
match method.constant_pool.get(&cp_index).unwrap() {
CpEntry::Integer(i) => {
@ -104,7 +104,7 @@ impl Vm {
}
pc += 1;
}
&opcodes::LDC_W => {
opcodes::LDC_W => {
let cp_index = read_u16(&code.opcodes, pc);
match method.constant_pool.get(&cp_index).unwrap() {
CpEntry::Integer(i) => {
@ -117,7 +117,7 @@ impl Vm {
}
pc += 2;
}
&opcodes::LDC2_W => {
opcodes::LDC2_W => {
let cp_index = read_u16(&code.opcodes, pc);
match method.constant_pool.get(&cp_index).unwrap() {
CpEntry::Double(d) => {
@ -131,7 +131,7 @@ impl Vm {
pc += 2;
}
&opcodes::ALOAD_0 => {
opcodes::ALOAD_0 => {
match instance.clone() {
Some(r) => {
stack.push(Arc::new(Value::Ref(r)));
@ -139,21 +139,21 @@ impl Vm {
None => { panic!("static context") }
}
}
&opcodes::IRETURN => {
opcodes::IRETURN => {
return stack.pop();
}
&opcodes::DRETURN => {
opcodes::DRETURN => {
return stack.pop();
}
&opcodes::FRETURN => {
opcodes::FRETURN => {
return stack.pop();
}
&opcodes::GETFIELD => {
opcodes::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() {
if let CpEntry::Fieldref(_class_index, name_and_type_index) = method.constant_pool.get(&cp_index).unwrap() {
if let Value::Ref(inst) = &*stack.pop()? { //TODO smell?
if let CpEntry::NameAndType(name, _) = 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);
stack.push(value.clone());
}
@ -161,10 +161,10 @@ impl Vm {
}
pc += 2;
}
&opcodes::NEW => {
opcodes::NEW => {
let cp_index = read_u16(&code.opcodes, pc);
if let CpEntry::ClassRef(class_name_index) = method.constant_pool.get(&cp_index).unwrap() {
if let CpEntry::Utf8(class) = method.constant_pool.get(class_name_index).unwrap() {
if let CpEntry::Utf8(_) = method.constant_pool.get(class_name_index).unwrap() {
let class = self.get_class(class_name)?;
let object = Arc::new(self.new_instance(class));
stack.push(Arc::new(Value::Ref(object.clone())));