62 lines
1.7 KiB
Rust
62 lines
1.7 KiB
Rust
use core::fmt::{Display, Formatter};
|
|
use std::error::Error as ErrorTrait;
|
|
|
|
use crate::classstore;
|
|
use crate::classstore::ClassStore;
|
|
use crate::stackframe::StackFrame;
|
|
|
|
#[derive(Debug)]
|
|
pub enum Error {
|
|
ClassStoreError(classstore::Error),
|
|
BadNameError(String),
|
|
}
|
|
|
|
impl From<classstore::Error> for Error {
|
|
fn from(value: classstore::Error) -> Self {
|
|
return Error::ClassStoreError(value);
|
|
}
|
|
}
|
|
|
|
impl ErrorTrait for Error {}
|
|
impl Display for Error {
|
|
fn fmt(&self, formatter: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
|
|
writeln!(formatter, "{self}")?;
|
|
if let Some(e) = self.source() {
|
|
writeln!(formatter, "\tCaused by: {e:?}")?;
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct JVM {
|
|
class_store: ClassStore,
|
|
stack_frames: Vec<StackFrame>,
|
|
}
|
|
|
|
impl JVM {
|
|
pub fn new() -> Self {
|
|
return JVM {
|
|
class_store: ClassStore::new(),
|
|
stack_frames: Vec::new(),
|
|
}
|
|
}
|
|
|
|
pub fn load_class(&mut self, name: &String) -> Result<String, classstore::Error> {
|
|
return self.class_store.load_class(name);
|
|
}
|
|
|
|
pub fn invoke_static(&mut self, class_name: &String, method_name: &String) -> Result<(), Error> {
|
|
|
|
let (class_file, class_index) = self.class_store.get_or_load_class(class_name)?;
|
|
|
|
let method_index = class_file.find_method_index(method_name)
|
|
.ok_or(Error::BadNameError(format!("Could not find method '{}' in class '{}'", method_name, class_name)))?;
|
|
|
|
let new_frame = StackFrame::new(class_file, class_index, method_index.try_into().expect(&format!("Bad method index: {}", method_index)));
|
|
|
|
self.stack_frames.push(new_frame);
|
|
|
|
return Ok(());
|
|
}
|
|
}
|