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 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, } 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 { 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(()); } }