Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reformat all with cargo fmt #2

Merged
merged 1 commit into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion jclass/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::error::ErrorKind::{InvalidInput, Io};
use std::fmt::{Debug, Display, Formatter};
use std::{error::Error as StdError, io, result};
use crate::error::ErrorKind::{InvalidInput, Io};

pub type Result<T> = result::Result<T, Error>;

Expand Down
4 changes: 2 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use std::process;
use vm::vm::VM;

fn print_usage() -> Result<(), String> {
let current_exe = env::current_exe().map_err(
|err| format!("Failed to get the current executable path: {}", err))?;
let current_exe = env::current_exe()
.map_err(|err| format!("Failed to get the current executable path: {}", err))?;
let file_name = current_exe
.file_name()
.and_then(|name| name.to_str())
Expand Down
1 change: 0 additions & 1 deletion tests/integration_test.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

use vm::vm::VM;

#[test]
Expand Down
125 changes: 85 additions & 40 deletions vm/src/class_loader.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
use std::collections::HashMap;
use std::fs::File;
use std::io::Read;
use jclass::attributes::Attribute;
use jclass::class_file::{parse, ClassFile};
use jclass::constant_pool::ConstantPool::{Methodref, NameAndType, Utf8};
use jclass::attributes::Attribute::Code;
use crate::error::{Result, Error, ErrorKind};
use crate::error::{Error, ErrorKind, Result};
use crate::method_area::java_class::{JavaClass, Methods};
use crate::method_area::java_method::JavaMethod;
use crate::method_area::method_area::MethodArea;
use crate::method_area::signature::Signature;
use jclass::attributes::Attribute;
use jclass::attributes::Attribute::Code;
use jclass::class_file::{parse, ClassFile};
use jclass::constant_pool::ConstantPool::{Methodref, NameAndType, Utf8};
use std::collections::HashMap;
use std::fs::File;
use std::io::Read;

#[derive(Debug)]
pub struct ClassLoader {
Expand All @@ -28,7 +28,9 @@ impl ClassLoader {

let java_class = Self::to_java_class(class_file)?;

Ok(Self { method_area: MethodArea::new(java_class) })
Ok(Self {
method_area: MethodArea::new(java_class),
})
}

fn to_java_class(class_file: ClassFile) -> Result<JavaClass> {
Expand All @@ -45,64 +47,107 @@ impl ClassLoader {
for method in methods.iter() {
let method_name = Self::get_cpool_string(class_file, method.name_index() as usize)
.ok_or(Error::new_constant_pool("Error getting method name"))?;
let method_signature = Self::get_cpool_string(class_file, method.descriptor_index() as usize)
.ok_or(Error::new_constant_pool("Error getting method method_signature"))?;
let method_signature =
Self::get_cpool_string(class_file, method.descriptor_index() as usize).ok_or(
Error::new_constant_pool("Error getting method method_signature"),
)?;
let code = Self::get_cpool_code_attribute(method.attributes())
.ok_or(Error::new_constant_pool("Error getting method code"))?;
let key_signature = method_name + ":" + method_signature.as_str();

method_by_signature.insert(key_signature.clone(), JavaMethod::new(Signature::from_str(method_signature.as_str())?, code.0, code.1, code.2));

let cpool_index = Self::get_cpool_method_index(class_file, method.name_index(), method.descriptor_index());
method_by_signature.insert(
key_signature.clone(),
JavaMethod::new(
Signature::from_str(method_signature.as_str())?,
code.0,
code.1,
code.2,
),
);

let cpool_index = Self::get_cpool_method_index(
class_file,
method.name_index(),
method.descriptor_index(),
);
if let Some(index) = cpool_index {
methodsignature_by_cpoolindex.insert(index, key_signature);
}
}

Ok(Methods::new(methodsignature_by_cpoolindex, method_by_signature))
Ok(Methods::new(
methodsignature_by_cpoolindex,
method_by_signature,
))
}

fn get_cpool_string(class_file: &ClassFile, index: usize) -> Option<String> {
let constant_pool = class_file.constant_pool();

constant_pool.get(index)
.and_then(|item| match item {
Utf8 { value } => Some(value.clone()),
_ => None
})
constant_pool.get(index).and_then(|item| match item {
Utf8 { value } => Some(value.clone()),
_ => None,
})
}

fn get_cpool_method_index(class_file: &ClassFile, name_index_to_find: u16, signature_index: u16) -> Option<u16> {
fn get_cpool_method_index(
class_file: &ClassFile,
name_index_to_find: u16,
signature_index: u16,
) -> Option<u16> {
let constant_pool = class_file.constant_pool();

let found_name_and_type_index = constant_pool.iter()
.enumerate()
.find_map(|index| if let NameAndType { name_index, descriptor_index } = *index.1 {
let found_name_and_type_index = constant_pool.iter().enumerate().find_map(|index| {
if let NameAndType {
name_index,
descriptor_index,
} = *index.1
{
if name_index == name_index_to_find && descriptor_index == signature_index {
Some(index.0)
} else { None }
} else { None })? as u16;
} else {
None
}
} else {
None
}
})? as u16;

let this_class_index = class_file.this_class();

constant_pool.iter()
.enumerate()
.find_map(|index| if let Methodref { class_index, name_and_type_index } = *index.1 {
if class_index == this_class_index && name_and_type_index == found_name_and_type_index {
constant_pool.iter().enumerate().find_map(|index| {
if let Methodref {
class_index,
name_and_type_index,
} = *index.1
{
if class_index == this_class_index
&& name_and_type_index == found_name_and_type_index
{
Some(index.0 as u16)
} else { None }
} else { None })
}

fn get_cpool_code_attribute(attributes: &Vec<Attribute>) -> Option<(u16, u16, Vec<u8>)> {
attributes.iter()
.find_map(|item| {
if let Code { max_stack, max_locals, code, .. } = item {
Some((*max_stack, *max_locals, code.clone()))
} else {
None
}
})
} else {
None
}
})
}

fn get_cpool_code_attribute(attributes: &Vec<Attribute>) -> Option<(u16, u16, Vec<u8>)> {
attributes.iter().find_map(|item| {
if let Code {
max_stack,
max_locals,
code,
..
} = item
{
Some((*max_stack, *max_locals, code.clone()))
} else {
None
}
})
}

pub fn method_area(&self) -> &MethodArea {
Expand Down
4 changes: 2 additions & 2 deletions vm/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{io, result};
use std::fmt::{Debug, Display, Formatter};
use crate::error::ErrorKind::{ClassFile, ConstantPool, Execution, Io};
use std::fmt::{Debug, Display, Formatter};
use std::{io, result};

pub type Result<T> = result::Result<T, Error>;

Expand Down
38 changes: 25 additions & 13 deletions vm/src/execution_engine/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ impl<'a> Engine<'a> {
let mut last_value: Option<i32> = None;

while !stack_frames.is_empty() {
let stack_frame = stack_frames.last_mut()
let stack_frame = stack_frames
.last_mut()
.ok_or(Error::new_execution("Error getting stack frame"))?;

match stack_frame.get_bytecode_byte() {
Expand Down Expand Up @@ -76,7 +77,6 @@ impl<'a> Engine<'a> {
stack_frame.incr_pc();
let pos = stack_frame.get_bytecode_byte() as usize;


let val = stack_frame.get_local(pos);
stack_frame.push(val);

Expand Down Expand Up @@ -167,7 +167,6 @@ impl<'a> Engine<'a> {
println!("ISUB -> {a} - {b} = {result}");
}
104 => {

let b = stack_frame.pop();
let a = stack_frame.pop();
let result = a * b;
Expand Down Expand Up @@ -259,8 +258,6 @@ impl<'a> Engine<'a> {
} else {
stack_frame.advance_pc(3);
}


}
162 => {
println!("IF_ICMPGE");
Expand Down Expand Up @@ -304,31 +301,46 @@ impl<'a> Engine<'a> {
stack_frame.advance_pc(offset);
}
172 => {
println!("IRETURN -> locals={:?}, operand_stack={:?}", stack_frame.locals, stack_frame.operand_stack);
println!(
"IRETURN -> locals={:?}, operand_stack={:?}",
stack_frame.locals, stack_frame.operand_stack
);
let ret = stack_frame.pop();
stack_frames.pop();
stack_frames.last_mut()
stack_frames
.last_mut()
.ok_or(Error::new_execution("Error getting stack last value"))?
.push(ret);
}
177 => {
println!("RETURN -> locals={:?}, operand_stack={:?}", stack_frame.locals, stack_frame.operand_stack);
last_value = stack_frames.last()
println!(
"RETURN -> locals={:?}, operand_stack={:?}",
stack_frame.locals, stack_frame.operand_stack
);
last_value = stack_frames
.last()
.ok_or(Error::new_execution("Error getting stack last value"))?
.locals.last().copied();
.locals
.last()
.copied();
stack_frames.pop(); // Return from method, pop the current frame
// add more logic here
// add more logic here
}
184 => {
println!("INVOKESTATIC -> locals={:?}, operand_stack={:?}", stack_frame.locals, stack_frame.operand_stack);
println!(
"INVOKESTATIC -> locals={:?}, operand_stack={:?}",
stack_frame.locals, stack_frame.operand_stack
);

stack_frame.incr_pc();
let high = stack_frame.get_bytecode_byte() as u16;

stack_frame.incr_pc();
let low = stack_frame.get_bytecode_byte() as u16;
let methodref_constpool_index = (high << 8) | low;
let static_method = self.method_area.get_method_by_cpool_index(methodref_constpool_index)?;
let static_method = self
.method_area
.get_method_by_cpool_index(methodref_constpool_index)?;

let mut next_frame = static_method.new_stack_frame();
let arg_num = static_method.get_signature().get_arg_num();
Expand Down
5 changes: 2 additions & 3 deletions vm/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@

pub mod vm;
mod error;
mod stack;
pub mod vm;

mod class_loader;
mod method_area;
mod execution_engine;
mod method_area;
14 changes: 9 additions & 5 deletions vm/src/method_area/java_class.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::collections::HashMap;
use crate::method_area::java_method::JavaMethod;

use std::collections::HashMap;

#[derive(Debug)]
pub(crate) struct JavaClass {
Expand All @@ -13,15 +12,20 @@ pub(crate) struct Methods {
pub(crate) method_by_signature: HashMap<String, JavaMethod>,
}


impl JavaClass {
pub fn new(methods: Methods) -> Self {
Self { methods }
}
}

impl Methods {
pub fn new(methodsignature_by_cpoolindex: HashMap<u16, String>, method_by_signature: HashMap<String, JavaMethod>) -> Self {
Self { methodsignature_by_cpoolindex, method_by_signature }
pub fn new(
methodsignature_by_cpoolindex: HashMap<u16, String>,
method_by_signature: HashMap<String, JavaMethod>,
) -> Self {
Self {
methodsignature_by_cpoolindex,
method_by_signature,
}
}
}
9 changes: 6 additions & 3 deletions vm/src/method_area/java_method.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@

use crate::method_area::signature::Signature;
use crate::stack::stack_frame::StackFrame;


#[derive(Debug)]
pub(crate) struct JavaMethod {
signature: Signature,
Expand All @@ -13,7 +11,12 @@ pub(crate) struct JavaMethod {

impl JavaMethod {
pub fn new(signature: Signature, max_stack: u16, max_locals: u16, bytecode: Vec<u8>) -> Self {
Self { signature, max_stack, max_locals, bytecode }
Self {
signature,
max_stack,
max_locals,
bytecode,
}
}

pub fn new_stack_frame(&self) -> StackFrame {
Expand Down
Loading