2024-08-30 15:33:54 +02:00
|
|
|
|
|
|
|
use crate::classfile::{ JavaClassFile, AttributeData };
|
|
|
|
|
|
|
|
#[derive(Copy, Clone, Debug)]
|
2024-09-02 11:28:00 +02:00
|
|
|
pub enum Value {
|
2024-08-30 15:33:54 +02:00
|
|
|
Boolean(bool),
|
|
|
|
Byte(u8),
|
|
|
|
Char(u16),
|
|
|
|
Short(u16),
|
|
|
|
Int(u32),
|
|
|
|
Float(u32),
|
|
|
|
Reference(u32),
|
|
|
|
ReturnAddress(u32),
|
|
|
|
Double0(u32),
|
|
|
|
Double1(u32),
|
|
|
|
Long0(u32),
|
|
|
|
Long1(u32),
|
|
|
|
Empty(),
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct OperandStack {
|
2024-09-02 11:28:00 +02:00
|
|
|
stack: Box<[Value]>,
|
2024-08-30 15:33:54 +02:00
|
|
|
depth: u16,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl OperandStack {
|
|
|
|
fn new(size: u16) -> Self {
|
|
|
|
return OperandStack {
|
2024-09-02 11:28:00 +02:00
|
|
|
stack: vec![Value::Empty(); size.into()].into_boxed_slice(),
|
2024-08-30 15:33:54 +02:00
|
|
|
depth: 0,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct StackFrame {
|
2024-09-02 11:28:00 +02:00
|
|
|
pub locals: Box<[Value]>,
|
|
|
|
pub operand_stack: OperandStack,
|
|
|
|
pub class_index: usize,
|
|
|
|
pub method_index: u16,
|
|
|
|
pub instruction_pointer: u32,
|
2024-08-30 15:33:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
impl StackFrame {
|
2024-09-02 11:28:00 +02:00
|
|
|
pub fn new(classfile: &JavaClassFile, class_index: usize, method_index: u16, arguments: &[Value]) -> Self {
|
2024-08-30 15:33:54 +02:00
|
|
|
let method_info = &classfile.methods[method_index as usize];
|
|
|
|
let code_data = match &method_info.attributes[method_info.code_attribute_index].data {
|
|
|
|
AttributeData::Code(data) => data,
|
|
|
|
_ => unreachable!(),
|
|
|
|
};
|
2024-09-02 11:28:00 +02:00
|
|
|
let mut locals = vec![Value::Empty(); code_data.max_locals.into()].into_boxed_slice();
|
|
|
|
|
|
|
|
assert!(locals.len() >= arguments.len());
|
|
|
|
|
|
|
|
for (index, v) in arguments.iter().enumerate() {
|
|
|
|
locals[index] = *v;
|
|
|
|
}
|
2024-08-30 15:33:54 +02:00
|
|
|
|
|
|
|
StackFrame {
|
2024-09-02 11:28:00 +02:00
|
|
|
locals,
|
2024-08-30 15:33:54 +02:00
|
|
|
operand_stack: OperandStack::new(code_data.max_stack),
|
2024-09-02 11:28:00 +02:00
|
|
|
class_index,
|
2024-08-30 15:33:54 +02:00
|
|
|
method_index,
|
|
|
|
instruction_pointer: 0,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|