rusty-jvm 0.5.0

An implementation of a Java Virtual Machine (JVM).
Documentation
use crate::vm::error::{Error, Result};
use crate::vm::execution_engine::{
    ops_comparison_processor, ops_constant_processor, ops_control_processor,
    ops_conversion_processor, ops_extended_processor, ops_load_processor, ops_math_processor,
    ops_reference_processor, ops_stack_processor, ops_store_processor,
};
use crate::vm::stack::stack_frame::{StackFrame, StackFrames};
use crate::vm::stack::stack_frames_util::StackFramesUtil;
use tracing::{span, trace, Level};

pub(crate) struct Engine {}

impl Engine {
    pub(crate) fn execute(initial_stack_frame: StackFrame, reason: &str) -> Result<Vec<i32>> {
        trace!("@@@ Entering execute: {reason}");

        let mut stack_frames = StackFrames::new(vec![initial_stack_frame]);
        let mut last_value = vec![];
        while !stack_frames.is_empty() {
            let (class, code, pc, line_numbers) = {
                let frame = stack_frames
                    .last()
                    .ok_or(Error::new_execution("Error getting stack frame"))?;
                (
                    frame.current_class_name().to_string(),
                    frame.get_bytecode_byte(),
                    frame.pc(),
                    frame.line_numbers(),
                )
            };
            let instruction_line_num = StackFramesUtil::extract_line_number(line_numbers, pc);
            let span = span!(Level::TRACE, "", "{class}:{instruction_line_num}");
            let _entered = span.enter();

            match code {
                0u8..=20u8 => {
                    ops_constant_processor::process(code, &class, &mut stack_frames)?;
                }
                21u8..=53u8 => {
                    ops_load_processor::process(code, &mut stack_frames)?;
                }
                54u8..=86u8 => {
                    ops_store_processor::process(code, &mut stack_frames)?;
                }
                87u8..=95u8 => {
                    ops_stack_processor::process(code, &mut stack_frames)?;
                }
                96u8..=132u8 => {
                    ops_math_processor::process(code, &mut stack_frames)?;
                }
                133u8..=147u8 => {
                    ops_conversion_processor::process(code, &mut stack_frames)?;
                }
                148u8..=166u8 => {
                    ops_comparison_processor::process(code, &mut stack_frames)?;
                }
                167u8..=177u8 => {
                    last_value = ops_control_processor::process(code, &mut stack_frames)?;
                }
                178u8..=195u8 => {
                    ops_reference_processor::process(code, &class, &mut stack_frames)?;
                }
                196u8..=201u8 => {
                    ops_extended_processor::process(code, &class, &mut stack_frames)?;
                }
                _ => unreachable!("{}", format! {"xxx = {}", code}),
            }
        }

        Ok(last_value)
    }
}